home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / database / dbase_c.zip / DBASE_C.LBR / DBCLEAN.C < prev    next >
Text File  |  1989-03-20  |  7KB  |  192 lines

  1. /****************************************************************
  2. * db_clean is a utility program for DBASE II files.  It performs*
  3. * the following functions.                                      *
  4. *                                                               *
  5. *    (i)   It strips all non-printing ASCII characters from the *
  6. *          data fields by changing them to blanks.              *
  7. *                                                               *
  8. *    (ii)  It strips all non-printing characters from the status*
  9. *          field except for the CP/M end of file marker (^Z)    *
  10. *          which it replace with a blank unless it is a valid   *
  11. *          end of file mark.                                    *
  12. *                                                               *
  13. *    (iii) It reset the record count in the DBASE file header.  *
  14. *                                                               *
  15. *    (C) Richard Hoffbeck                                 1983  *
  16. ****************************************************************/
  17.  
  18. #include   "libc.h"
  19. #include   "dbase.h"
  20. #define     DB_SECT_SZ   512        /* DBASE uses a 512 byte file buffer */
  21.  
  22. int         maxrec ;
  23. long        char_size ;
  24. DBASE_FILE  *db_ptr ;
  25.  
  26. main(argc,argv)
  27.      char *argv[] ;
  28.      int  argc ;
  29.  
  30.      {char          DONE = FALSE, db_buffer[1000] ;
  31.       int           i = 0, chng = FALSE, bad_eof = 0, bad_char = 0 ;
  32.       long          lseek() ;
  33.  
  34.       if( argc != 2 ){
  35.          help() ;
  36.          exit() ;
  37.       }
  38.  
  39.       else if( (db_ptr = db_open(argv[1])) == ERROR ){
  40.          printf("\n %s NOT FOUND",argv[1]) ;
  41.          exit() ;
  42.       }
  43.  
  44.       char_size = lseek(db_ptr->file_ptr,0L,2) ;
  45.       maxrec = (char_size-DATA_START) / db_ptr->rec_len  ;
  46.       db_seek(db_ptr,1,0) ;
  47.       printf("\nThere are a maximum of %d records",maxrec) ;
  48.       printf("\nProcessing ");
  49.       /*---------- Start of main loop ----------*/
  50.       while( ! DONE  &&  (db_read(db_ptr,db_buffer,1) != ERROR) ) {
  51.          chng = FALSE ;
  52.          if( ++i == maxrec )
  53.            DONE = TRUE ;
  54.          if( (i % 25) == 0 ) 
  55.             putchar('.') ;
  56.          if( db_buffer[0] == CPM_EOF ) {
  57.             if(  valid_eof(i,db_buffer) != FALSE )
  58.                DONE = TRUE ;
  59.             else  {                            /*invalid end of file */
  60.                chng = TRUE ;
  61.                db_buffer[0] = ' ' ;
  62.                bad_eof++ ;
  63.             }
  64.          }
  65.          if( strip(db_buffer,db_ptr->rec_len) > 0 ) {       /*invalid characters reset */
  66.             chng = TRUE ;
  67.             bad_char++ ;
  68.          }
  69.          if( chng == TRUE ) {                                     /*if there were corrections, then */
  70.             db_seek(db_ptr,i,0) ;                                 /* rewrite the record             */
  71.             db_write(db_ptr,db_buffer,1) ;
  72.          }
  73.       }
  74.  
  75.      /*----- finish up the book keeping -----*/
  76.      if( i != db_recnum(db_ptr) ) {
  77.          db_ptr->rec_num = i ;
  78.          db_ptr->chng_ind = TRUE ;
  79.          db_close(db_ptr) ;
  80.       }
  81.       printf("\n\n\n\tThere were %d bad end of file markers removed",bad_eof) ;
  82.       printf("\n\tand %d records with illegal characters were rewritten",bad_char) ;
  83. }
  84.  
  85.  
  86.  
  87. /*********************************************************
  88. * strip(str,len) strips the non-printing ascii characters*
  89. * from the string "str".  First the 8th bit is stripped  *
  90. * from  each  character and then the  following  rule is *
  91. * applied                                                *
  92. *                                                        *
  93. * (i)   If the character is <= 32 (space), except for ^Z *
  94. *       CP/M end of file, it is converted to a space     *
  95. *                                                        *
  96. * (ii)  Any character in the first position other than a *
  97. *       '*' (DBASE deleted record marker), a space or a  *
  98. *       ^Z is reset to a space (NORMAL status)           *
  99. *********************************************************/
  100. strip(buff,len) 
  101.      char buff[] ;
  102.      int  len ;
  103.  
  104.      {int      bad_char ;
  105.      bad_char = 0 ;
  106.  
  107.      /*----- process the last n-1 charaters in the string -----*/
  108.      while ( --len > 0 ) {
  109.         if( buff[len] & 128 ) {
  110.            buff[len] = buff[len] & 127 ;
  111.            bad_char++;
  112.         }
  113.         if( buff[len] < 32 ){
  114.            buff[len] = 32 ;
  115.            bad_char++ ;
  116.          }
  117.      }
  118.  
  119.      if( buff[0] != '*' && buff[0] != ' ' && buff[0] != CPM_EOF ) {
  120.         buff[0] = ' ' ;
  121.         bad_char++ ;
  122.      }
  123.  
  124.      return( bad_char ) ;
  125. }
  126.  
  127.  
  128. /**********************************************
  129. * valid_eof(i) determines whether or not the  *
  130. * CP/M end of file mark encountered in the    *
  131. * status field of the ith record is valid.  It*
  132. * uses the following set of rules :           *
  133. *                                             *
  134. * (i)   If the record is the maximum record in*
  135. *       the file, return TRUE.                *
  136. *                                             *
  137. * (ii)  If the record is not within a DBASE   *
  138. *       buffer size of the end of the file, a *
  139. *       FALSE value is returned               *
  140. *                                             *
  141. * (iii) If no other end of file mark is en-   *
  142. *       countered in the file, return TRUE    *
  143. *                                             *
  144. * (iv)  If two potentially valid EOF marks are*
  145. *       found, the  user is prompted for a    *
  146. *       decision.                             *
  147. **********************************************/
  148. valid_eof(i,buffer) 
  149.      int  i ;
  150.      char buffer[] ;
  151.  
  152.      {int   cur_rec ;
  153.       char  db_buffer[1000], c ;
  154.  
  155.      if( i >= maxrec-1 )
  156.         return( TRUE ) ;
  157.      else if( (i*db_ptr->rec_len+DATA_START) < (char_size-DB_SECT_SZ) )
  158.         return( FALSE ) ;
  159.      else if( strip(buffer,db_ptr->rec_len) > 2)
  160.         return( TRUE ) ;
  161.       else {
  162.          printf("\nUnable to determine whether the end of file mark");
  163.          printf("\nat record #%d is reasonable",i) ;
  164.          printf("\nIs this the end of the file[Y/N]:");
  165.          c = keyin() ;
  166.          if( (c == 'y') || (c == 'Y') )
  167.             return( TRUE ) ;
  168.          else
  169.            return( FALSE ) ;
  170.       } 
  171. }
  172.  
  173. help() {
  174.      puts("DBCLEAN is a utility program for cleaning up DBASE II files.");
  175.      puts("Because of some bugs, DBASE will occasionally place invalid ");
  176.      puts("characters in the record status field or in the data field that");
  177.      puts("efffectively lock up the database.  DBASE is also known to mis-");
  178.      puts("count the records which causes problems with some of the com-");
  179.      puts("mands.  DBCLEAN attempts to repair these damaged DBASE files and");
  180.      puts("the interested user should see the source file DBCLEAN.C for ");
  181.      puts("details."); puts(" ");
  182.      puts("     To use DBCLEAN simply type"); puts(" ");
  183.      puts("       DBCLEAN filename.dbf") ; puts(" ") ;
  184.      puts(">>>>> Caution: DBCLEAN rewrites the database in place so it <<<<<");
  185.      puts(">>>>> should only be used on a copy of your working dataset <<<<<");
  186.      puts(">>>>> until you have a corrected version.                   <<<<<");
  187. }
  188.  
  189.  
  190.  
  191.  
  192.