home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Dumbdb:
- ** A stupid string based database. It's slow, it's useless.
- ** But it does what I want it to.
- **
- ** This is public domain.
- ** Robert Osborne, May 1991
- **
- ** $Id: dumbdb.c,v 1.5 1991/04/30 19:16:31 robert Exp $
- */
- #include <stdio.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #ifndef __TURBOC__
- #include <sys/param.h>
- #include <malloc.h>
- #endif
- #ifndef MAXPATHLEN
- #define MAXPATHLEN 512
- #endif
- #include "dumbdb.h"
-
- #define VALID_DUMBDB(ptr) ((ptr) != 0)
-
- typedef struct dumbdb {
- FILE *fp;
- char *mode;
- char *path[MAXPATHLEN];
- } dumbdb;
-
- #define STREQ(a,b) (!strcmp((a),(b)))
- dumbDB
- open_dumbdb(path,mode)
- char *path; /* full path to the dumbdb */
- char *mode; /* mode "R","U" */
- {
- FILE *fp;
- dumbdb *ret;
- struct stat statbuf;
-
- ret = (dumbdb *)malloc(sizeof(dumbdb));
- if( ! ret )
- return (dumbDB) 0;
-
- strcpy(ret->path,path);
- if( STREQ(mode,"R") )
- {
- ret->mode = "r";
- }
- else if( STREQ(mode,"U") )
- {
- ret->mode = "a+";
- }
- else
- {
- free(ret);
- return (dumbDB) 0;
- }
-
- if( *ret->mode == 'a' && !lock_file(ret->path, 240, 5) )
- {
- free(ret);
- return (dumbDB) 0;
- }
-
- ret->fp = fopen(path, ret->mode);
- if( ret->fp == (FILE *) 0 )
- {
- free(ret);
- return (dumbDB) 0;
- }
- strcpy(ret->path, path);
-
-
- return ret;
- }
-
- int
- close_dumbdb(db)
- dumbDB db;
- {
- dumbdb *dbp = (dumbdb *) db;
- int ret;
- char editpath[MAXPATHLEN];
-
- if( ! VALID_DUMBDB(dbp) )
- {
- return -1;
- }
-
- if( dbp->mode[0] == 'a' )
- {
- unlock_file(dbp->path);
- }
- ret = fclose(dbp->fp);
- free(dbp);
- return ret;
- }
-
-
- /*
- ** rewind file, and get first entry
- */
- dumbdb_first_entry(db, buffer, argc, argv)
- dumbDB db;
- char *buffer;
- int argc; /* number of '\0' terminated strings to get */
- char *argv[]; /* pointers to strings within working buffer */
- {
- dumbdb *dbp = (dumbdb *) db;
-
- if( ! VALID_DUMBDB(dbp) || argc <= 0 )
- {
- return -1;
- }
-
- if( fseek(dbp->fp, 0L, 0) != 0 )
- {
- return -1;
- }
-
- return dumbdb_next_entry(db, buffer, argc, argv);
- }
- /*
- ** parse the next entry
- */
- int
- dumbdb_next_entry(db, buffer, argc,argv)
- dumbDB db;
- char *buffer;
- int argc; /* number of '\0' terminated strings to get */
- char *argv[]; /* pointers to strings within working buffer */
- {
- dumbdb *dbp = (dumbdb *) db;
- int c, count;
-
- if( ! VALID_DUMBDB(dbp) || argc <= 0 )
- {
- return -1;
- }
-
- count = 1;
- argv[0] = buffer;
- while( (c=fgetc(dbp->fp)) != -1 )
- {
- *buffer++ = c;
- if( c == '\0' )
- {
- if( count < argc )
- {
- argv[count++] = buffer;
- }
- else
- {
- return 0;
- }
- }
- }
- return -1;
- }
- static int
- eq_entry(argc,argv1,argv2)
- int argc; /* number of strings to compare */
- char *argv1[]; /* array of strings or null pointers */
- char *argv2[]; /* db entry to compare no modifiers */
- {
- int i;
-
- for(i=0; i<argc; i++)
- {
- if( argv1[i] == (char *) 0 )
- {
- continue;
- }
- if( STREQ(argv1[i],argv2[i]) )
- {
- continue;
- }
- return 0;
- }
- return 1;
- }
- /*
- ** find a entry that matches the given fields
- */
- int
- dumbdb_find_first(db,buffer,argc,argv,found)
- dumbDB db;
- char *buffer;
- int argc; /* number of '\0' terminated strings to add */
- char *argv[]; /* pointers to strings to add */
- char *found[]; /* pointer to found strings */
- {
- dumbdb *dbp = (dumbdb *) db;
- int ret;
-
- if( ! VALID_DUMBDB(dbp) || argc <= 0 )
- {
- return -1;
- }
-
- ret = dumbdb_first_entry(db, buffer, argc, found);
- while( ret == 0 )
- {
- if( eq_entry(argc, argv, found) )
- {
- return(0);
- }
- ret = dumbdb_next_entry(db, buffer, argc, found);
- }
- return -1;
- }
- int
- dumbdb_find_next(db,buffer,argc,argv,found)
- dumbDB db;
- char *buffer;
- int argc; /* number of '\0' terminated strings to add */
- char *argv[]; /* pointers to strings to add */
- char *found[]; /* pointer to found strings */
- {
- dumbdb *dbp = (dumbdb *) db;
- int ret;
-
- if( ! VALID_DUMBDB(dbp) || argc <= 0 )
- {
- return -1;
- }
-
- ret = dumbdb_next_entry(db, buffer, argc, found);
- while( ret == 0 )
- {
- if( eq_entry(argc, argv, found) )
- {
- return(0);
- }
- ret = dumbdb_next_entry(db, buffer, argc, found);
- }
- return -1;
- }
- /*
- ** add an entry to the end of the list
- ** NB: dumbdb_find_next or dumbdb_next_entry won't work
- ** without a intervening call to dumbdb_first_entry or
- ** dumbdb_find_first.
- */
- int
- dumbdb_add_entry(db,argc,argv)
- dumbDB db;
- int argc; /* number of '\0' terminated strings to add */
- char *argv[]; /* pointers to strings to add */
- {
- dumbdb *dbp = (dumbdb *) db;
-
- if( ! VALID_DUMBDB(dbp) || argc <= 0 )
- {
- return -1;
- }
- if( ! dbp->mode[0] == 'a' )
- {
- return -1;
- }
-
- if( fseek(dbp->fp, 0L, 2) != 0 )
- {
- return -1;
- }
-
- while( argc )
- {
- if( *argv != (char *) 0 )
- {
- fputs(*argv, dbp->fp);
- }
- fputc('\0', dbp->fp);
- argv++;
- argc--;
- }
- return 0;
- }
- /*
- ** Acts like a filter and removes all entries that match the
- ** given entry from the db.
- ** NB: dumbdb_find_next or dumbdb_next_entry won't work
- ** without a intervening call to dumbdb_first_entry or
- ** dumbdb_find_first.
- */
- int
- dumbdb_delete_entries(db,argc,argv)
- dumbDB db;
- int argc; /* number of '\0' terminated strings to add */
- char *argv[]; /* pointers to entry pattern to delete */
- {
- dumbdb *dbp = (dumbdb *) db;
- FILE *newfp;
- int count = 0;
- int ret;
- int i;
- char editpath[MAXPATHLEN];
- char buffer[DUMBDB_MAXENTRY];
- char *found[DUMBDB_MAXFIELDS];
-
- if( ! VALID_DUMBDB(dbp) || argc <= 0 )
- {
- return count;
- }
- if( ! dbp->mode[0] == 'a' )
- {
- return count;
- }
- sprintf(editpath, "%s.new", dbp->path);
- if( (newfp = fopen(editpath, "w+")) == (FILE *) 0 )
- {
- return count;
- }
-
- ret = dumbdb_first_entry(db, buffer, argc, found);
- while( ret == 0 )
- {
- if( ! eq_entry(argc, argv, found) )
- {
- for(i=0; i<argc; i++)
- {
- if( found[i] != (char *) 0 )
- {
- fputs(found[i], newfp);
- }
- fputc('\0', newfp);
- }
- }
- else
- {
- count++;
- }
- ret = dumbdb_next_entry(db, buffer, argc, found);
- }
-
- if( count > 0 )
- {
- fclose(dbp->fp);
- dbp->fp = newfp;
- unlink(dbp->path);
- #ifdef __TURBOC__
- rename(editpath, dbp->path);
- #else
- link(editpath, dbp->path);
- unlink(editpath);
- #endif
- }
- else
- {
- fclose(newfp);
- unlink(editpath);
- }
- return count;
- }
- /*
- ** Finds the first entry that matchs the search and replaces it.
- ** NB: dumbdb_find_next or dumbdb_next_entry won't work
- ** without a intervening call to dumbdb_first_entry or
- ** dumbdb_find_first.
- */
- int
- dumbdb_find_and_replace(db,argc,search,replace)
- dumbDB db;
- int argc; /* number of '\0' terminated strings to add */
- char *search[]; /* pointers to entry pattern to delete */
- char *replace[]; /* pointers to entry pattern to delete */
- {
- dumbdb *dbp = (dumbdb *) db;
- FILE *newfp;
- int ret, i, replaced = 1;
- char editpath[MAXPATHLEN];
- char buffer[DUMBDB_MAXENTRY];
- char *found[DUMBDB_MAXFIELDS];
-
- if( ! VALID_DUMBDB(dbp) || argc <= 0 )
- {
- return replaced;
- }
- if( ! dbp->mode[0] == 'a' )
- {
- return replaced;
- }
- sprintf(editpath, "%s.new", dbp->path);
- if( (newfp = fopen(editpath, "w+")) == (FILE *) 0 )
- {
- return replaced;
- }
-
- ret = dumbdb_first_entry(db, buffer, argc, found);
- while( ret == 0 )
- {
- if( !replaced || ! eq_entry(argc, search, found) )
- {
- for(i=0; i<argc; i++)
- {
- if( found[i] != (char *) 0 )
- {
- fputs(found[i], newfp);
- }
- fputc('\0', newfp);
- }
- }
- else
- {
- replaced = 0;
- for(i=0; i<argc; i++)
- {
- if( replace[i] != (char *) 0 )
- {
- fputs(replace[i], newfp);
- }
- fputc('\0', newfp);
- }
- }
- ret = dumbdb_next_entry(db, buffer, argc, found);
- }
-
- if( !replaced )
- {
- fclose(dbp->fp);
- dbp->fp = newfp;
- unlink(dbp->path);
- #ifdef __TURBOC__
- rename(editpath, dbp->path);
- #else
- link(editpath, dbp->path);
- unlink(editpath);
- #endif
- }
- else
- {
- fclose(newfp);
- unlink(editpath);
- }
- return replaced;
- }
-