| 
									
										
										
										
											2011-05-27 23:48:07 +01:00
										 |  |  | /* See LICENSE file for copyright and license details. */ | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-13 00:25:32 +01:00
										 |  |  | #include "fs.h"
 | 
					
						
							| 
									
										
										
										
											2011-05-27 23:48:07 +01:00
										 |  |  | #include "util.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-16 16:47:07 +00:00
										 |  |  | static int    Rflag   = 0; | 
					
						
							| 
									
										
										
										
											2015-01-17 00:01:51 +01:00
										 |  |  | static char  *modestr = ""; | 
					
						
							|  |  |  | static mode_t mask    = 0; | 
					
						
							|  |  |  | static int    ret     = 0; | 
					
						
							| 
									
										
										
										
											2011-05-27 23:48:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-07 13:33:39 +01:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2015-03-13 00:25:32 +01:00
										 |  |  | chmodr(const char *path, void *data, struct recursor *r) | 
					
						
							| 
									
										
										
										
											2011-05-27 23:48:07 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-06-11 00:30:07 +01:00
										 |  |  | 	struct stat st; | 
					
						
							| 
									
										
										
										
											2014-04-23 21:28:59 +02:00
										 |  |  | 	mode_t m; | 
					
						
							| 
									
										
										
										
											2011-06-11 00:30:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-19 20:59:37 +01:00
										 |  |  | 	if (stat(path, &st) < 0) { | 
					
						
							| 
									
										
										
										
											2014-04-23 22:00:08 +02:00
										 |  |  | 		weprintf("stat %s:", path); | 
					
						
							| 
									
										
										
										
											2014-10-02 23:46:04 +01:00
										 |  |  | 		ret = 1; | 
					
						
							| 
									
										
										
										
											2014-04-23 22:00:08 +02:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-06-11 00:30:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 21:28:59 +02:00
										 |  |  | 	m = parsemode(modestr, st.st_mode, mask); | 
					
						
							| 
									
										
										
										
											2014-11-19 20:59:37 +01:00
										 |  |  | 	if (chmod(path, m) < 0) { | 
					
						
							| 
									
										
										
										
											2014-04-22 12:11:46 +01:00
										 |  |  | 		weprintf("chmod %s:", path); | 
					
						
							| 
									
										
										
										
											2014-10-02 23:46:04 +01:00
										 |  |  | 		ret = 1; | 
					
						
							| 
									
										
										
										
											2015-03-05 19:08:28 +01:00
										 |  |  | 	} else if (Rflag) | 
					
						
							| 
									
										
										
										
											2015-03-13 00:25:32 +01:00
										 |  |  | 		recurse(path, NULL, r); | 
					
						
							| 
									
										
										
										
											2011-05-27 23:48:07 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-01-17 00:01:51 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | usage(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-02-16 16:47:07 +00:00
										 |  |  | 	eprintf("usage: %s [-R [-H | -L | -P]] mode file ...\n", argv0); | 
					
						
							| 
									
										
										
										
											2015-01-17 00:01:51 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | main(int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-03-13 00:25:32 +01:00
										 |  |  | 	struct recursor r = { .fn = chmodr, .hist = NULL, .depth = 0, .follow = 'P', .flags = 0}; | 
					
						
							| 
									
										
										
										
											2015-01-17 00:01:51 +01:00
										 |  |  | 	size_t i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-05 19:08:28 +01:00
										 |  |  | 	argv0 = *(argv++); | 
					
						
							|  |  |  | 	argc--; | 
					
						
							|  |  |  | 	for (; *argv && (*argv)[0] == '-'; argc--, argv++) { | 
					
						
							|  |  |  | 		if (!(*argv)[1]) | 
					
						
							| 
									
										
										
										
											2015-01-17 00:01:51 +01:00
										 |  |  | 			usage(); | 
					
						
							| 
									
										
										
										
											2015-03-05 19:08:28 +01:00
										 |  |  | 		for (i = 1; (*argv)[i]; i++) { | 
					
						
							|  |  |  | 			switch ((*argv)[i]) { | 
					
						
							|  |  |  | 			case 'R': | 
					
						
							|  |  |  | 				Rflag = 1; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case 'H': | 
					
						
							|  |  |  | 			case 'L': | 
					
						
							|  |  |  | 			case 'P': | 
					
						
							| 
									
										
										
										
											2015-03-13 00:25:32 +01:00
										 |  |  | 				r.follow = (*argv)[i]; | 
					
						
							| 
									
										
										
										
											2015-03-05 19:08:28 +01:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			case 'r': case 'w': case 'x': case 's': case 't': | 
					
						
							|  |  |  | 				/* -[rwxst] are valid modes, so we're done */ | 
					
						
							|  |  |  | 				if (i == 1) | 
					
						
							|  |  |  | 					goto done; | 
					
						
							|  |  |  | 				/* fallthrough */ | 
					
						
							|  |  |  | 			case '-': | 
					
						
							|  |  |  | 				/* -- terminator */ | 
					
						
							|  |  |  | 				if (i == 1 && !(*argv)[i + 1]) { | 
					
						
							|  |  |  | 					argv++; | 
					
						
							|  |  |  | 					argc--; | 
					
						
							|  |  |  | 					goto done; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				/* fallthrough */ | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				usage(); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-01-17 00:01:51 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | done: | 
					
						
							|  |  |  | 	mask = getumask(); | 
					
						
							| 
									
										
										
										
											2015-03-05 19:08:28 +01:00
										 |  |  | 	modestr = *argv; | 
					
						
							| 
									
										
										
										
											2015-01-17 00:01:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-05 19:08:28 +01:00
										 |  |  | 	if (argc < 2) | 
					
						
							| 
									
										
										
										
											2015-01-17 00:01:51 +01:00
										 |  |  | 		usage(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-05 19:08:28 +01:00
										 |  |  | 	for (--argc, ++argv; *argv; argc--, argv++) | 
					
						
							| 
									
										
										
										
											2015-03-13 00:25:32 +01:00
										 |  |  | 		chmodr(*argv, NULL, &r); | 
					
						
							| 
									
										
										
										
											2015-01-17 00:01:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-13 00:25:32 +01:00
										 |  |  | 	return ret || recurse_status; | 
					
						
							| 
									
										
										
										
											2015-01-17 00:01:51 +01:00
										 |  |  | } |