mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-24 23:05:52 -04:00
Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7eb6bf0397 | ||
|
|
49d6fdc036 | ||
|
|
8b35435f7c | ||
|
|
8ada751890 | ||
|
|
1a52e84874 | ||
|
|
53c5cbed23 | ||
|
|
4a81463880 | ||
|
|
09b7f5dbb1 | ||
|
|
6d7b6081ac | ||
|
|
31b7d79afe | ||
|
|
b2999e457f | ||
|
|
0f3203c312 | ||
|
|
a2edb26cd6 | ||
|
|
9bec528606 | ||
|
|
2f0e3b30a9 | ||
|
|
ff41a59f58 | ||
|
|
08f15335b5 | ||
|
|
bd36966bed | ||
|
|
f76933b149 | ||
|
|
378a074c82 | ||
|
|
c36cd31713 | ||
|
|
5e12ce1186 | ||
|
|
166aa72332 | ||
|
|
f9f6184f38 | ||
|
|
f625af9400 | ||
|
|
fc7952e7f3 | ||
|
|
cbce490e13 | ||
|
|
74a7f81d57 | ||
|
|
5b5591d8a8 | ||
|
|
c55f70218c | ||
|
|
6957ae33a9 | ||
|
|
8a5d6bba09 | ||
|
|
1d2c275fff | ||
|
|
d0fd26aa16 | ||
|
|
e20c5e9521 | ||
|
|
66203a982b | ||
|
|
b315601ce0 | ||
|
|
5f808dfbd7 | ||
|
|
0b73ca12fa | ||
|
|
03e2d0e329 | ||
|
|
182517e692 | ||
|
|
554e0a8dd0 | ||
|
|
b0f3f5784c | ||
|
|
3060d4aa1d | ||
|
|
1347d5126a | ||
|
|
5d1e1dcf4b | ||
|
|
74f5442401 | ||
|
|
c08bb0fb73 | ||
|
|
e30f065766 | ||
|
|
9dce9b45b3 | ||
|
|
60be6acf46 | ||
|
|
a5827a28d2 | ||
|
|
dcc875e41e | ||
|
|
128cf58433 | ||
|
|
7e0ca8e2f0 | ||
|
|
d79d1c69f7 | ||
|
|
a7d068abff | ||
|
|
7f931a0002 | ||
|
|
07b7c86c06 | ||
|
|
1f5c6343e6 |
@@ -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
|
||||
|
||||
@@ -10,3 +10,4 @@
|
||||
#undef HAVE_SHORT_INO_T
|
||||
#undef HAVE_GETOPT_LONG
|
||||
#undef REPLACE_INET_NTOA
|
||||
#undef HAVE_GETTIMEOFDAY_TZ
|
||||
|
||||
@@ -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
244
backup.c
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
@@ -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
286
config.guess
vendored
@@ -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.
|
||||
|
||||
13
configure.in
13
configure.in
@@ -53,7 +53,7 @@ AC_FUNC_UTIME_NULL
|
||||
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod)
|
||||
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_CHECK_FUNCS(strlcat strlcpy inet_aton socketpair)
|
||||
|
||||
AC_CACHE_CHECK([for working fnmatch],rsync_cv_HAVE_FNMATCH,[
|
||||
AC_TRY_RUN([#include <fnmatch.h>
|
||||
@@ -135,6 +135,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>
|
||||
|
||||
71
exclude.c
71
exclude.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
26
flist.c
26
flist.c
@@ -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;
|
||||
@@ -922,7 +928,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 +1005,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
27
generator.c
27
generator.c
@@ -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));
|
||||
|
||||
|
||||
241
io.c
241
io.c
@@ -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) {
|
||||
@@ -112,14 +159,6 @@ static int read_timeout(int fd, char *buf, int len)
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
if (eof_error) {
|
||||
@@ -128,6 +167,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 +195,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 +210,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 +234,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 +242,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 +249,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 +324,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,55 +331,50 @@ 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?n:1);
|
||||
|
||||
if (ret == -1 && errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret == -1 &&
|
||||
(errno == EAGAIN || errno == EWOULDBLOCK)) {
|
||||
blocked++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret <= 0) {
|
||||
rprintf(FERROR,"erroring writing %d bytes - exiting\n", len);
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
|
||||
blocked = 0;
|
||||
total += ret;
|
||||
|
||||
if (io_timeout)
|
||||
@@ -408,22 +393,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 +440,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 +449,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 +567,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;
|
||||
}
|
||||
|
||||
|
||||
23
lib/compat.c
23
lib/compat.c
@@ -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
|
||||
}
|
||||
|
||||
434
lib/fnmatch.c
434
lib/fnmatch.c
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
79
log.c
@@ -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 */
|
||||
|
||||
91
main.c
91
main.c
@@ -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,13 @@ 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);
|
||||
|
||||
if (remote_version >= 23)
|
||||
io_start_multiplex_out(f_out);
|
||||
|
||||
if (am_sender) {
|
||||
recv_exclude_list(f_in);
|
||||
if (cvs_exclude)
|
||||
@@ -400,8 +438,12 @@ 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;
|
||||
|
||||
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 +457,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 +490,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 +626,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 +639,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);
|
||||
|
||||
24
match.c
24
match.c
@@ -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);
|
||||
|
||||
54
options.c
54
options.c
@@ -63,6 +63,8 @@ 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;
|
||||
|
||||
char *backup_suffix = BACKUP_SUFFIX;
|
||||
char *tmpdir = NULL;
|
||||
@@ -72,6 +74,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 +84,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 +108,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 +129,11 @@ 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," --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 +171,7 @@ 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};
|
||||
|
||||
static char *short_options = "oblLWHpguDCtcahvqrRIxnSe:B:T:zP";
|
||||
|
||||
@@ -173,6 +179,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},
|
||||
@@ -225,6 +232,8 @@ static struct option long_options[] = {
|
||||
{"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 +329,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 +460,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 +492,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;
|
||||
@@ -539,6 +554,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 +567,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 +633,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;
|
||||
}
|
||||
|
||||
@@ -652,11 +679,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
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.3.2
|
||||
Version: 2.4.1
|
||||
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.1.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
41
receiver.c
41
receiver.c
@@ -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,12 +102,14 @@ 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 max_delete;
|
||||
static int deletion_count;
|
||||
|
||||
if (cvs_exclude)
|
||||
add_cvs_excludes();
|
||||
@@ -137,6 +137,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 +145,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 +225,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 +243,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 +251,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 +269,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 +293,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 +318,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 +398,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 +469,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
15
rsync.c
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
12
rsync.h
12
rsync.h
@@ -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"
|
||||
|
||||
@@ -474,7 +472,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
|
||||
|
||||
44
rsync.yo
44
rsync.yo
@@ -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,11 @@ 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
|
||||
--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 +306,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 +319,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 +346,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 +427,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 +597,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 +639,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()
|
||||
|
||||
|
||||
8
sender.c
8
sender.c
@@ -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);
|
||||
|
||||
|
||||
14
socket.c
14
socket.c
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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
31
test.sh
@@ -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}.?
|
||||
|
||||
65
util.c
65
util.c
@@ -26,30 +26,15 @@
|
||||
|
||||
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)
|
||||
/* create a file descriptor - like pipe() but use socketpair if
|
||||
possible (because of blocking issues on pipes */
|
||||
int fd_pair(int fd[2])
|
||||
{
|
||||
int val;
|
||||
#ifdef O_NONBLOCK
|
||||
#define FLAG_TO_SET O_NONBLOCK
|
||||
#if HAVE_SOCKETPAIR
|
||||
return socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
|
||||
#else
|
||||
#ifdef SYSV
|
||||
#define FLAG_TO_SET O_NDELAY
|
||||
#else /* BSD */
|
||||
#define FLAG_TO_SET FNDELAY
|
||||
return pipe(fd);
|
||||
#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
|
||||
}
|
||||
|
||||
|
||||
@@ -60,8 +45,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 +86,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 +95,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 +379,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 +779,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 +871,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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user