Xinqi Bao's Git
1 /* See LICENSE file for copyright and license details. */
10 #define FLAG(x) (flag[(x)-'a'])
12 static void test(const char *, const char *);
14 static bool match
= false;
16 static struct stat old
, new;
19 main(int argc
, char *argv
[]) {
25 while((opt
= getopt(argc
, argv
, "abcdefghln:o:pqrsuwx")) != -1)
27 case 'n': /* newer than file */
28 case 'o': /* older than file */
29 if(!(FLAG(opt
) = !stat(optarg
, (opt
== 'n' ? &new : &old
))))
32 default: /* miscellaneous operators */
35 case '?': /* error: unknown flag */
36 fprintf(stderr
, "usage: %s [-abcdefghlpqrsuwx] [-n file] [-o file] [file...]\n", argv
[0]);
40 while(fgets(buf
, sizeof buf
, stdin
)) {
41 if((p
= strchr(buf
, '\n')))
45 for(; optind
< argc
; optind
++)
46 if(FLAG('l') && (dir
= opendir(argv
[optind
]))) {
47 /* test directory contents */
48 while((d
= readdir(dir
)))
49 if(snprintf(buf
, sizeof buf
, "%s/%s", argv
[optind
], d
->d_name
) < sizeof buf
)
54 test(argv
[optind
], argv
[optind
]);
60 test(const char *path
, const char *name
) {
63 if(!stat(path
, &st
) && (FLAG('a') || name
[0] != '.') /* hidden files */
64 && (!FLAG('b') || S_ISBLK(st
.st_mode
)) /* block special */
65 && (!FLAG('c') || S_ISCHR(st
.st_mode
)) /* character special */
66 && (!FLAG('d') || S_ISDIR(st
.st_mode
)) /* directory */
67 && (!FLAG('e') || access(path
, F_OK
) == 0) /* exists */
68 && (!FLAG('f') || S_ISREG(st
.st_mode
)) /* regular file */
69 && (!FLAG('g') || st
.st_mode
& S_ISGID
) /* set-group-id flag */
70 && (!FLAG('h') || (!lstat(path
, &ln
) && S_ISLNK(ln
.st_mode
))) /* symbolic link */
71 && (!FLAG('n') || st
.st_mtime
> new.st_mtime
) /* newer than file */
72 && (!FLAG('o') || st
.st_mtime
< old
.st_mtime
) /* older than file */
73 && (!FLAG('p') || S_ISFIFO(st
.st_mode
)) /* named pipe */
74 && (!FLAG('r') || access(path
, R_OK
) == 0) /* readable */
75 && (!FLAG('s') || st
.st_size
> 0) /* not empty */
76 && (!FLAG('u') || st
.st_mode
& S_ISUID
) /* set-user-id flag */
77 && (!FLAG('w') || access(path
, W_OK
) == 0) /* writable */
78 && (!FLAG('x') || access(path
, X_OK
) == 0)) { /* executable */