[PATCH] rsync on cygwin - textmode config files

Ville Herva vherva at ENIGMA.viasys.com
Wed Feb 20 17:27:07 EST 2002


I've been running rsync-2.4.2 with an old patch of mine for some time for
backup purposes. Due to the recent remote bug, I thought it was time to
upgrade, even if the host was behind a firewall.

So I dug up the old patch (2.5.2 version attached), that I think I sent ages
ago to this list as well. It does the following:

   (1) Firstly, the only sensible way to run something as "daemon" under NT
       is to run it as service. One can use SrvAny.exe from the NT resource
       kit for this. However, as it is, rsync immediately forks another 
       process, and net stop has not desired effect, since srvany can't kill
       the rsync daemon. I added --dont-fork option so rsync can be forced 
       not to fork when run as daemon. This way starting and stopping
       services works right.

Ok. This is nowadays handled by --no-detach (I added --dont-fork for
backward compability).

   (2) Secondly, if I connect to rsync daemon from another machine and hit
       ctrl-c at the client end during transfer, the rsync daemon exists (not
       just the connection handler process, but every rsync). I guess this is
       because rsync gets sigpipe signal, which is handled by sig_int, which
       in turn sends sigusr to the parent. I have no idea why this should be.
       I changed sigpipe handler to SIG_IGN, and I now get the behaviour I
       want: if there is a network error (such as premature socket closing)
       the rysnc daemon won't die, and I can reconnect to it. I didn't do
       this cleanly: the connection handler process should in fact exit
       (perhaps after some clean up), but not the parent. This is not a
       problem, however, since the parent will reap the connection handler
       after a minute.

This I'm not sure about. Does more recent cygwin handle this better? I'll
try it without the patch and try to reproduce the bug I was seeing back
then.

   (3) Third, under CYGWIN, it makes little sense to force attribute check on
       the password file. It can be made to work if env var CYGWIN contains
       "ntea" (nt extended attribute mode -- CYGWIN emulates unix permissions
       through a hack), but frankly, it is a MAJOR pain in the ass to get 
       working especially when trying to run rsync as a NT service. Besides,
       CYGWIN permissions won't give you any added security -- the security
       should be handled with NTFS ACL's. So I added a #ifndef __CYGWIN__'s     

Perhaps this would make sense for mainline rsync as well?

   (4) Lastly, the original reason I began compiling my own version was that
       I had a binary version that did not force binary open (I got corrupted
       .doc files etc in the transmission.) I found out that the mainline
       rsync source (as of 2.4.2) already has that O_BINARY bit in do_open,
       so no problem here. It works without, if you mount everything with -b
       (binary) in CYGWIN or force that with "set CYGWIN=BINMODE", but 
       O_BINARY is the (most) correct way to do it -- it works regardless how
       the user has mounted his filesystems. However, if the mounts are
       binary, the configuration files are not read right: if, for example,
       the user makes a password file with notepad, he'll get an additional
       CR into the password (due to missing CR/LF->LF conversion). So I added
       open(O_TEXT) forcing to every config file open (#ifdef CYGWIN'ed, of
       course). Now the users shouldn't have to worry about mount types.

And this as well?

I contacted rsync cygwin mnaintainer (Lapo Luchini <lapo at lapo.it>), and he
suggested to forward (3) and (4) to rsync mailing list, so here they are.
The patch attached is against 2.5.2 and includes (3) and (4).


regards,

-- 
Ville Herva            vherva at viasys.com             +358-40-5756996
Viasys Oy              Hannuntie 6  FIN-02360 Espoo  +358-9-2313-2160
PGP key available: http://www.iki.fi/v/pgp.html  fax +358-9-2313-2250
-------------- next part --------------
diff -Naur --show-c-function --exclude=*.o --exclude=*.1852$ --exclude=*.exe --exclude=Makefile --exclude=con* --exclude=*~ rsync-2.5.2/authenticate.c rsync-2.5.2-patched/authenticate.c
--- rsync-2.5.2/authenticate.c	Thu Jan 24 04:33:45 2002
+++ rsync-2.5.2-patched/authenticate.c	Tue Feb 19 14:04:36 2002
@@ -82,13 +82,24 @@ static int get_secret(int module, char *
 
 	if (!fname || !*fname) return 0;
 
-	fd = open(fname,O_RDONLY);
+	fd = open(fname,O_RDONLY
+#ifdef __CYGWIN__
+			| O_TEXT
+#endif
+	);
 	if (fd == -1) return 0;
 
 	if (do_stat(fname, &st) == -1) {
 		rsyserr(FERROR, errno, "stat(%s)", fname);
 		ok = 0;
 	} else if (lp_strict_modes(module)) {
+/* Under CYGWIN, we don't want to force attribute check. It can be made to
+   work if env var CYGWIN contains "ntea" (nt extended attribute mode), but
+   frankly, it is a MAJOR pain in the ass to get working especially when 
+   trying to run rsync as a NT service. Besides, CYGWIN permissions won't
+   give us any added security -- the security should be handled with NTFS 
+   ACL's. */
+#ifndef __CYGWIN__
 		if ((st.st_mode & 06) != 0) {
 			rprintf(FERROR,"secrets file must not be other-accessible (see strict modes option)\n");
 			ok = 0;
@@ -96,6 +107,7 @@ static int get_secret(int module, char *
 			rprintf(FERROR,"secrets file must be owned by root when running as root (see strict modes)\n");
 			ok = 0;
 		}
+#endif
 	}
 	if (!ok) {
 		rprintf(FERROR,"continuing without secrets file\n");
@@ -144,7 +156,11 @@ static char *getpassf(char *filename)
 
 	if (!filename) return NULL;
 
-	if ( (fd=open(filename,O_RDONLY)) == -1) {
+	if ( (fd=open(filename,O_RDONLY
+#ifdef __CYGWIN__
+			      | O_TEXT
+#endif
+		)) == -1) {
 		rsyserr(FERROR, errno, "could not open password file \"%s\"",filename);
 		if (envpw) rprintf(FERROR,"falling back to RSYNC_PASSWORD environment variable.\n");	
 		return NULL;
@@ -153,6 +169,14 @@ static char *getpassf(char *filename)
 	if (do_stat(filename, &st) == -1) {
 		rsyserr(FERROR, errno, "stat(%s)", filename);
 		ok = 0;
+	} 
+/* Under CYGWIN, we don't want to force attribute check. It can be made to
+   work if env var CYGWIN contains "ntea" (nt extended attribute mode), but
+   frankly, it is a MAJOR pain in the ass to get working especially when 
+   trying to run rsync as a NT service. Besides, CYGWIN permissions won't
+   give us any added security -- the security should be handled with NTFS 
+   ACL's. */
+#ifndef __CYGWIN__
 	} else if ((st.st_mode & 06) != 0) {
 		rprintf(FERROR,"password file must not be other-accessible\n");
 		ok = 0;
@@ -160,6 +184,7 @@ static char *getpassf(char *filename)
 		rprintf(FERROR,"password file must be owned by root when running as root\n");
 		ok = 0;
 	}
+#endif
 	if (!ok) {
 		rprintf(FERROR,"continuing without password file\n");
 		if (envpw) rprintf(FERROR,"using RSYNC_PASSWORD environment variable.\n");
diff -Naur --show-c-function --exclude=*.o --exclude=*.1852$ --exclude=*.exe --exclude=Makefile --exclude=con* --exclude=*~ rsync-2.5.2/lib/mdfour.c rsync-2.5.2-patched/lib/mdfour.c
--- rsync-2.5.2/lib/mdfour.c	Thu Jun 28 08:07:15 2001
+++ rsync-2.5.2-patched/lib/mdfour.c	Tue Feb 19 14:06:00 2002
@@ -185,7 +185,11 @@ static void file_checksum1(char *fname)
 	struct mdfour md;
 	unsigned char buf[64*1024], sum[16];
 	
-	fd = open(fname,O_RDONLY);
+	fd = open(fname,O_RDONLY
+#ifdef __CYGWIN__
+			      | O_BINARY
+#endif
+		  );
 	if (fd == -1) {
 		perror("fname");
 		exit(1);
@@ -217,7 +221,12 @@ static void file_checksum2(char *fname)
 	MDstruct md;
 	unsigned char buf[64], sum[16];
 
-	fd = open(fname,O_RDONLY);
+	fd = open(fname,O_RDONLY
+	fd = open(fname,O_RDONLY
+#ifdef __CYGWIN__
+			      | O_BINARY
+#endif
+		  );
 	if (fd == -1) {
 		perror("fname");
 		exit(1);
diff -Naur --show-c-function --exclude=*.o --exclude=*.1852$ --exclude=*.exe --exclude=Makefile --exclude=con* --exclude=*~ rsync-2.5.2/params.c rsync-2.5.2-patched/params.c
--- rsync-2.5.2/params.c	Tue Feb  9 20:35:29 1999
+++ rsync-2.5.2-patched/params.c	Tue Feb 19 14:09:48 2002
@@ -488,8 +488,17 @@ static FILE *OpenConfFile( char *FileNam
     return( NULL );
     }
 
-  OpenedFile = fopen( FileName, "r" );
-  if( NULL == OpenedFile )
+#ifdef __CYGWIN__
+   {
+	/* CYGWIN has no O_TEXT equivalent for
+           fopen... */
+	int fd = open( FileName, O_RDONLY | O_TEXT);
+	OpenedFile = fdopen( fd, "r" );
+   }
+#else 
+   OpenedFile = fopen( FileName, "r" );
+#endif
+   if( NULL == OpenedFile )
     {
     rprintf(FERROR,"%s Unable to open configuration file \"%s\":\n\t%s\n",
 	    func, FileName, strerror(errno));


More information about the rsync mailing list