Blame config/util/checktree.c

Packit b099d7
/* $TOG: checktree.c /main/8 1998/02/06 11:23:04 kaleb $ */
Packit b099d7
Packit b099d7
/*
Packit b099d7
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
Packit b099d7
*/
Packit b099d7
Packit b099d7
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
#include <X11/Xos.h>
Packit b099d7
#include <stdio.h>
Packit b099d7
#include <sys/stat.h>
Packit b099d7
#include <sys/param.h>
Packit b099d7
#include <errno.h>
Packit b099d7
Packit b099d7
#ifndef X_NOT_POSIX
Packit b099d7
#include <dirent.h>
Packit b099d7
#else
Packit b099d7
#ifdef SYSV
Packit b099d7
#include <dirent.h>
Packit b099d7
#else
Packit b099d7
#ifdef USG
Packit b099d7
#include <dirent.h>
Packit b099d7
#else
Packit b099d7
#include <sys/dir.h>
Packit b099d7
#ifndef dirent
Packit b099d7
#define dirent direct
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
Packit b099d7
#ifdef S_IFLNK
Packit b099d7
#define Stat lstat
Packit b099d7
#else
Packit b099d7
#define Stat stat
Packit b099d7
#endif
Packit b099d7
Packit b099d7
#define CHARSALLOWED \
Packit b099d7
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_."
Packit b099d7
Packit b099d7
#define fmode_bits_minset 0444
Packit b099d7
#define fmode_bits_maxset 0777
Packit b099d7
#define fmode_bits_write  0222
Packit b099d7
#define dmode_bits_minset 0775
Packit b099d7
Packit b099d7
#ifdef X_NOT_STDC_ENV
Packit b099d7
extern int errno;
Packit b099d7
#endif
Packit b099d7
Packit b099d7
int dorcs = 1;			/* check RCS file */
Packit b099d7
int do83 = 1;			/* check for 8+3 clash */
Packit b099d7
int doro = 1;			/* disallow writable (checked out) files */
Packit b099d7
int dodot = 1;			/* disallow .files */
Packit b099d7
int dotwiddle = 1;		/* disallow file~ */
Packit b099d7
Packit b099d7
int dontcare(fn)
Packit b099d7
    char *fn;
Packit b099d7
{
Packit b099d7
    char *cp;
Packit b099d7
Packit b099d7
    if (fn[strlen(fn) - 1] == '~')
Packit b099d7
	return 1;
Packit b099d7
    cp = strrchr(fn, '.');
Packit b099d7
    return cp && (!strcmp(cp + 1, "Z") || !strcmp(cp + 1, "PS"));
Packit b099d7
}
Packit b099d7
Packit b099d7
checkfile(fullname, fn, fs)
Packit b099d7
    char *fullname, *fn;
Packit b099d7
    struct stat *fs;
