home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 125.img / PRO-C4.ZIP / BENCH1.ZIP / BENCH / IASCII.C < prev    next >
C/C++ Source or Header  |  1990-05-28  |  21KB  |  830 lines

  1. /* ==( io/src/iascii.c )== */
  2.  
  3. /* ----------------------------------------------- */
  4. /* Pro-C  Copyright (C) 1988 - 1990 Vestronix Inc. */
  5. /* Modification to this source is not supported    */
  6. /* by Vestronix Inc.                               */
  7. /*            All Rights Reserved                  */
  8. /* ----------------------------------------------- */
  9. /* Written   NA   24-Feb-88                        */
  10. /* Modified  VvA  28-Mar-90  See comments below    */
  11. /* ----------------------------------------------- */
  12. /* %W%  (%H% %T%) */
  13.  
  14. /*
  15.  *  Modifications
  16.  *
  17.  *  28-Mar-90  VvA - adjustments for locking modes, transactions
  18.  *  06-Feb-90  VvA - return IOEOF in lastkey for autonum
  19.  *  02-Feb-90  VvA - adjust return vals in lastkey
  20.  *  01-Feb-90  VvA - Enabled openmode in open_file()
  21.  *  12-Dec-89  Geo - V2 version with variable lines
  22.  *  25-Oct-89  Geo - 1.32 Merge
  23.  *   3-Aug-89  VvA - Modified for generic IO interface
  24.  *  26-Jul-89  BF/BC - Patched (by the terrible twosome)
  25.  *  23-Mar-88  Geo - Rejigged, code shrunk (yes it was)
  26. */
  27.  
  28. /*
  29.  *  -- D R A F T --  ASCII Sequential I/O via general IOGEN.C interface 
  30.  * WARNING Brian C reckons this is incorrect 13-Dec-89
  31. */
  32.  
  33. /*
  34.  *  This module handles the interface between the i/o calls from within
  35.  *  PRO-C and an ASCII file with fixed length records, but varying length
  36.  *  fields within the records
  37. */
  38.  
  39. # include <iodef.h>
  40. # include <iomsg.h>
  41. # include <proc.io>
  42. # include <bench.h>
  43. # include <iosup.h>
  44.  
  45. /* Open control (Geo will correct this into o_open & o_creat 13-Dec-89) */
  46. # ifndef QNX
  47. #include <fileio.h>
  48. # endif
  49.  
  50. #ifdef QNX
  51. #include <file_io.h>
  52. #define  OPN_FILE(fname)    sopen(fname, O_BINARY | O_RDWR | O_CACHE, SH_DENYNO )
  53. #define  CRT_FILE(fname)    sopen(fname, O_CREAT  | O_BINARY | O_RDWR | O_CACHE, SH_DENYNO, S_IREAD | S_IWRITE)
  54. #endif
  55.  
  56. #ifdef MSC
  57. #define  OPN_FILE(fname)    open(fname, O_BINARY | O_RDWR )
  58. #define  CRT_FILE(fname)    open(fname, O_CREAT  | O_BINARY | O_RDWR, S_IREAD | S_IWRITE)
  59. #endif
  60.  
  61. #ifdef PC
  62. #include <fcntl.h>
  63. #include <sys\types.h>
  64. #include <sys\stat.h>
  65.  
  66. #define  OPN_FILE(fname)    open(fname, O_BINARY | O_RDWR )
  67. #define  CRT_FILE(fname)    open(fname, O_CREAT  | O_BINARY | O_RDWR, S_IREAD | S_IWRITE)
  68. #endif
  69.  
  70. #ifdef __TURBOC__
  71. #include <fcntl.h>
  72. #include <sys/stat.h>
  73.  
  74. #define  OPN_FILE(fname)    open(fname, O_RDWR | O_BINARY)
  75. #define  CRT_FILE(fname)    open(fname, O_CREAT |  O_RDWR | O_BINARY, S_IREAD | S_IWRITE)
  76. #endif
  77.  
  78. #ifdef __WATCOMC__
  79. #include <fcntl.h>
  80. #include <io.h>
  81. #include <sys\types.h>
  82. #include <sys\stat.h>
  83. #include <stdlib.h>
  84.  
  85. #define  OPN_FILE(fname)    open(fname, O_BINARY | O_RDWR , S_IREAD | S_IWRITE)
  86. #define  CRT_FILE(fname)    open(fname, O_CREAT  | O_BINARY | O_RDWR, S_IREAD | S_IWRITE)
  87. #endif
  88.  
  89. #ifdef LC
  90. #include <fcntl.h>
  91.  
  92. #define  OPN_FILE(fname)    open(fname, O_RAW | O_RDWR)
  93. #define  CRT_FILE(fname)    open(fname, O_CREAT | O_RAW | O_RDWR)
  94. #endif
  95.  
  96. #ifdef __ZTC__
  97. #include <io.h>
  98. #include <dos.h>
  99. #include <sys\stat.h>
  100. #include <stdlib.h>
  101.  
  102. #define  OPN_FILE(fname)    open(fname, O_RDWR)
  103. #define  CRT_FILE(fname)    creat(fname, S_IREAD | S_IWRITE)
  104. #endif
  105.  
  106. #ifdef DC
  107. #include <dos.h>
  108.  
  109. #define  OPN_FILE(fname)    open(fname, O_RDWR)
  110. #define  CRT_FILE(fname)    creat(fname, 2)
  111. #endif
  112.  
  113. # ifdef UNIX
  114. # define OPN_FILE(fname) open(fname, O_RDWR)
  115. # define CRT_FILE(fname) open(fname, O_RDWR | O_CREAT | O_TRUNC, 0666)
  116. # endif
  117.  
  118. # ifndef USELOCK
  119. /*# define USELOCK*/  /* Dummy out this if no locking */
  120. # endif
  121.  
  122. /* Function prototypes */
  123. # ifdef ANSI
  124. static int isdeleted(char *, int);
  125. static int i_addrec(int, char *);
  126. static int i_close_file(int, char *);
  127. static int i_commit(int, char *);
  128. static int i_delrec(int, char *);
  129. static int i_filename(int, char *);
  130. static int i_findkey(int, char *);
  131. static int i_firstkey(int, char *);
  132. static int i_init_file(int, char *);
  133. static int i_lastkey(int, char *);
  134. static int i_lockrec(int, char *);
  135. static int i_login(int, char *);
  136. static int i_logoff(int, char *);
  137. static int i_nextrec(int, char *);
  138. static int i_open_file(int, char *);
  139. static int i_prevrec(int, char *);
  140. static int i_rereadrec(int, char *);
  141. static int i_rollback(int, char *);
  142. static int i_selectinx(int, char *);
  143. static int i_transact(int, char *);
  144. static int i_unlock_rec(int, char *);
  145. static int i_updrec(int, char *);
  146. static int read_rec(int, char *);
  147. static int write_rec(int, char *);
  148. static void checkopen(int);
  149. # else
  150. static int isdeleted();
  151. static int i_addrec();
  152. static int i_close_file();
  153. static int i_commit();
  154. static int i_delrec();
  155. static int i_filename();
  156. static int i_findkey();
  157. static int i_firstkey();
  158. static int i_init_file();
  159. static int i_lastkey();
  160. static int i_lockrec();
  161. static int i_login();
  162. static int i_logoff();
  163. static int i_nextrec();
  164. static int i_open_file();
  165. static int i_prevrec();
  166. static int i_rereadrec();
  167. static int i_rollback();
  168. static int i_selectinx();
  169. static int i_transact();
  170. static int i_unlock_rec();
  171. static int i_updrec();
  172. static int read_rec();
  173. static int write_rec();
  174. static void checkopen();
  175. # endif
  176.  
  177. /* EXTERNs */
  178. extern long lseek();
  179. extern char *alloc();
  180.  
  181. extern struct fd_def fd[]; /* iogen.c */
  182.  
  183. /*
  184.  *  Plus any externs required by the file manager for error codes etc.
  185. */
  186.  
  187. /* structure for ASCII file specific values */
  188. struct asc_def
  189. {
  190.    long offset;     /* Current offset into file for Read/Write */
  191.    int nextrec;     /* Next Record to Read */
  192.    char *localbuf;  /* Local Record Buffer for Read/Write */
  193.    int max_f;       /* Number of fields in Record */
  194.    int f_idx[128];  /* Offset of All Fields into Record. Sequential */
  195.    int f_len[128];  /* Length of All Fields in Record. Sequential */
  196.    int locked;
  197.    long lockoff;
  198. };
  199.  
  200. static struct asc_def afd[MAX_FILES];
  201.  
  202. /*
  203. static FILE *fdbg = NULL;
  204. */
  205.  
  206. /*
  207.  *
  208.  * Interface Functions
  209.  *
  210. */
  211.  
  212.  
  213. /*
  214.  *  Sets up File Name extension - dummy function here
  215. */
  216. static int i_filename(fd_sys, buffer)
  217. int fd_sys;
  218. char *buffer;
  219. {
  220.    return(IOGOOD);
  221. }
  222.  
  223. /*
  224.  *  File initialization - all descriptors start out as -1
  225. */
  226. static int i_init_file(fd_sys, buffer)
  227. int fd_sys;
  228. char *buffer;
  229. {
  230.    int n;
  231.  
  232.    for (n = 0; n < MAX_FILES; n++)      /* initialize all descriptors to -1 */
  233.       fd[n].fd_num = -1;
  234.       
  235.    return(IOGOOD);
  236. }
  237.  
  238. /*
  239.  *  File open function - required parameters are in fd structure
  240. */
  241. static int i_open_file(fd_sys, buffer)
  242. int fd_sys;
  243. char *buffer;
  244. {
  245.    int fds;
  246.    struct fd_def *fptr = &fd[fd_sys];
  247.    struct asc_def *aptr = &afd[fd_sys];
  248.  
  249. /*
  250.  * If the desired mode is OUTPUT, then delete any existing files.
  251. */
  252.    if (fptr->openmode & OUTPUT_FLAG)
  253.       unlink(fptr->filname);
  254.  
  255.    if ((fds = OPN_FILE(fptr->filname)) < 0)
  256.       fds = CRT_FILE(fptr->filname);
  257.  
  258.    if (fds < 0)                                 /* failed to open or create */
  259.    {
  260.       errmsg(FileNotFound_s, fptr->filname);
  261.       return(IOERROR);
  262.    }
  263.  
  264.    fptr->fd_num = fds;
  265.    aptr->localbuf = alloc(fptr->rec_len);
  266.    aptr->nextrec = -1;
  267.    aptr->locked = 0;
  268.    aptr->lockoff = 0L;
  269.  
  270.    return(IOGOOD);
  271. }
  272.  
  273.  
  274. /*
  275.  *  File close function
  276. */
  277. static int i_close_file(fd_sys, buffer)
  278. int fd_sys;
  279. char *buffer;
  280. {
  281.    close(fd[fd_sys].fd_num);
  282.    fd[fd_sys].fd_num = -1;
  283.    return(IOGOOD);
  284. }
  285.  
  286. /*
  287.  *  Select an index to perform processing on - done in IOGEN.C
  288. */
  289. static int i_selectinx(fd_sys, buffer)
  290. int fd_sys;
  291. char *buffer;
  292. {
  293.    return(IOGOOD);
  294. }
  295.  
  296. /*
  297.  *  Check and error message for unassigned descriptors
  298. */
  299.  
  300. static void checkopen(fd_sys)
  301. int fd_sys;
  302. {
  303.    if (fd[fd_sys].fd_num < 0)
  304.       abort_mess("Invalid file descriptor in GET_REC");
  305. }
  306.  
  307. /*
  308.  *  Find a record by key value
  309.  *  - For partial match, the first record GTE than given key will be returned.
  310. */
  311. static int i_findkey(fd_sys, buffer)
  312. int fd_sys;
  313. char *buffer;
  314. {
  315.    int ilen, olen, klen, ktype;
  316.    char *src, *key;
  317.    struct fd_def *fptr = &fd[fd_sys];
  318.    struct asc_def *aptr = &afd[fd_sys];
  319.    struct keyinfo *kptr = &fd[fd_sys].keys[fd[fd_sys].cur_key];
  320.  
  321.    checkopen(fd_sys);
  322.  
  323.    if (lseek(fptr->fd_num, 0L, FDIR_BEGIN) < 0L)
  324.       return(IONOKEY);
  325.  
  326.    klen  = kptr->seglen[0];                              /* key information */
  327.    ktype = fptr->flds[kptr->fldindex[0]].fldtype;
  328.    key   = buffer + kptr->segstart[0];
  329.    src   = aptr->localbuf + kptr->segstart[0];
  330.    ilen  = (ktype == CHRTYP) ? fstrlen(key, klen) : klen;
  331.  
  332.    aptr->nextrec = 0;
  333.  
  334.    for (;;)
  335.    {
  336.       if (read_rec(fd_sys, aptr->localbuf) != IOGOOD)
  337.          return(IONOKEY);
  338.  
  339.       aptr->nextrec++;
  340.  
  341.       if (fptr->exact)            /* compare field length and match the key */
  342.       {
  343.          olen = (ktype == CHRTYP) ? fstrlen(src, klen) : klen;
  344.          if ((ilen == olen) && !memcmp(key, src, olen))
  345.             break;                    /* found one... lengths and key match */
  346.       }
  347.       else      /* partial match only, return first record that is GTE keys */
  348.       {
  349.          if (ktype == CHRTYP && memcmp(key, src, ilen) <= 0)
  350.             break;
  351.          else if (ktype == INTTYP && *(int *)key <= *(int *)src)
  352.             break;
  353.          else if (ktype == LNGTYP && *(long *)key <= *(long *)src)
  354.             break;
  355.          else if (ktype == FLTTYP && *(float *)key <= *(float *)src)
  356.             break;
  357.          else if (ktype == DBLTYP && *(double *)key <= *(double *)src)
  358.             break;
  359.       }
  360.    }
  361.  
  362.    aptr->offset = (long) fptr->rec_len * (long) (aptr->nextrec - 1);
  363.    if (i_lockrec(fd_sys, buffer) != IOGOOD)
  364.       return(IOLOCKED);
  365.  
  366.    bytecpy(buffer, aptr->localbuf, fptr->rec_len);   /* copy to real buffer */
  367.  
  368.    return(IOGOOD);
  369. }
  370.  
  371. /*
  372.  *  Find first record in the file - first physical record for ASCII file
  373. */
  374. static int i_firstkey(fd_sys, buffer)
  375. int fd_sys;
  376. char *buffer;
  377. {
  378.    int stat;
  379.    struct fd_def *fptr = &fd[fd_sys];
  380.    struct asc_def *aptr = &afd[fd_sys];
  381.  
  382.    checkopen(fd_sys);
  383.  
  384.    if (lseek(fptr->fd_num, 0L, FDIR_BEGIN) < 0L)
  385.       return(IOERROR);
  386.    if ((stat = read_rec(fd_sys, aptr->localbuf)) != IOGOOD)
  387.       return(stat);                    /* allows return of IOEOF for ELEMOD */
  388.    if (isdeleted(aptr->localbuf, fptr->rec_len) == TRUE)     /* rec deleted */
  389.    {
  390.       aptr->nextrec = 1;
  391.       return(i_nextrec(fd_sys, buffer));
  392.    }
  393.    if (i_lockrec(fd_sys, buffer) != IOGOOD)
  394.       return(IOLOCKED);
  395.  
  396.    bytecpy(buffer, aptr->localbuf, fptr->rec_len);   /* copy to real buffer */
  397.    aptr->nextrec = 1;
  398.    return(IOGOOD);
  399. }
  400.  
  401. /*
  402.  *  Find last physical record in the file
  403. */
  404. static int i_lastkey(fd_sys, buffer)
  405. int fd_sys;
  406. char *buffer;
  407. {
  408.     int stat;
  409.     struct fd_def *fptr = &fd[fd_sys];
  410.     struct asc_def *aptr = &afd[fd_sys];
  411.  
  412.     checkopen(fd_sys);
  413.  
  414.     if ((aptr->offset = lseek(fptr->fd_num, 0L, FDIR_EOF)) <= 0L)
  415.          return(IOEOF);
  416.       
  417.     do                                 /* skip back past any deleted records */
  418.     {
  419.         aptr->offset -= (long)fptr->rec_len;           /* one record previous */
  420.         if (lseek(fptr->fd_num, aptr->offset, FDIR_BEGIN) < 0L)
  421.             return(IOEOF);                           /* reqd for autonumbering */
  422.         if ((stat = read_rec(fd_sys, aptr->localbuf)) != IOGOOD)
  423.             return(stat);
  424.     }
  425.     while(isdeleted(aptr->localbuf, fptr->rec_len) == TRUE);
  426.  
  427.     if (i_lockrec(fd_sys, buffer) != IOGOOD)
  428.         return(IOLOCKED);
  429.  
  430.     bytecpy(buffer, aptr->localbuf, fptr->rec_len);   /* copy to real buffer */
  431.     aptr->nextrec = 1;
  432.     return(IOGOOD);
  433. }
  434.  
  435. /*
  436.  *  Find next record in the file
  437.  *  - Although IOGEN does checking for duplicate key records in an EXACT 
  438.  *    search, ASCII sequential files are not indexed; thus this function
  439.  *    will continue traversing the file to find all occurrences matching
  440.  *    the original exact-matched key.
  441. */
  442. static int i_nextrec(fd_sys, buffer)
  443. int fd_sys;
  444. char *buffer;
  445. {
  446.    int ilen, olen, klen, ktype;
  447.    long iosignal;
  448.    char *src, *key;
  449.    struct fd_def *fptr = &fd[fd_sys];
  450.    struct asc_def *aptr = &afd[fd_sys];
  451.    struct keyinfo *kptr = &fd[fd_sys].keys[fd[fd_sys].cur_key];
  452.  
  453.    checkopen(fd_sys);
  454.  
  455.    if (fptr->exact)                                  /* get key information */
  456.    {
  457.       klen  = kptr->seglen[0];
  458.       ktype = fptr->flds[kptr->fldindex[0]].fldtype;
  459.       key   = buffer + kptr->segstart[0];
  460.       src   = aptr->localbuf + kptr->segstart[0];
  461.       ilen  = (ktype == CHRTYP) ? fstrlen(key, klen) : klen;
  462.    }
  463.  
  464.    do
  465.    {
  466.       aptr->offset = (long) aptr->nextrec * (long) fptr->rec_len;
  467.  
  468.       iosignal  = lseek(fptr->fd_num, aptr->offset, FDIR_BEGIN);
  469.       if(iosignal < 0L)
  470.          return(IOEOF);
  471.  
  472.       if (!fptr->exact)
  473.       {
  474.          if(read_rec(fd_sys, aptr->localbuf) != IOGOOD)
  475.             return(IOEOF);
  476.          aptr->nextrec++;
  477.       }
  478.       else                      /* following exact match, retry exact match */
  479.       {
  480.          do
  481.          {
  482.             if (read_rec(fd_sys, aptr->localbuf) != IOGOOD)
  483.                return(IOEOF);
  484.             olen = (ktype == CHRTYP) ? fstrlen(src, klen) : klen;
  485.             aptr->nextrec++;
  486.          }
  487.          while(ilen != olen || memcmp(key, src, olen) != 0);
  488.       }
  489.    }
  490.    while(isdeleted(aptr->localbuf, fptr->rec_len) == TRUE);  /* rec deleted */
  491.  
  492.    if(i_lockrec(fd_sys, buffer) != IOGOOD)
  493.       return(IOLOCKED);
  494.  
  495.    bytecpy(buffer, aptr->localbuf, fptr->rec_len);   /* copy to real buffer */
  496.  
  497.    return(IOGOOD);
  498. }
  499.  
  500. /*****************************************************************************
  501.  *  Find previous record in the file
  502.  *  - No checks are done at this level (as for nextrec) for exact key match.
  503. */
  504. static int i_prevrec(fd_sys, buffer)
  505. int fd_sys;
  506. char *buffer;
  507. {
  508.    struct fd_def *fptr = &fd[fd_sys];
  509.    struct asc_def *aptr = &afd[fd_sys];
  510.  
  511.    checkopen(fd_sys);
  512.  
  513.    do
  514.    {
  515.       aptr->nextrec -= 2;
  516.  
  517.       aptr->offset = (long) aptr->nextrec * (long) fptr->rec_len;
  518.       if (lseek(fptr->fd_num, aptr->offset, FDIR_BEGIN) < 0L)
  519.       {
  520.          aptr->nextrec = 1;
  521.          return(IOTOF);
  522.       }
  523.  
  524.       if (read_rec(fd_sys, aptr->localbuf) != IOGOOD)
  525.       {
  526.          aptr->nextrec = 1;
  527.          return(IOTOF);
  528.       }
  529.  
  530.       aptr->nextrec++;
  531.    }
  532.    while(isdeleted(aptr->localbuf, fptr->rec_len) == TRUE);  /* deleted rec */
  533.  
  534.    if(i_lockrec(fd_sys, buffer) != IOGOOD)
  535.       return(IOLOCKED);
  536.  
  537.    bytecpy(buffer, aptr->localbuf, fptr->rec_len);   /* copy to real buffer */
  538.  
  539.    return(IOGOOD);
  540. }
  541.  
  542. /*
  543.  *  re-read/reposition record pointer function - dummy function here
  544. */
  545. static int i_rereadrec(fd_sys, buffer)
  546. int fd_sys;
  547. char *buffer;
  548. {
  549.    return(IOGOOD);
  550. }
  551.  
  552. /*
  553.  *  Read a record from ASCII sequential file
  554. */
  555. static int read_rec(fd_sys, buffer)
  556. int fd_sys;
  557. char *buffer;
  558. {
  559.     int stat;
  560.     struct fd_def *fptr = &fd[fd_sys];
  561.  
  562.     stat = read(fptr->fd_num, buffer, fptr->rec_len);
  563.     if (stat < 0)
  564.         return(IOERROR);
  565.        else if (stat != fptr->rec_len)
  566.         return(IOEOF);
  567.     return(IOGOOD);
  568. }
  569.  
  570. /*
  571.  *  Write a record to ASCII sequential file
  572. */
  573. static int write_rec(fd_sys, buffer)
  574. int fd_sys;
  575. char *buffer;
  576. {
  577.    int stat;
  578.    struct fd_def *fptr = &fd[fd_sys];
  579.  
  580.    stat = write(fptr->fd_num, buffer, fptr->rec_len);
  581.    if (stat != fptr->rec_len)
  582.       return(IOERROR);
  583.    return(IOGOOD);
  584. }
  585.  
  586. /*
  587.  *  Check for deleted records in ASCII sequential file
  588. */
  589. static int isdeleted(pp, plen)
  590. char *pp;
  591. int plen;
  592. {
  593.    int i;
  594.  
  595.    for (i = 0; i < plen; i++, pp++)
  596.       if(*pp != '\0')
  597.          break;
  598.  
  599.    if (i == plen)
  600.       return(TRUE);
  601.    return(FALSE);
  602. }
  603.  
  604.  
  605. /*
  606.  *  Record add function
  607. */
  608. static int i_addrec(fd_sys, buffer)
  609. int fd_sys;
  610. char *buffer;
  611. {
  612.    do
  613.    {
  614.       afd[fd_sys].offset = lseek(fd[fd_sys].fd_num, 0L, FDIR_EOF);
  615.    }
  616.    while(i_lockrec(fd_sys, buffer) == IOLOCKED);
  617.  
  618.    return(write_rec(fd_sys, buffer));
  619. }
  620.  
  621. /*
  622.  *  Record update function
  623. */
  624. static int i_updrec(fd_sys, buffer)
  625. int fd_sys;
  626. char *buffer;
  627. {
  628.    struct fd_def *fptr = &fd[fd_sys];
  629.    struct asc_def *aptr = &afd[fd_sys];
  630.    int iosignal;
  631.  
  632.    aptr->nextrec--;
  633.    aptr->offset = (long) aptr->nextrec * (long) fptr->rec_len;
  634.    lseek(fptr->fd_num, aptr->offset, FDIR_BEGIN);
  635.  
  636.    iosignal = write_rec(fd_sys, buffer);
  637.    aptr->nextrec++;
  638.  
  639.    return(iosignal);
  640. }
  641.  
  642. /*
  643.  *  Record delete function
  644.  *  - deleted records are not removed from the file, but simply zeroed out
  645. */
  646. static int i_delrec(fd_sys, buffer)
  647. int fd_sys;
  648. char *buffer;
  649. {
  650.    int iosignal;
  651.    struct fd_def *fptr = &fd[fd_sys];
  652.    struct asc_def *aptr = &afd[fd_sys];
  653.  
  654.    zerorec(aptr->localbuf, fptr->rec_len);
  655.  
  656.    aptr->nextrec--;
  657.    aptr->offset = (long) aptr->nextrec * (long) fptr->rec_len;
  658.    lseek(fptr->fd_num, aptr->offset, FDIR_BEGIN);
  659.  
  660.    iosignal = write_rec(fd_sys, aptr->localbuf);
  661.    aptr->nextrec++;                          /* Always point to next record */
  662.  
  663.    return(iosignal);
  664. }
  665.  
  666. /*
  667.  *  Lock Record
  668. */  
  669. static int i_lockrec(fd_sys, buffer)
  670. int fd_sys;
  671. char *buffer;
  672. {
  673.    long iosignal;
  674.    struct fd_def *fptr = &fd[fd_sys];
  675.    struct asc_def *aptr = &afd[fd_sys];
  676.  
  677.    if (fptr->lockmode == NOLOCK)
  678.       return(IOGOOD);
  679.  
  680. /*
  681.    if (fdbg == NULL)
  682.       fdbg = fopen("lok.log", "w");
  683.    fprintf(fdbg, "  LOCK - %ld\n", aptr->offset);
  684. */
  685.  
  686. # ifdef USELOCK
  687.  
  688.    if (aptr->locked == 1)
  689.       i_unlock_rec(fd_sys, buffer);
  690.    iosignal = lseek(fptr->fd_num, aptr->offset, FDIR_BEGIN);
  691.    if(iosignal < 0L)                              /* this should not happen */
  692.       return(IOLOCKED);
  693.    if (lockf(fptr->fd_num, F_TEST, (long) fptr->rec_len) != 0)
  694.       return(IOLOCKED);
  695.  
  696. /*
  697.  * Now Re-Lock the same area with just read locks.
  698.  * If we don't do this, then the read() called in read_rec() to get
  699.  * the next record will sleep, but we want it to be able to read.
  700.  * The lock above is responsible for catching any locked regions.
  701.  * Re-locking below means that all records in the file can be read ok
  702.  * but the above locking() call will find the record is locked.
  703. */
  704.  
  705.    iosignal = lseek(fptr->fd_num, aptr->offset, FDIR_BEGIN);
  706.    if (lockf(fptr->fd_num, F_LOCK, (long) fptr->rec_len) != 0)
  707.       return(IOLOCKED);
  708.    aptr->locked = 1;
  709.    aptr->lockoff = aptr->offset;
  710.  
  711. # endif /* USELOCK */
  712.  
  713.    return(IOGOOD);
  714. }
  715.  
  716. /*
  717.  *  Unlock Record
  718. */
  719. static int i_unlock_rec(fd_sys, buffer)
  720. int fd_sys;
  721. char *buffer;
  722. {
  723.    struct fd_def *fptr = &fd[fd_sys];
  724.    struct asc_def *aptr = &afd[fd_sys];
  725.  
  726.    if (fptr->lockmode == NOLOCK)
  727.       return(IOGOOD);
  728.  
  729. /*
  730.    if (fdbg == NULL)
  731.       fdbg = fopen("lok.log", "w");
  732.    fprintf(fdbg, "UNLOCK - %ld\n", aptr->lockoff);
  733. */
  734.  
  735. # ifdef USELOCK
  736.  
  737.    if (lseek(fptr->fd_num, aptr->lockoff, FDIR_BEGIN) < 0L)
  738.       return(IOLOCKED);
  739.    if (lockf(fptr->fd_num, F_ULOCK, (long) fptr->rec_len) < 0)
  740.       return(IOERROR);
  741.    aptr->locked = 0;
  742.    aptr->lockoff = 0L;
  743.  
  744. # endif /* USELOCK */
  745.  
  746.    return(IOGOOD);
  747. }
  748.  
  749. /*
  750.  *  Login - dummy call
  751. */
  752. static int i_login(fd_sys, buffer)
  753. int fd_sys;
  754. char *buffer;
  755. {
  756.    return(IOGOOD);
  757. }
  758.  
  759. /*
  760.  *  Logoff - dummy call 
  761. */
  762. static int i_logoff(fd_sys, buffer)
  763. int fd_sys;
  764. char *buffer;
  765. {
  766.    return(IOGOOD);
  767. }
  768.  
  769. /*
  770.  *  End (Commit) transaction 
  771. */
  772. static int i_commit(fd_sys, buffer)
  773. int fd_sys;
  774. char *buffer;
  775. {
  776.    return(IOGOOD);
  777. }
  778.  
  779. /*
  780.  *  Rollback transaction
  781. */
  782. static int i_rollback(fd_sys, buffer)
  783. int fd_sys;
  784. char *buffer;
  785. {
  786.    return(IOGOOD);
  787. }
  788.  
  789. /*
  790.  *  Start transaction
  791. */
  792. static int i_transact(fd_sys, buffer)
  793. int fd_sys;
  794. char *buffer;
  795. {
  796.    return(IOGOOD);
  797. }
  798.  
  799.  
  800. /*
  801.  * Assign section
  802. */
  803.  
  804. void assign_IO_AS(dbnum)
  805. int dbnum;
  806. {
  807.    Fntab[dbnum - 1][0]  = (int(*)())0; /* Empty */
  808.    Fntab[dbnum - 1][1]  = i_init_file;
  809.    Fntab[dbnum - 1][2]  = i_open_file;
  810.    Fntab[dbnum - 1][3]  = i_close_file;
  811.    Fntab[dbnum - 1][4]  = i_addrec;
  812.    Fntab[dbnum - 1][5]  = i_delrec;
  813.    Fntab[dbnum - 1][6]  = i_findkey;
  814.    Fntab[dbnum - 1][7]  = i_firstkey;
  815.    Fntab[dbnum - 1][8]  = i_lastkey;
  816.    Fntab[dbnum - 1][9]  = i_lockrec;
  817.    Fntab[dbnum - 1][10] = i_nextrec;
  818.    Fntab[dbnum - 1][11] = i_prevrec;
  819.    Fntab[dbnum - 1][12] = i_unlock_rec;
  820.    Fntab[dbnum - 1][13] = i_updrec;
  821.    Fntab[dbnum - 1][14] = i_commit;
  822.    Fntab[dbnum - 1][15] = i_login;
  823.    Fntab[dbnum - 1][16] = i_logoff;
  824.    Fntab[dbnum - 1][17] = i_rollback;
  825.    Fntab[dbnum - 1][18] = i_transact;
  826.    Fntab[dbnum - 1][19] = i_selectinx;
  827.    Fntab[dbnum - 1][20] = i_rereadrec;
  828.    Fntab[dbnum - 1][21] = i_filename;
  829. }
  830.