1 /* $XConsortium: checktree.c,v 1.7 94/04/17 20:10:40 gildea Exp $ */
5 Copyright (c) 1993 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Except as contained in this notice, the name of the X Consortium shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from the X Consortium.
32 #include <sys/param.h>
58 #define CHARSALLOWED \
59 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_."
61 #define fmode_bits_minset 0444
62 #define fmode_bits_maxset 0777
63 #define fmode_bits_write 0222
64 #define dmode_bits_minset 0775
70 int dorcs = 1; /* check RCS file */
71 int do83 = 1; /* check for 8+3 clash */
72 int doro = 1; /* disallow writable (checked out) files */
73 int dodot = 1; /* disallow .files */
74 int dotwiddle = 1; /* disallow file~ */
81 if (fn[strlen(fn) - 1] == '~')
83 cp = strrchr(fn, '.');
84 return cp && (!strcmp(cp + 1, "Z") || !strcmp(cp + 1, "PS"));
87 checkfile(fullname, fn, fs)
95 if (dodot && fn[0] == '.') {
96 printf("dot file: %s\n", fullname);
99 for (len = 0, cp = fn; *cp; len++, cp++) {
100 if (!strchr(CHARSALLOWED, *cp)) {
101 if (dotwiddle || *cp != '~' || cp[1])
102 printf ("bad character: %s\n", fullname);
106 if (len > maxlen && !dontcare(fn))
107 printf("too long (%d): %s\n", len, fullname);
109 if ((fs->st_mode & S_IFLNK) == S_IFLNK) {
110 printf("symbolic link: %s\n", fullname);
114 mode = fs->st_mode & (~S_IFMT);
115 if ((fs->st_mode & S_IFDIR) == S_IFDIR) {
117 if ((mode & dmode_bits_minset) != dmode_bits_minset)
118 printf("directory mode 0%o not minimum 0%o: %s\n",
119 mode, dmode_bits_minset, fullname);
120 } else if ((fs->st_mode & S_IFREG) != S_IFREG)
121 printf("not a regular file: %s\n", fullname);
123 if ((mode & fmode_bits_minset) != fmode_bits_minset)
124 printf("file mode 0%o not minimum 0%o: %s\n",
125 fs->st_mode, fmode_bits_minset, fullname);
126 if (fs->st_nlink != 1)
127 printf("%d links instead of 1: %s\n", fs->st_nlink, fullname);
128 if (doro && (mode & fmode_bits_write) && !dontcare(fn))
129 printf("writable: %s\n", fullname);
131 if ((mode & ~fmode_bits_maxset) != 0)
132 printf("mode 0%o outside maximum set 0%o: %s\n",
133 mode, fmode_bits_maxset, fullname);
146 if (!(df = opendir(dir))) {
147 fprintf(stderr, "cannot open: %s\n", dir);
150 while (dp = readdir(df)) {
151 i = strlen(dp->d_name);
152 if (dp->d_name[i - 1] == 'v' && dp->d_name[i - 2] == ',') {
153 strcpy(p, dp->d_name);
155 if (Stat(dir, &fs) < 0) {
157 strcat(p, dp->d_name);
158 printf("not used: %s\n", dir);
172 for (; --n >= 0 && *cp1 && *cp2; cp1++, cp2++) {
176 if (c1 >= 'A' && c1 <= 'Z')
180 if (c2 >= 'A' && c2 <= 'Z')
185 return (int)c1 - (int)c2;
190 return (int)*cp1 - (int)*cp2;
201 i = Strncmp(*n1, *n2, 8);
203 cp1 = strrchr(*n1, '.');
204 cp2 = strrchr(*n2, '.');
210 i = Strncmp(cp1 + 1, cp2 + 1, 3);
227 if (!(df = opendir(dir))) {
228 fprintf(stderr, "cannot open: %s\n", dir);
231 p = dir + strlen(dir);
237 while (dp = readdir(df)) {
238 strcpy(p, dp->d_name);
239 if (Stat(dir, &fs) < 0) {
243 if ((fs.st_mode & S_IFDIR) == S_IFDIR) {
244 if (dp->d_name[0] == '.' &&
245 (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' &&
246 dp->d_name[2] == '\0')))
248 if (!strcmp (dp->d_name, "RCS")) {
253 if (!strcmp (dp->d_name, "SCCS"))
255 if (!strcmp (dp->d_name, "CVS.adm"))
257 checkfile(dir, p, &fs);
261 checkfile(dir, p, &fs);
262 if (dorcs && !dontcare(dp->d_name)) {
264 strcat(p, dp->d_name);
266 if (Stat(dir, &fs) < 0) {
267 strcpy(p, dp->d_name);
268 printf("no RCS: %s\n", dir);
272 s = (char *)malloc(strlen(dp->d_name) + 1);
273 strcpy(s, dp->d_name);
277 names = (char **)realloc((char *)names,
278 (max + 1) * sizeof(char *));
280 names = (char **)malloc((max + 1) * sizeof(char *));
287 qsort((char *)names, i, sizeof(char *), fncomp);
290 for (i = 0; i < max; i++) {
291 if (!fncomp(&names[i], &names[i + 1]))
292 printf("8+3 clash: %s%s and %s\n",
293 dir, names[i], names[i + 1]);
312 if (!strcmp(*argv, "-rcs")) {
316 } else if (!strcmp(*argv, "-83")) {
320 } else if (!strcmp(*argv, "-ro")) {
324 } else if (!strcmp(*argv, "-dot")) {
328 } else if (!strcmp(*argv, "-twiddle")) {
339 while (--argc >= 0) {
340 strcpy(buf, *argv++);