xref: /openbsd/gnu/usr.bin/perl/ext/SDBM_File/dbu.c (revision 09467b48)
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
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
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
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 *
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
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