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