4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-06 14:30:38 +08:00

* setfacl.c (usage): Standardize usage output. Change return type to

static void.
        (print_version): New function.
        (longopts): Added longopts for all options.
        (main): Accommodate changes in usage function and new version option.
This commit is contained in:
Corinna Vinschen 2002-05-24 14:40:14 +00:00
parent a6247be998
commit f1b53fa94c
2 changed files with 203 additions and 122 deletions

View File

@ -1,3 +1,11 @@
2002-05-23 Joshua Daniel Franklin <joshuadfranklin@yahoo.com>
* setfacl.c (usage): Standardize usage output. Change return type to
static void.
(print_version): New function.
(longopts): Added longopts for all options.
(main): Accommodate changes in usage function and new version option.
2002-05-23 Joshua Daniel Franklin <joshuadfranklin@yahoo.com> 2002-05-23 Joshua Daniel Franklin <joshuadfranklin@yahoo.com>
* getfacl.c (usage): Standardize usage output. Change return type to * getfacl.c (usage): Standardize usage output. Change return type to

View File

@ -37,6 +37,9 @@ details. */
#define ILLEGAL_MODE ((mode_t)0xffffffff) #define ILLEGAL_MODE ((mode_t)0xffffffff)
#endif #endif
static const char version[] = "$Revision$";
static char *prog_name;
typedef enum { typedef enum {
NoAction, NoAction,
Set, Set,
@ -46,8 +49,6 @@ typedef enum {
SetFromFile SetFromFile
} action_t; } action_t;
char *myname;
mode_t getperm (char *in) mode_t getperm (char *in)
{ {
if (isdigit (*in) && !in[1]) if (isdigit (*in) && !in[1])
@ -267,118 +268,157 @@ setfacl (action_t action, char *path, aclent_t *acls, int cnt)
if (action == Set) if (action == Set)
{ {
if (acl (path, SETACL, cnt, acls)) if (acl (path, SETACL, cnt, acls))
perror (myname); perror (prog_name);
return; return;
} }
if ((lcnt = acl (path, GETACL, MAX_ACL_ENTRIES, lacl)) < 0 if ((lcnt = acl (path, GETACL, MAX_ACL_ENTRIES, lacl)) < 0
|| (lcnt = modacl (lacl, lcnt, acls, cnt)) < 0 || (lcnt = modacl (lacl, lcnt, acls, cnt)) < 0
|| (lcnt = acl (path, SETACL, lcnt, lacl)) < 0) || (lcnt = acl (path, SETACL, lcnt, lacl)) < 0)
perror (myname); perror (prog_name);
} }
#define pn(txt) fprintf (fp, txt "\n", myname) static void
#define p(txt) fprintf (fp, txt "\n") usage (FILE * stream)
int
usage (int help)
{ {
FILE *fp = help ? stdout : stderr; fprintf (stream, ""
"Usage: %s [-r] (-f ACL_FILE | -s acl_entries) FILE...\n"
pn ("usage: %s [-r] -s acl_entries file..."); " %s [-r] ([-d acl_entries] [-m acl_entries]) FILE...\n"
pn (" %s [-r] -md acl_entries file..."); "\n"
pn (" %s [-r] -f acl_file file..."); "Modify file and directory access control lists (ACLs)\n"
if (!help) "\n"
pn ("Try `%s --help' for more information."); " -d, --delete delete one or more specified ACL entries\n"
" -f, --file set ACL entries for FILE to ACL entries read\n"
" from a ACL_FILE\n"
" -m, --modify modify one or more specified ACL entries\n"
" -r, --replace replace mask entry with maximum permissions\n"
" needed for the file group class\n"
" -s, --substitute substitute specified ACL entries for the\n"
" ACL of FILE\n"
" -h, --help output usage information and exit\n"
" -v, --version output version information and exit\n"
"\n"
"At least one of (-d, -f, -m, -s) must be specified\n"
"\n"
"", prog_name, prog_name);
if (stream == stdout)
{
printf(""
" Acl_entries are one or more comma-separated ACL entries \n"
" from the following list:\n"
"\n"
" u[ser]::perm\n"
" u[ser]:uid:perm\n"
" g[roup]::perm\n"
" g[roup]:gid:perm\n"
" m[ask]::perm\n"
" o[ther]::perm\n"
"\n"
" Default entries are like the above with the additional\n"
" default identifier. For example: \n"
"\n"
" d[efault]:u[ser]:uid:perm\n"
"\n"
" `perm' is either a 3-char permissions string in the form\n"
" \"rwx\" with the character - for no permission\n"
" or it is the octal representation of the permissions, a\n"
" value from 0 (equivalent to \"---\") to 7 (\"rwx\").\n"
" `uid' is a user name or a numerical uid.\n"
" `gid' is a group name or a numerical gid.\n"
"\n"
"\n"
"For each file given as parameter, %s will either replace its\n"
"complete ACL (-s, -f), or it will add, modify, or delete ACL\n"
"entries.\n"
"\n"
"The following options are supported:\n"
"\n"
"-d Delete one or more specified entries from the file's ACL.\n"
" The owner, group and others entries must not be deleted.\n"
" Acl_entries to be deleted should be specified without\n"
" permissions, as in the following list:\n"
"\n"
" u[ser]:uid\n"
" g[roup]:gid\n"
" d[efault]:u[ser]:uid\n"
" d[efault]:g[roup]:gid\n"
" d[efault]:m[ask]:\n"
" d[efault]:o[ther]:\n"
"\n"
"-f Take the Acl_entries from ACL_FILE one per line. Whitespace\n"
" characters are ignored, and the character \"#\" may be used\n"
" to start a comment. The special filename \"-\" indicates\n"
" reading from stdin.\n"
" Required entries are\n"
" - One user entry for the owner of the file.\n"
" - One group entry for the group of the file.\n"
" - One other entry.\n"
" If additional user and group entries are given:\n"
" - A mask entry for the file group class of the file.\n"
" - No duplicate user or group entries with the same uid/gid.\n"
" If it is a directory:\n"
" - One default user entry for the owner of the file.\n"
" - One default group entry for the group of the file.\n"
" - One default mask entry for the file group class.\n"
" - One default other entry.\n"
"\n"
"-m Add or modify one or more specified ACL entries.\n"
" Acl_entries is a comma-separated list of entries from the \n"
" same list as above.\n"
"\n"
"-r Causes the permissions specified in the mask entry to be\n"
" ignored and replaced by the maximum permissions needed for\n"
" the file group class.\n"
"\n"
"-s Like -f, but substitute the file's ACL with Acl_entries\n"
" specified in a comma-separated list on the command line.\n"
"\n"
"While the -d and -m options may be used in the same command, the\n"
"-f and -s options may be used only exclusively.\n"
"\n"
"Directories may contain default ACL entries. Files created\n"
"in a directory that contains default ACL entries will have\n"
"permissions according to the combination of the current umask,\n"
"the explicit permissions requested and the default ACL entries\n"
"Note: Under Cygwin, the default ACL entries are not taken into\n"
"account currently.\n", prog_name);
}
else else
{ fprintf(stream, "Try `%s --help' for more information.", prog_name);
p ("");
p ("Modify file and directory access control lists (ACLs)");
p ("");
pn ("For each file given as parameter, %s will either replace its");
p ("complete ACL (-s, -f)), or it will add, modify, or delete ACL");
p ("entries.");
p ("");
p ("The following options are supported:");
p ("");
p ("-s Substitute the ACL of the file by the entries specified on");
p (" the command line. Required entries are");
p (" - One user entry for the owner of the file.");
p (" - One group entry for the group of the file.");
p (" - One other entry.");
p (" If additional user and group entries are given:");
p (" - A mask entry for the file group class of the file.");
p (" - No duplicate user or group entries with the same uid/gid.");
p (" If it is a directory:");
p (" - One default user entry for the owner of the file.");
p (" - One default group entry for the group of the file.");
p (" - One default mask entry for the file group class of the file.");
p (" - One default other entry.");
p ("");
p (" Acl_entries are one or more comma-separated ACL entries from");
p (" the following list:");
p ("");
p (" u[ser]::perm");
p (" u[ser]:uid:perm");
p (" g[roup]::perm");
p (" g[roup]:gid:perm");
p (" m[ask]::perm");
p (" o[ther]::perm");
p ("");
p (" Default entries are like the above with the trailing default");
p (" identifier. E.g.");
p ("");
p (" d[efault]:u[ser]:uid:perm");
p ("");
p (" `perm' is either a 3-char permissions string in the form");
p (" \"rwx\" with the character - for not setting a permission");
p (" or it is the octal representation of the permissions, a");
p (" value from 0 (equivalent to \"---\") to 7 (\"rwx\").");
p (" `uid' is a user name or a numerical uid.");
p (" `gid' is a group name or a numerical gid.");
p ("");
p ("-f Like -s but take the ACL entries from `acl_file'. Acl_entries");
p (" are given one per line. Whitespace characters are ignored,");
p (" the character \"#\" may be used to start a comment. The");
p (" special filename \"-\" indicates reading from stdin.");
p ("");
p ("-m Add or modify one or more specified ACL entries. Acl_entries");
p (" is a comma-separated list of entries from the same list as");
p (" above.");
p ("");
p ("-d Delete one or more specified entries from the file's ACL.");
p (" The owner, group and others entries must not be deleted");
p (" Acl_entries are one or more comma-separated ACL entries");
p (" without permissions, taken from the following list:");
p ("");
p (" u[ser]:uid");
p (" g[roup]:gid");
p (" d[efault]:u[ser]:uid");
p (" d[efault]:g[roup]:gid");
p (" d[efault]:m[ask]:");
p (" d[efault]:o[ther]:");
p ("");
p ("-r Causes the permissions specified in the mask entry to be");
p (" ignored and replaced by the maximum permissions needed for");
p (" the file group class.");
p ("");
p ("While the -m and -d options may be used in the same command, the");
p ("-s and -f options may be used only exclusively.");
p ("");
p ("Directories may contain default ACL entries. Files created");
p ("in a directory that contains default ACL entries will have");
p ("permissions according to the combination of the current umask,");
p ("the explicit permissions requested and the default ACL entries");
p ("Note: Under Cygwin, the default ACL entries are not taken into");
p ("account currently.");
}
return 1;
} }
struct option longopts[] = { struct option longopts[] = {
{"delete", required_argument, NULL, 'd'},
{"file", required_argument, NULL, 'f'},
{"modify", required_argument, NULL, 'm'},
{"replace", no_argument, NULL, 'r'},
{"substitute", required_argument, NULL, 's'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'},
{0, no_argument, NULL, 0} {0, no_argument, NULL, 0}
}; };
static void
print_version ()
{
const char *v = strchr (version, ':');
int len;
if (!v)
{
v = "?";
len = 1;
}
else
{
v += 2;
len = strchr (v, ' ') - v;
}
printf ("\
setfacl (cygwin) %.*s\n\
ACL Modification Utility\n\
Copyright 2000, 2001, 2002 Red Hat, Inc.\n\
Compiled on %s", len, v, __DATE__);
}
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
@ -390,9 +430,16 @@ main (int argc, char **argv)
aclent_t acls[MAX_ACL_ENTRIES]; aclent_t acls[MAX_ACL_ENTRIES];
int aclidx = 0; int aclidx = 0;
myname = argv[0]; prog_name = strrchr (argv[0], '/');
if (prog_name == NULL)
prog_name = strrchr (argv[0], '\\');
if (prog_name == NULL)
prog_name = argv[0];
else
prog_name++;
memset (acls, 0, sizeof acls); memset (acls, 0, sizeof acls);
while ((c = getopt_long (argc, argv, "d:f:m:rs:", longopts, NULL)) != EOF) while ((c = getopt_long (argc, argv, "d:f:hm:rs:v", longopts, NULL)) != EOF)
switch (c) switch (c)
{ {
case 'd': case 'd':
@ -401,10 +448,13 @@ main (int argc, char **argv)
else if (action == Modify) else if (action == Modify)
action = ModNDel; action = ModNDel;
else else
return usage (0); {
usage (stderr);
return 1;
}
if (! getaclentries (Delete, optarg, acls, &aclidx)) if (! getaclentries (Delete, optarg, acls, &aclidx))
{ {
fprintf (stderr, "%s: illegal acl entries\n", myname); fprintf (stderr, "%s: illegal acl entries\n", prog_name);
return 2; return 2;
} }
break; break;
@ -412,23 +462,32 @@ main (int argc, char **argv)
if (action == NoAction) if (action == NoAction)
action = Set; action = Set;
else else
return usage (0); {
usage (stderr);
return 1;
}
if (! getaclentries (SetFromFile, optarg, acls, &aclidx)) if (! getaclentries (SetFromFile, optarg, acls, &aclidx))
{ {
fprintf (stderr, "%s: illegal acl entries\n", myname); fprintf (stderr, "%s: illegal acl entries\n", prog_name);
return 2; return 2;
} }
break; break;
case 'h':
usage (stdout);
return 0;
case 'm': case 'm':
if (action == NoAction) if (action == NoAction)
action = Modify; action = Modify;
else if (action == Delete) else if (action == Delete)
action = ModNDel; action = ModNDel;
else else
return usage (0); {
usage (stderr);
return 1;
}
if (! getaclentries (Modify, optarg, acls, &aclidx)) if (! getaclentries (Modify, optarg, acls, &aclidx))
{ {
fprintf (stderr, "%s: illegal acl entries\n", myname); fprintf (stderr, "%s: illegal acl entries\n", prog_name);
return 2; return 2;
} }
break; break;
@ -436,55 +495,69 @@ main (int argc, char **argv)
if (!ropt) if (!ropt)
ropt = 1; ropt = 1;
else else
return usage (0); {
usage (stderr);
return 1;
}
break; break;
case 's': case 's':
if (action == NoAction) if (action == NoAction)
action = Set; action = Set;
else else
return usage (0); {
usage (stderr);
return 1;
}
break; break;
if (! getaclentries (Set, optarg, acls, &aclidx)) if (! getaclentries (Set, optarg, acls, &aclidx))
{ {
fprintf (stderr, "%s: illegal acl entries\n", myname); fprintf (stderr, "%s: illegal acl entries\n", prog_name);
return 2; return 2;
} }
break; break;
case 'h': case 'v':
return usage (1); print_version ();
return 0;
default: default:
return usage (0); usage (stderr);
return 1;
} }
if (action == NoAction) if (action == NoAction)
return usage (0); {
usage (stderr);
return 1;
}
if (optind > argc - 1) if (optind > argc - 1)
return usage (0); {
usage (stderr);
return 1;
}
if (action == Set) if (action == Set)
switch (aclcheck (acls, aclidx, NULL)) switch (aclcheck (acls, aclidx, NULL))
{ {
case GRP_ERROR: case GRP_ERROR:
fprintf (stderr, "%s: more than one group entry.\n", myname); fprintf (stderr, "%s: more than one group entry.\n", prog_name);
return 2; return 2;
case USER_ERROR: case USER_ERROR:
fprintf (stderr, "%s: more than one user entry.\n", myname); fprintf (stderr, "%s: more than one user entry.\n", prog_name);
return 2; return 2;
case CLASS_ERROR: case CLASS_ERROR:
fprintf (stderr, "%s: more than one mask entry.\n", myname); fprintf (stderr, "%s: more than one mask entry.\n", prog_name);
return 2; return 2;
case OTHER_ERROR: case OTHER_ERROR:
fprintf (stderr, "%s: more than one other entry.\n", myname); fprintf (stderr, "%s: more than one other entry.\n", prog_name);
return 2; return 2;
case DUPLICATE_ERROR: case DUPLICATE_ERROR:
fprintf (stderr, "%s: duplicate additional user or group.\n", myname); fprintf (stderr, "%s: duplicate additional user or group.\n", prog_name);
return 2; return 2;
case ENTRY_ERROR: case ENTRY_ERROR:
fprintf (stderr, "%s: invalid entry type.\n", myname); fprintf (stderr, "%s: invalid entry type.\n", prog_name);
return 2; return 2;
case MISS_ERROR: case MISS_ERROR:
fprintf (stderr, "%s: missing entries.\n", myname); fprintf (stderr, "%s: missing entries.\n", prog_name);
return 2; return 2;
case MEM_ERROR: case MEM_ERROR:
fprintf (stderr, "%s: out of memory.\n", myname); fprintf (stderr, "%s: out of memory.\n", prog_name);
return 2; return 2;
default: default:
break; break;