manpath.c (274880) | manpath.c (275432) |
---|---|
1/* $Id: manpath.c,v 1.15 2014/04/23 21:06:41 schwarze Exp $ */ | 1/* $Id: manpath.c,v 1.19 2014/11/27 00:30:40 schwarze Exp $ */ |
2/* | 2/* |
3 * Copyright (c) 2011 Ingo Schwarze | 3 * Copyright (c) 2011, 2014 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 */ | 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" | 18#include "config.h" |
20#endif | |
21 | 19 |
20#include <sys/types.h> 21#include <sys/stat.h> 22 |
|
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_aux.h" 30#include "manpath.h" 31 32#define MAN_CONF_FILE "/etc/man.conf" 33#define MAN_CONF_KEY "_whatdb" 34 | 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_aux.h" 31#include "manpath.h" 32 33#define MAN_CONF_FILE "/etc/man.conf" 34#define MAN_CONF_KEY "_whatdb" 35 |
35static void manpath_add(struct manpaths *, const char *); 36static void manpath_parseline(struct manpaths *, char *); | 36static void manpath_add(struct manpaths *, const char *, int); 37static void manpath_parseline(struct manpaths *, char *, int); |
37 38void 39manpath_parse(struct manpaths *dirs, const char *file, 40 char *defp, char *auxp) 41{ | 38 39void 40manpath_parse(struct manpaths *dirs, const char *file, 41 char *defp, char *auxp) 42{ |
42#ifdef USE_MANPATH | 43#if HAVE_MANPATH |
43 char cmd[(PATH_MAX * 3) + 20]; 44 FILE *stream; 45 char *buf; 46 size_t sz, bsz; 47 48 strlcpy(cmd, "manpath", sizeof(cmd)); 49 if (file) { 50 strlcat(cmd, " -C ", sizeof(cmd)); --- 23 unchanged lines hidden (view full) --- 74 buf = mandoc_realloc(buf, bsz + 1024); 75 sz = fread(buf + bsz, 1, 1024, stream); 76 bsz += sz; 77 } while (sz > 0); 78 79 if ( ! ferror(stream) && feof(stream) && 80 bsz && '\n' == buf[bsz - 1]) { 81 buf[bsz - 1] = '\0'; | 44 char cmd[(PATH_MAX * 3) + 20]; 45 FILE *stream; 46 char *buf; 47 size_t sz, bsz; 48 49 strlcpy(cmd, "manpath", sizeof(cmd)); 50 if (file) { 51 strlcat(cmd, " -C ", sizeof(cmd)); --- 23 unchanged lines hidden (view full) --- 75 buf = mandoc_realloc(buf, bsz + 1024); 76 sz = fread(buf + bsz, 1, 1024, stream); 77 bsz += sz; 78 } while (sz > 0); 79 80 if ( ! ferror(stream) && feof(stream) && 81 bsz && '\n' == buf[bsz - 1]) { 82 buf[bsz - 1] = '\0'; |
82 manpath_parseline(dirs, buf); | 83 manpath_parseline(dirs, buf, 1); |
83 } 84 85 free(buf); 86 pclose(stream); 87#else 88 char *insert; 89 90 /* Always prepend -m. */ | 84 } 85 86 free(buf); 87 pclose(stream); 88#else 89 char *insert; 90 91 /* Always prepend -m. */ |
91 manpath_parseline(dirs, auxp); | 92 manpath_parseline(dirs, auxp, 1); |
92 93 /* If -M is given, it overrides everything else. */ 94 if (NULL != defp) { | 93 94 /* If -M is given, it overrides everything else. */ 95 if (NULL != defp) { |
95 manpath_parseline(dirs, defp); | 96 manpath_parseline(dirs, defp, 1); |
96 return; 97 } 98 99 /* MANPATH and man.conf(5) cooperate. */ 100 defp = getenv("MANPATH"); 101 if (NULL == file) 102 file = MAN_CONF_FILE; 103 104 /* No MANPATH; use man.conf(5) only. */ 105 if (NULL == defp || '\0' == defp[0]) { 106 manpath_manconf(dirs, file); 107 return; 108 } 109 110 /* Prepend man.conf(5) to MANPATH. */ 111 if (':' == defp[0]) { 112 manpath_manconf(dirs, file); | 97 return; 98 } 99 100 /* MANPATH and man.conf(5) cooperate. */ 101 defp = getenv("MANPATH"); 102 if (NULL == file) 103 file = MAN_CONF_FILE; 104 105 /* No MANPATH; use man.conf(5) only. */ 106 if (NULL == defp || '\0' == defp[0]) { 107 manpath_manconf(dirs, file); 108 return; 109 } 110 111 /* Prepend man.conf(5) to MANPATH. */ 112 if (':' == defp[0]) { 113 manpath_manconf(dirs, file); |
113 manpath_parseline(dirs, defp); | 114 manpath_parseline(dirs, defp, 0); |
114 return; 115 } 116 117 /* Append man.conf(5) to MANPATH. */ 118 if (':' == defp[strlen(defp) - 1]) { | 115 return; 116 } 117 118 /* Append man.conf(5) to MANPATH. */ 119 if (':' == defp[strlen(defp) - 1]) { |
119 manpath_parseline(dirs, defp); | 120 manpath_parseline(dirs, defp, 0); |
120 manpath_manconf(dirs, file); 121 return; 122 } 123 124 /* Insert man.conf(5) into MANPATH. */ 125 insert = strstr(defp, "::"); 126 if (NULL != insert) { 127 *insert++ = '\0'; | 121 manpath_manconf(dirs, file); 122 return; 123 } 124 125 /* Insert man.conf(5) into MANPATH. */ 126 insert = strstr(defp, "::"); 127 if (NULL != insert) { 128 *insert++ = '\0'; |
128 manpath_parseline(dirs, defp); | 129 manpath_parseline(dirs, defp, 0); |
129 manpath_manconf(dirs, file); | 130 manpath_manconf(dirs, file); |
130 manpath_parseline(dirs, insert + 1); | 131 manpath_parseline(dirs, insert + 1, 0); |
131 return; 132 } 133 134 /* MANPATH overrides man.conf(5) completely. */ | 132 return; 133 } 134 135 /* MANPATH overrides man.conf(5) completely. */ |
135 manpath_parseline(dirs, defp); | 136 manpath_parseline(dirs, defp, 0); |
136#endif 137} 138 139/* 140 * Parse a FULL pathname from a colon-separated list of arrays. 141 */ 142static void | 137#endif 138} 139 140/* 141 * Parse a FULL pathname from a colon-separated list of arrays. 142 */ 143static void |
143manpath_parseline(struct manpaths *dirs, char *path) | 144manpath_parseline(struct manpaths *dirs, char *path, int complain) |
144{ 145 char *dir; 146 147 if (NULL == path) 148 return; 149 150 for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":")) | 145{ 146 char *dir; 147 148 if (NULL == path) 149 return; 150 151 for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":")) |
151 manpath_add(dirs, dir); | 152 manpath_add(dirs, dir, complain); |
152} 153 154/* 155 * Add a directory to the array, ignoring bad directories. 156 * Grow the array one-by-one for simplicity's sake. 157 */ 158static void | 153} 154 155/* 156 * Add a directory to the array, ignoring bad directories. 157 * Grow the array one-by-one for simplicity's sake. 158 */ 159static void |
159manpath_add(struct manpaths *dirs, const char *dir) | 160manpath_add(struct manpaths *dirs, const char *dir, int complain) |
160{ 161 char buf[PATH_MAX]; | 161{ 162 char buf[PATH_MAX]; |
163 struct stat sb; |
|
162 char *cp; 163 size_t i; 164 | 164 char *cp; 165 size_t i; 166 |
165 if (NULL == (cp = realpath(dir, buf))) | 167 if (NULL == (cp = realpath(dir, buf))) { 168 if (complain) { 169 fputs("manpath: ", stderr); 170 perror(dir); 171 } |
166 return; | 172 return; |
173 } |
|
167 168 for (i = 0; i < dirs->sz; i++) 169 if (0 == strcmp(dirs->paths[i], dir)) 170 return; 171 | 174 175 for (i = 0; i < dirs->sz; i++) 176 if (0 == strcmp(dirs->paths[i], dir)) 177 return; 178 |
179 if (stat(cp, &sb) == -1) { 180 if (complain) { 181 fputs("manpath: ", stderr); 182 perror(dir); 183 } 184 return; 185 } 186 |
|
172 dirs->paths = mandoc_reallocarray(dirs->paths, 173 dirs->sz + 1, sizeof(char *)); 174 175 dirs->paths[dirs->sz++] = mandoc_strdup(cp); 176} 177 178void 179manpath_free(struct manpaths *p) --- 30 unchanged lines hidden (view full) --- 210 p += keysz; 211 while (isspace((unsigned char)*p)) 212 p++; 213 if ('\0' == *p) 214 continue; 215 if (NULL == (q = strrchr(p, '/'))) 216 continue; 217 *q = '\0'; | 187 dirs->paths = mandoc_reallocarray(dirs->paths, 188 dirs->sz + 1, sizeof(char *)); 189 190 dirs->paths[dirs->sz++] = mandoc_strdup(cp); 191} 192 193void 194manpath_free(struct manpaths *p) --- 30 unchanged lines hidden (view full) --- 225 p += keysz; 226 while (isspace((unsigned char)*p)) 227 p++; 228 if ('\0' == *p) 229 continue; 230 if (NULL == (q = strrchr(p, '/'))) 231 continue; 232 *q = '\0'; |
218 manpath_add(dirs, p); | 233 manpath_add(dirs, p, 0); |
219 } 220 221 fclose(stream); 222} | 234 } 235 236 fclose(stream); 237} |