home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c017 / 36.ddi / DBTOC.ZIP / DBTOC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1987-11-18  |  23.7 KB  |  726 lines

  1. /*-------------------------------------------------------------------------
  2.  
  3. *******This source was originally compiled with Lattice C V-3.11**********
  4.  
  5.     These functions have been released into the public domain for
  6.     personal use only.  If you find them of some use or would like to
  7.     use them for commercial purposes please send a donation of
  8.     $15.00 to the address below.  The money will be used to
  9.     finance the BBS run by myself (LOGITEK).  Good luck and happy
  10.     computing !
  11.  
  12.     Paul McDonald
  13.     2200 Columbia Pike
  14.     Apt. 917
  15.     Arlington Va. 22204
  16.  
  17.  
  18. ---------------------------------------------------------------------------
  19.     Name:     DBTOC
  20.  
  21.     Description:   This file contains the basic routines to read/write
  22.                    dbase III files.  A good understanding of the functions
  23.                    can be gained by studying the header file DBASE.H, which
  24.                    defines the data structures used.
  25.  
  26.     Date                     Author                   Explanation
  27.  ------------           -----------------        --------------------
  28.     11/18/87            Paul McDonald              Original Author
  29.  
  30.  
  31. ----------------------------------------------------------------------------*/
  32. #include "\lc\header\stdlib.h"
  33. #include "\switch\c\dbase.h"
  34.  
  35. #define  NULL 0
  36. #define  ERROR -1
  37.  
  38. /*---------------------------------------------------------------------------
  39.     Name:     OPENDBF
  40.     Description:   Opens a dbf file as r/w file, fills in the structure info
  41.                    and returns a pointer to the DBF structure.
  42. -----------------------------------------------------------------------------*/
  43.  
  44. DBF *opendbf(filename)
  45.  
  46.     char *filename;
  47. {
  48.  
  49.     char *getmem();
  50.     FIELD     *current;
  51.  
  52.     DBF  *tmp_ptr;
  53.     long offset;
  54.     int  cntr;
  55.  
  56.  
  57.     /* attempt memory allocation for header struct */
  58.     if(!(tmp_ptr = (DBF *)getmem(sizeof(DBF)))){
  59.          return(NULL);
  60.     }
  61.  
  62.      
  63.     if( (tmp_ptr->fh = o_pen(filename,2) ) == ERROR)           /* attempt to open the file for read/write access */
  64.          return(NULL);
  65.     cntr = 0;
  66.  
  67.     while(filename[cntr])
  68.          tmp_ptr->filename[cntr] = filename[cntr++];
  69.     tmp_ptr->filename[cntr] = 0;
  70.  
  71.     offset = 0;         /* start from top of file */
  72.  
  73.     l_seek(tmp_ptr->fh,offset,0);      
  74.  
  75.     r_ead(tmp_ptr->fh,&(tmp_ptr->header),sizeof(DBF_HEAD)); /* fill in the header struct from the file */
  76.  
  77.     tmp_ptr->no_fields = ((tmp_ptr->header.head_len - 1)/32 - 1);
  78.  
  79.     /* allocate memory for the first field structure */
  80.  
  81.     if( ! ( tmp_ptr->fields = (FIELD *)getmem(sizeof(FIELD) ) ) )
  82.          printstr(0,0,"ERROR ALLOCATING MEMORY !!!");                     
  83.  
  84.     r_ead(tmp_ptr->fh,tmp_ptr->fields,32);       /* read in the first field */
  85.     tmp_ptr->fields->prev = (FIELD *)0L;         /* start the list */
  86.     current = tmp_ptr->fields;                   /* current node on the list */
  87.     current->offset = 0L;                        /* first field is at offset 0 */
  88.     offset = current->fld_len;
  89.                                                  /* allocate space for the fields actual value */
  90.     if(current->type != 'D'){
  91.          if( !(current->fld_val = getmem(current->fld_len + 1)))
  92.               printstr(0,0,"ERROR ALLOCATING MEMORY !!");       
  93.     }else{                                                       /* for dates allocate space for the slashes */
  94.           if( !(current->fld_val = getmem(current->fld_len + 3)))
  95.               printstr(0,0,"ERROR ALLOCATING MEMORY !!");       
  96.     }
  97.                                   /* make the rest of the list */
  98.     for(cntr = 1; cntr < tmp_ptr->no_fields; ++cntr){
  99.          if( ! ( current->next = (FIELD *)getmem( sizeof(FIELD) ) ) )
  100.               printstr(0,0,"ERROR ALLOCATING MEMORY !!!");                     
  101.          r_ead(tmp_ptr->fh,current->next,32);
  102.          current->next->prev = current;
  103.          current = current->next;
  104.          current->offset = offset;          /* offset of this field from beg. of the record */
  105.                                             /* allocate space for the fields actual value */
  106.          if(current->type != 'D'){
  107.               if( !(current->fld_val = getmem(current->fld_len + 1)))
  108.                    printstr(0,0,"ERROR ALLOCATING MEMORY !!");      
  109.          }else{                                                       /* for dates allocate space for the slashes */
  110.               if( !(current->fld_val = getmem(current->fld_len + 3)))
  111.                    printstr(0,0,"ERROR ALLOCATING MEMORY !!");       
  112.          }
  113.  
  114.          offset += current->fld_len;        /* update next fields offset in record */
  115.     }
  116.     current->next = (FIELD *)0L;       /* end of list = NULL */
  117.  
  118. /* allocate memory for the record buffer and read the first record */
  119.     if(!(tmp_ptr->record = getmem(tmp_ptr->header.rec_len)))
  120.          printstr(0,0,"ERROR ALLOCATING MEMORY !!!");
  121.  
  122.     tmp_ptr->curr_rec = 0;
  123.     tmp_ptr->updated = 0;         /* set the updated flag to false */
  124.     return(tmp_ptr);
  125.  
  126. }
  127.  
  128. /*-----------------------------------------------------------------------------
  129.     Name:     READREC() 
  130.  
  131.     Description: - returns the given record in the DBF structure
  132.                    will return 1 if successful, 0 if rec not in DBF.
  133.                    -1 if read error;
  134.  
  135.     Syntax:   success = readrec(dbf_ptr,rec_num)
  136.               DBF  *dbf_ptr;
  137.               long rec_num;
  138. ------------------------------------------------------------------------------*/
  139.  
  140. int readrec(dbf_ptr,rec_num)
  141.  
  142.     DBF  *dbf_ptr;
  143.     unsigned long rec_num;
  144. {
  145.  
  146. long     offset;
  147.  
  148.     if(rec_num > dbf_ptr->header.no_recs)
  149.          return(0);
  150.  
  151.     offset = dbf_ptr->header.head_len + ((rec_num - 1) * dbf_ptr->header.rec_len);
  152.  
  153.     l_seek(dbf_ptr->fh,offset,0);
  154.  
  155.     if( r_ead(dbf_ptr->fh,dbf_ptr->record,dbf_ptr->header.rec_len) < dbf_ptr->header.rec_len)
  156.          return(-1);
  157.     else
  158.          readbuf(dbf_ptr);        /* read the i/o buffer and put the values
  159.                                      in the indiv. field buffers */
  160.     dbf_ptr->curr_rec = rec_num;
  161.  
  162.     return(1);
  163. }
  164.  
  165.                                                                                
  166. /*-----------------------------------------------------------------------------
  167.     Name:     WRITEREC() 
  168.  
  169.     Description: - writes record that is contained in the current record
  170.                    structure to the specified record.
  171.                    0 if record not found in dbf
  172.                    1 if successfull
  173.                    -1 if write error.
  174.  
  175.     Syntax:   success = writerec(dbf_ptr,rec_num)
  176.               DBF  *dbf_ptr;
  177.               long rec_num;
  178. ------------------------------------------------------------------------------*/
  179.  
  180. int writerec(dbf_ptr,rec_num)
  181.  
  182.     DBF  *dbf_ptr;
  183.     unsigned long rec_num;
  184. {
  185.  
  186. long     offset;
  187.  
  188.     if(rec_num > dbf_ptr->header.no_recs || rec_num < 1)
  189.          return(0);
  190.  
  191.     offset = dbf_ptr->header.head_len + ((rec_num - 1) * dbf_ptr->header.rec_len);
  192.     l_seek(dbf_ptr->fh,offset,0);
  193.  
  194.     writebuf(dbf_ptr);                 /* write the buffers back to the x-fer area */
  195.  
  196.     if( w_rite(dbf_ptr->fh,dbf_ptr->record,dbf_ptr->header.rec_len) < dbf_ptr->header.rec_len)
  197.          return(-1);
  198.     dbf_ptr->curr_rec = rec_num;
  199.     dbf_ptr->updated = 1;
  200.     return(1);
  201. }
  202.  
  203.                                                                                
  204. /*----------------------------------------------------------------------------
  205.     Name:     READBUF()
  206.  
  207.     Description:   Reads the record buffer and places the individual 
  208.                    field values in each fields buffer area.
  209.     Syntax:   readbuf(dbf_ptr);
  210.               DBF  *dbf_ptr;
  211. ---------------------------------------------------------------------------*/
  212. int readbuf(dbf_ptr)
  213.     DBF  *dbf_ptr;
  214. {
  215.  
  216. int cntr,
  217.     buf_ptr,
  218.     fld_buf;
  219.  
  220. FIELD    *work_ptr;
  221.  
  222.     work_ptr = dbf_ptr->fields;   /* get pointer to first field */
  223.     buf_ptr = 1;                  /* start at the second char of the buffer,
  224.                                      the first char is the logical deleted,
  225.                                      character either '*' or ' ' */
  226.     if(dbf_ptr->record[0] == '*')
  227.          dbf_ptr->deleted = 1;
  228.     else
  229.          dbf_ptr->deleted = 0;
  230.  
  231.     for(cntr = 0; cntr< dbf_ptr->no_fields; ++cntr){
  232.          fld_buf = 0;
  233.  
  234.          while(fld_buf < work_ptr->fld_len)
  235.               work_ptr->fld_val[fld_buf++] = dbf_ptr->record[buf_ptr++];
  236.  
  237.          work_ptr->fld_val[fld_buf] = 0;         /* put NULL at end */
  238.  
  239.          work_ptr = work_ptr->next;              /* goto next field */
  240.  
  241.     }
  242.  
  243.     return(0);
  244.  
  245. }
  246.  
  247.  
  248. /*----------------------------------------------------------------------------
  249.     Name:     WRITEBUF()
  250.  
  251.     Description:   Writes the record buffer and places the individual 
  252.                    field values in the record buffer.
  253.     Syntax:   writebuf(dbf_ptr);
  254.               DBF  *dbf_ptr;
  255. ---------------------------------------------------------------------------*/
  256. int writebuf(dbf_ptr)
  257.     DBF  *dbf_ptr;
  258. {
  259.  
  260. int cntr,
  261.     buf_ptr,
  262.     fld_buf;
  263. char     null_flg;
  264.  
  265. FIELD    *work_ptr;
  266.  
  267.     work_ptr = dbf_ptr->fields;   /* get pointer to first field */
  268.     buf_ptr = 1;                  /* start at the second character, first is
  269.                                      the deletion marker */
  270.  
  271.     for(cntr = 0; cntr< dbf_ptr->no_fields; ++cntr){
  272.          fld_buf = 0;
  273.          null_flg = 0;            /* if end of valid data in fld buff is hit */
  274.  
  275.          while(fld_buf < work_ptr->fld_len){
  276.               if(!work_ptr->fld_val[fld_buf])
  277.                    null_flg = 1;
  278.               if(!null_flg)
  279.                    dbf_ptr->record[buf_ptr++] = work_ptr->fld_val[fld_buf++];
  280.               else
  281.                    dbf_ptr->record[buf_ptr++] = ' ';  /* pad with spaces */
  282.          }
  283.  
  284.          work_ptr = work_ptr->next;              /* goto next field */
  285.  
  286.     }
  287.  
  288. return(0);
  289.  
  290. }
  291.  
  292.  
  293. /*--------------------------------------------------------------------------
  294.     Name:     APPEND()
  295.  
  296.     Description:   Adds a record to a dbase file, the entire record is filled
  297.                    with spaces to initialize it.
  298.     Syntax:   int  append(dbf_ptr)
  299.                    DBF  *dbf_ptr;
  300.               returns   1 - successful
  301.                         -1 - disk i/o
  302. ---------------------------------------------------------------------------*/
  303. int append(dbf_ptr)
  304.  
  305.     DBF  *dbf_ptr;
  306. {
  307.  
  308. unsigned int cntr;
  309. long     offset;
  310. char     eof_mark;
  311.  
  312.     eof_mark = 26;
  313.  
  314.     for(cntr=0; cntr < dbf_ptr->header.rec_len;++cntr)
  315.          dbf_ptr->record[cntr] = 0x20;                /* fill with spaces */
  316.  
  317.     offset = dbf_ptr->header.head_len + ((dbf_ptr->header.no_recs) * dbf_ptr->header.rec_len);
  318.     l_seek(dbf_ptr->fh,offset,0);
  319.  
  320.  
  321.     if( (w_rite(dbf_ptr->fh,dbf_ptr->record,dbf_ptr->header.rec_len)) < dbf_ptr->header.rec_len)
  322.          return(-1);    /* error writing to disk */
  323.  
  324.     ++(dbf_ptr->header.no_recs);
  325.     dbf_ptr->curr_rec = dbf_ptr->header.no_recs;
  326.  
  327.     offset += (dbf_ptr->header.rec_len);
  328.     l_seek(dbf_ptr->fh,offset,0);           /* goto new EOF */
  329.     w_rite(dbf_ptr->fh,&eof_mark,1);        /* put eof marker at eof */
  330.  
  331.     readrec(dbf_ptr,dbf_ptr->curr_rec);     /* read in the new record */
  332.  
  333.     return(1);     /* success */
  334.  
  335. }
  336. /*---------------------------------------------------------------------------
  337.     Name:     CLOSEDBF()
  338.  
  339.     Description:   Closes the dbf file updateing the header info.
  340.  
  341.     Syntax:   closedbf(dbf_ptr);
  342.               DBF  *dbf_ptr;
  343. ----------------------------------------------------------------------------*/
  344. int closedbf(dbf_ptr)
  345.  
  346.     DBF  *dbf_ptr;
  347. {
  348.     
  349. FIELD    *tmpfield,
  350.          *workptr;
  351. unsigned int  packdate,
  352.               sysdate();
  353.  
  354.  
  355.     if(dbf_ptr->updated){
  356.          packdate = sysdate();         /* get the system date */
  357.          dbf_ptr->header.dd = packdate & 0x001f;           /* update file date */
  358.          dbf_ptr->header.mm = (packdate >> 5) & 0x000f;
  359.          dbf_ptr->header.yy = (packdate >> 9) + 80;
  360.     }
  361.  
  362.     l_seek(dbf_ptr->fh,(long)0,0);     /* go to BOF */
  363.                                        /* write updated header to disk */
  364.  
  365.     w_rite(dbf_ptr->fh,&(dbf_ptr->header),sizeof(DBF_HEAD));
  366.  
  367.     c_lose(dbf_ptr->fh);
  368.  
  369.     tmpfield = dbf_ptr->fields;
  370.  
  371.     workptr = tmpfield;
  372.     while(workptr){
  373.          workptr = tmpfield->next;
  374.          rlsmem(tmpfield->fld_val,tmpfield->fld_len + 1);
  375.          rlsmem((char *)tmpfield,sizeof(FIELD));
  376.          tmpfield = workptr;
  377.     }
  378.  
  379.     rlsmem(dbf_ptr->record,dbf_ptr->header.rec_len);
  380.     rlsmem((char *)dbf_ptr,sizeof(DBF));
  381.  
  382.     return(0);
  383. }
  384.  
  385. /*-----------------------------------------------------------------------------
  386.     Name:     DELETE()
  387.  
  388.     Description:   Logically deletes the given record
  389.  
  390.     Syntax:        success = delete(dbf_ptr,rec_num)
  391.               DBF  *dbf_ptr;
  392.               long rec_num;
  393.               int  success   - 1 = successful
  394.                                0 = record not found
  395.                              (-1) = File i/o error
  396. ---------------------------------------------------------------------------*/
  397. int delete(dbf_ptr,rec_num)
  398.  
  399.     DBF  *dbf_ptr;
  400.     long rec_num;
  401. {
  402.  
  403. long     offset;
  404.  
  405.     if(dbf_ptr->header.no_recs < rec_num)
  406.          return(0);
  407.  
  408.     dbf_ptr->curr_rec = rec_num;
  409.     dbf_ptr->deleted = 1;
  410.  
  411.     offset = dbf_ptr->header.head_len + ((rec_num - 1) * dbf_ptr->header.rec_len);
  412.     l_seek(dbf_ptr->fh,offset,0);      /* seek to the record */
  413.  
  414.     if(w_rite(dbf_ptr->fh,"*",1) != 1)      /* an asterisk logically deletes the record */
  415.          return(-1);    /* must be a file i/o error */
  416.     else
  417.          return(1);     /* it worked */
  418.  
  419. }
  420.  
  421. /*-----------------------------------------------------------------------------
  422.     Name:     UNDELETE()
  423.  
  424.     Description:   Logically undeletes the given record
  425.  
  426.     Syntax:        success = undelete(dbf_ptr,rec_num)
  427.               DBF  *dbf_ptr;
  428.               long rec_num;
  429.               int  success   - 1 = successful
  430.                                0 = record not found
  431.                              (-1) = File i/o error
  432. ---------------------------------------------------------------------------*/
  433. int undelete(dbf_ptr,rec_num)
  434.  
  435.     DBF  *dbf_ptr;
  436.     long rec_num;
  437. {
  438.  
  439. long     offset;
  440.  
  441.     if(dbf_ptr->header.no_recs < rec_num)
  442.          return(0);
  443.  
  444.     dbf_ptr->curr_rec = rec_num;       /* this becomes the curr record */
  445.     dbf_ptr->deleted = 0;              /* reset deleted flag */
  446.  
  447.     offset = dbf_ptr->header.head_len + ((rec_num - 1) * dbf_ptr->header.rec_len);
  448.     l_seek(dbf_ptr->fh,offset,0);      /* seek to the record */
  449.  
  450.     if(w_rite(dbf_ptr->fh," ",1) != 1)      /* clear the asterisk */
  451.          return(-1);    /* must be a file i/o error */
  452.     else
  453.          return(1);     /* it worked */
  454.  
  455. }
  456.  
  457. /*---------------------------------------------------------------------------
  458.     Name:     MAKHEAD()
  459.  
  460.     Description:   This function creates the first part of the dbf's header
  461.                    on disk, subsequent calls to ADDFIELD() will allow you to
  462.                    customize the rest of the header to your needs.
  463. ----------------------------------------------------------------------------*/
  464. DBF  *makhead(filename)
  465.  
  466.     char *filename;
  467. {
  468.  
  469.     char *getmem();
  470.     DBF  *tmp_ptr;
  471.     long offset;
  472.     int  cntr;
  473.     unsigned int   packdate,
  474.                    sysdate();
  475.  
  476.     /* attempt memory allocation for header struct */
  477.  
  478.     if(!(tmp_ptr = (DBF *)getmem(sizeof(DBF)))){
  479.          return(NULL);
  480.     }
  481.     if( (tmp_ptr->fh = c_reate(filename,0) ) == ERROR)           /* create file with NO special attributes */
  482.          return(NULL);
  483.     cntr = 0;
  484.     while(filename[cntr])
  485.          tmp_ptr->filename[cntr] = filename[cntr++];
  486.     tmp_ptr->filename[cntr] = 0;
  487.  
  488.     tmp_ptr->header.vers = 3;
  489.     tmp_ptr->header.no_recs = 0;
  490.     tmp_ptr->header.head_len = sizeof(DBF_HEAD);
  491.     tmp_ptr->header.rec_len = 0;       /* account for logical deletion char */
  492.     for(cntr=0; cntr<20; ++cntr)
  493.          tmp_ptr->header.reserved[cntr] = 0;     /* clear out the reserved area */
  494.  
  495.     packdate = sysdate();         /* get the system date */
  496.     tmp_ptr->header.dd = packdate & 0x001f;
  497.     tmp_ptr->header.mm = (packdate >> 5) & 0x000f;
  498.     tmp_ptr->header.yy = (packdate >> 9) + 80;
  499.  
  500.     offset = 0;                        /* write the structure to disk */
  501.     l_seek(tmp_ptr->fh,offset,0);
  502.     w_rite(tmp_ptr->fh,&(tmp_ptr->header),sizeof(DBF_HEAD));
  503.  
  504.     tmp_ptr->fields = NULL;
  505.     tmp_ptr->curr_rec = 0;
  506.     tmp_ptr->record = NULL;       /* no record buffer allocated yet */
  507.     tmp_ptr->no_fields = 0;
  508.  
  509.     return(tmp_ptr);
  510.  
  511. }
  512.  
  513. /*-----------------------------------------------------------------------------
  514.     Name:     ADDFIELD()
  515.  
  516.     Description:   Adds a field descriptor structure to the structure
  517.                    already written to disk.  This function ONLY works
  518.                    for files that have NO records in them.
  519.     Syntax:   int  addfield(dbf_ptr,fieldname,type,length,dec_cnt)
  520.                    DBF  *dbf_ptr;
  521.                    char *fieldname,
  522.                         type;
  523.                    int  length,
  524.                         dec_cnt;
  525.          returns 1 - successful
  526.                  0 - improper field type
  527.                 -1 - file i/o error, or memory error
  528.  
  529.  
  530.     Note:     This function has NOT been tested !!
  531.  
  532. ------------------------------------------------------------------------------*/
  533. int addfield(dbf_ptr,fieldname,type,length,dec_cnt)
  534.  
  535.     DBF  *dbf_ptr;
  536.     char *fieldname,
  537.          type;
  538.     unsigned int   length,
  539.                    dec_cnt;
  540.  
  541. {
  542.  
  543.     char *getmem(),
  544.          cr_ret[2];
  545.     FIELD     *tempptr,
  546.               *workptr;
  547.     long offset;
  548.     int  cntr;
  549.     unsigned int   packdate,
  550.                    sysdate();
  551.  
  552.                                      /* allocate memory for the field descriptor */
  553.      if(!(tempptr = (FIELD *)getmem(sizeof(FIELD)))){
  554.               return(NULL);
  555.      }
  556.  
  557.     for(cntr = 0; cntr < 11 && fieldname[cntr]; ++cntr)
  558.          tempptr->name[cntr] = fieldname[cntr];
  559.     if(cntr < 10)
  560.          while(cntr < 12)                   /* padd with nulls */
  561.               tempptr->name[cntr++] = 0;
  562.                                             /* check for proper field type */
  563.     if(type != 'C' && type != 'D' && type != 'N'  && type != 'L'){
  564.          rlsmem((char *)tempptr,sizeof(FIELD));
  565.          return(0);
  566.     }
  567.  
  568.     tempptr->type = type;
  569.     tempptr->next = NULL;
  570.     tempptr->prev = NULL;
  571.     tempptr->fld_len = length;
  572.     tempptr->decimals = dec_cnt;
  573.     tempptr->offset = 0;
  574.     tempptr->fld_val = 0;
  575.  
  576.     if(dbf_ptr->no_fields ==0)
  577.          offset = 0;
  578.     else
  579.          offset = -2;              /* write over the CR and EOF marker at the end of the field space */
  580.  
  581.          l_seek(dbf_ptr->fh,offset,2);
  582.                                        /* write the field descriptor to disk */
  583.  
  584.     if( (w_rite(dbf_ptr->fh,tempptr,sizeof(FIELD))) != sizeof(FIELD) )
  585.          return(-1);                                  /* error writing to file */
  586.                                                       /* allocate space for
  587.                                                       actual field value */
  588.     if( !(tempptr->fld_val = getmem(length + 1)))
  589.          return(-1);
  590.     tempptr->offset = dbf_ptr->header.rec_len+1;      /* offset of field in the record */
  591.  
  592.     dbf_ptr->header.head_len += sizeof(FIELD);
  593.     if(dbf_ptr->record)      /* release current rec buffer if allocated */
  594.          rlsmem(dbf_ptr->record,dbf_ptr->header.rec_len); 
  595.     dbf_ptr->header.rec_len += length;      /* update header info */
  596.     ++dbf_ptr->no_fields;
  597.                                        /* allocate memory for a new rec buffer */
  598.     if(!(dbf_ptr->record = getmem(dbf_ptr->header.rec_len)))
  599.          return(-1);         /* out of memory !!! */
  600.  
  601.     if(!dbf_ptr->fields){              /* add this field descriptor to the linked list */
  602.          dbf_ptr->fields = tempptr;
  603.          tempptr->next = NULL;
  604.          tempptr->prev = NULL;
  605.     }else{
  606.          workptr = dbf_ptr->fields;
  607.          while(workptr->next)
  608.               workptr = workptr->next;
  609.  
  610.          workptr->next = tempptr;
  611.          tempptr->prev = workptr;
  612.          tempptr->next = NULL;
  613.     }     
  614.  
  615.     packdate = sysdate();         /* get the system date */
  616.     dbf_ptr->header.dd = packdate & 0x001f;           /* update file date */
  617.     dbf_ptr->header.mm = (packdate >> 5) & 0x000f;
  618.     dbf_ptr->header.yy = (packdate >> 9) + 80;
  619.  
  620.     l_seek(dbf_ptr->fh,offset,0);      /* goto top of file and rewrite header info */
  621.  
  622.     if( (w_rite(dbf_ptr->fh,&(dbf_ptr->header),sizeof(DBF_HEAD))) != sizeof(DBF_HEAD) )
  623.          return(-1);
  624.     
  625.     cr_ret[0] = 13;          /* CR marks as a field delimeter */
  626.     cr_ret[1] = 26;          /* EOF marker */
  627.     offset = 0;
  628.     l_seek(dbf_ptr->fh,offset,2);      /* goto EOF */
  629.     if( (w_rite(dbf_ptr->fh,cr_ret,2)) != 2  ) 
  630.               return(-1);   
  631.  
  632.     return(1);
  633.  
  634. }
  635. /*---------------------------------------------------------------------------
  636.     Name:     ZAP()
  637.  
  638.     Description:   Deletes all records in a dbf file
  639.  
  640.     Syntax:   int  zap(dbf_ptr)
  641.               DBF  *dbf_ptr;
  642.               returns   1 - successful
  643.                        -1 - file i/o error
  644. ---------------------------------------------------------------------------*/
  645. int  zap(dbf_ptr)
  646.     DBF  *dbf_ptr;
  647. {
  648.  
  649.     long offset;
  650.     unsigned int   packdate,
  651.                    sysdate(),
  652.                    tmpoff;
  653.  
  654.     FIELD     *workptr,
  655.               *tmpprev,
  656.               *tmpnext;
  657.     char      *tmpval,
  658.               cr_ret[2];
  659.  
  660.     char nulls[4];
  661.     int  cntr;
  662.  
  663.     for(cntr=0; cntr<4; ++cntr)        /* bytes to write at end of each field descriptor */
  664.          *(nulls+cntr) = NULL;
  665.  
  666.     if(c_lose(dbf_ptr->fh))          /* close the file */
  667.          return(-1);
  668.  
  669.     if(_del(dbf_ptr->filename))
  670.          return(-1);              /* delete the file */
  671.  
  672.     if( ( dbf_ptr->fh = c_reate(dbf_ptr->filename,0)) < 0)
  673.          return(-1);
  674.  
  675.     dbf_ptr->curr_rec = 0;
  676.     dbf_ptr->header.no_recs = 0;
  677.  
  678.     packdate = sysdate();         /* get the system date */
  679.     dbf_ptr->header.dd = packdate & 0x001f;           /* update file date */
  680.     dbf_ptr->header.mm = (packdate >> 5) & 0x000f;
  681.     dbf_ptr->header.yy = (packdate >> 9) + 80;
  682.  
  683.     offset = 0;
  684.     l_seek(dbf_ptr->fh,offset,0);      /* goto top of file and rewrite header info */
  685.  
  686.     if( (w_rite(dbf_ptr->fh,&(dbf_ptr->header),sizeof(DBF_HEAD))) != sizeof(DBF_HEAD) )
  687.          return(-1);
  688.  
  689.  
  690.  
  691.     workptr = dbf_ptr->fields;         /* pointer to list of field descriptors */
  692.  
  693.     for(cntr=0;cntr<dbf_ptr->no_fields; ++cntr){
  694.          offset = 0;
  695.          l_seek(dbf_ptr->fh,offset,2);      /* goto EOF */
  696.          tmpprev = workptr->prev;
  697.          tmpnext = workptr->next;
  698.          tmpoff = workptr->offset;
  699.          tmpval = workptr->fld_val;
  700.  
  701.          workptr->prev = NULL;
  702.          workptr->next = NULL;         /* clear these areas, as they are reserved */
  703.          workptr->offset = 0;
  704.          workptr->fld_val = 0;
  705.  
  706.          if( (w_rite(dbf_ptr->fh,workptr,(sizeof(FIELD))) ) < (sizeof(FIELD)) ) 
  707.               return(-1);
  708.  
  709.          workptr->prev = tmpprev;
  710.          workptr->next = tmpnext;
  711.          workptr->offset = tmpoff;          /* reset the pointers,values */
  712.          workptr->fld_val = tmpval;
  713.  
  714.          workptr=workptr->next;
  715.     }
  716.     cr_ret[0] = 13;          /* CR marks as a field delimeter */
  717.     cr_ret[1] = 26;          /* EOF marker */
  718.     offset = 0;
  719.     l_seek(dbf_ptr->fh,offset,2);      /* goto EOF */
  720.     if( (w_rite(dbf_ptr->fh,cr_ret,2)) != 2  ) 
  721.               return(-1);   
  722.  
  723.     return(1);
  724. }
  725.  
  726.