home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c004 / 1.ddi / CTISAM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-04-18  |  11.9 KB  |  579 lines

  1. /*
  2.  *    isam routines
  3.  *
  4.  *    This program is the CONFIDENTIAL and PROPRIETARY property 
  5.  *    of FairCom(R) Corporation. Any unauthorized use, reproduction or
  6.  *    transfer of this program is strictly prohibited.
  7.  *
  8.  *      Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989 FairCom Corporation
  9.  *    (Subject to limited distribution and
  10.  *     restricted disclosure only.)
  11.  *    *** ALL RIGHTS RESERVED ***
  12.  *
  13.  *    4006 West Broadway
  14.  *    Columbia, MO 65203
  15.  *
  16.  *
  17.  *    c-tree(R)    Version 4.3
  18.  *            Release C
  19.  *            February 7, 1989 17:30
  20.  *
  21.  */
  22.  
  23. #include "ctstdr.h"        /* standard i/o header         */
  24. #include "ctoptn.h"        /* c-tree configuration options */
  25. #include "cterrc.h"        /* c-tree error codes        */
  26. #include "ctstrc.h"        /* c-tree data structures    */
  27. #include "ctgvar.h"        /* c-tree global variables    */
  28. #include "ctisam.h"        /* c-tree isam header        */
  29. #ifdef VARLDATA
  30. #include "ctvrec.h"
  31. #endif
  32.  
  33. #define SEQNXT    1
  34. #define SEQPRV    2
  35.  
  36. POINTER  NEWREC(),EQLKEY(),GTEKEY(),NXTKEY(),PRVKEY(),FRSKEY();
  37. POINTER  LSTKEY(),GTKEY(),LTKEY(),LTEKEY();
  38. COUNT    compar();
  39. COUNT    REDREC(),WRTREC(),RETREC(),frmkey();
  40. COUNT    ierr(),addlok(),addikey(),rwtikey(),delikey();
  41. CTFILE  *tstfnm();
  42. COUNT     ctio();
  43. VOID     iundo();
  44. #ifdef VARLDATA
  45. COUNT    getvhdr();
  46. LOCAL VHDR vrhdr;
  47. #endif
  48.  
  49. #ifdef CTSERVER
  50. COUNT           MLTWRT();
  51. EXTERN UCOUNT  cts_mxaln,cts_clen;
  52. EXTERN COUNT   cts_ctry,cts_csuc,cts_cdat,cts_cseq;
  53. EXTERN TEXT   *cts_cptr;
  54.  
  55. cmbchk(keyno,recptr)
  56. COUNT  keyno;
  57. TEXT        *recptr;
  58. {
  59.     FAST CTFILE *knum,*dnum;
  60.  
  61.     cts_ctry = cts_csuc = cts_cseq = NO;
  62.     if ((knum = tstfnm(keyno)) == NULL || (dnum = tstfnm(ct_rvmap[keyno])) ==
  63.         NULL)
  64.         return;
  65.     if ((knum->length + dnum->reclen) <= cts_mxaln) {
  66.         cts_cptr = recptr;
  67.         cts_clen = dnum->reclen;
  68.         cts_ctry = CMBREDWO;
  69.         cts_cdat = ct_rvmap[keyno];
  70.         if (ct_ismlk == ENABLE)
  71.             cts_ctry = CMBREDLK;
  72.         else if (ct_ismlk == READREC)
  73.             cts_ctry = CMBREDLK + 1;
  74.     }
  75. }
  76. #endif
  77.  
  78. LOCAL COUNT ismred(datno,keyno,pntr,recptr)
  79. COUNT           datno,keyno;
  80. POINTER                   pntr;
  81. TEXT                   *recptr;
  82. {
  83. #ifdef CTSERVER
  84.     COUNT tmpsuc;
  85. #endif
  86.  
  87. #ifdef MUSTFRCE
  88.     TEXT  chkkey[MAXLEN];
  89.     COUNT i;
  90.  
  91.     ct_vfsg = NO;
  92. #endif
  93.  
  94. #ifdef CTSERVER
  95.     tmpsuc = cts_csuc;
  96.     cts_csuc = NO;
  97.     if (tmpsuc == NO) {
  98.         if (REDREC(datno,pntr,recptr))
  99.         return(ierr(uerr_cod,datno));
  100.     }
  101. #else
  102.     if (REDREC(datno,pntr,recptr))
  103.         return(ierr(uerr_cod,datno));
  104. #endif
  105.  
  106.     if (*recptr == DELFLG && (ct_key + datno)->clstyp == DAT_CLOSE)
  107. #ifndef MUSTFRCE
  108.         return(ierr(IRED_ERR,datno));
  109. #else
  110.         return(ierr(ITIM_ERR,datno));
  111.  
  112.     if (datno != keyno) {
  113.         if (ct_vfin[keyno] == YES)
  114.         ct_vfsg = keyno + 1;
  115.         else {
  116.         frmkey(keyno,recptr,chkkey,pntr);
  117.         if (compar(chkkey,ct_fndval,ct_key+keyno))
  118.             return(ierr(ITIM_ERR,datno));
  119.         }
  120.     }
  121.  
  122. #endif
  123.  
  124.     cur_recno[datno] = pntr;
  125.     cur_image[datno] = recptr;
  126.     return(ierr(NO_ERROR,0));
  127. }
  128.  
  129.  
  130. COUNT reset_cur(keyno,pntr,recptr)
  131. PFAST COUNT    keyno;
  132. POINTER              pntr;
  133. TEXT              *recptr;
  134. {
  135.     FAST COUNT datno;
  136.  
  137.     if (!pntr)
  138.         if (uerr_cod)
  139.             return(ierr(uerr_cod,keyno));
  140.         else
  141.             return(ierr(INOT_ERR,keyno)); /* target not found */
  142.  
  143.     datno = ct_rvmap[keyno];
  144.     if (addlok(pntr,datno))
  145.         return(isam_err);
  146.     else
  147.         return(ismred(datno,keyno,pntr,recptr));
  148. }
  149.  
  150. LOCAL COUNT reset_phy(ctnum,pntr,recptr,mode)
  151. CTFILE             *ctnum;
  152. POINTER                pntr;
  153. TEXT                *recptr;
  154. COUNT                    mode;
  155. {
  156.     POINTER bfpos;
  157.     COUNT    tstrec();
  158.  
  159.     isam_err = uerr_cod = NO_ERROR;
  160. #ifdef VARLDATA
  161.     if (ctnum->clstyp == VAT_CLOSE) {
  162.         while (getvhdr(ctnum,pntr,&vrhdr) == NO_ERROR &&
  163.             (vrhdr.recmrk == VDEL_FLAG || vrhdr.recmrk == VNOD_FLAG))
  164.             pntr += (vrhdr.trclen + SIZVHDR);
  165.         if (uerr_cod == NO_ERROR && vrhdr.recmrk != VACT_FLAG &&
  166.             tstrec(ctnum,pntr) == NO_ERROR)
  167.             uerr_cod = VFLG_ERR;
  168.     } else {
  169. #endif
  170.         if (mode == SEQPRV) {
  171.             bfpos = (ctnum->reclen + 127) / ctnum->reclen *
  172.                 ctnum->reclen;
  173.             if (pntr < bfpos)
  174.                 return(ierr(uerr_cod = LBOF_ERR,
  175.                     ctnum->filnum));
  176.         }
  177.         while (ctio(CTREAD,ctnum,pntr,ct_buf,1) == NO_ERROR &&
  178.             ct_buf[0] == DELFLG)
  179.             if (mode == SEQNXT) {
  180.                 if (tstrec(ctnum,(pntr += ctnum->reclen)))
  181.                     break;
  182.             } else {
  183.                 if ((pntr -= ctnum->reclen) < bfpos) {
  184.                     uerr_cod = LBOF_ERR;
  185.                     break;
  186.                 }
  187.             }
  188. #ifdef VARLDATA
  189.     }
  190. #endif
  191.  
  192.     if (uerr_cod)
  193.         return(ierr(uerr_cod,ctnum->filnum));
  194.     else if (addlok(pntr,ctnum->filnum ))
  195.         return(isam_err);
  196.     else
  197.         return(ismred(ctnum->filnum,ctnum->filnum,pntr,recptr));
  198. }
  199.  
  200. COUNT LKISAM(lokmod)
  201. COUNT         lokmod;
  202. {
  203.     FAST COUNT i;
  204.     FAST LOKS *lp;
  205.  
  206.     COUNT UDLOCK();
  207. #ifdef CTSERVER
  208.     VOID intlmsg(),addlmsg(),sndlmsg();
  209. #endif
  210.  
  211.     switch (lokmod) {
  212. case SUSPEND:
  213.         if (ct_ismlk == ENABLE || ct_ismlk == READREC)
  214.             ct_ismlk = SUSPEND;
  215.         break;
  216. case RESTORE:
  217.         if (ct_ismlk == SUSPEND)
  218.             ct_ismlk = ENABLE;
  219.         break;
  220. case RESTRED:
  221.         if (ct_ismlk == SUSPEND)
  222.             ct_ismlk = READREC;
  223.         break;
  224. case READREC:
  225.         if (ct_ismlk == ENABLE)
  226.             ct_ismlk = READREC;
  227.         break;
  228.     }
  229.     if (lokmod > ENABLE)
  230.         return(isam_err = NO_ERROR);
  231.  
  232. #ifdef CTSERVER
  233.     if (lokmod == FREE || lokmod == RESET)
  234.         intlmsg();
  235. #endif
  236.     for (i = 0, lp = ct_locks; i < MAX_LOCKS; i++,lp++)
  237.         if (lp->datfnm >= 0) {
  238.             if (lokmod == FREE || lokmod == RESET) {
  239. #ifdef CTSERVER
  240.                 addlmsg(lp->recnum,lp->datfnm);
  241. #else
  242.                 UDLOCK(lp->recnum,ct_key + lp->datfnm);
  243. #endif
  244.                 lp->datfnm = -1;
  245.             } else
  246.                 return(ierr(IPND_ERR,0));
  247.         }
  248. #ifdef CTSERVER
  249.         if (lokmod == FREE || lokmod == RESET)
  250.             sndlmsg();
  251. #endif
  252.     if (lokmod != RESET)
  253.         ct_ismlk = lokmod;
  254.     else
  255.         ct_ismlk = ENABLE;
  256.  
  257.     return(isam_err = NO_ERROR);
  258. }
  259.     
  260. COUNT ADDREC(datno,recptr)
  261. PFAST COUNT  datno;
  262. TEXT          *recptr;
  263. {
  264.     POINTER    pntr;
  265.     DATFILE   *dnum;
  266. #ifdef CTSERVER
  267.     COUNT         j;
  268. #endif
  269.  
  270.     isam_err = NO_ERROR;
  271.     if ((dnum = tstfnm(datno)) == NULL)
  272.         return(ierr(uerr_cod,datno));
  273.     else if (dnum->clstyp != DAT_CLOSE)
  274.         return(ierr(FMOD_ERR,datno));
  275. #ifdef CTSERVER
  276.     pntr   = DRNZERO;
  277.     ct_nwrcfg = YES;
  278.     j = MLTWRT(datno,&pntr,recptr,dnum->reclen,dnum->srlpos);
  279.     if (j == -2)
  280.         return(ierr(uerr_cod,0));
  281.     else if (j || addlok(pntr,datno)) {
  282.         ierr(uerr_cod,datno);
  283.         ct_nwrcfg = NO;
  284.         if (j != 1)
  285.             iundo(ISADD,datno,0,recptr,pntr,DRNZERO);
  286.         return(isam_err);
  287.     }
  288.         
  289. #else
  290.     else if ((pntr = NEWREC(datno)) == DRNZERO)
  291.         return(ierr(uerr_cod,datno));
  292.     setsrlpos(datno,recptr);
  293.  
  294.     ct_nwrcfg = YES;
  295.     if (addlok(pntr,datno))
  296.         return(isam_err);
  297.  
  298.     if (WRTREC(datno,pntr,recptr)) {
  299.         ierr(uerr_cod,datno);
  300.         iundo(ISADD,datno,0,recptr,pntr,DRNZERO);
  301.         return(isam_err);
  302.     }
  303. #endif
  304.  
  305.     if (addikey(datno,recptr,pntr))
  306.         return(isam_err);
  307.  
  308.     cur_recno[datno] = pntr;
  309.     cur_image[datno] = recptr;
  310. #ifdef DOSFLUSH
  311.     flushdos(datno);
  312. #endif
  313.     return(NO_ERROR);
  314. }
  315.  
  316. POINTER chkism(datno)
  317. COUNT datno;
  318.  
  319. {
  320.     DATFILE *dnum;
  321.     POINTER  pntr;
  322.  
  323.     isam_err = NO_ERROR;
  324.  
  325.     if ((dnum = tstfnm(datno)) == NULL)
  326.         ierr(uerr_cod,datno);
  327.     else if (dnum->clstyp != DAT_CLOSE)
  328.         ierr(FMOD_ERR,datno);
  329.     else if (!(pntr = cur_recno[datno]))
  330.         ierr(ICUR_ERR,datno);
  331.     else
  332.         addlok(pntr,datno);
  333.  
  334.     if (!isam_err)
  335.         return(pntr);
  336.     else
  337.         return(0);
  338. }
  339.     
  340.  
  341.  
  342. COUNT RWTREC(datno,recptr) /* assumes that current record for datno is old
  343.                   version to be rewritten by recptr */
  344. PFAST COUNT  datno;
  345. TEXT          *recptr;
  346. {
  347.     POINTER    pntr;
  348.     COUNT        i;
  349.  
  350.     if (!(pntr = chkism(datno)))
  351.         return(isam_err);
  352.  
  353.     if ((i = rwtikey(datno,recptr,pntr,pntr)) > 0)
  354.         return(isam_err);
  355.  
  356.     if (WRTREC(datno,pntr,recptr)) {
  357.         ierr(uerr_cod,datno);
  358.         iundo(ISRWT,datno,-i,recptr,pntr,pntr);
  359.         return(isam_err);
  360.     }
  361.  
  362.     cur_recno[datno] = pntr;
  363.     cur_image[datno] = recptr;
  364. #ifdef DOSFLUSH
  365.     flushdos(datno);
  366. #endif
  367.     return(NO_ERROR);
  368. }
  369.  
  370. COUNT DELREC(datno)
  371. PFAST COUNT  datno;
  372. {
  373.     TEXT      *recptr;
  374.     POINTER    pntr;
  375.     COUNT        i;
  376.  
  377.     if (!(pntr = chkism(datno)))
  378.         return(isam_err);
  379.  
  380.     recptr = cur_image[datno];
  381.  
  382.     if ((i = delikey(datno,recptr,pntr)) > 0)
  383.         return(isam_err);
  384.  
  385.     if (RETREC(datno,pntr)) {
  386.         ierr(uerr_cod,datno);
  387.         iundo(ISDEL,datno,-i,recptr,DRNZERO,pntr);
  388.         return(isam_err);
  389.     }
  390. #ifdef DOSFLUSH
  391.     flushdos(datno);
  392. #endif
  393.     return(NO_ERROR);
  394. }
  395.  
  396. COUNT EQLREC(keyno,target,recptr)
  397.  
  398. PFAST COUNT keyno;
  399. PFAST TEXT *target;
  400. PFAST TEXT *recptr;
  401.  
  402. {
  403. #ifdef MUSTFRCE
  404.     cpybuf(ct_fndval,target,(ct_key + keyno)->length);
  405. #endif
  406. #ifdef CTSERVER
  407.     cmbchk(keyno,recptr);
  408. #endif
  409.     return(reset_cur(keyno,EQLKEY(keyno,target),recptr));
  410. }
  411.  
  412. COUNT GTEREC(keyno,target,recptr)
  413.  
  414. PFAST COUNT keyno;
  415. PFAST TEXT *target;
  416. PFAST TEXT *recptr;
  417.  
  418. {
  419. #ifdef CTSERVER
  420.     cmbchk(keyno,recptr);
  421. #endif
  422.     return(reset_cur(keyno,GTEKEY(keyno,target,ct_fndval),recptr));
  423. }
  424.  
  425. COUNT LTEREC(keyno,target,recptr)
  426.  
  427. PFAST COUNT keyno;
  428. PFAST TEXT *target;
  429. PFAST TEXT *recptr;
  430.  
  431. {
  432. #ifdef CTSERVER
  433.     cmbchk(keyno,recptr);
  434. #endif
  435.     return(reset_cur(keyno,LTEKEY(keyno,target,ct_fndval),recptr));
  436. }
  437.  
  438. LOCAL COUNT seqrec(mode,filno,recptr)
  439. COUNT           mode,filno;
  440. TEXT                 *recptr;
  441. {
  442.     FAST COUNT   datno;
  443.     POINTER         pntr;
  444.     FAST CTFILE *ctnum;
  445.  
  446.     if ((ctnum = tstfnm(filno)) == NULL)
  447.         return(ierr(uerr_cod,filno));
  448.     if (ctnum->clstyp == IDX_CLOSE)
  449.         datno = ct_rvmap[filno];
  450.     else
  451.         datno = filno;
  452.     if (!(pntr = cur_recno[datno]))
  453.         return(ierr(ICUR_ERR,datno));
  454.  
  455.     if (ctnum->clstyp == IDX_CLOSE) {
  456.         if (frmkey(filno,cur_image[datno],ct_kyval,pntr)) {
  457. #ifdef CTSERVER
  458.         cmbchk(filno,recptr);
  459. #endif
  460.         if (mode == SEQNXT)
  461.             pntr = GTKEY(filno,ct_kyval,ct_fndval);
  462.         else
  463.             pntr = LTKEY(filno,ct_kyval,ct_fndval);
  464.         return(reset_cur(filno,pntr,recptr));
  465.         } else
  466.         return(ierr(INOT_ERR,filno));
  467.     } else if (ctnum->clstyp == DAT_CLOSE) {
  468.         if (mode == SEQNXT)
  469.         pntr += ctnum->reclen;
  470.         else
  471.         pntr -= ctnum->reclen;
  472. #ifdef VARLDATA
  473.     } else {
  474.         if (mode != SEQNXT)
  475.             return(ierr(uerr_cod = FMOD_ERR,filno));
  476.         if (getvhdr(ctnum,pntr,&vrhdr))
  477.             return(ierr(uerr_cod,filno));
  478.         pntr += (vrhdr.trclen + SIZVHDR);
  479.     }
  480. #else
  481.     }
  482. #endif
  483.     datno = reset_phy(ctnum,pntr,recptr,mode);
  484.     if (datno == LEOF_ERR || datno == LBOF_ERR || datno == READ_ERR)
  485.         isam_err = INOT_ERR;
  486.     return(isam_err);
  487. }
  488.  
  489. COUNT NXTREC(filno,recptr)
  490. COUNT         filno;
  491. TEXT           *recptr;
  492. {
  493.     return(seqrec(SEQNXT,filno,recptr));
  494. }
  495.  
  496. COUNT PRVREC(filno,recptr)
  497. PFAST COUNT  filno;
  498. TEXT          *recptr;
  499. {
  500.     return(seqrec(SEQPRV,filno,recptr));
  501. }
  502.  
  503. LOCAL COUNT bndrec(mode,filno,recptr)
  504. COUNT           mode,filno;
  505. PFAST TEXT             *recptr;
  506. {
  507.     FAST CTFILE *ctnum;
  508.     POINTER      recbyt;
  509. #ifdef MUSTFRCE
  510.     COUNT         tstrec();
  511. #endif
  512.  
  513.     if ((ctnum = tstfnm(filno)) == NULL)
  514.         return(ierr(uerr_cod,filno));
  515.     if (ctnum->clstyp == IDX_CLOSE) {
  516. #ifdef CTSERVER
  517.         cmbchk(filno,recptr);
  518. #endif
  519.         if (mode == SEQNXT)
  520.             recbyt = FRSKEY(filno,ct_fndval);
  521.         else
  522.             recbyt = LSTKEY(filno,ct_fndval);
  523.         return(reset_cur(filno,recbyt,recptr));
  524.     } else if (ctnum->clstyp == DAT_CLOSE) {
  525.         if (mode == SEQNXT)
  526.             recbyt = (ctnum->reclen + 127) / ctnum->reclen *
  527.             ctnum->reclen;
  528.         else {
  529. #ifdef MUSTFRCE
  530.             if (tstrec(ctnum,ctnum->numrec + 1L) &&
  531.             uerr_cod != LEOF_ERR)
  532.                 return(ierr(uerr_cod,filno));
  533. #endif
  534.             recbyt = ctnum->numrec + 1L - ctnum->reclen;
  535.         }
  536.     }
  537. #ifdef VARLDATA
  538.     else {
  539.         if (mode == SEQNXT)
  540.             recbyt = ctnum->recsiz + SIZVHDR;
  541.         else
  542.             return(ierr(uerr_cod = FMOD_ERR,filno));
  543.     }
  544. #endif
  545.     filno = reset_phy(ctnum,recbyt,recptr,mode);
  546.     if (filno == LEOF_ERR || filno == LBOF_ERR || filno == READ_ERR)
  547.         isam_err = INOT_ERR;
  548.     return(isam_err);
  549. }
  550.  
  551. COUNT FRSREC(filno,recptr)
  552. PFAST COUNT  filno;
  553. PFAST TEXT      *recptr;
  554. {
  555.     return(bndrec(SEQNXT,filno,recptr));
  556. }
  557.  
  558. COUNT LSTREC(filno,recptr)
  559. PFAST COUNT  filno;
  560. TEXT       *recptr;
  561. {
  562.     return(bndrec(SEQPRV,filno,recptr));
  563. }
  564.  
  565. RRDREC(datno,recptr)
  566. PFAST COUNT  datno;
  567. TEXT        *recptr;
  568. {
  569.     isam_err = 0;
  570.     if (cur_recno[datno] == DRNZERO)
  571.         return(ierr(ICUR_ERR,datno));
  572.     else if (addlok(cur_recno[datno],datno))
  573.         return(isam_err);
  574.     else
  575.         return(ismred(datno,datno,cur_recno[datno],recptr));
  576. }
  577.  
  578. /* end of ctisam.c */
  579.