mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-24 23:05:52 -04:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b41c3f9273 | ||
|
|
35bdd146e4 | ||
|
|
8d249b635c | ||
|
|
932be9aa52 | ||
|
|
c6b81a9865 | ||
|
|
e0414f4202 | ||
|
|
6e4fb64e61 | ||
|
|
37863201ad | ||
|
|
4f6325c362 | ||
|
|
f98df1d9b7 | ||
|
|
3d913675a1 | ||
|
|
2f9af90118 | ||
|
|
3eb388185b | ||
|
|
858fb9ebad | ||
|
|
2f03f956f4 | ||
|
|
0199b05f25 | ||
|
|
e2d1033d5d | ||
|
|
c46ded4621 | ||
|
|
8cd9fd4e8c | ||
|
|
41979ff87c | ||
|
|
b11ed3b150 |
10
Makefile.in
10
Makefile.in
@@ -24,7 +24,7 @@ LIBOBJ=lib/getopt.o lib/fnmatch.o lib/compat.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 \
|
||||
zlib/zutil.o zlib/adler32.o
|
||||
OBJS1=rsync.o exclude.o util.o md4.o main.o checksum.o match.o syscall.o log.o
|
||||
OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o md4.o main.o checksum.o match.o syscall.o log.o
|
||||
OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o fileio.o
|
||||
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
|
||||
OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ)
|
||||
@@ -60,3 +60,11 @@ proto:
|
||||
clean:
|
||||
rm -f *~ $(OBJS) rsync config.cache config.log config.status
|
||||
|
||||
|
||||
# this target is really just for my use. It only works on a limited
|
||||
# range of machines and is used to produce a list of potentially
|
||||
# dead (ie. unused) functions in the code. (tridge)
|
||||
finddead:
|
||||
nm *.o */*.o |grep 'U ' | awk '{print $$2}' | sort -u > nmused.txt
|
||||
nm *.o */*.o |grep 'T ' | awk '{print $$3}' | sort -u > nmfns.txt
|
||||
comm -13 nmused.txt nmfns.txt
|
||||
|
||||
@@ -112,7 +112,7 @@ static int get_secret(int module, char *user, char *secret, int len)
|
||||
}
|
||||
|
||||
/* generate a 16 byte hash from a password and challenge */
|
||||
void generate_hash(char *in, char *challenge, char *out)
|
||||
static void generate_hash(char *in, char *challenge, char *out)
|
||||
{
|
||||
char buf[16];
|
||||
|
||||
|
||||
72
cleanup.c
Normal file
72
cleanup.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
|
||||
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 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/* handling the cleanup when a transfer is interrupted is tricky when
|
||||
--partial is selected. We need to ensure that the partial file is
|
||||
kept if any real data has been transferred */
|
||||
int cleanup_got_literal=0;
|
||||
|
||||
static char *cleanup_fname;
|
||||
static char *cleanup_new_fname;
|
||||
static struct file_struct *cleanup_file;
|
||||
static int cleanup_fd1, cleanup_fd2;
|
||||
static struct map_struct *cleanup_buf;
|
||||
|
||||
void exit_cleanup(int code)
|
||||
{
|
||||
extern int keep_partial;
|
||||
|
||||
signal(SIGUSR1, SIG_IGN);
|
||||
|
||||
if (cleanup_got_literal && cleanup_fname && keep_partial) {
|
||||
char *fname = cleanup_fname;
|
||||
cleanup_fname = NULL;
|
||||
if (cleanup_buf) unmap_file(cleanup_buf);
|
||||
if (cleanup_fd1 != -1) close(cleanup_fd1);
|
||||
if (cleanup_fd2 != -1) close(cleanup_fd2);
|
||||
finish_transfer(cleanup_new_fname, fname, cleanup_file);
|
||||
}
|
||||
io_flush();
|
||||
if (cleanup_fname)
|
||||
do_unlink(cleanup_fname);
|
||||
if (code) {
|
||||
kill_all(SIGUSR1);
|
||||
}
|
||||
exit(code);
|
||||
}
|
||||
|
||||
void cleanup_disable(void)
|
||||
{
|
||||
cleanup_fname = NULL;
|
||||
cleanup_got_literal = 0;
|
||||
}
|
||||
|
||||
|
||||
void cleanup_set(char *fnametmp, char *fname, struct file_struct *file,
|
||||
struct map_struct *buf, int fd1, int fd2)
|
||||
{
|
||||
cleanup_fname = fnametmp;
|
||||
cleanup_new_fname = fname;
|
||||
cleanup_file = file;
|
||||
cleanup_buf = buf;
|
||||
cleanup_fd1 = fd1;
|
||||
cleanup_fd2 = fd2;
|
||||
}
|
||||
@@ -36,6 +36,11 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
|
||||
extern int am_client;
|
||||
extern int am_sender;
|
||||
|
||||
if (*path == '/') {
|
||||
rprintf(FERROR,"ERROR: The remote path must start with a module name\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = strchr(host, '@');
|
||||
if (p) {
|
||||
user = host;
|
||||
@@ -118,6 +123,7 @@ static int rsync_module(int fd, int i)
|
||||
char *name = lp_name(i);
|
||||
char *user;
|
||||
int start_glob=0;
|
||||
int ret;
|
||||
char *request=NULL;
|
||||
extern int am_sender;
|
||||
extern int remote_version;
|
||||
@@ -251,7 +257,7 @@ static int rsync_module(int fd, int i)
|
||||
}
|
||||
}
|
||||
|
||||
parse_arguments(argc, argv);
|
||||
ret = parse_arguments(argc, argv);
|
||||
|
||||
if (request) {
|
||||
if (*user) {
|
||||
@@ -266,8 +272,10 @@ static int rsync_module(int fd, int i)
|
||||
free(request);
|
||||
}
|
||||
|
||||
#if !TRIDGE
|
||||
/* don't allow the logs to be flooded too fast */
|
||||
if (verbose > 1) verbose = 1;
|
||||
#endif
|
||||
|
||||
argc -= optind;
|
||||
argp = argv + optind;
|
||||
@@ -276,6 +284,11 @@ static int rsync_module(int fd, int i)
|
||||
if (remote_version > 17 && am_sender)
|
||||
io_start_multiplex_out(fd);
|
||||
|
||||
if (!ret) {
|
||||
rprintf(FERROR,"Error parsing options (unsupported option?) - aborting\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
start_server(fd, fd, argc, argp);
|
||||
|
||||
return 0;
|
||||
@@ -375,7 +388,18 @@ int daemon_main(void)
|
||||
push_dir("/", 0);
|
||||
|
||||
if (is_a_socket(STDIN_FILENO)) {
|
||||
/* we are running via inetd */
|
||||
int i;
|
||||
|
||||
/* we are running via inetd - close off stdout and
|
||||
stderr so that library functions (and getopt) don't
|
||||
try to use them. Redirect them to /dev/null */
|
||||
for (i=1;i<3;i++) {
|
||||
close(i);
|
||||
open("/dev/null", O_RDWR);
|
||||
}
|
||||
|
||||
set_nonblocking(STDIN_FILENO);
|
||||
|
||||
return start_daemon(STDIN_FILENO);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ AC_HEADER_SYS_WAIT
|
||||
AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h unistd.h utime.h grp.h)
|
||||
AC_CHECK_HEADERS(compat.h sys/param.h ctype.h sys/wait.h sys/ioctl.h)
|
||||
AC_CHECK_HEADERS(sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h)
|
||||
AC_CHECK_HEADERS(glob.h)
|
||||
|
||||
AC_CHECK_SIZEOF(int)
|
||||
AC_CHECK_SIZEOF(long)
|
||||
@@ -40,7 +41,7 @@ echo no)
|
||||
AC_FUNC_MEMCMP
|
||||
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)
|
||||
AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime)
|
||||
AC_CHECK_FUNCS(memmove getopt_long lchown vsnprintf setsid glob strpbrk)
|
||||
|
||||
echo $ac_n "checking for working fnmatch... $ac_c"
|
||||
|
||||
53
flist.c
53
flist.c
@@ -49,6 +49,8 @@ extern int io_error;
|
||||
|
||||
static struct exclude_struct **local_exclude_list;
|
||||
|
||||
static void clean_flist(struct file_list *flist, int strip_root);
|
||||
|
||||
int link_stat(const char *Path, STRUCT_STAT *Buffer)
|
||||
{
|
||||
#if SUPPORT_LINKS
|
||||
@@ -92,7 +94,7 @@ static void send_directory(int f,struct file_list *flist,char *dir);
|
||||
static char *flist_dir;
|
||||
|
||||
|
||||
void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
|
||||
static void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
|
||||
{
|
||||
unsigned char flags;
|
||||
static time_t last_time;
|
||||
@@ -225,12 +227,6 @@ static void receive_file_entry(struct file_struct **fptr,
|
||||
|
||||
clean_fname(thisname);
|
||||
|
||||
if (relative_paths && thisname[0] == '/') {
|
||||
/* strip / off absolute paths in destination */
|
||||
memmove(thisname, thisname+1, strlen(thisname));
|
||||
if (!thisname[0]) strcpy(thisname,".");
|
||||
}
|
||||
|
||||
if ((p = strrchr(thisname,'/'))) {
|
||||
static char *lastdir;
|
||||
*p = 0;
|
||||
@@ -502,6 +498,8 @@ static void send_directory(int f,struct file_list *flist,char *dir)
|
||||
}
|
||||
p = fname + strlen(fname);
|
||||
|
||||
local_exclude_list = NULL;
|
||||
|
||||
if (cvs_exclude) {
|
||||
if (strlen(fname) + strlen(".cvsignore") <= MAXPATHLEN-1) {
|
||||
strcpy(p,".cvsignore");
|
||||
@@ -521,6 +519,10 @@ static void send_directory(int f,struct file_list *flist,char *dir)
|
||||
send_file_name(f,flist,fname,recurse,0);
|
||||
}
|
||||
|
||||
if (local_exclude_list) {
|
||||
add_exclude_list("!", &local_exclude_list, 0);
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
}
|
||||
|
||||
@@ -647,7 +649,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
|
||||
if (verbose && recurse && !am_server && f != -1)
|
||||
rprintf(FINFO,"done\n");
|
||||
|
||||
clean_flist(flist);
|
||||
clean_flist(flist, 0);
|
||||
|
||||
/* now send the uid/gid list. This was introduced in protocol
|
||||
version 15 */
|
||||
@@ -728,7 +730,7 @@ struct file_list *recv_file_list(int f)
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"received %d names\n",flist->count);
|
||||
|
||||
clean_flist(flist);
|
||||
clean_flist(flist, relative_paths);
|
||||
|
||||
if (verbose && recurse && !am_server) {
|
||||
rprintf(FINFO,"done\n");
|
||||
@@ -826,7 +828,7 @@ void flist_free(struct file_list *flist)
|
||||
* This routine ensures we don't have any duplicate names in our file list.
|
||||
* duplicate names can cause corruption because of the pipelining
|
||||
*/
|
||||
void clean_flist(struct file_list *flist)
|
||||
static void clean_flist(struct file_list *flist, int strip_root)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -848,6 +850,37 @@ void clean_flist(struct file_list *flist)
|
||||
free_file(flist->files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (strip_root) {
|
||||
/* we need to strip off the root directory in the case
|
||||
of relative paths, but this must be done _after_
|
||||
the sorting phase */
|
||||
for (i=0;i<flist->count;i++) {
|
||||
if (flist->files[i]->dirname &&
|
||||
flist->files[i]->dirname[0] == '/') {
|
||||
memmove(&flist->files[i]->dirname[0],
|
||||
&flist->files[i]->dirname[1],
|
||||
strlen(flist->files[i]->dirname));
|
||||
}
|
||||
|
||||
if (flist->files[i]->dirname &&
|
||||
!flist->files[i]->dirname[0]) {
|
||||
flist->files[i]->dirname = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (verbose <= 3) return;
|
||||
|
||||
for (i=0;i<flist->count;i++) {
|
||||
rprintf(FINFO,"[%d] i=%d %s %s mode=0%o len=%d\n",
|
||||
getpid(), i,
|
||||
flist->files[i]->dirname,
|
||||
flist->files[i]->basename,
|
||||
flist->files[i]->mode,
|
||||
flist->files[i]->length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
399
generator.c
Normal file
399
generator.c
Normal file
@@ -0,0 +1,399 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
|
||||
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 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int dry_run;
|
||||
extern int relative_paths;
|
||||
extern int preserve_links;
|
||||
extern int am_root;
|
||||
extern int preserve_devices;
|
||||
extern int preserve_hard_links;
|
||||
extern int update_only;
|
||||
extern int whole_file;
|
||||
extern int block_size;
|
||||
extern int csum_length;
|
||||
extern int ignore_times;
|
||||
extern int io_timeout;
|
||||
extern int remote_version;
|
||||
extern int always_checksum;
|
||||
|
||||
|
||||
/* choose whether to skip a particular file */
|
||||
static int skip_file(char *fname,
|
||||
struct file_struct *file, STRUCT_STAT *st)
|
||||
{
|
||||
if (st->st_size != file->length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if always checksum is set then we use the checksum instead
|
||||
of the file time to determine whether to sync */
|
||||
if (always_checksum && S_ISREG(st->st_mode)) {
|
||||
char sum[MD4_SUM_LENGTH];
|
||||
file_checksum(fname,sum,st->st_size);
|
||||
return (memcmp(sum,file->sum,csum_length) == 0);
|
||||
}
|
||||
|
||||
if (ignore_times) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (st->st_mtime == file->modtime);
|
||||
}
|
||||
|
||||
|
||||
/* use a larger block size for really big files */
|
||||
static int adapt_block_size(struct file_struct *file, int bsize)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (bsize != BLOCK_SIZE) return bsize;
|
||||
|
||||
ret = file->length / (10000); /* rough heuristic */
|
||||
ret = ret & ~15; /* multiple of 16 */
|
||||
if (ret < bsize) ret = bsize;
|
||||
if (ret > CHUNK_SIZE/2) ret = CHUNK_SIZE/2;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
send a sums struct down a fd
|
||||
*/
|
||||
static void send_sums(struct sum_struct *s,int f_out)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* tell the other guy how many we are going to be doing and how many
|
||||
bytes there are in the last chunk */
|
||||
write_int(f_out,s?s->count:0);
|
||||
write_int(f_out,s?s->n:block_size);
|
||||
write_int(f_out,s?s->remainder:0);
|
||||
if (s)
|
||||
for (i=0;i<s->count;i++) {
|
||||
write_int(f_out,s->sums[i].sum1);
|
||||
write_buf(f_out,s->sums[i].sum2,csum_length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
generate a stream of signatures/checksums that describe a buffer
|
||||
|
||||
generate approximately one checksum every n bytes
|
||||
*/
|
||||
static struct sum_struct *generate_sums(struct map_struct *buf,OFF_T len,int n)
|
||||
{
|
||||
int i;
|
||||
struct sum_struct *s;
|
||||
int count;
|
||||
int block_len = n;
|
||||
int remainder = (len%block_len);
|
||||
OFF_T offset = 0;
|
||||
|
||||
count = (len+(block_len-1))/block_len;
|
||||
|
||||
s = (struct sum_struct *)malloc(sizeof(*s));
|
||||
if (!s) out_of_memory("generate_sums");
|
||||
|
||||
s->count = count;
|
||||
s->remainder = remainder;
|
||||
s->n = n;
|
||||
s->flength = len;
|
||||
|
||||
if (count==0) {
|
||||
s->sums = NULL;
|
||||
return s;
|
||||
}
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"count=%d rem=%d n=%d flength=%d\n",
|
||||
s->count,s->remainder,s->n,(int)s->flength);
|
||||
|
||||
s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
|
||||
if (!s->sums) out_of_memory("generate_sums");
|
||||
|
||||
for (i=0;i<count;i++) {
|
||||
int n1 = MIN(len,n);
|
||||
char *map = map_ptr(buf,offset,n1);
|
||||
|
||||
s->sums[i].sum1 = get_checksum1(map,n1);
|
||||
get_checksum2(map,n1,s->sums[i].sum2);
|
||||
|
||||
s->sums[i].offset = offset;
|
||||
s->sums[i].len = n1;
|
||||
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);
|
||||
|
||||
len -= n1;
|
||||
offset += n1;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
{
|
||||
int fd;
|
||||
STRUCT_STAT st;
|
||||
struct map_struct *buf;
|
||||
struct sum_struct *s;
|
||||
int statret;
|
||||
struct file_struct *file = flist->files[i];
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"recv_generator(%s,%d)\n",fname,i);
|
||||
|
||||
statret = link_stat(fname,&st);
|
||||
|
||||
if (S_ISDIR(file->mode)) {
|
||||
if (dry_run) return;
|
||||
if (statret == 0 && !S_ISDIR(st.st_mode)) {
|
||||
if (do_unlink(fname) != 0) {
|
||||
rprintf(FERROR,"unlink %s : %s\n",fname,strerror(errno));
|
||||
return;
|
||||
}
|
||||
statret = -1;
|
||||
}
|
||||
if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
|
||||
if (!(relative_paths && errno==ENOENT &&
|
||||
create_directory_path(fname)==0 &&
|
||||
do_mkdir(fname,file->mode)==0)) {
|
||||
rprintf(FERROR,"mkdir %s : %s (2)\n",
|
||||
fname,strerror(errno));
|
||||
}
|
||||
}
|
||||
if (set_perms(fname,file,NULL,0) && verbose)
|
||||
rprintf(FINFO,"%s/\n",fname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (preserve_links && S_ISLNK(file->mode)) {
|
||||
#if SUPPORT_LINKS
|
||||
char lnk[MAXPATHLEN];
|
||||
int l;
|
||||
extern int safe_symlinks;
|
||||
|
||||
if (safe_symlinks && unsafe_symlink(file->link, fname)) {
|
||||
if (verbose) {
|
||||
rprintf(FINFO,"ignoring unsafe symlink %s -> %s\n",
|
||||
fname,file->link);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (statret == 0) {
|
||||
l = readlink(fname,lnk,MAXPATHLEN-1);
|
||||
if (l > 0) {
|
||||
lnk[l] = 0;
|
||||
if (strcmp(lnk,file->link) == 0) {
|
||||
set_perms(fname,file,&st,1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete_file(fname);
|
||||
if (do_symlink(file->link,fname) != 0) {
|
||||
rprintf(FERROR,"link %s -> %s : %s\n",
|
||||
fname,file->link,strerror(errno));
|
||||
} else {
|
||||
set_perms(fname,file,NULL,0);
|
||||
if (verbose) {
|
||||
rprintf(FINFO,"%s -> %s\n",
|
||||
fname,file->link);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_MKNOD
|
||||
if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
|
||||
if (statret != 0 ||
|
||||
st.st_mode != file->mode ||
|
||||
st.st_rdev != file->rdev) {
|
||||
delete_file(fname);
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
|
||||
fname,(int)file->mode,(int)file->rdev);
|
||||
if (do_mknod(fname,file->mode,file->rdev) != 0) {
|
||||
rprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
|
||||
} else {
|
||||
set_perms(fname,file,NULL,0);
|
||||
if (verbose)
|
||||
rprintf(FINFO,"%s\n",fname);
|
||||
}
|
||||
} else {
|
||||
set_perms(fname,file,&st,1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (preserve_hard_links && check_hard_link(file)) {
|
||||
if (verbose > 1)
|
||||
rprintf(FINFO,"%s is a hard link\n",f_name(file));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!S_ISREG(file->mode)) {
|
||||
rprintf(FINFO,"skipping non-regular file %s\n",fname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (statret == -1) {
|
||||
if (errno == ENOENT) {
|
||||
write_int(f_out,i);
|
||||
if (!dry_run) send_sums(NULL,f_out);
|
||||
} else {
|
||||
if (verbose > 1)
|
||||
rprintf(FERROR,"recv_generator failed to open %s\n",fname);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!S_ISREG(st.st_mode)) {
|
||||
if (delete_file(fname) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* now pretend the file didn't exist */
|
||||
write_int(f_out,i);
|
||||
if (!dry_run) send_sums(NULL,f_out);
|
||||
return;
|
||||
}
|
||||
|
||||
if (update_only && st.st_mtime > file->modtime) {
|
||||
if (verbose > 1)
|
||||
rprintf(FINFO,"%s is newer\n",fname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (skip_file(fname, file, &st)) {
|
||||
set_perms(fname,file,&st,1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dry_run) {
|
||||
write_int(f_out,i);
|
||||
return;
|
||||
}
|
||||
|
||||
if (whole_file) {
|
||||
write_int(f_out,i);
|
||||
send_sums(NULL,f_out);
|
||||
return;
|
||||
}
|
||||
|
||||
/* open the file */
|
||||
fd = open(fname,O_RDONLY);
|
||||
|
||||
if (fd == -1) {
|
||||
rprintf(FERROR,"failed to open %s : %s\n",fname,strerror(errno));
|
||||
rprintf(FERROR,"skipping %s\n",fname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (st.st_size > 0) {
|
||||
buf = map_file(fd,st.st_size);
|
||||
} else {
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"gen mapped %s of size %d\n",fname,(int)st.st_size);
|
||||
|
||||
s = generate_sums(buf,st.st_size,adapt_block_size(file, block_size));
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"sending sums for %d\n",i);
|
||||
|
||||
write_int(f_out,i);
|
||||
send_sums(s,f_out);
|
||||
|
||||
close(fd);
|
||||
if (buf) unmap_file(buf);
|
||||
|
||||
free_sums(s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
|
||||
{
|
||||
int i;
|
||||
int phase=0;
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"generator starting pid=%d count=%d\n",
|
||||
(int)getpid(),flist->count);
|
||||
|
||||
for (i = 0; i < flist->count; i++) {
|
||||
struct file_struct *file = flist->files[i];
|
||||
mode_t saved_mode = file->mode;
|
||||
if (!file->basename) continue;
|
||||
|
||||
/* we need to ensure that any directories we create have writeable
|
||||
permissions initially so that we can create the files within
|
||||
them. This is then fixed after the files are transferred */
|
||||
if (!am_root && S_ISDIR(file->mode)) {
|
||||
file->mode |= S_IWUSR; /* user write */
|
||||
}
|
||||
|
||||
recv_generator(local_name?local_name:f_name(file),
|
||||
flist,i,f);
|
||||
|
||||
file->mode = saved_mode;
|
||||
}
|
||||
|
||||
phase++;
|
||||
csum_length = SUM_LENGTH;
|
||||
ignore_times=1;
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"generate_files phase=%d\n",phase);
|
||||
|
||||
write_int(f,-1);
|
||||
|
||||
/* we expect to just sit around now, so don't exit on a
|
||||
timeout. If we really get a timeout then the other process should
|
||||
exit */
|
||||
io_timeout = 0;
|
||||
|
||||
if (remote_version >= 13) {
|
||||
/* in newer versions of the protocol the files can cycle through
|
||||
the system more than once to catch initial checksum errors */
|
||||
for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
|
||||
struct file_struct *file = flist->files[i];
|
||||
recv_generator(local_name?local_name:f_name(file),
|
||||
flist,i,f);
|
||||
}
|
||||
|
||||
phase++;
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"generate_files phase=%d\n",phase);
|
||||
|
||||
write_int(f,-1);
|
||||
}
|
||||
}
|
||||
26
io.c
26
io.c
@@ -24,6 +24,9 @@
|
||||
*/
|
||||
#include "rsync.h"
|
||||
|
||||
/* if no timeout is specified then use a 60 second select timeout */
|
||||
#define SELECT_TIMEOUT 60
|
||||
|
||||
static int io_multiplexing_out;
|
||||
static int io_multiplexing_in;
|
||||
static int multiplex_in_fd;
|
||||
@@ -67,6 +70,7 @@ 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
|
||||
@@ -75,7 +79,9 @@ 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;
|
||||
@@ -83,11 +89,10 @@ static int read_timeout(int fd, char *buf, int len)
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
tv.tv_sec = io_timeout;
|
||||
tv.tv_sec = io_timeout?io_timeout:SELECT_TIMEOUT;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (select(fd+1, &fds, NULL, NULL,
|
||||
io_timeout?&tv:NULL) != 1) {
|
||||
if (select(fd+1, &fds, NULL, NULL, &tv) != 1) {
|
||||
check_timeout();
|
||||
continue;
|
||||
}
|
||||
@@ -252,7 +257,9 @@ static void readfd(int fd,char *buffer,int N)
|
||||
continue;
|
||||
}
|
||||
|
||||
no_flush_read++;
|
||||
io_flush();
|
||||
no_flush_read--;
|
||||
|
||||
ret = read_unbuffered(fd,buffer + total,N-total);
|
||||
total += ret;
|
||||
@@ -318,7 +325,7 @@ 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;
|
||||
int reading=0;
|
||||
int blocked=0;
|
||||
|
||||
no_flush++;
|
||||
@@ -329,8 +336,9 @@ static void writefd_unbuffered(int fd,char *buf,int len)
|
||||
FD_SET(fd,&w_fds);
|
||||
fd_count = fd+1;
|
||||
|
||||
reading = (buffer_f_in != -1 &&
|
||||
read_buffer_len < MAX_READ_BUFFER);
|
||||
if (!no_flush_read) {
|
||||
reading = (buffer_f_in != -1);
|
||||
}
|
||||
|
||||
if (reading) {
|
||||
FD_SET(buffer_f_in,&r_fds);
|
||||
@@ -338,13 +346,13 @@ static void writefd_unbuffered(int fd,char *buf,int len)
|
||||
fd_count = buffer_f_in+1;
|
||||
}
|
||||
|
||||
tv.tv_sec = io_timeout;
|
||||
tv.tv_sec = io_timeout?io_timeout:SELECT_TIMEOUT;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
count = select(fd_count,
|
||||
reading?&r_fds:NULL,
|
||||
&w_fds,NULL,
|
||||
io_timeout?&tv:NULL);
|
||||
&tv);
|
||||
|
||||
if (count <= 0) {
|
||||
check_timeout();
|
||||
@@ -476,7 +484,7 @@ void write_buf(int f,char *buf,int len)
|
||||
}
|
||||
|
||||
/* write a string to the connection */
|
||||
void write_sbuf(int f,char *buf)
|
||||
static void write_sbuf(int f,char *buf)
|
||||
{
|
||||
write_buf(f, buf, strlen(buf));
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ typedef struct
|
||||
{
|
||||
char *motd_file;
|
||||
char *lock_file;
|
||||
char *log_file;
|
||||
int syslog_facility;
|
||||
int max_connections;
|
||||
char *socket_options;
|
||||
@@ -231,6 +232,7 @@ static struct parm_struct parm_table[] =
|
||||
{"lock file", P_STRING, P_GLOBAL, &Globals.lock_file, NULL, 0},
|
||||
{"syslog facility", P_ENUM, P_GLOBAL, &Globals.syslog_facility, enum_facilities,0},
|
||||
{"socket options", P_STRING, P_GLOBAL, &Globals.socket_options,NULL, 0},
|
||||
{"log file", P_STRING, P_GLOBAL, &Globals.log_file, NULL, 0},
|
||||
|
||||
{"name", P_STRING, P_LOCAL, &sDefault.name, NULL, 0},
|
||||
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, 0},
|
||||
@@ -295,6 +297,7 @@ static void init_locals(void)
|
||||
|
||||
FN_GLOBAL_STRING(lp_motd_file, &Globals.motd_file)
|
||||
FN_GLOBAL_STRING(lp_lock_file, &Globals.lock_file)
|
||||
FN_GLOBAL_STRING(lp_log_file, &Globals.log_file)
|
||||
FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
|
||||
FN_GLOBAL_INTEGER(lp_max_connections, &Globals.max_connections)
|
||||
FN_GLOBAL_INTEGER(lp_syslog_facility, &Globals.syslog_facility)
|
||||
|
||||
43
log.c
43
log.c
@@ -23,6 +23,40 @@
|
||||
*/
|
||||
#include "rsync.h"
|
||||
|
||||
static FILE *logfile;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
return the date and time as a string
|
||||
****************************************************************************/
|
||||
static char *timestring(void )
|
||||
{
|
||||
static char TimeBuf[200];
|
||||
time_t t = time(NULL);
|
||||
struct tm *tm = localtime(&t);
|
||||
|
||||
#ifdef HAVE_STRFTIME
|
||||
strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %T",tm);
|
||||
#else
|
||||
strlcpy(TimeBuf, asctime(tm), sizeof(TimeBuf)-1);
|
||||
#endif
|
||||
|
||||
if (TimeBuf[strlen(TimeBuf)-1] == '\n') {
|
||||
TimeBuf[strlen(TimeBuf)-1] = 0;
|
||||
}
|
||||
|
||||
return(TimeBuf);
|
||||
}
|
||||
|
||||
static void logit(int priority, char *buf)
|
||||
{
|
||||
if (logfile) {
|
||||
fprintf(logfile,"%s %s", timestring(), buf);
|
||||
fflush(logfile);
|
||||
} else {
|
||||
syslog(priority, "%s", buf);
|
||||
}
|
||||
}
|
||||
|
||||
void log_open(void)
|
||||
{
|
||||
@@ -33,6 +67,11 @@ void log_open(void)
|
||||
if (initialised) return;
|
||||
initialised = 1;
|
||||
|
||||
if (lp_log_file()) {
|
||||
logfile = fopen(lp_log_file(), "a");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef LOG_NDELAY
|
||||
options |= LOG_NDELAY;
|
||||
#endif
|
||||
@@ -44,7 +83,7 @@ void log_open(void)
|
||||
#endif
|
||||
|
||||
#ifndef LOG_NDELAY
|
||||
syslog(LOG_INFO,"rsyncd started\n");
|
||||
logit(LOG_INFO,"rsyncd started\n");
|
||||
#endif
|
||||
|
||||
/* this looks pointless, but it is needed in order for the
|
||||
@@ -86,7 +125,7 @@ void rprintf(int fd, const char *format, ...)
|
||||
|
||||
log_open();
|
||||
if (!io_multiplex_write(fd, buf, strlen(buf))) {
|
||||
syslog(priority, "%s", buf);
|
||||
logit(priority, buf);
|
||||
}
|
||||
|
||||
depth--;
|
||||
|
||||
22
main.c
22
main.c
@@ -250,15 +250,15 @@ 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);
|
||||
}
|
||||
|
||||
set_nonblocking(f_out);
|
||||
if (f_in != f_out)
|
||||
set_nonblocking(f_in);
|
||||
|
||||
send_files(flist,f_out,f_in);
|
||||
report(f_out);
|
||||
io_flush();
|
||||
@@ -288,6 +288,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
|
||||
if (f_in != f_out) close(f_out);
|
||||
|
||||
set_nonblocking(f_in);
|
||||
set_nonblocking(recv_pipe[1]);
|
||||
|
||||
recv_files(f_in,flist,local_name,recv_pipe[1]);
|
||||
report(f_in);
|
||||
@@ -301,6 +302,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
|
||||
if (f_in != f_out) close(f_in);
|
||||
|
||||
set_nonblocking(f_out);
|
||||
set_nonblocking(recv_pipe[0]);
|
||||
|
||||
io_start_buffering(f_out);
|
||||
|
||||
@@ -362,8 +364,12 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
|
||||
extern int cvs_exclude;
|
||||
extern int am_sender;
|
||||
|
||||
set_nonblocking(f_out);
|
||||
if (f_in != f_out)
|
||||
set_nonblocking(f_in);
|
||||
|
||||
setup_protocol(f_out, f_in);
|
||||
|
||||
|
||||
if (am_sender) {
|
||||
recv_exclude_list(f_in);
|
||||
if (cvs_exclude)
|
||||
@@ -538,7 +544,7 @@ static int start_client(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
RETSIGTYPE sigusr1_handler(int val) {
|
||||
static RETSIGTYPE sigusr1_handler(int val) {
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
@@ -566,7 +572,9 @@ int main(int argc,char *argv[])
|
||||
carried across */
|
||||
orig_umask = (int)umask(0);
|
||||
|
||||
parse_arguments(argc, argv);
|
||||
if (!parse_arguments(argc, argv)) {
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
2
md4.c
2
md4.c
@@ -102,7 +102,7 @@
|
||||
** Assumes X is an array of 16 ints.
|
||||
** The macro revx reverses the byte-ordering of the next word of X.
|
||||
*/
|
||||
void MDreverse(X)
|
||||
static void MDreverse(X)
|
||||
unsigned int32 *X;
|
||||
{ register unsigned int32 t;
|
||||
register unsigned int i;
|
||||
|
||||
13
options.c
13
options.c
@@ -120,9 +120,9 @@ void usage(int F)
|
||||
rprintf(F," -T --temp-dir=DIR create temporary files in directory DIR\n");
|
||||
rprintf(F," -z, --compress compress file data\n");
|
||||
rprintf(F," --exclude=PATTERN exclude file FILE\n");
|
||||
rprintf(F," --exclude-from=PATTERN exclude files listed in FILE\n");
|
||||
rprintf(F," --exclude-from=FILE exclude patterns listed in FILE\n");
|
||||
rprintf(F," --include=PATTERN don't exclude file FILE\n");
|
||||
rprintf(F," --include-from=PATTERN don't exclude files listed in FILE\n");
|
||||
rprintf(F," --include-from=FILE don't exclude patterns listed in FILE\n");
|
||||
rprintf(F," --suffix=SUFFIX override backup suffix\n");
|
||||
rprintf(F," --version print version number\n");
|
||||
rprintf(F," --daemon run as a rsync daemon\n");
|
||||
@@ -197,7 +197,8 @@ static struct option long_options[] = {
|
||||
{"port", 1, 0, OPT_PORT},
|
||||
{0,0,0,0}};
|
||||
|
||||
void parse_arguments(int argc, char *argv[])
|
||||
|
||||
int parse_arguments(int argc, char *argv[])
|
||||
{
|
||||
int opt;
|
||||
int option_index;
|
||||
@@ -301,7 +302,7 @@ void parse_arguments(int argc, char *argv[])
|
||||
preserve_hard_links=1;
|
||||
#else
|
||||
rprintf(FERROR,"ERROR: hard links not supported on this platform\n");
|
||||
exit_cleanup(1);
|
||||
return 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
@@ -412,10 +413,10 @@ void parse_arguments(int argc, char *argv[])
|
||||
break;
|
||||
|
||||
default:
|
||||
/* rprintf(FERROR,"bad option -%c\n",opt); */
|
||||
exit_cleanup(1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.0.19
|
||||
Version: 2.1.1
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.0.19.tar.gz
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.1.1.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
450
receiver.c
Normal file
450
receiver.c
Normal file
@@ -0,0 +1,450 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
|
||||
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 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int recurse;
|
||||
extern int delete_mode;
|
||||
extern int remote_version;
|
||||
extern int csum_length;
|
||||
extern struct stats stats;
|
||||
extern int dry_run;
|
||||
extern int am_server;
|
||||
extern int relative_paths;
|
||||
extern int preserve_hard_links;
|
||||
extern int cvs_exclude;
|
||||
extern int io_error;
|
||||
extern char *tmpdir;
|
||||
|
||||
|
||||
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.
|
||||
*/
|
||||
static int delete_already_done(struct file_list *flist,int j)
|
||||
{
|
||||
int i;
|
||||
STRUCT_STAT st;
|
||||
|
||||
if (link_stat(f_name(flist->files[j]), &st)) return 1;
|
||||
|
||||
for (i=0;i<dlist_len;i++) {
|
||||
if (st.st_ino == delete_list[i].inode &&
|
||||
st.st_dev == delete_list[i].dev)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void add_delete_entry(struct file_struct *file)
|
||||
{
|
||||
if (dlist_len == dlist_alloc_len) {
|
||||
dlist_alloc_len += 1024;
|
||||
delete_list = (struct delete_list *)Realloc(delete_list, sizeof(delete_list[0])*dlist_alloc_len);
|
||||
if (!delete_list) out_of_memory("add_delete_entry");
|
||||
}
|
||||
|
||||
delete_list[dlist_len].dev = file->dev;
|
||||
delete_list[dlist_len].inode = file->inode;
|
||||
dlist_len++;
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"added %s to delete list\n", f_name(file));
|
||||
}
|
||||
|
||||
static void delete_one(struct file_struct *f)
|
||||
{
|
||||
if (!S_ISDIR(f->mode)) {
|
||||
if (do_unlink(f_name(f)) != 0) {
|
||||
rprintf(FERROR,"unlink %s : %s\n",f_name(f),strerror(errno));
|
||||
} else if (verbose) {
|
||||
rprintf(FINFO,"deleting %s\n",f_name(f));
|
||||
}
|
||||
} else {
|
||||
if (do_rmdir(f_name(f)) != 0) {
|
||||
if (errno != ENOTEMPTY && errno != EEXIST)
|
||||
rprintf(FERROR,"rmdir %s : %s\n",f_name(f),strerror(errno));
|
||||
} else if (verbose) {
|
||||
rprintf(FINFO,"deleting directory %s\n",f_name(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)
|
||||
{
|
||||
struct file_list *local_file_list;
|
||||
int i, j;
|
||||
char *name;
|
||||
|
||||
if (cvs_exclude)
|
||||
add_cvs_excludes();
|
||||
|
||||
if (io_error) {
|
||||
rprintf(FINFO,"IO error encountered - skipping file deletion\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (j=0;j<flist->count;j++) {
|
||||
if (!S_ISDIR(flist->files[j]->mode) ||
|
||||
!(flist->files[j]->flags & FLAG_DELETE)) continue;
|
||||
|
||||
if (remote_version < 19 &&
|
||||
delete_already_done(flist, j)) continue;
|
||||
|
||||
name = strdup(f_name(flist->files[j]));
|
||||
|
||||
if (!(local_file_list = send_file_list(-1,1,&name))) {
|
||||
free(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (verbose > 1)
|
||||
rprintf(FINFO,"deleting in %s\n", name);
|
||||
|
||||
for (i=local_file_list->count-1;i>=0;i--) {
|
||||
if (!local_file_list->files[i]->basename) continue;
|
||||
if (remote_version < 19 &&
|
||||
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]);
|
||||
}
|
||||
}
|
||||
flist_free(local_file_list);
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int get_tmpname(char *fnametmp, char *fname)
|
||||
{
|
||||
char *f;
|
||||
|
||||
/* open tmp file */
|
||||
if (tmpdir) {
|
||||
f = strrchr(fname,'/');
|
||||
if (f == NULL)
|
||||
f = fname;
|
||||
else
|
||||
f++;
|
||||
if (strlen(tmpdir)+strlen(f)+10 > MAXPATHLEN) {
|
||||
rprintf(FERROR,"filename too long\n");
|
||||
return 0;
|
||||
}
|
||||
slprintf(fnametmp,MAXPATHLEN-1, "%s/.%s.XXXXXX",tmpdir,f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
f = strrchr(fname,'/');
|
||||
|
||||
if (strlen(fname)+9 > MAXPATHLEN) {
|
||||
rprintf(FERROR,"filename too long\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (f) {
|
||||
*f = 0;
|
||||
slprintf(fnametmp,MAXPATHLEN-1,"%s/.%s.XXXXXX",
|
||||
fname,f+1);
|
||||
*f = '/';
|
||||
} else {
|
||||
slprintf(fnametmp,MAXPATHLEN-1,".%s.XXXXXX",fname);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
|
||||
OFF_T total_size)
|
||||
{
|
||||
int i,n,remainder,len,count;
|
||||
OFF_T offset = 0;
|
||||
OFF_T offset2;
|
||||
char *data;
|
||||
static char file_sum1[MD4_SUM_LENGTH];
|
||||
static char file_sum2[MD4_SUM_LENGTH];
|
||||
char *map=NULL;
|
||||
|
||||
count = read_int(f_in);
|
||||
n = read_int(f_in);
|
||||
remainder = read_int(f_in);
|
||||
|
||||
sum_init();
|
||||
|
||||
for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) {
|
||||
|
||||
show_progress(offset, total_size);
|
||||
|
||||
if (i > 0) {
|
||||
extern int cleanup_got_literal;
|
||||
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,"data recv %d at %d\n",
|
||||
i,(int)offset);
|
||||
}
|
||||
|
||||
stats.literal_data += i;
|
||||
cleanup_got_literal = 1;
|
||||
|
||||
sum_update(data,i);
|
||||
|
||||
if (fd != -1 && write_file(fd,data,i) != i) {
|
||||
rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
offset += i;
|
||||
continue;
|
||||
}
|
||||
|
||||
i = -(i+1);
|
||||
offset2 = i*n;
|
||||
len = n;
|
||||
if (i == count-1 && remainder != 0)
|
||||
len = remainder;
|
||||
|
||||
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);
|
||||
|
||||
map = map_ptr(buf,offset2,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",
|
||||
fname,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
offset += len;
|
||||
}
|
||||
|
||||
end_progress();
|
||||
|
||||
if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
|
||||
rprintf(FERROR,"write failed on %s : %s\n",
|
||||
fname,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
sum_end(file_sum1);
|
||||
|
||||
if (remote_version >= 14) {
|
||||
read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO,"got file_sum\n");
|
||||
}
|
||||
if (fd != -1 &&
|
||||
memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
{
|
||||
int fd1,fd2;
|
||||
STRUCT_STAT st;
|
||||
char *fname;
|
||||
char fnametmp[MAXPATHLEN];
|
||||
struct map_struct *buf;
|
||||
int i;
|
||||
struct file_struct *file;
|
||||
int phase=0;
|
||||
int recv_ok;
|
||||
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO,"recv_files(%d) starting\n",flist->count);
|
||||
}
|
||||
|
||||
if (recurse && delete_mode && !local_name && flist->count>0) {
|
||||
delete_files(flist);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
cleanup_disable();
|
||||
|
||||
i = read_int(f_in);
|
||||
if (i == -1) {
|
||||
if (phase==0 && remote_version >= 13) {
|
||||
phase++;
|
||||
csum_length = SUM_LENGTH;
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"recv_files phase=%d\n",phase);
|
||||
write_int(f_gen,-1);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < 0 || i >= flist->count) {
|
||||
rprintf(FERROR,"Invalid file index %d in recv_files (count=%d)\n",
|
||||
i, flist->count);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
file = flist->files[i];
|
||||
fname = f_name(file);
|
||||
|
||||
stats.num_transferred_files++;
|
||||
stats.total_transferred_size += file->length;
|
||||
|
||||
if (local_name)
|
||||
fname = local_name;
|
||||
|
||||
if (dry_run) {
|
||||
if (!am_server && verbose)
|
||||
rprintf(FINFO,"%s\n",fname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"recv_files(%s)\n",fname);
|
||||
|
||||
/* open the file */
|
||||
fd1 = open(fname,O_RDONLY);
|
||||
|
||||
if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
|
||||
rprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno));
|
||||
receive_data(f_in,NULL,-1,NULL,file->length);
|
||||
close(fd1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fd1 != -1 && !S_ISREG(st.st_mode)) {
|
||||
rprintf(FERROR,"%s : not a regular file (recv_files)\n",fname);
|
||||
receive_data(f_in,NULL,-1,NULL,file->length);
|
||||
close(fd1);
|
||||
continue;
|
||||
}
|
||||
|
||||
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",fname,(int)st.st_size);
|
||||
} else {
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
if (!get_tmpname(fnametmp,fname)) {
|
||||
if (buf) unmap_file(buf);
|
||||
if (fd1 != -1) close(fd1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (NULL == do_mktemp(fnametmp)) {
|
||||
rprintf(FERROR,"mktemp %s failed\n",fnametmp);
|
||||
receive_data(f_in,buf,-1,NULL,file->length);
|
||||
if (buf) unmap_file(buf);
|
||||
if (fd1 != -1) close(fd1);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we initially set the perms without the
|
||||
setuid/setgid bits to ensure that there is no race
|
||||
condition. They are then correctly updated after
|
||||
the lchown. Thanks to snabb@epipe.fi for pointing
|
||||
this out */
|
||||
fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
|
||||
file->mode & ACCESSPERMS);
|
||||
|
||||
if (fd2 == -1 && relative_paths && errno == ENOENT &&
|
||||
create_directory_path(fnametmp) == 0) {
|
||||
fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
|
||||
file->mode & ACCESSPERMS);
|
||||
}
|
||||
if (fd2 == -1) {
|
||||
rprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
|
||||
receive_data(f_in,buf,-1,NULL,file->length);
|
||||
if (buf) unmap_file(buf);
|
||||
if (fd1 != -1) close(fd1);
|
||||
continue;
|
||||
}
|
||||
|
||||
cleanup_set(fnametmp, fname, file, buf, fd1, fd2);
|
||||
|
||||
if (!am_server && verbose)
|
||||
rprintf(FINFO,"%s\n",fname);
|
||||
|
||||
/* recv file data */
|
||||
recv_ok = receive_data(f_in,buf,fd2,fname,file->length);
|
||||
|
||||
if (buf) unmap_file(buf);
|
||||
if (fd1 != -1) {
|
||||
close(fd1);
|
||||
}
|
||||
close(fd2);
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"renaming %s to %s\n",fnametmp,fname);
|
||||
|
||||
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",
|
||||
fname);
|
||||
} else {
|
||||
if (verbose > 1)
|
||||
rprintf(FINFO,"redoing %s(%d)\n",fname,i);
|
||||
write_int(f_gen,i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (preserve_hard_links)
|
||||
do_hard_links(flist);
|
||||
|
||||
/* now we need to fix any directory permissions that were
|
||||
modified during the transfer */
|
||||
for (i = 0; i < flist->count; i++) {
|
||||
file = flist->files[i];
|
||||
if (!file->basename || !S_ISDIR(file->mode)) continue;
|
||||
recv_generator(f_name(file),flist,i,-1);
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"recv_files finished\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
2
rsync.h
2
rsync.h
@@ -169,7 +169,7 @@
|
||||
#include "lib/fnmatch.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GLOB
|
||||
#ifdef HAVE_GLOB_H
|
||||
#include <glob.h>
|
||||
#endif
|
||||
|
||||
|
||||
4
rsync.yo
4
rsync.yo
@@ -9,9 +9,9 @@ rsync [options] path [user@]host:path
|
||||
|
||||
rsync [options] path path
|
||||
|
||||
rsync [options] [user@]host::path path
|
||||
rsync [options] [user@]host::module[/path] path
|
||||
|
||||
rsync [options] path [user@]host::path
|
||||
rsync [options] path [user@]host::module[/path]
|
||||
|
||||
manpagedescription()
|
||||
|
||||
|
||||
@@ -91,6 +91,11 @@ support the "max connections" option. The rsync server uses record
|
||||
locking on this file to ensure that the max connections limit is not
|
||||
exceeded. The default is tt(/var/run/rsyncd.lock).
|
||||
|
||||
dit(bf(log file)) The "log file" option tells the rsync daemon to log
|
||||
messages to that file rather than using syslog. This is particularly
|
||||
useful on systems (such as AIX) where syslog() doesn't work for
|
||||
chrooted programs like rsync.
|
||||
|
||||
dit(bf(syslog facility)) The "syslog facility" option allows you to
|
||||
specify the syslog facility name to use when logging messages from the
|
||||
rsync server. You may use any standard syslog facility name which is
|
||||
|
||||
220
sender.c
Normal file
220
sender.c
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
|
||||
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 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int remote_version;
|
||||
extern int csum_length;
|
||||
extern struct stats stats;
|
||||
extern int io_error;
|
||||
extern int dry_run;
|
||||
extern int am_server;
|
||||
|
||||
|
||||
/*
|
||||
receive the checksums for a buffer
|
||||
*/
|
||||
static struct sum_struct *receive_sums(int f)
|
||||
{
|
||||
struct sum_struct *s;
|
||||
int i;
|
||||
OFF_T offset = 0;
|
||||
|
||||
s = (struct sum_struct *)malloc(sizeof(*s));
|
||||
if (!s) out_of_memory("receive_sums");
|
||||
|
||||
s->count = read_int(f);
|
||||
s->n = read_int(f);
|
||||
s->remainder = read_int(f);
|
||||
s->sums = NULL;
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"count=%d n=%d rem=%d\n",
|
||||
s->count,s->n,s->remainder);
|
||||
|
||||
if (s->count == 0)
|
||||
return(s);
|
||||
|
||||
s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
|
||||
if (!s->sums) out_of_memory("receive_sums");
|
||||
|
||||
for (i=0;i<s->count;i++) {
|
||||
s->sums[i].sum1 = read_int(f);
|
||||
read_buf(f,s->sums[i].sum2,csum_length);
|
||||
|
||||
s->sums[i].offset = offset;
|
||||
s->sums[i].i = i;
|
||||
|
||||
if (i == s->count-1 && s->remainder != 0) {
|
||||
s->sums[i].len = s->remainder;
|
||||
} else {
|
||||
s->sums[i].len = s->n;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
s->flength = offset;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void send_files(struct file_list *flist,int f_out,int f_in)
|
||||
{
|
||||
int fd;
|
||||
struct sum_struct *s;
|
||||
struct map_struct *buf;
|
||||
STRUCT_STAT st;
|
||||
char fname[MAXPATHLEN];
|
||||
int i;
|
||||
struct file_struct *file;
|
||||
int phase = 0;
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"send_files starting\n");
|
||||
|
||||
setup_readbuffer(f_in);
|
||||
|
||||
while (1) {
|
||||
int offset=0;
|
||||
|
||||
i = read_int(f_in);
|
||||
if (i == -1) {
|
||||
if (phase==0 && remote_version >= 13) {
|
||||
phase++;
|
||||
csum_length = SUM_LENGTH;
|
||||
write_int(f_out,-1);
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"send_files phase=%d\n",phase);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < 0 || i >= flist->count) {
|
||||
rprintf(FERROR,"Invalid file index %d (count=%d)\n",
|
||||
i, flist->count);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
file = flist->files[i];
|
||||
|
||||
stats.num_transferred_files++;
|
||||
stats.total_transferred_size += file->length;
|
||||
|
||||
fname[0] = 0;
|
||||
if (file->basedir) {
|
||||
strlcpy(fname,file->basedir,MAXPATHLEN-1);
|
||||
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);
|
||||
offset = strlen(file->basedir)+1;
|
||||
}
|
||||
strlcat(fname,f_name(file),MAXPATHLEN-strlen(fname));
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"send_files(%d,%s)\n",i,fname);
|
||||
|
||||
if (dry_run) {
|
||||
if (!am_server && verbose)
|
||||
rprintf(FINFO,"%s\n",fname);
|
||||
write_int(f_out,i);
|
||||
continue;
|
||||
}
|
||||
|
||||
s = receive_sums(f_in);
|
||||
if (!s) {
|
||||
io_error = 1;
|
||||
rprintf(FERROR,"receive_sums failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fd = open(fname,O_RDONLY);
|
||||
if (fd == -1) {
|
||||
io_error = 1;
|
||||
rprintf(FERROR,"send_files failed to open %s: %s\n",
|
||||
fname,strerror(errno));
|
||||
free_sums(s);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* map the local file */
|
||||
if (do_fstat(fd,&st) != 0) {
|
||||
io_error = 1;
|
||||
rprintf(FERROR,"fstat failed : %s\n",strerror(errno));
|
||||
free_sums(s);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (st.st_size > 0) {
|
||||
buf = map_file(fd,st.st_size);
|
||||
} else {
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"send_files mapped %s of size %d\n",
|
||||
fname,(int)st.st_size);
|
||||
|
||||
write_int(f_out,i);
|
||||
|
||||
write_int(f_out,s->count);
|
||||
write_int(f_out,s->n);
|
||||
write_int(f_out,s->remainder);
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"calling match_sums %s\n",fname);
|
||||
|
||||
if (!am_server && verbose)
|
||||
rprintf(FINFO,"%s\n",fname+offset);
|
||||
|
||||
match_sums(f_out,s,buf,st.st_size);
|
||||
|
||||
if (buf) unmap_file(buf);
|
||||
close(fd);
|
||||
|
||||
free_sums(s);
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"sender finished %s\n",fname);
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"send files finished\n");
|
||||
|
||||
match_report();
|
||||
|
||||
write_int(f_out,-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
35
socket.c
35
socket.c
@@ -54,6 +54,8 @@ int open_socket_out(char *host, int port)
|
||||
return -1;
|
||||
}
|
||||
|
||||
set_nonblocking(res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -110,9 +112,9 @@ determine if a file descriptor is in fact a socket
|
||||
****************************************************************************/
|
||||
int is_a_socket(int fd)
|
||||
{
|
||||
int v,l;
|
||||
l = sizeof(int);
|
||||
return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
|
||||
int v,l;
|
||||
l = sizeof(int);
|
||||
return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -165,6 +167,8 @@ void start_accept_loop(int port, int (*fn)(int ))
|
||||
if (fork()==0) {
|
||||
close(s);
|
||||
|
||||
set_nonblocking(fd);
|
||||
|
||||
_exit(fn(fd));
|
||||
}
|
||||
|
||||
@@ -281,27 +285,30 @@ become a daemon, discarding the controlling terminal
|
||||
****************************************************************************/
|
||||
void become_daemon(void)
|
||||
{
|
||||
if (fork())
|
||||
int i;
|
||||
|
||||
if (fork()) {
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
/* detach from the terminal */
|
||||
#ifdef HAVE_SETSID
|
||||
setsid();
|
||||
#else
|
||||
#ifdef TIOCNOTTY
|
||||
{
|
||||
int i = open("/dev/tty", O_RDWR);
|
||||
if (i >= 0)
|
||||
{
|
||||
ioctl(i, (int) TIOCNOTTY, (char *)0);
|
||||
close(i);
|
||||
}
|
||||
i = open("/dev/tty", O_RDWR);
|
||||
if (i >= 0) {
|
||||
ioctl(i, (int) TIOCNOTTY, (char *)0);
|
||||
close(i);
|
||||
}
|
||||
#endif /* TIOCNOTTY */
|
||||
#endif
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
/* make sure that stdin, stdout an stderr don't stuff things
|
||||
up (library functions, for example) */
|
||||
for (i=0;i<3;i++) {
|
||||
close(i);
|
||||
open("/dev/null", O_RDWR);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
||||
3
token.c
3
token.c
@@ -366,8 +366,7 @@ recv_deflated_token(int f, char **data)
|
||||
* put the data corresponding to a token that we've just returned
|
||||
* from recv_deflated_token into the decompressor's history buffer.
|
||||
*/
|
||||
void
|
||||
see_deflate_token(char *buf, int len)
|
||||
static void see_deflate_token(char *buf, int len)
|
||||
{
|
||||
int r, blklen;
|
||||
unsigned char hdr[5];
|
||||
|
||||
17
util.c
17
util.c
@@ -98,6 +98,9 @@ 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;
|
||||
}
|
||||
@@ -250,7 +253,7 @@ static int full_write(int desc, char *ptr, int len)
|
||||
for an error.
|
||||
|
||||
derived from GNU C's cccp.c. */
|
||||
int safe_read(int desc, char *ptr, int len)
|
||||
static int safe_read(int desc, char *ptr, int len)
|
||||
{
|
||||
int n_chars;
|
||||
|
||||
@@ -291,7 +294,7 @@ int copy_file(char *source, char *dest, mode_t mode)
|
||||
}
|
||||
|
||||
ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
|
||||
if (ofd < 0) {
|
||||
if (ofd == -1) {
|
||||
rprintf(FERROR,"open %s: %s\n",
|
||||
dest,strerror(errno));
|
||||
close(ifd);
|
||||
@@ -407,14 +410,6 @@ int name_to_gid(char *name, gid_t *gid)
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
check if a process exists.
|
||||
****************************************************************************/
|
||||
int process_exists(int pid)
|
||||
{
|
||||
return(kill(pid,0) == 0 || errno != ESRCH);
|
||||
}
|
||||
|
||||
/* lock a byte range in a open file */
|
||||
int lock_range(int fd, int offset, int len)
|
||||
{
|
||||
@@ -432,7 +427,7 @@ int lock_range(int fd, int offset, int len)
|
||||
|
||||
static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
|
||||
{
|
||||
#ifndef HAVE_GLOB
|
||||
#if !(defined(HAVE_GLOB) && defined(HAVE_GLOB_H))
|
||||
if (!*s) s = ".";
|
||||
argv[*argc] = strdup(s);
|
||||
(*argc)++;
|
||||
|
||||
Reference in New Issue
Block a user