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

  1. /*
  2.  * Copyright (c) 1989 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) 1989 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[] = "@(#)chmod.c    5.21 (Berkeley) 1/27/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. int retval;
  54.  
  55. void err __P((const char *, ...));
  56. void error __P((char *));
  57. void usage __P((void));
  58.  
  59. int
  60. main(argc, argv)
  61.     int argc;
  62.     char *argv[];
  63. {
  64.     register FTS *fts;
  65.     register FTSENT *p;
  66.     register int oct, omode;
  67.     struct stat sb;
  68.     mode_t *set;
  69.     int ch, fflag, rflag;
  70.     char *ep, *mode;
  71.  
  72.     fflag = rflag = 0;
  73.     while ((ch = getopt(argc, argv, "Rfrwx")) != EOF)
  74.         switch((char)ch) {
  75.         case 'R':
  76.             rflag = 1;
  77.             break;
  78.         case 'f':        /* no longer documented */
  79.             fflag = 1;
  80.             break;
  81.         case 'r':        /* "-[rwx]" are valid file modes */
  82.         case 'w':
  83.         case 'x':
  84.             --optind;
  85.             goto done;
  86.         case '?':
  87.         default:
  88.             usage();
  89.         }
  90. done:    argv += optind;
  91.     argc -= optind;
  92.  
  93.     if (argc < 2)
  94.         usage();
  95.  
  96.     mode = *argv;
  97.     if (*mode >= '0' && *mode <= '7') {
  98.         omode = (int)strtol(mode, &ep, 8);
  99.         if (omode < 0 || *ep)
  100.             err("invalid file mode: %s", mode);
  101.         oct = 1;
  102.     } else {
  103.         if (!(set = setmode(mode)))
  104.             err("invalid file mode: %s", mode);
  105.         oct = 0;
  106.     }
  107.  
  108.     retval = 0;
  109.     if (rflag) {
  110.         if ((fts = fts_open(++argv,
  111.             oct ? FTS_NOSTAT|FTS_PHYSICAL : FTS_PHYSICAL, 0)) == NULL)
  112.             err("%s", strerror(errno));
  113.         while (p = fts_read(fts))
  114.             switch(p->fts_info) {
  115.             case FTS_D:
  116.                 break;
  117.             case FTS_DNR:
  118.             case FTS_ERR:
  119.             case FTS_NS:
  120.                 err("%s: %s", p->fts_path, strerror(errno));
  121.             default:
  122.                 if (chmod(p->fts_accpath, oct ? omode :
  123.                     getmode(set, p->fts_statp->st_mode)) &&
  124.                     !fflag)
  125.                     error(p->fts_path);
  126.                 break;
  127.             }
  128.         exit(retval);
  129.     }
  130.     if (oct) {
  131.         while (*++argv)
  132.             if (chmod(*argv, omode) && !fflag)
  133.                 error(*argv);
  134.     } else
  135.         while (*++argv)
  136.             if ((lstat(*argv, &sb) ||
  137.                 chmod(*argv, getmode(set, sb.st_mode))) && !fflag)
  138.                 error(*argv);
  139.     exit(retval);
  140. }
  141.  
  142. void
  143. error(name)
  144.     char *name;
  145. {
  146.     (void)fprintf(stderr, "chmod: %s: %s\n", name, strerror(errno));
  147.     retval = 1;
  148. }
  149.  
  150. void
  151. usage()
  152. {
  153.     (void)fprintf(stderr, "usage: chmod [-R] mode file ...\n");
  154.     exit(1);
  155. }
  156.  
  157. #if __STDC__
  158. #include <stdarg.h>
  159. #else
  160. #include <varargs.h>
  161. #endif
  162.  
  163. void
  164. #if __STDC__
  165. err(const char *fmt, ...)
  166. #else
  167. err(fmt, va_alist)
  168.     char *fmt;
  169.         va_dcl
  170. #endif
  171. {
  172.     va_list ap;
  173. #if __STDC__
  174.     va_start(ap, fmt);
  175. #else
  176.     va_start(ap);
  177. #endif
  178.     (void)fprintf(stderr, "chmod: ");
  179.     (void)vfprintf(stderr, fmt, ap);
  180.     va_end(ap);
  181.     (void)fprintf(stderr, "\n");
  182.     exit(1);
  183.     /* NOTREACHED */
  184. }
  185.