diff options
Diffstat (limited to 'package/toolbox/src/src/chown.c')
-rw-r--r-- | package/toolbox/src/src/chown.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/package/toolbox/src/src/chown.c b/package/toolbox/src/src/chown.c new file mode 100644 index 000000000..d02721718 --- /dev/null +++ b/package/toolbox/src/src/chown.c @@ -0,0 +1,73 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <dirent.h> +#include <errno.h> +#include <pwd.h> +#include <grp.h> + +#include <unistd.h> +#include <time.h> + +int main(int argc, char **argv) +{ + int i; + + if (argc < 3) { + fprintf(stderr, "Usage: chown <USER>[:GROUP] <FILE1> [FILE2] ...\n"); + return 10; + } + + // Copy argv[1] to 'user' so we can truncate it at the period + // if a group id specified. + char user[32]; + char *group = NULL; + strncpy(user, argv[1], sizeof(user)); + if ((group = strchr(user, ':')) != NULL) { + *group++ = '\0'; + } else if ((group = strchr(user, '.')) != NULL) { + *group++ = '\0'; + } + + // Lookup uid (and gid if specified) + struct passwd *pw; + struct group *grp = NULL; + uid_t uid; + gid_t gid = -1; // passing -1 to chown preserves current group + + pw = getpwnam(user); + if (pw != NULL) { + uid = pw->pw_uid; + } else { + char* endptr; + uid = (int) strtoul(user, &endptr, 0); + if (endptr == user) { // no conversion + fprintf(stderr, "No such user '%s'\n", user); + return 10; + } + } + + if (group != NULL) { + grp = getgrnam(group); + if (grp != NULL) { + gid = grp->gr_gid; + } else { + char* endptr; + gid = (int) strtoul(group, &endptr, 0); + if (endptr == group) { // no conversion + fprintf(stderr, "No such group '%s'\n", group); + return 10; + } + } + } + + for (i = 2; i < argc; i++) { + if (chown(argv[i], uid, gid) < 0) { + fprintf(stderr, "Unable to chown %s: %s\n", argv[i], strerror(errno)); + return 10; + } + } + + return 0; +} |