diff --git a/coreutils/chmod.c b/coreutils/chmod.c index 4f37eac..1ce1cb6 100644 --- a/coreutils/chmod.c +++ b/coreutils/chmod.c @@ -2,14 +2,89 @@ #include #include #include +#include #include +#include "make_path.h" +#include "get_stat.h" -//TODO -int main(const int argc, const char **argv) { - unsigned int r_flag = 0; - unsigned int s_flag = 0; +int (*get_stat)(const char *prog_name, const char *path, struct stat *stat_path); +unsigned int r_flag; +unsigned int s_flag; +mode_t mode; + +int change(const char *file) { + struct stat old_file; + if (get_stat("chmod", file, &old_file)) + return 1; + + if (chmod(file, mode) == 0) { + struct stat new_file; + if (get_stat("chmod", file, &new_file)) + return 1; + + if (old_file.st_mode != new_file.st_mode) + return 0; + + if (!s_flag) + fprintf(stderr, "chmod: %s unchanged\n", file); + + return 1; + } + + else + fprintf(stderr, "chmod: unable to chown %s: %s\n", file, strerror(errno)); + + return 0; +} + +int chtree(const char *dst) { + int ret = change(dst); + + struct stat stat_path; + if (get_stat("chmod", dst, &stat_path)) + return 1; + + if (!S_ISDIR(stat_path.st_mode) || !r_flag) + return ret; + + DIR *dir = opendir(dst); + if (dir == NULL) { + if (!s_flag) + fprintf(stderr, "chown: %s: Can`t open directory\n", dst); + return 1; + } + + struct dirent *ep; + while ((ep = readdir(dir)) != NULL) { + if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..")) + continue; + + char *full_path = mu_make_path("chmod", dst, ep->d_name); + if (full_path == NULL) + continue; + + if (chtree(full_path)) + ret = 1; + + free(full_path); + } + + closedir(dir); + return ret; +} + +void parse_mode(const char *arg){ + char *p; + mode = strtol(arg, &p, 8); + if (*p) + return; +} + +int main(int argc, char **argv) { int i; + + get_stat = mu_get_lstat; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') break; @@ -17,16 +92,33 @@ int main(const int argc, const char **argv) { else if (!strcmp(argv[i], "-r")) r_flag = 1; - else if (!strcmp(argv[i], "-s")) + else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "-f")) s_flag = 1; + else if (!strcmp(argv[i], "-H")) + get_stat = mu_get_stat; + else if (!strcmp(argv[i], "--help")) { - printf("chmod [-r recursive] [-s silent] [file1 file2...]\n"); + printf("chmod [-H if a command line argument is a symbolic link] [-r recursive] [-s silent] [file1 file2...]\n"); return 0; } } - return 0; + if (argc - i - 1 <= 0) { + fprintf(stderr, "chmod: missing operand\n"); + return 1; + } + + parse_mode(argv[i]); + argv++; + argc--; + + int ret = 0; + for (; i < argc; i++) + if (chtree(argv[i])) + ret = 1; + + return ret; } diff --git a/coreutils/chown.c b/coreutils/chown.c index a3d48df..41c7cf8 100644 --- a/coreutils/chown.c +++ b/coreutils/chown.c @@ -10,32 +10,19 @@ #include "get_stat.h" unsigned int r_flag; -unsigned int stat_flag; - +int (*get_stat)(const char *prog_name, const char *path, struct stat *stat_path); int (*chown_func)(const char *pathname, uid_t owner, gid_t group); long gid; long uid; -int get_stat(const char *path, struct stat *stat_path) { - if (stat_flag) { - if (mu_get_stat("chown", path, stat_path)) - return 1; - } - - else if (mu_get_lstat("chown", path, stat_path)) - return 1; - - return 0; -} - int change(const char *file) { struct stat old_file; - if (get_stat(file, &old_file)) + if (get_stat("chown", file, &old_file)) return 1; if (chown_func(file, uid, gid) == 0) { struct stat new_file; - if (get_stat(file, &new_file)) + if (get_stat("chown", file, &new_file)) return 1; if (old_file.st_gid != new_file.st_gid || old_file.st_uid != new_file.st_uid) @@ -55,7 +42,7 @@ int cntree(const char *dst) { struct stat stat_path; - if (get_stat(dst, &stat_path)) + if (get_stat("chown", dst, &stat_path)) return 1; if (!S_ISDIR(stat_path.st_mode) || !r_flag) @@ -91,6 +78,7 @@ void get_owner(const char *arg) { unsigned int g_flag = 1; unsigned int u_flag = 1; + if (group == arg) u_flag = 0; @@ -122,6 +110,7 @@ void get_owner(const char *arg) { } int main(const int argc, char **argv) { + get_stat = mu_get_lstat; chown_func = lchown; int i; @@ -134,7 +123,7 @@ int main(const int argc, char **argv) { else if (!strcmp(argv[i], "-H")) { chown_func = chown; - stat_flag = 1; + get_stat = mu_get_stat; } else if (!strcmp(argv[i], "--help")) { diff --git a/coreutils/mknod.c b/coreutils/mknod.c index f365d9c..58be784 100644 --- a/coreutils/mknod.c +++ b/coreutils/mknod.c @@ -8,9 +8,9 @@ #include #include -unsigned int parse_int(const char *str) { +long parse_int(const char *str) { char *ptr = NULL; - unsigned int value = (unsigned int)strtol(str, &ptr, 10); + long value = strtol(str, &ptr, 10); if (*ptr) { fprintf(stderr, "mknod: not a number: %s\n", str); @@ -43,8 +43,8 @@ int main(const int argc, const char **argv) { } } - unsigned int major = 0; - unsigned int minor = 0; + long major = 0; + long minor = 0; dev_t dev = 0; if (argc - i >= 2 && argc - i != 3) {