| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: makewhatis.c,v 1.49 2013/06/24 20:57:47 christos Exp $ */ | | 1 | /* $NetBSD: makewhatis.c,v 1.49.20.1 2018/11/18 11:58:20 martin Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1999 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1999 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Matthias Scheler. | | 8 | * by Matthias Scheler. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -27,47 +27,48 @@ | | | @@ -27,47 +27,48 @@ |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #if HAVE_NBTOOL_CONFIG_H | | 32 | #if HAVE_NBTOOL_CONFIG_H |
33 | #include "nbtool_config.h" | | 33 | #include "nbtool_config.h" |
34 | #endif | | 34 | #endif |
35 | | | 35 | |
36 | #include <sys/cdefs.h> | | 36 | #include <sys/cdefs.h> |
37 | #if !defined(lint) | | 37 | #if !defined(lint) |
38 | __COPYRIGHT("@(#) Copyright (c) 1999\ | | 38 | __COPYRIGHT("@(#) Copyright (c) 1999\ |
39 | The NetBSD Foundation, Inc. All rights reserved."); | | 39 | The NetBSD Foundation, Inc. All rights reserved."); |
40 | __RCSID("$NetBSD: makewhatis.c,v 1.49 2013/06/24 20:57:47 christos Exp $"); | | 40 | __RCSID("$NetBSD: makewhatis.c,v 1.49.20.1 2018/11/18 11:58:20 martin Exp $"); |
41 | #endif /* not lint */ | | 41 | #endif /* not lint */ |
42 | | | 42 | |
43 | #include <sys/types.h> | | 43 | #include <sys/types.h> |
44 | #include <sys/param.h> | | 44 | #include <sys/param.h> |
45 | #include <sys/queue.h> | | 45 | #include <sys/queue.h> |
46 | #include <sys/stat.h> | | 46 | #include <sys/stat.h> |
47 | #include <sys/wait.h> | | 47 | #include <sys/wait.h> |
48 | | | 48 | |
49 | #include <ctype.h> | | 49 | #include <ctype.h> |
50 | #include <err.h> | | 50 | #include <err.h> |
51 | #include <errno.h> | | 51 | #include <errno.h> |
52 | #include <fcntl.h> | | 52 | #include <fcntl.h> |
53 | #include <fts.h> | | 53 | #include <fts.h> |
54 | #include <glob.h> | | 54 | #include <glob.h> |
55 | #include <locale.h> | | 55 | #include <locale.h> |
56 | #include <paths.h> | | 56 | #include <paths.h> |
57 | #include <signal.h> | | 57 | #include <signal.h> |
58 | #include <stdio.h> | | 58 | #include <stdio.h> |
59 | #include <stdlib.h> | | 59 | #include <stdlib.h> |
60 | #include <string.h> | | 60 | #include <string.h> |
| | | 61 | #include <time.h> |
61 | #include <unistd.h> | | 62 | #include <unistd.h> |
62 | #include <zlib.h> | | 63 | #include <zlib.h> |
63 | #include <util.h> | | 64 | #include <util.h> |
64 | | | 65 | |
65 | #include <man/manconf.h> | | 66 | #include <man/manconf.h> |
66 | #include <man/pathnames.h> | | 67 | #include <man/pathnames.h> |
67 | | | 68 | |
68 | #ifndef NROFF | | 69 | #ifndef NROFF |
69 | #define NROFF "nroff" | | 70 | #define NROFF "nroff" |
70 | #endif | | 71 | #endif |
71 | | | 72 | |
72 | typedef struct manpagestruct manpage; | | 73 | typedef struct manpagestruct manpage; |
73 | struct manpagestruct { | | 74 | struct manpagestruct { |
| @@ -87,30 +88,30 @@ struct whatisstruct { | | | @@ -87,30 +88,30 @@ struct whatisstruct { |
87 | | | 88 | |
88 | int main(int, char * const *); | | 89 | int main(int, char * const *); |
89 | static char *findwhitespace(char *); | | 90 | static char *findwhitespace(char *); |
90 | static char *strmove(char *, char *); | | 91 | static char *strmove(char *, char *); |
91 | static char *GetS(gzFile, char *, size_t); | | 92 | static char *GetS(gzFile, char *, size_t); |
92 | static int pathnamesection(const char *, const char *); | | 93 | static int pathnamesection(const char *, const char *); |
93 | static int manpagesection(char *); | | 94 | static int manpagesection(char *); |
94 | static char *createsectionstring(char *); | | 95 | static char *createsectionstring(char *); |
95 | static void addmanpage(manpage **, ino_t, char *, size_t, size_t); | | 96 | static void addmanpage(manpage **, ino_t, char *, size_t, size_t); |
96 | static void addwhatis(whatis **, char *, char *); | | 97 | static void addwhatis(whatis **, char *, char *); |
97 | static char *makesection(int); | | 98 | static char *makesection(int); |
98 | static char *makewhatisline(const char *, const char *, const char *); | | 99 | static char *makewhatisline(const char *, const char *, const char *); |
99 | static void catpreprocess(char *); | | 100 | static void catpreprocess(char *); |
100 | static char *parsecatpage(const char *, gzFile *); | | 101 | static char *parsecatpage(const char *, gzFile); |
101 | static int manpreprocess(char *); | | 102 | static int manpreprocess(char *); |
102 | static char *nroff(const char *, gzFile *); | | 103 | static char *nroff(const char *, gzFile); |
103 | static char *parsemanpage(const char *, gzFile *, int); | | 104 | static char *parsemanpage(const char *, gzFile, int); |
104 | static char *getwhatisdata(char *); | | 105 | static char *getwhatisdata(char *); |
105 | static void processmanpages(manpage **, whatis **); | | 106 | static void processmanpages(manpage **, whatis **); |
106 | static void dumpwhatis(FILE *, whatis *); | | 107 | static void dumpwhatis(FILE *, whatis *); |
107 | static int makewhatis(char * const *manpath); | | 108 | static int makewhatis(char * const *manpath); |
108 | | | 109 | |
109 | static char * const default_manpath[] = { | | 110 | static char * const default_manpath[] = { |
110 | "/usr/share/man", | | 111 | "/usr/share/man", |
111 | NULL | | 112 | NULL |
112 | }; | | 113 | }; |
113 | | | 114 | |
114 | static const char *sectionext = "0123456789ln"; | | 115 | static const char *sectionext = "0123456789ln"; |
115 | static const char *whatisdb = _PATH_WHATIS; | | 116 | static const char *whatisdb = _PATH_WHATIS; |
116 | static const char *whatisdb_new = _PATH_WHATIS ".new"; | | 117 | static const char *whatisdb_new = _PATH_WHATIS ".new"; |
| @@ -614,27 +615,27 @@ makewhatisline(const char *file, const c | | | @@ -614,27 +615,27 @@ makewhatisline(const char *file, const c |
614 | llen = strlen(line); | | 615 | llen = strlen(line); |
615 | dlen = strlen(del[i]); | | 616 | dlen = strlen(del[i]); |
616 | | | 617 | |
617 | result = emalloc(llen - dlen + slen + 1); | | 618 | result = emalloc(llen - dlen + slen + 1); |
618 | pos = ptr - line; | | 619 | pos = ptr - line; |
619 | | | 620 | |
620 | (void)memcpy(result, line, pos); | | 621 | (void)memcpy(result, line, pos); |
621 | (void)memcpy(&result[pos], section, slen); | | 622 | (void)memcpy(&result[pos], section, slen); |
622 | (void)strcpy(&result[pos + slen], &line[pos + dlen]); | | 623 | (void)strcpy(&result[pos + slen], &line[pos + dlen]); |
623 | return result; | | 624 | return result; |
624 | } | | 625 | } |
625 | | | 626 | |
626 | static char * | | 627 | static char * |
627 | parsecatpage(const char *name, gzFile *in) | | 628 | parsecatpage(const char *name, gzFile in) |
628 | { | | 629 | { |
629 | char buffer[8192]; | | 630 | char buffer[8192]; |
630 | char *section, *ptr, *last; | | 631 | char *section, *ptr, *last; |
631 | size_t size; | | 632 | size_t size; |
632 | | | 633 | |
633 | do { | | 634 | do { |
634 | if (GetS(in, buffer, sizeof(buffer)) == NULL) | | 635 | if (GetS(in, buffer, sizeof(buffer)) == NULL) |
635 | return NULL; | | 636 | return NULL; |
636 | } | | 637 | } |
637 | while (buffer[0] == '\n'); | | 638 | while (buffer[0] == '\n'); |
638 | | | 639 | |
639 | section = NULL; | | 640 | section = NULL; |
640 | if ((ptr = strchr(buffer, '(')) != NULL) { | | 641 | if ((ptr = strchr(buffer, '(')) != NULL) { |
| @@ -759,27 +760,27 @@ manpreprocess(char *line) | | | @@ -759,27 +760,27 @@ manpreprocess(char *line) |
759 | } else { | | 760 | } else { |
760 | to += length; | | 761 | to += length; |
761 | *to++ = ')'; | | 762 | *to++ = ')'; |
762 | length = strlen(trail); | | 763 | length = strlen(trail); |
763 | (void) memmove(to, trail, length + 1); | | 764 | (void) memmove(to, trail, length + 1); |
764 | } | | 765 | } |
765 | } | | 766 | } |
766 | } | | 767 | } |
767 | | | 768 | |
768 | return 0; | | 769 | return 0; |
769 | } | | 770 | } |
770 | | | 771 | |
771 | static char * | | 772 | static char * |
772 | nroff(const char *inname, gzFile *in) | | 773 | nroff(const char *inname, gzFile in) |
773 | { | | 774 | { |
774 | char tempname[MAXPATHLEN], buffer[65536], *data; | | 775 | char tempname[MAXPATHLEN], buffer[65536], *data; |
775 | int tempfd, bytes, pipefd[2], status; | | 776 | int tempfd, bytes, pipefd[2], status; |
776 | static int devnull = -1; | | 777 | static int devnull = -1; |
777 | pid_t child; | | 778 | pid_t child; |
778 | | | 779 | |
779 | if (gzrewind(in) < 0) | | 780 | if (gzrewind(in) < 0) |
780 | err(EXIT_FAILURE, "Cannot rewind pipe"); | | 781 | err(EXIT_FAILURE, "Cannot rewind pipe"); |
781 | | | 782 | |
782 | if ((devnull < 0) && | | 783 | if ((devnull < 0) && |
783 | ((devnull = open(_PATH_DEVNULL, O_WRONLY, 0)) < 0)) | | 784 | ((devnull = open(_PATH_DEVNULL, O_WRONLY, 0)) < 0)) |
784 | err(EXIT_FAILURE, "Cannot open `/dev/null'"); | | 785 | err(EXIT_FAILURE, "Cannot open `/dev/null'"); |
785 | | | 786 | |
| @@ -858,27 +859,27 @@ nroff(const char *inname, gzFile *in) | | | @@ -858,27 +859,27 @@ nroff(const char *inname, gzFile *in) |
858 | while (waitpid(child, &status, 0) != child); | | 859 | while (waitpid(child, &status, 0) != child); |
859 | if ((data != NULL) && | | 860 | if ((data != NULL) && |
860 | !(WIFEXITED(status) && (WEXITSTATUS(status) == 0))) { | | 861 | !(WIFEXITED(status) && (WEXITSTATUS(status) == 0))) { |
861 | free(data); | | 862 | free(data); |
862 | errx(EXIT_FAILURE, NROFF " on `%s' exited with %d status", | | 863 | errx(EXIT_FAILURE, NROFF " on `%s' exited with %d status", |
863 | inname, WEXITSTATUS(status)); | | 864 | inname, WEXITSTATUS(status)); |
864 | } | | 865 | } |
865 | | | 866 | |
866 | (void)unlink(tempname); | | 867 | (void)unlink(tempname); |
867 | return data; | | 868 | return data; |
868 | } | | 869 | } |
869 | | | 870 | |
870 | static char * | | 871 | static char * |
871 | parsemanpage(const char *name, gzFile *in, int defaultsection) | | 872 | parsemanpage(const char *name, gzFile in, int defaultsection) |
872 | { | | 873 | { |
873 | char *section, buffer[8192], *ptr; | | 874 | char *section, buffer[8192], *ptr; |
874 | static const char POD[] = ".\\\" Automatically generated by Pod"; | | 875 | static const char POD[] = ".\\\" Automatically generated by Pod"; |
875 | static const char IX[] = ".IX TITLE"; | | 876 | static const char IX[] = ".IX TITLE"; |
876 | | | 877 | |
877 | section = NULL; | | 878 | section = NULL; |
878 | do { | | 879 | do { |
879 | if (GetS(in, buffer, sizeof(buffer) - 1) == NULL) { | | 880 | if (GetS(in, buffer, sizeof(buffer) - 1) == NULL) { |
880 | free(section); | | 881 | free(section); |
881 | return NULL; | | 882 | return NULL; |
882 | } | | 883 | } |
883 | | | 884 | |
884 | /* | | 885 | /* |
| @@ -1087,27 +1088,27 @@ parsemanpage(const char *name, gzFile *i | | | @@ -1087,27 +1088,27 @@ parsemanpage(const char *name, gzFile *i |
1087 | } | | 1088 | } |
1088 | | | 1089 | |
1089 | if (section == NULL) | | 1090 | if (section == NULL) |
1090 | section = makesection(defaultsection); | | 1091 | section = makesection(defaultsection); |
1091 | | | 1092 | |
1092 | ptr = makewhatisline(name, buffer, section); | | 1093 | ptr = makewhatisline(name, buffer, section); |
1093 | free(section); | | 1094 | free(section); |
1094 | return ptr; | | 1095 | return ptr; |
1095 | } | | 1096 | } |
1096 | | | 1097 | |
1097 | static char * | | 1098 | static char * |
1098 | getwhatisdata(char *name) | | 1099 | getwhatisdata(char *name) |
1099 | { | | 1100 | { |
1100 | gzFile *in; | | 1101 | gzFile in; |
1101 | char *data; | | 1102 | char *data; |
1102 | int section; | | 1103 | int section; |
1103 | | | 1104 | |
1104 | if ((in = gzopen(name, "r")) == NULL) { | | 1105 | if ((in = gzopen(name, "r")) == NULL) { |
1105 | if (errno == 0) | | 1106 | if (errno == 0) |
1106 | errno = ENOMEM; | | 1107 | errno = ENOMEM; |
1107 | err(EXIT_FAILURE, "Cannot open `%s'", name); | | 1108 | err(EXIT_FAILURE, "Cannot open `%s'", name); |
1108 | /* NOTREACHED */ | | 1109 | /* NOTREACHED */ |
1109 | } | | 1110 | } |
1110 | | | 1111 | |
1111 | section = manpagesection(name); | | 1112 | section = manpagesection(name); |
1112 | if (section == 0) { | | 1113 | if (section == 0) { |
1113 | data = parsecatpage(name, in); | | 1114 | data = parsecatpage(name, in); |