Compare commits

..

67 Commits

Author SHA1 Message Date
rsync-bugs
ec3f7d1b61 preparing for release of 2.4.2 2000-03-30 14:24:37 +00:00
Andrew Tridgell
f0359dd00d went back to non-blokcing IO
it looks like ssh is willing to accept a non-blocking fd when used as
a transport, this seems to avoid the Solaris socketpair bug
2000-03-30 14:15:00 +00:00
Andrew Tridgell
ef55c686bc add a --ignore-errors option 2000-03-21 04:06:04 +00:00
David Dykstra
5f7ce2041c Describe symbolic link handling when writing to a "use chroot = no" module. 2000-02-25 17:02:45 +00:00
David Dykstra
328fcf113a Somebody was confused into thinking that "Here are some examples" in the
section on exclude/include was supposed to be about "+/-" so I changed
the statement to "Here are some exclude/include examples".
2000-02-22 19:47:44 +00:00
David Dykstra
24c857f1de Change socketpair test to verify that it works rather than just exists,
because I have an obscure system (Amdahl's UTS 2.1.2) in which socketpair()
exists but is broken.
2000-02-22 15:55:40 +00:00
David Dykstra
a784e10d00 Move the checking for -lsocket -lnsl ahead of the checking for most of
the functions, especially "socketpair" so that socket-related functions will
be properly discovered on SVR4-based systems such as Solaris.  Problem
discovered by Kenji Miyake <kenji@miyake.org>
2000-02-15 22:44:18 +00:00
rsync-bugs
7eb6bf0397 preparing for release of 2.4.1 2000-01-30 01:02:59 +00:00
Andrew Tridgell
49d6fdc036 patch from Jim Delahanty <mail_us@swbell.net> to ensure files are
deleted after being backed up in a rename operation
2000-01-30 00:56:43 +00:00
Andrew Tridgell
8b35435f7c another hang-at-end fix. It looks like we are more sensiitive to
these with socketpairs. The receiver now sleeps until it gets a signal
to tell it to exit

also fixed test.sh to use the current version remotely
2000-01-30 00:50:19 +00:00
Andrew Tridgell
8ada751890 damn.
with the new error handling code it is possible for rsync to get stuck
on the final transaction, leaving it hung.

looks like 2.4.1 will be pretty soon
2000-01-29 23:49:36 +00:00
rsync-bugs
1a52e84874 preparing for release of 2.4.0 2000-01-29 11:35:39 +00:00
Andrew Tridgell
53c5cbed23 change version to 2.4.0pre2 2000-01-29 05:25:53 +00:00
Andrew Tridgell
4a81463880 use full buffer length, not strlen 2000-01-29 05:16:13 +00:00
Andrew Tridgell
09b7f5dbb1 move the read only daemon test to after the protocol setup 2000-01-29 05:02:23 +00:00
Andrew Tridgell
6d7b6081ac damn!
the last pre-release had a bug that didn't setup the multiplexing
correctly. This means that pre-release will get "unexpected tag -7"
whenm talking to the fixed code.
2000-01-29 04:50:01 +00:00
Andrew Tridgell
31b7d79afe I've decided that this release will be 2.4.0, updated version to 2.4.0pre1 2000-01-29 03:11:07 +00:00
Andrew Tridgell
b2999e457f don't need PIPE_BUF any more 2000-01-29 02:56:36 +00:00
Andrew Tridgell
0f3203c312 fixed some logcode warnings 2000-01-29 02:49:03 +00:00
Andrew Tridgell
a2edb26cd6 fixed a bug in test suite that I introduced yesterday 2000-01-29 02:39:52 +00:00
Andrew Tridgell
9bec528606 runtime detect fnmatch() bug if ** is used.
its all too common to compile with a working libc and run on a broken
one.
2000-01-29 02:35:01 +00:00
Andrew Tridgell
2f0e3b30a9 changed version to 2.3.3pre2 2000-01-28 15:35:08 +00:00
Andrew Tridgell
ff41a59f58 - switched on multiplexing for all connections, not just daemon
connections (this fixes the stderr/stdout problem). Upped
  protocol version for backward compat
- use multiplexing on error fd
- upped minimal protocol version
- got rid of some ugly code in the write buffering
2000-01-28 15:29:59 +00:00
Andrew Tridgell
08f15335b5 switch to using socketpair instead of pipe if possible. This fixes the
ssh clag problems as long as you also fix the same problem in sshd

removed all the old read buffering code from io.c as this was only
there to try to reduce the chance of clagging up sshd.
2000-01-28 12:37:58 +00:00
Andrew Tridgell
bd36966bed report exit code when failing a test 2000-01-27 04:54:02 +00:00
Andrew Tridgell
f76933b149 fixed the error code problem with test.sh
(was a minor bug in send_file_list)
2000-01-27 04:53:39 +00:00
Andrew Tridgell
378a074c82 patch from James Delahanty <jimd@gie.com> to make --backup-dir work
cross-filesystem
2000-01-27 02:45:56 +00:00
Andrew Tridgell
c36cd31713 the convoluted nest of #ifdefs that is fnmatch.c caught us again. On
my system the LIBC tests meant it never compiled and we used the
broken system one.

hacked it so it does compile
2000-01-25 14:17:21 +00:00
Andrew Tridgell
5e12ce1186 fix segv bug in --progress handling 2000-01-25 13:16:42 +00:00
Andrew Tridgell
166aa72332 patch from David Murn to make sure the final 100% is always printed
when using --progress
2000-01-25 06:39:33 +00:00
Andrew Tridgell
f9f6184f38 updated version.h 2000-01-25 01:33:05 +00:00
Andrew Tridgell
f625af9400 updated config.guess from latest autoconf CVS tree 2000-01-24 13:12:20 +00:00
Andrew Tridgell
fc7952e7f3 updated --password-file docs 2000-01-24 12:28:45 +00:00
Andrew Tridgell
cbce490e13 reinstated the MAX_READ_BUFFER code. Its a nasty tradeoff - using lots
of memory vs. ssh bugs. uggh.
2000-01-24 12:23:39 +00:00
Andrew Tridgell
74a7f81d57 updated a debug message 2000-01-24 12:22:58 +00:00
Andrew Tridgell
5b5591d8a8 make the replacement inet_aton() function independent of
inet_addr(). Some systems were detecting a missing inet_aton(), but
actually had it and inet_addr() called it, causing infinite recursion
2000-01-24 12:02:44 +00:00
Andrew Tridgell
c55f70218c fixed a rare SEGV that can happen when a file disappears (due to
another program) during an update
2000-01-24 11:41:08 +00:00
Andrew Tridgell
6957ae33a9 moved file deletion to before the fork() to prevent a race condition
pointed out by byrnes@curl.com
2000-01-24 11:20:25 +00:00
Andrew Tridgell
8a5d6bba09 don't use stderr after we become a daemon 2000-01-24 09:19:44 +00:00
Andrew Tridgell
1d2c275fff I can't believe it - solaris allows unlink of a non-empty directory as
root, leaving a corrupt filesystem. Are those guys on drugs?

try to avoid the problem as best we can.
2000-01-24 09:13:39 +00:00
Andrew Tridgell
d0fd26aa16 added some more debug info to the "buffer overflow in
receive_file_entry" message
2000-01-24 08:16:57 +00:00
Andrew Tridgell
e20c5e9521 -a now implies -o and -D whether you are root or not 2000-01-24 05:52:44 +00:00
Andrew Tridgell
66203a982b added --backup-dir option from Bob Edwards
this is very useful for incremental backups
2000-01-24 04:58:53 +00:00
Andrew Tridgell
b315601ce0 removed Daves include-only optimisation. One of the bug reports turned
out to be caused by it and it seems rather a lot of extra effort for
what must really be a minor optimisation in most cases
2000-01-23 13:16:30 +00:00
Andrew Tridgell
5f808dfbd7 fix a problem with files > 2GB
(thanks to T.J.Adye@rl.ac.uk)
2000-01-23 12:30:34 +00:00
Andrew Tridgell
0b73ca12fa added --max-delete option 2000-01-23 11:43:04 +00:00
Andrew Tridgell
03e2d0e329 fixed mdfour code on Cray (64 bit problems)
Thanks to roebel@kgw.tu-berlin.de
2000-01-23 11:26:10 +00:00
Andrew Tridgell
182517e692 removed u_sleep() as it is no longer used anywhere 2000-01-23 07:38:20 +00:00
Andrew Tridgell
554e0a8dd0 added some really ugly code to allow errors to propogate to
clients when writing to a rsync server

it works like this:

- we have an extra pipe from the receiver to the generator
- the server always runs with multiplexing on
- errors from the generator go down the multiplexed connection
- errors from the receiver go over the pipe, and from there to
  the multiplexed conn

it required some incredibly ugly code. damn.
2000-01-23 07:36:56 +00:00
Andrew Tridgell
b0f3f5784c open on paths starting with // fails on win32 2000-01-23 03:00:27 +00:00
Andrew Tridgell
3060d4aa1d handle systems that don't take a 2nd argument to gettimeofday() 2000-01-23 02:16:51 +00:00
Andrew Tridgell
1347d5126a added --existing option, similar to one suggested by Gildas Quiniou <gildas@stip.fr> 2000-01-23 01:53:18 +00:00
Andrew Tridgell
5d1e1dcf4b don't try to write errors to a dead socket 2000-01-23 01:11:43 +00:00
David Dykstra
74f5442401 Make all the rsync objects dependent on all the header files except the
zlib header fiels in Makefile.in.  I've been burned several times because
objects did not get rebuilt when header files changed.
2000-01-10 22:39:45 +00:00
David Dykstra
c08bb0fb73 Needed to comment out the inclusion of headers in fnmatch.c because it
couldn't find some of them (especially <fnmatch.h>, because it wasn't
looking in the current directory).  The header files are included better
from ../rsync.h.
2000-01-10 20:36:20 +00:00
Andrew Tridgell
e30f065766 make --address work for a client connecting to a server 2000-01-10 04:49:51 +00:00
David Dykstra
9dce9b45b3 Upgrade lib/fnmatch.[ch] to the latest from glibc-2.1.2 because the
FNM_PATHNAME flag (to stop at slashes in path names) was not working.

Ironically, the bug in glibc's fnmatch was reported on the rsync mailing
list in late October, and rsync's configure.in was changed to detect the
bad glibc and use the internal fnmatch, but the internal fnmatch was based
on the same buggy glibc!
2000-01-07 17:58:44 +00:00
David Dykstra
60be6acf46 If a destination file cannot be opened, pretend it doesn't exist rather
than skipping it and thus not updating it.  For example, the ownership or
mode on a file may prevent opening it, but the directory may still be
writable so the file could be completely replaced.
2000-01-06 16:15:36 +00:00
Andrew Tridgell
a5827a28d2 when we do a lchown() on a file we have to flush the cached perms on
the file if the file has the setuid or setgid bits set as the chown
has a side effect of removing the setuid and setgid bits.
we re-do the stat in this case
2000-01-06 00:26:00 +00:00
David Dykstra
dcc875e41e Define the WEXITSTATUS macro for systems that don't have it. 1999-12-29 21:11:57 +00:00
David Dykstra
128cf58433 When writing to a daemon with read only = false and uid = root and -g,
was not preserving group permisions.  Bug was introduced March 1 in
version 1.100 of rsync.c with an error in re-ordering of the boolean
expressions.  In order to completely preserve the earlier semantics,
change_gid should depend on "(am_root || !am_daemon)", but I don't see why
group ownership should behave differently in a non-root daemon.
1999-12-29 20:50:48 +00:00
David Dykstra
7e0ca8e2f0 When not using -p and file being copied to already existed, was mistakenly
using all the mode bits of the existing file rather than just the permissions,
including the file type.
1999-12-29 20:45:23 +00:00
Andrew Tridgell
d79d1c69f7 fixed a bug with waitpid() - I'd forgotten about WEXITSTATUS ! 1999-12-09 06:46:11 +00:00
Andrew Tridgell
a7d068abff fixed man page typo 1999-12-03 04:24:25 +00:00
Andrew Tridgell
7f931a0002 fixed a segv bug when handling symlinks.
thanks to taver@otenet.gr
1999-12-02 05:50:09 +00:00
Andrew Tridgell
07b7c86c06 don't write more than PIPE_BUF bytes in any one write() in io.c
this makes sure that the write never blocks.
1999-11-23 08:43:16 +00:00
Andrew Tridgell
1f5c6343e6 removed old non-blocking fd code (a hangover from a earlier version of
io.c). Thanks to Theo for pointing out this brokenness.
1999-11-15 01:32:20 +00:00
32 changed files with 1508 additions and 607 deletions

View File

@@ -20,6 +20,8 @@ SHELL=/bin/sh
.SUFFIXES:
.SUFFIXES: .c .o
HEADS=byteorder.h config.h errcode.h proto.h rsync.h version.h \
lib/fnmatch.h lib/getopt.h lib/mdfour.h
LIBOBJ=lib/getopt.o lib/fnmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o
ZLIBOBJ=zlib/deflate.o zlib/infblock.o zlib/infcodes.o zlib/inffast.o \
zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
@@ -53,6 +55,8 @@ install-strip:
rsync: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o rsync $(OBJS) $(LIBS)
$(OBJS): $(HEADS)
rsync.1: rsync.yo
yodl2man -o rsync.1 rsync.yo
@@ -60,7 +64,7 @@ rsyncd.conf.5: rsyncd.conf.yo
yodl2man -o rsyncd.conf.5 rsyncd.conf.yo
proto:
cat *.c | awk -f mkproto.awk > proto.h
cat *.c lib/compat.c | awk -f mkproto.awk > proto.h
clean:
rm -f *~ $(OBJS) rsync

View File

@@ -10,3 +10,5 @@
#undef HAVE_SHORT_INO_T
#undef HAVE_GETOPT_LONG
#undef REPLACE_INET_NTOA
#undef HAVE_GETTIMEOFDAY_TZ
#undef HAVE_SOCKETPAIR

View File

@@ -56,7 +56,7 @@ static void gen_challenge(char *addr, char *challenge)
memset(input, 0, sizeof(input));
strlcpy((char *)input, addr, 17);
gettimeofday(&tv, NULL);
sys_gettimeofday(&tv);
SIVAL(input, 16, tv.tv_sec);
SIVAL(input, 20, tv.tv_usec);
SIVAL(input, 24, getpid());

244
backup.c
View File

@@ -22,9 +22,16 @@
extern int verbose;
extern char *backup_suffix;
extern char *backup_dir;
int make_backup(char *fname)
extern int am_root;
extern int preserve_devices;
extern int preserve_links;
extern int preserve_hard_links;
/* simple backup creates a backup with a suffix in the same directory */
static int make_simple_backup(char *fname)
{
char fnamebak[MAXPATHLEN];
if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
@@ -44,3 +51,238 @@ int make_backup(char *fname)
}
return 1;
}
/* recursively make a directory path */
static int make_dir(char *name, int mask)
{
char newdir [MAXPATHLEN];
char *p, *d;
/* copy pathname over, look for last '/' */
for (p = d = newdir; *name; *d++ = *name++)
if (*name == '/')
p = d;
if (p == newdir)
return 0;
*p = 0;
/* make the new directory, if that fails then make its parent */
while (do_mkdir (newdir, mask) != 0)
if ((errno != ENOENT) || !make_dir (newdir, mask))
return 0;
return 1;
} /* make_dir */
/****************************************************************************
Create a directory given an absolute path, perms based upon another directory
path
****************************************************************************/
static int make_bak_dir(char *fname,char *bak_path)
{
STRUCT_STAT st;
STRUCT_STAT *st2;
char fullpath[MAXPATHLEN];
extern int orig_umask;
char *p;
char *q;
while(strncmp(bak_path,"./",2)==0) bak_path += 2;
if(bak_path[strlen(bak_path)-1]!='/') {
slprintf(fullpath,sizeof(fullpath),"%s/",bak_path);
} else {
slprintf(fullpath,sizeof(fullpath),"%s",bak_path);
}
p=fullpath;
q=&fullpath[strlen(fullpath)]; /* End of bak_path string */
strcat(fullpath,fname);
/* Make the directories */
while ((p=strchr(p,'/'))) {
*p = 0;
if(do_lstat(fullpath,&st)!=0) {
do_mkdir(fullpath,0777 & ~orig_umask);
if(p>q) {
if(do_lstat(q,&st)!=0) {
rprintf(FERROR,"make_bak_dir stat %s : %s\n",fullpath,strerror(errno));
} else {
st2=&st;
set_modtime(fullpath,st2->st_mtime);
if(do_lchown(fullpath,st2->st_uid,st2->st_gid)!=0) {
rprintf(FERROR,"make_bak_dir chown %s : %s\n",fullpath,strerror(errno));
};
if(do_chmod(fullpath,st2->st_mode)!=0) {
rprintf(FERROR,"make_bak_dir failed to set permissions on %s : %s\n",fullpath,strerror(errno));
};
};
}
};
*p = '/';
p++;
}
return 0;
}
/* robustly move a file, creating new directory structures if necessary */
static int robust_move(char *src, char *dst)
{
int keep_trying = 4;
int keep_path_extfs = 0;
int failed;
while (keep_trying) {
if (keep_path_extfs) {
failed = copy_file(src, dst, 0755);
if (!failed) {
do_unlink(src);
}
} else {
failed = robust_rename (src, dst);
}
if (failed) {
if (verbose > 2)
rprintf (FERROR, "robust_move failed: %s(%d)\n",
strerror (errno), errno);
switch (errno) {
/* external filesystem */
case EXDEV:
keep_path_extfs = 1;
keep_trying--;
break;
/* no directory to write to */
case ENOENT:
make_dir (dst, 0755);
keep_trying--;
break;
default:
keep_trying = 0;
} /* switch */
} else
keep_trying = 0;
} /* while */
return (!failed);
} /* robust_move */
/* if we have a backup_dir, then we get here from make_backup().
We will move the file to be deleted into a parallel directory tree */
static int keep_backup(char *fname)
{
static int initialised;
char keep_name [MAXPATHLEN];
STRUCT_STAT st;
struct file_struct *file;
int kept=0;
int ret_code;
if (!initialised) {
if (backup_dir[strlen(backup_dir) - 1] == '/')
backup_dir[strlen(backup_dir) - 1] = 0;
if (verbose > 0)
rprintf (FINFO, "backup_dir is %s\n", backup_dir);
initialised = 1;
}
/* return if no file to keep */
#if SUPPORT_LINKS
if (do_lstat (fname, &st)) return 1;
#else
if (do_stat (fname, &st)) return 1;
#endif
file = make_file (0, fname);
/* make a complete pathname for backup file */
if (strlen(backup_dir) + strlen(fname) > (MAXPATHLEN - 1)) {
rprintf (FERROR, "keep_backup filename too long\n");
return 0;
}
slprintf(keep_name, sizeof (keep_name), "%s/%s", backup_dir, fname);
#ifdef HAVE_MKNOD
/* Check to see if this is a device file, or link */
if(IS_DEVICE(file->mode)) {
if(am_root && preserve_devices) {
make_bak_dir(fname,backup_dir);
if(do_mknod(keep_name,file->mode,file->rdev)!=0) {
rprintf(FERROR,"mknod %s : %s\n",keep_name,strerror(errno));
} else {
if(verbose>2)
rprintf(FINFO,"make_backup : DEVICE %s successful.\n",fname);
};
};
kept=1;
do_unlink(fname);
};
#endif
if(!kept && S_ISDIR(file->mode)) {
/* make an empty directory */
make_bak_dir(fname,backup_dir);
do_mkdir(keep_name,file->mode);
ret_code=do_rmdir(fname);
if(verbose>2)
rprintf(FINFO,"make_backup : RMDIR %s returns %i\n",fname,ret_code);
kept=1;
};
#if SUPPORT_LINKS
if(!kept && preserve_links && S_ISLNK(file->mode)) {
extern int safe_symlinks;
if (safe_symlinks && unsafe_symlink(file->link, keep_name)) {
if (verbose) {
rprintf(FINFO,"ignoring unsafe symlink %s -> %s\n",
keep_name,file->link);
}
kept=1;
}
make_bak_dir(fname,backup_dir);
if(do_symlink(file->link,keep_name) != 0) {
rprintf(FERROR,"link %s -> %s : %s\n",keep_name,file->link,strerror(errno));
};
do_unlink(fname);
kept=1;
};
#endif
if(!kept && preserve_hard_links && check_hard_link(file)) {
if(verbose > 1) rprintf(FINFO,"%s is a hard link\n",f_name(file));
};
if(!kept && !S_ISREG(file->mode)) {
rprintf(FINFO,"make_bak: skipping non-regular file %s\n",fname);
}
/* move to keep tree if a file */
if(!kept) {
if (!robust_move (fname, keep_name))
rprintf(FERROR, "keep_backup failed %s -> %s : %s\n",
fname, keep_name, strerror(errno));
};
set_perms (keep_name, file, NULL, 0);
free_file (file);
free (file);
if (verbose > 1)
rprintf (FINFO, "keep_backup %s -> %s\n", fname, keep_name);
return 1;
} /* keep_backup */
/* main backup switch routine */
int make_backup(char *fname)
{
if (backup_dir)
return (keep_backup(fname));
else
return (make_simple_backup(fname));
}

View File

@@ -39,6 +39,7 @@ void _exit_cleanup(int code, const char *file, int line)
if (code == 0 && io_error) code = RERR_FILEIO;
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
if (cleanup_got_literal && cleanup_fname && keep_partial) {
char *fname = cleanup_fname;

View File

@@ -36,6 +36,7 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
char *p, *user=NULL;
extern int remote_version;
extern int am_sender;
extern struct in_addr socket_address;
if (*path == '/') {
rprintf(FERROR,"ERROR: The remote path must start with a module name\n");
@@ -52,7 +53,7 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
if (!user) user = getenv("USER");
if (!user) user = getenv("LOGNAME");
fd = open_socket_out(host, rsync_port);
fd = open_socket_out(host, rsync_port, &socket_address);
if (fd == -1) {
exit_cleanup(RERR_SOCKETIO);
}
@@ -100,8 +101,10 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
}
io_printf(fd,"\n");
if (remote_version > 17 && !am_sender)
io_start_multiplex_in(fd);
if (remote_version < 23) {
if (remote_version == 22 || (remote_version > 17 && !am_sender))
io_start_multiplex_in(fd);
}
return client_run(fd, fd, -1, argc, argv);
}
@@ -162,9 +165,6 @@ static int rsync_module(int fd, int i)
module_id = i;
if (lp_read_only(i))
read_only = 1;
am_root = (getuid() == 0);
if (am_root) {
@@ -315,8 +315,10 @@ static int rsync_module(int fd, int i)
argp = argv + optind;
optind = 0;
if (remote_version > 17 && am_sender)
io_start_multiplex_out(fd);
if (remote_version < 23) {
if (remote_version == 22 || (remote_version > 17 && am_sender))
io_start_multiplex_out(fd);
}
if (!ret) {
option_error();
@@ -361,7 +363,7 @@ static int start_daemon(int fd)
set_socket_options(fd,"SO_KEEPALIVE");
set_socket_options(fd,lp_socket_options());
set_nonblocking(fd);
io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION);
@@ -433,15 +435,12 @@ int daemon_main(void)
open("/dev/null", O_RDWR);
}
set_nonblocking(STDIN_FILENO);
return start_daemon(STDIN_FILENO);
}
become_daemon();
if (!lp_load(config_file, 1)) {
fprintf(stderr,"failed to load config file %s\n", config_file);
exit_cleanup(RERR_SYNTAX);
}
@@ -457,7 +456,7 @@ int daemon_main(void)
if ((fd = do_open(lp_pid_file(), O_WRONLY|O_CREAT|O_TRUNC,
0666 & ~orig_umask)) == -1) {
cleanup_set_pid(0);
fprintf(stderr,"failed to create pid file %s\n", pid_file);
rprintf(FLOG,"failed to create pid file %s\n", pid_file);
exit_cleanup(RERR_FILEIO);
}
slprintf(pidbuf, sizeof(pidbuf), "%d\n", pid);

286
config.guess vendored
View File

@@ -1,6 +1,7 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999
# Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -23,6 +24,7 @@
# Written by Per Bothner <bothner@cygnus.com>.
# The master version of this file is at the FSF in /home/gd/gnu/lib.
# Please send patches to <autoconf-patches@gnu.org>.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
@@ -35,6 +37,20 @@
# (but try to keep the structure clean).
#
# Use $HOST_CC if defined. $CC may point to a cross-compiler
if test x"$CC_FOR_BUILD" = x; then
if test x"$HOST_CC" != x; then
CC_FOR_BUILD="$HOST_CC"
else
if test x"$CC" != x; then
CC_FOR_BUILD="$CC"
else
CC_FOR_BUILD=cc
fi
fi
fi
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 8/24/94.)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
@@ -77,7 +93,7 @@ main:
ret \$31,(\$26),1
.end main
EOF
${CC-cc} $dummy.s -o $dummy 2>/dev/null
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
if test "$?" = 0 ; then
./$dummy
case "$?" in
@@ -99,7 +115,13 @@ EOF
esac
fi
rm -f $dummy.s $dummy
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit 0 ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
# of the specific Alpha model?
echo alpha-pc-interix
exit 0 ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
@@ -134,6 +156,9 @@ EOF
wgrisc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
*:OS/390:*:*)
echo i370-ibm-openedition
exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;;
@@ -143,7 +168,7 @@ EOF
SR2?01:HI-UX/MPP:*:*)
echo hppa1.1-hitachi-hiuxmpp
exit 0;;
Pyramid*:OSx*:*:*|MIS*:OSx*:*:*|MIS*:SMP_DC-OSx*:*:*)
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3
@@ -151,7 +176,7 @@ EOF
echo pyramid-pyramid-bsd
fi
exit 0 ;;
NILE:*:*:dcosx)
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
sun4H:SunOS:5.*:*)
@@ -202,6 +227,32 @@ EOF
atari*:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
# > m68000). The system name ranges from "MiNT" over "FreeMiNT"
# to the lowercase version "mint" (or "freemint"). Finally
# the system name "TOS" denotes a system which is actually not
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
exit 0 ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
exit 0 ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit 0 ;;
sun3*:NetBSD:*:*)
echo m68k-sun-netbsd${UNAME_RELEASE}
exit 0 ;;
@@ -235,12 +286,16 @@ EOF
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
2020:CLIX:*:*)
2020:CLIX:*:* | 2430:CLIX:*:*)
echo clipper-intergraph-clix${UNAME_RELEASE}
exit 0 ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
sed 's/^ //' << EOF >$dummy.c
int main (argc, argv) int argc; char **argv; {
#ifdef __cplusplus
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
@@ -255,7 +310,7 @@ EOF
exit (-1);
}
EOF
${CC-cc} $dummy.c -o $dummy \
$CC_FOR_BUILD $dummy.c -o $dummy \
&& ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
@@ -276,15 +331,18 @@ EOF
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
-o ${TARGET_BINARY_INTERFACE}x = x ] ; then
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
[ ${TARGET_BINARY_INTERFACE}x = x ]
then
echo m88k-dg-dgux${UNAME_RELEASE}
else
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
else echo i586-dg-dgux${UNAME_RELEASE}
fi
exit 0 ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
@@ -321,7 +379,7 @@ EOF
exit(0);
}
EOF
${CC-cc} $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
@@ -369,25 +427,25 @@ EOF
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/6?? | 9000/7?? | 9000/80[24] | 9000/8?[13679] | 9000/892 )
9000/[678][0-9][0-9])
sed 's/^ //' << EOF >$dummy.c
#include <stdlib.h>
#include <unistd.h>
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
@@ -395,13 +453,13 @@ EOF
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(${CC-cc} $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
rm -f $dummy.c $dummy
esac
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
@@ -433,7 +491,7 @@ EOF
exit (0);
}
EOF
${CC-cc} $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
echo unknown-hitachi-hiuxwe2
exit 0 ;;
@@ -443,6 +501,9 @@ EOF
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit 0 ;;
*9??*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit 0 ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit 0 ;;
@@ -459,6 +520,9 @@ EOF
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit 0 ;;
hppa*:OpenBSD:*:*)
echo hppa-unknown-openbsd
exit 0 ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit 0 ;;
@@ -492,13 +556,13 @@ EOF
echo t90-cray-unicos${UNAME_RELEASE}
exit 0 ;;
CRAY*T3E:*:*:*)
echo t3e-cray-unicosmk${UNAME_RELEASE}
echo alpha-cray-unicosmk${UNAME_RELEASE}
exit 0 ;;
CRAY-2:*:*:*)
echo cray2-cray-unicos
exit 0 ;;
F300:UNIX_System_V:*:*)
FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
@@ -511,20 +575,26 @@ EOF
hp300:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sparc*:BSD/OS:*:*)
echo sparc-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
i?86:BSD/386:*:* | i?86:BSD/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
sparc*:BSD/OS:*:*)
echo sparc-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*)
if test -x /usr/bin/objformat; then
if test "elf" = "`/usr/bin/objformat`"; then
echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'`
exit 0
fi
fi
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;;
*:NetBSD:*:*)
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'`
exit 0 ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
@@ -535,6 +605,15 @@ EOF
i*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit 0 ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
# UNAME_MACHINE based on the output of uname instead of i386?
echo i386-pc-interix
exit 0 ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
exit 0 ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin
exit 0 ;;
@@ -545,15 +624,11 @@ EOF
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
*:Linux:*:*)
# uname on the ARM produces all sorts of strangeness, and we need to
# filter it out.
case "$UNAME_MACHINE" in
arm* | sa110*) UNAME_MACHINE="arm" ;;
esac
# The BFD linker knows what the default object file format is, so
# first see if it will tell us.
ld_help_string=`ld --help 2>&1`
# first see if it will tell us. cd to the root directory to prevent
# problems with other programs or directories called `ld' in the path.
ld_help_string=`cd /; ld --help 2>&1`
ld_supported_emulations=`echo $ld_help_string \
| sed -ne '/supported emulations:/!d
s/[ ][ ]*/ /g
@@ -561,12 +636,70 @@ EOF
s/ .*//
p'`
case "$ld_supported_emulations" in
i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;;
i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;;
sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;;
*ia64)
echo "${UNAME_MACHINE}-unknown-linux"
exit 0
;;
i?86linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit 0
;;
i?86coff)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
exit 0
;;
sparclinux)
echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
exit 0
;;
armlinux)
echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
exit 0
;;
elf32arm*)
echo "${UNAME_MACHINE}-unknown-linux-gnu"
exit 0
;;
armelf_linux*)
echo "${UNAME_MACHINE}-unknown-linux-gnu"
exit 0
;;
m68klinux)
echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
exit 0
;;
elf32ppc)
# Determine Lib Version
cat >$dummy.c <<EOF
#include <features.h>
#if defined(__GLIBC__)
extern char __libc_version[];
extern char __libc_release[];
#endif
main(argc, argv)
int argc;
char *argv[];
{
#if defined(__GLIBC__)
printf("%s %s\n", __libc_version, __libc_release);
#else
printf("unkown\n");
#endif
return 0;
}
EOF
LIBC=""
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
if test "$?" = 0 ; then
./$dummy | grep 1\.99 > /dev/null
if test "$?" = 0 ; then
LIBC="libc1"
fi
fi
rm -f $dummy.c $dummy
echo powerpc-unknown-linux-gnu${LIBC}
exit 0
;;
esac
if test "${UNAME_MACHINE}" = "alpha" ; then
@@ -588,7 +721,7 @@ EOF
.end main
EOF
LIBC=""
${CC-cc} $dummy.s -o $dummy 2>/dev/null
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
if test "$?" = 0 ; then
./$dummy
case "$?" in
@@ -607,22 +740,23 @@ EOF
16)
UNAME_MACHINE="alphaev6"
;;
esac
esac
objdump --private-headers $dummy | \
grep ld.so.1 > /dev/null
if test "$?" = 0 ; then
LIBC="libc1"
fi
fi
fi
rm -f $dummy.s $dummy
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
elif test "${UNAME_MACHINE}" = "mips" ; then
cat >$dummy.c <<EOF
main(argc, argv)
int argc;
char *argv[];
{
#ifdef __cplusplus
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#ifdef __MIPSEB__
printf ("%s-unknown-linux-gnu\n", argv[1]);
#endif
@@ -632,7 +766,7 @@ main(argc, argv)
return 0;
}
EOF
${CC-cc} $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
else
# Either a pre-BFD a.out linker (linux-gnuoldld)
@@ -654,10 +788,11 @@ EOF
# Determine whether the default compiler is a.out or elf
cat >$dummy.c <<EOF
#include <features.h>
main(argc, argv)
int argc;
char *argv[];
{
#ifdef __cplusplus
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#ifdef __ELF__
# ifdef __GLIBC__
# if __GLIBC__ >= 2
@@ -674,7 +809,7 @@ main(argc, argv)
return 0;
}
EOF
${CC-cc} $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
fi ;;
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
@@ -691,10 +826,20 @@ EOF
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit 0 ;;
i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
fi
exit 0 ;;
i?86:*:5:7*)
# Fixed at (any) Pentium or better
UNAME_MACHINE=i586
if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
fi
exit 0 ;;
i?86:*:3.2:*)
@@ -706,18 +851,15 @@ EOF
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
&& UNAME_MACHINE=i686
(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit 0 ;;
i?86:UnixWare:*:*)
if /bin/uname -X 2>/dev/null >/dev/null ; then
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
fi
echo ${UNAME_MACHINE}-unixware-${UNAME_RELEASE}-${UNAME_VERSION}
exit 0 ;;
pc:*:*:*)
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386.
@@ -759,7 +901,7 @@ EOF
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
i?86:LynxOS:2.*:*)
i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
TSUNAMI:LynxOS:2.*:*)
@@ -771,6 +913,9 @@ EOF
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
exit 0 ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
@@ -801,7 +946,7 @@ EOF
news*:NEWS-OS:*:6*)
echo mips-sony-newsos6
exit 0 ;;
R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*)
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
@@ -829,6 +974,9 @@ EOF
*:Rhapsody:*:*)
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
*:QNX:*:4*)
echo i386-qnx-qnx${UNAME_VERSION}
exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
@@ -935,7 +1083,7 @@ main ()
}
EOF
${CC-cc} $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
# Apollos put the system type in the environment.

View File

@@ -48,6 +48,50 @@ if test x"$rsync_cv_errno" = x"yes"; then
AC_DEFINE(HAVE_ERRNO_DECL)
fi
# The following test taken from the cvs sources
# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
# These need checks to be before checks for any other functions that
# might be in the same libraries.
# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
# libsocket.so which has a bad implementation of gethostbyname (it
# only looks in /etc/hosts), so we only look for -lsocket if we need
# it.
AC_CHECK_FUNCS(connect)
if test x"$ac_cv_func_connect" = x"no"; then
case "$LIBS" in
*-lnsl*) ;;
*) AC_CHECK_LIB(nsl_s, printf) ;;
esac
case "$LIBS" in
*-lnsl*) ;;
*) AC_CHECK_LIB(nsl, printf) ;;
esac
case "$LIBS" in
*-lsocket*) ;;
*) AC_CHECK_LIB(socket, connect) ;;
esac
case "$LIBS" in
*-linet*) ;;
*) AC_CHECK_LIB(inet, connect) ;;
esac
dnl We can't just call AC_CHECK_FUNCS(connect) here, because the value
dnl has been cached.
if test x"$ac_cv_lib_socket_connect" = x"yes" ||
test x"$ac_cv_lib_inet_connect" = x"yes"; then
# ac_cv_func_connect=yes
# don't! it would cause AC_CHECK_FUNC to succeed next time configure is run
AC_DEFINE(HAVE_CONNECT)
fi
fi
#
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
#
AC_CHECK_FUNCS(strcasecmp)
if test x"$ac_cv_func_strcasecmp" = x"no"; then
AC_CHECK_LIB(resolv, strcasecmp)
fi
AC_FUNC_MEMCMP
AC_FUNC_UTIME_NULL
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod)
@@ -55,6 +99,18 @@ AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime)
AC_CHECK_FUNCS(memmove lchown vsnprintf snprintf setsid glob strpbrk)
AC_CHECK_FUNCS(strlcat strlcpy inet_aton)
AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
AC_TRY_RUN([#include <sys/types.h>
#include <sys/socket.h>
main() {
int fd[2];
exit((socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != -1) ? 0 : 1);
}],
rsync_cv_HAVE_SOCKETPAIR=yes,rsync_cv_HAVE_SOCKETPAIR=no,rsync_cv_HAVE_SOCKETPAIR=cross)])
if test x"$rsync_cv_HAVE_SOCKETPAIR" = x"yes"; then
AC_DEFINE(HAVE_SOCKETPAIR)
fi
AC_CACHE_CHECK([for working fnmatch],rsync_cv_HAVE_FNMATCH,[
AC_TRY_RUN([#include <fnmatch.h>
main() { exit((fnmatch("*.o", "x.o", FNM_PATHNAME) == 0 &&
@@ -135,6 +191,17 @@ if test x"$rsync_cv_HAVE_UTIMBUF" = x"yes"; then
AC_DEFINE(HAVE_UTIMBUF)
fi
AC_CACHE_CHECK([if gettimeofday takes tz argument],rsync_cv_HAVE_GETTIMEOFDAY_TZ,[
AC_TRY_RUN([
#include <sys/time.h>
#include <unistd.h>
main() { struct timeval tv; exit(gettimeofday(&tv, NULL));}],
rsync_cv_HAVE_GETTIMEOFDAY_TZ=yes,rsync_cv_HAVE_GETTIMEOFDAY_TZ=no,rsync_cv_HAVE_GETTIMEOFDAY_TZ=cross)])
if test x"$rsync_cv_HAVE_GETTIMEOFDAY_TZ" = x"yes"; then
AC_DEFINE(HAVE_GETTIMEOFDAY_TZ)
fi
AC_CACHE_CHECK([for broken inet_ntoa],rsync_cv_REPLACE_INET_NTOA,[
AC_TRY_RUN([
#include <stdio.h>
@@ -150,48 +217,6 @@ if test x"$rsync_cv_REPLACE_INET_NTOA" = x"yes"; then
AC_DEFINE(REPLACE_INET_NTOA)
fi
# The following test taken from the cvs sources
# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
# libsocket.so which has a bad implementation of gethostbyname (it
# only looks in /etc/hosts), so we only look for -lsocket if we need
# it.
AC_CHECK_FUNCS(connect)
if test x"$ac_cv_func_connect" = x"no"; then
case "$LIBS" in
*-lnsl*) ;;
*) AC_CHECK_LIB(nsl_s, printf) ;;
esac
case "$LIBS" in
*-lnsl*) ;;
*) AC_CHECK_LIB(nsl, printf) ;;
esac
case "$LIBS" in
*-lsocket*) ;;
*) AC_CHECK_LIB(socket, connect) ;;
esac
case "$LIBS" in
*-linet*) ;;
*) AC_CHECK_LIB(inet, connect) ;;
esac
dnl We can't just call AC_CHECK_FUNCS(connect) here, because the value
dnl has been cached.
if test x"$ac_cv_lib_socket_connect" = x"yes" ||
test x"$ac_cv_lib_inet_connect" = x"yes"; then
# ac_cv_func_connect=yes
# don't! it would cause AC_CHECK_FUNC to succeed next time configure is run
AC_DEFINE(HAVE_CONNECT)
fi
fi
#
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
#
AC_CHECK_FUNCS(strcasecmp)
if test x"$ac_cv_func_strcasecmp" = x"no"; then
AC_CHECK_LIB(resolv, strcasecmp)
fi
#
# The following test was mostly taken from the tcl/tk plus patches
#

View File

@@ -27,50 +27,6 @@ extern int delete_mode;
static struct exclude_struct **exclude_list;
/*
* Optimization for special case when all included files are explicitly
* listed without wildcards in the "exclude" list followed by a "- *"
* to exclude the rest.
* Contributed by Dave Dykstra <dwd@bell-labs.com>
*/
static int only_included_files = 1;
static struct exclude_struct *exclude_the_rest;
int send_included_file_names(int f,struct file_list *flist)
{
struct exclude_struct *ex, **ex_list;
int n;
char *p;
if (!only_included_files || (exclude_the_rest == NULL) || delete_mode)
return 0;
if (verbose > 1) {
rprintf(FINFO,"(using include-only optimization) ");
}
/* set exclude_list to NULL temporarily so check_exclude */
/* will always return true */
ex_list = exclude_list;
exclude_list = NULL;
for (n=0; (ex = ex_list[n]) != NULL; n++) {
if (ex == exclude_the_rest)
break;
p = ex->pattern;
while (*p == '/') {
/* skip the allowed beginning slashes */
p++;
}
/* silently skip files that don't exist to
be more like non-optimized case */
if (access(p,0) == 0)
send_file_name(f,flist,p,0,0);
}
exclude_list = ex_list;
return 1;
}
/* build an exclude structure given a exclude pattern */
static struct exclude_struct *make_exclude(char *pattern, int include)
{
@@ -95,15 +51,18 @@ static struct exclude_struct *make_exclude(char *pattern, int include)
if (!ret->pattern) out_of_memory("make_exclude");
if (strpbrk(pattern, "*[?")) {
if (!ret->include && (*pattern == '*') && (*(pattern+1) == '\0')) {
exclude_the_rest = ret;
} else {
only_included_files = 0;
}
ret->regular_exp = 1;
ret->fnmatch_flags = strstr(pattern, "**") ? 0 : FNM_PATHNAME;
} else if (!ret->include) {
only_included_files = 0;
ret->fnmatch_flags = FNM_PATHNAME;
if (strstr(pattern, "**")) {
static int tested;
if (!tested) {
tested = 1;
if (fnmatch("a/b/*", "a/b/c/d", FNM_PATHNAME)==0) {
rprintf(FERROR,"WARNING: fnmatch FNM_PATHNAME is broken on your system\n");
}
}
ret->fnmatch_flags = 0;
}
}
if (strlen(pattern) > 1 && pattern[strlen(pattern)-1] == '/') {
@@ -145,15 +104,17 @@ static int check_one_exclude(char *name,struct exclude_struct *ex,
}
if (ex->regular_exp) {
if (fnmatch(pattern, name, ex->fnmatch_flags) == 0)
if (fnmatch(pattern, name, ex->fnmatch_flags) == 0) {
return 1;
}
} else {
int l1 = strlen(name);
int l2 = strlen(pattern);
if (l2 <= l1 &&
strcmp(name+(l1-l2),pattern) == 0 &&
(l1==l2 || (!match_start && name[l1-(l2+1)] == '/')))
(l1==l2 || (!match_start && name[l1-(l2+1)] == '/'))) {
return 1;
}
}
return 0;
@@ -199,8 +160,6 @@ void add_exclude_list(char *pattern,struct exclude_struct ***list, int include)
}
free((*list));
*list = NULL;
only_included_files = 1;
exclude_the_rest = NULL;
return;
}

29
flist.c
View File

@@ -299,7 +299,11 @@ static void receive_file_entry(struct file_struct **fptr,
memset((char *)file, 0, sizeof(*file));
(*fptr) = file;
if (l2 >= MAXPATHLEN-l1) overflow("receive_file_entry");
if (l2 >= MAXPATHLEN-l1) {
rprintf(FERROR,"overflow: flags=0x%x l1=%d l2=%d lastname=%s\n",
flags, l1, l2, lastname);
overflow("receive_file_entry");
}
strlcpy(thisname,lastname,l1+1);
read_sbuf(f,&thisname[l1],l2);
@@ -409,7 +413,8 @@ static int skip_filesystem(char *fname, STRUCT_STAT *st)
return (st2.st_dev != filesystem_dev);
}
static struct file_struct *make_file(int f, char *fname)
/* create a file_struct for a named file */
struct file_struct *make_file(int f, char *fname)
{
struct file_struct *file;
STRUCT_STAT st;
@@ -431,7 +436,7 @@ static struct file_struct *make_file(int f, char *fname)
if (readlink_stat(fname,&st,linkbuf) != 0) {
io_error = 1;
rprintf(FERROR,"%s: %s\n",
rprintf(FERROR,"readlink %s: %s\n",
fname,strerror(errno));
return NULL;
}
@@ -668,8 +673,10 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
}
if (link_stat(fname,&st) != 0) {
io_error=1;
rprintf(FERROR,"%s : %s\n",fname,strerror(errno));
if (f != -1) {
io_error=1;
rprintf(FERROR,"link_stat %s : %s\n",fname,strerror(errno));
}
continue;
}
@@ -737,8 +744,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
if (one_file_system)
set_filesystem(fname);
if (!recurse || !send_included_file_names(f,flist))
send_file_name(f,flist,fname,recurse,FLAG_DELETE);
send_file_name(f,flist,fname,recurse,FLAG_DELETE);
if (olddir != NULL) {
flist_dir = NULL;
@@ -856,7 +862,8 @@ struct file_list *recv_file_list(int f)
/* if protocol version is >= 17 then recv the io_error flag */
if (f != -1 && remote_version >= 17) {
extern int module_id;
if (lp_ignore_errors(module_id)) {
extern int ignore_errors;
if (lp_ignore_errors(module_id) || ignore_errors) {
read_int(f);
} else {
io_error |= read_int(f);
@@ -922,7 +929,7 @@ int flist_find(struct file_list *flist,struct file_struct *f)
/*
* free up one file
*/
static void free_file(struct file_struct *file)
void free_file(struct file_struct *file)
{
if (!file) return;
if (file->basename) free(file->basename);
@@ -999,12 +1006,12 @@ static void clean_flist(struct file_list *flist, int strip_root)
if (verbose <= 3) return;
for (i=0;i<flist->count;i++) {
rprintf(FINFO,"[%d] i=%d %s %s mode=0%o len=%d\n",
rprintf(FINFO,"[%d] i=%d %s %s mode=0%o len=%.0f\n",
getpid(), i,
NS(flist->files[i]->dirname),
NS(flist->files[i]->basename),
flist->files[i]->mode,
(int)flist->files[i]->length);
(double)flist->files[i]->length);
}
}

View File

@@ -136,8 +136,8 @@ static struct sum_struct *generate_sums(struct map_struct *buf,OFF_T len,int n)
}
if (verbose > 3)
rprintf(FINFO,"count=%d rem=%d n=%d flength=%d\n",
s->count,s->remainder,s->n,(int)s->flength);
rprintf(FINFO,"count=%d rem=%d n=%d flength=%.0f\n",
s->count,s->remainder,s->n,(double)s->flength);
s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
if (!s->sums) out_of_memory("generate_sums");
@@ -154,8 +154,8 @@ static struct sum_struct *generate_sums(struct map_struct *buf,OFF_T len,int n)
s->sums[i].i = i;
if (verbose > 3)
rprintf(FINFO,"chunk[%d] offset=%d len=%d sum1=%08x\n",
i,(int)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1);
rprintf(FINFO,"chunk[%d] offset=%.0f len=%d sum1=%08x\n",
i,(double)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1);
len -= n1;
offset += n1;
@@ -178,6 +178,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
extern char *compare_dest;
extern int list_only;
extern int preserve_perms;
extern int only_existing;
if (list_only) return;
@@ -186,13 +187,19 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
statret = link_stat(fname,&st);
if (only_existing && statret == -1 && errno == ENOENT) {
/* we only want to update existing files */
if (verbose > 1) rprintf(FINFO,"not creating %s\n",fname);
return;
}
if (statret == 0 &&
!preserve_perms &&
(S_ISDIR(st.st_mode) == S_ISDIR(file->mode))) {
/* if the file exists already and we aren't perserving
presmissions then act as though the remote end sent
us the file permissions we already have */
file->mode = st.st_mode;
file->mode = (file->mode & _S_IFMT) | (st.st_mode & ~_S_IFMT);
}
if (S_ISDIR(file->mode)) {
@@ -242,7 +249,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
}
delete_file(fname);
if (do_symlink(file->link,fname) != 0) {
rprintf(FERROR,"link %s -> %s : %s\n",
rprintf(FERROR,"symlink %s -> %s : %s\n",
fname,file->link,strerror(errno));
} else {
set_perms(fname,file,NULL,0);
@@ -353,8 +360,10 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
fd = do_open(fnamecmp, O_RDONLY, 0);
if (fd == -1) {
rprintf(FERROR,"failed to open %s : %s\n",fnamecmp,strerror(errno));
rprintf(FERROR,"skipping %s\n",fname);
rprintf(FERROR,"failed to open %s, continuing : %s\n",fnamecmp,strerror(errno));
/* pretend the file didn't exist */
write_int(f_out,i);
send_sums(NULL,f_out);
return;
}
@@ -365,7 +374,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
}
if (verbose > 3)
rprintf(FINFO,"gen mapped %s of size %d\n",fnamecmp,(int)st.st_size);
rprintf(FINFO,"gen mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
s = generate_sums(buf,st.st_size,adapt_block_size(file, block_size));

237
io.c
View File

@@ -18,7 +18,7 @@
*/
/*
Utilities used in rsync
socket and pipe IO utilities used in rsync
tridge, June 1996
*/
@@ -38,6 +38,9 @@ extern int io_timeout;
extern struct stats stats;
static int buffer_f_in = -1;
static int io_error_fd = -1;
static void read_loop(int fd, char *buf, int len);
void setup_readbuffer(int f_in)
{
@@ -64,13 +67,42 @@ static void check_timeout(void)
}
}
/* setup the fd used to propogate errors */
void io_set_error_fd(int fd)
{
io_error_fd = fd;
}
/* read some data from the error fd and write it to the write log code */
static void read_error_fd(void)
{
char buf[200];
int n;
int fd = io_error_fd;
int tag, len;
io_error_fd = -1;
read_loop(fd, buf, 4);
tag = IVAL(buf, 0);
len = tag & 0xFFFFFF;
tag = tag >> 24;
tag -= MPLEX_BASE;
while (len) {
n = len;
if (n > (sizeof(buf)-1)) n = sizeof(buf)-1;
read_loop(fd, buf, n);
rwrite((enum logcode)tag, buf, n);
len -= n;
}
io_error_fd = fd;
}
static char *read_buffer;
static char *read_buffer_p;
static int read_buffer_len;
static int read_buffer_size;
static int no_flush;
static int no_flush_read;
/* read from a socket with IO timeout. return the number of
bytes read. If no bytes can be read then exit, never return
@@ -79,24 +111,39 @@ static int read_timeout(int fd, char *buf, int len)
{
int n, ret=0;
no_flush_read++;
io_flush();
no_flush_read--;
while (ret == 0) {
fd_set fds;
struct timeval tv;
int fd_count = fd+1;
FD_ZERO(&fds);
FD_SET(fd, &fds);
if (io_error_fd != -1) {
FD_SET(io_error_fd, &fds);
if (io_error_fd > fd) fd_count = io_error_fd+1;
}
tv.tv_sec = io_timeout?io_timeout:SELECT_TIMEOUT;
tv.tv_usec = 0;
if (select(fd+1, &fds, NULL, NULL, &tv) != 1) {
errno = 0;
if (select(fd_count, &fds, NULL, NULL, &tv) < 1) {
if (errno == EBADF) {
exit_cleanup(RERR_SOCKETIO);
}
check_timeout();
continue;
}
if (io_error_fd != -1 && FD_ISSET(io_error_fd, &fds)) {
read_error_fd();
}
if (!FD_ISSET(fd, &fds)) continue;
n = read(fd, buf, len);
if (n > 0) {
@@ -113,14 +160,11 @@ static int read_timeout(int fd, char *buf, int len)
}
if (n == -1 &&
(errno == EAGAIN || errno == EWOULDBLOCK)) {
/* this shouldn't happen, if it does then
sleep for a short time to prevent us
chewing too much CPU */
u_sleep(100);
(errno == EWOULDBLOCK || errno == EAGAIN)) {
continue;
}
if (n == 0) {
if (eof_error) {
rprintf(FERROR,"unexpected EOF in read_timeout\n");
@@ -128,6 +172,9 @@ static int read_timeout(int fd, char *buf, int len)
exit_cleanup(RERR_STREAMIO);
}
/* this prevents us trying to write errors on a dead socket */
io_multiplexing_close();
rprintf(FERROR,"read error: %s\n", strerror(errno));
exit_cleanup(RERR_STREAMIO);
}
@@ -153,7 +200,6 @@ static void read_loop(int fd, char *buf, int len)
static int read_unbuffered(int fd, char *buf, int len)
{
static int remaining;
char ibuf[4];
int tag, ret=0;
char line[1024];
@@ -169,8 +215,8 @@ static int read_unbuffered(int fd, char *buf, int len)
continue;
}
read_loop(fd, ibuf, 4);
tag = IVAL(ibuf, 0);
read_loop(fd, line, 4);
tag = IVAL(line, 0);
remaining = tag & 0xFFFFFF;
tag = tag >> 24;
@@ -193,7 +239,7 @@ static int read_unbuffered(int fd, char *buf, int len)
read_loop(fd, line, remaining);
line[remaining] = 0;
rprintf(tag,"%s", line);
rprintf((enum logcode)tag,"%s", line);
remaining = 0;
}
@@ -201,40 +247,6 @@ static int read_unbuffered(int fd, char *buf, int len)
}
/* This function was added to overcome a deadlock problem when using
* ssh. It looks like we can't allow our receive queue to get full or
* ssh will clag up. Uggh. */
static void read_check(int f)
{
int n = 8192;
if (f == -1) return;
if (read_buffer_len == 0) {
read_buffer_p = read_buffer;
}
if (n > MAX_READ_BUFFER/4)
n = MAX_READ_BUFFER/4;
if (read_buffer_p != read_buffer) {
memmove(read_buffer,read_buffer_p,read_buffer_len);
read_buffer_p = read_buffer;
}
if (n > (read_buffer_size - read_buffer_len)) {
read_buffer_size += n;
read_buffer = (char *)Realloc(read_buffer,read_buffer_size);
if (!read_buffer) out_of_memory("read check");
read_buffer_p = read_buffer;
}
n = read_unbuffered(f,read_buffer+read_buffer_len,n);
read_buffer_len += n;
}
/* do a buffered read from fd. don't return until all N bytes
have been read. If all N can't be read then exit with an error */
static void readfd(int fd,char *buffer,int N)
@@ -242,23 +254,8 @@ static void readfd(int fd,char *buffer,int N)
int ret;
int total=0;
if ((read_buffer_len < N) && (N < 1024)) {
read_check(buffer_f_in);
}
while (total < N) {
if (read_buffer_len > 0 && buffer_f_in == fd) {
ret = MIN(read_buffer_len,N-total);
memcpy(buffer+total,read_buffer_p,ret);
read_buffer_p += ret;
read_buffer_len -= ret;
total += ret;
continue;
}
no_flush_read++;
io_flush();
no_flush_read--;
ret = read_unbuffered(fd,buffer + total,N-total);
total += ret;
@@ -332,8 +329,6 @@ static void writefd_unbuffered(int fd,char *buf,int len)
fd_set w_fds, r_fds;
int fd_count, count;
struct timeval tv;
int reading=0;
int blocked=0;
no_flush++;
@@ -341,46 +336,47 @@ static void writefd_unbuffered(int fd,char *buf,int len)
FD_ZERO(&w_fds);
FD_ZERO(&r_fds);
FD_SET(fd,&w_fds);
fd_count = fd+1;
fd_count = fd;
if (!no_flush_read) {
reading = (buffer_f_in != -1);
}
if (reading) {
FD_SET(buffer_f_in,&r_fds);
if (buffer_f_in > fd)
fd_count = buffer_f_in+1;
if (io_error_fd != -1) {
FD_SET(io_error_fd,&r_fds);
if (io_error_fd > fd_count)
fd_count = io_error_fd;
}
tv.tv_sec = io_timeout?io_timeout:SELECT_TIMEOUT;
tv.tv_usec = 0;
count = select(fd_count,
reading?&r_fds:NULL,
errno = 0;
count = select(fd_count+1,
io_error_fd != -1?&r_fds:NULL,
&w_fds,NULL,
&tv);
if (count <= 0) {
if (errno == EBADF) {
exit_cleanup(RERR_SOCKETIO);
}
check_timeout();
continue;
}
if (reading && FD_ISSET(buffer_f_in, &r_fds)) {
read_check(buffer_f_in);
if (io_error_fd != -1 && FD_ISSET(io_error_fd, &r_fds)) {
read_error_fd();
}
if (FD_ISSET(fd, &w_fds)) {
int n = (len-total)>>blocked;
int ret = write(fd,buf+total,n?n:1);
int ret, n = len-total;
ret = write(fd,buf+total,n);
if (ret == -1 && errno == EINTR) {
continue;
}
if (ret == -1 &&
(errno == EAGAIN || errno == EWOULDBLOCK)) {
blocked++;
(errno == EWOULDBLOCK || errno == EAGAIN)) {
continue;
}
@@ -389,7 +385,6 @@ static void writefd_unbuffered(int fd,char *buf,int len)
exit_cleanup(RERR_STREAMIO);
}
blocked = 0;
total += ret;
if (io_timeout)
@@ -408,22 +403,43 @@ void io_start_buffering(int fd)
{
if (io_buffer) return;
multiplex_out_fd = fd;
io_buffer = (char *)malloc(IO_BUFFER_SIZE+4);
io_buffer = (char *)malloc(IO_BUFFER_SIZE);
if (!io_buffer) out_of_memory("writefd");
io_buffer_count = 0;
/* leave room for the multiplex header in case it's needed */
io_buffer += 4;
}
/* write an message to a multiplexed stream. If this fails then rsync
exits */
static void mplex_write(int fd, enum logcode code, char *buf, int len)
{
char buffer[4096];
int n = len;
SIVAL(buffer, 0, ((MPLEX_BASE + (int)code)<<24) + len);
if (n > (sizeof(buffer)-4)) {
n = sizeof(buffer)-4;
}
memcpy(&buffer[4], buf, n);
writefd_unbuffered(fd, buffer, n+4);
len -= n;
buf += n;
if (len) {
writefd_unbuffered(fd, buf, len);
}
}
void io_flush(void)
{
int fd = multiplex_out_fd;
if (!io_buffer_count || no_flush) return;
if (io_multiplexing_out) {
SIVAL(io_buffer-4, 0, (MPLEX_BASE<<24) + io_buffer_count);
writefd_unbuffered(fd, io_buffer-4, io_buffer_count+4);
mplex_write(fd, FNONE, io_buffer, io_buffer_count);
} else {
writefd_unbuffered(fd, io_buffer, io_buffer_count);
}
@@ -434,7 +450,7 @@ void io_end_buffering(int fd)
{
io_flush();
if (!io_multiplexing_out) {
free(io_buffer-4);
free(io_buffer);
io_buffer = NULL;
}
}
@@ -443,7 +459,7 @@ static void writefd(int fd,char *buf,int len)
{
stats.total_written += len;
if (!io_buffer) {
if (!io_buffer || fd != multiplex_out_fd) {
writefd_unbuffered(fd, buf, len);
return;
}
@@ -561,31 +577,36 @@ void io_start_multiplex_in(int fd)
{
multiplex_in_fd = fd;
io_flush();
if (read_buffer_len) {
fprintf(stderr,"ERROR: data in read buffer at mplx start\n");
exit_cleanup(RERR_STREAMIO);
}
io_multiplexing_in = 1;
}
/* write an message to the error stream */
int io_multiplex_write(int f, char *buf, int len)
/* write an message to the multiplexed error stream */
int io_multiplex_write(enum logcode code, char *buf, int len)
{
if (!io_multiplexing_out) return 0;
io_flush();
SIVAL(io_buffer-4, 0, ((MPLEX_BASE + f)<<24) + len);
memcpy(io_buffer, buf, len);
stats.total_written += (len+4);
writefd_unbuffered(multiplex_out_fd, io_buffer-4, len+4);
mplex_write(multiplex_out_fd, code, buf, len);
return 1;
}
/* write a message to the special error fd */
int io_error_write(int f, enum logcode code, char *buf, int len)
{
if (f == -1) return 0;
mplex_write(f, code, buf, len);
return 1;
}
/* stop output multiplexing */
void io_multiplexing_close(void)
{
io_multiplexing_out = 0;
}
void io_close_input(int fd)
{
buffer_f_in = -1;
}

View File

@@ -149,15 +149,36 @@
#ifndef HAVE_INET_ATON
int inet_aton(const char *cp, struct in_addr *inp)
{
unsigned int a1, a2, a3, a4;
unsigned long ret;
if (strcmp(cp, "255.255.255.255") == 0) {
inp->s_addr = (unsigned) -1;
return 1;
}
inp->s_addr = inet_addr(cp);
if (sscanf(cp, "%u.%u.%u.%u", &a1, &a2, &a3, &a4) != 4 ||
a1 > 255 || a2 > 255 || a3 > 255 || a4 > 255) {
return 1;
}
ret = (a1 << 24) | (a2 << 16) | (a3 << 8) | a4;
inp->s_addr = htonl(ret);
if (inp->s_addr == (unsigned) -1) {
return 0;
}
return 1;
}
#endif
/* some systems don't take the 2nd argument */
int sys_gettimeofday(struct timeval *tv)
{
#if HAVE_GETTIMEOFDAY_TZ
return gettimeofday(tv, NULL);
#else
return gettimeofday(tv);
#endif
}

View File

@@ -1,33 +1,60 @@
#include "../rsync.h"
#ifndef HAVE_FNMATCH
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
/* ----- THE FOLLOWING UP TO 'END' is glibc-2.1.2 posix/fnmatch.c
except for the parts with '#if 0' */
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#if defined (STDC_HEADERS) || !defined (isascii)
#define ISASCII(c) 1
#else
#define ISASCII(c) isascii(c)
#if 0 /* header files included better by ../rsync.h */
#if HAVE_CONFIG_H
# include <config.h>
#endif
#define ISUPPER(c) (ISASCII (c) && isupper (c))
/* Enable GNU extensions in fnmatch.h. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
#include <errno.h>
#include <fnmatch.h>
#include <ctype.h>
#if HAVE_STRING_H || defined _LIBC
# include <string.h>
#else
# include <strings.h>
#endif
#if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
#endif
#endif /* 0 */
/* For platform which support the ISO C amendement 1 functionality we
support user defined character classes. */
#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
# include <wchar.h>
# include <wctype.h>
#endif
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
@@ -37,23 +64,95 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
extern int errno;
#if 1
# if defined STDC_HEADERS || !defined isascii
# define ISASCII(c) 1
# else
# define ISASCII(c) isascii(c)
# endif
#ifdef isblank
# define ISBLANK(c) (ISASCII (c) && isblank (c))
#else
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
#endif
#ifdef isgraph
# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
#else
# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
#endif
#define ISPRINT(c) (ISASCII (c) && isprint (c))
#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
#define ISALNUM(c) (ISASCII (c) && isalnum (c))
#define ISALPHA(c) (ISASCII (c) && isalpha (c))
#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
#define ISLOWER(c) (ISASCII (c) && islower (c))
#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
#define ISSPACE(c) (ISASCII (c) && isspace (c))
#define ISUPPER(c) (ISASCII (c) && isupper (c))
#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
/* The GNU C library provides support for user-defined character classes
and the functions from ISO C amendement 1. */
# ifdef CHARCLASS_NAME_MAX
# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
# else
/* This shouldn't happen but some implementation might still have this
problem. Use a reasonable default value. */
# define CHAR_CLASS_MAX_LENGTH 256
# endif
# ifdef _LIBC
# define IS_CHAR_CLASS(string) __wctype (string)
# else
# define IS_CHAR_CLASS(string) wctype (string)
# endif
# else
# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
# define IS_CHAR_CLASS(string) \
(STREQ (string, "alpha") || STREQ (string, "upper") \
|| STREQ (string, "lower") || STREQ (string, "digit") \
|| STREQ (string, "alnum") || STREQ (string, "xdigit") \
|| STREQ (string, "space") || STREQ (string, "print") \
|| STREQ (string, "punct") || STREQ (string, "graph") \
|| STREQ (string, "cntrl") || STREQ (string, "blank"))
# endif
/* Avoid depending on library functions or files
whose names are inconsistent. */
# if !defined _LIBC && !defined getenv
extern char *getenv ();
# endif
# ifndef errno
extern int errno;
# endif
/* Match STRING against the filename pattern PATTERN, returning zero if
it matches, nonzero if not. */
int
fnmatch (pattern, string, flags)
const char *pattern;
const char *string;
int flags;
static int
#ifdef _LIBC
internal_function
#endif
internal_fnmatch (const char *pattern, const char *string,
int no_leading_period, int flags)
{
register const char *p = pattern, *n = string;
register char c;
register unsigned char c;
/* Note that this evalutes C many times. */
#define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
/* Note that this evaluates C many times. */
# ifdef _LIBC
# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
# else
# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
# endif
while ((c = *p++) != '\0')
{
@@ -64,10 +163,11 @@ fnmatch (pattern, string, flags)
case '?':
if (*n == '\0')
return FNM_NOMATCH;
else if ((flags & FNM_FILE_NAME) && *n == '/')
else if (*n == '/' && (flags & FNM_FILE_NAME))
return FNM_NOMATCH;
else if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
else if (*n == '.' && no_leading_period
&& (n == string
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
return FNM_NOMATCH;
break;
@@ -75,95 +175,245 @@ fnmatch (pattern, string, flags)
if (!(flags & FNM_NOESCAPE))
{
c = *p++;
if (c == '\0')
/* Trailing \ loses. */
return FNM_NOMATCH;
c = FOLD (c);
}
if (FOLD (*n) != c)
if (FOLD ((unsigned char) *n) != c)
return FNM_NOMATCH;
break;
case '*':
if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
if (*n == '.' && no_leading_period
&& (n == string
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
return FNM_NOMATCH;
for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
if (((flags & FNM_FILE_NAME) && *n == '/') ||
(c == '?' && *n == '\0'))
return FNM_NOMATCH;
for (c = *p++; c == '?' || c == '*'; c = *p++)
{
if (*n == '/' && (flags & FNM_FILE_NAME))
/* A slash does not match a wildcard under FNM_FILE_NAME. */
return FNM_NOMATCH;
else if (c == '?')
{
/* A ? needs to match one character. */
if (*n == '\0')
/* There isn't another character; no match. */
return FNM_NOMATCH;
else
/* One character of the string is consumed in matching
this ? wildcard, so *??? won't match if there are
less than three characters. */
++n;
}
}
if (c == '\0')
return 0;
/* The wildcard(s) is/are the last element of the pattern.
If the name is a file name and contains another slash
this does mean it cannot match. */
return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
? FNM_NOMATCH : 0);
else
{
const char *endp;
{
char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
c1 = FOLD (c1);
for (--p; *n != '\0'; ++n)
if ((c == '[' || FOLD (*n) == c1) &&
fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
return 0;
return FNM_NOMATCH;
}
#if 0
endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
#else
/* replace call to internal glibc function with equivalent */
if (!(flags & FNM_FILE_NAME) || ((endp = strchr(n, '/')) == NULL))
endp = n + strlen(n);
#endif
if (c == '[')
{
int flags2 = ((flags & FNM_FILE_NAME)
? flags : (flags & ~FNM_PERIOD));
for (--p; n < endp; ++n)
if (internal_fnmatch (p, n,
(no_leading_period
&& (n == string
|| (n[-1] == '/'
&& (flags
& FNM_FILE_NAME)))),
flags2)
== 0)
return 0;
}
else if (c == '/' && (flags & FNM_FILE_NAME))
{
while (*n != '\0' && *n != '/')
++n;
if (*n == '/'
&& (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
flags) == 0))
return 0;
}
else
{
int flags2 = ((flags & FNM_FILE_NAME)
? flags : (flags & ~FNM_PERIOD));
if (c == '\\' && !(flags & FNM_NOESCAPE))
c = *p;
c = FOLD (c);
for (--p; n < endp; ++n)
if (FOLD ((unsigned char) *n) == c
&& (internal_fnmatch (p, n,
(no_leading_period
&& (n == string
|| (n[-1] == '/'
&& (flags
& FNM_FILE_NAME)))),
flags2) == 0))
return 0;
}
}
/* If we come here no match is possible with the wildcard. */
return FNM_NOMATCH;
case '[':
{
/* Nonzero if the sense of the character class is inverted. */
static int posixly_correct;
register int not;
char cold;
if (posixly_correct == 0)
posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
if (*n == '\0')
return FNM_NOMATCH;
if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
if (*n == '.' && no_leading_period && (n == string
|| (n[-1] == '/'
&& (flags
& FNM_FILE_NAME))))
return FNM_NOMATCH;
not = (*p == '!' || *p == '^');
if (*n == '/' && (flags & FNM_FILE_NAME))
/* `/' cannot be matched. */
return FNM_NOMATCH;
not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
if (not)
++p;
c = *p++;
for (;;)
{
register char cstart = c, cend = c;
unsigned char fn = FOLD ((unsigned char) *n);
if (!(flags & FNM_NOESCAPE) && c == '\\')
cstart = cend = *p++;
{
if (*p == '\0')
return FNM_NOMATCH;
c = FOLD ((unsigned char) *p);
++p;
cstart = cend = FOLD (cstart);
if (c == fn)
goto matched;
}
else if (c == '[' && *p == ':')
{
/* Leave room for the null. */
char str[CHAR_CLASS_MAX_LENGTH + 1];
size_t c1 = 0;
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
wctype_t wt;
# endif
const char *startp = p;
if (c == '\0')
for (;;)
{
if (c1 == CHAR_CLASS_MAX_LENGTH)
/* The name is too long and therefore the pattern
is ill-formed. */
return FNM_NOMATCH;
c = *++p;
if (c == ':' && p[1] == ']')
{
p += 2;
break;
}
if (c < 'a' || c >= 'z')
{
/* This cannot possibly be a character class name.
Match it as a normal range. */
p = startp;
c = '[';
goto normal_bracket;
}
str[c1++] = c;
}
str[c1] = '\0';
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
wt = IS_CHAR_CLASS (str);
if (wt == 0)
/* Invalid character class name. */
return FNM_NOMATCH;
if (__iswctype (__btowc ((unsigned char) *n), wt))
goto matched;
# else
if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
|| (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
|| (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
|| (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
|| (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
|| (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
|| (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
|| (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
|| (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
|| (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
|| (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
|| (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
goto matched;
# endif
}
else if (c == '\0')
/* [ (unterminated) loses. */
return FNM_NOMATCH;
c = *p++;
c = FOLD (c);
if ((flags & FNM_FILE_NAME) && c == '/')
/* [/] can never match. */
return FNM_NOMATCH;
if (c == '-' && *p != ']')
else
{
cend = *p++;
if (!(flags & FNM_NOESCAPE) && cend == '\\')
cend = *p++;
if (cend == '\0')
return FNM_NOMATCH;
cend = FOLD (cend);
normal_bracket:
if (FOLD (c) == fn)
goto matched;
cold = c;
c = *p++;
}
if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
goto matched;
if (c == '-' && *p != ']')
{
/* It is a range. */
unsigned char cend = *p++;
if (!(flags & FNM_NOESCAPE) && cend == '\\')
cend = *p++;
if (cend == '\0')
return FNM_NOMATCH;
if (cold <= fn && fn <= FOLD (cend))
goto matched;
c = *p++;
}
}
if (c == ']')
break;
}
if (!not)
return FNM_NOMATCH;
break;
matched:;
matched:
/* Skip the rest of the [...] that already matched. */
while (c != ']')
{
@@ -173,8 +423,21 @@ fnmatch (pattern, string, flags)
c = *p++;
if (!(flags & FNM_NOESCAPE) && c == '\\')
/* XXX 1003.2d11 is unclear if this is right. */
++p;
{
if (*p == '\0')
return FNM_NOMATCH;
/* XXX 1003.2d11 is unclear if this is right. */
++p;
}
else if (c == '[' && *p == ':')
{
do
if (*++p == '\0')
return FNM_NOMATCH;
while (*p != ':' || p[1] == ']');
p += 2;
c = *p;
}
}
if (not)
return FNM_NOMATCH;
@@ -182,7 +445,7 @@ fnmatch (pattern, string, flags)
break;
default:
if (c != FOLD (*n))
if (c != FOLD ((unsigned char) *n))
return FNM_NOMATCH;
}
@@ -197,8 +460,23 @@ fnmatch (pattern, string, flags)
return 0;
return FNM_NOMATCH;
# undef FOLD
}
int
fnmatch (pattern, string, flags)
const char *pattern;
const char *string;
int flags;
{
return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
}
#endif /* _LIBC or not __GNU_LIBRARY__. */
/* ----- END glibc-2.1.2 posix/fnmatch.c */
#else /* HAVE_FNMATCH */
void fnmatch_dummy(void) {}
#endif

View File

@@ -1,41 +1,48 @@
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
/* Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc.
This file is part of the GNU C Library.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef _FNMATCH_H
#define _FNMATCH_H 1
#ifdef __cplusplus
extern "C" {
#endif
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
#undef __P
#define __P(protos) protos
#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
# if !defined __GLIBC__ || !defined __P
# undef __P
# define __P(protos) protos
# endif
#else /* Not C++ or ANSI C. */
#undef __P
#define __P(protos) ()
# undef __P
# define __P(protos) ()
/* We can get away without defining `const' here only because in this file
it is used only inside the prototype for `fnmatch', which is elided in
non-ANSI C where `const' is problematical. */
#endif /* C++ or ANSI C. */
#ifndef const
# if (defined __STDC__ && __STDC__) || defined __cplusplus
# define __const const
# else
# define __const
# endif
#endif
/* We #undef these before defining them because some losing systems
(HP-UX A.08.07 for example) define these in <unistd.h>. */
@@ -49,21 +56,29 @@ extern "C" {
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
#ifndef FNM_FILE_NAME
#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
#endif
#ifndef FNM_LEADING_DIR
#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
#endif
#ifndef FNM_CASEFOLD
#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
#endif
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
#define FNM_NOMATCH 1
/* This value is returned if the implementation does not support
`fnmatch'. Since this is not the case here it will never be
returned but the conformance test suites still require the symbol
to be defined. */
#ifdef _XOPEN_SOURCE
# define FNM_NOSYS (-1)
#endif
/* Match STRING against the filename pattern PATTERN,
returning zero if it matches, FNM_NOMATCH if not. */
extern int fnmatch __P ((const char *__pattern, const char *__string,
extern int fnmatch __P ((__const char *__pattern, __const char *__string,
int __flags));
#ifdef __cplusplus

View File

@@ -37,9 +37,9 @@ static struct mdfour *m;
#define lshift(x,s) (((x)<<(s)) | ((x)>>(32-(s))))
#endif
#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + 0x5A827999,s)
#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + 0x6ED9EBA1,s)
#define ROUND1(a,b,c,d,k,s) a = lshift((uint32)(a + F(b,c,d) + X[k]), s)
#define ROUND2(a,b,c,d,k,s) a = lshift((uint32)(a + G(b,c,d) + X[k] + 0x5A827999),s)
#define ROUND3(a,b,c,d,k,s) a = lshift((uint32)(a + H(b,c,d) + X[k] + 0x6ED9EBA1),s)
/* this applies md4 to 64 byte chunks */
static void mdfour64(uint32 *M)

79
log.c
View File

@@ -24,7 +24,7 @@
#include "rsync.h"
static FILE *logfile;
static int log_error_fd = -1;
static void logit(int priority, char *buf)
{
@@ -77,60 +77,66 @@ void log_open(void)
logit(LOG_INFO,"rsyncd started\n");
#endif
}
/* this is the rsync debugging function. Call it with FINFO, FERROR or FLOG */
void rprintf(int fd, const char *format, ...)
/* setup the error file descriptor - used when we are a server
that is receiving files */
void set_error_fd(int fd)
{
log_error_fd = fd;
}
/* this is the underlying (unformatted) rsync debugging function. Call
it with FINFO, FERROR or FLOG */
void rwrite(enum logcode code, char *buf, int len)
{
va_list ap;
char buf[1024];
int len;
FILE *f=NULL;
extern int am_daemon;
extern int am_server;
extern int quiet;
/* recursion can happen with certain fatal conditions */
if (quiet != 0 && fd == FINFO) return;
va_start(ap, format);
len = vslprintf(buf, sizeof(buf), format, ap);
va_end(ap);
if (quiet && code == FINFO) return;
if (len < 0) exit_cleanup(RERR_MESSAGEIO);
if (len > sizeof(buf)-1) exit_cleanup(RERR_MESSAGEIO);
buf[len] = 0;
if (fd == FLOG) {
if (code == FLOG) {
if (am_daemon) logit(LOG_INFO, buf);
return;
}
/* first try to pass it off the our sibling */
if (am_server && io_error_write(log_error_fd, code, buf, len)) {
return;
}
/* then try to pass it to the other end */
if (am_server && io_multiplex_write(code, buf, len)) {
return;
}
if (am_daemon) {
static int depth;
int priority = LOG_INFO;
if (fd == FERROR) priority = LOG_WARNING;
if (code == FERROR) priority = LOG_WARNING;
if (depth) return;
depth++;
log_open();
if (!io_multiplex_write(fd, buf, strlen(buf))) {
logit(priority, buf);
}
logit(priority, buf);
depth--;
return;
}
if (fd == FERROR) {
if (code == FERROR) {
f = stderr;
}
if (fd == FINFO) {
extern int am_server;
if (code == FINFO) {
if (am_server)
f = stderr;
else
@@ -143,8 +149,25 @@ void log_open(void)
if (buf[len-1] == '\r' || buf[len-1] == '\n') fflush(f);
}
void rflush(int fd)
/* this is the rsync debugging function. Call it with FINFO, FERROR or FLOG */
void rprintf(enum logcode code, const char *format, ...)
{
va_list ap;
char buf[1024];
int len;
va_start(ap, format);
len = vslprintf(buf, sizeof(buf), format, ap);
va_end(ap);
if (len > sizeof(buf)-1) exit_cleanup(RERR_MESSAGEIO);
rwrite(code, buf, len);
}
void rflush(enum logcode code)
{
FILE *f = NULL;
extern int am_daemon;
@@ -153,15 +176,15 @@ void rflush(int fd)
return;
}
if (fd == FLOG) {
if (code == FLOG) {
return;
}
if (fd == FERROR) {
if (code == FERROR) {
f = stderr;
}
if (fd == FINFO) {
if (code == FINFO) {
extern int am_server;
if (am_server)
f = stderr;
@@ -177,7 +200,7 @@ void rflush(int fd)
/* a generic logging routine for send/recv, with parameter
substitiution */
static void log_formatted(int fd,
static void log_formatted(enum logcode code,
char *format, char *op, struct file_struct *file,
struct stats *initial_stats)
{
@@ -267,7 +290,7 @@ static void log_formatted(int fd,
s = p+l;
}
rprintf(fd,"%s\n", buf);
rprintf(code,"%s\n", buf);
}
/* log the outgoing transfer of a file */

99
main.c
View File

@@ -261,10 +261,6 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
argv[0] = ".";
}
set_nonblocking(f_out);
if (f_in != f_out)
set_nonblocking(f_in);
flist = send_file_list(f_out,argc,argv);
if (!flist || flist->count == 0) {
exit_cleanup(0);
@@ -282,45 +278,78 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
int pid;
int status=0;
int recv_pipe[2];
int error_pipe[2];
extern int preserve_hard_links;
extern int delete_after;
extern int recurse;
extern int delete_mode;
extern int remote_version;
if (preserve_hard_links)
init_hard_links(flist);
if (pipe(recv_pipe) < 0) {
if (!delete_after) {
/* I moved this here from recv_files() to prevent a race condition */
if (recurse && delete_mode && !local_name && flist->count>0) {
delete_files(flist);
}
}
if (fd_pair(recv_pipe) < 0) {
rprintf(FERROR,"pipe failed in do_recv\n");
exit_cleanup(RERR_SOCKETIO);
}
if (fd_pair(error_pipe) < 0) {
rprintf(FERROR,"error pipe failed in do_recv\n");
exit_cleanup(RERR_SOCKETIO);
}
io_flush();
if ((pid=do_fork()) == 0) {
close(recv_pipe[0]);
close(error_pipe[0]);
if (f_in != f_out) close(f_out);
set_nonblocking(f_in);
set_nonblocking(recv_pipe[1]);
/* we can't let two processes write to the socket at one time */
io_multiplexing_close();
/* set place to send errors */
set_error_fd(error_pipe[1]);
recv_files(f_in,flist,local_name,recv_pipe[1]);
report(f_in);
write_int(recv_pipe[1],1);
close(recv_pipe[1]);
io_flush();
_exit(0);
/* finally we go to sleep until our parent kills us with
a USR2 signal */
while (1) sleep(60);
}
close(recv_pipe[1]);
close(error_pipe[1]);
io_close_input(f_in);
if (f_in != f_out) close(f_in);
set_nonblocking(f_out);
set_nonblocking(recv_pipe[0]);
io_start_buffering(f_out);
io_set_error_fd(error_pipe[0]);
generate_files(f_out,flist,local_name,recv_pipe[0]);
read_int(recv_pipe[0]);
close(recv_pipe[0]);
if (remote_version >= 24) {
/* send a final goodbye message */
write_int(f_out, -1);
}
io_flush();
waitpid(pid, &status, 0);
kill(pid, SIGUSR2);
wait_process(pid, &status);
return status;
}
@@ -334,9 +363,18 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
extern int delete_mode;
extern int delete_excluded;
extern int am_daemon;
extern int module_id;
extern int am_sender;
if (verbose > 2)
rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
if (am_daemon && lp_read_only(module_id) && !am_sender) {
rprintf(FERROR,"ERROR: module is read only\n");
exit_cleanup(RERR_SYNTAX);
return;
}
if (argc > 0) {
dir = argv[0];
@@ -375,13 +413,16 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
{
extern int cvs_exclude;
extern int am_sender;
extern int remote_version;
set_nonblocking(f_out);
if (f_in != f_out)
set_nonblocking(f_in);
setup_protocol(f_out, f_in);
set_nonblocking(f_in);
set_nonblocking(f_out);
if (remote_version >= 23)
io_start_multiplex_out(f_out);
if (am_sender) {
recv_exclude_list(f_in);
if (cvs_exclude)
@@ -400,8 +441,15 @@ int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
char *local_name = NULL;
extern int am_sender;
extern int list_only;
extern int remote_version;
set_nonblocking(f_in);
set_nonblocking(f_out);
setup_protocol(f_out,f_in);
if (remote_version >= 23)
io_start_multiplex_in(f_in);
if (am_sender) {
extern int cvs_exclude;
@@ -415,18 +463,18 @@ int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
if (verbose > 3)
rprintf(FINFO,"file list sent\n");
set_nonblocking(f_out);
if (f_in != f_out)
set_nonblocking(f_in);
send_files(flist,f_out,f_in);
if (pid != -1) {
if (verbose > 3)
rprintf(FINFO,"client_run waiting on %d\n",pid);
io_flush();
waitpid(pid, &status, 0);
wait_process(pid, &status);
}
report(-1);
if (remote_version >= 24) {
/* final goodbye message */
read_int(f_in);
}
exit_cleanup(status);
}
@@ -448,7 +496,7 @@ int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
if (verbose > 3)
rprintf(FINFO,"client_run2 waiting on %d\n",pid);
io_flush();
waitpid(pid, &status, 0);
wait_process(pid, &status);
}
return status | status2;
@@ -584,6 +632,10 @@ static RETSIGTYPE sigusr1_handler(int val) {
exit_cleanup(RERR_SIGNAL);
}
static RETSIGTYPE sigusr2_handler(int val) {
_exit(0);
}
int main(int argc,char *argv[])
{
extern int am_root;
@@ -593,6 +645,7 @@ int main(int argc,char *argv[])
extern int am_server;
signal(SIGUSR1, sigusr1_handler);
signal(SIGUSR2, sigusr2_handler);
starttime = time(NULL);
am_root = (getuid() == 0);
@@ -648,6 +701,8 @@ int main(int argc,char *argv[])
#endif
if (am_server) {
set_nonblocking(STDIN_FILENO);
set_nonblocking(STDOUT_FILENO);
start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
}

24
match.c
View File

@@ -97,8 +97,8 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
OFF_T j;
if (verbose > 2 && i >= 0)
rprintf(FINFO,"match at %d last_match=%d j=%d len=%d n=%d\n",
(int)offset,(int)last_match,i,(int)s->sums[i].len,(int)n);
rprintf(FINFO,"match at %.0f last_match=%.0f j=%d len=%d n=%.0f\n",
(double)offset,(double)last_match,i,s->sums[i].len,(double)n);
send_token(f,i,buf,last_match,n,i<0?0:s->sums[i].len);
data_transfer += n;
@@ -119,19 +119,19 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
else
last_match = offset;
if (buf)
if (buf) {
show_progress(last_match, buf->file_size);
if (i == -1) end_progress();
if (i == -1) end_progress(buf->file_size);
}
}
static void hash_search(int f,struct sum_struct *s,
struct map_struct *buf,OFF_T len)
{
OFF_T offset;
OFF_T offset, end;
int j,k, last_i;
int end;
char sum2[SUM_LENGTH];
uint32 s1, s2, sum;
schar *map;
@@ -141,7 +141,7 @@ static void hash_search(int f,struct sum_struct *s,
last_i = -1;
if (verbose > 2)
rprintf(FINFO,"hash search b=%d len=%d\n",s->n,(int)len);
rprintf(FINFO,"hash search b=%d len=%.0f\n",s->n,(double)len);
k = MIN(len, s->n);
@@ -158,8 +158,8 @@ static void hash_search(int f,struct sum_struct *s,
end = len + 1 - s->sums[s->count-1].len;
if (verbose > 3)
rprintf(FINFO,"hash search s->n=%d len=%d count=%d\n",
s->n,(int)len,s->count);
rprintf(FINFO,"hash search s->n=%d len=%.0f count=%d\n",
s->n,(double)len,s->count);
do {
tag t = gettag2(s1,s2);
@@ -167,7 +167,7 @@ static void hash_search(int f,struct sum_struct *s,
j = tag_table[t];
if (verbose > 4)
rprintf(FINFO,"offset=%d sum=%08x\n",(int)offset,sum);
rprintf(FINFO,"offset=%.0f sum=%08x\n",(double)offset,sum);
if (j == NULL_TAG) {
goto null_tag;
@@ -185,8 +185,8 @@ static void hash_search(int f,struct sum_struct *s,
if (l != s->sums[i].len) continue;
if (verbose > 3)
rprintf(FINFO,"potential match at %d target=%d %d sum=%08x\n",
(int)offset,j,i,sum);
rprintf(FINFO,"potential match at %.0f target=%d %d sum=%08x\n",
(double)offset,j,i,sum);
if (!done_csum2) {
map = (schar *)map_ptr(buf,offset,l);

View File

@@ -63,6 +63,9 @@ int copy_unsafe_links=0;
int block_size=BLOCK_SIZE;
int size_only=0;
int delete_after=0;
int only_existing=0;
int max_delete=0;
int ignore_errors=0;
char *backup_suffix = BACKUP_SUFFIX;
char *tmpdir = NULL;
@@ -72,6 +75,7 @@ char *shell_cmd = NULL;
char *log_format = NULL;
char *password_file = NULL;
char *rsync_path = RSYNC_NAME;
char *backup_dir = NULL;
int rsync_port = RSYNC_PORT;
int verbose = 0;
@@ -81,7 +85,7 @@ int list_only = 0;
struct in_addr socket_address = {INADDR_ANY};
void usage(int F)
void usage(enum logcode F)
{
rprintf(F,"rsync version %s Copyright Andrew Tridgell and Paul Mackerras\n\n",
VERSION);
@@ -105,6 +109,7 @@ void usage(int F)
rprintf(F," -r, --recursive recurse into directories\n");
rprintf(F," -R, --relative use relative path names\n");
rprintf(F," -b, --backup make backups (default %s suffix)\n",BACKUP_SUFFIX);
rprintf(F," --backup-dir make backups into this directory\n");
rprintf(F," --suffix=SUFFIX override backup suffix\n");
rprintf(F," -u, --update update only (don't overwrite newer files)\n");
rprintf(F," -l, --links preserve soft links\n");
@@ -125,9 +130,12 @@ void usage(int F)
rprintf(F," -e, --rsh=COMMAND specify rsh replacement\n");
rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
rprintf(F," -C, --cvs-exclude auto ignore files in the same way CVS does\n");
rprintf(F," --existing only update files that already exist\n");
rprintf(F," --delete delete files that don't exist on the sending side\n");
rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
rprintf(F," --delete-after delete after transferring, not before\n");
rprintf(F," --ignore-errors delete even if there are IO errors\n");
rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
rprintf(F," --partial keep partially transferred files\n");
rprintf(F," --force force deletion of directories even if not empty\n");
rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
@@ -165,7 +173,8 @@ enum {OPT_VERSION, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS,
OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST,
OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
OPT_DELETE_AFTER};
OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR,
OPT_IGNORE_ERRORS};
static char *short_options = "oblLWHpguDCtcahvqrRIxnSe:B:T:zP";
@@ -173,6 +182,7 @@ static struct option long_options[] = {
{"version", 0, 0, OPT_VERSION},
{"server", 0, 0, OPT_SERVER},
{"sender", 0, 0, OPT_SENDER},
{"existing", 0, 0, OPT_EXISTING},
{"delete", 0, 0, OPT_DELETE},
{"delete-excluded", 0, 0, OPT_DELETE_EXCLUDED},
{"force", 0, 0, OPT_FORCE},
@@ -221,10 +231,13 @@ static struct option long_options[] = {
{"progress", 0, 0, OPT_PROGRESS},
{"partial", 0, 0, OPT_PARTIAL},
{"delete-after",0, 0, OPT_DELETE_AFTER},
{"ignore-errors",0, 0, OPT_IGNORE_ERRORS},
{"config", 1, 0, OPT_CONFIG},
{"port", 1, 0, OPT_PORT},
{"log-format", 1, 0, OPT_LOG_FORMAT},
{"address", 1, 0, OPT_ADDRESS},
{"max-delete", 1, 0, OPT_MAX_DELETE},
{"backup-dir", 1, 0, OPT_BACKUP_DIR},
{0,0,0,0}};
@@ -320,6 +333,10 @@ int parse_arguments(int argc, char *argv[], int frommain)
delete_mode = 1;
break;
case OPT_EXISTING:
only_existing = 1;
break;
case OPT_DELETE_AFTER:
delete_after = 1;
break;
@@ -447,10 +464,8 @@ int parse_arguments(int argc, char *argv[], int frommain)
preserve_perms=1;
preserve_times=1;
preserve_gid=1;
if (am_root) {
preserve_devices=1;
preserve_uid=1;
}
preserve_uid=1;
preserve_devices=1;
break;
case OPT_SERVER:
@@ -481,6 +496,10 @@ int parse_arguments(int argc, char *argv[], int frommain)
block_size = atoi(optarg);
break;
case OPT_MAX_DELETE:
max_delete = atoi(optarg);
break;
case OPT_TIMEOUT:
io_timeout = atoi(optarg);
break;
@@ -513,6 +532,10 @@ int parse_arguments(int argc, char *argv[], int frommain)
keep_partial = 1;
break;
case OPT_IGNORE_ERRORS:
ignore_errors = 1;
break;
case 'P':
do_progress = 1;
keep_partial = 1;
@@ -539,6 +562,10 @@ int parse_arguments(int argc, char *argv[], int frommain)
}
break;
case OPT_BACKUP_DIR:
backup_dir = optarg;
break;
default:
slprintf(err_buf,sizeof(err_buf),"unrecognised option\n");
return 0;
@@ -548,12 +575,15 @@ int parse_arguments(int argc, char *argv[], int frommain)
}
/* need to pass all the valid options from the client to the server */
void server_options(char **args,int *argc)
{
int ac = *argc;
static char argstr[50];
static char bsize[30];
static char iotime[30];
static char mdelete[30];
int i, x;
args[ac++] = "--server";
@@ -611,12 +641,17 @@ void server_options(char **args,int *argc)
if (x != 1) args[ac++] = argstr;
if (block_size != BLOCK_SIZE) {
sprintf(bsize,"-B%d",block_size);
slprintf(bsize,sizeof(bsize),"-B%d",block_size);
args[ac++] = bsize;
}
if (max_delete && am_sender) {
slprintf(mdelete,sizeof(mdelete),"--max-delete=%d",max_delete);
args[ac++] = mdelete;
}
if (io_timeout) {
sprintf(iotime,"--timeout=%d",io_timeout);
slprintf(iotime,sizeof(iotime),"--timeout=%d",io_timeout);
args[ac++] = iotime;
}
@@ -643,6 +678,9 @@ void server_options(char **args,int *argc)
if (delete_after)
args[ac++] = "--delete-after";
if (ignore_errors)
args[ac++] = "--ignore-errors";
if (copy_unsafe_links)
args[ac++] = "--copy-unsafe-links";
@@ -652,11 +690,22 @@ void server_options(char **args,int *argc)
if (numeric_ids)
args[ac++] = "--numeric-ids";
if (only_existing && am_sender)
args[ac++] = "--existing";
if (tmpdir) {
args[ac++] = "--temp-dir";
args[ac++] = tmpdir;
}
if (backup_dir && am_sender) {
/* only the receiver needs this option, if we are the sender
* then we need to send it to the receiver.
*/
args[ac++] = "--backup-dir";
args[ac++] = backup_dir;
}
if (compare_dest && am_sender) {
/* the server only needs this option if it is not the sender,
* and it may be an older version that doesn't know this

View File

@@ -1,10 +1,10 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: 2.3.2
Version: 2.4.2
Release: 1
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.3.2.tar.gz
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.4.2.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync

View File

@@ -36,14 +36,12 @@ extern char *compare_dest;
extern int make_backups;
extern char *backup_suffix;
static struct delete_list {
dev_t dev;
INO_T inode;
} *delete_list;
static int dlist_len, dlist_alloc_len;
/* yuck! This function wouldn't have been necessary if I had the sorting
algorithm right. Unfortunately fixing the sorting algorithm would introduce
a backward incompatibility as file list indexes are sent over the link.
@@ -104,17 +102,20 @@ static void delete_one(struct file_struct *f)
/* this deletes any files on the receiving side that are not present
on the sending side. For version 1.6.4 I have changed the behaviour
to match more closely what most people seem to expect of this option */
static void delete_files(struct file_list *flist)
void delete_files(struct file_list *flist)
{
struct file_list *local_file_list;
int i, j;
char *name;
extern int module_id;
extern int ignore_errors;
extern int max_delete;
static int deletion_count;
if (cvs_exclude)
add_cvs_excludes();
if (io_error && !lp_ignore_errors(module_id)) {
if (io_error && !(lp_ignore_errors(module_id) || ignore_errors)) {
rprintf(FINFO,"IO error encountered - skipping file deletion\n");
return;
}
@@ -137,6 +138,7 @@ static void delete_files(struct file_list *flist)
rprintf(FINFO,"deleting in %s\n", name);
for (i=local_file_list->count-1;i>=0;i--) {
if (max_delete && deletion_count > max_delete) break;
if (!local_file_list->files[i]->basename) continue;
if (remote_version < 19 &&
S_ISDIR(local_file_list->files[i]->mode))
@@ -144,10 +146,12 @@ static void delete_files(struct file_list *flist)
if (-1 == flist_find(flist,local_file_list->files[i])) {
char *f = f_name(local_file_list->files[i]);
int k = strlen(f) - strlen(backup_suffix);
/* Hi Andrew, do we really need to play with backup_suffix here? */
if (make_backups && ((k <= 0) ||
(strcmp(f+k,backup_suffix) != 0))) {
(void) make_backup(f);
} else {
deletion_count++;
delete_one(local_file_list->files[i]);
}
}
@@ -222,8 +226,8 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
extern int cleanup_got_literal;
if (verbose > 3) {
rprintf(FINFO,"data recv %d at %d\n",
i,(int)offset);
rprintf(FINFO,"data recv %d at %.0f\n",
i,(double)offset);
}
stats.literal_data += i;
@@ -240,7 +244,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
}
i = -(i+1);
offset2 = i*n;
offset2 = i*(OFF_T)n;
len = n;
if (i == count-1 && remainder != 0)
len = remainder;
@@ -248,13 +252,15 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
stats.matched_data += len;
if (verbose > 3)
rprintf(FINFO,"chunk[%d] of size %d at %d offset=%d\n",
i,len,(int)offset2,(int)offset);
rprintf(FINFO,"chunk[%d] of size %d at %.0f offset=%.0f\n",
i,len,(double)offset2,(double)offset);
map = map_ptr(buf,offset2,len);
if (buf) {
map = map_ptr(buf,offset2,len);
see_token(map, len);
sum_update(map,len);
see_token(map, len);
sum_update(map,len);
}
if (fd != -1 && write_file(fd,map,len) != len) {
rprintf(FERROR,"write failed on %s : %s\n",
@@ -264,7 +270,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
offset += len;
}
end_progress();
end_progress(total_size);
if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
rprintf(FERROR,"write failed on %s : %s\n",
@@ -288,6 +294,8 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
}
/* main routine for receiver process. Receiver process runs on the
same host as the generator process. */
int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
{
@@ -311,12 +319,6 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
rprintf(FINFO,"recv_files(%d) starting\n",flist->count);
}
if (!delete_after) {
if (recurse && delete_mode && !local_name && flist->count>0) {
delete_files(flist);
}
}
while (1) {
cleanup_disable();
@@ -397,7 +399,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
if (fd1 != -1 && st.st_size > 0) {
buf = map_file(fd1,st.st_size);
if (verbose > 2)
rprintf(FINFO,"recv mapped %s of size %d\n",fnamecmp,(int)st.st_size);
rprintf(FINFO,"recv mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
} else {
buf = NULL;
}
@@ -468,7 +470,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
finish_transfer(fname, fnametmp, file);
cleanup_disable();
if (!recv_ok) {
if (csum_length == SUM_LENGTH) {
rprintf(FERROR,"ERROR: file corruption in %s. File changed during transfer?\n",

15
rsync.c
View File

@@ -56,8 +56,6 @@ int delete_file(char *fname)
int ret;
extern int recurse;
if (robust_unlink(fname) == 0 || errno == ENOENT) return 0;
#if SUPPORT_LINKS
ret = do_lstat(fname, &st);
#else
@@ -69,6 +67,7 @@ int delete_file(char *fname)
}
if (!S_ISDIR(st.st_mode)) {
if (robust_unlink(fname) == 0 || errno == ENOENT) return 0;
rprintf(FERROR,"unlink(%s) : %s\n", fname, strerror(errno));
return -1;
}
@@ -152,7 +151,6 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
int updated = 0;
STRUCT_STAT st2;
int change_uid, change_gid;
extern int am_daemon;
if (dry_run) return 0;
@@ -179,7 +177,7 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
}
change_uid = am_root && preserve_uid && st->st_uid != file->uid;
change_gid = !am_daemon && preserve_gid && file->gid != (gid_t) -1 && \
change_gid = preserve_gid && file->gid != (gid_t) -1 && \
st->st_gid != file->gid;
if (change_gid && !am_root) {
/* enforce bsd-style group semantics: non-root can only
@@ -195,6 +193,12 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
rprintf(FERROR,"chown %s : %s\n", fname,strerror(errno));
return 0;
}
/* a lchown had been done - we have to re-stat if the
destination had the setuid or setgid bits set due
to the side effect of the chown call */
if (st->st_mode & (S_ISUID | S_ISGID)) {
link_stat(fname, st);
}
updated = 1;
}
@@ -254,6 +258,3 @@ void finish_transfer(char *fname, char *fnametmp, struct file_struct *file)
set_perms(fname,file,NULL,0);
}
}

21
rsync.h
View File

@@ -47,8 +47,8 @@
#define SAME_TIME (1<<7)
/* update this if you make incompatible changes */
#define PROTOCOL_VERSION 21
#define MIN_PROTOCOL_VERSION 11
#define PROTOCOL_VERSION 24
#define MIN_PROTOCOL_VERSION 15
#define MAX_PROTOCOL_VERSION 30
#define RSYNC_PORT 873
@@ -58,14 +58,12 @@
#define CHUNK_SIZE (32*1024)
#define MAX_MAP_SIZE (256*1024)
#define IO_BUFFER_SIZE (4092)
#define MAX_READ_BUFFER (1024*1024)
#define MAX_ARGS 1000
#define MPLEX_BASE 7
#define FERROR 1
#define FINFO 2
#define FLOG 3
enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3};
#include "errcode.h"
@@ -459,6 +457,15 @@ extern int errno;
#define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG))
#endif
/* work out what fcntl flag to use for non-blocking */
#ifdef O_NONBLOCK
# define NONBLOCK_FLAG O_NONBLOCK
#elif defined(SYSV)
# define NONBLOCK_FLAG O_NDELAY
#else
# define NONBLOCK_FLAG FNDELAY
#endif
#define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode) || S_ISFIFO(mode))
@@ -474,7 +481,7 @@ extern int errno;
#define NS(s) ((s)?(s):"<NULL>")
/* use magic gcc attributes to catch format errors */
void rprintf(int , const char *, ...)
void rprintf(enum logcode , const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif

View File

@@ -216,17 +216,6 @@ Here is a short summary of the options available in rsync. Please refer
to the detailed description below for a complete description.
verb(
Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST
or rsync [OPTION]... [USER@]HOST:SRC DEST
or rsync [OPTION]... SRC [SRC]... DEST
or rsync [OPTION]... [USER@]HOST::SRC [DEST]
or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
SRC on single-colon remote HOST will be expanded by remote shell
SRC on server remote HOST may contain shell wildcards or multiple
sources separated by space as long as they have same top-level
Options
-v, --verbose increase verbosity
-q, --quiet decrease verbosity
-c, --checksum always checksum
@@ -234,6 +223,7 @@ Options
-r, --recursive recurse into directories
-R, --relative use relative path names
-b, --backup make backups (default ~ suffix)
--backup-dir=DIR put backups in the specified directory
--suffix=SUFFIX override backup suffix
-u, --update update only (don't overwrite newer files)
-l, --links preserve soft links
@@ -254,8 +244,12 @@ Options
-e, --rsh=COMMAND specify rsh replacement
--rsync-path=PATH specify path to rsync on the remote machine
-C, --cvs-exclude auto ignore files in the same way CVS does
--existing only update files that already exist
--delete delete files that don't exist on the sending side
--delete-excluded also delete excluded files on the receiving side
--delete-after delete after transferring, not before
--ignore-errors delete even if there are IO errors
--max-delete=NUM don't delete more than NUM files
--partial keep partially transferred files
--force force deletion of directories even if not empty
--numeric-ids don't map uid/gid values by user/group name
@@ -313,7 +307,7 @@ dit(bf(-I, --ignore-times)) Normally rsync will skip any files that are
already the same length and have the same time-stamp. This option turns
off this behavior.
dit(bf(-I, --size-only)) Normally rsync will skip any files that are
dit(bf(--size-only)) Normally rsync will skip any files that are
already the same length and have the same time-stamp. With the
--size-only option files will be skipped if they have the same size,
regardless of timestamp. This is useful when starting to use rsync
@@ -326,12 +320,9 @@ explicitly checked on the receiver and any files of the same name
which already exist and have the same checksum and size on the
receiver are skipped. This option can be quite slow.
dit(bf(-a, --archive)) This is equivalent to -rlptg. It is a quick way
dit(bf(-a, --archive)) This is equivalent to -rlptgoD. It is a quick way
of saying you want recursion and want to preserve everything.
Note: if the user launching rsync is root then the -o (preserve
uid) and -D (preserve devices) options are also implied.
dit(bf(-r, --recursive)) This tells rsync to copy directories
recursively. If you don't specify this then rsync won't copy
directories at all.
@@ -356,6 +347,10 @@ dit(bf(-b, --backup)) With this option preexisting destination files are
renamed with a ~ extension as each file is transferred. You can
control the backup suffix using the --suffix option.
dit(bf(--backup-dir=DIR)) In combination with the --backup option, this
tells rsync to store all backups in the specified directory. This is
very useful for incremental backups.
dit(bf(--suffix=SUFFIX)) This option allows you to override the default
backup suffix used with the -b option. The default is a ~.
@@ -433,6 +428,13 @@ dit(bf(-x, --one-file-system)) This tells rsync not to cross filesystem
boundaries when recursing. This is useful for transferring the
contents of only one filesystem.
dit(bf(--existing)) This tells rsync not to create any new files -
only update files that already exist on the destination.
dit(bf(--max-delete=NUM)) This tells rsync not to delete more than NUM
files or directories. This is useful when mirroring very large trees
to prevent disasters.
dit(bf(--delete)) This tells rsync to delete any files on the receiving
side that aren't on the sending side. Files that are excluded from
transfer are excluded from being deleted unless you use --delete-excluded.
@@ -596,10 +598,10 @@ respond to requests accordingly. See the rsyncd.conf(5) man page for more
details.
dit(bf(--address)) By default rsync will bind to the wildcard address
when run as a daemon with the --daemon option. The --address option
allows you to specify a specific IP address (or hostname) to bind
to. This makes virtual hosting possible in conjunction with the
--config option.
when run as a daemon with the --daemon option or when connecting to a
rsync server. The --address option allows you to specify a specific IP
address (or hostname) to bind to. This makes virtual hosting possible
in conjunction with the --config option.
dit(bf(--config=FILE)) This specifies an alternate config file than
the default /etc/rsyncd.conf. This is only relevant when --daemon is
@@ -638,7 +640,8 @@ dit(bf(--password-file)) This option allows you to provide a password
in a file for accessing a remote rsync server. Note that this option
is only useful when accessing a rsync server using the built in
transport, not when using a remote shell as the transport. The file
must not be world readable.
must not be world readable. It should contain just the password as a
single line.
enddit()
@@ -697,7 +700,7 @@ itemize(
The +/- rules are most useful in exclude lists, allowing you to have a
single exclude list that contains both include and exclude options.
Here are some examples:
Here are some exclude/include examples:
itemize(
it() --exclude "*.o" would exclude all filenames matching *.o

View File

@@ -128,8 +128,11 @@ dit(bf(use chroot)) If "use chroot" is true, the rsync server will chroot
to the "path" before starting the file transfer with the client. This has
the advantage of extra protection against possible implementation security
holes, but it has the disadvantages of requiring super-user privileges and
of not being able to follow symbolic links outside of the new root path.
The default is to use chroot.
of not being able to follow symbolic links outside of the new root path
when reading. For writing when "use chroot" is false, for security reasons
symlinks may only be relative paths pointing to other files within the
root path, and leading slashes are removed from absolute paths. The
default for "use chroot" is true.
dit(bf(max connections)) The "max connections" option allows you to
specify the maximum number of simultaneous connections you will allow

View File

@@ -70,8 +70,8 @@ static struct sum_struct *receive_sums(int f)
offset += s->sums[i].len;
if (verbose > 3)
rprintf(FINFO,"chunk[%d] len=%d offset=%d sum1=%08x\n",
i,s->sums[i].len,(int)s->sums[i].offset,s->sums[i].sum1);
rprintf(FINFO,"chunk[%d] len=%d offset=%.0f sum1=%08x\n",
i,s->sums[i].len,(double)s->sums[i].offset,s->sums[i].sum1);
}
s->flength = offset;
@@ -185,8 +185,8 @@ void send_files(struct file_list *flist,int f_out,int f_in)
}
if (verbose > 2)
rprintf(FINFO,"send_files mapped %s of size %d\n",
fname,(int)st.st_size);
rprintf(FINFO,"send_files mapped %s of size %.0f\n",
fname,(double)st.st_size);
write_int(f_out,i);

View File

@@ -89,10 +89,11 @@ static int establish_proxy_connection(int fd, char *host, int port)
/* open a socket to a tcp remote host with the specified port
based on code from Warren
proxy support by Stephen Rothwell */
int open_socket_out(char *host, int port)
int open_socket_out(char *host, int port, struct in_addr *address)
{
int type = SOCK_STREAM;
struct sockaddr_in sock_out;
struct sockaddr_in sock;
int res;
struct hostent *hp;
char *h;
@@ -137,6 +138,13 @@ int open_socket_out(char *host, int port)
sock_out.sin_port = htons(p);
sock_out.sin_family = PF_INET;
if (address) {
sock.sin_addr = *address;
sock.sin_port = 0;
sock.sin_family = hp->h_addrtype;
bind(res, (struct sockaddr * ) &sock,sizeof(sock));
}
if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
rprintf(FERROR,"failed to connect to %s - %s\n", h, strerror(errno));
close(res);
@@ -148,8 +156,6 @@ int open_socket_out(char *host, int port)
return -1;
}
set_nonblocking(res);
return res;
}
@@ -266,8 +272,6 @@ void start_accept_loop(int port, int (*fn)(int ))
if (fork()==0) {
close(s);
set_nonblocking(fd);
_exit(fn(fd));
}

View File

@@ -84,6 +84,9 @@ int do_open(char *pathname, int flags, mode_t mode)
/* for Windows */
flags |= O_BINARY;
#endif
/* some systems can't handle a double / */
if (pathname[0] == '/' && pathname[1] == '/') pathname++;
return open(pathname, flags, mode);
}

31
test.sh
View File

@@ -24,7 +24,9 @@ not for end users. You may experience failures on some platforms that
do not indicate a problem with rsync.
EOF
export PATH=.:$PATH
RSYNC=`pwd`/rsync
runtest() {
echo -n "Test $1: "
eval "$2"
@@ -67,8 +69,11 @@ checkit() {
failed=
echo "Running: \"$1\"" >${log}
echo "">>${log}
eval "$1 || failed=YES" >>${log} 2>&1
eval "$1" >>${log} 2>&1
status=$?
if [ $status != 0 ]; then
failed="YES";
fi
echo "-------------">>${log}
echo "check how the files compare with diff:">>${log}
echo "">>${log}
@@ -88,7 +93,7 @@ checkit() {
cat ${log}
rm ${log}
else
echo " FAILED (test # ${testnum})."
echo " FAILED (test # ${testnum} status=$status)."
fi
return 1
fi
@@ -120,33 +125,33 @@ EOF
# Main script starts here
runtest "basic operation" 'checkit "rsync -av ${FROM}/ ${TO}" ${FROM}/ ${TO}'
runtest "basic operation" 'checkit "$RSYNC -av ${FROM}/ ${TO}" ${FROM}/ ${TO}'
ln ${FROM}/pslist ${FROM}/dir
runtest "hard links" 'checkit "rsync -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
runtest "hard links" 'checkit "$RSYNC -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
rm ${TO}/${F1}
runtest "one file" 'checkit "rsync -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
runtest "one file" 'checkit "$RSYNC -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
echo "extra line" >> ${TO}/${F1}
runtest "extra data" 'checkit "rsync -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
runtest "extra data" 'checkit "$RSYNC -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
cp ${FROM}/${F1} ${TO}/ThisShouldGo
runtest " --delete" 'checkit "rsync --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
runtest " --delete" 'checkit "$RSYNC --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
LONGDIR=${FROM}/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job
mkdir -p ${LONGDIR}
date > ${LONGDIR}/1
ls -la / > ${LONGDIR}/2
runtest "long paths" 'checkit "rsync --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
runtest "long paths" 'checkit "$RSYNC --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
if type ssh >/dev/null 2>&1; then
if [ "`ssh -o'BatchMode yes' localhost echo yes 2>/dev/null`" = "yes" ]; then
rm -rf ${TO}
runtest "ssh: basic test" 'checkit "rsync -avH -e ssh ${FROM}/ localhost:${TO}" ${FROM}/ ${TO}'
runtest "ssh: basic test" 'checkit "$RSYNC -avH -e ssh --rsync-path=$RSYNC ${FROM}/ localhost:${TO}" ${FROM}/ ${TO}'
mv ${TO}/${F1} ${TO}/ThisShouldGo
runtest "ssh: renamed file" 'checkit "rsync --delete -avH -e ssh ${FROM}/ localhost:${TO}" ${FROM}/ ${TO}'
runtest "ssh: renamed file" 'checkit "$RSYNC --delete -avH -e ssh --rsync-path=$RSYNC ${FROM}/ localhost:${TO}" ${FROM}/ ${TO}'
else
printmsg "Skipping SSH tests because ssh conection to localhost not authorised"
fi
@@ -158,7 +163,7 @@ rm -rf ${TO}
mkdir -p ${FROM}2/dir/subdir
cp -a ${FROM}/dir/subdir/subsubdir ${FROM}2/dir/subdir
cp ${FROM}/dir/* ${FROM}2/dir 2>/dev/null
runtest "excludes" 'checkit "rsync -vv -Hlrt --delete --include /dir/ --include /dir/\* --include /dir/\*/subsubdir --include /dir/\*/subsubdir/\*\* --exclude \*\* ${FROM}/dir ${TO}" ${FROM}2/ ${TO}'
runtest "excludes" 'checkit "$RSYNC -vv -Hlrt --delete --include /dir/ --include /dir/\* --include /dir/\*/subsubdir --include /dir/\*/subsubdir/\*\* --exclude \*\* ${FROM}/dir ${TO}" ${FROM}2/ ${TO}'
rm -r ${FROM}2
checkforlogs ${LOG}.?

85
util.c
View File

@@ -26,30 +26,47 @@
extern int verbose;
/****************************************************************************
Set a fd into nonblocking mode. Uses POSIX O_NONBLOCK if available,
else
if SYSV use O_NDELAY
if BSD use FNDELAY
****************************************************************************/
int set_nonblocking(int fd)
void set_nonblocking(int fd)
{
int val;
#ifdef O_NONBLOCK
#define FLAG_TO_SET O_NONBLOCK
#else
#ifdef SYSV
#define FLAG_TO_SET O_NDELAY
#else /* BSD */
#define FLAG_TO_SET FNDELAY
#endif
#endif
if((val = fcntl(fd, F_GETFL, 0)) == -1)
return -1;
val |= FLAG_TO_SET;
return fcntl( fd, F_SETFL, val);
#undef FLAG_TO_SET
return;
if (!(val & NONBLOCK_FLAG)) {
val |= NONBLOCK_FLAG;
fcntl(fd, F_SETFL, val);
}
}
/* create a file descriptor pair - like pipe() but use socketpair if
possible (because of blocking issues on pipes)
always set non-blocking
*/
int fd_pair(int fd[2])
{
int ret;
#if HAVE_SOCKETPAIR
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
#else
ret = pipe(fd);
#endif
if (ret == 0) {
set_nonblocking(fd[0]);
set_nonblocking(fd[1]);
}
return ret;
}
@@ -60,8 +77,8 @@ int piped_child(char **command,int *f_in,int *f_out)
int to_child_pipe[2];
int from_child_pipe[2];
if (pipe(to_child_pipe) < 0 ||
pipe(from_child_pipe) < 0) {
if (fd_pair(to_child_pipe) < 0 ||
fd_pair(from_child_pipe) < 0) {
rprintf(FERROR,"pipe: %s\n",strerror(errno));
exit_cleanup(RERR_IPC);
}
@@ -101,9 +118,6 @@ int piped_child(char **command,int *f_in,int *f_out)
*f_in = from_child_pipe[0];
*f_out = to_child_pipe[1];
set_nonblocking(*f_in);
set_nonblocking(*f_out);
return pid;
}
@@ -113,8 +127,8 @@ int local_child(int argc, char **argv,int *f_in,int *f_out)
int to_child_pipe[2];
int from_child_pipe[2];
if (pipe(to_child_pipe) < 0 ||
pipe(from_child_pipe) < 0) {
if (fd_pair(to_child_pipe) < 0 ||
fd_pair(from_child_pipe) < 0) {
rprintf(FERROR,"pipe: %s\n",strerror(errno));
exit_cleanup(RERR_IPC);
}
@@ -397,17 +411,6 @@ int robust_rename(char *from, char *to)
return -1;
return do_rename(from, to);
#endif
}
/* sleep for a while via select */
void u_sleep(int usec)
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = usec;
select(0, NULL, NULL, NULL, &tv);
}
@@ -808,12 +811,12 @@ int u_strcmp(const char *cs1, const char *cs2)
static OFF_T last_ofs;
void end_progress(void)
void end_progress(OFF_T size)
{
extern int do_progress, am_server;
if (do_progress && !am_server) {
rprintf(FINFO,"\n");
rprintf(FINFO,"%.0f (100%%)\n", (double)size);
}
last_ofs = 0;
}
@@ -900,3 +903,15 @@ char *timestring(time_t t)
return(TimeBuf);
}
/****************************************************************************
like waitpid but does the WEXITSTATUS
****************************************************************************/
#ifndef WEXITSTATUS
#define WEXITSTATUS(stat) ((int)(((stat)>>8)&0xFF))
#endif
void wait_process(pid_t pid, int *status)
{
waitpid(pid, status, 0);
*status = WEXITSTATUS(*status);
}

View File

@@ -1 +1 @@
#define VERSION "2.3.2"
#define VERSION "2.4.2"