#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 chown_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; }