mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-25 07:15:35 -04:00
Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86a2dd0a0a | ||
|
|
63f0774f75 | ||
|
|
d47741cac6 | ||
|
|
5d5811f7d9 | ||
|
|
dcc3a131d1 | ||
|
|
7212be9237 | ||
|
|
44e2e57837 | ||
|
|
d1be231290 | ||
|
|
a926daecbf | ||
|
|
53dd3135f1 | ||
|
|
cd64343a7a | ||
|
|
9e3c856a39 | ||
|
|
1e8ae5ede6 | ||
|
|
83fff1aa60 | ||
|
|
055af77666 | ||
|
|
cd8185f2bd | ||
|
|
6bd98f0617 | ||
|
|
14d43f1fcf | ||
|
|
3a64ad1fd0 | ||
|
|
5557c8e3e0 | ||
|
|
baf3e5049e | ||
|
|
b389939f87 | ||
|
|
af77cc6b57 | ||
|
|
1309d90dde | ||
|
|
a9766ef147 | ||
|
|
5a788adec1 | ||
|
|
50abd20bb3 | ||
|
|
37f9805dab | ||
|
|
b5f9e67d57 | ||
|
|
ed06894a01 | ||
|
|
d532c0f569 | ||
|
|
ec9df38086 | ||
|
|
81791cfccb | ||
|
|
2fb27e9146 | ||
|
|
946347b8ff |
125
README
125
README
@@ -20,53 +20,69 @@ USAGE
|
||||
|
||||
Basically you use rsync just like rcp, but rsync has many additional options.
|
||||
|
||||
Here is a brief description of available options:
|
||||
Here is a brief description of rsync usage:
|
||||
|
||||
Options:
|
||||
-v, --verbose increase verbosity
|
||||
-c, --checksum always checksum
|
||||
-a, --archive archive mode (same as -rlptDog)
|
||||
-r, --recursive recurse into directories
|
||||
-R, --relative use relative path names
|
||||
-b, --backup make backups (default ~ extension)
|
||||
-u, --update update only (don't overwrite newer files)
|
||||
-l, --links preserve soft links
|
||||
-L, --copy-links treat soft links like regular files
|
||||
-H, --hard-links preserve hard links
|
||||
-p, --perms preserve permissions
|
||||
-o, --owner preserve owner (root only)
|
||||
-g, --group preserve group
|
||||
-D, --devices preserve devices (root only)
|
||||
-t, --times preserve times
|
||||
-S, --sparse handle sparse files efficiently
|
||||
-n, --dry-run show what would have been transferred
|
||||
-W, --whole-file copy whole files, no incremental checks
|
||||
-x, --one-file-system don't cross filesystem boundaries
|
||||
-B, --block-size SIZE checksum blocking size
|
||||
-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
|
||||
--delete delete files that don't exist on the sending side
|
||||
--force force deletion of directories even if not empty
|
||||
--numeric-ids don't map uid/gid values by user/group name
|
||||
--timeout TIME set IO timeout in seconds
|
||||
-I, --ignore-times don't exclude files that match length and time
|
||||
-T --temp-dir DIR create temporary files in directory DIR
|
||||
-z, --compress compress file data
|
||||
--exclude FILE exclude file FILE
|
||||
--exclude-from FILE exclude files listed in FILE
|
||||
--suffix SUFFIX override backup suffix
|
||||
--version print version number
|
||||
--daemon run as a rsync daemon
|
||||
--config FILE specify alternate rsyncd.conf file
|
||||
--port PORT specify alternate rsyncd port number
|
||||
Usage: rsync [OPTION]... SRC [USER@]HOST:DEST
|
||||
or rsync [OPTION]... [USER@]HOST:SRC DEST
|
||||
or rsync [OPTION]... SRC DEST
|
||||
or rsync [OPTION]... [USER@]HOST::SRC [DEST]
|
||||
or rsync [OPTION]... SRC [USER@]HOST::DEST
|
||||
or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
|
||||
|
||||
Options
|
||||
-v, --verbose increase verbosity
|
||||
-c, --checksum always checksum
|
||||
-a, --archive archive mode
|
||||
-r, --recursive recurse into directories
|
||||
-R, --relative use relative path names
|
||||
-b, --backup make backups (default ~ extension)
|
||||
-u, --update update only (don't overwrite newer files)
|
||||
-l, --links preserve soft links
|
||||
-L, --copy-links treat soft links like regular files
|
||||
--safe-links ignore links outside the destination tree
|
||||
-H, --hard-links preserve hard links
|
||||
-p, --perms preserve permissions
|
||||
-o, --owner preserve owner (root only)
|
||||
-g, --group preserve group
|
||||
-D, --devices preserve devices (root only)
|
||||
-t, --times preserve times
|
||||
-S, --sparse handle sparse files efficiently
|
||||
-n, --dry-run show what would have been transferred
|
||||
-W, --whole-file copy whole files, no incremental checks
|
||||
-x, --one-file-system don't cross filesystem boundaries
|
||||
-B, --block-size=SIZE checksum blocking size
|
||||
-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
|
||||
--delete delete files that don't exist on the sending side
|
||||
--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
|
||||
--timeout=TIME set IO timeout in seconds
|
||||
-I, --ignore-times don't exclude files that match length and time
|
||||
-T --temp-dir=DIR create temporary files in directory DIR
|
||||
--compare-dest=DIR also compare destination files relative to DIR
|
||||
-z, --compress compress file data
|
||||
--exclude=PATTERN exclude files matching PATTERN
|
||||
--exclude-from=FILE exclude patterns listed in FILE
|
||||
--include=PATTERN don't exclude files matching PATTERN
|
||||
--include-from=FILE don't exclude patterns listed in FILE
|
||||
--suffix=SUFFIX override backup suffix
|
||||
--version print version number
|
||||
--daemon run as a rsync daemon
|
||||
--config=FILE specify alternate rsyncd.conf file
|
||||
--port=PORT specify alternate rsyncd port number
|
||||
--stats give some file transfer stats
|
||||
--progress show progress during transfer
|
||||
--log-format=FORMAT log file transfers using specified format
|
||||
-h, --help show this help screen
|
||||
|
||||
|
||||
SETUP
|
||||
-----
|
||||
|
||||
Rsync uses rsh or ssh for communication. It does not need to be setuid
|
||||
and requires no special privilages for installation. It does not
|
||||
and requires no special privileges for installation. It does not
|
||||
require a inetd entry or a daemon. You must, however, have a working
|
||||
rsh or ssh system. Using ssh is recommended for its security
|
||||
features.
|
||||
@@ -88,7 +104,7 @@ RSYNC SERVERS
|
||||
-------------
|
||||
|
||||
rsync can also talk to "rsync servers" which can provide anonymous or
|
||||
authenticated rsync. See the rsync.conf(5) man page for details on how
|
||||
authenticated rsync. See the rsyncd.conf(5) man page for details on how
|
||||
to setup a rsync server. See the rsync(1) man page for info on how to
|
||||
connect to a rsync server.
|
||||
|
||||
@@ -100,25 +116,25 @@ There is a mailing list for the discussion of rsync and its
|
||||
applications. It is open to anyone to join. I will announce new
|
||||
versions on this list.
|
||||
|
||||
To join the mailing list send mail to listproc@samba.anu.edu.au with
|
||||
To join the mailing list send mail to listproc@samba.org with
|
||||
no subject and a body of "subscribe rsync Your Name".
|
||||
|
||||
To send mail to everyone on the list send it to rsync@samba.anu.edu.au
|
||||
To send mail to everyone on the list send it to rsync@samba.org
|
||||
|
||||
|
||||
BUG REPORTS
|
||||
-----------
|
||||
|
||||
If you have web access then please look at
|
||||
http://samba.anu.edu.au/rsync/
|
||||
http://rsync.samba.org/rsync/
|
||||
|
||||
This will give you access to the bug tracking system used by the
|
||||
developers of rsync and will allow you to look at other bug reports or
|
||||
submit a new bug report.
|
||||
|
||||
If you don't have web access then mail bug reports to
|
||||
rsync-bugs@samba.anu.edu.au or (if you think it will be of interest to
|
||||
lots of people) send it to rsync@samba.anu.edu.au
|
||||
rsync-bugs@samba.org or (if you think it will be of interest to lots
|
||||
of people) send it to rsync@samba.org
|
||||
|
||||
|
||||
CVS TREE
|
||||
@@ -128,10 +144,10 @@ If you want to get the very latest version of rsync direct from the
|
||||
source code repository then you can use anonymous cvs. You will need a
|
||||
recent version of cvs then use the following commands:
|
||||
|
||||
cvs -d :pserver:cvs@samba.anu.edu.au:/cvsroot login
|
||||
cvs -d :pserver:cvs@cvs.samba.org:/cvsroot login
|
||||
Password: cvs
|
||||
|
||||
cvs -d :pserver:cvs@samba.anu.edu.au:/cvsroot co rsync
|
||||
cvs -d :pserver:cvs@cvs.samba.org:/cvsroot co rsync
|
||||
|
||||
Look at the cvs documentation for more details.
|
||||
|
||||
@@ -142,18 +158,13 @@ COPYRIGHT
|
||||
Rsync was written by Andrew Tridgell and Paul Mackerras, and is
|
||||
available under the Gnu Public License.
|
||||
|
||||
tridge@samba.anu.edu.au
|
||||
tridge@samba.org
|
||||
paulus@cs.anu.edu.au
|
||||
|
||||
|
||||
AVAILABILITY
|
||||
------------
|
||||
|
||||
The main ftp site for rsync is ftp://samba.anu.edu.au/pub/rsync
|
||||
This is also available as rsync://samba.anu.edu.au/rsyncftp/
|
||||
|
||||
Mirrors are available at:
|
||||
|
||||
ftp://sunsite.auc.dk/pub/unix/rsync
|
||||
ftp://ftp.sunet.se/pub/unix/admin/rsync
|
||||
ftp://ftp.fu-berlin.de/pub/unix/network/rsync/
|
||||
The main web site for rsync is http://rsync.samba.org/
|
||||
The main ftp site is ftp://rsync.samba.org/pub/rsync/
|
||||
This is also available as rsync://rsync.samba.org/rsyncftp/
|
||||
|
||||
@@ -55,7 +55,7 @@ static void gen_challenge(char *addr, char *challenge)
|
||||
|
||||
memset(input, 0, sizeof(input));
|
||||
|
||||
strlcpy((char *)input, addr, 16);
|
||||
strlcpy((char *)input, addr, 17);
|
||||
gettimeofday(&tv, NULL);
|
||||
SIVAL(input, 16, tv.tv_sec);
|
||||
SIVAL(input, 20, tv.tv_usec);
|
||||
@@ -75,12 +75,31 @@ static int get_secret(int module, char *user, char *secret, int len)
|
||||
int fd, found=0;
|
||||
char line[MAXPATHLEN];
|
||||
char *p, *pass=NULL;
|
||||
STRUCT_STAT st;
|
||||
int ok = 1;
|
||||
extern int am_root;
|
||||
|
||||
if (!fname || !*fname) return 0;
|
||||
|
||||
fd = open(fname,O_RDONLY);
|
||||
if (fd == -1) return 0;
|
||||
|
||||
if (do_stat(fname, &st) == -1) {
|
||||
rprintf(FERROR,"stat(%s) : %s\n", fname, strerror(errno));
|
||||
ok = 0;
|
||||
} else if ((st.st_mode & 06) != 0) {
|
||||
rprintf(FERROR,"secrets file must not be other-accessible\n");
|
||||
ok = 0;
|
||||
} else if (am_root && (st.st_uid != 0)) {
|
||||
rprintf(FERROR,"secrets file must be owned by root when running as root\n");
|
||||
ok = 0;
|
||||
}
|
||||
if (!ok) {
|
||||
rprintf(FERROR,"continuing without secrets file\n");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (!found) {
|
||||
int i = 0;
|
||||
memset(line, 0, sizeof(line));
|
||||
|
||||
@@ -31,7 +31,7 @@ static int cleanup_fd1, cleanup_fd2;
|
||||
static struct map_struct *cleanup_buf;
|
||||
static int cleanup_pid = 0;
|
||||
|
||||
void exit_cleanup(int code)
|
||||
void _exit_cleanup(int code, const char *file, int line)
|
||||
{
|
||||
extern int keep_partial;
|
||||
|
||||
@@ -58,7 +58,7 @@ void exit_cleanup(int code)
|
||||
}
|
||||
}
|
||||
|
||||
if (code) log_exit(code);
|
||||
if (code) log_exit(code, file, line);
|
||||
|
||||
exit(code);
|
||||
}
|
||||
|
||||
@@ -187,6 +187,12 @@ static int rsync_module(int fd, int i)
|
||||
gid = atoi(p);
|
||||
}
|
||||
|
||||
p = lp_include_from(i);
|
||||
add_exclude_file(p, 1, 1);
|
||||
|
||||
p = lp_include(i);
|
||||
add_include_line(p);
|
||||
|
||||
p = lp_exclude_from(i);
|
||||
add_exclude_file(p, 1, 0);
|
||||
|
||||
@@ -253,7 +259,7 @@ static int rsync_module(int fd, int i)
|
||||
request = strdup(p);
|
||||
start_glob++;
|
||||
}
|
||||
glob_expand(name, argv, &argc, MAX_ARGS);
|
||||
glob_expand(name, argv, &argc, MAX_ARGS, !use_chroot);
|
||||
} else {
|
||||
argc++;
|
||||
}
|
||||
@@ -276,9 +282,7 @@ static int rsync_module(int fd, int i)
|
||||
* and which aren't.
|
||||
*/
|
||||
for (i = 1; i < argc; i++) {
|
||||
char *copy = sanitize_path(argv[i]);
|
||||
free((void *)argv[i]);
|
||||
argv[i] = copy;
|
||||
sanitize_path(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,8 +314,12 @@ static int rsync_module(int fd, int i)
|
||||
io_start_multiplex_out(fd);
|
||||
|
||||
if (!ret) {
|
||||
rprintf(FERROR,"Error parsing options (unsupported option?) - aborting\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
option_error();
|
||||
}
|
||||
|
||||
if (lp_timeout(i)) {
|
||||
extern int io_timeout;
|
||||
io_timeout = lp_timeout(i);
|
||||
}
|
||||
|
||||
start_server(fd, fd, argc, argp);
|
||||
|
||||
12
configure.in
12
configure.in
@@ -2,6 +2,9 @@ dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(byteorder.h)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
# compile with optimisation and without debugging by default
|
||||
CFLAGS=${CFLAGS-"-O"}
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
AC_VALIDATE_CACHE_SYSTEM_TYPE
|
||||
|
||||
@@ -49,6 +52,7 @@ AC_FUNC_UTIME_NULL
|
||||
AC_CHECK_FUNCS(mmap munmap waitpid getcwd strdup strerror chown chmod mknod)
|
||||
AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime)
|
||||
AC_CHECK_FUNCS(memmove getopt_long lchown vsnprintf snprintf setsid glob strpbrk)
|
||||
AC_CHECK_FUNCS(strlcat strlcpy)
|
||||
|
||||
echo $ac_n "checking for working fnmatch... $ac_c"
|
||||
AC_TRY_RUN([#include <fnmatch.h>
|
||||
@@ -158,6 +162,14 @@ if test x"$ac_cv_func_connect" = x"no"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
|
||||
#
|
||||
AC_CHECK_FUNCS(strcasecmp)
|
||||
if test x"$ac_cv_func_strcasecmp" = x"no"; then
|
||||
AC_CHECK_LIB(resolv, strcasecmp)
|
||||
fi
|
||||
|
||||
#
|
||||
# The following test was mostly taken from the tcl/tk plus patches
|
||||
#
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#define RERR_SYNTAX 1 /* syntax or usage error */
|
||||
#define RERR_PROTOCOL 2 /* protocol incompatibility */
|
||||
#define RERR_FILESELECT 3 /* errors selecting input/output files, dirs */
|
||||
#define RERR_NOSUPPORT 4 /* requested action not supported */
|
||||
#define RERR_UNSUPPORTED 4 /* requested action not supported */
|
||||
|
||||
#define RERR_SOCKETIO 10 /* error in socket IO */
|
||||
#define RERR_FILEIO 11 /* error in file IO */
|
||||
|
||||
19
exclude.c
19
exclude.c
@@ -160,6 +160,10 @@ int check_exclude(char *name,struct exclude_struct **local_exclude_list,
|
||||
{
|
||||
int n;
|
||||
|
||||
if (name && (name[0] == '.') && !name[1])
|
||||
/* never exclude '.', even if somebody does --exclude '*' */
|
||||
return 0;
|
||||
|
||||
if (exclude_list) {
|
||||
for (n=0; exclude_list[n]; n++)
|
||||
if (check_one_exclude(name,exclude_list[n],st))
|
||||
@@ -264,7 +268,7 @@ void send_exclude_list(int f)
|
||||
if (exclude_list[i]->include) {
|
||||
if (remote_version < 19) {
|
||||
rprintf(FERROR,"remote rsync does not support include syntax - aborting\n");
|
||||
exit_cleanup(RERR_NOSUPPORT);
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
write_int(f,l+2);
|
||||
write_buf(f,"+ ",2);
|
||||
@@ -301,6 +305,17 @@ void add_exclude_line(char *p)
|
||||
free(p);
|
||||
}
|
||||
|
||||
void add_include_line(char *p)
|
||||
{
|
||||
char *tok;
|
||||
if (!p || !*p) return;
|
||||
p = strdup(p);
|
||||
if (!p) out_of_memory("add_include_line");
|
||||
for (tok=strtok(p," "); tok; tok=strtok(NULL," "))
|
||||
add_exclude(tok, 1);
|
||||
free(p);
|
||||
}
|
||||
|
||||
|
||||
static char *cvs_ignore_list[] = {
|
||||
"RCS","SCCS","CVS","CVS.adm","RCSLOG","cvslog.*",
|
||||
@@ -321,7 +336,7 @@ void add_cvs_excludes(void)
|
||||
add_exclude(cvs_ignore_list[i], 0);
|
||||
|
||||
if ((p=getenv("HOME")) && strlen(p) < (MAXPATHLEN-12)) {
|
||||
slprintf(fname,sizeof(fname)-1, "%s/.cvsignore",p);
|
||||
slprintf(fname,sizeof(fname), "%s/.cvsignore",p);
|
||||
add_exclude_file(fname,0,0);
|
||||
}
|
||||
|
||||
|
||||
32
flist.c
32
flist.c
@@ -58,6 +58,10 @@ static void list_file_entry(struct file_struct *f)
|
||||
char *perm_map = "rwxrwxrwx";
|
||||
int i;
|
||||
|
||||
if (!f->basename)
|
||||
/* this can happen if duplicate names were removed */
|
||||
return;
|
||||
|
||||
for (i=0;i<9;i++) {
|
||||
if (f->mode & (1<<i)) perms[9-i] = perm_map[8-i];
|
||||
}
|
||||
@@ -230,7 +234,7 @@ static void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
|
||||
last_gid = file->gid;
|
||||
last_time = file->modtime;
|
||||
|
||||
strlcpy(lastname,fname,MAXPATHLEN-1);
|
||||
strlcpy(lastname,fname,MAXPATHLEN);
|
||||
lastname[MAXPATHLEN-1] = 0;
|
||||
}
|
||||
|
||||
@@ -265,11 +269,11 @@ static void receive_file_entry(struct file_struct **fptr,
|
||||
|
||||
if (l2 >= MAXPATHLEN-l1) overflow("receive_file_entry");
|
||||
|
||||
strlcpy(thisname,lastname,l1);
|
||||
strlcpy(thisname,lastname,l1+1);
|
||||
read_sbuf(f,&thisname[l1],l2);
|
||||
thisname[l1+l2] = 0;
|
||||
|
||||
strlcpy(lastname,thisname,MAXPATHLEN-1);
|
||||
strlcpy(lastname,thisname,MAXPATHLEN);
|
||||
lastname[MAXPATHLEN-1] = 0;
|
||||
|
||||
clean_fname(thisname);
|
||||
@@ -370,7 +374,7 @@ static struct file_struct *make_file(char *fname)
|
||||
char *p;
|
||||
char cleaned_name[MAXPATHLEN];
|
||||
|
||||
strlcpy(cleaned_name, fname, MAXPATHLEN-1);
|
||||
strlcpy(cleaned_name, fname, MAXPATHLEN);
|
||||
cleaned_name[MAXPATHLEN-1] = 0;
|
||||
clean_fname(cleaned_name);
|
||||
fname = cleaned_name;
|
||||
@@ -531,7 +535,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
|
||||
return;
|
||||
}
|
||||
|
||||
strlcpy(fname,dir,MAXPATHLEN-1);
|
||||
strlcpy(fname,dir,MAXPATHLEN);
|
||||
l = strlen(fname);
|
||||
if (fname[l-1] != '/') {
|
||||
if (l == MAXPATHLEN-1) {
|
||||
@@ -540,7 +544,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
|
||||
closedir(d);
|
||||
return;
|
||||
}
|
||||
strlcat(fname,"/", MAXPATHLEN-1);
|
||||
strlcat(fname,"/", MAXPATHLEN);
|
||||
l++;
|
||||
}
|
||||
p = fname + strlen(fname);
|
||||
@@ -562,7 +566,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
|
||||
if (strcmp(dname,".")==0 ||
|
||||
strcmp(dname,"..")==0)
|
||||
continue;
|
||||
strlcpy(p,dname,MAXPATHLEN-(l+1));
|
||||
strlcpy(p,dname,MAXPATHLEN-l);
|
||||
send_file_name(f,flist,fname,recurse,0);
|
||||
}
|
||||
|
||||
@@ -608,11 +612,11 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
|
||||
char fname2[MAXPATHLEN];
|
||||
char *fname = fname2;
|
||||
|
||||
strlcpy(fname,argv[i],MAXPATHLEN-1);
|
||||
strlcpy(fname,argv[i],MAXPATHLEN);
|
||||
|
||||
l = strlen(fname);
|
||||
if (l != 1 && fname[l-1] == '/') {
|
||||
strlcat(fname,".",MAXPATHLEN-1);
|
||||
strlcat(fname,".",MAXPATHLEN);
|
||||
}
|
||||
|
||||
if (link_stat(fname,&st) != 0) {
|
||||
@@ -644,7 +648,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
|
||||
thus getting their permissions right */
|
||||
*p = 0;
|
||||
if (strcmp(lastpath,fname)) {
|
||||
strlcpy(lastpath, fname, sizeof(lastpath)-1);
|
||||
strlcpy(lastpath, fname, sizeof(lastpath));
|
||||
*p = '/';
|
||||
for (p=fname+1; (p=strchr(p,'/')); p++) {
|
||||
int copy_links_saved = copy_links;
|
||||
@@ -956,11 +960,11 @@ char *f_name(struct file_struct *f)
|
||||
n = (n+1)%10;
|
||||
|
||||
if (f->dirname) {
|
||||
strlcpy(p, f->dirname, MAXPATHLEN-1);
|
||||
strlcat(p, "/", MAXPATHLEN-1);
|
||||
strlcat(p, f->basename, MAXPATHLEN-1);
|
||||
strlcpy(p, f->dirname, MAXPATHLEN);
|
||||
strlcat(p, "/", MAXPATHLEN);
|
||||
strlcat(p, f->basename, MAXPATHLEN);
|
||||
} else {
|
||||
strlcpy(p, f->basename, MAXPATHLEN-1);
|
||||
strlcpy(p, f->basename, MAXPATHLEN);
|
||||
}
|
||||
|
||||
return p;
|
||||
|
||||
@@ -273,7 +273,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
if ((statret == -1) && (compare_dest != NULL)) {
|
||||
/* try the file at compare_dest instead */
|
||||
int saveerrno = errno;
|
||||
slprintf(fnamecmpbuf,MAXPATHLEN-1,"%s/%s",compare_dest,fname);
|
||||
slprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",compare_dest,fname);
|
||||
statret = link_stat(fnamecmpbuf,&st);
|
||||
if (!S_ISREG(st.st_mode))
|
||||
statret = -1;
|
||||
|
||||
2
io.c
2
io.c
@@ -538,7 +538,7 @@ void io_printf(int fd, const char *format, ...)
|
||||
int len;
|
||||
|
||||
va_start(ap, format);
|
||||
len = vslprintf(buf, sizeof(buf)-1, format, ap);
|
||||
len = vslprintf(buf, sizeof(buf), format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (len < 0) exit_cleanup(RERR_STREAMIO);
|
||||
|
||||
49
lib/compat.c
49
lib/compat.c
@@ -36,7 +36,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETCWD
|
||||
char *getcwd(char *buf, int size)
|
||||
char *getcwd(char *buf, int size)
|
||||
{
|
||||
return getwd(buf);
|
||||
}
|
||||
@@ -44,7 +44,7 @@ char *getcwd(char *buf, int size)
|
||||
|
||||
|
||||
#ifndef HAVE_WAITPID
|
||||
pid_t waitpid(pid_t pid, int *statptr, int options)
|
||||
pid_t waitpid(pid_t pid, int *statptr, int options)
|
||||
{
|
||||
return wait4(pid, statptr, options, NULL);
|
||||
}
|
||||
@@ -52,7 +52,7 @@ pid_t waitpid(pid_t pid, int *statptr, int options)
|
||||
|
||||
|
||||
#ifndef HAVE_MEMMOVE
|
||||
void *memmove(void *dest, const void *src, size_t n)
|
||||
void *memmove(void *dest, const void *src, size_t n)
|
||||
{
|
||||
memcpy(dest, src, n);
|
||||
return dest;
|
||||
@@ -63,7 +63,7 @@ void *memmove(void *dest, const void *src, size_t n)
|
||||
/* Find the first ocurrence in S of any character in ACCEPT.
|
||||
derived from glibc
|
||||
*/
|
||||
char *strpbrk(const char *s, const char *accept)
|
||||
char *strpbrk(const char *s, const char *accept)
|
||||
{
|
||||
while (*s != '\0') {
|
||||
const char *a = accept;
|
||||
@@ -78,17 +78,52 @@ char *strpbrk(const char *s, const char *accept)
|
||||
#endif
|
||||
|
||||
#ifdef REPLACE_INET_NTOA
|
||||
char *rep_inet_ntoa(struct in_addr ip)
|
||||
char *rep_inet_ntoa(struct in_addr ip)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)&ip.s_addr;
|
||||
static char buf[18];
|
||||
#if WORDS_BIGENDIAN
|
||||
slprintf(buf, 17, "%d.%d.%d.%d",
|
||||
slprintf(buf, 18, "%d.%d.%d.%d",
|
||||
(int)p[0], (int)p[1], (int)p[2], (int)p[3]);
|
||||
#else
|
||||
slprintf(buf, 17, "%d.%d.%d.%d",
|
||||
slprintf(buf, 18, "%d.%d.%d.%d",
|
||||
(int)p[3], (int)p[2], (int)p[1], (int)p[0]);
|
||||
#endif
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/* like strncpy but does not 0 fill the buffer and always null
|
||||
terminates. bufsize is the size of the destination buffer */
|
||||
size_t strlcpy(char *d, const char *s, size_t bufsize)
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
size_t ret = len;
|
||||
if (len >= bufsize) len = bufsize-1;
|
||||
memcpy(d, s, len);
|
||||
d[len] = 0;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
/* like strncat but does not 0 fill the buffer and always null
|
||||
terminates. bufsize is the length of the buffer, which should
|
||||
be one more than the maximum resulting string length */
|
||||
size_t strlcat(char *d, const char *s, size_t bufsize)
|
||||
{
|
||||
size_t len1 = strlen(d);
|
||||
size_t len2 = strlen(s);
|
||||
size_t ret = len1 + len2;
|
||||
|
||||
if (len1+len2 >= bufsize) {
|
||||
len2 = bufsize - (len1+1);
|
||||
}
|
||||
if (len2 > 0) {
|
||||
memcpy(d+len1, s, len2);
|
||||
d[len1+len2] = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
34
lib/mdfour.c
34
lib/mdfour.c
@@ -28,30 +28,14 @@
|
||||
|
||||
static struct mdfour *m;
|
||||
|
||||
static inline uint32 F(uint32 X, uint32 Y, uint32 Z)
|
||||
{
|
||||
return (X&Y) | ((~X)&Z);
|
||||
}
|
||||
|
||||
static inline uint32 G(uint32 X, uint32 Y, uint32 Z)
|
||||
{
|
||||
return (X&Y) | (X&Z) | (Y&Z);
|
||||
}
|
||||
|
||||
static inline uint32 H(uint32 X, uint32 Y, uint32 Z)
|
||||
{
|
||||
return X^Y^Z;
|
||||
}
|
||||
|
||||
static inline uint32 lshift(uint32 x, int s)
|
||||
{
|
||||
#define F(X,Y,Z) (((X)&(Y)) | ((~(X))&(Z)))
|
||||
#define G(X,Y,Z) (((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z)))
|
||||
#define H(X,Y,Z) ((X)^(Y)^(Z))
|
||||
#ifdef LARGE_INT32
|
||||
x &= 0xFFFFFFFF;
|
||||
return ((x<<s)&0xFFFFFFFF) | (x>>(32-s));
|
||||
#define lshift(x,s) ((((x)<<(s))&0xFFFFFFFF) | (((x)>>(32-(s)))&0xFFFFFFFF))
|
||||
#else
|
||||
return ((x<<s) | (x>>(32-s)));
|
||||
#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)
|
||||
@@ -209,8 +193,8 @@ static void file_checksum1(char *fname)
|
||||
{
|
||||
int fd, i;
|
||||
struct mdfour md;
|
||||
unsigned char buf[64], sum[16];
|
||||
|
||||
unsigned char buf[64*1024], sum[16];
|
||||
|
||||
fd = open(fname,O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror("fname");
|
||||
@@ -234,6 +218,7 @@ static void file_checksum1(char *fname)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#if 0
|
||||
#include "../md4.h"
|
||||
|
||||
static void file_checksum2(char *fname)
|
||||
@@ -268,11 +253,14 @@ static void file_checksum2(char *fname)
|
||||
printf("%02X", sum[i]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
file_checksum1(argv[1]);
|
||||
#if 0
|
||||
file_checksum2(argv[1]);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
* missing. Some systems only have snprintf() but not vsnprintf(), so
|
||||
* the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
|
||||
*
|
||||
* Andrew Tridgell (tridge@samba.anu.edu.au) Oct 1998
|
||||
* Andrew Tridgell (tridge@samba.org) Oct 1998
|
||||
* fixed handling of %.0f
|
||||
* added test for HAVE_LONG_DOUBLE
|
||||
*
|
||||
|
||||
28
loadparm.c
28
loadparm.c
@@ -51,7 +51,7 @@
|
||||
#define strequal(a,b) (strcasecmp(a,b)==0)
|
||||
#define BOOLSTR(b) ((b) ? "Yes" : "No")
|
||||
typedef char pstring[1024];
|
||||
#define pstrcpy(a,b) strlcpy(a,b,sizeof(pstring)-1)
|
||||
#define pstrcpy(a,b) strlcpy(a,b,sizeof(pstring))
|
||||
|
||||
/* the following are used by loadparm for option lists */
|
||||
typedef enum
|
||||
@@ -129,7 +129,12 @@ typedef struct
|
||||
char *secrets_file;
|
||||
char *exclude;
|
||||
char *exclude_from;
|
||||
char *include;
|
||||
char *include_from;
|
||||
char *log_format;
|
||||
char *refuse_options;
|
||||
char *dont_compress;
|
||||
int timeout;
|
||||
} service;
|
||||
|
||||
|
||||
@@ -151,7 +156,12 @@ static service sDefault =
|
||||
NULL, /* secrets file */
|
||||
NULL, /* exclude */
|
||||
NULL, /* exclude from */
|
||||
NULL, /* include */
|
||||
NULL, /* include from */
|
||||
"%o %h [%a] %m (%u) %f %l", /* log format */
|
||||
NULL, /* refuse options */
|
||||
"*.gz *.tgz *.zip *.z *.rpm *.deb", /* dont compress */
|
||||
0 /* timeout */
|
||||
};
|
||||
|
||||
|
||||
@@ -242,6 +252,7 @@ static struct parm_struct parm_table[] =
|
||||
{"log file", P_STRING, P_GLOBAL, &Globals.log_file, NULL, 0},
|
||||
{"pid file", P_STRING, P_GLOBAL, &Globals.pid_file, NULL, 0},
|
||||
|
||||
{"timeout", P_INTEGER, P_LOCAL, &sDefault.timeout, NULL, 0},
|
||||
{"name", P_STRING, P_LOCAL, &sDefault.name, NULL, 0},
|
||||
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, 0},
|
||||
{"path", P_STRING, P_LOCAL, &sDefault.path, NULL, 0},
|
||||
@@ -256,8 +267,12 @@ static struct parm_struct parm_table[] =
|
||||
{"secrets file", P_STRING, P_LOCAL, &sDefault.secrets_file,NULL, 0},
|
||||
{"exclude", P_STRING, P_LOCAL, &sDefault.exclude, NULL, 0},
|
||||
{"exclude from", P_STRING, P_LOCAL, &sDefault.exclude_from,NULL, 0},
|
||||
{"include", P_STRING, P_LOCAL, &sDefault.include, NULL, 0},
|
||||
{"include from", P_STRING, P_LOCAL, &sDefault.include_from,NULL, 0},
|
||||
{"transfer logging", P_BOOL, P_LOCAL, &sDefault.transfer_logging,NULL,0},
|
||||
{"log format", P_STRING, P_LOCAL, &sDefault.log_format, NULL, 0},
|
||||
{"refuse options", P_STRING, P_LOCAL, &sDefault.refuse_options,NULL, 0},
|
||||
{"dont compress", P_STRING, P_LOCAL, &sDefault.dont_compress,NULL, 0},
|
||||
{NULL, P_BOOL, P_NONE, NULL, NULL, 0}
|
||||
};
|
||||
|
||||
@@ -329,7 +344,12 @@ FN_LOCAL_STRING(lp_auth_users, auth_users)
|
||||
FN_LOCAL_STRING(lp_secrets_file, secrets_file)
|
||||
FN_LOCAL_STRING(lp_exclude, exclude)
|
||||
FN_LOCAL_STRING(lp_exclude_from, exclude_from)
|
||||
FN_LOCAL_STRING(lp_include, include)
|
||||
FN_LOCAL_STRING(lp_include_from, include_from)
|
||||
FN_LOCAL_STRING(lp_log_format, log_format)
|
||||
FN_LOCAL_STRING(lp_refuse_options, refuse_options)
|
||||
FN_LOCAL_STRING(lp_dont_compress, dont_compress)
|
||||
FN_LOCAL_INTEGER(lp_timeout, timeout)
|
||||
|
||||
/* local prototypes */
|
||||
static int strwicmp( char *psz1, char *psz2 );
|
||||
@@ -448,7 +468,7 @@ static int map_parameter(char *parmname)
|
||||
if (strwicmp(parm_table[iIndex].label, parmname) == 0)
|
||||
return(iIndex);
|
||||
|
||||
rprintf(FERROR, "Unknown parameter encountered: \"%s\"\n", parmname);
|
||||
rprintf(FERROR, "Unknown Parameter encountered: \"%s\"\n", parmname);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
@@ -560,7 +580,7 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
|
||||
|
||||
if (parmnum < 0)
|
||||
{
|
||||
rprintf(FERROR, "Ignoring unknown parameter \"%s\"\n", parmname);
|
||||
rprintf(FERROR, "IGNORING unknown parameter \"%s\"\n", parmname);
|
||||
return(True);
|
||||
}
|
||||
|
||||
@@ -606,7 +626,7 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
|
||||
break;
|
||||
|
||||
case P_GSTRING:
|
||||
strlcpy((char *)parm_ptr,parmvalue,sizeof(pstring)-1);
|
||||
strlcpy((char *)parm_ptr,parmvalue,sizeof(pstring));
|
||||
break;
|
||||
|
||||
case P_ENUM:
|
||||
|
||||
26
log.c
26
log.c
@@ -90,7 +90,7 @@ void log_open(void)
|
||||
/* recursion can happen with certain fatal conditions */
|
||||
|
||||
va_start(ap, format);
|
||||
len = vslprintf(buf, sizeof(buf)-1, format, ap);
|
||||
len = vslprintf(buf, sizeof(buf), format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (len < 0) exit_cleanup(RERR_MESSAGEIO);
|
||||
@@ -186,9 +186,10 @@ static void log_formatted(int fd,
|
||||
int l;
|
||||
extern struct stats stats;
|
||||
extern int am_sender;
|
||||
extern int am_daemon;
|
||||
int64 b;
|
||||
|
||||
strlcpy(buf, format, sizeof(buf)-1);
|
||||
strlcpy(buf, format, sizeof(buf));
|
||||
|
||||
for (s=&buf[0];
|
||||
s && (p=strchr(s,'%')); ) {
|
||||
@@ -196,21 +197,21 @@ static void log_formatted(int fd,
|
||||
s = p + 1;
|
||||
|
||||
switch (p[1]) {
|
||||
case 'h': n = client_name(0); break;
|
||||
case 'a': n = client_addr(0); break;
|
||||
case 'h': if (am_daemon) n = client_name(0); break;
|
||||
case 'a': if (am_daemon) n = client_addr(0); break;
|
||||
case 'l':
|
||||
slprintf(buf2,sizeof(buf2)-1,"%.0f",
|
||||
slprintf(buf2,sizeof(buf2),"%.0f",
|
||||
(double)file->length);
|
||||
n = buf2;
|
||||
break;
|
||||
case 'p':
|
||||
slprintf(buf2,sizeof(buf2)-1,"%d",
|
||||
slprintf(buf2,sizeof(buf2),"%d",
|
||||
(int)getpid());
|
||||
n = buf2;
|
||||
break;
|
||||
case 'o': n = op; break;
|
||||
case 'f':
|
||||
slprintf(buf2, sizeof(buf2)-1, "%s/%s",
|
||||
slprintf(buf2, sizeof(buf2), "%s/%s",
|
||||
file->basedir?file->basedir:"",
|
||||
f_name(file));
|
||||
clean_fname(buf2);
|
||||
@@ -229,7 +230,7 @@ static void log_formatted(int fd,
|
||||
b = stats.total_read -
|
||||
initial_stats->total_read;
|
||||
}
|
||||
slprintf(buf2,sizeof(buf2)-1,"%.0f", (double)b);
|
||||
slprintf(buf2,sizeof(buf2),"%.0f", (double)b);
|
||||
n = buf2;
|
||||
break;
|
||||
case 'c':
|
||||
@@ -240,7 +241,7 @@ static void log_formatted(int fd,
|
||||
b = stats.total_read -
|
||||
initial_stats->total_read;
|
||||
}
|
||||
slprintf(buf2,sizeof(buf2)-1,"%.0f", (double)b);
|
||||
slprintf(buf2,sizeof(buf2),"%.0f", (double)b);
|
||||
n = buf2;
|
||||
break;
|
||||
}
|
||||
@@ -295,7 +296,7 @@ void log_recv(struct file_struct *file, struct stats *initial_stats)
|
||||
}
|
||||
|
||||
/* called when the transfer is interrupted for some reason */
|
||||
void log_exit(int code)
|
||||
void log_exit(int code, const char *file, int line)
|
||||
{
|
||||
if (code == 0) {
|
||||
extern struct stats stats;
|
||||
@@ -304,7 +305,8 @@ void log_exit(int code)
|
||||
(double)stats.total_read,
|
||||
(double)stats.total_size);
|
||||
} else {
|
||||
rprintf(FLOG,"transfer interrupted (code %d)\n", code);
|
||||
rprintf(FLOG,"transfer interrupted (code %d) at %s(%d)\n",
|
||||
code, file, line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +315,7 @@ void log_exit(int code)
|
||||
|
||||
it i called when a file starts to be transferred
|
||||
*/
|
||||
void log_transfer(struct file_struct *file, char *fname)
|
||||
void log_transfer(struct file_struct *file, const char *fname)
|
||||
{
|
||||
extern int verbose;
|
||||
|
||||
|
||||
2
main.c
2
main.c
@@ -36,7 +36,7 @@ static void report(int f)
|
||||
extern int do_stats;
|
||||
|
||||
if (am_daemon) {
|
||||
log_exit(0);
|
||||
log_exit(0, __FILE__, __LINE__);
|
||||
if (f == -1 || !am_sender) return;
|
||||
}
|
||||
|
||||
|
||||
2
match.c
2
match.c
@@ -94,7 +94,7 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
|
||||
OFF_T offset,int i)
|
||||
{
|
||||
OFF_T n = offset - last_match;
|
||||
int j;
|
||||
OFF_T j;
|
||||
|
||||
if (verbose > 2 && i >= 0)
|
||||
rprintf(FINFO,"match at %d last_match=%d j=%d len=%d n=%d\n",
|
||||
|
||||
@@ -58,7 +58,7 @@ BEGIN {
|
||||
next;
|
||||
}
|
||||
|
||||
!/^OFF_T|^off_t|^pid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time/ {
|
||||
!/^OFF_T|^size_t|^off_t|^pid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time/ {
|
||||
next;
|
||||
}
|
||||
|
||||
|
||||
57
options.c
57
options.c
@@ -86,9 +86,9 @@ void usage(int F)
|
||||
rprintf(F,"Usage: rsync [OPTION]... SRC [USER@]HOST:DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... SRC DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
|
||||
rprintf(F," or rsync [OPTION]... SRC [USER@]HOST::DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
|
||||
rprintf(F,"\nOptions\n");
|
||||
rprintf(F," -v, --verbose increase verbosity\n");
|
||||
rprintf(F," -c, --checksum always checksum\n");
|
||||
@@ -142,7 +142,7 @@ void usage(int F)
|
||||
rprintf(F,"the block size defaults to %d\n",BLOCK_SIZE);
|
||||
|
||||
rprintf(F,"\nPlease see the rsync(1) and rsyncd.conf(5) man pages for full documentation\n");
|
||||
rprintf(F,"See http://samba.anu.edu.au/rsync/ for updates and bug reports\n");
|
||||
rprintf(F,"See http://rsync.samba.org/ for updates and bug reports\n");
|
||||
}
|
||||
|
||||
enum {OPT_VERSION,OPT_SUFFIX,OPT_SENDER,OPT_SERVER,OPT_EXCLUDE,
|
||||
@@ -205,14 +205,63 @@ static struct option long_options[] = {
|
||||
{0,0,0,0}};
|
||||
|
||||
|
||||
static char err_buf[100];
|
||||
|
||||
void option_error(void)
|
||||
{
|
||||
if (err_buf[0]) {
|
||||
rprintf(FLOG,"%s", err_buf);
|
||||
rprintf(FERROR,"%s", err_buf);
|
||||
} else {
|
||||
rprintf(FLOG,"Error parsing options - unsupported option?\n");
|
||||
rprintf(FERROR,"Error parsing options - unsupported option?\n");
|
||||
}
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
/* check to see if we should refuse this option */
|
||||
static int check_refuse_options(char *ref, int opt)
|
||||
{
|
||||
int i, len;
|
||||
char *p;
|
||||
const char *name;
|
||||
|
||||
for (i=0; long_options[i].name; i++) {
|
||||
if (long_options[i].val == opt) break;
|
||||
}
|
||||
|
||||
if (!long_options[i].name) return 0;
|
||||
|
||||
name = long_options[i].name;
|
||||
len = strlen(name);
|
||||
|
||||
while ((p = strstr(ref,name))) {
|
||||
if ((p==ref || p[-1]==' ') &&
|
||||
(p[len] == ' ' || p[len] == 0)) {
|
||||
slprintf(err_buf,sizeof(err_buf),
|
||||
"The '%s' option is not supported by this server\n", name);
|
||||
return 1;
|
||||
}
|
||||
ref += len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int parse_arguments(int argc, char *argv[])
|
||||
{
|
||||
int opt;
|
||||
int option_index;
|
||||
char *ref = lp_refuse_options(module_id);
|
||||
|
||||
while ((opt = getopt_long(argc, argv,
|
||||
short_options, long_options, &option_index))
|
||||
!= -1) {
|
||||
|
||||
if (ref) {
|
||||
if (check_refuse_options(ref, opt)) return 0;
|
||||
}
|
||||
|
||||
switch (opt) {
|
||||
case OPT_VERSION:
|
||||
rprintf(FINFO,"rsync version %s protocol version %d\n\n",
|
||||
@@ -308,6 +357,7 @@ int parse_arguments(int argc, char *argv[])
|
||||
#if SUPPORT_HARD_LINKS
|
||||
preserve_hard_links=1;
|
||||
#else
|
||||
slprintf(err_buf,sizeof(err_buf),"hard links are not supported on this server\n");
|
||||
rprintf(FERROR,"ERROR: hard links not supported on this platform\n");
|
||||
return 0;
|
||||
#endif
|
||||
@@ -428,6 +478,7 @@ int parse_arguments(int argc, char *argv[])
|
||||
break;
|
||||
|
||||
default:
|
||||
slprintf(err_buf,sizeof(err_buf),"unrecognised option\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.2.0
|
||||
Version: 2.2.1
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.2.0.tar.gz
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.2.1.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
25
receiver.c
25
receiver.c
@@ -33,6 +33,8 @@ extern int cvs_exclude;
|
||||
extern int io_error;
|
||||
extern char *tmpdir;
|
||||
extern char *compare_dest;
|
||||
extern int make_backups;
|
||||
extern char *backup_suffix;
|
||||
|
||||
|
||||
static struct delete_list {
|
||||
@@ -139,8 +141,15 @@ static void delete_files(struct file_list *flist)
|
||||
S_ISDIR(local_file_list->files[i]->mode))
|
||||
add_delete_entry(local_file_list->files[i]);
|
||||
if (-1 == flist_find(flist,local_file_list->files[i])) {
|
||||
delete_one(local_file_list->files[i]);
|
||||
}
|
||||
char *f = f_name(local_file_list->files[i]);
|
||||
int k = strlen(f) - strlen(backup_suffix);
|
||||
if (make_backups && ((k <= 0) ||
|
||||
(strcmp(f+k,backup_suffix) != 0))) {
|
||||
(void) make_backup(f);
|
||||
} else {
|
||||
delete_one(local_file_list->files[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
flist_free(local_file_list);
|
||||
free(name);
|
||||
@@ -163,7 +172,7 @@ static int get_tmpname(char *fnametmp, char *fname)
|
||||
rprintf(FERROR,"filename too long\n");
|
||||
return 0;
|
||||
}
|
||||
slprintf(fnametmp,MAXPATHLEN-1, "%s/.%s.XXXXXX",tmpdir,f);
|
||||
slprintf(fnametmp,MAXPATHLEN, "%s/.%s.XXXXXX",tmpdir,f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -176,11 +185,11 @@ static int get_tmpname(char *fnametmp, char *fname)
|
||||
|
||||
if (f) {
|
||||
*f = 0;
|
||||
slprintf(fnametmp,MAXPATHLEN-1,"%s/.%s.XXXXXX",
|
||||
slprintf(fnametmp,MAXPATHLEN,"%s/.%s.XXXXXX",
|
||||
fname,f+1);
|
||||
*f = '/';
|
||||
} else {
|
||||
slprintf(fnametmp,MAXPATHLEN-1,".%s.XXXXXX",fname);
|
||||
slprintf(fnametmp,MAXPATHLEN,".%s.XXXXXX",fname);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -353,7 +362,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
|
||||
if ((fd1 == -1) && (compare_dest != NULL)) {
|
||||
/* try the file at compare_dest instead */
|
||||
slprintf(fnamecmpbuf,MAXPATHLEN-1,"%s/%s",
|
||||
slprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",
|
||||
compare_dest,fname);
|
||||
fnamecmp = fnamecmpbuf;
|
||||
fd1 = open(fnamecmp,O_RDONLY);
|
||||
@@ -387,6 +396,10 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* mktemp is deliberately used here instead of mkstemp.
|
||||
because O_EXCL is used on the open, the race condition
|
||||
is not a problem or a security hole, and we want to
|
||||
control the access permissions on the created file. */
|
||||
if (NULL == do_mktemp(fnametmp)) {
|
||||
rprintf(FERROR,"mktemp %s failed\n",fnametmp);
|
||||
receive_data(f_in,buf,-1,NULL,file->length);
|
||||
|
||||
36
rsync.c
36
rsync.c
@@ -94,7 +94,7 @@ int delete_file(char *fname)
|
||||
if (strcmp(dname,".")==0 ||
|
||||
strcmp(dname,"..")==0)
|
||||
continue;
|
||||
slprintf(buf, sizeof(buf)-1, "%s/%s", fname, dname);
|
||||
slprintf(buf, sizeof(buf), "%s/%s", fname, dname);
|
||||
if (verbose > 0)
|
||||
rprintf(FINFO,"deleting %s\n", buf);
|
||||
if (delete_file(buf) != 0) {
|
||||
@@ -191,23 +191,33 @@ void sig_int(void)
|
||||
exit_cleanup(RERR_SIGNAL);
|
||||
}
|
||||
|
||||
int make_backup(char *fname)
|
||||
{
|
||||
char fnamebak[MAXPATHLEN];
|
||||
if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
|
||||
rprintf(FERROR,"backup filename too long\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix);
|
||||
if (do_rename(fname,fnamebak) != 0) {
|
||||
if (errno != ENOENT) {
|
||||
rprintf(FERROR,"rename %s %s : s\n",fname,fnamebak,strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
} else if (verbose > 1) {
|
||||
rprintf(FINFO,"backed up %s to %s\n",fname,fnamebak);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* finish off a file transfer, renaming the file and setting the permissions
|
||||
and ownership */
|
||||
void finish_transfer(char *fname, char *fnametmp, struct file_struct *file)
|
||||
{
|
||||
if (make_backups) {
|
||||
char fnamebak[MAXPATHLEN];
|
||||
if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
|
||||
rprintf(FERROR,"backup filename too long\n");
|
||||
return;
|
||||
}
|
||||
slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix);
|
||||
if (do_rename(fname,fnamebak) != 0 && errno != ENOENT) {
|
||||
rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (make_backups && !make_backup(fname))
|
||||
return;
|
||||
|
||||
/* move tmp file over real file */
|
||||
if (do_rename(fnametmp,fname) != 0) {
|
||||
|
||||
11
rsync.h
11
rsync.h
@@ -474,3 +474,14 @@ extern int errno;
|
||||
#ifdef REPLACE_INET_NTOA
|
||||
#define inet_ntoa rep_inet_ntoa
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
size_t strlcpy(char *d, const char *s, size_t bufsize);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
size_t strlcat(char *d, const char *s, size_t bufsize);
|
||||
#endif
|
||||
|
||||
#define exit_cleanup(code) _exit_cleanup(code, __FILE__, __LINE__)
|
||||
|
||||
140
rsync.yo
140
rsync.yo
@@ -1,5 +1,5 @@
|
||||
mailto(rsync-bugs@samba.anu.edu.au)
|
||||
manpage(rsync)(1)(13 May 1998)()()
|
||||
mailto(rsync-bugs@samba.org)
|
||||
manpage(rsync)(1)(24 Nov 1998)()()
|
||||
manpagename(rsync)(faster, flexible replacement for rcp)
|
||||
manpagesynopsis()
|
||||
|
||||
@@ -59,8 +59,7 @@ itemize(
|
||||
|
||||
it() for copying from a remote rsync server to the local
|
||||
machine. This is invoked when the source path contains a ::
|
||||
separator. You can also use a rsync:// URL if no username
|
||||
is required.
|
||||
separator or a rsync:// URL.
|
||||
|
||||
it() for copying from the local machine to a remote rsync
|
||||
server. This is invoked when the destination path contains a ::
|
||||
@@ -71,8 +70,8 @@ itemize(
|
||||
local destination.
|
||||
)
|
||||
|
||||
Note that in all cases at least one of the source and destination
|
||||
paths must be local.
|
||||
Note that in all cases (other than listing) at least one of the source
|
||||
and destination paths must be local.
|
||||
|
||||
manpagesection(SETUP)
|
||||
|
||||
@@ -82,7 +81,7 @@ Once installed you can use rsync to any machine that you can use rsh
|
||||
to. rsync uses rsh for its communications, unless both the source and
|
||||
destination are local.
|
||||
|
||||
You can also specify a alternative to rsh, by either using the -e
|
||||
You can also specify an alternative to rsh, by either using the -e
|
||||
command line option, or by setting the RSYNC_RSH environment variable.
|
||||
|
||||
One common substitute is to use ssh, which offers a high degree of
|
||||
@@ -108,18 +107,18 @@ differences. See the tech report for details.
|
||||
|
||||
quote(rsync -avz foo:src/bar /data/tmp)
|
||||
|
||||
recursively transfer all files from the directory src/bar on the
|
||||
this would recursively transfer all files from the directory src/bar on the
|
||||
machine foo into the /data/tmp/bar directory on the local machine. The
|
||||
files are transferred in "archive" mode, which ensures that symbolic
|
||||
links, devices, attributes, permissions, ownerships etc are preserved
|
||||
in the transfer. Additionally compression will be used to reduce the
|
||||
in the transfer. Additionally, compression will be used to reduce the
|
||||
size of data portions of the transfer.
|
||||
|
||||
quote(rsync -avz foo:src/bar/ /data/tmp)
|
||||
|
||||
With a trailing slash on the source this behavior changes to transfer
|
||||
a trailing slash on the source changes this behavior to transfer
|
||||
all files from the directory src/bar on the machine foo into the
|
||||
/data/tmp/. With a trailing / on a source name it means "copy the
|
||||
/data/tmp/. A trailing / on a source name means "copy the
|
||||
contents of this directory". Without a trailing slash it means "copy
|
||||
the directory". This difference becomes particularly important when
|
||||
using the --delete option.
|
||||
@@ -128,6 +127,11 @@ You can also use rsync in local-only mode, where both the source and
|
||||
destination don't have a ':' in the name. In this case it behaves like
|
||||
an improved copy command.
|
||||
|
||||
quote(rsync somehost.mydomain.com::)
|
||||
|
||||
this would list all the anonymous rsync modules available on the host
|
||||
somehost.mydomain.com. (See the following section for more details.)
|
||||
|
||||
|
||||
manpagesection(CONNECTING TO AN RSYNC SERVER)
|
||||
|
||||
@@ -135,7 +139,7 @@ It is also possible to use rsync without using rsh or ssh as the
|
||||
transport. In this case you will connect to a remote rsync server
|
||||
running on TCP port 873.
|
||||
|
||||
Using rsync in this was is the same as using it with rsh or ssh except
|
||||
Using rsync in this way is the same as using it with rsh or ssh except
|
||||
that:
|
||||
|
||||
itemize(
|
||||
@@ -143,13 +147,13 @@ itemize(
|
||||
separate the hostname from the path.
|
||||
|
||||
it() the remote server may print a message of the day when you
|
||||
connect
|
||||
connect.
|
||||
|
||||
it() if you specify no path name on the remote server then the
|
||||
list of accessible paths on the server will be shown.
|
||||
|
||||
|
||||
it() if you specify no local destination then a listing of the
|
||||
specified files on the remote server is provided
|
||||
specified files on the remote server is provided.
|
||||
)
|
||||
|
||||
Some paths on the remote server may require authentication. If so then
|
||||
@@ -167,8 +171,8 @@ manpagesection(EXAMPLES)
|
||||
|
||||
Here are some examples of how I use rsync.
|
||||
|
||||
To backup my wife's home directory, which consists of large MS word
|
||||
files and mail folders I use a cron job that runs
|
||||
To backup my wife's home directory, which consists of large MS Word
|
||||
files and mail folders, I use a cron job that runs
|
||||
|
||||
quote(rsync -Cavz . arvidsjaur:backup)
|
||||
|
||||
@@ -199,16 +203,16 @@ this is launched from cron every few hours.
|
||||
|
||||
manpagesection(OPTIONS SUMMARY)
|
||||
|
||||
Here is a short summary of the options avalable in rsync. Please refer
|
||||
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 [USER@]HOST:DEST
|
||||
or rsync [OPTION]... [USER@]HOST:SRC DEST
|
||||
or rsync [OPTION]... SRC DEST
|
||||
or rsync [OPTION]... [USER@]HOST::SRC DEST
|
||||
or rsync [OPTION]... [USER@]HOST::SRC [DEST]
|
||||
or rsync [OPTION]... SRC [USER@]HOST::DEST
|
||||
or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC DEST
|
||||
or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
|
||||
|
||||
Options
|
||||
-v, --verbose increase verbosity
|
||||
@@ -263,7 +267,7 @@ manpageoptions()
|
||||
|
||||
rsync uses the GNU long options package. Many of the command line
|
||||
options have two variants, one short and one long. These are shown
|
||||
below separated by commas. Some options only have a long variant.
|
||||
below, separated by commas. Some options only have a long variant.
|
||||
|
||||
startdit()
|
||||
dit(bf(-h, --help)) Print a short help page describing the options
|
||||
@@ -272,12 +276,12 @@ available in rsync
|
||||
dit(bf(--version)) print the rsync version number and exit
|
||||
|
||||
dit(bf(-v, --verbose)) This option increases the amount of information you
|
||||
are given during the transfer. By default rsync works silently. A
|
||||
are given during the transfer. By default, rsync works silently. A
|
||||
single -v will give you information about what files are being
|
||||
transferred and a brief summary at the end. Two -v flags will give you
|
||||
information on what files are being skipped and slightly more
|
||||
information at the end. More than two -v flags should only be used if
|
||||
you are debugging rsync
|
||||
you are debugging rsync.
|
||||
|
||||
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
|
||||
@@ -290,18 +294,18 @@ 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 -rlptDg. It is a quick way
|
||||
of saying I want recursion and want to preserve everything.
|
||||
of saying you want recursion and want to preserve everything.
|
||||
|
||||
Note: if the user launching rsync is root then the -o option (preserve
|
||||
uid) is also implied.
|
||||
|
||||
dit(bf(-r, --recursive)) This tells rsync to copy directories recursively
|
||||
dit(bf(-r, --recursive)) This tells rsync to copy directories recursively.
|
||||
|
||||
dit(bf(-R, --relative)) Use relative paths. This means that the full path
|
||||
names specified on the command line are sent to the server rather than
|
||||
just the last parts of the filenames. This is particularly useful when
|
||||
you want to sent several different directories at the same time. For
|
||||
example if you used the command
|
||||
you want to send several different directories at the same time. For
|
||||
example, if you used the command
|
||||
|
||||
verb(rsync foo/bar/foo.c remote:/tmp/)
|
||||
|
||||
@@ -323,7 +327,7 @@ file.
|
||||
|
||||
dit(bf(-l, --links)) This tells rsync to recreate symbolic links on the
|
||||
remote system to be the same as the local system. Without this
|
||||
option all symbolic links are skipped.
|
||||
option, all symbolic links are skipped.
|
||||
|
||||
dit(bf(-L, --copy-links)) This tells rsync to treat symbolic links just
|
||||
like ordinary files.
|
||||
@@ -331,7 +335,7 @@ like ordinary files.
|
||||
dit(bf(--safe-links)) This tells rsync to ignore any symbolic links
|
||||
which point outside the destination tree. All absolute symlinks are
|
||||
also ignored. Using this option in conjunction with --relative may
|
||||
give unexpecetd results.
|
||||
give unexpected results.
|
||||
|
||||
dit(bf(-H, --hard-links)) This tells rsync to recreate hard links on
|
||||
the remote system to be the same as the local system. Without this
|
||||
@@ -346,7 +350,7 @@ dit(bf(-W, --whole-file)) With this option the incremental rsync algorithm
|
||||
is not used and the whole file is sent as-is instead. This may be
|
||||
useful when using rsync with a local machine.
|
||||
|
||||
dit(bf(--partial)) By default rsync will delete any partially
|
||||
dit(bf(--partial)) By default, rsync will delete any partially
|
||||
transferred file if the transfer is interrupted. In some circumstances
|
||||
it is more desirable to keep partially transferred files. Using the
|
||||
--partial option tells rsync to keep the partial file which should
|
||||
@@ -359,7 +363,7 @@ dit(bf(-o, --owner)) This option causes rsync to update the remote owner
|
||||
of the file to be the same as the local owner. This is only available
|
||||
to the super-user. Note that if the source system is a daemon using chroot,
|
||||
the --numeric-ids option is implied because the source system cannot get
|
||||
access to the user names.
|
||||
access to the usernames.
|
||||
|
||||
dit(bf(-g, --group)) This option causes rsync to update the remote group
|
||||
of the file to be the same as the local group. Note that if the source
|
||||
@@ -371,7 +375,12 @@ block device information to the remote system to recreate these
|
||||
devices. This option is only available to the super-user.
|
||||
|
||||
dit(bf(-t, --times)) This tells rsync to transfer modification times along
|
||||
with the files and update them on the remote system
|
||||
with the files and update them on the remote system. Note that if this
|
||||
option is not used, the optimization that excludes files that have not been
|
||||
modified cannot be effective; in other words, a missing -t or -a will
|
||||
cause the next transfer to behave as if it used -I, and all files will have
|
||||
their checksums compared and show up in log messages even if they haven't
|
||||
changed.
|
||||
|
||||
dit(bf(-n, --dry-run)) This tells rsync to not do any file transfers,
|
||||
instead it will just report the actions it would have taken.
|
||||
@@ -424,14 +433,14 @@ the rsync algorithm. See the technical report for details.
|
||||
|
||||
dit(bf(-e, --rsh COMMAND)) This option allows you to choose an alternative
|
||||
remote shell program to use for communication between the local and
|
||||
remote copies of rsync. By default rsync will use rsh, but you may
|
||||
remote copies of rsync. By default, rsync will use rsh, but you may
|
||||
like to instead use ssh because of its high security.
|
||||
|
||||
You can also choose the remote shell program using the RSYNC_RSH
|
||||
environment variable.
|
||||
|
||||
dit(bf(--rsync-path PATH)) Use this to specify the path to the copy of
|
||||
rsync on the remote machine. Useful when its not in your path.
|
||||
rsync on the remote machine. Useful when it's not in your path.
|
||||
|
||||
dit(bf(--exclude pattern)) This option allows you to selectively exclude
|
||||
certain files from the list of files to be transferred. This is most
|
||||
@@ -440,7 +449,7 @@ useful in combination with a recursive transfer.
|
||||
You may use as many --exclude options on the command line as you like
|
||||
to build up the list of files to exclude.
|
||||
|
||||
See the section of exclude patterns for information on the syntax of
|
||||
See the section on exclude patterns for information on the syntax of
|
||||
this option.
|
||||
|
||||
dit(bf(--exclude-from FILE)) This option is similar to the --exclude
|
||||
@@ -505,11 +514,13 @@ dit(bf(--compare-dest DIR)) This option instructs rsync to use DIR as an
|
||||
additional directory to compare destination files against when doing
|
||||
transfers. This is useful for doing transfers to a new destination while
|
||||
leaving existing files intact, and then doing a flash-cutover when all
|
||||
files have been successfully transfered (for example by moving directories
|
||||
around and removing the old directory). This option increases the
|
||||
usefulness of --partial because partially transferred files will remain in
|
||||
the new temporary destination until they have a chance to be completed.
|
||||
If DIR is a relative path, it is relative to the destination directory.
|
||||
files have been successfully transferred (for example by moving directories
|
||||
around and removing the old directory, although this requires also doing
|
||||
the transfer with -I to avoid skipping files that haven't changed). This
|
||||
option increases the usefulness of --partial because partially transferred
|
||||
files will remain in the new temporary destination until they have a chance
|
||||
to be completed. If DIR is a relative path, it is relative to the
|
||||
destination directory.
|
||||
|
||||
dit(bf(-z, --compress)) With this option, rsync compresses any data from
|
||||
the source file(s) which it sends to the destination machine. This
|
||||
@@ -527,7 +538,7 @@ at both ends.
|
||||
|
||||
By default rsync will use the user name and group name to determine
|
||||
what ownership to give files. The special uid 0 and the special group
|
||||
0 and never mapped via user/group names even if the --numeric-ids
|
||||
0 are never mapped via user/group names even if the --numeric-ids
|
||||
option is not specified.
|
||||
|
||||
If the source system is a daemon using chroot, or if a user or group name
|
||||
@@ -551,12 +562,12 @@ the default /etc/rsyncd.conf. This is only relevant when --daemon is
|
||||
specified.
|
||||
|
||||
dit(bf(--port PORT)) This specifies an alternate TCP port number to use
|
||||
rather than the default port 873.
|
||||
rather than the default port 873.
|
||||
|
||||
dit(bf(--log-format=FORMAT)) Normally rsync just logs filenames as
|
||||
they are transferred. This allows you to specify exactly what gets
|
||||
logged on a per file basis. The log format is specified using the same
|
||||
format conventions as the log format option in rsyncd.conf.
|
||||
dit(bf(--log-format=FORMAT)) This allows you to specify exactly what the
|
||||
rsync client logs to stdout on a per-file basis. The log format is
|
||||
specified using the same format conventions as the log format option in
|
||||
rsyncd.conf.
|
||||
|
||||
dit(bf(--stats)) This tells rsync to print a verbose set of statistics
|
||||
on the file transfer, allowing you to tell how effective the rsync
|
||||
@@ -572,17 +583,17 @@ enddit()
|
||||
manpagesection(EXCLUDE PATTERNS)
|
||||
|
||||
The exclude and include patterns specified to rsync allow for flexible
|
||||
selection of what files to transfer and what files to skip.
|
||||
selection of which files to transfer and which files to skip.
|
||||
|
||||
rsync build a ordered list of include/exclude options as specified on
|
||||
the command line. When a filename is encountered rsync then checks the
|
||||
rsync builds a ordered list of include/exclude options as specified on
|
||||
the command line. When a filename is encountered, rsync checks the
|
||||
name against each exclude/include pattern in turn. The first matching
|
||||
pattern is acted on. If it is an exclude pattern than that file is
|
||||
skipped. If it is an include pattern then that filename is not
|
||||
skipped. If no matching include/exclude pattern is found then the
|
||||
filename is not skipped.
|
||||
|
||||
The patterns themselves can take several forms. The rules are:
|
||||
The patterns can take several forms. The rules are:
|
||||
|
||||
itemize(
|
||||
it() if the pattern starts with a / then it is matched against the
|
||||
@@ -626,18 +637,21 @@ itemize(
|
||||
it() --exclude "/foo" would exclude a file in the base directory called foo
|
||||
it() --exclude "foo/" would exclude any directory called foo
|
||||
it() --include "*/" --include "*.c" --exclude "*" would include all
|
||||
directories and C source files.
|
||||
directories and C source files
|
||||
it() --include "foo/" --include "foo/bar.c" --exclude "*" would include
|
||||
only foo/bar.c (the foo/ directory must be explicitly included or
|
||||
it would be excluded by the "*")
|
||||
)
|
||||
|
||||
manpagesection(DIAGNOSTICS)
|
||||
|
||||
rsync occasinally produces error messages that may seem a little
|
||||
rsync occasionally produces error messages that may seem a little
|
||||
cryptic. The one that seems to cause the most confusion is "protocol
|
||||
version mismatch - is your shell clean?".
|
||||
|
||||
This message is usually caused by your startup scripts or remote shell
|
||||
facility producing unwanted garbage on the stream that rsync is using
|
||||
for its transport. The way ot diagnose this problem is to run your
|
||||
for its transport. The way to diagnose this problem is to run your
|
||||
remote shell like this:
|
||||
|
||||
verb(
|
||||
@@ -648,7 +662,7 @@ then look at out.dat. If everything is working correctly then out.dat
|
||||
should be a zero length file. You you are getting the above error from
|
||||
rsync then you will probably find that out.dat contains some text or
|
||||
data. Look at the contents and try to work out what is producing
|
||||
it. The most common cause is incorrectly configued shell startup
|
||||
it. The most common cause is incorrectly configured shell startup
|
||||
scripts (such as .cshrc or .profile) that contain output statements
|
||||
for non-interactive logins.
|
||||
|
||||
@@ -672,7 +686,7 @@ password to a shell transport such as ssh.
|
||||
dit(bf(USER) or bf(LOGNAME)) The USER or LOGNAME environment variables
|
||||
are used to determine the default username sent to a rsync server.
|
||||
|
||||
dit(bf(HOME)) The HOME environment variable is used to find the users
|
||||
dit(bf(HOME)) The HOME environment variable is used to find the user's
|
||||
default .cvsignore file.
|
||||
|
||||
enddit()
|
||||
@@ -697,7 +711,7 @@ values
|
||||
see also the comments on the --delete option
|
||||
|
||||
Please report bugs! The rsync bug tracking system is online at
|
||||
url(http://samba.anu.edu.au/rsync/)(http://samba.anu.edu.au/rsync/)
|
||||
url(http://rsync.samba.org/rsync/)(http://rsync.samba.org/rsync/)
|
||||
|
||||
manpagesection(VERSION)
|
||||
This man page is current for version 2.0 of rsync
|
||||
@@ -707,16 +721,16 @@ manpagesection(CREDITS)
|
||||
rsync is distributed under the GNU public license. See the file
|
||||
COPYING for details.
|
||||
|
||||
The primary ftp site for rsync is
|
||||
url(ftp://samba.anu.edu.au/pub/rsync)(ftp://samba.anu.edu.au/pub/rsync).
|
||||
|
||||
A WEB site is available at
|
||||
url(http://samba.anu.edu.au/rsync/)(http://samba.anu.edu.au/rsync/)
|
||||
url(http://rsync.samba.org/)(http://rsync.samba.org/)
|
||||
|
||||
The primary ftp site for rsync is
|
||||
url(ftp://rsync.samba.org/pub/rsync)(ftp://rsync.samba.org/pub/rsync).
|
||||
|
||||
We would be delighted to hear from you if you like this program.
|
||||
|
||||
This program uses the zlib compression library written by Jean-loup
|
||||
Gailly and Mark Adler.
|
||||
This program uses the excellent zlib compression library written by
|
||||
Jean-loup Gailly and Mark Adler.
|
||||
|
||||
manpagesection(THANKS)
|
||||
|
||||
@@ -728,6 +742,6 @@ probably missed some people, my apologies if I have.
|
||||
manpageauthor()
|
||||
|
||||
rsync was written by Andrew Tridgell and Paul Mackerras. They may be
|
||||
contacted via email at tridge@samba.anu.edu.au and
|
||||
contacted via email at tridge@samba.org and
|
||||
Paul.Mackerras@cs.anu.edu.au
|
||||
|
||||
|
||||
124
rsyncd.conf.yo
124
rsyncd.conf.yo
@@ -1,5 +1,5 @@
|
||||
mailto(rsync-bugs@samba.anu.edu.au)
|
||||
manpage(rsyncd.conf)(5)(13 May 1998)()()
|
||||
mailto(rsync-bugs@samba.org)
|
||||
manpage(rsyncd.conf)(5)(25 Nov 1998)()()
|
||||
manpagename(rsyncd.conf)(configuration file for rsync server)
|
||||
manpagesynopsis()
|
||||
|
||||
@@ -46,7 +46,7 @@ manpagesection(LAUNCHING THE RSYNC DAEMON)
|
||||
The rsync daemon is launched by specifying the --daemon option to
|
||||
rsync. The daemon must run with root privileges.
|
||||
|
||||
You can launch it either via inetd or as a standalone daemon. If run
|
||||
You can launch it either via inetd or as a stand-alone daemon. If run
|
||||
as a daemon then just run the command "rsync --daemon" from a suitable
|
||||
startup script.
|
||||
|
||||
@@ -107,39 +107,6 @@ ftp, kern, lpr, mail, news, security, syslog, user, uucp, local0,
|
||||
local1, local2, local3, local4, local5, local6 and local7. The default
|
||||
is daemon.
|
||||
|
||||
dit(bf(transfer logging)) The "transfer logging" option enables per-file
|
||||
logging of downloads and uploads in a format somewhat similar to that
|
||||
used by ftp daemons. If you want to customise the log formats look at
|
||||
log_send, log_recv and log_transfer in log.c
|
||||
|
||||
dit(bf(log format)) The "log format" option allows you to specify the
|
||||
format used for logging file transfers when transfer logging is
|
||||
enabled. The format is a text string containing embedded single
|
||||
character escape sequences prefixed with a percent (%) character.
|
||||
|
||||
The prefixes that are understood are:
|
||||
|
||||
itemize(
|
||||
it() %h for the remote host name
|
||||
it() %a for the remote IP address
|
||||
it() %l for the length of the file in bytes
|
||||
it() %p for the process id of this rsync session
|
||||
it() %o for the operation, which is either "send" or "recv"
|
||||
it() %f for the filename
|
||||
it() %P for the module path
|
||||
it() %m for the module name
|
||||
it() %t for the current time
|
||||
it() %u for the authenticated username (or the null string)
|
||||
it() %b for the number of bytes actually transferred
|
||||
it() %c when sending files this gives the number of checksum bytes
|
||||
received for this file
|
||||
)
|
||||
|
||||
The default log format is "%o %h [%a] %m (%u) %f %l"
|
||||
|
||||
A perl script called rsyncstats to summarise this format is included
|
||||
in the rsync source code distribution.
|
||||
|
||||
dit(bf(socket options)) This option can provide endless fun for people
|
||||
who like to tune their systems to the utmost degree. You can set all
|
||||
sorts of socket options which may make transfers faster (or
|
||||
@@ -209,6 +176,20 @@ equivalent to the client specifying the --exclude-from option with a
|
||||
equivalent file. See also the note about security for the exclude
|
||||
option above.
|
||||
|
||||
dit(bf(include)) The "include" option allows you to specify a space
|
||||
separated list of patterns which rsync should not exclude. This is
|
||||
equivalent to the client specifying these patterns with the --include
|
||||
option. This is useful as it allows you to build up quite complex
|
||||
exclude/include rules.
|
||||
|
||||
See the section of exclude patterns for information on the syntax of
|
||||
this option.
|
||||
|
||||
dit(bf(include from)) The "include from" option specifies a filename
|
||||
on the server that contains include patterns, one per line. This is
|
||||
equivalent to the client specifying the --include-from option with a
|
||||
equivalent file.
|
||||
|
||||
dit(bf(auth users)) The "auth users" option specifies a comma
|
||||
and space separated list of usernames that will be allowed to connect
|
||||
to this module. The usernames do not need to exist on the local
|
||||
@@ -279,6 +260,67 @@ rejected. See the "hosts allow" option for more information.
|
||||
|
||||
The default is no "hosts deny" option, which means all hosts can connect.
|
||||
|
||||
dit(bf(transfer logging)) The "transfer logging" option enables per-file
|
||||
logging of downloads and uploads in a format somewhat similar to that
|
||||
used by ftp daemons. If you want to customize the log formats look at
|
||||
the log format option.
|
||||
|
||||
dit(bf(log format)) The "log format" option allows you to specify the
|
||||
format used for logging file transfers when transfer logging is
|
||||
enabled. The format is a text string containing embedded single
|
||||
character escape sequences prefixed with a percent (%) character.
|
||||
|
||||
The prefixes that are understood are:
|
||||
|
||||
itemize(
|
||||
it() %h for the remote host name
|
||||
it() %a for the remote IP address
|
||||
it() %l for the length of the file in bytes
|
||||
it() %p for the process id of this rsync session
|
||||
it() %o for the operation, which is either "send" or "recv"
|
||||
it() %f for the filename
|
||||
it() %P for the module path
|
||||
it() %m for the module name
|
||||
it() %t for the current time
|
||||
it() %u for the authenticated username (or the null string)
|
||||
it() %b for the number of bytes actually transferred
|
||||
it() %c when sending files this gives the number of checksum bytes
|
||||
received for this file
|
||||
)
|
||||
|
||||
The default log format is "%o %h [%a] %m (%u) %f %l"
|
||||
|
||||
A perl script called rsyncstats to summarize this format is included
|
||||
in the rsync source code distribution.
|
||||
|
||||
dit(bf(timeout)) The "timeout" option allows you to override the
|
||||
clients choice for IO timeout for this module. Using this option you
|
||||
can ensure that rsync won't wait on a dead client forever. The timeout
|
||||
is specified in seconds. A value of zero means no timeout and is the
|
||||
default. A good choice for anonymous rsync servers may be 600 (giving
|
||||
a 10 minute timeout).
|
||||
|
||||
dit(bf(refuse options)) The "refuse options" option allows you to
|
||||
specify a space separated list of rsync command line options that will
|
||||
be refused by your rsync server. The full names of the options must be
|
||||
used (i.e., you must use "checksum" not "c" to disable checksumming).
|
||||
When an option is refused, the server prints an error message and exits.
|
||||
To prevent all compression, you can use "dont compress = *" (see below)
|
||||
instead of "refuse options = compress" to avoid returning an error to a
|
||||
client that requests compression.
|
||||
|
||||
dit(bf(dont compress)) The "dont compress" option allows you to select
|
||||
filenames based on wildcard patterns that should not be compressed
|
||||
during transfer. Compression is expensive in terms of CPU usage so it
|
||||
is usually good to not try to compress files that won't compress well,
|
||||
such as already compressed files.
|
||||
|
||||
The "dont compress" option takes a space separated list of
|
||||
case-insensitive wildcard patterns. Any source filename matching one
|
||||
of the patterns will not be compressed during transfer.
|
||||
|
||||
The default setting is verb(*.gz *.tgz *.zip *.z *.rpm *.deb)
|
||||
|
||||
enddit()
|
||||
|
||||
manpagesection(AUTHENTICATION STRENGTH)
|
||||
@@ -286,7 +328,7 @@ manpagesection(AUTHENTICATION STRENGTH)
|
||||
The authentication protocol used in rsync is a 128 bit MD4 based
|
||||
challenge response system. Although I believe that no one has ever
|
||||
demonstrated a brute-force break of this sort of system you should
|
||||
realise that this is not a "military strength" authentication system.
|
||||
realize that this is not a "military strength" authentication system.
|
||||
It should be good enough for most purposes but if you want really top
|
||||
quality security then I recommend that you run rsync over ssh.
|
||||
|
||||
@@ -364,7 +406,7 @@ client. this means a client may be mystified as to why a transfer
|
||||
failed. The error will have been logged by syslog on the server.
|
||||
|
||||
Please report bugs! The rsync bug tracking system is online at
|
||||
url(http://samba.anu.edu.au/rsync/)(http://samba.anu.edu.au/rsync/)
|
||||
url(http://rsync.samba.org/)(http://rsync.samba.org/)
|
||||
|
||||
manpagesection(VERSION)
|
||||
This man page is current for version 2.0 of rsync
|
||||
@@ -375,10 +417,10 @@ rsync is distributed under the GNU public license. See the file
|
||||
COPYING for details.
|
||||
|
||||
The primary ftp site for rsync is
|
||||
url(ftp://samba.anu.edu.au/pub/rsync)(ftp://samba.anu.edu.au/pub/rsync).
|
||||
url(ftp://rsync.samba.org/pub/rsync)(ftp://rsync.samba.org/pub/rsync).
|
||||
|
||||
A WEB site is available at
|
||||
url(http://samba.anu.edu.au/rsync/)(http://samba.anu.edu.au/rsync/)
|
||||
url(http://rsync.samba.org/)(http://rsync.samba.org/)
|
||||
|
||||
We would be delighted to hear from you if you like this program.
|
||||
|
||||
@@ -394,6 +436,6 @@ documentation!
|
||||
manpageauthor()
|
||||
|
||||
rsync was written by Andrew Tridgell and Paul Mackerras. They may be
|
||||
contacted via email at tridge@samba.anu.edu.au and
|
||||
contacted via email at tridge@samba.org and
|
||||
Paul.Mackerras@cs.anu.edu.au
|
||||
|
||||
|
||||
8
sender.c
8
sender.c
@@ -128,17 +128,17 @@ void send_files(struct file_list *flist,int f_out,int f_in)
|
||||
|
||||
fname[0] = 0;
|
||||
if (file->basedir) {
|
||||
strlcpy(fname,file->basedir,MAXPATHLEN-1);
|
||||
strlcpy(fname,file->basedir,MAXPATHLEN);
|
||||
if (strlen(fname) == MAXPATHLEN-1) {
|
||||
io_error = 1;
|
||||
rprintf(FERROR, "send_files failed on long-named directory %s\n",
|
||||
fname);
|
||||
return;
|
||||
}
|
||||
strlcat(fname,"/",MAXPATHLEN-1);
|
||||
strlcat(fname,"/",MAXPATHLEN);
|
||||
offset = strlen(file->basedir)+1;
|
||||
}
|
||||
strlcat(fname,f_name(file),MAXPATHLEN-strlen(fname));
|
||||
strlcat(fname,f_name(file),MAXPATHLEN);
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"send_files(%d,%s)\n",i,fname);
|
||||
@@ -200,6 +200,8 @@ void send_files(struct file_list *flist,int f_out,int f_in)
|
||||
if (!am_server) {
|
||||
log_transfer(file, fname+offset);
|
||||
}
|
||||
|
||||
set_compression(fname);
|
||||
|
||||
match_sums(f_out,s,buf,st.st_size);
|
||||
|
||||
|
||||
4
socket.c
4
socket.c
@@ -330,7 +330,7 @@ char *client_addr(int fd)
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
|
||||
strlcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr), sizeof(addr_buf)-1);
|
||||
strlcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr), sizeof(addr_buf));
|
||||
return addr_buf;
|
||||
}
|
||||
|
||||
@@ -363,7 +363,7 @@ char *client_name(int fd)
|
||||
if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
|
||||
sizeof(sockin->sin_addr),
|
||||
AF_INET))) {
|
||||
strlcpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
|
||||
strlcpy(name_buf,(char *)hp->h_name,sizeof(name_buf));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
# script that comes with wuftpd
|
||||
#
|
||||
# Andrew Tridgell, October 1998
|
||||
# rsync-bugs@samba.anu.edu.au
|
||||
# rsync-bugs@samba.org
|
||||
#
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -76,6 +76,10 @@ int do_rmdir(char *pathname)
|
||||
int do_open(char *pathname, int flags, mode_t mode)
|
||||
{
|
||||
if (dry_run) return -1;
|
||||
#ifdef O_BINARY
|
||||
/* for Windows */
|
||||
flags |= O_BINARY;
|
||||
#endif
|
||||
CHECK_RO
|
||||
return open(pathname, flags, mode);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ Imagine you have two files, $A$ and $B$, and you wish to update $B$ to be
|
||||
the same as $A$. The obvious method is to copy $A$ onto $B$.
|
||||
|
||||
Now imagine that the two files are on machines connected by a slow
|
||||
communications link, for example a dial up IP link. If $A$ is large,
|
||||
communications link, for example a dialup IP link. If $A$ is large,
|
||||
copying $A$ onto $B$ will be slow. To make it faster you could
|
||||
compress $A$ before sending it, but that will usually only gain a
|
||||
factor of 2 to 4.
|
||||
@@ -133,7 +133,7 @@ possible offsets within a file in a ``rolling'' fashion, with very
|
||||
little computation at each point.
|
||||
|
||||
Despite its simplicity, this checksum was found to be quite adequate as
|
||||
a first level check for a match of two file blocks. We have found in
|
||||
a first-level check for a match of two file blocks. We have found in
|
||||
practice that the probability of this checksum matching when the
|
||||
blocks are not equal is quite low. This is important because the much
|
||||
more expensive strong checksum must be calculated for each block where
|
||||
@@ -158,16 +158,16 @@ contains a null value if no element of the list has that hash value.
|
||||
|
||||
At each offset in the file the 32-bit rolling checksum and its 16-bit
|
||||
hash are calculated. If the hash table entry for that hash value is
|
||||
not a null value, the second level check is invoked.
|
||||
not a null value, the second-level check is invoked.
|
||||
|
||||
The second level check involves scanning the sorted checksum list
|
||||
The second-level check involves scanning the sorted checksum list
|
||||
starting with the entry pointed to by the hash table entry, looking
|
||||
for an entry whose 32-bit rolling checksum matches the current value.
|
||||
The scan terminates when it reaches an entry whose 16-bit hash
|
||||
differs. If this search finds a match, the third level check is
|
||||
differs. If this search finds a match, the third-level check is
|
||||
invoked.
|
||||
|
||||
The third level check involves calculating the strong checksum for the
|
||||
The third-level check involves calculating the strong checksum for the
|
||||
current offset in the file and comparing it with the strong checksum
|
||||
value in the current list entry. If the two strong checksums match,
|
||||
we assume that we have found a block of $A$ which matches a block of
|
||||
@@ -246,14 +246,14 @@ The columns in the table are as follows:
|
||||
\begin{description}
|
||||
\item [block size] The size in bytes of the checksummed blocks.
|
||||
\item [matches] The number of times a block of $B$ was found in $A$.
|
||||
\item [tag hits] The number of times the 16 bit hash of the rolling
|
||||
\item [tag hits] The number of times the 16-bit hash of the rolling
|
||||
checksum matched a hash of one of the checksums from $B$.
|
||||
\item [false alarms] The number of times the 32 bit rolling checksum
|
||||
\item [false alarms] The number of times the 32-bit rolling checksum
|
||||
matched but the strong checksum didn't.
|
||||
\item [data] The amount of file data transferred verbatim, in bytes.
|
||||
\item [written] The total number of bytes written by $\alpha$
|
||||
\item [written] The total number of bytes written by $\alpha$,
|
||||
including protocol overheads. This is almost all file data.
|
||||
\item [read] The total number of bytes read by $\alpha$ including
|
||||
\item [read] The total number of bytes read by $\alpha$, including
|
||||
protocol overheads. This is almost all checksum information.
|
||||
\end{description}
|
||||
|
||||
@@ -269,7 +269,7 @@ case. Each pair of checksums consumes 20 bytes: 4 bytes for the
|
||||
rolling checksum plus 16 bytes for the 128-bit MD4 checksum.
|
||||
|
||||
The number of false alarms was less than $1/1000$ of the number of
|
||||
true matches, indicating that the 32 bit rolling checksum is quite
|
||||
true matches, indicating that the 32-bit rolling checksum is quite
|
||||
good at screening out false matches.
|
||||
|
||||
The number of tag hits indicates that the second level of the
|
||||
@@ -305,6 +305,6 @@ diff between the two releases is 4155 lines long totalling 120 kB.
|
||||
|
||||
An implementation of rsync which provides a convenient interface
|
||||
similar to the common UNIX command rcp has been written and is
|
||||
available for download from ftp://samba.anu.edu.au/pub/rsync.
|
||||
available for download from http://rsync.samba.org/
|
||||
|
||||
\end{document}
|
||||
|
||||
39
token.c
39
token.c
@@ -21,7 +21,44 @@
|
||||
#include "zlib/zlib.h"
|
||||
|
||||
extern int do_compression;
|
||||
static int compression_level = Z_DEFAULT_COMPRESSION;
|
||||
|
||||
/* determine the compression level based on a wildcard filename list */
|
||||
void set_compression(char *fname)
|
||||
{
|
||||
extern int module_id;
|
||||
char *dont;
|
||||
char *tok;
|
||||
|
||||
if (!do_compression) return;
|
||||
|
||||
compression_level = Z_DEFAULT_COMPRESSION;
|
||||
dont = lp_dont_compress(module_id);
|
||||
|
||||
if (!dont || !*dont) return;
|
||||
|
||||
if ((dont[0] == '*') && (!dont[1])) {
|
||||
/* an optimization to skip the rest of this routine */
|
||||
compression_level = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
dont = strdup(dont);
|
||||
fname = strdup(fname);
|
||||
if (!dont || !fname) return;
|
||||
|
||||
strlower(dont);
|
||||
strlower(fname);
|
||||
|
||||
for (tok=strtok(dont," ");tok;tok=strtok(NULL," ")) {
|
||||
if (fnmatch(tok, fname, 0) == 0) {
|
||||
compression_level = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(dont);
|
||||
free(fname);
|
||||
}
|
||||
|
||||
/* non-compressing recv token */
|
||||
static int simple_recv_token(int f,char **data)
|
||||
@@ -104,7 +141,7 @@ send_deflated_token(int f, int token,
|
||||
tx_strm.next_in = NULL;
|
||||
tx_strm.zalloc = NULL;
|
||||
tx_strm.zfree = NULL;
|
||||
if (deflateInit2(&tx_strm, Z_DEFAULT_COMPRESSION,
|
||||
if (deflateInit2(&tx_strm, compression_level,
|
||||
Z_DEFLATED, -15, 8,
|
||||
Z_DEFAULT_STRATEGY) != Z_OK) {
|
||||
rprintf(FERROR, "compression init failed\n");
|
||||
|
||||
133
util.c
133
util.c
@@ -358,31 +358,6 @@ void kill_all(int sig)
|
||||
}
|
||||
}
|
||||
|
||||
/* like strncpy but does not 0 fill the buffer and always null
|
||||
terminates (thus it can use maxlen+1 space in d) */
|
||||
void strlcpy(char *d, char *s, int maxlen)
|
||||
{
|
||||
int len = strlen(s);
|
||||
if (len > maxlen) len = maxlen;
|
||||
memcpy(d, s, len);
|
||||
d[len] = 0;
|
||||
}
|
||||
|
||||
/* like strncat but does not 0 fill the buffer and always null
|
||||
terminates (thus it can use maxlen+1 space in d) */
|
||||
void strlcat(char *d, char *s, int maxlen)
|
||||
{
|
||||
int len1 = strlen(d);
|
||||
int len2 = strlen(s);
|
||||
if (len1+len2 > maxlen) {
|
||||
len2 = maxlen-len1;
|
||||
}
|
||||
if (len2 > 0) {
|
||||
memcpy(d+len1, s, len2);
|
||||
d[len1+len2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* turn a user name into a uid */
|
||||
int name_to_uid(char *name, uid_t *uid)
|
||||
{
|
||||
@@ -425,7 +400,7 @@ int lock_range(int fd, int offset, int len)
|
||||
}
|
||||
|
||||
|
||||
static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
|
||||
static void glob_expand_one(char *s, char **argv, int *argc, int maxargs, int sanitize_paths)
|
||||
{
|
||||
#if !(defined(HAVE_GLOB) && defined(HAVE_GLOB_H))
|
||||
if (!*s) s = ".";
|
||||
@@ -438,7 +413,9 @@ static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
|
||||
|
||||
if (!*s) s = ".";
|
||||
|
||||
argv[*argc] = strdup(s);
|
||||
s = strdup(s);
|
||||
sanitize_path(s);
|
||||
argv[*argc] = s;
|
||||
|
||||
memset(&globbuf, 0, sizeof(globbuf));
|
||||
glob(argv[*argc], 0, NULL, &globbuf);
|
||||
@@ -457,7 +434,7 @@ static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
|
||||
#endif
|
||||
}
|
||||
|
||||
void glob_expand(char *base1, char **argv, int *argc, int maxargs)
|
||||
void glob_expand(char *base1, char **argv, int *argc, int maxargs, int sanitize_paths)
|
||||
{
|
||||
char *s = argv[*argc];
|
||||
char *p, *q;
|
||||
@@ -481,11 +458,11 @@ void glob_expand(char *base1, char **argv, int *argc, int maxargs)
|
||||
while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
|
||||
/* split it at this point */
|
||||
*p = 0;
|
||||
glob_expand_one(q, argv, argc, maxargs);
|
||||
glob_expand_one(q, argv, argc, maxargs, sanitize_paths);
|
||||
q = p+strlen(base);
|
||||
}
|
||||
|
||||
if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs);
|
||||
if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs, sanitize_paths);
|
||||
|
||||
free(s);
|
||||
free(base);
|
||||
@@ -502,14 +479,13 @@ void strlower(char *s)
|
||||
}
|
||||
}
|
||||
|
||||
/* this is like vsnprintf but the 'n' limit does not include
|
||||
the terminating null. So if you have a 1024 byte buffer then
|
||||
pass 1023 for n */
|
||||
/* this is like vsnprintf but it always null terminates, so you
|
||||
can fit at most n-1 chars in */
|
||||
int vslprintf(char *str, int n, const char *format, va_list ap)
|
||||
{
|
||||
int ret = vsnprintf(str, n, format, ap);
|
||||
if (ret > n || ret < 0) {
|
||||
str[n] = 0;
|
||||
if (ret >= n || ret < 0) {
|
||||
str[n-1] = 0;
|
||||
return -1;
|
||||
}
|
||||
str[ret] = 0;
|
||||
@@ -581,51 +557,70 @@ void clean_fname(char *name)
|
||||
|
||||
/*
|
||||
* Make path appear as if a chroot had occurred:
|
||||
* 0. call clean_fname on it.
|
||||
* 1. remove leading "/" (or replace with "." if at end)
|
||||
* 2. remove leading ".." components
|
||||
* 3. delete any other "<dir>/.." (recursively)
|
||||
* Return a malloc'ed copy.
|
||||
* While we're at it, remove double slashes and "." components like
|
||||
* clean_fname does(), but DON'T remove a trailing slash because that
|
||||
* is sometimes significant on command line arguments.
|
||||
* Can only shrink paths, so sanitizes in place.
|
||||
* Contributed by Dave Dykstra <dwd@bell-labs.com>
|
||||
*/
|
||||
|
||||
char *sanitize_path(char *p)
|
||||
void sanitize_path(char *p)
|
||||
{
|
||||
char *copy, *copyp;
|
||||
char *start, *sanp;
|
||||
|
||||
clean_fname(p);
|
||||
|
||||
copy = (char *) malloc(strlen(p)+1);
|
||||
copyp = copy;
|
||||
start = p;
|
||||
sanp = p;
|
||||
while (*p == '/') {
|
||||
/* remove leading slashes */
|
||||
p++;
|
||||
}
|
||||
while (*p != '\0') {
|
||||
if ((*p == '/') && (copyp == copy)) {
|
||||
/* remove leading slash */
|
||||
p++;
|
||||
}
|
||||
else if ((*p == '.') && (*(p+1) == '.') &&
|
||||
/* this loop iterates once per filename component in p.
|
||||
* both p (and sanp if the original had a slash) should
|
||||
* always be left pointing after a slash
|
||||
*/
|
||||
if ((*p == '.') && ((*(p+1) == '/') || (*(p+1) == '\0'))) {
|
||||
/* skip "." component */
|
||||
while (*++p == '/') {
|
||||
/* skip following slashes */
|
||||
;
|
||||
}
|
||||
} else if ((*p == '.') && (*(p+1) == '.') &&
|
||||
((*(p+2) == '/') || (*(p+2) == '\0'))) {
|
||||
/* remove .. followed by slash or end */
|
||||
/* skip ".." component followed by slash or end */
|
||||
p += 2;
|
||||
if (copyp != copy) {
|
||||
/* backup the copy one level */
|
||||
while ((--copyp != copy) && (*copyp == '/'))
|
||||
/* skip trailing slashes */
|
||||
;
|
||||
while ((copyp != copy) && (*copyp != '/'))
|
||||
/* skip back through slash */
|
||||
copyp--;
|
||||
if (*p == '/')
|
||||
p++;
|
||||
if (sanp != start) {
|
||||
/* back up sanp one level */
|
||||
--sanp; /* now pointing at slash */
|
||||
while ((sanp > start) && (*(sanp - 1) != '/')) {
|
||||
/* skip back up to slash */
|
||||
sanp--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* copy one component */
|
||||
while (1) {
|
||||
*copyp++ = *p++;
|
||||
if ((*p == '\0') || (*(p-1) == '/'))
|
||||
/* copy one component through next slash */
|
||||
*sanp++ = *p++;
|
||||
if ((*p == '\0') || (*(p-1) == '/')) {
|
||||
while (*p == '/') {
|
||||
/* skip multiple slashes */
|
||||
p++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*copyp = '\0';
|
||||
return(copy);
|
||||
if (sanp == start) {
|
||||
/* ended up with nothing, so put in "." component */
|
||||
*sanp++ = '.';
|
||||
}
|
||||
*sanp = '\0';
|
||||
}
|
||||
|
||||
|
||||
@@ -650,10 +645,10 @@ char *push_dir(char *dir, int save)
|
||||
}
|
||||
|
||||
if (*dir == '/') {
|
||||
strlcpy(curr_dir, dir, sizeof(curr_dir)-1);
|
||||
strlcpy(curr_dir, dir, sizeof(curr_dir));
|
||||
} else {
|
||||
strlcat(curr_dir,"/", sizeof(curr_dir)-1);
|
||||
strlcat(curr_dir,dir, sizeof(curr_dir)-1);
|
||||
strlcat(curr_dir,"/", sizeof(curr_dir));
|
||||
strlcat(curr_dir,dir, sizeof(curr_dir));
|
||||
}
|
||||
|
||||
clean_fname(curr_dir);
|
||||
@@ -672,7 +667,7 @@ int pop_dir(char *dir)
|
||||
return ret;
|
||||
}
|
||||
|
||||
strlcpy(curr_dir, dir, sizeof(curr_dir)-1);
|
||||
strlcpy(curr_dir, dir, sizeof(curr_dir));
|
||||
|
||||
free(dir);
|
||||
|
||||
@@ -683,8 +678,8 @@ int pop_dir(char *dir)
|
||||
to ensure that signed/unsigned usage is consistent between machines. */
|
||||
int u_strcmp(const char *cs1, const char *cs2)
|
||||
{
|
||||
const uchar *s1 = (uchar *)cs1;
|
||||
const uchar *s2 = (uchar *)cs2;
|
||||
const uchar *s1 = (const uchar *)cs1;
|
||||
const uchar *s2 = (const uchar *)cs2;
|
||||
|
||||
while (*s1 && *s2 && (*s1 == *s2)) {
|
||||
s1++; s2++;
|
||||
@@ -777,7 +772,7 @@ char *timestring(time_t t)
|
||||
#ifdef HAVE_STRFTIME
|
||||
strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %T",tm);
|
||||
#else
|
||||
strlcpy(TimeBuf, asctime(tm), sizeof(TimeBuf)-1);
|
||||
strlcpy(TimeBuf, asctime(tm), sizeof(TimeBuf));
|
||||
#endif
|
||||
|
||||
if (TimeBuf[strlen(TimeBuf)-1] == '\n') {
|
||||
|
||||
Reference in New Issue
Block a user