home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume21 / amd / part04 / info_file.c < prev    next >
C/C++ Source or Header  |  1990-04-10  |  4KB  |  224 lines

  1. /*
  2.  * $Id: info_file.c,v 5.1.1.1 90/01/11 17:07:25 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.  *    %W% (Berkeley) %G%
  26.  */
  27.  
  28. /*
  29.  * Get info from file
  30.  */
  31.  
  32. #include "am.h"
  33.  
  34. #ifdef HAS_FILE_MAPS
  35. #include <ctype.h>
  36. #include <sys/stat.h>
  37.  
  38. #define    MAX_LINE_LEN    2048
  39.  
  40. static int read_line(buf, size, fp)
  41. char *buf;
  42. int size;
  43. FILE *fp;
  44. {
  45.     int done = 0;
  46.  
  47.     do {
  48.         while (fgets(buf, size, fp)) {
  49.             int len = strlen(buf);
  50.             done += len;
  51.             if (len > 1 && buf[len-2] == '\\' &&
  52.                     buf[len-1] == '\n') {
  53.                 int ch;
  54.                 buf += len - 2;
  55.                 size -= len - 2;
  56.                 /*
  57.                  * Skip leading white space on next line
  58.                  */
  59.                 while ((ch = getc(fp)) != EOF &&
  60.                     isascii(ch) && isspace(ch))
  61.                         ;
  62.                 (void) ungetc(ch, fp);
  63.             } else {
  64.                 return done;
  65.             }
  66.         }
  67.     } while (size > 0 && !feof(fp));
  68.  
  69.     return done;
  70. }
  71.  
  72. /*
  73.  * Try to locate a key in a file
  74.  */
  75. static int search_or_reload_file(fp, map, key, val, m, fn)
  76. FILE *fp;
  77. char *map;
  78. char *key;
  79. char **val;
  80. mnt_map *m;
  81. void (*fn) P((mnt_map*, char*, char*));
  82. {
  83.     char key_val[MAX_LINE_LEN];
  84.     int chuck = 0;
  85.     int line_no = 0;
  86.  
  87.     while (read_line(key_val, sizeof(key_val), fp)) {
  88.         char *kp;
  89.         char *cp;
  90.         char *hash;
  91.         int len = strlen(key_val);
  92.         line_no++;
  93.  
  94.         /*
  95.          * Make sure we got the whole line
  96.          */
  97.         if (key_val[len-1] != '\n') {
  98.             plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map);
  99.             chuck = 1;
  100.         } else {
  101.             key_val[len-1] = '\0';
  102.         }
  103.  
  104.         /*
  105.          * Strip comments
  106.          */
  107.         hash = strchr(key_val, '#');
  108.         if (hash)
  109.             *hash = '\0';
  110.  
  111.         /*
  112.          * Find start of key
  113.          */
  114.         for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++)
  115.             ;
  116.  
  117.         /*
  118.          * Ignore blank lines
  119.          */
  120.         if (!*kp)
  121.             goto again;
  122.  
  123.         /*
  124.          * Find end of key
  125.          */
  126.         for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++)
  127.             ;
  128.  
  129.         /*
  130.          * Check whether key matches
  131.          */
  132.         if (*cp)
  133.             *cp++ = '\0';
  134.  
  135.         if ((*key == *kp && strcmp(key, kp) == 0) || fn) {
  136.             while (*cp && isascii(*cp) && isspace(*cp))
  137.                 cp++;
  138.             if (*cp) {
  139.                 /*
  140.                  * Return a copy of the data
  141.                  */
  142.                 char *dc = strdup(cp);
  143.                 if (fn)
  144.                     (*fn)(m, kp, dc);
  145.                 else
  146.                     *val = dc;
  147. #ifdef DEBUG
  148.                 dlog("%s returns %s", key, dc);
  149. #endif
  150.                 if (!fn)
  151.                     return 0;
  152.             } else {
  153.                 plog(XLOG_USER, "%s: line %d has no value field", map, line_no);
  154.             }
  155.         }
  156.  
  157. again:
  158.         /*
  159.          * If the last read didn't get a whole line then
  160.          * throw away the remainder before continuing...
  161.          */
  162.         if (chuck) {
  163.             while (fgets(key_val, sizeof(key_val), fp) &&
  164.                 !strchr(key_val, '\n'))
  165.                     ;
  166.             chuck = 0;
  167.         }
  168.     }
  169.  
  170.     return fn ? 0 : ENOENT;
  171. }
  172.  
  173. int file_init(map)
  174. char *map;
  175. {
  176.     FILE *mapf = fopen(map, "r");
  177.     if (mapf) {
  178.         (void) fclose(mapf);
  179.         return 0;
  180.     }
  181.     return errno;
  182. }
  183.  
  184. int file_reload(m, map, fn)
  185. mnt_map *m;
  186. char *map;
  187. void (*fn)();
  188. {
  189.     FILE *mapf = fopen(map, "r");
  190.     if (mapf) {
  191.         int error = search_or_reload_file(mapf, map, 0, 0, m, fn);
  192.         (void) fclose(mapf);
  193.         return error;
  194.     }
  195.  
  196.     return errno;
  197. }
  198.  
  199. int file_search(m, map, key, pval, tp)
  200. mnt_map *m;
  201. char *map;
  202. char *key;
  203. char **pval;
  204. time_t *tp;
  205. {
  206.     FILE *mapf = fopen(map, "r");
  207.     if (mapf) {
  208.         struct stat stb;
  209.         int error;
  210.         error = fstat(fileno(mapf), &stb);
  211.         if (!error && *tp < stb.st_mtime) {
  212.             *tp = stb.st_mtime;
  213.             error = -1;
  214.         } else {
  215.             error = search_or_reload_file(mapf, map, key, pval, 0, 0);
  216.         }
  217.         (void) fclose(mapf);
  218.         return error;
  219.     }
  220.  
  221.     return errno;
  222. }
  223. #endif
  224.