This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
(perl #132777) document PL_exit_flags
[perl5.git] / ext / SDBM_File / dbu.c
CommitLineData
463ee0b2
LW
1#include <stdio.h>
2#include <sys/file.h>
3#ifdef SDBM
17f28c40 4#include "EXTERN.h"
463ee0b2
LW
5#include "sdbm.h"
6#else
7#include <ndbm.h>
8#endif
9#include <string.h>
10
463ee0b2 11extern int getopt();
463ee0b2
LW
12extern void oops();
13
14char *progname;
15
16static int rflag;
17static 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
30typedef struct {
31 char *sname;
32 int scode;
33 int flags;
34} cmd;
35
36static 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
59static cmd *parse();
60static void badk(), doit(), prdatum();
61
62int
ba106d47 63main(int argc, char **argv)
463ee0b2
LW
64{
65 int c;
5aaab254 66 cmd *act;
463ee0b2
LW
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
93static void
5aaab254 94doit(cmd *act, char *file)
463ee0b2
LW
95{
96 datum key;
97 datum val;
5aaab254
KW
98 DBM *db;
99 char *op;
100 int n;
463ee0b2
LW
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
190static void
ba106d47 191badk(char *word)
463ee0b2 192{
5aaab254 193 int i;
463ee0b2
LW
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
206static cmd *
5aaab254 207parse(char *str)
463ee0b2 208{
5aaab254
KW
209 int i = CTABSIZ;
210 cmd *p;
463ee0b2
LW
211
212 for (p = cmds; i--; p++)
213 if (strcmp(p->sname, str) == 0)
214 return p;
215 return NULL;
216}
217
218static void
ba106d47 219prdatum(FILE *stream, datum d)
463ee0b2 220{
5aaab254 221 int c;
8944ce78 222 U8 *p = (U8 *) d.dptr;
5aaab254 223 int n = d.dsize;
463ee0b2
LW
224
225 while (n--) {
8944ce78
KW
226 c = *p++;
227#ifndef EBCDIC /* Meta notation doesn't make sense on EBCDIC systems*/
463ee0b2 228 if (c & 0200) {
8944ce78
KW
229 fprintf(stream, "M-");
230 c &= 0177;
463ee0b2 231 }
8944ce78
KW
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 }
463ee0b2
LW
245 }
246}
247
248