diff --git a/coreutils/chmod.c b/coreutils/chmod.c index 4e571b7..7492f4d 100644 --- a/coreutils/chmod.c +++ b/coreutils/chmod.c @@ -11,13 +11,13 @@ 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) { +int change(const char *file, const char *mode_arg) { struct stat old_file; if (get_stat("chmod", file, &old_file)) return 1; + mode_t mode = mu_parse_mode(mode_arg, old_file.st_mode); if (chmod(file, mode) == 0) { struct stat new_file; if (get_stat("chmod", file, &new_file)) @@ -38,8 +38,8 @@ int change(const char *file) { return 0; } -int chtree(const char *dst) { - int ret = change(dst); +int chtree(const char *dst, const char *mode_arg) { + int ret = change(dst, mode_arg); struct stat stat_path; if (get_stat("chmod", dst, &stat_path)) @@ -64,7 +64,7 @@ int chtree(const char *dst) { if (full_path == NULL) continue; - if (chtree(full_path)) + if (chtree(full_path, mode_arg)) ret = 1; free(full_path); @@ -105,13 +105,13 @@ int main(int argc, char **argv) { return 1; } - mode = mu_parse_mode(argv[i]); + char *mode_arg = argv[i]; argv++; argc--; int ret = 0; for (; i < argc; i++) - if (chtree(argv[i])) + if (chtree(argv[i], mode_arg)) ret = 1; return ret; diff --git a/coreutils/mknod.c b/coreutils/mknod.c index 7e9f26d..5e803b5 100644 --- a/coreutils/mknod.c +++ b/coreutils/mknod.c @@ -35,7 +35,7 @@ int main(const int argc, const char **argv) { break; else if (!strncmp("-m=", argv[i], 3)) - mode = mu_parse_mode(argv[i] + 3); + mode = mu_parse_mode(argv[i] + 3, 0); } long major = 0; @@ -71,7 +71,7 @@ int main(const int argc, const char **argv) { else { printf("mknod [-m=mode] [NAME] [TYPE] [MAJOR MINOR]\n"); - printf("Types:\n b - block device\n c or u - character device\n p - fifo (MAJOR MINOR must be omitted)\n s - socket\n"); + printf("Types:\n b - block device\n c or u - character device\n p - named pipe/fifo (MAJOR MINOR must be omitted)\n s - socket\n"); return 0; } diff --git a/libmu/parse_mode.h b/libmu/parse_mode.h index 9fd77fc..1e5ba5c 100644 --- a/libmu/parse_mode.h +++ b/libmu/parse_mode.h @@ -13,7 +13,7 @@ #define RD_PERM (4) #define FULL_PERM (7) -mode_t mu_parse_mode(const char *s) { +mode_t mu_parse_mode(const char *s, mode_t cur_mode) { char *p = NULL; mode_t mode = (mode_t)strtol(s, &p, 8); @@ -73,12 +73,11 @@ mode_t mu_parse_mode(const char *s) { if (mask == 0) mask = U(FULL_PERM); - if (append) - return mask & mode; + mask = mask & mode; + if (!append) + mode = ~mode; - mode_t test = mask & mode; - printf("test: %d\n", test); - return test; + return (cur_mode & ~mask) | (mode & mask); } #endif