| 
						
						
						
					 | 
				
				 | 
				
					@ -1,66 +1,31 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/* See LICENSE file for copyright and license details. */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <sys/stat.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <dirent.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <stdbool.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <limits.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <stdio.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <stdlib.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <string.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <unistd.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <sys/stat.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "arg.h" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					char *argv0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define FLAG(x)  (flag[(x)-'a']) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					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; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					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; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						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('c') || S_ISCHR(st.st_mode))                        /* character special */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						&& (!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('w') || access(path, W_OK) == 0)                    /* writable          */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						&& (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) {   /* executable        */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(FLAG('q')) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if (FLAG('q')) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								exit(0); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							match = true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							match = 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							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; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} |