home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume20 / index-db / part01 / dbio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-23  |  5.0 KB  |  266 lines

  1. #ifndef lint
  2. static char *RCSid = "$Header: /u5/davy/progs/index/RCS/dbio.c,v 1.1 89/08/09 11:06:36 davy Exp $";
  3. #endif
  4. /*
  5.  * dbio.c - database input/output routines.
  6.  *
  7.  * David A. Curry
  8.  * Research Institute for Advanced Computer Science
  9.  * Mail Stop 230-5
  10.  * NASA Ames Research Center
  11.  * Moffett Field, CA 94035
  12.  * davy@riacs.edu
  13.  *
  14.  * $Log:    dbio.c,v $
  15.  * Revision 1.1  89/08/09  11:06:36  davy
  16.  * Initial revision
  17.  * 
  18.  */
  19. #include <sys/param.h>
  20. #include <sys/stat.h>
  21. #include <curses.h>
  22. #include <stdio.h>
  23. #include "defs.h"
  24.  
  25. struct    dbfile *db;        /* array of database entries        */
  26. struct    idxfile idx;        /* description of the database file    */
  27.  
  28. int    dbmodified = 0;        /* non-zero if database needs saving    */
  29. int    dbentries, dbsize;    /* number of entries, size of db array    */
  30.  
  31. /*
  32.  * read_idxfile - read the database description file.
  33.  */
  34. read_idxfile(dbname)
  35. char *dbname;
  36. {
  37.     FILE *fp;
  38.     register int len;
  39.     char buf[BUFSIZ], idxfile[MAXPATHLEN];
  40.  
  41.     /*
  42.      * Construct the file name.
  43.      */
  44.     sprintf(idxfile, "%s/%s%s", dbasedir, dbname, IDXFILE_SUFFIX);
  45.  
  46.     /*
  47.      * Open the file.
  48.      */
  49.     if ((fp = fopen(idxfile, "r")) == NULL) {
  50.         error("%s: cannot open \"%s\".\n", pname, idxfile, 0);
  51.         exit(1);
  52.     }
  53.  
  54.     /*
  55.      * Zero out the structure.
  56.      */
  57.     bzero(&idx, sizeof(struct idxfile));
  58.  
  59.     /*
  60.      * Read lines from the file.
  61.      */
  62.     while (idx.idx_nlines < MAXDBLINES) {
  63.         /*
  64.          * End of file.
  65.          */
  66.         if (fgets(buf, sizeof(buf), fp) == NULL)
  67.             break;
  68.  
  69.         /*
  70.          * Strip the newline.
  71.          */
  72.         len = strlen(buf) - 1;
  73.         buf[len] = '\0';
  74.  
  75.         /*
  76.          * If the first character is '!', then this line
  77.          * should not participate in searches.  Save the
  78.          * stuff after the '!'.  Otherwise this line does
  79.          * participate in searches, save the whole line.
  80.          */
  81.         if (*buf == '!') {
  82.             idx.idx_lines[idx.idx_nlines] = savestr(buf+1);
  83.             idx.idx_search[idx.idx_nlines] = 0;
  84.             len--;
  85.         }
  86.         else {
  87.             idx.idx_lines[idx.idx_nlines] = savestr(buf);
  88.             idx.idx_search[idx.idx_nlines] = 1;
  89.         }
  90.  
  91.         /*
  92.          * Increment the number of lines.
  93.          */
  94.         idx.idx_nlines++;
  95.  
  96.         /*
  97.          * Save the length of the longest field name.
  98.          */
  99.         if (len > idx.idx_maxlen)
  100.             idx.idx_maxlen = len;
  101.     }
  102.  
  103.     /*
  104.      * Close the file.
  105.      */
  106.     fclose(fp);
  107. }
  108.  
  109. /*
  110.  * read_dbfile - read the database file itself.
  111.  */
  112. read_dbfile(dbname)
  113. char *dbname;
  114. {
  115.     FILE *fp;
  116.     register int i;
  117.     struct dbfile *malloc(), *realloc();
  118.     char buf[BUFSIZ], dbfile[MAXPATHLEN];
  119.  
  120.     /*
  121.      * Allocate some entries in the array.  16 is just an
  122.      * arbitrary number.
  123.      */
  124.     dbsize = 16;
  125.     dbentries = 0;
  126.  
  127.     if ((db = malloc(dbsize * sizeof(struct dbfile))) == NULL) {
  128.         error("%s: out of memory.\n", pname, 0, 0);
  129.         exit(1);
  130.     }
  131.  
  132.     /*
  133.      * Construct the name of the file.
  134.      */
  135.     sprintf(dbfile, "%s/%s%s", dbasedir, dbname, DBFILE_SUFFIX);
  136.  
  137.     /*
  138.      * Open the file.
  139.      */
  140.     if ((fp = fopen(dbfile, "r")) == NULL)
  141.         return;
  142.  
  143.     /*
  144.      * Until we hit end of file...
  145.      */
  146.     while (!feof(fp)) {
  147.         /*
  148.          * If we need to, allocate some more entries.
  149.          */
  150.         if (dbentries >= dbsize) {
  151.             dbsize *= 2;
  152.             db = realloc(db, dbsize * sizeof(struct dbfile));
  153.  
  154.             if (db == NULL) {
  155.                 error("%s: out of memory.\n", pname, 0, 0);
  156.                 exit(1);
  157.             }
  158.         }
  159.  
  160.         /*
  161.          * Read in one entry at a time.
  162.          */
  163.         for (i = 0; i < idx.idx_nlines; i++) {
  164.             /*
  165.              * If we hit end of file before getting a
  166.              * complete entry, toss this one.
  167.              */
  168.             if (fgets(buf, sizeof(buf), fp) == NULL)
  169.                 goto out;
  170.  
  171.             /*
  172.              * Save the length of the line, strip the
  173.              * newline, and save the line.
  174.              */
  175.             db[dbentries].db_lens[i] = strlen(buf) - 1;
  176.             buf[db[dbentries].db_lens[i]] = '\0';
  177.  
  178.             db[dbentries].db_lines[i] = savestr(buf);
  179.         }
  180.  
  181.         /*
  182.          * Mark this entry as valid and increase the
  183.          * number of entries.
  184.          */
  185.         db[dbentries].db_flag = DB_VALID;
  186.         dbentries++;
  187.     }
  188.  
  189. out:
  190.     /*
  191.      * Make sure what we've got is sorted.
  192.      */
  193.     qsort(db, dbentries, sizeof(struct dbfile), dbsort);
  194.  
  195.     fclose(fp);
  196. }
  197.  
  198. /*
  199.  * save_db - save the database to disk.
  200.  */
  201. save_db(dbname)
  202. char *dbname;
  203. {
  204.     FILE *fp;
  205.     struct stat st;
  206.     register int i, j;
  207.     char realfile[MAXPATHLEN], bakfile[MAXPATHLEN];
  208.  
  209.     /*
  210.      * If it doesn't need saving, never mind.
  211.      */
  212.     if (!dbmodified)
  213.         return;
  214.  
  215.     /*
  216.      * Create the name of the file and a backup file.
  217.      */
  218.     sprintf(realfile, "%s/%s%s", dbasedir, dbname, DBFILE_SUFFIX);
  219.     sprintf(bakfile, "%s/#%s%s", dbasedir, dbname, DBFILE_SUFFIX);
  220.  
  221.     /*
  222.      * Default creation mode.
  223.      */
  224.     st.st_mode = 0400;
  225.  
  226.     /*
  227.      * If the file already exists, rename it to the
  228.      * backup file name.
  229.      */
  230.     if (stat(realfile, &st) == 0)
  231.         rename(realfile, bakfile);
  232.  
  233.     /*
  234.      * Open the new file.
  235.      */
  236.     if ((fp = fopen(realfile, "w")) == NULL) {
  237.         error("%s: cannot create \"%s\".\n", pname, realfile);
  238.         exit(1);
  239.     }
  240.  
  241.     /*
  242.      * Make sure the database is sorted.
  243.      */
  244.     qsort(db, dbentries, sizeof(struct dbfile), dbsort);
  245.  
  246.     /*
  247.      * Write out the entries.
  248.      */
  249.     for (i=0; i < dbentries; i++) {
  250.         if ((db[i].db_flag & DB_VALID) == 0)
  251.             continue;
  252.  
  253.         for (j=0; j < idx.idx_nlines; j++)
  254.             fprintf(fp, "%s\n", db[i].db_lines[j]);
  255.     }
  256.  
  257.     /*
  258.      * Set the file mode to the mode of the original
  259.      * file.  Mark the database as unmodified.
  260.      */
  261.     fchmod(fileno(fp), st.st_mode & 0777);
  262.     dbmodified = 0;
  263.  
  264.     fclose(fp);
  265. }
  266.