Annotation of mandoc/manpath.c, Revision 1.5
1.5 ! schwarze 1: /* $Id: manpath.c,v 1.4 2011/11/26 22:38:11 schwarze 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.5 ! schwarze 39: manpath_parse(struct manpaths *dirs, const char *file,
! 40: char *defp, char *auxp)
1.1 kristaps 41: {
42:
1.4 schwarze 43: manpath_parseline(dirs, auxp);
44:
45: if (NULL == defp)
1.1 kristaps 46: defp = getenv("MANPATH");
47:
48: if (NULL == defp)
1.5 ! schwarze 49: manpath_parseconf(dirs, file);
1.1 kristaps 50: else
51: manpath_parseline(dirs, defp);
52: }
53:
54: /*
55: * Parse a FULL pathname from a colon-separated list of arrays.
56: */
57: void
1.4 schwarze 58: manpath_parseline(struct manpaths *dirs, char *path)
1.1 kristaps 59: {
60: char *dir;
61:
62: if (NULL == path)
63: return;
64:
65: for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":"))
66: manpath_add(dirs, dir);
67: }
68:
69: /*
70: * Add a directory to the array, ignoring bad directories.
71: * Grow the array one-by-one for simplicity's sake.
72: */
73: static void
1.4 schwarze 74: manpath_add(struct manpaths *dirs, const char *dir)
1.1 kristaps 75: {
76: char buf[PATH_MAX];
77: char *cp;
78: int i;
79:
80: if (NULL == (cp = realpath(dir, buf)))
81: return;
82:
83: for (i = 0; i < dirs->sz; i++)
84: if (0 == strcmp(dirs->paths[i], dir))
85: return;
86:
87: dirs->paths = mandoc_realloc
1.4 schwarze 88: (dirs->paths,
1.1 kristaps 89: ((size_t)dirs->sz + 1) * sizeof(char *));
90:
91: dirs->paths[dirs->sz++] = mandoc_strdup(cp);
92: }
93:
94: void
1.5 ! schwarze 95: manpath_parseconf(struct manpaths *dirs, const char *file)
1.1 kristaps 96: {
1.2 kristaps 97: #ifdef USE_MANPATH
1.1 kristaps 98: FILE *stream;
99: char *buf;
100: size_t sz, bsz;
101:
102: /* Open manpath(1). Ignore errors. */
103:
104: stream = popen("manpath", "r");
105: if (NULL == stream)
106: return;
107:
108: buf = NULL;
109: bsz = 0;
110:
111: /* Read in as much output as we can. */
112:
113: do {
114: buf = mandoc_realloc(buf, bsz + 1024);
115: sz = fread(buf + (int)bsz, 1, 1024, stream);
116: bsz += sz;
117: } while (sz > 0);
118:
119: if ( ! ferror(stream) && feof(stream) &&
120: bsz && '\n' == buf[bsz - 1]) {
121: buf[bsz - 1] = '\0';
122: manpath_parseline(dirs, buf);
123: }
124:
125: free(buf);
126: pclose(stream);
127: #else
1.5 ! schwarze 128: manpath_manconf(dirs, file ? file : MAN_CONF_FILE);
1.2 kristaps 129: #endif
130: }
131:
132: void
133: manpath_free(struct manpaths *p)
134: {
135: int i;
136:
137: for (i = 0; i < p->sz; i++)
138: free(p->paths[i]);
139:
140: free(p->paths);
141: }
142:
143: void
1.5 ! schwarze 144: manpath_manconf(struct manpaths *dirs, const char *file)
1.2 kristaps 145: {
146: FILE *stream;
1.1 kristaps 147: char *p, *q;
1.4 schwarze 148: size_t len, keysz;
1.1 kristaps 149:
150: keysz = strlen(MAN_CONF_KEY);
151: assert(keysz > 0);
152:
1.3 kristaps 153: if (NULL == (stream = fopen(file, "r")))
1.1 kristaps 154: return;
155:
156: while (NULL != (p = fgetln(stream, &len))) {
157: if (0 == len || '\n' != p[--len])
158: break;
159: p[len] = '\0';
160: while (isspace((unsigned char)*p))
161: p++;
162: if (strncmp(MAN_CONF_KEY, p, keysz))
163: continue;
164: p += keysz;
165: while (isspace(*p))
166: p++;
167: if ('\0' == *p)
168: continue;
169: if (NULL == (q = strrchr(p, '/')))
170: continue;
171: *q = '\0';
172: manpath_add(dirs, p);
173: }
174:
175: fclose(stream);
176: }
CVSweb