Annotation of src/usr.bin/mandoc/manpath.c, Revision 1.2
1.2 ! schwarze 1: /* $Id: manpath.c,v 1.1 2011/11/26 16:41:35 schwarze Exp $ */
1.1 schwarze 2: /*
3: * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
4: * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <sys/types.h>
20: #include <assert.h>
21: #include <ctype.h>
22: #include <limits.h>
23: #include <stdio.h>
24: #include <stdlib.h>
25: #include <string.h>
26:
27: #include "mandoc.h"
28: #include "manpath.h"
29:
30: #define MAN_CONF_FILE "/etc/man.conf"
31: #define MAN_CONF_KEY "_whatdb"
32:
33: static void manpath_add(struct manpaths *, const char *);
34:
35: void
1.2 ! schwarze 36: manpath_parse(struct manpaths *dirs, const char *file,
! 37: char *defp, char *auxp)
1.1 schwarze 38: {
39:
40: manpath_parseline(dirs, auxp);
41:
42: if (NULL == defp)
43: defp = getenv("MANPATH");
44:
45: if (NULL == defp)
1.2 ! schwarze 46: manpath_parseconf(dirs, file);
1.1 schwarze 47: else
48: manpath_parseline(dirs, defp);
49: }
50:
51: /*
52: * Parse a FULL pathname from a colon-separated list of arrays.
53: */
54: void
55: manpath_parseline(struct manpaths *dirs, char *path)
56: {
57: char *dir;
58:
59: if (NULL == path)
60: return;
61:
62: for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":"))
63: manpath_add(dirs, dir);
64: }
65:
66: /*
67: * Add a directory to the array, ignoring bad directories.
68: * Grow the array one-by-one for simplicity's sake.
69: */
70: static void
71: manpath_add(struct manpaths *dirs, const char *dir)
72: {
73: char buf[PATH_MAX];
74: char *cp;
75: int i;
76:
77: if (NULL == (cp = realpath(dir, buf)))
78: return;
79:
80: for (i = 0; i < dirs->sz; i++)
81: if (0 == strcmp(dirs->paths[i], dir))
82: return;
83:
84: dirs->paths = mandoc_realloc
85: (dirs->paths,
86: ((size_t)dirs->sz + 1) * sizeof(char *));
87:
88: dirs->paths[dirs->sz++] = mandoc_strdup(cp);
89: }
90:
91: void
1.2 ! schwarze 92: manpath_parseconf(struct manpaths *dirs, const char *file)
1.1 schwarze 93: {
94:
1.2 ! schwarze 95: manpath_manconf(dirs, file ? file : MAN_CONF_FILE);
1.1 schwarze 96: }
97:
98: void
99: manpath_free(struct manpaths *p)
100: {
101: int i;
102:
103: for (i = 0; i < p->sz; i++)
104: free(p->paths[i]);
105:
106: free(p->paths);
107: }
108:
109: void
1.2 ! schwarze 110: manpath_manconf(struct manpaths *dirs, const char *file)
1.1 schwarze 111: {
112: FILE *stream;
113: char *p, *q;
114: size_t len, keysz;
115:
116: keysz = strlen(MAN_CONF_KEY);
117: assert(keysz > 0);
118:
119: if (NULL == (stream = fopen(file, "r")))
120: return;
121:
122: while (NULL != (p = fgetln(stream, &len))) {
123: if (0 == len || '\n' != p[--len])
124: break;
125: p[len] = '\0';
126: while (isspace((unsigned char)*p))
127: p++;
128: if (strncmp(MAN_CONF_KEY, p, keysz))
129: continue;
130: p += keysz;
131: while (isspace(*p))
132: p++;
133: if ('\0' == *p)
134: continue;
135: if (NULL == (q = strrchr(p, '/')))
136: continue;
137: *q = '\0';
138: manpath_add(dirs, p);
139: }
140:
141: fclose(stream);
142: }