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.