PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/commands/find.c

http://minishell-uvt.googlecode.com/
C | 212 lines | 131 code | 43 blank | 38 comment | 39 complexity | a62db096182541d36455a8ee89251548 MD5 | raw file
  1. /*
  2. * Unix Find command
  3. * Author: Rimescu Adi-Ciprian
  4. */
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <unistd.h>
  8. #include <dirent.h>
  9. #include <regex.h>
  10. #include <stdio.h>
  11. #include <ftw.h>
  12. #include <getopt.h>
  13. /*
  14. * Constants declaration
  15. */
  16. #define ERR_DIR_NOT_OPEN "Directory could not be opened."
  17. #define ERR_DIR_STAT_FAILED "Stat could not be read."
  18. #define ERR_DIR_CH_FAILED "Directory could not be changed."
  19. #define MAX_OPTIONS 20
  20. /*
  21. * Functions prototypes
  22. */
  23. void find(char *);
  24. int list(const char*, const struct stat *, int);
  25. /*
  26. * Global variables;
  27. */
  28. static int verbose_flag;
  29. char **options_array = NULL;
  30. char **argument_array = NULL;
  31. int opt_arg_array_index = 0;
  32. int main(int argc, char **argv)
  33. {
  34. // If no last argument is provided,
  35. // then consider root as default.
  36. char *search_path = NULL;
  37. int c;
  38. // Dynamic alocate memory.
  39. options_array = malloc(MAX_OPTIONS * sizeof(char *));
  40. argument_array = malloc(20 * sizeof(char *));
  41. while (1) {
  42. static struct option long_options[] = {
  43. /* These options set a flag. */
  44. {"verbose", 0, &verbose_flag, 1},
  45. {"brief", 0, &verbose_flag, 0},
  46. /* These options don't set a flag.
  47. We distinguish them by their indices. */
  48. {"amin", 1, 0, 'a'},
  49. {"anewer", 1, 0, 'b'},
  50. {"atime", 1, 0, 'c'},
  51. {"cmin", 1, 0, 'd'},
  52. {"cnewer", 1, 0, 'e'},
  53. {"ctime", 1, 0, 'f'},
  54. {"mmin", 1, 0, 'g'},
  55. {"newer", 1, 0, 'h'},
  56. {"mtime", 1, 0, 'i'},
  57. {"name", 1, 0, 'j'},
  58. {"iname", 1, 0, 'k'},
  59. {"type", 1, 0, 'l'},
  60. {"size", 1, 0, 'm'},
  61. {"perm", 1, 0, 'n'},
  62. {"readable", 1, 0, 'o'},
  63. {"executable", 1, 0, 'p'},
  64. {"writable", 1, 0, 'r'},
  65. {0, 0, 0, 0}
  66. };
  67. /* getopt_long stores the option index here. */
  68. int option_index = 0;
  69. c = getopt_long_only (argc, argv, "a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:r:",
  70. long_options, &option_index);
  71. /* Detect the end of the options. */
  72. if (c == -1)
  73. break;
  74. switch (c) {
  75. case 0:
  76. /* If this option set a flag, do nothing else now. */
  77. if (long_options[option_index].flag != 0)
  78. break;
  79. printf ("option %s", long_options[option_index].name);
  80. if (optarg)
  81. printf (" with arg %s", optarg);
  82. printf ("\n");
  83. break;
  84. /// AMIN
  85. case 'a':
  86. options_array[opt_arg_array_index] = malloc(100 * sizeof(char));
  87. strcpy(options_array[opt_arg_array_index], "amin");
  88. argument_array[opt_arg_array_index] = malloc(sizeof(optarg));
  89. strcpy(argument_array[opt_arg_array_index], optarg);
  90. opt_arg_array_index++;
  91. break;
  92. /// TYPE
  93. case 'l':
  94. options_array[opt_arg_array_index] = malloc(100 * sizeof(char));
  95. strcpy(options_array[opt_arg_array_index], "type");
  96. argument_array[opt_arg_array_index] = malloc(sizeof(optarg));
  97. strcpy(argument_array[opt_arg_array_index], optarg);
  98. opt_arg_array_index++;
  99. break;
  100. case '?':
  101. /* getopt_long already printed an error message. */
  102. break;
  103. default:
  104. abort ();
  105. }
  106. }
  107. search_path = malloc(100 * sizeof(char));
  108. /* Any remaining command line argument is considered to be the search path. */
  109. if (optind < argc) {
  110. search_path = argv[optind++];
  111. } else {
  112. search_path = "/";
  113. }
  114. find(search_path);
  115. return 0;
  116. }
  117. int list(const char *name, const struct stat *status, int type) {
  118. // FTW_F The object is a file
  119. // FTW_D ,, ,, ,, ,, directory
  120. // FTW_DNR ,, ,, ,, ,, directory that could not be read
  121. // FTW_SL ,, ,, ,, ,, symbolic link
  122. // FTW_NS The object is NOT a symbolic link and is one for
  123. // which stat() could not be executed
  124. if(type == FTW_NS)
  125. return 0;
  126. int is_valid_result = 1;
  127. // If we have elements in the options array,
  128. // then apply search filters, else simply act
  129. // as recursive "ls".
  130. if(opt_arg_array_index > 0) {
  131. int i;
  132. for(i=0; i<opt_arg_array_index; i++) {
  133. /// AMIN - accessed minutes ago
  134. if(strcmp(options_array[opt_arg_array_index], "amin") == 0) {
  135. char *argument = argument_array[opt_arg_array_index];
  136. if(argument[0] == '+') {
  137. //status->st_atime
  138. } else if(argument[0] == '-') {
  139. } else {
  140. }
  141. is_valid_result = 0;
  142. }
  143. /// TYPE (file, directory, link)
  144. if(strcmp(options_array[opt_arg_array_index], "type") == 0) {
  145. is_valid_result = 0;
  146. if((strcmp(argument_array[opt_arg_array_index], "file") == 0) &&
  147. type == FTW_F)
  148. is_valid_result = 1;
  149. if((strcmp(argument_array[opt_arg_array_index], "directory") == 0) &&
  150. type == FTW_D)
  151. is_valid_result = 1;
  152. if((strcmp(argument_array[opt_arg_array_index], "link") == 0) &&
  153. type == FTW_SL)
  154. is_valid_result = 1;
  155. }
  156. }
  157. }
  158. if(is_valid_result) {
  159. if(type == FTW_F)
  160. printf("%s\n", name);
  161. if(type == FTW_D && strcmp(".", name) != 0)
  162. printf("%s/\n", name);
  163. }
  164. return 0;
  165. }
  166. void find(char *path) {
  167. printf("Results found:\n\n");
  168. ftw(path, list, 1);
  169. }