summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pool <mbp@samba.org>2003-12-04 04:23:29 +0000
committerMartin Pool <mbp@samba.org>2003-12-04 04:23:29 +0000
commit9fb21d28828123e8bab3e32f20a0e794e830f7d5 (patch)
tree62b9a56279a8c728c0fa152c6cbf677a5b1eccb9
parentb11b50bcd026a0a052bdfab7b96c97045b658d86 (diff)
downloadrsync-9fb21d28828123e8bab3e32f20a0e794e830f7d5.tar.gz
Buffer management fix.
Prepare for 2.5.7 release.
-rw-r--r--NEWS120
-rw-r--r--batch.c21
-rw-r--r--checksum.c32
-rw-r--r--configure.in11
-rw-r--r--exclude.c361
-rw-r--r--fileio.c37
-rw-r--r--flist.c311
-rw-r--r--hlink.c4
-rw-r--r--io.c261
-rw-r--r--loadparm.c86
-rw-r--r--log.c28
-rw-r--r--match.c156
-rw-r--r--params.c8
-rw-r--r--receiver.c209
-rw-r--r--rsync.c78
-rw-r--r--rsync.h129
-rw-r--r--sender.c254
-rw-r--r--token.c84
-rw-r--r--uidlist.c6
-rw-r--r--util.c124
20 files changed, 882 insertions, 1438 deletions
diff --git a/NEWS b/NEWS
index 6d78a518..5c5d3d18 100644
--- a/NEWS
+++ b/NEWS
@@ -1,120 +1,12 @@
-NEWS for rsync version 2.5.7
-Protocol: 27 (changed)
-Changes since version 2.5.6:
+NEWS for rsync version 2.5.7:
- ENHANCEMENTS:
-
- * Added --files-from, --no-relative, --no-implied-dirs, and --from0.
- Note that --from0 affects the line-ending character for all the
- --*-from options. (Wayne Davison)
-
- * Length of csum2 is now per-file starting with protocol verison
- 27. (J.W. Schultz)
-
- * Per-file dynamic block size is now sqrt(file length).
- The per-file checksum size is determined according
- to an algorythm provided by Donovan Baarda which
- reduces the probability of rsync algorithm
- corrupting data and falling back using the whole md4
- checksums. (J.W. Schultz, Donovan Baarda)
-
- * The --stats option no longer includes the (debug) malloc summary
- unless the verbose option was specified at least twice.
-
- BUG FIXES:
-
- * Fixed several exclude/include matching bugs when using wild-cards.
- This has a several user-visible effects, all of which make the
- matching more consistent and intuitive. This should hopefully not
- cause anyone problems since it makes the matching work more like
- what people are expecting. (Wayne Davison)
-
- - A pattern with a "**" no longer causes a "*" to match slashes.
- For example, with "/*/foo/**", "foo" must be 2 levels deep.
-
- - "**/foo" now matches at the base of the transfer (i.e. /foo).
-
- - An non-anchored wildcard term floats to match beyond the base of
- the transfer. E.g. "CVS/R*" matches at the end of the path,
- just like the non-wildcard term "CVS/Root" does.
-
- - Including a "**" in the match term causes it to be matched
- against the entire path, not just the name portion, even if
- there aren't any interior slashes in the term. E.g. "foo**bar"
- would exclude "/path/foo-bar" (just like before) as well as
- "/foo-path/baz-bar" (for instance).
-
- * The exclude list specified in the daemon's config file is now
- properly applied to the pulled items no matter how deep the
- user's file args are in the source tree. (Wayne Davison)
-
- * For protocol version >= 27, mdfour_tail() is called when the
- block size (including checksum_seed) is a multiple of 64.
- Previously it was not called, giving the wrong MD4 checksum.
- (Craig Barratt)
-
- * For protocol version >= 27, a 64 bit bit counter is used in
- mdfour.c as required by the RFC. Previously only a 32 bit bit
- counter was used, causing incorrect MD4 file checksums for
- file sizes >= 512MB - 4. (Craig Barratt)
-
- * Fixed a crash bug when interacting with older rsync versions and
- multiple files of the same name are destined for the same dir.
- (Wayne Davison)
-
- * Keep tmp names from overflowing MAXPATHLEN.
+ SECURITY:
- * Make --link-dest honor the absence of -p, -o, and -g.
-
- * Made rsync treat a trailing slash in the destination in a more
- consistent manner.
-
- * Fixed file I/O error detection. (John Van Essen)
-
- * Fixed a compression (-z) bug when syncing a mostly-matching file
- that contains already-compressed data. (Yasuoka Masahiko and
- Wayne Davison)
-
- * Fixed a bug in the --backup code that could cause deleted files
- to not get backed up.
-
- * Call setgroups() in a more portable manner.
-
- * Improved file-related error messages to better indicate exactly
- what pathname failed. (Wayne Davison)
-
- * Fixed some bugs in the handling of --delete and --exclude when
- using the --relative (-R) option. (Wayne Davison)
-
- * Fixed bug that prevented regular files from replacing
- special files and caused a directory in --link-dest or
- --compare-dest to block the creation of a file with the
- same path. A directory still cannot be replaced by a
- regular file unless --delete specified. (J.W. Schultz)
-
- * Detect and report when open or opendir succeed but read and
- readdir fail caused by network filesystems issues and truncated
- files. (David Norwood, Michael Brown, J.W. Schultz)
-
- INTERNAL:
-
- * Eliminated vestigial support for old versions that we stopped
- supporting. (J.W. Schultz)
-
- * Simplified some of the option-parsing code. (Wayne Davison)
-
- * Some cleanup made to the exclude code, as well as some new
- defines added to enhance readability. (Wayne Davison)
-
- * Changed the protocol-version code so that it can interact at a
- lower protocol level than the maximum supported by both sides.
- Added an undocumented option, --protocol=N, to force the value
- we advertise to the other side (primarily for testing purposes).
- (Wayne Davison)
+ * Fix buffer handling bugs. (Andrew Tridgell, Martin Pool, Paul
+ Russell, Andrea Barisani)
NEWS for rsync version 2.5.6, aka the dwd-between-jobs release
-Protocol: 26 (unchanged)
Changes since version 2.5.5:
ENHANCEMENTS:
@@ -155,7 +47,7 @@ Changes since version 2.5.5:
(Dave Dykstra)
BUG FIXES:
-
+
* Fix "forward name lookup failed" errors on AIX 4.3.3. (John
L. Allen, Martin Pool)
@@ -191,7 +83,7 @@ Changes since version 2.5.5:
INTERNAL:
- * Many code cleanups and improved internal documentation. (Martin
+ * Many code cleanups and improved internal documentation. (Martin
Pool, Nelson Beebe)
* Portability fixes. (Dave Dykstra and Wayne Davison)
diff --git a/batch.c b/batch.c
index d3f65233..d503373d 100644
--- a/batch.c
+++ b/batch.c
@@ -185,15 +185,14 @@ struct file_list *create_flist_from_batch(void)
fdb_open = 1;
fdb_close = 0;
- batch_flist = (struct file_list *) malloc(sizeof(batch_flist[0]));
+ batch_flist = new(struct file_list);
if (!batch_flist) {
out_of_memory("create_flist_from_batch");
}
batch_flist->count = 0;
batch_flist->malloced = 1000;
- batch_flist->files =
- (struct file_struct **) malloc(sizeof(batch_flist->files[0]) *
- batch_flist->malloced);
+ batch_flist->files = new_array(struct file_struct *,
+ batch_flist->malloced);
if (!batch_flist->files) {
out_of_memory("create_flist_from_batch");
}
@@ -207,14 +206,10 @@ struct file_list *create_flist_from_batch(void)
batch_flist->malloced += 1000;
else
batch_flist->malloced *= 2;
- batch_flist->files =
- (struct file_struct **) realloc(batch_flist->
- files,
- sizeof
- (batch_flist->
- files[0]) *
- batch_flist->
- malloced);
+ batch_flist->files
+ = realloc_array(batch_flist->files,
+ struct file_struct *,
+ batch_flist->malloced);
if (!batch_flist->files)
out_of_memory("create_flist_from_batch");
}
@@ -282,7 +277,7 @@ void read_batch_flist_info(struct file_struct **fptr)
char buff[256];
struct file_struct *file;
- file = (struct file_struct *) malloc(sizeof(*file));
+ file = new(struct file_struct);
if (!file)
out_of_memory("read_batch_flist_info");
memset((char *) file, 0, sizeof(*file));
diff --git a/checksum.c b/checksum.c
index 57dac48e..1dde0a77 100644
--- a/checksum.c
+++ b/checksum.c
@@ -24,7 +24,7 @@ int csum_length=2; /* initial value */
#define CSUM_CHUNK 64
int checksum_seed = 0;
-extern int protocol_version;
+extern int remote_version;
/*
a simple 32 bit checksum that can be upadted from either end
@@ -58,7 +58,7 @@ void get_checksum2(char *buf,int len,char *sum)
if (len > len1) {
if (buf1) free(buf1);
- buf1 = (char *)malloc(len+4);
+ buf1 = new_array(char, len+4);
len1 = len;
if (!buf1) out_of_memory("get_checksum2");
}
@@ -74,13 +74,7 @@ void get_checksum2(char *buf,int len,char *sum)
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
mdfour_update(&m, (uchar *)(buf1+i), CSUM_CHUNK);
}
- /*
- * Prior to version 27 an incorrect MD4 checksum was computed
- * by failing to call mdfour_tail() for block sizes that
- * are multiples of 64. This is fixed by calling mdfour_update()
- * even when there are no more bytes.
- */
- if (len - i > 0 || protocol_version >= 27) {
+ if (len - i > 0) {
mdfour_update(&m, (uchar *)(buf1+i), (len-i));
}
@@ -111,16 +105,8 @@ void file_checksum(char *fname,char *sum,OFF_T size)
mdfour_update(&m, (uchar *)tmpchunk, CSUM_CHUNK);
}
- /*
- * Prior to version 27 an incorrect MD4 checksum was computed
- * by failing to call mdfour_tail() for block sizes that
- * are multiples of 64. This is fixed by calling mdfour_update()
- * even when there are no more bytes.
- */
if (len - i > 0) {
memcpy(tmpchunk, map_ptr(buf,i,len-i), len-i);
- }
- if (len - i > 0 || protocol_version >= 27) {
mdfour_update(&m, (uchar *)tmpchunk, (len-i));
}
@@ -131,6 +117,16 @@ void file_checksum(char *fname,char *sum,OFF_T size)
}
+void checksum_init(void)
+{
+ if (remote_version >= 14)
+ csum_length = 2; /* adaptive */
+ else
+ csum_length = SUM_LENGTH;
+}
+
+
+
static int sumresidue;
static char sumrbuf[CSUM_CHUNK];
static struct mdfour md;
@@ -184,7 +180,7 @@ void sum_update(char *p, int len)
void sum_end(char *sum)
{
- if (sumresidue || protocol_version >= 27) {
+ if (sumresidue) {
mdfour_update(&md, (uchar *)sumrbuf, sumresidue);
}
diff --git a/configure.in b/configure.in
index 68dac5a0..de1abd34 100644
--- a/configure.in
+++ b/configure.in
@@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR([byteorder.h])
AC_CONFIG_HEADER(config.h)
AC_PREREQ(2.52)
-RSYNC_VERSION=2.5.6
+RSYNC_VERSION=2.5.7
AC_SUBST(RSYNC_VERSION)
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
@@ -429,6 +429,15 @@ if test x"$rsync_cv_HAVE_SOCKETPAIR" = x"yes"; then
AC_DEFINE(HAVE_SOCKETPAIR, 1, [ ])
fi
+AC_CACHE_CHECK([for working fnmatch],rsync_cv_HAVE_FNMATCH,[
+AC_TRY_RUN([#include <fnmatch.h>
+main() { exit((fnmatch("*.o", "x.o", FNM_PATHNAME) == 0 &&
+ fnmatch("a/b/*", "a/b/c/d", FNM_PATHNAME) != 0) ? 0: 1); }],
+rsync_cv_HAVE_FNMATCH=yes,rsync_cv_HAVE_FNMATCH=no,rsync_cv_HAVE_FNMATCH=cross)])
+if test x"$rsync_cv_HAVE_FNMATCH" = x"yes"; then
+ AC_DEFINE(HAVE_FNMATCH, 1, [ ])
+fi
+
if test x"$with_included_popt" != x"yes"
then
AC_CHECK_LIB(popt, poptGetContext, , [with_included_popt=yes])
diff --git a/exclude.c b/exclude.c
index 1bb042b3..4948020d 100644
--- a/exclude.c
+++ b/exclude.c
@@ -1,19 +1,19 @@
/* -*- c-file-style: "linux" -*-
- *
+ *
* Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
* Copyright (C) 1996 by Paul Mackerras
* Copyright (C) 2002 by Martin Pool
- *
+ *
* 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.
@@ -27,20 +27,16 @@
#include "rsync.h"
extern int verbose;
+extern int delete_mode;
-struct exclude_struct **exclude_list;
-struct exclude_struct **local_exclude_list;
-struct exclude_struct **server_exclude_list;
-char *exclude_path_prefix = NULL;
+static struct exclude_struct **exclude_list;
/** Build an exclude structure given a exclude pattern */
static struct exclude_struct *make_exclude(const char *pattern, int include)
{
struct exclude_struct *ret;
- char *cp;
- int pat_len;
- ret = (struct exclude_struct *)malloc(sizeof(*ret));
+ ret = new(struct exclude_struct);
if (!ret) out_of_memory("make_exclude");
memset(ret, 0, sizeof(*ret));
@@ -54,37 +50,33 @@ static struct exclude_struct *make_exclude(const char *pattern, int include)
ret->include = include;
}
- if (exclude_path_prefix)
- ret->match_flags |= MATCHFLG_ABS_PATH;
- if (exclude_path_prefix && *pattern == '/') {
- ret->pattern = malloc(strlen(exclude_path_prefix)
- + strlen(pattern) + 1);
- if (!ret->pattern) out_of_memory("make_exclude");
- sprintf(ret->pattern, "%s%s", exclude_path_prefix, pattern);
- }
- else {
- ret->pattern = strdup(pattern);
- if (!ret->pattern) out_of_memory("make_exclude");
- }
+ ret->pattern = strdup(pattern);
+
+ if (!ret->pattern) out_of_memory("make_exclude");
if (strpbrk(pattern, "*[?")) {
- ret->match_flags |= MATCHFLG_WILD;
- if (strstr(pattern, "**")) {
- ret->match_flags |= MATCHFLG_WILD2;
- /* If the pattern starts with **, note that. */
- if (*pattern == '*' && pattern[1] == '*')
- ret->match_flags |= MATCHFLG_WILD2_PREFIX;
- }
+ ret->regular_exp = 1;
+ ret->fnmatch_flags = FNM_PATHNAME;
+ if (strstr(pattern, "**")) {
+ static int tested;
+ if (!tested) {
+ tested = 1;
+ if (fnmatch("a/b/*", "a/b/c/d", FNM_PATHNAME)==0) {
+ rprintf(FERROR,"WARNING: fnmatch FNM_PATHNAME is broken on your system\n");
+ }
+ }
+ ret->fnmatch_flags = 0;
+ }
}
- pat_len = strlen(ret->pattern);
- if (pat_len > 1 && ret->pattern[pat_len-1] == '/') {
- ret->pattern[pat_len-1] = 0;
+ if (strlen(pattern) > 1 && pattern[strlen(pattern)-1] == '/') {
+ ret->pattern[strlen(pattern)-1] = 0;
ret->directory = 1;
}
- for (cp = ret->pattern; (cp = strchr(cp, '/')) != NULL; cp++)
- ret->slash_cnt++;
+ if (!strchr(ret->pattern,'/')) {
+ ret->local = 1;
+ }
return ret;
}
@@ -96,98 +88,35 @@ static void free_exclude(struct exclude_struct *ex)
free(ex);
}
-
-void free_exclude_list(struct exclude_struct ***listp)
-{
- struct exclude_struct **list = *listp;
-
- if (verbose > 2)
- rprintf(FINFO,"clearing exclude list\n");
-
- if (!list)
- return;
-
- while (*list)
- free_exclude(*list++);
-
- free(*listp);
- *listp = NULL;
-}
-
static int check_one_exclude(char *name, struct exclude_struct *ex,
- int name_is_dir)
+ STRUCT_STAT *st)
{
char *p;
- int match_start = 0;
+ int match_start=0;
char *pattern = ex->pattern;
- /* If the pattern does not have any slashes AND it does not have
- * a "**" (which could match a slash), then we just match the
- * name portion of the path. */
- if (!ex->slash_cnt && !(ex->match_flags & MATCHFLG_WILD2)) {
- if ((p = strrchr(name,'/')) != NULL)
- name = p+1;
- }
- else if ((ex->match_flags & MATCHFLG_ABS_PATH) && *name != '/') {
- static char full_name[MAXPATHLEN];
- extern char curr_dir[];
- int plus = curr_dir[1] == '\0'? 1 : 0;
- snprintf(full_name, sizeof full_name,
- "%s/%s", curr_dir+plus, name);
- name = full_name;
- }
+ if (ex->local && (p=strrchr(name,'/')))
+ name = p+1;
if (!name[0]) return 0;
- if (ex->directory && !name_is_dir) return 0;
+ if (ex->directory && !S_ISDIR(st->st_mode)) return 0;
- if (*pattern == '/') {
+ if (*pattern == '/' && *name != '/') {
match_start = 1;
pattern++;
- if (*name == '/')
- name++;
}
- if (ex->match_flags & MATCHFLG_WILD) {
- /* A non-anchored match with an infix slash and no "**"
- * needs to match the last slash_cnt+1 name elements. */
- if (!match_start && ex->slash_cnt &&
- !(ex->match_flags & MATCHFLG_WILD2)) {
- int cnt = ex->slash_cnt + 1;
- for (p = name + strlen(name) - 1; p >= name; p--) {
- if (*p == '/' && !--cnt)
- break;
- }
- name = p+1;
- }
- if (wildmatch(pattern, name))
+ if (ex->regular_exp) {
+ if (fnmatch(pattern, name, ex->fnmatch_flags) == 0) {
return 1;
- if (ex->match_flags & MATCHFLG_WILD2_PREFIX) {
- /* If the **-prefixed pattern has a '/' as the next
- * character, then try to match the rest of the
- * pattern at the root. */
- if (pattern[2] == '/' && wildmatch(pattern+3, name))
- return 1;
}
- else if (!match_start && ex->match_flags & MATCHFLG_WILD2) {
- /* A non-anchored match with an infix or trailing "**"
- * (but not a prefixed "**") needs to try matching
- * after every slash. */
- while ((name = strchr(name, '/')) != NULL) {
- name++;
- if (wildmatch(pattern, name))
- return 1;
- }
- }
- } else if (match_start) {
- if (strcmp(name,pattern) == 0)
- return 1;
} else {
int l1 = strlen(name);
int l2 = strlen(pattern);
- if (l2 <= l1 &&
+ if (l2 <= l1 &&
strcmp(name+(l1-l2),pattern) == 0 &&
- (l1==l2 || name[l1-(l2+1)] == '/')) {
+ (l1==l2 || (!match_start && name[l1-(l2+1)] == '/'))) {
return 1;
}
}
@@ -198,18 +127,18 @@ static int check_one_exclude(char *name, struct exclude_struct *ex,
static void report_exclude_result(char const *name,
struct exclude_struct const *ent,
- int name_is_dir)
+ STRUCT_STAT const *st)
{
- /* If a trailing slash is present to match only directories,
- * then it is stripped out by make_exclude. So as a special
- * case we add it back in here. */
-
- if (verbose >= 2)
- rprintf(FINFO, "%s %s %s because of pattern %s%s\n",
- ent->include ? "including" : "excluding",
- name_is_dir ? "directory" : "file",
- name, ent->pattern,
- ent->directory ? "/" : "");
+ /* If a trailing slash is present to match only directories,
+ * then it is stripped out by make_exclude. So as a special
+ * case we add it back in here. */
+
+ if (verbose >= 2)
+ rprintf(FINFO, "%s %s %s because of pattern %s%s\n",
+ ent->include ? "including" : "excluding",
+ S_ISDIR(st->st_mode) ? "directory" : "file",
+ name, ent->pattern,
+ ent->directory ? "/" : "");
}
@@ -217,114 +146,136 @@ static void report_exclude_result(char const *name,
* Return true if file NAME is defined to be excluded by either
* LOCAL_EXCLUDE_LIST or the globals EXCLUDE_LIST.
*/
-int check_exclude(struct exclude_struct **list, char *name, int name_is_dir)
+int check_exclude(char *name, struct exclude_struct **local_exclude_list,
+ STRUCT_STAT *st)
{
- struct exclude_struct *ent;
+ int n;
+ struct exclude_struct *ent;
+
+ if (name && (name[0] == '.') && !name[1])
+ /* never exclude '.', even if somebody does --exclude '*' */
+ return 0;
+
+ if (exclude_list) {
+ for (n=0; exclude_list[n]; n++) {
+ ent = exclude_list[n];
+ if (check_one_exclude(name, ent, st)) {
+ report_exclude_result(name, ent, st);
+ return !ent->include;
+ }
+ }
+ }
- while ((ent = *list++) != NULL) {
- if (check_one_exclude(name, ent, name_is_dir)) {
- report_exclude_result(name, ent, name_is_dir);
- return !ent->include;
- }
+ if (local_exclude_list) {
+ for (n=0; local_exclude_list[n]; n++) {
+ ent = local_exclude_list[n];
+ if (check_one_exclude(name, ent, st)) {
+ report_exclude_result(name, ent, st);
+ return !ent->include;
+ }
+ }
}
return 0;
}
-void add_exclude(struct exclude_struct ***listp, const char *pattern, int include)
+void add_exclude_list(const char *pattern, struct exclude_struct ***list, int include)
{
- struct exclude_struct **list = *listp;
- int len = 0;
-
- if (*pattern == '!' && !pattern[1]) {
- free_exclude_list(listp);
- return;
+ 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_exclude((*list)[len]);
+ }
+ free((*list));
+ *list = NULL;
+ return;
}
- if (list)
- for (; list[len]; len++) {}
-
- list = *listp = (struct exclude_struct **)Realloc(list,sizeof(struct exclude_struct *)*(len+2));
-
- if (!list || !(list[len] = make_exclude(pattern, include)))
+ *list = realloc_array(*list, 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,%s)\n",pattern,
- include ? "include" : "exclude");
+ include ? "include" : "exclude");
}
- list[len+1] = NULL;
+ (*list)[len+1] = NULL;
}
+void add_exclude(const char *pattern, int include)
+{
+ add_exclude_list(pattern,&exclude_list, include);
+}
-void add_exclude_file(struct exclude_struct ***listp, const char *fname,
- int fatal, int include)
+struct exclude_struct **make_exclude_list(const char *fname,
+ struct exclude_struct **list1,
+ int fatal, int include)
{
- int fd;
+ struct exclude_struct **list=list1;
+ FILE *f;
char line[MAXPATHLEN];
- char *eob = line + MAXPATHLEN - 1;
- extern int eol_nulls;
- if (!fname || !*fname)
- return;
-
- if (*fname != '-' || fname[1])
- fd = open(fname, O_RDONLY|O_BINARY);
- else
- fd = 0;
- if (fd < 0) {
+ if (strcmp(fname, "-")) {
+ f = fopen(fname,"r");
+ } else {
+ f = fdopen(0, "r");
+ }
+ if (!f) {
if (fatal) {
rsyserr(FERROR, errno,
- "failed to open %s file %s",
- include ? "include" : "exclude",
- fname);
+ "failed to open %s file %s",
+ include ? "include" : "exclude",
+ fname);
exit_cleanup(RERR_FILEIO);
}
- return;
+ return list;
}
- while (1) {
- char ch, *s = line;
- int cnt;
- while (1) {
- if ((cnt = read(fd, &ch, 1)) <= 0) {
- if (cnt < 0 && errno == EINTR)
- continue;
- break;
- }
- if (eol_nulls? !ch : (ch == '\n' || ch == '\r'))
- break;
- if (s < eob)
- *s++ = ch;
- }
- *s = '\0';
- if (*line && *line != ';' && *line != '#') {
+ while (fgets(line,MAXPATHLEN,f)) {
+ int l = strlen(line);
+ while (l && (line[l-1] == '\n' || line[l-1] == '\r')) l--;
+ line[l] = 0;
+ if (line[0] && (line[0] != ';') && (line[0] != '#')) {
/* Skip lines starting with semicolon or pound.
- * It probably wouldn't cause any harm to not skip
- * them but there's no need to save them. */
- add_exclude(listp, line, include);
+ It probably wouldn't cause any harm to not skip
+ them but there's no need to save them. */
+ add_exclude_list(line,&list,include);
}
- if (cnt <= 0)
- break;
}
- close(fd);
+ fclose(f);
+ return list;
+}
+
+
+void add_exclude_file(const char *fname, int fatal, int include)
+{
+ if (!fname || !*fname) return;
+
+ exclude_list = make_exclude_list(fname,exclude_list,fatal,include);
}
void send_exclude_list(int f)
{
int i;
- extern int protocol_version;
+ extern int remote_version;
extern int list_only, recurse;
/* This is a complete hack - blame Rusty.
*
* FIXME: This pattern shows up in the output of
* report_exclude_result(), which is not ideal. */
- if (list_only && !recurse)
- add_exclude(&exclude_list, "/*/*", ADD_EXCLUDE);
+ if (list_only && !recurse) {
+ add_exclude("/*/*", 0);
+ }
if (!exclude_list) {
write_int(f,0);
@@ -335,13 +286,13 @@ void send_exclude_list(int f)
int l;
char pattern[MAXPATHLEN];
- strlcpy(pattern,exclude_list[i]->pattern,sizeof(pattern));
+ strlcpy(pattern,exclude_list[i]->pattern,sizeof(pattern));
if (exclude_list[i]->directory) strlcat(pattern,"/", sizeof(pattern));
l = strlen(pattern);
if (l == 0) continue;
if (exclude_list[i]->include) {
- if (protocol_version < 19) {
+ if (remote_version < 19) {
rprintf(FERROR,"remote rsync does not support include syntax - aborting\n");
exit_cleanup(RERR_UNSUPPORTED);
}
@@ -351,7 +302,7 @@ void send_exclude_list(int f)
write_int(f,l);
}
write_buf(f,pattern,l);
- }
+ }
write_int(f,0);
}
@@ -365,7 +316,7 @@ void recv_exclude_list(int f)
while ((l=read_int(f))) {
if (l >= MAXPATHLEN) overflow("recv_exclude_list");
read_sbuf(f,line,l);
- add_exclude(&exclude_list, line, ADD_EXCLUDE);
+ add_exclude(line,0);
}
}
@@ -401,7 +352,7 @@ char *get_exclude_tok(char *p)
/* Is this a '+' or '-' followed by a space (not whitespace)? */
if ((*s=='+' || *s=='-') && *(s+1)==' ')
s+=2;
-
+
/* Skip to the next space or the end of the string */
while (!isspace(* (unsigned char *) s) && *s != '\0')
s++;
@@ -417,16 +368,26 @@ char *get_exclude_tok(char *p)
return(t);
}
-
-void add_exclude_line(struct exclude_struct ***listp,
- const char *line, int include)
+
+void add_exclude_line(char *p)
{
- char *tok, *p;
- if (!line || !*line) return;
- p = strdup(line);
+ char *tok;
+ if (!p || !*p) return;
+ p = strdup(p);
if (!p) out_of_memory("add_exclude_line");
+ for (tok=get_exclude_tok(p); tok; tok=get_exclude_tok(NULL))
+ add_exclude(tok, 0);
+ free(p);
+}
+
+void add_include_line(char *p)
+{
+ char *tok;
+ if (!p || !*p) return;
+ p = strdup(p);
+ if (!p) out_of_memory("add_include_line");
for (tok=get_exclude_tok(p); tok; tok=get_exclude_tok(NULL))
- add_exclude(listp, tok, include);
+ add_exclude(tok, 1);
free(p);
}
@@ -444,14 +405,14 @@ void add_cvs_excludes(void)
char fname[MAXPATHLEN];
char *p;
int i;
-
+
for (i=0; cvs_ignore_list[i]; i++)
- add_exclude(&exclude_list, cvs_ignore_list[i], ADD_EXCLUDE);
+ add_exclude(cvs_ignore_list[i], 0);
if ((p=getenv("HOME")) && strlen(p) < (MAXPATHLEN-12)) {
snprintf(fname,sizeof(fname), "%s/.cvsignore",p);
- add_exclude_file(&exclude_list,fname,MISSING_OK,ADD_EXCLUDE);
+ add_exclude_file(fname,0,0);
}
- add_exclude_line(&exclude_list, getenv("CVSIGNORE"), ADD_EXCLUDE);
+ add_exclude_line(getenv("CVSIGNORE"));
}
diff --git a/fileio.c b/fileio.c
index 088ed639..bcc541a0 100644
--- a/fileio.c
+++ b/fileio.c
@@ -69,22 +69,19 @@ static int write_sparse(int f,char *buf,size_t len)
return len;
}
-/*
- * write_file does not allow incomplete writes. It loops internally
- * until len bytes are written or errno is set.
- */
+
+
int write_file(int f,char *buf,size_t len)
{
int ret = 0;
+ if (!sparse_files) {
+ return write(f,buf,len);
+ }
+
while (len>0) {
- int r1;
- if (sparse_files) {
- int len1 = MIN(len, SPARSE_WRITE_SIZE);
- r1 = write_sparse(f, buf, len1);
- } else {
- r1 = write(f, buf, len);
- }
+ int len1 = MIN(len, SPARSE_WRITE_SIZE);
+ int r1 = write_sparse(f, buf, len1);
if (r1 <= 0) {
if (ret > 0) return ret;
return r1;
@@ -105,7 +102,7 @@ int write_file(int f,char *buf,size_t len)
struct map_struct *map_file(int fd,OFF_T len)
{
struct map_struct *map;
- map = (struct map_struct *)malloc(sizeof(*map));
+ map = new(struct map_struct);
if (!map) out_of_memory("map_file");
map->fd = fd;
@@ -115,7 +112,6 @@ struct map_struct *map_file(int fd,OFF_T len)
map->p_offset = 0;
map->p_fd_offset = 0;
map->p_len = 0;
- map->status = 0;
return map;
}
@@ -160,7 +156,7 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len)
/* make sure we have allocated enough memory for the window */
if (window_size > map->p_size) {
- map->p = (char *)Realloc(map->p, window_size);
+ map->p = realloc_array(map->p, char, window_size);
if (!map->p) out_of_memory("map_ptr");
map->p_size = window_size;
}
@@ -192,11 +188,7 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len)
}
if ((nread=read(map->fd,map->p + read_offset,read_size)) != read_size) {
- if (nread < 0) {
- nread = 0;
- if (!map->status)
- map->status = errno;
- }
+ if (nread < 0) nread = 0;
/* the best we can do is zero the buffer - the file
has changed mid transfer! */
memset(map->p+read_offset+nread, 0, read_size - nread);
@@ -211,18 +203,13 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len)
}
-int unmap_file(struct map_struct *map)
+void unmap_file(struct map_struct *map)
{
- int ret;
-
if (map->p) {
free(map->p);
map->p = NULL;
}
- ret = map->status;
memset(map, 0, sizeof(*map));
free(map);
-
- return ret;
}
diff --git a/flist.c b/flist.c
index 8bc3ab37..18b874b3 100644
--- a/flist.c
+++ b/flist.c
@@ -1,18 +1,18 @@
-/*
+/*
Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
-
+
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.
@@ -41,8 +41,6 @@ extern int always_checksum;
extern int cvs_exclude;
extern int recurse;
-extern char *files_from;
-extern int filesfrom_fd;
extern int one_file_system;
extern int make_backups;
@@ -54,28 +52,25 @@ extern int preserve_uid;
extern int preserve_gid;
extern int preserve_times;
extern int relative_paths;
-extern int implied_dirs;
extern int copy_links;
extern int copy_unsafe_links;
-extern int protocol_version;
+extern int remote_version;
extern int io_error;
extern int sanitize_paths;
extern int read_batch;
extern int write_batch;
-extern struct exclude_struct **exclude_list;
-extern struct exclude_struct **server_exclude_list;
-extern struct exclude_struct **local_exclude_list;
+static struct exclude_struct **local_exclude_list;
static struct file_struct null_file;
-static void clean_flist(struct file_list *flist, int strip_root, int no_dups);
+static void clean_flist(struct file_list *flist, int strip_root);
static int show_filelist_p(void)
{
- return verbose && (recurse || files_from) && !am_server;
+ return verbose && recurse && !am_server;
}
static void start_filelist_progress(char *kind)
@@ -123,10 +118,10 @@ static struct string_area *string_area_new(int size)
if (size <= 0)
size = ARENA_SIZE;
- a = malloc(sizeof(*a));
+ a = new(struct string_area);
if (!a)
out_of_memory("string_area_new");
- a->current = a->base = malloc(size);
+ a->current = a->base = new_array(char, size);
if (!a->current)
out_of_memory("string_area_new buffer");
a->end = a->base + size;
@@ -221,12 +216,12 @@ int readlink_stat(const char *path, STRUCT_STAT * buffer, char *linkbuf)
if (S_ISLNK(buffer->st_mode)) {
int l;
l = readlink((char *) path, linkbuf, MAXPATHLEN - 1);
- if (l == -1)
+ if (l == -1)
return -1;
linkbuf[l] = 0;
if (copy_unsafe_links && unsafe_symlink(linkbuf, path)) {
if (verbose > 1) {
- rprintf(FINFO,"copying unsafe symlink \"%s\" -> \"%s\"\n",
+ rprintf(FINFO,"copying unsafe symlink \"%s\" -> \"%s\"\n",
path, linkbuf);
}
return do_stat(path, buffer);
@@ -252,37 +247,20 @@ int link_stat(const char *path, STRUCT_STAT * buffer)
}
/*
- * This function is used to check if a file should be included/excluded
- * from the list of files based on its name and type etc. The value of
- * exclude_level is set to either SERVER_EXCLUDES or ALL_EXCLUDES.
+ This function is used to check if a file should be included/excluded
+ from the list of files based on its name and type etc
*/
-static int check_exclude_file(char *fname, int is_dir, int exclude_level)
+static int check_exclude_file(int f, char *fname, STRUCT_STAT * st)
{
-#if 0 /* This currently never happens, so avoid a useless compare. */
- if (exclude_level == NO_EXCLUDES)
+ extern int delete_excluded;
+
+ /* f is set to -1 when calculating deletion file list */
+ if ((f == -1) && delete_excluded) {
return 0;
-#endif
- if (fname) {
- /* never exclude '.', even if somebody does --exclude '*' */
- if (fname[0] == '.' && !fname[1])
- return 0;
- /* Handle the -R version of the '.' dir. */
- if (fname[0] == '/') {
- int len = strlen(fname);
- if (fname[len-1] == '.' && fname[len-2] == '/')
- return 0;
- }
}
- if (server_exclude_list
- && check_exclude(server_exclude_list, fname, is_dir))
- return 1;
- if (exclude_level != ALL_EXCLUDES)
- return 0;
- if (exclude_list && check_exclude(exclude_list, fname, is_dir))
- return 1;
- if (local_exclude_list
- && check_exclude(local_exclude_list, fname, is_dir))
+ if (check_exclude(fname, local_exclude_list, st)) {
return 1;
+ }
return 0;
}
@@ -327,27 +305,28 @@ static char *flist_dir;
static void flist_expand(struct file_list *flist)
{
if (flist->count >= flist->malloced) {
- size_t new_bytes;
void *new_ptr;
-
+
if (flist->malloced < 1000)
flist->malloced += 1000;
else
flist->malloced *= 2;
- new_bytes = sizeof(flist->files[0]) * flist->malloced;
-
if (flist->files)
- new_ptr = realloc(flist->files, new_bytes);
+ new_ptr = realloc_array(flist->files,
+ struct file_struct *,
+ flist->malloced);
else
- new_ptr = malloc(new_bytes);
+ new_ptr = new_array(struct file_struct *,
+ flist->malloced);
if (verbose >= 2) {
rprintf(FINFO, "expand file_list to %.0f bytes, did%s move\n",
- (double) new_bytes,
+ (double)sizeof(flist->files[0])
+ * flist->malloced,
(new_ptr == flist->files) ? " not" : "");
}
-
+
flist->files = (struct file_struct **) new_ptr;
if (!flist->files)
@@ -396,7 +375,7 @@ static void send_file_entry(struct file_struct *file, int f,
for (l1 = 0;
lastname[l1] && (fname[l1] == lastname[l1]) && (l1 < 255);
- l1++) {}
+ l1++);
l2 = strlen(fname) - l1;
if (l1 > 0)
@@ -446,7 +425,7 @@ static void send_file_entry(struct file_struct *file, int f,
#if SUPPORT_HARD_LINKS
if (preserve_hard_links && S_ISREG(file->mode)) {
- if (protocol_version < 26) {
+ if (remote_version < 26) {
/* 32-bit dev_t and ino_t */
write_int(f, (int) file->dev);
write_int(f, (int) file->inode);
@@ -459,7 +438,7 @@ static void send_file_entry(struct file_struct *file, int f,
#endif
if (always_checksum) {
- if (protocol_version < 21) {
+ if (remote_version < 21) {
write_buf(f, file->sum, 2);
} else {
write_buf(f, file->sum, MD4_SUM_LENGTH);
@@ -502,7 +481,7 @@ static void receive_file_entry(struct file_struct **fptr,
else
l2 = read_byte(f);
- file = (struct file_struct *) malloc(sizeof(*file));
+ file = new(struct file_struct);
if (!file)
out_of_memory("receive_file_entry");
memset((char *) file, 0, sizeof(*file));
@@ -569,7 +548,7 @@ static void receive_file_entry(struct file_struct **fptr,
rprintf(FERROR, "overflow: l=%d\n", l);
overflow("receive_file_entry");
}
- file->link = (char *) malloc(l + 1);
+ file->link = new_array(char, l + 1);
if (!file->link)
out_of_memory("receive_file_entry 2");
read_sbuf(f, file->link, l);
@@ -579,7 +558,7 @@ static void receive_file_entry(struct file_struct **fptr,
}
#if SUPPORT_HARD_LINKS
if (preserve_hard_links && S_ISREG(file->mode)) {
- if (protocol_version < 26) {
+ if (remote_version < 26) {
file->dev = read_int(f);
file->inode = read_int(f);
} else {
@@ -590,10 +569,10 @@ static void receive_file_entry(struct file_struct **fptr,
#endif
if (always_checksum) {
- file->sum = (char *) malloc(MD4_SUM_LENGTH);
+ file->sum = new_array(char, MD4_SUM_LENGTH);
if (!file->sum)
out_of_memory("md4 sum");
- if (protocol_version < 21) {
+ if (remote_version < 21) {
read_buf(f, file->sum, 2);
} else {
read_buf(f, file->sum, MD4_SUM_LENGTH);
@@ -660,8 +639,8 @@ static int skip_filesystem(char *fname, STRUCT_STAT * st)
* statting directories if we're not recursing, but this is not a very
* important case. Some systems may not have d_type.
**/
-struct file_struct *make_file(char *fname, struct string_area **ap,
- int exclude_level)
+struct file_struct *make_file(int f, char *fname, struct string_area **ap,
+ int noexcludes)
{
struct file_struct *file;
STRUCT_STAT st;
@@ -683,26 +662,27 @@ struct file_struct *make_file(char *fname, struct string_area **ap,
if (readlink_stat(fname, &st, linkbuf) != 0) {
int save_errno = errno;
- if (errno == ENOENT && exclude_level != NO_EXCLUDES) {
- /* either symlink pointing nowhere or file that
+ if ((errno == ENOENT) && !noexcludes) {
+ /* either symlink pointing nowhere or file that
* was removed during rsync run; see if excluded
* before reporting an error */
- if (check_exclude_file(fname, 0, exclude_level)) {
+ memset((char *) &st, 0, sizeof(st));
+ if (check_exclude_file(f, fname, &st)) {
/* file is excluded anyway, ignore silently */
return NULL;
}
}
io_error = 1;
- rprintf(FERROR, "readlink %s failed: %s\n",
- full_fname(fname), strerror(save_errno));
+ rprintf(FERROR, "readlink %s: %s\n",
+ fname, strerror(save_errno));
return NULL;
}
- /* backup.c calls us with exclude_level set to NO_EXCLUDES. */
- if (exclude_level == NO_EXCLUDES)
+ /* we use noexcludes from backup.c */
+ if (noexcludes)
goto skip_excludes;
- if (S_ISDIR(st.st_mode) && !recurse && !files_from) {
+ if (S_ISDIR(st.st_mode) && !recurse) {
rprintf(FINFO, "skipping directory %s\n", fname);
return NULL;
}
@@ -712,18 +692,19 @@ struct file_struct *make_file(char *fname, struct string_area **ap,
return NULL;
}
- if (check_exclude_file(fname, S_ISDIR(st.st_mode) != 0, exclude_level))
+ if (check_exclude_file(f, fname, &st))
return NULL;
+
if (lp_ignore_nonreadable(module_id) && access(fname, R_OK) != 0)
return NULL;
skip_excludes:
if (verbose > 2)
- rprintf(FINFO, "make_file(%s,*,%d)\n", fname, exclude_level);
+ rprintf(FINFO, "make_file(%d,%s)\n", f, fname);
- file = (struct file_struct *) malloc(sizeof(*file));
+ file = new(struct file_struct);
if (!file)
out_of_memory("make_file");
memset((char *) file, 0, sizeof(*file));
@@ -799,12 +780,8 @@ void send_file_name(int f, struct file_list *flist, char *fname,
int recursive, unsigned base_flags)
{
struct file_struct *file;
- extern int delete_excluded;
- /* f is set to -1 when calculating deletion file list */
- file = make_file(fname, &flist->string_area,
- f == -1 && delete_excluded? SERVER_EXCLUDES
- : ALL_EXCLUDES);
+ file = make_file(f, fname, &flist->string_area, 0);
if (!file)
return;
@@ -816,7 +793,7 @@ void send_file_name(int f, struct file_list *flist, char *fname,
if (write_batch) /* dw */
file->flags = FLAG_DELETE;
- if (file->basename[0]) {
+ if (strcmp(file->basename, "")) {
flist->files[flist->count++] = file;
send_file_entry(file, f, base_flags);
}
@@ -843,8 +820,7 @@ static void send_directory(int f, struct file_list *flist, char *dir)
d = opendir(dir);
if (!d) {
io_error = 1;
- rprintf(FERROR, "opendir %s failed: %s\n",
- full_fname(dir), strerror(errno));
+ rprintf(FERROR, "opendir(%s): %s\n", dir, strerror(errno));
return;
}
@@ -853,8 +829,9 @@ static void send_directory(int f, struct file_list *flist, char *dir)
if (fname[l - 1] != '/') {
if (l == MAXPATHLEN - 1) {
io_error = 1;
- rprintf(FERROR, "skipping long-named directory: %s\n",
- full_fname(fname));
+ rprintf(FERROR,
+ "skipping long-named directory %s\n",
+ fname);
closedir(d);
return;
}
@@ -868,51 +845,45 @@ 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");
- add_exclude_file(&exclude_list,fname,MISSING_OK,ADD_EXCLUDE);
+ 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",
- full_fname(fname));
+ fname);
}
}
- for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) {
+ for (di = readdir(d); di; di = readdir(d)) {
char *dname = d_name(di);
- if (dname[0] == '.' && (dname[1] == '\0'
- || (dname[1] == '.' && dname[2] == '\0')))
+ if (strcmp(dname, ".") == 0 || strcmp(dname, "..") == 0)
continue;
strlcpy(p, dname, MAXPATHLEN - l);
send_file_name(f, flist, fname, recurse, 0);
}
- if (errno) {
- io_error = 1;
- rprintf(FERROR, "readdir(%s): (%d) %s\n",
- dir, errno, strerror(errno));
- }
- if (local_exclude_list)
- free_exclude_list(&local_exclude_list); /* Zeros pointer too */
+ if (local_exclude_list) {
+ add_exclude_list("!", &local_exclude_list, 0);
+ }
closedir(d);
}
/**
- * The delete_files() function in receiver.c sets f to -1 so that we just
- * construct the file list in memory without sending it over the wire. It
- * also has the side-effect of ignoring user-excludes if delete_excluded
- * is set (so that the delete list includes user-excluded files).
+ *
+ * I <b>think</b> f==-1 means that the list should just be built in
+ * memory and not transmitted. But who can tell? -- mbp
**/
struct file_list *send_file_list(int f, int argc, char *argv[])
{
- int l;
+ int i, l;
STRUCT_STAT st;
char *p, *dir, *olddir;
char lastpath[MAXPATHLEN] = "";
struct file_list *flist;
int64 start_write;
- int use_ff_fd = 0;
if (show_filelist_p() && f != -1)
start_filelist_progress("building file list");
@@ -923,37 +894,23 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
if (f != -1) {
io_start_buffering(f);
- if (filesfrom_fd >= 0) {
- if (argv[0] && !push_dir(argv[0], 0)) {
- rprintf(FERROR, "push_dir %s failed: %s\n",
- full_fname(argv[0]), strerror(errno));
- exit_cleanup(RERR_FILESELECT);
- }
- use_ff_fd = 1;
- }
}
- while (1) {
+ for (i = 0; i < argc; i++) {
char fname2[MAXPATHLEN];
char *fname = fname2;
- if (use_ff_fd) {
- if (read_filesfrom_line(filesfrom_fd, fname) == 0)
- break;
- sanitize_path(fname, NULL);
- } else {
- if (argc-- == 0)
- break;
- strlcpy(fname, *argv++, MAXPATHLEN);
- if (sanitize_paths)
- sanitize_path(fname, NULL);
- }
+ strlcpy(fname, argv[i], MAXPATHLEN);
l = strlen(fname);
- if (fname[l - 1] == '/') {
- if (l == 2 && fname[0] == '.') {
- /* Turn "./" into just "." rather than "./." */
- fname[1] = '\0';
+ if (l != 1 && fname[l - 1] == '/') {
+ if ((l == 2) && (fname[0] == '.')) {
+ /* Turn ./ into just . rather than ./.
+ This was put in to avoid a problem with
+ rsync -aR --delete from ./
+ The send_file_name() below of ./ was
+ mysteriously preventing deletes */
+ fname[1] = 0;
} else {
strlcat(fname, ".", MAXPATHLEN);
}
@@ -962,13 +919,13 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
if (link_stat(fname, &st) != 0) {
if (f != -1) {
io_error = 1;
- rprintf(FERROR, "link_stat %s failed: %s\n",
- full_fname(fname), strerror(errno));
+ rprintf(FERROR, "link_stat %s : %s\n",
+ fname, strerror(errno));
}
continue;
}
- if (S_ISDIR(st.st_mode) && !recurse && !files_from) {
+ if (S_ISDIR(st.st_mode) && !recurse) {
rprintf(FINFO, "skipping directory %s\n", fname);
continue;
}
@@ -986,37 +943,31 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
dir = fname;
fname = p + 1;
}
- } else if (f != -1 && implied_dirs && (p=strrchr(fname,'/')) && p != fname) {
+ } else if (f != -1 && (p = strrchr(fname, '/'))) {
/* this ensures we send the intermediate directories,
thus getting their permissions right */
- char *lp = lastpath, *fn = fname, *slash = fname;
*p = 0;
- /* Skip any initial directories in our path that we
- * have in common with lastpath. */
- while (*fn && *lp == *fn) {
- if (*fn == '/')
- slash = fn;
- lp++, fn++;
- }
- *p = '/';
- if (fn != p || (*lp && *lp != '/')) {
- int copy_links_saved = copy_links;
- int recurse_saved = recurse;
- copy_links = copy_unsafe_links;
- /* set recurse to 1 to prevent make_file
- * from ignoring directory, but still
- * turn off the recursive parameter to
- * send_file_name */
- recurse = 1;
- while ((slash = strchr(slash+1, '/')) != 0) {
- *slash = 0;
- send_file_name(f, flist, fname, 0, 0);
- *slash = '/';
+ if (strcmp(lastpath, fname)) {
+ strlcpy(lastpath, fname, sizeof(lastpath));
+ *p = '/';
+ for (p = fname + 1; (p = strchr(p, '/'));
+ p++) {
+ int copy_links_saved = copy_links;
+ int recurse_saved = recurse;
+ *p = 0;
+ copy_links = copy_unsafe_links;
+ /* set recurse to 1 to prevent make_file
+ from ignoring directory, but still
+ turn off the recursive parameter to
+ send_file_name */
+ recurse = 1;
+ send_file_name(f, flist, fname, 0,
+ 0);
+ copy_links = copy_links_saved;
+ recurse = recurse_saved;
+ *p = '/';
}
- copy_links = copy_links_saved;
- recurse = recurse_saved;
- *p = 0;
- strlcpy(lastpath, fname, sizeof lastpath);
+ } else {
*p = '/';
}
}
@@ -1029,8 +980,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
if (!olddir) {
io_error = 1;
- rprintf(FERROR, "push_dir %s failed: %s\n",
- full_fname(dir), strerror(errno));
+ rprintf(FERROR, "push_dir %s : %s\n",
+ dir, strerror(errno));
continue;
}
@@ -1045,8 +996,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
if (olddir != NULL) {
flist_dir = NULL;
if (pop_dir(olddir) != 0) {
- rprintf(FERROR, "pop_dir %s failed: %s\n",
- full_fname(dir), strerror(errno));
+ rprintf(FERROR, "pop_dir %s : %s\n",
+ dir, strerror(errno));
exit_cleanup(RERR_FILESELECT);
}
}
@@ -1060,16 +1011,16 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
finish_filelist_progress(flist);
}
- clean_flist(flist, 0, 0);
+ clean_flist(flist, 0);
/* now send the uid/gid list. This was introduced in protocol
version 15 */
- if (f != -1) {
+ if (f != -1 && remote_version >= 15) {
send_uid_list(f);
}
- /* send the io_error flag */
- if (f != -1) {
+ /* if protocol version is >= 17 then send the io_error flag */
+ if (f != -1 && remote_version >= 17) {
extern int module_id;
write_int(f, lp_ignore_errors(module_id) ? 0 : io_error);
}
@@ -1101,22 +1052,20 @@ struct file_list *recv_file_list(int f)
start_read = stats.total_read;
- flist = (struct file_list *) malloc(sizeof(flist[0]));
+ flist = new(struct file_list);
if (!flist)
goto oom;
flist->count = 0;
flist->malloced = 1000;
- flist->files =
- (struct file_struct **) malloc(sizeof(flist->files[0]) *
- flist->malloced);
+ flist->files = new_array(struct file_struct *, flist->malloced);
if (!flist->files)
goto oom;
for (flags = read_byte(f); flags; flags = read_byte(f)) {
int i = flist->count;
-
+
flist_expand(flist);
receive_file_entry(&flist->files[i], flags, f);
@@ -1137,19 +1086,19 @@ struct file_list *recv_file_list(int f)
if (verbose > 2)
rprintf(FINFO, "received %d names\n", flist->count);
- clean_flist(flist, relative_paths, 1);
+ clean_flist(flist, relative_paths);
if (show_filelist_p()) {
finish_filelist_progress(flist);
}
/* now recv the uid/gid list. This was introduced in protocol version 15 */
- if (f != -1) {
+ if (f != -1 && remote_version >= 15) {
recv_uid_list(f, flist);
}
- /* recv the io_error flag */
- if (f != -1 && !read_batch) { /* dw-added readbatch */
+ /* if protocol version is >= 17 then recv the io_error flag */
+ if (f != -1 && remote_version >= 17 && !read_batch) { /* dw-added readbatch */
extern int module_id;
extern int ignore_errors;
if (lp_ignore_errors(module_id) || ignore_errors) {
@@ -1251,7 +1200,7 @@ struct file_list *flist_new(void)
{
struct file_list *flist;
- flist = (struct file_list *) malloc(sizeof(flist[0]));
+ flist = new(struct file_list);
if (!flist)
out_of_memory("send_file_list");
@@ -1294,11 +1243,11 @@ void flist_free(struct file_list *flist)
/*
* This routine ensures we don't have any duplicate names in our file list.
- * duplicate names can cause corruption because of the pipelining
+ * duplicate names can cause corruption because of the pipelining
*/
-static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
+static void clean_flist(struct file_list *flist, int strip_root)
{
- int i, prev_i = 0;
+ int i;
char *name, *prev_name = NULL;
if (!flist || flist->count == 0)
@@ -1307,9 +1256,8 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
qsort(flist->files, flist->count,
sizeof(flist->files[0]), (int (*)()) file_compare);
- for (i = no_dups? 0 : flist->count; i < flist->count; i++) {
+ for (i = 0; i < flist->count; i++) {
if (flist->files[i]->basename) {
- prev_i = i;
prev_name = f_name(flist->files[i]);
break;
}
@@ -1324,11 +1272,6 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
"removing duplicate name %s from file list %d\n",
name, i);
}
- /* Make sure that if we unduplicate '.', that we don't
- * lose track of a user-specified starting point (or
- * else deletions will mysteriously fail with -R). */
- if (flist->files[i]->flags & FLAG_DELETE)
- flist->files[prev_i]->flags |= FLAG_DELETE;
/* it's not great that the flist knows the semantics of
* the file memory usage, but i'd rather not add a flag
* byte to that struct.
@@ -1338,10 +1281,6 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
else
free_file(flist->files[i]);
}
- else
- prev_i = i;
- /* We set prev_name every iteration to avoid it becoming
- * invalid when names[][] in f_name() wraps around. */
prev_name = name;
}
diff --git a/hlink.c b/hlink.c
index a38a65bd..3826ce52 100644
--- a/hlink.c
+++ b/hlink.c
@@ -57,9 +57,7 @@ void init_hard_links(struct file_list *flist)
if (hlink_list)
free(hlink_list);
- if (!(hlink_list =
- (struct file_struct *) malloc(sizeof(hlink_list[0]) *
- flist->count)))
+ if (!(hlink_list = new_array(struct file_struct, flist->count)))
out_of_memory("init_hard_links");
for (i = 0; i < flist->count; i++)
diff --git a/io.c b/io.c
index 36d5f1b2..e47e6d0b 100644
--- a/io.c
+++ b/io.c
@@ -76,12 +76,6 @@ int kludge_around_eof = False;
static int io_error_fd = -1;
-static int io_filesfrom_f_in = -1;
-static int io_filesfrom_f_out = -1;
-static char io_filesfrom_buf[2048];
-static char *io_filesfrom_bp;
-static char io_filesfrom_lastchar;
-static int io_filesfrom_buflen;
static void read_loop(int fd, char *buf, size_t len);
@@ -91,7 +85,7 @@ static void check_timeout(void)
time_t t;
err_list_push();
-
+
if (!io_timeout) return;
if (!last_io) {
@@ -124,8 +118,8 @@ static void read_error_fd(void)
int fd = io_error_fd;
int tag, len;
- /* io_error_fd is temporarily disabled -- is this meant to
- * prevent indefinite recursion? */
+ /* io_error_fd is temporarily disabled -- is this meant to
+ * prevent indefinite recursion? */
io_error_fd = -1;
read_loop(fd, buf, 4);
@@ -137,8 +131,8 @@ static void read_error_fd(void)
while (len) {
n = len;
- if (n > (sizeof buf - 1))
- n = sizeof buf - 1;
+ if (n > (sizeof(buf)-1))
+ n = sizeof(buf)-1;
read_loop(fd, buf, n);
rwrite((enum logcode)tag, buf, n);
len -= n;
@@ -147,24 +141,6 @@ static void read_error_fd(void)
io_error_fd = fd;
}
-/**
- * When we're the receiver and we have a local --files-from list of names
- * that needs to be sent over the socket to the sender, we have to do two
- * things at the same time: send the sender a list of what files we're
- * processing and read the incoming file+info list from the sender. We do
- * this by augmenting the read_timeout() function to copy this data. It
- * uses the io_filesfrom_buf to read a block of data from f_in (when it is
- * ready, since it might be a pipe) and then blast it out f_out (when it
- * is ready to receive more data).
- */
-void io_set_filesfrom_fds(int f_in, int f_out)
-{
- io_filesfrom_f_in = f_in;
- io_filesfrom_f_out = f_out;
- io_filesfrom_bp = io_filesfrom_buf;
- io_filesfrom_lastchar = '\0';
- io_filesfrom_buflen = 0;
-}
/**
* It's almost always an error to get an EOF when we're trying to read
@@ -176,28 +152,28 @@ void io_set_filesfrom_fds(int f_in, int f_out)
* program where that is a problem (start_socket_client),
* kludge_around_eof is True and we just exit.
*/
-static void whine_about_eof(void)
+static void whine_about_eof (void)
{
if (kludge_around_eof)
- exit_cleanup(0);
+ exit_cleanup (0);
else {
- rprintf(FERROR,
- "%s: connection unexpectedly closed "
- "(%.0f bytes read so far)\n",
- RSYNC_NAME, (double)stats.total_read);
-
- exit_cleanup(RERR_STREAMIO);
+ rprintf (FERROR,
+ "%s: connection unexpectedly closed "
+ "(%.0f bytes read so far)\n",
+ RSYNC_NAME, (double)stats.total_read);
+
+ exit_cleanup (RERR_STREAMIO);
}
}
-static void die_from_readerr(int err)
+static void die_from_readerr (int err)
{
/* this prevents us trying to write errors on a dead socket */
io_multiplexing_close();
-
+
rprintf(FERROR, "%s: read error: %s\n",
- RSYNC_NAME, strerror(err));
+ RSYNC_NAME, strerror (err));
exit_cleanup(RERR_STREAMIO);
}
@@ -213,7 +189,7 @@ static void die_from_readerr(int err)
* give a better explanation. We can tell whether the connection has
* started by looking e.g. at whether the remote version is known yet.
*/
-static int read_timeout(int fd, char *buf, size_t len)
+static int read_timeout (int fd, char *buf, size_t len)
{
int n, ret=0;
@@ -221,33 +197,16 @@ static int read_timeout(int fd, char *buf, size_t len)
while (ret == 0) {
/* until we manage to read *something* */
- fd_set r_fds, w_fds;
+ fd_set fds;
struct timeval tv;
int fd_count = fd+1;
int count;
- FD_ZERO(&r_fds);
- FD_SET(fd, &r_fds);
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
if (io_error_fd != -1) {
- FD_SET(io_error_fd, &r_fds);
- if (io_error_fd >= fd_count) fd_count = io_error_fd+1;
- }
- if (io_filesfrom_f_out != -1) {
- int new_fd;
- if (io_filesfrom_buflen == 0) {
- if (io_filesfrom_f_in != -1) {
- FD_SET(io_filesfrom_f_in, &r_fds);
- new_fd = io_filesfrom_f_in;
- } else {
- io_filesfrom_f_out = -1;
- new_fd = -1;
- }
- } else {
- FD_ZERO(&w_fds);
- FD_SET(io_filesfrom_f_out, &w_fds);
- new_fd = io_filesfrom_f_out;
- }
- if (new_fd >= fd_count) fd_count = new_fd+1;
+ FD_SET(io_error_fd, &fds);
+ if (io_error_fd > fd) fd_count = io_error_fd+1;
}
tv.tv_sec = io_timeout?io_timeout:SELECT_TIMEOUT;
@@ -255,9 +214,7 @@ static int read_timeout(int fd, char *buf, size_t len)
errno = 0;
- count = select(fd_count, &r_fds,
- io_filesfrom_buflen? &w_fds : NULL,
- NULL, &tv);
+ count = select(fd_count, &fds, NULL, NULL, &tv);
if (count == 0) {
check_timeout();
@@ -270,76 +227,11 @@ static int read_timeout(int fd, char *buf, size_t len)
continue;
}
-
- if (io_error_fd != -1 && FD_ISSET(io_error_fd, &r_fds)) {
+ if (io_error_fd != -1 && FD_ISSET(io_error_fd, &fds)) {
read_error_fd();
}
- if (io_filesfrom_f_out != -1) {
- if (io_filesfrom_buflen) {
- if (FD_ISSET(io_filesfrom_f_out, &w_fds)) {
- int l = write(io_filesfrom_f_out,
- io_filesfrom_bp,
- io_filesfrom_buflen);
- if (l > 0) {
- if (!(io_filesfrom_buflen -= l))
- io_filesfrom_bp = io_filesfrom_buf;
- else
- io_filesfrom_bp += l;
- } else {
- /* XXX should we complain? */
- io_filesfrom_f_out = -1;
- }
- }
- } else if (io_filesfrom_f_in != -1) {
- if (FD_ISSET(io_filesfrom_f_in, &r_fds)) {
- int l = read(io_filesfrom_f_in,
- io_filesfrom_buf,
- sizeof io_filesfrom_buf);
- if (l <= 0) {
- /* Send end-of-file marker */
- io_filesfrom_buf[0] = '\0';
- io_filesfrom_buf[1] = '\0';
- io_filesfrom_buflen = io_filesfrom_lastchar? 2 : 1;
- io_filesfrom_f_in = -1;
- } else {
- extern int eol_nulls;
- if (!eol_nulls) {
- char *s = io_filesfrom_buf + l;
- /* Transform CR and/or LF into '\0' */
- while (s-- > io_filesfrom_buf) {
- if (*s == '\n' || *s == '\r')
- *s = '\0';
- }
- }
- if (!io_filesfrom_lastchar) {
- /* Last buf ended with a '\0', so don't
- * let this buf start with one. */
- while (l && !*io_filesfrom_bp)
- io_filesfrom_bp++, l--;
- }
- if (!l)
- io_filesfrom_bp = io_filesfrom_buf;
- else {
- char *f = io_filesfrom_bp;
- char *t = f;
- char *eob = f + l;
- /* Eliminate any multi-'\0' runs. */
- while (f != eob) {
- if (!(*t++ = *f++)) {
- while (f != eob && !*f)
- f++, l--;
- }
- }
- io_filesfrom_lastchar = f[-1];
- }
- io_filesfrom_buflen = l;
- }
- }
- }
- }
-
- if (!FD_ISSET(fd, &r_fds)) continue;
+ if (!FD_ISSET(fd, &fds)) continue;
n = read(fd, buf, len);
@@ -351,76 +243,28 @@ static int read_timeout(int fd, char *buf, size_t len)
last_io = time(NULL);
continue;
} else if (n == 0) {
- whine_about_eof();
+ whine_about_eof ();
return -1; /* doesn't return */
} else if (n == -1) {
if (errno == EINTR || errno == EWOULDBLOCK ||
errno == EAGAIN)
continue;
- die_from_readerr(errno);
+ else
+ die_from_readerr (errno);
}
}
return ret;
}
-/**
- * Read a line into the "fname" buffer (which must be at least MAXPATHLEN
- * characters long).
- */
-int read_filesfrom_line(int fd, char *fname)
-{
- char ch, *s, *eob = fname + MAXPATHLEN - 1;
- int cnt;
- extern int io_timeout;
- extern int eol_nulls;
- extern char *remote_filesfrom_file;
- extern int am_server;
- int reading_remotely = remote_filesfrom_file || (am_server && fd == 0);
- int nulls = eol_nulls || reading_remotely;
-
- start:
- s = fname;
- while (1) {
- cnt = read(fd, &ch, 1);
- if (cnt < 0 && (errno == EWOULDBLOCK
- || errno == EINTR || errno == EAGAIN)) {
- struct timeval tv;
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
- tv.tv_sec = io_timeout? io_timeout : SELECT_TIMEOUT;
- tv.tv_usec = 0;
- if (!select(fd+1, &fds, NULL, NULL, &tv))
- check_timeout();
- continue;
- }
- if (cnt != 1)
- break;
- if (nulls? !ch : (ch == '\r' || ch == '\n')) {
- /* Skip empty lines if reading locally. */
- if (!reading_remotely && s == fname)
- continue;
- break;
- }
- if (s < eob)
- *s++ = ch;
- }
- *s = '\0';
- /* Dump comments. */
- if (*fname == '#' || *fname == ';')
- goto start;
-
- return s - fname;
-}
/**
* Continue trying to read len bytes - don't return until len has been
* read.
**/
-static void read_loop(int fd, char *buf, size_t len)
+static void read_loop (int fd, char *buf, size_t len)
{
while (len) {
int n = read_timeout(fd, buf, len);
@@ -471,9 +315,9 @@ static int read_unbuffered(int fd, char *buf, size_t len)
exit_cleanup(RERR_STREAMIO);
}
- if (remaining > sizeof line - 1) {
- rprintf(FERROR, "multiplexing overflow %ld\n\n",
- (long)remaining);
+ if (remaining > sizeof(line) - 1) {
+ rprintf(FERROR, "multiplexing overflow %d\n\n",
+ remaining);
exit_cleanup(RERR_STREAMIO);
}
@@ -494,15 +338,15 @@ static int read_unbuffered(int fd, char *buf, size_t len)
* have been read. If all @p n can't be read then exit with an
* error.
**/
-static void readfd(int fd, char *buffer, size_t N)
+static void readfd (int fd, char *buffer, size_t N)
{
int ret;
size_t total=0;
-
+
while (total < N) {
io_flush();
- ret = read_unbuffered(fd, buffer + total, N-total);
+ ret = read_unbuffered (fd, buffer + total, N-total);
total += ret;
}
@@ -523,6 +367,7 @@ int32 read_int(int f)
int64 read_longint(int f)
{
+ extern int remote_version;
int64 ret;
char b[8];
ret = read_int(f);
@@ -535,8 +380,10 @@ int64 read_longint(int f)
rprintf(FERROR,"Integer overflow - attempted 64 bit offset\n");
exit_cleanup(RERR_UNSUPPORTED);
#else
- readfd(f,b,8);
- ret = IVAL(b,0) | (((int64)IVAL(b,4))<<32);
+ if (remote_version >= 16) {
+ readfd(f,b,8);
+ ret = IVAL(b,0) | (((int64)IVAL(b,4))<<32);
+ }
#endif
return ret;
@@ -549,14 +396,14 @@ void read_buf(int f,char *buf,size_t len)
void read_sbuf(int f,char *buf,size_t len)
{
- read_buf(f,buf,len);
+ read_buf (f,buf,len);
buf[len] = 0;
}
unsigned char read_byte(int f)
{
unsigned char c;
- read_buf(f, (char *)&c, 1);
+ read_buf (f, (char *)&c, 1);
return c;
}
@@ -579,7 +426,7 @@ static void sleep_for_bwlimit(int bytes_written)
assert(bytes_written > 0);
assert(bwlimit > 0);
-
+
tv.tv_usec = bytes_written * 1000 / bwlimit;
tv.tv_sec = tv.tv_usec / 1000000;
tv.tv_usec = tv.tv_usec % 1000000;
@@ -607,11 +454,11 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
while (total < len) {
FD_ZERO(&w_fds);
+ FD_ZERO(&r_fds);
FD_SET(fd,&w_fds);
fd_count = fd;
if (io_error_fd != -1) {
- FD_ZERO(&r_fds);
FD_SET(io_error_fd,&r_fds);
if (io_error_fd > fd_count)
fd_count = io_error_fd;
@@ -688,7 +535,7 @@ void io_start_buffering(int fd)
{
if (io_buffer) return;
multiplex_out_fd = fd;
- io_buffer = (char *)malloc(IO_BUFFER_SIZE);
+ io_buffer = new_array(char, IO_BUFFER_SIZE);
if (!io_buffer) out_of_memory("writefd");
io_buffer_count = 0;
}
@@ -704,8 +551,8 @@ static void mplex_write(int fd, enum logcode code, char *buf, size_t len)
SIVAL(buffer, 0, ((MPLEX_BASE + (int)code)<<24) + len);
- if (n > (sizeof buffer - 4)) {
- n = sizeof buffer - 4;
+ if (n > (sizeof(buffer)-4)) {
+ n = sizeof(buffer)-4;
}
memcpy(&buffer[4], buf, n);
@@ -765,7 +612,7 @@ static void writefd(int fd,char *buf,size_t len)
len -= n;
io_buffer_count += n;
}
-
+
if (io_buffer_count == IO_BUFFER_SIZE) io_flush();
}
}
@@ -793,23 +640,19 @@ void write_int_named(int f, int32 x, const char *phase)
*/
void write_longint(int f, int64 x)
{
+ extern int remote_version;
char b[8];
- if (x <= 0x7FFFFFFF) {
+ if (remote_version < 16 || x <= 0x7FFFFFFF) {
write_int(f, (int)x);
return;
}
-#ifdef NO_INT64
- rprintf(FERROR,"Integer overflow - attempted 64 bit offset\n");
- exit_cleanup(RERR_UNSUPPORTED);
-#else
write_int(f, (int32)0xFFFFFFFF);
SIVAL(b,0,(x&0xFFFFFFFF));
SIVAL(b,4,((x>>32)&0xFFFFFFFF));
writefd(f,b,8);
-#endif
}
void write_buf(int f,char *buf,size_t len)
@@ -867,9 +710,9 @@ void io_printf(int fd, const char *format, ...)
va_list ap;
char buf[1024];
int len;
-
+
va_start(ap, format);
- len = vsnprintf(buf, sizeof buf, format, ap);
+ len = vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
if (len < 0) exit_cleanup(RERR_STREAMIO);
diff --git a/loadparm.c b/loadparm.c
index 9dc80e70..6b156107 100644
--- a/loadparm.c
+++ b/loadparm.c
@@ -6,17 +6,17 @@
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
*/
-/*
+/*
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.
@@ -36,7 +36,7 @@
* 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
* 4) If it's a global then initialise it in init_globals. If a local
* (ie. service) parameter then initialise it in the sDefault structure
- *
+ *
*
* Notes:
* The configuration file is processed sequentially for speed. It is NOT
@@ -61,7 +61,7 @@ typedef char pstring[1024];
typedef enum
{
P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
- P_PATH,P_STRING,P_GSTRING,P_ENUM,P_SEP
+ P_STRING,P_GSTRING,P_ENUM,P_SEP
} parm_type;
typedef enum
@@ -93,7 +93,7 @@ struct parm_struct
#define iSERVICE(i) (*pSERVICE(i))
#define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices))
-/*
+/*
* This structure describes global (ie., server-wide) parameters.
*/
typedef struct
@@ -109,8 +109,8 @@ static global Globals;
-/*
- * This structure describes a single service.
+/*
+ * This structure describes a single service.
*/
typedef struct
{
@@ -144,7 +144,7 @@ typedef struct
/* This is a default service used to prime a services structure */
-static service sDefault =
+static service sDefault =
{
NULL, /* name */
NULL, /* path */
@@ -156,7 +156,7 @@ static service sDefault =
False, /* transfer logging */
False, /* ignore errors */
"nobody",/* uid */
-
+
/* TODO: This causes problems on Debian, where it is called
* "nogroup". Debian patch this in their version of the
* package, but it would be nice to be consistent. Possibly
@@ -165,7 +165,7 @@ static service sDefault =
* What is the best behaviour? Perhaps always using (gid_t)
* -2? */
"nobody",/* gid */
-
+
NULL, /* hosts allow */
NULL, /* hosts deny */
NULL, /* auth users */
@@ -222,7 +222,7 @@ static struct enum_list enum_facilities[] = {
{ LOG_NEWS, "news" },
#endif
#ifdef LOG_AUTH
- { LOG_AUTH, "security" },
+ { LOG_AUTH, "security" },
#endif
#ifdef LOG_SYSLOG
{ LOG_SYSLOG, "syslog" },
@@ -274,7 +274,7 @@ static struct parm_struct parm_table[] =
{"name", P_STRING, P_LOCAL, &sDefault.name, NULL, 0},
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, 0},
{"lock file", P_STRING, P_LOCAL, &sDefault.lock_file, NULL, 0},
- {"path", P_PATH, P_LOCAL, &sDefault.path, NULL, 0},
+ {"path", P_STRING, P_LOCAL, &sDefault.path, NULL, 0},
{"read only", P_BOOL, P_LOCAL, &sDefault.read_only, NULL, 0},
{"list", P_BOOL, P_LOCAL, &sDefault.list, NULL, 0},
{"use chroot", P_BOOL, P_LOCAL, &sDefault.use_chroot, NULL, 0},
@@ -319,8 +319,8 @@ static void init_locals(void)
/*
- In this section all the functions that are used to access the
- parameters from the rest of the program are defined
+ In this section all the functions that are used to access the
+ parameters from the rest of the program are defined
*/
#define FN_GLOBAL_STRING(fn_name,ptr) \
@@ -376,11 +376,12 @@ FN_LOCAL_INTEGER(lp_timeout, timeout)
FN_LOCAL_INTEGER(lp_max_connections, max_connections)
/* local prototypes */
-static int strwicmp(char *psz1, char *psz2);
-static int map_parameter(char *parmname);
-static BOOL set_boolean(BOOL *pb, char *parmvalue);
+static int strwicmp( char *psz1, char *psz2 );
+static int map_parameter( char *parmname);
+static BOOL set_boolean( BOOL *pb, char *parmvalue );
static int getservicebyname(char *name, service *pserviceDest);
-static void copy_service(service *pserviceDest, service *pserviceSource);
+static void copy_service( service *pserviceDest,
+ service *pserviceSource);
static BOOL do_parameter(char *parmname, char *parmvalue);
static BOOL do_section(char *sectionname);
@@ -420,7 +421,7 @@ static void string_set(char **s, const char *v)
/***************************************************************************
-add a new service to the services array initialising it with the given
+add a new service to the services array initialising it with the given
service
***************************************************************************/
static int add_a_service(service *pservice, char *name)
@@ -432,7 +433,7 @@ static int add_a_service(service *pservice, char *name)
tservice = *pservice;
/* it might already exist */
- if (name)
+ if (name)
{
i = getservicebyname(name,NULL);
if (i >= 0)
@@ -441,10 +442,10 @@ static int add_a_service(service *pservice, char *name)
i = iNumServices;
- ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
+ ServicePtrs = realloc_array(ServicePtrs, service *, num_to_alloc);
if (ServicePtrs)
- pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
+ pSERVICE(iNumServices) = new(service);
if (!ServicePtrs || !pSERVICE(iNumServices))
return(-1);
@@ -454,7 +455,7 @@ static int add_a_service(service *pservice, char *name)
init_service(pSERVICE(i));
copy_service(pSERVICE(i),&tservice);
if (name)
- string_set(&iSERVICE(i).name,name);
+ string_set(&iSERVICE(i).name,name);
return(i);
}
@@ -492,7 +493,7 @@ static int strwicmp(char *psz1, char *psz2)
}
/***************************************************************************
-Map a parameter's string representation to something we can use.
+Map a parameter's string representation to something we can use.
Returns False if the parameter string is not recognised, else TRUE.
***************************************************************************/
static int map_parameter(char *parmname)
@@ -502,7 +503,7 @@ static int map_parameter(char *parmname)
if (*parmname == '-')
return(-1);
- for (iIndex = 0; parm_table[iIndex].label; iIndex++)
+ for (iIndex = 0; parm_table[iIndex].label; iIndex++)
if (strwicmp(parm_table[iIndex].label, parmname) == 0)
return(iIndex);
@@ -513,7 +514,7 @@ static int map_parameter(char *parmname)
/***************************************************************************
Set a boolean variable from the text value stored in the passed string.
-Returns True in success, False if the passed string does not correctly
+Returns True in success, False if the passed string does not correctly
represent a boolean.
***************************************************************************/
static BOOL set_boolean(BOOL *pb, char *parmvalue)
@@ -547,7 +548,7 @@ static int getservicebyname(char *name, service *pserviceDest)
int iService;
for (iService = iNumServices - 1; iService >= 0; iService--)
- if (strwicmp(iSERVICE(iService).name, name) == 0)
+ if (strwicmp(iSERVICE(iService).name, name) == 0)
{
if (pserviceDest != NULL)
copy_service(pserviceDest, pSERVICE(iService));
@@ -563,7 +564,7 @@ static int getservicebyname(char *name, service *pserviceDest)
Copy a service structure to another
***************************************************************************/
-static void copy_service(service *pserviceDest,
+static void copy_service(service *pserviceDest,
service *pserviceSource)
{
int i;
@@ -571,9 +572,9 @@ static void copy_service(service *pserviceDest,
for (i=0;parm_table[i].label;i++)
if (parm_table[i].ptr && parm_table[i].class == P_LOCAL) {
void *def_ptr = parm_table[i].ptr;
- void *src_ptr =
+ void *src_ptr =
((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
- void *dest_ptr =
+ void *dest_ptr =
((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
switch (parm_table[i].type)
@@ -593,7 +594,6 @@ static void copy_service(service *pserviceDest,
*(char *)dest_ptr = *(char *)src_ptr;
break;
- case P_PATH:
case P_STRING:
string_set(dest_ptr,*(char **)src_ptr);
break;
@@ -614,7 +614,6 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
int parmnum, i;
void *parm_ptr=NULL; /* where we are going to store the result */
void *def_ptr=NULL;
- char *cp;
parmnum = map_parameter(parmname);
@@ -661,15 +660,6 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
sscanf(parmvalue,"%o",(int *)parm_ptr);
break;
- case P_PATH:
- string_set(parm_ptr,parmvalue);
- if ((cp = *(char**)parm_ptr) != NULL) {
- int len = strlen(cp);
- while (len > 1 && cp[len-1] == '/') len--;
- cp[len] = '\0';
- }
- break;
-
case P_STRING:
string_set(parm_ptr,parmvalue);
break;
@@ -721,7 +711,7 @@ static BOOL do_section(char *sectionname)
init_locals();
/* if we've just struck a global section, note the fact. */
- bInGlobalSection = isglobal;
+ bInGlobalSection = isglobal;
/* check for multiple global sections */
if (bInGlobalSection)
@@ -753,7 +743,7 @@ static BOOL do_section(char *sectionname)
/***************************************************************************
-Load the services array from the services file. Return True on success,
+Load the services array from the services file. Return True on success,
False on failure.
***************************************************************************/
BOOL lp_load(char *pszFname, int globals_only)
@@ -763,11 +753,11 @@ BOOL lp_load(char *pszFname, int globals_only)
extern int am_root;
pstring n2;
BOOL bRetval;
-
+
bRetval = False;
bInGlobalSection = True;
-
+
init_globals();
if (pszFname)
@@ -780,7 +770,7 @@ BOOL lp_load(char *pszFname, int globals_only)
/* We get sections first, so have to start 'behind' to make up */
iServiceIndex = -1;
bRetval = pm_process(n2, globals_only?NULL:do_section, do_parameter);
-
+
return (bRetval);
}
@@ -804,7 +794,7 @@ int lp_number(char *name)
int iService;
for (iService = iNumServices - 1; iService >= 0; iService--)
- if (strequal(lp_name(iService), name))
+ if (strequal(lp_name(iService), name))
break;
return (iService);
diff --git a/log.c b/log.c
index 34ff6d3d..66ec1480 100644
--- a/log.c
+++ b/log.c
@@ -90,10 +90,10 @@ static struct err_list *err_list_tail;
static void err_list_add(int code, char *buf, int len)
{
struct err_list *el;
- el = (struct err_list *)malloc(sizeof(*el));
+ el = new(struct err_list);
if (!el) exit_cleanup(RERR_MALLOC);
el->next = NULL;
- el->buf = malloc(len+4);
+ el->buf = new_array(char, len+4);
if (!el->buf) exit_cleanup(RERR_MALLOC);
memcpy(el->buf+4, buf, len);
SIVAL(el->buf, 0, ((code+MPLEX_BASE)<<24) | len);
@@ -238,9 +238,9 @@ void rwrite(enum logcode code, char *buf, int len)
return;
}
- /* next, if we are a server and multiplexing is enabled,
- * pass it to the other side. */
- if (am_server && io_multiplex_write(code, buf, len)) {
+ /* next, if we are a server but not in daemon mode, and multiplexing
+ * is enabled, pass it to the other side. */
+ if (am_server && !am_daemon && io_multiplex_write(code, buf, len)) {
return;
}
@@ -250,9 +250,7 @@ void rwrite(enum logcode code, char *buf, int len)
* side because we don't want the client to see most errors for
* security reasons. We do want early messages when running daemon
* mode over a remote shell to go to the remote side; those will
- * fall through to the next case.
- * Note that this is only for the time before multiplexing is enabled.
- */
+ * fall through to the next case. */
if (am_daemon && (!am_server || log_initialised)) {
static int depth;
int priority = LOG_INFO;
@@ -572,3 +570,17 @@ void log_exit(int code, const char *file, int line)
name, code, file, line);
}
}
+
+/*
+ * Log the incoming transfer of a file for interactive use,
+ * this will be called at the end where the client was run.
+ * Called when a file starts to be transferred.
+ */
+void log_transfer(struct file_struct *file, const char *fname)
+{
+ extern int verbose;
+
+ if (!verbose) return;
+
+ rprintf(FINFO, "%s\n", fname);
+}
diff --git a/match.c b/match.c
index 926aad61..e7bd667c 100644
--- a/match.c
+++ b/match.c
@@ -1,17 +1,17 @@
-/*
+/*
Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -19,9 +19,12 @@
#include "rsync.h"
+extern int csum_length;
+
extern int verbose;
extern int am_server;
-extern int do_progress;
+
+extern int remote_version;
typedef unsigned short tag;
@@ -40,8 +43,8 @@ static int total_matches;
extern struct stats stats;
struct target {
- tag t;
- int i;
+ tag t;
+ int i;
};
static struct target *targets;
@@ -53,33 +56,34 @@ static int *tag_table;
static int compare_targets(struct target *t1,struct target *t2)
{
- return (int)t1->t - (int)t2->t;
+ return((int)t1->t - (int)t2->t);
}
static void build_hash_table(struct sum_struct *s)
{
- int i;
+ int i;
- if (!tag_table)
- tag_table = (int *)malloc(sizeof(tag_table[0])*TABLESIZE);
+ if (!tag_table)
+ tag_table = new_array(int, TABLESIZE);
- targets = (struct target *)malloc(sizeof(targets[0])*s->count);
- if (!tag_table || !targets)
- out_of_memory("build_hash_table");
+ targets = new_array(struct target, s->count);
+ if (!tag_table || !targets)
+ out_of_memory("build_hash_table");
- for (i = 0; i < (int)s->count; i++) {
- targets[i].i = i;
- targets[i].t = gettag(s->sums[i].sum1);
- }
+ for (i=0;i<(int) s->count;i++) {
+ targets[i].i = i;
+ targets[i].t = gettag(s->sums[i].sum1);
+ }
- qsort(targets,s->count,sizeof(targets[0]),(int (*)())compare_targets);
+ qsort(targets,s->count,sizeof(targets[0]),(int (*)())compare_targets);
- for (i = 0; i < TABLESIZE; i++)
- tag_table[i] = NULL_TAG;
+ for (i=0;i<TABLESIZE;i++)
+ tag_table[i] = NULL_TAG;
- for (i = s->count-1; i >= 0; i--)
- tag_table[targets[i].t] = i;
+ for (i=s->count-1;i>=0;i--) {
+ tag_table[targets[i].t] = i;
+ }
}
@@ -115,8 +119,8 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
stats.matched_data += s->sums[i].len;
n += s->sums[i].len;
}
-
- for (j = 0; j < n; j += CHUNK_SIZE) {
+
+ for (j=0;j<n;j+=CHUNK_SIZE) {
int n1 = MIN(CHUNK_SIZE,n-j);
sum_update(map_ptr(buf,last_match+j,n1),n1);
}
@@ -127,7 +131,7 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
else
last_match = offset;
- if (buf && do_progress) {
+ if (buf) {
show_progress(last_match, buf->file_size);
if (i == -1) end_progress(buf->file_size);
@@ -141,7 +145,7 @@ static void hash_search(int f,struct sum_struct *s,
OFF_T offset, end;
int j,k, last_i;
char sum2[SUM_LENGTH];
- uint32 s1, s2, sum;
+ uint32 s1, s2, sum;
schar *map;
/* last_i is used to encourage adjacent matches, allowing the RLL coding of the
@@ -150,34 +154,36 @@ static void hash_search(int f,struct sum_struct *s,
if (verbose > 2)
rprintf(FINFO,"hash search b=%ld len=%.0f\n",
- (long) s->blength, (double)len);
-
- k = MIN(len, (OFF_T)s->blength);
+ (long) s->n, (double)len);
+ /* cast is to make s->n signed; it should always be reasonably
+ * small */
+ k = MIN(len, (OFF_T) s->n);
+
map = (schar *)map_ptr(buf,0,k);
-
+
sum = get_checksum1((char *)map, k);
s1 = sum & 0xFFFF;
s2 = sum >> 16;
if (verbose > 3)
rprintf(FINFO, "sum=%.8x k=%d\n", sum, k);
-
+
offset = 0;
-
+
end = len + 1 - s->sums[s->count-1].len;
-
+
if (verbose > 3)
- rprintf(FINFO, "hash search s->blength=%ld len=%.0f count=%ld\n",
- (long) s->blength, (double) len, (long) s->count);
-
+ rprintf(FINFO, "hash search s->n=%ld len=%.0f count=%ld\n",
+ (long) s->n, (double) len, (long) s->count);
+
do {
tag t = gettag2(s1,s2);
int done_csum2 = 0;
-
+
j = tag_table[t];
if (verbose > 4)
rprintf(FINFO,"offset=%.0f sum=%08x\n",(double)offset,sum);
-
+
if (j == NULL_TAG) {
goto null_tag;
}
@@ -186,47 +192,47 @@ static void hash_search(int f,struct sum_struct *s,
tag_hits++;
for (; j < (int) s->count && targets[j].t == t; j++) {
int l, i = targets[j].i;
-
+
if (sum != s->sums[i].sum1) continue;
-
+
/* also make sure the two blocks are the same length */
- l = MIN((OFF_T)s->blength, len-offset);
- if (l != s->sums[i].len) continue;
+ l = MIN(s->n,len-offset);
+ if (l != s->sums[i].len) continue;
if (verbose > 3)
rprintf(FINFO,"potential match at %.0f target=%d %d sum=%08x\n",
(double)offset,j,i,sum);
-
+
if (!done_csum2) {
map = (schar *)map_ptr(buf,offset,l);
get_checksum2((char *)map,l,sum2);
done_csum2 = 1;
}
-
- if (memcmp(sum2,s->sums[i].sum2,s->s2length) != 0) {
+
+ if (memcmp(sum2,s->sums[i].sum2,csum_length) != 0) {
false_alarms++;
continue;
}
/* we've found a match, but now check to see
- * if last_i can hint at a better match */
+ if last_i can hint at a better match */
for (j++; j < (int) s->count && targets[j].t == t; j++) {
int i2 = targets[j].i;
if (i2 == last_i + 1) {
if (sum != s->sums[i2].sum1) break;
- if (memcmp(sum2,s->sums[i2].sum2,s->s2length) != 0) break;
- /* we've found an adjacent match - the RLL coder
- * will be happy */
+ if (memcmp(sum2,s->sums[i2].sum2,csum_length) != 0) break;
+ /* we've found an adjacent match - the RLL coder
+ will be happy */
i = i2;
break;
}
}
last_i = i;
-
+
matched(f,s,buf,offset,i);
offset += s->sums[i].len - 1;
- k = MIN((OFF_T)s->blength, len-offset);
+ k = MIN((len-offset), s->n);
map = (schar *)map_ptr(buf,offset,k);
sum = get_checksum1((char *)map, k);
s1 = sum & 0xFFFF;
@@ -234,13 +240,13 @@ static void hash_search(int f,struct sum_struct *s,
matches++;
break;
}
-
+
null_tag:
/* Trim off the first byte from the checksum */
map = (schar *)map_ptr(buf,offset,k+1);
s1 -= map[0] + CHAR_OFFSET;
s2 -= k * (map[0]+CHAR_OFFSET);
-
+
/* Add on the next byte (if there is one) to the checksum */
if (k < (len-offset)) {
s1 += (map[k]+CHAR_OFFSET);
@@ -255,13 +261,13 @@ static void hash_search(int f,struct sum_struct *s,
match. The 3 reads are caused by the
running match, the checksum update and the
literal send. */
- if (offset > last_match
- && offset-last_match >= CHUNK_SIZE+s->blength
- && end-offset > CHUNK_SIZE) {
- matched(f,s,buf,offset - s->blength, -2);
+ if (offset > last_match &&
+ offset-last_match >= CHUNK_SIZE+s->n &&
+ (end-offset > CHUNK_SIZE)) {
+ matched(f,s,buf,offset - s->n, -2);
}
} while (++offset < end);
-
+
matched(f,s,buf,len,-1);
map_ptr(buf,len-1,1);
}
@@ -289,25 +295,25 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
last_match = 0;
false_alarms = 0;
tag_hits = 0;
- matches = 0;
- data_transfer = 0;
+ matches=0;
+ data_transfer=0;
sum_init();
if (len > 0 && s->count>0) {
build_hash_table(s);
-
- if (verbose > 2)
+
+ if (verbose > 2)
rprintf(FINFO,"built hash table\n");
-
+
hash_search(f,s,buf,len);
-
- if (verbose > 2)
+
+ if (verbose > 2)
rprintf(FINFO,"done hash search\n");
} else {
OFF_T j;
/* by doing this in pieces we avoid too many seeks */
- for (j = 0; j < len-CHUNK_SIZE; j += CHUNK_SIZE) {
+ for (j=0;j<(len-CHUNK_SIZE);j+=CHUNK_SIZE) {
int n1 = MIN(CHUNK_SIZE,(len-CHUNK_SIZE)-j);
matched(f,s,buf,j+n1,-2);
}
@@ -316,21 +322,23 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
sum_end(file_sum);
- if (verbose > 2)
- rprintf(FINFO,"sending file_sum\n");
- write_buf(f,file_sum,MD4_SUM_LENGTH);
- if (write_batch) /* dw */
- write_batch_delta_file(file_sum, MD4_SUM_LENGTH);
+ if (remote_version >= 14) {
+ if (verbose > 2)
+ rprintf(FINFO,"sending file_sum\n");
+ write_buf(f,file_sum,MD4_SUM_LENGTH);
+ if (write_batch) /* dw */
+ write_batch_delta_file(file_sum, MD4_SUM_LENGTH);
+ }
if (targets) {
free(targets);
targets=NULL;
}
-
+
if (verbose > 2)
rprintf(FINFO, "false_alarms=%d tag_hits=%d matches=%d\n",
false_alarms, tag_hits, matches);
-
+
total_tag_hits += tag_hits;
total_false_alarms += false_alarms;
total_matches += matches;
diff --git a/params.c b/params.c
index 81638118..56a2a914 100644
--- a/params.c
+++ b/params.c
@@ -207,7 +207,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
if( i > (bSize - 2) )
{
bSize += BUFR_INC;
- bufr = Realloc( bufr, bSize );
+ bufr = realloc_array( bufr, char, bSize );
if( NULL == bufr )
{
rprintf(FERROR, "%s Memory re-allocation failure.", func);
@@ -301,7 +301,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
if( i > (bSize - 2) ) /* Ensure there's space for next char. */
{
bSize += BUFR_INC;
- bufr = Realloc( bufr, bSize );
+ bufr = realloc_array( bufr, char, bSize );
if( NULL == bufr )
{
rprintf(FERROR, "%s Memory re-allocation failure.", func) ;
@@ -366,7 +366,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
if( i > (bSize - 2) ) /* Make sure there's enough room. */
{
bSize += BUFR_INC;
- bufr = Realloc( bufr, bSize );
+ bufr = realloc_array( bufr, char, bSize );
if( NULL == bufr )
{
rprintf(FERROR, "%s Memory re-allocation failure.", func) ;
@@ -530,7 +530,7 @@ BOOL pm_process( char *FileName,
else /* If we don't have a buffer */
{ /* allocate one, then parse, */
bSize = BUFR_INC; /* then free. */
- bufr = (char *)malloc( bSize );
+ bufr = new_array( char, bSize );
if( NULL == bufr )
{
rprintf(FERROR,"%s memory allocation failure.\n", func);
diff --git a/receiver.c b/receiver.c
index 13a62948..030d32c5 100644
--- a/receiver.c
+++ b/receiver.c
@@ -23,7 +23,7 @@
extern int verbose;
extern int recurse;
extern int delete_mode;
-extern int protocol_version;
+extern int remote_version;
extern int csum_length;
extern struct stats stats;
extern int dry_run;
@@ -35,10 +35,7 @@ extern int io_error;
extern char *tmpdir;
extern char *compare_dest;
extern int make_backups;
-extern int do_progress;
-extern char *backup_dir;
extern char *backup_suffix;
-extern int backup_suffix_len;
static struct delete_list {
DEV64_T dev;
@@ -59,7 +56,7 @@ static int delete_already_done(struct file_list *flist,int j)
for (i=0;i<dlist_len;i++) {
if (st.st_ino == delete_list[i].inode &&
- (DEV64_T)st.st_dev == delete_list[i].dev)
+ st.st_dev == delete_list[i].dev)
return 1;
}
@@ -70,7 +67,8 @@ static void add_delete_entry(struct file_struct *file)
{
if (dlist_len == dlist_alloc_len) {
dlist_alloc_len += 1024;
- delete_list = (struct delete_list *)Realloc(delete_list, sizeof(delete_list[0])*dlist_alloc_len);
+ delete_list = realloc_array(delete_list, struct delete_list,
+ dlist_alloc_len);
if (!delete_list) out_of_memory("add_delete_entry");
}
@@ -82,33 +80,26 @@ static void add_delete_entry(struct file_struct *file)
rprintf(FINFO,"added %s to delete list\n", f_name(file));
}
-static void delete_one(char *fn, int is_dir)
+static void delete_one(struct file_struct *f)
{
- if (!is_dir) {
- if (robust_unlink(fn) != 0) {
- rprintf(FERROR, "delete_one: unlink %s failed: %s\n",
- full_fname(fn), strerror(errno));
+ if (!S_ISDIR(f->mode)) {
+ if (robust_unlink(f_name(f)) != 0) {
+ rprintf(FERROR,"delete_one: unlink %s: %s\n",f_name(f),strerror(errno));
} else if (verbose) {
- rprintf(FINFO, "deleting %s\n", fn);
+ rprintf(FINFO,"deleting %s\n",f_name(f));
}
} else {
- if (do_rmdir(fn) != 0) {
- if (errno != ENOTEMPTY && errno != EEXIST) {
- rprintf(FERROR, "delete_one: rmdir %s failed: %s\n",
- full_fname(fn), strerror(errno));
- }
+ if (do_rmdir(f_name(f)) != 0) {
+ if (errno != ENOTEMPTY && errno != EEXIST)
+ rprintf(FERROR,"delete_one: rmdir %s: %s\n",
+ f_name(f), strerror(errno));
} else if (verbose) {
- rprintf(FINFO, "deleting directory %s\n", fn);
+ rprintf(FINFO,"deleting directory %s\n",f_name(f));
}
}
}
-static int is_backup_file(char *fn)
-{
- int k = strlen(fn) - backup_suffix_len;
- return k > 0 && strcmp(fn+k, backup_suffix) == 0;
-}
/* this deletes any files on the receiving side that are not present
@@ -136,7 +127,7 @@ void delete_files(struct file_list *flist)
if (!S_ISDIR(flist->files[j]->mode) ||
!(flist->files[j]->flags & FLAG_DELETE)) continue;
- if (protocol_version < 19 &&
+ if (remote_version < 19 &&
delete_already_done(flist, j)) continue;
name = strdup(f_name(flist->files[j]));
@@ -152,20 +143,20 @@ void delete_files(struct file_list *flist)
for (i=local_file_list->count-1;i>=0;i--) {
if (max_delete && deletion_count > max_delete) break;
if (!local_file_list->files[i]->basename) continue;
- if (protocol_version < 19 &&
+ 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])) {
char *f = f_name(local_file_list->files[i]);
- if (make_backups && (backup_dir || !is_backup_file(f))) {
+ int k = strlen(f) - strlen(backup_suffix);
+/* Hi Andrew, do we really need to play with backup_suffix here? */
+ if (make_backups && ((k <= 0) ||
+ (strcmp(f+k,backup_suffix) != 0))) {
(void) make_backup(f);
- if (verbose)
- rprintf(FINFO, "deleting %s\n", f);
} else {
- int mode = local_file_list->files[i]->mode;
- delete_one(f, S_ISDIR(mode) != 0);
+ deletion_count++;
+ delete_one(local_file_list->files[i]);
}
- deletion_count++;
}
}
flist_free(local_file_list);
@@ -174,63 +165,40 @@ void delete_files(struct file_list *flist)
}
-/*
- * get_tmpname() - create a tmp filename for a given filename
- *
- * If a tmpdir is defined, use that as the directory to
- * put it in. Otherwise, the tmp filename is in the same
- * directory as the given name. Note that there may be no
- * directory at all in the given name!
- *
- * The tmp filename is basically the given filename with a
- * dot prepended, and .XXXXXX appended (for mkstemp() to
- * put its unique gunk in). Take care to not exceed
- * either the MAXPATHLEN or NAME_MAX, esp. the last, as
- * the basename basically becomes 8 chars longer. In that
- * case, the original name is shortened sufficiently to
- * make it all fit.
- *
- * Of course, there's no real reason for the tmp name to
- * look like the original, except to satisfy us humans.
- * As long as it's unique, rsync will work.
- */
-
static int get_tmpname(char *fnametmp, char *fname)
{
char *f;
- int length = 0;
- int maxname;
+ /* open tmp file */
if (tmpdir) {
- strlcpy(fnametmp, tmpdir, MAXPATHLEN - 2);
- length = strlen(fnametmp);
- fnametmp[length++] = '/';
- fnametmp[length] = '\0'; /* always NULL terminated */
- }
-
- if ((f = strrchr(fname, '/')) != NULL) {
- ++f;
- if (!tmpdir) {
- length = f - fname;
- /* copy up to and including the slash */
- strlcpy(fnametmp, fname, length + 1);
+ 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;
}
- } else {
- f = fname;
+ snprintf(fnametmp,MAXPATHLEN, "%s/.%s.XXXXXX",tmpdir,f);
+ return 1;
}
- fnametmp[length++] = '.';
- fnametmp[length] = '\0'; /* always NULL terminated */
- maxname = MIN(MAXPATHLEN - 7 - length, NAME_MAX - 8);
+ f = strrchr(fname,'/');
- if (maxname < 1) {
- rprintf(FERROR, "temporary filename too long: %s\n", fname);
- fnametmp[0] = '\0';
+ if (strlen(fname)+9 > MAXPATHLEN) {
+ rprintf(FERROR,"filename too long\n");
return 0;
}
- strlcpy(fnametmp + length, f, maxname);
- strcat(fnametmp + length, ".XXXXXX");
+ if (f) {
+ *f = 0;
+ snprintf(fnametmp,MAXPATHLEN,"%s/.%s.XXXXXX",
+ fname,f+1);
+ *f = '/';
+ } else {
+ snprintf(fnametmp,MAXPATHLEN,".%s.XXXXXX",fname);
+ }
return 1;
}
@@ -240,8 +208,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
OFF_T total_size)
{
int i;
- struct sum_struct sum;
- unsigned int len;
+ unsigned int n,remainder,len,count;
OFF_T offset = 0;
OFF_T offset2;
char *data;
@@ -249,13 +216,15 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
static char file_sum2[MD4_SUM_LENGTH];
char *map=NULL;
- read_sum_head(f_in, &sum);
+ count = read_int(f_in);
+ n = read_int(f_in);
+ remainder = read_int(f_in);
sum_init();
for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) {
- if (do_progress)
- show_progress(offset, total_size);
+
+ show_progress(offset, total_size);
if (i > 0) {
extern int cleanup_got_literal;
@@ -271,8 +240,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
sum_update(data,i);
if (fd != -1 && write_file(fd,data,i) != i) {
- rprintf(FERROR, "write failed on %s: %s\n",
- full_fname(fname), strerror(errno));
+ rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
exit_cleanup(RERR_FILEIO);
}
offset += i;
@@ -280,10 +248,10 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
}
i = -(i+1);
- offset2 = i*(OFF_T)sum.blength;
- len = sum.blength;
- if (i == (int) sum.count-1 && sum.remainder != 0)
- len = sum.remainder;
+ offset2 = i*(OFF_T)n;
+ len = n;
+ if (i == (int) count-1 && remainder != 0)
+ len = remainder;
stats.matched_data += len;
@@ -299,31 +267,32 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
}
if (fd != -1 && write_file(fd,map,len) != (int) len) {
- rprintf(FERROR, "write failed on %s: %s\n",
- full_fname(fname), strerror(errno));
+ rprintf(FERROR,"write failed on %s : %s\n",
+ fname,strerror(errno));
exit_cleanup(RERR_FILEIO);
}
offset += len;
}
- if (do_progress)
- end_progress(total_size);
+ end_progress(total_size);
if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
- rprintf(FERROR, "write failed on %s: %s\n",
- full_fname(fname), strerror(errno));
+ rprintf(FERROR,"write failed on %s : %s\n",
+ fname,strerror(errno));
exit_cleanup(RERR_FILEIO);
}
sum_end(file_sum1);
- read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
- if (verbose > 2) {
- rprintf(FINFO,"got file_sum\n");
- }
- if (fd != -1
- && memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0) {
- return 0;
+ if (remote_version >= 14) {
+ read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
+ if (verbose > 2) {
+ rprintf(FINFO,"got file_sum\n");
+ }
+ if (fd != -1 &&
+ memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0) {
+ return 0;
+ }
}
return 1;
}
@@ -362,7 +331,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
i = read_int(f_in);
if (i == -1) {
- if (phase==0) {
+ if (phase==0 && remote_version >= 13) {
phase++;
csum_length = SUM_LENGTH;
if (verbose > 2)
@@ -389,8 +358,8 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
fname = local_name;
if (dry_run) {
- if (!am_server && verbose) { /* log transfer */
- rprintf(FINFO, "%s\n", fname);
+ if (!am_server) {
+ log_transfer(file, fname);
}
continue;
}
@@ -414,35 +383,22 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
}
if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
- rprintf(FERROR, "fstat %s failed: %s\n",
- full_fname(fnamecmp), strerror(errno));
+ rprintf(FERROR,"fstat %s : %s\n",fnamecmp,strerror(errno));
receive_data(f_in,NULL,-1,NULL,file->length);
close(fd1);
continue;
}
- if (fd1 != -1 && S_ISDIR(st.st_mode) && fnamecmp == fname) {
- /* this special handling for directories
- * wouldn't be necessary if robust_rename()
- * and the underlying robust_unlink could cope
- * with directories
- */
- rprintf(FERROR,"recv_files: %s is a directory\n",
- full_fname(fnamecmp));
- receive_data(f_in, NULL, -1, NULL, file->length);
- close(fd1);
- continue;
- }
-
if (fd1 != -1 && !S_ISREG(st.st_mode)) {
+ rprintf(FERROR,"%s : not a regular file (recv_files)\n",fnamecmp);
+ receive_data(f_in,NULL,-1,NULL,file->length);
close(fd1);
- fd1 = -1;
- buf = NULL;
+ continue;
}
if (fd1 != -1 && !preserve_perms) {
- /* if the file exists already and we aren't preserving
- permissions then act as though the remote end sent
+ /* if the file exists already and we aren't perserving
+ presmissions then act as though the remote end sent
us the file permissions we already have */
file->mode = st.st_mode;
}
@@ -480,8 +436,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
}
if (fd2 == -1) {
- rprintf(FERROR, "mkstemp %s failed: %s\n",
- full_fname(fnametmp), strerror(errno));
+ rprintf(FERROR,"mkstemp %s failed: %s\n",fnametmp,strerror(errno));
receive_data(f_in,buf,-1,NULL,file->length);
if (buf) unmap_file(buf);
if (fd1 != -1) close(fd1);
@@ -490,8 +445,8 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
cleanup_set(fnametmp, fname, file, buf, fd1, fd2);
- if (!am_server && verbose) { /* log transfer */
- rprintf(FINFO, "%s\n", fname);
+ if (!am_server) {
+ log_transfer(file, fname);
}
/* recv file data */
@@ -515,7 +470,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
if (!recv_ok) {
if (csum_length == SUM_LENGTH) {
rprintf(FERROR,"ERROR: file corruption in %s. File changed during transfer?\n",
- full_fname(fname));
+ fname);
} else {
if (verbose > 1)
rprintf(FINFO,"redoing %s(%d)\n",fname,i);
diff --git a/rsync.c b/rsync.c
index 36d7b8b1..4e95965d 100644
--- a/rsync.c
+++ b/rsync.c
@@ -1,17 +1,17 @@
-/*
+/*
Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -43,8 +43,8 @@ void free_sums(struct sum_struct *s)
/*
- * delete a file or directory. If force_delete is set then delete
- * recursively
+ * delete a file or directory. If force_delete is set then delete
+ * recursively
*/
int delete_file(char *fname)
{
@@ -67,31 +67,29 @@ int delete_file(char *fname)
if (!S_ISDIR(st.st_mode)) {
if (robust_unlink(fname) == 0 || errno == ENOENT) return 0;
- rprintf(FERROR, "delete_file: unlink %s failed: %s\n",
- full_fname(fname), strerror(errno));
+ rprintf(FERROR,"delete_file: unlink(%s) : %s\n", fname, strerror(errno));
return -1;
}
if (do_rmdir(fname) == 0 || errno == ENOENT) return 0;
- if (!force_delete || !recurse ||
+ if (!force_delete || !recurse ||
(errno != ENOTEMPTY && errno != EEXIST)) {
- rprintf(FERROR, "delete_file: rmdir %s failed: %s\n",
- full_fname(fname), strerror(errno));
+ rprintf(FERROR,"delete_file: rmdir(%s) : %s\n", fname, strerror(errno));
return -1;
}
/* now we do a recsursive delete on the directory ... */
d = opendir(fname);
if (!d) {
- rprintf(FERROR, "delete_file: opendir %s failed: %s\n",
- full_fname(fname), strerror(errno));
+ rprintf(FERROR,"delete_file: opendir(%s): %s\n",
+ fname,strerror(errno));
return -1;
}
- for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) {
+ for (di=readdir(d); di; di=readdir(d)) {
char *dname = d_name(di);
- if (strcmp(dname,".") == 0
- || strcmp(dname,"..") == 0)
+ if (strcmp(dname,".")==0 ||
+ strcmp(dname,"..")==0)
continue;
snprintf(buf, sizeof(buf), "%s/%s", fname, dname);
if (verbose > 0)
@@ -100,19 +98,12 @@ int delete_file(char *fname)
closedir(d);
return -1;
}
- }
- if (errno) {
- rprintf(FERROR, "delete_file: readdir %s failed: %s\n",
- full_fname(fname), strerror(errno));
- closedir(d);
- return -1;
- }
+ }
closedir(d);
-
+
if (do_rmdir(fname) != 0) {
- rprintf(FERROR, "delete_file: rmdir %s failed: %s\n",
- full_fname(fname), strerror(errno));
+ rprintf(FERROR,"delete_file: rmdir(%s) : %s\n", fname, strerror(errno));
return -1;
}
@@ -133,7 +124,7 @@ static int is_in_group(gid_t gid)
/* treat failure (-1) as if not member of any group */
ngroups = getgroups(0, 0);
if (ngroups > 0) {
- gidset = (GETGROUPS_T *) malloc(ngroups * sizeof(GETGROUPS_T));
+ gidset = new_array(GETGROUPS_T, ngroups);
ngroups = getgroups(ngroups, gidset);
}
}
@@ -154,7 +145,7 @@ static int is_in_group(gid_t gid)
}
int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
- int report)
+ int report)
{
int updated = 0;
STRUCT_STAT st2;
@@ -164,8 +155,7 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
if (!st) {
if (link_stat(fname,&st2) != 0) {
- rprintf(FERROR, "stat %s failed: %s\n",
- full_fname(fname), strerror(errno));
+ rprintf(FERROR,"stat %s : %s\n",fname,strerror(errno));
return 0;
}
st = &st2;
@@ -177,8 +167,8 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
because some filesystems can't do it */
if (set_modtime(fname,file->modtime) != 0 &&
!S_ISDIR(st->st_mode)) {
- rprintf(FERROR, "failed to set times on %s: %s\n",
- full_fname(fname), strerror(errno));
+ rprintf(FERROR,"failed to set times on %s : %s\n",
+ fname,strerror(errno));
return 0;
} else {
updated = 1;
@@ -199,8 +189,7 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
change_gid?file->gid:st->st_gid) != 0) {
/* shouldn't have attempted to change uid or gid
unless have the privilege */
- rprintf(FERROR, "chown %s failed: %s\n",
- full_fname(fname), strerror(errno));
+ rprintf(FERROR,"chown %s : %s\n", fname,strerror(errno));
return 0;
}
/* a lchown had been done - we have to re-stat if the
@@ -214,17 +203,17 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
#ifdef HAVE_CHMOD
if (!S_ISLNK(st->st_mode)) {
- if ((st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS)) {
+ if (st->st_mode != file->mode) {
updated = 1;
- if (do_chmod(fname,(file->mode & CHMOD_BITS)) != 0) {
- rprintf(FERROR, "failed to set permissions on %s: %s\n",
- full_fname(fname), strerror(errno));
+ if (do_chmod(fname,file->mode) != 0) {
+ rprintf(FERROR,"failed to set permissions on %s : %s\n",
+ fname,strerror(errno));
return 0;
}
}
}
#endif
-
+
if (verbose > 1 && report) {
if (updated)
rprintf(FINFO,"%s\n",fname);
@@ -251,18 +240,17 @@ void finish_transfer(char *fname, char *fnametmp, struct file_struct *file)
/* move tmp file over real file */
if (robust_rename(fnametmp,fname) != 0) {
if (errno == EXDEV) {
- /* rename failed on cross-filesystem link.
+ /* rename failed on cross-filesystem link.
Copy the file instead. */
if (copy_file(fnametmp,fname, file->mode & INITACCESSPERMS)) {
- rprintf(FERROR, "copy %s -> \"%s\": %s\n",
- full_fname(fnametmp), fname,
- strerror(errno));
+ rprintf(FERROR,"copy %s -> %s : %s\n",
+ fnametmp,fname,strerror(errno));
} else {
set_perms(fname,file,NULL,0);
}
} else {
- rprintf(FERROR,"rename %s -> \"%s\": %s\n",
- full_fname(fnametmp), fname, strerror(errno));
+ rprintf(FERROR,"rename %s -> %s : %s\n",
+ fnametmp,fname,strerror(errno));
}
do_unlink(fnametmp);
} else {
diff --git a/rsync.h b/rsync.h
index 21a19884..46c74b99 100644
--- a/rsync.h
+++ b/rsync.h
@@ -50,28 +50,20 @@
#define SAME_TIME (1<<7)
/* update this if you make incompatible changes */
-#define PROTOCOL_VERSION 27
+#define PROTOCOL_VERSION 26
/* We refuse to interoperate with versions that are not in this range.
* Note that we assume we'll work with later versions: the onus is on
* people writing them to make sure that they don't send us anything
* we won't understand.
*
- * Interoperation with old but supported protocol versions
- * should cause a warning to be printed. At a future date
- * the old protocol will become the minimum and
- * compatibility code removed.
- *
- * There are two possible explanations for the limit at
- * MAX_PROTOCOL_VERSION: either to allow new major-rev versions that
- * do not interoperate with us, and (more likely) so that we can
- * detect an attempt to connect rsync to a non-rsync server, which is
- * unlikely to begin by sending a byte between MIN_PROTOCL_VERSION and
- * MAX_PROTOCOL_VERSION. */
-
-#define MIN_PROTOCOL_VERSION 17
-#define OLD_PROTOCOL_VERSION 20
-#define MAX_PROTOCOL_VERSION 40
+ * There are two possible explanations for the limit at thirty: either
+ * to allow new major-rev versions that do not interoperate with us,
+ * and (more likely) so that we can detect an attempt to connect rsync
+ * to a non-rsync server, which is unlikely to begin by sending a byte
+ * between 15 and 30. */
+#define MIN_PROTOCOL_VERSION 15
+#define MAX_PROTOCOL_VERSION 30
#define RSYNC_PORT 873
@@ -85,16 +77,6 @@
#define MPLEX_BASE 7
-#define NO_EXCLUDES 0
-#define SERVER_EXCLUDES 1
-#define ALL_EXCLUDES 2
-
-#define MISSING_OK 0
-#define MISSING_FATAL 1
-
-#define ADD_INCLUDE 1
-#define ADD_EXCLUDE 0
-
/* Log values. I *think* what these mean is: FLOG goes to the server
* logfile; FERROR and FINFO try to end up on the client, with
* different levels of filtering. */
@@ -124,10 +106,6 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
#include <stdlib.h>
#endif
-#if defined(HAVE_MALLOC_H) && (defined(HAVE_MALLINFO) || !defined(HAVE_STDLIB_H))
-#include <malloc.h>
-#endif
-
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
@@ -136,6 +114,10 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
#include <string.h>
#endif
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
@@ -192,10 +174,20 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
#endif
#endif
+#ifdef HAVE_FNMATCH
+#include <fnmatch.h>
+#else
+#include "lib/fnmatch.h"
+#endif
+
#ifdef HAVE_GLOB_H
#include <glob.h>
#endif
+#ifdef HAVE_MALLOC_H
+# include <malloc.h>
+#endif
+
/* these are needed for the uid/gid mapping code */
#include <pwd.h>
#include <grp.h>
@@ -281,17 +273,6 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
#define NO_INT64
#endif
-#if (SIZEOF_LONG == 8)
-#define uint64 unsigned long
-#elif (SIZEOF_INT == 8)
-#define uint64 unsigned int
-#elif HAVE_LONGLONG
-#define uint64 unsigned long long
-#else
-/* As long as it gets... */
-#define uint64 unsigned off_t
-#endif
-
/* Starting from protocol version 26, we always use 64-bit
* ino_t and dev_t internally, even if this platform does not
* allow files to have 64-bit inums. That's because the
@@ -323,8 +304,8 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
* cope with platforms on which this is an unsigned int or even a
* struct. Later.
*/
-#define INO64_T uint64
-#define DEV64_T uint64
+#define INO64_T int64
+#define DEV64_T int64
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
@@ -341,17 +322,11 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
/* the length of the md4 checksum */
#define MD4_SUM_LENGTH 16
#define SUM_LENGTH 16
-#define SHORT_SUM_LENGTH 2
-#define BLOCKSUM_BIAS 10
#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
#endif
-#ifndef NAME_MAX
-#define NAME_MAX 255
-#endif
-
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif
@@ -410,35 +385,23 @@ struct sum_struct {
OFF_T flength; /**< total file length */
size_t count; /**< how many chunks */
size_t remainder; /**< flength % block_length */
- size_t blength; /**< block_length */
- size_t s2length; /**< sum2_length */
+ size_t n; /**< block_length */
struct sum_buf *sums; /**< points to info for each chunk */
};
struct map_struct {
- char *p; /* Window pointer */
- int fd; /* File Descriptor */
- int p_size; /* Window size at allocation */
- int p_len; /* Window size after fill */
- /* p_size and p_len could be
- * consolodated by using a local
- * variable in map_ptr() */
- int status; /* first errno from read errors */
- OFF_T file_size; /* File size (from stat) */
- OFF_T p_offset; /* Window start */
- OFF_T p_fd_offset; /* offset of cursor in fd ala lseek */
+ char *p;
+ int fd,p_size,p_len;
+ OFF_T file_size, p_offset, p_fd_offset;
};
-#define MATCHFLG_WILD 0x0001 /* pattern has '*', '[', and/or '?' */
-#define MATCHFLG_WILD2 0x0002 /* pattern has '**' */
-#define MATCHFLG_WILD2_PREFIX 0x0004 /* pattern starts with '**' */
-#define MATCHFLG_ABS_PATH 0x0008 /* path-match on absolute path */
struct exclude_struct {
char *pattern;
- int match_flags;
+ int regular_exp;
+ int fnmatch_flags;
int include;
int directory;
- int slash_cnt;
+ int local;
};
struct stats {
@@ -465,7 +428,6 @@ static inline int flist_up(struct file_list *flist, int i)
#include "byteorder.h"
#include "lib/mdfour.h"
-#include "lib/wildmatch.h"
#include "lib/permstring.h"
#include "lib/addrinfo.h"
@@ -480,13 +442,11 @@ int asprintf(char **ptr, const char *format, ...);
int vasprintf(char **ptr, const char *format, va_list ap);
#endif
-#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
-#define vsnprintf rsync_vsnprintf
-int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
+#if !defined(HAVE_VSNPRINTF) && !defined(HAVE_C99_VSNPRINTF)
+int vsnprintf (char *str, size_t count, const char *fmt, va_list args);
#endif
-#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
-#define snprintf rsync_snprintf
+#if !defined(HAVE_SNPRINTF) && !defined(HAVE_C99_VSNPRINTF)
int snprintf(char *str,size_t count,const char *fmt,...);
#endif
@@ -537,16 +497,6 @@ extern int errno;
#define S_IWUSR 0200
#endif
-#ifndef ACCESSPERMS
-#define ACCESSPERMS 0777
-#endif
-
-#ifndef S_ISVTX
-#define S_ISVTX 0
-#endif
-
-#define CHMOD_BITS (S_ISUID | S_ISGID | S_ISVTX | ACCESSPERMS)
-
#ifndef _S_IFMT
#define _S_IFMT 0170000
#endif
@@ -610,6 +560,9 @@ extern int errno;
#define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode) || S_ISFIFO(mode))
+#ifndef ACCESSPERMS
+#define ACCESSPERMS 0777
+#endif
/* Initial mask on permissions given to temporary files. Mask off setuid
bits and group access because of potential race-condition security
holes, and mask other access because mode 707 is bizarre */
@@ -626,6 +579,10 @@ extern int errno;
#endif
+/* Convenient wrappers for malloc and realloc. Use them. */
+#define new(type) ((type *)malloc(sizeof(type)))
+#define new_array(type, num) ((type *)_new_array(sizeof(type), (num)))
+#define realloc_array(ptr, type, num) ((type *)_realloc_array((ptr), sizeof(type), (num)))
/* use magic gcc attributes to catch format errors */
void rprintf(enum logcode , const char *, ...)
@@ -642,10 +599,6 @@ void rsyserr(enum logcode, int, const char *, ...)
#define inet_ntoa rep_inet_ntoa
#endif
-/* Make sure that the O_BINARY flag is defined. */
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
#ifndef HAVE_STRLCPY
size_t strlcpy(char *d, const char *s, size_t bufsize);
diff --git a/sender.c b/sender.c
index 3d390526..001ab003 100644
--- a/sender.c
+++ b/sender.c
@@ -1,17 +1,17 @@
-/*
+/*
Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -20,6 +20,7 @@
#include "rsync.h"
extern int verbose;
+extern int remote_version;
extern int csum_length;
extern struct stats stats;
extern int io_error;
@@ -36,19 +37,6 @@ extern int am_server;
**/
-void read_sum_head(int f, struct sum_struct *sum)
-{
- extern int protocol_version;
-
- sum->count = read_int(f);
- sum->blength = read_int(f);
- if (protocol_version < 27)
- sum->s2length = csum_length;
- else
- sum->s2length = read_int(f);
- sum->remainder = read_int(f);
-}
-
/**
* Receive the checksums for a buffer
**/
@@ -58,27 +46,27 @@ static struct sum_struct *receive_sums(int f)
int i;
OFF_T offset = 0;
- s = (struct sum_struct *)malloc(sizeof(*s));
+ s = new(struct sum_struct);
if (!s) out_of_memory("receive_sums");
- read_sum_head(f, s);
-
+ s->count = read_int(f);
+ s->n = read_int(f);
+ s->remainder = read_int(f);
s->sums = NULL;
if (verbose > 3)
- rprintf(FINFO, "count=%ld n=%ld rem=%ld\n",
- (long) s->count, (long) s->blength,
- (long) s->remainder);
+ rprintf(FINFO,"count=%ld n=%ld rem=%ld\n",
+ (long) s->count, (long) s->n, (long) s->remainder);
- if (s->count == 0)
+ if (s->count == 0)
return(s);
- s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
+ s->sums = new_array(struct sum_buf, s->count);
if (!s->sums) out_of_memory("receive_sums");
- for (i = 0; i < (int) s->count; i++) {
+ for (i=0; i < (int) s->count;i++) {
s->sums[i].sum1 = read_int(f);
- read_buf(f, s->sums[i].sum2, s->s2length);
+ read_buf(f,s->sums[i].sum2,csum_length);
s->sums[i].offset = offset;
s->sums[i].i = i;
@@ -86,13 +74,13 @@ static struct sum_struct *receive_sums(int f)
if (i == (int) s->count-1 && s->remainder != 0) {
s->sums[i].len = s->remainder;
} else {
- s->sums[i].len = s->blength;
+ s->sums[i].len = s->n;
}
offset += s->sums[i].len;
if (verbose > 3)
- rprintf(FINFO, "chunk[%d] len=%d offset=%.0f sum1=%08x\n",
- i, s->sums[i].len, (double)s->sums[i].offset, s->sums[i].sum1);
+ rprintf(FINFO,"chunk[%d] len=%d offset=%.0f sum1=%08x\n",
+ i,s->sums[i].len,(double)s->sums[i].offset,s->sums[i].sum1);
}
s->flength = offset;
@@ -102,17 +90,17 @@ static struct sum_struct *receive_sums(int f)
-void send_files(struct file_list *flist, int f_out, int f_in)
-{
+void send_files(struct file_list *flist,int f_out,int f_in)
+{
int fd = -1;
struct sum_struct *s;
struct map_struct *buf = NULL;
STRUCT_STAT st;
- char fname[MAXPATHLEN];
+ char fname[MAXPATHLEN];
int i;
struct file_struct *file;
int phase = 0;
- extern struct stats stats;
+ extern struct stats stats;
struct stats initial_stats;
extern int write_batch; /* dw */
extern int read_batch; /* dw */
@@ -123,26 +111,26 @@ void send_files(struct file_list *flist, int f_out, int f_in)
int done; /* dw */
if (verbose > 2)
- rprintf(FINFO, "send_files starting\n");
+ rprintf(FINFO,"send_files starting\n");
while (1) {
- int offset = 0;
+ int offset=0;
i = read_int(f_in);
if (i == -1) {
- if (phase == 0) {
+ if (phase==0 && remote_version >= 13) {
phase++;
csum_length = SUM_LENGTH;
- write_int(f_out, -1);
+ write_int(f_out,-1);
if (verbose > 2)
- rprintf(FINFO, "send_files phase=%d\n", phase);
+ rprintf(FINFO,"send_files phase=%d\n",phase);
continue;
}
break;
}
if (i < 0 || i >= flist->count) {
- rprintf(FERROR, "Invalid file index %d (count=%d)\n",
+ rprintf(FERROR,"Invalid file index %d (count=%d)\n",
i, flist->count);
exit_cleanup(RERR_PROTOCOL);
}
@@ -154,26 +142,26 @@ void send_files(struct file_list *flist, int f_out, int f_in)
fname[0] = 0;
if (file->basedir) {
- strlcpy(fname, file->basedir, MAXPATHLEN);
+ strlcpy(fname,file->basedir,MAXPATHLEN);
if (strlen(fname) == MAXPATHLEN-1) {
io_error = 1;
rprintf(FERROR, "send_files failed on long-named directory %s\n",
- full_fname(fname));
+ fname);
return;
}
- strlcat(fname, "/", MAXPATHLEN);
+ strlcat(fname,"/",MAXPATHLEN);
offset = strlen(file->basedir)+1;
}
- strlcat(fname, f_name(file), MAXPATHLEN);
-
- if (verbose > 2)
- rprintf(FINFO, "send_files(%d, %s)\n", i, fname);
-
- if (dry_run) {
- if (!am_server && verbose) { /* log transfer */
- rprintf(FINFO, "%s\n", fname+offset);
+ strlcat(fname,f_name(file),MAXPATHLEN);
+
+ if (verbose > 2)
+ rprintf(FINFO,"send_files(%d,%s)\n",i,fname);
+
+ if (dry_run) {
+ if (!am_server) {
+ log_transfer(file, fname+offset);
}
- write_int(f_out, i);
+ write_int(f_out,i);
continue;
}
@@ -182,130 +170,128 @@ void send_files(struct file_list *flist, int f_out, int f_in)
s = receive_sums(f_in);
if (!s) {
io_error = 1;
- rprintf(FERROR, "receive_sums failed\n");
+ rprintf(FERROR,"receive_sums failed\n");
return;
}
if (write_batch)
- write_batch_csum_info(&i, flist->count, s);
-
+ write_batch_csum_info(&i,flist->count,s);
+
if (!read_batch) {
fd = do_open(fname, O_RDONLY, 0);
if (fd == -1) {
io_error = 1;
- rprintf(FERROR, "send_files failed to open %s: %s\n",
- full_fname(fname), strerror(errno));
+ rprintf(FERROR,"send_files failed to open %s: %s\n",
+ fname,strerror(errno));
free_sums(s);
continue;
}
-
+
/* map the local file */
- if (do_fstat(fd, &st) != 0) {
+ if (do_fstat(fd,&st) != 0) {
io_error = 1;
- rprintf(FERROR, "fstat failed: %s\n", strerror(errno));
+ rprintf(FERROR,"fstat failed : %s\n",strerror(errno));
free_sums(s);
close(fd);
return;
}
-
+
if (st.st_size > 0) {
- buf = map_file(fd, st.st_size);
+ buf = map_file(fd,st.st_size);
} else {
buf = NULL;
}
-
+
if (verbose > 2)
- rprintf(FINFO, "send_files mapped %s of size %.0f\n",
- fname, (double)st.st_size);
-
- write_int(f_out, i);
+ rprintf(FINFO,"send_files mapped %s of size %.0f\n",
+ fname,(double)st.st_size);
+ write_int(f_out,i);
+
if (write_batch)
- write_batch_delta_file((char *)&i, sizeof(i));
+ write_batch_delta_file((char *)&i,sizeof(i));
- write_sum_head(f_out, s);
+ write_int(f_out,s->count);
+ write_int(f_out,s->n);
+ write_int(f_out,s->remainder);
}
-
- if (verbose > 2 && !read_batch)
- rprintf(FINFO, "calling match_sums %s\n", fname);
-
- if (!am_server && verbose) { /* log transfer */
- rprintf(FINFO, "%s\n", fname+offset);
+
+ if (verbose > 2)
+ if (!read_batch)
+ rprintf(FINFO,"calling match_sums %s\n",fname);
+
+ if (!am_server) {
+ log_transfer(file, fname+offset);
}
set_compression(fname);
- if (read_batch) { /* dw */
- /* read checksums originally computed on sender side */
- read_batch_csum_info(i, s, &checksums_match);
- if (checksums_match) {
- read_batch_delta_file( (char *) &j, sizeof(int) );
- if (j != i) { /* if flist index entries don't match*/
- rprintf(FINFO, "index mismatch in send_files\n");
- rprintf(FINFO, "read index = %d flist ndx = %d\n", j, i);
- close_batch_delta_file();
- close_batch_csums_file();
- exit_cleanup(1);
- } else {
- write_int(f_out, j);
- write_sum_head(f_out, s);
- done = 0;
- while (!done) {
- read_batch_delta_file( (char *) &buff_len, sizeof(int) );
- write_int(f_out, buff_len);
- if (buff_len == 0) {
- done = 1;
- } else {
- if (buff_len > 0) {
- read_batch_delta_file(buff, buff_len);
- write_buf(f_out, buff, buff_len);
- }
- }
- } /* end while */
- read_batch_delta_file( buff, MD4_SUM_LENGTH);
- write_buf(f_out, buff, MD4_SUM_LENGTH);
-
- } /* j=i */
- } else { /* not checksum match */
- rprintf (FINFO, "readbatch & checksums don't match\n");
- rprintf (FINFO, "filename=%s is being skipped\n", fname);
- continue;
- }
- } else {
- match_sums(f_out, s, buf, st.st_size);
- log_send(file, &initial_stats);
- }
+ if (read_batch) { /* dw */
+ /* read checksums originally computed on sender side */
+ read_batch_csum_info(i, s, &checksums_match);
+ if (checksums_match) {
+ read_batch_delta_file( (char *) &j, sizeof(int) );
+ if (j != i) { /* if flist index entries don't match*/
+ rprintf(FINFO,"index mismatch in send_files\n");
+ rprintf(FINFO,"read index = %d flist ndx = %d\n",j,i);
+ close_batch_delta_file();
+ close_batch_csums_file();
+ exit_cleanup(1);
+ }
+ else {
+ write_int(f_out,j);
+ write_int(f_out,s->count);
+ write_int(f_out,s->n);
+ write_int(f_out,s->remainder);
+ done=0;
+ while (!done) {
+ read_batch_delta_file( (char *) &buff_len, sizeof(int) );
+ write_int(f_out,buff_len);
+ if (buff_len == 0) {
+ done = 1;
+ }
+ else {
+ if (buff_len > 0) {
+ read_batch_delta_file(buff, buff_len);
+ write_buf(f_out,buff,buff_len);
+ }
+ }
+ } /* end while */
+ read_batch_delta_file( buff, MD4_SUM_LENGTH);
+ write_buf(f_out, buff, MD4_SUM_LENGTH);
+
+ } /* j=i */
+ } else { /* not checksum match */
+ rprintf (FINFO,"readbatch & checksums don't match\n");
+ rprintf (FINFO,"filename=%s is being skipped\n",
+ fname);
+ continue;
+ }
+ } else {
+ match_sums(f_out,s,buf,st.st_size);
+ log_send(file, &initial_stats);
+ }
if (!read_batch) { /* dw */
- if (buf) {
- j = unmap_file(buf);
- if (j) {
- io_error = 1;
- rprintf(FERROR,
- "read errors mapping %s: (%d) %s\n",
- full_fname(fname),
- j,
- strerror(j));
- }
- }
- close(fd);
+ if (buf) unmap_file(buf);
+ close(fd);
}
-
+
free_sums(s);
-
+
if (verbose > 2)
- rprintf(FINFO, "sender finished %s\n", fname);
+ rprintf(FINFO,"sender finished %s\n",fname);
}
if (verbose > 2)
- rprintf(FINFO, "send files finished\n");
+ rprintf(FINFO,"send files finished\n");
match_report();
- write_int(f_out, -1);
+ write_int(f_out,-1);
if (write_batch || read_batch) { /* dw */
- close_batch_csums_file();
- close_batch_delta_file();
+ close_batch_csums_file();
+ close_batch_delta_file();
}
}
diff --git a/token.c b/token.c
index 8f498f1f..b7098a6d 100644
--- a/token.c
+++ b/token.c
@@ -51,7 +51,7 @@ void set_compression(char *fname)
strlower(fname);
for (tok=strtok(dont," ");tok;tok=strtok(NULL," ")) {
- if (wildmatch(tok, fname)) {
+ if (fnmatch(tok, fname, 0) == 0) {
compression_level = 0;
break;
}
@@ -68,7 +68,7 @@ static int simple_recv_token(int f,char **data)
int n;
if (!buf) {
- buf = (char *)malloc(CHUNK_SIZE);
+ buf = new_array(char, CHUNK_SIZE);
if (!buf) out_of_memory("simple_recv_token");
}
@@ -90,8 +90,8 @@ static int simple_recv_token(int f,char **data)
static void simple_send_token(int f,int token,
struct map_struct *buf,OFF_T offset,int n)
{
- extern int write_batch;
- int hold_int;
+ extern int write_batch; /* dw */
+ int hold_int; /* dw */
if (n > 0) {
int l = 0;
@@ -100,8 +100,8 @@ static void simple_send_token(int f,int token,
write_int(f,n1);
write_buf(f,map_ptr(buf,offset+l,n1),n1);
if (write_batch) {
- write_batch_delta_file( (char *) &n1, sizeof(int) );
- write_batch_delta_file(map_ptr(buf,offset+l,n1),n1);
+ write_batch_delta_file( (char *) &n1, sizeof(int) );
+ write_batch_delta_file(map_ptr(buf,offset+l,n1),n1);
}
l += n1;
}
@@ -110,8 +110,8 @@ static void simple_send_token(int f,int token,
if (token != -2) {
write_int(f,-(token+1));
if (write_batch) {
- hold_int = -(token+1);
- write_batch_delta_file( (char *) &hold_int, sizeof(int) );
+ hold_int = -(token+1);
+ write_batch_delta_file( (char *) &hold_int, sizeof(int) );
}
}
}
@@ -127,12 +127,6 @@ static void simple_send_token(int f,int token,
#define MAX_DATA_COUNT 16383 /* fit 14 bit count into 2 bytes with flags */
-/* zlib.h says that if we want to be able to compress something in a single
- * call, avail_out must be at least 0.1% larger than avail_in plus 12 bytes.
- * We'll add in 0.1%+16, just to be safe (and we'll avoid floating point,
- * to ensure that this is a compile-time value). */
-#define AVAIL_OUT_SIZE(avail_in_size) ((avail_in_size)*1001/1000+16)
-
/* For coding runs of tokens */
static int last_token = -1;
static int run_start;
@@ -144,14 +138,6 @@ static z_stream tx_strm;
/* Output buffer */
static char *obuf;
-/* We want obuf to be able to hold both MAX_DATA_COUNT+2 bytes as well as
- * AVAIL_OUT_SIZE(CHUNK_SIZE) bytes, so make sure that it's large enough. */
-#if MAX_DATA_COUNT+2 > AVAIL_OUT_SIZE(CHUNK_SIZE)
-#define OBUF_SIZE (MAX_DATA_COUNT+2)
-#else
-#define OBUF_SIZE AVAIL_OUT_SIZE(CHUNK_SIZE)
-#endif
-
/* Send a deflated token */
static void
send_deflated_token(int f, int token,
@@ -159,8 +145,8 @@ send_deflated_token(int f, int token,
{
int n, r;
static int init_done, flush_pending;
- extern int write_batch;
- char temp_byte;
+ extern int write_batch; /* dw */
+ char temp_byte; /* dw */
if (last_token == -1) {
/* initialization */
@@ -174,7 +160,7 @@ send_deflated_token(int f, int token,
rprintf(FERROR, "compression init failed\n");
exit_cleanup(RERR_STREAMIO);
}
- if ((obuf = malloc(OBUF_SIZE)) == NULL)
+ if ((obuf = new_array(char, MAX_DATA_COUNT+2)) == NULL)
out_of_memory("send_deflated_token");
init_done = 1;
} else
@@ -193,26 +179,26 @@ send_deflated_token(int f, int token,
n = last_token - run_start;
if (r >= 0 && r <= 63) {
write_byte(f, (n==0? TOKEN_REL: TOKENRUN_REL) + r);
- if (write_batch) {
- temp_byte = (char)( (n==0? TOKEN_REL: TOKENRUN_REL) + r);
- write_batch_delta_file(&temp_byte,sizeof(char));
+ if (write_batch) { /* dw */
+ temp_byte = (char)( (n==0? TOKEN_REL: TOKENRUN_REL) + r);
+ write_batch_delta_file(&temp_byte,sizeof(char));
}
} else {
write_byte(f, (n==0? TOKEN_LONG: TOKENRUN_LONG));
write_int(f, run_start);
- if (write_batch) {
- temp_byte = (char)(n==0? TOKEN_LONG: TOKENRUN_LONG);
- write_batch_delta_file(&temp_byte,sizeof(temp_byte));
- write_batch_delta_file((char *)&run_start,sizeof(run_start));
+ if (write_batch) { /* dw */
+ temp_byte = (char)(n==0? TOKEN_LONG: TOKENRUN_LONG);
+ write_batch_delta_file(&temp_byte,sizeof(temp_byte));
+ write_batch_delta_file((char *)&run_start,sizeof(run_start));
}
}
if (n != 0) {
write_byte(f, n);
write_byte(f, n >> 8);
- if (write_batch) {
- write_batch_delta_file((char *)&n,sizeof(char));
- temp_byte = (char)(n >> 8);
- write_batch_delta_file(&temp_byte,sizeof(temp_byte));
+ if (write_batch) { /* dw */
+ write_batch_delta_file((char *)&n,sizeof(char));
+ temp_byte = (char) n >> 8;
+ write_batch_delta_file(&temp_byte,sizeof(temp_byte));
}
}
last_run_end = last_token;
@@ -272,8 +258,8 @@ send_deflated_token(int f, int token,
obuf[0] = DEFLATED_DATA + (n >> 8);
obuf[1] = n;
write_buf(f, obuf, n+2);
- if (write_batch)
- write_batch_delta_file(obuf,n+2);
+ if (write_batch) /* dw */
+ write_batch_delta_file(obuf,n+2);
}
}
} while (nb != 0 || tx_strm.avail_out == 0);
@@ -283,9 +269,9 @@ send_deflated_token(int f, int token,
if (token == -1) {
/* end of file - clean up */
write_byte(f, END_FLAG);
- if (write_batch) {
- temp_byte = END_FLAG;
- write_batch_delta_file((char *)&temp_byte,sizeof(temp_byte));
+ if (write_batch) { /* dw */
+ temp_byte = END_FLAG;
+ write_batch_delta_file((char *)&temp_byte,sizeof(temp_byte));
}
} else if (token != -2) {
@@ -294,7 +280,7 @@ send_deflated_token(int f, int token,
tx_strm.next_in = (Bytef *) map_ptr(buf, offset, toklen);
tx_strm.avail_in = toklen;
tx_strm.next_out = (Bytef *) obuf;
- tx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
+ tx_strm.avail_out = MAX_DATA_COUNT;
r = deflate(&tx_strm, Z_INSERT_ONLY);
if (r != Z_OK || tx_strm.avail_in != 0) {
rprintf(FERROR, "deflate on token returned %d (%d bytes left)\n",
@@ -336,8 +322,8 @@ recv_deflated_token(int f, char **data)
rprintf(FERROR, "inflate init failed\n");
exit_cleanup(RERR_STREAMIO);
}
- if ((cbuf = malloc(MAX_DATA_COUNT)) == NULL
- || (dbuf = malloc(AVAIL_OUT_SIZE(CHUNK_SIZE))) == NULL)
+ if (!(cbuf = new_array(char, MAX_DATA_COUNT))
+ || !(dbuf = new_array(char, CHUNK_SIZE)))
out_of_memory("recv_deflated_token");
init_done = 1;
} else {
@@ -366,9 +352,9 @@ recv_deflated_token(int f, char **data)
/* check previous inflated stuff ended correctly */
rx_strm.avail_in = 0;
rx_strm.next_out = (Bytef *)dbuf;
- rx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
+ rx_strm.avail_out = CHUNK_SIZE;
r = inflate(&rx_strm, Z_SYNC_FLUSH);
- n = AVAIL_OUT_SIZE(CHUNK_SIZE) - rx_strm.avail_out;
+ n = CHUNK_SIZE - rx_strm.avail_out;
/*
* Z_BUF_ERROR just means no progress was
* made, i.e. the decompressor didn't have
@@ -422,9 +408,9 @@ recv_deflated_token(int f, char **data)
case r_inflating:
rx_strm.next_out = (Bytef *)dbuf;
- rx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
+ rx_strm.avail_out = CHUNK_SIZE;
r = inflate(&rx_strm, Z_NO_FLUSH);
- n = AVAIL_OUT_SIZE(CHUNK_SIZE) - rx_strm.avail_out;
+ n = CHUNK_SIZE - rx_strm.avail_out;
if (r != Z_OK) {
rprintf(FERROR, "inflate returned %d (%d bytes)\n", r, n);
exit_cleanup(RERR_STREAMIO);
@@ -479,7 +465,7 @@ static void see_deflate_token(char *buf, int len)
}
}
rx_strm.next_out = (Bytef *)dbuf;
- rx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
+ rx_strm.avail_out = CHUNK_SIZE;
r = inflate(&rx_strm, Z_SYNC_FLUSH);
if (r != Z_OK) {
rprintf(FERROR, "inflate (token) returned %d\n", r);
diff --git a/uidlist.c b/uidlist.c
index 14611a55..d8a7af11 100644
--- a/uidlist.c
+++ b/uidlist.c
@@ -41,7 +41,7 @@ static struct idlist *gidlist;
static struct idlist *add_list(int id, char *name)
{
- struct idlist *list = (struct idlist *)malloc(sizeof(list[0]));
+ struct idlist *list = new(struct idlist);
if (!list) out_of_memory("add_list");
list->next = NULL;
list->name = strdup(name);
@@ -241,7 +241,7 @@ void recv_uid_list(int f, struct file_list *flist)
id = read_int(f);
while (id != 0) {
int len = read_byte(f);
- name = (char *)malloc(len+1);
+ name = new_array(char, len+1);
if (!name) out_of_memory("recv_uid_list");
read_sbuf(f, name, len);
if (!list) {
@@ -264,7 +264,7 @@ void recv_uid_list(int f, struct file_list *flist)
id = read_int(f);
while (id != 0) {
int len = read_byte(f);
- name = (char *)malloc(len+1);
+ name = new_array(char, len+1);
if (!name) out_of_memory("recv_uid_list");
read_sbuf(f, name, len);
if (!list) {
diff --git a/util.c b/util.c
index e6420646..35db736e 100644
--- a/util.c
+++ b/util.c
@@ -345,10 +345,9 @@ int robust_unlink(char *fname)
counter = 1;
} while (((rc = access(path, 0)) == 0) && (counter != start));
- if (verbose > 0) {
+ if (verbose > 0)
rprintf(FINFO,"renaming %s to %s because of text busy\n",
- fname, path);
- }
+ fname, path);
/* maybe we should return rename()'s exit status? Nah. */
if (do_rename(fname, path) != 0) {
@@ -459,31 +458,14 @@ int lock_range(int fd, int offset, int len)
return fcntl(fd,F_SETLK,&lock) == 0;
}
-static int exclude_server_path(char *arg)
-{
- char *s;
- extern struct exclude_struct **server_exclude_list;
-
- if (server_exclude_list) {
- for (s = arg; (s = strchr(s, '/')) != NULL; ) {
- *s = '\0';
- if (check_exclude(server_exclude_list, arg, 1)) {
- /* We must leave arg truncated! */
- return 1;
- }
- *s++ = '/';
- }
- }
- return 0;
-}
static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
{
#if !(defined(HAVE_GLOB) && defined(HAVE_GLOB_H))
if (!*s) s = ".";
- s = argv[*argc] = strdup(s);
- exclude_server_path(s);
+ argv[*argc] = strdup(s);
(*argc)++;
+ return;
#else
extern int sanitize_paths;
glob_t globbuf;
@@ -491,21 +473,20 @@ static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
if (!*s) s = ".";
- s = argv[*argc] = strdup(s);
+ argv[*argc] = strdup(s);
if (sanitize_paths) {
- sanitize_path(s, NULL);
+ sanitize_path(argv[*argc], NULL);
}
memset(&globbuf, 0, sizeof(globbuf));
- if (!exclude_server_path(s))
- glob(s, 0, NULL, &globbuf);
+ glob(argv[*argc], 0, NULL, &globbuf);
if (globbuf.gl_pathc == 0) {
(*argc)++;
globfree(&globbuf);
return;
}
for (i=0; i<(maxargs - (*argc)) && i < (int) globbuf.gl_pathc;i++) {
- if (i == 0) free(s);
+ if (i == 0) free(argv[*argc]);
argv[(*argc) + i] = strdup(globbuf.gl_pathv[i]);
if (!argv[(*argc) + i]) out_of_memory("glob_expand");
}
@@ -514,31 +495,29 @@ static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
#endif
}
-/* This routine is only used in daemon mode. */
void glob_expand(char *base1, char **argv, int *argc, int maxargs)
{
char *s = argv[*argc];
char *p, *q;
char *base = base1;
- int base_len = strlen(base);
if (!s || !*s) return;
- if (strncmp(s, base, base_len) == 0)
- s += base_len;
+ if (strncmp(s, base, strlen(base)) == 0) {
+ s += strlen(base);
+ }
s = strdup(s);
if (!s) out_of_memory("glob_expand");
if (asprintf(&base," %s/", base1) <= 0) out_of_memory("glob_expand");
- base_len++;
q = s;
while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
/* split it at this point */
*p = 0;
glob_expand_one(q, argv, argc, maxargs);
- q = p + base_len;
+ q = p+strlen(base);
}
if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs);
@@ -559,13 +538,6 @@ void strlower(char *s)
}
}
-void *Realloc(void *p, int size)
-{
- if (!p) return (void *)malloc(size);
- return (void *)realloc(p, size);
-}
-
-
void clean_fname(char *name)
{
char *p;
@@ -669,7 +641,7 @@ void sanitize_path(char *p, char *reldir)
}
allowdotdot = 0;
if ((*p == '.') && (*(p+1) == '.') &&
- ((*(p+2) == '/') || (*(p+2) == '\0'))) {
+ ((*(p+2) == '/') || (*(p+2) == '\0'))) {
/* ".." component followed by slash or end */
if ((depth > 0) && (sanp == start)) {
/* allow depth levels of .. at the beginning */
@@ -720,7 +692,7 @@ void sanitize_path(char *p, char *reldir)
}
-char curr_dir[MAXPATHLEN];
+static char curr_dir[MAXPATHLEN];
/**
* Like chdir() but can be reversed with pop_dir() if @p save is set.
@@ -746,7 +718,7 @@ char *push_dir(char *dir, int save)
if (*dir == '/') {
strlcpy(curr_dir, dir, sizeof(curr_dir));
- } else if (dir[0] != '.' || dir[1] != '\0') {
+ } else {
strlcat(curr_dir,"/", sizeof(curr_dir));
strlcat(curr_dir,dir, sizeof(curr_dir));
}
@@ -774,52 +746,6 @@ int pop_dir(char *dir)
return 0;
}
-/**
- * Return a quoted string with the full pathname of the indicated filename.
- * The string " (in MODNAME)" may also be appended. The returned pointer
- * remains valid until the next time full_fname() is called.
- **/
-char *full_fname(char *fn)
-{
- extern int module_id;
- static char *result = NULL;
- char *m1, *m2, *m3;
- char *p1, *p2;
-
- if (result)
- free(result);
-
- if (*fn == '/')
- p1 = p2 = "";
- else {
- p1 = curr_dir;
- p2 = "/";
- }
- if (module_id >= 0) {
- m1 = " (in ";
- m2 = lp_name(module_id);
- m3 = ")";
- if (*p1) {
- if (!lp_use_chroot(module_id)) {
- char *p = lp_path(module_id);
- if (*p != '/' || p[1])
- p1 += strlen(p);
- }
- if (!*p1)
- p2++;
- else
- p1++;
- }
- else
- fn++;
- } else
- m1 = m2 = m3 = "";
-
- asprintf(&result, "\"%s%s%s\"%s%s%s", p1, p2, fn, m1, m2, m3);
-
- return result;
-}
-
/** 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)
@@ -1008,3 +934,23 @@ int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
return ret;
}
#endif
+
+
+#define MALLOC_MAX 0x40000000
+
+void *_new_array(unsigned int size, unsigned long num)
+{
+ if (num >= MALLOC_MAX/size)
+ return NULL;
+ return malloc(size * num);
+}
+
+void *_realloc_array(void *ptr, unsigned int size, unsigned long num)
+{
+ if (num >= MALLOC_MAX/size)
+ return NULL;
+ /* No realloc should need this, but just in case... */
+ if (!ptr)
+ return malloc(size * num);
+ return realloc(ptr, size * num);
+}