1*b8851fccSafresh1 #include <stdio.h>
2*b8851fccSafresh1 #include <sys/file.h>
3*b8851fccSafresh1 #ifdef SDBM
4*b8851fccSafresh1 #include "EXTERN.h"
5*b8851fccSafresh1 #include "sdbm.h"
6*b8851fccSafresh1 #else
7*b8851fccSafresh1 #include <ndbm.h>
8*b8851fccSafresh1 #endif
9*b8851fccSafresh1 #include <string.h>
10*b8851fccSafresh1
11*b8851fccSafresh1 extern int getopt();
12*b8851fccSafresh1 extern void oops();
13*b8851fccSafresh1
14*b8851fccSafresh1 char *progname;
15*b8851fccSafresh1
16*b8851fccSafresh1 static int rflag;
17*b8851fccSafresh1 static char *usage = "%s [-R] cat | look |... dbmname";
18*b8851fccSafresh1
19*b8851fccSafresh1 #define DERROR 0
20*b8851fccSafresh1 #define DLOOK 1
21*b8851fccSafresh1 #define DINSERT 2
22*b8851fccSafresh1 #define DDELETE 3
23*b8851fccSafresh1 #define DCAT 4
24*b8851fccSafresh1 #define DBUILD 5
25*b8851fccSafresh1 #define DPRESS 6
26*b8851fccSafresh1 #define DCREAT 7
27*b8851fccSafresh1
28*b8851fccSafresh1 #define LINEMAX 8192
29*b8851fccSafresh1
30*b8851fccSafresh1 typedef struct {
31*b8851fccSafresh1 char *sname;
32*b8851fccSafresh1 int scode;
33*b8851fccSafresh1 int flags;
34*b8851fccSafresh1 } cmd;
35*b8851fccSafresh1
36*b8851fccSafresh1 static cmd cmds[] = {
37*b8851fccSafresh1
38*b8851fccSafresh1 "fetch", DLOOK, O_RDONLY,
39*b8851fccSafresh1 "get", DLOOK, O_RDONLY,
40*b8851fccSafresh1 "look", DLOOK, O_RDONLY,
41*b8851fccSafresh1 "add", DINSERT, O_RDWR,
42*b8851fccSafresh1 "insert", DINSERT, O_RDWR,
43*b8851fccSafresh1 "store", DINSERT, O_RDWR,
44*b8851fccSafresh1 "delete", DDELETE, O_RDWR,
45*b8851fccSafresh1 "remove", DDELETE, O_RDWR,
46*b8851fccSafresh1 "dump", DCAT, O_RDONLY,
47*b8851fccSafresh1 "list", DCAT, O_RDONLY,
48*b8851fccSafresh1 "cat", DCAT, O_RDONLY,
49*b8851fccSafresh1 "creat", DCREAT, O_RDWR | O_CREAT | O_TRUNC,
50*b8851fccSafresh1 "new", DCREAT, O_RDWR | O_CREAT | O_TRUNC,
51*b8851fccSafresh1 "build", DBUILD, O_RDWR | O_CREAT,
52*b8851fccSafresh1 "squash", DPRESS, O_RDWR,
53*b8851fccSafresh1 "compact", DPRESS, O_RDWR,
54*b8851fccSafresh1 "compress", DPRESS, O_RDWR
55*b8851fccSafresh1 };
56*b8851fccSafresh1
57*b8851fccSafresh1 #define CTABSIZ (sizeof (cmds)/sizeof (cmd))
58*b8851fccSafresh1
59*b8851fccSafresh1 static cmd *parse();
60*b8851fccSafresh1 static void badk(), doit(), prdatum();
61*b8851fccSafresh1
62*b8851fccSafresh1 int
main(int argc,char ** argv)63*b8851fccSafresh1 main(int argc, char **argv)
64*b8851fccSafresh1 {
65*b8851fccSafresh1 int c;
66*b8851fccSafresh1 cmd *act;
67*b8851fccSafresh1 extern int optind;
68*b8851fccSafresh1 extern char *optarg;
69*b8851fccSafresh1
70*b8851fccSafresh1 progname = argv[0];
71*b8851fccSafresh1
72*b8851fccSafresh1 while ((c = getopt(argc, argv, "R")) != EOF)
73*b8851fccSafresh1 switch (c) {
74*b8851fccSafresh1 case 'R': /* raw processing */
75*b8851fccSafresh1 rflag++;
76*b8851fccSafresh1 break;
77*b8851fccSafresh1
78*b8851fccSafresh1 default:
79*b8851fccSafresh1 oops("usage: %s", usage);
80*b8851fccSafresh1 break;
81*b8851fccSafresh1 }
82*b8851fccSafresh1
83*b8851fccSafresh1 if ((argc -= optind) < 2)
84*b8851fccSafresh1 oops("usage: %s", usage);
85*b8851fccSafresh1
86*b8851fccSafresh1 if ((act = parse(argv[optind])) == NULL)
87*b8851fccSafresh1 badk(argv[optind]);
88*b8851fccSafresh1 optind++;
89*b8851fccSafresh1 doit(act, argv[optind]);
90*b8851fccSafresh1 return 0;
91*b8851fccSafresh1 }
92*b8851fccSafresh1
93*b8851fccSafresh1 static void
doit(cmd * act,char * file)94*b8851fccSafresh1 doit(cmd *act, char *file)
95*b8851fccSafresh1 {
96*b8851fccSafresh1 datum key;
97*b8851fccSafresh1 datum val;
98*b8851fccSafresh1 DBM *db;
99*b8851fccSafresh1 char *op;
100*b8851fccSafresh1 int n;
101*b8851fccSafresh1 char *line;
102*b8851fccSafresh1 #ifdef TIME
103*b8851fccSafresh1 long start;
104*b8851fccSafresh1 extern long time();
105*b8851fccSafresh1 #endif
106*b8851fccSafresh1
107*b8851fccSafresh1 if ((db = dbm_open(file, act->flags, 0644)) == NULL)
108*b8851fccSafresh1 oops("cannot open: %s", file);
109*b8851fccSafresh1
110*b8851fccSafresh1 if ((line = (char *) malloc(LINEMAX)) == NULL)
111*b8851fccSafresh1 oops("%s: cannot get memory", "line alloc");
112*b8851fccSafresh1
113*b8851fccSafresh1 switch (act->scode) {
114*b8851fccSafresh1
115*b8851fccSafresh1 case DLOOK:
116*b8851fccSafresh1 while (fgets(line, LINEMAX, stdin) != NULL) {
117*b8851fccSafresh1 n = strlen(line) - 1;
118*b8851fccSafresh1 line[n] = 0;
119*b8851fccSafresh1 key.dptr = line;
120*b8851fccSafresh1 key.dsize = n;
121*b8851fccSafresh1 val = dbm_fetch(db, key);
122*b8851fccSafresh1 if (val.dptr != NULL) {
123*b8851fccSafresh1 prdatum(stdout, val);
124*b8851fccSafresh1 putchar('\n');
125*b8851fccSafresh1 continue;
126*b8851fccSafresh1 }
127*b8851fccSafresh1 prdatum(stderr, key);
128*b8851fccSafresh1 fprintf(stderr, ": not found.\n");
129*b8851fccSafresh1 }
130*b8851fccSafresh1 break;
131*b8851fccSafresh1 case DINSERT:
132*b8851fccSafresh1 break;
133*b8851fccSafresh1 case DDELETE:
134*b8851fccSafresh1 while (fgets(line, LINEMAX, stdin) != NULL) {
135*b8851fccSafresh1 n = strlen(line) - 1;
136*b8851fccSafresh1 line[n] = 0;
137*b8851fccSafresh1 key.dptr = line;
138*b8851fccSafresh1 key.dsize = n;
139*b8851fccSafresh1 if (dbm_delete(db, key) == -1) {
140*b8851fccSafresh1 prdatum(stderr, key);
141*b8851fccSafresh1 fprintf(stderr, ": not found.\n");
142*b8851fccSafresh1 }
143*b8851fccSafresh1 }
144*b8851fccSafresh1 break;
145*b8851fccSafresh1 case DCAT:
146*b8851fccSafresh1 for (key = dbm_firstkey(db); key.dptr != 0;
147*b8851fccSafresh1 key = dbm_nextkey(db)) {
148*b8851fccSafresh1 prdatum(stdout, key);
149*b8851fccSafresh1 putchar('\t');
150*b8851fccSafresh1 prdatum(stdout, dbm_fetch(db, key));
151*b8851fccSafresh1 putchar('\n');
152*b8851fccSafresh1 }
153*b8851fccSafresh1 break;
154*b8851fccSafresh1 case DBUILD:
155*b8851fccSafresh1 #ifdef TIME
156*b8851fccSafresh1 start = time(0);
157*b8851fccSafresh1 #endif
158*b8851fccSafresh1 while (fgets(line, LINEMAX, stdin) != NULL) {
159*b8851fccSafresh1 n = strlen(line) - 1;
160*b8851fccSafresh1 line[n] = 0;
161*b8851fccSafresh1 key.dptr = line;
162*b8851fccSafresh1 if ((op = strchr(line, '\t')) != 0) {
163*b8851fccSafresh1 key.dsize = op - line;
164*b8851fccSafresh1 *op++ = 0;
165*b8851fccSafresh1 val.dptr = op;
166*b8851fccSafresh1 val.dsize = line + n - op;
167*b8851fccSafresh1 }
168*b8851fccSafresh1 else
169*b8851fccSafresh1 oops("bad input; %s", line);
170*b8851fccSafresh1
171*b8851fccSafresh1 if (dbm_store(db, key, val, DBM_REPLACE) < 0) {
172*b8851fccSafresh1 prdatum(stderr, key);
173*b8851fccSafresh1 fprintf(stderr, ": ");
174*b8851fccSafresh1 oops("store: %s", "failed");
175*b8851fccSafresh1 }
176*b8851fccSafresh1 }
177*b8851fccSafresh1 #ifdef TIME
178*b8851fccSafresh1 printf("done: %d seconds.\n", time(0) - start);
179*b8851fccSafresh1 #endif
180*b8851fccSafresh1 break;
181*b8851fccSafresh1 case DPRESS:
182*b8851fccSafresh1 break;
183*b8851fccSafresh1 case DCREAT:
184*b8851fccSafresh1 break;
185*b8851fccSafresh1 }
186*b8851fccSafresh1
187*b8851fccSafresh1 dbm_close(db);
188*b8851fccSafresh1 }
189*b8851fccSafresh1
190*b8851fccSafresh1 static void
badk(char * word)191*b8851fccSafresh1 badk(char *word)
192*b8851fccSafresh1 {
193*b8851fccSafresh1 int i;
194*b8851fccSafresh1
195*b8851fccSafresh1 if (progname)
196*b8851fccSafresh1 fprintf(stderr, "%s: ", progname);
197*b8851fccSafresh1 fprintf(stderr, "bad keywd %s. use one of\n", word);
198*b8851fccSafresh1 for (i = 0; i < (int)CTABSIZ; i++)
199*b8851fccSafresh1 fprintf(stderr, "%-8s%c", cmds[i].sname,
200*b8851fccSafresh1 ((i + 1) % 6 == 0) ? '\n' : ' ');
201*b8851fccSafresh1 fprintf(stderr, "\n");
202*b8851fccSafresh1 exit(1);
203*b8851fccSafresh1 /*NOTREACHED*/
204*b8851fccSafresh1 }
205*b8851fccSafresh1
206*b8851fccSafresh1 static cmd *
parse(char * str)207*b8851fccSafresh1 parse(char *str)
208*b8851fccSafresh1 {
209*b8851fccSafresh1 int i = CTABSIZ;
210*b8851fccSafresh1 cmd *p;
211*b8851fccSafresh1
212*b8851fccSafresh1 for (p = cmds; i--; p++)
213*b8851fccSafresh1 if (strcmp(p->sname, str) == 0)
214*b8851fccSafresh1 return p;
215*b8851fccSafresh1 return NULL;
216*b8851fccSafresh1 }
217*b8851fccSafresh1
218*b8851fccSafresh1 static void
prdatum(FILE * stream,datum d)219*b8851fccSafresh1 prdatum(FILE *stream, datum d)
220*b8851fccSafresh1 {
221*b8851fccSafresh1 int c;
222*b8851fccSafresh1 U8 *p = (U8 *) d.dptr;
223*b8851fccSafresh1 int n = d.dsize;
224*b8851fccSafresh1
225*b8851fccSafresh1 while (n--) {
226*b8851fccSafresh1 c = *p++;
227*b8851fccSafresh1 #ifndef EBCDIC /* Meta notation doesn't make sense on EBCDIC systems*/
228*b8851fccSafresh1 if (c & 0200) {
229*b8851fccSafresh1 fprintf(stream, "M-");
230*b8851fccSafresh1 c &= 0177;
231*b8851fccSafresh1 }
232*b8851fccSafresh1 #endif
233*b8851fccSafresh1 /* \c notation applies for \0 . \x1f, plus \c? */
234*b8851fccSafresh1 if (c <= 0x1F || c == QUESTION_MARK_CTRL) {
235*b8851fccSafresh1 fprintf(stream, "^%c", toCTRL(c));
236*b8851fccSafresh1 }
237*b8851fccSafresh1 #ifdef EBCDIC /* Instead of meta, use \x{} for non-printables */
238*b8851fccSafresh1 else if (! isPRINT_A(c)) {
239*b8851fccSafresh1 fprintf(stream, "\\x{%02x}", c);
240*b8851fccSafresh1 }
241*b8851fccSafresh1 #endif
242*b8851fccSafresh1 else { /* must be an ASCII printable */
243*b8851fccSafresh1 putc(c, stream);
244*b8851fccSafresh1 }
245*b8851fccSafresh1 }
246*b8851fccSafresh1 }
247*b8851fccSafresh1
248*b8851fccSafresh1
249