1 /* 2 * Copyright (c) 1992 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) 1992 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.4 (Berkeley) 03/03/93"; 16 #endif /* not lint */ 17 18 #include <sys/types.h> 19 #include <sys/stat.h> 20 21 #include <err.h> 22 #include <fts.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <unistd.h> 27 28 u_long string_to_flags __P((char **, u_long *, u_long *)); 29 void usage __P((void)); 30 31 int 32 main(argc, argv) 33 int argc; 34 char *argv[]; 35 { 36 register FTS *ftsp; 37 register FTSENT *p; 38 register int oct; 39 u_long clear, set; 40 int ch, fts_options, retval, rflag, hflag, Hflag; 41 char *flags, *ep; 42 43 rflag = hflag = Hflag = 0; 44 fts_options = FTS_PHYSICAL; 45 while ((ch = getopt(argc, argv, "HRh")) != EOF) 46 switch((char)ch) { 47 case 'H': 48 Hflag = 1; 49 fts_options |= FTS_COMFOLLOW; 50 break; 51 case 'R': 52 rflag = 1; 53 break; 54 case 'h': 55 hflag = 1; 56 fts_options &= ~FTS_PHYSICAL; 57 fts_options |= FTS_LOGICAL; 58 break; 59 case '?': 60 default: 61 usage(); 62 } 63 argv += optind; 64 argc -= optind; 65 66 if (argc < 2) 67 usage(); 68 69 flags = *argv; 70 if (*flags >= '0' && *flags <= '7') { 71 set = (int)strtol(flags, &ep, 8); 72 if (set < 0 || *ep) 73 errx(1, "invalid flags: %s", flags); 74 fts_options |= FTS_NOSTAT; 75 oct = 1; 76 } else { 77 if (string_to_flags(&flags, &set, &clear)) 78 errx(1, "invalid flag: %s", flags); 79 clear = ~clear; 80 oct = 0; 81 } 82 83 if ((ftsp = fts_open(++argv, fts_options , 0)) == NULL) 84 err(1, ""); 85 86 for (retval = 0; p = fts_read(ftsp);) 87 switch(p->fts_info) { 88 case FTS_D: 89 if (!rflag) 90 fts_set(ftsp, p, FTS_SKIP); 91 break; 92 case FTS_DNR: 93 case FTS_ERR: 94 case FTS_NS: 95 err(1, "%s", p->fts_path); 96 default: 97 if (p->fts_info == FTS_SL && 98 !(hflag || 99 (Hflag && p->fts_level == FTS_ROOTLEVEL))) 100 continue; 101 if (oct) { 102 if (!chflags(p->fts_accpath, set)) 103 break; 104 } else { 105 p->fts_statp->st_flags |= set; 106 p->fts_statp->st_flags &= clear; 107 if (!chflags(p->fts_accpath, 108 p->fts_statp->st_flags)) 109 break; 110 } 111 warn("%s", p->fts_path); 112 retval = 1; 113 break; 114 } 115 exit(retval); 116 } 117 118 void 119 usage() 120 { 121 (void)fprintf(stderr, "usage: chflags [-HRh] flags file ...\n"); 122 exit(1); 123 } 124