mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-10-20 04:51:58 -04:00
- hard links
- better sparse handling - FERROR and FINFO
This commit is contained in:
1 parent
d5ee1f8e7a
commit
dc5ddbccac
13 files changed
+445
-224
No files matched your search
+1
-1
@@ -21,7 +21,7 @@ SHELL=/bin/sh
|
||||
|
||||
LIBOBJ=lib/getopt.o lib/fnmatch.o
|
||||
OBJS1=rsync.o exclude.o util.o md4.o main.o checksum.o match.o
|
||||
OBJS=$(OBJS1) flist.o io.o compat.o $(LIBOBJ)
|
||||
OBJS=$(OBJS1) flist.o io.o compat.o hlink.o $(LIBOBJ)
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) -c $*.c -o $*.o
|
||||
|
||||
@@ -29,11 +29,13 @@ Here is a brief description of available options:
|
||||
-b, --backup make backups (default ~ extension)
|
||||
-u, --update update only (don't overwrite newer files)
|
||||
-l, --links preserve soft links
|
||||
-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
|
||||
-x, --one-file-system don't cross filesystem boundaries
|
||||
-B, --block-size SIZE checksum blocking size
|
||||
@@ -45,10 +47,10 @@ Here is a brief description of available options:
|
||||
--exclude FILE exclude file FILE
|
||||
--exclude-from FILE exclude files listed in FILE
|
||||
--suffix SUFFIX override backup suffix
|
||||
--csum-length LENGTH set the checksum length
|
||||
--version print version number
|
||||
|
||||
|
||||
|
||||
SETUP
|
||||
-----
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ void send_file_entry_v10(struct file_struct *file,int f)
|
||||
{
|
||||
unsigned char flags;
|
||||
static mode_t last_mode=0;
|
||||
static dev_t last_dev=0;
|
||||
static dev_t last_rdev=0;
|
||||
static uid_t last_uid=0;
|
||||
static gid_t last_gid=0;
|
||||
static char lastdir[MAXPATHLEN]="";
|
||||
@@ -59,7 +59,7 @@ void send_file_entry_v10(struct file_struct *file,int f)
|
||||
flags = FILE_VALID;
|
||||
|
||||
if (file->mode == last_mode) flags |= SAME_MODE;
|
||||
if (file->dev == last_dev) flags |= SAME_DEV;
|
||||
if (file->rdev == last_rdev) flags |= SAME_RDEV;
|
||||
if (file->uid == last_uid) flags |= SAME_UID;
|
||||
if (file->gid == last_gid) flags |= SAME_GID;
|
||||
|
||||
@@ -84,8 +84,8 @@ void send_file_entry_v10(struct file_struct *file,int f)
|
||||
write_int(f,(int)file->uid);
|
||||
if (preserve_gid && !(flags & SAME_GID))
|
||||
write_int(f,(int)file->gid);
|
||||
if (preserve_devices && IS_DEVICE(file->mode) && !(flags & SAME_DEV))
|
||||
write_int(f,(int)file->dev);
|
||||
if (preserve_devices && IS_DEVICE(file->mode) && !(flags & SAME_RDEV))
|
||||
write_int(f,(int)file->rdev);
|
||||
|
||||
#if SUPPORT_LINKS
|
||||
if (preserve_links && S_ISLNK(file->mode)) {
|
||||
@@ -99,7 +99,7 @@ void send_file_entry_v10(struct file_struct *file,int f)
|
||||
}
|
||||
|
||||
last_mode = file->mode;
|
||||
last_dev = file->dev;
|
||||
last_rdev = file->rdev;
|
||||
last_uid = file->uid;
|
||||
last_gid = file->gid;
|
||||
p = strrchr(file->name,'/');
|
||||
@@ -118,7 +118,7 @@ void receive_file_entry_v10(struct file_struct *file,
|
||||
unsigned char flags,int f)
|
||||
{
|
||||
static mode_t last_mode=0;
|
||||
static dev_t last_dev=0;
|
||||
static dev_t last_rdev=0;
|
||||
static uid_t last_uid=0;
|
||||
static gid_t last_gid=0;
|
||||
static char lastdir[MAXPATHLEN]="";
|
||||
@@ -148,7 +148,7 @@ void receive_file_entry_v10(struct file_struct *file,
|
||||
if (preserve_gid)
|
||||
file->gid = (flags & SAME_GID) ? last_gid : (gid_t)read_int(f);
|
||||
if (preserve_devices && IS_DEVICE(file->mode))
|
||||
file->dev = (flags & SAME_DEV) ? last_dev : (dev_t)read_int(f);
|
||||
file->rdev = (flags & SAME_RDEV) ? last_rdev : (dev_t)read_int(f);
|
||||
|
||||
#if SUPPORT_LINKS
|
||||
if (preserve_links && S_ISLNK(file->mode)) {
|
||||
@@ -164,7 +164,7 @@ void receive_file_entry_v10(struct file_struct *file,
|
||||
read_buf(f,file->sum,csum_length);
|
||||
|
||||
last_mode = file->mode;
|
||||
last_dev = file->dev;
|
||||
last_rdev = file->rdev;
|
||||
last_uid = file->uid;
|
||||
last_gid = file->gid;
|
||||
p = strrchr(file->name,'/');
|
||||
|
||||
+2
-1
@@ -28,6 +28,7 @@ AC_TYPE_OFF_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_PID_T
|
||||
AC_STRUCT_ST_RDEV
|
||||
AC_CHECK_TYPE(ino_t,unsigned)
|
||||
|
||||
echo $ac_n "checking for errno in errno.h... $ac_c"
|
||||
AC_TRY_COMPILE([#include <errno.h>],[int i = errno],
|
||||
@@ -38,7 +39,7 @@ AC_FUNC_MEMCMP
|
||||
AC_FUNC_MMAP
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_CHECK_FUNCS(waitpid strtok pipe getcwd mkdir strdup strerror chown chmod mknod)
|
||||
AC_CHECK_FUNCS(fchmod fstat strchr bcopy bzero readlink utime utimes)
|
||||
AC_CHECK_FUNCS(fchmod fstat strchr bcopy bzero readlink link utime utimes)
|
||||
AC_CHECK_FUNCS(memmove getopt_long)
|
||||
|
||||
echo $ac_n "checking for working fnmatch... $ac_c"
|
||||
|
||||
@@ -86,7 +86,7 @@ void add_exclude_list(char *pattern,char ***list)
|
||||
|
||||
if (strcmp(pattern,"!") == 0) {
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"clearing exclude list\n");
|
||||
fprintf(FERROR,"clearing exclude list\n");
|
||||
while ((len)--)
|
||||
free((*list)[len]);
|
||||
free((*list));
|
||||
@@ -104,7 +104,7 @@ void add_exclude_list(char *pattern,char ***list)
|
||||
out_of_memory("add_exclude");
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"add_exclude(%s)\n",pattern);
|
||||
fprintf(FERROR,"add_exclude(%s)\n",pattern);
|
||||
|
||||
(*list)[len+1] = NULL;
|
||||
}
|
||||
@@ -121,7 +121,7 @@ char **make_exclude_list(char *fname,char **list1,int fatal)
|
||||
char line[MAXPATHLEN];
|
||||
if (!f) {
|
||||
if (fatal) {
|
||||
fprintf(stderr,"%s : %s\n",fname,strerror(errno));
|
||||
fprintf(FERROR,"%s : %s\n",fname,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
return list;
|
||||
|
||||
@@ -33,6 +33,7 @@ extern int cvs_exclude;
|
||||
extern int one_file_system;
|
||||
extern int make_backups;
|
||||
extern int preserve_links;
|
||||
extern int preserve_hard_links;
|
||||
extern int preserve_perms;
|
||||
extern int preserve_devices;
|
||||
extern int preserve_uid;
|
||||
@@ -52,7 +53,7 @@ static int match_file_name(char *fname,struct stat *st)
|
||||
{
|
||||
if (check_exclude(fname,local_exclude_list)) {
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"excluding file %s\n",fname);
|
||||
fprintf(FERROR,"excluding file %s\n",fname);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -83,7 +84,7 @@ void send_file_entry_v11(struct file_struct *file,int f)
|
||||
unsigned char flags;
|
||||
static time_t last_time=0;
|
||||
static mode_t last_mode=0;
|
||||
static dev_t last_dev=0;
|
||||
static dev_t last_rdev=0;
|
||||
static uid_t last_uid=0;
|
||||
static gid_t last_gid=0;
|
||||
static char lastname[MAXPATHLEN]="";
|
||||
@@ -99,7 +100,7 @@ void send_file_entry_v11(struct file_struct *file,int f)
|
||||
flags = FILE_VALID;
|
||||
|
||||
if (file->mode == last_mode) flags |= SAME_MODE;
|
||||
if (file->dev == last_dev) flags |= SAME_DEV;
|
||||
if (file->rdev == last_rdev) flags |= SAME_RDEV;
|
||||
if (file->uid == last_uid) flags |= SAME_UID;
|
||||
if (file->gid == last_gid) flags |= SAME_GID;
|
||||
if (file->modtime == last_time) flags |= SAME_TIME;
|
||||
@@ -128,8 +129,8 @@ void send_file_entry_v11(struct file_struct *file,int f)
|
||||
write_int(f,(int)file->uid);
|
||||
if (preserve_gid && !(flags & SAME_GID))
|
||||
write_int(f,(int)file->gid);
|
||||
if (preserve_devices && IS_DEVICE(file->mode) && !(flags & SAME_DEV))
|
||||
write_int(f,(int)file->dev);
|
||||
if (preserve_devices && IS_DEVICE(file->mode) && !(flags & SAME_RDEV))
|
||||
write_int(f,(int)file->rdev);
|
||||
|
||||
#if SUPPORT_LINKS
|
||||
if (preserve_links && S_ISLNK(file->mode)) {
|
||||
@@ -138,12 +139,19 @@ void send_file_entry_v11(struct file_struct *file,int f)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SUPPORT_HARD_LINKS
|
||||
if (preserve_hard_links && S_ISREG(file->mode)) {
|
||||
write_int(f,file->dev);
|
||||
write_int(f,file->inode);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (always_checksum) {
|
||||
write_buf(f,file->sum,csum_length);
|
||||
}
|
||||
|
||||
last_mode = file->mode;
|
||||
last_dev = file->dev;
|
||||
last_rdev = file->rdev;
|
||||
last_uid = file->uid;
|
||||
last_gid = file->gid;
|
||||
last_time = file->modtime;
|
||||
@@ -159,7 +167,7 @@ void receive_file_entry_v11(struct file_struct *file,
|
||||
{
|
||||
static mode_t last_time=0;
|
||||
static mode_t last_mode=0;
|
||||
static dev_t last_dev=0;
|
||||
static dev_t last_rdev=0;
|
||||
static uid_t last_uid=0;
|
||||
static gid_t last_gid=0;
|
||||
static char lastname[MAXPATHLEN]="";
|
||||
@@ -173,6 +181,8 @@ void receive_file_entry_v11(struct file_struct *file,
|
||||
else
|
||||
l2 = read_byte(f);
|
||||
|
||||
bzero((char *)file,sizeof(*file));
|
||||
|
||||
file->name = (char *)malloc(l1+l2+1);
|
||||
if (!file->name) out_of_memory("receive_file_entry");
|
||||
|
||||
@@ -188,7 +198,7 @@ void receive_file_entry_v11(struct file_struct *file,
|
||||
if (preserve_gid)
|
||||
file->gid = (flags & SAME_GID) ? last_gid : (gid_t)read_int(f);
|
||||
if (preserve_devices && IS_DEVICE(file->mode))
|
||||
file->dev = (flags & SAME_DEV) ? last_dev : (dev_t)read_int(f);
|
||||
file->rdev = (flags & SAME_RDEV) ? last_rdev : (dev_t)read_int(f);
|
||||
|
||||
#if SUPPORT_LINKS
|
||||
if (preserve_links && S_ISLNK(file->mode)) {
|
||||
@@ -199,12 +209,19 @@ void receive_file_entry_v11(struct file_struct *file,
|
||||
file->link[l] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SUPPORT_HARD_LINKS
|
||||
if (preserve_hard_links && S_ISREG(file->mode)) {
|
||||
file->dev = read_int(f);
|
||||
file->inode = read_int(f);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (always_checksum)
|
||||
read_buf(f,file->sum,csum_length);
|
||||
|
||||
last_mode = file->mode;
|
||||
last_dev = file->dev;
|
||||
last_rdev = file->rdev;
|
||||
last_uid = file->uid;
|
||||
last_gid = file->gid;
|
||||
last_time = file->modtime;
|
||||
@@ -224,13 +241,13 @@ static struct file_struct *make_file(int recurse,char *fname)
|
||||
bzero(sum,SUM_LENGTH);
|
||||
|
||||
if (lstat(fname,&st) != 0) {
|
||||
fprintf(stderr,"%s: %s\n",
|
||||
fprintf(FERROR,"%s: %s\n",
|
||||
fname,strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (S_ISDIR(st.st_mode) && !recurse) {
|
||||
fprintf(stderr,"skipping directory %s\n",fname);
|
||||
fprintf(FERROR,"skipping directory %s\n",fname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -241,7 +258,9 @@ static struct file_struct *make_file(int recurse,char *fname)
|
||||
return NULL;
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"make_file(%s)\n",fname);
|
||||
fprintf(FERROR,"make_file(%s)\n",fname);
|
||||
|
||||
bzero((char *)&file,sizeof(file));
|
||||
|
||||
file.name = strdup(fname);
|
||||
file.modtime = st.st_mtime;
|
||||
@@ -249,8 +268,10 @@ static struct file_struct *make_file(int recurse,char *fname)
|
||||
file.mode = st.st_mode;
|
||||
file.uid = st.st_uid;
|
||||
file.gid = st.st_gid;
|
||||
file.dev = st.st_dev;
|
||||
file.inode = st.st_ino;
|
||||
#ifdef HAVE_ST_RDEV
|
||||
file.dev = st.st_rdev;
|
||||
file.rdev = st.st_rdev;
|
||||
#endif
|
||||
|
||||
#if SUPPORT_LINKS
|
||||
@@ -258,7 +279,7 @@ static struct file_struct *make_file(int recurse,char *fname)
|
||||
int l;
|
||||
char lnk[MAXPATHLEN];
|
||||
if ((l=readlink(fname,lnk,MAXPATHLEN-1)) == -1) {
|
||||
fprintf(stderr,"readlink %s : %s\n",fname,strerror(errno));
|
||||
fprintf(FERROR,"readlink %s : %s\n",fname,strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
lnk[l] = 0;
|
||||
@@ -326,7 +347,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
|
||||
|
||||
d = opendir(dir);
|
||||
if (!d) {
|
||||
fprintf(stderr,"%s: %s\n",
|
||||
fprintf(FERROR,"%s: %s\n",
|
||||
dir,strerror(errno));
|
||||
return;
|
||||
}
|
||||
@@ -364,8 +385,8 @@ struct file_list *send_file_list(int f,int recurse,int argc,char *argv[])
|
||||
struct file_list *flist;
|
||||
|
||||
if (verbose && recurse) {
|
||||
fprintf(am_server?stderr:stdout,"building file list ... ");
|
||||
fflush(am_server?stderr:stdout);
|
||||
fprintf(FINFO,"building file list ... ");
|
||||
fflush(FINFO);
|
||||
}
|
||||
|
||||
flist = (struct file_list *)malloc(sizeof(flist[0]));
|
||||
@@ -389,12 +410,12 @@ struct file_list *send_file_list(int f,int recurse,int argc,char *argv[])
|
||||
}
|
||||
|
||||
if (lstat(fname,&st) != 0) {
|
||||
fprintf(stderr,"%s : %s\n",fname,strerror(errno));
|
||||
fprintf(FERROR,"%s : %s\n",fname,strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (S_ISDIR(st.st_mode) && !recurse) {
|
||||
fprintf(stderr,"skipping directory %s\n",fname);
|
||||
fprintf(FERROR,"skipping directory %s\n",fname);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -410,11 +431,11 @@ struct file_list *send_file_list(int f,int recurse,int argc,char *argv[])
|
||||
|
||||
if (dir && *dir) {
|
||||
if (getcwd(dbuf,MAXPATHLEN-1) == NULL) {
|
||||
fprintf(stderr,"getwd : %s\n",strerror(errno));
|
||||
fprintf(FERROR,"getwd : %s\n",strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
if (chdir(dir) != 0) {
|
||||
fprintf(stderr,"chdir %s : %s\n",dir,strerror(errno));
|
||||
fprintf(FERROR,"chdir %s : %s\n",dir,strerror(errno));
|
||||
continue;
|
||||
}
|
||||
flist_dir = dir;
|
||||
@@ -423,7 +444,7 @@ struct file_list *send_file_list(int f,int recurse,int argc,char *argv[])
|
||||
send_file_name(f,flist,recurse,fname);
|
||||
flist_dir = NULL;
|
||||
if (chdir(dbuf) != 0) {
|
||||
fprintf(stderr,"chdir %s : %s\n",dbuf,strerror(errno));
|
||||
fprintf(FERROR,"chdir %s : %s\n",dbuf,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
continue;
|
||||
@@ -439,10 +460,10 @@ struct file_list *send_file_list(int f,int recurse,int argc,char *argv[])
|
||||
write_flush(f);
|
||||
}
|
||||
|
||||
clean_flist(flist);
|
||||
|
||||
if (verbose && recurse)
|
||||
fprintf(am_server?stderr:stdout,"done\n");
|
||||
fprintf(FINFO,"done\n");
|
||||
|
||||
clean_flist(flist);
|
||||
|
||||
return flist;
|
||||
}
|
||||
@@ -454,7 +475,7 @@ struct file_list *recv_file_list(int f)
|
||||
unsigned char flags;
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"recv_file_list starting\n");
|
||||
fprintf(FERROR,"recv_file_list starting\n");
|
||||
|
||||
flist = (struct file_list *)malloc(sizeof(flist[0]));
|
||||
if (!flist)
|
||||
@@ -488,12 +509,12 @@ struct file_list *recv_file_list(int f)
|
||||
flist->count++;
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"recv_file_name(%s)\n",flist->files[i].name);
|
||||
fprintf(FERROR,"recv_file_name(%s)\n",flist->files[i].name);
|
||||
}
|
||||
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"received %d names\n",flist->count);
|
||||
fprintf(FERROR,"received %d names\n",flist->count);
|
||||
|
||||
clean_flist(flist);
|
||||
|
||||
@@ -505,7 +526,7 @@ oom:
|
||||
}
|
||||
|
||||
|
||||
static int flist_compare(struct file_struct *f1,struct file_struct *f2)
|
||||
int file_compare(struct file_struct *f1,struct file_struct *f2)
|
||||
{
|
||||
if (!f1->name && !f2->name) return 0;
|
||||
if (!f1->name) return -1;
|
||||
@@ -520,14 +541,14 @@ int flist_find(struct file_list *flist,struct file_struct *f)
|
||||
|
||||
while (low != high) {
|
||||
int mid = (low+high)/2;
|
||||
int ret = flist_compare(&flist->files[mid],f);
|
||||
int ret = file_compare(&flist->files[mid],f);
|
||||
if (ret == 0) return mid;
|
||||
if (ret > 0)
|
||||
high=mid;
|
||||
else
|
||||
low=mid+1;
|
||||
}
|
||||
if (flist_compare(&flist->files[low],f) == 0)
|
||||
if (file_compare(&flist->files[low],f) == 0)
|
||||
return low;
|
||||
return -1;
|
||||
}
|
||||
@@ -594,17 +615,17 @@ void clean_flist(struct file_list *flist)
|
||||
|
||||
qsort(flist->files,flist->count,
|
||||
sizeof(flist->files[0]),
|
||||
(int (*)())flist_compare);
|
||||
(int (*)())file_compare);
|
||||
|
||||
for (i=1;i<flist->count;i++) {
|
||||
if (flist->files[i].name &&
|
||||
strcmp(flist->files[i].name,flist->files[i-1].name) == 0) {
|
||||
if (verbose > 1 && !am_server)
|
||||
fprintf(stderr,"removing duplicate name %s from file list\n",
|
||||
flist->files[i].name);
|
||||
fprintf(FERROR,"removing duplicate name %s from file list %d\n",
|
||||
flist->files[i-1].name,i-1);
|
||||
free(flist->files[i-1].name);
|
||||
flist->files[i-1].name = NULL;
|
||||
}
|
||||
bzero((char *)&flist->files[i-1],sizeof(flist->files[i-1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
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 am_server;
|
||||
extern int dry_run;
|
||||
|
||||
#if SUPPORT_HARD_LINKS
|
||||
static int hlink_compare(struct file_struct *f1,struct file_struct *f2)
|
||||
{
|
||||
if (!S_ISREG(f1->mode) && !S_ISREG(f2->mode)) return 0;
|
||||
if (!S_ISREG(f1->mode)) return -1;
|
||||
if (!S_ISREG(f2->mode)) return 1;
|
||||
|
||||
if (f1->dev != f2->dev)
|
||||
return (f1->dev - f2->dev);
|
||||
|
||||
if (f1->inode != f2->inode)
|
||||
return (f1->inode - f2->inode);
|
||||
|
||||
return file_compare(f1,f2);
|
||||
}
|
||||
|
||||
|
||||
static struct file_struct *hlink_list = NULL;
|
||||
static int hlink_count=0;
|
||||
#endif
|
||||
|
||||
void init_hard_links(struct file_list *flist)
|
||||
{
|
||||
#if SUPPORT_HARD_LINKS
|
||||
if (flist->count < 2) return;
|
||||
|
||||
if (hlink_list) free(hlink_list);
|
||||
|
||||
if (!(hlink_list =
|
||||
(struct file_struct *)malloc(sizeof(hlink_list[0])*flist->count)))
|
||||
out_of_memory("init_hard_links");
|
||||
|
||||
bcopy((char *)flist->files,hlink_list,sizeof(hlink_list[0])*flist->count);
|
||||
|
||||
qsort(hlink_list,flist->count,
|
||||
sizeof(hlink_list[0]),
|
||||
(int (*)())hlink_compare);
|
||||
|
||||
hlink_count=flist->count;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* check if a file should be skipped because it is the same as an
|
||||
earlier hard link */
|
||||
int check_hard_link(struct file_struct *file)
|
||||
{
|
||||
#if SUPPORT_HARD_LINKS
|
||||
int low=0,high=hlink_count;
|
||||
int mid=0,ret=0;
|
||||
|
||||
if (!hlink_list || !S_ISREG(file->mode)) return 0;
|
||||
|
||||
while (low != high) {
|
||||
mid = (low+high)/2;
|
||||
ret = hlink_compare(&hlink_list[mid],file);
|
||||
if (ret == 0) break;
|
||||
if (ret > 0)
|
||||
high=mid;
|
||||
else
|
||||
low=mid+1;
|
||||
}
|
||||
|
||||
if (hlink_compare(&hlink_list[mid],file) != 0) return 0;
|
||||
|
||||
if (mid > 0 &&
|
||||
S_ISREG(hlink_list[mid-1].mode) &&
|
||||
file->dev == hlink_list[mid-1].dev &&
|
||||
file->inode == hlink_list[mid-1].inode)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* create any hard links in the flist */
|
||||
void do_hard_links(struct file_list *flist)
|
||||
{
|
||||
#if SUPPORT_HARD_LINKS
|
||||
int i;
|
||||
|
||||
if (!hlink_list) return;
|
||||
|
||||
for (i=1;i<hlink_count;i++) {
|
||||
if (S_ISREG(hlink_list[i].mode) &&
|
||||
S_ISREG(hlink_list[i-1].mode) &&
|
||||
hlink_list[i].name && hlink_list[i-1].name &&
|
||||
hlink_list[i].dev == hlink_list[i-1].dev &&
|
||||
hlink_list[i].inode == hlink_list[i-1].inode) {
|
||||
struct stat st1,st2;
|
||||
|
||||
if (stat(hlink_list[i-1].name,&st1) != 0) continue;
|
||||
if (stat(hlink_list[i].name,&st2) != 0) {
|
||||
if (!dry_run && link(hlink_list[i-1].name,hlink_list[i].name) != 0) {
|
||||
fprintf(FINFO,"link %s => %s : %s\n",
|
||||
hlink_list[i].name,hlink_list[i-1].name,strerror(errno));
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (st2.st_dev == st1.st_dev && st2.st_ino == st1.st_ino) continue;
|
||||
|
||||
if (!dry_run && (unlink(hlink_list[i].name) != 0 ||
|
||||
link(hlink_list[i-1].name,hlink_list[i].name) != 0)) {
|
||||
fprintf(FINFO,"link %s => %s : %s\n",
|
||||
hlink_list[i].name,hlink_list[i-1].name,strerror(errno));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
fprintf(FINFO,"%s => %s\n",
|
||||
hlink_list[i].name,hlink_list[i-1].name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -28,6 +28,7 @@ static int total_written = 0;
|
||||
static int total_read = 0;
|
||||
|
||||
extern int verbose;
|
||||
extern int sparse_files;
|
||||
|
||||
int write_total(void)
|
||||
{
|
||||
@@ -128,7 +129,7 @@ int read_int(int f)
|
||||
char b[4];
|
||||
if ((ret=readfd(f,b,4)) != 4) {
|
||||
if (verbose > 1)
|
||||
fprintf(stderr,"Error reading %d bytes : %s\n",
|
||||
fprintf(FERROR,"Error reading %d bytes : %s\n",
|
||||
4,ret==-1?strerror(errno):"EOF");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
@@ -141,7 +142,7 @@ void read_buf(int f,char *buf,int len)
|
||||
int ret;
|
||||
if ((ret=readfd(f,buf,len)) != len) {
|
||||
if (verbose > 1)
|
||||
fprintf(stderr,"Error reading %d bytes : %s\n",
|
||||
fprintf(FERROR,"Error reading %d bytes : %s\n",
|
||||
len,ret==-1?strerror(errno):"EOF");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
@@ -161,43 +162,51 @@ static int last_sparse = 0;
|
||||
|
||||
int sparse_end(int f)
|
||||
{
|
||||
#if SPARSE_FILES
|
||||
if (last_sparse) {
|
||||
lseek(f,-1,SEEK_CUR);
|
||||
return (write(f,&last_byte,1) == 1 ? 0 : -1);
|
||||
}
|
||||
#endif
|
||||
last_sparse = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int write_sparse(int f,char *buf,int len)
|
||||
{
|
||||
int l=0;
|
||||
int l1=0,l2=0;
|
||||
int ret;
|
||||
|
||||
#if SPARSE_FILES
|
||||
for (l=0;l<len && buf[l]==0;l++) ;
|
||||
if (!sparse_files)
|
||||
return write(f,buf,len);
|
||||
|
||||
if (l > 0)
|
||||
lseek(f,l,SEEK_CUR);
|
||||
for (l1=0;l1<len && buf[l1]==0;l1++) ;
|
||||
for (l2=0;l2<(len-l1) && buf[len-(l2+1)]==0;l2++) ;
|
||||
|
||||
last_byte = buf[len-1];
|
||||
#endif
|
||||
|
||||
if (l == len) {
|
||||
last_sparse = 1;
|
||||
if (l1 == len || l2 > 0)
|
||||
last_sparse=1;
|
||||
|
||||
if (l1 > 0)
|
||||
lseek(f,l1,SEEK_CUR);
|
||||
|
||||
if (l1 == len)
|
||||
return len;
|
||||
}
|
||||
|
||||
last_sparse = 0;
|
||||
if ((ret=write(f,buf+l1,len-(l1+l2))) != len-(l1+l2)) {
|
||||
if (ret == -1 || ret == 0) return ret;
|
||||
return (l1+ret);
|
||||
}
|
||||
|
||||
return (l + write(f,buf+l,len-l));
|
||||
if (l2 > 0)
|
||||
lseek(f,l2,SEEK_CUR);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int read_write(int fd_in,int fd_out,int size)
|
||||
{
|
||||
static char *buf=NULL;
|
||||
static int bufsize = CHUNK_SIZE;
|
||||
int bufsize = sparse_files?SPARSE_WRITE_SIZE:WRITE_SIZE;
|
||||
int total=0;
|
||||
|
||||
if (!buf) {
|
||||
@@ -257,7 +266,7 @@ void write_int(int f,int x)
|
||||
char b[4];
|
||||
SIVAL(b,0,x);
|
||||
if ((ret=writefd(f,b,4)) != 4) {
|
||||
fprintf(stderr,"write_int failed : %s\n",
|
||||
fprintf(FERROR,"write_int failed : %s\n",
|
||||
ret==-1?strerror(errno):"EOF");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
@@ -268,7 +277,7 @@ void write_buf(int f,char *buf,int len)
|
||||
{
|
||||
int ret;
|
||||
if ((ret=writefd(f,buf,len)) != len) {
|
||||
fprintf(stderr,"write_buf failed : %s\n",
|
||||
fprintf(FERROR,"write_buf failed : %s\n",
|
||||
ret==-1?strerror(errno):"EOF");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ static char *rsync_path = RSYNC_NAME;
|
||||
|
||||
int make_backups = 0;
|
||||
int preserve_links = 0;
|
||||
int preserve_hard_links = 0;
|
||||
int preserve_perms = 0;
|
||||
int preserve_devices = 0;
|
||||
int preserve_uid = 0;
|
||||
@@ -44,6 +45,7 @@ int ignore_times=0;
|
||||
int delete_mode=0;
|
||||
int one_file_system=0;
|
||||
int remote_version=0;
|
||||
int sparse_files=0;
|
||||
extern int csum_length;
|
||||
|
||||
int am_server = 0;
|
||||
@@ -109,6 +111,8 @@ static void server_options(char **args,int *argc)
|
||||
argstr[x++] = 'n';
|
||||
if (preserve_links)
|
||||
argstr[x++] = 'l';
|
||||
if (preserve_hard_links)
|
||||
argstr[x++] = 'H';
|
||||
if (preserve_uid)
|
||||
argstr[x++] = 'o';
|
||||
if (preserve_gid)
|
||||
@@ -129,6 +133,8 @@ static void server_options(char **args,int *argc)
|
||||
argstr[x++] = 'I';
|
||||
if (one_file_system)
|
||||
argstr[x++] = 'x';
|
||||
if (sparse_files)
|
||||
argstr[x++] = 'S';
|
||||
argstr[x] = 0;
|
||||
|
||||
if (x != 1) args[ac++] = argstr;
|
||||
@@ -199,10 +205,10 @@ int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
|
||||
args[argc] = NULL;
|
||||
|
||||
if (verbose > 3) {
|
||||
fprintf(stderr,"cmd=");
|
||||
fprintf(FERROR,"cmd=");
|
||||
for (i=0;i<argc;i++)
|
||||
fprintf(stderr,"%s ",args[i]);
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(FERROR,"%s ",args[i]);
|
||||
fprintf(FERROR,"\n");
|
||||
}
|
||||
|
||||
return piped_child(args,f_in,f_out);
|
||||
@@ -222,13 +228,13 @@ static char *get_local_name(struct file_list *flist,char *name)
|
||||
if (stat(name,&st) == 0) {
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
if (chdir(name) != 0) {
|
||||
fprintf(stderr,"chdir %s : %s\n",name,strerror(errno));
|
||||
fprintf(FERROR,"chdir %s : %s\n",name,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (flist->count > 1) {
|
||||
fprintf(stderr,"ERROR: destination must be a directory when copying more than 1 file\n");
|
||||
fprintf(FERROR,"ERROR: destination must be a directory when copying more than 1 file\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
return name;
|
||||
@@ -241,14 +247,14 @@ static char *get_local_name(struct file_list *flist,char *name)
|
||||
return NULL;
|
||||
|
||||
if (mkdir(name,0777) != 0) {
|
||||
fprintf(stderr,"mkdir %s : %s\n",name,strerror(errno));
|
||||
fprintf(FERROR,"mkdir %s : %s\n",name,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
} else {
|
||||
fprintf(am_server?stderr:stdout,"created directory %s\n",name);
|
||||
fprintf(FINFO,"created directory %s\n",name);
|
||||
}
|
||||
|
||||
if (chdir(name) != 0) {
|
||||
fprintf(stderr,"chdir %s : %s\n",name,strerror(errno));
|
||||
fprintf(FERROR,"chdir %s : %s\n",name,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
@@ -265,10 +271,10 @@ void do_server_sender(int argc,char *argv[])
|
||||
struct file_list *flist;
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"server_sender starting pid=%d\n",(int)getpid());
|
||||
fprintf(FERROR,"server_sender starting pid=%d\n",(int)getpid());
|
||||
|
||||
if (chdir(dir) != 0) {
|
||||
fprintf(stderr,"chdir %s: %s\n",dir,strerror(errno));
|
||||
fprintf(FERROR,"chdir %s: %s\n",dir,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
argc--;
|
||||
@@ -294,23 +300,47 @@ void do_server_sender(int argc,char *argv[])
|
||||
}
|
||||
|
||||
|
||||
static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
|
||||
{
|
||||
int pid;
|
||||
int status=0;
|
||||
|
||||
if (preserve_hard_links)
|
||||
init_hard_links(flist);
|
||||
|
||||
if ((pid=fork()) == 0) {
|
||||
recv_files(f_in,flist,local_name);
|
||||
if (preserve_hard_links)
|
||||
do_hard_links(flist);
|
||||
if (verbose > 2)
|
||||
fprintf(FERROR,"receiver read %d\n",read_total());
|
||||
exit_cleanup(0);
|
||||
}
|
||||
|
||||
generate_files(f_out,flist,local_name);
|
||||
|
||||
waitpid(pid, &status, 0);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void do_server_recv(int argc,char *argv[])
|
||||
{
|
||||
int pid,status;
|
||||
int status;
|
||||
char *dir = NULL;
|
||||
struct file_list *flist;
|
||||
char *local_name=NULL;
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
|
||||
fprintf(FERROR,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
|
||||
|
||||
if (argc > 0) {
|
||||
dir = argv[0];
|
||||
argc--;
|
||||
argv++;
|
||||
if (chdir(dir) != 0) {
|
||||
fprintf(stderr,"chdir %s : %s\n",dir,strerror(errno));
|
||||
fprintf(FERROR,"chdir %s : %s\n",dir,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
}
|
||||
@@ -320,7 +350,7 @@ void do_server_recv(int argc,char *argv[])
|
||||
|
||||
flist = recv_file_list(STDIN_FILENO);
|
||||
if (!flist || flist->count == 0) {
|
||||
fprintf(stderr,"nothing to do\n");
|
||||
fprintf(FERROR,"nothing to do\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
@@ -332,16 +362,7 @@ void do_server_recv(int argc,char *argv[])
|
||||
local_name = get_local_name(flist,argv[0]);
|
||||
}
|
||||
|
||||
if ((pid=fork()) == 0) {
|
||||
recv_files(STDIN_FILENO,flist,local_name);
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"receiver read %d\n",read_total());
|
||||
exit_cleanup(0);
|
||||
}
|
||||
|
||||
generate_files(STDOUT_FILENO,flist,local_name);
|
||||
|
||||
waitpid(pid, &status, 0);
|
||||
status = do_recv(STDIN_FILENO,STDOUT_FILENO,flist,local_name);
|
||||
exit_cleanup(status);
|
||||
}
|
||||
|
||||
@@ -360,11 +381,13 @@ static void usage(FILE *f)
|
||||
fprintf(f,"-b, --backup make backups (default ~ extension)\n");
|
||||
fprintf(f,"-u, --update update only (don't overwrite newer files)\n");
|
||||
fprintf(f,"-l, --links preserve soft links\n");
|
||||
fprintf(f,"-H, --hard-links preserve hard links\n");
|
||||
fprintf(f,"-p, --perms preserve permissions\n");
|
||||
fprintf(f,"-o, --owner preserve owner (root only)\n");
|
||||
fprintf(f,"-g, --group preserve group\n");
|
||||
fprintf(f,"-D, --devices preserve devices (root only)\n");
|
||||
fprintf(f,"-t, --times preserve times\n");
|
||||
fprintf(f,"-S, --sparse handle sparse files efficiently\n");
|
||||
fprintf(f,"-n, --dry-run show what would have been transferred\n");
|
||||
fprintf(f,"-x, --one-file-system don't cross filesystem boundaries\n");
|
||||
fprintf(f,"-B, --block-size SIZE checksum blocking size\n");
|
||||
@@ -387,7 +410,7 @@ static void usage(FILE *f)
|
||||
enum {OPT_VERSION,OPT_SUFFIX,OPT_SENDER,OPT_SERVER,OPT_EXCLUDE,
|
||||
OPT_EXCLUDE_FROM,OPT_DELETE,OPT_RSYNC_PATH,OPT_CSUM_LENGTH};
|
||||
|
||||
static char *short_options = "oblpguDCtcahvrIxne:B:";
|
||||
static char *short_options = "oblHpguDCtcahvrIxnSe:B:";
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"version", 0, 0, OPT_VERSION},
|
||||
@@ -402,6 +425,7 @@ static struct option long_options[] = {
|
||||
{"ignore-times",0, 0, 'I'},
|
||||
{"help", 0, 0, 'h'},
|
||||
{"dry-run", 0, 0, 'n'},
|
||||
{"sparse", 0, 0, 'S'},
|
||||
{"cvs-exclude", 0, 0, 'C'},
|
||||
{"archive", 0, 0, 'a'},
|
||||
{"checksum", 0, 0, 'c'},
|
||||
@@ -412,6 +436,7 @@ static struct option long_options[] = {
|
||||
{"devices", 0, 0, 'D'},
|
||||
{"perms", 0, 0, 'p'},
|
||||
{"links", 0, 0, 'l'},
|
||||
{"hard-links", 0, 0, 'H'},
|
||||
{"owner", 0, 0, 'o'},
|
||||
{"group", 0, 0, 'g'},
|
||||
{"times", 0, 0, 't'},
|
||||
@@ -422,7 +447,7 @@ static struct option long_options[] = {
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
int pid, status, pid2, status2;
|
||||
int pid, status, status2;
|
||||
int opt;
|
||||
int option_index;
|
||||
char *shell_cmd = NULL;
|
||||
@@ -482,7 +507,7 @@ int main(int argc,char *argv[])
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage(stdout);
|
||||
usage(FINFO);
|
||||
exit_cleanup(0);
|
||||
|
||||
case 'b':
|
||||
@@ -493,6 +518,10 @@ int main(int argc,char *argv[])
|
||||
dry_run=1;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
sparse_files=1;
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
cvs_exclude=1;
|
||||
break;
|
||||
@@ -501,11 +530,17 @@ int main(int argc,char *argv[])
|
||||
update_only=1;
|
||||
break;
|
||||
|
||||
#if SUPPORT_LINKS
|
||||
case 'l':
|
||||
#if SUPPORT_LINKS
|
||||
preserve_links=1;
|
||||
break;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
#if SUPPORT_HARD_LINKS
|
||||
preserve_hard_links=1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
preserve_perms=1;
|
||||
@@ -515,7 +550,7 @@ int main(int argc,char *argv[])
|
||||
if (getuid() == 0) {
|
||||
preserve_uid=1;
|
||||
} else {
|
||||
fprintf(stderr,"-o only allowed for root\n");
|
||||
fprintf(FERROR,"-o only allowed for root\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
break;
|
||||
@@ -528,7 +563,7 @@ int main(int argc,char *argv[])
|
||||
if (getuid() == 0) {
|
||||
preserve_devices=1;
|
||||
} else {
|
||||
fprintf(stderr,"-D only allowed for root\n");
|
||||
fprintf(FERROR,"-D only allowed for root\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
break;
|
||||
@@ -565,7 +600,7 @@ int main(int argc,char *argv[])
|
||||
|
||||
case OPT_SENDER:
|
||||
if (!am_server) {
|
||||
usage(stderr);
|
||||
usage(FERROR);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
sender = 1;
|
||||
@@ -584,7 +619,7 @@ int main(int argc,char *argv[])
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr,"bad option -%c\n",opt);
|
||||
fprintf(FERROR,"bad option -%c\n",opt);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
}
|
||||
@@ -606,7 +641,7 @@ int main(int argc,char *argv[])
|
||||
remote_version = read_int(STDIN_FILENO);
|
||||
if (remote_version < MIN_PROTOCOL_VERSION ||
|
||||
remote_version > MAX_PROTOCOL_VERSION) {
|
||||
fprintf(stderr,"protocol version mismatch - is your shell clean?\n");
|
||||
fprintf(FERROR,"protocol version mismatch - is your shell clean?\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
write_int(STDOUT_FILENO,PROTOCOL_VERSION);
|
||||
@@ -626,7 +661,7 @@ int main(int argc,char *argv[])
|
||||
}
|
||||
|
||||
if (argc < 2) {
|
||||
usage(stderr);
|
||||
usage(FERROR);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
@@ -668,7 +703,7 @@ int main(int argc,char *argv[])
|
||||
}
|
||||
|
||||
if (verbose > 3) {
|
||||
fprintf(stderr,"cmd=%s machine=%s user=%s path=%s\n",
|
||||
fprintf(FERROR,"cmd=%s machine=%s user=%s path=%s\n",
|
||||
shell_cmd?shell_cmd:"",
|
||||
shell_machine?shell_machine:"",
|
||||
shell_user?shell_user:"",
|
||||
@@ -676,7 +711,7 @@ int main(int argc,char *argv[])
|
||||
}
|
||||
|
||||
if (!sender && argc != 1) {
|
||||
usage(stderr);
|
||||
usage(FERROR);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
@@ -688,7 +723,7 @@ int main(int argc,char *argv[])
|
||||
remote_version = read_int(f_in);
|
||||
if (remote_version < MIN_PROTOCOL_VERSION ||
|
||||
remote_version > MAX_PROTOCOL_VERSION) {
|
||||
fprintf(stderr,"protocol version mismatch - is your shell clean?\n");
|
||||
fprintf(FERROR,"protocol version mismatch - is your shell clean?\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
}
|
||||
@@ -696,7 +731,7 @@ int main(int argc,char *argv[])
|
||||
setup_protocol();
|
||||
|
||||
if (verbose > 3)
|
||||
fprintf(stderr,"parent=%d child=%d sender=%d recurse=%d\n",
|
||||
fprintf(FERROR,"parent=%d child=%d sender=%d recurse=%d\n",
|
||||
(int)getpid(),pid,sender,recurse);
|
||||
|
||||
if (sender) {
|
||||
@@ -706,10 +741,10 @@ int main(int argc,char *argv[])
|
||||
send_exclude_list(f_out);
|
||||
flist = send_file_list(f_out,recurse,argc,argv);
|
||||
if (verbose > 3)
|
||||
fprintf(stderr,"file list sent\n");
|
||||
fprintf(FERROR,"file list sent\n");
|
||||
send_files(flist,f_out,f_in);
|
||||
if (verbose > 3)
|
||||
fprintf(stderr,"waiting on %d\n",pid);
|
||||
fprintf(FERROR,"waiting on %d\n",pid);
|
||||
waitpid(pid, &status, 0);
|
||||
report(-1);
|
||||
exit_cleanup(status);
|
||||
@@ -719,22 +754,13 @@ int main(int argc,char *argv[])
|
||||
|
||||
flist = recv_file_list(f_in);
|
||||
if (!flist || flist->count == 0) {
|
||||
fprintf(stderr,"nothing to do\n");
|
||||
fprintf(FERROR,"nothing to do\n");
|
||||
exit_cleanup(0);
|
||||
}
|
||||
|
||||
local_name = get_local_name(flist,argv[0]);
|
||||
|
||||
if ((pid2=fork()) == 0) {
|
||||
recv_files(f_in,flist,local_name);
|
||||
if (verbose > 1)
|
||||
fprintf(stderr,"receiver read %d\n",read_total());
|
||||
exit_cleanup(0);
|
||||
}
|
||||
|
||||
generate_files(f_out,flist,local_name);
|
||||
|
||||
waitpid(pid2, &status2, 0);
|
||||
status2 = do_recv(f_in,f_out,flist,local_name);
|
||||
|
||||
report(f_in);
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ static void matched(int f,struct sum_struct *s,char *buf,off_t len,
|
||||
|
||||
if (verbose > 2)
|
||||
if (i != -1)
|
||||
fprintf(stderr,"match at %d last_match=%d j=%d len=%d n=%d\n",
|
||||
fprintf(FERROR,"match at %d last_match=%d j=%d len=%d n=%d\n",
|
||||
(int)offset,(int)last_match,i,(int)s->sums[i].len,n);
|
||||
|
||||
if (n > 0) {
|
||||
@@ -125,7 +125,7 @@ static void hash_search(int f,struct sum_struct *s,char *buf,off_t len)
|
||||
char *map;
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"hash search b=%d len=%d\n",s->n,(int)len);
|
||||
fprintf(FERROR,"hash search b=%d len=%d\n",s->n,(int)len);
|
||||
|
||||
k = MIN(len, s->n);
|
||||
|
||||
@@ -135,21 +135,21 @@ static void hash_search(int f,struct sum_struct *s,char *buf,off_t len)
|
||||
s1 = sum & 0xFFFF;
|
||||
s2 = sum >> 16;
|
||||
if (verbose > 3)
|
||||
fprintf(stderr, "sum=%.8x k=%d\n", sum, k);
|
||||
fprintf(FERROR, "sum=%.8x k=%d\n", sum, k);
|
||||
|
||||
offset = 0;
|
||||
|
||||
end = len + 1 - s->sums[s->count-1].len;
|
||||
|
||||
if (verbose > 3)
|
||||
fprintf(stderr,"hash search s->n=%d len=%d count=%d\n",
|
||||
fprintf(FERROR,"hash search s->n=%d len=%d count=%d\n",
|
||||
s->n,(int)len,s->count);
|
||||
|
||||
do {
|
||||
tag t = gettag2(s1,s2);
|
||||
j = tag_table[t];
|
||||
if (verbose > 4)
|
||||
fprintf(stderr,"offset=%d sum=%08x\n",
|
||||
fprintf(FERROR,"offset=%d sum=%08x\n",
|
||||
offset,sum);
|
||||
|
||||
if (j != NULL_TAG) {
|
||||
@@ -162,7 +162,7 @@ static void hash_search(int f,struct sum_struct *s,char *buf,off_t len)
|
||||
|
||||
if (sum == s->sums[i].sum1) {
|
||||
if (verbose > 3)
|
||||
fprintf(stderr,"potential match at %d target=%d %d sum=%08x\n",
|
||||
fprintf(FERROR,"potential match at %d target=%d %d sum=%08x\n",
|
||||
offset,j,i,sum);
|
||||
|
||||
if (!done_csum2) {
|
||||
@@ -220,12 +220,12 @@ void match_sums(int f,struct sum_struct *s,char *buf,off_t len)
|
||||
build_hash_table(s);
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"built hash table\n");
|
||||
fprintf(FERROR,"built hash table\n");
|
||||
|
||||
hash_search(f,s,buf,len);
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"done hash search\n");
|
||||
fprintf(FERROR,"done hash search\n");
|
||||
} else {
|
||||
matched(f,s,buf,len,len,-1);
|
||||
}
|
||||
@@ -236,7 +236,7 @@ void match_sums(int f,struct sum_struct *s,char *buf,off_t len)
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr, "false_alarms=%d tag_hits=%d matches=%d\n",
|
||||
fprintf(FERROR, "false_alarms=%d tag_hits=%d matches=%d\n",
|
||||
false_alarms, tag_hits, matches);
|
||||
|
||||
total_tag_hits += tag_hits;
|
||||
@@ -250,7 +250,7 @@ void match_report(void)
|
||||
if (verbose <= 1)
|
||||
return;
|
||||
|
||||
fprintf(am_server?stderr:stdout,
|
||||
fprintf(FINFO,
|
||||
"total: matches=%d tag_hits=%d false_alarms=%d data=%d\n",
|
||||
total_matches,total_tag_hits,
|
||||
total_false_alarms,total_data_transfer);
|
||||
|
||||
@@ -32,6 +32,7 @@ extern int block_size;
|
||||
extern int update_only;
|
||||
extern int make_backups;
|
||||
extern int preserve_links;
|
||||
extern int preserve_hard_links;
|
||||
extern int preserve_perms;
|
||||
extern int preserve_devices;
|
||||
extern int preserve_uid;
|
||||
@@ -105,7 +106,7 @@ static struct sum_struct *generate_sums(char *buf,off_t len,int n)
|
||||
}
|
||||
|
||||
if (verbose > 3)
|
||||
fprintf(stderr,"count=%d rem=%d n=%d flength=%d\n",
|
||||
fprintf(FERROR,"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);
|
||||
@@ -123,7 +124,7 @@ static struct sum_struct *generate_sums(char *buf,off_t len,int n)
|
||||
s->sums[i].i = i;
|
||||
|
||||
if (verbose > 3)
|
||||
fprintf(stderr,"chunk[%d] offset=%d len=%d sum1=%08x\n",
|
||||
fprintf(FERROR,"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;
|
||||
@@ -153,7 +154,7 @@ static struct sum_struct *receive_sums(int f)
|
||||
s->sums = NULL;
|
||||
|
||||
if (verbose > 3)
|
||||
fprintf(stderr,"count=%d n=%d rem=%d\n",
|
||||
fprintf(FERROR,"count=%d n=%d rem=%d\n",
|
||||
s->count,s->n,s->remainder);
|
||||
|
||||
block_len = s->n;
|
||||
@@ -179,7 +180,7 @@ static struct sum_struct *receive_sums(int f)
|
||||
offset += s->sums[i].len;
|
||||
|
||||
if (verbose > 3)
|
||||
fprintf(stderr,"chunk[%d] len=%d offset=%d sum1=%08x\n",
|
||||
fprintf(FERROR,"chunk[%d] len=%d offset=%d sum1=%08x\n",
|
||||
i,s->sums[i].len,(int)s->sums[i].offset,s->sums[i].sum1);
|
||||
}
|
||||
|
||||
@@ -199,7 +200,7 @@ static void set_perms(char *fname,struct file_struct *file,struct stat *st,
|
||||
|
||||
if (!st) {
|
||||
if (stat(fname,&st2) != 0) {
|
||||
fprintf(stderr,"stat %s : %s\n",fname,strerror(errno));
|
||||
fprintf(FERROR,"stat %s : %s\n",fname,strerror(errno));
|
||||
return;
|
||||
}
|
||||
st = &st2;
|
||||
@@ -209,7 +210,7 @@ static void set_perms(char *fname,struct file_struct *file,struct stat *st,
|
||||
st->st_mtime != file->modtime) {
|
||||
updated = 1;
|
||||
if (set_modtime(fname,file->modtime) != 0) {
|
||||
fprintf(stderr,"failed to set times on %s : %s\n",
|
||||
fprintf(FERROR,"failed to set times on %s : %s\n",
|
||||
fname,strerror(errno));
|
||||
return;
|
||||
}
|
||||
@@ -220,7 +221,7 @@ static void set_perms(char *fname,struct file_struct *file,struct stat *st,
|
||||
st->st_mode != file->mode) {
|
||||
updated = 1;
|
||||
if (chmod(fname,file->mode) != 0) {
|
||||
fprintf(stderr,"failed to set permissions on %s : %s\n",
|
||||
fprintf(FERROR,"failed to set permissions on %s : %s\n",
|
||||
fname,strerror(errno));
|
||||
return;
|
||||
}
|
||||
@@ -234,16 +235,16 @@ static void set_perms(char *fname,struct file_struct *file,struct stat *st,
|
||||
preserve_uid?file->uid:-1,
|
||||
preserve_gid?file->gid:-1) != 0) {
|
||||
if (verbose>1 || preserve_uid)
|
||||
fprintf(stderr,"chown %s : %s\n",fname,strerror(errno));
|
||||
fprintf(FERROR,"chown %s : %s\n",fname,strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose > 1 && report) {
|
||||
if (updated)
|
||||
fprintf(am_server?stderr:stdout,"%s\n",fname);
|
||||
fprintf(FINFO,"%s\n",fname);
|
||||
else
|
||||
fprintf(am_server?stderr:stdout,"%s is uptodate\n",fname);
|
||||
fprintf(FINFO,"%s is uptodate\n",fname);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,66 +257,73 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
struct sum_struct *s;
|
||||
char sum[SUM_LENGTH];
|
||||
int statret;
|
||||
struct file_struct *file = &flist->files[i];
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"recv_generator(%s)\n",fname);
|
||||
fprintf(FERROR,"recv_generator(%s)\n",fname);
|
||||
|
||||
statret = lstat(fname,&st);
|
||||
|
||||
#if SUPPORT_LINKS
|
||||
if (preserve_links && S_ISLNK(flist->files[i].mode)) {
|
||||
if (preserve_links && S_ISLNK(file->mode)) {
|
||||
char lnk[MAXPATHLEN];
|
||||
int l;
|
||||
if (statret == 0) {
|
||||
l = readlink(fname,lnk,MAXPATHLEN-1);
|
||||
if (l > 0) {
|
||||
lnk[l] = 0;
|
||||
if (strcmp(lnk,flist->files[i].link) == 0) {
|
||||
set_perms(fname,&flist->files[i],&st,1);
|
||||
if (strcmp(lnk,file->link) == 0) {
|
||||
set_perms(fname,file,&st,1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dry_run) unlink(fname);
|
||||
if (!dry_run && symlink(flist->files[i].link,fname) != 0) {
|
||||
fprintf(stderr,"link %s -> %s : %s\n",
|
||||
fname,flist->files[i].link,strerror(errno));
|
||||
if (!dry_run && symlink(file->link,fname) != 0) {
|
||||
fprintf(FERROR,"link %s -> %s : %s\n",
|
||||
fname,file->link,strerror(errno));
|
||||
} else {
|
||||
set_perms(fname,&flist->files[i],NULL,0);
|
||||
set_perms(fname,file,NULL,0);
|
||||
if (verbose)
|
||||
fprintf(am_server?stderr:stdout,"%s -> %s\n",
|
||||
fname,flist->files[i].link);
|
||||
fprintf(FINFO,"%s -> %s\n",
|
||||
fname,file->link);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MKNOD
|
||||
if (preserve_devices && IS_DEVICE(flist->files[i].mode)) {
|
||||
if (preserve_devices && IS_DEVICE(file->mode)) {
|
||||
if (statret != 0 ||
|
||||
st.st_mode != flist->files[i].mode ||
|
||||
st.st_rdev != flist->files[i].dev) {
|
||||
st.st_mode != file->mode ||
|
||||
st.st_rdev != file->rdev) {
|
||||
if (!dry_run) unlink(fname);
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"mknod(%s,0%o,0x%x)\n",
|
||||
fname,(int)flist->files[i].mode,(int)flist->files[i].dev);
|
||||
fprintf(FERROR,"mknod(%s,0%o,0x%x)\n",
|
||||
fname,(int)file->mode,(int)file->rdev);
|
||||
if (!dry_run &&
|
||||
mknod(fname,flist->files[i].mode,flist->files[i].dev) != 0) {
|
||||
fprintf(stderr,"mknod %s : %s\n",fname,strerror(errno));
|
||||
mknod(fname,file->mode,file->rdev) != 0) {
|
||||
fprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
|
||||
} else {
|
||||
set_perms(fname,&flist->files[i],NULL,0);
|
||||
set_perms(fname,file,NULL,0);
|
||||
if (verbose)
|
||||
fprintf(am_server?stderr:stdout,"%s\n",fname);
|
||||
fprintf(FINFO,"%s\n",fname);
|
||||
}
|
||||
} else {
|
||||
set_perms(fname,&flist->files[i],&st,1);
|
||||
set_perms(fname,file,&st,1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!S_ISREG(flist->files[i].mode)) {
|
||||
fprintf(stderr,"skipping non-regular file %s\n",fname);
|
||||
if (preserve_hard_links && check_hard_link(file)) {
|
||||
if (verbose > 1)
|
||||
fprintf(FINFO,"%s is a hard link\n",file->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!S_ISREG(file->mode)) {
|
||||
fprintf(FERROR,"skipping non-regular file %s\n",fname);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -325,19 +333,19 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
if (!dry_run) send_sums(NULL,f_out);
|
||||
} else {
|
||||
if (verbose > 1)
|
||||
fprintf(stderr,"recv_generator failed to open %s\n",fname);
|
||||
fprintf(FERROR,"recv_generator failed to open %s\n",fname);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!S_ISREG(st.st_mode)) {
|
||||
fprintf(stderr,"%s : not a regular file\n",fname);
|
||||
fprintf(FERROR,"%s : not a regular file\n",fname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (update_only && st.st_mtime >= flist->files[i].modtime) {
|
||||
if (update_only && st.st_mtime >= file->modtime) {
|
||||
if (verbose > 1)
|
||||
fprintf(stderr,"%s is newer\n",fname);
|
||||
fprintf(FERROR,"%s is newer\n",fname);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -345,11 +353,11 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
file_checksum(fname,sum,st.st_size);
|
||||
}
|
||||
|
||||
if (st.st_size == flist->files[i].length &&
|
||||
((!ignore_times && st.st_mtime == flist->files[i].modtime) ||
|
||||
if (st.st_size == file->length &&
|
||||
((!ignore_times && st.st_mtime == file->modtime) ||
|
||||
(always_checksum && S_ISREG(st.st_mode) &&
|
||||
memcmp(sum,flist->files[i].sum,csum_length) == 0))) {
|
||||
set_perms(fname,&flist->files[i],&st,1);
|
||||
memcmp(sum,file->sum,csum_length) == 0))) {
|
||||
set_perms(fname,file,&st,1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -362,7 +370,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
fd = open(fname,O_RDONLY);
|
||||
|
||||
if (fd == -1) {
|
||||
fprintf(stderr,"failed to open %s : %s\n",fname,strerror(errno));
|
||||
fprintf(FERROR,"failed to open %s : %s\n",fname,strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -373,7 +381,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
}
|
||||
|
||||
if (verbose > 3)
|
||||
fprintf(stderr,"mapped %s of size %d\n",fname,(int)st.st_size);
|
||||
fprintf(FERROR,"mapped %s of size %d\n",fname,(int)st.st_size);
|
||||
|
||||
s = generate_sums(buf,st.st_size,block_size);
|
||||
|
||||
@@ -402,10 +410,10 @@ static void receive_data(int f_in,char *buf,int fd,char *fname)
|
||||
for (i=read_int(f_in); i != 0; i=read_int(f_in)) {
|
||||
if (i > 0) {
|
||||
if (verbose > 3)
|
||||
fprintf(stderr,"data recv %d at %d\n",i,(int)offset);
|
||||
fprintf(FERROR,"data recv %d at %d\n",i,(int)offset);
|
||||
|
||||
if (read_write(f_in,fd,i) != i) {
|
||||
fprintf(stderr,"write failed on %s : %s\n",fname,strerror(errno));
|
||||
fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
offset += i;
|
||||
@@ -417,11 +425,11 @@ static void receive_data(int f_in,char *buf,int fd,char *fname)
|
||||
len = remainder;
|
||||
|
||||
if (verbose > 3)
|
||||
fprintf(stderr,"chunk[%d] of size %d at %d offset=%d\n",
|
||||
fprintf(FERROR,"chunk[%d] of size %d at %d offset=%d\n",
|
||||
i,len,(int)offset2,(int)offset);
|
||||
|
||||
if (write_sparse(fd,map_ptr(buf,offset2,len),len) != len) {
|
||||
fprintf(stderr,"write failed on %s : %s\n",fname,strerror(errno));
|
||||
fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
offset += len;
|
||||
@@ -429,7 +437,7 @@ static void receive_data(int f_in,char *buf,int fd,char *fname)
|
||||
}
|
||||
|
||||
if (offset > 0 && sparse_end(fd) != 0) {
|
||||
fprintf(stderr,"write failed on %s : %s\n",fname,strerror(errno));
|
||||
fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
}
|
||||
@@ -439,16 +447,16 @@ static void delete_one(struct file_struct *f)
|
||||
{
|
||||
if (!S_ISDIR(f->mode)) {
|
||||
if (!dry_run && unlink(f->name) != 0) {
|
||||
fprintf(stderr,"unlink %s : %s\n",f->name,strerror(errno));
|
||||
fprintf(FERROR,"unlink %s : %s\n",f->name,strerror(errno));
|
||||
} else if (verbose) {
|
||||
fprintf(stderr,"deleting %s\n",f->name);
|
||||
fprintf(FERROR,"deleting %s\n",f->name);
|
||||
}
|
||||
} else {
|
||||
if (!dry_run && rmdir(f->name) != 0) {
|
||||
if (errno != ENOTEMPTY)
|
||||
fprintf(stderr,"rmdir %s : %s\n",f->name,strerror(errno));
|
||||
fprintf(FERROR,"rmdir %s : %s\n",f->name,strerror(errno));
|
||||
} else if (verbose) {
|
||||
fprintf(stderr,"deleting directory %s\n",f->name);
|
||||
fprintf(FERROR,"deleting directory %s\n",f->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -497,9 +505,10 @@ int recv_files(int f_in,struct file_list *flist,char *local_name)
|
||||
char fnametmp[MAXPATHLEN];
|
||||
char *buf;
|
||||
int i;
|
||||
struct file_struct *file;
|
||||
|
||||
if (verbose > 2) {
|
||||
fprintf(stderr,"recv_files(%d) starting\n",flist->count);
|
||||
fprintf(FERROR,"recv_files(%d) starting\n",flist->count);
|
||||
}
|
||||
|
||||
if (recurse && delete_mode && !local_name && flist->count>0) {
|
||||
@@ -511,7 +520,8 @@ int recv_files(int f_in,struct file_list *flist,char *local_name)
|
||||
i = read_int(f_in);
|
||||
if (i == -1) break;
|
||||
|
||||
fname = flist->files[i].name;
|
||||
file = &flist->files[i];
|
||||
fname = file->name;
|
||||
|
||||
if (local_name)
|
||||
fname = local_name;
|
||||
@@ -523,19 +533,19 @@ int recv_files(int f_in,struct file_list *flist,char *local_name)
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"recv_files(%s)\n",fname);
|
||||
fprintf(FERROR,"recv_files(%s)\n",fname);
|
||||
|
||||
/* open the file */
|
||||
fd1 = open(fname,O_RDONLY);
|
||||
|
||||
if (fd1 != -1 && fstat(fd1,&st) != 0) {
|
||||
fprintf(stderr,"fstat %s : %s\n",fname,strerror(errno));
|
||||
fprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno));
|
||||
close(fd1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fd1 != -1 && !S_ISREG(st.st_mode)) {
|
||||
fprintf(stderr,"%s : not a regular file\n",fname);
|
||||
fprintf(FERROR,"%s : not a regular file\n",fname);
|
||||
close(fd1);
|
||||
return -1;
|
||||
}
|
||||
@@ -547,17 +557,17 @@ int recv_files(int f_in,struct file_list *flist,char *local_name)
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"mapped %s of size %d\n",fname,(int)st.st_size);
|
||||
fprintf(FERROR,"mapped %s of size %d\n",fname,(int)st.st_size);
|
||||
|
||||
/* open tmp file */
|
||||
sprintf(fnametmp,"%s.XXXXXX",fname);
|
||||
if (NULL == mktemp(fnametmp)) {
|
||||
fprintf(stderr,"mktemp %s failed\n",fnametmp);
|
||||
fprintf(FERROR,"mktemp %s failed\n",fnametmp);
|
||||
return -1;
|
||||
}
|
||||
fd2 = open(fnametmp,O_WRONLY|O_CREAT,flist->files[i].mode);
|
||||
fd2 = open(fnametmp,O_WRONLY|O_CREAT,file->mode);
|
||||
if (fd2 == -1) {
|
||||
fprintf(stderr,"open %s : %s\n",fnametmp,strerror(errno));
|
||||
fprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -576,30 +586,30 @@ int recv_files(int f_in,struct file_list *flist,char *local_name)
|
||||
close(fd2);
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"renaming %s to %s\n",fnametmp,fname);
|
||||
fprintf(FERROR,"renaming %s to %s\n",fnametmp,fname);
|
||||
|
||||
if (make_backups) {
|
||||
char fnamebak[MAXPATHLEN];
|
||||
sprintf(fnamebak,"%s%s",fname,backup_suffix);
|
||||
if (rename(fname,fnamebak) != 0 && errno != ENOENT) {
|
||||
fprintf(stderr,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
|
||||
fprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* move tmp file over real file */
|
||||
if (rename(fnametmp,fname) != 0) {
|
||||
fprintf(stderr,"rename %s -> %s : %s\n",
|
||||
fprintf(FERROR,"rename %s -> %s : %s\n",
|
||||
fnametmp,fname,strerror(errno));
|
||||
}
|
||||
|
||||
cleanup_fname = NULL;
|
||||
|
||||
set_perms(fname,&flist->files[i],NULL,0);
|
||||
set_perms(fname,file,NULL,0);
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"recv_files finished\n");
|
||||
fprintf(FERROR,"recv_files finished\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -615,9 +625,10 @@ off_t send_files(struct file_list *flist,int f_out,int f_in)
|
||||
char fname[MAXPATHLEN];
|
||||
off_t total=0;
|
||||
int i;
|
||||
struct file_struct *file;
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"send_files starting\n");
|
||||
fprintf(FERROR,"send_files starting\n");
|
||||
|
||||
setup_nonblocking(f_in,f_out);
|
||||
|
||||
@@ -626,15 +637,17 @@ off_t send_files(struct file_list *flist,int f_out,int f_in)
|
||||
i = read_int(f_in);
|
||||
if (i == -1) break;
|
||||
|
||||
file = &flist->files[i];
|
||||
|
||||
fname[0] = 0;
|
||||
if (flist->files[i].dir) {
|
||||
strcpy(fname,flist->files[i].dir);
|
||||
if (file->dir) {
|
||||
strcpy(fname,file->dir);
|
||||
strcat(fname,"/");
|
||||
}
|
||||
strcat(fname,flist->files[i].name);
|
||||
strcat(fname,file->name);
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"send_files(%d,%s)\n",i,fname);
|
||||
fprintf(FERROR,"send_files(%d,%s)\n",i,fname);
|
||||
|
||||
if (dry_run) {
|
||||
if (!am_server && verbose)
|
||||
@@ -645,20 +658,20 @@ off_t send_files(struct file_list *flist,int f_out,int f_in)
|
||||
|
||||
s = receive_sums(f_in);
|
||||
if (!s) {
|
||||
fprintf(stderr,"receive_sums failed\n");
|
||||
fprintf(FERROR,"receive_sums failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = open(fname,O_RDONLY);
|
||||
if (fd == -1) {
|
||||
fprintf(stderr,"send_files failed to open %s: %s\n",
|
||||
fprintf(FERROR,"send_files failed to open %s: %s\n",
|
||||
fname,strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* map the local file */
|
||||
if (fstat(fd,&st) != 0) {
|
||||
fprintf(stderr,"fstat failed : %s\n",strerror(errno));
|
||||
fprintf(FERROR,"fstat failed : %s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -669,7 +682,7 @@ off_t send_files(struct file_list *flist,int f_out,int f_in)
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"send_files mapped %s of size %d\n",
|
||||
fprintf(FERROR,"send_files mapped %s of size %d\n",
|
||||
fname,(int)st.st_size);
|
||||
|
||||
write_int(f_out,i);
|
||||
@@ -679,7 +692,7 @@ off_t send_files(struct file_list *flist,int f_out,int f_in)
|
||||
write_int(f_out,s->remainder);
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"calling match_sums %s\n",fname);
|
||||
fprintf(FERROR,"calling match_sums %s\n",fname);
|
||||
|
||||
if (!am_server && verbose)
|
||||
printf("%s\n",fname);
|
||||
@@ -693,11 +706,14 @@ off_t send_files(struct file_list *flist,int f_out,int f_in)
|
||||
free_sums(s);
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"sender finished %s\n",fname);
|
||||
fprintf(FERROR,"sender finished %s\n",fname);
|
||||
|
||||
total += st.st_size;
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(FERROR,"send files finished\n");
|
||||
|
||||
match_report();
|
||||
|
||||
write_int(f_out,-1);
|
||||
@@ -713,25 +729,28 @@ void generate_files(int f,struct file_list *flist,char *local_name)
|
||||
int i;
|
||||
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"generator starting pid=%d count=%d\n",
|
||||
fprintf(FERROR,"generator starting pid=%d count=%d\n",
|
||||
(int)getpid(),flist->count);
|
||||
|
||||
for (i = 0; i < flist->count; i++) {
|
||||
if (!flist->files[i].name) continue;
|
||||
if (S_ISDIR(flist->files[i].mode)) {
|
||||
struct file_struct *file = &flist->files[i];
|
||||
if (!file->name) continue;
|
||||
if (S_ISDIR(file->mode)) {
|
||||
if (dry_run) continue;
|
||||
if (mkdir(flist->files[i].name,flist->files[i].mode) != 0 &&
|
||||
if (mkdir(file->name,file->mode) != 0 &&
|
||||
errno != EEXIST) {
|
||||
fprintf(stderr,"mkdir %s : %s\n",
|
||||
flist->files[i].name,strerror(errno));
|
||||
fprintf(FERROR,"mkdir %s : %s\n",
|
||||
file->name,strerror(errno));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
recv_generator(local_name?local_name:flist->files[i].name,
|
||||
recv_generator(local_name?local_name:file->name,
|
||||
flist,i,f);
|
||||
}
|
||||
write_int(f,-1);
|
||||
write_flush(f);
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,"generator wrote %d\n",write_total());
|
||||
fprintf(FERROR,"generator wrote %d\n",write_total());
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#define FILE_VALID 1
|
||||
#define SAME_MODE (1<<1)
|
||||
#define SAME_DEV (1<<2)
|
||||
#define SAME_RDEV (1<<2)
|
||||
#define SAME_UID (1<<3)
|
||||
#define SAME_GID (1<<4)
|
||||
#define SAME_DIR (1<<5)
|
||||
@@ -38,13 +38,15 @@
|
||||
#define MIN_PROTOCOL_VERSION 10
|
||||
#define MAX_PROTOCOL_VERSION 20
|
||||
|
||||
#define SPARSE_WRITE_SIZE (4*1024)
|
||||
#define WRITE_SIZE (32*1024)
|
||||
#define CHUNK_SIZE (32*1024)
|
||||
#define MAX_MAP_SIZE (4*1024*1024)
|
||||
|
||||
#define BLOCKING_TIMEOUT 10
|
||||
|
||||
/* do we try to create sparse files */
|
||||
#define SPARSE_FILES 1
|
||||
#define FERROR stderr
|
||||
#define FINFO (am_server?stderr:stdout)
|
||||
|
||||
#include "config.h"
|
||||
|
||||
@@ -175,7 +177,9 @@ struct file_struct {
|
||||
time_t modtime;
|
||||
off_t length;
|
||||
mode_t mode;
|
||||
ino_t inode;
|
||||
dev_t dev;
|
||||
dev_t rdev;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
char *name;
|
||||
@@ -250,6 +254,7 @@ extern int errno;
|
||||
#endif
|
||||
|
||||
#define SUPPORT_LINKS (HAVE_READLINK && defined(S_ISLNK))
|
||||
#define SUPPORT_HARD_LINKS HAVE_LINK
|
||||
|
||||
#ifndef S_ISLNK
|
||||
#define S_ISLNK(x) 0
|
||||
|
||||
@@ -78,7 +78,7 @@ char *map_ptr(char *buf,off_t offset,int len)
|
||||
|
||||
if (lseek(map_fd,offset,SEEK_SET) != offset ||
|
||||
read(map_fd,p,len) != len) {
|
||||
fprintf(stderr,"EOF in map_ptr!\n");
|
||||
fprintf(FERROR,"EOF in map_ptr!\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
@@ -110,14 +110,14 @@ int piped_child(char **command,int *f_in,int *f_out)
|
||||
|
||||
if (pipe(to_child_pipe) < 0 ||
|
||||
pipe(from_child_pipe) < 0) {
|
||||
fprintf(stderr,"pipe: %s\n",strerror(errno));
|
||||
fprintf(FERROR,"pipe: %s\n",strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
fprintf(stderr,"fork: %s\n",strerror(errno));
|
||||
fprintf(FERROR,"fork: %s\n",strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
@@ -127,18 +127,18 @@ int piped_child(char **command,int *f_in,int *f_out)
|
||||
close(to_child_pipe[1]) < 0 ||
|
||||
close(from_child_pipe[0]) < 0 ||
|
||||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
|
||||
fprintf(stderr,"Failed to dup/close : %s\n",strerror(errno));
|
||||
fprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
execvp(command[0], command);
|
||||
fprintf(stderr,"Failed to exec %s : %s\n",
|
||||
fprintf(FERROR,"Failed to exec %s : %s\n",
|
||||
command[0],strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
if (close(from_child_pipe[1]) < 0 ||
|
||||
close(to_child_pipe[0]) < 0) {
|
||||
fprintf(stderr,"Failed to close : %s\n",strerror(errno));
|
||||
fprintf(FERROR,"Failed to close : %s\n",strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ int piped_child(char **command,int *f_in,int *f_out)
|
||||
|
||||
void out_of_memory(char *str)
|
||||
{
|
||||
fprintf(stderr,"out of memory in %s\n",str);
|
||||
fprintf(FERROR,"out of memory in %s\n",str);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user