diff options
Diffstat (limited to 'chown.c')
-rw-r--r-- | chown.c | 45 |
1 files changed, 28 insertions, 17 deletions
@@ -37,13 +37,17 @@ #include <sys/stat.h> #include <unistd.h> +#ifndef OPEN_MAX +#define OPEN_MAX _POSIX_OPEN_MAX +#endif + +/* TODO: replace these with NFTW_* flags */ static enum { NOFOLLOW, FOLLOWARGV, FOLLOWALL } links = FOLLOWARGV; -static int recursive = 0; static uid_t newowner = -1; static gid_t newgroup = -1; static int retval = 0; -static int nftw_chown(const char *p, const struct stat *st, int typeflag, struct FTW *f) +static int ch_own(const char *p, const struct stat *st, int typeflag, struct FTW *f) { (void)typeflag; (void)f; @@ -52,7 +56,7 @@ static int nftw_chown(const char *p, const struct stat *st, int typeflag, struct retval = 1; } else if (S_ISLNK(st->st_mode)) { - /* handle specially */ + /* TODO: based on value of 'links' */ } else { if (chown(p, newowner, newgroup) != 0) { @@ -97,18 +101,10 @@ static void parse_owner(char *owner) } } -int do_chown(char *path, int recurse, int howlinks, uid_t uid, gid_t gid) -{ - recursive = recurse; - links = howlinks; - newowner = uid; - newgroup = gid; - // FIXME: This is where to recurse and handle the difference betwixt links types - return nftw_chown(path, NULL, 0, NULL); -} - int main(int argc, char *argv[]) { + int recursive = 0; + setlocale(LC_ALL, ""); int c; @@ -149,15 +145,30 @@ int main(int argc, char *argv[]) } if (optind >= argc - 1) { + fprintf(stderr, "chown: missing operand(s)\n"); return 1; } parse_owner(argv[optind++]); - while (optind < argc) { - do_chown(argv[optind], recursive, links, newowner, newgroup); - optind++; - } + do { + char *path = argv[optind]; + + struct stat st; + if (stat(path, &st) != 0) { + fprintf(stderr, "chown: %s: %s\n", path, + strerror(errno)); + retval = 1; + continue; + } + + if (S_ISDIR(st.st_mode) && recursive) { + nftw(path, ch_own, OPEN_MAX, FTW_DEPTH | FTW_PHYS); + } else { + ch_own(path, &st, 0, NULL); + } + + } while (++optind < argc); return 0; } |