/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1992-2011 AT&T Intellectual Property *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* David Korn
* Glenn Fowler
* AT&T Research
*
* chgrp+chown
*/
static const char usage_1[] =
"[-?@(#)$Id: chgrp (AT&T Research) 2011-01-03 $\n]"
;
static const char usage_grp_1[] =
"[+NAME?chgrp - change the group ownership of files]"
"[+DESCRIPTION?\bchgrp\b changes the group ownership of each file"
" to \agroup\a, which can be either a group name or a numeric"
" group id. The user ownership of each file may also be changed to"
" \auser\a by prepending \auser\a\b:\b to the group name.]"
;
static const char usage_own_1[] =
"[+NAME?chown - change the ownership of files]"
"[+DESCRIPTION?\bchown\b changes the ownership of each file"
" to \auser\a, which can be either a user name or a numeric"
" user id. The group ownership of each file may also be changed to"
" \auser\a by appending \b:\b\agroup\a to the user name.]"
;
static const char usage_2[] =
"[b:before?Only change files with \bctime\b before (less than) the "
"\bmtime\b of \afile\a.]:[file]"
"[c:changes?Describe only files whose ownership actually changes.]"
"[f:quiet|silent?Do not report files whose ownership fails to change.]"
"[l|h:symlink?Change the ownership of symbolic links on systems that "
"support this. Implies \b--physical\b.]"
"[m:map?The first operand is interpreted as a file that contains a map "
"of space separated \afrom_uid:from_gid to_uid:to_gid\a pairs. The "
"\auid\a or \agid\a part of each pair may be omitted to mean any \auid\a "
"or \agid\a. Ownership of files matching the \afrom\a part of any pair "
"is changed to the corresponding \ato\a part of the pair. The matching "
"for each file operand is in the order \auid\a:\agid\a, \auid\a:, "
":\agid\a. For a given file, once a \auid\a or \agid\a mapping is "
"determined it is not overridden by any subsequent match. Unmatched "
"files are silently ignored.]"
"[n:show?Show actions but don't execute.]"
"[N:numeric?By default numeric user and group id operands are first "
"interpreted as names; if no name exists then they are interpreted as "
"explicit numeric ids. \b--numeric\b interprets numeric id operands as "
"numeric ids.]"
"[r:reference?Omit the explicit ownership operand and use the ownership "
"of \afile\a instead.]:[file]"
"[u:unmapped?Print a diagnostic for each file for which either the "
"\auid\a or \agid\a or both were not mapped.]"
"[v:verbose?Describe changed permissions of all files.]"
"[H:metaphysical?Follow symbolic links for command arguments; otherwise "
"don't follow symbolic links when traversing directories.]"
"[L:logical|follow?Follow symbolic links when traversing directories.]"
"[P:physical|nofollow?Don't follow symbolic links when traversing "
"directories.]"
"[R:recursive?Recursively change ownership of directories and their "
"contents.]"
"[X:test?Canonicalize output for testing.]"
"\n"
"\n"
;
static const char usage_3[] =
" file ...\n"
"\n"
"[+EXIT STATUS?]{"
"[+0?All files changed successfully.]"
"[+>0?Unable to change ownership of one or more files.]"
"}"
"[+SEE ALSO?\bchmod\b(1), \btw\b(1), \bgetconf\b(1), \bls\b(1)]"
;
#if defined(__STDPP__directive) && defined(__STDPP__hide)
#else
#define lchown ______lchown
#endif
#include <cmd.h>
#include <cdt.h>
#include <ls.h>
#include <ctype.h>
#include <fts_fix.h>
#if defined(__STDPP__directive) && defined(__STDPP__hide)
#else
#endif
{
} Key_t;
{
} Map_t;
#if !_lib_lchown
#ifndef ENOSYS
#endif
int
{
return ENOSYS;
}
#endif /* _lib_chown */
/*
* parse uid and gid from s
*/
static void
{
register char* t;
register int n;
register int m;
char* z;
while (isspace(*s))
s++;
if (n)
{
if ((n = t++ - s) >= sizeof(buf))
n = sizeof(buf) - 1;
}
{
if (*s)
{
n = (int)strtol(s, &z, 0);
if (*z || !(options & OPT_NUMERIC))
{
n = m;
else if (*z)
}
}
for (s = t; (n = *t) && !isspace(n); t++);
if (n)
{
if ((n = t++ - s) >= sizeof(buf))
n = sizeof(buf) - 1;
}
}
if (*s)
{
n = (int)strtol(s, &z, 0);
if (*z || !(options & OPT_NUMERIC))
{
n = m;
else if (*z)
}
}
if (e)
*e = t;
}
int
{
register int options = 0;
register char* s;
register Map_t* m;
register int i;
int flags;
int uid;
int gid;
char* op;
char* usage;
char* t;
unsigned long before;
before = ~0;
else
{
}
else
for (;;)
{
{
case 'b':
continue;
case 'c':
case 'v':
options |= OPT_VERBOSE;
continue;
case 'f':
continue;
case 'l':
options |= OPT_LCHOWN;
continue;
case 'm':
continue;
case 'n':
continue;
case 'N':
options |= OPT_NUMERIC;
continue;
case 'r':
continue;
case 'u':
options |= OPT_UNMAPPED;
continue;
case 'H':
logical = 0;
continue;
case 'L':
logical = 0;
continue;
case 'P':
flags |= FTS_PHYSICAL;
logical = 0;
continue;
case 'R':
logical = 0;
continue;
case 'X':
continue;
case ':':
continue;
case '?':
break;
}
break;
}
s = *argv;
if (options & OPT_LCHOWN)
{
flags |= FTS_PHYSICAL;
logical = 0;
}
if (logical)
if (map)
{
if (streq(s, "-"))
{
{
}
}
}
{
}
{
case OPT_UID:
s = ERROR_translate(0, 0, 0, " owner");
break;
case OPT_GID:
s = ERROR_translate(0, 0, 0, " group");
break;
s = ERROR_translate(0, 0, 0, " owner and group");
break;
default:
s = "";
break;
}
{
case FTS_F:
case FTS_D:
case FTS_SL:
case FTS_SLNONE:
break;
if (map)
{
i = 0;
do
{
{
{
}
{
}
}
}
else
{
}
{
else
}
{
{
op = "lchown";
}
else
{
op = "chown";
}
{
{
}
sfprintf(sfstdout, "%s uid:%05d->%05d gid:%05d->%05d %s\n", op, ent->fts_statp->st_uid, uid, ent->fts_statp->st_gid, gid, ent->fts_path);
}
}
break;
case FTS_DC:
break;
case FTS_DNR:
goto anyway;
case FTS_DNX:
goto anyway;
case FTS_NS:
break;
}
if (map)
return error_info.errors != 0;
}