Annotation of mandoc/manpath.c, Revision 1.4
1.4 ! schwarze 1: /* $Id: manpath.c,v 1.3 2011/11/24 10:44:56 kristaps Exp $ */
1.1 kristaps 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: #ifdef HAVE_CONFIG_H
19: #include "config.h"
20: #endif
21:
1.4 ! schwarze 22: #include <sys/types.h>
1.1 kristaps 23: #include <assert.h>
24: #include <ctype.h>
25: #include <limits.h>
26: #include <stdio.h>
27: #include <stdlib.h>
28: #include <string.h>
29:
30: #include "mandoc.h"
31: #include "manpath.h"
32:
33: #define MAN_CONF_FILE "/etc/man.conf"
34: #define MAN_CONF_KEY "_whatdb"
35:
36: static void manpath_add(struct manpaths *, const char *);
37:
38: void
1.4 ! schwarze 39: manpath_parse(struct manpaths *dirs, char *defp, char *auxp)
1.1 kristaps 40: {
41:
1.4 ! schwarze 42: manpath_parseline(dirs, auxp);
! 43:
! 44: if (NULL == defp)
1.1 kristaps 45: defp = getenv("MANPATH");
46:
47: if (NULL == defp)
48: manpath_parseconf(dirs);
49: else
50: manpath_parseline(dirs, defp);
51: }
52:
53: /*
54: * Parse a FULL pathname from a colon-separated list of arrays.
55: */
56: void
1.4 ! schwarze 57: manpath_parseline(struct manpaths *dirs, char *path)
1.1 kristaps 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
1.4 ! schwarze 73: manpath_add(struct manpaths *dirs, const char *dir)
1.1 kristaps 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
1.4 ! schwarze 87: (dirs->paths,
1.1 kristaps 88: ((size_t)dirs->sz + 1) * sizeof(char *));
89:
90: dirs->paths[dirs->sz++] = mandoc_strdup(cp);
91: }
92:
93: void
94: manpath_parseconf(struct manpaths *dirs)
95: {
1.2 kristaps 96: #ifdef USE_MANPATH
1.1 kristaps 97: FILE *stream;
98: char *buf;
99: size_t sz, bsz;
100:
101: /* Open manpath(1). Ignore errors. */
102:
103: stream = popen("manpath", "r");
104: if (NULL == stream)
105: return;
106:
107: buf = NULL;
108: bsz = 0;
109:
110: /* Read in as much output as we can. */
111:
112: do {
113: buf = mandoc_realloc(buf, bsz + 1024);
114: sz = fread(buf + (int)bsz, 1, 1024, stream);
115: bsz += sz;
116: } while (sz > 0);
117:
118: if ( ! ferror(stream) && feof(stream) &&
119: bsz && '\n' == buf[bsz - 1]) {
120: buf[bsz - 1] = '\0';
121: manpath_parseline(dirs, buf);
122: }
123:
124: free(buf);
125: pclose(stream);
126: #else
1.3 kristaps 127: manpath_manconf(MAN_CONF_FILE, dirs);
1.2 kristaps 128: #endif
129: }
130:
131: void
132: manpath_free(struct manpaths *p)
133: {
134: int i;
135:
136: for (i = 0; i < p->sz; i++)
137: free(p->paths[i]);
138:
139: free(p->paths);
140: }
141:
142: void
1.3 kristaps 143: manpath_manconf(const char *file, struct manpaths *dirs)
1.2 kristaps 144: {
145: FILE *stream;
1.1 kristaps 146: char *p, *q;
1.4 ! schwarze 147: size_t len, keysz;
1.1 kristaps 148:
149: keysz = strlen(MAN_CONF_KEY);
150: assert(keysz > 0);
151:
1.3 kristaps 152: if (NULL == (stream = fopen(file, "r")))
1.1 kristaps 153: return;
154:
155: while (NULL != (p = fgetln(stream, &len))) {
156: if (0 == len || '\n' != p[--len])
157: break;
158: p[len] = '\0';
159: while (isspace((unsigned char)*p))
160: p++;
161: if (strncmp(MAN_CONF_KEY, p, keysz))
162: continue;
163: p += keysz;
164: while (isspace(*p))
165: p++;
166: if ('\0' == *p)
167: continue;
168: if (NULL == (q = strrchr(p, '/')))
169: continue;
170: *q = '\0';
171: manpath_add(dirs, p);
172: }
173:
174: fclose(stream);
175: }
CVSweb