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