Advertisement
Guest User

Untitled

a guest
Apr 24th, 2019
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.58 KB | None | 0 0
  1.  
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include <signal.h>
  7. #include <dirent.h>
  8. #include <string.h>
  9. #include <time.h>
  10. #include <fcntl.h>
  11. #include <sys/types.h>
  12. #include <sys/stat.h>
  13. #include <syslog.h>
  14. #include <sys/mman.h>
  15.  
  16. int sleepTime = 300;
  17. int sig_check = 0;
  18. int isRecurention = 0;
  19. int isCopyingByParametr = 0;
  20.  
  21. int checkParameters(int argc, char *argv[])
  22. {
  23. // Sprawdzenie czy 1. i 2. argument jest sciezka do katalogu
  24. struct stat file, file2;
  25. stat(argv[1], &file);
  26. if (!S_ISDIR(file.st_mode))
  27. {
  28. printf("Sciezka %s nie prowadzi do katalogu!\n", argv[1]);
  29. return 0;
  30. }
  31. stat(argv[2], &file2);
  32. if (!S_ISDIR(file2.st_mode))
  33. {
  34. printf("Sciezka %s nie prowadzi do katalogu!\n", argv[2]);
  35. return 0;
  36. }
  37.  
  38.  
  39. if (argc >= 7)
  40. return 0;
  41.  
  42. // Sprawdzenie 3. argumentu ( Czy jest liczba )
  43. if (argc >= 4)
  44. {
  45. if (atoi(argv[3]) > 0)
  46. sleepTime = atoi(argv[3]);
  47. else
  48. {
  49. printf("Zly 3 parametr!!");
  50. return 0;
  51. }
  52. }
  53.  
  54. // Sprawdzenie czy zostal przekazany 4. argument i jego wartosci
  55.  
  56. if (argc >= 5)
  57. {
  58. if (!strcmp(argv[4], "-R"))
  59. {
  60. isRecurention = 1;
  61. }
  62. else
  63. {
  64. if (atoi(argv[4]) > 0)
  65. {
  66. isCopyingByParametr = atoi(argv[4]);
  67. }
  68. else
  69. {
  70. printf("Zly 4 parametr!!!\n");
  71. return 0;
  72. }
  73. }
  74. }
  75.  
  76. // Sprawdzenie czy zostal przekazany 5. argument i jego wartosci
  77.  
  78. if (argc == 6)
  79. {
  80. if (!strcmp(argv[5], "-R") && isRecurention == 0)
  81. {
  82. isRecurention = 1;
  83. }
  84. else
  85. {
  86. if (atoi(argv[5]) > 0 && isCopyingByParametr == 0)
  87. {
  88. isCopyingByParametr = atoi(argv[5]);
  89. }
  90. else
  91. {
  92. printf("Zly 5 parametr!!!\n");
  93. return 0;
  94. }
  95. }
  96. }
  97.  
  98. return -1;
  99. }
  100.  
  101. void signalHandler()
  102. {
  103. syslog(LOG_INFO, "Demon odebral sygnal SIGURS1\n");
  104. sig_check = 1;
  105. }
  106.  
  107.  
  108. /* Zmiana czasu modyfikacji pliku
  109. void changeModifyTime(char *path)
  110. {
  111. struct stat attribSource;
  112. stat(path, &attribSource);
  113. time_t result = time(NULL);
  114. result += 2 * sleepTime;
  115. printf("%s\n", asctime(gmtime(&result)));
  116. attribSource.st_mtime = result;
  117. }
  118. */
  119.  
  120. // funkcja zwraca wielkosc pliku
  121.  
  122. size_t getFileSize(const char *filePath)
  123. {
  124. struct stat st;
  125. stat(filePath, &st);
  126. return st.st_size;
  127. }
  128.  
  129. // Funkcja kopiujaca pliki uzywajac mmap/write
  130.  
  131. int copyLargeFile(char *pathSource, char *pathTarget, char *fileName)
  132. {
  133. // Tworzenie nowego ciagu znakow reprezentujacego sciezke do kopiowanego pliku
  134. char newPathSource[strlen(pathSource) + strlen(fileName) + 2];
  135. strcpy(newPathSource, pathSource);
  136. strcat(newPathSource, "/");
  137. strcat(newPathSource, fileName);
  138.  
  139. int in = open(newPathSource, O_RDONLY);
  140. if (in < 0)
  141. {
  142. printf("Blad przy otwieraniu pliku %s\n", pathSource);
  143. syslog(LOG_ERR, "Blad przy otwieraniu pliku %s\n", pathSource);
  144. return 0;
  145. }
  146.  
  147. // Tworzenie nowego ciagu znakow reprezentujacego sciezke do miejsca kopiowania pliku
  148. char newPathTarget[strlen(pathTarget) + strlen(fileName) + 2];
  149. strcpy(newPathTarget, pathTarget);
  150. strcat(newPathTarget, "/");
  151. strcat(newPathTarget, fileName);
  152.  
  153. int out = open(newPathTarget, O_WRONLY | O_CREAT, S_IRWXU);
  154. if (out < 0)
  155. {
  156. printf("Blad przy otwieraniu pliku %s\n", pathTarget);
  157. syslog(LOG_ERR, "Blad przy otwieraniu pliku %s\n", pathTarget);
  158. return 0;
  159. }
  160.  
  161. size_t sizeFileSource = getFileSize(newPathSource);
  162.  
  163. void *mmappedData = mmap(NULL, sizeFileSource, PROT_READ, MAP_PRIVATE | MAP_POPULATE, in, 0);
  164. write(out, mmappedData, sizeFileSource);
  165. syslog(LOG_INFO, "Skopiowano plik: %s do folderu: %s\n", newPathSource, pathTarget);
  166. munmap(mmappedData, sizeFileSource);
  167. close(in);
  168. close(out);
  169.  
  170. //changeModifyTime(newPathTarget);
  171. //time_t result = time(NULL);
  172. //printf("Kopiowanie Duze: %s\n", asctime(gmtime(&result)));
  173. }
  174.  
  175. // Funckja kopiujaca pliki uzywajac read/write
  176.  
  177. int copy(char *pathSource, char *pathTarget, char *fileName)
  178. {
  179. // Tworzenie nowego ciagu znakow reprezentujacego sciezke do kopiowanego pliku
  180. char newPathSource[strlen(pathSource) + strlen(fileName) + 2];
  181. strcpy(newPathSource, pathSource);
  182. strcat(newPathSource, "/");
  183. strcat(newPathSource, fileName);
  184.  
  185. int in = open(newPathSource, O_RDONLY);
  186. if (in < 0)
  187. {
  188. printf("Blad przy otwieraniu pliku %s\n", pathSource);
  189. syslog(LOG_ERR, "Blad przy otwieraniu pliku %s\n", pathSource);
  190. return 0;
  191. }
  192. // Tworzenie nowego ciagu znakow reprezentujacego sciezke do miejsca kopiowania pliku
  193. char newPathTarget[strlen(pathTarget) + strlen(fileName) + 2];
  194. strcpy(newPathTarget, pathTarget);
  195. strcat(newPathTarget, "/");
  196. strcat(newPathTarget, fileName);
  197.  
  198.  
  199. int out = open(newPathTarget, O_WRONLY | O_CREAT, S_IRWXU);
  200. if (out < 0)
  201. {
  202. printf("Blad przy otwieraniu pliku %s\n", pathTarget);
  203. syslog(LOG_ERR, "Blad przy otwieraniu pliku %s\n", pathTarget);
  204. return 0;
  205. }
  206.  
  207. char *buffor = malloc(sizeof(char) * 1000);
  208. int size;
  209. int outSize = 1000;
  210.  
  211. while (outSize == 1000)
  212. {
  213. size = read(in, buffor, sizeof(char) * 1000);
  214. outSize = write(out, buffor, size);
  215. }
  216. free(buffor);
  217. close(in);
  218. close(out);
  219. //changeModifyTime(newPathTarget);
  220. //time_t result = time(NULL);
  221. //printf("Skopiowane %s\n", asctime(gmtime(&result)));
  222. syslog(LOG_INFO, "Skopiowano plik: %s do folderu: %s\n", newPathSource, pathTarget);
  223. return 1;
  224. }
  225.  
  226. // Funkcja usuwajaca pliki z katalogu docelowego ktorych nie ma w katalogu zrodlowym
  227.  
  228. int delete(char *pathSource, char *pathTarget)
  229. {
  230.  
  231. struct dirent *tar;
  232. DIR *target;
  233. target = opendir(pathTarget);
  234. if (target == NULL)
  235. {
  236. printf("Blad przy otwieraniu katalogu %s\n", pathSource);
  237. syslog(LOG_ERR, "Blad przy otwieraniu katalogu %s\n", pathSource);
  238. return 0;
  239. }
  240.  
  241. struct stat sorStat;
  242.  
  243. while ((tar = readdir(target)) != NULL)
  244. {
  245. if (!strcmp(tar->d_name, ".") || !strcmp(tar->d_name, ".."))
  246. {
  247. // Nothing
  248. }
  249. else
  250. {
  251. // Tworzenie nowego ciagu znakow reprezentujacego sciezki do badanych plikow
  252. char newPathSource[strlen(pathSource) + strlen(tar->d_name) + 2];
  253. strcpy(newPathSource, pathSource);
  254. strcat(newPathSource, "/");
  255. strcat(newPathSource, tar->d_name);
  256.  
  257. char newPathTarget[strlen(pathTarget) + strlen(tar->d_name) + 2];
  258. strcpy(newPathTarget, pathTarget);
  259. strcat(newPathTarget, "/");
  260. strcat(newPathTarget, tar->d_name);
  261. // Sprawdzenie czy badany plik z katalogu docelowego istnieje rowniez w katalogu zrodlowym
  262. if (!(lstat(newPathSource, &sorStat) == 0))
  263. {
  264. if (tar->d_type == DT_DIR && isRecurention == 1) // Sprawdzenie czy plik jest katalogiem i czy zostal przekazany parametr -R
  265. {
  266. // Usuwanie wszystkich plikow z danego katalogu
  267. delete(newPathSource, newPathTarget);
  268. if (rmdir(newPathTarget) == 0) // Usuniecie katalogu
  269. syslog(LOG_INFO, "Usunieto katalog %s", newPathTarget);
  270. else
  271. syslog(LOG_ERR, "Blad przy usuwaniu katalogu %s", newPathTarget);
  272. }
  273. if (tar->d_type == DT_REG) // Sprawdzenie czy plik jest plikiem regularnym
  274. {
  275. // Usuwanie pliku
  276. if (unlink(newPathTarget) == 0)
  277. {
  278. syslog(LOG_INFO, "Usunieto plik: %s\n", newPathTarget);
  279. }
  280. else
  281. syslog(LOG_ERR, "Blad przy usuwaniu katalogu %s", newPathTarget);
  282. }
  283. }
  284. }
  285. }
  286.  
  287. closedir(target);
  288. }
  289.  
  290. // Funkcja kopiuje pliki z folderu zrodlowego do folderu docelowego
  291.  
  292. int copyFiles(char *pathSource, char *pathTarget)
  293. {
  294.  
  295. DIR *source;
  296. source = opendir(pathSource);
  297. if (source == NULL)
  298. {
  299. printf("Blad przy otwieraniu katalogu %s\n", pathSource);
  300. syslog(LOG_ERR, "Blad przy otwieraniu katalogu %s\n", pathSource);
  301. return 0;
  302. }
  303.  
  304. struct dirent *sor;
  305. struct stat targetStat, sourceStat;
  306.  
  307. while ((sor = readdir(source)) != NULL)
  308. {
  309. if (!strcmp(sor->d_name, ".") || !strcmp(sor->d_name, ".."))
  310. {
  311. // Nothing
  312. }
  313. else
  314. {
  315. // Tworzenie nowego ciagu znakow reprezentujacego sciezki do badanych plikow
  316. char newPathSource[strlen(pathSource) + strlen(sor->d_name) + 2];
  317. strcpy(newPathSource, pathSource);
  318. strcat(newPathSource, "/");
  319. strcat(newPathSource, sor->d_name);
  320.  
  321. char newPathTarget[strlen(pathTarget) + strlen(sor->d_name) + 2];
  322. strcpy(newPathTarget, pathTarget);
  323. strcat(newPathTarget, "/");
  324. strcat(newPathTarget, sor->d_name);
  325.  
  326. // Sprawdzenie czy badany plik z katalogu zrodlowego istnieje rowniez w katalogu docelowym
  327. if (!lstat(newPathTarget, &targetStat))
  328. {
  329. if (sor->d_type == DT_REG)
  330. {
  331. // Obliczenie roznicy pomiedzy czasem modyfikacji obu plikow
  332. double result = difftime(sourceStat.st_mtime, targetStat.st_mtime);
  333. if (result > 0) // jesli roznica jest powyzej zera to plik w katalogu docelowym ma date pozniejsza niz plik w katalogu zrodlowym
  334. {
  335. if (isCopyingByParametr > 0) // Sprawdzenie czy zostal przekazany parametr dotyczacy drugiego sposobu kopiowania
  336. {
  337. size_t sizeOfFile = getFileSize(newPathSource);
  338. if (sizeOfFile > isCopyingByParametr) // jesli rozmiar pliku jest wiekszy od parametru, wykonywane jest kopiowanie 'copyLargeFiles'
  339. copyLargeFile(pathSource, pathTarget, sor->d_name);
  340. else // zwykle kopiowanie
  341. copy(pathSource, pathTarget, sor->d_name);
  342. }
  343. else
  344. { // jesli dodatkowy parametr nie zostal przekazany, wykonywane jest zwyczajne kopiowanie
  345. copy(pathSource, pathTarget, sor->d_name);
  346. }
  347. }
  348. }
  349. if (sor->d_type == DT_DIR && isRecurention == 1) // sprawdzenie czy plik jest katalogiem i czy zostal przekazany parametr -R
  350. {
  351. // Usuwanie i Kopiowanie plikow w katalogu podrzednym
  352. delete(newPathSource, newPathTarget);
  353. copyFiles(newPathSource, newPathTarget);
  354. }
  355. }
  356. else // Ta partia kodu jest wykonywana jesli plik nie istnieje w katalogu docelowym a istnieje w zrodlowym
  357. {
  358. if (sor->d_type == DT_REG) // Sprawdzenie czy plik jest plikiem regularnym
  359. {
  360. if (isCopyingByParametr > 0) // Sprawdzenie czy zostal przekazany parametr dotyyczacy drugiego sposobu kopiowania
  361. {
  362. size_t sizeOfFile = getFileSize(newPathSource);
  363. printf("Size: %ld\n", sizeOfFile);
  364. if (sizeOfFile > isCopyingByParametr) // jesli rozmiar pliku jest wiekszy od parametru, wykonywane jest kopiowanie 'copyLargeFiles'
  365. copyLargeFile(pathSource, pathTarget, sor->d_name);
  366. else // zwykle kopiowanie
  367. copy(pathSource, pathTarget, sor->d_name);
  368. }
  369. else
  370. { // jesli dodatkowy parametr nie zostal przekazany, wykonywane jest zwyczajne kopiowanie
  371. copy(pathSource, pathTarget, sor->d_name);
  372. }
  373. }
  374. if (sor->d_type == DT_DIR && isRecurention == 1) // sprawdzenie czy plik jest katalogiem i czy zostal przekazany parametr -R
  375. {
  376. // Stworzenie nowego katalogu w katalogu docelowym i skopiowanie plikow do niego z katalogu zrodlowego
  377. mkdir(newPathTarget, 0700);
  378. copyFiles(newPathSource, newPathTarget);
  379. }
  380. }
  381. }
  382. }
  383. closedir(source);
  384. }
  385.  
  386. int main(int argc, char *argv[])
  387. {
  388. // Sprawdzenie poprawnosci parametrow
  389. int check = checkParameters(argc, argv);
  390. if (check == 0){
  391. printf("Przekazane parametry sa bledne\n\n");
  392. printf("Prawidlowy uklad parametrow podstawowych wyglada nastepujaco\n");
  393. printf("./main <Katalog Zrodlowy> <Katalog Docelowy>\n\n");
  394. printf("Prawidlowe uklady parametrow opcjonalnych wygladaja nastepujaco\n");
  395. printf("<1> <2> <-R> ,<1> <-R> <2> , <1> <2> , <1> <-R>\n\n");
  396. printf(" 1 - czas snu demona ( liczba calkowita )\n");
  397. printf(" 2 - prog rozmiaru pliku dla kopiowania read/write i mmap/write\n");
  398. printf("-R - rekurencyjna synchornizacja katalogow\n\n");
  399. printf("Przyklad: ./main katalog1 katalog2 100 -R 1500\n");
  400. return 0;
  401. }
  402.  
  403.  
  404. struct sigaction action, oldAction;
  405. pid_t pid;
  406.  
  407. // Tworzenie procesu potomnego
  408.  
  409. pid = fork();
  410.  
  411. if (pid < 0)
  412. {
  413. printf("Nie utworzono procesu potomnego\n");
  414. }
  415.  
  416. if (pid > 0)
  417. { // proces macierzysty
  418. return 0;
  419. }
  420.  
  421. if (pid == 0) // Poprawne utworzenie procesu potomnego
  422. {
  423. int proces = getpid();
  424.  
  425.  
  426. printf("Jesli chcesz zakonczyc prace demona uzyj polecenia: kill <nr_procesu>\n");
  427. printf("Jesli chcesz wybudzic demona ze snu, uzyj polecenia kill -s 10 <nr_procesu>\n");
  428. printf("Numer procesu: %d\n", proces);
  429.  
  430. openlog("demon", LOG_PID, LOG_DAEMON);
  431. syslog(LOG_INFO, "Demon zaczal dzialac!!\n");
  432.  
  433. if (setsid() < 0)
  434. {
  435. syslog(LOG_ERR, "Problem z wyslaniem\n");
  436. exit(-1);
  437. }
  438.  
  439. // Ustawienie akcji sygnalu na signalHandler
  440.  
  441. action.sa_handler = signalHandler;
  442. sigfillset(&action.sa_mask);
  443. action.sa_flags = 0;
  444.  
  445. // Ustawienie nowej akcji 'action' zwiazana z sygnalem SIGUSR1
  446.  
  447. if (sigaction(SIGUSR1, &action, &oldAction) < 0)
  448. {
  449. printf("Blad przy ustawieniu nowej akcji dla sygnalu SIGUSR1");
  450. }
  451.  
  452. printf("PROGRAM STAJE SIE DEMONEM!\n");
  453.  
  454. while (1)
  455. {
  456.  
  457. syslog(LOG_INFO, "Demon zasnal na: %d s\n", sleepTime);
  458. sleep(sleepTime);
  459.  
  460.  
  461. switch (sig_check)
  462. {
  463. case 0:
  464. syslog(LOG_INFO, "Demon sie obudzil\n");
  465. break;
  466.  
  467. case 1:
  468. syslog(LOG_INFO, "Demon sie obudzil po wykryciu sygnalu SIGURS1\n");
  469. sig_check = 0;
  470. break;
  471. }
  472.  
  473. delete(argv[1], argv[2]);
  474. copyFiles(argv[1], argv[2]);
  475. }
  476.  
  477. return 0;
  478. }
  479. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement