21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * %W% (Berkeley) %G% 40 *
| 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * %W% (Berkeley) %G% 40 *
|
58 59/* (libdb version 2) uses .db extensions but an old dbm API */ 60/* check for libgdbm to distinguish it from linux systems */ 61#if defined(DBM_SUFFIX) && !defined(HAVE_LIBGDBM) 62# define HAVE_DB_SUFFIX 63#endif /* not defined(DBM_SUFFIX) && !defined(HAVE_LIBGDBM) */ 64 65#ifdef HAVE_MAP_NDBM 66 67static int 68store_data(voidp db, char *k, char *v) 69{ 70 datum key, val; 71 72 key.dptr = k; 73 val.dptr = v; 74 key.dsize = strlen(k) + 1; 75 val.dsize = strlen(v) + 1; 76 return dbm_store((DBM *) db, key, val, DBM_INSERT); 77} 78 79 80/* 81 * Read one line from file. 82 */ 83static int 84read_line(char *buf, int size, FILE *fp) 85{ 86 int done = 0; 87 88 do { 89 while (fgets(buf, size, fp)) { 90 int len = strlen(buf); 91 92 done += len; 93 if (len > 1 && buf[len - 2] == '\\' && buf[len - 1] == '\n') { 94 int ch; 95 buf += len - 2; 96 size -= len - 2; 97 *buf = '\n'; 98 buf[1] = '\0'; 99 100 /* 101 * Skip leading white space on next line 102 */ 103 while ((ch = getc(fp)) != EOF && isascii(ch) && isspace(ch)) ; 104 (void) ungetc(ch, fp); 105 } else { 106 return done; 107 } 108 } 109 } while (size > 0 && !feof(fp)); 110 111 return done; 112} 113 114 115/* 116 * Read through a map. 117 */ 118static int 119read_file(FILE *fp, char *map, voidp db) 120{ 121 char key_val[2048]; 122 int chuck = 0; 123 int line_no = 0; 124 int errs = 0; 125 126 while (read_line(key_val, 2048, fp)) { 127 char *kp; 128 char *cp; 129 char *hash; 130 int len = strlen(key_val); 131 132 line_no++; 133 134 /* 135 * Make sure we got the whole line 136 */ 137 if (key_val[len - 1] != '\n') { 138 fprintf(stderr, "line %d in \"%s\" is too long", line_no, map); 139 chuck = 1; 140 } else { 141 key_val[len - 1] = '\0'; 142 } 143 144 /* 145 * Strip comments 146 */ 147 hash = strchr(key_val, '#'); 148 if (hash) 149 *hash = '\0'; 150 151 /* 152 * Find start of key 153 */ 154 for (kp = key_val; *kp && isascii(*kp) && isspace((int)*kp); kp++) ; 155 156 /* 157 * Ignore blank lines 158 */ 159 if (!*kp) 160 goto again; 161 162 /* 163 * Find end of key 164 */ 165 for (cp = kp; *cp && (!isascii(*cp) || !isspace((int)*cp)); cp++) ; 166 167 /* 168 * Check whether key matches, or whether 169 * the entry is a wildcard entry. 170 */ 171 if (*cp) 172 *cp++ = '\0'; 173 while (*cp && isascii(*cp) && isspace((int)*cp)) 174 cp++; 175 if (*kp == '+') { 176 fprintf(stderr, "Can't interpolate %s\n", kp); 177 errs++; 178 } else if (*cp) { 179 if (db) { 180 if (store_data(db, kp, cp) < 0) { 181 fprintf(stderr, "Could store %s -> %s\n", kp, cp); 182 errs++; 183 } 184 } else { 185 printf("%s\t%s\n", kp, cp); 186 } 187 } else { 188 fprintf(stderr, "%s: line %d has no value field", map, line_no); 189 errs++; 190 } 191 192 again: 193 /* 194 * If the last read didn't get a whole line then 195 * throw away the remainder before continuing... 196 */ 197 if (chuck) { 198 while (fgets(key_val, sizeof(key_val), fp) && 199 !strchr(key_val, '\n')) ; 200 chuck = 0; 201 } 202 } 203 return errs; 204} 205 206 207static int 208remove_file(char *f) 209{ 210 if (unlink(f) < 0 && errno != ENOENT) 211 return -1; 212 213 return 0; 214} 215 216 217int 218main(int argc, char *argv[]) 219{ 220 FILE *mapf; /* the input file to read from */ 221 int error; 222 char *mapsrc; 223 DBM *db = NULL; 224 static char maptmp[] = "dbmXXXXXX"; 225#ifdef HAVE_DB_SUFFIX 226 char maptdb[16]; 227 char *map_name_db = (char *) NULL; 228#else /* not HAVE_DB_SUFFIX */ 229 char maptpag[16], maptdir[16]; 230 char *map_name_pag = (char *) NULL, *map_name_dir = (char *) NULL; 231#endif /* not HAVE_DB_SUFFIX */ 232 int len; 233 char *sl; 234 int printit = 0; 235 int usage = 0; 236 int ch; 237 extern int optind; 238 239 /* test options */ 240 while ((ch = getopt(argc, argv, "p")) != -1) 241 switch (ch) { 242 case 'p': 243 printit = 1; 244 break; 245 default: 246 usage++; 247 break; 248 } 249 250 if (usage || optind != (argc - 1)) { 251 fputs("Usage: mk-amd-map [-p] file-map\n", stderr); 252 exit(1); 253 } 254 mapsrc = argv[optind]; 255 256 /* test if can get to the map directory */ 257 sl = strrchr(mapsrc, '/'); 258 if (sl) { 259 *sl = '\0'; 260 if (chdir(mapsrc) < 0) { 261 fputs("Can't chdir to ", stderr); 262 perror(mapsrc); 263 exit(1); 264 } 265 mapsrc = sl + 1; 266 } 267 268 /* open source file */ 269 mapf = fopen(mapsrc, "r"); 270 if (!mapf) { 271 fprintf(stderr, "cannot open source file "); 272 perror(mapsrc); 273 exit(1); 274 } 275 276#ifndef DEBUG 277 signal(SIGINT, SIG_IGN); 278#endif /* DEBUG */ 279 280 if (!printit) { 281 len = strlen(mapsrc); 282#ifdef HAVE_DB_SUFFIX 283 map_name_db = (char *) malloc(len + 4); 284 error = (map_name_db == NULL); 285#else /* not HAVE_DB_SUFFIX */ 286 map_name_pag = (char *) malloc(len + 5); 287 map_name_dir = (char *) malloc(len + 5); 288 error = (map_name_pag == NULL || map_name_dir == NULL); 289#endif /* not HAVE_DB_SUFFIX */ 290 if (error) { 291 perror("mk-amd-map: malloc"); 292 exit(1); 293 } 294 295 mktemp(maptmp); 296 297 /* remove existing temps (if any) */ 298#ifdef HAVE_DB_SUFFIX 299 sprintf(maptdb, "%s.db", maptmp); 300 if (remove_file(maptdb) < 0) { 301 fprintf(stderr, "Can't remove existing temporary file; "); 302 perror(maptdb); 303 exit(1); 304 } 305#else /* not HAVE_DB_SUFFIX */ 306 sprintf(maptpag, "%s.pag", maptmp); 307 sprintf(maptdir, "%s.dir", maptmp); 308 if (remove_file(maptpag) < 0 || remove_file(maptdir) < 0) { 309 fprintf(stderr, "Can't remove existing temporary files; %s and ", maptpag); 310 perror(maptdir); 311 exit(1); 312 } 313#endif /* not HAVE_DB_SUFFIX */ 314 315 db = dbm_open(maptmp, O_RDWR|O_CREAT, 0444); 316 if (!db) { 317 fprintf(stderr, "cannot initialize temporary database: %s", maptmp); 318 exit(1); 319 } 320 } 321 322 /* print db to stdout or to temp database */ 323 error = read_file(mapf, mapsrc, db); 324 fclose(mapf); 325 if (error) { 326 if (printit) 327 fprintf(stderr, "Error reading source file %s\n", mapsrc); 328 else 329 fprintf(stderr, "Error creating database map for %s\n", mapsrc); 330 exit(1); 331 } 332 333 if (printit) 334 exit(0); /* nothing more to do */ 335 336 /* if gets here, we wrote to a database */ 337 338 dbm_close(db); 339 /* all went well */ 340 341#ifdef HAVE_DB_SUFFIX 342 sprintf(map_name_db, "%s.db", mapsrc); 343 if (rename(maptdb, map_name_db) < 0) { 344 fprintf(stderr, "Couldn't rename %s to ", maptdb); 345 perror(map_name_db); 346 /* Throw away the temporary map */ 347 unlink(maptdb); 348 exit(1); 349 } 350#else /* not HAVE_DB_SUFFIX */ 351 sprintf(map_name_pag, "%s.pag", mapsrc); 352 sprintf(map_name_dir, "%s.dir", mapsrc); 353 if (rename(maptpag, map_name_pag) < 0) { 354 fprintf(stderr, "Couldn't rename %s to ", maptpag); 355 perror(map_name_pag); 356 /* Throw away the temporary map */ 357 unlink(maptpag); 358 unlink(maptdir); 359 exit(1); 360 } 361 if (rename(maptdir, map_name_dir) < 0) { 362 fprintf(stderr, "Couldn't rename %s to ", maptdir); 363 perror(map_name_dir); 364 /* remove the (presumably bad) .pag file */ 365 unlink(map_name_pag); 366 /* throw away remaining part of original map */ 367 unlink(map_name_dir); 368 /* throw away the temporary map */ 369 unlink(maptdir); 370 fprintf(stderr, "WARNING: existing map \"%s.{dir,pag}\" destroyed\n", 371 mapsrc); 372 exit(1); 373 } 374#endif /* not HAVE_DB_SUFFIX */ 375 376 exit(0); 377} 378 379#else /* not HAVE_MAP_NDBM */ 380 381int 382main() 383{ 384 fputs("mk-amd-map: This system does not support hashed database files\n", stderr); 385 exit(1); 386} 387 388#endif /* not HAVE_MAP_NDBM */
| 62 63/* (libdb version 2) uses .db extensions but an old dbm API */ 64/* check for libgdbm to distinguish it from linux systems */ 65#if defined(DBM_SUFFIX) && !defined(HAVE_LIBGDBM) 66# define HAVE_DB_SUFFIX 67#endif /* not defined(DBM_SUFFIX) && !defined(HAVE_LIBGDBM) */ 68 69#ifdef HAVE_MAP_NDBM 70 71static int 72store_data(voidp db, char *k, char *v) 73{ 74 datum key, val; 75 76 key.dptr = k; 77 val.dptr = v; 78 key.dsize = strlen(k) + 1; 79 val.dsize = strlen(v) + 1; 80 return dbm_store((DBM *) db, key, val, DBM_INSERT); 81} 82 83 84/* 85 * Read one line from file. 86 */ 87static int 88read_line(char *buf, int size, FILE *fp) 89{ 90 int done = 0; 91 92 do { 93 while (fgets(buf, size, fp)) { 94 int len = strlen(buf); 95 96 done += len; 97 if (len > 1 && buf[len - 2] == '\\' && buf[len - 1] == '\n') { 98 int ch; 99 buf += len - 2; 100 size -= len - 2; 101 *buf = '\n'; 102 buf[1] = '\0'; 103 104 /* 105 * Skip leading white space on next line 106 */ 107 while ((ch = getc(fp)) != EOF && isascii(ch) && isspace(ch)) ; 108 (void) ungetc(ch, fp); 109 } else { 110 return done; 111 } 112 } 113 } while (size > 0 && !feof(fp)); 114 115 return done; 116} 117 118 119/* 120 * Read through a map. 121 */ 122static int 123read_file(FILE *fp, char *map, voidp db) 124{ 125 char key_val[2048]; 126 int chuck = 0; 127 int line_no = 0; 128 int errs = 0; 129 130 while (read_line(key_val, 2048, fp)) { 131 char *kp; 132 char *cp; 133 char *hash; 134 int len = strlen(key_val); 135 136 line_no++; 137 138 /* 139 * Make sure we got the whole line 140 */ 141 if (key_val[len - 1] != '\n') { 142 fprintf(stderr, "line %d in \"%s\" is too long", line_no, map); 143 chuck = 1; 144 } else { 145 key_val[len - 1] = '\0'; 146 } 147 148 /* 149 * Strip comments 150 */ 151 hash = strchr(key_val, '#'); 152 if (hash) 153 *hash = '\0'; 154 155 /* 156 * Find start of key 157 */ 158 for (kp = key_val; *kp && isascii(*kp) && isspace((int)*kp); kp++) ; 159 160 /* 161 * Ignore blank lines 162 */ 163 if (!*kp) 164 goto again; 165 166 /* 167 * Find end of key 168 */ 169 for (cp = kp; *cp && (!isascii(*cp) || !isspace((int)*cp)); cp++) ; 170 171 /* 172 * Check whether key matches, or whether 173 * the entry is a wildcard entry. 174 */ 175 if (*cp) 176 *cp++ = '\0'; 177 while (*cp && isascii(*cp) && isspace((int)*cp)) 178 cp++; 179 if (*kp == '+') { 180 fprintf(stderr, "Can't interpolate %s\n", kp); 181 errs++; 182 } else if (*cp) { 183 if (db) { 184 if (store_data(db, kp, cp) < 0) { 185 fprintf(stderr, "Could store %s -> %s\n", kp, cp); 186 errs++; 187 } 188 } else { 189 printf("%s\t%s\n", kp, cp); 190 } 191 } else { 192 fprintf(stderr, "%s: line %d has no value field", map, line_no); 193 errs++; 194 } 195 196 again: 197 /* 198 * If the last read didn't get a whole line then 199 * throw away the remainder before continuing... 200 */ 201 if (chuck) { 202 while (fgets(key_val, sizeof(key_val), fp) && 203 !strchr(key_val, '\n')) ; 204 chuck = 0; 205 } 206 } 207 return errs; 208} 209 210 211static int 212remove_file(char *f) 213{ 214 if (unlink(f) < 0 && errno != ENOENT) 215 return -1; 216 217 return 0; 218} 219 220 221int 222main(int argc, char *argv[]) 223{ 224 FILE *mapf; /* the input file to read from */ 225 int error; 226 char *mapsrc; 227 DBM *db = NULL; 228 static char maptmp[] = "dbmXXXXXX"; 229#ifdef HAVE_DB_SUFFIX 230 char maptdb[16]; 231 char *map_name_db = (char *) NULL; 232#else /* not HAVE_DB_SUFFIX */ 233 char maptpag[16], maptdir[16]; 234 char *map_name_pag = (char *) NULL, *map_name_dir = (char *) NULL; 235#endif /* not HAVE_DB_SUFFIX */ 236 int len; 237 char *sl; 238 int printit = 0; 239 int usage = 0; 240 int ch; 241 extern int optind; 242 243 /* test options */ 244 while ((ch = getopt(argc, argv, "p")) != -1) 245 switch (ch) { 246 case 'p': 247 printit = 1; 248 break; 249 default: 250 usage++; 251 break; 252 } 253 254 if (usage || optind != (argc - 1)) { 255 fputs("Usage: mk-amd-map [-p] file-map\n", stderr); 256 exit(1); 257 } 258 mapsrc = argv[optind]; 259 260 /* test if can get to the map directory */ 261 sl = strrchr(mapsrc, '/'); 262 if (sl) { 263 *sl = '\0'; 264 if (chdir(mapsrc) < 0) { 265 fputs("Can't chdir to ", stderr); 266 perror(mapsrc); 267 exit(1); 268 } 269 mapsrc = sl + 1; 270 } 271 272 /* open source file */ 273 mapf = fopen(mapsrc, "r"); 274 if (!mapf) { 275 fprintf(stderr, "cannot open source file "); 276 perror(mapsrc); 277 exit(1); 278 } 279 280#ifndef DEBUG 281 signal(SIGINT, SIG_IGN); 282#endif /* DEBUG */ 283 284 if (!printit) { 285 len = strlen(mapsrc); 286#ifdef HAVE_DB_SUFFIX 287 map_name_db = (char *) malloc(len + 4); 288 error = (map_name_db == NULL); 289#else /* not HAVE_DB_SUFFIX */ 290 map_name_pag = (char *) malloc(len + 5); 291 map_name_dir = (char *) malloc(len + 5); 292 error = (map_name_pag == NULL || map_name_dir == NULL); 293#endif /* not HAVE_DB_SUFFIX */ 294 if (error) { 295 perror("mk-amd-map: malloc"); 296 exit(1); 297 } 298 299 mktemp(maptmp); 300 301 /* remove existing temps (if any) */ 302#ifdef HAVE_DB_SUFFIX 303 sprintf(maptdb, "%s.db", maptmp); 304 if (remove_file(maptdb) < 0) { 305 fprintf(stderr, "Can't remove existing temporary file; "); 306 perror(maptdb); 307 exit(1); 308 } 309#else /* not HAVE_DB_SUFFIX */ 310 sprintf(maptpag, "%s.pag", maptmp); 311 sprintf(maptdir, "%s.dir", maptmp); 312 if (remove_file(maptpag) < 0 || remove_file(maptdir) < 0) { 313 fprintf(stderr, "Can't remove existing temporary files; %s and ", maptpag); 314 perror(maptdir); 315 exit(1); 316 } 317#endif /* not HAVE_DB_SUFFIX */ 318 319 db = dbm_open(maptmp, O_RDWR|O_CREAT, 0444); 320 if (!db) { 321 fprintf(stderr, "cannot initialize temporary database: %s", maptmp); 322 exit(1); 323 } 324 } 325 326 /* print db to stdout or to temp database */ 327 error = read_file(mapf, mapsrc, db); 328 fclose(mapf); 329 if (error) { 330 if (printit) 331 fprintf(stderr, "Error reading source file %s\n", mapsrc); 332 else 333 fprintf(stderr, "Error creating database map for %s\n", mapsrc); 334 exit(1); 335 } 336 337 if (printit) 338 exit(0); /* nothing more to do */ 339 340 /* if gets here, we wrote to a database */ 341 342 dbm_close(db); 343 /* all went well */ 344 345#ifdef HAVE_DB_SUFFIX 346 sprintf(map_name_db, "%s.db", mapsrc); 347 if (rename(maptdb, map_name_db) < 0) { 348 fprintf(stderr, "Couldn't rename %s to ", maptdb); 349 perror(map_name_db); 350 /* Throw away the temporary map */ 351 unlink(maptdb); 352 exit(1); 353 } 354#else /* not HAVE_DB_SUFFIX */ 355 sprintf(map_name_pag, "%s.pag", mapsrc); 356 sprintf(map_name_dir, "%s.dir", mapsrc); 357 if (rename(maptpag, map_name_pag) < 0) { 358 fprintf(stderr, "Couldn't rename %s to ", maptpag); 359 perror(map_name_pag); 360 /* Throw away the temporary map */ 361 unlink(maptpag); 362 unlink(maptdir); 363 exit(1); 364 } 365 if (rename(maptdir, map_name_dir) < 0) { 366 fprintf(stderr, "Couldn't rename %s to ", maptdir); 367 perror(map_name_dir); 368 /* remove the (presumably bad) .pag file */ 369 unlink(map_name_pag); 370 /* throw away remaining part of original map */ 371 unlink(map_name_dir); 372 /* throw away the temporary map */ 373 unlink(maptdir); 374 fprintf(stderr, "WARNING: existing map \"%s.{dir,pag}\" destroyed\n", 375 mapsrc); 376 exit(1); 377 } 378#endif /* not HAVE_DB_SUFFIX */ 379 380 exit(0); 381} 382 383#else /* not HAVE_MAP_NDBM */ 384 385int 386main() 387{ 388 fputs("mk-amd-map: This system does not support hashed database files\n", stderr); 389 exit(1); 390} 391 392#endif /* not HAVE_MAP_NDBM */
|