Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <unistd.h>
- #include <syslog.h>
- #include <string.h>
- #include <stdbool.h>
- #include <dirent.h>
- #include <assert.h>
- #include <time.h>
- #include <signal.h>
- #include <sys/mman.h>
- #include <utime.h>
- int timepar = 300;
- bool checkDirectory = 0;
- size_t size = 1000000;
- char* CreatePath(char* path, char* filetomerge)
- {
- int length = strlen(path) + strlen(filetomerge);
- char *fullpath = malloc( sizeof(char) * ( length + 1 ) );
- memset( fullpath, 0x00, length ); //wyczysc nowa tablice
- strcat(fullpath, path);
- strcat(fullpath, "/");
- strcat(fullpath, filetomerge);
- return fullpath;
- }
- void CopyByMapping(char* poczatkowy, char * koncowy, struct dirent * ep, struct dirent * ep2)
- {
- syslog(LOG_NOTICE, "MAPOWANIE");
- int sfd, dfd;
- char *src, *dest;
- size_t filesize;
- char* name1 = CreatePath(poczatkowy, ep->d_name); //tworzenie sciezki zrodla
- char* name2 = CreatePath(koncowy, ep->d_name); //sciezka docelowa
- sfd = open(name1, O_RDONLY);
- filesize = lseek(sfd, 0, SEEK_END);
- src = mmap(NULL, filesize, PROT_READ, MAP_PRIVATE, sfd, 0);
- dfd = open(name2, O_RDWR | O_CREAT, 0777);
- ftruncate(dfd, filesize);
- dest = mmap(NULL, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, dfd, 0);
- memcpy(dest, src, filesize); // Czy można
- munmap(src, filesize);
- munmap(dest, filesize);
- free(name1);
- free(name2);
- close(sfd);
- close(dfd);
- }
- int ReadMappingBorder(char* a)
- {
- int i = 1;
- int j = 0;
- size = 0;
- size_t power = 1;
- size_t digit = 0;
- int length = strlen(a);
- while (i<length) //petla zamienia liczbe ze string na int
- {
- digit = a[length - i] - '0';
- power = 1;
- for (j = 1; j<i; j++)
- power *= 10;
- i++;
- size = size + (digit*power);
- }
- return 1;
- }
- int ReadWakeTime(char* a)
- {
- int i = 0;
- int j = 0;
- timepar = 0;
- int power = 1;
- int digit = 0;
- int length = strlen(a);
- while (i<length) //zamiana liczby string na int
- {
- digit = a[length - i - 1] - '0';
- power = 1;
- for (j = 0; j<i; j++)
- power *= 10;
- i++;
- timepar = timepar + (digit*power);
- }
- return 1;
- }
- bool CheckDirectories(char** argv)
- {
- DIR* chk1 = opendir(argv[1]); //jesli mozna otworzyc katalog bez bledow, to sciezki sa poprawne
- if (chk1 == NULL)
- {
- printf("Bad directory: %s \n", argv[1]);
- return false;
- }
- closedir(chk1);
- chk1 = opendir(argv[2]);
- if (chk1 == NULL)
- {
- printf("Bad directory: %s \n", argv[2]);
- return false;
- }
- closedir(chk1);
- return true;
- }
- bool IsDigit(char* digit, int length)
- {
- int i = 0;
- if (digit[0] == '-') //pomijanie znaku '-' - przesylany przy rozmiarze granicy do mapowania
- i++;
- for (; i<length; i++)
- {
- if (digit[i] >= '0' && digit[i] <= '9'); //jesli jest charem ktory jest liczba
- else
- return false; //jesli nie
- }
- return true;
- }
- int RemoveDirectory(char *path)
- {
- DIR *d = opendir(path);
- size_t path_len = strlen(path);
- int r = -1;
- if (d)
- {
- struct dirent *p;
- r = 0;
- while (!r && (p = readdir(d)))
- {
- int r2 = -1;
- char *buf;
- size_t len;
- if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) //ignorowanie zawartosci kazdego folderu . i ..
- {
- continue;
- }
- len = path_len + strlen(p->d_name) + 2;
- buf = malloc(len);
- if (buf)
- {
- struct stat statbuf;
- snprintf(buf, len, "%s/%s", path, p->d_name);
- if (!stat(buf, &statbuf))
- {
- if (S_ISDIR(statbuf.st_mode)) //jesli ma w sobie folder, to rekurencyjnie wywolaj funkcje
- { //jest to spowodowane brakiem mozliwosci usuwania niepustych folderow
- r2 = RemoveDirectory(buf);
- }
- else //jesli ma w sobie plik, usun go
- {
- r2 = unlink(buf);
- }
- }
- free(buf);
- }
- r = r2;
- }
- closedir(d);
- }
- if (!r) //jesli jest pusty, to usun folder
- {
- r = rmdir(path);
- }
- return r;
- }
- bool RecogniseArgument(int which, char **argv)
- {
- int length = strlen(argv[which]);
- if (strcmp(argv[which], "-R") == 0) //jesli podano -R
- checkDirectory = true;
- else if (argv[which][0] == '-' && IsDigit(argv[which], length)) //jesli podano granice mapowania
- ReadMappingBorder(argv[which]);
- else if (IsDigit(argv[which], length)) //jesli podano czas
- ReadWakeTime(argv[which]);
- else { //jesli dodatkowy parametr jest bledny
- fprintf(stderr, "Wrong argument number: %d. \n", which);
- errno=EINVAL;
- perror("Demon");
- return false;
- }
- return true;
- }
- int CheckArguments(int argc, char **argv)
- {
- if (argc<3) //jesli nie podano sciezek
- {
- fprintf(stderr, "No enought arguments. \n");
- errno=EINVAL;
- perror("Demon");
- return -1;
- }
- else if (argc == 3 && CheckDirectories(argv)); //jesli podano poprawne katalogi
- //nie rob nic, ale nie else
- else if (argc == 4 && CheckDirectories(argv)) //jesli podano katalogi i 1 parametr
- {
- if(!RecogniseArgument(3, argv))
- return -1;
- }
- else if (argc == 5 && CheckDirectories(argv)) //jesli dwa argumenty dodatkowe
- {
- if(!RecogniseArgument(3, argv) || !RecogniseArgument(4, argv))
- return -1;
- }
- else if (argc == 6 && CheckDirectories(argv)) //jesli podano trzy dodatkowe parametry
- {
- if(!RecogniseArgument(3, argv) || !RecogniseArgument(4, argv) || !RecogniseArgument(5, argv))
- return -1;
- }
- else
- {
- fprintf(stderr, "Too many arguments! \n");
- errno=EINVAL;
- perror("Demon");
- return false;
- }
- return 0;
- }
- void CopyFile(char* poczatkowy, char * koncowy, struct dirent * ep, struct dirent * ep2)
- {
- int out,in; //FILE *out, *in;
- char* name1 = CreatePath(poczatkowy, ep->d_name);
- char* name2 = CreatePath(koncowy, ep->d_name);
- in = open(name1, O_RDONLY);
- out = open(name2, O_WRONLY | O_CREAT | O_TRUNC,0777);
- size_t n, m;
- char * buff = (char *)calloc(100,sizeof(char));
- do //kopiowanie porcjami
- {
- n = read(in,buff,sizeof(buff)-1);
- if (n) m = write(out,buff, n);
- else m = 0;
- } while ((n > 0) && (n == m));
- close(out);
- close(in);
- free(name1); //zwolnij pamiec sciezek
- free(name2);
- syslog(LOG_NOTICE, ep->d_name); //kontrolny zapis w logach
- return;
- }
- void UpdateDirectory(char* poczatkowy, char * koncowy)
- {
- DIR* directoryParent = opendir(poczatkowy);
- struct utimbuf new_times;
- struct dirent *ep, *ep2;
- struct stat file, file1;
- time_t mod1, mod2;
- int fd;
- do
- {
- ep = readdir(directoryParent); //przegladaj katalog glowny
- if (ep == NULL) //jesli pusty, zostaw
- break;
- DIR* directoryChild = opendir(koncowy); //otworz katalog docelowy
- do
- {
- ep2 = readdir(directoryChild); //przegladaj zawartosc katalogu docelowego
- if (ep2 == NULL) //jesli pusty, zostaw
- break;
- chdir(poczatkowy);
- lstat(ep->d_name, &file); //czytaj dane o pliku z katalogu
- size_t filesize = file.st_size;
- if ((file.st_mode & S_IFMT == S_IFLNK) || (ep->d_name[0] == '.')) //jesli nie jest linkiem
- break;
- chdir(koncowy); //operacje na docelowym katalogu
- lstat(ep2->d_name, &file1);
- mod1 = file.st_mtime;
- mod2 = file1.st_mtime;
- int tmp = open(ep->d_name, O_RDONLY);
- if (tmp <0) //jesli nie mozna otworzyc pliku, to on nie istnieje
- {
- if (S_ISDIR(file.st_mode)) //jesli jest katalogiem
- {
- if (checkDirectory) //jesli demon ma uwzgledniac katalogi
- {
- char* podkatalog1 = CreatePath(poczatkowy, ep->d_name);
- char* podkatalog2 = CreatePath(koncowy, ep->d_name);
- mkdir(podkatalog2, 0777); //stworz podkatalog w folderze docelowym
- UpdateDirectory(podkatalog1, podkatalog2); //rekurencyjnie wykonaj dla podkatalogu
- free(podkatalog1);
- free(podkatalog2);
- }
- break;
- }
- fd = open(ep->d_name, O_CREAT, 0777);
- close(fd);
- if (filesize>size) //jesli jest ponad progiem uzytkownika do mapowania
- CopyByMapping(poczatkowy, koncowy, ep, ep2);
- else
- CopyFile(poczatkowy, koncowy, ep, ep2);
- new_times.actime = file.st_atime;
- new_times.modtime = file.st_mtime;
- char* nazwa_pomocnicza = CreatePath(koncowy, ep2->d_name);
- utime(nazwa_pomocnicza, &new_times); //ustaw czas modyfikacji taki jak w katalogu glownym
- free(nazwa_pomocnicza);
- break;
- }
- else
- close(tmp); //zamknij plik jesli go otworzyles
- if (S_ISDIR(file.st_mode)) //jesli jest katalogiem i istnieje
- {
- if (checkDirectory)
- {
- char* podkatalog1 = CreatePath(poczatkowy, ep->d_name);
- char* podkatalog2 = CreatePath(koncowy, ep->d_name);
- UpdateDirectory(podkatalog1, podkatalog2); //rekurencyjnie sprawdz jego zawartosc
- free(podkatalog1);
- free(podkatalog2);
- }
- break;
- }
- if ((difftime(mod1, mod2) != 0.0 && (strcmp(ep->d_name, ep2->d_name) == 0)))
- { //jesli itnieje i ma inny czas modyfikacji
- fd = open(ep->d_name, O_RDONLY);
- size_t filesize = lseek(fd, 0, SEEK_END);
- close(fd);
- if (filesize>size)
- CopyByMapping(poczatkowy, koncowy, ep, ep2);
- else
- CopyFile(poczatkowy, koncowy, ep, ep2);
- new_times.actime = file.st_atime; //zmiana czasu modyfikacji na ten, z katalogu glownego
- new_times.modtime = file.st_mtime;
- char* nazwa_pomocnicza = CreatePath(koncowy, ep2->d_name);
- utime(nazwa_pomocnicza, &new_times); //ustaw czas modyfikacji taki jak w katalogu glownym
- free(nazwa_pomocnicza);
- break;
- }
- } while ((ep2) != NULL); //dopoki nie przejrzysz katalogu docelowego
- closedir(directoryChild);
- } while (ep != NULL); //dopoki nie przejrzysz katalogu glownego
- closedir(directoryParent);
- return;
- }
- void DeleteNotExisting(char* poczatkowy, char * koncowy)
- {
- struct dirent *ep2;
- struct stat file;
- DIR* directoryChild = opendir(koncowy);
- do
- {
- ep2 = readdir(directoryChild);
- if (ep2 == NULL)
- break;
- DIR* directoryParent = opendir(poczatkowy);
- chdir(koncowy);
- lstat(ep2->d_name, &file);
- if ((file.st_mode & S_IFMT == S_IFLNK) || (ep2->d_name[0] == '.')) //ignoruj linki
- continue;
- chdir(poczatkowy);
- int exists = open(ep2->d_name, O_RDONLY); //jesli istnieje, to mozna go otworzyc
- if (exists <0) // jesli nie mozna
- {
- chdir(koncowy);
- if (!stat(ep2->d_name, &file))
- {
- if (S_ISDIR(file.st_mode)) //jesli jest folderem
- {
- char sciezka[256] = "";
- strcat(sciezka, koncowy);
- strcat(sciezka, "/");
- strcat(sciezka, ep2->d_name);
- RemoveDirectory(sciezka); //rekurencyjnie usun podkatalog
- continue;
- }
- else
- {
- unlink(ep2->d_name); //jesli jest plikiem, usun go
- continue;
- }
- }
- }
- else //zamknij jesli otworzyzles
- close(exists);
- if (S_ISDIR(file.st_mode)) //jesli otworzyles katalog
- {
- char* podkatalog1 = CreatePath(poczatkowy, ep2->d_name);
- char* podkatalog2 = CreatePath(koncowy, ep2->d_name);
- mkdir(podkatalog2, 0777);
- DeleteNotExisting(podkatalog1, podkatalog2); //sprawdz rekurencyjnie podkatalog
- free(podkatalog1);
- free(podkatalog2);
- }
- closedir(directoryParent);
- } while (ep2 != NULL);
- closedir(directoryChild);
- }
- void Handler() //obsluga sygnalu
- {
- syslog(LOG_NOTICE, "Succesfully woked up demon.");
- }
- int main(int argc, char** argv)
- {
- signal(SIGUSR1, Handler);
- char* poczatkowy = argv[1], *koncowy = argv[2];
- if (CheckArguments(argc, argv) == -1)
- return -1;
- setlogmask(LOG_UPTO(LOG_NOTICE));
- openlog("demonpliki", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
- pid_t pid, sid;
- /*
- pid = fork(); //rozgalezienie
- if (pid < 0)
- exit(EXIT_FAILURE);
- if (pid > 0)
- exit(EXIT_SUCCESS);
- umask(0);
- sid = setsid();
- if (sid < 0)
- exit(EXIT_FAILURE);
- */
- while (1)
- {
- syslog(LOG_NOTICE, "Program started by User %d", getuid()); //informacja kontrolna w logach
- UpdateDirectory(poczatkowy, koncowy); //zaktualizuj nowe/modyfikowane pliki
- DeleteNotExisting(poczatkowy, koncowy); //usun nieistniejace pliki w katalogu glownym
- sleep(timepar); //uspij demona
- }
- closelog(); //zamknij logi
- exit(EXIT_SUCCESS); //wyjdz
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement