Daemon synchronizujący dwa katalogi

0

Witam
Mam problem z daemonem w linuxie, gdy próbuje go odpalić wyskakuje komunikat naruszenie ochrony pamięci. Daemon miał za zadanie kopiować pliki z katalogu źródłowego do docelowego, oraz je usuwać jeśli były jakieś pliki w katalogu docelowym które nie są w katalogu źródłowym

Kod programu:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/types.h>
#include <dirent.h>
#include <syslog.h>
#include <signal.h>
#include <sys/syslog.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include"header.h"

#define BUFSIZE 1024

int sleeplenght = 5; //długość drzemki demona
int i;


int main(int argc,char* argv[])
{
	sigset_t iset, iset2;
	struct sigaction sleeper;
	struct sigaction listener;
	int pid, j,rec;
	long int size;
	int flag = 1; rec=0; size=100000;
	openlog("demon", LOG_PID, LOG_LOCAL1);

// SPRAWDZENIE POPRAWNOŚCI PARAMETRÓW FUNKCJI

	if (( argc < 3 ) || ( argc > 6 )) //czy podana jest wlasciwa liczba parametrow funkcji
	{
		syslog(LOG_ERR,"niewłasciwe wywolanie funkcji");
		exit(1);
	}
	else if (access(argv[1],0) == -1) //czy istnieje dostęp do podanej przez uzytkownika sciezki
	{
		syslog(LOG_ERR,"Sciezka1 - '%s' - nie istnieje\n",argv[1]);
		exit(1);
	}
	else if (access(argv[2],0) == -1) //czy istnieje dostęp do podanej przez uzytkownika sciezki
	{
		syslog(LOG_ERR,"Sciezka1 - '%s' - nie istnieje\n",argv[2]);
		exit(1);
	}
	else if ((if_Dir(argv[1])) != 1) //czy podana ścieżka jest katalogiem
	{
		syslog(LOG_ERR,"Sciezka1 - '%s' - nie jest katalogiem\n",argv[1]);
		exit(1);
	}
	else if ((if_Dir(argv[2])) != 1) //czy podana ścieżka jest katalogiem
	{
		syslog(LOG_ERR,"Sciezka1 - '%s' - nie jest katalogiem\n",argv[2]);
		exit(1);
	}

// DODATKOWE PARAMETRY FUNKCJI
	if (argc > 3)
	{
		for (i=3; i < argc; i++)
		{
			switch (i)
			{
				case 3: //rekurencyjna synchronizacja katalogów
					if ((argv[i][0] == '-') || (argv[i][1] == 'R')) rec = 1;
					break;
				case 4: //parametr określa długość drzemki demona
					for (j=0; j < strlen(argv[i]); ++j)
					{
						if (!(isdigit(argv[i][j])))
						{
							flag = 0;
						}
					}
					if (flag=1) sleeplenght = atoi(argv[i]);
					break;
				case 5: //parametr określa graniczny rozmiar pliku przy którym zmieniamy metode kopiowania
					flag = 1;
					for (j=0; j < strlen(argv[i]); ++j)
					{
						if (!(isdigit(argv[i][j])))
						{

							flag = 0;

						}
					}
					if (flag=1) size = atoi(argv[i]);
					break;
				default: break;
			}
		}
	}
	while(1 == 1)
	{
		sigemptyset(&iset);
		sigemptyset(&iset2);
		sleeper.sa_handler = &fsleep;
		sleeper.sa_mask = iset;
		sleeper.sa_flags = 0;
		sigaction(SIGALRM, &sleeper, NULL);
		listener.sa_handler = &fsig;
		listener.sa_mask = iset2;
		listener.sa_flags = 0;
		sigaction(SIGUSR1, &listener, NULL);
		syslog(LOG_INFO,"demon śpi");
		alarm(sleeplenght);
		pause();
		syslog(LOG_INFO,"demon budzi sie");
		synchronize(argv[1], argv[2],rec,size);
		deleteExtras(argv[1], argv[2],rec);
	}
	closelog ();
	return 0;
}

int mode(struct stat info)
{
	if(S_ISDIR(info.st_mode)) return 1;
	else
	if(S_ISREG(info.st_mode)) return 0;
	else return -1;
}

void fsleep(int sig)
{
	syslog(LOG_INFO,"demon obudził się z drzemki");
}

void fsig(int sig)
{
	syslog(LOG_INFO,"obudzenie sygnałem SIGUSR1");
}




//Funcja sprawdza czy podana sciazka jest katalogiem

int if_Dir(char* path)
{
	struct stat info;
	if((stat(path, &info)) < 0) //jeśli nie udało się pobranie informacji o ścieżce, zwracana jest wartość -1
	{
		syslog(LOG_ERR,"nieudane pobranie informacji o pliku\n");
		return -1;
	}
	else return mode(info);
}

//FUNKCJA KOPIUJĄCA PLIKI

int copy(char *source, char *target)
{
	int zrodlowy, docelowy, przeczytanych;
	char buf[BUFSIZE];
	zrodlowy = open(source, O_RDONLY);
	docelowy = open(target, O_WRONLY | O_CREAT | O_TRUNC, 0777);
	syslog(LOG_INFO,"plik z %s został skopiowany do %s",source,target);
	do
	{
		przeczytanych = read(zrodlowy, buf, BUFSIZE);
		if((write(docelowy, buf, przeczytanych)) < 0)
		{
			syslog(LOG_ERR,"nieudane zapisanie do pliku");
			return -1;
		}
	}while(przeczytanych);
	close(zrodlowy);
	close(docelowy);
	return 0;
}

//FUNKCJA KOPIUJĄCA PLIKI (MAPOWANIE)

int copy_mmap(char *source, char *target, struct stat *st)
{
	int zrodlowy, docelowy;
	char* buf;
	zrodlowy = open(source, O_RDONLY);
	docelowy = open(target, O_WRONLY | O_CREAT | O_TRUNC, 0777);
	syslog(LOG_INFO,"plik z %s został skopiowany do %s stosując metode mapowania",source,target);
	buf = mmap(0,st->st_size,PROT_READ, MAP_SHARED, zrodlowy, 0);
	if((write(docelowy, buf, st->st_size)) < 0)
	{
		syslog(LOG_ERR,"nieudane zapisanie do pliku");
		return -1;
	}
	close(zrodlowy);
	close(docelowy);
	return 0;
}

//SYNCHRONIZACJA KATALOGÓW

int synchronize(char *src, char *dst, int rec, long int size)
{
	DIR *catSrc;
	DIR *catDst;
	struct dirent *dit;
	char srcpath[30];
	char dstpath[30];
	struct stat srcfileinfo;
	struct stat dstfileinfo;
	if (((catSrc = opendir(src)) == NULL) || ((catDst = opendir(dst)) == NULL))
	{
		syslog(LOG_ERR,"Blad otwarcia katalogu\n");
		return -1;
	}
	syslog(LOG_INFO,"synchronizacja dwóch katalogów %s %s",src,dst);
	while ((dit = readdir(catSrc)) != NULL)
	{
		if( (strcmp(dit->d_name,".")==0) || (strcmp(dit->d_name,"..")==0) ) continue;
		dstfileinfo.st_mtime = 0;
		strcpy(srcpath,src);
		strcpy(dstpath,dst);
		strcat(srcpath,"/");
		strcat(srcpath,dit->d_name);
		strcat(dstpath,"/");
		strcat(dstpath,dit->d_name);
		stat(srcpath,&srcfileinfo);
		stat(dstpath,&dstfileinfo);
		switch (mode(srcfileinfo)) //sprawdzamy czym jest ścieżka
		{
			case 0: //jeśli ścieżka jest zwykłym plikiem
				if(srcfileinfo.st_mtime > dstfileinfo.st_mtime) //jeśli data modyfikacji pliku w katalogu źródłowym jest późniejsza
				{
					if (srcfileinfo.st_size > size) //jeśli rozmiar pliku przekracza zadany rozmiar
					copy_mmap(srcpath,dstpath,&srcfileinfo); //kopiowanie przez mapowanie
					else copy(srcpath,dstpath); //zwykłe kopiowanie
				}
				i++;
				break;
			case 1: //jesli ścieżka jest folderem
				if (rec == 1) //jeśli użytkownik wybral rekurencyjną synchronizacje
				{
					if (stat(dstpath,&dstfileinfo) == -1) //jeśli w katalogu docelowym brak folderu z katalogu źródłowego
					{
						mkdir(dstpath,srcfileinfo.st_mode); //utworz w katalogu docelowym folder
						synchronize(srcpath,dstpath,rec,size); //przekopiuj do niego pliki z folderu z katalogu źródłowego
					}
					else synchronize(srcpath,dstpath,rec,size);
				}
				break;
			default: break;
		}
	}
	syslog(LOG_INFO,"readdir() found a total of %i files", i);
	closedir(catDst);
	closedir(catSrc);
	free(dit);
	return 0;
}

