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