Advertisement
Guest User

Untitled

a guest
Apr 20th, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.57 KB | None | 0 0
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <fcntl.h>
  6. #include <errno.h>
  7. #include <unistd.h>
  8. #include <syslog.h>
  9. #include <string.h>
  10. #include <stdbool.h>
  11. #include <dirent.h>
  12. #include <assert.h>
  13. #include <time.h>
  14. #include <signal.h>
  15. #include <sys/mman.h>
  16. #include <utime.h>
  17.  
  18. int timepar = 300;
  19. bool checkDirectory = 0;
  20. size_t size = 1000000;
  21.  
  22. char* CreatePath(char* path, char* filetomerge)
  23. {
  24. int length = strlen(path) + strlen(filetomerge);
  25. char *fullpath = malloc( sizeof(char) * ( length + 1 ) );
  26. memset( fullpath, 0x00, length ); //wyczysc nowa tablice
  27. strcat(fullpath, path);
  28. strcat(fullpath, "/");
  29. strcat(fullpath, filetomerge);
  30. return fullpath;
  31. }
  32.  
  33. void CopyByMapping(char* poczatkowy, char * koncowy, struct dirent * ep, struct dirent * ep2)
  34. {
  35. syslog(LOG_NOTICE, "MAPOWANIE");
  36. int sfd, dfd;
  37. char *src, *dest;
  38. size_t filesize;
  39.  
  40. char* name1 = CreatePath(poczatkowy, ep->d_name); //tworzenie sciezki zrodla
  41. char* name2 = CreatePath(koncowy, ep->d_name); //sciezka docelowa
  42.  
  43. sfd = open(name1, O_RDONLY);
  44. filesize = lseek(sfd, 0, SEEK_END);
  45. src = mmap(NULL, filesize, PROT_READ, MAP_PRIVATE, sfd, 0);
  46. dfd = open(name2, O_RDWR | O_CREAT, 0777);
  47. ftruncate(dfd, filesize);
  48. dest = mmap(NULL, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, dfd, 0);
  49. memcpy(dest, src, filesize); // Czy można
  50. munmap(src, filesize);
  51. munmap(dest, filesize);
  52.  
  53. free(name1);
  54. free(name2);
  55. close(sfd);
  56. close(dfd);
  57. }
  58.  
  59. int ReadMappingBorder(char* a)
  60. {
  61. int i = 1;
  62. int j = 0;
  63. size = 0;
  64. size_t power = 1;
  65. size_t digit = 0;
  66. int length = strlen(a);
  67. while (i<length) //petla zamienia liczbe ze string na int
  68. {
  69.  
  70. digit = a[length - i] - '0';
  71. power = 1;
  72. for (j = 1; j<i; j++)
  73. power *= 10;
  74. i++;
  75. size = size + (digit*power);
  76. }
  77. return 1;
  78. }
  79.  
  80.  
  81. int ReadWakeTime(char* a)
  82. {
  83. int i = 0;
  84. int j = 0;
  85. timepar = 0;
  86. int power = 1;
  87. int digit = 0;
  88. int length = strlen(a);
  89. while (i<length) //zamiana liczby string na int
  90. {
  91. digit = a[length - i - 1] - '0';
  92. power = 1;
  93. for (j = 0; j<i; j++)
  94. power *= 10;
  95.  
  96. i++;
  97. timepar = timepar + (digit*power);
  98. }
  99. return 1;
  100. }
  101.  
  102. bool CheckDirectories(char** argv)
  103. {
  104. DIR* chk1 = opendir(argv[1]); //jesli mozna otworzyc katalog bez bledow, to sciezki sa poprawne
  105. if (chk1 == NULL)
  106. {
  107. printf("Bad directory: %s \n", argv[1]);
  108. return false;
  109. }
  110. closedir(chk1);
  111. chk1 = opendir(argv[2]);
  112. if (chk1 == NULL)
  113. {
  114. printf("Bad directory: %s \n", argv[2]);
  115. return false;
  116. }
  117. closedir(chk1);
  118. return true;
  119. }
  120.  
  121.  
  122.  
  123. bool IsDigit(char* digit, int length)
  124. {
  125. int i = 0;
  126. if (digit[0] == '-') //pomijanie znaku '-' - przesylany przy rozmiarze granicy do mapowania
  127. i++;
  128. for (; i<length; i++)
  129. {
  130. if (digit[i] >= '0' && digit[i] <= '9'); //jesli jest charem ktory jest liczba
  131. else
  132. return false; //jesli nie
  133. }
  134. return true;
  135. }
  136.  
  137. int RemoveDirectory(char *path)
  138. {
  139. DIR *d = opendir(path);
  140. size_t path_len = strlen(path);
  141. int r = -1;
  142.  
  143. if (d)
  144. {
  145. struct dirent *p;
  146. r = 0;
  147.  
  148. while (!r && (p = readdir(d)))
  149. {
  150. int r2 = -1;
  151. char *buf;
  152. size_t len;
  153.  
  154. if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) //ignorowanie zawartosci kazdego folderu . i ..
  155. {
  156. continue;
  157. }
  158.  
  159. len = path_len + strlen(p->d_name) + 2;
  160. buf = malloc(len);
  161.  
  162. if (buf)
  163. {
  164. struct stat statbuf;
  165. snprintf(buf, len, "%s/%s", path, p->d_name);
  166. if (!stat(buf, &statbuf))
  167. {
  168. if (S_ISDIR(statbuf.st_mode)) //jesli ma w sobie folder, to rekurencyjnie wywolaj funkcje
  169. { //jest to spowodowane brakiem mozliwosci usuwania niepustych folderow
  170. r2 = RemoveDirectory(buf);
  171. }
  172. else //jesli ma w sobie plik, usun go
  173. {
  174. r2 = unlink(buf);
  175. }
  176. }
  177. free(buf);
  178. }
  179. r = r2;
  180. }
  181. closedir(d);
  182. }
  183.  
  184. if (!r) //jesli jest pusty, to usun folder
  185. {
  186. r = rmdir(path);
  187. }
  188.  
  189. return r;
  190. }
  191.  
  192. bool RecogniseArgument(int which, char **argv)
  193. {
  194. int length = strlen(argv[which]);
  195.  
  196. if (strcmp(argv[which], "-R") == 0) //jesli podano -R
  197. checkDirectory = true;
  198.  
  199. else if (argv[which][0] == '-' && IsDigit(argv[which], length)) //jesli podano granice mapowania
  200. ReadMappingBorder(argv[which]);
  201.  
  202. else if (IsDigit(argv[which], length)) //jesli podano czas
  203. ReadWakeTime(argv[which]);
  204.  
  205. else { //jesli dodatkowy parametr jest bledny
  206. fprintf(stderr, "Wrong argument number: %d. \n", which);
  207. errno=EINVAL;
  208. perror("Demon");
  209. return false;
  210. }
  211. return true;
  212. }
  213.  
  214. int CheckArguments(int argc, char **argv)
  215. {
  216. if (argc<3) //jesli nie podano sciezek
  217. {
  218. fprintf(stderr, "No enought arguments. \n");
  219. errno=EINVAL;
  220. perror("Demon");
  221. return -1;
  222. }
  223.  
  224. else if (argc == 3 && CheckDirectories(argv)); //jesli podano poprawne katalogi
  225. //nie rob nic, ale nie else
  226. else if (argc == 4 && CheckDirectories(argv)) //jesli podano katalogi i 1 parametr
  227. {
  228. if(!RecogniseArgument(3, argv))
  229. return -1;
  230. }
  231.  
  232. else if (argc == 5 && CheckDirectories(argv)) //jesli dwa argumenty dodatkowe
  233. {
  234. if(!RecogniseArgument(3, argv) || !RecogniseArgument(4, argv))
  235. return -1;
  236. }
  237.  
  238. else if (argc == 6 && CheckDirectories(argv)) //jesli podano trzy dodatkowe parametry
  239. {
  240. if(!RecogniseArgument(3, argv) || !RecogniseArgument(4, argv) || !RecogniseArgument(5, argv))
  241. return -1;
  242. }
  243.  
  244. else
  245. {
  246. fprintf(stderr, "Too many arguments! \n");
  247. errno=EINVAL;
  248. perror("Demon");
  249. return false;
  250. }
  251. return 0;
  252. }
  253.  
  254.  
  255. void CopyFile(char* poczatkowy, char * koncowy, struct dirent * ep, struct dirent * ep2)
  256. {
  257. int out,in; //FILE *out, *in;
  258.  
  259. char* name1 = CreatePath(poczatkowy, ep->d_name);
  260. char* name2 = CreatePath(koncowy, ep->d_name);
  261.  
  262. in = open(name1, O_RDONLY);
  263. out = open(name2, O_WRONLY | O_CREAT | O_TRUNC,0777);
  264.  
  265. size_t n, m;
  266. char * buff = (char *)calloc(100,sizeof(char));
  267.  
  268. do //kopiowanie porcjami
  269. {
  270. n = read(in,buff,sizeof(buff)-1);
  271. if (n) m = write(out,buff, n);
  272. else m = 0;
  273. } while ((n > 0) && (n == m));
  274.  
  275. close(out);
  276. close(in);
  277. free(name1); //zwolnij pamiec sciezek
  278. free(name2);
  279. syslog(LOG_NOTICE, ep->d_name); //kontrolny zapis w logach
  280. return;
  281. }
  282.  
  283. void UpdateDirectory(char* poczatkowy, char * koncowy)
  284. {
  285. DIR* directoryParent = opendir(poczatkowy);
  286. struct utimbuf new_times;
  287. struct dirent *ep, *ep2;
  288. struct stat file, file1;
  289. time_t mod1, mod2;
  290. int fd;
  291.  
  292. do
  293. {
  294. ep = readdir(directoryParent); //przegladaj katalog glowny
  295. if (ep == NULL) //jesli pusty, zostaw
  296. break;
  297.  
  298. DIR* directoryChild = opendir(koncowy); //otworz katalog docelowy
  299.  
  300. do
  301. {
  302. ep2 = readdir(directoryChild); //przegladaj zawartosc katalogu docelowego
  303. if (ep2 == NULL) //jesli pusty, zostaw
  304. break;
  305.  
  306. chdir(poczatkowy);
  307. lstat(ep->d_name, &file); //czytaj dane o pliku z katalogu
  308. size_t filesize = file.st_size;
  309. if ((file.st_mode & S_IFMT == S_IFLNK) || (ep->d_name[0] == '.')) //jesli nie jest linkiem
  310. break;
  311.  
  312. chdir(koncowy); //operacje na docelowym katalogu
  313. lstat(ep2->d_name, &file1);
  314. mod1 = file.st_mtime;
  315. mod2 = file1.st_mtime;
  316. int tmp = open(ep->d_name, O_RDONLY);
  317.  
  318. if (tmp <0) //jesli nie mozna otworzyc pliku, to on nie istnieje
  319. {
  320. if (S_ISDIR(file.st_mode)) //jesli jest katalogiem
  321. {
  322. if (checkDirectory) //jesli demon ma uwzgledniac katalogi
  323. {
  324. char* podkatalog1 = CreatePath(poczatkowy, ep->d_name);
  325. char* podkatalog2 = CreatePath(koncowy, ep->d_name);
  326.  
  327. mkdir(podkatalog2, 0777); //stworz podkatalog w folderze docelowym
  328. UpdateDirectory(podkatalog1, podkatalog2); //rekurencyjnie wykonaj dla podkatalogu
  329. free(podkatalog1);
  330. free(podkatalog2);
  331. }
  332. break;
  333. }
  334.  
  335. fd = open(ep->d_name, O_CREAT, 0777);
  336. close(fd);
  337.  
  338. if (filesize>size) //jesli jest ponad progiem uzytkownika do mapowania
  339. CopyByMapping(poczatkowy, koncowy, ep, ep2);
  340. else
  341. CopyFile(poczatkowy, koncowy, ep, ep2);
  342.  
  343. new_times.actime = file.st_atime;
  344. new_times.modtime = file.st_mtime;
  345. char* nazwa_pomocnicza = CreatePath(koncowy, ep2->d_name);
  346. utime(nazwa_pomocnicza, &new_times); //ustaw czas modyfikacji taki jak w katalogu glownym
  347. free(nazwa_pomocnicza);
  348. break;
  349. }
  350.  
  351. else
  352. close(tmp); //zamknij plik jesli go otworzyles
  353.  
  354. if (S_ISDIR(file.st_mode)) //jesli jest katalogiem i istnieje
  355. {
  356. if (checkDirectory)
  357. {
  358. char* podkatalog1 = CreatePath(poczatkowy, ep->d_name);
  359. char* podkatalog2 = CreatePath(koncowy, ep->d_name);
  360. UpdateDirectory(podkatalog1, podkatalog2); //rekurencyjnie sprawdz jego zawartosc
  361. free(podkatalog1);
  362. free(podkatalog2);
  363. }
  364. break;
  365. }
  366. if ((difftime(mod1, mod2) != 0.0 && (strcmp(ep->d_name, ep2->d_name) == 0)))
  367. { //jesli itnieje i ma inny czas modyfikacji
  368. fd = open(ep->d_name, O_RDONLY);
  369. size_t filesize = lseek(fd, 0, SEEK_END);
  370. close(fd);
  371. if (filesize>size)
  372. CopyByMapping(poczatkowy, koncowy, ep, ep2);
  373. else
  374. CopyFile(poczatkowy, koncowy, ep, ep2);
  375.  
  376. new_times.actime = file.st_atime; //zmiana czasu modyfikacji na ten, z katalogu glownego
  377. new_times.modtime = file.st_mtime;
  378. char* nazwa_pomocnicza = CreatePath(koncowy, ep2->d_name);
  379. utime(nazwa_pomocnicza, &new_times); //ustaw czas modyfikacji taki jak w katalogu glownym
  380. free(nazwa_pomocnicza);
  381. break;
  382. }
  383.  
  384. } while ((ep2) != NULL); //dopoki nie przejrzysz katalogu docelowego
  385.  
  386. closedir(directoryChild);
  387. } while (ep != NULL); //dopoki nie przejrzysz katalogu glownego
  388.  
  389. closedir(directoryParent);
  390. return;
  391. }
  392.  
  393. void DeleteNotExisting(char* poczatkowy, char * koncowy)
  394. {
  395. struct dirent *ep2;
  396. struct stat file;
  397. DIR* directoryChild = opendir(koncowy);
  398.  
  399. do
  400. {
  401. ep2 = readdir(directoryChild);
  402. if (ep2 == NULL)
  403. break;
  404. DIR* directoryParent = opendir(poczatkowy);
  405. chdir(koncowy);
  406. lstat(ep2->d_name, &file);
  407.  
  408. if ((file.st_mode & S_IFMT == S_IFLNK) || (ep2->d_name[0] == '.')) //ignoruj linki
  409. continue;
  410.  
  411. chdir(poczatkowy);
  412. int exists = open(ep2->d_name, O_RDONLY); //jesli istnieje, to mozna go otworzyc
  413.  
  414. if (exists <0) // jesli nie mozna
  415. {
  416. chdir(koncowy);
  417. if (!stat(ep2->d_name, &file))
  418. {
  419. if (S_ISDIR(file.st_mode)) //jesli jest folderem
  420. {
  421. char sciezka[256] = "";
  422. strcat(sciezka, koncowy);
  423. strcat(sciezka, "/");
  424. strcat(sciezka, ep2->d_name);
  425. RemoveDirectory(sciezka); //rekurencyjnie usun podkatalog
  426. continue;
  427. }
  428. else
  429. {
  430. unlink(ep2->d_name); //jesli jest plikiem, usun go
  431. continue;
  432. }
  433. }
  434. }
  435. else //zamknij jesli otworzyzles
  436. close(exists);
  437.  
  438. if (S_ISDIR(file.st_mode)) //jesli otworzyles katalog
  439. {
  440. char* podkatalog1 = CreatePath(poczatkowy, ep2->d_name);
  441. char* podkatalog2 = CreatePath(koncowy, ep2->d_name);
  442. mkdir(podkatalog2, 0777);
  443. DeleteNotExisting(podkatalog1, podkatalog2); //sprawdz rekurencyjnie podkatalog
  444. free(podkatalog1);
  445. free(podkatalog2);
  446. }
  447.  
  448. closedir(directoryParent);
  449.  
  450. } while (ep2 != NULL);
  451.  
  452. closedir(directoryChild);
  453. }
  454.  
  455. void Handler() //obsluga sygnalu
  456. {
  457. syslog(LOG_NOTICE, "Succesfully woked up demon.");
  458. }
  459.  
  460. int main(int argc, char** argv)
  461. {
  462. signal(SIGUSR1, Handler);
  463. char* poczatkowy = argv[1], *koncowy = argv[2];
  464.  
  465. if (CheckArguments(argc, argv) == -1)
  466. return -1;
  467.  
  468. setlogmask(LOG_UPTO(LOG_NOTICE));
  469. openlog("demonpliki", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
  470. pid_t pid, sid;
  471.  
  472. /*
  473. pid = fork(); //rozgalezienie
  474. if (pid < 0)
  475. exit(EXIT_FAILURE);
  476.  
  477. if (pid > 0)
  478. exit(EXIT_SUCCESS);
  479.  
  480. umask(0);
  481.  
  482. sid = setsid();
  483. if (sid < 0)
  484. exit(EXIT_FAILURE);
  485. */
  486. while (1)
  487. {
  488. syslog(LOG_NOTICE, "Program started by User %d", getuid()); //informacja kontrolna w logach
  489. UpdateDirectory(poczatkowy, koncowy); //zaktualizuj nowe/modyfikowane pliki
  490. DeleteNotExisting(poczatkowy, koncowy); //usun nieistniejace pliki w katalogu glownym
  491. sleep(timepar); //uspij demona
  492. }
  493. closelog(); //zamknij logi
  494. exit(EXIT_SUCCESS); //wyjdz
  495. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement