mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-27 00:05:36 -04:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
143384f367 | ||
|
|
8c3b04730b | ||
|
|
aa9b77a56c | ||
|
|
b72f24c719 | ||
|
|
a800434a82 | ||
|
|
3b3c3d4390 | ||
|
|
d846b09874 | ||
|
|
1d3754aede | ||
|
|
e44f9a12c4 | ||
|
|
5243c216d6 | ||
|
|
79a51e7ee6 | ||
|
|
cad2bba7d8 | ||
|
|
fe8c0a9824 | ||
|
|
6cdc6b1344 | ||
|
|
05848a2cc7 | ||
|
|
528bfcd79a | ||
|
|
a1e13a937c | ||
|
|
e3fe383aaa | ||
|
|
43bd68e5dd | ||
|
|
ea2111d10a | ||
|
|
4c36ddbeec | ||
|
|
2b6b4d539b | ||
|
|
35f69d8ad9 | ||
|
|
7b1ce0d746 |
@@ -25,7 +25,7 @@ ZLIBOBJ=zlib/deflate.o zlib/infblock.o zlib/infcodes.o zlib/inffast.o \
|
||||
zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
|
||||
zlib/zutil.o zlib/adler32.o
|
||||
OBJS1=rsync.o exclude.o util.o md4.o main.o checksum.o match.o syscall.o log.o
|
||||
OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o
|
||||
OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o fileio.o
|
||||
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
|
||||
OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ)
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ static int rsync_module(int fd, int i)
|
||||
}
|
||||
|
||||
p = lp_exclude_from(i);
|
||||
add_exclude_file(p, 1);
|
||||
add_exclude_file(p, 1, 0);
|
||||
|
||||
p = lp_exclude(i);
|
||||
add_exclude_line(p);
|
||||
@@ -362,6 +362,11 @@ int daemon_main(void)
|
||||
{
|
||||
extern char *config_file;
|
||||
|
||||
/* this ensures that we don't call getcwd after the chroot,
|
||||
which doesn't work on platforms that use popen("pwd","r")
|
||||
for getcwd */
|
||||
push_dir("/", 0);
|
||||
|
||||
if (is_a_socket(STDIN_FILENO)) {
|
||||
/* we are running via inetd */
|
||||
return start_daemon(STDIN_FILENO);
|
||||
|
||||
2
compat.c
2
compat.c
@@ -44,10 +44,8 @@ void setup_protocol(int f_out,int f_in)
|
||||
if (am_server) {
|
||||
remote_version = read_int(f_in);
|
||||
write_int(f_out,PROTOCOL_VERSION);
|
||||
write_flush(f_out);
|
||||
} else {
|
||||
write_int(f_out,PROTOCOL_VERSION);
|
||||
write_flush(f_out);
|
||||
remote_version = read_int(f_in);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ AC_FUNC_MEMCMP
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_CHECK_FUNCS(mmap munmap waitpid getcwd strdup strerror chown chmod mknod)
|
||||
AC_CHECK_FUNCS(fchmod fstat strchr bcopy bzero readlink link utime utimes)
|
||||
AC_CHECK_FUNCS(memmove getopt_long lchown setlinebuf vsnprintf setsid glob)
|
||||
AC_CHECK_FUNCS(memmove getopt_long lchown setlinebuf vsnprintf setsid glob strpbrk)
|
||||
|
||||
echo $ac_n "checking for working fnmatch... $ac_c"
|
||||
AC_TRY_RUN([#include <fnmatch.h>
|
||||
|
||||
325
exclude.c
325
exclude.c
@@ -17,160 +17,229 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
a lot of this stuff was derived from GNU tar
|
||||
*/
|
||||
/* a lot of this stuff was originally derived from GNU tar, although
|
||||
it has now changed so much that it is hard to tell :) */
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
|
||||
static char **exclude_list;
|
||||
static struct exclude_struct **exclude_list;
|
||||
|
||||
static int is_regex(char *str)
|
||||
/* build an exclude structure given a exclude pattern */
|
||||
static struct exclude_struct *make_exclude(char *pattern, int include)
|
||||
{
|
||||
return strchr(str, '*') || strchr(str, '[') || strchr(str, '?');
|
||||
struct exclude_struct *ret;
|
||||
|
||||
ret = (struct exclude_struct *)malloc(sizeof(*ret));
|
||||
if (!ret) out_of_memory("make_exclude");
|
||||
|
||||
memset(ret, 0, sizeof(*ret));
|
||||
|
||||
ret->orig = strdup(pattern);
|
||||
|
||||
if (strncmp(pattern,"- ",2) == 0) {
|
||||
pattern += 2;
|
||||
} else if (strncmp(pattern,"+ ",2) == 0) {
|
||||
ret->include = 1;
|
||||
pattern += 2;
|
||||
} else {
|
||||
ret->include = include;
|
||||
}
|
||||
|
||||
ret->pattern = strdup(pattern);
|
||||
|
||||
if (!ret->orig || !ret->pattern) out_of_memory("make_exclude");
|
||||
|
||||
if (strpbrk(pattern, "*[?")) ret->regular_exp = 1;
|
||||
|
||||
if (strlen(pattern) > 1 && pattern[strlen(pattern)-1] == '/') {
|
||||
ret->pattern[strlen(pattern)-1] = 0;
|
||||
ret->directory = 1;
|
||||
}
|
||||
|
||||
if (!strchr(ret->pattern,'/')) {
|
||||
ret->local = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void free_exclude(struct exclude_struct *ex)
|
||||
{
|
||||
free(ex->orig);
|
||||
free(ex->pattern);
|
||||
memset(ex,0,sizeof(*ex));
|
||||
free(ex);
|
||||
}
|
||||
|
||||
static int check_one_exclude(char *name,struct exclude_struct *ex,
|
||||
STRUCT_STAT *st)
|
||||
{
|
||||
char *p;
|
||||
int match_start=0;
|
||||
char *pattern = ex->pattern;
|
||||
|
||||
if (ex->local && (p=strrchr(name,'/')))
|
||||
name = p+1;
|
||||
|
||||
if (!name[0]) return 0;
|
||||
|
||||
if (ex->directory && !S_ISDIR(st->st_mode)) return 0;
|
||||
|
||||
if (*pattern == '/' && *name != '/') {
|
||||
match_start = 1;
|
||||
pattern++;
|
||||
}
|
||||
|
||||
if (ex->regular_exp) {
|
||||
if (fnmatch(pattern, name, 0) == 0)
|
||||
return 1;
|
||||
} else {
|
||||
int l1 = strlen(name);
|
||||
int l2 = strlen(pattern);
|
||||
if (l2 <= l1 &&
|
||||
strcmp(name+(l1-l2),pattern) == 0 &&
|
||||
(l1==l2 || (!match_start && name[l1-(l2+1)] == '/')))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int check_one_exclude(char *name,char *pattern)
|
||||
int check_exclude(char *name,struct exclude_struct **local_exclude_list,
|
||||
STRUCT_STAT *st)
|
||||
{
|
||||
char *p;
|
||||
int n;
|
||||
|
||||
if (!strchr(pattern,'/') && (p=strrchr(name,'/')))
|
||||
name = p+1;
|
||||
if (exclude_list) {
|
||||
for (n=0; exclude_list[n]; n++)
|
||||
if (check_one_exclude(name,exclude_list[n],st))
|
||||
return !exclude_list[n]->include;
|
||||
}
|
||||
|
||||
if (!name[0]) return 0;
|
||||
if (local_exclude_list) {
|
||||
for (n=0; local_exclude_list[n]; n++)
|
||||
if (check_one_exclude(name,local_exclude_list[n],st))
|
||||
return !local_exclude_list[n]->include;
|
||||
}
|
||||
|
||||
if (*pattern == '/' && *name != '/') pattern++;
|
||||
|
||||
if (is_regex(pattern)) {
|
||||
if (fnmatch(pattern, name, 0) == 0)
|
||||
return 1;
|
||||
} else {
|
||||
int l1 = strlen(name);
|
||||
int l2 = strlen(pattern);
|
||||
if (l2 <= l1 &&
|
||||
strcmp(name+(l1-l2),pattern) == 0 &&
|
||||
(l1==l2 || name[l1-(l2+1)] == '/'))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int check_exclude(char *name,char **local_exclude_list)
|
||||
void add_exclude_list(char *pattern,struct exclude_struct ***list, int include)
|
||||
{
|
||||
int n;
|
||||
int len=0;
|
||||
if (list && *list)
|
||||
for (; (*list)[len]; len++) ;
|
||||
|
||||
if (exclude_list) {
|
||||
for (n=0; exclude_list[n]; n++)
|
||||
if (check_one_exclude(name,exclude_list[n]))
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(pattern,"!") == 0) {
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"clearing exclude list\n");
|
||||
while ((len)--) {
|
||||
free_exclude((*list)[len]);
|
||||
}
|
||||
free((*list));
|
||||
*list = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (local_exclude_list) {
|
||||
for (n=0; local_exclude_list[n]; n++)
|
||||
if (check_one_exclude(name,local_exclude_list[n]))
|
||||
return 1;
|
||||
}
|
||||
*list = (struct exclude_struct **)Realloc(*list,sizeof(struct exclude_struct *)*(len+2));
|
||||
|
||||
if (!*list || !((*list)[len] = make_exclude(pattern, include)))
|
||||
out_of_memory("add_exclude");
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"add_exclude(%s)\n",pattern);
|
||||
|
||||
(*list)[len+1] = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
void add_exclude(char *pattern, int include)
|
||||
{
|
||||
add_exclude_list(pattern,&exclude_list, include);
|
||||
}
|
||||
|
||||
struct exclude_struct **make_exclude_list(char *fname,
|
||||
struct exclude_struct **list1,
|
||||
int fatal, int include)
|
||||
{
|
||||
struct exclude_struct **list=list1;
|
||||
FILE *f = fopen(fname,"r");
|
||||
char line[MAXPATHLEN];
|
||||
if (!f) {
|
||||
if (fatal) {
|
||||
rprintf(FERROR,"%s : %s\n",fname,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
while (fgets(line,MAXPATHLEN,f)) {
|
||||
int l = strlen(line);
|
||||
if (l && line[l-1] == '\n') l--;
|
||||
line[l] = 0;
|
||||
if (line[0]) add_exclude_list(line,&list,include);
|
||||
}
|
||||
fclose(f);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
void add_exclude_list(char *pattern,char ***list)
|
||||
{
|
||||
int len=0;
|
||||
if (list && *list)
|
||||
for (; (*list)[len]; len++) ;
|
||||
|
||||
if (strcmp(pattern,"!") == 0) {
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"clearing exclude list\n");
|
||||
while ((len)--)
|
||||
free((*list)[len]);
|
||||
free((*list));
|
||||
*list = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*list) {
|
||||
*list = (char **)malloc(sizeof(char *)*2);
|
||||
} else {
|
||||
*list = (char **)realloc(*list,sizeof(char *)*(len+2));
|
||||
}
|
||||
|
||||
if (!*list || !((*list)[len] = strdup(pattern)))
|
||||
out_of_memory("add_exclude");
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"add_exclude(%s)\n",pattern);
|
||||
|
||||
(*list)[len+1] = NULL;
|
||||
}
|
||||
|
||||
void add_exclude(char *pattern)
|
||||
{
|
||||
add_exclude_list(pattern,&exclude_list);
|
||||
}
|
||||
|
||||
char **make_exclude_list(char *fname,char **list1,int fatal)
|
||||
{
|
||||
char **list=list1;
|
||||
FILE *f = fopen(fname,"r");
|
||||
char line[MAXPATHLEN];
|
||||
if (!f) {
|
||||
if (fatal) {
|
||||
rprintf(FERROR,"%s : %s\n",fname,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
while (fgets(line,MAXPATHLEN,f)) {
|
||||
int l = strlen(line);
|
||||
if (l && line[l-1] == '\n') l--;
|
||||
line[l] = 0;
|
||||
if (line[0]) add_exclude_list(line,&list);
|
||||
}
|
||||
fclose(f);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
void add_exclude_file(char *fname,int fatal)
|
||||
void add_exclude_file(char *fname,int fatal,int include)
|
||||
{
|
||||
if (!fname || !*fname) return;
|
||||
|
||||
exclude_list = make_exclude_list(fname,exclude_list,fatal);
|
||||
exclude_list = make_exclude_list(fname,exclude_list,fatal,include);
|
||||
}
|
||||
|
||||
|
||||
void send_exclude_list(int f)
|
||||
{
|
||||
int i;
|
||||
if (exclude_list)
|
||||
for (i=0;exclude_list[i];i++) {
|
||||
int l = strlen(exclude_list[i]);
|
||||
if (l == 0) continue;
|
||||
write_int(f,l);
|
||||
write_buf(f,exclude_list[i],l);
|
||||
}
|
||||
write_int(f,0);
|
||||
int i;
|
||||
extern int remote_version;
|
||||
|
||||
if (!exclude_list) {
|
||||
write_int(f,0);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0;exclude_list[i];i++) {
|
||||
char *pattern = exclude_list[i]->orig;
|
||||
int l;
|
||||
|
||||
if (remote_version < 19) {
|
||||
if (strncmp(pattern,"+ ", 2)==0) {
|
||||
rprintf(FERROR,"remote rsync does not support include syntax - aborting\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
if (strncmp(pattern,"- ", 2) == 0) {
|
||||
pattern += 2;
|
||||
}
|
||||
}
|
||||
|
||||
l = strlen(pattern);
|
||||
if (l == 0) continue;
|
||||
write_int(f,l);
|
||||
write_buf(f,pattern,l);
|
||||
}
|
||||
|
||||
write_int(f,0);
|
||||
}
|
||||
|
||||
|
||||
void recv_exclude_list(int f)
|
||||
{
|
||||
char line[MAXPATHLEN];
|
||||
int l;
|
||||
while ((l=read_int(f))) {
|
||||
if (l >= MAXPATHLEN) overflow("recv_exclude_list");
|
||||
read_sbuf(f,line,l);
|
||||
add_exclude(line);
|
||||
}
|
||||
char line[MAXPATHLEN];
|
||||
int l;
|
||||
while ((l=read_int(f))) {
|
||||
if (l >= MAXPATHLEN) overflow("recv_exclude_list");
|
||||
read_sbuf(f,line,l);
|
||||
add_exclude(line,0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +250,7 @@ void add_exclude_line(char *p)
|
||||
p = strdup(p);
|
||||
if (!p) out_of_memory("add_exclude_line");
|
||||
for (tok=strtok(p," "); tok; tok=strtok(NULL," "))
|
||||
add_exclude(tok);
|
||||
add_exclude(tok, 0);
|
||||
free(p);
|
||||
}
|
||||
|
||||
@@ -197,17 +266,17 @@ static char *cvs_ignore_list[] = {
|
||||
|
||||
void add_cvs_excludes(void)
|
||||
{
|
||||
char fname[MAXPATHLEN];
|
||||
char *p;
|
||||
int i;
|
||||
char fname[MAXPATHLEN];
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
for (i=0; cvs_ignore_list[i]; i++)
|
||||
add_exclude(cvs_ignore_list[i]);
|
||||
for (i=0; cvs_ignore_list[i]; i++)
|
||||
add_exclude(cvs_ignore_list[i], 0);
|
||||
|
||||
if ((p=getenv("HOME")) && strlen(p) < (MAXPATHLEN-12)) {
|
||||
slprintf(fname,sizeof(fname)-1, "%s/.cvsignore",p);
|
||||
add_exclude_file(fname,0);
|
||||
}
|
||||
if ((p=getenv("HOME")) && strlen(p) < (MAXPATHLEN-12)) {
|
||||
slprintf(fname,sizeof(fname)-1, "%s/.cvsignore",p);
|
||||
add_exclude_file(fname,0,0);
|
||||
}
|
||||
|
||||
add_exclude_line(getenv("CVSIGNORE"));
|
||||
add_exclude_line(getenv("CVSIGNORE"));
|
||||
}
|
||||
|
||||
218
fileio.c
Normal file
218
fileio.c
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
File IO utilities used in rsync
|
||||
*/
|
||||
#include "rsync.h"
|
||||
|
||||
static char last_byte;
|
||||
static int last_sparse;
|
||||
extern int sparse_files;
|
||||
|
||||
int sparse_end(int f)
|
||||
{
|
||||
if (last_sparse) {
|
||||
do_lseek(f,-1,SEEK_CUR);
|
||||
return (write(f,&last_byte,1) == 1 ? 0 : -1);
|
||||
}
|
||||
last_sparse = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int write_sparse(int f,char *buf,int len)
|
||||
{
|
||||
int l1=0,l2=0;
|
||||
int ret;
|
||||
|
||||
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];
|
||||
|
||||
if (l1 == len || l2 > 0)
|
||||
last_sparse=1;
|
||||
|
||||
if (l1 > 0)
|
||||
do_lseek(f,l1,SEEK_CUR);
|
||||
|
||||
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 (l2 > 0)
|
||||
do_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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct map_struct *map_file(int fd,OFF_T len)
|
||||
{
|
||||
struct map_struct *ret;
|
||||
ret = (struct map_struct *)malloc(sizeof(*ret));
|
||||
if (!ret) out_of_memory("map_file");
|
||||
|
||||
ret->map = NULL;
|
||||
ret->fd = fd;
|
||||
ret->size = len;
|
||||
ret->p = NULL;
|
||||
ret->p_size = 0;
|
||||
ret->p_offset = 0;
|
||||
ret->p_len = 0;
|
||||
|
||||
#ifdef USE_MMAP
|
||||
len = MIN(len, MAX_MAP_SIZE);
|
||||
ret->map = (char *)do_mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
|
||||
if (ret->map == (char *)-1) {
|
||||
ret->map = NULL;
|
||||
} else {
|
||||
ret->p_len = len;
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
char *map_ptr(struct map_struct *map,OFF_T offset,int len)
|
||||
{
|
||||
int nread;
|
||||
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
|
||||
if (len > (map->size-offset))
|
||||
len = map->size-offset;
|
||||
|
||||
#ifdef USE_MMAP
|
||||
if (map->map) {
|
||||
if (offset >= map->p_offset &&
|
||||
offset+len <= map->p_offset+map->p_len) {
|
||||
return (map->map + (offset - map->p_offset));
|
||||
}
|
||||
if (munmap(map->map, map->p_len) != 0) {
|
||||
rprintf(FERROR,"munmap failed : %s\n", strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
/* align the mmap region on a nice boundary back a bit from
|
||||
where it is asked for to allow for some seeking */
|
||||
if (offset > 2*CHUNK_SIZE) {
|
||||
map->p_offset = offset - 2*CHUNK_SIZE;
|
||||
map->p_offset &= ~((OFF_T)(CHUNK_SIZE-1));
|
||||
} else {
|
||||
map->p_offset = 0;
|
||||
}
|
||||
|
||||
/* map up to MAX_MAP_SIZE */
|
||||
map->p_len = MAX(len, MAX_MAP_SIZE);
|
||||
map->p_len = MIN(map->p_len, map->size - map->p_offset);
|
||||
|
||||
map->map = (char *)do_mmap(NULL,map->p_len,PROT_READ,
|
||||
MAP_SHARED,map->fd,map->p_offset);
|
||||
|
||||
if (map->map == (char *)-1) {
|
||||
map->map = NULL;
|
||||
map->p_len = 0;
|
||||
map->p_offset = 0;
|
||||
} else {
|
||||
return (map->map + (offset - map->p_offset));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (offset >= map->p_offset &&
|
||||
offset+len <= map->p_offset+map->p_len) {
|
||||
return (map->p + (offset - map->p_offset));
|
||||
}
|
||||
|
||||
len = MAX(len,CHUNK_SIZE);
|
||||
if (len > (map->size-offset))
|
||||
len = map->size-offset;
|
||||
|
||||
if (len > map->p_size) {
|
||||
if (map->p) free(map->p);
|
||||
map->p = (char *)malloc(len);
|
||||
if (!map->p) out_of_memory("map_ptr");
|
||||
map->p_size = len;
|
||||
}
|
||||
|
||||
map->p_offset = offset;
|
||||
map->p_len = len;
|
||||
|
||||
if (do_lseek(map->fd,offset,SEEK_SET) != offset) {
|
||||
rprintf(FERROR,"lseek failed in map_ptr\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
if ((nread=read(map->fd,map->p,len)) != len) {
|
||||
if (nread < 0) nread = 0;
|
||||
/* the best we can do is zero the buffer - the file
|
||||
has changed mid transfer! */
|
||||
memset(map->p+nread, 0, len - nread);
|
||||
}
|
||||
|
||||
return map->p;
|
||||
}
|
||||
|
||||
|
||||
void unmap_file(struct map_struct *map)
|
||||
{
|
||||
#ifdef USE_MMAP
|
||||
if (map->map) {
|
||||
munmap(map->map,map->p_len);
|
||||
map->map = NULL;
|
||||
}
|
||||
#endif
|
||||
if (map->p) {
|
||||
free(map->p);
|
||||
map->p = NULL;
|
||||
}
|
||||
memset(map, 0, sizeof(*map));
|
||||
free(map);
|
||||
}
|
||||
|
||||
105
flist.c
105
flist.c
@@ -21,12 +21,13 @@
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern struct stats stats;
|
||||
|
||||
extern int csum_length;
|
||||
|
||||
extern int verbose;
|
||||
extern int am_server;
|
||||
extern int always_checksum;
|
||||
extern int64 total_size;
|
||||
|
||||
extern int cvs_exclude;
|
||||
|
||||
@@ -46,7 +47,7 @@ extern int copy_links;
|
||||
extern int remote_version;
|
||||
extern int io_error;
|
||||
|
||||
static char **local_exclude_list;
|
||||
static struct exclude_struct **local_exclude_list;
|
||||
|
||||
int link_stat(const char *Path, STRUCT_STAT *Buffer)
|
||||
{
|
||||
@@ -67,7 +68,7 @@ int link_stat(const char *Path, STRUCT_STAT *Buffer)
|
||||
*/
|
||||
static int match_file_name(char *fname,STRUCT_STAT *st)
|
||||
{
|
||||
if (check_exclude(fname,local_exclude_list)) {
|
||||
if (check_exclude(fname,local_exclude_list,st)) {
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"excluding file %s\n",fname);
|
||||
return 0;
|
||||
@@ -90,49 +91,6 @@ static void send_directory(int f,struct file_list *flist,char *dir);
|
||||
|
||||
static char *flist_dir;
|
||||
|
||||
static void clean_fname(char *name)
|
||||
{
|
||||
char *p;
|
||||
int l;
|
||||
int modified = 1;
|
||||
|
||||
if (!name) return;
|
||||
|
||||
while (modified) {
|
||||
modified = 0;
|
||||
|
||||
if ((p=strstr(name,"/./"))) {
|
||||
modified = 1;
|
||||
while (*p) {
|
||||
p[0] = p[2];
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((p=strstr(name,"//"))) {
|
||||
modified = 1;
|
||||
while (*p) {
|
||||
p[0] = p[1];
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (strncmp(p=name,"./",2) == 0) {
|
||||
modified = 1;
|
||||
do {
|
||||
p[0] = p[2];
|
||||
} while (*p++);
|
||||
}
|
||||
|
||||
l = strlen(p=name);
|
||||
if (l > 1 && p[l-1] == '/') {
|
||||
modified = 1;
|
||||
p[l-1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
|
||||
{
|
||||
@@ -169,6 +127,11 @@ void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
|
||||
if (l1 > 0) flags |= SAME_NAME;
|
||||
if (l2 > 255) flags |= LONG_NAME;
|
||||
|
||||
/* we must make sure we don't send a zero flags byte or the other
|
||||
end will terminate the flist transfer */
|
||||
if (flags == 0 && !S_ISDIR(file->mode)) flags |= FLAG_DELETE;
|
||||
if (flags == 0) flags |= LONG_NAME;
|
||||
|
||||
write_byte(f,flags);
|
||||
if (flags & SAME_NAME)
|
||||
write_byte(f,l1);
|
||||
@@ -459,7 +422,7 @@ static struct file_struct *make_file(char *fname)
|
||||
}
|
||||
|
||||
if (!S_ISDIR(st.st_mode))
|
||||
total_size += st.st_size;
|
||||
stats.total_size += st.st_size;
|
||||
|
||||
return file;
|
||||
}
|
||||
@@ -493,10 +456,10 @@ static void send_file_name(int f,struct file_list *flist,char *fname,
|
||||
}
|
||||
|
||||
if (S_ISDIR(file->mode) && recursive) {
|
||||
char **last_exclude_list = local_exclude_list;
|
||||
send_directory(f,flist,f_name(file));
|
||||
local_exclude_list = last_exclude_list;
|
||||
return;
|
||||
struct exclude_struct **last_exclude_list = local_exclude_list;
|
||||
send_directory(f,flist,f_name(file));
|
||||
local_exclude_list = last_exclude_list;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,7 +498,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
|
||||
if (cvs_exclude) {
|
||||
if (strlen(fname) + strlen(".cvsignore") <= MAXPATHLEN-1) {
|
||||
strcpy(p,".cvsignore");
|
||||
local_exclude_list = make_exclude_list(fname,NULL,0);
|
||||
local_exclude_list = make_exclude_list(fname,NULL,0,0);
|
||||
} else {
|
||||
io_error = 1;
|
||||
rprintf(FINFO,"cannot cvs-exclude in long-named directory %s\n",fname);
|
||||
@@ -548,7 +511,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
|
||||
strcmp(dname,"..")==0)
|
||||
continue;
|
||||
strlcpy(p,dname,MAXPATHLEN-(l+1));
|
||||
send_file_name(f,flist,fname,recurse,FLAG_DELETE);
|
||||
send_file_name(f,flist,fname,recurse,0);
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
@@ -561,15 +524,17 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
|
||||
int i,l;
|
||||
STRUCT_STAT st;
|
||||
char *p,*dir;
|
||||
char dbuf[MAXPATHLEN];
|
||||
char lastpath[MAXPATHLEN]="";
|
||||
struct file_list *flist;
|
||||
int64 start_write;
|
||||
|
||||
if (verbose && recurse && !am_server && f != -1) {
|
||||
rprintf(FINFO,"building file list ... ");
|
||||
rflush(FINFO);
|
||||
}
|
||||
|
||||
start_write = stats.total_written;
|
||||
|
||||
flist = (struct file_list *)malloc(sizeof(flist[0]));
|
||||
if (!flist) out_of_memory("send_file_list");
|
||||
|
||||
@@ -641,24 +606,23 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
|
||||
fname = ".";
|
||||
|
||||
if (dir && *dir) {
|
||||
if (getcwd(dbuf,MAXPATHLEN-1) == NULL) {
|
||||
rprintf(FERROR,"getwd : %s\n",strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
if (chdir(dir) != 0) {
|
||||
char *olddir = push_dir(dir, 1);
|
||||
|
||||
if (!olddir) {
|
||||
io_error=1;
|
||||
rprintf(FERROR,"chdir %s : %s\n",
|
||||
rprintf(FERROR,"push_dir %s : %s\n",
|
||||
dir,strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
flist_dir = dir;
|
||||
if (one_file_system)
|
||||
set_filesystem(fname);
|
||||
send_file_name(f,flist,fname,recurse,FLAG_DELETE);
|
||||
flist_dir = NULL;
|
||||
if (chdir(dbuf) != 0) {
|
||||
rprintf(FERROR,"chdir %s : %s\n",
|
||||
dbuf,strerror(errno));
|
||||
if (pop_dir(olddir) != 0) {
|
||||
rprintf(FERROR,"pop_dir %s : %s\n",
|
||||
dir,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
continue;
|
||||
@@ -691,7 +655,8 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
|
||||
|
||||
if (f != -1) {
|
||||
io_end_buffering(f);
|
||||
write_flush(f);
|
||||
stats.flist_size = stats.total_written - start_write;
|
||||
stats.num_files = flist->count;
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
@@ -705,12 +670,15 @@ struct file_list *recv_file_list(int f)
|
||||
{
|
||||
struct file_list *flist;
|
||||
unsigned char flags;
|
||||
int64 start_read;
|
||||
|
||||
if (verbose && recurse && !am_server) {
|
||||
rprintf(FINFO,"receiving file list ... ");
|
||||
rflush(FINFO);
|
||||
}
|
||||
|
||||
start_read = stats.total_read;
|
||||
|
||||
flist = (struct file_list *)malloc(sizeof(flist[0]));
|
||||
if (!flist)
|
||||
goto oom;
|
||||
@@ -741,7 +709,7 @@ struct file_list *recv_file_list(int f)
|
||||
receive_file_entry(&flist->files[i],flags,f);
|
||||
|
||||
if (S_ISREG(flist->files[i]->mode))
|
||||
total_size += flist->files[i]->length;
|
||||
stats.total_size += flist->files[i]->length;
|
||||
|
||||
flist->count++;
|
||||
|
||||
@@ -772,6 +740,9 @@ struct file_list *recv_file_list(int f)
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"recv_file_list done\n");
|
||||
|
||||
stats.flist_size = stats.total_read - start_read;
|
||||
stats.num_files = flist->count;
|
||||
|
||||
return flist;
|
||||
|
||||
oom:
|
||||
@@ -786,8 +757,8 @@ int file_compare(struct file_struct **f1,struct file_struct **f2)
|
||||
if (!(*f1)->basename) return -1;
|
||||
if (!(*f2)->basename) return 1;
|
||||
if ((*f1)->dirname == (*f2)->dirname)
|
||||
return strcmp((*f1)->basename, (*f2)->basename);
|
||||
return strcmp(f_name(*f1),f_name(*f2));
|
||||
return u_strcmp((*f1)->basename, (*f2)->basename);
|
||||
return u_strcmp(f_name(*f1),f_name(*f2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
415
io.c
415
io.c
@@ -24,34 +24,20 @@
|
||||
*/
|
||||
#include "rsync.h"
|
||||
|
||||
static int64 total_written;
|
||||
static int64 total_read;
|
||||
|
||||
static int io_multiplexing_out;
|
||||
static int io_multiplexing_in;
|
||||
static int multiplex_in_fd;
|
||||
static int multiplex_out_fd;
|
||||
static time_t last_io;
|
||||
|
||||
static int eof_error=1;
|
||||
extern int verbose;
|
||||
extern int sparse_files;
|
||||
extern int io_timeout;
|
||||
|
||||
int64 write_total(void)
|
||||
{
|
||||
return total_written;
|
||||
}
|
||||
|
||||
int64 read_total(void)
|
||||
{
|
||||
return total_read;
|
||||
}
|
||||
extern struct stats stats;
|
||||
|
||||
static int buffer_f_in = -1;
|
||||
|
||||
void setup_nonblocking(int f_in,int f_out)
|
||||
void setup_readbuffer(int f_in)
|
||||
{
|
||||
set_blocking(f_out,0);
|
||||
buffer_f_in = f_in;
|
||||
}
|
||||
|
||||
@@ -80,45 +66,77 @@ static char *read_buffer;
|
||||
static char *read_buffer_p;
|
||||
static int read_buffer_len;
|
||||
static int read_buffer_size;
|
||||
static int no_flush;
|
||||
|
||||
/* read from a socket with IO timeout. return the number of
|
||||
bytes read. If no bytes can be read then exit, never return
|
||||
a number <= 0 */
|
||||
static int read_timeout(int fd, char *buf, int len)
|
||||
{
|
||||
int n, ret=0;
|
||||
|
||||
io_flush();
|
||||
|
||||
while (ret == 0) {
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
tv.tv_sec = io_timeout;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (select(fd+1, &fds, NULL, NULL,
|
||||
io_timeout?&tv:NULL) != 1) {
|
||||
check_timeout();
|
||||
continue;
|
||||
}
|
||||
|
||||
n = read(fd, buf, len);
|
||||
|
||||
if (n > 0) {
|
||||
stats.total_read += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
ret += n;
|
||||
if (io_timeout)
|
||||
last_io = time(NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n == -1 && errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
if (eof_error) {
|
||||
rprintf(FERROR,"EOF in read_timeout\n");
|
||||
}
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
rprintf(FERROR,"read error: %s\n", strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* continue trying to read len bytes - don't return until len
|
||||
has been read */
|
||||
static void read_loop(int fd, char *buf, int len)
|
||||
{
|
||||
while (len) {
|
||||
int n = read(fd, buf, len);
|
||||
if (n > 0) {
|
||||
buf += n;
|
||||
len -= n;
|
||||
}
|
||||
if (n == 0) {
|
||||
rprintf(FERROR,"EOF in read_loop\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
if (n == -1) {
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
int n = read_timeout(fd, buf, len);
|
||||
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK) {
|
||||
rprintf(FERROR,"io error: %s\n",
|
||||
strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
tv.tv_sec = io_timeout;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (select(fd+1, &fds, NULL, NULL,
|
||||
io_timeout?&tv:NULL) != 1) {
|
||||
check_timeout();
|
||||
}
|
||||
}
|
||||
buf += n;
|
||||
len -= n;
|
||||
}
|
||||
}
|
||||
|
||||
/* read from the file descriptor handling multiplexing -
|
||||
return number of bytes read
|
||||
never return <= 0 */
|
||||
static int read_unbuffered(int fd, char *buf, int len)
|
||||
{
|
||||
static int remaining;
|
||||
@@ -127,7 +145,7 @@ static int read_unbuffered(int fd, char *buf, int len)
|
||||
char line[1024];
|
||||
|
||||
if (!io_multiplexing_in || fd != multiplex_in_fd)
|
||||
return read(fd, buf, len);
|
||||
return read_timeout(fd, buf, len);
|
||||
|
||||
while (ret == 0) {
|
||||
if (remaining) {
|
||||
@@ -170,12 +188,13 @@ static int read_unbuffered(int fd, char *buf, int len)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This function was added to overcome a deadlock problem when using
|
||||
* ssh. It looks like we can't allow our receive queue to get full or
|
||||
* ssh will clag up. Uggh. */
|
||||
static void read_check(int f)
|
||||
{
|
||||
int n;
|
||||
int n = 8192;
|
||||
|
||||
if (f == -1) return;
|
||||
|
||||
@@ -183,12 +202,6 @@ static void read_check(int f)
|
||||
read_buffer_p = read_buffer;
|
||||
}
|
||||
|
||||
if ((n=num_waiting(f)) <= 0)
|
||||
return;
|
||||
|
||||
/* things could deteriorate if we read in really small chunks */
|
||||
if (n < 10) n = 1024;
|
||||
|
||||
if (n > MAX_READ_BUFFER/4)
|
||||
n = MAX_READ_BUFFER/4;
|
||||
|
||||
@@ -199,28 +212,26 @@ static void read_check(int f)
|
||||
|
||||
if (n > (read_buffer_size - read_buffer_len)) {
|
||||
read_buffer_size += n;
|
||||
if (!read_buffer)
|
||||
read_buffer = (char *)malloc(read_buffer_size);
|
||||
else
|
||||
read_buffer = (char *)realloc(read_buffer,read_buffer_size);
|
||||
read_buffer = (char *)Realloc(read_buffer,read_buffer_size);
|
||||
if (!read_buffer) out_of_memory("read check");
|
||||
read_buffer_p = read_buffer;
|
||||
}
|
||||
|
||||
n = read_unbuffered(f,read_buffer+read_buffer_len,n);
|
||||
if (n > 0) {
|
||||
read_buffer_len += n;
|
||||
}
|
||||
read_buffer_len += n;
|
||||
}
|
||||
|
||||
static int readfd(int fd,char *buffer,int N)
|
||||
|
||||
/* do a buffered read from fd. don't return until all N bytes
|
||||
have been read. If all N can't be read then exit with an error */
|
||||
static void readfd(int fd,char *buffer,int N)
|
||||
{
|
||||
int ret;
|
||||
int total=0;
|
||||
struct timeval tv;
|
||||
|
||||
if (read_buffer_len < N)
|
||||
if (read_buffer_len < N && N < 1024) {
|
||||
read_check(buffer_f_in);
|
||||
}
|
||||
|
||||
while (total < N) {
|
||||
if (read_buffer_len > 0 && buffer_f_in == fd) {
|
||||
@@ -234,45 +245,17 @@ static int readfd(int fd,char *buffer,int N)
|
||||
|
||||
io_flush();
|
||||
|
||||
while ((ret = read_unbuffered(fd,buffer + total,N-total)) == -1) {
|
||||
fd_set fds;
|
||||
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
||||
return -1;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
tv.tv_sec = io_timeout;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (select(fd+1, &fds, NULL, NULL,
|
||||
io_timeout?&tv:NULL) != 1) {
|
||||
check_timeout();
|
||||
}
|
||||
}
|
||||
|
||||
if (ret <= 0)
|
||||
return total;
|
||||
ret = read_unbuffered(fd,buffer + total,N-total);
|
||||
total += ret;
|
||||
}
|
||||
|
||||
if (io_timeout)
|
||||
last_io = time(NULL);
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
int32 read_int(int f)
|
||||
{
|
||||
int ret;
|
||||
char b[4];
|
||||
if ((ret=readfd(f,b,4)) != 4) {
|
||||
if (verbose > 1)
|
||||
rprintf(FERROR,"(%d) read_int: Error reading %d bytes : %s\n",
|
||||
getpid(),4,ret==-1?strerror(errno):"EOF");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
total_read += 4;
|
||||
return IVAL(b,0);
|
||||
char b[4];
|
||||
readfd(f,b,4);
|
||||
return IVAL(b,0);
|
||||
}
|
||||
|
||||
int64 read_longint(int f)
|
||||
@@ -289,13 +272,7 @@ int64 read_longint(int f)
|
||||
exit_cleanup(1);
|
||||
#else
|
||||
if (remote_version >= 16) {
|
||||
if ((ret=readfd(f,b,8)) != 8) {
|
||||
if (verbose > 1)
|
||||
rprintf(FERROR,"(%d) read_longint: Error reading %d bytes : %s\n",
|
||||
getpid(),8,ret==-1?strerror(errno):"EOF");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
total_read += 8;
|
||||
readfd(f,b,8);
|
||||
ret = IVAL(b,0) | (((int64)IVAL(b,4))<<32);
|
||||
}
|
||||
#endif
|
||||
@@ -305,14 +282,7 @@ int64 read_longint(int f)
|
||||
|
||||
void read_buf(int f,char *buf,int len)
|
||||
{
|
||||
int ret;
|
||||
if ((ret=readfd(f,buf,len)) != len) {
|
||||
if (verbose > 1)
|
||||
rprintf(FERROR,"(%d) read_buf: Error reading %d bytes : %s\n",
|
||||
getpid(),len,ret==-1?strerror(errno):"EOF");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
total_read += len;
|
||||
readfd(f,buf,len);
|
||||
}
|
||||
|
||||
void read_sbuf(int f,char *buf,int len)
|
||||
@@ -323,149 +293,79 @@ void read_sbuf(int f,char *buf,int len)
|
||||
|
||||
unsigned char read_byte(int f)
|
||||
{
|
||||
unsigned char c;
|
||||
read_buf(f,(char *)&c,1);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
static char last_byte;
|
||||
static int last_sparse;
|
||||
|
||||
int sparse_end(int f)
|
||||
{
|
||||
if (last_sparse) {
|
||||
do_lseek(f,-1,SEEK_CUR);
|
||||
return (write(f,&last_byte,1) == 1 ? 0 : -1);
|
||||
}
|
||||
last_sparse = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int write_sparse(int f,char *buf,int len)
|
||||
{
|
||||
int l1=0,l2=0;
|
||||
int ret;
|
||||
|
||||
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];
|
||||
|
||||
if (l1 == len || l2 > 0)
|
||||
last_sparse=1;
|
||||
|
||||
if (l1 > 0)
|
||||
do_lseek(f,l1,SEEK_CUR);
|
||||
|
||||
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 (l2 > 0)
|
||||
do_lseek(f,l2,SEEK_CUR);
|
||||
|
||||
return len;
|
||||
unsigned char c;
|
||||
read_buf(f,(char *)&c,1);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static int writefd_unbuffered(int fd,char *buf,int len)
|
||||
/* write len bytes to fd, possibly reading from buffer_f_in if set
|
||||
in order to unclog the pipe. don't return until all len
|
||||
bytes have been written */
|
||||
static void writefd_unbuffered(int fd,char *buf,int len)
|
||||
{
|
||||
int total = 0;
|
||||
fd_set w_fds, r_fds;
|
||||
int fd_count, count, got_select=0;
|
||||
int fd_count, count;
|
||||
struct timeval tv;
|
||||
int reading;
|
||||
|
||||
no_flush++;
|
||||
|
||||
reading = (buffer_f_in != -1 && read_buffer_len < MAX_READ_BUFFER);
|
||||
|
||||
while (total < len) {
|
||||
int ret = write(fd,buf+total,len-total);
|
||||
|
||||
if (ret == 0) return total;
|
||||
|
||||
if (ret == -1 && !(errno == EWOULDBLOCK || errno == EAGAIN))
|
||||
return -1;
|
||||
|
||||
if (ret == -1 && got_select) {
|
||||
/* hmmm, we got a write select on the fd and
|
||||
then failed to write. Why doesn't that
|
||||
mean that the fd is dead? It doesn't on
|
||||
some systems it seems (eg. IRIX) */
|
||||
u_sleep(1000);
|
||||
}
|
||||
|
||||
got_select = 0;
|
||||
|
||||
|
||||
if (ret != -1) {
|
||||
total += ret;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (read_buffer_len < MAX_READ_BUFFER && buffer_f_in != -1)
|
||||
read_check(buffer_f_in);
|
||||
|
||||
fd_count = fd+1;
|
||||
FD_ZERO(&w_fds);
|
||||
FD_ZERO(&r_fds);
|
||||
FD_SET(fd,&w_fds);
|
||||
if (buffer_f_in != -1) {
|
||||
fd_count = fd+1;
|
||||
|
||||
if (reading) {
|
||||
FD_SET(buffer_f_in,&r_fds);
|
||||
if (buffer_f_in > fd)
|
||||
fd_count = buffer_f_in+1;
|
||||
}
|
||||
|
||||
tv.tv_sec = BLOCKING_TIMEOUT;
|
||||
tv.tv_sec = io_timeout;
|
||||
tv.tv_usec = 0;
|
||||
count = select(fd_count,buffer_f_in == -1? NULL: &r_fds,
|
||||
&w_fds,NULL,&tv);
|
||||
|
||||
if (count == -1 && errno != EINTR) {
|
||||
if (verbose > 1)
|
||||
rprintf(FERROR,"select error: %s\n", strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
|
||||
count = select(fd_count,
|
||||
reading?&r_fds:NULL,
|
||||
&w_fds,NULL,
|
||||
io_timeout?&tv:NULL);
|
||||
|
||||
if (count <= 0) {
|
||||
check_timeout();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(fd, &w_fds)) {
|
||||
got_select = 1;
|
||||
int ret = write(fd,buf+total,len-total);
|
||||
|
||||
if (ret == -1 && errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret <= 0) {
|
||||
rprintf(FERROR,"erroring writing %d bytes - exiting\n", len);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
total += ret;
|
||||
stats.total_written += ret;
|
||||
|
||||
if (io_timeout)
|
||||
last_io = time(NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reading && FD_ISSET(buffer_f_in, &r_fds)) {
|
||||
read_check(buffer_f_in);
|
||||
}
|
||||
}
|
||||
|
||||
if (io_timeout)
|
||||
last_io = time(NULL);
|
||||
|
||||
return total;
|
||||
no_flush--;
|
||||
}
|
||||
|
||||
|
||||
@@ -487,21 +387,13 @@ void io_start_buffering(int fd)
|
||||
void io_flush(void)
|
||||
{
|
||||
int fd = multiplex_out_fd;
|
||||
if (!io_buffer_count) return;
|
||||
if (!io_buffer_count || no_flush) return;
|
||||
|
||||
if (io_multiplexing_out) {
|
||||
SIVAL(io_buffer-4, 0, (MPLEX_BASE<<24) + io_buffer_count);
|
||||
if (writefd_unbuffered(fd, io_buffer-4, io_buffer_count+4) !=
|
||||
io_buffer_count+4) {
|
||||
rprintf(FERROR,"write failed\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
writefd_unbuffered(fd, io_buffer-4, io_buffer_count+4);
|
||||
} else {
|
||||
if (writefd_unbuffered(fd, io_buffer, io_buffer_count) !=
|
||||
io_buffer_count) {
|
||||
rprintf(FERROR,"write failed\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
writefd_unbuffered(fd, io_buffer, io_buffer_count);
|
||||
}
|
||||
io_buffer_count = 0;
|
||||
}
|
||||
@@ -515,11 +407,12 @@ void io_end_buffering(int fd)
|
||||
}
|
||||
}
|
||||
|
||||
static int writefd(int fd,char *buf,int len1)
|
||||
static void writefd(int fd,char *buf,int len)
|
||||
{
|
||||
int len = len1;
|
||||
|
||||
if (!io_buffer) return writefd_unbuffered(fd, buf, len);
|
||||
if (!io_buffer) {
|
||||
writefd_unbuffered(fd, buf, len);
|
||||
return;
|
||||
}
|
||||
|
||||
while (len) {
|
||||
int n = MIN(len, IO_BUFFER_SIZE-io_buffer_count);
|
||||
@@ -532,29 +425,20 @@ static int writefd(int fd,char *buf,int len1)
|
||||
|
||||
if (io_buffer_count == IO_BUFFER_SIZE) io_flush();
|
||||
}
|
||||
|
||||
return len1;
|
||||
}
|
||||
|
||||
|
||||
void write_int(int f,int32 x)
|
||||
{
|
||||
int ret;
|
||||
char b[4];
|
||||
SIVAL(b,0,x);
|
||||
if ((ret=writefd(f,b,4)) != 4) {
|
||||
rprintf(FERROR,"write_int failed : %s\n",
|
||||
ret==-1?strerror(errno):"EOF");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
total_written += 4;
|
||||
writefd(f,b,4);
|
||||
}
|
||||
|
||||
void write_longint(int f, int64 x)
|
||||
{
|
||||
extern int remote_version;
|
||||
char b[8];
|
||||
int ret;
|
||||
|
||||
if (remote_version < 16 || x <= 0x7FFFFFFF) {
|
||||
write_int(f, (int)x);
|
||||
@@ -565,23 +449,12 @@ void write_longint(int f, int64 x)
|
||||
SIVAL(b,0,(x&0xFFFFFFFF));
|
||||
SIVAL(b,4,((x>>32)&0xFFFFFFFF));
|
||||
|
||||
if ((ret=writefd(f,b,8)) != 8) {
|
||||
rprintf(FERROR,"write_longint failed : %s\n",
|
||||
ret==-1?strerror(errno):"EOF");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
total_written += 8;
|
||||
writefd(f,b,8);
|
||||
}
|
||||
|
||||
void write_buf(int f,char *buf,int len)
|
||||
{
|
||||
int ret;
|
||||
if ((ret=writefd(f,buf,len)) != len) {
|
||||
rprintf(FERROR,"write_buf failed : %s\n",
|
||||
ret==-1?strerror(errno):"EOF");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
total_written += len;
|
||||
writefd(f,buf,len);
|
||||
}
|
||||
|
||||
/* write a string to the connection */
|
||||
@@ -596,15 +469,14 @@ void write_byte(int f,unsigned char c)
|
||||
write_buf(f,(char *)&c,1);
|
||||
}
|
||||
|
||||
void write_flush(int f)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int read_line(int f, char *buf, int maxlen)
|
||||
{
|
||||
eof_error = 0;
|
||||
|
||||
while (maxlen) {
|
||||
buf[0] = 0;
|
||||
read_buf(f, buf, 1);
|
||||
if (buf[0] == 0) return 0;
|
||||
if (buf[0] == '\n') {
|
||||
buf[0] = 0;
|
||||
break;
|
||||
@@ -618,6 +490,9 @@ int read_line(int f, char *buf, int maxlen)
|
||||
*buf = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
eof_error = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
18
lib/compat.c
18
lib/compat.c
@@ -58,3 +58,21 @@ void *memmove(void *dest, const void *src, size_t n)
|
||||
return dest;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRPBRK
|
||||
/* Find the first ocurrence in S of any character in ACCEPT.
|
||||
derived from glibc
|
||||
*/
|
||||
char *strpbrk(const char *s, const char *accept)
|
||||
{
|
||||
while (*s != '\0') {
|
||||
const char *a = accept;
|
||||
while (*a != '\0') {
|
||||
if (*a++ == *s) return (char *)s;
|
||||
}
|
||||
++s;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
#define BOOL int
|
||||
#define False 0
|
||||
#define True 1
|
||||
#define Realloc realloc
|
||||
#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((char *)(p1)) - (char *)(p2)))
|
||||
#define strequal(a,b) (strcasecmp(a,b)==0)
|
||||
#define BOOLSTR(b) ((b) ? "Yes" : "No")
|
||||
@@ -368,6 +367,7 @@ static int add_a_service(service *pservice, char *name)
|
||||
i = iNumServices;
|
||||
|
||||
ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
|
||||
|
||||
if (ServicePtrs)
|
||||
pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
|
||||
|
||||
|
||||
76
main.c
76
main.c
@@ -20,7 +20,8 @@
|
||||
#include "rsync.h"
|
||||
|
||||
time_t starttime = 0;
|
||||
int64 total_size = 0;
|
||||
|
||||
struct stats stats;
|
||||
|
||||
extern int csum_length;
|
||||
|
||||
@@ -28,16 +29,17 @@ extern int verbose;
|
||||
|
||||
static void report(int f)
|
||||
{
|
||||
int64 in,out,tsize;
|
||||
time_t t = time(NULL);
|
||||
extern int am_server;
|
||||
extern int am_sender;
|
||||
extern int am_daemon;
|
||||
extern int do_stats;
|
||||
|
||||
if (am_daemon) {
|
||||
syslog(LOG_INFO,"wrote %.0f bytes read %.0f bytes total size %.0f\n",
|
||||
(double)write_total(),(double)read_total(),
|
||||
(double)total_size);
|
||||
(double)stats.total_written,
|
||||
(double)stats.total_read,
|
||||
(double)stats.total_size);
|
||||
if (f == -1 || !am_sender) return;
|
||||
}
|
||||
|
||||
@@ -46,27 +48,46 @@ static void report(int f)
|
||||
if (am_server && !am_sender) return;
|
||||
|
||||
if (am_server && am_sender) {
|
||||
write_longint(f,read_total());
|
||||
write_longint(f,write_total());
|
||||
write_longint(f,total_size);
|
||||
write_flush(f);
|
||||
write_longint(f,stats.total_read);
|
||||
write_longint(f,stats.total_written);
|
||||
write_longint(f,stats.total_size);
|
||||
return;
|
||||
}
|
||||
|
||||
if (am_sender) {
|
||||
in = read_total();
|
||||
out = write_total();
|
||||
tsize = total_size;
|
||||
} else {
|
||||
out = read_longint(f);
|
||||
in = read_longint(f);
|
||||
tsize = read_longint(f);
|
||||
if (!am_sender) {
|
||||
int64 r;
|
||||
stats.total_written = read_longint(f);
|
||||
r = read_longint(f);
|
||||
stats.total_size = read_longint(f);
|
||||
stats.total_read = r;
|
||||
}
|
||||
|
||||
if (do_stats) {
|
||||
printf("\nNumber of files: %d\n", stats.num_files);
|
||||
printf("Number of files transferred: %d\n",
|
||||
stats.num_transferred_files);
|
||||
printf("Total file size: %.0f bytes\n",
|
||||
(double)stats.total_size);
|
||||
printf("Total transferred file size: %.0f bytes\n",
|
||||
(double)stats.total_transferred_size);
|
||||
printf("Literal data: %.0f bytes\n",
|
||||
(double)stats.literal_data);
|
||||
printf("Matched data: %.0f bytes\n",
|
||||
(double)stats.matched_data);
|
||||
printf("File list size: %d\n", stats.flist_size);
|
||||
printf("Total bytes written: %.0f\n",
|
||||
(double)stats.total_written);
|
||||
printf("Total bytes read: %.0f\n\n",
|
||||
(double)stats.total_read);
|
||||
}
|
||||
|
||||
printf("wrote %.0f bytes read %.0f bytes %.2f bytes/sec\n",
|
||||
(double)out,(double)in,(in+out)/(0.5 + (t-starttime)));
|
||||
(double)stats.total_written,
|
||||
(double)stats.total_read,
|
||||
(stats.total_written+stats.total_read)/(0.5 + (t-starttime)));
|
||||
printf("total size is %.0f speedup is %.2f\n",
|
||||
(double)tsize,(1.0*tsize)/(in+out));
|
||||
(double)stats.total_size,
|
||||
(1.0*stats.total_size)/(stats.total_written+stats.total_read));
|
||||
}
|
||||
|
||||
|
||||
@@ -150,8 +171,8 @@ static char *get_local_name(struct file_list *flist,char *name)
|
||||
|
||||
if (do_stat(name,&st) == 0) {
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
if (chdir(name) != 0) {
|
||||
rprintf(FERROR,"chdir %s : %s (1)\n",
|
||||
if (!push_dir(name, 0)) {
|
||||
rprintf(FERROR,"push_dir %s : %s (1)\n",
|
||||
name,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
@@ -177,8 +198,9 @@ static char *get_local_name(struct file_list *flist,char *name)
|
||||
rprintf(FINFO,"created directory %s\n",name);
|
||||
}
|
||||
|
||||
if (chdir(name) != 0) {
|
||||
rprintf(FERROR,"chdir %s : %s (2)\n",name,strerror(errno));
|
||||
if (!push_dir(name, 0)) {
|
||||
rprintf(FERROR,"push_dir %s : %s (2)\n",
|
||||
name,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
@@ -199,8 +221,8 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
|
||||
|
||||
if (!relative_paths && chdir(dir) != 0) {
|
||||
rprintf(FERROR,"chdir %s: %s (3)\n",dir,strerror(errno));
|
||||
if (!relative_paths && !push_dir(dir, 0)) {
|
||||
rprintf(FERROR,"push_dir %s: %s (3)\n",dir,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
argc--;
|
||||
@@ -290,8 +312,8 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
|
||||
dir = argv[0];
|
||||
argc--;
|
||||
argv++;
|
||||
if (!am_daemon && chdir(dir) != 0) {
|
||||
rprintf(FERROR,"chdir %s : %s (4)\n",
|
||||
if (!am_daemon && !push_dir(dir, 0)) {
|
||||
rprintf(FERROR,"push_dir %s : %s (4)\n",
|
||||
dir,strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
@@ -498,6 +520,8 @@ int main(int argc,char *argv[])
|
||||
starttime = time(NULL);
|
||||
am_root = (getuid() == 0);
|
||||
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
|
||||
if (argc < 2) {
|
||||
usage(FERROR);
|
||||
exit_cleanup(1);
|
||||
|
||||
18
match.c
18
match.c
@@ -34,13 +34,13 @@ typedef unsigned short tag;
|
||||
static int false_alarms;
|
||||
static int tag_hits;
|
||||
static int matches;
|
||||
static int data_transfer;
|
||||
static int64 data_transfer;
|
||||
|
||||
static int total_false_alarms;
|
||||
static int total_tag_hits;
|
||||
static int total_matches;
|
||||
static int64 total_data_transfer;
|
||||
|
||||
extern struct stats stats;
|
||||
|
||||
struct target {
|
||||
tag t;
|
||||
@@ -103,11 +103,10 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
|
||||
send_token(f,i,buf,last_match,n,i<0?0:s->sums[i].len);
|
||||
data_transfer += n;
|
||||
|
||||
if (n > 0)
|
||||
write_flush(f);
|
||||
|
||||
if (i >= 0)
|
||||
if (i >= 0) {
|
||||
stats.matched_data += s->sums[i].len;
|
||||
n += s->sums[i].len;
|
||||
}
|
||||
|
||||
for (j=0;j<n;j+=CHUNK_SIZE) {
|
||||
int n1 = MIN(CHUNK_SIZE,n-j);
|
||||
@@ -276,7 +275,7 @@ void match_sums(int f,struct sum_struct *s,struct map_struct *buf,OFF_T len)
|
||||
total_tag_hits += tag_hits;
|
||||
total_false_alarms += false_alarms;
|
||||
total_matches += matches;
|
||||
total_data_transfer += data_transfer;
|
||||
stats.literal_data += data_transfer;
|
||||
}
|
||||
|
||||
void match_report(void)
|
||||
@@ -285,7 +284,8 @@ void match_report(void)
|
||||
return;
|
||||
|
||||
rprintf(FINFO,
|
||||
"total: matches=%d tag_hits=%d false_alarms=%d data=%ld\n",
|
||||
"total: matches=%d tag_hits=%d false_alarms=%d data=%.0f\n",
|
||||
total_matches,total_tag_hits,
|
||||
total_false_alarms,(long)total_data_transfer);
|
||||
total_false_alarms,
|
||||
(double)stats.literal_data);
|
||||
}
|
||||
|
||||
42
options.c
42
options.c
@@ -55,6 +55,7 @@ int am_sender=0;
|
||||
int recurse = 0;
|
||||
int am_daemon=0;
|
||||
int am_client=0;
|
||||
int do_stats=0;
|
||||
|
||||
int block_size=BLOCK_SIZE;
|
||||
|
||||
@@ -74,12 +75,15 @@ void usage(int F)
|
||||
{
|
||||
rprintf(F,"rsync version %s Copyright Andrew Tridgell and Paul Mackerras\n\n",
|
||||
VERSION);
|
||||
rprintf(F,"Usage:\t%s [options] src user@host:dest\nOR",RSYNC_NAME);
|
||||
rprintf(F,"\t%s [options] user@host:src dest\n\n",RSYNC_NAME);
|
||||
rprintf(F,"Options:\n");
|
||||
rprintf(F,"Usage:\t%s [options] src user@host:dest\n",RSYNC_NAME);
|
||||
rprintf(F,"OR\t%s [options] user@host:src dest\n",RSYNC_NAME);
|
||||
rprintf(F,"OR\t%s [options] src dest\n",RSYNC_NAME);
|
||||
rprintf(F,"OR\t%s [options] user@host::src dest\n",RSYNC_NAME);
|
||||
rprintf(F,"OR\t%s [options] src user@host::dest\n",RSYNC_NAME);
|
||||
rprintf(F,"\nOptions:\n");
|
||||
rprintf(F,"-v, --verbose increase verbosity\n");
|
||||
rprintf(F,"-c, --checksum always checksum\n");
|
||||
rprintf(F,"-a, --archive archive mode (same as -rlptDog)\n");
|
||||
rprintf(F,"-a, --archive archive mode\n");
|
||||
rprintf(F,"-r, --recursive recurse into directories\n");
|
||||
rprintf(F,"-R, --relative use relative path names\n");
|
||||
rprintf(F,"-b, --backup make backups (default ~ extension)\n");
|
||||
@@ -109,20 +113,27 @@ void usage(int F)
|
||||
rprintf(F,"-z, --compress compress file data\n");
|
||||
rprintf(F," --exclude FILE exclude file FILE\n");
|
||||
rprintf(F," --exclude-from FILE exclude files listed in FILE\n");
|
||||
rprintf(F," --include FILE don't exclude file FILE\n");
|
||||
rprintf(F," --include-from FILE don't exclude files listed in FILE\n");
|
||||
rprintf(F," --suffix SUFFIX override backup suffix\n");
|
||||
rprintf(F," --version print version number\n");
|
||||
rprintf(F," --daemon run as a rsync daemon\n");
|
||||
rprintf(F," --config FILE specify alternate rsyncd.conf file\n");
|
||||
rprintf(F," --port PORT specify alternate rsyncd port number\n");
|
||||
rprintf(F," --port PORT specify alternate rsyncd port number\n");
|
||||
rprintf(F," --stats give some file transfer stats\n");
|
||||
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"the backup suffix defaults to %s\n",BACKUP_SUFFIX);
|
||||
rprintf(F,"the block size defaults to %d\n",BLOCK_SIZE);
|
||||
|
||||
rprintf(F,"\nPlease see the rsync(1) and rsyncd.conf(5) man pages for full documentation\n");
|
||||
rprintf(F,"See http://samba.anu.edu.au/rsync/ for updates and bug reports\n");
|
||||
}
|
||||
|
||||
enum {OPT_VERSION,OPT_SUFFIX,OPT_SENDER,OPT_SERVER,OPT_EXCLUDE,
|
||||
OPT_EXCLUDE_FROM,OPT_DELETE,OPT_NUMERIC_IDS,OPT_RSYNC_PATH,
|
||||
OPT_FORCE,OPT_TIMEOUT,OPT_DAEMON,OPT_CONFIG,OPT_PORT};
|
||||
OPT_FORCE,OPT_TIMEOUT,OPT_DAEMON,OPT_CONFIG,OPT_PORT,
|
||||
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS};
|
||||
|
||||
static char *short_options = "oblLWHpguDCtcahvrRIxnSe:B:T:z";
|
||||
|
||||
@@ -135,6 +146,8 @@ static struct option long_options[] = {
|
||||
{"numeric-ids", 0, 0, OPT_NUMERIC_IDS},
|
||||
{"exclude", 1, 0, OPT_EXCLUDE},
|
||||
{"exclude-from",1, 0, OPT_EXCLUDE_FROM},
|
||||
{"include", 1, 0, OPT_INCLUDE},
|
||||
{"include-from",1, 0, OPT_INCLUDE_FROM},
|
||||
{"rsync-path", 1, 0, OPT_RSYNC_PATH},
|
||||
{"one-file-system",0, 0, 'x'},
|
||||
{"ignore-times",0, 0, 'I'},
|
||||
@@ -165,6 +178,7 @@ static struct option long_options[] = {
|
||||
{"temp-dir", 1, 0, 'T'},
|
||||
{"compress", 0, 0, 'z'},
|
||||
{"daemon", 0, 0, OPT_DAEMON},
|
||||
{"stats", 0, 0, OPT_STATS},
|
||||
{"config", 1, 0, OPT_CONFIG},
|
||||
{"port", 1, 0, OPT_PORT},
|
||||
{0,0,0,0}};
|
||||
@@ -213,11 +227,19 @@ void parse_arguments(int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case OPT_EXCLUDE:
|
||||
add_exclude(optarg);
|
||||
add_exclude(optarg, 0);
|
||||
break;
|
||||
|
||||
case OPT_INCLUDE:
|
||||
add_exclude(optarg, 1);
|
||||
break;
|
||||
|
||||
case OPT_EXCLUDE_FROM:
|
||||
add_exclude_file(optarg,1);
|
||||
add_exclude_file(optarg,1, 0);
|
||||
break;
|
||||
|
||||
case OPT_INCLUDE_FROM:
|
||||
add_exclude_file(optarg,1, 1);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
@@ -351,6 +373,10 @@ void parse_arguments(int argc, char *argv[])
|
||||
am_daemon = 1;
|
||||
break;
|
||||
|
||||
case OPT_STATS:
|
||||
do_stats = 1;
|
||||
break;
|
||||
|
||||
case OPT_CONFIG:
|
||||
config_file = optarg;
|
||||
break;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.0.12
|
||||
Version: 2.0.16
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.0.12.tar.gz
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.0.16.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
1
params.c
1
params.c
@@ -77,7 +77,6 @@
|
||||
#define BOOL int
|
||||
#define False 0
|
||||
#define True 1
|
||||
#define Realloc realloc
|
||||
|
||||
/* -------------------------------------------------------------------------- **
|
||||
* Constants...
|
||||
|
||||
442
rsync.c
442
rsync.c
@@ -51,6 +51,7 @@ extern int am_root;
|
||||
extern int relative_paths;
|
||||
extern int io_timeout;
|
||||
extern int io_error;
|
||||
extern struct stats stats;
|
||||
|
||||
/*
|
||||
free a sums struct
|
||||
@@ -74,6 +75,7 @@ static int delete_file(char *fname)
|
||||
extern int force_delete;
|
||||
STRUCT_STAT st;
|
||||
int ret;
|
||||
extern int recurse;
|
||||
|
||||
if (do_unlink(fname) == 0 || errno == ENOENT) return 0;
|
||||
|
||||
@@ -93,7 +95,8 @@ static int delete_file(char *fname)
|
||||
}
|
||||
|
||||
if (do_rmdir(fname) == 0 || errno == ENOENT) return 0;
|
||||
if (!force_delete || (errno != ENOTEMPTY && errno != EEXIST)) {
|
||||
if (!force_delete || !recurse ||
|
||||
(errno != ENOTEMPTY && errno != EEXIST)) {
|
||||
rprintf(FERROR,"rmdir(%s) : %s\n", fname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
@@ -147,7 +150,6 @@ static void send_sums(struct sum_struct *s,int f_out)
|
||||
write_int(f_out,s->sums[i].sum1);
|
||||
write_buf(f_out,s->sums[i].sum2,csum_length);
|
||||
}
|
||||
write_flush(f_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -528,7 +530,6 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
|
||||
write_int(f_out,i);
|
||||
send_sums(s,f_out);
|
||||
write_flush(f_out);
|
||||
|
||||
close(fd);
|
||||
if (buf) unmap_file(buf);
|
||||
@@ -559,6 +560,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname)
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"data recv %d at %d\n",i,(int)offset);
|
||||
|
||||
stats.literal_data += i;
|
||||
sum_update(data,i);
|
||||
|
||||
if (fd != -1 && write_file(fd,data,i) != i) {
|
||||
@@ -573,6 +575,8 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname)
|
||||
if (i == count-1 && remainder != 0)
|
||||
len = remainder;
|
||||
|
||||
stats.matched_data += len;
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"chunk[%d] of size %d at %d offset=%d\n",
|
||||
i,len,(int)offset2,(int)offset);
|
||||
@@ -638,11 +642,7 @@ static void add_delete_entry(struct file_struct *file)
|
||||
{
|
||||
if (dlist_len == dlist_alloc_len) {
|
||||
dlist_alloc_len += 1024;
|
||||
if (!delete_list) {
|
||||
delete_list = (struct delete_list *)malloc(sizeof(delete_list[0])*dlist_alloc_len);
|
||||
} else {
|
||||
delete_list = (struct delete_list *)realloc(delete_list, sizeof(delete_list[0])*dlist_alloc_len);
|
||||
}
|
||||
delete_list = (struct delete_list *)Realloc(delete_list, sizeof(delete_list[0])*dlist_alloc_len);
|
||||
if (!delete_list) out_of_memory("add_delete_entry");
|
||||
}
|
||||
|
||||
@@ -696,7 +696,8 @@ static void delete_files(struct file_list *flist)
|
||||
if (!S_ISDIR(flist->files[j]->mode) ||
|
||||
!(flist->files[j]->flags & FLAG_DELETE)) continue;
|
||||
|
||||
if (delete_already_done(flist, j)) continue;
|
||||
if (remote_version < 19 &&
|
||||
delete_already_done(flist, j)) continue;
|
||||
|
||||
name = strdup(f_name(flist->files[j]));
|
||||
|
||||
@@ -710,7 +711,8 @@ static void delete_files(struct file_list *flist)
|
||||
|
||||
for (i=local_file_list->count-1;i>=0;i--) {
|
||||
if (!local_file_list->files[i]->basename) continue;
|
||||
if (S_ISDIR(local_file_list->files[i]->mode))
|
||||
if (remote_version < 19 &&
|
||||
S_ISDIR(local_file_list->files[i]->mode))
|
||||
add_delete_entry(local_file_list->files[i]);
|
||||
if (-1 == flist_find(flist,local_file_list->files[i])) {
|
||||
delete_one(local_file_list->files[i]);
|
||||
@@ -741,216 +743,237 @@ void sig_int(void)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int get_tmpname(char *fnametmp, char *fname)
|
||||
{
|
||||
char *f;
|
||||
|
||||
/* open tmp file */
|
||||
if (tmpdir) {
|
||||
f = strrchr(fname,'/');
|
||||
if (f == NULL)
|
||||
f = fname;
|
||||
else
|
||||
f++;
|
||||
if (strlen(tmpdir)+strlen(f)+10 > MAXPATHLEN) {
|
||||
rprintf(FERROR,"filename too long\n");
|
||||
return 0;
|
||||
}
|
||||
slprintf(fnametmp,MAXPATHLEN-1, "%s/.%s.XXXXXX",tmpdir,f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
f = strrchr(fname,'/');
|
||||
|
||||
if (strlen(fname)+9 > MAXPATHLEN) {
|
||||
rprintf(FERROR,"filename too long\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (f) {
|
||||
*f = 0;
|
||||
slprintf(fnametmp,MAXPATHLEN-1,"%s/.%s.XXXXXX",
|
||||
fname,f+1);
|
||||
*f = '/';
|
||||
} else {
|
||||
slprintf(fnametmp,MAXPATHLEN-1,".%s.XXXXXX",fname);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
{
|
||||
int fd1,fd2;
|
||||
STRUCT_STAT st;
|
||||
char *fname;
|
||||
char fnametmp[MAXPATHLEN];
|
||||
struct map_struct *buf;
|
||||
int i;
|
||||
struct file_struct *file;
|
||||
int phase=0;
|
||||
int recv_ok;
|
||||
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO,"recv_files(%d) starting\n",flist->count);
|
||||
}
|
||||
|
||||
if (recurse && delete_mode && !local_name && flist->count>0) {
|
||||
delete_files(flist);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
i = read_int(f_in);
|
||||
if (i == -1) {
|
||||
if (phase==0 && remote_version >= 13) {
|
||||
phase++;
|
||||
csum_length = SUM_LENGTH;
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"recv_files phase=%d\n",phase);
|
||||
write_int(f_gen,-1);
|
||||
write_flush(f_gen);
|
||||
continue;
|
||||
int fd1,fd2;
|
||||
STRUCT_STAT st;
|
||||
char *fname;
|
||||
char fnametmp[MAXPATHLEN];
|
||||
struct map_struct *buf;
|
||||
int i;
|
||||
struct file_struct *file;
|
||||
int phase=0;
|
||||
int recv_ok;
|
||||
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO,"recv_files(%d) starting\n",flist->count);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
file = flist->files[i];
|
||||
fname = f_name(file);
|
||||
if (recurse && delete_mode && !local_name && flist->count>0) {
|
||||
delete_files(flist);
|
||||
}
|
||||
|
||||
if (local_name)
|
||||
fname = local_name;
|
||||
while (1) {
|
||||
i = read_int(f_in);
|
||||
if (i == -1) {
|
||||
if (phase==0 && remote_version >= 13) {
|
||||
phase++;
|
||||
csum_length = SUM_LENGTH;
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"recv_files phase=%d\n",phase);
|
||||
write_int(f_gen,-1);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (dry_run) {
|
||||
if (!am_server && verbose)
|
||||
printf("%s\n",fname);
|
||||
continue;
|
||||
}
|
||||
if (i < 0 || i >= flist->count) {
|
||||
rprintf(FERROR,"Invalid file index %d in recv_files (count=%d)\n",
|
||||
i, flist->count);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"recv_files(%s)\n",fname);
|
||||
file = flist->files[i];
|
||||
fname = f_name(file);
|
||||
|
||||
/* open the file */
|
||||
fd1 = open(fname,O_RDONLY);
|
||||
stats.num_transferred_files++;
|
||||
stats.total_transferred_size += file->length;
|
||||
|
||||
if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
|
||||
rprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno));
|
||||
receive_data(f_in,NULL,-1,NULL);
|
||||
close(fd1);
|
||||
continue;
|
||||
}
|
||||
if (local_name)
|
||||
fname = local_name;
|
||||
|
||||
if (fd1 != -1 && !S_ISREG(st.st_mode)) {
|
||||
rprintf(FERROR,"%s : not a regular file (recv_files)\n",fname);
|
||||
receive_data(f_in,NULL,-1,NULL);
|
||||
close(fd1);
|
||||
continue;
|
||||
}
|
||||
if (dry_run) {
|
||||
if (!am_server && verbose)
|
||||
printf("%s\n",fname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fd1 != -1 && st.st_size > 0) {
|
||||
buf = map_file(fd1,st.st_size);
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"recv mapped %s of size %d\n",fname,(int)st.st_size);
|
||||
} else {
|
||||
buf = NULL;
|
||||
}
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"recv_files(%s)\n",fname);
|
||||
|
||||
/* open tmp file */
|
||||
if (tmpdir) {
|
||||
char *f;
|
||||
f = strrchr(fname,'/');
|
||||
if (f == NULL)
|
||||
f = fname;
|
||||
else
|
||||
f++;
|
||||
if (strlen(tmpdir)+strlen(f)+10 > MAXPATHLEN) {
|
||||
rprintf(FERROR,"filename too long\n");
|
||||
if (buf) unmap_file(buf);
|
||||
close(fd1);
|
||||
continue;
|
||||
}
|
||||
slprintf(fnametmp,sizeof(fnametmp)-1, "%s/.%s.XXXXXX",tmpdir,f);
|
||||
} else {
|
||||
char *f = strrchr(fname,'/');
|
||||
/* open the file */
|
||||
fd1 = open(fname,O_RDONLY);
|
||||
|
||||
if (strlen(fname)+9 > MAXPATHLEN) {
|
||||
rprintf(FERROR,"filename too long\n");
|
||||
if (buf) unmap_file(buf);
|
||||
close(fd1);
|
||||
continue;
|
||||
}
|
||||
if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
|
||||
rprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno));
|
||||
receive_data(f_in,NULL,-1,NULL);
|
||||
close(fd1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (f) {
|
||||
*f = 0;
|
||||
slprintf(fnametmp,sizeof(fnametmp)-1,"%s/.%s.XXXXXX",fname,f+1);
|
||||
*f = '/';
|
||||
} else {
|
||||
slprintf(fnametmp,sizeof(fnametmp)-1,".%s.XXXXXX",fname);
|
||||
}
|
||||
}
|
||||
if (NULL == do_mktemp(fnametmp)) {
|
||||
rprintf(FERROR,"mktemp %s failed\n",fnametmp);
|
||||
receive_data(f_in,buf,-1,NULL);
|
||||
if (buf) unmap_file(buf);
|
||||
close(fd1);
|
||||
continue;
|
||||
}
|
||||
fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,file->mode);
|
||||
if (fd2 == -1 && relative_paths && errno == ENOENT &&
|
||||
create_directory_path(fnametmp) == 0) {
|
||||
fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,file->mode);
|
||||
}
|
||||
if (fd2 == -1) {
|
||||
rprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
|
||||
receive_data(f_in,buf,-1,NULL);
|
||||
if (buf) unmap_file(buf);
|
||||
close(fd1);
|
||||
continue;
|
||||
}
|
||||
if (fd1 != -1 && !S_ISREG(st.st_mode)) {
|
||||
rprintf(FERROR,"%s : not a regular file (recv_files)\n",fname);
|
||||
receive_data(f_in,NULL,-1,NULL);
|
||||
close(fd1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fd1 != -1 && st.st_size > 0) {
|
||||
buf = map_file(fd1,st.st_size);
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"recv mapped %s of size %d\n",fname,(int)st.st_size);
|
||||
} else {
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
if (!get_tmpname(fnametmp,fname)) {
|
||||
if (buf) unmap_file(buf);
|
||||
close(fd1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (NULL == do_mktemp(fnametmp)) {
|
||||
rprintf(FERROR,"mktemp %s failed\n",fnametmp);
|
||||
receive_data(f_in,buf,-1,NULL);
|
||||
if (buf) unmap_file(buf);
|
||||
close(fd1);
|
||||
continue;
|
||||
}
|
||||
|
||||
fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,file->mode);
|
||||
if (fd2 == -1 && relative_paths && errno == ENOENT &&
|
||||
create_directory_path(fnametmp) == 0) {
|
||||
fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,file->mode);
|
||||
}
|
||||
if (fd2 == -1) {
|
||||
rprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
|
||||
receive_data(f_in,buf,-1,NULL);
|
||||
if (buf) unmap_file(buf);
|
||||
close(fd1);
|
||||
continue;
|
||||
}
|
||||
|
||||
cleanup_fname = fnametmp;
|
||||
cleanup_fname = fnametmp;
|
||||
|
||||
if (!am_server && verbose)
|
||||
printf("%s\n",fname);
|
||||
if (!am_server && verbose)
|
||||
printf("%s\n",fname);
|
||||
|
||||
/* recv file data */
|
||||
recv_ok = receive_data(f_in,buf,fd2,fname);
|
||||
|
||||
if (buf) unmap_file(buf);
|
||||
if (fd1 != -1) {
|
||||
close(fd1);
|
||||
}
|
||||
close(fd2);
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"renaming %s to %s\n",fnametmp,fname);
|
||||
|
||||
if (make_backups) {
|
||||
char fnamebak[MAXPATHLEN];
|
||||
if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
|
||||
rprintf(FERROR,"backup filename too long\n");
|
||||
continue;
|
||||
}
|
||||
slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix);
|
||||
if (do_rename(fname,fnamebak) != 0 && errno != ENOENT) {
|
||||
rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* recv file data */
|
||||
recv_ok = receive_data(f_in,buf,fd2,fname);
|
||||
/* move tmp file over real file */
|
||||
if (do_rename(fnametmp,fname) != 0) {
|
||||
if (errno == EXDEV) {
|
||||
/* rename failed on cross-filesystem link.
|
||||
Copy the file instead. */
|
||||
if (copy_file(fnametmp,fname, file->mode)) {
|
||||
rprintf(FERROR,"copy %s -> %s : %s\n",
|
||||
fnametmp,fname,strerror(errno));
|
||||
} else {
|
||||
set_perms(fname,file,NULL,0);
|
||||
}
|
||||
do_unlink(fnametmp);
|
||||
} else {
|
||||
rprintf(FERROR,"rename %s -> %s : %s\n",
|
||||
fnametmp,fname,strerror(errno));
|
||||
do_unlink(fnametmp);
|
||||
}
|
||||
} else {
|
||||
set_perms(fname,file,NULL,0);
|
||||
}
|
||||
|
||||
if (buf) unmap_file(buf);
|
||||
if (fd1 != -1) {
|
||||
close(fd1);
|
||||
}
|
||||
close(fd2);
|
||||
cleanup_fname = NULL;
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"renaming %s to %s\n",fnametmp,fname);
|
||||
|
||||
if (make_backups) {
|
||||
char fnamebak[MAXPATHLEN];
|
||||
if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
|
||||
rprintf(FERROR,"backup filename too long\n");
|
||||
continue;
|
||||
|
||||
if (!recv_ok) {
|
||||
if (csum_length == SUM_LENGTH) {
|
||||
rprintf(FERROR,"ERROR: file corruption in %s. File changed during transfer?\n",
|
||||
fname);
|
||||
} else {
|
||||
if (verbose > 1)
|
||||
rprintf(FINFO,"redoing %s(%d)\n",fname,i);
|
||||
write_int(f_gen,i);
|
||||
}
|
||||
}
|
||||
}
|
||||
slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix);
|
||||
if (do_rename(fname,fnamebak) != 0 && errno != ENOENT) {
|
||||
rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
|
||||
continue;
|
||||
|
||||
if (preserve_hard_links)
|
||||
do_hard_links(flist);
|
||||
|
||||
/* now we need to fix any directory permissions that were
|
||||
modified during the transfer */
|
||||
for (i = 0; i < flist->count; i++) {
|
||||
file = flist->files[i];
|
||||
if (!file->basename || !S_ISDIR(file->mode)) continue;
|
||||
recv_generator(f_name(file),flist,i,-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* move tmp file over real file */
|
||||
if (do_rename(fnametmp,fname) != 0) {
|
||||
if (errno == EXDEV) {
|
||||
/* rename failed on cross-filesystem link.
|
||||
Copy the file instead. */
|
||||
if (copy_file(fnametmp,fname, file->mode)) {
|
||||
rprintf(FERROR,"copy %s -> %s : %s\n",
|
||||
fnametmp,fname,strerror(errno));
|
||||
} else {
|
||||
set_perms(fname,file,NULL,0);
|
||||
}
|
||||
do_unlink(fnametmp);
|
||||
} else {
|
||||
rprintf(FERROR,"rename %s -> %s : %s\n",
|
||||
fnametmp,fname,strerror(errno));
|
||||
do_unlink(fnametmp);
|
||||
}
|
||||
} else {
|
||||
set_perms(fname,file,NULL,0);
|
||||
}
|
||||
|
||||
cleanup_fname = NULL;
|
||||
|
||||
|
||||
if (!recv_ok) {
|
||||
if (csum_length == SUM_LENGTH) {
|
||||
rprintf(FERROR,"ERROR: file corruption in %s. File changed during transfer?\n",
|
||||
fname);
|
||||
} else {
|
||||
if (verbose > 1)
|
||||
rprintf(FINFO,"redoing %s(%d)\n",fname,i);
|
||||
write_int(f_gen,i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (preserve_hard_links)
|
||||
do_hard_links(flist);
|
||||
|
||||
/* now we need to fix any directory permissions that were
|
||||
modified during the transfer */
|
||||
for (i = 0; i < flist->count; i++) {
|
||||
file = flist->files[i];
|
||||
if (!file->basename || !S_ISDIR(file->mode)) continue;
|
||||
recv_generator(f_name(file),flist,i,-1);
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"recv_files finished\n");
|
||||
|
||||
return 0;
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"recv_files finished\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -965,21 +988,21 @@ void send_files(struct file_list *flist,int f_out,int f_in)
|
||||
int i;
|
||||
struct file_struct *file;
|
||||
int phase = 0;
|
||||
int offset=0;
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"send_files starting\n");
|
||||
|
||||
setup_nonblocking(f_in,f_out);
|
||||
setup_readbuffer(f_in);
|
||||
|
||||
while (1) {
|
||||
int offset=0;
|
||||
|
||||
i = read_int(f_in);
|
||||
if (i == -1) {
|
||||
if (phase==0 && remote_version >= 13) {
|
||||
phase++;
|
||||
csum_length = SUM_LENGTH;
|
||||
write_int(f_out,-1);
|
||||
write_flush(f_out);
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"send_files phase=%d\n",phase);
|
||||
continue;
|
||||
@@ -987,8 +1010,17 @@ void send_files(struct file_list *flist,int f_out,int f_in)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < 0 || i >= flist->count) {
|
||||
rprintf(FERROR,"Invalid file index %d (count=%d)\n",
|
||||
i, flist->count);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
file = flist->files[i];
|
||||
|
||||
stats.num_transferred_files++;
|
||||
stats.total_transferred_size += file->length;
|
||||
|
||||
fname[0] = 0;
|
||||
if (file->basedir) {
|
||||
strlcpy(fname,file->basedir,MAXPATHLEN-1);
|
||||
@@ -1061,7 +1093,6 @@ void send_files(struct file_list *flist,int f_out,int f_in)
|
||||
printf("%s\n",fname+offset);
|
||||
|
||||
match_sums(f_out,s,buf,st.st_size);
|
||||
write_flush(f_out);
|
||||
|
||||
if (buf) unmap_file(buf);
|
||||
close(fd);
|
||||
@@ -1078,7 +1109,6 @@ void send_files(struct file_list *flist,int f_out,int f_in)
|
||||
match_report();
|
||||
|
||||
write_int(f_out,-1);
|
||||
write_flush(f_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -1118,7 +1148,6 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
|
||||
rprintf(FINFO,"generate_files phase=%d\n",phase);
|
||||
|
||||
write_int(f,-1);
|
||||
write_flush(f);
|
||||
|
||||
/* we expect to just sit around now, so don't exit on a timeout. If we
|
||||
really get a timeout then the other process should exit */
|
||||
@@ -1138,12 +1167,7 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
|
||||
rprintf(FINFO,"generate_files phase=%d\n",phase);
|
||||
|
||||
write_int(f,-1);
|
||||
write_flush(f);
|
||||
}
|
||||
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"generator wrote %ld\n",(long)write_total());
|
||||
}
|
||||
|
||||
|
||||
|
||||
34
rsync.h
34
rsync.h
@@ -41,7 +41,7 @@
|
||||
#define SAME_TIME (1<<7)
|
||||
|
||||
/* update this if you make incompatible changes */
|
||||
#define PROTOCOL_VERSION 18
|
||||
#define PROTOCOL_VERSION 19
|
||||
#define MIN_PROTOCOL_VERSION 11
|
||||
#define MAX_PROTOCOL_VERSION 30
|
||||
|
||||
@@ -51,13 +51,11 @@
|
||||
#define WRITE_SIZE (32*1024)
|
||||
#define CHUNK_SIZE (32*1024)
|
||||
#define MAX_MAP_SIZE (1*1024*1024)
|
||||
#define IO_BUFFER_SIZE (4096)
|
||||
#define IO_BUFFER_SIZE (4092)
|
||||
#define MAX_READ_BUFFER (1024*1024)
|
||||
|
||||
#define MAX_ARGS 1000
|
||||
|
||||
#define BLOCKING_TIMEOUT 10
|
||||
|
||||
#define MPLEX_BASE 7
|
||||
#define FERROR 1
|
||||
#define FINFO 2
|
||||
@@ -282,9 +280,9 @@ struct file_struct {
|
||||
};
|
||||
|
||||
struct file_list {
|
||||
int count;
|
||||
int malloced;
|
||||
struct file_struct **files;
|
||||
int count;
|
||||
int malloced;
|
||||
struct file_struct **files;
|
||||
};
|
||||
|
||||
struct sum_buf {
|
||||
@@ -309,6 +307,28 @@ struct map_struct {
|
||||
OFF_T size, p_offset;
|
||||
};
|
||||
|
||||
struct exclude_struct {
|
||||
char *orig;
|
||||
char *pattern;
|
||||
int regular_exp;
|
||||
int include;
|
||||
int directory;
|
||||
int local;
|
||||
};
|
||||
|
||||
struct stats {
|
||||
int64 total_size;
|
||||
int64 total_transferred_size;
|
||||
int64 total_written;
|
||||
int64 total_read;
|
||||
int64 literal_data;
|
||||
int64 matched_data;
|
||||
int flist_size;
|
||||
int num_files;
|
||||
int num_transferred_files;
|
||||
};
|
||||
|
||||
|
||||
/* we need this function because of the silly way in which duplicate
|
||||
entries are handled in the file lists - we can't change this
|
||||
without breaking existing versions */
|
||||
|
||||
85
rsync.yo
85
rsync.yo
@@ -217,9 +217,12 @@ explicitly checked on the receiver and any files of the same name
|
||||
which already exist and have the same checksum and size on the
|
||||
receiver are skipped. This option can be quite slow.
|
||||
|
||||
dit(bf(-a, --archive)) This is equivalent to -rlptDog. It is a quick way
|
||||
dit(bf(-a, --archive)) This is equivalent to -rlptDg. It is a quick way
|
||||
of saying I want recursion and want to preserve everything.
|
||||
|
||||
Note: if the user launching rsync is root then the -o option (preserve
|
||||
uid) is also implied.
|
||||
|
||||
dit(bf(-r, --recursive)) This tells rsync to copy directories recursively
|
||||
|
||||
dit(bf(-R, --relative)) Use relative paths. This means that the full path
|
||||
@@ -337,23 +340,30 @@ environment variable.
|
||||
dit(bf(--rsync-path PATH)) Use this to specify the path to the copy of
|
||||
rsync on the remote machine. Useful when its not in your path.
|
||||
|
||||
dit(bf(--exclude FILE)) This option allows you to selectively exclude
|
||||
dit(bf(--exclude pattern)) This option allows you to selectively exclude
|
||||
certain files from the list of files to be transferred. This is most
|
||||
useful in combination with a recursive transfer.
|
||||
|
||||
The option FILE can either be a file name or a shell wildcard
|
||||
expression. If it is a directory name then rsync will not recurse into
|
||||
directories of that name.
|
||||
|
||||
You may use as many --exclude options on the command line as you like
|
||||
to build up the list of files to exclude.
|
||||
|
||||
If the filename is a single ! then the exclude list is reset.
|
||||
See the section of exclude patterns for information on the syntax of
|
||||
this option.
|
||||
|
||||
dit(bf(--exclude-from FILE)) This option is similar to the --exclude
|
||||
option, but instead it adds all filenames listed in the file FILE to
|
||||
the exclude list.
|
||||
|
||||
dit(bf(--include pattern)) This option tells rsync to not exclude the
|
||||
specified pattern of filenames. This is useful as it allows you to
|
||||
build up quite complex exclude/include rules.
|
||||
|
||||
See the section of exclude patterns for information on the syntax of
|
||||
this option.
|
||||
|
||||
dit(bf(--include-from FILE)) This specifies a list of include patterns
|
||||
from a file.
|
||||
|
||||
dit(bf(-C, --cvs-exclude)) This is a useful shorthand for excluding a
|
||||
broad range of files that you often don't want to transfer between
|
||||
systems. It uses the same algorithm that CVS uses to determine if
|
||||
@@ -434,8 +444,69 @@ specified.
|
||||
dit(bf(--port PORT)) This specifies an alternate TCP port number to use
|
||||
rather than the default port 873.
|
||||
|
||||
dit(bf(--stats)) This tells rsync to print a verbose set of statistics
|
||||
on the file transfer, allowing you to tell how effective the rsync
|
||||
algorithm is for your data.
|
||||
|
||||
enddit()
|
||||
|
||||
manpagesection(EXCLUDE PATTERNS)
|
||||
|
||||
The exclude and include patterns specified to rsync allow for flexible
|
||||
selection of what files to transfer and what files to skip.
|
||||
|
||||
rsync build a ordered list of include/exclude options as specified on
|
||||
the command line. When a filename is encountered rsync then checks the
|
||||
name against each exclude/include pattern in turn. The first matching
|
||||
pattern is acted on. If it is an exclude pattern than that file is
|
||||
skipped. If it is an include pattern then that filename is not
|
||||
skipped. If no matching include/exclude pattern is found then the
|
||||
filename is not skipped.
|
||||
|
||||
The patterns themselves can take several forms. The rules are:
|
||||
|
||||
itemize(
|
||||
it() if the pattern starts with a / then it is matched against the
|
||||
start of the filename, otherwise it is matched against the end of
|
||||
the filename. Thus /foo would match a file called foo
|
||||
at the base of the tree whereas foo would match any file
|
||||
called foo anywhere in the tree.
|
||||
|
||||
it() if the pattern ends with a / then it will only match a
|
||||
directory, not a file, link or device.
|
||||
|
||||
it() if the pattern contains a wildcard character from the set
|
||||
*?[ then regular expression matching is applied using the
|
||||
normal shell filename matching rules. Otherwise a simple string
|
||||
match is used.
|
||||
|
||||
it() if the pattern contains a / (not counting a trailing /) then it
|
||||
is matched against the full filename, including any leading
|
||||
directory. If the pattern doesn't contain a / then it is matched
|
||||
only against the final component of the filename.
|
||||
|
||||
it() if the pattern starts with "+ " (a plus followed by a space)
|
||||
then it is always considered a include pattern, even if specified as
|
||||
part of an exclude option. The "+ " part is discarded before matching.
|
||||
|
||||
it() if the pattern starts with "- " (a minus followed by a space)
|
||||
then it is always considered a exclude pattern, even if specified as
|
||||
part of an include option. The "- " part is discarded before matching.
|
||||
)
|
||||
|
||||
The +/- rules are most useful in exclude lists, allowing you to have a
|
||||
single exclude list that contains both include and exclude options.
|
||||
|
||||
Here are some examples:
|
||||
|
||||
itemize(
|
||||
it() --exclude "*.o" would exclude all filenames matching *.o
|
||||
it() --exclude "/foo" would exclude a file in the base directory called foo
|
||||
it() --exclude "foo/" would exclude any directory called foo
|
||||
it() --include "*/" --include "*.c" --exclude "*" would include all
|
||||
directories and C source files.
|
||||
)
|
||||
|
||||
manpagefiles()
|
||||
|
||||
/etc/rsyncd.conf
|
||||
|
||||
20
test.sh
20
test.sh
@@ -10,6 +10,14 @@
|
||||
#
|
||||
#
|
||||
|
||||
cat <<EOF
|
||||
|
||||
This set of tests is not completely portable. It is intended for developers
|
||||
not for end users. You may experience failures on some platforms that
|
||||
do not indicate a problem with rsync.
|
||||
|
||||
EOF
|
||||
|
||||
export PATH=.:$PATH
|
||||
TMP=/tmp/rsync-test.$$
|
||||
FROM=${TMP}/from
|
||||
@@ -98,14 +106,21 @@ cp ${FROM}/${F1} ${TO}/ThisShouldGo
|
||||
checkit "rsync --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO} \
|
||||
5 " --delete"
|
||||
|
||||
LONGDIR=${FROM}/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job
|
||||
mkdir -p ${LONGDIR}
|
||||
date > ${LONGDIR}/1
|
||||
ls -la / > ${LONGDIR}/2
|
||||
checkit "rsync --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO} \
|
||||
6 "long paths"
|
||||
|
||||
if type ssh >/dev/null ; then
|
||||
rm -rf ${TO}
|
||||
checkit "rsync -avH -e ssh ${FROM}/ localhost:${TO}" ${FROM}/ ${TO} \
|
||||
6 "ssh: basic test"
|
||||
7 "ssh: basic test"
|
||||
|
||||
mv ${TO}/${F1} ${TO}/ThisShouldGo
|
||||
checkit "rsync --delete -avH -e ssh ${FROM}/ localhost:${TO}" ${FROM}/ ${TO}\
|
||||
7 "ssh: renamed file"
|
||||
8 "ssh: renamed file"
|
||||
else
|
||||
echo ""
|
||||
echo "**** Skipping SSH tests because ssh is not in the path ****"
|
||||
@@ -113,4 +128,3 @@ else
|
||||
fi
|
||||
|
||||
checkforlogs ${LOG}.?
|
||||
|
||||
|
||||
269
util.c
269
util.c
@@ -32,131 +32,6 @@ int num_waiting(int fd)
|
||||
}
|
||||
|
||||
|
||||
struct map_struct *map_file(int fd,OFF_T len)
|
||||
{
|
||||
struct map_struct *ret;
|
||||
ret = (struct map_struct *)malloc(sizeof(*ret));
|
||||
if (!ret) out_of_memory("map_file");
|
||||
|
||||
ret->map = NULL;
|
||||
ret->fd = fd;
|
||||
ret->size = len;
|
||||
ret->p = NULL;
|
||||
ret->p_size = 0;
|
||||
ret->p_offset = 0;
|
||||
ret->p_len = 0;
|
||||
|
||||
#ifdef USE_MMAP
|
||||
len = MIN(len, MAX_MAP_SIZE);
|
||||
ret->map = (char *)do_mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
|
||||
if (ret->map == (char *)-1) {
|
||||
ret->map = NULL;
|
||||
} else {
|
||||
ret->p_len = len;
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
char *map_ptr(struct map_struct *map,OFF_T offset,int len)
|
||||
{
|
||||
int nread;
|
||||
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
|
||||
if (len > (map->size-offset))
|
||||
len = map->size-offset;
|
||||
|
||||
#ifdef USE_MMAP
|
||||
if (map->map) {
|
||||
if (offset >= map->p_offset &&
|
||||
offset+len <= map->p_offset+map->p_len) {
|
||||
return (map->map + (offset - map->p_offset));
|
||||
}
|
||||
if (munmap(map->map, map->p_len) != 0) {
|
||||
rprintf(FERROR,"munmap failed : %s\n", strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
/* align the mmap region on a nice boundary back a bit from
|
||||
where it is asked for to allow for some seeking */
|
||||
if (offset > 2*CHUNK_SIZE) {
|
||||
map->p_offset = offset - 2*CHUNK_SIZE;
|
||||
map->p_offset &= ~((OFF_T)(CHUNK_SIZE-1));
|
||||
} else {
|
||||
map->p_offset = 0;
|
||||
}
|
||||
|
||||
/* map up to MAX_MAP_SIZE */
|
||||
map->p_len = MAX(len, MAX_MAP_SIZE);
|
||||
map->p_len = MIN(map->p_len, map->size - map->p_offset);
|
||||
|
||||
map->map = (char *)do_mmap(NULL,map->p_len,PROT_READ,
|
||||
MAP_SHARED,map->fd,map->p_offset);
|
||||
|
||||
if (map->map == (char *)-1) {
|
||||
map->map = NULL;
|
||||
map->p_len = 0;
|
||||
map->p_offset = 0;
|
||||
} else {
|
||||
return (map->map + (offset - map->p_offset));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (offset >= map->p_offset &&
|
||||
offset+len <= map->p_offset+map->p_len) {
|
||||
return (map->p + (offset - map->p_offset));
|
||||
}
|
||||
|
||||
len = MAX(len,CHUNK_SIZE);
|
||||
if (len > (map->size-offset))
|
||||
len = map->size-offset;
|
||||
|
||||
if (len > map->p_size) {
|
||||
if (map->p) free(map->p);
|
||||
map->p = (char *)malloc(len);
|
||||
if (!map->p) out_of_memory("map_ptr");
|
||||
map->p_size = len;
|
||||
}
|
||||
|
||||
map->p_offset = offset;
|
||||
map->p_len = len;
|
||||
|
||||
if (do_lseek(map->fd,offset,SEEK_SET) != offset) {
|
||||
rprintf(FERROR,"lseek failed in map_ptr\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
if ((nread=read(map->fd,map->p,len)) != len) {
|
||||
if (nread < 0) nread = 0;
|
||||
/* the best we can do is zero the buffer - the file
|
||||
has changed mid transfer! */
|
||||
memset(map->p+nread, 0, len - nread);
|
||||
}
|
||||
|
||||
return map->p;
|
||||
}
|
||||
|
||||
|
||||
void unmap_file(struct map_struct *map)
|
||||
{
|
||||
#ifdef USE_MMAP
|
||||
if (map->map) {
|
||||
munmap(map->map,map->p_len);
|
||||
map->map = NULL;
|
||||
}
|
||||
#endif
|
||||
if (map->p) {
|
||||
free(map->p);
|
||||
map->p = NULL;
|
||||
}
|
||||
memset(map, 0, sizeof(*map));
|
||||
free(map);
|
||||
}
|
||||
|
||||
|
||||
/* this is taken from CVS */
|
||||
int piped_child(char **command,int *f_in,int *f_out)
|
||||
@@ -302,36 +177,6 @@ int set_modtime(char *fname,time_t modtime)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
|
||||
else
|
||||
if SYSV use O_NDELAY
|
||||
if BSD use FNDELAY
|
||||
****************************************************************************/
|
||||
int set_blocking(int fd, int set)
|
||||
{
|
||||
int val;
|
||||
#ifdef O_NONBLOCK
|
||||
#define FLAG_TO_SET O_NONBLOCK
|
||||
#else
|
||||
#ifdef SYSV
|
||||
#define FLAG_TO_SET O_NDELAY
|
||||
#else /* BSD */
|
||||
#define FLAG_TO_SET FNDELAY
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if((val = fcntl(fd, F_GETFL, 0)) == -1)
|
||||
return -1;
|
||||
if(set) /* Turn blocking on - ie. clear nonblock flag */
|
||||
val &= ~FLAG_TO_SET;
|
||||
else
|
||||
val |= FLAG_TO_SET;
|
||||
return fcntl( fd, F_SETFL, val);
|
||||
#undef FLAG_TO_SET
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
create any necessary directories in fname. Unfortunately we don't know
|
||||
what perms to give the directory when this is called so we need to rely
|
||||
@@ -708,3 +553,117 @@ int slprintf(char *str, int n, char *format, ...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void *Realloc(void *p, int size)
|
||||
{
|
||||
if (!p) return (void *)malloc(size);
|
||||
return (void *)realloc(p, size);
|
||||
}
|
||||
|
||||
|
||||
void clean_fname(char *name)
|
||||
{
|
||||
char *p;
|
||||
int l;
|
||||
int modified = 1;
|
||||
|
||||
if (!name) return;
|
||||
|
||||
while (modified) {
|
||||
modified = 0;
|
||||
|
||||
if ((p=strstr(name,"/./"))) {
|
||||
modified = 1;
|
||||
while (*p) {
|
||||
p[0] = p[2];
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((p=strstr(name,"//"))) {
|
||||
modified = 1;
|
||||
while (*p) {
|
||||
p[0] = p[1];
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (strncmp(p=name,"./",2) == 0) {
|
||||
modified = 1;
|
||||
do {
|
||||
p[0] = p[2];
|
||||
} while (*p++);
|
||||
}
|
||||
|
||||
l = strlen(p=name);
|
||||
if (l > 1 && p[l-1] == '/') {
|
||||
modified = 1;
|
||||
p[l-1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char curr_dir[MAXPATHLEN];
|
||||
|
||||
/* like chdir() but can be reversed with pop_dir() if save is set. It
|
||||
is also much faster as it remembers where we have been */
|
||||
char *push_dir(char *dir, int save)
|
||||
{
|
||||
char *ret = curr_dir;
|
||||
static int initialised;
|
||||
|
||||
if (!initialised) {
|
||||
initialised = 1;
|
||||
getcwd(curr_dir, sizeof(curr_dir)-1);
|
||||
}
|
||||
|
||||
if (chdir(dir)) return NULL;
|
||||
|
||||
if (save) {
|
||||
ret = strdup(curr_dir);
|
||||
}
|
||||
|
||||
if (*dir == '/') {
|
||||
strlcpy(curr_dir, dir, sizeof(curr_dir)-1);
|
||||
} else {
|
||||
strlcat(curr_dir,"/", sizeof(curr_dir)-1);
|
||||
strlcat(curr_dir,dir, sizeof(curr_dir)-1);
|
||||
}
|
||||
|
||||
clean_fname(curr_dir);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* reverse a push_dir call */
|
||||
int pop_dir(char *dir)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = chdir(dir);
|
||||
if (ret) {
|
||||
free(dir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
strlcpy(curr_dir, dir, sizeof(curr_dir)-1);
|
||||
|
||||
free(dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we need to supply our own strcmp function for file list comparisons
|
||||
to ensure that signed/unsigned usage is consistent between machines. */
|
||||
int u_strcmp(const char *cs1, const char *cs2)
|
||||
{
|
||||
const uchar *s1 = (uchar *)cs1;
|
||||
const uchar *s2 = (uchar *)cs2;
|
||||
|
||||
while (*s1 && *s2 && (*s1 == *s2)) {
|
||||
s1++; s2++;
|
||||
}
|
||||
|
||||
return (int)*s1 - (int)*s2;
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ int r;
|
||||
break;
|
||||
case 3: /* illegal */
|
||||
DUMPBITS(3)
|
||||
s->mode = BAD;
|
||||
s->mode = zBAD;
|
||||
z->msg = (char*)"invalid block type";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
@@ -186,7 +186,7 @@ int r;
|
||||
NEEDBITS(32)
|
||||
if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
|
||||
{
|
||||
s->mode = BAD;
|
||||
s->mode = zBAD;
|
||||
z->msg = (char*)"invalid stored block lengths";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
@@ -219,7 +219,7 @@ int r;
|
||||
#ifndef PKZIP_BUG_WORKAROUND
|
||||
if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
|
||||
{
|
||||
s->mode = BAD;
|
||||
s->mode = zBAD;
|
||||
z->msg = (char*)"too many length or distance symbols";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
@@ -252,7 +252,7 @@ int r;
|
||||
ZFREE(z, s->sub.trees.blens);
|
||||
r = t;
|
||||
if (r == Z_DATA_ERROR)
|
||||
s->mode = BAD;
|
||||
s->mode = zBAD;
|
||||
LEAVE
|
||||
}
|
||||
s->sub.trees.index = 0;
|
||||
@@ -289,7 +289,7 @@ int r;
|
||||
(c == 16 && i < 1))
|
||||
{
|
||||
ZFREE(z, s->sub.trees.blens);
|
||||
s->mode = BAD;
|
||||
s->mode = zBAD;
|
||||
z->msg = (char*)"invalid bit length repeat";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
@@ -317,7 +317,7 @@ int r;
|
||||
if (t != Z_OK)
|
||||
{
|
||||
if (t == (uInt)Z_DATA_ERROR)
|
||||
s->mode = BAD;
|
||||
s->mode = zBAD;
|
||||
r = t;
|
||||
LEAVE
|
||||
}
|
||||
@@ -361,7 +361,7 @@ int r;
|
||||
case DONE:
|
||||
r = Z_STREAM_END;
|
||||
LEAVE
|
||||
case BAD:
|
||||
case zBAD:
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
default:
|
||||
|
||||
@@ -22,7 +22,7 @@ typedef enum {
|
||||
CHECK2, /* two check bytes to go */
|
||||
CHECK1, /* one check byte to go */
|
||||
DONE, /* finished check, done */
|
||||
BAD} /* got an error--stay here */
|
||||
zBAD} /* got an error--stay here */
|
||||
inflate_mode;
|
||||
|
||||
/* inflate private state */
|
||||
@@ -38,7 +38,7 @@ struct internal_state {
|
||||
uLong was; /* computed check value */
|
||||
uLong need; /* stream check value */
|
||||
} check; /* if CHECK, check values to compare */
|
||||
uInt marker; /* if BAD, inflateSync's marker bytes count */
|
||||
uInt marker; /* if zBAD, inflateSync's marker bytes count */
|
||||
} sub; /* submode */
|
||||
|
||||
/* mode independent information */
|
||||
@@ -164,14 +164,14 @@ int f;
|
||||
NEEDBYTE
|
||||
if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
|
||||
{
|
||||
z->state->mode = BAD;
|
||||
z->state->mode = zBAD;
|
||||
z->msg = (char*)"unknown compression method";
|
||||
z->state->sub.marker = 5; /* can't try inflateSync */
|
||||
break;
|
||||
}
|
||||
if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
|
||||
{
|
||||
z->state->mode = BAD;
|
||||
z->state->mode = zBAD;
|
||||
z->msg = (char*)"invalid window size";
|
||||
z->state->sub.marker = 5; /* can't try inflateSync */
|
||||
break;
|
||||
@@ -182,7 +182,7 @@ int f;
|
||||
b = NEXTBYTE;
|
||||
if (((z->state->sub.method << 8) + b) % 31)
|
||||
{
|
||||
z->state->mode = BAD;
|
||||
z->state->mode = zBAD;
|
||||
z->msg = (char*)"incorrect header check";
|
||||
z->state->sub.marker = 5; /* can't try inflateSync */
|
||||
break;
|
||||
@@ -213,7 +213,7 @@ int f;
|
||||
z->state->mode = DICT0;
|
||||
return Z_NEED_DICT;
|
||||
case DICT0:
|
||||
z->state->mode = BAD;
|
||||
z->state->mode = zBAD;
|
||||
z->msg = (char*)"need dictionary";
|
||||
z->state->sub.marker = 0; /* can try inflateSync */
|
||||
return Z_STREAM_ERROR;
|
||||
@@ -221,7 +221,7 @@ int f;
|
||||
r = inflate_blocks(z->state->blocks, z, r);
|
||||
if (r == Z_DATA_ERROR)
|
||||
{
|
||||
z->state->mode = BAD;
|
||||
z->state->mode = zBAD;
|
||||
z->state->sub.marker = 0; /* can try inflateSync */
|
||||
break;
|
||||
}
|
||||
@@ -255,7 +255,7 @@ int f;
|
||||
|
||||
if (z->state->sub.check.was != z->state->sub.check.need)
|
||||
{
|
||||
z->state->mode = BAD;
|
||||
z->state->mode = zBAD;
|
||||
z->msg = (char*)"incorrect data check";
|
||||
z->state->sub.marker = 5; /* can't try inflateSync */
|
||||
break;
|
||||
@@ -264,7 +264,7 @@ int f;
|
||||
z->state->mode = DONE;
|
||||
case DONE:
|
||||
return Z_STREAM_END;
|
||||
case BAD:
|
||||
case zBAD:
|
||||
return Z_DATA_ERROR;
|
||||
default:
|
||||
return Z_STREAM_ERROR;
|
||||
@@ -310,9 +310,9 @@ z_streamp z;
|
||||
/* set up */
|
||||
if (z == Z_NULL || z->state == Z_NULL)
|
||||
return Z_STREAM_ERROR;
|
||||
if (z->state->mode != BAD)
|
||||
if (z->state->mode != zBAD)
|
||||
{
|
||||
z->state->mode = BAD;
|
||||
z->state->mode = zBAD;
|
||||
z->state->sub.marker = 0;
|
||||
}
|
||||
if ((n = z->avail_in) == 0)
|
||||
|
||||
@@ -21,7 +21,7 @@ typedef enum {
|
||||
CODES, /* processing fixed or dynamic block */
|
||||
DRY, /* output remaining window bytes */
|
||||
DONE, /* finished last block, done */
|
||||
BAD} /* got a data error--stuck here */
|
||||
zBAD} /* got a data error--stuck here */
|
||||
inflate_block_mode;
|
||||
|
||||
/* inflate blocks semi-private state */
|
||||
|
||||
@@ -200,11 +200,6 @@ void zcfree (voidpf opaque, voidpf ptr)
|
||||
|
||||
#ifndef MY_ZCALLOC /* Any system without a special alloc function */
|
||||
|
||||
#ifndef STDC
|
||||
extern voidp calloc OF((uInt items, uInt size));
|
||||
extern void free OF((voidpf ptr));
|
||||
#endif
|
||||
|
||||
voidpf zcalloc (opaque, items, size)
|
||||
voidpf opaque;
|
||||
unsigned items;
|
||||
|
||||
Reference in New Issue
Block a user