Logo Search packages:      
Sourcecode: acm version File versions  Download package

dbu.c

#include <stdio.h>
#include <sys/file.h>
#ifdef SDBM
#include "sdbm.h"
#else
#include <ndbm.h>
#endif

#if STDC_HEADERS || HAVE_STRING_H
#include <string.h>
/* An ANSI string.h and pre-ANSI memory.h might conflict.  */
#if !STDC_HEADERS && HAVE_MEMORY_H
#include <memory.h>
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
#define index           strchr
#define rindex          strrchr
#define bcopy(s, d, n)  memcpy ((d), (s), (n))
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
#define bzero(s, n)     memset ((s), 0, (n))
#else /* not STDC_HEADERS and not HAVE_STRING_H */
#include <strings.h>
/* memory.h and strings.h conflict on some systems.  */
#endif /* not STDC_HEADERS and not HAVE_STRING_H */

extern int  getopt();
extern void oops();

char *progname;

static int rflag;
static char *usage = "%s [-R] cat | look |... dbmname";

#define DERROR    0
#define DLOOK     1
#define DINSERT   2
#define DDELETE 3
#define     DCAT  4
#define DBUILD    5
#define DPRESS    6
#define DCREAT    7

#define LINEMAX   8192

typedef struct {
      char *sname;
      int scode;
      int flags;
} cmd;

static cmd cmds[] = {

      "fetch", DLOOK,   O_RDONLY,
      "get", DLOOK,           O_RDONLY,
      "look", DLOOK,          O_RDONLY,
      "add", DINSERT,         O_RDWR,
      "insert", DINSERT,      O_RDWR,
      "store", DINSERT, O_RDWR,
      "delete", DDELETE,      O_RDWR,
      "remove", DDELETE,      O_RDWR,
      "dump", DCAT,           O_RDONLY,
      "list", DCAT,           O_RDONLY,
      "cat", DCAT,            O_RDONLY,
      "creat", DCREAT,  O_RDWR | O_CREAT | O_TRUNC,
      "new", DCREAT,          O_RDWR | O_CREAT | O_TRUNC,
      "build", DBUILD,  O_RDWR | O_CREAT,
      "squash", DPRESS, O_RDWR,
      "compact", DPRESS,      O_RDWR,
      "compress", DPRESS,     O_RDWR
};

#define CTABSIZ (sizeof (cmds)/sizeof (cmd))

static cmd *parse();
static void badk(), doit(), prdatum();

int
main(argc, argv)
int   argc;
char *argv[];
{
      int c;
      register cmd *act;
      extern int optind;
      extern char *optarg;

      progname = argv[0];

      while ((c = getopt(argc, argv, "R")) != EOF)
            switch (c) {
            case 'R':          /* raw processing  */
                  rflag++;
                  break;

            default:
                  oops("usage: %s", usage);
                  break;
            }

      if ((argc -= optind) < 2)
            oops("usage: %s", usage);

      if ((act = parse(argv[optind])) == NULL)
            badk(argv[optind]);
      optind++;
      doit(act, argv[optind]);
      return 0;
}

static void
doit(act, file)
register cmd *act;
char *file;
{
      datum key;
      datum val;
      register DBM *db;
      register char *op;
      register int n;
      char *line;
#ifdef TIME
      long start;
      extern long time();
#endif

      if ((db = dbm_open(file, act->flags, 0644)) == NULL)
            oops("cannot open: %s", file);

      if ((line = (char *) malloc(LINEMAX)) == NULL)
            oops("%s: cannot get memory", "line alloc");

      switch (act->scode) {

      case DLOOK:
            while (fgets(line, LINEMAX, stdin) != NULL) {
                  n = strlen(line) - 1;
                  line[n] = 0;
                  key.dptr = line;
                  key.dsize = n;
                  val = dbm_fetch(db, key);
                  if (val.dptr != NULL) {
                        prdatum(stdout, val);
                        putchar('\n');
                        continue;
                  }
                  prdatum(stderr, key);
                  fprintf(stderr, ": not found.\n");
            }
            break;
      case DINSERT:
            break;
      case DDELETE:
            while (fgets(line, LINEMAX, stdin) != NULL) {
                  n = strlen(line) - 1;
                  line[n] = 0;
                  key.dptr = line;
                  key.dsize = n;
                  if (dbm_delete(db, key) == -1) {
                        prdatum(stderr, key);
                        fprintf(stderr, ": not found.\n");
                  }
            }
            break;
      case DCAT:
            for (key = dbm_firstkey(db); key.dptr != 0; 
                 key = dbm_nextkey(db)) {
                  prdatum(stdout, key);
                  putchar('\t');
                  prdatum(stdout, dbm_fetch(db, key));
                  putchar('\n');
            }
            break;
      case DBUILD:
#ifdef TIME
            start = time(0);
#endif
            while (fgets(line, LINEMAX, stdin) != NULL) {
                  n = strlen(line) - 1;
                  line[n] = 0;
                  key.dptr = line;
                  if ((op = strchr(line, '\t')) != 0) {
                        key.dsize = op - line;
                        *op++ = 0;
                        val.dptr = op;
                        val.dsize = line + n - op;
                  }
                  else
                        oops("bad input; %s", line);
      
                  if (dbm_store(db, key, val, DBM_REPLACE) < 0) {
                        prdatum(stderr, key);
                        fprintf(stderr, ": ");
                        oops("store: %s", "failed");
                  }
            }
#ifdef TIME
            printf("done: %d seconds.\n", time(0) - start);
#endif
            break;
      case DPRESS:
            break;
      case DCREAT:
            break;
      }

      dbm_close(db);
}

static void
badk(word)
char *word;
{
      register int i;

      if (progname)
            fprintf(stderr, "%s: ", progname);
      fprintf(stderr, "bad keywd %s. use one of\n", word);
      for (i = 0; i < (int)CTABSIZ; i++)
            fprintf(stderr, "%-8s%c", cmds[i].sname,
                  ((i + 1) % 6 == 0) ? '\n' : ' ');
      fprintf(stderr, "\n");
      exit(1);
      /*NOTREACHED*/
}

static cmd *
parse(str)
register char *str;
{
      register int i = CTABSIZ;
      register cmd *p;
      
      for (p = cmds; i--; p++)
            if (strcmp(p->sname, str) == 0)
                  return p;
      return NULL;
}

static void
prdatum(stream, d)
FILE *stream;
datum d;
{
      register int c;
      register char *p = d.dptr;
      register int n = d.dsize;

      fprintf (stream, "\"");
      while (n--) {
            c = *p++ & 0377;
            if (c & 0200) {
                  fprintf(stream, "M-");
                  c &= 0177;
            }
            if (c == 0177 || c < ' ') 
                  fprintf(stream, "^%c", (c == 0177) ? '?' : c + '@');
            else
                  putc(c, stream);
      }
      fprintf (stream, "\"");
}



Generated by  Doxygen 1.6.0   Back to index