Xinqi Bao's Git
9dbf9c11d4e2b9de71a366ef54959ed50687d372
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]);
39 for(; optind
< argc
; optind
++)
40 if(FLAG('l') && (dir
= opendir(argv
[optind
]))) {
41 /* test directory contents */
42 while((d
= readdir(dir
)))
43 if(snprintf(buf
, sizeof buf
, "%s/%s", argv
[optind
], d
->d_name
) < sizeof buf
)
48 test(argv
[optind
], argv
[optind
]);
54 test(const char *path
, const char *name
) {
57 if(!stat(path
, &st
) && ( FLAG('a') || name
[0] != '.') /* hidden files */
58 && (!FLAG('b') || S_ISBLK(st
.st_mode
)) /* block special */
59 && (!FLAG('c') || S_ISCHR(st
.st_mode
)) /* character special */
60 && (!FLAG('d') || S_ISDIR(st
.st_mode
)) /* directory */
61 && (!FLAG('e') || access(path
, F_OK
) == 0) /* exists */
62 && (!FLAG('f') || S_ISREG(st
.st_mode
)) /* regular file */
63 && (!FLAG('g') || st
.st_mode
& S_ISGID
) /* set-group-id flag */
64 && (!FLAG('h') || (!lstat(path
, &ln
) && S_ISLNK(ln
.st_mode
))) /* symbolic link */
65 && (!FLAG('n') || st
.st_mtime
> new.st_mtime
) /* newer than file */
66 && (!FLAG('o') || st
.st_mtime
< old
.st_mtime
) /* older than file */
67 && (!FLAG('p') || S_ISFIFO(st
.st_mode
)) /* named pipe */
68 && (!FLAG('r') || access(path
, R_OK
) == 0) /* readable */
69 && (!FLAG('s') || st
.st_size
> 0) /* not empty */
70 && (!FLAG('u') || st
.st_mode
& S_ISUID
) /* set-user-id flag */
71 && (!FLAG('w') || access(path
, W_OK
) == 0) /* writable */
72 && (!FLAG('x') || access(path
, X_OK
) == 0)) { /* executable */