Advertisement
Guest User

Untitled

a guest
May 23rd, 2019
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.09 KB | None | 0 0
  1. #pragma clang diagnostic push
  2. #pragma ide diagnostic ignored "hicpp-signed-bitwise"
  3.  
  4. #include <utime.h> // modyfikacja czasu
  5. #include <string.h> // Operacje na łańcuchach znaków.
  6. #include <stdlib.h> // Najbardziej podstawowe funkcje - exit(), malloc().
  7. #include <dirent.h> // Udostępnia funkcje, makra, i struktury, które umożliwiają łatwe trawersowanie katalogów.
  8. #include <signal.h> // Obsługa sygnałów.
  9. #include <unistd.h>
  10. #include <limits.h> // limity systemowe
  11. #include <sys/types.h> // Różne typy danych.
  12. #include <fcntl.h> // Działanie na plikach i inne operacje.
  13. #include <sys/mman.h> // Deklaracje zarządzania pamięcią.
  14. #include <stdio.h> // Standard Input/Output, czyli standardowe wejście-wyjście.
  15. #include <sys/stat.h> // Nagłówek określa strukturę danych zwracanych przez funkcje fstat, stat
  16. #include <syslog.h> // Definicje dla rejestrowanie błędów systemu.
  17.  
  18.  
  19. /* Zmienne globalne, które zostaną wykorzystane gdy użytkownik uruchomi program bez dodatkowych opcji: '-S', '-P' */
  20. int sleep_time = 15;
  21. int fsiz = 26214400; // 25 MB
  22. int sig_check = 0;
  23. //********************************************************** Funkcja wyświetla błąd dla użytkownika, jeżeli źle wprowadził argumenty.
  24.  
  25. void arg_err() {
  26. printf("\nWystapil Blad! Argumenty zostały źle wpisane\n");
  27. printf("\nPrawidlowe wywolanie: 'sciezka_do_katalogu_zrodlowego' 'sciezka_do_katalogu_docelowego' '-R' '-S' '-P'\n\n"
  28. "-R - Program skopiuje rowniez katalogi\n"
  29. "-S - Wpisana wartosc oznacza ilosc sekund po jakich demon wyjdzie z uspienia.\n"
  30. "-P - Wpisana wartosc okresla prog dzielacy pliki male od duzych.\n\n");
  31. }
  32.  
  33. //********************************************************** Funkcja sprawdza czy napotkaliśmy na katalog, plik lub coś innego.
  34.  
  35.  
  36. int check_path(struct stat type)
  37. {
  38.  
  39. if (S_ISREG(type.st_mode)) // funkcja S_ISREG sprawdza czy sciezka jest plikiem regularnym.
  40. {
  41. return 0;
  42. }
  43. if (S_ISDIR(type.st_mode)) // funkcja S_ISREG sprawdza czy sciezka jest plikiem regularnym.
  44. {
  45. return 1;
  46. }
  47.  
  48. }
  49.  
  50. int check_arguments(char *source, char *target, int count, char *arg[]) {
  51. // argumenty funkcji:
  52. // source - ścieżka do katalogu źródłowego
  53. // target - ścieżka do katalogu docelowego
  54. // count - ilość wywołanych argumentow w trakcie
  55.  
  56.  
  57. int i, pom, o_time = 0, o_size = 0;
  58.  
  59. if ((count >= 3) && (count <= 8)) // sprawdzamy czy podana ilość argumentów jest poprawna
  60. {
  61.  
  62. strcpy(source, arg[1]); // kopiujemy do tablicy 'sciezka_zrodlowa' ścieżkę do katalogu źródłowego
  63. strcpy(target, arg[2]); // kopiujemy do tablicy 'sciezka_docelowa' ścieżkę do katalogu docelowego
  64.  
  65. for (i = 3; i < count; i++) // demon musi przyjąc minimalnie 3 argumenty, więc pętla zaSyna się od 3
  66. {
  67.  
  68.  
  69. if (strcmp(arg[i], "-S") == 0 && o_size !=
  70. 1) // Jeżeli kolejny argument zaczyna się na '-S' oznacza to, że użytkownik w następnym argumencie podał Sas uśpienia demona (w sekundach).
  71. {
  72. o_time = 1;
  73. } else if (strcmp(arg[i], "-P") == 0 && o_time !=
  74. 1) // Jezeli napotkaliśmy na '-P' oznacza to, że kolejnym argumentem jest liczba okreslająca próg oddzieląjacy małe od dużych plików.
  75. {
  76. o_size = 1;
  77. } else if ((pom = atoi(arg[i])) != 0 && o_time == 1 &&
  78. o_size != 1) // Odczytujemy ustawioną przez użytkownika ilość sekund uśpienia demona.
  79. {
  80. sleep_time = pom;
  81. o_time = 2;
  82. } else if ((pom = atoi(arg[i])) != 0 && o_size == 1 &&
  83. o_time != 1) // Próg oddziela pliki duże od małych
  84. {
  85. fsiz = pom;
  86. o_size = 2;
  87. } else {
  88. arg_err();
  89. }
  90. }
  91.  
  92. if (o_size == 1 || o_time ==
  93. 1) // Jeżeli po wystąpieniu '-S' lub'-P' użytkownik nie wprowadził żadnej liczby, zwracany jest błąd.
  94. {
  95. arg_err();
  96. return -1;
  97. }
  98.  
  99. } else // Jeżeli została podana zła liczba argumentów, wyświetl błąd.
  100. {
  101. arg_err();
  102. return -1;
  103. }
  104. }
  105.  
  106.  
  107. //********************************************************** Odebranie syngału - SIGURS1, aby natychmiast obudzić demona.
  108.  
  109. void signal_handling(int sig_check) {
  110. syslog(LOG_INFO, "Demon odebral sygnal SIGURS1\n");
  111. sig_check = 1;
  112. }
  113.  
  114. int copy(char *inf, char *outf) {
  115. ssize_t output, input;
  116. struct stat stat_s;
  117. const int buff = 4096;
  118. int buffer[buff];
  119. int f_source, f_target;
  120.  
  121. if ((f_source = open(inf, O_RDONLY)) < -1) {
  122. syslog(LOG_ERR, "BLAD: copy: Nie mozna otworzyc: '%s'", inf);
  123. return 0;
  124. }
  125.  
  126. if (fstat(f_source, &stat_s) < 0) {
  127. syslog(LOG_ERR, "BLAD: copy: stat(): '%s'", inf);
  128. return 0;
  129. }
  130.  
  131. if ((f_target = open(outf, O_WRONLY | O_CREAT | O_TRUNC, stat_s.st_mode)) < 0) {
  132. syslog(LOG_ERR, "BLAD: copy: Nie mozna otworzyc: '%s'", inf);
  133. return 0;
  134. }
  135.  
  136. while ((input = read(f_source, &buffer, buff)) != 0) {
  137. output = write(f_target, &buffer, input);
  138. }
  139.  
  140. close(f_source);
  141. close(f_target);
  142. return 1;
  143. }
  144.  
  145. int mmapcopy(char *inf, char *outf) {
  146.  
  147. int f_source, f_target;
  148. char *src, *dst;
  149. struct stat statbuf;
  150.  
  151.  
  152.  
  153. // write(f_target, src, statbuf.st_size);
  154. // munmap(src, statbuf.st_size);
  155. //
  156. // close(f_source);
  157. // close(f_target);
  158. return 1;
  159. }
  160.  
  161. void list_copy(char *source, char *target) {
  162. int f_source, f_target;
  163. char *src, *dst;
  164. struct stat statbuf;
  165. struct dirent *file_s; // info o lokacji dla zrodla
  166. struct stat stat_t; // info o pliku docelowym
  167. struct stat stat_s; // info o pliku zrodlowym
  168. DIR *dir_s; // wskaznik na ścieżke
  169. struct utimbuf new_time; // przetrzymuje nowa date modyfikacji
  170.  
  171. char tmp_s[PATH_MAX]; // tmp do przetrzymywania sciezki zrodla
  172. char tmp_t[PATH_MAX]; // tmp do przetrzymywania sciezki celu
  173.  
  174.  
  175. if ((dir_s = opendir(source))) {
  176. // czytaj ścieżke
  177. while (file_s = readdir(dir_s)) {
  178. snprintf(tmp_s, PATH_MAX, "%s/%s", source, file_s->d_name);
  179. snprintf(tmp_t, PATH_MAX, "%s/%s", target, file_s->d_name);
  180.  
  181. stat(tmp_s, &stat_s);
  182. if (file_s->d_type == DT_REG) { //
  183. if (stat(tmp_t, &stat_t) != 0) {
  184.  
  185. if (fsiz > stat_s.st_size) {
  186. if (copy(tmp_s, tmp_t) == 1) {
  187. syslog(LOG_INFO, "Skopiowano: '%s' do '%s'", tmp_s, tmp_t);
  188. } else {
  189. syslog(LOG_INFO, "Nie skopiowano: '%s' do '%s'", tmp_s, tmp_t);
  190. }
  191. } else {
  192. if (mmapcopy(tmp_s, tmp_t) == 1) {
  193. write(f_target, src, statbuf.st_size);
  194. munmap(src, statbuf.st_size);
  195.  
  196. close(f_source);
  197. close(f_target);
  198. syslog(LOG_INFO, "(mmap) Skopiowano plik: '%s' do '%s'", tmp_s, tmp_t);
  199.  
  200.  
  201. } else {
  202. syslog(LOG_INFO, "(mmap) Nie skopiowano pliku : '%s' do '%s'", tmp_s, tmp_t);
  203. }
  204. }
  205.  
  206. new_time.modtime = stat_s.st_mtime;
  207. utime(tmp_t, &new_time);
  208. }
  209. }
  210. }
  211. } else {
  212. syslog(LOG_INFO, "Niepowodzenie w otworzeniu sciezki: '%s', '%s'", source, target);
  213. }
  214.  
  215. closedir(dir_s);
  216. }
  217.  
  218. void delete(char *source, char *target) { // usuwa pliki nieistniejace w katalogu zrodlowym
  219. struct dirent *dest; // info o lokacji dla celu
  220. struct dirent *file_s; // info o lokacji dla zrodla
  221. struct stat stat_s; // info o pliku zrodlowym
  222. struct stat stat_t; // info o pliku docelowym
  223. DIR *path_t; // wskaznik na ścieżke
  224. char tmp_s[PATH_MAX]; //maksymalna dlugosc sciezki w linux
  225. char tmp_t[PATH_MAX]; // maksymalna dkugosc sciezki w linux
  226.  
  227. if ((path_t = opendir(target)) != 0) {
  228.  
  229. while (dest = readdir(path_t)){
  230. if (strcmp(dest->d_name, ".") || strcmp(dest->d_name, "..")) {
  231.  
  232.  
  233. snprintf(tmp_s, PATH_MAX, "%s/%s", source, dest->d_name);
  234. snprintf(tmp_t, PATH_MAX, "%s/%s", target, dest->d_name);
  235.  
  236. if (stat(tmp_t, &stat_t) == 0) {
  237.  
  238. if (check_path(stat_t) == 0) {
  239.  
  240. if (stat(tmp_s, &stat_s) == 0) {
  241.  
  242.  
  243. } else {
  244. if (unlink(tmp_t) == 0) {
  245. syslog(LOG_INFO, "Usunieto plik: '%s'", tmp_t);
  246. } else {
  247. syslog(LOG_ERR, "Nie udalo sie usunac pliku: '%s'", tmp_t);
  248. }
  249. }
  250. }
  251.  
  252. } else {
  253. syslog(LOG_ERR, "Podana sciezka nie istnieje '%s'", tmp_t);
  254. }
  255. }
  256.  
  257. }
  258.  
  259.  
  260. }
  261.  
  262. else{
  263. syslog(LOG_ERR, "Blad sciezki: '%s' ", target);
  264. }
  265. closedir (path_t);
  266. }
  267.  
  268. int main(int argc, char **argv) {
  269. char source[PATH_MAX]; // przechowuje ścieżkę do folderu zrodlowego
  270. char target[PATH_MAX]; // przechowuje ścieżkę do folderu docelowego
  271.  
  272. struct stat zrodlowa_status; // przechowuje status pliku/folderu wskazywanego przez source[PATH_MAX]
  273. struct stat docelowa_status; // przechowuje status pliku/folderu wskazywanego przez target[PATH_MAX]
  274.  
  275. struct sigaction new_action, old_action;
  276.  
  277. pid_t pid,sid;
  278. int proces; // przechowuje numer procesu potomnego, aby móc później wyłąSyć demona komendą kill
  279.  
  280.  
  281. //********************************************************** Sprawdzenie podanych argumentów dla demona
  282.  
  283. if (check_arguments(source, target, argc, argv) == -1) {
  284. exit(-1);
  285. }
  286.  
  287. //********************************************************** Sprawdzenie poprawności ścieżek
  288.  
  289. if (lstat(source, &zrodlowa_status) !=0) // Funkcja lstat() sprawdza istnienie scieżki o nazwie zapisanej w 'sciezka_zrodlowa' dzięki zmiennej środowiskowej path.
  290. { // W przypadku sukcesu zwraca 0, a w przypadku błędu -1.
  291. // W przypadku sukcesu lstat() zwraca status pliku znajdującego się pod 'sciezka_zrodlowa' do zmiennej zrodlowa_status.
  292. printf("Blad, podana sciezka zrodlowa: '%s' nie istnieje!\n", source);
  293. exit(-1);
  294. }
  295.  
  296. if (lstat(target, &docelowa_status) != 0) {
  297. printf("Blad, podana sciezka docelowa: '%s' nie istnieje!\n", target);
  298. exit(-1);
  299. }
  300.  
  301.  
  302. //********************************************************** Sprawdzenie czy podane ścieżki są katalogami
  303.  
  304.  
  305. if (check_path(zrodlowa_status) != 1) // Sprawdzamy czy podana scieżka źródłowa jest folderem.
  306. {
  307. printf("Blad, podana sciezka zrodlowa: '%s' nie jest katalogiem!\n", source);
  308. exit(-1);
  309. }
  310.  
  311. if (check_path(docelowa_status) != 1) // Sprawdzamy czy podana ścieżka docelowa jest folderem.
  312. {
  313. printf("Blad, podana sciezka docelowa: '%s' nie jest katalogiem!\n", target);
  314. exit(-1);
  315. }
  316.  
  317.  
  318.  
  319. //Proces potomny
  320.  
  321. pid = fork(); // Tworzenie procesu potomnego
  322.  
  323. if (pid < 0) {
  324. printf("Blad utworzenia procesu potomnego\n");
  325. exit(-1);
  326. }
  327.  
  328. // Proces macierzysty
  329. if (pid > 0) {
  330. return 0;
  331. }
  332.  
  333.  
  334. // Proces potomny,
  335. if (pid == 0) {
  336. proces = getpid(); // Zmiennej 'proces' przypisujemy numer procesu potomnego, aby zakończyć pracę demona poleceniem 'kill'.
  337. printf("Demon zostal uruchomiony\n");
  338. printf("\nArgumenty:\n -S:\t%d Sekund\n -P:\t%d Bajtów\n \n", sleep_time, fsiz);
  339. printf("Numer procesu: %d\nAby zakonczyc prace demona uzyj polecenia: kill <nr_procesu>\nAby wykorzystac SIGUSR1 uzyj polecenia: kill -s 10 <nr_procesu>\n",
  340. proces);
  341.  
  342. //********************************************************** Inicjalizacja logu systemowego
  343.  
  344. openlog("demon", LOG_PID, LOG_DAEMON); //wpis do logu systemowego
  345.  
  346. syslog(LOG_INFO, "Demon synchronizujacy zostal uruchomiony.\n"); //wysyla informacje do logu systemowego,
  347. sid=setsid();
  348. if (sid < 0) //setsid() zwraca PID aktualnego procesu
  349. {
  350. syslog(LOG_ERR, "Wystąpił błąd przy wysylaniu informacji do logu systemowego\n");
  351. exit(-1);
  352. }
  353. umask(0);
  354.  
  355.  
  356. //********************************************************** Inicjalizacja przerwania systemowgo
  357.  
  358. new_action.sa_handler = signal_handling;
  359. sigfillset(&new_action.sa_mask);
  360. new_action.sa_flags = 0;
  361.  
  362. if (sigaction(SIGUSR1, &new_action, &old_action) < 0) {
  363. syslog(LOG_ERR, "Wystapil blad z obsluga sygnalu SIGUSR1.\n");
  364. exit(-1);
  365. }
  366.  
  367.  
  368. while (1) {
  369.  
  370. switch (sig_check) {
  371. case 0:
  372. syslog(LOG_INFO, "Demon wybudził się po %d sekundach.\n", sleep_time);
  373. break;
  374. case 1:
  375. syslog(LOG_INFO, "Wykryto SIGUSR1- Demon zostaje wybudzony.");
  376. break;
  377. }
  378.  
  379. delete(source, target);
  380.  
  381. list_copy(source, target);
  382.  
  383. syslog(LOG_INFO, "Demon wykonał synchronizacje, przechodzi w stan uśpienia\n");
  384. sleep(sleep_time);
  385. }
  386. }
  387. return 0;
  388. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement