[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