home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / chflags / chflags.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-20  |  5.1 KB  |  222 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. char copyright[] =
  36. "@(#) Copyright (c) 1992 The Regents of the University of California.\n\
  37.  All rights reserved.\n";
  38. #endif /* not lint */
  39.  
  40. #ifndef lint
  41. static char sccsid[] = "@(#)chflags.c    5.2 (Berkeley) 3/10/92";
  42. #endif /* not lint */
  43.  
  44. #include <sys/types.h>
  45. #include <sys/stat.h>
  46. #include <errno.h>
  47. #include <fts.h>
  48. #include <unistd.h>
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52.  
  53. typedef struct cmdset {
  54.     long clrbits;
  55.     long setbits;
  56. } CMDS;
  57. CMDS cmds;
  58. int retval;
  59.  
  60. void     err __P((const char *, ...));
  61. void     error __P((char *));
  62. int     getflags __P((CMDS *, int));
  63. void    *setflags __P((char *));
  64. void     usage __P((void));
  65.  
  66. int
  67. main(argc, argv)
  68.     int argc;
  69.     char *argv[];
  70. {
  71.     register FTS *fts;
  72.     register FTSENT *p;
  73.     register long oflags;
  74.     register int oct;
  75.     register char *flags;
  76.     struct stat sb;
  77.     void *set;
  78.     int ch, rflag;
  79.     char *ep;
  80.  
  81.     rflag = 0;
  82.     while ((ch = getopt(argc, argv, "R")) != EOF)
  83.         switch((char)ch) {
  84.         case 'R':
  85.             rflag = 1;
  86.             break;
  87.         case '?':
  88.         default:
  89.             usage();
  90.         }
  91.     argv += optind;
  92.     argc -= optind;
  93.  
  94.     if (argc < 2)
  95.         usage();
  96.  
  97.     flags = *argv;
  98.     if (*flags >= '0' && *flags <= '7') {
  99.         oflags = (int)strtol(flags, &ep, 8);
  100.                 if (oflags < 0 || *ep)
  101.                         err("invalid flags: %s", flags);
  102.                 oct = 1;
  103.     } else {
  104.         if ((set = setflags(flags)) == NULL)
  105.                         err("invalid flags: %s", flags);
  106.         oct = 0;
  107.     }
  108.  
  109.     retval = 0;
  110.     if (rflag) {
  111.         if (!(fts = fts_open(++argv,
  112.             oct ? FTS_NOSTAT|FTS_PHYSICAL : FTS_PHYSICAL, 0)))
  113.             err("%s", strerror(errno));
  114.         while (p = fts_read(fts))
  115.             switch(p->fts_info) {
  116.             case FTS_D:
  117.                 break;
  118.             case FTS_DNR:
  119.             case FTS_ERR:
  120.             case FTS_NS:
  121.                 err("%s: %s", p->fts_path, strerror(errno));
  122.             default:
  123.                 if (chflags(p->fts_accpath, oct ? oflags :
  124.                     getflags(set, p->fts_statp->st_flags)))
  125.                     error(p->fts_path);
  126.                 break;
  127.             }
  128.         exit(retval);
  129.     }
  130.     if (oct) {
  131.         while (*++argv)
  132.             if (chflags(*argv, oflags))
  133.                 error(*argv);
  134.     } else
  135.         while (*++argv)
  136.             if (lstat(*argv, &sb) ||
  137.                 chflags(*argv, getflags(set, sb.st_flags)))
  138.                 error(*argv);
  139.     exit(retval);
  140. }
  141.  
  142. /*
  143.  * These are analogous to the setmode/getmode routines in the C library.
  144.  */
  145. void *
  146. setflags(cp)
  147.     char *cp;
  148. {
  149.     register CMDS *fset;
  150.     register char *arg;
  151.  
  152.     fset = &cmds;
  153.     fset->clrbits = 0;
  154.     fset->setbits = 0;
  155.     while (cp) {
  156.         while ((arg = strsep(&cp, ",")) != NULL && *arg == '\0')
  157.             /* void */;
  158.         if (!strcasecmp(arg, "dump"))
  159.             fset->clrbits |= NODUMP;
  160.         else if (!strcasecmp(arg, "nodump"))
  161.             fset->setbits |= NODUMP;
  162.         else
  163.             return (NULL);
  164.     }
  165.     return (fset);
  166. }
  167.  
  168. int
  169. getflags(fset, oflags)
  170.     register CMDS *fset;
  171.     register int oflags;
  172. {
  173.  
  174.     oflags &= ~fset->clrbits;
  175.     oflags |= fset->setbits;
  176.     return (oflags);
  177. }
  178.  
  179. #if __STDC__
  180. #include <stdarg.h>
  181. #else
  182. #include <varargs.h>
  183. #endif
  184.  
  185. void
  186. #if __STDC__
  187. err(const char *fmt, ...)
  188. #else
  189. err(fmt, va_alist)
  190.     char *fmt;
  191.         va_dcl
  192. #endif
  193. {
  194.     va_list ap;
  195. #if __STDC__
  196.     va_start(ap, fmt);
  197. #else
  198.     va_start(ap);
  199. #endif
  200.     (void)fprintf(stderr, "chflags: ");
  201.     (void)vfprintf(stderr, fmt, ap);
  202.     va_end(ap);
  203.     (void)fprintf(stderr, "\n");
  204.     exit(1);
  205.     /* NOTREACHED */
  206. }
  207.  
  208. void
  209. error(name)
  210.     char *name;
  211. {
  212.     (void)fprintf(stderr, "chflags: %s: %s.\n", name, strerror(errno));
  213.     retval = 1;
  214. }
  215.  
  216. void
  217. usage()
  218. {
  219.     (void)fprintf(stderr, "usage: chflags [-R] flags file ...\n");
  220.     exit(1);
  221. }
  222.