Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <limits.h> // PATH_MAX
- #include <errno.h>
- #include <time.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <dirent.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <libgen.h>
- /* defines */
- #define MAXLEN 40 //размер буфера для записи в файл
- /* types */
- struct eval { //структура параметров условия
- off_t sMin, sMax; // минимальный & максимальный размеры
- time_t dMin, dMax; // минимальный & максимальный дата создания
- };
- typedef struct eval EVAL;
- typedef struct dirent DIRENT; // dirent.h
- typedef struct stat STAT; // sys/stat.h
- /* prototypes */
- int check_args(char []); //проверяет аргументы на валидность
- int open_dir(DIR **, char *); //открывает директорию, учтён контроль контроль за ошибками
- int close_dir(DIR **, char *); //закрывает и тоже учтено
- int processing(char *); //просмотро каталогов
- int inFile(char *); //функция записи результата в файл
- time_t code_date(char []); //кодирует дату
- char *decode_date(time_t); //декодирует дату
- /* global */
- static EVAL data; //здесь наши параметры
- static char foutput[PATH_MAX]; //путь к файлу с результатами
- static int fdesc = 0; //файловый дескриптор файлы результатов
- static char *program = NULL; //имя программмы
- int numFile = 0;
- /* source */
- int main(int argc, char *argv[]) //argv - массив аргументов argc - количество аргументов
- {
- char curDir[PATH_MAX]; //каталог для поиска
- if (argc != 7) { //проверка на кол-во аргументов
- fprintf(stderr, "%s: Too few arguments: %d\n", program, argc); //поток ошибок!
- exit(1);
- }
- /* input data */
- //program = &(argv[0][(strlen(argv[0]) - strlen(strrchr(argv[0], '/'))) + 1]);
- program = basename(argv[0]);
- strcpy(curDir, argv[1]); //argv[1] - PATH for search
- strcpy(foutput, argv[2]); //argv[2] - PATH to output file
- /* sizes */
- data.sMin = atoi(argv[3]); //перевод размеров в int из char*
- data.sMax = atoi(argv[4]);
- /* dates of create */
- data.dMin = code_date(argv[5]); //кодирование data для сравнения в секунды
- data.dMax = code_date(argv[6]);
- /* open file */
- if ((fdesc = open(foutput, O_WRONLY)) == -1) { //открытие файла для вывода результатов
- fprintf(stderr, "%s: %s: %s\n", program, strerror(errno), foutput); // вывод ошибки
- }
- check_args(curDir);
- processing(curDir);
- /* close file */
- close(fdesc); //закрытие файлов с результатами
- printf("%d \n", numFile);
- return 0;
- }
- time_t code_date(char date[]) //кодирование даты из формата например 1.1.1970 в три переменных типа int
- {
- struct tm t; //объявлена в time.h
- memset(&t, 0, sizeof(t));
- /* separate string */
- t.tm_mday = atoi(strtok(date, ".")); //занесение дня
- t.tm_mon = atoi(strtok(NULL, ".")) - 1; //занесение месяца
- t.tm_year = atoi(strtok(NULL, ".")) - 1900; //занесение года
- return mktime(&t); //возвращаем секунды (объявлена в time.h)
- }
- char *decode_date(time_t date) //декодирование, перевод из секунд в формат 1.1.1970
- {
- static char buf[MAXLEN];
- struct tm *t = localtime(&date);
- sprintf(buf, "%d.%d.%d", (*t).tm_mday, (*t).tm_mon + 1, (*t).tm_year + 1900);
- return buf;
- }
- int check_args(char *curDir) {
- char buf[PATH_MAX], tmp[50];
- buf[0] = '\0';
- if ((curDir)[strlen(curDir) - 1] == '/' && strlen(curDir) > 1) {
- (curDir)[strlen(curDir) - 1] = '\0';
- }
- if (!strcmp(curDir, ".") || (curDir[0] == '.' && curDir[1] =='/')) {
- getcwd(buf, PATH_MAX);
- strcpy(curDir,&(curDir[1]));
- strcat(buf, curDir);
- strcpy(curDir, buf);
- }
- if (!strcmp(curDir, "..") || (curDir[0] == '.' && curDir[1] == '.' && curDir[2] == '/')) {
- getcwd(buf, PATH_MAX);
- strcpy(curDir, &(curDir[2]));
- strcpy(tmp, curDir);
- strncpy(curDir, buf, strlen(buf) - strlen(strrchr(buf, '/')));
- strcat(curDir, tmp);
- }
- return 0;
- }
- int open_dir(DIR **dir, char *path) //открытие директории
- {
- if ((*dir = opendir(path)) == NULL) { //откытие директории path в структуру dir
- fprintf(stderr, "%s: %s: %s\n", program, strerror(errno), path); //ошибка
- return -1;
- }
- return 0;
- }
- int close_dir(DIR **dir, char *path) //закрытие директории
- {
- if (*dir != NULL) {
- if (closedir(*dir) != 0) {
- fprintf(stderr, "%s: %s: %s\n", program, strerror(errno), path); //ошибка
- exit(1);
- }
- }
- return 0;
- }
- int processing(char *path) //рекурсивная функция просмотра директорий
- {
- DIR *dir = NULL; //тут хранится информация о текущей открытой директории
- DIRENT *curPath = NULL; //путь к текущему рассматриваемому файлу
- STAT curInfo; //тут хранится информация о текущем рассматриваемом файле
- char pathName[PATH_MAX], *buf = NULL;
- open_dir(&dir, path); //открытие директории
- if (dir == NULL) { //если директория пуста
- return 0;
- }
- errno = 0;
- while ((curPath = readdir(dir)) != NULL) { //читаем файлы из директории
- if (errno != 0) {
- fprintf(stderr, "%s: %s: %s\n", program, strerror(errno), pathName);
- continue;
- }
- if ((!strcmp((*curPath).d_name, ".")) || (!strcmp((*curPath).d_name, ".."))) { //если попался файл . или .. ,то ничего не делаем
- continue;
- }
- if (!((*curPath).d_type == DT_REG || (*curPath).d_type == DT_DIR)) continue; //исправление ошибки No such File or Directory
- if (strcmp(path, "/")==0) //если у нас путь '/'
- sprintf(pathName, "%s%s", path, (*curPath).d_name); //то обрезаем его
- else sprintf(pathName, "%s/%s", path, (*curPath).d_name); //прибавляем к текущему пути рассматриваемый файл
- // full PATH
- if (stat(pathName, &curInfo) == 0) { //получаем инфу о файле в структуру
- if (S_ISDIR(curInfo.st_mode)) { //если текущий файл оказался директорией, то заходим в рекурсию
- processing(pathName);
- }
- else {
- //printf("%s - %o\n", (*curPath).d_name, curInfo.st_mode); //выводим его на экран, в противном случае
- /////////////////////////////////////////////////////////////////////////////////////
- //проверка по нашим критериям //проверка по размеру
- if (curInfo.st_size > data.sMin && curInfo.st_size < data.sMax
- && curInfo.st_ctime >= data.dMin && curInfo.st_ctime <= data.dMax) { //проверка по дате
- buf = malloc(strlen(pathName) + strlen((*curPath).d_name) + MAXLEN); //выделение памяти для строки с ответом
- sprintf(buf, "%s %lu %s\n", pathName, curInfo.st_size, decode_date(curInfo.st_ctime)); //формирование строки с ответом
- printf("%s", buf); //вывод её на экран
- ++numFile;
- inFile(buf); //вывод в файл
- free(buf); //очищаем память
- }
- //////////////////////////////////////////////////////////////////////////////////////
- }
- }
- else {
- fprintf(stderr, "%s: %s: %s\n", program, strerror(errno), pathName); //вывод ошибки на stat
- }
- errno = 0;
- }
- close_dir(&dir, path);
- return 0;
- }
- int inFile(char *buf) //вывод ответа в файл
- {
- write(fdesc, buf, strlen(buf));
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement