Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <signal.h>
- #include <dirent.h>
- #include <string.h>
- #include <time.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <syslog.h>
- #include <sys/mman.h>
- int sleepTime = 300;
- int sig_check = 0;
- int isRecurention = 0;
- int isCopyingByParametr = 0;
- int checkParameters(int argc, char *argv[])
- {
- // Sprawdzenie czy 1. i 2. argument jest sciezka do katalogu
- struct stat file, file2;
- stat(argv[1], &file);
- if (!S_ISDIR(file.st_mode))
- {
- printf("Sciezka %s nie prowadzi do katalogu!\n", argv[1]);
- return 0;
- }
- stat(argv[2], &file2);
- if (!S_ISDIR(file2.st_mode))
- {
- printf("Sciezka %s nie prowadzi do katalogu!\n", argv[2]);
- return 0;
- }
- if (argc >= 7)
- return 0;
- // Sprawdzenie 3. argumentu ( Czy jest liczba )
- if (argc >= 4)
- {
- if (atoi(argv[3]) > 0)
- sleepTime = atoi(argv[3]);
- else
- {
- printf("Zly 3 parametr!!");
- return 0;
- }
- }
- // Sprawdzenie czy zostal przekazany 4. argument i jego wartosci
- if (argc >= 5)
- {
- if (!strcmp(argv[4], "-R"))
- {
- isRecurention = 1;
- }
- else
- {
- if (atoi(argv[4]) > 0)
- {
- isCopyingByParametr = atoi(argv[4]);
- }
- else
- {
- printf("Zly 4 parametr!!!\n");
- return 0;
- }
- }
- }
- // Sprawdzenie czy zostal przekazany 5. argument i jego wartosci
- if (argc == 6)
- {
- if (!strcmp(argv[5], "-R") && isRecurention == 0)
- {
- isRecurention = 1;
- }
- else
- {
- if (atoi(argv[5]) > 0 && isCopyingByParametr == 0)
- {
- isCopyingByParametr = atoi(argv[5]);
- }
- else
- {
- printf("Zly 5 parametr!!!\n");
- return 0;
- }
- }
- }
- return -1;
- }
- void signalHandler()
- {
- syslog(LOG_INFO, "Demon odebral sygnal SIGURS1\n");
- sig_check = 1;
- }
- /* Zmiana czasu modyfikacji pliku
- void changeModifyTime(char *path)
- {
- struct stat attribSource;
- stat(path, &attribSource);
- time_t result = time(NULL);
- result += 2 * sleepTime;
- printf("%s\n", asctime(gmtime(&result)));
- attribSource.st_mtime = result;
- }
- */
- // funkcja zwraca wielkosc pliku
- size_t getFileSize(const char *filePath)
- {
- struct stat st;
- stat(filePath, &st);
- return st.st_size;
- }
- // Funkcja kopiujaca pliki uzywajac mmap/write
- int copyLargeFile(char *pathSource, char *pathTarget, char *fileName)
- {
- // Tworzenie nowego ciagu znakow reprezentujacego sciezke do kopiowanego pliku
- char newPathSource[strlen(pathSource) + strlen(fileName) + 2];
- strcpy(newPathSource, pathSource);
- strcat(newPathSource, "/");
- strcat(newPathSource, fileName);
- int in = open(newPathSource, O_RDONLY);
- if (in < 0)
- {
- printf("Blad przy otwieraniu pliku %s\n", pathSource);
- syslog(LOG_ERR, "Blad przy otwieraniu pliku %s\n", pathSource);
- return 0;
- }
- // Tworzenie nowego ciagu znakow reprezentujacego sciezke do miejsca kopiowania pliku
- char newPathTarget[strlen(pathTarget) + strlen(fileName) + 2];
- strcpy(newPathTarget, pathTarget);
- strcat(newPathTarget, "/");
- strcat(newPathTarget, fileName);
- int out = open(newPathTarget, O_WRONLY | O_CREAT, S_IRWXU);
- if (out < 0)
- {
- printf("Blad przy otwieraniu pliku %s\n", pathTarget);
- syslog(LOG_ERR, "Blad przy otwieraniu pliku %s\n", pathTarget);
- return 0;
- }
- size_t sizeFileSource = getFileSize(newPathSource);
- void *mmappedData = mmap(NULL, sizeFileSource, PROT_READ, MAP_PRIVATE | MAP_POPULATE, in, 0);
- write(out, mmappedData, sizeFileSource);
- syslog(LOG_INFO, "Skopiowano plik: %s do folderu: %s\n", newPathSource, pathTarget);
- munmap(mmappedData, sizeFileSource);
- close(in);
- close(out);
- //changeModifyTime(newPathTarget);
- //time_t result = time(NULL);
- //printf("Kopiowanie Duze: %s\n", asctime(gmtime(&result)));
- }
- // Funckja kopiujaca pliki uzywajac read/write
- int copy(char *pathSource, char *pathTarget, char *fileName)
- {
- // Tworzenie nowego ciagu znakow reprezentujacego sciezke do kopiowanego pliku
- char newPathSource[strlen(pathSource) + strlen(fileName) + 2];
- strcpy(newPathSource, pathSource);
- strcat(newPathSource, "/");
- strcat(newPathSource, fileName);
- int in = open(newPathSource, O_RDONLY);
- if (in < 0)
- {
- printf("Blad przy otwieraniu pliku %s\n", pathSource);
- syslog(LOG_ERR, "Blad przy otwieraniu pliku %s\n", pathSource);
- return 0;
- }
- // Tworzenie nowego ciagu znakow reprezentujacego sciezke do miejsca kopiowania pliku
- char newPathTarget[strlen(pathTarget) + strlen(fileName) + 2];
- strcpy(newPathTarget, pathTarget);
- strcat(newPathTarget, "/");
- strcat(newPathTarget, fileName);
- int out = open(newPathTarget, O_WRONLY | O_CREAT, S_IRWXU);
- if (out < 0)
- {
- printf("Blad przy otwieraniu pliku %s\n", pathTarget);
- syslog(LOG_ERR, "Blad przy otwieraniu pliku %s\n", pathTarget);
- return 0;
- }
- char *buffor = malloc(sizeof(char) * 1000);
- int size;
- int outSize = 1000;
- while (outSize == 1000)
- {
- size = read(in, buffor, sizeof(char) * 1000);
- outSize = write(out, buffor, size);
- }
- free(buffor);
- close(in);
- close(out);
- //changeModifyTime(newPathTarget);
- //time_t result = time(NULL);
- //printf("Skopiowane %s\n", asctime(gmtime(&result)));
- syslog(LOG_INFO, "Skopiowano plik: %s do folderu: %s\n", newPathSource, pathTarget);
- return 1;
- }
- // Funkcja usuwajaca pliki z katalogu docelowego ktorych nie ma w katalogu zrodlowym
- int delete(char *pathSource, char *pathTarget)
- {
- struct dirent *tar;
- DIR *target;
- target = opendir(pathTarget);
- if (target == NULL)
- {
- printf("Blad przy otwieraniu katalogu %s\n", pathSource);
- syslog(LOG_ERR, "Blad przy otwieraniu katalogu %s\n", pathSource);
- return 0;
- }
- struct stat sorStat;
- while ((tar = readdir(target)) != NULL)
- {
- if (!strcmp(tar->d_name, ".") || !strcmp(tar->d_name, ".."))
- {
- // Nothing
- }
- else
- {
- // Tworzenie nowego ciagu znakow reprezentujacego sciezki do badanych plikow
- char newPathSource[strlen(pathSource) + strlen(tar->d_name) + 2];
- strcpy(newPathSource, pathSource);
- strcat(newPathSource, "/");
- strcat(newPathSource, tar->d_name);
- char newPathTarget[strlen(pathTarget) + strlen(tar->d_name) + 2];
- strcpy(newPathTarget, pathTarget);
- strcat(newPathTarget, "/");
- strcat(newPathTarget, tar->d_name);
- // Sprawdzenie czy badany plik z katalogu docelowego istnieje rowniez w katalogu zrodlowym
- if (!(lstat(newPathSource, &sorStat) == 0))
- {
- if (tar->d_type == DT_DIR && isRecurention == 1) // Sprawdzenie czy plik jest katalogiem i czy zostal przekazany parametr -R
- {
- // Usuwanie wszystkich plikow z danego katalogu
- delete(newPathSource, newPathTarget);
- if (rmdir(newPathTarget) == 0) // Usuniecie katalogu
- syslog(LOG_INFO, "Usunieto katalog %s", newPathTarget);
- else
- syslog(LOG_ERR, "Blad przy usuwaniu katalogu %s", newPathTarget);
- }
- if (tar->d_type == DT_REG) // Sprawdzenie czy plik jest plikiem regularnym
- {
- // Usuwanie pliku
- if (unlink(newPathTarget) == 0)
- {
- syslog(LOG_INFO, "Usunieto plik: %s\n", newPathTarget);
- }
- else
- syslog(LOG_ERR, "Blad przy usuwaniu katalogu %s", newPathTarget);
- }
- }
- }
- }
- closedir(target);
- }
- // Funkcja kopiuje pliki z folderu zrodlowego do folderu docelowego
- int copyFiles(char *pathSource, char *pathTarget)
- {
- DIR *source;
- source = opendir(pathSource);
- if (source == NULL)
- {
- printf("Blad przy otwieraniu katalogu %s\n", pathSource);
- syslog(LOG_ERR, "Blad przy otwieraniu katalogu %s\n", pathSource);
- return 0;
- }
- struct dirent *sor;
- struct stat targetStat, sourceStat;
- while ((sor = readdir(source)) != NULL)
- {
- if (!strcmp(sor->d_name, ".") || !strcmp(sor->d_name, ".."))
- {
- // Nothing
- }
- else
- {
- // Tworzenie nowego ciagu znakow reprezentujacego sciezki do badanych plikow
- char newPathSource[strlen(pathSource) + strlen(sor->d_name) + 2];
- strcpy(newPathSource, pathSource);
- strcat(newPathSource, "/");
- strcat(newPathSource, sor->d_name);
- char newPathTarget[strlen(pathTarget) + strlen(sor->d_name) + 2];
- strcpy(newPathTarget, pathTarget);
- strcat(newPathTarget, "/");
- strcat(newPathTarget, sor->d_name);
- // Sprawdzenie czy badany plik z katalogu zrodlowego istnieje rowniez w katalogu docelowym
- if (!lstat(newPathTarget, &targetStat))
- {
- if (sor->d_type == DT_REG)
- {
- // Obliczenie roznicy pomiedzy czasem modyfikacji obu plikow
- double result = difftime(sourceStat.st_mtime, targetStat.st_mtime);
- if (result > 0) // jesli roznica jest powyzej zera to plik w katalogu docelowym ma date pozniejsza niz plik w katalogu zrodlowym
- {
- if (isCopyingByParametr > 0) // Sprawdzenie czy zostal przekazany parametr dotyczacy drugiego sposobu kopiowania
- {
- size_t sizeOfFile = getFileSize(newPathSource);
- if (sizeOfFile > isCopyingByParametr) // jesli rozmiar pliku jest wiekszy od parametru, wykonywane jest kopiowanie 'copyLargeFiles'
- copyLargeFile(pathSource, pathTarget, sor->d_name);
- else // zwykle kopiowanie
- copy(pathSource, pathTarget, sor->d_name);
- }
- else
- { // jesli dodatkowy parametr nie zostal przekazany, wykonywane jest zwyczajne kopiowanie
- copy(pathSource, pathTarget, sor->d_name);
- }
- }
- }
- if (sor->d_type == DT_DIR && isRecurention == 1) // sprawdzenie czy plik jest katalogiem i czy zostal przekazany parametr -R
- {
- // Usuwanie i Kopiowanie plikow w katalogu podrzednym
- delete(newPathSource, newPathTarget);
- copyFiles(newPathSource, newPathTarget);
- }
- }
- else // Ta partia kodu jest wykonywana jesli plik nie istnieje w katalogu docelowym a istnieje w zrodlowym
- {
- if (sor->d_type == DT_REG) // Sprawdzenie czy plik jest plikiem regularnym
- {
- if (isCopyingByParametr > 0) // Sprawdzenie czy zostal przekazany parametr dotyyczacy drugiego sposobu kopiowania
- {
- size_t sizeOfFile = getFileSize(newPathSource);
- printf("Size: %ld\n", sizeOfFile);
- if (sizeOfFile > isCopyingByParametr) // jesli rozmiar pliku jest wiekszy od parametru, wykonywane jest kopiowanie 'copyLargeFiles'
- copyLargeFile(pathSource, pathTarget, sor->d_name);
- else // zwykle kopiowanie
- copy(pathSource, pathTarget, sor->d_name);
- }
- else
- { // jesli dodatkowy parametr nie zostal przekazany, wykonywane jest zwyczajne kopiowanie
- copy(pathSource, pathTarget, sor->d_name);
- }
- }
- if (sor->d_type == DT_DIR && isRecurention == 1) // sprawdzenie czy plik jest katalogiem i czy zostal przekazany parametr -R
- {
- // Stworzenie nowego katalogu w katalogu docelowym i skopiowanie plikow do niego z katalogu zrodlowego
- mkdir(newPathTarget, 0700);
- copyFiles(newPathSource, newPathTarget);
- }
- }
- }
- }
- closedir(source);
- }
- int main(int argc, char *argv[])
- {
- // Sprawdzenie poprawnosci parametrow
- int check = checkParameters(argc, argv);
- if (check == 0){
- printf("Przekazane parametry sa bledne\n\n");
- printf("Prawidlowy uklad parametrow podstawowych wyglada nastepujaco\n");
- printf("./main <Katalog Zrodlowy> <Katalog Docelowy>\n\n");
- printf("Prawidlowe uklady parametrow opcjonalnych wygladaja nastepujaco\n");
- printf("<1> <2> <-R> ,<1> <-R> <2> , <1> <2> , <1> <-R>\n\n");
- printf(" 1 - czas snu demona ( liczba calkowita )\n");
- printf(" 2 - prog rozmiaru pliku dla kopiowania read/write i mmap/write\n");
- printf("-R - rekurencyjna synchornizacja katalogow\n\n");
- printf("Przyklad: ./main katalog1 katalog2 100 -R 1500\n");
- return 0;
- }
- struct sigaction action, oldAction;
- pid_t pid;
- // Tworzenie procesu potomnego
- pid = fork();
- if (pid < 0)
- {
- printf("Nie utworzono procesu potomnego\n");
- }
- if (pid > 0)
- { // proces macierzysty
- return 0;
- }
- if (pid == 0) // Poprawne utworzenie procesu potomnego
- {
- int proces = getpid();
- printf("Jesli chcesz zakonczyc prace demona uzyj polecenia: kill <nr_procesu>\n");
- printf("Jesli chcesz wybudzic demona ze snu, uzyj polecenia kill -s 10 <nr_procesu>\n");
- printf("Numer procesu: %d\n", proces);
- openlog("demon", LOG_PID, LOG_DAEMON);
- syslog(LOG_INFO, "Demon zaczal dzialac!!\n");
- if (setsid() < 0)
- {
- syslog(LOG_ERR, "Problem z wyslaniem\n");
- exit(-1);
- }
- // Ustawienie akcji sygnalu na signalHandler
- action.sa_handler = signalHandler;
- sigfillset(&action.sa_mask);
- action.sa_flags = 0;
- // Ustawienie nowej akcji 'action' zwiazana z sygnalem SIGUSR1
- if (sigaction(SIGUSR1, &action, &oldAction) < 0)
- {
- printf("Blad przy ustawieniu nowej akcji dla sygnalu SIGUSR1");
- }
- printf("PROGRAM STAJE SIE DEMONEM!\n");
- while (1)
- {
- syslog(LOG_INFO, "Demon zasnal na: %d s\n", sleepTime);
- sleep(sleepTime);
- switch (sig_check)
- {
- case 0:
- syslog(LOG_INFO, "Demon sie obudzil\n");
- break;
- case 1:
- syslog(LOG_INFO, "Demon sie obudzil po wykryciu sygnalu SIGURS1\n");
- sig_check = 0;
- break;
- }
- delete(argv[1], argv[2]);
- copyFiles(argv[1], argv[2]);
- }
- return 0;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement