dmenu for lunch applications in dwm
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
2.8 KiB

13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
  1. /* See LICENSE file for copyright and license details. */
  2. #include <dirent.h>
  3. #include <stdbool.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <sys/stat.h>
  9. #define FLAG(x) (flag[(x)-'a'])
  10. static void test(const char *, const char *);
  11. static bool match = false;
  12. static bool flag[26];
  13. static struct stat old, new;
  14. int
  15. main(int argc, char *argv[]) {
  16. struct dirent *d;
  17. char buf[BUFSIZ];
  18. DIR *dir;
  19. int opt;
  20. while((opt = getopt(argc, argv, "abcdefghln:o:pqrsuwx")) != -1)
  21. switch(opt) {
  22. case 'n': /* newer than file */
  23. case 'o': /* older than file */
  24. if(!(FLAG(opt) = !stat(optarg, (opt == 'n' ? &new : &old))))
  25. perror(optarg);
  26. break;
  27. default: /* miscellaneous operators */
  28. FLAG(opt) = true;
  29. break;
  30. case '?': /* error: unknown flag */
  31. fprintf(stderr, "usage: %s [-abcdefghlpqrsuwx] [-n file] [-o file] [file...]\n", argv[0]);
  32. exit(2);
  33. }
  34. for(; optind < argc; optind++)
  35. if(FLAG('l') && (dir = opendir(argv[optind]))) {
  36. /* test directory contents */
  37. while((d = readdir(dir)))
  38. if(snprintf(buf, sizeof buf, "%s/%s", argv[optind], d->d_name) < sizeof buf)
  39. test(buf, d->d_name);
  40. closedir(dir);
  41. }
  42. else
  43. test(argv[optind], argv[optind]);
  44. return match ? 0 : 1;
  45. }
  46. void
  47. test(const char *path, const char *name) {
  48. struct stat st, ln;
  49. if(!stat(path, &st) && !lstat(path, &ln)
  50. && ( FLAG('a') || name[0] != '.') /* hidden */
  51. && (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */
  52. && (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */
  53. && (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */
  54. && (!FLAG('e') || access(path, F_OK) == 0) /* exists */
  55. && (!FLAG('f') || S_ISREG(st.st_mode)) /* regular file */
  56. && (!FLAG('g') || st.st_mode & S_ISGID) /* set-group-id flag */
  57. && (!FLAG('h') || (!lstat(path, &ln) && S_ISLNK(ln.st_mode))) /* symbolic link */
  58. && (!FLAG('n') || st.st_mtime > new.st_mtime) /* newer than file */
  59. && (!FLAG('o') || st.st_mtime < old.st_mtime) /* older than file */
  60. && (!FLAG('p') || S_ISFIFO(st.st_mode)) /* named pipe */
  61. && (!FLAG('r') || access(path, R_OK) == 0) /* readable */
  62. && (!FLAG('s') || st.st_size > 0) /* not empty */
  63. && (!FLAG('u') || st.st_mode & S_ISUID) /* set-user-id flag */
  64. && (!FLAG('w') || access(path, W_OK) == 0) /* writable */
  65. && (!FLAG('x') || access(path, X_OK) == 0)) { /* executable */
  66. if(FLAG('q'))
  67. exit(0);
  68. match = true;
  69. puts(name);
  70. }
  71. }