1: /*
   2:  *	Program Name:   symcompact.c
   3:  *	Date: December 3, 1994
   4:  *	Author: S.M. Schultz
   5:  *
   6:  *	-----------------   Modification History   ---------------
   7:  *      Version Date            Reason For Modification
   8:  *      1.0     03Dec94         1. Initial release into the public domain.
   9: */
  10: 
  11: #include <stdio.h>
  12: #include <varargs.h>
  13: #include <sys/types.h>
  14: #include <fcntl.h>
  15: #include <sys/stat.h>
  16: #include <sys/dir.h>
  17: 
  18: static  char    *fmsg = "Can't fchdir() back to starting directory";
  19: static  int oct, status, fflag, rflag;
  20: static  u_short set, clear;
  21: static  struct  stat st;
  22: static  void    usage();
  23: 
  24: extern  long    strtol();
  25: extern  int optind, errno;
  26: extern  u_short string_to_flags();  /* from ../ls */
  27: 
  28: main(argc, argv)
  29:     int argc;
  30:     char    *argv[];
  31:     {
  32:     register char *p;
  33:     char    *flags, *ep;
  34:     int ch, fcurdir;
  35:     long    tmp;
  36: 
  37:     while   ((ch = getopt(argc, argv, "Rf")) != EOF)
  38:         {
  39:         switch  (ch)
  40:             {
  41:             case 'R':
  42:                 rflag++;
  43:                 break;
  44:             case 'f':
  45:                 fflag++;
  46:                 break;
  47:             case '?':
  48:             default:
  49:                 usage();
  50:             }
  51:         }
  52:     argv += optind;
  53:     argc += optind;
  54:     if  (argc < 2)
  55:         usage();
  56: 
  57:     flags = *argv++;
  58:     if  (*flags >= '0' && *flags <= '7')
  59:         {
  60:         tmp = strtol(flags, &ep, 8);
  61:         if  (tmp < 0 || tmp >= 64L*1024*1024 || *ep)
  62:             die("invalid flags: %s", flags);
  63:         oct = 1;
  64:         set = tmp;
  65:         }
  66:     else
  67:         {
  68:         if  (string_to_flags(&flags, &set, &clear))
  69:             die("invalid flag: %s", flags);
  70:         clear = ~clear;
  71:         oct = 0;
  72:         }
  73: 
  74:     if  (rflag)
  75:         {
  76:         fcurdir = open(".", O_RDONLY);
  77:         if  (fcurdir < 0)
  78:             die("Can't open .");
  79:         }
  80: 
  81:     while   (p = *argv++)
  82:         {
  83:         if  (lstat(p, &st) < 0)
  84:             {
  85:             status |= warning(p);
  86:             continue;
  87:             }
  88:         if  (rflag && (st.st_mode&S_IFMT) == S_IFDIR)
  89:             {
  90:             status |= recurse(p, fcurdir);
  91:             continue;
  92:             }
  93:         if  ((st.st_mode&S_IFMT) == S_IFLNK && stat(p, &st) < 0)
  94:             {
  95:             status |= warning(p);
  96:             continue;
  97:             }
  98:         if  (chflags(p, newflags(st.st_flags)) < 0)
  99:             {
 100:             status |= warning(p);
 101:             continue;
 102:             }
 103:         }
 104:     close(fcurdir);
 105:     exit(status);
 106:     }
 107: 
 108: recurse(dir, savedir)
 109:     char    *dir;
 110:     int savedir;
 111:     {
 112:     register DIR *dirp;
 113:     register struct direct *dp;
 114:     int ecode;
 115: 
 116:     if  (chdir(dir) < 0)
 117:         {
 118:         warning(dir);
 119:         return(1);
 120:         }
 121:     if  ((dirp = opendir(".")) == NULL)
 122:         {
 123:         warning(dir);
 124:         return(1);
 125:         }
 126:     dp = readdir(dirp);
 127:     dp = readdir(dirp); /* read "." and ".." */
 128:     ecode = 0;
 129:     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
 130:         {
 131:         if  (lstat(dp->d_name, &st) < 0)
 132:             {
 133:             ecode = warning(dp->d_name);
 134:             if  (ecode)
 135:                 break;
 136:             continue;
 137:             }
 138:         if  ((st.st_mode&S_IFMT) == S_IFDIR)
 139:             {
 140:             ecode = recurse(dp->d_name, dirfd(dirp));
 141:             if  (ecode)
 142:                 break;
 143:             continue;
 144:             }
 145:         if  ((st.st_mode&S_IFMT) == S_IFLNK)
 146:             continue;
 147:         if  (chflags(dp->d_name, newflags(st.st_flags)) < 0 &&
 148:                     (ecode = warning(dp->d_name)))
 149:             break;
 150:         }
 151: /*
 152:  * Lastly change the flags on the directory we are in before returning to
 153:  * the previous level.
 154: */
 155:     if  (fstat(dirfd(dirp), &st) < 0)
 156:         die("can't fstat .");
 157:     if  (fchflags(dirfd(dirp), newflags(st.st_flags)) < 0)
 158:         ecode = warning(dir);
 159:     if  (fchdir(savedir) < 0)
 160:         die(fmsg);
 161:     closedir(dirp);
 162:     return(ecode);
 163:     }
 164: 
 165: /* VARARGS1 */
 166: die(fmt, va_alist)
 167:     char *fmt;
 168:     va_dcl
 169:     {
 170:     va_list ap;
 171: 
 172:     va_start(ap);
 173:     vfprintf(stderr, fmt, ap);
 174:     fputc('\n', stderr);
 175:     va_end(ap);
 176:     exit(1);
 177:     }
 178: 
 179: warning(msg)
 180:     char *msg;
 181:     {
 182: 
 183:     if  (!fflag)
 184:         fprintf(stderr, "chflags: %s: %s\n", msg, strerror(errno));
 185:     return(!fflag);
 186:     }
 187: 
 188: newflags(flags)
 189:     u_short flags;
 190:     {
 191: 
 192:     if  (oct)
 193:         flags = set;
 194:     else
 195:         {
 196:         flags |= set;
 197:         flags &= clear;
 198:         }
 199:     return(flags);
 200:     }
 201: 
 202: static void
 203: usage()
 204:     {
 205:     fputs("usage: chflags [-Rf] flags file ...\n", stderr);
 206:     exit(1);
 207:     }

Defined functions

die defined in line 166; used 5 times
main defined in line 28; never used
newflags defined in line 188; used 3 times
recurse defined in line 108; used 2 times
usage defined in line 202; used 3 times
warning defined in line 179; used 8 times

Defined variables

clear defined in line 20; used 4 times
fflag defined in line 19; used 3 times
fmsg defined in line 18; used 1 times
oct defined in line 19; used 3 times
rflag defined in line 19; used 3 times
set defined in line 20; used 4 times
st defined in line 21; used 11 times
status defined in line 19; used 5 times
Last modified: 1994-12-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3966
Valid CSS Valid XHTML 1.0 Strict