add chown
This commit is contained in:
		
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,8 +1,8 @@ | |||||||
| include config.mk | include config.mk | ||||||
|  |  | ||||||
| LIB = util/enmasse.o util/eprintf.o | LIB = util/enmasse.o util/eprintf.o util/recurse.o | ||||||
| SRC = basename.c cat.c date.c dirname.c echo.c false.c grep.c ln.c pwd.c rm.c \ | SRC = basename.c cat.c chown.c date.c dirname.c echo.c false.c grep.c ln.c \ | ||||||
|       sleep.c tee.c touch.c true.c wc.c |       pwd.c rm.c sleep.c tee.c touch.c true.c wc.c | ||||||
| OBJ = $(SRC:.c=.o) $(LIB) | OBJ = $(SRC:.c=.o) $(LIB) | ||||||
| BIN = $(SRC:.c=) | BIN = $(SRC:.c=) | ||||||
| MAN = $(SRC:.c=.1) | MAN = $(SRC:.c=.1) | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								chown.1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								chown.1
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | .TH CHOWN 1 sbase\-VERSION | ||||||
|  | .SH NAME | ||||||
|  | chown \- change file ownership | ||||||
|  | .SH SYNOPSIS | ||||||
|  | .B chown | ||||||
|  | .RB [ -Rr ] | ||||||
|  | .RI [ owner ][: group ] | ||||||
|  | .RI [ files ...] | ||||||
|  | .SH DESCRIPTION | ||||||
|  | .B chown | ||||||
|  | changes the user or group ownership for the given files. | ||||||
|  | .SH OPTIONS | ||||||
|  | .TP | ||||||
|  | .B -R, -r | ||||||
|  | change directory ownership recursively. | ||||||
							
								
								
									
										66
									
								
								chown.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								chown.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | /* See LICENSE file for copyright and license details. */ | ||||||
