#include <stdlib.h>
#include <stdio.h>
#include <pwd.h>
#include <grp.h>
#include <locale.h>
#include <sys/acl.h>
#include <errno.h>
static char *pruname(uid_t);
static char *prgname(gid_t);
static char *display(int);
static void usage();
int
main(int argc, char *argv[])
{
int c;
int aflag = 0;
int dflag = 0;
int errflag = 0;
int savecnt;
int aclcnt;
int mask = 0;
aclent_t *aclp;
aclent_t *tp;
char *permp;
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
if (argc < 2)
usage();
while ((c = getopt(argc, argv, "ad")) != EOF) {
switch (c) {
case 'a':
aflag++;
break;
case 'd':
dflag++;
break;
case '?':
errflag++;
break;
}
}
if (errflag)
usage();
if (optind >= argc)
usage();
for (; optind < argc; optind++) {
register char *filep;
filep = argv[optind];
errno = 0;
if ((aclcnt = acl(filep, GETACLCNT, 0, NULL)) < 0) {
if (errno == ENOSYS) {
(void) fprintf(stderr,
gettext("File system doesn't support "
"aclent_t style ACL's.\n"
"See acl(7) for more information on "
"POSIX-draft ACL support.\n"));
exit(2);
}
perror(filep);
exit(2);
}
if (aclcnt < MIN_ACL_ENTRIES) {
(void) fprintf(stderr,
gettext("%d: acl count too small from %s\n"),
aclcnt, filep);
exit(2);
}
if ((aclp = (aclent_t *)malloc(sizeof (aclent_t) * aclcnt))
== NULL) {
(void) fprintf(stderr,
gettext("Insufficient memory\n"));
exit(1);
}
errno = 0;
if (acl(filep, GETACL, aclcnt, aclp) < 0) {
perror(filep);
exit(2);
}
(void) printf("\n# file: %s\n", filep);
savecnt = aclcnt;
for (tp = aclp; aclcnt--; tp++) {
if (tp->a_type == USER_OBJ)
(void) printf("# owner: %s\n",
pruname(tp->a_id));
if (tp->a_type == GROUP_OBJ)
(void) printf("# group: %s\n",
prgname(tp->a_id));
if (tp->a_type == CLASS_OBJ)
mask = tp->a_perm;
}
aclcnt = savecnt;
for (tp = aclp; aclcnt--; tp++) {
switch (tp->a_type) {
case USER:
if (!dflag) {
permp = display(tp->a_perm);
(void) printf("user:%s:%s\t\t",
pruname(tp->a_id), permp);
free(permp);
permp = display(tp->a_perm & mask);
(void) printf(
"#effective:%s\n", permp);
free(permp);
}
break;
case USER_OBJ:
if (!dflag) {
permp = display(tp->a_perm);
(void) printf("user::%s\n", permp);
free(permp);
}
break;
case GROUP:
if (!dflag) {
permp = display(tp->a_perm);
(void) printf("group:%s:%s\t\t",
prgname(tp->a_id), permp);
free(permp);
permp = display(tp->a_perm & mask);
(void) printf(
"#effective:%s\n", permp);
free(permp);
}
break;
case GROUP_OBJ:
if (!dflag) {
permp = display(tp->a_perm);
(void) printf("group::%s\t\t", permp);
free(permp);
permp = display(tp->a_perm & mask);
(void) printf(
"#effective:%s\n", permp);
free(permp);
}
break;
case CLASS_OBJ:
if (!dflag) {
permp = display(tp->a_perm);
(void) printf("mask:%s\n", permp);
free(permp);
}
break;
case OTHER_OBJ:
if (!dflag) {
permp = display(tp->a_perm);
(void) printf("other:%s\n", permp);
free(permp);
}
break;
case DEF_USER:
if (!aflag) {
permp = display(tp->a_perm);
(void) printf("default:user:%s:%s\n",
pruname(tp->a_id), permp);
free(permp);
}
break;
case DEF_USER_OBJ:
if (!aflag) {
permp = display(tp->a_perm);
(void) printf("default:user::%s\n",
permp);
free(permp);
}
break;
case DEF_GROUP:
if (!aflag) {
permp = display(tp->a_perm);
(void) printf("default:group:%s:%s\n",
prgname(tp->a_id), permp);
free(permp);
}
break;
case DEF_GROUP_OBJ:
if (!aflag) {
permp = display(tp->a_perm);
(void) printf("default:group::%s\n",
permp);
free(permp);
}
break;
case DEF_CLASS_OBJ:
if (!aflag) {
permp = display(tp->a_perm);
(void) printf("default:mask:%s\n",
permp);
free(permp);
}
break;
case DEF_OTHER_OBJ:
if (!aflag) {
permp = display(tp->a_perm);
(void) printf("default:other:%s\n",
permp);
free(permp);
}
break;
default:
(void) fprintf(stderr,
gettext("unrecognized entry\n"));
break;
}
}
free(aclp);
}
return (0);
}
static char *
display(int perm)
{
char *buf;
buf = malloc(4);
if (buf == NULL) {
(void) fprintf(stderr, gettext("Insufficient memory\n"));
exit(1);
}
if (perm & 4)
buf[0] = 'r';
else
buf[0] = '-';
if (perm & 2)
buf[1] = 'w';
else
buf[1] = '-';
if (perm & 1)
buf[2] = 'x';
else
buf[2] = '-';
buf[3] = '\0';
return (buf);
}
static char *
pruname(uid_t uid)
{
struct passwd *passwdp;
static char uidp[10];
passwdp = getpwuid(uid);
if (passwdp == (struct passwd *)NULL) {
(void) sprintf(uidp, "%u", uid);
return (uidp);
} else
return (passwdp->pw_name);
}
static char *
prgname(gid_t gid)
{
struct group *groupp;
static char gidp[10];
groupp = getgrgid(gid);
if (groupp == (struct group *)NULL) {
(void) sprintf(gidp, "%u", gid);
return (gidp);
} else
return (groupp->gr_name);
}
static void
usage()
{
(void) fprintf(stderr,
gettext("usage: getfacl [-ad] file ... \n"));
exit(1);
}