chgrp.c revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1992-2007 AT&T Knowledge Ventures *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Knowledge Ventures *
* *
* 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) 2006-10-11 $\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[] =
"[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 the symbolic links on systems that"
" support this.]"
"[m:map?The first operand is interpreted as a file that contains a map"
" of \afrom_uid:from_gid to_uid:to_gid\a pairs. Ownership of files"
" matching the \afrom\a part of any pair is changed to the corresponding"
" \ato\a part of the pair. The process stops at the first match for"
" each file. Unmatched files are silently ignored.]"
"[n:show?Show actions but don't execute.]"
"[r:reference?Omit the explicit ownership operand and use the ownership of"
" \afile\a instead.]:[file]"
"[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.h>
#if defined(__STDPP__directive) && defined(__STDPP__hide)
#else
#endif
{
int id; /* id */
int uid; /* id maps to this uid */
int gid; /* id maps to this gid */
} Map_t;
#define NOID (-1)
#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;
char* z;
char buf[64];
while (isspace(*s))
s++;
if (n)
{
if ((n = t++ - s) >= sizeof(buf))
n = sizeof(buf) - 1;
while (isspace(*t))
t++;
}
{
if (*s)
{
{
n = (int)strtol(s, &z, 0);
if (*z)
}
*uid = n;
}
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)
}
*gid = n;
}
if (e)
*e = t;
}
int
{
register int options = 0;
register char* s;
register Map_t* m;
int flags;
int uid;
int gid;
char* op;
char* usage;
else
{
}
else
for (;;)
{
{
case 'c':
case 'v':
options |= OPT_VERBOSE;
continue;
case 'f':
continue;
case 'l':
options |= OPT_LCHOWN;
continue;
case 'm':
continue;
case 'n':
continue;
case 'r':
continue;
case 'H':
continue;
case 'L':
continue;
case 'P':
flags |= FTS_PHYSICAL;
continue;
case 'R':
continue;
case 'X':
continue;
case ':':
continue;
case '?':
break;
}
break;
}
s = *argv;
if (map)
{
char* t;
int nuid;
int ngid;
if (streq(s, "-"))
{
{
{
}
{
}
else
}
{
{
}
else
}
}
}
{
}
{
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:
if (map)
{
{
}
{
}
}
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_accpath);
}
}
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;
}