Compare commits

...

11 Commits

Author SHA1 Message Date
rsync-bugs
945eba8c1f preparing for release of 1.7.2 1998-04-05 06:46:11 +00:00
Andrew Tridgell
d867229ba0 handle sparse files more efficiently 1998-04-05 06:43:38 +00:00
Andrew Tridgell
1b2d733af2 a couple more system calls wrapped in syscall.c 1998-04-05 06:26:24 +00:00
Andrew Tridgell
366345fe05 in local->local mode don't use exec to start the "remote" rsync,
instead just fork()
1998-04-05 06:07:37 +00:00
Andrew Tridgell
dd04a03440 fixed a bug in the hlink code - it wasn't taking account of the new
pointer list code for flist.
1998-04-05 04:34:52 +00:00
Andrew Tridgell
575f2fca9a fixed a string termination bug in the uidlist handling code. I've also
added a read_sbuf() routine that fixes this kind of bug generically to
avoid similar problems in future.
1998-04-01 05:20:19 +00:00
Andrew Tridgell
fc4e8d51ff don't need to test for SETPGRP any more as it is no longer used 1998-03-27 03:38:06 +00:00
Andrew Tridgell
98ae8c3e38 Solaris uses EEXIST instead of ENOTEMPTY. 1998-03-27 03:04:34 +00:00
rsync-bugs
49f4b973a1 preparing for release of 1.7.1 1998-03-26 06:11:18 +00:00
Andrew Tridgell
a070c37b7e fixed a bug I introduced in the last big commit 1998-03-26 06:09:04 +00:00
Andrew Tridgell
17faa41c7d added some debugging code 1998-03-26 05:48:37 +00:00
12 changed files with 248 additions and 129 deletions

View File

@@ -40,8 +40,6 @@ echo no)
AC_FUNC_MEMCMP
AC_FUNC_MMAP
AC_FUNC_UTIME_NULL
AC_FUNC_SETPGRP
AC_FUNC_GETPGRP
AC_CHECK_FUNCS(waitpid strtok pipe getcwd mkdir strdup strerror chown chmod mknod)
AC_CHECK_FUNCS(fchmod fstat strchr bcopy bzero readlink link utime utimes)
AC_CHECK_FUNCS(memmove getopt_long lchown setlinebuf)

View File

@@ -164,9 +164,9 @@ void recv_exclude_list(int f)
char line[MAXPATHLEN];
int l;
while ((l=read_int(f))) {
read_buf(f,line,l);
line[l] = 0;
add_exclude(line);
if (l >= MAXPATHLEN) overflow("recv_exclude_list");
read_sbuf(f,line,l);
add_exclude(line);
}
}

13
flist.c
View File

@@ -251,8 +251,10 @@ void receive_file_entry(struct file_struct **fptr,
bzero((char *)file,sizeof(*file));
(*fptr) = file;
if (l2 >= MAXPATHLEN-l1) overflow("receive_file_entry");
strncpy(thisname,lastname,l1);
read_buf(f,&thisname[l1],l2);
read_sbuf(f,&thisname[l1],l2);
thisname[l1+l2] = 0;
strncpy(lastname,thisname,MAXPATHLEN-1);
@@ -292,8 +294,7 @@ void receive_file_entry(struct file_struct **fptr,
int l = read_int(f);
file->link = (char *)malloc(l+1);
if (!file->link) out_of_memory("receive_file_entry 2");
read_buf(f,file->link,l);
file->link[l] = 0;
read_sbuf(f,file->link,l);
}
#if SUPPORT_HARD_LINKS
@@ -669,6 +670,9 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
write_int(f, io_error);
}
if (verbose > 2)
fprintf(FINFO,"send_file_list done\n");
return flist;
}
@@ -741,6 +745,9 @@ struct file_list *recv_file_list(int f)
io_error |= read_int(f);
}
if (verbose > 2)
fprintf(FINFO,"recv_file_list done\n");
return flist;
oom:

24
hlink.c
View File

