home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 568a.lha / RexxRMF_v1.1 / rebuildrmfindex.c < prev    next >
C/C++ Source or Header  |  1991-09-11  |  10KB  |  275 lines

  1.  
  2. /*-------------------------------------------------------------------------*
  3.  *                                                                         *
  4.  * Attempts to rebuild Index file from data file.                          *
  5.  *                                                                         *
  6.  * Compile/link under Manx C 5.0d                                          *
  7.  *   cc -hi allprecomp -pp -wnuq -o rebuildrmfindex.o rebuildrmfindex.c    *
  8.  *   ln -o rebuildrmfindex rebuildrmfindex.o -lc                           *
  9.  *                                                                         *
  10.  * Compile/link for Lattice 5.10                                           *
  11.  *     LC -L -Hinclude:allprecomp.q rebuildrmfindex                        *
  12.  *           (pre-compiled header file)                                    *
  13.  *                                                                         *
  14.  *-------------------------------------------------------------------------*/
  15.  
  16. #include "avl.structs.h"
  17.  
  18. int rebuild_index( char *datafile, char *newindex );
  19.  
  20. main( int argc, char *argv[] )
  21. {
  22.     char *oldd,*newi;
  23.     long oldnamelen;
  24.     int noerrs;
  25.  
  26.     if( argc < 2 ) {
  27.         printf("\n Syntax is %s 'name of rmf file'\n",argv[0]);
  28.         exit( 10 );
  29.     }
  30.         
  31.     oldnamelen = strlen(argv[1]) + 50;    
  32.     oldd = AllocMem( oldnamelen, MEMF_CLEAR );
  33.     newi = AllocMem( oldnamelen, MEMF_CLEAR );
  34.     
  35.     strcpy(oldd,argv[1]);
  36.  
  37.     strcpy(newi,argv[1]);
  38.     strcat(newi,".NEW.RMFINDEX");
  39.     
  40.     noerrs = rebuild_index( oldd, newi );
  41.     
  42.     if( noerrs ) {
  43.         printf("\n\n A new index has been created\n");
  44.         printf("     New Index File Name: %s \n",newi);
  45.     }
  46.     else {
  47.         printf("\n\n  Unable to rebuild Index File\n\n");
  48.     }
  49.     
  50.     FreeMem( oldd, oldnamelen );
  51.     FreeMem( newi, oldnamelen );
  52.     
  53. }
  54.  
  55. int rebuild_index( char *datafile, char *newindex )
  56. {
  57.  
  58.      char                  * databuffer, * datapointer;
  59.      struct RecordHeader   * rh;
  60.      struct DataFileHeader * dfh;
  61.      struct DiskIndex      * dtnode;
  62.      struct IndexFile      *ix;
  63.      LONG                  bread,rba;
  64.      LONG                  reclen,totallen;
  65.      LONG newIfile,oldDfile;
  66.      ULONG recordcount;
  67.      int i,j,dlen,kindx;
  68.  
  69.      databuffer  = NULL;
  70.      recordcount = 0;
  71.  
  72.      oldDfile = Open( datafile, MODE_OLDFILE );
  73.      if( !oldDfile ) {
  74.          printf("\n COULD NOT OPEN file %s\n\n",datafile);
  75.          return( FALSE );
  76.      }
  77.  
  78.      newIfile = Open( newindex, MODE_NEWFILE );
  79.      if( !newIfile ) {
  80.          printf("\n COULD NOT CREATED file %s\n\n",newindex);
  81.          Close( oldDfile );
  82.          return( FALSE );
  83.      }    
  84.  
  85.      dtnode = AllocMem( sizeof(struct DiskIndex), MEMF_CLEAR );    
  86.      dfh    = AllocMem( sizeof(struct DataFileHeader), MEMF_CLEAR );    
  87.      rh     = AllocMem( sizeof(struct RecordHeader), MEMF_CLEAR );    
  88.      ix     = AllocMem( sizeof(struct IndexFile), MEMF_CLEAR );    
  89.      
  90.      if( !ix || !rh || !dfh || !dtnode ) { /* a mem alloc. failed */
  91.          printf("\nUnable to allocate memory\n\n");
  92.          if( rh )
  93.              FreeMem(rh,sizeof(struct RecordHeader));
  94.          if( dfh )
  95.              FreeMem(dfh,sizeof(struct DataFileHeader));
  96.          if( dtnode )
  97.              FreeMem(dtnode,sizeof(struct DiskIndex));
  98.          if( ix )
  99.              FreeMem(ix,sizeof(struct IndexFile));
  100.          Close( oldDfile );
  101.          Close( newIfile );
  102.          return( FALSE  );
  103.      }
  104.      
  105.      /* init. and write fixed length IndexHeader info */
  106.      
  107.      for( i = 0; i < MAXINDICES; i++ )
  108.           ix->dups = 1;    /* will allow duplicates */
  109.           
  110.      /* rba_primary must point to the first DI_Info block */
  111.      /* DI_Info always follows IndexHeader                */
  112.      ix->rba_primary = sizeof(struct IndexFile);
  113.      
  114.      Write(newIfile,ix,sizeof(struct IndexFile) );
  115.      
  116.      
  117.      /* read past datafile header */
  118.      bread = Read( oldDfile, dfh, sizeof(struct DataFileHeader) );
  119.      
  120.      /* our current position is where first record is located */
  121.      rba = Seek(oldDfile, 0, OFFSET_CURRENT );    
  122.      rba = Seek(oldDfile, 0, OFFSET_CURRENT );    
  123.      
  124. while( 1 ) {
  125.  
  126.      bread = Read( oldDfile, rh, sizeof(struct RecordHeader) );
  127.      if( bread == 0 ) /* end of file */
  128.          break;
  129.      
  130.      if( bread < sizeof(struct RecordHeader) ) { /* read error */
  131.          Close( oldDfile );
  132.          Close( newIfile );
  133.          FreeMem( rh, sizeof(struct RecordHeader) );
  134.          FreeMem( dfh,sizeof(struct DataFileHeader));
  135.          FreeMem( dtnode,sizeof(struct DiskIndex));
  136.          FreeMem( ix,sizeof(struct IndexFile));
  137.          return( NULL );
  138.      }
  139.      
  140.          
  141.      reclen = rh->recordlength;
  142.      if( reclen <= 0 ) { /* if zero must be a deleted block */
  143.                          /* create deleteindex entry        */     
  144.          dtnode->di_info.recaddr = rba;
  145.          dtnode->di_info.blklength = rh->blocklength;
  146.          dtnode->di_info.recstatus = 'D';
  147.          dtnode->di_info.keylen[0] = 3;
  148.          
  149.          dtnode->keydata[0] = 'z'; /* a dummy key */
  150.          dtnode->keydata[1] = 'd'; /* even the delete index */
  151.          dtnode->keydata[2] = 'r'; /* requires a non-null primary key */
  152.          
  153.          totallen = sizeof(struct DI_Info) + 3;
  154.          Write(newIfile,dtnode,totallen);
  155.          Seek(oldDfile,rh->blocklength,OFFSET_CURRENT);
  156.          rba = Seek(oldDfile, 0, OFFSET_CURRENT );    
  157.          rba = Seek(oldDfile, 0, OFFSET_CURRENT );    
  158.          
  159.          continue; 
  160.      }
  161.      
  162.      /* else assume active data block */
  163.      databuffer = AllocMem( reclen, MEMF_CLEAR );
  164.      datapointer = databuffer;
  165.      if( !databuffer ) {  /* no mem to load data record */
  166.          Close( oldDfile );
  167.          Close( newIfile );
  168.          FreeMem( rh, sizeof(struct RecordHeader) );
  169.          FreeMem( dfh,sizeof(struct DataFileHeader));
  170.          FreeMem( dtnode,sizeof(struct DiskIndex));
  171.          FreeMem( ix,sizeof(struct IndexFile));
  172.          return( NULL );
  173.      }
  174.      
  175.      /* read data record */     
  176.      bread = Read( oldDfile, databuffer, reclen );
  177.      if( bread == 0 ) /* end of file */
  178.          break;
  179.      
  180.      if( bread < reclen ) { /* read error */
  181.          Close( oldDfile );
  182.          Close( newIfile );
  183.          FreeMem( databuffer, reclen );
  184.          FreeMem( rh, sizeof(struct RecordHeader) );
  185.          FreeMem( dfh,sizeof(struct DataFileHeader));
  186.          FreeMem( dtnode,sizeof(struct DiskIndex));
  187.          FreeMem( ix,sizeof(struct IndexFile));
  188.          return( NULL );
  189.      }
  190.      
  191.      
  192.      dlen = strlen(datapointer); /* this is gonna get the length of     */
  193.                                  /* the prime key, its NULL terminated  */
  194.                                  /* the data record is a series of NULL */
  195.                                  /* terminated strings                  */
  196.  
  197.      if( dlen > 0 && dlen < MAXKEYLEN ) { /* valid key length */
  198.      
  199.          dtnode->di_info.recaddr   = rba;
  200.          dtnode->di_info.blklength = rh->blocklength;
  201.          dtnode->di_info.recstatus = 'A';
  202.          dtnode->di_info.keylen[0] = dlen;
  203.  
  204.          kindx = 0;                           
  205.          for( j = 0; j < dlen; j++ )
  206.               dtnode->keydata[kindx++] = *(datapointer+j);
  207.  
  208.          totallen = sizeof(struct DI_Info) + dlen;
  209.          datapointer = ((char *)(ULONG)datapointer + dlen + 1);
  210.  
  211.          for( i = 1; i <= rh->numaltindx; i++ ) {
  212.  
  213.               switch( *datapointer )
  214.                 {
  215.                   case 0xf1:
  216.                   case 0xf2:
  217.                   case 0xf3:
  218.                   case 0xf4:
  219.                   case 0xf5:
  220.                        ++datapointer;
  221.                        dlen = strlen(datapointer);
  222.                        if( dlen > 0 && dlen < MAXKEYLEN ) {
  223.                            dtnode->di_info.keylen[i] = dlen;
  224.                            for( j = 0; j < dlen; j++ )
  225.                                 dtnode->keydata[kindx++] = *(datapointer+j);
  226.                            totallen = totallen + dlen;
  227.                            datapointer = ((char *)(ULONG)datapointer + dlen + 1);
  228.                        }
  229.                 }
  230.          }
  231.  
  232.          Write(newIfile,dtnode,totallen);
  233.          ++recordcount;
  234.      
  235.      }
  236.  
  237.      /* reclen does not include the 4byte Trailer (blocklength does) */
  238.      /* skip over this records trailing null bytes                   */
  239.      Seek(oldDfile,sizeof(struct EOR_Trailer),OFFSET_CURRENT);
  240.      
  241.      rba = Seek(oldDfile,0,OFFSET_CURRENT);  /* just to make sure I  */
  242.      rba = Seek(oldDfile,0,OFFSET_CURRENT);  /* do this twice, Seek  */
  243.                                              /* returns the previous */
  244.                                              /* file position.       */
  245.                                              /* Thus setting RBA for */
  246.                                              /* next record          */
  247.      
  248.      FreeMem(databuffer,reclen);             /* varying length data  */
  249.                                              /* so free each time    */
  250.      
  251. }     
  252.      
  253. /* position to beginning of IndexFile   */     
  254. /* write fixed Index info. back to file */
  255. /* (just making sure)                   */
  256.  
  257. ix->numberofrecords = recordcount;
  258. Seek(newIfile,0,OFFSET_BEGINNING);
  259. Write(newIfile,ix,sizeof(struct IndexFile) );
  260.  
  261. Seek(newIfile,0,OFFSET_END);
  262.  
  263. Close( newIfile );
  264. Close( oldDfile );
  265.  
  266. FreeMem( rh,sizeof(struct RecordHeader));
  267. FreeMem( dfh,sizeof(struct DataFileHeader));
  268. FreeMem( dtnode,sizeof(struct DiskIndex));
  269. FreeMem( ix,sizeof(struct IndexFile));
  270.  
  271. return( TRUE );
  272.      
  273. }
  274.  
  275.