sbase

suckless unix tools
git clone git://git.2f30.org/sbase.git
Log | Files | Refs | README | LICENSE

chown.c (2116B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <errno.h>
      3 #include <grp.h>
      4 #include <limits.h>
      5 #include <pwd.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <unistd.h>
      9 
     10 #include "fs.h"
     11 #include "util.h"
     12 
     13 static int   hflag = 0;
     14 static uid_t uid = -1;
     15 static gid_t gid = -1;
     16 static int   ret = 0;
     17 
     18 static void
     19 chownpwgr(const char *path, struct stat *st, void *data, struct recursor *r)
     20 {
     21 	char *chownf_name;
     22 	int (*chownf)(const char *, uid_t, gid_t);
     23 
     24 	if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && r->depth) || (hflag && !(r->depth))) {
     25 		chownf_name = "lchown";
     26 		chownf = lchown;
     27 	} else {
     28 		chownf_name = "chown";
     29 		chownf = chown;
     30 	}
     31 
     32 	if (chownf(path, uid, gid) < 0) {
     33 		weprintf("%s %s:", chownf_name, path);
     34 		ret = 1;
     35 	} else if (S_ISDIR(st->st_mode)) {
     36 		recurse(path, NULL, r);
     37 	}
     38 }
     39 
     40 static void
     41 usage(void)
     42 {
     43 	eprintf("usage: %s [-h] [-R [-H | -L | -P]] owner[:[group]] file ...\n"
     44 	        "       %s [-h] [-R [-H | -L | -P]] :group file ...\n",
     45 	        argv0, argv0);
     46 }
     47 
     48 int
     49 main(int argc, char *argv[])
     50 {
     51 	struct group *gr;
     52 	struct passwd *pw;
     53 	struct recursor r = { .fn = chownpwgr, .hist = NULL, .depth = 0, .maxdepth = 1,
     54 	                      .follow = 'P', .flags = 0 };
     55 	char *owner, *group;
     56 
     57 	ARGBEGIN {
     58 	case 'h':
     59 		hflag = 1;
     60 		break;
     61 	case 'r':
     62 	case 'R':
     63 		r.maxdepth = 0;
     64 		break;
     65 	case 'H':
     66 	case 'L':
     67 	case 'P':
     68 		r.follow = ARGC();
     69 		break;
     70 	default:
     71 		usage();
     72 	} ARGEND
     73 
     74 	if (argc < 2)
     75 		usage();
     76 
     77 	owner = argv[0];
     78 	if ((group = strchr(owner, ':')))
     79 		*group++ = '\0';
     80 
     81 	if (owner && *owner) {
     82 		errno = 0;
     83 		pw = getpwnam(owner);
     84 		if (pw) {
     85 			uid = pw->pw_uid;
     86 		} else {
     87 			if (errno)
     88 				eprintf("getpwnam %s:", owner);
     89 			uid = estrtonum(owner, 0, UINT_MAX);
     90 		}
     91 	}
     92 	if (group && *group) {
     93 		errno = 0;
     94 		gr = getgrnam(group);
     95 		if (gr) {
     96 			gid = gr->gr_gid;
     97 		} else {
     98 			if (errno)
     99 				eprintf("getgrnam %s:", group);
    100 			gid = estrtonum(group, 0, UINT_MAX);
    101 		}
    102 	}
    103 	if (uid == (uid_t)-1 && gid == (gid_t)-1)
    104 		usage();
    105 
    106 	for (argc--, argv++; *argv; argc--, argv++)
    107 		recurse(*argv, NULL, &r);
    108 
    109 	return ret || recurse_status;
    110 }