root/tags/5.52/ciupd.c

Revision 4, 51.3 kB (checked in by heitor.barbieri, 2 years ago)

Versão 5.52 do cisis (28/04/2010)

Line 
1/*
2CCOPTS = -DINCPRECX=0 -DEXCFMCGI=1 -DEXCFMXML=1
3$(CC) -DINCPROCX=0 $(CCOPTS) wtrig2.c
4*/
5
6#include <stdio.h>
7#include <string.h>
8#include <ctype.h>
9#define DIR_FILE 1                  /* list=directory */
10#if DIR_FILE
11#include <sys/types.h>
12#include <dirent.h>
13#endif
14#include "cisis.h"
15
16#ifndef PROCXSLT
17#if UNIX
18#define PROCXSLT  0
19#else /* UNIX */
20#define PROCXSLT  0
21#endif /* UNIX */
22#endif
23#if PROCXSLT
24#include <libxslt/transform.h>
25#include <libxslt/xsltutils.h>
26#endif /* PROCXSLT */
27
28#ifndef INCPROCX      // proc Y / proc T (bug if called by cifm3.c)      /* usa CIIFU (+FST(+FMT)) */
29#define INCPROCX  1
30#define INCPROCXT 1
31#endif
32
33#ifndef INCPRECX      // 6words/if= in Gsplit (ciupdsplt.c)              /* usa CITRM */
34#define INCPRECX  1
35#endif
36
37#ifndef INCPRCCX      // socket client with Gload (ciupdsocx.c)          /* */
38#define INCPRCCX  1
39#endif
40
41#ifndef INCPRSSX      // server                                          /* */
42#define INCPRSSX  0   // 1
43#endif
44
45#if INCPRCCX
46#ifndef PROCXSOCKREC
47#define PROCXSOCKREC 1    // include ciupdsocx.c
48#endif /* PROCXSOCKREC */
49#endif /* INCPRCCX */
50
51
52#if CICPP
53#if INCPROCX
54#include "ciifu.hpp"
55#endif
56#endif
57
58#if CICPP
59#if INCPRECX
60#include "citrm.hpp"
61#endif
62#endif
63
64#ifdef USE_ERROR_SYS
65#include <ui_win.hpp>
66#include <errorsys.hpp>
67extern MY_ERROR_SYSTEM * errsys;
68extern MESS_SYSTEM *mess;
69extern UIW_WINDOW * wprogress;
70#include <textdb.hpp>
71#define USE_INFO_SYS
72#endif
73
74/* ----------------------------- upd.c ------------------------------ */
75
76#define RUCTRACE    00
77#define RUCTRACX    00
78#define RUCTRAC2    00
79#define RUFTRACE    0
80#define RUGTRACE    0
81#define RUHTRACE    0
82#define RUITRACE    0
83#define RUJTRACE    0
84#define RUKTRACE    0
85#define RUFxRACE    0
86
87#define RUUTRACE    0
88
89#define MULTRACE    1           /* multrace runtime switch */
90
91#if !CICPP
92
93int  recisis0_m=1;              /* recisis0() init .mst */
94int  recisis0_s=0;              /* recisis0() system file type */
95
96#endif /* CICPP */
97
98#if !CICPP
99#define CIUPD_CISISX_SOURCE 1
100#include "cisisx.c"
101#endif
102
103#if PROCXSLT
104#include "cidump.c"
105#endif /* PROCXSLT */ 
106
107#if CICPP
108#define NO_IREC  -1L
109#endif /* CICPP */
110
111#if MULTI
112
113#if CICPP
114int RECSTRU :: xrecunlck(int option)
115#else /* CICPP */
116int recunlck(irec,option)                                              /*
117------------
118                    se option = EWLOCK faz EWL unlock
119                    se option = DELOCK faz DEL unlock
120                    se option = RLOCK faz RL unlock;
121                    retorna RCNORMAL ou aborta
122                                                                      */
123LONGX irec;          /* vrecp[] element defining RECdbxp/MFRmfn */
124int option;
125#endif /* CICPP */
126{
127    RECSTRU *recp;
128    DBXSTRU *dbxp;
129    FFI oldgdbl;
130    LONGX mfn;
131    int fd,rc;
132    FFI n;
133    int uok=0,force=0;
134    LONGX comb;      /* gdb getmfr comb */
135    int comp;       /* gdb getmfr comp */
136
137#if CICPP
138#if RUUTRACE
139    LONGX irec = NO_IREC;
140#endif
141    RECSTRU *wrecp=NULL;
142    recp=this;
143#else
144    LONGX wrec;
145    if (irec < 0 || irec >= maxnrec) fatal("recunlck/irec");
146    if (!nrecs || !vrecp[irec]) fatal("recunlck/recinit");
147    recp=vrecp[irec];
148#endif
149
150    /* get input information */
151    dbxp=RECdbxp;
152    mfn=MFRmfn;
153
154    /* keep old RECgdbl */
155    oldgdbl=RECgdbl;
156
157    /* allocate working control record / record leader */
158#if CICPP
159    try { wrecp=new RECSTRU(cisisxp); wrecp->xrecalloc(sizeof(M0STRU)); }
160    catch (BAD_ALLOC) { return(-1); }
161    wrecp->recdbxp=dbxp;
162    recp=wrecp;
163#else /* CICPP */
164    for (wrec=maxnrec; wrec--; ) {
165        if (!vrecp[wrec]) /* ja' decrementado */ break;
166    }
167    if (wrec < 0) return(-1);
168    recallok(wrec,sizeof(M0STRU));
169    VRECdbxp(wrec)=dbxp;
170    recp=vrecp[wrec];
171#endif /* CICPP */
172
173
174    if (option & FORCE) { force=1; option-=FORCE; }
175
176    if (option & RDELOCK) option = (mfn) ? RLOCK : DELOCK;
177
178    if (option != EWLOCK && option != DELOCK && option != RLOCK)
179        fatal("recunlck/option");
180
181#if RUUTRACE
182 printf("recunlck - irec=%ld  dbn=%s/%ld  unlck=%d\n",irec,DBXname,mfn,option);
183#endif
184
185    if (DBXnetws == MONONETS) {
186        if (multrace)
187            printf("<u> %s/%ld [%s MONONETS]\n",
188              DBXname,mfn,(option&RDELOCK)?((option==RLOCK)?"RL":"DEL"):"EWL");
189        return(RCNORMAL);
190    }
191
192    if (!DBXmsopn) fatal("recunlck/msopn");
193    dbxopenw(DBXname,DBXname,mx1extp,&DBXmsopn,&DBXmsopw,"recunlck/msopn/w");
194    fd=DBXmsopn;
195
196    /* step 1: lock the .mst file and get the ctl rec */
197
198    if (multrace) printf("<u> %s .mst lock \n",DBXname);
199#if BEFORE950220
200    /* .mst file lock: lock */
201    if (dbxflock(dbxp,"M")) fatal("recunlck/file lock");
202    /* get the current ctl rec */
203    keeplock=REClock; REClock=NOLOCK;
204    if (recread(recp,0L) != RCNORMAL) fatal("recunlck/read/ctl");
205    REClock=keeplock;
206    /* check another's exclusive write lock */
207    if (MF0mfcxx3 && !DBXewlxx && !force) {
208        if (multrace) printf("<u> %s has exclusive write lock\n",DBXname);
209        fatal("recunlck/exclusive write lock");
210    }
211#else
212    if (dbxflock(dbxp,"M")) {
213        if (multrace) printf("<u> %s .mst lock/denied \n",DBXname);
214        if (dbxewlrc) return(RCLOCK);
215        fatal("recunlck/file lock");
216    }
217    /* wait another's exclusive write lock */
218    if (force) {
219        if (LSEEK64(DBXmsopn,0L,SEEK_SET) != 0) fatal("recunlck/force/lseek");
220        n=CIREAD(DBXmsopn,MFX,sizeof(M0STRU));
221#if CNV_PCBINUM
222        ConvertMST_CTLSTRUCT(MFX);
223#endif
224        if (n != sizeof(M0STRU)) {
225            if (dbxewlrc) return(RCLOCK);
226            fatal("recunlck/force/read");
227        }
228    }
229    else
230        if (dbxwlock(dbxp,MFX,dbxwloop)) {
231            if (multrace) printf("<u> %s .mst ewl is on !!!\n",DBXname);
232            if (dbxewlrc) return(RCLOCK);
233            fatal("recunlck/must wait ewl");
234        }
235    /* copy MFX to what will be written */
236    memcpy(DBXmsibp,MFX,sizeof(M0STRU));
237#endif
238
239    /* check data entry lock */
240    if (option & RDELOCK && (!MF0mfcxx2 || !DBXdelxx) && !force) {
241        if (multrace)
242            printf("<u> %s/mfcxx2=%ld delxx=%d\n",DBXname,MF0mfcxx2,DBXdelxx);
243        fatal("recunlck/data entry lock is off");
244    }
245
246    /* step 2: logical unlock */
247
248    if (option == EWLOCK || option == DELOCK) {         /* EWL or DEL */
249        if (option == EWLOCK) {
250            /* unflag exclusive write lock */
251            if (MF0mfcxx3 || DBXewlxx) {
252                if (MF0mfcxx3) MF0mfcxx3--;
253                if (DBXewlxx) DBXewlxx--;
254                /* update input buffer */
255                ((M0STRU *)DBXmsibp)->m0mfcxx3=MF0mfcxx3;
256                uok=1;
257            }
258        }
259        else {
260            /* unflag data entry lock */
261            if (MF0mfcxx2 || DBXdelxx) {
262                if (MF0mfcxx2) MF0mfcxx2--;
263                if (DBXdelxx) DBXdelxx--;
264                /* update input buffer */
265                ((M0STRU *)DBXmsibp)->m0mfcxx2=MF0mfcxx2;
266                uok=1;
267            }
268        }
269        /* write it back */
270        if (uok) {
271            if (LSEEK64(fd,0L,SEEK_SET) != 0)
272                fatal("recunlck/lseek/ctl");
273#if DBXMSTXL /* AOT 18/06/2002 */
274    if (DBXmstxl) {
275                ((M0STRU *)DBXmsibp)->m0mftype += DBXmstxl * 256;
276    }
277#endif
278#if CNV_PCBINUM
279            memcpy(cnv_pcbuff,DBXmsibp,sizeof(M0STRU));
280            ConvertMST_CTLSTRUCT(cnv_pcbuff);
281            if (CIWRITE(fd,cnv_pcbuff,sizeof(M0STRU)) != sizeof(M0STRU))
282#else
283            if (CIWRITE(fd,DBXmsibp,sizeof(M0STRU)) != sizeof(M0STRU))
284#endif
285                fatal("recunlck/write/ctl");
286#if DBXMSTXL /* AOT 18/06/2002 */
287    if (DBXmstxl) {
288                ((M0STRU *)DBXmsibp)->m0mftype &= 0x00FF;
289    }
290#endif
291        }
292
293    } /* end of data entry lock */
294
295    else {                                              /* RL */
296
297        /* get its xref to rewrite the leader segment */
298        recreadl=1; /* leader only */
299        rc=recread(recp,mfn);
300        comb=recxrefb; comp=recxrefp;
301#ifndef USE_ERROR_SYS
302        if (rc == RCEOF || rc == RCPDEL) fatal("recunlck/EOFPDEL");
303#else
304        if (!(rc == RCEOF || rc == RCPDEL)) {
305#endif
306
307        /* reset existing record lock and call recwmast */
308        if (oldgdbl || (force && RECgdbw)) {
309            if (multrace)
310              printf("<u> %s/%ld mfrl=%04x=+%d\n",DBXname,mfn,RECgdbl,MFRmfrl);
311            /* write back the leader segment */
312#if CICPP
313            recwmast(NULL,comb,comp,0,1); /* leader only */
314#else
315            recwmast(NULL,recp,comb,comp,0,1); /* leader only */
316#endif /* CICPP */
317            uok=1;
318        }
319#ifdef USE_ERROR_SYS
320                }
321#endif
322    } /* end of record unlock */
323
324    /* step 3: .mst file unlock */
325
326    if (multrace)
327        printf("<u> %s .mst unlock [%s %s]\n",DBXname,
328              (option&RDELOCK)?((option==RLOCK)?"RL":"DEL"):"EWL",
329              (uok)?"off":"unlock denied");
330
331    if (dbxulock(dbxp,"M")) fatal("recunlck/file unlock");
332
333#if CICPP
334    if (wrecp) delete wrecp;
335    recp=this;
336#else
337#if BEFORE20000809
338    if (wrec) if (vrecp[wrec]) {
339#else
340    if (wrec >= 0) if (vrecp[wrec]) {
341#endif
342        FREE(vrecp[wrec]); vrecp[wrec]=NULL; nrecs--;
343    }
344    recp=vrecp[irec];
345#endif
346
347    if (uok) {
348        RECgdbl=RECgdbw=0;
349        return(RCNORMAL);
350    }
351
352    return(RCEOF);
353}
354#endif /* MULTI */
355
356
357#if CICPP
358int RECSTRU :: xrecupdat(void)
359#else /* CICPP */
360int recupdat(crec,irec)                                                 /*
361------------
362                    abenda se vrecp nao inicializado;
363                    abenda se registros crec/irec ainda nao alocados;
364                    abenda se tipo de crec diferente de TYPEMF0;
365                    abenda se mfn menor do que 1 ou maior do que MAXMFN;
366                    seta dbxp de irec igual ao de crec;
367                    chama recwrite();
368                    retorna RCNORMAL
369                                                                      */
370LONGX crec;          /* indice de vrecp, para recwrite() */
371LONGX irec;          /* indice de vrecp, para recwrite() */
372#endif /* CICPP */
373{
374
375    RECSTRU *recp, *crecp;
376    LONGX mfn;
377    int rc;
378
379    if (rectrace) multrace=1;
380
381#if CICPP
382    try { crecp = new RECSTRU(cisisxp); }
383    catch (BAD_ALLOC) { fatal("recupdat/ALLOC/crecp"); }
384
385    crecp->xrecalloc(sizeof(M0STRU));
386    recp =this;
387    crecp->xrecord(RDBname,0L);
388
389    recp=crecp;         /* tmp */
390
391#else /* CICPP */
392
393    if (!nrecs)
394        fatal("recupdat/RECINIT");
395
396    if (crec < 0 || crec >= maxnrec) fatal("recupdat/crec/index");
397    if (irec < 0 || irec >= maxnrec) fatal("recupdat/irec/index");
398
399    recp=vrecp[crec];   /* tmp */
400
401#endif /* CICPP */
402
403    if (MF0nxtmfn < 1) fatal("recupdat/crec/nxtmfn");
404
405    if (MF0nxtmfb < 1) fatal("recupdat/crec/nxtmfb");
406
407    if (MF0mftype != MSMFTUSR &&
408        MF0mftype != MSMFTMSG) fatal("recupdat/crec/mftype");
409
410    if (MF0nxtmfn == 1)
411        if (MF0mftype != MSMFTMSG)
412            if (MF0nxtmfp <= sizeof(M0STRU)) fatal("recupdat/crec/nxtmfp/1");
413
414    if (MF0nxtmfp > MSBSIZ) fatal("recupdat/crec/nxtmfp/MSBSIZ");
415
416#if CICPP
417    recp=this;
418#else /* CICPP */
419    crecp=vrecp[crec]; recp=vrecp[irec];
420#endif /* CICPP */
421
422    if (!crecp || !recp)
423        fatal("recupdat/RECALLOC");
424
425    if (crecp->rectype != TYPEMF0)
426        fatal("recupdat/TYPEMF0");
427
428    if ((mfn=MFRmfn) < 1 || mfn > MAXUPDMFN)
429#if MULTI
430      if (!(RECwlock & NEWREC && MFRmfn == 0))
431#endif
432        fatal("recupdat/mfn");
433
434#if !CICPP
435#if RUCTRACE || RUCTRAC2
436printf("recupdat - crec=%ld  irec=%ld  dbn(crec)=%s  mfn=%ld  opw=%d,%d\n",
437 crec,irec,VRDBname(crec),mfn,VRDBxropw(crec),VRDBmsopw(crec));
438#endif
439#endif /* CICPP */
440
441    RECdbxp=crecp->recdbxp;             /* get dbxp from control record */
442#if CICPP
443    rc=recwrite(crecp);
444#else
445    rc=recwrite(crecp,recp);
446#endif /* CICPP */
447
448#if RUCTRACE
449#if CICPP
450    recp=crecp;
451#else
452    recp=vrecp[crec];
453#endif /* CICPP */
454    printf("recupdat - RECrc=%d  Ctlmfr: %ld,%ld,%ld,%d,%d,%ld,%ld,%ld,%ld\n",
455        RECrc,
456        MF0ctlmfn,MF0nxtmfn,MF0nxtmfb,MF0nxtmfp,
457        MF0mftype,MF0reccnt,MF0mfcxx1,MF0mfcxx2,MF0mfcxx3);
458#if CICPP
459    recp = this;
460#else
461    recp=vrecp[irec];
462#endif /* CICPP */
463    printf("recupdat - RECrc=%d  Leader: %ld,%d,%ld,%d,%d,%d,%d\n",
464        RECrc,MFRmfn,MFRmfrl,MFRmfbwb,MFRmfbwp,MFRbase,MFRnvf,MFRstatus);
465    printf("recupdat - rc=%d\n",rc);
466#endif
467#if !CICPP
468#if RUCTRAC2
469printf("recupdat : crec=%ld  irec=%ld  dbn(crec)=%s  mfn=%ld  opw=%d,%d\n",
470 crec,irec,VRDBname(crec),mfn,VRDBxropw(crec),VRDBmsopw(crec));
471#endif
472#endif /* CICPP */
473
474#if CICPP
475    delete crecp;
476#endif /* CICPP */
477
478    return(rc);
479}
480
481
482#if CICPP
483int RECSTRU :: xrecwrite(RECSTRU *crecp)
484#else /* CICPP */
485int recwrite(crecp,recp)                                              /*
486------------
487                    seta dbxp e ms0p desce crecp;
488                    seta mfn desde recp;
489                    abenda de dbxp diferentes;
490                    obtem ptr para .mst e seu (mfn) status em .xrf;
491                    regrava o registro recp;
492                    altera e regrava o registro crecp;
493                    mantem .xrf;
494                    retorna RCNORMAL ou aborta
495                                                                      */
496RECSTRU *crecp;     /* elemento de vrecp, para info/store nxtmfn,mfb,mfp */
497RECSTRU *recp;      /* elemento de vrecp, para info/store mfbwb,mfbwp  */
498#endif /* CICPP */
499{
500    DBXSTRU *dbxp;
501    M0STRU *ms0p;   /* defines MS0 */
502    M1STRU *mshp;   /* defines MSH */
503
504    LONGX mfn;
505    LONGX lastmfn;
506    int newblk;
507
508    int rc;
509    FFI n;
510    XRPTR xrftiv;    /* gdb .xrf pointer */
511    LONGX comb;      /* gdb getmfr comb */
512    int comp;        /* gdb getmfr comp */
513
514    M1STRU header;  /* to read LEADER bytes */
515
516#if CNV_PCFILES
517    char unibuff[MSNVSPLT]; /* CNV_PCFILES/recwrite - mshp */
518#endif
519
520    int pend;       /* if update is pending */
521    int pendnew;    /* if update is pending - newrec */
522    int pendupd;    /* if update is pending - update */
523
524    LONGX thiscomb;
525    off_t xbyte;
526    int thiscomp;
527    LONGX nxtcomp;
528
529    int flagnew;        /* record will be written as a newrec */
530    unsigned inplace;   /* NEVER or MAYBE */
531
532#if MULTI
533    int isnewrec;
534#if BEFORE950220
535    int keeplock;
536#endif
537#endif
538
539#if DBXMSTXL
540int pow, vtot;
541#endif
542
543#define NEVER 0
544#define MAYBE 1
545
546#if CICPP
547    RECSTRU *recp = this;
548#endif /* CICPP */
549
550    dbxp=crecp->recdbxp;
551
552#if BEFORE950724
553    if (!DBXxropn) fatal("recwrite/xropn");
554    if (!DBXmsopn) fatal("recwrite/msopn");
555#else
556    if (!DBXxropn || !DBXmsopn) mstsetup(DBXname,0L,0L);
557#endif
558
559    dbxopenw(DBXname,DBXname,xx1extp,&DBXxropn,&DBXxropw,"recwrite/xropn/w");
560    dbxopenw(DBXname,DBXname,mx1extp,&DBXmsopn,&DBXmsopw,"recwrite/msopn/w");
561
562    if (!DBXxropw) fatal("recwrite/xropw");
563    if (!DBXmsopw) fatal("recwrite/msopw");
564
565    if (!DBXxribp) fatal("recwrite/xribp");
566    if (!DBXmsibp) fatal("recwrite/msibp");
567
568#if CICPP
569    ms0p= &crecp->recmfp->m0;
570#else
571    ms0p= &crecp->recmf.m0;
572#endif /* CICPP */
573
574    if (MS0mftype != MSMFTUSR && MS0mftype != MSMFTMSG)
575        fatal("recwrite/mftype");
576
577    mfn=MFRmfn;
578
579#if RUCTRACE
580printf("recwrite - dbn/%d=%s  mfn=%ld  nxtmfn=%ld  nxtmfb=%ld  nxtmfp=%d\n",
581 MS0mftype,DBXname,mfn,MS0nxtmfn,MS0nxtmfb,MS0nxtmfp);
582#endif
583
584#if MULTI
585    isnewrec=RECwlock & NEWREC;
586
587    if (DBXnetws != MONONETS) {
588        if ((RECwlock & WUNLOCK && RECwlock & WLOCK) ||
589           !(RECwlock & WUNLOCK || RECwlock & WLOCK))
590            fatal("recwrite/WLOCK/WUNLOCK");
591        /* step 1: lock the .mst file and get the current ctl rec */
592        /* assure data entry lock has been granted (also ewl) */
593        if (!DBXdelxx) fatal("recwrite/lock/data entry lock is off");
594        /* assure record lock has been granted */
595        if (!isnewrec)
596            if (!RECgdbl) fatal("recwrite/lock/record lock needed");
597        /* .mst file lock: lock */
598        if (multrace) printf("<w> %s .mst lock \n",DBXname);
599#if BEFORE950220
600        if (dbxflock(dbxp,"M")) fatal("recwrite/lock/file lock");
601        /* reset internal lock flag and get the current ctl rec */
602        keeplock=crecp->reclock; crecp->reclock=NOLOCK;
603        if (recread(crecp,0L) != RCNORMAL) fatal("recwrite/lock/read");
604        crecp->reclock=keeplock;
605        /* check another's exclusive write lock - should never occur */
606        if (MS0mfcxx3 && !DBXewlxx) {
607            if (multrace) printf("<w> %s has exclusive write lock\n",DBXname);
608            fatal("recwrite/lock/exclusive write lock");
609        }
610#else
611        if (dbxflock(dbxp,"M")) {
612            if (multrace) printf("<w> %s .mst lock/denied \n",DBXname);
613            if (dbxewlrc) return(RCLOCK);
614            fatal("recwrite/lock/file lock");
615        }
616        /* wait another's exclusive write lock */
617        if (dbxwlock(dbxp,(char *)ms0p,dbxwloop)) {
618            if (multrace) printf("<w> %s .mst ewl is on !!!\n",DBXname);
619            if (dbxewlrc) return(RCLOCK);
620            fatal("recwrite/lock/must wait ewl");
621        }
622#endif
623
624        /* check data entry lock */
625        if (!MS0mfcxx2) fatal("recwrite/lock/data entry lock/mfcxx2");
626        if (!DBXdelxx) fatal("recwrite/lock/data entry lock needed");
627
628        /* assign nxtmfn */
629        if (isnewrec) {
630            if (!mfn) {
631                mfn=MFRmfn=MS0nxtmfn;
632                if (multrace) printf("<w> %s -> mfn=%ld\n",DBXname,MFRmfn);
633            }
634        }
635    }
636#endif /* MULTI */
637
638    lastmfn=MS0nxtmfn-1;
639
640    if (RECdbxp != dbxp)
641        fatal("recwrite/dbxp");
642
643    rc=recxref(recp,mfn,&comb,&comp);
644
645    if (comb > MS0nxtmfb)
646        fatal("recwrite/chknew/comb");
647    if (comp >= MSBSIZ)
648        fatal("recwrite/chknew/comp");
649
650#if DBXMSTXL
651    pendnew=recxrefn;
652    pendupd=recxrefm;
653#else
654    xrftiv=DBXxribp->xrmfptr[(mfn-1)%XRMAXTIV]; /* not available for mfn=0 */
655
656    pendnew=(int)(labs(xrftiv) & XRXMASKN);
657    pendupd=(int)(labs(xrftiv) & XRXMASKU);
658#endif
659
660    pend=(pendnew | pendupd);
661    if (pendnew && pendupd)
662        fatal("recwrite/pend");
663
664    if (MS0mftype == MSMFTMSG) {
665        pend=1;                         /* to force inplace=MAYBE */
666        pendnew=1;                      /* and mfbwb/mfbwp=0      */
667    }
668
669#if RUCTRACE
670printf("recwrite - comb=%ld  comp=%d  new=%d  upd=%d  pend=%d  rc=%d\n",
671comb,comp,pendnew,pendupd,pend,rc);
672#endif
673
674
675    mshp= &header;
676    if (rc == RCEOF || rc == RCPDEL) {
677#if MULTI
678        if (DBXnetws != MONONETS) {
679            if (multrace) printf("<w> %s/%ld rc=%d\n",DBXname,MFRmfn,rc);
680            if (!isnewrec) fatal("recwrite/lock/EOFPDEL");
681        }
682#endif /* MULTI */
683        if (pend)
684            if (MS0mftype != MSMFTMSG) /* 07/03/97 */
685                fatal("recwrite/chknew/pend/EOFPDEL");
686
687        memset((char *)mshp,0x00,LEADER);
688
689        MSHstatus=DELETED;
690        comb=MS0nxtmfb;
691        comp=MS0nxtmfp-1;
692#if RUCTRACE
693printf("recwrite - comb=%ld  comp=%d [%ld,%ld+%d]\n",
694 comb,comp,MS0nxtmfn,MS0nxtmfb,MS0nxtmfp);
695#endif
696    }
697    else {
698#if MULTI
699        if (multrace) printf("<w> %s/%ld rc=%d\n",DBXname,MFRmfn,rc);
700        if (DBXnetws != MONONETS)
701            if (isnewrec)
702                if (RECwlock & FORCE) ; else fatal("recwrite/lock/NORMALDEL");
703#endif /* MULTI */
704        xbyte=(((off_t)(comb-1))<<MSBSHIFT)+comp;
705        if (LSEEK64(DBXmsopn,xbyte,SEEK_SET) != xbyte)
706            fatal("recwrite/lseek/leader");
707        n=CIREAD(DBXmsopn,(char *)mshp,LEADER); /* MSNVSPLT */
708#if CNV_PCBINUM
709        ConvertMST_LEADER((char *)mshp,0,LEADER);
710#endif
711#if CNV_PCFILES
712        memcpy(unibuff,(char *)mshp,MSNVSPLT);
713        memcpy(((char *)mshp)+0,unibuff+0,4); /* mfn= */
714        memcpy(((char *)mshp)+4,unibuff+6,4); /* mfbwb= */
715        memcpy(((char *)mshp)+8,unibuff+4,2); /* mfrl= */
716#endif
717        if (n != LEADER) {
718#if RUCTRACE
719printf("recwrite - fd=%d  lseek=%"P_OFF_T"  n=%d\n",DBXmsopn,(LONG_LONG)xbyte,n);
720#endif
721            fatal("recwrite/read");
722        }
723        if (MSHmfn != mfn)
724            fatal("recwrite/check/mfn");
725        if (MS0mftype == MSMFTMSG)
726            MSHmfrl=MSBSIZ;                     /* to force inplace=MAYBE */
727#if MULTI
728        /* step 2: check existing record lock */
729        if (DBXnetws != MONONETS) {
730            if (multrace)
731              printf("<w> %s/%ld mfrl=%04x=%d\n",DBXname,mfn,MSHmfrl,MSHmfrl);
732            if (!isnewrec)
733              if (MSHmfrl <= (FFI)MFRL_MAX) fatal("recwrite/lock/record lock");
734            if (MSHmfrl > (FFI)MFRL_MAX) {
735              MSHmfrl=(FFI)0-MSHmfrl;
736              if (multrace)
737               printf("<w> %s/%ld mfrl=%04x=+%d\n",DBXname,mfn,0x0000,MSHmfrl);
738            }
739        }
740#endif /* MULTI */
741    }
742
743#if RUCTRACE
744printf("recwrite - rec: %ld,%d,%ld,%d,%d,%d,%d\n",
745        MFRmfn,MFRmfrl,MFRmfbwb,MFRmfbwp,MFRbase,MFRnvf,MFRstatus);
746printf("recwrite - mst: %ld,%d,%ld,%d,%d,%d,%d\n",
747        MSHmfn,MSHmfrl,MSHmfbwb,MSHmfbwp,MSHbase,MSHnvf,MSHstatus);
748#endif
749
750    if (rc == RCEOF || rc == RCPDEL)
751        if (MFRstatus == DELETED)
752            fatal("recwrite/deleted");
753
754    if (rc == RCEOF || rc == RCPDEL || pendnew)
755        flagnew=1;
756    else
757        flagnew=0;
758
759
760    if (pend) {
761
762        MFRmfbwb=MSHmfbwb;
763        MFRmfbwp=MSHmfbwp;
764        inplace=MAYBE;
765    }
766
767    else {              /* no if update is pending */
768
769        if (MSHmfbwb != 0 && MSHmfbwp != 0)
770            fatal("recwrite/mfbwlink");
771
772        if (rc != RCNORMAL) {                                   /* 26/09/90 */
773            MFRmfbwb=0;
774            MFRmfbwp=0;
775            inplace=MAYBE;
776        }
777        else {                  /* cancel xrfptr/add */
778            MFRmfbwb=comb;
779            MFRmfbwp=comp;
780            inplace=NEVER;
781        }
782    }
783
784    if (MS0mftype != MSMFTMSG) {
785        if (MFRmfrl & 0x01)
786            MFX[MFRmfrl++]=' '; /* gdb always an even number */
787#if DBXMSTXL
788    vtot = 1;
789    for (pow = 1; pow <= DBXmstxl; pow++) {
790        vtot *= 2;
791    }
792    vtot -= 1;
793    while (MFRmfrl & vtot)
794        MFX[MFRmfrl++]=' ';
795
796/*      if (DBXmstxl == 2) {
797            while (MFRmfrl & 0x03)
798                MFX[MFRmfrl++]=' ';
799        }
800        if (DBXmstxl == 3) {
801            while (MFRmfrl & 0x07)
802                MFX[MFRmfrl++]=' ';
803        } */
804#endif
805    }
806
807#if MULTI
808    /* step 3: check actual maximum record length */
809    if (DBXnetws != MONONETS) {
810        if (MFRmfrl > (FFI)MFRL_MAX) fatal("recwrite/lock/mfrl");
811    }
812#endif /* MULTI */
813
814
815#if RUCTRACE
816printf("recwrite - mfbwb=%ld  mfbwp=%d  inplace=%d  flagnew=%d\n",
817 MFRmfbwb,MFRmfbwp,inplace,flagnew);
818#endif
819
820
821    if (MFRmfrl <= MSHmfrl && inplace == MAYBE) {
822        thiscomb=comb;
823        thiscomp=comp;
824        newblk=0;
825    }
826    else {
827        thiscomb=MS0nxtmfb;
828        thiscomp=MS0nxtmfp-1;
829#if DBXMSTXL
830        /*if (thiscomp & 0x01 ||
831           (DBXmstxl == 2 && thiscomp & 0x03) ||
832           (DBXmstxl == 3 && thiscomp & 0x07))*/
833
834    if (thiscomp & 0x01 || (thiscomp & vtot))
835#else
836        if (thiscomp & 0x01)
837#endif
838            fatal("recwrite/check/even");
839
840        newblk=0;
841        if (thiscomp > (MSBSIZ-MSNVSPLT)) {
842            thiscomb++;
843            thiscomp=0;
844            newblk=1;
845        }
846
847        MS0nxtmfb=thiscomb;
848        nxtcomp= (MS0mftype == MSMFTMSG) ? MSBSIZ : thiscomp+MFRmfrl;
849        for (;;)
850            if (nxtcomp < MSBSIZ)
851                break;
852            else {
853                MS0nxtmfb++;
854                nxtcomp-=MSBSIZ;
855                newblk=1;
856            }
857        if (nxtcomp > (MSBSIZ-MSNVSPLT)) {              /* 17/01/91 */
858            MS0nxtmfb++;
859            nxtcomp=0;
860            newblk=1;
861        }
862        MS0nxtmfp=nxtcomp+1;    /* gdb first = sizeof(M0STRU)+1 */
863
864        if (MS0nxtmfp == 1)
865            newblk=0;
866        if (thiscomp == 0)
867            newblk=1;
868        if (MS0mftype == MSMFTMSG)
869            newblk=1;
870    }
871
872
873    if (mfn >= MS0nxtmfn) {
874        MS0nxtmfn=mfn+1;
875        DBXmsmfn=MS0nxtmfn;
876    }
877
878#if RUCTRACE
879printf("recwrite - thiscomb=%ld  thiscomp=%d\n",thiscomb,thiscomp);
880printf("recwrite - MS0nxtmfn=%ld  MS0nxtmfb=%ld  MS0nxtmfp=%d\n",
881 MS0nxtmfn,MS0nxtmfb,MS0nxtmfp);
882#endif
883
884
885#if MULTI
886    /* step 4: process record lock/unlock */
887    if (DBXnetws != MONONETS) {
888        /* process WUNLOCK/WLOCK */
889        MFRmfrl=(FFI)0-MFRmfrl;
890        RECgdbl=MFRmfrl; RECgdbw=1;
891        /* reset or keep record lock */
892        if (RECwlock & WUNLOCK) {
893            if (multrace)
894              printf("<w> %s/%ld mfrl=%04x=%d\n",DBXname,mfn,RECgdbl,MFRmfrl);
895            MFRmfrl=(FFI)0-MFRmfrl;
896            if (multrace)
897              printf("<w> %s/%ld mfrl=%04x=+%d\n",DBXname,mfn,RECgdbl,MFRmfrl);
898            RECgdbl=RECgdbw=0;
899        }
900    }
901#endif /* MULTI */
902
903#if CICPP
904    recwmast(crecp,thiscomb,thiscomp,newblk,0);
905#else
906    recwmast(crecp,recp,thiscomb,thiscomp,newblk,0);
907#endif /* CICPP */
908
909#if MULTI
910    /* step 5: process existing record lock */
911    if (DBXnetws != MONONETS) {
912        if (MFRmfrl > (FFI)MFRL_MAX) {
913            if (multrace)
914              printf("<w> %s/%ld mfrl=%04x=%d\n",DBXname,mfn,MFRmfrl,MFRmfrl);
915            if (!RECgdbl || !RECgdbw) fatal("recupdat/check/gdbl");
916            MFRmfrl=(FFI)0-MFRmfrl;
917            if (multrace)
918              printf("<w> %s/%ld mfrl=%04x=+%d\n",DBXname,mfn,MFRmfrl,MFRmfrl);
919        }
920    }
921#endif /* MULTI */
922
923    /* encode .xrf pointer for the record location */
924    comb = thiscomb;
925    comp = thiscomp;
926    if (flagnew)
927        comp |= XRXMASKN;
928    else
929        comp |= XRXMASKU;
930
931#if DBXMSTXL
932    xrftiv = comb * (XRXDIVIDE>>DBXmstxl) + (comp>>DBXmstxl);
933#else
934    xrftiv = comb * XRXDIVIDE + comp;
935#endif
936
937    /* complement .xrf pointer for logically deleted records */
938    if (MFRstatus == DELETED)
939        xrftiv= -xrftiv;
940
941#if CICPP
942    recwxref(xrftiv,lastmfn);
943#else
944    recwxref(recp,xrftiv,lastmfn);
945#endif /* CICPP */   
946
947#if MULTI
948    /* step 6: .mst file lock: unlock */
949    if (DBXnetws != MONONETS) {
950        if (multrace) printf("<w> %s .mst unlock [RL off]\n",DBXname);
951        if (dbxulock(dbxp,"M")) fatal("recwrite/lock/file unlock");
952    }
953#endif /* MULTI */
954
955
956    return(RCNORMAL);
957
958#undef NEVER
959#undef MAYBE
960}
961
962
963#if CICPP
964int RECSTRU :: xrecwmast(RECSTRU *crecp,
965                         LONGX     comb,
966                         int      comp,
967                         int      newblk,
968                         FFI      wlen)
969#else /* CICPP */
970int recwmast(crecp,recp,comb,comp,newblk,wlen)                        /*
971------------
972                    seta dbxp e ms0p desde crecp;
973                    regrava o registro recp na posicao comb/comp;
974                    preenche ultimo .mst block, se for o caso;
975                    reseta DBXmsibp->msbufn;
976                    regrava o registro crecp;
977                    retorna RCNORMAL ou aborta
978                                                                      */
979RECSTRU *crecp;     /* elemento de vrecp, para info */
980RECSTRU *recp;      /* elemento de vrecp, para info */
981LONGX comb;          /* gdb getmfr comb */
982int comp;           /* gdb getmfr comp */
983int newblk;         /* new .mst blk switch */
984FFI wlen;           /* 0=MFRmfrl, 1=leader, 2=+dir, n=mfrl */
985#endif /* CICPP */
986{
987    DBXSTRU *dbxp;
988
989    FFI n; /* deveria ser int para pegar o retorno da CIWRITE */
990    int k;
991    off_t xbyte;
992
993    FFI mfrl;
994
995#if CNV_PCFILES
996    char unibuff[MSNVSPLT]; /* CNV_PCFILES/recwmast - MFX */
997#endif
998
999#if DBXMSTXL
1000    UWORD keepmftype;
1001#endif
1002
1003#if CICPP
1004    RECSTRU *recp = this;
1005#endif /* CICPP */
1006
1007    if (crecp) dbxp=crecp->recdbxp; else dbxp=RECdbxp;
1008
1009    xbyte=((((off_t)(comb-1))<<MSBSHIFT)+comp);
1010
1011#if RUCTRACE
1012printf("recwmast - fd=%d  lseek=%"P_OFF_T"  newblk=%d\n",
1013 DBXmsopn,(LONG_LONG)xbyte,newblk);
1014#endif
1015
1016    if (recp)
1017        if (LSEEK64(DBXmsopn,xbyte,SEEK_SET) != xbyte)
1018            fatal("recwmast/lseek/rec");
1019
1020    if (wlen) {
1021        if (wlen == 1) mfrl=LEADER;             /* leader */
1022        else if (wlen == 2) mfrl=MFRbase;       /*  + dir */
1023        else mfrl=wlen;                         /* waall! */
1024    }
1025    else {
1026        mfrl=MFRmfrl;
1027#if MULTI
1028        if (DBXnetws != MONONETS)
1029            if (MFRmfrl > (FFI)MFRL_MAX)
1030                mfrl=(FFI)0-MFRmfrl;
1031#endif /* MULTI */
1032    }
1033
1034    /* retag.c calls recwmast(recp,NULL,0,0,0,sizeof(M0STRU)) */
1035    if (recp) {
1036#if CNV_PCFILES
1037        if (MFRmfn > 0) {
1038            memcpy(unibuff,MFX,MSNVSPLT);
1039            memcpy(MFX+0,unibuff+0,4); /* mfn= */
1040            memcpy(MFX+6,unibuff+4,4); /* mfbwb= */
1041            memcpy(MFX+4,unibuff+8,2); /* mfrl= */
1042        }
1043#endif
1044#if CNV_PCBINUM
1045        memcpy(cnv_pcbuff,MFX,mfrl);
1046        if (MFRmfn > 0) {
1047            k=MFRnvf; /* CNV_PCFILES ok */
1048            ConvertMST_LEADER(cnv_pcbuff,0,LEADER);
1049            if (wlen != 1) ConvertMST_DIR(cnv_pcbuff,k);
1050        }
1051        else ConvertMST_CTLSTRUCT(cnv_pcbuff);
1052        if ((n=CIWRITE(DBXmsopn,cnv_pcbuff,mfrl)) != mfrl) {
1053#else
1054        if ((n=CIWRITE(DBXmsopn,MFX,mfrl)) != mfrl) {
1055#endif
1056#if RUCTRACE
1057printf("recwmast - write/rec  n=%d  mfrl=%d\n",n,mfrl);
1058#endif
1059            fatal("recwmast/write/rec");
1060        }
1061#if CNV_PCFILES
1062        if (MFRmfn > 0)
1063            memcpy(MFX,unibuff,MSNVSPLT);
1064#endif
1065    }
1066
1067    if (newblk) {
1068        k=MSBSIZ-((xbyte+mfrl)&XRXMASK);
1069
1070#if RUCTRACE
1071printf("recwmast - fill=%d\n",k);
1072#endif
1073        memset(DBXmsibp->msbuff,0x00,(size_t)k);
1074
1075        if ((n=CIWRITE(DBXmsopn,DBXmsibp->msbuff,k)) != k) { /* 0x00 */
1076
1077#if RUCTRACE
1078printf("recwmast - write/end  n=%d  k=%d\n",n,k);
1079#endif
1080            fatal("recwmast/write/end");
1081        }
1082    }
1083
1084    DBXmsibp->msbufn=0;                         /* reset .mst input buffer */
1085
1086    if (!crecp) return(RCNORMAL);
1087
1088    LSEEK64(DBXmsopn,0L,SEEK_SET);
1089
1090    recp=crecp; /* tmp for MFX */
1091
1092#if DBXMSTXL /* AOT/AARG 05/01/99 */
1093    if (DBXmstxl) {
1094        keepmftype=MF0mftype;
1095        MF0mftype += DBXmstxl * 256;
1096    }
1097#endif
1098
1099#if CNV_PCBINUM
1100    memcpy(cnv_pcbuff,MFX,sizeof(M0STRU));
1101    ConvertMST_CTLSTRUCT(cnv_pcbuff);
1102    n=CIWRITE(DBXmsopn,cnv_pcbuff,sizeof(M0STRU));
1103#else
1104    n=CIWRITE(DBXmsopn,MFX,sizeof(M0STRU));
1105#endif
1106    if (n != sizeof(M0STRU)) {
1107#if RUCTRACE
1108printf("recwmast - write/ctl  n=%d\n",n);
1109#endif
1110        fatal("recwmast/write/ctl");
1111    }
1112
1113#if DBXMSTXL /* AOT/AARG 05/01/99 */
1114    if (DBXmstxl) {
1115        MF0mftype=keepmftype;
1116    }
1117#endif
1118
1119    return(RCNORMAL);
1120}
1121
1122
1123#if CICPP
1124int RECSTRU :: xrecwxref(XRPTR    pointer,
1125                         LONGX     lastmfn)
1126#else /* CICPP */
1127int recwxref(recp,pointer,lastmfn)                                     /*
1128------------
1129                    seta dbxp/mfn desde recp;
1130                    atualiza .xrf;
1131                    retorna RCNORMAL ou aborta
1132                                                                      */
1133RECSTRU *recp;      /* elemento de vrecp, para info */
1134XRPTR pointer;      /* .xrf pointer para mfn */
1135LONGX lastmfn;       /* ultimo mfn em .xrf */
1136#endif /* CICPP */
1137{
1138    DBXSTRU *dbxp;
1139    LONGX mfn;
1140
1141    FFI n,k,j;
1142    int flag127;
1143    off_t xbyte;
1144    LONGX x;
1145    char *p;
1146
1147    int thisidx,lastidx;
1148    XRPOS thispos,lastpos;
1149    XRPTR xrftiv;
1150#if CNV_PCBINUM
1151    XRSTRU *xrp;
1152#endif
1153
1154    LONGX wcomb;
1155    int  wcomp;
1156
1157#if CICPP
1158    RECSTRU *recp = this;
1159#endif /* CICPP */
1160
1161    dbxp=RECdbxp;
1162    mfn=MFRmfn;
1163
1164    lastpos=(lastmfn+XRMAXTV1)/XRMAXTIV;
1165    if (lastpos < 1)
1166        lastpos=1;
1167    flag127=0;
1168    if (lastmfn)
1169        if (mfn > lastmfn && (lastmfn % XRMAXTIV) == 0)         /* 127 ok */
1170            { lastpos++; flag127=1; }
1171
1172    thispos=    (mfn+XRMAXTV1)/XRMAXTIV;
1173
1174    lastidx=(lastmfn-1)%XRMAXTIV;
1175    if (flag127)
1176        lastidx = -1;   /* 21/01/91 */
1177
1178    thisidx=    (mfn-1)%XRMAXTIV;
1179
1180#if RUCTRACX
1181printf("recwxref - lastmfn=%ld             \n",lastmfn);
1182printf("recwxref - lastpos=%ld  thispos=%ld\n",lastpos,thispos);
1183printf("recwxref - lastidx=%d   thisidx=%d \n",lastidx,thisidx);
1184#endif
1185
1186    if (!lastmfn) recxref(recp,1L,&wcomb,&wcomp);       /* 28/01/91 */
1187
1188    if (thispos < lastpos) {
1189
1190#if RUCTRACX
1191printf("recwxref - thispos < lastpos\n");
1192#endif
1193
1194#if BEFORE940815
1195        if (recxref(recp,mfn,&wcomb,&wcomp) == RCEOF)
1196            fatal("recwxref/recxref/thispos");
1197        if (DBXxribp->xrxrpos != thispos)
1198            fatal("recwxref/check/thispos");
1199        DBXxribp->xrmfptr[thisidx]=pointer;
1200#else
1201        if (DBXxribp->xrxrpos == thispos) DBXxribp->xrmfptr[thisidx]=pointer;
1202#endif
1203
1204        xbyte=(off_t)( (((off_t)(thispos-1))<<XRSHIFT)+XRPOSSIZ+thisidx*XRPTRSIZ );
1205        if (LSEEK64(DBXxropn,xbyte,SEEK_SET) != xbyte)
1206            fatal("recwxref/lseek/thispos");
1207#if BEFORE970319
1208        p=(char *)&DBXxribp->xrmfptr[thisidx];
1209#else
1210        p=(char *)&pointer;
1211#endif
1212
1213#if CNV_PCBINUM
1214        memcpy(cnv_pcbuff,p,XRPTRSIZ);
1215        ConvertXRF_PTR(cnv_pcbuff);
1216        if ((n=CIWRITE(DBXxropn,cnv_pcbuff,XRPTRSIZ)) != XRPTRSIZ) {
1217#else
1218        if ((n=CIWRITE(DBXxropn,p,XRPTRSIZ)) != XRPTRSIZ) {
1219#endif
1220#if RUCTRACX
1221printf("recwxref - rewrite/mfptr  n=%d\n",n);
1222#endif
1223            fatal("recwxref/rewrite/mfptr");
1224        }
1225    }
1226
1227    else /* 21/01/91 */
1228
1229    if (thispos > lastpos) {
1230
1231#if RUCTRACX
1232printf("recwxref - thispos > lastpos\n");
1233#endif
1234
1235        if (lastmfn)
1236            if (recxref(recp,lastmfn,&wcomb,&wcomp) == RCEOF)
1237                fatal("recwxref/recxref/lastmfn");
1238
1239        x = (flag127) ? (lastpos-1) : (-lastpos);
1240        if (DBXxribp->xrxrpos != x)
1241            fatal("recwxref/xrpos/lastpos");
1242
1243        DBXxribp->xrxrpos=lastpos;        /* unflag last block */
1244
1245#if DBXMSTXL /* AOT, 07/04/2003 */
1246    xrftiv = (-1) * (XRXDIVIDE>>DBXmstxl) + ((0)>>DBXmstxl);  /* PDEL pointer */
1247#else
1248        xrftiv=(-1)*XRXDIVIDE + (0);      /* PDEL pointer */
1249#endif
1250
1251        for (n=lastidx+1; n<XRMAXTIV; n++)
1252            DBXxribp->xrmfptr[n] = xrftiv;
1253
1254        xbyte=(((off_t)(lastpos-1))<<XRSHIFT);
1255        if (LSEEK64(DBXxropn,xbyte,SEEK_SET) != xbyte)
1256            fatal("recwxref/lseek/lastpos");
1257#if CNV_PCBINUM
1258        memcpy(cnv_pcbuff,DBXxribp,XRBSIZ);
1259        ConvertXRF_REC(cnv_pcbuff);
1260        if ((n=CIWRITE(DBXxropn,cnv_pcbuff,XRBSIZ)) != XRBSIZ) {
1261#else
1262        if ((n=CIWRITE(DBXxropn,(char *)DBXxribp,XRBSIZ)) != XRBSIZ) {
1263#endif
1264#if RUCTRACX
1265printf("recwxref - rewrite/lastpos  n=%d\n",n);
1266#endif
1267            fatal("recwxref/rewrite/lastpos");
1268        }
1269
1270
1271        while (++lastpos < thispos) {
1272
1273            DBXxribp->xrxrpos = lastpos;
1274
1275            for (n=0; n < XRMAXTIV; )
1276                DBXxribp->xrmfptr[n++] = xrftiv;
1277
1278#if CNV_PCBINUM
1279            memcpy(cnv_pcbuff,DBXxribp,XRBSIZ);
1280            ConvertXRF_REC(cnv_pcbuff);
1281            if ((n=CIWRITE(DBXxropn,cnv_pcbuff,XRBSIZ)) != XRBSIZ) {
1282#else
1283            if ((n=CIWRITE(DBXxropn,(char *)DBXxribp,XRBSIZ)) != XRBSIZ) {
1284#endif
1285#if RUCTRACX
1286printf("recwxref - write/midpos  n=%d\n",n);
1287#endif
1288                fatal("recwxref/write/midpos");
1289            }
1290        }
1291
1292
1293        DBXxribp->xrxrpos= -thispos;      /* flag last block */
1294
1295        for (n=0; n<thisidx; n++)
1296            DBXxribp->xrmfptr[n] = xrftiv;
1297
1298        DBXxribp->xrmfptr[thisidx] = pointer;
1299
1300        xrftiv= (0)*XRXDIVIDE + (0);      /* EOF pointer */
1301
1302        for (n=thisidx+1; n<XRMAXTIV; n++)
1303            DBXxribp->xrmfptr[n] = xrftiv;
1304
1305#if CNV_PCBINUM
1306        memcpy(cnv_pcbuff,DBXxribp,XRBSIZ);
1307        ConvertXRF_REC(cnv_pcbuff);
1308        if ((n=CIWRITE(DBXxropn,cnv_pcbuff,XRBSIZ)) != XRBSIZ) {
1309#else
1310        if ((n=CIWRITE(DBXxropn,(char *)DBXxribp,XRBSIZ)) != XRBSIZ) {
1311#endif
1312#if RUCTRACX
1313printf("recwxref - write/thispos  n=%d\n",n);
1314#endif
1315            fatal("recwxref/write/thispos");
1316        }
1317    }
1318
1319
1320    else /* 21/01/91 */
1321
1322    if (thispos == lastpos) {
1323
1324#if RUCTRACX
1325printf("recwxref - thispos == lastpos\n");
1326#endif
1327
1328        recxref(recp,mfn,&wcomb,&wcomp);
1329
1330        if (labs(DBXxribp->xrxrpos) != thispos)
1331            fatal("recwxref/check/lastpos");
1332
1333        k=j=0;
1334#if DBXMSTXL /* AOT, 07/04/2003 */
1335    xrftiv = (-1) * (XRXDIVIDE>>DBXmstxl) + ((0)>>DBXmstxl);  /* PDEL pointer */
1336#else
1337        xrftiv=(-1)*XRXDIVIDE + (0);      /* PDEL pointer */
1338#endif
1339
1340        for (n=lastidx+1; n<thisidx; n++) {
1341            DBXxribp->xrmfptr[n] = xrftiv;
1342            k+=XRPTRSIZ; j++;
1343        }
1344
1345        DBXxribp->xrmfptr[thisidx] = pointer;
1346        k+=XRPTRSIZ;
1347
1348        xbyte=(off_t)( (((off_t)(thispos-1))<<XRSHIFT)+XRPOSSIZ+(thisidx-j)*XRPTRSIZ );
1349        if (LSEEK64(DBXxropn,xbyte,SEEK_SET) != xbyte)
1350            fatal("recwxref/lseek/mfptrs");
1351        p=(char *)&DBXxribp->xrmfptr[thisidx-j];
1352
1353#if CNV_PCBINUM
1354        xrp=(XRSTRU *)cnv_pcbuff;
1355        memcpy(cnv_pcbuff,p,k);
1356        for (n=0; n <= j; n++) /* (j+1) ptr's*/
1357            ConvertXRF_PTR(&cnv_pcbuff[n*XRPTRSIZ]);
1358        if ((n=CIWRITE(DBXxropn,cnv_pcbuff,k)) != k) {
1359#else
1360        if ((n=CIWRITE(DBXxropn,p,k)) != k) {
1361#endif
1362#if RUCTRACX
1363printf("recwxref - rewrite/mfptrs  k=%d  n=%d\n",k,n);
1364#endif
1365            fatal("recwxref/rewrite/mfptrs");
1366        }
1367    }
1368
1369
1370    if (mfn > lastmfn && (mfn % XRMAXTIV) == 0) {       /* 127 ok */
1371
1372#if RUCTRACX
1373printf("recwxref - thispos == lastpos 127\n");
1374#endif
1375
1376        if (recxref(recp,mfn,&wcomb,&wcomp) == RCEOF)   /* 08/08/91 */
1377            fatal("recwxref/recxref/mfn127");
1378//printf("mfn=%ld comp=%ld comb=%ld\n", mfn, (long)wcomp, (long)wcomb);
1379        if (DBXxribp->xrxrpos != -thispos) {
1380            printf("*** %ld/%ld ",DBXxribp->xrxrpos,thispos);
1381            fatal("recwxref/xrpos/thispos");
1382        }
1383
1384        DBXxribp->xrxrpos=thispos;        /* unflag last block */
1385
1386        xbyte=(((off_t)(thispos-1))<<XRSHIFT);
1387        if (LSEEK64(DBXxropn,xbyte,SEEK_SET) != xbyte)
1388            fatal("recwxref/lseek/thispos/last");
1389        /* should write only xrxrpos and lseek next blk */
1390#if CNV_PCBINUM
1391        memcpy(cnv_pcbuff,DBXxribp,XRBSIZ);
1392        ConvertXRF_REC(cnv_pcbuff);
1393        if ((n=CIWRITE(DBXxropn,cnv_pcbuff,XRBSIZ)) != XRBSIZ) {
1394#else
1395        if ((n=CIWRITE(DBXxropn,(char *)DBXxribp,XRBSIZ)) != XRBSIZ) {
1396#endif
1397#if RUCTRACX
1398printf("recwxref - rewrite/thispos/last  n=%d\n",n);
1399#endif
1400            fatal("recwxref/rewrite/thispos/last");
1401        }
1402
1403
1404        DBXxribp->xrxrpos= -(thispos+1);  /* flag last block */
1405
1406        xrftiv= (0)*XRXDIVIDE + (0);      /* EOF pointer */
1407
1408        for (n=0; n < XRMAXTIV; )
1409            DBXxribp->xrmfptr[n++] = xrftiv;
1410
1411#if CNV_PCBINUM
1412        memcpy(cnv_pcbuff,DBXxribp,XRBSIZ);
1413        ConvertXRF_REC(cnv_pcbuff);
1414        if ((n=CIWRITE(DBXxropn,cnv_pcbuff,XRBSIZ)) != XRBSIZ) {
1415#else
1416        if ((n=CIWRITE(DBXxropn,(char *)DBXxribp,XRBSIZ)) != XRBSIZ) {
1417#endif
1418#if RUCTRACX
1419printf("recwxref - write/newpos  n=%d\n",n);
1420#endif
1421            fatal("recwxref/write/newpos");
1422        }
1423    }
1424
1425    return(RCNORMAL);
1426}
1427
1428
1429
1430#include "cihsh.c"   /* CISIS Interface hashing & binary table search source code */
1431#if CIWTF                                /* WTFUN support */
1432#if !CICPP
1433#if !CIAPI
1434//#include "cihsh.c"   /* CISIS Interface hashing & binary table search source code */
1435#include "wtrun.c"   /* wtfnew(); wtfset(); wtfdel(); wtnew(); wtexit(); loadcoll() source code */
1436#endif /* CIWTF */
1437#endif /* CIAPI */
1438#endif /* CICPP */
1439
1440#if INCPRCCX
1441/* procx.c */
1442#include "ciupdsocy.c"       /* mainfile() source code */
1443#if PROCXSOCKREC
1444#include "ciupdsocx.c"       /* mainclient() source code */
1445#endif /* PROCXSOCKREC */
1446#endif /* INCPRCCX */
1447
1448#if INCPRSSX
1449#define PROCXSERVREC 1
1450#if PROCXSERVREC
1451#if PC
1452#include "ciupdserwpc.c"
1453#else
1454#include "ciupdserw.c"
1455#endif
1456#endif /* PROCXSERVREC */
1457#endif /* INCPRSSX */
1458
1459
1460
1461
1462#if CICPP
1463char * RECSTRU :: xfldupdat(char *batchp)
1464#else /* CICPP */
1465char *fldupdat(irec,batchp)                                           /*
1466--------------
1467                    abenda se vrecp nao inicializado;
1468                    abenda se registro irec ainda nao alocado;
1469                    abenda se tipo de irec diferente de TYPEMFR;
1470                    executa comandos desde batchp sobre registro irec;
1471                    retorna NULL ou .ptr erro
1472                                                                      */
1473LONGX irec;          /* indice de vrecp, para recwrite() */
1474char *batchp;       /* ptr comandos Dtag ou Atag'string' */
1475#endif /* CICPP */
1476{
1477#if !CICPP
1478    extern int bugadddel;               /* 13/03/94 */
1479#endif /* CICPP */
1480    RECSTRU *recp;
1481
1482    DIRSTRU *mfdirp,*dirarea=NULL,*dirp,*dp,*dxp;
1483    char *srcareap=NULL;                                             /* v3.4 */
1484    FFI realmfrl;
1485
1486    int maxdirs,dirsleft;
1487    FFI ndel,nadd;
1488    FFI vlendel,vlenadd;
1489    FFI lastpos,nxtpos;
1490    char *mfp,*nxtp,*newp;
1491
1492    char *p,c,cc,*errp,*sp,*sxp;
1493    int tag;
1494    FFI n,k,loop,reploop;
1495
1496    int iocc,tagocc;
1497    LONGX nbytes,mfn;
1498
1499    int i,j,anychange,nn;
1500    char tempdir[sizeof(DIRSTRU)];
1501    int sort=0;
1502
1503#define STRIPMARKUP 1
1504
1505#if STRIPMARKUP
1506    FFI smumaxlen=(FFI)MFRL_MAX;
1507    FFI fldlenmin=0;
1508    FFI fldleft,fldqleft,striplen,erased;
1509    LONGX l1,l2;
1510    int nn1,nn2;
1511    int match,endmatch,tagmatch;
1512    char *xp,*fldp,*fldq;
1513#endif /* STRIPMARKUP */
1514
1515/* procx.c */
1516#define PROCXMFUPDATE 1
1517#if PROCXMFUPDATE
1518int xfd/*,n*/,parmcopy;
1519#if CICPP
1520RECSTRU *upirecp,*upcrecp;
1521#else /* CICPP */
1522LONGX upirec,upcrec;
1523/*char *p;*/
1524#endif /* CICPP */
1525#endif /* PROCXMFUPDATE */
1526
1527/* procx.c */
1528#define PROCXWRITEFILE 1
1529#if PROCXWRITEFILE
1530char *wfnamp;
1531int wffd,wflen;
1532char *wfxp;
1533char *wfmtspecp;
1534#define KEEPDBX 1
1535#if KEEPDBX
1536LONGX keepndbx;
1537LONGX idbx;
1538#endif /* KEEPDBX */
1539#endif /* PROCXWRITEFILE */
1540
1541/* procx.c */
1542#if RECGIZM
1543#define PROCXGIZMREC 1
1544#endif
1545#if PROCXGIZMREC
1546#if RECDECO
1547#define PROCXDECOREC 1
1548#endif
1549#define PROCXSPLIREC 1
1550#define PROCXCLPSREC 1
1551#endif /* PROCXGIZMREC */
1552
1553/* precx.c */
1554#if INCPRECX
1555#define PROCXMARKREC 1
1556#if PROCXMARKREC
1557#define upmF1 '1'
1558#define upmF2 '2'
1559#define upmF3 '3'
1560#define upmF4 '4'
1561#endif /* PROCXMARKREC */
1562#endif /* INCPRECX */
1563
1564/* procx.c */
1565#define PROCXLOADREC 1
1566#if PROCXLOADREC
1567#endif /* PROCXLOADREC */
1568
1569
1570/* procx.c */
1571#define PROCXDUMPREC 1
1572#if PROCXDUMPREC
1573int isgdump=0;
1574#endif /* PROCXDUMPREC */
1575
1576/* procx.c */
1577#define PROCXREADREC 1
1578#if PROCXREADREC
1579char *rfnamp;
1580char *rfmfnp;
1581LONGX rfmfn;
1582#if CICPP
1583RECSTRU *uprrecp,*uprrexp;
1584#else /* CICPP */
1585LONGX uprrec,uprrex;
1586#endif /* CICPP */
1587int xdir;
1588RECSTRU *keeprecp;
1589char *rp;
1590#endif /* PROCXREADREC */
1591
1592/* procx.c */
1593#if !CICPP /* porque falta implementar em c++ */
1594#define PROCXIFPRESET 1
1595#if PROCXIFPRESET
1596char *ifprnamp;
1597char *ifprmfnp;
1598LONGX ifprmfn;
1599#endif /* PROCXIFPRESET */
1600#endif /* CICPP */
1601
1602#if INCPROCX /* usa CIIFU (+FST(+FMT)) */
1603/* procx.c */
1604#if !CICPP /* porque falta implementar em c++ */
1605#define PROCXIFUPDATE 1
1606#if PROCXIFUPDATE
1607int pstflag=IFUPISIS;
1608int endup=IFUPWRIT; /* single record */
1609char *stwp=NULL;
1610FST_CODE *fstpgmp=NULL;
1611LONGX maxlk1=1000;
1612LONGX maxlk2=500;
1613char *fstspecp=NULL;
1614char *ifnamp;
1615char *mfnamp;
1616char *mfnp;
1617LONGX ifmfn;
1618int yfd;
1619#endif /* PROCXIFUPDATE */
1620#endif /* CICPP */
1621#endif /* INCPROCX */
1622
1623#if INCPROCXT /* usa CIFST(+FMT) */
1624/* procx.c */
1625#if !CICPP /* porque falta implementar em c++ */
1626#define PROCXFSUPDATE 1
1627#if PROCXFSUPDATE
1628int tyyopth=0;
1629#endif /* PROCXFSUPDATE */
1630#endif /* CICPP */
1631#endif /* INCPROCXT */
1632
1633#if CICPP
1634#define freex(srcareap,dirarea) {\
1635                if (srcareap) delete[] srcareap; if (dirarea) delete[] dirarea; }
1636#else /* CICPP */
1637#define freex(srcareap,dirarea) {\
1638                  if (srcareap) { \
1639            FREE(srcareap); srcareap=NULL; } \
1640          if (dirarea) { \
1641            FREE(dirarea); dirarea=NULL; } \
1642        }
1643#endif /* CICPP */
1644
1645#if CICPP
1646#if RUFTRACE
1647    LONGX irec = NO_IREC;
1648#endif
1649    recp=this;
1650#else /* CICPP */
1651    if (!nrecs)
1652        fatal("fldupdat/RECINIT");
1653
1654    recp=vrecp[irec];
1655#endif /* CICPP */
1656    if (!recp)
1657        fatal("fldupdat/RECALLOC");
1658
1659    if (RECtype != TYPEMFR)
1660        fatal("fldupdat/TYPEMFR");
1661
1662#if RUFTRACE
1663printf("fldupdat - irec=%ld  nbytes=%ld  batchp='%s'\n",
1664 irec,RECnbytes,batchp);
1665#endif
1666
1667#ifndef PROCG
1668#define PROCG  1
1669#endif /* PROCG */
1670#if PROCG
1671#include "ciupg.c"
1672#endif /* PROCG */
1673
1674#if 0
1675    nbytes = (RECnbytes < MAXMFRL) ? RECnbytes : MAXMFRL;
1676    nbytes = (RECnbytes < rec_maxmfrl) ? RECnbytes : rec_maxmfrl;
1677    nbytes = rec_maxmfrl;
1678#endif
1679    nbytes = (RECnbytes > rec_maxmfrl) ? RECnbytes : rec_maxmfrl;
1680
1681#if CICPP
1682    try { dirarea = (DIRSTRU *) new char [nbytes]; }
1683    catch (BAD_ALLOC) { dirarea = (DIRSTRU *)ALLONULL; }
1684#else /* CICPP */
1685    dirarea=(DIRSTRU *)ALLOC((ALLOPARM)nbytes);
1686#endif /* CICPP */
1687    if (dirarea == (DIRSTRU *)ALLONULL)
1688        fatal("fldupdat/ALLOC/dir");
1689
1690    maxdirs=nbytes/sizeof(DIRSTRU);
1691#if CICPP
1692    try { srcareap = (char *) new char [maxdirs]; }
1693    catch (BAD_ALLOC) { srcareap = (char *)ALLONULL; }
1694#else /* CICPP */
1695    srcareap=(char *)ALLOC((ALLOPARM)maxdirs);                  /* v3.4 */
1696#endif /* CICPP */
1697    if (srcareap == (char *)ALLONULL) {
1698        freex(srcareap,dirarea);
1699            fatal("fldupdat/ALLOC/src");
1700    }
1701
1702    memset(srcareap,'?',maxdirs);       /* no default */        /* v3.4 */
1703
1704
1705    dirsleft=MFRnvf;
1706
1707    realmfrl=MFRbase;
1708
1709    sp=srcareap; dirp=dirarea;
1710    for (mfdirp=MFRdir, n=dirsleft; n--; mfdirp++, dirp++, sp++) {
1711        dirp->tag = mfdirp->tag;
1712        dirp->pos = mfdirp->pos;
1713        dirp->len = mfdirp->len;
1714        *sp = 'r';              /* source is record */          /* v3.4 */
1715        realmfrl+=mfdirp->len;
1716    }
1717#if RUFTRACE
1718printf("fldupdat - RECrc=%d  Leader: %ld,%d,%ld,%d,%d,%d,%d\n",
1719 RECrc,MFRmfn,MFRmfrl,MFRmfbwb,MFRmfbwp,MFRbase,MFRnvf,MFRstatus);
1720printf("fldupdat - dirsleft=%d  realmfrl=%d\n",dirsleft,realmfrl);
1721for (dirp=dirarea, loop=0; loop<dirsleft; loop++, dirp++)
1722 printf("fldupdat - dir[%d]: tag=%d  pos=%d  len=%d\n",
1723  loop,dirp->tag,dirp->pos,dirp->len);
1724#endif
1725
1726    MFRmfrl=realmfrl;
1727
1728
1729    for (ndel=nadd=0, vlendel=vlenadd=0, p=batchp; *p; ) {
1730
1731        if (isspace(*p))  {
1732            p++;
1733            continue;
1734        }
1735
1736        c=toupper(*p); errp=p++;
1737        switch (c) {
1738
1739        case 'S':
1740                for (tag=0; isdigit(*p); p++) tag=tag*10+(*p-'0');
1741            if (*p) {
1742            freex(srcareap,dirarea);
1743                    return(errp);
1744            }
1745        if (tag) {
1746            int len,cmp;
1747                for (i=0; i+1 < MFRnvf; i++) {
1748                    if (DIRtag(i) != tag) continue;
1749                    for (j=i+1; j < MFRnvf; j++) {
1750                        if (DIRtag(j) != tag) continue;
1751                    len=DIRlen(i); if (len>DIRlen(j)) len=DIRlen(j);
1752                    cmp=memcmp(FIELDP(i),FIELDP(j),len);
1753                            if (cmp > 0 || cmp==0 && DIRlen(i) > DIRlen(j)) {
1754                                memcpy(tempdir,&MFRdir[i],sizeof(DIRSTRU));
1755                                memcpy(&MFRdir[i],&MFRdir[j],sizeof(DIRSTRU));
1756                                memcpy(&MFRdir[j],tempdir,sizeof(DIRSTRU));
1757                        }
1758                }
1759                }
1760                break;
1761        }
1762            for (anychange=1; anychange; ) {
1763                anychange=0;
1764                for (i=0; i+1 < MFRnvf; i++) {
1765                    j=i+1;
1766                    if (DIRtag(i) > DIRtag(j)) {
1767                                memcpy(tempdir,&MFRdir[i],sizeof(DIRSTRU));
1768                                memcpy(&MFRdir[i],&MFRdir[j],sizeof(DIRSTRU));
1769                                memcpy(&MFRdir[j],tempdir,sizeof(DIRSTRU));
1770                                anychange=1; sort=1;
1771                        }
1772                }
1773        }
1774            break;
1775
1776        case '=':
1777            for (mfn=0; isdigit(*p); p++) 
1778                mfn=mfn*10+(*p-'0');
1779            if (mfn == 0) {
1780        freex(srcareap,dirarea);
1781                return(errp);
1782            }
1783            MFRmfn=mfn;
1784            break;
1785
1786        case 'D':
1787            while (isspace(*p))
1788                p++;
1789            if (*p == '.') {                    /* logically deleted */
1790                MFRstatus=DELETED;
1791                p++;
1792                break;
1793            }
1794            if (*p == ':') {            /* logically deleted/active */
1795                MFRstatus=(MFRstatus==DELETED)?ACTIVE:DELETED;
1796                p++;
1797                break;
1798            }
1799            if (*p == '*') {
1800                tag=0;
1801                p++;
1802            }
1803            else {
1804                for (tag=0; isdigit(*p); p++)
1805                    tag=tag*10+(*p-'0');
1806                if (tag == 0) {
1807            freex(srcareap,dirarea);
1808                    return(errp);
1809                }
1810            }
1811            while (isspace(*p))
1812                p++;
1813            if (tag > 0 && *p == '/') {
1814                p++;
1815                while (isspace(*p))
1816                    p++;
1817                for (tagocc=0; isdigit(*p); p++)
1818                    tagocc=tagocc*10+(*p-'0');
1819#if RUJTRACE
1820printf("fldupdat - D/r - tag=%d  tagocc=%d\n",
1821 tag,tagocc);
1822#endif
1823            }
1824            else
1825                tagocc=0;
1826            for (sp=srcareap, iocc=0, dirp=dirarea, n=dirsleft; n--; ) {
1827                if (dirp->tag == tag || tag == 0) {
1828                    if (tagocc) {
1829                        iocc++;
1830                        if (iocc != tagocc) {
1831                            dirp++; sp++;                       /* v3.4 */
1832                            continue;
1833                        }
1834                    }
1835#if RUJTRACE
1836printf("fldupdat - D/r - tag=%d  tagocc=%d  iocc=%d\n",
1837 tag,tagocc,iocc);
1838#endif
1839                    if (*sp != 'r') {                           /* v3.4 */
1840            freex(srcareap,dirarea);
1841                        return(errp);
1842                    }
1843#if 1 /* BUGADDDEL */
1844                    if (bugadddel) if (nadd) {
1845            freex(srcareap,dirarea);
1846                        return(errp);
1847                    }
1848#endif
1849                    vlendel+=dirp->len;
1850                    for (sxp=sp, dp=dirp, loop=n; loop--; ) {
1851                        dxp=dp; dp++;
1852                        dxp->tag = dp->tag;
1853                        dxp->pos = dp->pos;
1854                        dxp->len = dp->len;
1855                        *sxp = *(sxp+1); sxp++;                 /* v3.4 */
1856                    }
1857                    dirsleft--;
1858                    ndel++;
1859#if RUFTRACE
1860printf("fldupdat - D - tag=%d  dirsleft=%d  vlendel=%d\n",
1861 tag,dirsleft,vlendel);
1862for (sxp=srcareap, dp=dirarea, loop=0; loop<dirsleft; loop++, dp++, sxp++)
1863 printf("fldupdat - dir[%d]: tag=%d  pos=%d(%c)  len=%d\n",
1864  loop,dp->tag,dp->pos,*sxp,dp->len);
1865#endif
1866                }
1867                else
1868                    dirp++;
1869            }
1870            break;
1871
1872        case 'A':
1873        case 'H':
1874#if STRIPMARKUP
1875        case '<':
1876        erased=0; endmatch=0;
1877#endif /* STRIPMARKUP */
1878            cc=c;
1879            while (isspace(*p))
1880                p++;
1881            for (tag=0; isdigit(*p); p++)
1882                tag=tag*10+(*p-'0');
1883            if (*p == '\0' || tag == 0) {
1884            freex(srcareap,dirarea);
1885                    return(errp);
1886            }
1887            while (*p == ' ')           /* enable any delimiter, but space */
1888                p++;
1889/* CMD 'H' */
1890            if (c == 'H') {
1891                for (nn=n=0; isdigit(*p); p++, nn++)
1892                    n=n*10+(*p-'0');
1893#if RUKTRACE
1894printf("+++c=%c tag=%d n=%d *p='%c'\n",c,tag,n,*p);
1895#endif
1896                if (!nn || (n && !isspace(*p))) {
1897            freex(srcareap,dirarea);
1898                    return(errp);
1899                }
1900                if (n) p++;
1901                p+=n;
1902            }
1903#if STRIPMARKUP
1904/* CMD '<' */
1905            else if (c == '<') {
1906
1907                nn1=0; l1=0;
1908                nn2=0; l2=0;
1909        if (isdigit(*p)) {
1910            for (; isdigit(*p); ) { l1=l1*10+(*p-'0'); p++, nn1++; }
1911                    if (nn1) while (isspace(*p)) p++;
1912            for (; isdigit(*p); ) { l2=l2*10+(*p-'0'); p++, nn2++; }
1913                    if (nn2) while (isspace(*p)) p++;
1914        }
1915        else while (*p) {
1916            if (*p == '>') break;
1917            if (strncmp(p,"markmax=",8) == 0) {
1918                for (p+=8; isdigit(*p); ) { l1=l1*10+(*p-'0'); p++, nn1++; }
1919                if (nn1) nn1+=8;
1920                while (isspace(*p)) p++;
1921                continue;
1922            }
1923            if (strncmp(p,"flenmin=",8) == 0) {
1924                for (p+=8; isdigit(*p); ) { l2=l2*10+(*p-'0'); p++, nn2++; }
1925                if (nn2) nn2+=8;
1926                while (isspace(*p)) p++;
1927                continue;
1928            }
1929            break;
1930        }
1931                if (*p++ != '>') {
1932            freex(srcareap,dirarea);
1933                    return(errp);
1934                }
1935        if (nn1) smumaxlen=(FFI)l1;
1936        if (nn2) fldlenmin=(FFI)l2;
1937        /*...*/
1938            for (n=0, fldp=p; *fldp; fldp++, n++) {
1939                xp=fldp;
1940                if (*xp++ != '<') continue;
1941                if (*xp++ != '/') continue;
1942                nn=0; while (isspace(*xp)) { xp++; nn++; }
1943                for (tagmatch=0; isdigit(*xp); xp++, nn++)
1944                    tagmatch=tagmatch*10+(*xp-'0');
1945                while (isspace(*xp)) { xp++; nn++; }
1946                if (*xp++ != '>') continue;
1947                if (tagmatch != tag) continue;
1948                endmatch=2+nn+1; break;
1949            }
1950            if (!endmatch) {
1951                freex(srcareap,dirarea);
1952                return(errp);
1953            }
1954
1955            fldp=p;
1956            fldleft=n;
1957            for (xp=fldp; fldleft > 0; ) {
1958                if (*fldp != '<') {
1959                    if (erased) *xp = *fldp; xp++; fldp++; fldleft--; continue;
1960                }
1961                for (striplen=1, match=0, fldq=fldp, fldqleft=fldleft; fldqleft > 0; ) {
1962                    if (striplen > smumaxlen) break;
1963                    if (*fldq == '>') { match=1; break; }
1964                    fldq++; fldqleft--; striplen++; continue;
1965                }
1966                if (!match) {
1967                    if (erased) *xp = *fldp; xp++; fldp++; fldleft--; continue;
1968                }
1969                fldp+=striplen; fldleft-=striplen; erased+=striplen;
1970            }
1971        if (erased) memset(xp,' ',erased);
1972        /*...*/
1973                p+=n;
1974        /*... p+=endmatch; ...*/
1975        /*... n-=erased; ...*/
1976        }
1977#endif /* STRIPMARKUP */
1978/* CMD 'A' */
1979/* CMD '{' */
1980        else {
1981            c= *p++;
1982#if RUFxRACE
1983printf("+++c=%c\n",c);
1984#endif
1985            for (n=0; *p; p++, n++)
1986                if (*p == c) break;
1987#if RUFxRACE
1988else printf("+++%d  p=%c\n",n,*p);
1989printf("+++%d\n",n);
1990#endif
1991            if (*p != c) {
1992                freex(srcareap,dirarea);
1993                return(errp);
1994            }
1995        }
1996/* END CMD 'A' */
1997/* END CMD 'H' */
1998/* END CMD '<' */
1999/* END CMD '{' */
2000
2001#if STRIPMARKUP
2002            if (cc == '<' && n /*...*/ -erased /*...*/ < fldlenmin) {
2003        /*...*/ p+=endmatch; /*...*/
2004        }
2005        else {
2006#endif /* STRIPMARKUP */
2007        sp=srcareap+dirsleft;
2008            for (reploop=1, dirp=dirarea+dirsleft; reploop-- ; dirp++, sp++) {
2009                if (dirsleft >= maxdirs) {
2010            freex(srcareap,dirarea);
2011                    return(errp);
2012                }
2013                dirp->tag = (UWORD)tag;
2014                dirp->pos = (FFI)(p-batchp)-n;                  /* v3.4 */
2015#if STRIPMARKUP
2016        /*...*/ p+=endmatch; /*...*/
2017        /*...*/ n-=erased; /*...*/
2018#endif /* STRIPMARKUP */
2019                dirp->len = (FFI)n;
2020                *sp = 'b';      /* source is batchp */          /* v3.4 */
2021                vlenadd+=dirp->len;
2022                dirsleft++;
2023                nadd++;
2024#if RUFTRACE
2025printf("fldupdat - A - tag=%d  dirsleft=%d  vlenadd=%d\n",
2026tag,dirsleft,vlenadd);
2027for (sxp=srcareap, dp=dirarea, loop=0; loop<dirsleft; loop++, dp++, sxp++)
2028 printf("fldupdat - dir[%d]: tag=%d  pos=%d(%c)  len=%d\n",
2029  loop,dp->tag,dp->pos,*sxp,dp->len);
2030#endif
2031            }
2032#if STRIPMARKUP
2033        }
2034            if (cc != 'H' && cc != '<')
2035#else /* STRIPMARKUP */
2036            if (cc != 'H')
2037#endif /* STRIPMARKUP */
2038        p++;
2039            break;
2040
2041        default:
2042        freex(srcareap,dirarea);
2043            return(errp);
2044        }
2045    }
2046#if BEFORE20000426
2047    if ((MFRmfrl+(nadd-ndel)*sizeof(DIRSTRU)-vlendel+vlenadd) > RECnbytes) {
2048#else
2049    if ((LONGX)(MFRmfrl+(nadd-ndel)*sizeof(DIRSTRU)-vlendel+vlenadd) >
2050        (LONGX)RECnbytes) { /* AOT/RP - 26/04/2000 - para ALPHACPU (IPEN) */
2051#endif
2052    freex(srcareap,dirarea);
2053        return(batchp);
2054    }
2055
2056    if (ndel) {
2057        mfdirp=MFRdir;
2058        newp=MFX+MFRbase-(k=sizeof(DIRSTRU)*ndel); lastpos=0;
2059        sp=srcareap;
2060        for (dirp=dirarea, n=dirsleft; n--; dirp++, sp++)
2061            if (*sp == 'r') {                                   /* v3.4 */
2062                mfdirp->tag = dirp->tag;
2063                mfdirp->pos = lastpos;
2064                mfdirp->len = dirp->len;
2065                p=MFX+MFRbase+dirp->pos;
2066                memcpy(newp,p,dirp->len); newp+=dirp->len;
2067                lastpos+=dirp->len;
2068                mfdirp++;
2069            }
2070        MFRbase-=k;
2071        MFRnvf-=ndel;
2072        MFRmfrl-=(k+vlendel);
2073    }
2074
2075    if (nadd) {
2076        nxtpos=MFRmfrl-MFRbase;
2077        nxtp=MFX+MFRmfrl+(k=sizeof(DIRSTRU)*nadd);
2078        for (p=(mfp=nxtp-1)-k, mfdirp=MFRdir, n=MFRnvf; n--; ) {
2079            for (loop=mfdirp->len; loop--; )
2080                    *mfp-- = *p--;
2081            /* mfdirp->pos+=k;  MFRbase will be changed */
2082            mfdirp++;
2083        }
2084        if (mfdirp != &MFRdir[MFRnvf])
2085            fatal("fldupdat/bug");
2086        sp=srcareap;                                            /* v3.4 */
2087        for (mfp=nxtp, dirp=dirarea, n=dirsleft; n--; dirp++, sp++) {
2088            if (*sp == 'r')                                     /* v3.4 */
2089                continue;
2090            p=batchp+dirp->pos;                                 /* v3.4 */
2091            memcpy(mfp,p,dirp->len); mfp+=dirp->len;
2092            mfdirp->tag = dirp->tag;
2093            mfdirp->pos = nxtpos;
2094            mfdirp->len = dirp->len;
2095            mfdirp++;
2096            nxtpos+=dirp->len;
2097        }
2098        MFRbase+=k;
2099        MFRnvf+=nadd;
2100        MFRmfrl+=(k+vlenadd);
2101    }
2102
2103#if RUGTRACE
2104    printf("fldupdat - RECrc=%d  Leader: %ld,%d,%ld,%d,%d,%d,%d\n",
2105        RECrc,MFRmfn,MFRmfrl,MFRmfbwb,MFRmfbwp,MFRbase,MFRnvf,MFRstatus);
2106for (mfdirp=MFRdir, loop=0; loop<MFRnvf; loop++, mfdirp++) {
2107 printf("fldupdat - dir[%d]: tag=%d  pos=%d  len=%d",
2108  loop,mfdirp->tag,mfdirp->pos,mfdirp->len);
2109#if RUHTRACE
2110 printf("  ->");
2111 for (p=MFX+MFRbase+mfdirp->pos, n=mfdirp->len; n--; p++)
2112  printf("%c",*p);
2113 printf("<-");
2114#endif
2115printf("\n");
2116}
2117#endif
2118
2119    freex(srcareap,dirarea);
2120
2121    if (sort) {
2122#if CICPP
2123        try { srcareap = (char *) new char [MFRmfrl-MFRbase+1]; }
2124        catch (BAD_ALLOC) { srcareap = (char *)ALLONULL; }
2125#else /* CICPP */
2126        srcareap=(char *)ALLOC((ALLOPARM)(MFRmfrl-MFRbase+1));
2127#endif /* CICPP */
2128        if (srcareap == (char *)ALLONULL) fatal("fldupdat/ALLOC/sort");
2129        dirarea=NULL;
2130        dirp=MFRdir;
2131        sp=srcareap;
2132        lastpos=0;
2133        for (n=MFRnvf; n--; dirp++) {
2134            p=MFX+MFRbase+dirp->pos;
2135            memcpy(sp,p,dirp->len); sp+=dirp->len;
2136            dirp->pos = lastpos;
2137            lastpos+=dirp->len;
2138        }
2139        memcpy(MFX+MFRbase,srcareap,MFRmfrl-MFRbase);
2140    freex(srcareap,dirarea);
2141    }
2142
2143    return(NULL);
2144#undef freex
2145}
Note: See TracBrowser for help on using the browser.