home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / PROCWRKB.ZIP / BENCH1.ZIP / BENCH / ICISAM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-07  |  19.8 KB  |  850 lines

  1. /* ==( io/src/icisam.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  25-Jun-90  See comments below    */
  11. /* ----------------------------------------------- */
  12. /* %W%  (%H% %T%) */
  13.  
  14. /*
  15.  *  Modifications
  16.  *
  17.  *  01-Aug-90  VvA - IONONEXT and EOF reseek adjustments
  18.  *  25-Jun-90  VvA - distinct type for long int dates
  19.  *  28-Mar-90  VvA - adjustments for locking modes, transactions
  20.  *  01-Feb-90  VvA - openmode enabled, some bug fixes
  21.  *  14-Dec-89  VvA - V.2 modifications
  22.  *  01-Aug-89  VvA - Modified for generic I/O interface
  23.  *  01-Sep-88  VvA - Numerical & segmented keys added
  24. */
  25.  
  26. /*  C-ISAM specific I/O calls via general IOGEN.C interface  */
  27.  
  28.  
  29. # include <stdio.h>
  30. # include <bench.h>
  31. # include <isam.h>
  32. # include <iodef.h>
  33. # include <iomsg.h>
  34. # include <proc.io>
  35. # include <iosup.h>
  36.  
  37. #define  ENOFILE  2      /* C-ISAM */
  38.  
  39.  
  40. /* C-ISAM prototypes */
  41. PROTO (double lddbl, (char *));
  42. PROTO (double ldfloat, (char *));
  43. PROTO (int isaddindex, (int, struct keydesc *));
  44. PROTO (int isbegin, (void));
  45. PROTO (int isbuild, (char *, int, struct keydesc *, int));
  46. PROTO (int isclose, (int));
  47. PROTO (int iscommit, (void));
  48. PROTO (int isdelcurr, (int));
  49. PROTO (int iserase, (char *));
  50. PROTO (int isflush, (int));
  51. PROTO (int isindexinfo, (int, struct keydesc *, int));
  52. PROTO (int islogclose, (void));
  53. PROTO (int islogopen, (char *));
  54. PROTO (int isopen, (char *, int));
  55. PROTO (int isread, (int, char *, int));
  56. PROTO (int isrelease, (int));
  57. PROTO (int isrewcurr, (int, char *));
  58. PROTO (int isrollback, (void));
  59. PROTO (int isstart, (int, struct keydesc *, int, char *, int));
  60. PROTO (int iswrcurr, (int, char *));
  61. PROTO (int ldchar, (char *, int, char *));
  62. PROTO (int stchar, (char *, char *, int));
  63. PROTO (int stdbl, (double, char *));
  64. PROTO (int stfloat, (float, char *));
  65. PROTO (int stlong, (long, char *));
  66. PROTO (long ldlong, (char *));
  67.  
  68. /* Function prototypes */
  69. static PROTO (int create_file, (int));
  70. static PROTO (int i_addrec, (int, char *));
  71. static PROTO (int i_close_file, (int, char *));
  72. static PROTO (int i_commit, (int, char *));
  73. static PROTO (int i_delrec, (int, char *));
  74. static PROTO (int i_filename, (int, char *));
  75. static PROTO (int i_findkey, (int, char *));
  76. static PROTO (int i_firstkey, (int, char *));
  77. static PROTO (int i_init_file, (int, char *));
  78. static PROTO (int i_lastkey, (int, char *));
  79. static PROTO (int i_lockrec, (int, char *));
  80. static PROTO (int i_login, (int, char *));
  81. static PROTO (int i_logoff, (int, char *));
  82. static PROTO (int i_nextrec, (int, char *));
  83. static PROTO (int i_open_file, (int, char *));
  84. static PROTO (int i_prevrec, (int, char *));
  85. static PROTO (int i_rereadrec, (int, char *));
  86. static PROTO (int i_rollback, (int, char *));
  87. static PROTO (int i_selectinx, (int, char *));
  88. static PROTO (int i_transact, (int, char *));
  89. static PROTO (int i_unlock_rec, (int, char *));
  90. static PROTO (int i_updrec, (int, char *));
  91. static PROTO (int io_xlate, (int, int, char *));
  92. static PROTO (int load_keys, (int));
  93. static PROTO (int start_translog, (void));
  94. static PROTO (void buf2isam, (int, char *, char *));
  95. static PROTO (void close_translog, (void));
  96. static PROTO (void isam2buf, (int, char *, char *));
  97.  
  98.  
  99. static int IS_OPENMODE;
  100. static int IS_LOCKMODE;
  101. static int IS_TRANSACT = 0;
  102. static int logisopen = FALSE;
  103. static int prev_move[MAX_FILES];
  104. static struct keydesc fkey[MAX_FILES][MAX_KEYS];  /* keydescs for each file */
  105. static char storbuff[MAX_RECLEN];         /* for C-ISAM copy of data record */
  106.  
  107.  
  108. /*
  109.  *
  110.  * Interface Functions
  111.  *
  112. */
  113.  
  114. /*
  115.  *  Sets up File Name extension.
  116. */
  117. static int i_filename(fd_sys, buffer)
  118. int fd_sys;
  119. char *buffer;
  120. {
  121.      char *tptr;
  122.  
  123.      if ((tptr = strrchr(buffer, '.')) != NULL)
  124.          *tptr = '\0';
  125.  
  126.     return(IOGOOD);
  127. }
  128.  
  129. /*
  130.  *  Initialize file
  131. */
  132. static int i_init_file(fd_sys, buffer)
  133. int fd_sys;
  134. char *buffer;
  135. {
  136.     return(IOGOOD);
  137. }
  138.  
  139.  
  140. /*
  141.  *  File open function
  142. */
  143. static int i_open_file(fd_sys, buffer)
  144. int fd_sys;
  145. char *buffer;
  146. {
  147.     int iostat;
  148.     struct dictinfo ch;
  149.     struct fd_def *fptr = &fd[fd_sys];
  150.  
  151.     if (fptr->openmode & OUTPUT_FLAG)
  152.         iserase(fptr->filname);          /* for OUTPUT, delete existing files */
  153.  
  154.     if (fptr->openmode & UPDATE_FLAG)
  155.         IS_OPENMODE = ISINOUT;
  156.     else if (fptr->openmode & INPUT_FLAG)
  157.         IS_OPENMODE = ISINPUT;
  158.     else
  159.         IS_OPENMODE = ISOUTPUT;                    /* either OUTPUT or APPEND */
  160.  
  161.     if (fptr->openmode & P_TRANSACT)
  162.     {
  163.         IS_TRANSACT = ISTRANS;
  164.         if (start_translog())
  165.             return(IOERROR);
  166.     }
  167.  
  168.     if ((iostat = isopen(fptr->filname, ISMANULOCK+IS_OPENMODE+IS_TRANSACT)) < SUCCESS)
  169.     {                                              /* try to create the file */
  170.         if (fptr->openmode & INPUT_FLAG)
  171.         {
  172.             iostat = io_xlate(fd_sys, iserrno, "CISM OPEN1");
  173.             close_translog();
  174.             return(iostat);
  175.         }
  176.  
  177.         if ((iostat = create_file(fd_sys)) <= IOERROR)
  178.         {
  179.             close_translog();
  180.             return(IOERROR);
  181.         }
  182.     }
  183.     else                   /* at this point, the file is successfully opened */
  184.     {
  185.         isindexinfo(iostat, (struct keydesc *)&ch, 0);  /* iostat contains fd */
  186.  
  187.         if(ch.di_recsize != fptr->rec_len+1)   /* not same reclen as expected */
  188.         {
  189.             errmsg(FileRecLenChg_s, fptr->filname);
  190.             fptr->fd_num = iostat;            /* ensure closing the correct file */
  191.             i_close_file(fd_sys, "");
  192.             return(IOERROR);
  193.         }
  194.  
  195.         load_keys(fd_sys);
  196.     }
  197.  
  198.     fptr->fd_num = iostat;                     /* retain the file descriptor */
  199.     return(IOGOOD);
  200. }
  201.  
  202.  
  203. /*
  204.  *  Initialize and open C-ISAM transaction log file
  205.  *  - end users should delete the recovery.log file periodically as
  206.  *    it can become very large with an active database
  207. */
  208. static int start_translog()
  209. {
  210.     if (logisopen)
  211.         return(TRUE);
  212.  
  213.     if (access("recovery.log", 00) < 0)
  214.     {
  215.         if (creat("recovery.log", S_IWRITE) == -1)
  216.         {
  217.             errmsg(FileTrnsLogCreate);
  218.             return(IOERROR);
  219.         }
  220.     }
  221.     if (islogopen("recovery.log") == -1)
  222.     {
  223.         errmsg(FileTrnsLogOpen);
  224.         return(IOERROR);
  225.     }
  226.     logisopen = TRUE;
  227.     return(IOGOOD);
  228. }
  229.  
  230.  
  231. /*
  232.  *  C-ISAM create file function
  233.  *  - file has to be created in exclusive mode to set up indexes; it is
  234.  *    then closed and reopened in shared mode; stat is file descriptor
  235. */
  236. static int create_file(fd_sys)
  237. int fd_sys;
  238. {
  239.     int iostat, j, nkeys;
  240.     char fname[FILENAME_LEN];
  241.     struct fd_def *fptr = &fd[fd_sys];
  242.  
  243.     strcpy(fname, fptr->filname);
  244.     strcat(fname, ".dat");
  245.     if (access(fname, 00) == 0)       /* file already exists, do not clobber */
  246.     {                                  /* iserrno here will be from isopen() */
  247.       errmsg(DataFileXist_s, fptr->filname);
  248.         return(io_xlate(fd_sys, iserrno, "CISM OPEN2"));
  249.     }
  250.  
  251.     nkeys = load_keys(fd_sys);
  252.  
  253.     if (isbuild(fptr->filname, fptr->rec_len+1, &fkey[fd_sys][0], ISINOUT+ISEXCLLOCK+IS_TRANSACT) < SUCCESS)
  254.         return(io_xlate(fd_sys, iserrno, "CISM CRT1"));
  255.  
  256.     if ((iostat = isopen(fptr->filname, ISINOUT+ISEXCLLOCK+IS_TRANSACT)) < SUCCESS)
  257.         return(io_xlate(fd_sys, iserrno, "CISM CRT2"));
  258.  
  259.     for (j = 1; j < nkeys; j++)                  /* create remaining indexes */
  260.         if (isaddindex(iostat, &fkey[fd_sys][j]))
  261.             return(io_xlate(fd_sys, iserrno, "CISM IXCRT"));
  262.  
  263.     if (isclose(iostat))
  264.         return(io_xlate(fd_sys, iserrno, "CISM CRT3"));
  265.  
  266.     if ((iostat = isopen(fptr->filname, ISMANULOCK+IS_OPENMODE+IS_TRANSACT)) < SUCCESS)
  267.         return(io_xlate(fd_sys, iserrno, "CISM CRT4"));
  268.  
  269.     return(iostat);
  270. }
  271.  
  272.  
  273. /*
  274.  *  C-ISAM key load function
  275.  *  - loads into C-ISAM key descriptor structure
  276. */
  277. static int load_keys(fd_sys)
  278. int fd_sys;
  279. {
  280.     int fx, m, n = 0;
  281.     struct fd_def *fptr = &fd[fd_sys];
  282.  
  283.     while (fptr->keys[n].segcount != -1)
  284.     {
  285.         for (m = 0; m < fptr->keys[n].segcount; m++)
  286.         {
  287.             fkey[fd_sys][n].k_part[m].kp_start = fptr->keys[n].segstart[m];
  288.             fkey[fd_sys][n].k_part[m].kp_leng  = fptr->keys[n].seglen[m];
  289.  
  290.             fx = fptr->keys[n].fldindex[m];
  291.             switch(fptr->flds[fx].fldtype)         /* data type of key segment */
  292.             {
  293.                 case CHRTYP : 
  294.                 case DATTYP :
  295.                     fkey[fd_sys][n].k_part[m].kp_type  = CHARTYPE;
  296.                     break;
  297.                 case INTTYP : 
  298.                     fkey[fd_sys][n].k_part[m].kp_leng = INTSIZE;
  299.                     fkey[fd_sys][n].k_part[m].kp_type = INTTYPE;
  300.                     break;
  301.                 case LNGTYP : 
  302.                 case TIMTYP :
  303.                     fkey[fd_sys][n].k_part[m].kp_leng = LONGSIZE;
  304.                     fkey[fd_sys][n].k_part[m].kp_type = LONGTYPE;
  305.                     break;
  306.                 case FLTTYP : 
  307.                     fkey[fd_sys][n].k_part[m].kp_type = FLOATTYPE;
  308.                     fkey[fd_sys][n].k_part[m].kp_leng = FLOATSIZE;
  309.                     break;
  310.                 case DBLTYP : 
  311.                     fkey[fd_sys][n].k_part[m].kp_type = DOUBLETYPE;
  312.                     fkey[fd_sys][n].k_part[m].kp_leng = DOUBLESIZE;
  313.                     break;
  314.             }
  315.         }
  316.         fkey[fd_sys][n].k_nparts = m;           /* segment count for this key */
  317.  
  318.         if (fptr->keys[n].keytype == KEY_DUPLICATE)
  319.             fkey[fd_sys][n].k_flags = ISDUPS;
  320.         else
  321.             fkey[fd_sys][n].k_flags = ISNODUPS;
  322.  
  323.         n++;                                     /* increment total key count */
  324.     }
  325.     return(n);
  326. }
  327.  
  328.  
  329. /*
  330.  *  File close function
  331. */
  332. static int i_close_file(fd_sys, buffer)
  333. int fd_sys;
  334. char *buffer;
  335. {
  336.     struct fd_def *fptr = &fd[fd_sys];
  337.  
  338.     if (isclose(fptr->fd_num))
  339.         return(io_xlate(fd_sys, iserrno, "CISM CLOSE"));
  340.  
  341.     fptr->active = NO;
  342.     close_translog();
  343.     return(IOGOOD);
  344. }
  345.  
  346.  
  347. /*
  348.  *  Close recovery.log file, if used
  349. */
  350. static void close_translog()
  351. {
  352.     int n;
  353.  
  354.     if (logisopen)
  355.     {
  356.         for (n = 0; n < MAX_FILES; n++)              /* all files closed yet? */
  357.             if (fd[n].active)
  358.                 return;
  359.  
  360.         islogclose();
  361.         logisopen = FALSE;
  362.     }
  363. }
  364.  
  365.  
  366. /*
  367.  *  Select an index to perform processing on - already done in IOGEN.C
  368.  *  - also sets C-ISAM's own lock modes for subsequent read
  369. */
  370. static int i_selectinx(fd_sys, buffer)
  371. int fd_sys;
  372. char *buffer;
  373. {
  374.     if (fd[fd_sys].lockmode == NOLOCK)
  375.         IS_LOCKMODE = NOLOCK;
  376.     else
  377.         IS_LOCKMODE = ISLOCK;                       /* C-ISAM's own lock flag */
  378.     return(IOGOOD);
  379. }
  380.  
  381. /*
  382.  *  Find a record by key value
  383. */
  384. static int i_findkey(fd_sys, buffer)
  385. int fd_sys;
  386. char *buffer;
  387. {
  388.     int ck, IS_MD;
  389.     struct fd_def *fptr = &fd[fd_sys];
  390.  
  391.     buf2isam(fd_sys, buffer, storbuff);
  392.     ck = fptr->cur_key;
  393.     IS_MD = (fptr->exact ? ISEQUAL : ISGTEQ);
  394.  
  395.     if(isstart(fptr->fd_num, &fkey[fd_sys][ck], 0, storbuff, IS_MD) < SUCCESS)
  396.         return(io_xlate(fd_sys, iserrno, "CISM FIND 1"));
  397.  
  398.     if(isread(fptr->fd_num, storbuff, IS_MD + IS_LOCKMODE) < SUCCESS)
  399.         return(io_xlate(fd_sys, iserrno, "CISM FIND 2"));
  400.  
  401.     isam2buf(fd_sys, buffer, storbuff);
  402.     return(IOGOOD);
  403. }
  404.  
  405. /*
  406.  *  Find first record in the file
  407. */
  408. static int i_firstkey(fd_sys, buffer)
  409. int fd_sys;
  410. char *buffer;
  411. {
  412.     int ck;
  413.     struct fd_def *fptr = &fd[fd_sys];
  414.  
  415.     ck = fptr->cur_key;
  416.  
  417.     if(isstart(fptr->fd_num, &fkey[fd_sys][ck], 0, storbuff, ISFIRST) < SUCCESS)
  418.         return(io_xlate(fd_sys, iserrno, "CISM FRST 1"));
  419.  
  420.     if (isread(fptr->fd_num, storbuff, ISNEXT + IS_LOCKMODE) < SUCCESS)
  421.         return(io_xlate(fd_sys, iserrno, "CISM FRST 2"));
  422.  
  423.     isam2buf(fd_sys, buffer, storbuff); 
  424.     return(IOGOOD);
  425. }
  426.  
  427. /*
  428.  *  Find last physical record in the file
  429. */
  430. static int i_lastkey(fd_sys, buffer)
  431. int fd_sys;
  432. char *buffer;
  433. {
  434.     int ck;
  435.     struct fd_def *fptr = &fd[fd_sys];
  436.  
  437.     ck = fptr->cur_key;
  438.  
  439.     if(isstart(fptr->fd_num, &fkey[fd_sys][ck], 0, storbuff, ISLAST) < SUCCESS)
  440.         return((iserrno == EENDFILE) ? IOEOF : io_xlate(fd_sys, iserrno, "CISM LAST 1"));
  441.  
  442.     if(isread(fptr->fd_num, storbuff, ISPREV + IS_LOCKMODE) < SUCCESS)
  443.         return((iserrno == EENDFILE) ? IOEOF : io_xlate(fd_sys, iserrno, "CISM LAST 2"));
  444.  
  445.     isam2buf(fd_sys, buffer, storbuff);
  446.     return(IOGOOD);
  447. }
  448.  
  449. /*
  450.  *  Find next record in the file
  451. */
  452. static int i_nextrec(fd_sys, buffer)
  453. int fd_sys;
  454. char *buffer;
  455. {
  456.     struct fd_def *fptr = &fd[fd_sys];
  457.  
  458.     buf2isam(fd_sys, buffer, storbuff);
  459.  
  460.     if (isread(fptr->fd_num, storbuff, ISNEXT + IS_LOCKMODE) < SUCCESS)
  461.     {
  462.         if (iserrno == EENDFILE)
  463.         {
  464.             i_lastkey(fd_sys, buffer);
  465.             return(IOEOF);
  466.         }
  467.         return(io_xlate(fd_sys, iserrno, "CISM NEXT"));
  468.     }
  469.  
  470.     prev_move[fd_sys] = NEXT;
  471.     isam2buf(fd_sys, buffer, storbuff);
  472.     return(IOGOOD);
  473. }
  474.  
  475. /*
  476.  *  Find previous record in the file
  477. */
  478. static int i_prevrec(fd_sys, buffer)
  479. int fd_sys;
  480. char *buffer;
  481. {
  482.     struct fd_def *fptr = &fd[fd_sys];
  483.  
  484.     buf2isam(fd_sys, buffer, storbuff);
  485.  
  486.     if (isread(fptr->fd_num, storbuff, ISPREV + IS_LOCKMODE) < SUCCESS)
  487.     {
  488.         if (iserrno == EENDFILE)
  489.         {
  490.             i_firstkey(fd_sys, buffer);
  491.             return(IOTOF);
  492.         }
  493.         else
  494.             return(io_xlate(fd_sys, iserrno, "CISM PREV"));
  495.     }
  496.  
  497.     prev_move[fd_sys] = PREV;
  498.     isam2buf(fd_sys, buffer, storbuff);
  499.     return(IOGOOD);
  500. }
  501.  
  502. /*
  503.  *  Re-read/reposition record pointer function
  504.  *  - uses physical order index and global record number
  505. */
  506. static int i_rereadrec(fd_sys, buffer)
  507. int fd_sys;
  508. char *buffer;
  509. {
  510.     if (prev_move[fd_sys] == NEXT)
  511.         return(i_prevrec(fd_sys, buffer));
  512.     else
  513.         return(i_nextrec(fd_sys, buffer));
  514. }
  515.  
  516.  
  517. /*
  518.  *  Add a new record.
  519. */
  520. static int i_addrec(fd_sys, buffer)
  521. int fd_sys;
  522. char *buffer;
  523. {
  524.     struct fd_def *fptr = &fd[fd_sys];
  525.  
  526.     buf2isam(fd_sys, buffer, storbuff);
  527.  
  528.     if (iswrcurr(fptr->fd_num, storbuff) < SUCCESS)
  529.         return(io_xlate(fd_sys, iserrno, "CISM ADD"));
  530.  
  531.     isflush(fptr->fd_num);
  532.     return(IOGOOD);
  533. }
  534.  
  535. /*
  536.  *  Update the current record.
  537. */
  538. static int i_updrec(fd_sys, buffer)
  539. int fd_sys;
  540. char *buffer;
  541. {
  542.     struct fd_def *fptr = &fd[fd_sys];
  543.  
  544.     buf2isam(fd_sys, buffer, storbuff);
  545.  
  546.     if (isrewcurr(fptr->fd_num, storbuff) < SUCCESS)
  547.         return(io_xlate(fd_sys, iserrno, "CISM UPD"));
  548.  
  549.     isflush(fptr->fd_num);
  550.     return(IOGOOD);
  551. }
  552.  
  553. /*
  554.  *  Delete the current record.
  555. */
  556. static int i_delrec(fd_sys, buffer)
  557. int fd_sys;
  558. char *buffer;
  559. {
  560.     struct fd_def *fptr = &fd[fd_sys];
  561.  
  562.     if (isdelcurr(fd[fd_sys].fd_num))
  563.         return io_xlate(fd_sys, iserrno, "CISM DEL");
  564.  
  565.     isflush(fptr->fd_num);
  566.     return(IOGOOD);
  567. }
  568.  
  569. /*
  570.  *  Lock Record - rereads current record into storbuff to lock
  571.  *  - to preserve edits, storbuff is NOT converted to PRO-C buffer
  572. */  
  573. static int i_lockrec(fd_sys, buffer)
  574. int fd_sys;
  575. char *buffer;
  576. {
  577.     struct fd_def *fptr = &fd[fd_sys];
  578.  
  579.     if (isread(fptr->fd_num, storbuff, ISCURR + IS_LOCKMODE) < SUCCESS)
  580.     {
  581.         if (iserrno == EENDFILE)             /* bypass retry count if EOF/TOF */
  582.             return(IOGOOD);
  583.         return(io_xlate(fd_sys, iserrno, "CISM LOCK"));
  584.     }
  585.  
  586.     return(IOGOOD);
  587. }
  588.  
  589. /*
  590.  *  Unlock Record
  591. */
  592. static int i_unlock_rec(fd_sys, buffer)
  593. int fd_sys;
  594. char *buffer;
  595. {
  596.     if (isrelease(fd[fd_sys].fd_num))
  597.         return(io_xlate(fd_sys, iserrno, "CISM ULCK"));
  598.  
  599.     return(IOGOOD);
  600. }
  601.  
  602. /*
  603.  *  Login
  604. */
  605. static int i_login(fd_sys, buffer)
  606. int fd_sys;
  607. char *buffer;
  608. {
  609.     return(IOGOOD);
  610. }
  611.  
  612. /*
  613.  *  Logoff
  614. */
  615. static int i_logoff(fd_sys, buffer)
  616. int fd_sys;
  617. char *buffer;
  618. {
  619.     return(IOGOOD);
  620. }
  621.  
  622. /*
  623.  *  End (Commit) transaction - releases any outstanding locks
  624. */
  625. static int i_commit(fd_sys, buffer)
  626. int fd_sys;
  627. char *buffer;
  628. {
  629.     if (!IS_TRANSACT)
  630.         return(IOGOOD);
  631.  
  632.     if (iscommit())
  633.     {
  634.         errmsg(FileTrnsCommit);
  635.         return(io_xlate(fd_sys, iserrno, "CISM ETRN"));
  636.     }
  637.     return(IOGOOD);
  638. }
  639.  
  640. /*
  641.  *  Rollback transaction
  642. */
  643. static int i_rollback(fd_sys, buffer)
  644. int fd_sys;
  645. char *buffer;
  646. {
  647.     if (!IS_TRANSACT)
  648.         return(IOGOOD);
  649.  
  650.     if (isrollback())
  651.     {
  652.         errmsg(FileTrnsRlback);
  653.         return(io_xlate(fd_sys, iserrno, "CISM ATRN"));
  654.     }
  655.     return(IOGOOD);
  656. }
  657.  
  658. /*
  659.  *  Start transaction
  660. */
  661. static int i_transact(fd_sys, buffer)
  662. int fd_sys;
  663. char *buffer;
  664. {
  665.     if (!IS_TRANSACT)
  666.         return(IOGOOD);
  667.  
  668.     if (isbegin())
  669.     {
  670.         errmsg(FileTrnsBegin);
  671.         return(io_xlate(fd_sys, iserrno, "CISM BTRN"));
  672.     }
  673.     return(IOGOOD);
  674. }
  675.  
  676.  
  677. /*
  678.  *  Convert record to C-ISAM form from PRO-C buffer format before storing
  679. */
  680. static void buf2isam(fd_sys, P_buff, CI_buff)
  681. int fd_sys;
  682. char *P_buff, *CI_buff;
  683. {
  684.     short itmp;
  685.     long ltmp;
  686.     float ftmp;
  687.     double dtmp;
  688.     int x = 0, foff, flen;
  689.     struct fd_def *fptr = &fd[fd_sys];
  690.  
  691.     zerorec(CI_buff, fptr->rec_len+1);
  692.  
  693.     while (fptr->flds[x].fldname)          /* NULL fieldname terminates list */
  694.     {
  695.         foff = fptr->flds[x].fldstart;
  696.         flen = fptr->flds[x].fldlen;
  697.         switch(fptr->flds[x].fldtype)
  698.         {
  699.             case LOGTYP :
  700.             case MEMTYP :
  701.             case CHRTYP :
  702.             case DATTYP :
  703.                 stchar(&P_buff[foff], &CI_buff[foff], flen); 
  704.                 break;
  705.             case INTTYP :
  706.                 bytecpy(&itmp, &P_buff[foff], flen); 
  707.                 stint(itmp, &CI_buff[foff]);
  708.                 break;
  709.             case LNGTYP :
  710.             case TIMTYP :
  711.                 bytecpy(<mp, &P_buff[foff], flen);
  712.                 stlong(ltmp, &CI_buff[foff]);
  713.                 break;
  714.             case FLTTYP :
  715.                 bytecpy(&ftmp, &P_buff[foff], flen);
  716. /*                stfloat(ftmp, &CI_buff[foff]);     (C-ISAM bug)  */
  717.                 break;
  718.             case DBLTYP :
  719.                 bytecpy(&dtmp, &P_buff[foff], flen);
  720.                 stdbl(dtmp, &CI_buff[foff]);
  721.                 break;
  722.         }
  723.         x++;
  724.     }
  725. }
  726.  
  727. /*
  728.  *  Convert record to PRO-C buffer format from C-ISAM form before returning
  729. */
  730. static void isam2buf(fd_sys, P_buff, CI_buff)
  731. int fd_sys;
  732. char *P_buff, *CI_buff;
  733. {
  734.     short itmp;
  735.     long ltmp;
  736.     float ftmp;
  737.     double dtmp;
  738.     int x = 0, foff, flen;
  739.     char tbuff[MAX_FLDLEN];        /* dummy buffer for char field extraction */
  740.     struct fd_def *fptr = &fd[fd_sys];
  741.  
  742.     zerorec(P_buff, fptr->rec_len);
  743.  
  744.     while (fptr->flds[x].fldname)          /* NULL fieldname terminates list */
  745.     {
  746.         foff = fptr->flds[x].fldstart;
  747.         flen = fptr->flds[x].fldlen;
  748.         switch(fptr->flds[x].fldtype)
  749.         {
  750.             case LOGTYP :
  751.             case MEMTYP :
  752.             case DATTYP :
  753.             case CHRTYP :
  754.                 zerorec(tbuff, MAX_FLDLEN);
  755.                 ldchar(&CI_buff[foff], flen, tbuff);
  756.                 bytecpy(&P_buff[foff], tbuff, flen);
  757.                 break;
  758.             case INTTYP :
  759.                 itmp = ldint(&CI_buff[foff]);
  760.                 bytecpy(&P_buff[foff], &itmp, flen);
  761.                 break;
  762.             case LNGTYP :
  763.             case TIMTYP :
  764.                 ltmp = ldlong(&CI_buff[foff]);
  765.                 bytecpy(&P_buff[foff], <mp, flen);
  766.                 break;
  767.             case FLTTYP :
  768. /*                dtmp = ldfloat(&CI_buff[foff]);   (C-ISAM bug!) */
  769.                 ftmp = 0;   /*  for now ... (float)dtmp;  */
  770.                 bytecpy(&P_buff[foff], &ftmp, flen);
  771.                 break;
  772.             case DBLTYP :
  773.                 dtmp = lddbl(&CI_buff[foff]);
  774.                 bytecpy(&P_buff[foff], &dtmp, flen);
  775.                 break;
  776.         }
  777.         x++;
  778.     }
  779. }
  780.  
  781.  
  782. /*
  783.  *  This routine translates C-ISAM Error codes into PRO-C error codes.
  784.  *  If no PRO-C equivalent, displays the error number.
  785. */
  786. static int io_xlate(fd_sys, ernum, rtnname)
  787. int fd_sys;
  788. int ernum;
  789. char *rtnname;
  790. {
  791.     switch(ernum)
  792.     {
  793.         case  EDUPL      :
  794.             return(IODUP);
  795.         case  ENOTOPEN   :
  796.             return(IOBADOPEN);
  797.         case  ENOFILE    :
  798.             return(IONOFILE);
  799.         case  EENDFILE   :   
  800.         case  ENOREC     :   
  801.         case  ENOCURR    :
  802.             return(IONOKEY);
  803.         case  ELOCKED    :
  804.         case  EFLOCKED   :
  805.             return(IOLOCKED);
  806.         case  ELOGWRIT   :
  807.         case  ENOTRANS   :
  808.         case  ENOBEGIN   :
  809.             return(IONOTRANS);
  810.     }
  811.  
  812.     if (fd_sys >= 0)
  813.         errmsg(FileDbgError_sdss, "C-ISAM", ernum, fd[fd_sys].filname, rtnname);
  814.     else      /* if routines called from generated apps without valid fd_sys */
  815.         errmsg(FileDbgError_sds, "C-ISAM", ernum, rtnname);
  816.     return(IOERROR);
  817. }
  818.  
  819.  
  820. /*
  821.  * Assign section
  822. */
  823. void assign_IO_CI(dbnum)
  824. int dbnum;
  825. {
  826.     Fntab[dbnum - 1][0]  = (int(*)())0; /* Empty */
  827.     Fntab[dbnum - 1][1]  = i_init_file;
  828.     Fntab[dbnum - 1][2]  = i_open_file;
  829.     Fntab[dbnum - 1][3]  = i_close_file;
  830.     Fntab[dbnum - 1][4]  = i_addrec;
  831.     Fntab[dbnum - 1][5]  = i_delrec;
  832.     Fntab[dbnum - 1][6]  = i_findkey;
  833.     Fntab[dbnum - 1][7]  = i_firstkey;
  834.     Fntab[dbnum - 1][8]  = i_lastkey;
  835.     Fntab[dbnum - 1][9]  = i_lockrec;
  836.     Fntab[dbnum - 1][10] = i_nextrec;
  837.     Fntab[dbnum - 1][11] = i_prevrec;
  838.     Fntab[dbnum - 1][12] = i_unlock_rec;
  839.     Fntab[dbnum - 1][13] = i_updrec;
  840.     Fntab[dbnum - 1][14] = i_commit;
  841.     Fntab[dbnum - 1][15] = i_login;
  842.     Fntab[dbnum - 1][16] = i_logoff;
  843.     Fntab[dbnum - 1][17] = i_rollback;
  844.     Fntab[dbnum - 1][18] = i_transact;
  845.     Fntab[dbnum - 1][19] = i_selectinx;
  846.     Fntab[dbnum - 1][20] = i_rereadrec;
  847.     Fntab[dbnum - 1][21] = i_filename;
  848. }
  849.  
  850.