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

  1. /* ==( bench/iogen.c )== */
  2. /* ----------------------------------------------- */
  3. /* Pro-C  Copyright (C) 1988 - 1990 Vestronix Inc. */
  4. /* Modification to this source is not supported    */
  5. /* by Vestronix Inc.                               */
  6. /*            All Rights Reserved                  */
  7. /* ----------------------------------------------- */
  8. /* Written   VvA     Aug-89                        */
  9. /* Modified  VvA  11-Apr-90  See comments below    */
  10. /* ----------------------------------------------- */
  11. /* %W%  (%H% %T%) */
  12.  
  13. /*
  14.  *  Modifications
  15.  *
  16.  *  11-Apr-90  VvA - addrec=appendrec, delrec=removerec
  17.  *  28-Mar-90  VvA - adjustments for locking modes, transactions
  18.  *  13-Mar-90  VvA - allow for database name, user id, passwords
  19.  *  01-Feb-90  VvA - adj open_file, selectinx, replace "" with NULLs
  20. */
  21.  
  22. /*  I/O Library  -  General Functions
  23.  *  This module will provide the interface between generic I/O calls from 
  24.  *  generated PRO-C applications and the specific I/O managers supported.
  25.  *  The calls are macro definitions, defined for the I/O manager chosen. 
  26.  *
  27.  *  Original I/O library modules by:  AMcDonald, BZigon, NAttwell
  28.  *  Generalized I/O library concept:  GLong 
  29. */
  30.  
  31.  
  32. # include <stdio.h>
  33. # include <proc.io>
  34. # include <bench.h>
  35. # include <iodef.h>
  36. # include <iomsg.h>
  37. # include <passwd.h>
  38.  
  39.  
  40. #ifdef ANSI
  41. static int skiprec(int, char *, int);
  42. #else
  43. static int skiprec();
  44. #endif
  45.  
  46.  
  47. #define DB_INIT(dbnum, buffer)        (*Fntab[dbnum-1][1])(-1, buffer)
  48. #define DB_LOGIN(dbnum, buffer)       (*Fntab[dbnum-1][15])(-1, buffer)
  49.  
  50. #define DB_OPEN(n, buffer)            (*Fntab[fd[n].dbnum-1][2])(n, buffer)
  51. #define DB_CLOSE(n, buffer)           (*Fntab[fd[n].dbnum-1][3])(n, buffer)
  52. #define DB_ADD(n, buffer)             (*Fntab[fd[n].dbnum-1][4])(n, buffer)
  53. #define DB_DEL(n, buffer)             (*Fntab[fd[n].dbnum-1][5])(n, buffer)
  54. #define DB_FIND(n, buffer)            (*Fntab[fd[n].dbnum-1][6])(n, buffer)
  55. #define DB_FIRST(n, buffer)           (*Fntab[fd[n].dbnum-1][7])(n, buffer)
  56. #define DB_LAST(n, buffer)            (*Fntab[fd[n].dbnum-1][8])(n, buffer)
  57. #define DB_LOCK(n, buffer)            (*Fntab[fd[n].dbnum-1][9])(n, buffer)
  58. #define DB_NEXT(n, buffer)            (*Fntab[fd[n].dbnum-1][10])(n, buffer)
  59. #define DB_PREV(n, buffer)            (*Fntab[fd[n].dbnum-1][11])(n, buffer)
  60. #define DB_ULOCK(n, buffer)           (*Fntab[fd[n].dbnum-1][12])(n, buffer)
  61. #define DB_UPD(n, buffer)             (*Fntab[fd[n].dbnum-1][13])(n, buffer)
  62. #define DB_COMMIT(n, buffer)          (*Fntab[fd[n].dbnum-1][14])(n, buffer)
  63. #define DB_LOGOFF(n, buffer)          (*Fntab[fd[n].dbnum-1][16])(n, buffer)
  64. #define DB_ROLLBACK(n, buffer)        (*Fntab[fd[n].dbnum-1][17])(n, buffer)
  65. #define DB_TRANSACT(n, buffer)        (*Fntab[fd[n].dbnum-1][18])(n, buffer)
  66. #define DB_SELINX(n, buffer)          (*Fntab[fd[n].dbnum-1][19])(n, buffer)
  67. #define DB_REREAD(n, buffer)          (*Fntab[fd[n].dbnum-1][20])(n, buffer)
  68. #define DB_NAME(n, buffer)            (*Fntab[fd[n].dbnum-1][21])(n, buffer)
  69.  
  70.  
  71. struct fd_def fd[MAX_FILES];
  72. static int first_time = 1;
  73. static int ForEver;       /* for file locking modes */
  74.  
  75. extern char userid[];
  76. extern char password[];
  77.  
  78.  
  79. /*
  80.  * General database and structure initialization
  81.  * - database name, user id, password should be NULLs if not used
  82. */
  83. int init_file(dbname, uid, psw, dbnum)
  84. char *dbname, *uid, *psw;
  85. int dbnum;
  86. {
  87.    int iostat, i;
  88.  
  89.    /* If table is not set up - go home */
  90.    if (Fntab[dbnum-1][1] == (int(*)())0) /* Added by Geo 30-Nov-89 */
  91.       abort_mess("Database indirection tables not loaded");
  92.  
  93.    if (first_time)
  94.    {
  95.       /* password check if reqd */
  96.       if (iostat = login(uid, psw, dbnum))
  97.          return(io_error(-1, iostat, "INIT1", NULL));
  98.  
  99.       /* database initialization if reqd */
  100.       if (iostat = DB_INIT(dbnum, dbname))
  101.          return(io_error(-1, iostat, "INIT2", NULL));
  102.  
  103.       first_time = 0;
  104.       for (i = 0; i < MAX_FILES; i++)
  105.          fd[i].active = NO;
  106.    }
  107.  
  108.    return(IOGOOD);
  109. }
  110.  
  111.  
  112. /*
  113.  *  Generic open_file:  calls I/O specific init_file and open_file
  114.  *  - fd structure should contain everything required by I/O mgr's open call
  115.  *  - I/O mgr interface function should take care of create, if needed
  116. */
  117. int open_file(fname, fsize, keys, flds, mode, dbnum)
  118. char *fname;
  119. int fsize;
  120. struct keyinfo *keys;
  121. struct fldinfx *flds;
  122. int mode, dbnum;
  123. {
  124.    int fd_sys;                   /* file id value, also index into fd table */
  125.    int iostat, i;
  126.    char filename[PATHNAME_LEN];
  127.    char *buffer = NULL;         /* not actually used here but dummy for open */
  128.  
  129.    /* If table is not set up - go home */
  130.    if (Fntab[dbnum-1][1] == (int(*)())0) /* Added by Geo 30-Nov-89 */
  131.       abort_mess("Database indirection tables not loaded");
  132.  
  133.    for (fd_sys = UNUSED, i = 0; i < MAX_FILES; ++i)
  134.       if (! fd[i].active)                   /* found first unused file defn */
  135.       {
  136.          fd[fd_sys = i].dbnum = dbnum;
  137.          break;
  138.       }
  139.  
  140.    if (fd_sys == UNUSED)           /* if fd_sys still UNUSED, table is full */
  141.    {
  142.       errmsg(FileMaxOpen);
  143.       return(IOERROR);
  144.    }
  145.  
  146.    strcpy(filename, fname);
  147.    DB_NAME(fd_sys, filename);    /* set up file name as reqd by I/O manager */
  148.  
  149.    fd[fd_sys].active = YES;
  150.    fd[fd_sys].cur_key = 0;                         /* default current index */
  151.    fd[fd_sys].got_rec = NO;
  152.    fd[fd_sys].rec_len = fsize;          /* in case we create a dummy buffer */
  153.    fd[fd_sys].openmode = mode;
  154.    fd[fd_sys].lockmode = 0;              /* assigned in each selectinx call */
  155.    strcpy(fd[fd_sys].filname, filename);             /* for error reporting */
  156.    fd[fd_sys].flds = flds;
  157.    fd[fd_sys].keys = keys;
  158.  
  159.    /* find field count */
  160.    for (i = 0; fd[fd_sys].flds[i].fldname; i++)
  161.       ;
  162.    fd[fd_sys].fld_cnt = i;
  163.  
  164.    /* find key count */
  165.    for (i = 0; fd[fd_sys].keys[i].segcount >= 0; i++)
  166.       ;
  167.    fd[fd_sys].key_cnt = i;
  168.  
  169.    if (iostat = DB_OPEN(fd_sys, buffer))
  170.       return(io_error(fd_sys, iostat, "OPEN", NULL));
  171.  
  172.    return(fd_sys);
  173. }
  174.  
  175.  
  176. /*
  177.  *  Generic close_file - includes setting first_time if all files closed
  178. */
  179. int close_file(fd_sys)
  180. int fd_sys;
  181. {
  182.    int iostat, n;
  183.  
  184.    if (iostat = DB_CLOSE(fd_sys, NULL))
  185.       return(io_error(fd_sys, iostat, "CLOSE", NULL));
  186.  
  187.    if (fd_sys > -1)         /* trap in case this is called with fd_sys = -1 */
  188.       fd[fd_sys].active = NO;
  189.  
  190.    first_time = 1;
  191.    for (n = 0; n < MAX_FILES; n++)     /* first time set only if all closed */
  192.       if (fd[n].active == YES)
  193.          first_time = 0;
  194.  
  195.    return(IOGOOD);
  196. }
  197.  
  198.  
  199. /*
  200.  *  Generic select index:
  201. */
  202. void selectinx(fd_sys, keyno, match, retry)
  203. int fd_sys, keyno, match, retry;
  204. {
  205.    fd[fd_sys].cur_key = --keyno;
  206.    fd[fd_sys].exact = match;            /* should be 1 for exact, 0 for GTE */
  207.    fd[fd_sys].lockmode = retry;
  208.    ForEver = (retry == -1);
  209.    DB_SELINX(fd_sys, NULL);
  210. }
  211.  
  212.  
  213. /*
  214.  *  Generic key locate:
  215. */
  216. int findkey(fd_sys, buffer)
  217. int fd_sys;
  218. char *buffer;
  219. {
  220.    int iostat, tries;
  221.  
  222.    tries = fd[fd_sys].lockmode;
  223.    do
  224.    {
  225.       iostat = DB_FIND(fd_sys, buffer);
  226.       if (iostat != IOLOCKED)
  227.          break;
  228.    }
  229.    while ((--tries > 0) || ForEver);
  230.  
  231.    if (iostat != IOGOOD)
  232.       return(io_error(fd_sys, iostat, "FIND", NULL));
  233.  
  234.    return(IOGOOD);
  235. }
  236.  
  237.  
  238. /*
  239.  *  Duplicate key check for record to be added:
  240. */
  241. int checkrec(fd_sys, buffer, inx)
  242. int fd_sys;
  243. char *buffer;
  244. int inx;
  245. {
  246.    int iostat, oldexact;
  247.    char tmpbuf[MAX_RECLEN];
  248.    struct fd_def *fptr = &fd[fd_sys];
  249.  
  250.    memcpy(tmpbuf, buffer, fptr->rec_len);
  251.    oldexact = fptr->exact;
  252.  
  253.    selectinx(fd_sys, inx, EXACT, 0);
  254.  
  255.    if (!(iostat = DB_FIND(fd_sys, tmpbuf))) /* direct call bypasses message */
  256.    {
  257.       ulock_rec(fd_sys, tmpbuf);
  258.       fptr->exact = oldexact;
  259.       return(IODUP);
  260.    }
  261.  
  262.    fptr->exact = oldexact;
  263.    return(IOGOOD);
  264. }
  265.  
  266.  
  267. /*
  268.  *  Generic top of file by current key:
  269. */
  270. int firstkey(fd_sys, buffer)
  271. int fd_sys;
  272. char *buffer;
  273. {
  274.    int iostat, tries;
  275.  
  276.    tries = fd[fd_sys].lockmode;
  277.    do
  278.    {
  279.       iostat = DB_FIRST(fd_sys, buffer);
  280.       if (iostat != IOLOCKED)
  281.          break;
  282.    }
  283.    while ((--tries > 0) || ForEver);
  284.  
  285.    if (iostat != IOGOOD)
  286.       return(io_error(fd_sys, iostat, "FRST", NULL));
  287.  
  288.    return(IOGOOD);
  289. }
  290.  
  291.  
  292. /*
  293.  *  Generic end of file by current key:
  294. */
  295. int lastkey(fd_sys, buffer)
  296. int fd_sys;
  297. char *buffer;
  298. {
  299.    int iostat, tries;
  300.  
  301.    tries = fd[fd_sys].lockmode;
  302.    do
  303.    {
  304.       iostat = DB_LAST(fd_sys, buffer);
  305.       if (iostat != IOLOCKED)
  306.          break;
  307.    }
  308.    while ((--tries > 0) || ForEver);
  309.  
  310.    if (iostat != IOGOOD)
  311.       return(io_error(fd_sys, iostat, "LAST", NULL));
  312.  
  313.    return(IOGOOD);
  314. }
  315.  
  316.  
  317. /*
  318.  *  Generic next record by current key:
  319. */
  320. int nextrec(fd_sys, buffer)
  321. int fd_sys;
  322. char *buffer;
  323. {
  324.    return(skiprec(fd_sys, buffer, NEXT));
  325. }
  326.  
  327.  
  328. /*
  329.  *  Generic previous record by current key:
  330. */
  331. int prevrec(fd_sys, buffer)
  332. int fd_sys;
  333. char *buffer;
  334. {
  335.    return(skiprec(fd_sys, buffer, PREV));
  336. }
  337.  
  338.  
  339. /*
  340.  *  General next/previous file traversal:
  341.  *  - next and previous record moves are identical except for actual call
  342.  *    and return condition from the I/O manager
  343. */
  344. static int skiprec(fd_sys, buffer, direction)
  345. int fd_sys, direction;
  346. char *buffer;
  347. {
  348.    int klen, iostat, tries;
  349.    char tmpbuf[MAX_RECLEN], oldkey[MAX_RECLEN], newkey[MAX_RECLEN];
  350.    struct fd_def *fptr = &fd[fd_sys];
  351.  
  352.    if (fptr->exact)       /* if exact match used, keep copy of starting key */
  353.    {
  354.       memcpy(tmpbuf, buffer, fptr->rec_len);
  355.       extract_key(fd_sys, buffer, oldkey);
  356.    }
  357.  
  358.    tries = fd[fd_sys].lockmode;
  359.    do
  360.    {
  361.       if (direction == NEXT)
  362.          iostat = DB_NEXT(fd_sys, buffer);
  363.       else
  364.          iostat = DB_PREV(fd_sys, buffer);
  365.       if (iostat != IOLOCKED)
  366.          break;
  367.    }
  368.    while ((--tries > 0) || ForEver);
  369.  
  370.    if (iostat != IOGOOD)
  371.    {
  372.       if (direction == NEXT)
  373.          return(io_error(fd_sys, iostat, "NEXT", NULL));
  374.       else
  375.          return(io_error(fd_sys, iostat, "PREV", NULL));
  376.    }
  377.  
  378.    if (fptr->exact)     /* for exact "next", check if new key still matches */
  379.    {
  380.       klen = extract_key(fd_sys, buffer, newkey);
  381.       if (memcmp(oldkey, newkey, klen))
  382.       {
  383.          DB_ULOCK(fd_sys, buffer);
  384.          memcpy(buffer, tmpbuf, fptr->rec_len);       /* restore old buffer */
  385.          if (iostat = DB_REREAD(fd_sys, buffer))    /* restore old recpointer */
  386.             return(io_error(fd_sys, iostat, "REREAD", NULL));
  387.          return(IONONEXT);             /* keys don't match for exact "next" */
  388.       }
  389.    }
  390.    return(IOGOOD);
  391. }
  392.  
  393.  
  394. /*
  395.  *  Extracts all segments of a key into a temporary buffer
  396.  *  (DEC 89 - used to be static)
  397. */
  398. int extract_key(fd_sys, buffer, keybuf)         /* returns total key length */
  399. int fd_sys;
  400. char *buffer, *keybuf;
  401. {
  402.    int m, ko;
  403.    struct keyinfo *kptr = &fd[fd_sys].keys[fd[fd_sys].cur_key];
  404.  
  405.    struct fd_def *fptr = &fd[fd_sys];  /* ANDRE */
  406.  
  407.    for (m = 0, ko = 0; m < kptr->segcount; m++)
  408.    {
  409.       memcpy(&keybuf[ko], &buffer[kptr->segstart[m]], kptr->seglen[m]);
  410.       ko += kptr->seglen[m];
  411.  
  412.         /*
  413.          * 99 is a special key match, which allows the search
  414.          * to inquire on n-1 of the segments, whilst still
  415.          * ordering by all of the segments.  Really only for
  416.          * Oracle (ie. for Special Projects - NIG)
  417.         */
  418.       if (fptr->exact == 99 && (m + 2) == kptr->segcount)
  419.          break;
  420.    }
  421.    return(ko);
  422. }
  423.  
  424.  
  425. /*
  426.  *  Generic add_rec:
  427. */
  428. int appendrec(fd_sys, buffer)
  429. int fd_sys;
  430. char *buffer;
  431. {
  432.    int iostat;
  433.  
  434.    iostat = DB_ADD(fd_sys, buffer);
  435.    DB_ULOCK(fd_sys, buffer);
  436.  
  437.    if (iostat != IOGOOD)
  438.       return(io_error(fd_sys, iostat, "ADD", NULL));
  439.    return(IOGOOD);
  440. }
  441.  
  442.  
  443. /*
  444.  *  Generic upd_rec:
  445. */
  446. int updrec(fd_sys, buffer)
  447. int fd_sys;
  448. char *buffer;
  449. {
  450.    int iostat;
  451.  
  452.    iostat = DB_UPD(fd_sys, buffer);
  453.    DB_ULOCK(fd_sys, buffer);
  454.  
  455.    if (iostat != IOGOOD)
  456.       return(io_error(fd_sys, iostat, "UPD", NULL));
  457.    return(IOGOOD);
  458. }
  459.  
  460.  
  461. /*
  462.  *  Generic del_rec:
  463. */
  464. int removerec(fd_sys, buffer)
  465. int fd_sys;
  466. char *buffer;
  467. {
  468.    int iostat;
  469.  
  470.    iostat = DB_DEL(fd_sys, buffer);
  471.    DB_ULOCK(fd_sys, buffer);
  472.  
  473.    if (iostat != IOGOOD)
  474.       return(io_error(fd_sys, iostat, "DEL", NULL));
  475.    return(IOGOOD);
  476. }
  477.  
  478.  
  479. /*
  480.  *  Lock record - may be a dummy call for some I/O managers
  481.  *  - value in lockmode determines if lock tried, and how often
  482.  *  - because some file managers, ie Btrieve, use the lock function to do
  483.  *    repositioning, the onus will be on specific I/O modules to bounce
  484.  *    NOLOCK instances back with IOGOOD
  485. */
  486. int lock_rec(fd_sys, buffer)
  487. int fd_sys;
  488. char *buffer;
  489. {
  490.    int iostat, tries;
  491.  
  492.    tries = fd[fd_sys].lockmode;
  493.    do
  494.    {
  495.       if ((iostat = DB_LOCK(fd_sys, buffer)) != IOLOCKED)
  496.          break;
  497.    }
  498.    while ((--tries > 0) || ForEver);
  499.  
  500.    if (iostat != IOGOOD)
  501.       return(io_error(fd_sys, iostat, "LOCK", NULL));
  502.  
  503.    return(IOGOOD);
  504. }
  505.  
  506.  
  507. /*
  508.  *  Unlock record - may be a dummy call for some I/O managers
  509. */
  510. int ulock_rec(fd_sys, buffer)
  511. int fd_sys;
  512. char *buffer;
  513. {
  514.    return(DB_ULOCK(fd_sys, buffer));
  515. }
  516.  
  517.  
  518. /*
  519.  *  Login - may be a dummy call for some I/O managers
  520.  *  (if uid and psw are NULL, file manager itself can call for these)
  521.  *  - loginstr contains user id at offset 0, decrypted password at
  522.  *    offset 20 and is a static char array to avoid encrypt/decrypt
  523.  *    problems if files are closed and later reopened using this function
  524. */
  525. int login(uid, psw, dbnum)
  526. char *uid, *psw;
  527. int dbnum;
  528. {
  529.    static char loginstr[41], *loginptr;
  530.  
  531.    if (uid && psw && !loginptr)
  532.    {
  533.       loginptr = loginstr;
  534.       strcpy(loginptr, uid);
  535.       strcpy(loginptr + 20, psw);
  536.    }
  537.  
  538.    return(DB_LOGIN(dbnum, loginptr));
  539. }
  540.  
  541.  
  542. /*
  543.  *  Logoff - may be a dummy call for some I/O managers
  544. */
  545. int logoff(fd_sys)
  546. int fd_sys;
  547. {
  548.    return(DB_LOGOFF(fd_sys, NULL));
  549. }
  550.  
  551.  
  552. /*
  553.  *  Start transaction - may be a dummy call for some I/O managers
  554. */
  555. int transact(fd_sys)
  556. int fd_sys;
  557. {
  558.    return(DB_TRANSACT(fd_sys, NULL));
  559. }
  560.  
  561.  
  562. /*
  563.  *  Commit transaction - may be a dummy call for some I/O managers
  564. */
  565. int commit(fd_sys)
  566. int fd_sys;
  567. {
  568.    return(DB_COMMIT(fd_sys, NULL));
  569. }
  570.  
  571.  
  572. /*
  573.  *  Rollback transaction - may be a dummy call for some I/O managers
  574. */
  575. int rollback(fd_sys)
  576. int fd_sys;
  577. {
  578.    return(DB_ROLLBACK(fd_sys, NULL));
  579. }
  580.  
  581.  
  582. /*
  583.  *  General error handling routine
  584.  *  (pass -1 in fd_sys to close all files and exit)
  585. */
  586. int io_error(fd_sys, ernum, errcode, nextpgm)
  587. int fd_sys, ernum;
  588. char *errcode;
  589. char *nextpgm;
  590. {
  591.    int n;
  592.    extern int no_msg;    /* suppresses error messages */
  593.  
  594.    if (!no_msg && (ernum != IOERROR))
  595.    {
  596.       switch(ernum)
  597.       {
  598.          case IONOTRANS :
  599.             errmsg(FileNoTrans_s, fd[fd_sys].filname);
  600.             break;
  601.          case IONONEXT :
  602.             errmsg(FileNoMoreMatch_ss, "target key", fd[fd_sys].filname);
  603.             break;
  604.          case IONOLOCK :
  605.             errmsg(FileNotLocked_s, fd[fd_sys].filname);
  606.             break;
  607.          case IOLOCKED :
  608.             errmsg(FileLocked_s, fd[fd_sys].filname);
  609.             break;
  610.          case IOEOF :
  611.             errmsg(FileEnd_s, fd[fd_sys].filname);
  612.             break;
  613.          case IOTOF :
  614.             errmsg(FileTop_s, fd[fd_sys].filname);
  615.             break;
  616.          case IODUP :
  617.             errmsg(FileDuplKey_ss, "of target", fd[fd_sys].filname);
  618.             break;
  619.          case IONOKEY :
  620.             errmsg(FileNoKey_ss, "of target", fd[fd_sys].filname);
  621.             break;
  622.          case IOINDEXPOSN :
  623.             errmsg(FileDiffKey_s, fd[fd_sys].filname);
  624.             break;
  625.          case IOBADOPEN :
  626.             errmsg(FileNotOpened_s, fd[fd_sys].filname);
  627.             break;
  628.          case IONOFILE :
  629.             errmsg(FileNotFound_s, fd[fd_sys].filname);
  630.             break;
  631.          default :
  632.             errmsg(FileDbgError_sds, fd[fd_sys].filname, ernum, errcode);
  633.       }
  634.    }
  635.  
  636.    if (fd_sys == -1)
  637.    {
  638.       for (n = 0; n < MAX_FILES; n++)
  639.          if (fd[n].active == YES)
  640.             close_file(n++);
  641.       /*close_help();*/
  642.       chain(nextpgm, NULL);
  643.    }
  644.  
  645.    return(ernum);
  646. }
  647.