diff --git a/coreutils/chown.c b/coreutils/chown.c new file mode 100644 index 0000000..a317a62 --- /dev/null +++ b/coreutils/chown.c @@ -0,0 +1,96 @@ +//TODO + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int (*chown_func)(const char *pathname, uid_t owner, gid_t group); +long gid; +long uid; + +int cntree(const char *dst) { + if (chown_func(dst, uid, gid) == 0) + puts("changed"); + + return 0; +} + +void get_owner(const char *arg) { + char *group = strchr(arg, ':'); + + unsigned int g_flag = 1; + unsigned int u_flag = 1; + if (group == arg) + u_flag = 0; + + else if (!group) + g_flag = 0; + + if (g_flag) { + group[0] = '\0'; + group++; + + struct group *grp = getgrnam(group); + if (!grp) { + fprintf(stderr, "chown: invalid group: %s\n", group); + exit(1); + } + + gid = grp->gr_gid; + } + + if (u_flag) { + struct passwd *pwd = getpwnam(arg); + if (!pwd) { + fprintf(stderr, "chown: invalid user: %s\n", arg); + exit(1); + } + + uid = pwd->pw_gid; + } +} + +int main(const int argc, char **argv) { + chown_func = lchown; + + int i; + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-') + break; + + else if (!strcmp(argv[i], "-H")) + chown_func = chown; + + else if (!strcmp(argv[i], "--help")) { + printf("chown [-H (if a command line argument is a symbolic link)] [owner]:[group] [file file2...]\n"); + return 0; + } + } + + if (argc - i == 0) { + fprintf(stderr, "chown: missing operand\n"); + return 1; + } + + gid = -1; + uid = -1; + get_owner(argv[i++]); + + if (argc - i == 0) { + fprintf(stderr, "chown: missing operand\n"); + return 1; + } + + int ret = 0; + for (; i < argc; i++) + if (cntree(argv[i])) + ret = 1; + + return ret; +}