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