home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff319.lzh / CNewsSrc / cnews.orig.lzh / libfake / dbm.c next >
C/C++ Source or Header  |  1989-06-27  |  3KB  |  160 lines

  1. /*
  2.  * Incredibly slow Uglix dbm simulation.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include "libc.h"
  9.  
  10. #define STRLEN(s) (sizeof (s) - 1)    /* s must be a char array */
  11.  
  12. static char *pagname = NULL;
  13. static FILE *db;
  14. static int dbrdonly;
  15.  
  16. typedef struct {
  17.     char *dptr;
  18.     int dsize;
  19. } datum;
  20.  
  21. dbminit(file)
  22. char *file;
  23. {
  24.     dbrdonly = 0;
  25.  
  26.     if (pagname != NULL)            /* old name? */
  27.         free(pagname);
  28.     pagname = malloc((unsigned)(strlen(file) + STRLEN(".pag") + 1));
  29.     if (pagname == NULL) {
  30.         warning("cannot allocate memory to open database `%s'\n", file);
  31.         return -1;
  32.     }
  33.     (void) strcpy(pagname, file);
  34.     (void) strcat(pagname, ".pag");
  35.  
  36.     if ((db = fopen(pagname, "r+")) == NULL) {
  37.         db = fopen(pagname, "r");
  38.         dbrdonly = 1;
  39.     }
  40.     if (db == NULL) {
  41.         warning("cannot open database `%s'\n", file);
  42.         return -1;
  43.     }
  44.     return 0;
  45. }
  46.  
  47. datum
  48. fetch(key)
  49. datum key;
  50. {
  51.     datum item;
  52.  
  53.     rewind(db);
  54.     while (getitem(&item, db) != EOF)        /* read key */
  55.         if (strncmp(item.dptr, key.dptr, key.dsize) == 0)
  56.             if (getitem(&item, db) == EOF)    /* read data */
  57.                 break;
  58.             else
  59.                 return item;
  60.     /* EOF */
  61.     item.dptr = NULL;
  62.     item.dsize = 0;
  63.     return item;
  64. }
  65.  
  66. delete(key)
  67. datum key;
  68. {
  69.     datum item;
  70.     FILE *temp;
  71.     FILE *tmpfile();
  72.  
  73.     if (dbrdonly)
  74.         return -1;
  75.     temp = tmpfile();
  76.     if (temp == NULL)
  77.         return -1;
  78.     /* copy from db to temp, omitting key & its data */
  79.     rewind(db);
  80.     while (getitem(&item, db) != EOF)
  81.         if (strncmp(item.dptr, key.dptr, key.dsize) == 0) {
  82.             if (getitem(&item, db) == EOF)    /* toss data too */
  83.                 return -1;
  84.         } else
  85.             if (putitem(&item, temp) == EOF)
  86.                 return -1;
  87.     /* copy back from temp to db */
  88.     rewind(temp);
  89.     db = freopen(pagname, "w+", db);
  90.     while (getitem(&item, temp) != EOF)
  91.         if (putitem(&item, db) == EOF)
  92.             return -1;
  93.     return 0;
  94. }
  95.  
  96. store(key, dat)
  97. datum key, dat;
  98. {
  99.     if (dbrdonly)
  100.         return -1;
  101. #ifdef REALDBM            /* else, it's only for news */
  102.     if (delete(key) == -1)
  103.         return -1;
  104. #endif
  105.     if (putitem(&key, db) == EOF || putitem(&dat, db) == EOF)
  106.         return -1;
  107.     return 0;
  108. }
  109.  
  110. datum
  111. firstkey()
  112. {
  113.     datum trash;
  114.     datum nextkey();
  115.  
  116.     rewind(db);
  117.     return nextkey(trash);
  118. }
  119.  
  120. /* ARGSUSED */
  121. datum
  122. nextkey(key)            /* simplistic version, ignores key */
  123. datum key;
  124. {
  125.     static datum dat;
  126.  
  127.     if (getitem(&dat, db) == EOF)
  128.         dat.dptr = NULL;
  129.     return dat;
  130. }
  131.  
  132. static int
  133. getitem(datump, fp)
  134. register datum *datump;            /* points at static storage */
  135. FILE *fp;
  136. {
  137.     static char *data = NULL;    /* the current item */
  138.  
  139.     if (fread((char *)&datump->dsize, sizeof datump->dsize, 1, fp) != 1)
  140.         return EOF;
  141.     if (data != NULL)
  142.         free(data);        /* pitch old item */
  143.     datump->dptr = data = malloc((unsigned)datump->dsize);
  144.     if (data == NULL ||
  145.         fread(datump->dptr, datump->dsize, 1, fp) != 1)
  146.         return EOF;
  147.     return 0;
  148. }
  149.  
  150. static int
  151. putitem(datump, fp)
  152. datum *datump;
  153. FILE *fp;
  154. {
  155.     if (fwrite((char *)&datump->dsize, sizeof datump->dsize, 1, fp) != 1 ||
  156.         fwrite(datump->dptr, datump->dsize, 1, fp) != 1)
  157.         return EOF;
  158.     return 0;
  159. }
  160.