1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)chflags.c 5.1 (Berkeley) 12/12/91"; 16 #endif /* not lint */ 17 18 #include <sys/types.h> 19 #include <sys/stat.h> 20 #include <fts.h> 21 #include <stdio.h> 22 #include <string.h> 23 24 extern int errno; 25 int retval; 26 27 main(argc, argv) 28 int argc; 29 char **argv; 30 { 31 extern int optind; 32 register FTS *fts; 33 register FTSENT *p; 34 register int oct, oflags; 35 register char *flags; 36 void *set, *setflags(); 37 struct stat sb; 38 int ch, fflag, rflag; 39 40 fflag = rflag = 0; 41 while ((ch = getopt(argc, argv, "Rf")) != EOF) 42 switch((char)ch) { 43 case 'R': 44 rflag = 1; 45 break; 46 case 'f': /* no longer documented */ 47 fflag = 1; 48 break; 49 case '?': 50 default: 51 usage(); 52 } 53 argv += optind; 54 argc -= optind; 55 56 if (argc < 2) 57 usage(); 58 59 flags = *argv; 60 if (*flags >= '0' && *flags <= '7') { 61 oflags = (int)strtol(flags, (char **)NULL, 8); 62 oct = 1; 63 } else { 64 if (!(set = setflags(flags))) { 65 (void)fprintf(stderr, "chflags: invalid flags.\n"); 66 exit(1); 67 } 68 oct = 0; 69 } 70 71 retval = 0; 72 if (rflag) { 73 if (!(fts = fts_open(++argv, 74 oct ? FTS_NOSTAT|FTS_PHYSICAL : FTS_PHYSICAL, 0))) { 75 (void)fprintf(stderr, "chflags: %s.\n", 76 strerror(errno)); 77 exit(1); 78 } 79 while (p = fts_read(fts)) 80 switch(p->fts_info) { 81 case FTS_D: 82 break; 83 case FTS_DNR: 84 case FTS_ERR: 85 case FTS_NS: 86 (void)fprintf(stderr, "chflags: %s: %s.\n", 87 p->fts_path, strerror(errno)); 88 exit(1); 89 default: 90 if (chflags(p->fts_accpath, oct ? oflags : 91 getflags(set, p->fts_statb.st_flags)) && 92 !fflag) 93 error(p->fts_path); 94 break; 95 } 96 exit(retval); 97 } 98 if (oct) { 99 while (*++argv) 100 if (chflags(*argv, oflags) && !fflag) 101 error(*argv); 102 } else 103 while (*++argv) 104 if ((lstat(*argv, &sb) || 105 chflags(*argv, getflags(set, sb.st_flags))) && 106 !fflag) 107 error(*argv); 108 exit(retval); 109 } 110 111 error(name) 112 char *name; 113 { 114 (void)fprintf(stderr, "chflags: %s: %s.\n", name, strerror(errno)); 115 retval = 1; 116 } 117 118 usage() 119 { 120 (void)fprintf(stderr, "Usage: chflags [-R] flags file ...\n"); 121 exit(1); 122 } 123 124 /* 125 * These are analogous to the setmode/getmode routines in the C library. 126 */ 127 struct cmdset { 128 long clrbits; 129 long setbits; 130 } cmds; 131 132 void * 133 setflags(cp) 134 char *cp; 135 { 136 register struct cmdset *fset; 137 register char *arg; 138 139 fset = &cmds; 140 fset->clrbits = 0; 141 fset->setbits = 0; 142 while (cp) { 143 while ((arg = strsep(&cp, ",")) != NULL && *arg == '\0') 144 /* void */; 145 if (!strcasecmp(arg, "dump")) 146 fset->clrbits |= NODUMP; 147 else if (!strcasecmp(arg, "nodump")) 148 fset->setbits |= NODUMP; 149 else 150 return (NULL); 151 } 152 return (fset); 153 } 154 155 getflags(fset, oflags) 156 register struct cmdset *fset; 157 register int oflags; 158 { 159 160 oflags &= ~fset->clrbits; 161 oflags |= fset->setbits; 162 return (oflags); 163 } 164