Convert uses of XKeycodeToKeysym (deprecated) to XkbKeycodeToKeysym
[oweals/cde.git] / util / checktree.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $TOG: checktree.c /main/8 1998/02/06 11:23:04 kaleb $ */
24
25 /*
26
27 Copyright (c) 1993, 1998  The Open Group
28
29 All Rights Reserved.
30
31 The above copyright notice and this permission notice shall be included in
32 all copies or substantial portions of the Software.
33
34 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
37 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
38 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
39 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40
41 Except as contained in this notice, the name of The Open Group shall not be
42 used in advertising or otherwise to promote the sale, use or other dealings
43 in this Software without prior written authorization from The Open Group.
44 */
45
46 #include <X11/Xos.h>
47 #include <stdio.h>
48 #include <sys/stat.h>
49 #include <sys/param.h>
50 #include <errno.h>
51
52 #ifndef X_NOT_POSIX
53 #include <dirent.h>
54 #else
55 #ifdef SYSV
56 #include <dirent.h>
57 #else
58 #ifdef USG
59 #include <dirent.h>
60 #else
61 #include <sys/dir.h>
62 #ifndef dirent
63 #define dirent direct
64 #endif
65 #endif
66 #endif
67 #endif
68
69 #ifdef S_IFLNK
70 #define Stat lstat
71 #else
72 #define Stat stat
73 #endif
74
75 #define CHARSALLOWED \
76 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_."
77
78 #define fmode_bits_minset 0444
79 #define fmode_bits_maxset 0777
80 #define fmode_bits_write  0222
81 #define dmode_bits_minset 0775
82
83 #ifdef X_NOT_STDC_ENV
84 extern int errno;
85 #endif
86
87 int dorcs = 1;                  /* check RCS file */
88 int do83 = 1;                   /* check for 8+3 clash */
89 int doro = 1;                   /* disallow writable (checked out) files */
90 int dodot = 1;                  /* disallow .files */
91 int dotwiddle = 1;              /* disallow file~ */
92
93 int dontcare(fn)
94     char *fn;
95 {
96     char *cp;
97
98     if (fn[strlen(fn) - 1] == '~')
99         return 1;
100     cp = strrchr(fn, '.');
101     return cp && (!strcmp(cp + 1, "Z") || !strcmp(cp + 1, "PS"));
102 }
103
104 checkfile(fullname, fn, fs)
105     char *fullname, *fn;
106     struct stat *fs;
107 {
108     char *cp;
109     int maxlen = 12;
110     int len, mode;
111
112     if (dodot && fn[0] == '.') {
113         printf("dot file: %s\n", fullname);
114         return;
115     }
116     for (len = 0, cp = fn; *cp; len++, cp++) {
117         if (!strchr(CHARSALLOWED, *cp)) {
118             if (dotwiddle || *cp != '~' || cp[1])
119                 printf ("bad character: %s\n", fullname);
120             break;
121         }
122     }
123     if (len > maxlen && !dontcare(fn))
124         printf("too long (%d): %s\n", len, fullname);
125 #ifdef S_IFLNK
126     if ((fs->st_mode & S_IFLNK) == S_IFLNK) {
127         printf("symbolic link: %s\n", fullname);
128         return;
129     }
130 #endif
131     mode = fs->st_mode & (~S_IFMT);
132     if ((fs->st_mode & S_IFDIR) == S_IFDIR) {
133         maxlen = 14;
134         if ((mode & dmode_bits_minset) != dmode_bits_minset)
135             printf("directory mode 0%o not minimum 0%o: %s\n",
136                    mode, dmode_bits_minset, fullname);
137     } else if ((fs->st_mode & S_IFREG) != S_IFREG)
138         printf("not a regular file: %s\n", fullname);
139     else {
140         if ((mode & fmode_bits_minset) != fmode_bits_minset)
141             printf("file mode 0%o not minimum 0%o: %s\n",
142                    fs->st_mode, fmode_bits_minset, fullname);
143         if (fs->st_nlink != 1)
144             printf("%d links instead of 1: %s\n", fs->st_nlink, fullname);
145         if (doro && (mode & fmode_bits_write) && !dontcare(fn))
146             printf("writable: %s\n", fullname);
147     }
148     if ((mode & ~fmode_bits_maxset) != 0)
149         printf("mode 0%o outside maximum set 0%o: %s\n",
150                mode, fmode_bits_maxset, fullname);
151 }
152
153 void
154 checkrcs(dir, p)
155     char *dir;
156     char *p;
157 {
158     DIR *df;
159     struct dirent *dp;
160     struct stat fs;
161     int i;
162
163     if (!(df = opendir(dir))) {
164         fprintf(stderr, "cannot open: %s\n", dir);
165         return;
166     }
167     while (dp = readdir(df)) {
168         i = strlen(dp->d_name);
169         if (dp->d_name[i - 1] == 'v' && dp->d_name[i - 2] == ',') {
170             strcpy(p, dp->d_name);
171             p[i - 2] = '\0';
172             if (Stat(dir, &fs) < 0) {
173                 strcpy(p, "RCS/");
174                 strcat(p, dp->d_name);
175                 printf("not used: %s\n", dir);
176             }
177         }
178     }
179     closedir(df);
180 }
181
182 int
183 Strncmp(cp1, cp2, n)
184     char *cp1, *cp2;
185     int n;
186 {
187     char c1, c2;
188
189     for (; --n >= 0 && *cp1 && *cp2; cp1++, cp2++) {
190         if (*cp1 != *cp2) {
191             c1 = *cp1;
192             c2 = *cp2;
193             if (c1 >= 'A' && c1 <= 'Z')
194                 c1 += 'a' - 'A';
195             else if (c1 == '-')
196                 c1 = '_';
197             if (c2 >= 'A' && c2 <= 'Z')
198                 c2 += 'a' - 'A';
199             else if (c2 == '-')
200                 c2 = '_';
201             if (c1 != c2)
202                 return (int)c1 - (int)c2;
203         }
204     }
205     if (n < 0)
206         return 0;
207     return (int)*cp1 - (int)*cp2;
208 }
209
210 int
211 fncomp(n1, n2)
212     char **n1, **n2;
213 {
214     int i, res;
215     char *cp1, *cp2;
216     char c1, c2;
217
218     i = Strncmp(*n1, *n2, 8);
219     if (!i) {
220         cp1 = strrchr(*n1, '.');
221         cp2 = strrchr(*n2, '.');
222         if (cp1 || cp2) {
223             if (!cp1)
224                 return -1;
225             if (!cp2)
226                 return 1;
227             i = Strncmp(cp1 + 1, cp2 + 1, 3);
228         }
229     }
230     return i;
231 }
232
233 void
234 checkdir(dir)
235     char *dir;
236 {
237     DIR *df;
238     struct dirent *dp;
239     char *p;
240     struct stat fs;
241     char *s, **names;
242     int i, max;
243
244     if (!(df = opendir(dir))) {
245         fprintf(stderr, "cannot open: %s\n", dir);
246         return;
247     }
248     p = dir + strlen(dir);
249     if (p[-1] != '/')
250         *p++ = '/';
251     i = 0;
252     max = 0;
253     names = NULL;
254     while (dp = readdir(df)) {
255         strcpy(p, dp->d_name);
256         if (Stat(dir, &fs) < 0) {
257             perror(dir);
258             continue;
259         }
260         if ((fs.st_mode & S_IFDIR) == S_IFDIR) {
261             if (dp->d_name[0] == '.' &&
262                 (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' &&
263                                            dp->d_name[2] == '\0')))
264                 continue;
265             if (!strcmp (dp->d_name, "RCS")) {
266                 if (dorcs)
267                     checkrcs(dir, p);
268                 continue;
269             }
270             if (!strcmp (dp->d_name, "SCCS"))
271                 continue;
272             if (!strcmp (dp->d_name, "CVS.adm"))
273                 continue;
274             checkfile(dir, p, &fs);
275             checkdir(dir);
276             continue;
277         }
278         checkfile(dir, p, &fs);
279         if (dorcs && !dontcare(dp->d_name)) {
280             strcpy(p, "RCS/");
281             strcat(p, dp->d_name);
282             strcat(p, ",v");
283             if (Stat(dir, &fs) < 0) {
284                 strcpy(p, dp->d_name);
285                 printf("no RCS: %s\n", dir);
286             }
287         }
288         if (do83) {
289             s = (char *)malloc(strlen(dp->d_name) + 1);
290             strcpy(s, dp->d_name);
291             if (i >= max) {
292                 max += 25;
293                 if (names)
294                     names = (char **)realloc((char *)names,
295                                              (max + 1) * sizeof(char *));
296                 else
297                     names = (char **)malloc((max + 1) * sizeof(char *));
298             }
299             names[i++] = s;
300         }
301     }
302     closedir(df);
303     if (do83) {
304         qsort((char *)names, i, sizeof(char *), fncomp);
305         max = i - 1;
306         *p = '\0';
307         for (i = 0; i < max; i++) {
308             if (!fncomp(&names[i], &names[i + 1]))
309                 printf("8+3 clash: %s%s and %s\n",
310                        dir, names[i], names[i + 1]);
311             free(names[i]);
312         }
313         if (names) {
314             free(names[i]);
315             free((char *)names);
316         }
317     }
318 }
319
320 main(argc, argv)
321     int argc;
322     char **argv;
323 {
324     char buf[2048];
325
326     argc--;
327     argv++;
328     while (argc > 0) {
329         if (!strcmp(*argv, "-rcs")) {
330             dorcs = 0;
331             argc--;
332             argv++;
333         } else if (!strcmp(*argv, "-83")) {
334             do83 = 0;
335             argc--;
336             argv++;
337         } else if (!strcmp(*argv, "-ro")) {
338             doro = 0;
339             argc--;
340             argv++;
341         } else if (!strcmp(*argv, "-dot")) {
342             dodot = 0;
343             argc--;
344             argv++;
345         } else if (!strcmp(*argv, "-twiddle")) {
346             dotwiddle = 0;
347             argc--;
348             argv++;
349         } else
350             break;
351     }
352     if (!argc) {
353         strcpy(buf, ".");
354         checkdir(buf);
355     } else
356         while (--argc >= 0) {
357             strcpy(buf, *argv++);
358             checkdir(buf);
359         }
360 }