break out special local mail processing (e.g., mapping to the
[unix-history] / usr / src / usr.bin / man / config.c
CommitLineData
1ef31675 1/*
00186a84
KB
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
1ef31675 4 *
f15db449 5 * %sccs.include.redist.c%
1ef31675
KB
6 */
7
8#ifndef lint
10c2c2ed 9static char sccsid[] = "@(#)config.c 8.7 (Berkeley) %G%";
1ef31675
KB
10#endif /* not lint */
11
da0c0e56
KB
12#include <sys/types.h>
13#include <sys/queue.h>
14
15#include <ctype.h>
16#include <err.h>
1ef31675 17#include <errno.h>
da0c0e56 18#include <stdio.h>
011519cd 19#include <stdlib.h>
da0c0e56 20#include <string.h>
011519cd 21
da0c0e56
KB
22#include "config.h"
23#include "pathnames.h"
1ef31675 24
c46750de 25struct _head head;
011519cd 26
1ef31675 27/*
da0c0e56
KB
28 * config --
29 *
30 * Read the configuration file and build a doubly linked
31 * list that looks like:
32 *
33 * tag1 <-> record <-> record <-> record
34 * |
35 * tag2 <-> record <-> record <-> record
1ef31675 36 */
da0c0e56 37void
7d9403e1
KB
38config(fname)
39 char *fname;
1ef31675 40{
c46750de
KB
41 TAG *tp;
42 ENTRY *ep;
da0c0e56 43 FILE *cfp;
011519cd 44 size_t len;
da0c0e56
KB
45 int lcnt;
46 char *p, *t;
47
7d9403e1
KB
48 if (fname == NULL)
49 fname = _PATH_MANCONF;
50 if ((cfp = fopen(fname, "r")) == NULL)
51 err(1, "%s", fname);
c46750de 52 TAILQ_INIT(&head);
10c2c2ed 53 for (lcnt = 1; (p = fgetln(cfp, &len)) != NULL; ++lcnt) {
97231dd4 54 if (len == 1) /* Skip empty lines. */
da0c0e56
KB
55 continue;
56 if (p[len - 1] != '\n') { /* Skip corrupted lines. */
7d9403e1 57 warnx("%s: line %d corrupted", fname, lcnt);
da0c0e56 58 continue;
011519cd 59 }
da0c0e56
KB
60 p[len - 1] = '\0'; /* Terminate the line. */
61
62 /* Skip leading space. */
63 for (; *p != '\0' && isspace(*p); ++p);
64 /* Skip empty/comment lines. */
65 if (*p == '\0' || *p == '#')
011519cd 66 continue;
da0c0e56
KB
67 /* Find first token. */
68 for (t = p; *t && !isspace(*t); ++t);
69 if (*t == '\0') /* Need more than one token.*/
011519cd 70 continue;
da0c0e56
KB
71 *t = '\0';
72
c46750de
KB
73 for (tp = head.tqh_first; /* Find any matching tag. */
74 tp != NULL && strcmp(p, tp->s); tp = tp->q.tqe_next);
da0c0e56 75
c46750de
KB
76 if (tp == NULL) /* Create a new tag. */
77 tp = addlist(p);
da0c0e56
KB
78
79 /*
80 * Attach new records. The keyword _build takes the rest of
81 * the line as a single entity, everything else is white
82 * space separated. The reason we're not just using strtok(3)
83 * for all of the parsing is so we don't get caught if a line
84 * has only a single token on it.
85 */
86 if (!strcmp(p, "_build")) {
87 while (*++t && isspace(*t));
88 if ((ep = malloc(sizeof(ENTRY))) == NULL ||
89 (ep->s = strdup(t)) == NULL)
90 err(1, NULL);
c46750de 91 TAILQ_INSERT_TAIL(&tp->list, ep, q);
18cef530 92 } else for (++t; (p = strtok(t, " \t\n")) != NULL; t = NULL) {
da0c0e56
KB
93 if ((ep = malloc(sizeof(ENTRY))) == NULL ||
94 (ep->s = strdup(p)) == NULL)
95 err(1, NULL);
c46750de 96 TAILQ_INSERT_TAIL(&tp->list, ep, q);
011519cd
KB
97 }
98 }
011519cd 99}
1ef31675 100
da0c0e56
KB
101/*
102 * addlist --
103 * Add a tag to the list.
104 */
c46750de 105TAG *
da0c0e56
KB
106addlist(name)
107 char *name;
011519cd 108{
c46750de 109 TAG *tp;
da0c0e56 110
c46750de
KB
111 if ((tp = calloc(1, sizeof(TAG))) == NULL ||
112 (tp->s = strdup(name)) == NULL)
da0c0e56 113 err(1, NULL);
c46750de
KB
114 TAILQ_INIT(&tp->list);
115 TAILQ_INSERT_TAIL(&head, tp, q);
116 return (tp);
011519cd
KB
117}
118
da0c0e56
KB
119/*
120 * getlist --
c46750de 121 * Return the linked list of entries for a tag if it exists.
da0c0e56 122 */
c46750de 123TAG *
da0c0e56
KB
124getlist(name)
125 char *name;
011519cd 126{
c46750de 127 TAG *tp;
011519cd 128
c46750de
KB
129 for (tp = head.tqh_first; tp != NULL; tp = tp->q.tqe_next)
130 if (!strcmp(name, tp->s))
131 return (tp);
da0c0e56 132 return (NULL);
1ef31675
KB
133}
134
da0c0e56
KB
135void
136debug(l)
137 char *l;
011519cd 138{
c46750de
KB
139 TAG *tp;
140 ENTRY *ep;
011519cd 141
da0c0e56 142 (void)printf("%s ===============\n", l);
c46750de
KB
143 for (tp = head.tqh_first; tp != NULL; tp = tp->q.tqe_next) {
144 printf("%s\n", tp->s);
145 for (ep = tp->list.tqh_first; ep != NULL; ep = ep->q.tqe_next)
da0c0e56 146 printf("\t%s\n", ep->s);
011519cd 147 }
1ef31675 148}