Annotation of src/usr.bin/mandoc/manpath.c, Revision 1.3
1.3 ! schwarze 1: /* $Id: manpath.c,v 1.2 2011/12/12 01:59:13 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:
1.3 ! schwarze 19: #include <sys/param.h>
! 20:
1.1 schwarze 21: #include <assert.h>
22: #include <ctype.h>
23: #include <limits.h>
24: #include <stdio.h>
25: #include <stdlib.h>
26: #include <string.h>
27:
28: #include "mandoc.h"
29: #include "manpath.h"
30:
31: #define MAN_CONF_FILE "/etc/man.conf"
32: #define MAN_CONF_KEY "_whatdb"
33:
34: static void manpath_add(struct manpaths *, const char *);
1.3 ! schwarze 35: static void manpath_parseline(struct manpaths *, char *);
1.1 schwarze 36:
37: void
1.2 schwarze 38: manpath_parse(struct manpaths *dirs, const char *file,
39: char *defp, char *auxp)
1.1 schwarze 40: {
41:
42: manpath_parseline(dirs, auxp);
43:
44: if (NULL == defp)
45: defp = getenv("MANPATH");
46:
47: if (NULL == defp)
1.3 ! schwarze 48: manpath_manconf(dirs, file ? file : MAN_CONF_FILE);
1.1 schwarze 49: else
50: manpath_parseline(dirs, defp);
51: }
52:
53: /*
54: * Parse a FULL pathname from a colon-separated list of arrays.
55: */
1.3 ! schwarze 56: static void
1.1 schwarze 57: manpath_parseline(struct manpaths *dirs, char *path)
58: {
59: char *dir;
60:
61: if (NULL == path)
62: return;
63:
64: for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":"))
65: manpath_add(dirs, dir);
66: }
67:
68: /*
69: * Add a directory to the array, ignoring bad directories.
70: * Grow the array one-by-one for simplicity's sake.
71: */
72: static void
73: manpath_add(struct manpaths *dirs, const char *dir)
74: {
75: char buf[PATH_MAX];
76: char *cp;
77: int i;
78:
79: if (NULL == (cp = realpath(dir, buf)))
80: return;
81:
82: for (i = 0; i < dirs->sz; i++)
83: if (0 == strcmp(dirs->paths[i], dir))
84: return;
85:
86: dirs->paths = mandoc_realloc
87: (dirs->paths,
88: ((size_t)dirs->sz + 1) * sizeof(char *));
89:
90: dirs->paths[dirs->sz++] = mandoc_strdup(cp);
91: }
92:
93: void
94: manpath_free(struct manpaths *p)
95: {
96: int i;
97:
98: for (i = 0; i < p->sz; i++)
99: free(p->paths[i]);
100:
101: free(p->paths);
102: }
103:
104: void
1.2 schwarze 105: manpath_manconf(struct manpaths *dirs, const char *file)
1.1 schwarze 106: {
107: FILE *stream;
108: char *p, *q;
109: size_t len, keysz;
110:
111: keysz = strlen(MAN_CONF_KEY);
112: assert(keysz > 0);
113:
114: if (NULL == (stream = fopen(file, "r")))
115: return;
116:
117: while (NULL != (p = fgetln(stream, &len))) {
118: if (0 == len || '\n' != p[--len])
119: break;
120: p[len] = '\0';
121: while (isspace((unsigned char)*p))
122: p++;
123: if (strncmp(MAN_CONF_KEY, p, keysz))
124: continue;
125: p += keysz;
126: while (isspace(*p))
127: p++;
128: if ('\0' == *p)
129: continue;
130: if (NULL == (q = strrchr(p, '/')))
131: continue;
132: *q = '\0';
133: manpath_add(dirs, p);
134: }
135:
136: fclose(stream);
137: }