|  | #include <errno.h> | ||||||
|  | #include <grp.h> | ||||||
|  | #include <pwd.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include "util.h" | ||||||
|  |  | ||||||
|  | static void chownpwgr(const char *); | ||||||
|  |  | ||||||
|  | static bool rflag = false; | ||||||
|  | static struct passwd *pw = NULL; | ||||||
|  | static struct group *gr = NULL; | ||||||
|  |  | ||||||
|  | int | ||||||
|  | main(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	char c, *owner, *group; | ||||||
|  |  | ||||||
|  | 	while((c = getopt(argc, argv, "Rr")) != -1) | ||||||
|  | 		switch(c) { | ||||||
|  | 		case 'R': | ||||||
|  | 		case 'r': | ||||||
|  | 			rflag = true; | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			exit(EXIT_FAILURE); | ||||||
|  | 		} | ||||||
|  | 	if(optind == argc) | ||||||
|  | 		eprintf("usage: %s [-Rr] [owner][:group] [file...]\n", argv[0]); | ||||||
|  | 	owner = argv[optind++]; | ||||||
|  | 	if((group = strchr(owner, ':'))) | ||||||
|  | 		*group++ = '\0'; | ||||||
|  |  | ||||||
|  | 	if(owner && *owner) { | ||||||
|  | 		errno = 0; | ||||||
|  | 		pw = getpwnam(owner); | ||||||
|  | 		if(errno != 0) | ||||||
|  | 			eprintf("getpwnam %s:", owner); | ||||||
|  | 		else if(!pw) | ||||||
|  | 			eprintf("getpwnam %s: no such user\n", owner); | ||||||
|  | 	} | ||||||
|  | 	if(group && *group) { | ||||||
|  | 		errno = 0; | ||||||
|  | 		gr = getgrnam(group); | ||||||
|  | 		if(errno != 0) | ||||||
|  | 			eprintf("getgrnam %s:", group); | ||||||
|  | 		else if(!gr) | ||||||
|  | 			eprintf("getgrnam %s: no such user\n", group); | ||||||
|  | 	} | ||||||
|  | 	for(; optind < argc; optind++) | ||||||
|  | 		chownpwgr(argv[optind]); | ||||||
|  | 	return EXIT_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | chownpwgr(const char *path) | ||||||
|  | { | ||||||
|  | 	if(chown(path, pw ? pw->pw_uid : -1, gr ? gr->gr_gid : -1) != 0) | ||||||
|  | 		eprintf("chown %s:", path); | ||||||
|  | 	if(rflag) | ||||||
|  | 		recurse(path, chownpwgr); | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								rm.c
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								rm.c
									
									
									
									
									
								
							| @@ -1,10 +1,7 @@ | |||||||
| /* See LICENSE file for copyright and license details. */ | /* See LICENSE file for copyright and license details. */ | ||||||
| #include <dirent.h> |  | ||||||
| #include <errno.h> |  | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> |  | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include "util.h" | #include "util.h" | ||||||
|  |  | ||||||
| @@ -34,36 +31,11 @@ main(int argc, char *argv[]) | |||||||
| 	return EXIT_SUCCESS; | 	return EXIT_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
| void rm(const char *path) | void | ||||||
|  | rm(const char *path) | ||||||
| { | { | ||||||
| 	if(remove(path) == 0) | 	if(rflag) | ||||||
| 		return; | 		recurse(path, rm); | ||||||
| 	if(errno == ENOTEMPTY && rflag) { | 	if(remove(path) != 0 && !fflag) | ||||||
| 		char *buf; |  | ||||||
| 		long size; |  | ||||||
| 		struct dirent *d; |  | ||||||
| 		DIR *dp; |  | ||||||
|  |  | ||||||
| 		if((size = pathconf(".", _PC_PATH_MAX)) < 0) |  | ||||||
| 			size = BUFSIZ; |  | ||||||
| 		if(!(buf = malloc(size))) |  | ||||||
| 			eprintf("malloc:"); |  | ||||||
| 		if(!getcwd(buf, size)) |  | ||||||
| 			eprintf("getcwd:"); |  | ||||||
| 		if(!(dp = opendir(path))) |  | ||||||
| 			eprintf("opendir %s:", path); |  | ||||||
| 		if(chdir(path) != 0) |  | ||||||
| 			eprintf("chdir %s:", path); |  | ||||||
| 		while((d = readdir(dp))) |  | ||||||
| 			if(strcmp(d->d_name, ".") && strcmp(d->d_name, "..")) |  | ||||||
| 				rm(d->d_name); |  | ||||||
|  |  | ||||||
| 		closedir(dp); |  | ||||||
| 		if(chdir(buf) != 0) |  | ||||||
| 			eprintf("chdir %s:", buf); |  | ||||||
| 		if(remove(path) == 0) |  | ||||||
| 			return; |  | ||||||
| 	} |  | ||||||
| 	if(!fflag) |  | ||||||
| 		eprintf("remove %s:", path); | 		eprintf("remove %s:", path); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								util.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								util.h
									
									
									
									
									
								
							| @@ -2,3 +2,4 @@ | |||||||
|  |  | ||||||
| void enmasse(int, char **, int (*)(const char *, const char *)); | void enmasse(int, char **, int (*)(const char *, const char *)); | ||||||
| void eprintf(const char *, ...); | void eprintf(const char *, ...); | ||||||
|  | void recurse(const char *, void (*)(const char *)); | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								util/recurse.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								util/recurse.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | /* See LICENSE file for copyright and license details. */ | ||||||
|  | #include <dirent.h> | ||||||
|  | #include <errno.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include "../util.h" | ||||||
|  |  | ||||||
|  | void | ||||||
|  | recurse(const char *path, void (*fn)(const char *)) | ||||||
|  | { | ||||||
|  | 	char *buf; | ||||||
|  | 	long size; | ||||||
|  | 	struct dirent *d; | ||||||
|  | 	DIR *dp; | ||||||
|  |  | ||||||
|  | 	if(!(dp = opendir(path))) { | ||||||
|  | 		if(errno == ENOTDIR) | ||||||
|  | 			return; | ||||||
|  | 		else | ||||||
|  | 			eprintf("opendir %s:", path); | ||||||
|  | 	} | ||||||
|  | 	if((size = pathconf(".", _PC_PATH_MAX)) < 0) | ||||||
|  | 		size = BUFSIZ; | ||||||
|  | 	if(!(buf = malloc(size))) | ||||||
|  | 		eprintf("malloc:"); | ||||||
|  | 	if(!getcwd(buf, size)) | ||||||
|  | 		eprintf("getcwd:"); | ||||||
|  | 	if(chdir(path) != 0) | ||||||
|  | 		eprintf("chdir %s:", path); | ||||||
|  | 	while((d = readdir(dp))) | ||||||
|  | 		if(strcmp(d->d_name, ".") && strcmp(d->d_name, "..")) | ||||||
|  | 			fn(d->d_name); | ||||||
|  |  | ||||||
|  | 	closedir(dp); | ||||||
|  | 	if(chdir(buf) != 0) | ||||||
|  | 		eprintf("chdir %s:", buf); | ||||||
|  | 	free(buf); | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user