| 
																	
																	
																	
																 | 
																@ -1,66 +1,31 @@ | 
															
														
														
													
														
															
																 | 
																 | 
																/* See LICENSE file for copyright and license details. */ | 
																 | 
																 | 
																/* See LICENSE file for copyright and license details. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#include <sys/stat.h> | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																#include <dirent.h> | 
																 | 
																 | 
																#include <dirent.h> | 
															
														
														
													
														
															
																 | 
																 | 
																#include <stdbool.h> | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#include <limits.h> | 
															
														
														
													
														
															
																 | 
																 | 
																#include <stdio.h> | 
																 | 
																 | 
																#include <stdio.h> | 
															
														
														
													
														
															
																 | 
																 | 
																#include <stdlib.h> | 
																 | 
																 | 
																#include <stdlib.h> | 
															
														
														
													
														
															
																 | 
																 | 
																#include <string.h> | 
																 | 
																 | 
																#include <string.h> | 
															
														
														
													
														
															
																 | 
																 | 
																#include <unistd.h> | 
																 | 
																 | 
																#include <unistd.h> | 
															
														
														
													
														
															
																 | 
																 | 
																#include <sys/stat.h> | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#include "arg.h" | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																char *argv0; | 
															
														
														
													
														
															
																 | 
																 | 
																
 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																#define FLAG(x)  (flag[(x)-'a']) | 
																 | 
																 | 
																#define FLAG(x)  (flag[(x)-'a']) | 
															
														
														
													
														
															
																 | 
																 | 
																
 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																static void test(const char *, const char *); | 
																 | 
																 | 
																static void test(const char *, const char *); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																static void usage(void); | 
															
														
														
													
														
															
																 | 
																 | 
																
 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																static bool match = false; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																static bool flag[26]; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																static int match = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																static int flag[26]; | 
															
														
														
													
														
															
																 | 
																 | 
																static struct stat old, new; | 
																 | 
																 | 
																static struct stat old, new; | 
															
														
														
													
														
															
																 | 
																 | 
																
 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																int | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																main(int argc, char *argv[]) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																	struct dirent *d; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																	char buf[BUFSIZ], *p; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																	DIR *dir; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																	int opt; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
 | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																	while((opt = getopt(argc, argv, "abcdefghln:o:pqrsuvwx")) != -1) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																		switch(opt) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																		case 'n': /* newer than file */ | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																		case 'o': /* older than file */ | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																			if(!(FLAG(opt) = !stat(optarg, (opt == 'n' ? &new : &old)))) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																				perror(optarg); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																			break; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																		default:  /* miscellaneous operators */ | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																			FLAG(opt) = true; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																			break; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																		case '?': /* error: unknown flag */ | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																			fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] [-n file] [-o file] [file...]\n", argv[0]); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																			exit(2); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																		} | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																	if(optind == argc) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																		while(fgets(buf, sizeof buf, stdin)) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																			if((p = strchr(buf, '\n'))) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																				*p = '\0'; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																			test(buf, buf); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																		} | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																	for(; optind < argc; optind++) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																		if(FLAG('l') && (dir = opendir(argv[optind]))) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																			/* test directory contents */ | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																			while((d = readdir(dir))) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																				if(snprintf(buf, sizeof buf, "%s/%s", argv[optind], d->d_name) < sizeof buf) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																					test(buf, d->d_name); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																			closedir(dir); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																		} | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																		else | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																			test(argv[optind], argv[optind]); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
 | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																	return match ? 0 : 1; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																} | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
 | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																void | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																test(const char *path, const char *name) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																static void | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																test(const char *path, const char *name) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																	struct stat st, ln; | 
																 | 
																 | 
																	struct stat st, ln; | 
															
														
														
													
														
															
																 | 
																 | 
																
 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																	if((!stat(path, &st) && (FLAG('a') || name[0] != '.')         /* hidden files      */ | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	if ((!stat(path, &st) && (FLAG('a') || name[0] != '.')        /* hidden files      */ | 
															
														
														
													
														
															
																 | 
																 | 
																	&& (!FLAG('b') || S_ISBLK(st.st_mode))                        /* block special     */ | 
																 | 
																 | 
																	&& (!FLAG('b') || S_ISBLK(st.st_mode))                        /* block special     */ | 
															
														
														
													
														
															
																 | 
																 | 
																	&& (!FLAG('c') || S_ISCHR(st.st_mode))                        /* character special */ | 
																 | 
																 | 
																	&& (!FLAG('c') || S_ISCHR(st.st_mode))                        /* character special */ | 
															
														
														
													
														
															
																 | 
																 | 
																	&& (!FLAG('d') || S_ISDIR(st.st_mode))                        /* directory         */ | 
																 | 
																 | 
																	&& (!FLAG('d') || S_ISDIR(st.st_mode))                        /* directory         */ | 
															
														
														
													
												
													
														
															
																| 
																	
																	
																	
																		
																			
																		
																	
																 | 
																@ -76,9 +41,69 @@ test(const char *path, const char *name) { | 
															
														
														
													
														
															
																 | 
																 | 
																	&& (!FLAG('u') || st.st_mode & S_ISUID)                       /* set-user-id flag  */ | 
																 | 
																 | 
																	&& (!FLAG('u') || st.st_mode & S_ISUID)                       /* set-user-id flag  */ | 
															
														
														
													
														
															
																 | 
																 | 
																	&& (!FLAG('w') || access(path, W_OK) == 0)                    /* writable          */ | 
																 | 
																 | 
																	&& (!FLAG('w') || access(path, W_OK) == 0)                    /* writable          */ | 
															
														
														
													
														
															
																 | 
																 | 
																	&& (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) {   /* executable        */ | 
																 | 
																 | 
																	&& (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) {   /* executable        */ | 
															
														
														
													
														
															
																 | 
																 | 
																		if(FLAG('q')) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		if (FLAG('q')) | 
															
														
														
													
														
															
																 | 
																 | 
																			exit(0); | 
																 | 
																 | 
																			exit(0); | 
															
														
														
													
														
															
																 | 
																 | 
																		match = true; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		match = 1; | 
															
														
														
													
														
															
																 | 
																 | 
																		puts(name); | 
																 | 
																 | 
																		puts(name); | 
															
														
														
													
														
															
																 | 
																 | 
																	} | 
																 | 
																 | 
																	} | 
															
														
														
													
														
															
																 | 
																 | 
																} | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																static void | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																usage(void) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] " | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	        "[-n file] [-o file] [file...]\n", argv0); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	exit(2); /* like test(1) return > 1 on error */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																int | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																main(int argc, char *argv[]) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	struct dirent *d; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	char path[PATH_MAX], *line = NULL, *file; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	size_t linesiz = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	ssize_t n; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	DIR *dir; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	int r; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	ARGBEGIN { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	case 'n': /* newer than file */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	case 'o': /* older than file */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		file = EARGF(usage()); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		if (!(FLAG(ARGC()) = !stat(file, (ARGC() == 'n' ? &new : &old)))) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			perror(file); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		break; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	default: | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		/* miscellaneous operators */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		if (strchr("abcdefghlpqrsuvwx", ARGC())) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			FLAG(ARGC()) = 1; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		else | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			usage(); /* unknown flag */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	} ARGEND; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	if (!argc) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		/* read list from stdin */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		while ((n = getline(&line, &linesiz, stdin)) > 0) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			if (n && line[n - 1] == '\n') | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																				line[n - 1] = '\0'; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			test(line, line); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		free(line); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	} else { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		for (; argc; argc--, argv++) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			if (FLAG('l') && (dir = opendir(*argv))) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																				/* test directory contents */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																				while ((d = readdir(dir))) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																					r = snprintf(path, sizeof path, "%s/%s", | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																					             *argv, d->d_name); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																					if (r >= 0 && (size_t)r < sizeof path) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																						test(path, d->d_name); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																				} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																				closedir(dir); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			} else { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																				test(*argv, *argv); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																			} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																		} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																	return match ? 0 : 1; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																} |