Advertisement
Amorf

Untitled

Apr 17th, 2022
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.08 KB | None | 0 0
  1. #include <sys/types.h>
  2.  
  3. #include <sys/stat.h>
  4.  
  5. #include <unistd.h>
  6.  
  7. #include <stdio.h>
  8.  
  9. #include <string.h>
  10.  
  11. #include <stdlib.h>
  12.  
  13. #include <dirent.h>
  14.  
  15. #include <errno.h>
  16.  
  17. #include <memory.h>
  18.  
  19. /*----------------------------------------------
  20.  
  21. Функция GETKOL рекурсивная. Возвращает количичестов
  22.  
  23. файлов по заданной директории и поддерикториях.
  24.  
  25. ----------------------------------------------*/
  26.  
  27. int getkol(char* dirn) // Функция возращает количество рег. файлов в заданном каталоге включая подкаталоге
  28.  
  29. {
  30.  
  31. int dsize=0;//колич. файлов
  32.  
  33. DIR* dirs; //создаем указатель на поток директории
  34.  
  35. //if(*(dirn+(int)strlen(dirn)-1)==92) *(dirn+(int)strlen(dirn)-1)=0;
  36.  
  37. dirs = opendir(dirn); //открваем директорию с именем dirn
  38.  
  39. if (dirs) // если удается создать поток (открыть директорию)
  40.  
  41. {
  42.  
  43. struct dirent* dirstr; //создаем указатель на структуру для хранения
  44.  
  45. // элемента из потока директории
  46.  
  47. while(dirstr = readdir(dirs)) //пока удается получаем файл из потока
  48.  
  49. {
  50.  
  51. char* fnm=dirstr->d_name; //получаем из структуры имя файла
  52.  
  53. char* fullnm=(char*)alloca(strlen(dirn)+strlen(fnm)+1);//выделяем память по полное имя
  54.  
  55. //файла (путь + имя)
  56.  
  57. strcpy(fullnm,dirn);//операции для получения полного имени
  58.  
  59. strcat(fullnm,"/");
  60.  
  61. strcat(fullnm,fnm);
  62.  
  63. struct stat fst; //структура для хранения информации о файле
  64.  
  65. stat(fullnm,&fst); //получаем информацию о файле в структуру
  66.  
  67. if(S_ISREG(fst.st_mode)&&!S_ISLNK(fst.st_mode)) //Увеличиваем счетчик если файл
  68.  
  69. // регулярный и не является ссылкой (!второе условие не срабатывает (Ubuntu 10.04))
  70.  
  71. {
  72.  
  73. dsize++;
  74.  
  75. } else
  76.  
  77. if(S_ISDIR(fst.st_mode)&&strcmp(fnm,".")&&strcmp(fnm,"..")&&!S_ISLNK(fst.st_mode))//Если
  78.  
  79. //файл является каталогом и не является ссылкой(не сработало!).
  80.  
  81. // strcmp возвращает 0 если строки равны.
  82.  
  83. {
  84.  
  85. dsize=dsize+getkol(fullnm); //вызваем функцию рекурсивно
  86.  
  87. }
  88.  
  89. }
  90.  
  91. closedir(dirs); //закрываем каталог
  92.  
  93. }
  94.  
  95. else printf("Couldn't open derictory - %s\n",dirn);
  96.  
  97. return dsize;
  98.  
  99. }
  100.  
  101. /*----------------------------------------------
  102.  
  103. Функция GETLIST рекурсивна, на переданный указатель
  104.  
  105. записывает список имен файлов по заданому имени
  106.  
  107. каталога, а также заполняет соответственно массив
  108.  
  109. размеров каждого файла.
  110.  
  111. Входной параметр функциц "_i" служит для получения
  112.  
  113. числа фактически считанных файлов.
  114.  
  115. ----------------------------------------------*/
  116.  
  117. void getlist(int* _i,char** _str,char* dirn,int* _fsize)
  118.  
  119. {
  120.  
  121. DIR* dirs;
  122.  
  123. dirs = opendir(dirn);
  124.  
  125. if (dirs)
  126.  
  127. {
  128.  
  129. struct dirent* dirstr;
  130.  
  131. while(dirstr = readdir(dirs))
  132.  
  133. {
  134.  
  135. char* fnm=dirstr->d_name; //получаем из структуры имя файла
  136.  
  137. char* fullnm=(char*)alloca(strlen(dirn)+strlen(fnm)+1);
  138.  
  139. strcpy(fullnm,dirn);
  140.  
  141. strcat(fullnm,"/");
  142.  
  143. strcat(fullnm,fnm);
  144.  
  145. struct stat fst;
  146.  
  147. stat(fullnm,&fst);
  148.  
  149. if(S_ISREG(fst.st_mode)&&!S_ISLNK(fst.st_mode))
  150.  
  151. {
  152.  
  153. strcpy(_str[*_i],fullnm);//копирование полного имени файла в массив
  154.  
  155. *(_fsize+*_i)=fst.st_size;//заполняем массив размера файла
  156.  
  157. (*_i)++;
  158.  
  159. }
  160.  
  161. if(S_ISDIR(fst.st_mode)&&strcmp(fnm,".")&&strcmp(fnm,"..")&&!S_ISLNK(fst.st_mode))
  162.  
  163. {
  164.  
  165. getlist(_i,_str,fullnm,_fsize); //если файл каталог функция вызывает саму себя
  166.  
  167. }
  168.  
  169. }
  170.  
  171. closedir(dirs);
  172.  
  173. }
  174.  
  175. else printf("Couldn't open derictory - %s\n",dirn);
  176.  
  177. }
  178.  
  179. /*----------------------------------------------
  180.  
  181. Функция создает новый процесс в котором сравниваются
  182.  
  183. два фала. Входные параметры: имя первого, имя второго и размер
  184.  
  185. файла. В функцию буду передаватся только файлы одинакового размера.
  186.  
  187. ----------------------------------------------*/
  188.  
  189. int xfork(char *fnm1,char *fnm2,int* _fs)
  190.  
  191. {
  192.  
  193. int ppid = fork(); //создается новый дочерний процесс
  194.  
  195. if(ppid==0) //если процесс ребенок
  196.  
  197. {
  198.  
  199. int t=0;
  200.  
  201. FILE* fd1 = fopen(fnm1,"r");
  202.  
  203. FILE* fd2 = fopen(fnm2,"r");
  204.  
  205. while(abs(fgetc(fd1))==fgetc(fd2)) t++;//сравниваем посимвольно
  206.  
  207. //выводим форматированную строку с результатом
  208.  
  209. printf("\n_____ PID: %d ____\n1> %s\n2> %s\n === Result: %d of %d bytes match ===\n",getpid(),fnm1,fnm2,t,*_fs);
  210.  
  211. fclose(fd1);
  212.  
  213. fclose(fd2);
  214.  
  215. }
  216.  
  217. return ppid;
  218.  
  219. }
  220.  
  221. /*----------------------------------------------
  222.  
  223. Главная функция. Входные параметры получаем из командной строки.
  224.  
  225. ----------------------------------------------*/
  226.  
  227. main(int argc, char *argv[])
  228.  
  229. {
  230.  
  231. if(argc>4)//Если задано параметров больше чем требуетсяэ
  232.  
  233. {
  234.  
  235. puts("Put that info in argv: DIR1 DIR2 N");
  236.  
  237. exit(1);
  238.  
  239. }
  240.  
  241. char* fnm1=argv[1];//Получаем имена файлов.
  242.  
  243. char* fnm2=argv[2];
  244.  
  245. int N;
  246.  
  247. if(!sscanf(argv[3],"%d",&N))//Если вместо числа одновременно
  248.  
  249. { //запущеных процессоввведена строка.
  250.  
  251. puts("Not whole number");
  252.  
  253. exit(1);
  254.  
  255. }
  256.  
  257. errno=0; //Обнуляем переменную ошибок описанную в заголовочом файле.
  258.  
  259. char** str1; // Список файлов в директориях, поддерикториях.
  260.  
  261. char** str2;
  262.  
  263. int* fsize1; // Массив размеров.
  264.  
  265. int* fsize2; // Массив размеров.
  266.  
  267. int ksize1=getkol(argv[1]); //Подсчитываем файлы в 2ух каталогах
  268.  
  269. int ksize2=getkol(argv[2]);
  270.  
  271. printf("Total files found: %d ",ksize1+ksize2);
  272.  
  273. /*----------------------------------------------
  274.  
  275. Далее идет процесс выделения памяти под необходимые данные
  276.  
  277. ----------------------------------------------*/
  278.  
  279. str1=malloc(ksize1*(sizeof(char*)));
  280.  
  281. str2=malloc(ksize2*(sizeof(char*)));
  282.  
  283. fsize1=malloc(ksize1*(sizeof(int)));
  284.  
  285. fsize2=malloc(ksize2*(sizeof(int)));
  286.  
  287. int i=0; //переменная счетчик
  288.  
  289. while(i<ksize1)
  290.  
  291. {
  292.  
  293. *(str1+i)=malloc(512*sizeof(char));
  294.  
  295. i++;
  296.  
  297. }
  298.  
  299. i=0;
  300.  
  301. while(i<ksize2)
  302.  
  303. {
  304.  
  305. *(str2+i)=malloc(512*sizeof(char));
  306.  
  307. i++;
  308.  
  309. }
  310.  
  311. ksize1=0;
  312.  
  313. ksize2=0;//обнуляем размер
  314.  
  315. getlist(&ksize1,str1,argv[1],fsize1);//получаем список имен и размеров файлов
  316.  
  317. getlist(&ksize2,str2,argv[2],fsize2);
  318.  
  319. printf("Total files read: %d\n",ksize1+ksize2);
  320.  
  321. /*i=0;
  322.  
  323. while(i<ksize)//Выводим список файлов и размер каждого
  324.  
  325. {
  326.  
  327. printf("%s -- %d bytes\n",*(str+i),*(size+i));
  328.  
  329. i++;
  330.  
  331. }*/
  332.  
  333. i=0; //обнуляем счетчик
  334.  
  335. int fr=1; //результат работы фокр
  336.  
  337. int k,n=0; // переменные счетчики
  338.  
  339. while(i<ksize1) //в этом цикле берется итый размер файла из первого каталога
  340.  
  341. {
  342.  
  343. k=0;//катый размер во 2ом каталоге
  344.  
  345. while(k<ksize2) //катый размер 2ого каталога
  346.  
  347. {
  348.  
  349. if(fr > 0)//если процесс родетельский
  350.  
  351. {
  352.  
  353. if(*(fsize1+i)==*(fsize2+k))//если совпали размеры
  354.  
  355. {
  356.  
  357. if(n++>N) wait(); //Если запущено больше N процессов
  358.  
  359. //ждем первого завершивсегося.
  360.  
  361. fr=xfork(*(str1+i),*(str2+k),fsize1+i);
  362.  
  363. //Вызвали функцию сравнения в новом процессе.
  364.  
  365. }
  366.  
  367. k++;
  368.  
  369. } else break;//если процесс не родительский прерываем цикл
  370.  
  371. }
  372.  
  373. i++;
  374.  
  375. }
  376.  
  377. if(fr>0)//если процесс родетельский
  378.  
  379. {
  380.  
  381. while(wait()>0); //ожидание завершения всех доч. процессов.
  382.  
  383. char *err= strerror(errno);//проверяме переменную ошибок
  384.  
  385. printf("\nErrno result: %s \n",err);//Выводим отчет об ошибках.
  386.  
  387. }
  388.  
  389. //далее освобождаем динамическую память
  390.  
  391. i=0;
  392.  
  393. while(i<ksize1)
  394.  
  395. {
  396.  
  397. free(*(str1+i));
  398.  
  399. i++;
  400.  
  401. }
  402.  
  403. while(i<ksize2)
  404.  
  405. {
  406.  
  407. free(*(str2+i));
  408.  
  409. i++;
  410.  
  411. }
  412.  
  413. free(str1);
  414.  
  415. free(str2);
  416.  
  417. free(fsize1);
  418.  
  419. free(fsize2);
  420.  
  421. return 0;
  422.  
  423. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement