From d18e770ce9e98942eb923dec70cabf44407d5ff4 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 6 Nov 2023 23:00:26 +0300 Subject: [PATCH] Big update: 1/N fix --- coreutils/chgrp.c | 50 ++++++++++++++++++------------------ coreutils/chmod.c | 65 ++++++++++++++++++++++++++++++----------------- coreutils/chown.c | 23 ++++++++++++----- 3 files changed, 83 insertions(+), 55 deletions(-) diff --git a/coreutils/chgrp.c b/coreutils/chgrp.c index 35ea83b..77c9c18 100644 --- a/coreutils/chgrp.c +++ b/coreutils/chgrp.c @@ -11,9 +11,8 @@ int (*get_stat)(const char *prog_name, const char *path, struct stat *stat_path); unsigned int r_flag; unsigned int s_flag; -struct group *grp; -int change(const char *file) { +int change(const char *file, const struct group *grp) { struct stat stat_path; if (mu_get_stat("chgrp", file, &stat_path)) return 1; @@ -28,8 +27,8 @@ int change(const char *file) { return 0; } -int chtree(const char *dst) { - int ret = change(dst); +int chtree(const char *dst, const struct group *grp) { + int ret = change(dst, grp); struct stat stat_path; if (get_stat("chgrp", dst, &stat_path)) @@ -55,7 +54,7 @@ int chtree(const char *dst) { if (full_path == NULL) continue; - if (chtree(full_path)) + if (chtree(full_path, grp)) ret = 1; free(full_path); @@ -66,45 +65,46 @@ int chtree(const char *dst) { } int main(int argc, char **argv) { - int i; - get_stat = mu_get_lstat; - for (i = 1; i < argc; i++) { - if (argv[i][0] != '-') - break; - else if (!strcmp(argv[i], "-r")) - r_flag = 1; + int opt; + while ((opt = getopt(argc, argv, "RfH") != -1)) { + switch (opt) { + case 'R': + r_flag = 1; + break; - else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "-f")) - s_flag = 1; + case 'f': + s_flag = 1; + break; - else if (!strcmp(argv[i], "-H")) - get_stat = mu_get_stat; + case 'H': + get_stat = mu_get_stat; + break; - else if (!strcmp(argv[i], "--help")) { - printf("chgrp [-H if a command line argument is a symbolic link] [-r recursive] [-s silent] [group] [file1 file2...]\n"); - return 0; + default: + printf("chgrp [group] [file1 file2...]\n\t[-H if a command line argument is a symbolic link]\n\t[-R recursive] [-f silent]\n"); + return 0; } } - if (argc - i < 2) { + if (argv[optind] == NULL) { fprintf(stderr, "chgrp: missing operand\n"); return 1; } - grp = getgrnam(argv[i]); + struct group *grp = getgrnam(argv[optind]); if (!grp) { fprintf(stderr, "chgrp: unknow group\n"); return 1; } - argv++; - argc--; + argv += optind; + argc -= optind; int ret = 0; - for (; i < argc; i++) - if (chtree(argv[i])) + for (int i = 1; i < argc; i++) + if (chtree(argv[i], grp)) ret = 1; return ret; diff --git a/coreutils/chmod.c b/coreutils/chmod.c index ed4cc50..bbd163e 100644 --- a/coreutils/chmod.c +++ b/coreutils/chmod.c @@ -66,42 +66,59 @@ int chtree(const char *dst, const char *mode_arg) { } int main(int argc, char **argv) { - int i; - get_stat = mu_get_lstat; - for (i = 1; i < argc; i++) { - if (argv[i][0] != '-') + + /* Arg hacking */ + char *arg, **argp; + argp = argv; + while ((arg = *++argp)) { + if (arg[0] != '-') { + arg = NULL; break; - - else if (!strcmp(argv[i], "-r")) - r_flag = 1; - - 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 [-H if a command line argument is a symbolic link] [-r recursive] [-s silent] [ugoa]{+|-|=}[rwxXst] / [sstrwxrwxrwx] [file1 file2...]\n"); - return 0; } - if (argc - i <= 2) + if (arg[1] && (!strchr("-x", arg[1]) || !strchr("-r", arg[1]) || !strchr("-w", arg[1]))) { + arg[0] = 'a'; break; + } } - if (argc - i < 2) { + int opt; + while ((opt = getopt(argc, argv, "RfH") != -1)) { + switch (opt) { + case 'R': + r_flag = 1; + break; + + case 'f': + s_flag = 1; + break; + + case 'H': + get_stat = mu_get_stat; + break; + + default: + printf("chmod [ugoa]{+|-|=}[rwxXst] / [sstrwxrwxrwx] [file1 file2...]\n\t[-H if a command line argument is a symbolic link]\n\t[-R recursive] [-s silent]\n"); + return 0; + } + } + + if (argv[optind] == NULL) { fprintf(stderr, "chmod: missing operand\n"); - return 1; + return 0; } - char *mode_arg = argv[i]; - argv++; - argc--; + /* Fix arg */ + if (arg) + arg[0] = '-'; + + char *mode_arg = argv[optind]; + argv += optind; + argc -= optind; int ret = 0; - for (; i < argc; i++) + for (int i = 1; i < argc; i++) if (chtree(argv[i], mode_arg)) ret = 1; diff --git a/coreutils/chown.c b/coreutils/chown.c index 0511ecf..92a0c5b 100644 --- a/coreutils/chown.c +++ b/coreutils/chown.c @@ -10,6 +10,7 @@ #include "get_stat.h" unsigned int r_flag; +unsigned int s_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; @@ -17,7 +18,9 @@ long uid; int change(const char *file) { if (chown_func(file, uid, gid)) { - fprintf(stderr, "chown: unable to chown %s: %s\n", file, strerror(errno)); + if (!s_flag) + fprintf(stderr, "chown: unable to chown %s: %s\n", file, strerror(errno)); + return 1; } @@ -27,7 +30,6 @@ int change(const char *file) { int cntree(const char *dst) { int ret = change(dst); - struct stat stat_path; if (get_stat("chown", dst, &stat_path)) return 1; @@ -37,7 +39,9 @@ int cntree(const char *dst) { DIR *dir = opendir(dst); if (dir == NULL) { - fprintf(stderr, "chown: %s: Can`t open directory\n", dst); + if (!s_flag) + fprintf(stderr, "chown: %s: Can`t open directory\n", dst); + return 1; } @@ -78,7 +82,9 @@ void get_owner(const char *arg) { struct group *grp = getgrnam(group); if (!grp) { - fprintf(stderr, "chown: invalid group: %s\n", group); + if (!s_flag) + fprintf(stderr, "chown: invalid group: %s\n", group); + exit(1); } @@ -88,7 +94,9 @@ void get_owner(const char *arg) { if (u_flag) { struct passwd *pwd = getpwnam(arg); if (!pwd) { - fprintf(stderr, "chown: invalid user: %s\n", arg); + if (!s_flag) + fprintf(stderr, "chown: invalid user: %s\n", arg); + exit(1); } @@ -108,13 +116,16 @@ int main(const int argc, char **argv) { else if (!strcmp(argv[i], "-r")) r_flag = 1; + else if (!strcmp(argv[i], "-s")) + s_flag = 1; + else if (!strcmp(argv[i], "-H")) { chown_func = chown; get_stat = mu_get_stat; } else if (!strcmp(argv[i], "--help")) { - printf("chown [-H if a command line argument is a symbolic link] [-r recursive] [owner]:[group] [file file2...]\n"); + printf("chown [group] [file1 file2...]\n\t[-H if a command line argument is a symbolic link]\n\t[-r recursive]\n"); return 0; } }