11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
31 */
32
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <sys/param.h>
36
37 #include <ctype.h>
38 #include <dirent.h>
39 #include <err.h>
40 #include <signal.h>
41 #include <stddef.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46
47 #include "man.h"
48 #include "stringlist.h"
49
50
159
160 if ((sbuf = malloc(sizeof (struct sbuf))) == NULL)
161 err(1, "malloc");
162 if ((sbuf->content = (char *)malloc(LINE_ALLOC)) == NULL)
163 err(1, "malloc");
164 sbuf->last = sbuf->content + LINE_ALLOC - 1;
165 sbuf_clear(sbuf);
166
167 return (sbuf);
168 }
169
170 /*
171 * Ensure that there is enough room in the sbuf
172 * for nchars more characters.
173 */
174 static void
175 sbuf_need(struct sbuf *sbuf, int nchars)
176 {
177 char *new_content;
178 size_t size, cntsize;
179
180 /* Double the size of the allocation until the buffer is big enough */
181 while (sbuf->end + nchars > sbuf->last) {
182 size = sbuf->last + 1 - sbuf->content;
183 size *= 2;
184 cntsize = sbuf->end - sbuf->content;
185
186 new_content = (char *)malloc(size);
187 (void) memcpy(new_content, sbuf->content, cntsize);
188 free(sbuf->content);
189 sbuf->content = new_content;
190 sbuf->end = new_content + cntsize;
191 sbuf->last = new_content + size - 1;
192 }
193 }
194
195 /*
196 * Append a string of a given length to the sbuf.
197 */
198 static void
199 sbuf_append(struct sbuf *sbuf, const char *text, int length)
200 {
201 if (length > 0) {
202 sbuf_need(sbuf, length);
203 (void) memcpy(sbuf->end, text, length);
204 sbuf->end += length;
205 }
206 }
207
208 /*
242
243 /*
244 * Return the null-terminated string built by the sbuf.
245 */
246 static char *
247 sbuf_content(struct sbuf *sbuf)
248 {
249
250 *sbuf->end = '\0';
251 return (sbuf->content);
252 }
253
254 /*
255 * Return true if no man page exists in the directory with
256 * any of the names in the stringlist.
257 */
258 static int
259 no_page_exists(char *dir, stringlist *names, char *suffix)
260 {
261 char path[MAXPATHLEN];
262 size_t i;
263
264 for (i = 0; i < names->sl_cur; i++) {
265 (void) snprintf(path, MAXPATHLEN, "%s/%s.%s.gz",
266 dir, names->sl_str[i], suffix);
267 if (access(path, F_OK) < 0) {
268 path[strlen(path) - 3] = '\0';
269 if (access(path, F_OK) < 0)
270 continue;
271 }
272 return (0);
273 }
274 return (1);
275 }
276
277 /* ARGSUSED sig */
278 static void
279 trap_signal(int sig)
280 {
281
282 if (tempfile[0] != '\0')
283 (void) unlink(tempfile);
284
285 exit(1);
286 }
287
288 /*
289 * Attempt to open an output file.
290 * Return NULL if unsuccessful.
291 */
292 static FILE *
293 open_output(char *name)
|
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
31 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
32 */
33
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <sys/param.h>
37
38 #include <ctype.h>
39 #include <dirent.h>
40 #include <err.h>
41 #include <signal.h>
42 #include <stddef.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47
48 #include "man.h"
49 #include "stringlist.h"
50
51
160
161 if ((sbuf = malloc(sizeof (struct sbuf))) == NULL)
162 err(1, "malloc");
163 if ((sbuf->content = (char *)malloc(LINE_ALLOC)) == NULL)
164 err(1, "malloc");
165 sbuf->last = sbuf->content + LINE_ALLOC - 1;
166 sbuf_clear(sbuf);
167
168 return (sbuf);
169 }
170
171 /*
172 * Ensure that there is enough room in the sbuf
173 * for nchars more characters.
174 */
175 static void
176 sbuf_need(struct sbuf *sbuf, int nchars)
177 {
178 char *new_content;
179 size_t size, cntsize;
180 size_t grow = 128;
181
182 while (grow < nchars) {
183 grow += 128; /* we grow in chunks of 128 bytes */
184 }
185
186 /* Grow if the buffer isn't big enough */
187 if (sbuf->end + nchars > sbuf->last) {
188 size = sbuf->last + 1 - sbuf->content;
189 size += grow;
190 cntsize = sbuf->end - sbuf->content;
191
192 if ((new_content = realloc(sbuf->content, size)) == NULL) {
193 perror("realloc");
194 if (tempfile[0] != '\0')
195 (void) unlink(tempfile);
196 exit(1);
197 }
198 sbuf->content = new_content;
199 sbuf->end = new_content + cntsize;
200 sbuf->last = new_content + size - 1;
201 }
202 }
203
204 /*
205 * Append a string of a given length to the sbuf.
206 */
207 static void
208 sbuf_append(struct sbuf *sbuf, const char *text, int length)
209 {
210 if (length > 0) {
211 sbuf_need(sbuf, length);
212 (void) memcpy(sbuf->end, text, length);
213 sbuf->end += length;
214 }
215 }
216
217 /*
251
252 /*
253 * Return the null-terminated string built by the sbuf.
254 */
255 static char *
256 sbuf_content(struct sbuf *sbuf)
257 {
258
259 *sbuf->end = '\0';
260 return (sbuf->content);
261 }
262
263 /*
264 * Return true if no man page exists in the directory with
265 * any of the names in the stringlist.
266 */
267 static int
268 no_page_exists(char *dir, stringlist *names, char *suffix)
269 {
270 char path[MAXPATHLEN];
271 char *suffixes[] = { "", ".gz", ".bz2", NULL };
272 size_t i;
273 int j;
274
275 for (i = 0; i < names->sl_cur; i++) {
276 for (j = 0; suffixes[j] != NULL; j++) {
277 (void) snprintf(path, MAXPATHLEN, "%s/%s.%s%s",
278 dir, names->sl_str[i], suffix, suffixes[j]);
279 if (access(path, F_OK) == 0) {
280 return (0);
281 }
282 }
283 }
284 return (1);
285 }
286
287 /* ARGSUSED sig */
288 static void
289 trap_signal(int sig)
290 {
291
292 if (tempfile[0] != '\0')
293 (void) unlink(tempfile);
294
295 exit(1);
296 }
297
298 /*
299 * Attempt to open an output file.
300 * Return NULL if unsuccessful.
301 */
302 static FILE *
303 open_output(char *name)
|