@@ -47,23 +47,23 @@ static int hlink_count;
void init_hard_links(struct file_list *flist)
{
#if SUPPORT_HARD_LINKS
if (flist->count < 2) return;
int i;
if (flist->count < 2) return;
if (hlink_list) free(hlink_list);
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");
if (!(hlink_list =
(struct file_struct *)malloc(sizeof(hlink_list[0])*flist->count)))
out_of_memory("init_hard_links");
bcopy((char *)flist->files,
(char *)hlink_list,
sizeof(hlink_list[0])*flist->count);
for (i = 0; i < flist->count; i++)
bcopy(flist->files[i], &hlink_list[i], sizeof(hlink_list[0]));
qsort(hlink_list,flist->count,
sizeof(hlink_list[0]),
(int (*)())hlink_compare);
qsort(hlink_list,flist->count,
sizeof(hlink_list[0]),
(int (*)())hlink_compare);
hlink_count=flist->count;
hlink_count=flist->count;
#endif
}

82
io.c
View File

@@ -134,6 +134,7 @@ static int readfd(int fd,char *buffer,int N)
memcpy(buffer+total,read_buffer_p,ret);
read_buffer_p += ret;
read_buffer_len -= ret;
total += ret;
continue;
}
@@ -217,6 +218,12 @@ void read_buf(int f,char *buf,int len)
total_read += len;
}
void read_sbuf(int f,char *buf,int len)
{
read_buf(f,buf,len);
buf[len] = 0;
}
unsigned char read_byte(int f)
{
unsigned char c;
@@ -230,45 +237,66 @@ static int last_sparse;
int sparse_end(int f)
{
if (last_sparse) {
lseek(f,-1,SEEK_CUR);
return (write(f,&last_byte,1) == 1 ? 0 : -1);
}
last_sparse = 0;
return 0;
if (last_sparse) {
lseek(f,-1,SEEK_CUR);
return (write(f,&last_byte,1) == 1 ? 0 : -1);
}
last_sparse = 0;
return 0;
}
int write_sparse(int f,char *buf,int len)
static int write_sparse(int f,char *buf,int len)
{
int l1=0,l2=0;
int ret;
int l1=0,l2=0;
int ret;
if (!sparse_files)
return write(f,buf,len);
for (l1=0;l1<len && buf[l1]==0;l1++) ;
for (l2=0;l2<(len-l1) && buf[len-(l2+1)]==0;l2++) ;
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];
last_byte = buf[len-1];
if (l1 == len || l2 > 0)
last_sparse=1;
if (l1 == len || l2 > 0)
last_sparse=1;
if (l1 > 0)
lseek(f,l1,SEEK_CUR);
if (l1 > 0)
lseek(f,l1,SEEK_CUR);
if (l1 == len)
return len;
if (l1 == len)
return len;
if ((ret=write(f,buf+l1,len-(l1+l2))) != len-(l1+l2)) {
if (ret == -1 || ret == 0) return ret;
return (l1+ret);
}
if ((ret=write(f,buf+l1,len-(l1+l2))) != len-(l1+l2)) {
if (ret == -1 || ret == 0) return ret;
return (l1+ret);
}
if (l2 > 0)
lseek(f,l2,SEEK_CUR);
return len;
}
if (l2 > 0)
lseek(f,l2,SEEK_CUR);
return len;
int write_file(int f,char *buf,int len)
{
int ret = 0;
if (!sparse_files)
return write(f,buf,len);
while (len>0) {
int len1 = MIN(len, SPARSE_WRITE_SIZE);
int r1 = write_sparse(f, buf, len1);
if (r1 <= 0) {
if (ret > 0) return ret;
return r1;
}
len -= r1;
buf += r1;
ret += r1;
}
return ret;
}

141
main.c
View File

@@ -61,7 +61,7 @@ int io_error = 0;
extern int csum_length;
int am_server = 0;
static int sender;
int am_sender;
int recurse = 0;
static void usage(FILE *f);
@@ -73,7 +73,7 @@ static void report(int f)
if (!verbose) return;
if (am_server && sender) {
if (am_server && am_sender) {
write_longint(f,read_total());
write_longint(f,write_total());
write_longint(f,total_size);
@@ -81,7 +81,7 @@ static void report(int f)
return;
}
if (sender) {
if (am_sender) {
in = read_total();
out = write_total();
tsize = total_size;
@@ -115,7 +115,7 @@ static void server_options(char **args,int *argc)
args[ac++] = "--server";
if (!sender)
if (!am_sender)
args[ac++] = "--sender";
x = 1;
@@ -202,65 +202,70 @@ static void server_options(char **args,int *argc)
static int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
{
char *args[100];
int i,argc=0, ret;
char *tok,*dir=NULL;
char *args[100];
int i,argc=0, ret;
char *tok,*dir=NULL;
if (!local_server) {
if (!cmd)
cmd = getenv(RSYNC_RSH_ENV);
if (!cmd)
cmd = RSYNC_RSH;
cmd = strdup(cmd);
if (!cmd)
goto oom;
if (!local_server) {
if (!cmd)
cmd = getenv(RSYNC_RSH_ENV);
if (!cmd)
cmd = RSYNC_RSH;
cmd = strdup(cmd);
if (!cmd)
goto oom;
for (tok=strtok(cmd," ");tok;tok=strtok(NULL," ")) {
args[argc++] = tok;
}
for (tok=strtok(cmd," ");tok;tok=strtok(NULL," ")) {
args[argc++] = tok;
}
#if HAVE_REMSH
/* remsh (on HPUX) takes the arguments the other way around */
args[argc++] = machine;
if (user) {
args[argc++] = "-l";
args[argc++] = user;
}
/* remsh (on HPUX) takes the arguments the other way around */
args[argc++] = machine;
if (user) {
args[argc++] = "-l";
args[argc++] = user;
}
#else
if (user) {
args[argc++] = "-l";
args[argc++] = user;
}
args[argc++] = machine;
if (user) {
args[argc++] = "-l";
args[argc++] = user;
}
args[argc++] = machine;
#endif
}
args[argc++] = rsync_path;
args[argc++] = rsync_path;
server_options(args,&argc);
server_options(args,&argc);
}
args[argc++] = ".";
args[argc++] = ".";
if (path && *path)
args[argc++] = path;
if (path && *path)
args[argc++] = path;
args[argc] = NULL;
args[argc] = NULL;
if (verbose > 3) {
fprintf(FINFO,"cmd=");
for (i=0;i<argc;i++)
fprintf(FINFO,"%s ",args[i]);
fprintf(FINFO,"\n");
}
if (verbose > 3) {
fprintf(FINFO,"cmd=");
for (i=0;i<argc;i++)
fprintf(FINFO,"%s ",args[i]);
fprintf(FINFO,"\n");
}
ret = piped_child(args,f_in,f_out);
if (dir) free(dir);
if (local_server) {
ret = local_child(argc, args, f_in, f_out);
} else {
ret = piped_child(args,f_in,f_out);
}
return ret;
if (dir) free(dir);
return ret;
oom:
out_of_memory("do_cmd");
return 0; /* not reached */
out_of_memory("do_cmd");
return 0; /* not reached */
}
@@ -291,7 +296,7 @@ static char *get_local_name(struct file_list *flist,char *name)
if (!name)
return NULL;
if (mkdir(name,0777 & ~orig_umask) != 0) {
if (do_mkdir(name,0777 & ~orig_umask) != 0) {
fprintf(FERROR,"mkdir %s : %s (1)\n",name,strerror(errno));
exit_cleanup(1);
} else {
@@ -420,6 +425,22 @@ void do_server_recv(int argc,char *argv[])
}
void start_server(int argc, char *argv[])
{
setup_protocol(STDOUT_FILENO,STDIN_FILENO);
if (am_sender) {
recv_exclude_list(STDIN_FILENO);
if (cvs_exclude)
add_cvs_excludes();
do_server_sender(argc,argv);
} else {
do_server_recv(argc,argv);
}
exit_cleanup(0);
}
static void usage(FILE *f)
{
fprintf(f,"rsync version %s Copyright Andrew Tridgell and Paul Mackerras\n\n",
@@ -682,7 +703,7 @@ int main(int argc,char *argv[])
usage(FERROR);
exit_cleanup(1);
}
sender = 1;
am_sender = 1;
break;
case 'r':
@@ -740,17 +761,7 @@ int main(int argc,char *argv[])
#endif
if (am_server) {
setup_protocol(STDOUT_FILENO,STDIN_FILENO);
if (sender) {
recv_exclude_list(STDIN_FILENO);
if (cvs_exclude)
add_cvs_excludes();
do_server_sender(argc,argv);
} else {
do_server_recv(argc,argv);
}
exit_cleanup(0);
start_server(argc, argv);
}
if (argc < 2) {
@@ -761,14 +772,14 @@ int main(int argc,char *argv[])
p = strchr(argv[0],':');
if (p) {
sender = 0;
am_sender = 0;
*p = 0;
shell_machine = argv[0];
shell_path = p+1;
argc--;
argv++;
} else {
sender = 1;
am_sender = 1;
p = strchr(argv[argc-1],':');
if (!p) {
@@ -803,7 +814,7 @@ int main(int argc,char *argv[])
shell_path?shell_path:"");
}
if (!sender && argc != 1) {
if (!am_sender && argc != 1) {
usage(FERROR);
exit_cleanup(1);
}
@@ -819,9 +830,9 @@ int main(int argc,char *argv[])
if (verbose > 3)
fprintf(FINFO,"parent=%d child=%d sender=%d recurse=%d\n",
(int)getpid(),pid,sender,recurse);
(int)getpid(),pid,am_sender,recurse);
if (sender) {
if (am_sender) {
if (cvs_exclude)
add_cvs_excludes();
if (delete_mode)

18
rsync.c
View File

@@ -93,7 +93,7 @@ static int delete_file(char *fname)
}
if (do_rmdir(fname) == 0 || errno == ENOENT) return 0;
if (!force_delete || errno != ENOTEMPTY) {
if (!force_delete || (errno != ENOTEMPTY && errno != EEXIST)) {
fprintf(FERROR,"rmdir(%s) : %s\n", fname, strerror(errno));
return -1;
}
@@ -384,10 +384,10 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
}
statret = -1;
}
if (statret != 0 && mkdir(fname,file->mode) != 0 && errno != EEXIST) {
if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
if (!(relative_paths && errno==ENOENT &&
create_directory_path(fname)==0 &&
mkdir(fname,file->mode)==0)) {
do_mkdir(fname,file->mode)==0)) {
fprintf(FERROR,"mkdir %s : %s (2)\n",
fname,strerror(errno));
}
@@ -561,7 +561,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname)
sum_update(data,i);
if (fd != -1 && write_sparse(fd,data,i) != i) {
if (fd != -1 && write_file(fd,data,i) != i) {
fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
exit_cleanup(1);
}
@@ -582,7 +582,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname)
see_token(map, len);
sum_update(map,len);
if (fd != -1 && write_sparse(fd,map,len) != len) {
if (fd != -1 && write_file(fd,map,len) != len) {
fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
exit_cleanup(1);
}
@@ -618,7 +618,7 @@ static void delete_one(struct file_struct *f)
}
} else {
if (do_rmdir(f_name(f)) != 0) {
if (errno != ENOTEMPTY)
if (errno != ENOTEMPTY && errno != EEXIST)
fprintf(FERROR,"rmdir %s : %s\n",f_name(f),strerror(errno));
} else if (verbose) {
fprintf(FINFO,"deleting directory %s\n",f_name(f));
@@ -834,7 +834,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
} else {
sprintf(fnametmp,"%s.XXXXXX",fname);
}
if (NULL == mktemp(fnametmp)) {
if (NULL == do_mktemp(fnametmp)) {
fprintf(FERROR,"mktemp %s failed\n",fnametmp);
receive_data(f_in,buf,-1,NULL);
if (buf) unmap_file(buf);
@@ -878,14 +878,14 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
continue;
}
sprintf(fnamebak,"%s%s",fname,backup_suffix);
if (rename(fname,fnamebak) != 0 && errno != ENOENT) {
if (do_rename(fname,fnamebak) != 0 && errno != ENOENT) {
fprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
continue;
}
}
/* move tmp file over real file */
if (rename(fnametmp,fname) != 0) {
if (do_rename(fnametmp,fname) != 0) {
if (errno == EXDEV) {
/* rename failed on cross-filesystem link.
Copy the file instead. */

View File

@@ -43,7 +43,7 @@
#define MIN_PROTOCOL_VERSION 11
#define MAX_PROTOCOL_VERSION 30
#define SPARSE_WRITE_SIZE (4*1024)
#define SPARSE_WRITE_SIZE (1024)
#define WRITE_SIZE (32*1024)
#define CHUNK_SIZE (32*1024)
#define MAX_MAP_SIZE (4*1024*1024)

View File

@@ -77,3 +77,21 @@ int do_chmod(const char *path, mode_t mode)
return chmod(path, mode);
}
#endif
int do_rename(char *fname1, char *fname2)
{
if (dry_run) return 0;
return rename(fname1, fname2);
}
int do_mkdir(char *fname, mode_t mode)
{
if (dry_run) return 0;
return mkdir(fname, mode);
}
char *do_mktemp(char *template)
{
if (dry_run) return NULL;
return mktemp(template);
}

View File

@@ -256,9 +256,9 @@ void recv_uid_list(int f, struct file_list *flist)
id = read_int(f);
while (id != 0) {
int len = read_byte(f);
name = (char *)malloc(len);
name = (char *)malloc(len+1);
if (!name) out_of_memory("recv_uid_list");
read_buf(f, name, len);
read_sbuf(f, name, len);
if (!list) {
uidlist = add_list(id, name);
list = uidlist;
@@ -279,9 +279,9 @@ void recv_uid_list(int f, struct file_list *flist)
id = read_int(f);
while (id != 0) {
int len = read_byte(f);
name = (char *)malloc(len);
name = (char *)malloc(len+1);
if (!name) out_of_memory("recv_uid_list");
read_buf(f, name, len);
read_sbuf(f, name, len);
if (!list) {
gidlist = add_list(id, name);
list = gidlist;

61
util.c
View File

@@ -159,10 +159,67 @@ int piped_child(char **command,int *f_in,int *f_out)
return pid;
}
int local_child(int argc, char **argv,int *f_in,int *f_out)
{
int pid;
int to_child_pipe[2];
int from_child_pipe[2];
if (pipe(to_child_pipe) < 0 ||
pipe(from_child_pipe) < 0) {
fprintf(FERROR,"pipe: %s\n",strerror(errno));
exit_cleanup(1);
}
pid = do_fork();
if (pid < 0) {
fprintf(FERROR,"fork: %s\n",strerror(errno));
exit_cleanup(1);
}
if (pid == 0) {
extern int am_sender;
extern int am_server;
am_sender = !am_sender;
am_server = 1;
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
close(to_child_pipe[1]) < 0 ||
close(from_child_pipe[0]) < 0 ||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
fprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
exit_cleanup(1);
}
if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
start_server(argc, argv);
}
if (close(from_child_pipe[1]) < 0 ||
close(to_child_pipe[0]) < 0) {
fprintf(FERROR,"Failed to close : %s\n",strerror(errno));
exit_cleanup(1);
}
*f_in = from_child_pipe[0];
*f_out = to_child_pipe[1];
return pid;
}
void out_of_memory(char *str)
{
fprintf(FERROR,"out of memory in %s\n",str);
fprintf(FERROR,"ERROR: out of memory in %s\n",str);
exit_cleanup(1);
}
void overflow(char *str)
{
fprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
exit_cleanup(1);
}
@@ -241,7 +298,7 @@ int create_directory_path(char *fname)
p = fname;
while ((p=strchr(p,'/'))) {
*p = 0;
mkdir(fname,0777 & ~orig_umask);
do_mkdir(fname,0777 & ~orig_umask);
*p = '/';
p++;
}

View File

@@ -1 +1 @@
#define VERSION "1.7.0"
#define VERSION "1.7.2"