home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / util / checkfn / checkfn.c next >
Encoding:
C/C++ Source or Header  |  1989-11-17  |  5.1 KB  |  187 lines

  1. /*
  2.  * checkfn - check file names for bad stuff
  3.  *
  4.  *    1.  non-RCS filenames are 12 characters or less
  5.  *    2.  filenames contain [a-zA-Z0-9_-.] and , if in RCS directory
  6.  *    3.  file not a symbolic link
  7.  *    4.  directory has at least 0775
  8.  *    5.  non-directory does not have multiple hard links
  9.  *    6.  protection bits are at least 444 and less than or equal to 777
  10.  *
  11.  * Copyright 1988 Massachusetts Institute of Technology
  12.  *
  13.  * Permission to use, copy, modify, and distribute this software and its
  14.  * documentation for any purpose and without fee is hereby granted, provided
  15.  * that the above copyright notice appear in all copies and that both that
  16.  * copyright notice and this permission notice appear in supporting
  17.  * documentation, and that the name of M.I.T. not be used in advertising or
  18.  * publicity pertaining to distribution of the software without specific,
  19.  * written prior permission.  M.I.T. makes no representations about the
  20.  * suitability of this software for any purpose.  It is provided "as is"
  21.  * without express or implied warranty.
  22.  *
  23.  * Author:  Jim Fulton, MIT X Consortium
  24.  */
  25.  
  26. #include <stdio.h>            /* for printf */
  27. #include <X11/Xos.h>            /* for types and strings */
  28. #include <sys/stat.h>            /* for stat */
  29. #include <errno.h>            /* for errno */
  30.  
  31. extern int errno;            /* errno.h is very stupid */
  32. extern int sys_nerr;
  33. extern char *sys_errlist[];
  34.  
  35. #define streq(a,b) (strcmp ((a), (b)) == 0)
  36.  
  37. #define CHARSALLOWED \
  38. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_."
  39.  
  40. char *ProgramName;            /* for printing error messages */
  41. unsigned int fmode_bits_minset = 0444;    /* want every file to have */
  42. unsigned int fmode_bits_maxset = 0777;    /* don't want outside of this */
  43. unsigned int dmode_bits_minset = 0775;    /* want every dir to have */
  44. int dotfiles_allowed = 0;        /* complain about hidden files */
  45.  
  46. static void usage ()
  47. {
  48.     fprintf (stderr, "usage:  %s [-min modes] [-max modes] [directory]\n",
  49.          ProgramName);
  50.     fprintf (stderr, "\n");
  51.     exit (1);
  52. }
  53.  
  54. static char *SysError ()
  55. {
  56.     return (errno > 0 && errno < sys_nerr) ? sys_errlist[errno] :
  57.         "unknown error";
  58. }
  59.  
  60. unsigned int parse_num (s)
  61.     char *s;
  62. {
  63.     char *fmt = "%u";
  64.     unsigned int retval = 0;
  65.  
  66.     if (*s == '0') s++, fmt = "%o";
  67.     if (*s == 'x' || *s == 'X') s++, fmt = "%x";
  68.     (void) sscanf (s, fmt, &retval);
  69.     return retval;
  70. }
  71.  
  72. main (argc, argv)
  73.     int argc;
  74.     char *argv[];
  75. {
  76.     int i;
  77.  
  78.     ProgramName = argv[0];
  79.  
  80.     for (i = 1; i < argc; i++) {
  81.     char *arg = argv[i];
  82.  
  83.     if (streq (arg, "-min")) {
  84.         if (++i >= argc) usage ();
  85.         fmode_bits_minset = parse_num (argv[i]);
  86.         continue;
  87.     } else if (streq (arg, "-max")) {
  88.         if (++i >= argc) usage ();
  89.         fmode_bits_maxset = parse_num (argv[i]);
  90.         continue;
  91.     } else if (streq (arg, "-dot")) {
  92.         dotfiles_allowed = 1;
  93.         continue;
  94.     } else if (arg[0] != '-') {
  95.         check (arg);
  96.         continue;
  97.     }
  98.     usage ();
  99.     }
  100.  
  101.     exit (0);
  102. }
  103.  
  104. check (filename)
  105.     char *filename;
  106. {
  107.     char *cp= rindex (filename, '/');
  108.     char *base = cp ? cp + 1 : filename;
  109.     int maxlen = 12, len = strlen (base);
  110.     int rcsslop = 0;
  111.     struct stat st;
  112.     unsigned int mode;
  113.  
  114.     if (base[0] == '.' && !dotfiles_allowed) {
  115.     if (!(base[1] == '\0' || (base[1] == '.' && base[2] == '\0'))) {
  116.         printf ("%s\t\thidden file beginning with dot\n", filename);
  117.     }
  118.     return;
  119.     }
  120.  
  121.     for (len = 0, cp = base; *cp; len++, cp++) {
  122.     if (*cp == ',') {
  123.         if (cp[1] != 'v' || cp[2] != '\0') {
  124.         printf ("%s\t\tbad character ',' in filename\n", filename);
  125.         return;
  126.         }
  127.         if ((base - 4) < filename || strncmp (base - 4, "RCS/", 4) != 0) {
  128.         printf ("%s\t\tRCS file not in RCS directory\n", filename);
  129.         return;
  130.         }
  131.         rcsslop = 2;
  132.     } else if (index (CHARSALLOWED, *cp) == NULL) {
  133.         printf ("%s\t\tbad character '%c' in filename\n", filename, *cp);
  134.         return;
  135.     }
  136. #ifdef S_IFLNK
  137.     if (lstat (filename, &st) != 0) {
  138.         printf ("%s\t\tunable to lstat file, errno %d, %s\n",
  139.             filename, errno, SysError());
  140.         return;
  141.     }
  142.     if ((st.st_mode & S_IFLNK) == S_IFLNK) {
  143.         printf ("%s\t\tsymbolic links not allowed\n", filename);
  144.         return;
  145.     }
  146. #endif
  147.     mode = st.st_mode & (~S_IFMT);    /* just mode bits */
  148.     if ((st.st_mode & S_IFDIR) == S_IFDIR) {
  149.         maxlen = 14;
  150.         if ((mode & dmode_bits_minset) != dmode_bits_minset) {
  151.         printf ("%s\t\tdirectory mode 0%o not minimum 0%o\n",
  152.             filename, mode, dmode_bits_minset);
  153.         return;
  154.         }
  155.     } else if ((st.st_mode & S_IFREG) != S_IFREG) {
  156.         printf ("%s\t\tnot a regular file\n", filename);
  157.         return;
  158.     } else {
  159.         if ((mode & fmode_bits_minset) != fmode_bits_minset) {
  160.         printf ("%s\t\tfile mode 0%o not minimum 0%o\n",
  161.             filename, st.st_mode, fmode_bits_minset);
  162.         return;
  163.         }
  164.         if (st.st_nlink != 1) {
  165.         printf ("%s\t\thas %d links instead of 1\n", 
  166.             filename, st.st_nlink);
  167.         return;
  168.         }
  169.     }
  170.     if ((mode & ~fmode_bits_maxset) != 0) {
  171.         printf ("%s\t\tmode 0%o outside maximum set 0%o\n",
  172.             filename, mode, fmode_bits_maxset);
  173.         return;
  174.     }
  175.     }
  176.  
  177.     maxlen += rcsslop;
  178.     if (len > maxlen) {
  179.     printf ("%s\t\tfilename %stoo long, %d chars instead of %d\n", 
  180.         filename, ((len > 14 && rcsslop == 0) ? "much " : ""),
  181.         len, maxlen);
  182.     return;
  183.     }
  184.  
  185.     return;
  186. }
  187.