Packit b099d7
{
Packit b099d7
    char *cp;
Packit b099d7
    int maxlen = 12;
Packit b099d7
    int len, mode;
Packit b099d7
Packit b099d7
    if (dodot && fn[0] == '.') {
Packit b099d7
	printf("dot file: %s\n", fullname);
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
    for (len = 0, cp = fn; *cp; len++, cp++) {
Packit b099d7
	if (!strchr(CHARSALLOWED, *cp)) {
Packit b099d7
	    if (dotwiddle || *cp != '~' || cp[1])
Packit b099d7
		printf ("bad character: %s\n", fullname);
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    if (len > maxlen && !dontcare(fn))
Packit b099d7
	printf("too long (%d): %s\n", len, fullname);
Packit b099d7
#ifdef S_IFLNK
Packit b099d7
    if ((fs->st_mode & S_IFLNK) == S_IFLNK) {
Packit b099d7
	printf("symbolic link: %s\n", fullname);
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
#endif
Packit b099d7
    mode = fs->st_mode & (~S_IFMT);
Packit b099d7
    if ((fs->st_mode & S_IFDIR) == S_IFDIR) {
Packit b099d7
	maxlen = 14;
Packit b099d7
	if ((mode & dmode_bits_minset) != dmode_bits_minset)
Packit b099d7
	    printf("directory mode 0%o not minimum 0%o: %s\n",
Packit b099d7
		   mode, dmode_bits_minset, fullname);
Packit b099d7
    } else if ((fs->st_mode & S_IFREG) != S_IFREG)
Packit b099d7
	printf("not a regular file: %s\n", fullname);
Packit b099d7
    else {
Packit b099d7
	if ((mode & fmode_bits_minset) != fmode_bits_minset)
Packit b099d7
	    printf("file mode 0%o not minimum 0%o: %s\n",
Packit b099d7
		   fs->st_mode, fmode_bits_minset, fullname);
Packit b099d7
	if (fs->st_nlink != 1)
Packit b099d7
	    printf("%d links instead of 1: %s\n", fs->st_nlink, fullname);
Packit b099d7
	if (doro && (mode & fmode_bits_write) && !dontcare(fn))
Packit b099d7
	    printf("writable: %s\n", fullname);
Packit b099d7
    }
Packit b099d7
    if ((mode & ~fmode_bits_maxset) != 0)
Packit b099d7
	printf("mode 0%o outside maximum set 0%o: %s\n",
Packit b099d7
	       mode, fmode_bits_maxset, fullname);
Packit b099d7
}
Packit b099d7
Packit b099d7
void
Packit b099d7
checkrcs(dir, p)
Packit b099d7
    char *dir;
Packit b099d7
    char *p;
Packit b099d7
{
Packit b099d7
    DIR *df;
Packit b099d7
    struct dirent *dp;
Packit b099d7
    struct stat fs;
Packit b099d7
    int i;
Packit b099d7
Packit b099d7
    if (!(df = opendir(dir))) {
Packit b099d7
	fprintf(stderr, "cannot open: %s\n", dir);
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
    while (dp = readdir(df)) {
Packit b099d7
	i = strlen(dp->d_name);
Packit b099d7
	if (dp->d_name[i - 1] == 'v' && dp->d_name[i - 2] == ',') {
Packit b099d7
	    strcpy(p, dp->d_name);
Packit b099d7
	    p[i - 2] = '\0';
Packit b099d7
	    if (Stat(dir, &fs) < 0) {
Packit b099d7
		strcpy(p, "RCS/");
Packit b099d7
		strcat(p, dp->d_name);
Packit b099d7
		printf("not used: %s\n", dir);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    closedir(df);
Packit b099d7
}
Packit b099d7
Packit b099d7
int
Packit b099d7
Strncmp(cp1, cp2, n)
Packit b099d7
    char *cp1, *cp2;
Packit b099d7
    int n;
Packit b099d7
{
Packit b099d7
    char c1, c2;
Packit b099d7
Packit b099d7
    for (; --n >= 0 && *cp1 && *cp2; cp1++, cp2++) {
Packit b099d7
	if (*cp1 != *cp2) {
Packit b099d7
	    c1 = *cp1;
Packit b099d7
	    c2 = *cp2;
Packit b099d7
	    if (c1 >= 'A' && c1 <= 'Z')
Packit b099d7
		c1 += 'a' - 'A';
Packit b099d7
	    else if (c1 == '-')
Packit b099d7
		c1 = '_';
Packit b099d7
	    if (c2 >= 'A' && c2 <= 'Z')
Packit b099d7
		c2 += 'a' - 'A';
Packit b099d7
	    else if (c2 == '-')
Packit b099d7
		c2 = '_';
Packit b099d7
	    if (c1 != c2)
Packit b099d7
		return (int)c1 - (int)c2;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    if (n < 0)
Packit b099d7
	return 0;
Packit b099d7
    return (int)*cp1 - (int)*cp2;
Packit b099d7
}
Packit b099d7
Packit b099d7
int
Packit b099d7
fncomp(n1, n2)
Packit b099d7
    char **n1, **n2;
Packit b099d7
{
Packit b099d7
    int i, res;
Packit b099d7
    char *cp1, *cp2;
Packit b099d7
    char c1, c2;
Packit b099d7
Packit b099d7
    i = Strncmp(*n1, *n2, 8);
Packit b099d7
    if (!i) {
Packit b099d7
	cp1 = strrchr(*n1, '.');
Packit b099d7
	cp2 = strrchr(*n2, '.');
Packit b099d7
	if (cp1 || cp2) {
Packit b099d7
	    if (!cp1)
Packit b099d7
		return -1;
Packit b099d7
	    if (!cp2)
Packit b099d7
		return 1;
Packit b099d7
	    i = Strncmp(cp1 + 1, cp2 + 1, 3);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    return i;
Packit b099d7
}
Packit b099d7
Packit b099d7
void
Packit b099d7
checkdir(dir)
Packit b099d7
    char *dir;
Packit b099d7
{
Packit b099d7
    DIR *df;
Packit b099d7
    struct dirent *dp;
Packit b099d7
    char *p;
Packit b099d7
    struct stat fs;
Packit b099d7
    char *s, **names;
Packit b099d7
    int i, max;
Packit b099d7
Packit b099d7
    if (!(df = opendir(dir))) {
Packit b099d7
	fprintf(stderr, "cannot open: %s\n", dir);
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
    p = dir + strlen(dir);
Packit b099d7
    if (p[-1] != '/')
Packit b099d7
	*p++ = '/';
Packit b099d7
    i = 0;
Packit b099d7
    max = 0;
Packit b099d7
    names = NULL;
Packit b099d7
    while (dp = readdir(df)) {
Packit b099d7
	strcpy(p, dp->d_name);
Packit b099d7
	if (Stat(dir, &fs) < 0) {
Packit b099d7
	    perror(dir);
Packit b099d7
	    continue;
Packit b099d7
	}
Packit b099d7
	if ((fs.st_mode & S_IFDIR) == S_IFDIR) {
Packit b099d7
	    if (dp->d_name[0] == '.' &&
Packit b099d7
		(dp->d_name[1] == '\0' || (dp->d_name[1] == '.' &&
Packit b099d7
					   dp->d_name[2] == '\0')))
Packit b099d7
		continue;
Packit b099d7
	    if (!strcmp (dp->d_name, "RCS")) {
Packit b099d7
		if (dorcs)
Packit b099d7
		    checkrcs(dir, p);
Packit b099d7
		continue;
Packit b099d7
	    }
Packit b099d7
	    if (!strcmp (dp->d_name, "SCCS"))
Packit b099d7
		continue;
Packit b099d7
	    if (!strcmp (dp->d_name, "CVS.adm"))
Packit b099d7
		continue;
Packit b099d7
	    checkfile(dir, p, &fs);
Packit b099d7
	    checkdir(dir);
Packit b099d7
	    continue;
Packit b099d7
	}
Packit b099d7
	checkfile(dir, p, &fs);
Packit b099d7
	if (dorcs && !dontcare(dp->d_name)) {
Packit b099d7
	    strcpy(p, "RCS/");
Packit b099d7
	    strcat(p, dp->d_name);
Packit b099d7
	    strcat(p, ",v");
Packit b099d7
	    if (Stat(dir, &fs) < 0) {
Packit b099d7
		strcpy(p, dp->d_name);
Packit b099d7
		printf("no RCS: %s\n", dir);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
	if (do83) {
Packit b099d7
	    s = (char *)malloc(strlen(dp->d_name) + 1);
Packit b099d7
	    strcpy(s, dp->d_name);
Packit b099d7
	    if (i >= max) {
Packit b099d7
		max += 25;
Packit b099d7
		if (names)
Packit b099d7
		    names = (char **)realloc((char *)names,
Packit b099d7
					     (max + 1) * sizeof(char *));
Packit b099d7
		else
Packit b099d7
		    names = (char **)malloc((max + 1) * sizeof(char *));
Packit b099d7
	    }
Packit b099d7
	    names[i++] = s;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    closedir(df);
Packit b099d7
    if (do83) {
Packit b099d7
	qsort((char *)names, i, sizeof(char *), fncomp);
Packit b099d7
	max = i - 1;
Packit b099d7
	*p = '\0';
Packit b099d7
	for (i = 0; i < max; i++) {
Packit b099d7
	    if (!fncomp(&names[i], &names[i + 1]))
Packit b099d7
		printf("8+3 clash: %s%s and %s\n",
Packit b099d7
		       dir, names[i], names[i + 1]);
Packit b099d7
	    free(names[i]);
Packit b099d7
	}
Packit b099d7
	if (names) {
Packit b099d7
	    free(names[i]);
Packit b099d7
	    free((char *)names);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
main(argc, argv)
Packit b099d7
    int argc;
Packit b099d7
    char **argv;
Packit b099d7
{
Packit b099d7
    char buf[2048];
Packit b099d7
Packit b099d7
    argc--;
Packit b099d7
    argv++;
Packit b099d7
    while (argc > 0) {
Packit b099d7
	if (!strcmp(*argv, "-rcs")) {
Packit b099d7
	    dorcs = 0;
Packit b099d7
	    argc--;
Packit b099d7
	    argv++;
Packit b099d7
	} else if (!strcmp(*argv, "-83")) {
Packit b099d7
	    do83 = 0;
Packit b099d7
	    argc--;
Packit b099d7
	    argv++;
Packit b099d7
	} else if (!strcmp(*argv, "-ro")) {
Packit b099d7
	    doro = 0;
Packit b099d7
	    argc--;
Packit b099d7
	    argv++;
Packit b099d7
	} else if (!strcmp(*argv, "-dot")) {
Packit b099d7
	    dodot = 0;
Packit b099d7
	    argc--;
Packit b099d7
	    argv++;
Packit b099d7
	} else if (!strcmp(*argv, "-twiddle")) {
Packit b099d7
	    dotwiddle = 0;
Packit b099d7
	    argc--;
Packit b099d7
	    argv++;
Packit b099d7
	} else
Packit b099d7
	    break;
Packit b099d7
    }
Packit b099d7
    if (!argc) {
Packit b099d7
	strcpy(buf, ".");
Packit b099d7
	checkdir(buf);
Packit b099d7
    } else
Packit b099d7
	while (--argc >= 0) {
Packit b099d7
	    strcpy(buf, *argv++);
Packit b099d7
	    checkdir(buf);
Packit b099d7
	}
Packit b099d7
}