ref: 64e312636599ea2c86f21dc1176dca7da77bd74a
dir: /dbu.c/
#include <u.h>
#include <libc.h>
#include <stdio.h>
#include "sdbm.h"
extern void oops(char *, char *);
extern char getopt(int, char *[], char *);
char *progname;
static int rflag;
static char *usage = "[-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, OREAD,
"get", DLOOK, OREAD,
"look", DLOOK, OREAD,
"add", DINSERT, ORDWR,
"insert", DINSERT, ORDWR,
"store", DINSERT, ORDWR,
"delete", DDELETE, ORDWR,
"remove", DDELETE, ORDWR,
"dump", DCAT, OREAD,
"list", DCAT, OREAD,
"cat", DCAT, OREAD,
"creat", DCREAT, ORDWR | OTRUNC,
"new", DCREAT, ORDWR | OTRUNC,
"build", DBUILD, ORDWR,
"squash", DPRESS, ORDWR,
"compact", DPRESS, ORDWR,
"compress", DPRESS, ORDWR
};
#define CTABSIZ (sizeof (cmds)/sizeof (cmd))
static cmd *parse(char *);
static void badk(char *), doit(cmd *, char *), prdatum(FILE *, datum);
int
main(int argc, char *argv[])
{
cmd *act;
progname = argv[0];
ARGBEGIN {
case 'R':
rflag++;
break;
default:
oops("usage %s", usage);
break;
} ARGEND
if (argc < 2) oops("usage %s", usage);
if ((act = parse(argv[0])) == nil) badk(argv[0]);
doit(act, argv[1]);
exits(0);
}
static void
doit(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(long *);
#endif
int dbcreate;
Dir *dstat;
if ((dstat = dirstat(file)) == nil)
dbcreate = 1;
else {
dbcreate = 0;
free(dstat);
}
if ((db = dbm_open(file, act->flags, 0644, dbcreate)) == nil)
oops("cannot open: %s", file);
if ((line = (char *) malloc(LINEMAX)) == nil)
oops("%s: cannot get memory", "line alloc");
switch (act->scode) {
case DLOOK:
while (fgets(line, LINEMAX, stdin) != nil) {
n = strlen(line) - 1;
line[n] = 0;
key.dptr = line;
key.dsize = n;
val = dbm_fetch(db, key);
if (val.dptr != nil) {
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) != nil) {
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) != nil) {
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(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");
exits("bad keyword");
/*NOTREACHED*/
}
static cmd *
parse(char *str)
{
register int i = CTABSIZ;
register cmd *p;
for (p = cmds; i--; p++)
if (strcmp(p->sname, str) == 0)
return p;
return nil;
}
static void
prdatum(FILE *stream, datum d)
{
register int c;
register char *p = d.dptr;
register int n = d.dsize;
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);
}
}