home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume21 / amd / part05 / mk-amd-map.c < prev    next >
C/C++ Source or Header  |  1990-04-10  |  7KB  |  310 lines

  1. /*
  2.  * $Id: mk-amd-map.c,v 5.1.1.2 90/01/11 17:09:31 jsp Exp Locker: jsp $
  3.  *
  4.  * Copyright (c) 1990 Jan-Simon Pendry
  5.  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  6.  * Copyright (c) 1990 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * This code is derived from software contributed to Berkeley by
  10.  * Jan-Simon Pendry at Imperial College, London.
  11.  *
  12.  * Redistribution and use in source and binary forms are permitted
  13.  * provided that the above copyright notice and this paragraph are
  14.  * duplicated in all such forms and that any documentation,
  15.  * advertising materials, and other materials related to such
  16.  * distribution and use acknowledge that the software was developed
  17.  * by Imperial College of Science, Technology and Medicine, London, UK.
  18.  * The names of the College and University may not be used to endorse
  19.  * or promote products derived from this software without specific
  20.  * prior written permission.
  21.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  22.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  23.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  24.  */
  25.  
  26. /*
  27.  * Convert a file map into an ndbm map
  28.  */
  29.  
  30. #ifndef lint
  31. char copyright[] = "\
  32. @(#)Copyright (c) 1990 Jan-Simon Pendry\n\
  33. @(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\
  34. @(#)Copyright (c) 1990 The Regents of the University of California.\n\
  35. @(#)All rights reserved.\n";
  36. #endif /* not lint */
  37.  
  38. #ifndef lint
  39. static char rcsid[] = "$Id: mk-amd-map.c,v 5.1.1.2 90/01/11 17:09:31 jsp Exp Locker: jsp $";
  40. static char sccsid[] = "%W% (Berkeley) %G%";
  41. #endif /* not lint */
  42.  
  43. #include "am.h"
  44.  
  45. #ifdef OS_HAS_GDBM
  46. #define HAS_DATABASE
  47. #include "gdbm.h"
  48. #endif
  49.  
  50. #ifndef HAS_DATABASE
  51. #ifdef OS_HAS_NDBM
  52. #define HAS_DATABASE
  53. #define    USE_NDBM
  54. #include <ndbm.h>
  55.  
  56. #define create_database(name) dbm_open(name, O_RDWR|O_CREAT, 0444)
  57.  
  58. static int store_data(db, k, v)
  59. voidp db;
  60. char *k, *v;
  61. {
  62.     datum key, val;
  63.  
  64.     key.dptr = k; val.dptr = v;
  65.     key.dsize = strlen(k) + 1;
  66.     val.dsize = strlen(v) + 1;
  67.     return dbm_store((DBM *) db, key, val, DBM_INSERT);
  68. }
  69.  
  70. #endif /* OS_HAS_NDBM */
  71. #endif /* !OS_HAS_DATABASE */
  72.  
  73. #ifdef HAS_DATABASE
  74. #include <fcntl.h>
  75. #include <ctype.h>
  76.  
  77. static int read_line(buf, size, fp)
  78. char *buf;
  79. int size;
  80. FILE *fp;
  81. {
  82.     int done = 0;
  83.  
  84.     do {
  85.         while (fgets(buf, size, fp)) {
  86.             int len = strlen(buf);
  87.             done += len;
  88.             if (len > 1 && buf[len-2] == '\\' &&
  89.                     buf[len-1] == '\n') {
  90.                 int ch;
  91.                 buf += len - 2;
  92.                 size -= len - 2;
  93.                 /*
  94.                  * Skip leading white space on next line
  95.                  */
  96.                 while ((ch = getc(fp)) != EOF &&
  97.                     isascii(ch) && isspace(ch))
  98.                         ;
  99.                 (void) ungetc(ch, fp);
  100.             } else {
  101.                 return done;
  102.             }
  103.         }
  104.     } while (size > 0 && !feof(fp));
  105.  
  106.     return done;
  107. }
  108.  
  109. /*
  110.  * Read through a map
  111.  */
  112. static int read_file(fp, map, db)
  113. FILE *fp;
  114. char *map;
  115. voidp db;
  116. {
  117.     char key_val[2048];
  118.     int chuck = 0;
  119.     int line_no = 0;
  120.     int errs = 0;
  121.  
  122.     while (read_line(key_val, sizeof(key_val), fp)) {
  123.         char *kp;
  124.         char *cp;
  125.         char *hash;
  126.         int len = strlen(key_val);
  127.         line_no++;
  128.  
  129.         /*
  130.          * Make sure we got the whole line
  131.          */
  132.         if (key_val[len-1] != '\n') {
  133.             fprintf(stderr, "line %d in \"%s\" is too long", line_no, map);
  134.             chuck = 1;
  135.         } else {
  136.             key_val[len-1] = '\0';
  137.         }
  138.  
  139.         /*
  140.          * Strip comments
  141.          */
  142.         hash = strchr(key_val, '#');
  143.         if (hash)
  144.             *hash = '\0';
  145.  
  146.         /*
  147.          * Find start of key
  148.          */
  149.         for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++)
  150.             ;
  151.  
  152.         /*
  153.          * Ignore blank lines
  154.          */
  155.         if (!*kp)
  156.             goto again;
  157.  
  158.         /*
  159.          * Find end of key
  160.          */
  161.         for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++)
  162.             ;
  163.  
  164.         /*
  165.          * Check whether key matches, or whether
  166.          * the entry is a wildcard entry.
  167.          */
  168.         if (*cp)
  169.             *cp++ = '\0';
  170.         while (*cp && isascii(*cp) && isspace(*cp))
  171.             cp++;
  172.         if (*kp == '+') {
  173.             fprintf(stderr, "Can't interpolate %s\n", kp);
  174.             errs++;
  175.         } else if (*cp) {
  176. #ifdef DEBUG
  177.             printf("%s\t%s\n", kp, cp);
  178. #endif
  179.             if (store_data(db, kp, cp) < 0) {
  180.                 fprintf(stderr, "Could store %s -> %s\n", kp, cp);
  181.                 errs++;
  182.             }
  183.         } else {
  184.             fprintf(stderr, "%s: line %d has no value field", map, line_no);
  185.             errs++;
  186.         }
  187.  
  188. again:
  189.         /*
  190.          * If the last read didn't get a whole line then
  191.          * throw away the remainder before continuing...
  192.          */
  193.         if (chuck) {
  194.             while (fgets(key_val, sizeof(key_val), fp) &&
  195.                 !strchr(key_val, '\n'))
  196.                     ;
  197.             chuck = 0;
  198.         }
  199.     }
  200.     return errs;
  201. }
  202.  
  203. static int remove(f)
  204. char *f;
  205. {
  206.     if (unlink(f) < 0 && errno != ENOENT)
  207.         return -1;
  208.     return 0;
  209. }
  210.  
  211. main(argc, argv)
  212. int argc;
  213. char *argv[];
  214. {
  215.     FILE *mapf;
  216.     char *map;
  217.     int rc = 0;
  218.     DBM *mapd;
  219.     char *maptmp = "dbmXXXXXX";
  220.     char maptpag[16], maptdir[16];
  221.     char *mappag, *mapdir;
  222.     int len;
  223.     char *sl;
  224.  
  225.     if (argc != 2) {
  226.         fputs("Usage: mk-amd-map file-map\n", stderr);
  227.         exit(1);
  228.     }
  229.  
  230.     map = argv[1];
  231.     sl = strrchr(map, '/');
  232.     if (sl) {
  233.         *sl = '\0';
  234.         if (chdir(map) < 0) {
  235.             fputs("Can't chdir to ", stderr);
  236.             perror(map);
  237.             exit(1);
  238.         }
  239.         map = sl + 1;
  240.     }
  241. #ifdef USE_NDBM
  242.     len = strlen(map);
  243.     mappag = (char *) malloc(len + 5);
  244.     mapdir = (char *) malloc(len + 5);
  245.     if (!mappag || !mapdir) {
  246.         perror("malloc");
  247.         exit(1);
  248.     }
  249.     mktemp(maptmp);
  250.     sprintf(maptpag, "%s.pag", maptmp);
  251.     sprintf(maptdir, "%s.dir", maptmp);
  252.     if (remove(maptpag) < 0 || remove(maptdir) < 0) {
  253.         fprintf(stderr, "Can't remove existing temporary files; %s and", maptpag);
  254.         perror(maptdir);
  255.         exit(1);
  256.     }
  257. #endif
  258.     mapf =  fopen(map, "r");
  259.     if (mapf)
  260.         mapd = create_database(maptmp);
  261.     else
  262.         mapd = 0;
  263. #ifndef DEBUG
  264.     signal(SIGINT, SIG_IGN);
  265. #endif
  266.     if (mapd) {
  267.         int error = read_file(mapf, map, mapd);
  268.         (void) fclose(mapf);
  269.         if (error) {
  270.             fprintf(stderr, "Error creating ndbm map for %s\n", map);
  271.             rc = 1;
  272.         }
  273. #ifdef USE_NDBM
  274.         sprintf(mappag, "%s.pag", map);
  275.         sprintf(mapdir, "%s.dir", map);
  276.         if (rename(maptpag, mappag) < 0) {
  277.             fprintf(stderr, "Couldn't rename %s to ", maptpag);
  278.             perror(mappag);
  279.             /* Throw away the temporary map */
  280.             unlink(maptpag);
  281.             unlink(maptdir);
  282.             rc = 1;
  283.         } else if (rename(maptdir, mapdir) < 0) {
  284.             fprintf(stderr, "Couldn't rename %s to ", maptdir);
  285.             perror(mapdir);
  286.             /* Put the .pag file back */
  287.             rename(mappag, maptpag);
  288.             /* Throw away remaining part of original map */
  289.             unlink(mapdir);
  290.             fprintf(stderr, "WARNING: existing map \"%s.{dir,pag}\" destroyed\n", map);
  291.             rc = 1;
  292.         }
  293. #endif
  294.     } else {
  295. #ifdef USE_NDBM
  296.         fprintf(stderr, "Can't open \"%s.{dir,pag}\" for ", map);
  297. #endif
  298.         perror("writing");
  299.         rc = 1;
  300.     }
  301.     exit(rc);
  302. }
  303. #else
  304. main()
  305. {
  306.     fputs("This system does not support hashed database files\n", stderr);
  307.     exit(0);
  308. }
  309. #endif
  310.