home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.sbin / amd / mk-amd-map / mk-amd-map.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-12  |  7.9 KB  |  349 lines

  1. /*
  2.  * Copyright (c) 1990 Jan-Simon Pendry
  3.  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  4.  * Copyright (c) 1990 The Regents of the University of California.
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Jan-Simon Pendry at Imperial College, London.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  * 3. All advertising materials mentioning features or use of this software
  19.  *    must display the following acknowledgement:
  20.  *    This product includes software developed by the University of
  21.  *    California, Berkeley and its contributors.
  22.  * 4. Neither the name of the University nor the names of its contributors
  23.  *    may be used to endorse or promote products derived from this software
  24.  *    without specific prior written permission.
  25.  *
  26.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  27.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36.  * SUCH DAMAGE.
  37.  *
  38.  *    @(#)mk-amd-map.c    5.4 (Berkeley) 5/12/91
  39.  *
  40.  * $Id: mk-amd-map.c,v 5.2.1.4 91/05/07 22:18:47 jsp Alpha $
  41.  */
  42.  
  43. /*
  44.  * Convert a file map into an ndbm map
  45.  */
  46.  
  47. #ifndef lint
  48. char copyright[] = "\
  49. @(#)Copyright (c) 1990 Jan-Simon Pendry\n\
  50. @(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\
  51. @(#)Copyright (c) 1990 The Regents of the University of California.\n\
  52. @(#)All rights reserved.\n";
  53. #endif /* not lint */
  54.  
  55. #ifndef lint
  56. static char rcsid[] = "$Id: mk-amd-map.c,v 5.2.1.4 91/05/07 22:18:47 jsp Alpha $";
  57. static char sccsid[] = "@(#)mk-amd-map.c    5.4 (Berkeley) 5/12/91";
  58. #endif /* not lint */
  59.  
  60. #include "am.h"
  61.  
  62. #ifndef SIGINT
  63. #include <signal.h>
  64. #endif
  65.  
  66. #ifdef OS_HAS_NDBM
  67. #define HAS_DATABASE
  68. #include <ndbm.h>
  69.  
  70. #define create_database(name) dbm_open(name, O_RDWR|O_CREAT, 0444)
  71.  
  72. static int store_data(db, k, v)
  73. voidp db;
  74. char *k, *v;
  75. {
  76.     datum key, val;
  77.  
  78.     key.dptr = k; val.dptr = v;
  79.     key.dsize = strlen(k) + 1;
  80.     val.dsize = strlen(v) + 1;
  81.     return dbm_store((DBM *) db, key, val, DBM_INSERT);
  82. }
  83.  
  84. #endif /* OS_HAS_NDBM */
  85.  
  86. #ifdef HAS_DATABASE
  87. #include <fcntl.h>
  88. #include <ctype.h>
  89.  
  90. static int read_line(buf, size, fp)
  91. char *buf;
  92. int size;
  93. FILE *fp;
  94. {
  95.     int done = 0;
  96.  
  97.     do {
  98.         while (fgets(buf, size, fp)) {
  99.             int len = strlen(buf);
  100.             done += len;
  101.             if (len > 1 && buf[len-2] == '\\' &&
  102.                     buf[len-1] == '\n') {
  103.                 int ch;
  104.                 buf += len - 2;
  105.                 size -= len - 2;
  106.                 *buf = '\n'; buf[1] = '\0';
  107.                 /*
  108.                  * Skip leading white space on next line
  109.                  */
  110.                 while ((ch = getc(fp)) != EOF &&
  111.                     isascii(ch) && isspace(ch))
  112.                         ;
  113.                 (void) ungetc(ch, fp);
  114.             } else {
  115.                 return done;
  116.             }
  117.         }
  118.     } while (size > 0 && !feof(fp));
  119.  
  120.     return done;
  121. }
  122.  
  123. /*
  124.  * Read through a map
  125.  */
  126. static int read_file(fp, map, db)
  127. FILE *fp;
  128. char *map;
  129. voidp db;
  130. {
  131.     char key_val[2048];
  132.     int chuck = 0;
  133.     int line_no = 0;
  134.     int errs = 0;
  135.  
  136.     while (read_line(key_val, sizeof(key_val), fp)) {
  137.         char *kp;
  138.         char *cp;
  139.         char *hash;
  140.         int len = strlen(key_val);
  141.         line_no++;
  142.  
  143.         /*
  144.          * Make sure we got the whole line
  145.          */
  146.         if (key_val[len-1] != '\n') {
  147.             fprintf(stderr, "line %d in \"%s\" is too long", line_no, map);
  148.             chuck = 1;
  149.         } else {
  150.             key_val[len-1] = '\0';
  151.         }
  152.  
  153.         /*
  154.          * Strip comments
  155.          */
  156.         hash = strchr(key_val, '#');
  157.         if (hash)
  158.             *hash = '\0';
  159.  
  160.         /*
  161.          * Find start of key
  162.          */
  163.         for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++)
  164.             ;
  165.  
  166.         /*
  167.          * Ignore blank lines
  168.          */
  169.         if (!*kp)
  170.             goto again;
  171.  
  172.         /*
  173.          * Find end of key
  174.          */
  175.         for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++)
  176.             ;
  177.  
  178.         /*
  179.          * Check whether key matches, or whether
  180.          * the entry is a wildcard entry.
  181.          */
  182.         if (*cp)
  183.             *cp++ = '\0';
  184.         while (*cp && isascii(*cp) && isspace(*cp))
  185.             cp++;
  186.         if (*kp == '+') {
  187.             fprintf(stderr, "Can't interpolate %s\n", kp);
  188.             errs++;
  189.         } else if (*cp) {
  190.             if (db) {
  191.                 if (store_data(db, kp, cp) < 0) {
  192.                     fprintf(stderr, "Could store %s -> %s\n", kp, cp);
  193.                     errs++;
  194.                 }
  195.             } else {
  196.                 printf("%s\t%s\n", kp, cp);
  197.             }
  198.         } else {
  199.             fprintf(stderr, "%s: line %d has no value field", map, line_no);
  200.             errs++;
  201.         }
  202.  
  203. again:
  204.         /*
  205.          * If the last read didn't get a whole line then
  206.          * throw away the remainder before continuing...
  207.          */
  208.         if (chuck) {
  209.             while (fgets(key_val, sizeof(key_val), fp) &&
  210.                 !strchr(key_val, '\n'))
  211.                     ;
  212.             chuck = 0;
  213.         }
  214.     }
  215.     return errs;
  216. }
  217.  
  218. static int remove_file(f)
  219. char *f;
  220. {
  221.     if (unlink(f) < 0 && errno != ENOENT)
  222.         return -1;
  223.     return 0;
  224. }
  225.  
  226. main(argc, argv)
  227. int argc;
  228. char *argv[];
  229. {
  230.     FILE *mapf;
  231.     char *map;
  232.     int rc = 0;
  233.     DBM *mapd;
  234.     static char maptmp[] = "dbmXXXXXX";
  235.     char maptpag[16], maptdir[16];
  236.     char *mappag, *mapdir;
  237.     int len;
  238.     char *sl;
  239.     int printit = 0;
  240.     int usage = 0;
  241.     int ch;
  242.     extern int optind;
  243.  
  244.     while ((ch = getopt(argc, argv, "p")) != EOF)
  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.  
  259.     map = argv[optind];
  260.     sl = strrchr(map, '/');
  261.     if (sl) {
  262.         *sl = '\0';
  263.         if (chdir(map) < 0) {
  264.             fputs("Can't chdir to ", stderr);
  265.             perror(map);
  266.             exit(1);
  267.         }
  268.         map = sl + 1;
  269.     }
  270.  
  271.     if (!printit) {
  272.         len = strlen(map);
  273.         mappag = (char *) malloc(len + 5);
  274.         mapdir = (char *) malloc(len + 5);
  275.         if (!mappag || !mapdir) {
  276.             perror("mk-amd-map: malloc");
  277.             exit(1);
  278.         }
  279.         mktemp(maptmp);
  280.         sprintf(maptpag, "%s.pag", maptmp);
  281.         sprintf(maptdir, "%s.dir", maptmp);
  282.         if (remove_file(maptpag) < 0 || remove_file(maptdir) < 0) {
  283.             fprintf(stderr, "Can't remove existing temporary files; %s and", maptpag);
  284.             perror(maptdir);
  285.             exit(1);
  286.         }
  287.     }
  288.  
  289.     mapf =  fopen(map, "r");
  290.     if (mapf && !printit)
  291.         mapd = create_database(maptmp);
  292.     else
  293.         mapd = 0;
  294.  
  295. #ifndef DEBUG
  296.     signal(SIGINT, SIG_IGN);
  297. #endif
  298.  
  299.     if (mapd || printit) {
  300.         int error = read_file(mapf, map, mapd);
  301.         (void) fclose(mapf);
  302.         if (printit) {
  303.             if (error) {
  304.                 fprintf(stderr, "Error creating ndbm map for %s\n", map);
  305.                 rc = 1;
  306.             }
  307.         } else {
  308.             if (error) {
  309.                 fprintf(stderr, "Error reading source file  %s\n", map);
  310.                 rc = 1;
  311.             } else {
  312.                 sprintf(mappag, "%s.pag", map);
  313.                 sprintf(mapdir, "%s.dir", map);
  314.                 if (rename(maptpag, mappag) < 0) {
  315.                     fprintf(stderr, "Couldn't rename %s to ", maptpag);
  316.                     perror(mappag);
  317.                     /* Throw away the temporary map */
  318.                     unlink(maptpag);
  319.                     unlink(maptdir);
  320.                     rc = 1;
  321.                 } else if (rename(maptdir, mapdir) < 0) {
  322.                     fprintf(stderr, "Couldn't rename %s to ", maptdir);
  323.                     perror(mapdir);
  324.                     /* Put the .pag file back */
  325.                     rename(mappag, maptpag);
  326.                     /* Throw away remaining part of original map */
  327.                     unlink(mapdir);
  328.                     fprintf(stderr,
  329.                         "WARNING: existing map \"%s.{dir,pag}\" destroyed\n",
  330.                         map);
  331.                     rc = 1;
  332.                 }
  333.             }
  334.         }
  335.     } else {
  336.         fprintf(stderr, "Can't open \"%s.{dir,pag}\" for ", map);
  337.         perror("writing");
  338.         rc = 1;
  339.     }
  340.     exit(rc);
  341. }
  342. #else
  343. main()
  344. {
  345.     fputs("mk-amd-map: This system does not support hashed database files\n", stderr);
  346.     exit(1);
  347. }
  348. #endif /* HAS_DATABASE */
  349.