#include #include #include #include #include #include #include #include #include #include //======================================= #define BUFSIZE 512 //size of chunk to be read #define PERM 0644 //file permission for new file #define _PC_PATH_MAX_1 80 void check_cmd_line(int argc, char** argv, char* flag, char* arg1, char* arg2); int copyfile (const char *name1, const char * name2, char* flag); void synfiles(char *file1, char *file2, char *flag); void syncDir (char *name1, char* name2, char *flag); void copy_subdir(char* dir1, char* dir2, char* flag); char find_same_subdir(char* subdir, char* dirk); int find_entry (char *dirname, char *fileName); int isDir (char *name); int fileTyping (char *pathname); char IsOverWriteFile(char* file2, char* flag); char IsCreateFile(char* file2, char* flag); void Disp_Replaced_by(char* file1, char* file2, char* flag); void Disp_Added_to(char* file1, char* file2, char* flag); void GetDirFile(char* fullname, char* dirname, char* filename); void ModifyTime(char* file1, char* file2); //======================================= int main(int argc, char *argv[]) { char flag[4]; char arg1[80],arg2[80]; int i; for(i=0; i<4; i++) flag[i]=0; strcpy(arg1,""); strcpy(arg2,""); check_cmd_line(argc,argv,flag,arg1,arg2); //two directories exist and their name are different if( (isDir(arg1)==1) && (isDir(arg2)==1) && (strcmp(arg1, arg2)!=0)) syncDir(arg1, arg2, flag); //2 files exist else if((isDir(arg1)==0) && (isDir(arg2)==0) && (strcmp(arg1, arg2)!=0)) {char f1[80]; char f2[80]; char dir1[80]; char dir2[80]; GetDirFile(arg1, dir1, f1); GetDirFile(arg2, dir2, f2); if(strcmp(f1,f2)==0) synfiles(arg1, arg2, flag); } else {printf("Command line argument wrong! \n"); exit(1); } exit (0); } //============================================================ void check_cmd_line(int argc, char** argv, char* flag, char* arg1, char* arg2) { int op_n; if(argc > 7) { printf("Command line arguments too many!\n"); exit(1); } if(argc < 3) { printf("Command line arguments too little!\n"); exit(1); } /* treat option */ op_n=argc-3; while(op_n > 0) { op_n--; argv++; if( (strcmp(*argv,"-q")==0) && (flag[0]==0) ) flag[0]='q'; else if( (strcmp(*argv,"-r")==0) && (flag[1]==0) ) flag[1]='r'; else if( (strcmp(*argv,"-c")==0) && (flag[2]==0) ) flag[2]='c'; else if( (strcmp(*argv,"-i")==0) && (flag[3]==0) ) flag[3]='i'; else { printf("Command line arguments wrong!\n"); exit(1); } } argv++; strcpy(arg1,*argv); argv++; strcpy(arg2,*argv); } //============================================================ int isDir(char *name) {int i; i= fileTyping(name); // printf("the file type value is %d \n", i); // exit (0); return i; } //============================================================ int fileTyping (char *pathname) {struct stat s; int retval; retval = stat(pathname, &s); if(retval == -1) return -1; if (S_ISREG(s.st_mode)) return 0; if(S_ISDIR(s.st_mode)) return 1; else return -1; } //========================================================= //file1 and file2 are given by their path name void synfiles (char *file1, char *file2, char* flag) {int copyfs; int filedes1, filedes2; struct stat statFile1, statFile2; time_t time1, time2; // open files and get its time of last modification if((filedes1=open(file1, O_RDONLY))==-1) {printf("error %d\n", errno); exit (-1); } else if (fstat(filedes1, &statFile1)==-1) {printf("Couldn't fstat %s\n", file1); exit(-2); } else time1=statFile1.st_mtime; // open files 2 and set its time of last modification if((filedes2=open(file2, O_RDONLY))==-1) {printf("error %d\n", errno); exit (-3); } else {if(fstat(filedes2, &statFile2)==-1) {printf("Could not fstat %s\n", file2); exit(-4); } time2=statFile2.st_mtime; } //if file1 is newer than file2 if(time1>time2) { char f=IsOverWriteFile(file2,flag); if( f != 0 ) { copyfs=copyfile(file1, file2, flag); //file1 overwrite file2 if( copyfs == 0 ) //success { ModifyTime(file1,file2); //file1_t to file2_t Disp_Replaced_by(file1,file2,flag); //dips.. } else printf("Error copy file.\n"); } } //if file1 is older than file2 else if(time10) { //write buffer to the output file if (write(outfile, buffer, nread)d_ino==0) continue; if(strcmp(dir->d_name,".")==0 || strcmp(dir->d_name,"..")==0) continue; strcpy(fullfilename1,dir1); strcat(fullfilename1,dir->d_name); strcpy(fullfilename2, dir2); strcat(fullfilename2,dir->d_name); if(isDir(fullfilename1)!=0) {if(flag[1] == 'r') {char ff=find_same_subdir(dir->d_name,dir2); if(ff != 0) //same subdir in dir1,dir2 {strcat(fullfilename1, "/"); strcat(fullfilename2, "/"); syncDir(fullfilename1, fullfilename2, flag); //recursive } else //subdir in dir1, no in dir2 copy_subdir(fullfilename1, fullfilename2, flag); } } else {if(find_entry(dir2, dir->d_name)==1) // file does exist in directory 2 synfiles(fullfilename1, fullfilename2, flag); else // no file with same name in directory 2 {int cpfs; char f=IsCreateFile(fullfilename2,flag); if(f != 0 ) {//fname1 overwrite fname2 cpfs=copyfile(fullfilename1, fullfilename2, flag); if(cpfs == 0 ) //success {ModifyTime(fullfilename1,fullfilename2); //fname1_t to fname2_t Disp_Added_to(fullfilename1,fullfilename2,flag); //dips.. } else printf("Error copying files.\n"); } } } } closedir(dp); dp=NULL; //update dir1 if((dp=opendir(dir2))==NULL) printf("error opening directory 2!\n"); while(dir=readdir(dp)) {if(dir->d_ino==0) continue; if(strcmp(dir->d_name,".")==0 || strcmp(dir->d_name,"..")==0) continue; strcpy(fullfilename2, dir2); strcat(fullfilename2, dir->d_name); strcpy(fullfilename1,dir1); strcat(fullfilename1, dir->d_name); if(isDir(fullfilename2)!=0) {if(flag[1] == 'r') {char ff=find_same_subdir(dir->d_name,dir1); if(ff == 0) //subdir in dir1, no in dir2 copy_subdir(fullfilename2, fullfilename1, flag); } } else {if((find_entry (dir1, dir->d_name))==0) // file does NOT exist in directory 1 {int cpfs; char f=IsCreateFile(fullfilename1,flag); if(f != 0 ) {cpfs=copyfile(fullfilename2, fullfilename1, flag); //fname2 overwrite fname1 if(cpfs == 0 ) //success {ModifyTime(fullfilename2, fullfilename1); //fname2_t to fname1_t Disp_Added_to(fullfilename2, fullfilename1,flag); //dips.. } else printf("Error copying file.\n"); } } } } closedir(dp); dp=NULL; } //===================================================== void copy_subdir(char* dir1, char* dir2, char* flag) {static DIR *dp=NULL; struct dirent *dir; char sdir1[80],sdir2[80]; int cpfs; mkdir(dir2, 0744); if((dp=opendir(dir1))==NULL) printf("error opening directory!\n"); while(dir=readdir(dp)) { if(strcmp(dir->d_name,".")==0 || strcmp(dir->d_name,"..")==0) continue; strcpy(sdir1,dir1); strcat(sdir1,"/"); strcat(sdir1,dir->d_name); strcpy(sdir2,dir2); strcat(sdir2,"/"); strcat(sdir2,dir->d_name); if(isDir(sdir1)!=0) //sdir1 is a full name for a dir copy_subdir(sdir1, sdir2, flag); //recursive else {char f=IsCreateFile(sdir2, flag); if(f != 0) {cpfs=copyfile(sdir1, sdir2, flag); //sdir1 overwrite sdir2 if( cpfs == 0 ) //success {ModifyTime(sdir1,sdir2); //sdir1_t to sdir2_t Disp_Added_to(sdir1,sdir2,flag); //dips.. } else printf("Error copying file. \n"); } } } closedir(dp); } //======================================================== //subdir is not full name, dirk is full name //found, return 1; no found, return 0 char find_same_subdir(char* subdir, char* dirk) {char fullfilename2[60]; static DIR *dp=NULL; struct dirent *dir; if((dp=opendir(dirk))==NULL) printf("error opening directory!\n"); while(dir=readdir(dp)) { strcpy(fullfilename2,dirk); strcat(fullfilename2,"/"); strcat(fullfilename2,dir->d_name); if(isDir(fullfilename2)) { if( strcmp(dir->d_name,subdir) == 0 ) { closedir(dp); return 1; } } } closedir(dp); return 0; } //=========================================================== //this piece of code from text book by Keith et al. p 71) //fileName is the ending name of the file int find_entry (char *dirname, char *fileName) {DIR *dp=NULL; struct dirent *dir; if(dp!=NULL) closedir(dp); dp=opendir(dirname); if(dp==NULL) return(0); dir=readdir(dp); while(dir) {if(dir->d_ino==0) continue; if(strcmp(dir->d_name, fileName)==0) {closedir(dp); return (1); } dir=readdir(dp); } closedir(dp); dp=NULL; return 0; } //======================================================== //get dirname and filename from fullname void GetDirFile(char* fullname, char* dirname, char* filename) { char *pdest; char str[100]; strcpy(str,fullname); pdest=strrchr(str,'/'); if(pdest == NULL) //no '/' in str { strcpy(filename,str); strcpy(dirname,""); } else { strcpy(filename,pdest+1); *(pdest+1)=0; strcpy(dirname,str); } } //======================================================== //prompt,ask(-c/-i). overwrite? return 1; no, return 0 char IsOverWriteFile(char* file2, char* flag) { //flag: -c, -i char f=1; char str[40]; if(flag[2]=='c' || flag[3]=='i') { printf("%s exists, overwrite? (y/n/x) ",file2); gets(str); if( strlen(str)==1 && (str[0]=='y' || str[0]=='Y') ) f=1; else if( strlen(str)==1 && (str[0]=='n' || str[0]=='N') ) f=0; else if( strlen(str)==1 && (str[0]=='x' || str[0]=='X') ) exit(1); else f=0; } return f; } //======================================================== //prompt,ask(-i). Create? return 1; no, return 0 char IsCreateFile(char* file2, char* flag) { //flag: -i char f=1; char str[40]; if(flag[3]=='i') { printf("Create %s? (y/n/x) ",file2); gets(str); if( strlen(str)==1 && (str[0]=='y' || str[0]=='Y') ) f=1; else if( strlen(str)==1 && (str[0]=='n' || str[0]=='N') ) f=0; else if( strlen(str)==1 && (str[0]=='x' || str[0]=='X') ) exit(1); else f=0; } return f; } //======================================================== //file1,file2 full filename void Disp_Replaced_by(char* file1, char* file2, char* flag) { struct stat statbuf1; time_t t1; stat(file1, &statbuf1); t1=statbuf1.st_mtime; if(flag[0] != 'q') printf("%s Replaced by %s: %s\n",file2,file1,asctime(localtime(&t1))); } //======================================================== //file1,file2 full filename //disp: filename(of file2) Added to dirname(of file2) void Disp_Added_to(char* file1, char* file2, char* flag) { struct stat statbuf1; time_t t1; char dirname[80]; char filename[80]; stat(file1, &statbuf1); t1=statbuf1.st_mtime; GetDirFile(file2, dirname, filename); if(flag[0] != 'q') printf("%s Added to %s: %s\n",filename,dirname,asctime(localtime(&t1))); } //======================================================== //file2_t to file1_t. file1,file2: full filename void ModifyTime(char* file1, char* file2) { struct utimbuf times; struct stat statbuf1; time_t t1m,t1a; stat(file1, &statbuf1); t1m=statbuf1.st_mtime; t1a=statbuf1.st_atime; times.modtime=t1m; times.actime=t1a; utime (file2, ×); }