Commit | Line | Data |
---|---|---|
da158ee3 DF |
1 | /* |
2 | * Copyright (c) 1980 Regents of the University of California. | |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | */ | |
6 | ||
7 | #ifndef lint | |
8 | char copyright[] = | |
9 | "@(#) Copyright (c) 1980 Regents of the University of California.\n\ | |
10 | All rights reserved.\n"; | |
11 | #endif not lint | |
12 | ||
4a33a05c | 13 | #ifndef lint |
8d4fc212 | 14 | static char sccsid[] = "@(#)catman.c 5.8 (Berkeley) %G%"; |
da158ee3 | 15 | #endif not lint |
a930013b | 16 | |
4a33a05c SL |
17 | /* |
18 | * catman: update cat'able versions of manual pages | |
19 | * (whatis database also) | |
20 | */ | |
21 | #include <stdio.h> | |
22 | #include <sys/types.h> | |
a7b24fe9 | 23 | #include <sys/stat.h> |
083e92b6 | 24 | #include <sys/file.h> |
a7b24fe9 SL |
25 | #include <sys/time.h> |
26 | #include <sys/dir.h> | |
4a33a05c | 27 | #include <ctype.h> |
a930013b | 28 | |
4a33a05c SL |
29 | char buf[BUFSIZ]; |
30 | char pflag; | |
31 | char nflag; | |
32 | char wflag; | |
33 | char man[MAXNAMLEN+6] = "manx/"; | |
083e92b6 | 34 | int exstat = 0; |
4a33a05c | 35 | char cat[MAXNAMLEN+6] = "catx/"; |
3f2e11aa | 36 | char lncat[MAXNAMLEN+9] = "../catx/"; |
083e92b6 DS |
37 | char *manpath = "/usr/man"; |
38 | char *sections = "12345678ln"; | |
39 | char *makewhatis = "/usr/lib/makewhatis"; | |
40 | char *index(), *rindex(); | |
41 | char *strcpy(); | |
42 | char *getenv(); | |
dbfb06ee | 43 | |
a930013b | 44 | main(ac, av) |
4a33a05c SL |
45 | int ac; |
46 | char *av[]; | |
47 | { | |
083e92b6 DS |
48 | char *mp, *nextp; |
49 | ||
50 | if ((mp = getenv("MANPATH")) != NULL) | |
51 | manpath = mp; | |
a930013b | 52 | |
90d7286e | 53 | ac--, av++; |
5b8531dd | 54 | while (ac > 0 && av[0][0] == '-') { |
90d7286e SL |
55 | switch (av[0][1]) { |
56 | ||
57 | case 'p': | |
a930013b | 58 | pflag++; |
90d7286e SL |
59 | break; |
60 | ||
61 | case 'n': | |
a930013b | 62 | nflag++; |
90d7286e SL |
63 | break; |
64 | ||
65 | case 'w': | |
a930013b | 66 | wflag++; |
a930013b | 67 | break; |
90d7286e SL |
68 | |
69 | case 'M': | |
70 | case 'P': | |
71 | if (ac < 1) { | |
083e92b6 | 72 | fprintf(stderr, "%s: missing path\n", |
90d7286e SL |
73 | av[0]); |
74 | exit(1); | |
75 | } | |
76 | ac--, av++; | |
083e92b6 | 77 | manpath = *av; |
90d7286e SL |
78 | break; |
79 | ||
80 | default: | |
81 | goto usage; | |
82 | } | |
83 | ac--, av++; | |
a930013b | 84 | } |
5b8531dd | 85 | if (ac > 1) { |
a930013b | 86 | usage: |
90d7286e | 87 | printf("usage: catman [ -p ] [ -n ] [ -w ] [ -M path ] [ sections ]\n"); |
a930013b BJ |
88 | exit(-1); |
89 | } | |
083e92b6 DS |
90 | if (ac == 1) |
91 | sections = *av; | |
92 | for (mp = manpath; mp && ((nextp = index(mp, ':')), 1); mp = nextp) { | |
93 | if (nextp) | |
94 | *nextp++ = '\0'; | |
95 | doit(mp); | |
96 | } | |
97 | exit(exstat); | |
98 | } | |
99 | ||
100 | doit(mandir) | |
101 | char *mandir; | |
102 | { | |
103 | register char *msp, *csp, *sp; | |
104 | int changed = 0; | |
105 | int status; | |
106 | ||
a930013b BJ |
107 | if (wflag) |
108 | goto whatis; | |
90d7286e | 109 | if (chdir(mandir) < 0) { |
083e92b6 DS |
110 | sprintf(buf, "catman: %s", mandir); |
111 | perror(buf); | |
112 | /* exstat = 1; */ | |
113 | return; | |
90d7286e | 114 | } |
083e92b6 DS |
115 | if (pflag) |
116 | printf("cd %s\n", mandir); | |
a930013b BJ |
117 | msp = &man[5]; |
118 | csp = &cat[5]; | |
ae5a109c | 119 | (void) umask(0); |
a930013b | 120 | for (sp = sections; *sp; sp++) { |
4a33a05c SL |
121 | register DIR *mdir; |
122 | register struct direct *dir; | |
123 | struct stat sbuf; | |
124 | ||
a930013b BJ |
125 | man[3] = cat[3] = *sp; |
126 | *msp = *csp = '\0'; | |
dbfb06ee | 127 | if ((mdir = opendir(man)) == NULL) { |
083e92b6 DS |
128 | sprintf(buf, "catman: opendir: %s", man); |
129 | perror(buf); | |
130 | /* exstat = 1; */ | |
a930013b BJ |
131 | continue; |
132 | } | |
133 | if (stat(cat, &sbuf) < 0) { | |
083e92b6 | 134 | register char *cp; |
108423c7 | 135 | |
083e92b6 | 136 | (void) strcpy(buf, cat); |
108423c7 SL |
137 | cp = rindex(buf, '/'); |
138 | if (cp && cp[1] == '\0') | |
139 | *cp = '\0'; | |
140 | if (pflag) | |
141 | printf("mkdir %s\n", buf); | |
ae5a109c | 142 | else if (mkdir(buf, 0777) < 0) { |
108423c7 SL |
143 | sprintf(buf, "catman: mkdir: %s", cat); |
144 | perror(buf); | |
083e92b6 | 145 | exstat = 1; |
108423c7 SL |
146 | continue; |
147 | } | |
083e92b6 DS |
148 | (void) stat(cat, &sbuf); |
149 | } | |
150 | if (access(cat, R_OK|W_OK|X_OK) == -1) { | |
151 | sprintf(buf, "catman: %s", cat); | |
152 | perror(buf); | |
153 | exstat = 1; | |
154 | continue; | |
155 | } | |
156 | if ((sbuf.st_mode & S_IFMT) != S_IFDIR) { | |
157 | fprintf(stderr, "catman: %s: Not a directory\n", cat); | |
158 | exstat = 1; | |
159 | continue; | |
a930013b | 160 | } |
dbfb06ee | 161 | while ((dir = readdir(mdir)) != NULL) { |
4a33a05c | 162 | time_t time; |
083e92b6 | 163 | register char *tsp; |
4a33a05c | 164 | FILE *inf; |
3120d0c0 | 165 | int makelink; |
4a33a05c | 166 | |
dbfb06ee | 167 | if (dir->d_ino == 0 || dir->d_name[0] == '.') |
a930013b BJ |
168 | continue; |
169 | /* | |
4a33a05c | 170 | * Make sure this is a man file, i.e., that it |
a930013b BJ |
171 | * ends in .[0-9] or .[0-9][a-z] |
172 | */ | |
dbfb06ee | 173 | tsp = rindex(dir->d_name, '.'); |
a930013b BJ |
174 | if (tsp == NULL) |
175 | continue; | |
38f37492 | 176 | if (!isdigit(*++tsp) && *tsp != *sp) |
4a33a05c SL |
177 | continue; |
178 | if (*++tsp && !isalpha(*tsp)) | |
179 | continue; | |
180 | if (*tsp && *++tsp) | |
a930013b | 181 | continue; |
083e92b6 | 182 | (void) strcpy(msp, dir->d_name); |
a930013b | 183 | if ((inf = fopen(man, "r")) == NULL) { |
8d4fc212 | 184 | sprintf(buf, "catman: %s", man); |
083e92b6 | 185 | perror(buf); |
a930013b BJ |
186 | exstat = 1; |
187 | continue; | |
188 | } | |
3120d0c0 | 189 | makelink = 0; |
a930013b BJ |
190 | if (getc(inf) == '.' && getc(inf) == 's' |
191 | && getc(inf) == 'o') { | |
3120d0c0 | 192 | if (getc(inf) != ' ' || |
3f2e11aa | 193 | fgets(lncat+3, sizeof(lncat)-3, inf)==NULL) { |
3120d0c0 KM |
194 | fclose(inf); |
195 | continue; | |
196 | } | |
197 | if (lncat[strlen(lncat)-1] == '\n') | |
198 | lncat[strlen(lncat)-1] = '\0'; | |
3f2e11aa | 199 | if (strncmp(lncat+3, "man", 3) != 0) { |
3120d0c0 KM |
200 | fclose(inf); |
201 | continue; | |
202 | } | |
3f2e11aa | 203 | bcopy("../cat", lncat, sizeof("../cat")-1); |
3120d0c0 | 204 | makelink = 1; |
a930013b BJ |
205 | } |
206 | fclose(inf); | |
083e92b6 | 207 | (void) strcpy(csp, dir->d_name); |
a930013b BJ |
208 | if (stat(cat, &sbuf) >= 0) { |
209 | time = sbuf.st_mtime; | |
083e92b6 | 210 | (void) stat(man, &sbuf); |
a930013b BJ |
211 | if (time >= sbuf.st_mtime) |
212 | continue; | |
083e92b6 | 213 | (void) unlink(cat); |
a930013b | 214 | } |
3120d0c0 KM |
215 | if (makelink) { |
216 | /* | |
217 | * Don't unlink a directory by accident. | |
218 | */ | |
3f2e11aa KM |
219 | if (stat(lncat+3, &sbuf) >= 0 && |
220 | (((sbuf.st_mode&S_IFMT)==S_IFREG) || | |
221 | ((sbuf.st_mode&S_IFMT)==S_IFLNK))) | |
083e92b6 | 222 | (void) unlink(cat); |
3120d0c0 | 223 | if (pflag) |
3f2e11aa | 224 | printf("ln -s %s %s\n", lncat, cat); |
3120d0c0 | 225 | else |
3f2e11aa KM |
226 | if (symlink(lncat, cat) == -1) { |
227 | sprintf(buf, "catman: symlink: %s", cat); | |
083e92b6 DS |
228 | perror(buf); |
229 | exstat = 1; | |
230 | continue; | |
231 | } | |
3120d0c0 KM |
232 | } |
233 | else { | |
234 | sprintf(buf, "nroff -man %s > %s", man, cat); | |
083e92b6 DS |
235 | if (pflag) |
236 | printf("%s\n", buf); | |
237 | else if ((status = system(buf)) != 0) { | |
238 | fprintf(stderr, "catman: nroff: %s: exit status %d: Owooooo!\n", cat, status); | |
239 | exstat = 1; | |
240 | continue; | |
241 | } | |
3120d0c0 | 242 | } |
a930013b BJ |
243 | changed = 1; |
244 | } | |
dbfb06ee | 245 | closedir(mdir); |
a930013b BJ |
246 | } |
247 | if (changed && !nflag) { | |
248 | whatis: | |
083e92b6 DS |
249 | sprintf(buf, "%s %s", makewhatis, mandir); |
250 | if (pflag) | |
251 | printf("%s\n", buf); | |
252 | else if ((status = system(buf)) != 0) { | |
253 | fprintf(stderr, "catman: %s: exit status %d\n", | |
254 | buf, status); | |
a930013b | 255 | exstat = 1; |
083e92b6 | 256 | } |
a930013b | 257 | } |
083e92b6 | 258 | return; |
a930013b | 259 | } |