forked from rogercgui/cisis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathciupd.c
2143 lines (1849 loc) · 51.5 KB
/
ciupd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
CCOPTS = -DINCPRECX=0 -DEXCFMCGI=1 -DEXCFMXML=1
$(CC) -DINCPROCX=0 $(CCOPTS) wtrig2.c
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define DIR_FILE 1 /* list=directory */
#if DIR_FILE
#include <sys/types.h>
#include <dirent.h>
#endif
#include "cisis.h"
#ifndef PROCXSLT
#if UNIX
#define PROCXSLT 0
#else /* UNIX */
#define PROCXSLT 0
#endif /* UNIX */
#endif
#if PROCXSLT
#include <libxslt/transform.h>
#include <libxslt/xsltutils.h>
#endif /* PROCXSLT */
#ifndef INCPROCX // proc Y / proc T (bug if called by cifm3.c) /* usa CIIFU (+FST(+FMT)) */
#define INCPROCX 1
#define INCPROCXT 1
#endif
#ifndef INCPRECX // 6words/if= in Gsplit (ciupdsplt.c) /* usa CITRM */
#define INCPRECX 1
#endif
#ifndef INCPRCCX // socket client with Gload (ciupdsocx.c) /* */
#define INCPRCCX 1
#endif
#ifndef INCPRSSX // server /* */
#define INCPRSSX 0 // 1
#endif
#if INCPRCCX
#ifndef PROCXSOCKREC
#define PROCXSOCKREC 1 // include ciupdsocx.c
#endif /* PROCXSOCKREC */
#endif /* INCPRCCX */
#if CICPP
#if INCPROCX
#include "ciifu.hpp"
#endif
#endif
#if CICPP
#if INCPRECX
#include "citrm.hpp"
#endif
#endif
#ifdef USE_ERROR_SYS
#include <ui_win.hpp>
#include <errorsys.hpp>
extern MY_ERROR_SYSTEM * errsys;
extern MESS_SYSTEM *mess;
extern UIW_WINDOW * wprogress;
#include <textdb.hpp>
#define USE_INFO_SYS
#endif
/* ----------------------------- upd.c ------------------------------ */
#define RUCTRACE 00
#define RUCTRACX 00
#define RUCTRAC2 00
#define RUFTRACE 0
#define RUGTRACE 0
#define RUHTRACE 0
#define RUITRACE 0
#define RUJTRACE 0
#define RUKTRACE 0
#define RUFxRACE 0
#define RUUTRACE 0
#define MULTRACE 1 /* multrace runtime switch */
#if !CICPP
int recisis0_m=1; /* recisis0() init .mst */
int recisis0_s=0; /* recisis0() system file type */
#endif /* CICPP */
#if !CICPP
#define CIUPD_CISISX_SOURCE 1
#include "cisisx.c"
#endif
#if PROCXSLT
#include "cidump.c"
#endif /* PROCXSLT */
#if CICPP
#define NO_IREC -1L
#endif /* CICPP */
#if MULTI
#if CICPP
int RECSTRU :: xrecunlck(int option)
#else /* CICPP */
int recunlck(irec,option) /*
------------
se option = EWLOCK faz EWL unlock
se option = DELOCK faz DEL unlock
se option = RLOCK faz RL unlock;
retorna RCNORMAL ou aborta
*/
LONGX irec; /* vrecp[] element defining RECdbxp/MFRmfn */
int option;
#endif /* CICPP */
{
RECSTRU *recp;
DBXSTRU *dbxp;
FFI oldgdbl;
LONGX mfn;
int fd,rc;
FFI n;
int uok=0,force=0;
LONGX comb; /* gdb getmfr comb */
int comp; /* gdb getmfr comp */
#if CICPP
#if RUUTRACE
LONGX irec = NO_IREC;
#endif
RECSTRU *wrecp=NULL;
recp=this;
#else
LONGX wrec;
if (irec < 0 || irec >= maxnrec) fatal("recunlck/irec");
if (!nrecs || !vrecp[irec]) fatal("recunlck/recinit");
recp=vrecp[irec];
#endif
/* get input information */
dbxp=RECdbxp;
mfn=MFRmfn;
/* keep old RECgdbl */
oldgdbl=RECgdbl;
/* allocate working control record / record leader */
#if CICPP
try { wrecp=new RECSTRU(cisisxp); wrecp->xrecalloc(sizeof(M0STRU)); }
catch (BAD_ALLOC) { return(-1); }
wrecp->recdbxp=dbxp;
recp=wrecp;
#else /* CICPP */
for (wrec=maxnrec; wrec--; ) {
if (!vrecp[wrec]) /* ja' decrementado */ break;
}
if (wrec < 0) return(-1);
recallok(wrec,sizeof(M0STRU));
VRECdbxp(wrec)=dbxp;
recp=vrecp[wrec];
#endif /* CICPP */
if (option & FORCE) { force=1; option-=FORCE; }
if (option & RDELOCK) option = (mfn) ? RLOCK : DELOCK;
if (option != EWLOCK && option != DELOCK && option != RLOCK)
fatal("recunlck/option");
#if RUUTRACE
printf("recunlck - irec=%"_LD_" dbn=%s/%"_LD_" unlck=%d\n",irec,DBXname,mfn,option);
#endif
if (DBXnetws == MONONETS) {
if (multrace)
printf("<u> %s/%"_LD_" [%s MONONETS]\n",
DBXname,mfn,(option&RDELOCK)?((option==RLOCK)?"RL":"DEL"):"EWL");
return(RCNORMAL);
}
if (!DBXmsopn) fatal("recunlck/msopn");
dbxopenw(DBXname,DBXname,mx1extp,&DBXmsopn,&DBXmsopw,"recunlck/msopn/w");
fd=DBXmsopn;
/* step 1: lock the .mst file and get the ctl rec */
if (multrace) printf("<u> %s .mst lock \n",DBXname);
#if BEFORE950220
/* .mst file lock: lock */
if (dbxflock(dbxp,"M")) fatal("recunlck/file lock");
/* get the current ctl rec */
keeplock=REClock; REClock=NOLOCK;
if (recread(recp,0L) != RCNORMAL) fatal("recunlck/read/ctl");
REClock=keeplock;
/* check another's exclusive write lock */
if (MF0mfcxx3 && !DBXewlxx && !force) {
if (multrace) printf("<u> %s has exclusive write lock\n",DBXname);
fatal("recunlck/exclusive write lock");
}
#else
if (dbxflock(dbxp,"M")) {
if (multrace) printf("<u> %s .mst lock/denied \n",DBXname);
if (dbxewlrc) return(RCLOCK);
fatal("recunlck/file lock");
}
/* wait another's exclusive write lock */
if (force) {
if (LSEEK64(DBXmsopn,0L,SEEK_SET) != 0) fatal("recunlck/force/lseek");
n=CIREAD(DBXmsopn,MFX,sizeof(M0STRU));
#if CNV_PCBINUM
ConvertMST_CTLSTRUCT(MFX);
#endif
if (n != sizeof(M0STRU)) {
if (dbxewlrc) return(RCLOCK);
fatal("recunlck/force/read");
}
}
else
if (dbxwlock(dbxp,MFX,dbxwloop)) {
if (multrace) printf("<u> %s .mst ewl is on !!!\n",DBXname);
if (dbxewlrc) return(RCLOCK);
fatal("recunlck/must wait ewl");
}
/* copy MFX to what will be written */
memmove(DBXmsibp,MFX,sizeof(M0STRU));
#endif
/* check data entry lock */
if (option & RDELOCK && (!MF0mfcxx2 || !DBXdelxx) && !force) {
if (multrace)
printf("<u> %s/mfcxx2=%"_LD_" delxx=%d\n",DBXname,MF0mfcxx2,DBXdelxx);
fatal("recunlck/data entry lock is off");
}
/* step 2: logical unlock */
if (option == EWLOCK || option == DELOCK) { /* EWL or DEL */
if (option == EWLOCK) {
/* unflag exclusive write lock */
if (MF0mfcxx3 || DBXewlxx) {
if (MF0mfcxx3) MF0mfcxx3--;
if (DBXewlxx) DBXewlxx--;
/* update input buffer */
((M0STRU *)DBXmsibp)->m0mfcxx3=MF0mfcxx3;
uok=1;
}
}
else {
/* unflag data entry lock */
if (MF0mfcxx2 || DBXdelxx) {
if (MF0mfcxx2) MF0mfcxx2--;
if (DBXdelxx) DBXdelxx--;
/* update input buffer */
((M0STRU *)DBXmsibp)->m0mfcxx2=MF0mfcxx2;
uok=1;
}
}
/* write it back */
if (uok) {
if (LSEEK64(fd,0L,SEEK_SET) != 0)
fatal("recunlck/lseek/ctl");
#if DBXMSTXL /* AOT 18/06/2002 */
if (DBXmstxl) {
((M0STRU *)DBXmsibp)->m0mftype += DBXmstxl * 256;
}
#endif
#if CNV_PCBINUM
memmove(cnv_pcbuff,DBXmsibp,sizeof(M0STRU));
ConvertMST_CTLSTRUCT(cnv_pcbuff);
if (CIWRITE(fd,cnv_pcbuff,sizeof(M0STRU)) != sizeof(M0STRU))
#else
if (CIWRITE(fd,DBXmsibp,sizeof(M0STRU)) != sizeof(M0STRU))
#endif
fatal("recunlck/write/ctl");
#if DBXMSTXL /* AOT 18/06/2002 */
if (DBXmstxl) {
((M0STRU *)DBXmsibp)->m0mftype &= 0x00FF;
}
#endif
}
} /* end of data entry lock */
else { /* RL */
/* get its xref to rewrite the leader segment */
recreadl=1; /* leader only */
rc=recread(recp,mfn);
comb=recxrefb; comp=recxrefp;
#ifndef USE_ERROR_SYS
if (rc == RCEOF || rc == RCPDEL) fatal("recunlck/EOFPDEL");
#else
if (!(rc == RCEOF || rc == RCPDEL)) {
#endif
/* reset existing record lock and call recwmast */
if (oldgdbl || (force && RECgdbw)) {
if (multrace)
printf("<u> %s/%"_LD_" mfrl=%04x=+%d\n",DBXname,mfn,RECgdbl,MFRmfrl);
/* write back the leader segment */
#if CICPP
recwmast(NULL,comb,comp,0,1); /* leader only */
#else
recwmast(NULL,recp,comb,comp,0,1); /* leader only */
#endif /* CICPP */
uok=1;
}
#ifdef USE_ERROR_SYS
}
#endif
} /* end of record unlock */
/* step 3: .mst file unlock */
if (multrace)
printf("<u> %s .mst unlock [%s %s]\n",DBXname,
(option&RDELOCK)?((option==RLOCK)?"RL":"DEL"):"EWL",
(uok)?"off":"unlock denied");
if (dbxulock(dbxp,"M")) fatal("recunlck/file unlock");
#if CICPP
if (wrecp) delete wrecp;
recp=this;
#else
#if BEFORE20000809
if (wrec) if (vrecp[wrec]) {
#else
if (wrec >= 0) if (vrecp[wrec]) {
#endif
FREE(vrecp[wrec]); vrecp[wrec]=NULL; nrecs--;
}
recp=vrecp[irec];
#endif
if (uok) {
RECgdbl=RECgdbw=0;
return(RCNORMAL);
}
return(RCEOF);
}
#endif /* MULTI */
#if CICPP
int RECSTRU :: xrecupdat(void)
#else /* CICPP */
int recupdat(crec,irec) /*
------------
abenda se vrecp nao inicializado;
abenda se registros crec/irec ainda nao alocados;
abenda se tipo de crec diferente de TYPEMF0;
abenda se mfn menor do que 1 ou maior do que MAXMFN;
seta dbxp de irec igual ao de crec;
chama recwrite();
retorna RCNORMAL
*/
LONGX crec; /* indice de vrecp, para recwrite() */
LONGX irec; /* indice de vrecp, para recwrite() */
#endif /* CICPP */
{
RECSTRU *recp, *crecp;
LONGX mfn;
int rc;
if (rectrace) multrace=1;
#if CICPP
try { crecp = new RECSTRU(cisisxp); }
catch (BAD_ALLOC) { fatal("recupdat/ALLOC/crecp"); }
crecp->xrecalloc(sizeof(M0STRU));
recp =this;
crecp->xrecord(RDBname,0L);
recp=crecp; /* tmp */
#else /* CICPP */
if (!nrecs)
fatal("recupdat/RECINIT");
if (crec < 0 || crec >= maxnrec) fatal("recupdat/crec/index");
if (irec < 0 || irec >= maxnrec) fatal("recupdat/irec/index");
recp=vrecp[crec]; /* tmp */
#endif /* CICPP */
if (MF0nxtmfn < 1) fatal("recupdat/crec/nxtmfn");
if (MF0nxtmfb < 1) fatal("recupdat/crec/nxtmfb");
if (MF0mftype != MSMFTUSR &&
MF0mftype != MSMFTMSG) fatal("recupdat/crec/mftype");
if (MF0nxtmfn == 1)
if (MF0mftype != MSMFTMSG)
if (MF0nxtmfp <= sizeof(M0STRU)) fatal("recupdat/crec/nxtmfp/1");
if (MF0nxtmfp > MSBSIZ) fatal("recupdat/crec/nxtmfp/MSBSIZ");
#if CICPP
recp=this;
#else /* CICPP */
crecp=vrecp[crec]; recp=vrecp[irec];
#endif /* CICPP */
if (!crecp || !recp)
fatal("recupdat/RECALLOC");
if (crecp->rectype != TYPEMF0)
fatal("recupdat/TYPEMF0");
if ((mfn=MFRmfn) < 1 || mfn > MAXUPDMFN)
#if MULTI
if (!(RECwlock & NEWREC && MFRmfn == 0))
#endif
fatal("recupdat/mfn");
#if !CICPP
#if RUCTRACE || RUCTRAC2
printf("recupdat - crec=%"_LD_" irec=%"_LD_" dbn(crec)=%s mfn=%"_LD_" opw=%d,%d\n",
crec,irec,VRDBname(crec),mfn,VRDBxropw(crec),VRDBmsopw(crec));
#endif
#endif /* CICPP */
RECdbxp=crecp->recdbxp; /* get dbxp from control record */
#if CICPP
rc=recwrite(crecp);
#else
rc=recwrite(crecp,recp);
#endif /* CICPP */
#if RUCTRACE
#if CICPP
recp=crecp;
#else
recp=vrecp[crec];
#endif /* CICPP */
printf("recupdat - RECrc=%d Ctlmfr: %"_LD_",%"_LD_",%"_LD_",%d,%d,%"_LD_"%"_LD_"%"_LD_"%"_LD_"\n",
RECrc,
MF0ctlmfn,MF0nxtmfn,MF0nxtmfb,MF0nxtmfp,
MF0mftype,MF0reccnt,MF0mfcxx1,MF0mfcxx2,MF0mfcxx3);
#if CICPP
recp = this;
#else
recp=vrecp[irec];
#endif /* CICPP */
printf("recupdat - RECrc=%d Leader: %"_LD_",%d,%"_LD_",%d,%d,%d,%d\n",
RECrc,MFRmfn,MFRmfrl,MFRmfbwb,MFRmfbwp,MFRbase,MFRnvf,MFRstatus);
printf("recupdat - rc=%d\n",rc);
#endif
#if !CICPP
#if RUCTRAC2
printf("recupdat : crec=%"_LD_" irec=%"_LD_" dbn(crec)=%s mfn=%"_LD_" opw=%d,%d\n",
crec,irec,VRDBname(crec),mfn,VRDBxropw(crec),VRDBmsopw(crec));
#endif
#endif /* CICPP */
#if CICPP
delete crecp;
#endif /* CICPP */
return(rc);
}
#if CICPP
int RECSTRU :: xrecwrite(RECSTRU *crecp)
#else /* CICPP */
int recwrite(crecp,recp) /*
------------
seta dbxp e ms0p desce crecp;
seta mfn desde recp;
abenda de dbxp diferentes;
obtem ptr para .mst e seu (mfn) status em .xrf;
regrava o registro recp;
altera e regrava o registro crecp;
mantem .xrf;
retorna RCNORMAL ou aborta
*/
RECSTRU *crecp; /* elemento de vrecp, para info/store nxtmfn,mfb,mfp */
RECSTRU *recp; /* elemento de vrecp, para info/store mfbwb,mfbwp */
#endif /* CICPP */
{
DBXSTRU *dbxp;
M0STRU *ms0p; /* defines MS0 */
M1STRU *mshp; /* defines MSH */
LONGX mfn;
LONGX lastmfn;
int newblk;
int rc;
FFI n;
XRPTR xrftiv; /* gdb .xrf pointer */
LONGX comb; /* gdb getmfr comb */
int comp; /* gdb getmfr comp */
M1STRU header; /* to read LEADER bytes */
#if CNV_PCFILES
char unibuff[MSNVSPLT]; /* CNV_PCFILES/recwrite - mshp */
#endif
int pend; /* if update is pending */
int pendnew; /* if update is pending - newrec */
int pendupd; /* if update is pending - update */
LONGX thiscomb;
off_t xbyte;
int thiscomp;
LONGX nxtcomp;
int flagnew; /* record will be written as a newrec */
unsigned inplace; /* NEVER or MAYBE */
#if MULTI
int isnewrec;
#if BEFORE950220
int keeplock;
#endif
#endif
#if DBXMSTXL
int pow, vtot;
#endif
#define NEVER 0
#define MAYBE 1
#if CICPP
RECSTRU *recp = this;
#endif /* CICPP */
dbxp=crecp->recdbxp;
#if BEFORE950724
if (!DBXxropn) fatal("recwrite/xropn");
if (!DBXmsopn) fatal("recwrite/msopn");
#else
if (!DBXxropn || !DBXmsopn) mstsetup(DBXname,0L,0L);
#endif
dbxopenw(DBXname,DBXname,xx1extp,&DBXxropn,&DBXxropw,"recwrite/xropn/w");
dbxopenw(DBXname,DBXname,mx1extp,&DBXmsopn,&DBXmsopw,"recwrite/msopn/w");
if (!DBXxropw) fatal("recwrite/xropw");
if (!DBXmsopw) fatal("recwrite/msopw");
if (!DBXxribp) fatal("recwrite/xribp");
if (!DBXmsibp) fatal("recwrite/msibp");
#if CICPP
ms0p= &crecp->recmfp->m0;
#else
ms0p= &crecp->recmf.m0;
#endif /* CICPP */
if (MS0mftype != MSMFTUSR && MS0mftype != MSMFTMSG)
fatal("recwrite/mftype");
mfn=MFRmfn;
#if RUCTRACE
printf("recwrite - dbn/%d=%s mfn=%"_LD_" nxtmfn=%"_LD_" nxtmfb=%"_LD_" nxtmfp=%d\n",
MS0mftype,DBXname,mfn,MS0nxtmfn,MS0nxtmfb,MS0nxtmfp);
#endif
#if MULTI
isnewrec=RECwlock & NEWREC;
if (DBXnetws != MONONETS) {
if ((RECwlock & WUNLOCK && RECwlock & WLOCK) ||
!(RECwlock & WUNLOCK || RECwlock & WLOCK))
fatal("recwrite/WLOCK/WUNLOCK");
/* step 1: lock the .mst file and get the current ctl rec */
/* assure data entry lock has been granted (also ewl) */
if (!DBXdelxx) fatal("recwrite/lock/data entry lock is off");
/* assure record lock has been granted */
if (!isnewrec)
if (!RECgdbl) fatal("recwrite/lock/record lock needed");
/* .mst file lock: lock */
if (multrace) printf("<w> %s .mst lock \n",DBXname);
#if BEFORE950220
if (dbxflock(dbxp,"M")) fatal("recwrite/lock/file lock");
/* reset internal lock flag and get the current ctl rec */
keeplock=crecp->reclock; crecp->reclock=NOLOCK;
if (recread(crecp,0L) != RCNORMAL) fatal("recwrite/lock/read");
crecp->reclock=keeplock;
/* check another's exclusive write lock - should never occur */
if (MS0mfcxx3 && !DBXewlxx) {
if (multrace) printf("<w> %s has exclusive write lock\n",DBXname);
fatal("recwrite/lock/exclusive write lock");
}
#else
if (dbxflock(dbxp,"M")) {
if (multrace) printf("<w> %s .mst lock/denied \n",DBXname);
if (dbxewlrc) return(RCLOCK);
fatal("recwrite/lock/file lock");
}
/* wait another's exclusive write lock */
if (dbxwlock(dbxp,(char *)ms0p,dbxwloop)) {
if (multrace) printf("<w> %s .mst ewl is on !!!\n",DBXname);
if (dbxewlrc) return(RCLOCK);
fatal("recwrite/lock/must wait ewl");
}
#endif
/* check data entry lock */
if (!MS0mfcxx2) fatal("recwrite/lock/data entry lock/mfcxx2");
if (!DBXdelxx) fatal("recwrite/lock/data entry lock needed");
/* assign nxtmfn */
if (isnewrec) {
if (!mfn) {
mfn=MFRmfn=MS0nxtmfn;
if (multrace) printf("<w> %s -> mfn=%"_LD_"\n",DBXname,MFRmfn);
}
}
}
#endif /* MULTI */
lastmfn=MS0nxtmfn-1;
if (RECdbxp != dbxp)
fatal("recwrite/dbxp");
rc=recxref(recp,mfn,&comb,&comp);
if (comb > MS0nxtmfb)
fatal("recwrite/chknew/comb");
if (comp >= MSBSIZ)
fatal("recwrite/chknew/comp");
#if DBXMSTXL
pendnew=recxrefn;
pendupd=recxrefm;
#else
xrftiv=DBXxribp->xrmfptr[(mfn-1)%XRMAXTIV]; /* not available for mfn=0 */
pendnew=(int)(labs(xrftiv) & XRXMASKN);
pendupd=(int)(labs(xrftiv) & XRXMASKU);
#endif
pend=(pendnew | pendupd);
if (pendnew && pendupd)
fatal("recwrite/pend");
if (MS0mftype == MSMFTMSG) {
pend=1; /* to force inplace=MAYBE */
pendnew=1; /* and mfbwb/mfbwp=0 */
}
#if RUCTRACE
printf("recwrite - comb=%"_LD_" comp=%d new=%d upd=%d pend=%d rc=%d\n",
comb,comp,pendnew,pendupd,pend,rc);
#endif
mshp= &header;
if (rc == RCEOF || rc == RCPDEL) {
#if MULTI
if (DBXnetws != MONONETS) {
if (multrace) printf("<w> %s/%"_LD_" rc=%d\n",DBXname,MFRmfn,rc);
if (!isnewrec) fatal("recwrite/lock/EOFPDEL");
}
#endif /* MULTI */
if (pend)
if (MS0mftype != MSMFTMSG) /* 07/03/97 */
fatal("recwrite/chknew/pend/EOFPDEL");
memset((char *)mshp,0x00,LEADER);
MSHstatus=DELETED;
comb=MS0nxtmfb;
comp=MS0nxtmfp-1;
#if RUCTRACE
printf("recwrite - comb=%"_LD_" comp=%d [%"_LD_,"%"_LD_"+%d]\n",
comb,comp,MS0nxtmfn,MS0nxtmfb,MS0nxtmfp);
#endif
}
else {
#if MULTI
if (multrace) printf("<w> %s/%"_LD_" rc=%d\n",DBXname,MFRmfn,rc);
if (DBXnetws != MONONETS)
if (isnewrec)
if (RECwlock & FORCE) ; else fatal("recwrite/lock/NORMALDEL");
#endif /* MULTI */
xbyte=(((off_t)(comb-1))<<MSBSHIFT)+comp;
if (LSEEK64(DBXmsopn,xbyte,SEEK_SET) != xbyte)
fatal("recwrite/lseek/leader");
n=CIREAD(DBXmsopn,(char *)mshp,LEADER); /* MSNVSPLT */
#if CNV_PCBINUM
ConvertMST_LEADER((char *)mshp,0,LEADER);
#endif
#if CNV_PCFILES
memmove(unibuff,(char *)mshp,MSNVSPLT);
memmove(((char *)mshp)+0,unibuff+0,4); /* mfn= */
memmove(((char *)mshp)+4,unibuff+6,4); /* mfbwb= */
memmove(((char *)mshp)+8,unibuff+4,2); /* mfrl= */
#endif
if (n != LEADER) {
#if RUCTRACE
printf("recwrite - fd=%d lseek=%"P_OFF_T" n=%d\n",DBXmsopn,(LONG_LONG)xbyte,n);
#endif
fatal("recwrite/read");
}
if (MSHmfn != mfn)
fatal("recwrite/check/mfn");
if (MS0mftype == MSMFTMSG)
MSHmfrl=MSBSIZ; /* to force inplace=MAYBE */
#if MULTI
/* step 2: check existing record lock */
if (DBXnetws != MONONETS) {
if (multrace)
printf("<w> %s/%"_LD_" mfrl=%04x=%d\n",DBXname,mfn,MSHmfrl,MSHmfrl);
if (!isnewrec)
if (MSHmfrl <= (FFI)MFRL_MAX) fatal("recwrite/lock/record lock");
if (MSHmfrl > (FFI)MFRL_MAX) {
MSHmfrl=(FFI)0-MSHmfrl;
if (multrace)
printf("<w> %s/%"_LD_" mfrl=%04x=+%d\n",DBXname,mfn,0x0000,MSHmfrl);
}
}
#endif /* MULTI */
}
#if RUCTRACE
printf("recwrite - rec: %"_LD_",%d,%"_LD_",%d,%d,%d,%d\n",
MFRmfn,MFRmfrl,MFRmfbwb,MFRmfbwp,MFRbase,MFRnvf,MFRstatus);
printf("recwrite - mst: %"_LD_",%d,%"_LD_",%d,%d,%d,%d\n",
MSHmfn,MSHmfrl,MSHmfbwb,MSHmfbwp,MSHbase,MSHnvf,MSHstatus);
#endif
if (rc == RCEOF || rc == RCPDEL)
if (MFRstatus == DELETED)
fatal("recwrite/deleted");
if (rc == RCEOF || rc == RCPDEL || pendnew)
flagnew=1;
else
flagnew=0;
if (pend) {
MFRmfbwb=MSHmfbwb;
MFRmfbwp=MSHmfbwp;
inplace=MAYBE;
}
else { /* no if update is pending */
if (MSHmfbwb != 0 && MSHmfbwp != 0)
fatal("recwrite/mfbwlink");
if (rc != RCNORMAL) { /* 26/09/90 */
MFRmfbwb=0;
MFRmfbwp=0;
inplace=MAYBE;
}
else { /* cancel xrfptr/add */
MFRmfbwb=comb;
MFRmfbwp=comp;
inplace=NEVER;
}
}
if (MS0mftype != MSMFTMSG) {
if (MFRmfrl & 0x01)
MFX[MFRmfrl++]=' '; /* gdb always an even number */
#if DBXMSTXL
vtot = 1;
for (pow = 1; pow <= DBXmstxl; pow++) {
vtot *= 2;
}
vtot -= 1;
while (MFRmfrl & vtot)
MFX[MFRmfrl++]=' ';
/* if (DBXmstxl == 2) {
while (MFRmfrl & 0x03)
MFX[MFRmfrl++]=' ';
}
if (DBXmstxl == 3) {
while (MFRmfrl & 0x07)
MFX[MFRmfrl++]=' ';
} */
#endif
}
#if MULTI
/* step 3: check actual maximum record length */
if (DBXnetws != MONONETS) {
if (MFRmfrl > (FFI)MFRL_MAX) fatal("recwrite/lock/mfrl");
}
#endif /* MULTI */
#if RUCTRACE
printf("recwrite - mfbwb=%"_LD_" mfbwp=%d inplace=%d flagnew=%d\n",
MFRmfbwb,MFRmfbwp,inplace,flagnew);
#endif
if (MFRmfrl <= MSHmfrl && inplace == MAYBE) {
thiscomb=comb;
thiscomp=comp;
newblk=0;
}
else {
thiscomb=MS0nxtmfb;
thiscomp=MS0nxtmfp-1;
#if DBXMSTXL
/*if (thiscomp & 0x01 ||
(DBXmstxl == 2 && thiscomp & 0x03) ||
(DBXmstxl == 3 && thiscomp & 0x07))*/
if (thiscomp & 0x01 || (thiscomp & vtot))
#else
if (thiscomp & 0x01)
#endif
fatal("recwrite/check/even");
newblk=0;
if (thiscomp > (MSBSIZ-MSNVSPLT)) {
thiscomb++;
thiscomp=0;
newblk=1;
}
MS0nxtmfb=thiscomb;
nxtcomp= (MS0mftype == MSMFTMSG) ? MSBSIZ : thiscomp+MFRmfrl;
for (;;)
if (nxtcomp < MSBSIZ)
break;
else {
MS0nxtmfb++;
nxtcomp-=MSBSIZ;
newblk=1;
}
if (nxtcomp > (MSBSIZ-MSNVSPLT)) { /* 17/01/91 */
MS0nxtmfb++;
nxtcomp=0;
newblk=1;
}
MS0nxtmfp=nxtcomp+1; /* gdb first = sizeof(M0STRU)+1 */
if (MS0nxtmfp == 1)
newblk=0;
if (thiscomp == 0)
newblk=1;
if (MS0mftype == MSMFTMSG)
newblk=1;
}
if (mfn >= MS0nxtmfn) {
MS0nxtmfn=mfn+1;
DBXmsmfn=MS0nxtmfn;
}
#if RUCTRACE
printf("recwrite - thiscomb=%"_LD_" thiscomp=%d\n",thiscomb,thiscomp);
printf("recwrite - MS0nxtmfn=%"_LD_" MS0nxtmfb=%"_LD_" MS0nxtmfp=%d\n",
MS0nxtmfn,MS0nxtmfb,MS0nxtmfp);
#endif
#if MULTI
/* step 4: process record lock/unlock */
if (DBXnetws != MONONETS) {
/* process WUNLOCK/WLOCK */
MFRmfrl=(FFI)0-MFRmfrl;
RECgdbl=MFRmfrl; RECgdbw=1;
/* reset or keep record lock */
if (RECwlock & WUNLOCK) {
if (multrace)
printf("<w> %s/%"_LD_" mfrl=%04x=%d\n",DBXname,mfn,RECgdbl,MFRmfrl);
MFRmfrl=(FFI)0-MFRmfrl;
if (multrace)
printf("<w> %s/%"_LD_" mfrl=%04x=+%d\n",DBXname,mfn,RECgdbl,MFRmfrl);
RECgdbl=RECgdbw=0;
}
}
#endif /* MULTI */
#if CICPP
recwmast(crecp,thiscomb,thiscomp,newblk,0);
#else
recwmast(crecp,recp,thiscomb,thiscomp,newblk,0);
#endif /* CICPP */
#if MULTI
/* step 5: process existing record lock */
if (DBXnetws != MONONETS) {
if (MFRmfrl > (FFI)MFRL_MAX) {
if (multrace)
printf("<w> %s/%"_LD_" mfrl=%04x=%d\n",DBXname,mfn,MFRmfrl,MFRmfrl);
if (!RECgdbl || !RECgdbw) fatal("recupdat/check/gdbl");
MFRmfrl=(FFI)0-MFRmfrl;
if (multrace)
printf("<w> %s/%"_LD_" mfrl=%04x=+%d\n",DBXname,mfn,MFRmfrl,MFRmfrl);
}
}
#endif /* MULTI */
/* encode .xrf pointer for the record location */
comb = thiscomb;
comp = thiscomp;
if (flagnew)
comp |= XRXMASKN;
else
comp |= XRXMASKU;
#if DBXMSTXL
xrftiv = comb * (XRXDIVIDE>>DBXmstxl) + (comp>>DBXmstxl);
#else
xrftiv = comb * XRXDIVIDE + comp;
#endif
/* complement .xrf pointer for logically deleted records */
if (MFRstatus == DELETED)
xrftiv= -xrftiv;
#if CICPP
recwxref(xrftiv,lastmfn);
#else
recwxref(recp,xrftiv,lastmfn);
#endif /* CICPP */
#if MULTI
/* step 6: .mst file lock: unlock */
if (DBXnetws != MONONETS) {
if (multrace) printf("<w> %s .mst unlock [RL off]\n",DBXname);
if (dbxulock(dbxp,"M")) fatal("recwrite/lock/file unlock");
}
#endif /* MULTI */
return(RCNORMAL);
#undef NEVER
#undef MAYBE
}
#if CICPP
int RECSTRU :: xrecwmast(RECSTRU *crecp,
LONGX comb,
int comp,
int newblk,
FFI wlen)
#else /* CICPP */
int recwmast(crecp,recp,comb,comp,newblk,wlen) /*
------------
seta dbxp e ms0p desde crecp;
regrava o registro recp na posicao comb/comp;
preenche ultimo .mst block, se for o caso;
reseta DBXmsibp->msbufn;
regrava o registro crecp;
retorna RCNORMAL ou aborta
*/
RECSTRU *crecp; /* elemento de vrecp, para info */
RECSTRU *recp; /* elemento de vrecp, para info */
LONGX comb; /* gdb getmfr comb */
int comp; /* gdb getmfr comp */
int newblk; /* new .mst blk switch */
FFI wlen; /* 0=MFRmfrl, 1=leader, 2=+dir, n=mfrl */
#endif /* CICPP */
{
DBXSTRU *dbxp;
FFI n; /* deveria ser int para pegar o retorno da CIWRITE */
int k;
off_t xbyte;
FFI mfrl;
#if CNV_PCFILES
char unibuff[MSNVSPLT]; /* CNV_PCFILES/recwmast - MFX */
#endif
#if DBXMSTXL
UWORD keepmftype;