[BACK]Return to manpath.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Annotation of mandoc/manpath.c, Revision 1.7

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

CVSweb