Advertisement
Guest User

Untitled

a guest
Apr 18th, 2014
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.16 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <limits.h> // PATH_MAX
  5. #include <errno.h>
  6. #include <time.h>
  7.  
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <dirent.h>
  11. #include <unistd.h>
  12. #include <fcntl.h>
  13. #include <libgen.h>
  14.  
  15. /* defines */
  16. #define MAXLEN 40 //размер буфера для записи в файл
  17.  
  18. /* types */
  19. struct eval { //структура параметров условия
  20. off_t sMin, sMax; // минимальный & максимальный размеры
  21. time_t dMin, dMax; // минимальный & максимальный дата создания
  22. };
  23.  
  24. typedef struct eval EVAL;
  25. typedef struct dirent DIRENT; // dirent.h
  26. typedef struct stat STAT; // sys/stat.h
  27.  
  28. /* prototypes */
  29. int check_args(char []); //проверяет аргументы на валидность
  30. int open_dir(DIR **, char *); //открывает директорию, учтён контроль контроль за ошибками
  31. int close_dir(DIR **, char *); //закрывает и тоже учтено
  32. int processing(char *); //просмотро каталогов
  33. int inFile(char *); //функция записи результата в файл
  34. time_t code_date(char []); //кодирует дату
  35. char *decode_date(time_t); //декодирует дату
  36.  
  37. /* global */
  38. static EVAL data; //здесь наши параметры
  39. static char foutput[PATH_MAX]; //путь к файлу с результатами
  40. static int fdesc = 0; //файловый дескриптор файлы результатов
  41. static char *program = NULL; //имя программмы
  42. int numFile = 0;
  43.  
  44.  
  45. /* source */
  46. int main(int argc, char *argv[]) //argv - массив аргументов argc - количество аргументов
  47. {
  48. char curDir[PATH_MAX]; //каталог для поиска
  49.  
  50. if (argc != 7) { //проверка на кол-во аргументов
  51. fprintf(stderr, "%s: Too few arguments: %d\n", program, argc); //поток ошибок!
  52. exit(1);
  53. }
  54.  
  55. /* input data */
  56. //program = &(argv[0][(strlen(argv[0]) - strlen(strrchr(argv[0], '/'))) + 1]);
  57. program = basename(argv[0]);
  58. strcpy(curDir, argv[1]); //argv[1] - PATH for search
  59. strcpy(foutput, argv[2]); //argv[2] - PATH to output file
  60. /* sizes */
  61. data.sMin = atoi(argv[3]); //перевод размеров в int из char*
  62. data.sMax = atoi(argv[4]);
  63. /* dates of create */
  64. data.dMin = code_date(argv[5]); //кодирование data для сравнения в секунды
  65. data.dMax = code_date(argv[6]);
  66.  
  67. /* open file */
  68. if ((fdesc = open(foutput, O_WRONLY)) == -1) { //открытие файла для вывода результатов
  69. fprintf(stderr, "%s: %s: %s\n", program, strerror(errno), foutput); // вывод ошибки
  70. }
  71.  
  72. check_args(curDir);
  73.  
  74. processing(curDir);
  75.  
  76. /* close file */
  77. close(fdesc); //закрытие файлов с результатами
  78. printf("%d \n", numFile);
  79.  
  80. return 0;
  81.  
  82. }
  83.  
  84. time_t code_date(char date[]) //кодирование даты из формата например 1.1.1970 в три переменных типа int
  85. {
  86. struct tm t; //объявлена в time.h
  87. memset(&t, 0, sizeof(t));
  88. /* separate string */
  89. t.tm_mday = atoi(strtok(date, ".")); //занесение дня
  90. t.tm_mon = atoi(strtok(NULL, ".")) - 1; //занесение месяца
  91. t.tm_year = atoi(strtok(NULL, ".")) - 1900; //занесение года
  92.  
  93. return mktime(&t); //возвращаем секунды (объявлена в time.h)
  94. }
  95.  
  96. char *decode_date(time_t date) //декодирование, перевод из секунд в формат 1.1.1970
  97. {
  98. static char buf[MAXLEN];
  99. struct tm *t = localtime(&date);
  100.  
  101. sprintf(buf, "%d.%d.%d", (*t).tm_mday, (*t).tm_mon + 1, (*t).tm_year + 1900);
  102.  
  103. return buf;
  104. }
  105.  
  106.  
  107.  
  108. int check_args(char *curDir) {
  109. char buf[PATH_MAX], tmp[50];
  110.  
  111. buf[0] = '\0';
  112. if ((curDir)[strlen(curDir) - 1] == '/' && strlen(curDir) > 1) {
  113. (curDir)[strlen(curDir) - 1] = '\0';
  114. }
  115.  
  116. if (!strcmp(curDir, ".") || (curDir[0] == '.' && curDir[1] =='/')) {
  117. getcwd(buf, PATH_MAX);
  118. strcpy(curDir,&(curDir[1]));
  119. strcat(buf, curDir);
  120. strcpy(curDir, buf);
  121. }
  122.  
  123. if (!strcmp(curDir, "..") || (curDir[0] == '.' && curDir[1] == '.' && curDir[2] == '/')) {
  124. getcwd(buf, PATH_MAX);
  125. strcpy(curDir, &(curDir[2]));
  126. strcpy(tmp, curDir);
  127. strncpy(curDir, buf, strlen(buf) - strlen(strrchr(buf, '/')));
  128. strcat(curDir, tmp);
  129. }
  130.  
  131. return 0;
  132. }
  133.  
  134.  
  135.  
  136. int open_dir(DIR **dir, char *path) //открытие директории
  137. {
  138. if ((*dir = opendir(path)) == NULL) { //откытие директории path в структуру dir
  139. fprintf(stderr, "%s: %s: %s\n", program, strerror(errno), path); //ошибка
  140. return -1;
  141. }
  142. return 0;
  143. }
  144.  
  145. int close_dir(DIR **dir, char *path) //закрытие директории
  146. {
  147. if (*dir != NULL) {
  148. if (closedir(*dir) != 0) {
  149. fprintf(stderr, "%s: %s: %s\n", program, strerror(errno), path); //ошибка
  150. exit(1);
  151. }
  152. }
  153. return 0;
  154. }
  155.  
  156. int processing(char *path) //рекурсивная функция просмотра директорий
  157. {
  158. DIR *dir = NULL; //тут хранится информация о текущей открытой директории
  159. DIRENT *curPath = NULL; //путь к текущему рассматриваемому файлу
  160. STAT curInfo; //тут хранится информация о текущем рассматриваемом файле
  161. char pathName[PATH_MAX], *buf = NULL;
  162.  
  163.  
  164. open_dir(&dir, path); //открытие директории
  165. if (dir == NULL) { //если директория пуста
  166. return 0;
  167. }
  168.  
  169. errno = 0;
  170.  
  171. while ((curPath = readdir(dir)) != NULL) { //читаем файлы из директории
  172.  
  173. if (errno != 0) {
  174. fprintf(stderr, "%s: %s: %s\n", program, strerror(errno), pathName);
  175. continue;
  176. }
  177.  
  178. if ((!strcmp((*curPath).d_name, ".")) || (!strcmp((*curPath).d_name, ".."))) { //если попался файл . или .. ,то ничего не делаем
  179. continue;
  180. }
  181. if (!((*curPath).d_type == DT_REG || (*curPath).d_type == DT_DIR)) continue; //исправление ошибки No such File or Directory
  182.  
  183. if (strcmp(path, "/")==0) //если у нас путь '/'
  184. sprintf(pathName, "%s%s", path, (*curPath).d_name); //то обрезаем его
  185. else sprintf(pathName, "%s/%s", path, (*curPath).d_name); //прибавляем к текущему пути рассматриваемый файл
  186.  
  187. // full PATH
  188.  
  189.  
  190. if (stat(pathName, &curInfo) == 0) { //получаем инфу о файле в структуру
  191. if (S_ISDIR(curInfo.st_mode)) { //если текущий файл оказался директорией, то заходим в рекурсию
  192. processing(pathName);
  193. }
  194. else {
  195.  
  196. //printf("%s - %o\n", (*curPath).d_name, curInfo.st_mode); //выводим его на экран, в противном случае
  197. /////////////////////////////////////////////////////////////////////////////////////
  198.  
  199.  
  200. //проверка по нашим критериям //проверка по размеру
  201. if (curInfo.st_size > data.sMin && curInfo.st_size < data.sMax
  202. && curInfo.st_ctime >= data.dMin && curInfo.st_ctime <= data.dMax) { //проверка по дате
  203.  
  204. buf = malloc(strlen(pathName) + strlen((*curPath).d_name) + MAXLEN); //выделение памяти для строки с ответом
  205.  
  206. sprintf(buf, "%s %lu %s\n", pathName, curInfo.st_size, decode_date(curInfo.st_ctime)); //формирование строки с ответом
  207. printf("%s", buf); //вывод её на экран
  208. ++numFile;
  209. inFile(buf); //вывод в файл
  210.  
  211.  
  212. free(buf); //очищаем память
  213. }
  214. //////////////////////////////////////////////////////////////////////////////////////
  215. }
  216. }
  217. else {
  218. fprintf(stderr, "%s: %s: %s\n", program, strerror(errno), pathName); //вывод ошибки на stat
  219. }
  220. errno = 0;
  221. }
  222. close_dir(&dir, path);
  223.  
  224. return 0;
  225. }
  226.  
  227.  
  228. int inFile(char *buf) //вывод ответа в файл
  229. {
  230. write(fdesc, buf, strlen(buf));
  231.  
  232. return 0;
  233. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement