- hard links

- better sparse handling
- FERROR and FINFO
This commit is contained in:
Andrew Tridgell committed 1996-06-30 03:57:22 +00:00
1 parent d5ee1f8e7a
commit dc5ddbccac
13 files changed
+445 -224

No files matched your search

+1 -1
View File
@@ -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
+3 -1
View File
@@ -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
-----
+8 -8
View File
@@ -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
View File
@@ -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"
+3 -3
View File
@@ -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;
+57 -36
View File
@@ -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]));
}
}
}
+138
View File
@@ -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
}
+27 -18
View File
@@ -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);
}
+78 -52
View File
@@ -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);
+10 -10
View File
@@ -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);
+103 -84
View File
@@ -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());
}
+8 -3
View File
@@ -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
+7 -7
View File
@@ -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);
}