//FUNCKCJA USUWA PLIKI Z KATALOGU DOCELOWEGO

void deleteExtras(char *src, char *dst, int rec)
{
	DIR *catSrc;
	DIR *catDst;
	struct dirent *dit;
	char srcpath[30];
	char dstpath[30];
	struct stat srcfileinfo;
	struct stat dstfileinfo;
	dit=malloc(sizeof(struct dirent));
	if (((catDst = opendir(dst)) == NULL))
	{
		syslog(LOG_ERR,"Blad otwarcia katalogu\n");
	}
	while((dit = readdir(catDst))!=NULL)
	{
		if( (strcmp(dit->d_name,".")==0) || (strcmp(dit->d_name,"..")==0) ) continue;
		strcpy(srcpath,src);
		strcat(srcpath,"/");
		strcat(srcpath,dit->d_name);
		strcpy(dstpath,dst);
		strcat(dstpath,"/");
		strcat(dstpath,dit->d_name);
		lstat(dstpath,&dstfileinfo);
		if(mode(dstfileinfo) == 0)//regularny plik
		{
			if(lstat(srcpath,&srcfileinfo)==0) //istnieje taki plik w docelowym
			{
				if(mode(srcfileinfo) != 0)//jezeli nie jest regularnym plikiem
				{
					unlink(dstpath);
					syslog(LOG_INFO,"plik %s został usuniety",dstpath);
				}
			}
			else//nie ma takiego pliku w docelowym
			{
				unlink(dstpath);
				syslog(LOG_INFO,"plik %s został usuniety",dstpath);
			}
		}
		if(mode(dstfileinfo) == 1 && rec)//katalog i oprcja -R
		{
			if(lstat(srcpath,&srcfileinfo)==0) // istnieje taki katalog
			{
				if(mode(srcfileinfo) == 1)//katalog
				deleteExtras(srcpath, dstpath,rec);
			}
			else//nie ma takiego katalogu
			{
				deleteExtras(srcpath, dstpath,rec);
				rmdir(dstpath);
			}
		}
	}
	closedir(catDst);
	free(dit);
}

Oraz header:

#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>


int mode(struct stat info); //funkcja zwraca wartosc ktora reprezentuje rodzaj: 1-folder, 0-plik, - 1 inne
void fsleep(int sig); //funkcja dla wywołania sygnału SIGALRM
void fsig(int sig); //funkcja dla wywołania sygnału SIGUSR1
int if_Dir(char* path); //sprawdza, czy dana ścieżka jest katalogiem
int copy(char *source, char *target); //funkcja kopiujaca pliki
int copy_mmap(char *source, char *target, struct stat *st);//funkcja kopiująca pliki poprzez mapowanie
int synchronize(char *src, char *dst, int rec, long int size);//funkcja synchronizuje podkatalogi
void deleteExtras(char *src, char *dst, int rec);//funkcja usuwa zbędne foldery z katalogu docelowego


#endif // HEADER_H_INCLUDED

Za każdą pomoc z góry dziękuje.

0

Sam napisałeś ten kod?

Jeśli tak, powinieneś wiedzieć o co chodzi (z małą pomocą debuggera).

Jeżeli nie, zgłoś się do autora.

1 użytkowników online, w tym zalogowanych: 0, gości: 1