return rc;
}
-#include <pwd.h>
-#include <grp.h>
-#include <mntent.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <ctype.h>
-
-static int rmtacl_notify(int ops)
-{
- FILE *fp;
- struct mntent *mnt;
- int found = 0, fd = 0, rc = 0;
-
- fp = setmntent(MOUNTED, "r");
- if (fp == NULL) {
- rc = -errno;
- llapi_error(LLAPI_MSG_ERROR, rc,
- "error setmntent(%s)", MOUNTED);
- return rc;
- }
-
- while (1) {
- mnt = getmntent(fp);
- if (!mnt)
- break;
-
- if (!llapi_is_lustre_mnt(mnt))
- continue;
-
- fd = open(mnt->mnt_dir, O_RDONLY | O_DIRECTORY);
- if (fd < 0) {
- rc = -errno;
- llapi_error(LLAPI_MSG_ERROR, rc,
- "Can't open '%s'", mnt->mnt_dir);
- goto out;
- }
-
- rc = ioctl(fd, LL_IOC_RMTACL, ops);
- close(fd);
- if (rc < 0) {
- rc = -errno;
- llapi_error(LLAPI_MSG_ERROR, rc,
- "ioctl RMTACL on '%s' err %d",
- mnt->mnt_dir, rc);
- goto out;
- }
-
- found++;
- }
-
-out:
- endmntent(fp);
- return ((rc != 0) ? rc : found);
-}
-
-static char *next_token(char *p, int div)
-{
- if (p == NULL)
- return NULL;
-
- if (div)
- while (*p && *p != ':' && !isspace(*p))
- p++;
- else
- while (*p == ':' || isspace(*p))
- p++;
-
- return *p ? p : NULL;
-}
-
-static int rmtacl_name2id(char *name, int is_user)
-{
- if (is_user) {
- struct passwd *pw;
-
- pw = getpwnam(name);
- if (pw == NULL)
- return INVALID_ID;
- else
- return (int)(pw->pw_uid);
- } else {
- struct group *gr;
-
- gr = getgrnam(name);
- if (gr == NULL)
- return INVALID_ID;
- else
- return (int)(gr->gr_gid);
- }
-}
-
-static int isodigit(int c)
-{
- return (c >= '0' && c <= '7') ? 1 : 0;
-}
-
-/*
- * Whether the name is just digits string (uid/gid) already or not.
- * Return value:
- * 1: str is id
- * 0: str is not id
- */
-static int str_is_id(char *str)
-{
- if (str == NULL)
- return 0;
-
- if (*str == '0') {
- str++;
- if (*str == 'x' || *str == 'X') { /* for Hex. */
- if (!isxdigit(*(++str)))
- return 0;
-
- while (isxdigit(*(++str)));
- } else if (isodigit(*str)) { /* for Oct. */
- while (isodigit(*(++str)));
- }
- } else if (isdigit(*str)) { /* for Dec. */
- while (isdigit(*(++str)));
- }
-
- return (*str == 0) ? 1 : 0;
-}
-
-typedef struct {
- char *name;
- int length;
- int is_user;
- int next_token;
-} rmtacl_name_t;
-
-#define RMTACL_OPTNAME(name) name, sizeof(name) - 1
-
-static rmtacl_name_t rmtacl_namelist[] = {
- { RMTACL_OPTNAME("user:"), 1, 0 },
- { RMTACL_OPTNAME("group:"), 0, 0 },
- { RMTACL_OPTNAME("default:user:"), 1, 0 },
- { RMTACL_OPTNAME("default:group:"), 0, 0 },
- /* for --tabular option */
- { RMTACL_OPTNAME("user"), 1, 1 },
- { RMTACL_OPTNAME("group"), 0, 1 },
- { 0 }
-};
-
-static int rgetfacl_output(char *str)
-{
- char *start = NULL, *end = NULL;
- int is_user = 0, n, id;
- char c;
- rmtacl_name_t *rn;
-
- if (str == NULL)
- return -1;
-
- for (rn = rmtacl_namelist; rn->name; rn++) {
- if(strncmp(str, rn->name, rn->length) == 0) {
- if (!rn->next_token)
- start = str + rn->length;
- else
- start = next_token(str + rn->length, 0);
- is_user = rn->is_user;
- break;
- }
- }
-
- end = next_token(start, 1);
- if (end == NULL || start == end) {
- n = printf("%s", str);
- return n;
- }
-
- c = *end;
- *end = 0;
- id = rmtacl_name2id(start, is_user);
- if (id == INVALID_ID) {
- if (str_is_id(start)) {
- *end = c;
- n = printf("%s", str);
- } else
- return -1;
- } else if ((id == NOBODY_UID && is_user) ||
- (id == NOBODY_GID && !is_user)) {
- *end = c;
- n = printf("%s", str);
- } else {
- *end = c;
- *start = 0;
- n = printf("%s%d%s", str, id, end);
- }
- return n;
-}
-
-static int child_status(int status)
-{
- return WIFEXITED(status) ? WEXITSTATUS(status) : -1;
-}
-
-static int do_rmtacl(int argc, char *argv[], int ops, int (output_func)(char *))
-{
- pid_t pid = 0;
- int fd[2], status, rc;
- FILE *fp;
- char buf[PIPE_BUF];
-
- if (output_func) {
- if (pipe(fd) < 0) {
- rc = -errno;
- llapi_error(LLAPI_MSG_ERROR, rc, "Can't create pipe");
- return rc;
- }
-
- pid = fork();
- if (pid < 0) {
- rc = -errno;
- llapi_error(LLAPI_MSG_ERROR, rc, "Can't fork");
- close(fd[0]);
- close(fd[1]);
- return rc;
- } else if (!pid) {
- /* child process redirects its output. */
- close(fd[0]);
- close(1);
- if (dup2(fd[1], 1) < 0) {
- rc = -errno;
- llapi_error(LLAPI_MSG_ERROR, rc,
- "Can't dup2 %d", fd[1]);
- close(fd[1]);
- return rc;
- }
- } else {
- close(fd[1]);
- }
- }
-
- if (!pid) {
- status = rmtacl_notify(ops);
- if (status < 0)
- return -errno;
-
- exit(execvp(argv[0], argv));
- }
-
- /* the following is parent process */
- fp = fdopen(fd[0], "r");
- if (fp == NULL) {
- rc = -errno;
- llapi_error(LLAPI_MSG_ERROR, rc, "fdopen %d failed", fd[0]);
- kill(pid, SIGKILL);
- close(fd[0]);
- return rc;
- }
-
- while (fgets(buf, PIPE_BUF, fp) != NULL) {
- if (output_func(buf) < 0)
- fprintf(stderr, "WARNING: unexpected error!\n[%s]\n",
- buf);
- }
- fclose(fp);
- close(fd[0]);
-
- if (waitpid(pid, &status, 0) < 0) {
- rc = -errno;
- llapi_error(LLAPI_MSG_ERROR, rc, "waitpid %d failed", pid);
- return rc;
- }
-
- return child_status(status);
-}
-
-int llapi_lsetfacl(int argc, char *argv[])
-{
- return do_rmtacl(argc, argv, RMT_LSETFACL, NULL);
-}
-
-int llapi_lgetfacl(int argc, char *argv[])
-{
- return do_rmtacl(argc, argv, RMT_LGETFACL, NULL);
-}
-
-int llapi_rsetfacl(int argc, char *argv[])
-{
- return do_rmtacl(argc, argv, RMT_RSETFACL, NULL);
-}
-
-int llapi_rgetfacl(int argc, char *argv[])
-{
- return do_rmtacl(argc, argv, RMT_RGETFACL, rgetfacl_output);
-}
-
-int llapi_cp(int argc, char *argv[])
-{
- int rc;
-
- rc = rmtacl_notify(RMT_RSETFACL);
- if (rc < 0)
- return rc;
-
- exit(execvp(argv[0], argv));
-}
-
-int llapi_ls(int argc, char *argv[])
-{
- int rc;
-
- rc = rmtacl_notify(RMT_LGETFACL);
- if (rc < 0)
- return rc;
-
- exit(execvp(argv[0], argv));
-}
-
/* Print mdtname 'name' into 'buf' using 'format'. Add -MDT0000 if needed.
* format must have %s%s, buf must be > 16
* Eg: if name = "lustre-MDT0000", "lustre", or "lustre-MDT0000_UUID"