Changes made to main.c on implementing real time Rsync

Steven Xu
Tue, 09 Nov 2010 19:04:00 -0000

Hi, All,

I am implementing real-time Rsync on Windows 2008 system.  I set up Rsync
server and Rsync client on two machines.  An windows service is watching all
the Windows   file events with FileSystemWatcher. However, the service
cannot tell the exactly what happened to folders such as create, delete, or
modified.  So, I ignored folder event, and only catch file changing events.
After I catch all those files changed, then call Rsync client periodically
to transfer changes to the server.

Now the problems arises. Because Rsync can only create one level folder but
recursively creating missing folders, sometime, my Rsync client failed
because it need to create more than 1 level of folders on destination to
hold the new file.

Example   "rsync  -av  source/l1/l2/l3/abc.txt
dest::Worksheets/l1/l2/l3/"
The above command is generated by my windows file watching system to make
sure source and destination have the same folder structure.  If the
destination only misses l3 folder, it will creates automatically.  However,
it misses l2 also,  Rsync server will return back an error.

Example:

"C:\Program Files (x86)\cwRsync\bin\rsync" -av
"/cygdrive/e/fileserver/Worksheets/scotia/stalk/download/work/ctrl.2972"
"lba023::Rsync/scotia/stalk/download/work/"
sending incremental file list
rsync: mkdir "scotia/stalk/download/work" (in Rsync) failed: No such
file or
dir
ectory (2)
rsync error: error in file IO (code 11) at main.c(577) [Receiver=3.0.7]
rsync: connection unexpectedly closed (5 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(610)
[sender=3.0.7]


So, I changed main.c to create folder recursively.  The following are the
changes.

            if (mkdir_defmode(dest_path) != 0)
            {
                /*create folder recursively*/
                char parentFolder[200];
                char *pFound = dest_path + 1;//ignore the first /
                STRUCT_STAT st1;
                while( (pFound = strchr(pFound, '/')) != NULL)
                {
                    memcpy(parentFolder, dest_path, pFound - dest_path);
                    parentFolder[pFound - dest_path] = '\0';
                    if ( do_stat(parentFolder, &st1) == 0) {
		            /* If the destination is a dir, enter it and use
mode 1. */
		              if (S_ISDIR(st1.st_mode)) {
					    pFound = pFound + 1;
                        continue;
                      }
                    }
		       if( mkdir_defmode( parentFolder ) != 0 )
                   {
			   rsyserr(FERROR, errno, "mkdir recursive parent
folder %s  for child folder %s failed",
			       full_fname(parentFolder),
full_fname(dest_path));
			          exit_cleanup(RERR_FILEIO);
                    }
				    pFound = pFound + 1;
                 }
                 if( mkdir_defmode( dest_path ) != 0 )
                 {
			      rsyserr(FERROR, errno, "mkdir %s failed",
				     full_fname(dest_path));
			      exit_cleanup(RERR_FILEIO);
                 }

        }



The original code is:

   		if (mkdir_defmode(dest_path) != 0) {
			rsyserr(FERROR, errno, "mkdir %s failed",
				full_fname(dest_path));
			exit_cleanup(RERR_FILEIO);
		}



The problems related to this change is that the folder time stamp of the
folder could not be same as source.


If you have comments, please let me know.


Thanks,

Steven Xu