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