1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <sys/types.h> 5#include <dirent.h> 6#include <errno.h> 7#include <pwd.h> 8#include <grp.h> 9 10#include <unistd.h> 11#include <time.h> 12 13int chown_main(int argc, char **argv) 14{ 15 int i; 16 17 if (argc < 3) { 18 fprintf(stderr, "Usage: chown <USER>[:GROUP] <FILE1> [FILE2] ...\n"); 19 return 10; 20 } 21 22 // Copy argv[1] to 'user' so we can truncate it at the period 23 // if a group id specified. 24 char user[32]; 25 char *group = NULL; 26 strncpy(user, argv[1], sizeof(user)); 27 if ((group = strchr(user, ':')) != NULL) { 28 *group++ = '\0'; 29 } else if ((group = strchr(user, '.')) != NULL) { 30 *group++ = '\0'; 31 } 32 33 // Lookup uid (and gid if specified) 34 struct passwd *pw; 35 struct group *grp = NULL; 36 uid_t uid; 37 gid_t gid = -1; // passing -1 to chown preserves current group 38 39 pw = getpwnam(user); 40 if (pw != NULL) { 41 uid = pw->pw_uid; 42 } else { 43 char* endptr; 44 uid = (int) strtoul(user, &endptr, 0); 45 if (endptr == user) { // no conversion 46 fprintf(stderr, "No such user '%s'\n", user); 47 return 10; 48 } 49 } 50 51 if (group != NULL) { 52 grp = getgrnam(group); 53 if (grp != NULL) { 54 gid = grp->gr_gid; 55 } else { 56 char* endptr; 57 gid = (int) strtoul(group, &endptr, 0); 58 if (endptr == group) { // no conversion 59 fprintf(stderr, "No such group '%s'\n", group); 60 return 10; 61 } 62 } 63 } 64 65 for (i = 2; i < argc; i++) { 66 if (chown(argv[i], uid, gid) < 0) { 67 fprintf(stderr, "Unable to chown %s: %s\n", argv[i], strerror(errno)); 68 return 10; 69 } 70 } 71 72 return 0; 73} 74