da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1992-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * chmod
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char usage[] =
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[-?\n@(#)$Id: chmod (AT&T Research) 2009-07-02 $\n]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinUSAGE_LICENSE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+NAME?chmod - change the access permissions of files]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+DESCRIPTION?\bchmod\b changes the permission of each file "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "according to mode, which can be either a symbolic representation "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "of changes to make, or an octal number representing the bit "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "pattern for the new permissions.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?Symbolic mode strings consist of one or more comma separated list "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "of operations that can be perfomed on the mode. Each operation is of "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "the form \auser\a \aop\a \aperm\a where \auser\a is zero or more of "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "the following letters:]{"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+u?User permission bits.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+g?Group permission bits.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+o?Other permission bits.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+a?All permission bits. This is the default if none are specified.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "}"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?The \aperm\a portion consists of zero or more of the following letters:]{"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+r?Read permission.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+s?Setuid when \bu\b is selected for \awho\a and setgid when \bg\b "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "is selected for \awho\a.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+w?Write permission.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+x?Execute permission for files, search permission for directories.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+X?Same as \bx\b except that it is ignored for files that do not "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "already have at least one \bx\b bit set.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+l?Exclusive lock bit on systems that support it. Group execute "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "must be off.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+t?Sticky bit on systems that support it.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "}"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?The \aop\a portion consists of one or more of the following characters:]{"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[++?Cause the permission selected to be added to the existing "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "permissions. | is equivalent to +.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+-?Cause the permission selected to be removed to the existing "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "permissions.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+=?Cause the permission to be set to the given permissions.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+&?Cause the permission selected to be \aand\aed with the existing "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "permissions.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+^?Cause the permission selected to be propagated to more "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "restrictive groups.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "}"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?Symbolic modes with the \auser\a portion omitted are subject to "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\bumask\b(2) settings unless the \b=\b \aop\a or the "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\b--ignore-umask\b option is specified.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?A numeric mode is from one to four octal digits (0-7), "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "derived by adding up the bits with values 4, 2, and 1. "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "Any omitted digits are assumed to be leading zeros. The "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "first digit selects the set user ID (4) and set group ID "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "(2) and save text image (1) attributes. The second digit "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "selects permissions for the user who owns the file: read "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "(4), write (2), and execute (1); the third selects permissions"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "for other users in the file's group, with the same values; "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "and the fourth for other users not in the file's group, with "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "the same values.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?For symbolic links, by default, \bchmod\b changes the mode on the file "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "referenced by the symbolic link, not on the symbolic link itself. "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "The \b-h\b options can be specified to change the mode of the link. "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "When traversing directories with \b-R\b, \bchmod\b either follows "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "symbolic links or does not follow symbolic links, based on the "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "options \b-H\b, \b-L\b, and \b-P\b. The configuration parameter "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\bPATH_RESOLVE\b determines the default behavior if none of these "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "options is specified.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?When the \b-c\b or \b-v\b options are specified, change notifications "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "are written to standard output using the format, "
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin "\b%s: mode changed to %0.4o (%s)\b, with arguments of the "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "pathname, the numeric mode, and the resulting permission bits as "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "would be displayed by the \bls\b command.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?For backwards compatibility, if an invalid option is given that is a valid "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "symbolic mode specification, \bchmod\b treats this as a mode "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "specification rather than as an option specification.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[H:metaphysical?Follow symbolic links for command arguments; otherwise don't "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "follow symbolic links when traversing directories.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[L:logical|follow?Follow symbolic links when traversing directories.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[P:physical|nofollow?Don't follow symbolic links when traversing directories.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[R:recursive?Change the mode for files in subdirectories recursively.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[c:changes?Describe only files whose permission actually change.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[f:quiet|silent?Do not report files whose permissioins fail to change.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[h:symlink?Change the mode of the symbolic links on systems that "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "support this.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[i:ignore-umask?Ignore the \bumask\b(2) value in symbolic mode "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "expressions. This is probably how you expect \bchmod\b to work.]"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin"[n:show?Show actions but do not change any file modes.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[F:reference?Omit the \amode\a operand and use the mode of \afile\a "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "instead.]:[file]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[v:verbose?Describe changed permissions of all files.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\nmode file ...\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+EXIT STATUS?]{"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+0?All files changed successfully.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+>0?Unable to change mode of one or more files.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"}"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+SEE ALSO?\bchgrp\b(1), \bchown\b(1), \btw\b(1), \bgetconf\b(1), \bls\b(1), "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\bumask\b(2)]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(__STDPP__directive) && defined(__STDPP__hide)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin__STDPP__directive pragma pp:hide lchmod
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define lchmod ______lchmod
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <cmd.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ls.h>
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#include <fts_fix.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/symlink"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(__STDPP__directive) && defined(__STDPP__hide)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin__STDPP__directive pragma pp:nohide lchmod
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef lchmod
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int lchmod(const char*, mode_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinb_chmod(int argc, char** argv, void* context)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int mode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int force = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* amode = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTS* fts;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT*ent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int (*chmodf)(const char*, mode_t);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int logical = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int notify = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int ignore = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int show = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_lchmod
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int chlink = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat st;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_NOTIFY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags = fts_flags() | FTS_TOP | FTS_NOPOSTORDER | FTS_NOSEEDOTDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NOTE: we diverge from the normal optget boilerplate
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * to allow `chmod -x etc' to fall through
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (optget(argv, usage))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'c':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin notify = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'f':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin force = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'h':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_lchmod
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin chlink = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'i':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ignore = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 'n':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin show = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'v':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin notify = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'F':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (stat(opt_info.arg, &st))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_exit(1), "%s: cannot stat", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = st.st_mode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin amode = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'H':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= FTS_META|FTS_PHYSICAL;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz logical = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'L':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~(FTS_META|FTS_PHYSICAL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz logical = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'P':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~FTS_META;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= FTS_PHYSICAL;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz logical = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'R':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~FTS_TOP;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz logical = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_usage(2), "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv += opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (error_info.errors || !*argv || !amode && !*(argv + 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_usage(2), "%s", optusage(NiL));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (logical)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz flags &= ~(FTS_META|FTS_PHYSICAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ignore)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ignore = umask(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (amode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin amode = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin amode = *argv++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = strperm(amode, &last, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ignore)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin umask(ignore);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_exit(1), "%s: invalid mode", amode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin chmodf =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_lchmod
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin chlink ? lchmod :
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin chmod;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fts = fts_open(argv, flags, NiL)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ignore)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin umask(ignore);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(1), "%s: not found", *argv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (!sh_checksig(context) && (ent = fts_read(fts)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (ent->fts_info)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FTS_SL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (chmodf == chmod)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & FTS_PHYSICAL) || (flags & FTS_META) && ent->fts_level == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts_set(NiL, ent, FTS_FOLLOW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FTS_F:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FTS_D:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FTS_SLNONE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin anyway:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (amode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = strperm(amode, &last, ent->fts_statp->st_mode);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (show || (*chmodf)(ent->fts_accpath, mode) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (notify == 2 || notify == 1 && (mode&S_IPERM) != (ent->fts_statp->st_mode&S_IPERM))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout, "%s: mode changed to %0.4o (%s)\n", ent->fts_path, mode, fmtmode(mode, 1)+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!force)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(0), "%s: cannot change mode", ent->fts_accpath);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FTS_DC:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!force)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_warn(0), "%s: directory causes cycle", ent->fts_accpath);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FTS_DNR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!force)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(0), "%s: cannot read directory", ent->fts_accpath);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto anyway;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FTS_DNX:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!force)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(0), "%s: cannot search directory", ent->fts_accpath);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto anyway;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FTS_NS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!force)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(0), "%s: not found", ent->fts_accpath);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts_close(fts);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ignore)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin umask(ignore);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return error_info.errors != 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}