Xinqi Bao's Git
b4dba64d215dbac2135e7a5b7cf708ab4d53d2c8
1 /* See LICENSE file for copyright and license details. */
9 #define FLAG(x) (flag[(x)-'a'])
11 static void test(const char *, const char *);
13 static bool match
= false;
15 static struct stat old
, new;
18 main(int argc
, char *argv
[]) {
24 while((opt
= getopt(argc
, argv
, "abcdefghln:o:pqrsuwx")) != -1)
26 case 'n': /* newer than file */
27 case 'o': /* older than file */
28 if(!(FLAG(opt
) = !stat(optarg
, (opt
== 'n' ? &new : &old
))))
31 default: /* miscellaneous operators */
34 case '?': /* error: unknown flag */
35 fprintf(stderr
, "usage: %s [-abcdefghlpqrsuwx] [-n file] [-o file] [file...]\n", argv
[0]);
38 for(; optind
< argc
; optind
++)
39 if(FLAG('l') && (dir
= opendir(argv
[optind
]))) {
40 /* test directory contents */
41 while((d
= readdir(dir
)))
42 if(snprintf(buf
, sizeof buf
, "%s/%s", argv
[optind
], d
->d_name
) < sizeof buf
)
47 test(argv
[optind
], argv
[optind
]);
53 test(const char *path
, const char *name
) {
56 if(!stat(path
, &st
) && (FLAG('a') || name
[0] != '.') /* hidden files */
57 && (!FLAG('b') || S_ISBLK(st
.st_mode
)) /* block special */
58 && (!FLAG('c') || S_ISCHR(st
.st_mode
)) /* character special */
59 && (!FLAG('d') || S_ISDIR(st
.st_mode
)) /* directory */
60 && (!FLAG('e') || access(path
, F_OK
) == 0) /* exists */
61 && (!FLAG('f') || S_ISREG(st
.st_mode
)) /* regular file */
62 && (!FLAG('g') || st
.st_mode
& S_ISGID
) /* set-group-id flag */
63 && (!FLAG('h') || (!lstat(path
, &ln
) && S_ISLNK(ln
.st_mode
))) /* symbolic link */
64 && (!FLAG('n') || st
.st_mtime
> new.st_mtime
) /* newer than file */
65 && (!FLAG('o') || st
.st_mtime
< old
.st_mtime
) /* older than file */
66 && (!FLAG('p') || S_ISFIFO(st
.st_mode
)) /* named pipe */
67 && (!FLAG('r') || access(path
, R_OK
) == 0) /* readable */
68 && (!FLAG('s') || st
.st_size
> 0) /* not empty */
69 && (!FLAG('u') || st
.st_mode
& S_ISUID
) /* set-user-id flag */
70 && (!FLAG('w') || access(path
, W_OK
) == 0) /* writable */
71 && (!FLAG('x') || access(path
, X_OK
) == 0)) { /* executable */