home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 May / W2KPRK.iso / apps / posix / source / CHMOD / CHMOD.C next >
C/C++ Source or Header  |  1999-11-17  |  7KB  |  279 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.19 (Berkeley) 3/12/91";
  42. #endif /* not lint */
  43. #ifdef DF_POSIX
  44. #include <misc.h>
  45. #include <bsdlib.h>
  46. #endif
  47.  
  48. #include <sys/types.h>
  49. #include <sys/stat.h>
  50. #include <fts.h>
  51. #include <stdio.h>
  52. #include <string.h>
  53. #include <stdlib.h>
  54. #if WIN_NT
  55. # include <unistd.h>
  56. #endif
  57.  
  58. extern int errno;
  59. int retval;
  60.  
  61. void error __P((const char *));
  62. void usage __P((void));
  63.  
  64. #if WIN_NT
  65. extern int globulate __P((int, int, char **));
  66. extern void deglobulate __P((void));
  67. extern int globulated_argc;
  68. extern char **globulated_argv;
  69. pid_t ppid;
  70. int globulation;
  71. #endif
  72.  
  73. int
  74. #if __STDC__
  75. main (int argc, char **argv)
  76. #else
  77. main(argc, argv)
  78.     int argc;
  79.     char **argv;
  80. #endif
  81. {
  82.     extern int optind;
  83.     register FTS *fts;
  84.     register FTSENT *p;
  85.     register int oct;
  86.     mode_t omode;
  87.     register char *mode;
  88. #if WIN_NT
  89.     mode_t *set;
  90. #else
  91.     mode_t *set, *setmode();
  92. #endif
  93.     struct stat sb;
  94.     int ch, fflag, rflag;
  95.  
  96. #if WIN_NT
  97.     ppid = getppid();
  98.     if (ppid == (pid_t) 1) /* if parent is CMD.EXE */
  99.     {
  100.         globulation = globulate(1, argc, argv);
  101.         if (globulation == 0)
  102.         {
  103.             argc = globulated_argc;
  104.             argv = globulated_argv;
  105.         }
  106.     }
  107. #endif
  108.     fflag = rflag = 0;
  109.     while ((ch = getopt(argc, argv, "Rfrwx")) != EOF)
  110.         switch((char)ch) {
  111.         case 'R':
  112.             rflag = 1;
  113.             break;
  114.         case 'f':        /* no longer documented */
  115.             fflag = 1;
  116.             break;
  117.         case 'r':        /* "-[rwx]" are valid file modes */
  118.         case 'w':
  119.         case 'x':
  120.             --optind;
  121.             goto done;
  122.         case '?':
  123.         default:
  124.             usage();
  125.         }
  126. done:    argv += optind;
  127.     argc -= optind;
  128.  
  129.     if (argc < 2)
  130.         usage();
  131.  
  132.     mode = *argv;
  133.     if (*mode >= '0' && *mode <= '7') {
  134.         omode = (mode_t)strtol(mode, (char **)NULL, 8);
  135.         oct = 1;
  136.     } else {
  137.         if (!(set = setmode(mode))) {
  138.             (void)fprintf(stderr, "chmod: invalid file mode.\n");
  139. #if WIN_NT
  140.             if (ppid == (pid_t) 1 && globulation == 0)
  141.                 deglobulate();
  142. #endif
  143.             exit(EXIT_FAILURE);
  144.         }
  145.         oct = 0;
  146.     }
  147.  
  148.     retval = 0;
  149.     if (rflag) {
  150.         if (!(fts = fts_open(++argv,
  151.             oct ? FTS_NOSTAT|FTS_PHYSICAL : FTS_PHYSICAL, 0))) {
  152. #if 0
  153. (void) fprintf(stderr, "strerror #1\n");
  154. #endif
  155.             (void)fprintf(stderr, "chmod: %s.\n", strerror(errno));
  156. #if WIN_NT
  157.             if (ppid == (pid_t) 1 && globulation == 0)
  158.                 deglobulate();
  159. #endif
  160.             exit(EXIT_FAILURE);
  161.         }
  162.         while ((p = fts_read(fts)) != NULL)
  163.             switch(p->fts_info) {
  164.             case FTS_D:
  165.                 break;
  166.             case FTS_DNR:
  167.             case FTS_ERR:
  168.             case FTS_NS:
  169. #if 0
  170. (void) fprintf(stderr, "strerror #2\n");
  171. #endif
  172.                 (void)fprintf(stderr, "chmod: %s: %s.\n",
  173.                     p->fts_path, strerror(errno));
  174. #if WIN_NT
  175.                 if (ppid == (pid_t) 1 &&
  176.                     globulation == 0)
  177.                     deglobulate();
  178. #endif
  179.                 exit(EXIT_FAILURE);
  180.             default:
  181. # if 0
  182. (void) fprintf(stderr, "*argv: \"%s\"; omode: %lo\n", p->fts_accpath, (unsigned long)( oct ? omode :getmode(set, p->fts_statb.st_mode)));
  183. # endif
  184.                 if (chmod(p->fts_accpath, oct ? omode :
  185.                     getmode(set, p->fts_statb.st_mode)) &&
  186.                     !fflag) {
  187. #if 0
  188. (void) fprintf(stderr, "#1\n");
  189. #endif
  190.                     error(p->fts_path);
  191.                 }
  192.                 break;
  193.             }
  194. #if WIN_NT
  195.         if (ppid == (pid_t) 1 && globulation == 0)
  196.             deglobulate();
  197. #endif
  198.         exit(retval);
  199.     }
  200. #if 0
  201. printf ("argv %s\n", *argv);
  202. printf ("lstat %d\n",  lstat(*argv, &sb));
  203. printf ("mode %d\n",  sb.st_mode);
  204. printf ("stat %d\n",  stat("/demo/cc.exe", &sb));
  205. printf ("mode (stat) %d\n",  sb.st_mode);
  206. printf ("chmod %d\n",  chmod("/demo/cc.exe", 0777));
  207. #endif
  208.  
  209. #if WIN_NT
  210.     if (oct) {
  211.         while (*++argv) {
  212. # if 0
  213. (void) fprintf(stderr, "*argv: \"%s\"; omode: %lo\n", *argv, (unsigned long) omode);
  214. # endif
  215.             if (chmod(*argv, omode) && !fflag) {
  216. # if 0
  217. (void) fprintf(stderr, "#2\n");
  218. # endif
  219.                 error(*argv);
  220.             }
  221.         }
  222.     } else
  223.         while (*++argv)
  224. # if WIN_NT
  225.             if ((stat(*argv, &sb) ||
  226.                 chmod(*argv, getmode(set, sb.st_mode))) && !fflag) {
  227. #  if 0
  228. (void) fprintf(stderr, "#3a\n");
  229. #  endif
  230.                 error(*argv);
  231.             }
  232. # else
  233.             if ((lstat(*argv, &sb) ||
  234.                 chmod(*argv, getmode(set, sb.st_mode))) && !fflag) {
  235. #   if 0
  236. (void) fprintf(stderr, "#3b\n");
  237. #   endif
  238.                 error(*argv);
  239.             }
  240. # endif /* WIN_NT */
  241. #endif
  242. #if WIN_NT
  243.     if (ppid == (pid_t) 1 && globulation == 0)
  244.         deglobulate();
  245. #endif
  246.     return retval;
  247. }
  248.  
  249. void
  250. #if __STDC__
  251. error (const char *name)
  252. #else
  253. error(name)
  254.     char *name;
  255. #endif
  256. {
  257. #if 0
  258. (void) fprintf(stderr, "strerror #3\n");
  259. #endif
  260.     (void)fprintf(stderr, "chmod: %s: %s.\n", name, strerror(errno));
  261.     retval = 1;
  262.     return;
  263. }
  264.  
  265. void
  266. #if __STDC__
  267. usage (void)
  268. #else
  269. usage()
  270. #endif
  271. {
  272.     (void)fprintf(stderr, "chmod: chmod [-R] mode file ...\n");
  273. #if WIN_NT
  274.     if (ppid == (pid_t) 1 && globulation == 0)
  275.         deglobulate();
  276. #endif
  277.     exit(EXIT_FAILURE);
  278. }
  279.