The --iconv option has now made it to the trunk.
This commit is contained in:
4
NEWS
4
NEWS
@@ -61,6 +61,10 @@ Changes since 2.6.9:
|
|||||||
all attributes of a file by using a special extended-attribute idiom.
|
all attributes of a file by using a special extended-attribute idiom.
|
||||||
There is also an analogous "fake super" option for an rsync daemon.
|
There is also an analogous "fake super" option for an rsync daemon.
|
||||||
|
|
||||||
|
- Added the --iconv option, which allows rsync to convert filenames from
|
||||||
|
one character set to another during the transfer. (Currently must be
|
||||||
|
manually enabled via configure's --enable-iconv option.)
|
||||||
|
|
||||||
- You may specify --max-delete=0 to a 3.0.0 client as long as the receiving
|
- You may specify --max-delete=0 to a 3.0.0 client as long as the receiving
|
||||||
side is at least version 3.0.0. This means that you can pull from an
|
side is at least version 3.0.0. This means that you can pull from an
|
||||||
older rsync with this option, but pushing to an older rsync will generate
|
older rsync with this option, but pushing to an older rsync will generate
|
||||||
|
|||||||
@@ -687,7 +687,7 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
|
|||||||
|
|
||||||
if (!ret || err_msg) {
|
if (!ret || err_msg) {
|
||||||
if (err_msg)
|
if (err_msg)
|
||||||
rwrite(FERROR, err_msg, strlen(err_msg));
|
rwrite(FERROR, err_msg, strlen(err_msg), 0);
|
||||||
else
|
else
|
||||||
option_error();
|
option_error();
|
||||||
msleep(400);
|
msleep(400);
|
||||||
|
|||||||
16
configure.in
16
configure.in
@@ -568,6 +568,22 @@ if test $ac_cv_func_getpgrp = yes; then
|
|||||||
AC_FUNC_GETPGRP
|
AC_FUNC_GETPGRP
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(iconv,
|
||||||
|
AC_HELP_STRING([--disable-iconv],
|
||||||
|
[disable rsync's --iconv option]),
|
||||||
|
[], [enable_iconv=$ac_cv_func_iconv_open])
|
||||||
|
AH_TEMPLATE([ICONV_OPTION],
|
||||||
|
[Define if you want the --iconv option. Specifing a value will set the
|
||||||
|
default iconv setting (a NULL means no --iconv processing by default).])
|
||||||
|
if test x"$enable_iconv" != x"no"; then
|
||||||
|
if test x"$enable_iconv" = x"yes"; then
|
||||||
|
AC_DEFINE(ICONV_OPTION, NULL)
|
||||||
|
else
|
||||||
|
AC_DEFINE_UNQUOTED(ICONV_OPTION, "$enable_iconv")
|
||||||
|
fi
|
||||||
|
AC_DEFINE(UTF8_CHARSET, "UTF-8", [String to pass to iconv() for the UTF-8 charset.])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_CACHE_CHECK([whether chown() modifies symlinks],rsync_cv_chown_modifies_symlink,[
|
AC_CACHE_CHECK([whether chown() modifies symlinks],rsync_cv_chown_modifies_symlink,[
|
||||||
AC_TRY_RUN([
|
AC_TRY_RUN([
|
||||||
#if HAVE_UNISTD_H
|
#if HAVE_UNISTD_H
|
||||||
|
|||||||
177
flist.c
177
flist.c
@@ -70,6 +70,12 @@ extern struct chmod_mode_struct *chmod_modes;
|
|||||||
extern struct filter_list_struct filter_list;
|
extern struct filter_list_struct filter_list;
|
||||||
extern struct filter_list_struct server_filter_list;
|
extern struct filter_list_struct server_filter_list;
|
||||||
|
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
extern int ic_ndx;
|
||||||
|
extern int need_unsorted_flist;
|
||||||
|
extern iconv_t ic_send, ic_recv;
|
||||||
|
#endif
|
||||||
|
|
||||||
int io_error;
|
int io_error;
|
||||||
int checksum_len;
|
int checksum_len;
|
||||||
dev_t filesystem_dev; /* used to implement -x */
|
dev_t filesystem_dev; /* used to implement -x */
|
||||||
@@ -346,7 +352,35 @@ static void send_file_entry(int f, struct file_struct *file, int ndx)
|
|||||||
int l1, l2;
|
int l1, l2;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
f_name(file, fname);
|
#ifdef ICONV_OPTION
|
||||||
|
if (ic_send != (iconv_t)-1) {
|
||||||
|
ICONV_CONST char *ibuf;
|
||||||
|
char *obuf = fname;
|
||||||
|
size_t ocnt = MAXPATHLEN, icnt;
|
||||||
|
|
||||||
|
iconv(ic_send, NULL,0, NULL,0);
|
||||||
|
if ((ibuf = (ICONV_CONST char *)file->dirname) != NULL) {
|
||||||
|
icnt = strlen(ibuf);
|
||||||
|
ocnt--; /* pre-subtract the space for the '/' */
|
||||||
|
if (iconv(ic_send, &ibuf,&icnt, &obuf,&ocnt) == (size_t)-1)
|
||||||
|
goto convert_error;
|
||||||
|
*obuf++ = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
ibuf = (ICONV_CONST char *)file->basename;
|
||||||
|
icnt = strlen(ibuf);
|
||||||
|
if (iconv(ic_send, &ibuf,&icnt, &obuf,&ocnt) == (size_t)-1) {
|
||||||
|
convert_error:
|
||||||
|
io_error |= IOERR_GENERAL;
|
||||||
|
rprintf(FINFO,
|
||||||
|
"[%s] cannot convert filename: %s (%s)\n",
|
||||||
|
who_am_i(), f_name(file, fname), strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*obuf = '\0';
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
f_name(file, fname);
|
||||||
|
|
||||||
flags = file->flags & FLAG_TOP_DIR; /* FLAG_TOP_DIR == XMIT_TOP_DIR */
|
flags = file->flags & FLAG_TOP_DIR; /* FLAG_TOP_DIR == XMIT_TOP_DIR */
|
||||||
|
|
||||||
@@ -598,7 +632,31 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
|
|||||||
read_sbuf(f, &thisname[l1], l2);
|
read_sbuf(f, &thisname[l1], l2);
|
||||||
thisname[l1 + l2] = 0;
|
thisname[l1 + l2] = 0;
|
||||||
|
|
||||||
strlcpy(lastname, thisname, MAXPATHLEN);
|
/* Abuse basename_len for a moment... */
|
||||||
|
basename_len = strlcpy(lastname, thisname, MAXPATHLEN);
|
||||||
|
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
if (ic_recv != (iconv_t)-1) {
|
||||||
|
char *obuf = thisname, *ibuf = lastname;
|
||||||
|
size_t ocnt = MAXPATHLEN, icnt = basename_len;
|
||||||
|
|
||||||
|
if (icnt >= MAXPATHLEN) {
|
||||||
|
errno = E2BIG;
|
||||||
|
goto convert_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
iconv(ic_recv, NULL,0, NULL,0);
|
||||||
|
if (iconv(ic_recv, &ibuf,&icnt, &obuf,&ocnt) == (size_t)-1) {
|
||||||
|
convert_error:
|
||||||
|
io_error |= IOERR_GENERAL;
|
||||||
|
rprintf(FINFO,
|
||||||
|
"[%s] cannot convert filename: %s (%s)\n",
|
||||||
|
who_am_i(), lastname, strerror(errno));
|
||||||
|
obuf = thisname;
|
||||||
|
}
|
||||||
|
*obuf = '\0';
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
clean_fname(thisname, 0);
|
clean_fname(thisname, 0);
|
||||||
|
|
||||||
@@ -792,6 +850,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
|
|||||||
F_OWNER(file) = uid;
|
F_OWNER(file) = uid;
|
||||||
if (preserve_gid)
|
if (preserve_gid)
|
||||||
F_GROUP(file) = gid;
|
F_GROUP(file) = gid;
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
if (ic_ndx)
|
||||||
|
F_NDX(file) = flist->count + flist->ndx_start;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (basename != thisname) {
|
if (basename != thisname) {
|
||||||
file->dirname = lastdir;
|
file->dirname = lastdir;
|
||||||
@@ -1385,7 +1447,13 @@ void send_extra_file_list(int f, int at_least)
|
|||||||
FLAG_DIVERT_DIRS | FLAG_XFER_DIR);
|
FLAG_DIVERT_DIRS | FLAG_XFER_DIR);
|
||||||
write_byte(f, 0);
|
write_byte(f, 0);
|
||||||
|
|
||||||
clean_flist(flist, 0, 0);
|
#ifdef ICONV_OPTION
|
||||||
|
if (!need_unsorted_flist)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
flist->sorted = flist->files;
|
||||||
|
clean_flist(flist, 0, 0);
|
||||||
|
}
|
||||||
file_total += flist->count;
|
file_total += flist->count;
|
||||||
future_cnt += flist->count;
|
future_cnt += flist->count;
|
||||||
stats.flist_size += stats.total_written - start_write;
|
stats.flist_size += stats.total_written - start_write;
|
||||||
@@ -1670,12 +1738,30 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
|||||||
stats.flist_xfertime = (int64)(end_tv.tv_sec - start_tv.tv_sec) * 1000
|
stats.flist_xfertime = (int64)(end_tv.tv_sec - start_tv.tv_sec) * 1000
|
||||||
+ (end_tv.tv_usec - start_tv.tv_usec) / 1000;
|
+ (end_tv.tv_usec - start_tv.tv_usec) / 1000;
|
||||||
|
|
||||||
|
/* When converting names, both sides keep an unsorted file-list array
|
||||||
|
* because the names will differ on the sending and receiving sides
|
||||||
|
* (both sides will use the unsorted index number for each item). */
|
||||||
|
|
||||||
/* Sort the list without removing any duplicates in non-incremental
|
/* Sort the list without removing any duplicates in non-incremental
|
||||||
* mode. This allows the receiving side to ask for whatever name it
|
* mode. This allows the receiving side to ask for whatever name it
|
||||||
* kept. For incremental mode, the sender also removes duplicates
|
* kept. For incremental mode, the sender also removes duplicates
|
||||||
* in this initial file-list so that it avoids re-sending duplicated
|
* in this initial file-list so that it avoids re-sending duplicated
|
||||||
* directories. */
|
* directories. */
|
||||||
clean_flist(flist, 0, inc_recurse);
|
#ifdef ICONV_OPTION
|
||||||
|
if (need_unsorted_flist) {
|
||||||
|
if (inc_recurse) {
|
||||||
|
if (!(flist->sorted = new_array(struct file_struct *, flist->count)))
|
||||||
|
out_of_memory("recv_file_list");
|
||||||
|
memcpy(flist->sorted, flist->files,
|
||||||
|
flist->count * sizeof (struct file_struct*));
|
||||||
|
clean_flist(flist, 0, 1);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
flist->sorted = flist->files;
|
||||||
|
clean_flist(flist, 0, inc_recurse);
|
||||||
|
}
|
||||||
file_total += flist->count;
|
file_total += flist->count;
|
||||||
|
|
||||||
if (!numeric_ids && !inc_recurse)
|
if (!numeric_ids && !inc_recurse)
|
||||||
@@ -1778,11 +1864,27 @@ struct file_list *recv_file_list(int f)
|
|||||||
if (show_filelist_p())
|
if (show_filelist_p())
|
||||||
finish_filelist_progress(flist);
|
finish_filelist_progress(flist);
|
||||||
|
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
if (need_unsorted_flist) {
|
||||||
|
/* Create an extra array of index pointers that we can sort for
|
||||||
|
* the generator's use (for wading through the files in sorted
|
||||||
|
* order and for calling flist_find()). We keep the "files"
|
||||||
|
* list unsorted for our exchange of index numbers with the
|
||||||
|
* other side (since their names may not sort the same). */
|
||||||
|
if (!(flist->sorted = new_array(struct file_struct *, flist->count)))
|
||||||
|
out_of_memory("recv_file_list");
|
||||||
|
memcpy(flist->sorted, flist->files,
|
||||||
|
flist->count * sizeof (struct file_struct*));
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
flist->sorted = flist->files;
|
||||||
|
|
||||||
clean_flist(flist, relative_paths, 1);
|
clean_flist(flist, relative_paths, 1);
|
||||||
|
|
||||||
if (inc_recurse) {
|
if (inc_recurse) {
|
||||||
qsort(dir_flist->files + dstart, dir_flist->count - dstart,
|
dir_flist->sorted = dir_flist->files;
|
||||||
sizeof dir_flist->files[0], (int (*)())file_compare);
|
qsort(dir_flist->sorted + dstart, dir_flist->count - dstart,
|
||||||
|
sizeof dir_flist->sorted[0], (int (*)())file_compare);
|
||||||
} else if (f >= 0)
|
} else if (f >= 0)
|
||||||
recv_uid_list(f, flist);
|
recv_uid_list(f, flist);
|
||||||
|
|
||||||
@@ -1845,36 +1947,36 @@ int flist_find(struct file_list *flist, struct file_struct *f)
|
|||||||
|
|
||||||
while (low <= high) {
|
while (low <= high) {
|
||||||
mid = (low + high) / 2;
|
mid = (low + high) / 2;
|
||||||
if (F_IS_ACTIVE(flist->files[mid]))
|
if (F_IS_ACTIVE(flist->sorted[mid]))
|
||||||
mid_up = mid;
|
mid_up = mid;
|
||||||
else {
|
else {
|
||||||
/* Scan for the next non-empty entry using the cached
|
/* Scan for the next non-empty entry using the cached
|
||||||
* distance values. If the value isn't fully up-to-
|
* distance values. If the value isn't fully up-to-
|
||||||
* date, update it. */
|
* date, update it. */
|
||||||
mid_up = mid + F_DEPTH(flist->files[mid]);
|
mid_up = mid + F_DEPTH(flist->sorted[mid]);
|
||||||
if (!F_IS_ACTIVE(flist->files[mid_up])) {
|
if (!F_IS_ACTIVE(flist->sorted[mid_up])) {
|
||||||
do {
|
do {
|
||||||
mid_up += F_DEPTH(flist->files[mid_up]);
|
mid_up += F_DEPTH(flist->sorted[mid_up]);
|
||||||
} while (!F_IS_ACTIVE(flist->files[mid_up]));
|
} while (!F_IS_ACTIVE(flist->sorted[mid_up]));
|
||||||
F_DEPTH(flist->files[mid]) = mid_up - mid;
|
F_DEPTH(flist->sorted[mid]) = mid_up - mid;
|
||||||
}
|
}
|
||||||
if (mid_up > high) {
|
if (mid_up > high) {
|
||||||
/* If there's nothing left above us, set high to
|
/* If there's nothing left above us, set high to
|
||||||
* a non-empty entry below us and continue. */
|
* a non-empty entry below us and continue. */
|
||||||
high = mid - (int)flist->files[mid]->len32;
|
high = mid - (int)flist->sorted[mid]->len32;
|
||||||
if (!F_IS_ACTIVE(flist->files[high])) {
|
if (!F_IS_ACTIVE(flist->sorted[high])) {
|
||||||
do {
|
do {
|
||||||
high -= (int)flist->files[high]->len32;
|
high -= (int)flist->sorted[high]->len32;
|
||||||
} while (!F_IS_ACTIVE(flist->files[high]));
|
} while (!F_IS_ACTIVE(flist->sorted[high]));
|
||||||
flist->files[mid]->len32 = mid - high;
|
flist->sorted[mid]->len32 = mid - high;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
diff = f_name_cmp(flist->files[mid_up], f);
|
diff = f_name_cmp(flist->sorted[mid_up], f);
|
||||||
if (diff == 0) {
|
if (diff == 0) {
|
||||||
if (protocol_version < 29
|
if (protocol_version < 29
|
||||||
&& S_ISDIR(flist->files[mid_up]->mode)
|
&& S_ISDIR(flist->sorted[mid_up]->mode)
|
||||||
!= S_ISDIR(f->mode))
|
!= S_ISDIR(f->mode))
|
||||||
return -1;
|
return -1;
|
||||||
return mid_up;
|
return mid_up;
|
||||||
@@ -1960,6 +2062,8 @@ void flist_free(struct file_list *flist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pool_destroy(flist->file_pool);
|
pool_destroy(flist->file_pool);
|
||||||
|
if (flist->sorted && flist->sorted != flist->files)
|
||||||
|
free(flist->sorted);
|
||||||
free(flist->files);
|
free(flist->files);
|
||||||
free(flist);
|
free(flist);
|
||||||
}
|
}
|
||||||
@@ -1980,11 +2084,11 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort(flist->files, flist->count,
|
qsort(flist->sorted, flist->count,
|
||||||
sizeof flist->files[0], (int (*)())file_compare);
|
sizeof flist->sorted[0], (int (*)())file_compare);
|
||||||
|
|
||||||
for (i = no_dups? 0 : flist->count; i < flist->count; i++) {
|
for (i = no_dups? 0 : flist->count; i < flist->count; i++) {
|
||||||
if (F_IS_ACTIVE(flist->files[i])) {
|
if (F_IS_ACTIVE(flist->sorted[i])) {
|
||||||
prev_i = i;
|
prev_i = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1992,11 +2096,11 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
|
|||||||
flist->low = prev_i;
|
flist->low = prev_i;
|
||||||
while (++i < flist->count) {
|
while (++i < flist->count) {
|
||||||
int j;
|
int j;
|
||||||
struct file_struct *file = flist->files[i];
|
struct file_struct *file = flist->sorted[i];
|
||||||
|
|
||||||
if (!F_IS_ACTIVE(file))
|
if (!F_IS_ACTIVE(file))
|
||||||
continue;
|
continue;
|
||||||
if (f_name_cmp(file, flist->files[prev_i]) == 0)
|
if (f_name_cmp(file, flist->sorted[prev_i]) == 0)
|
||||||
j = prev_i;
|
j = prev_i;
|
||||||
else if (protocol_version >= 29 && S_ISDIR(file->mode)) {
|
else if (protocol_version >= 29 && S_ISDIR(file->mode)) {
|
||||||
int save_mode = file->mode;
|
int save_mode = file->mode;
|
||||||
@@ -2009,7 +2113,7 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
|
|||||||
} else
|
} else
|
||||||
j = -1;
|
j = -1;
|
||||||
if (j >= 0) {
|
if (j >= 0) {
|
||||||
struct file_struct *fp = flist->files[j];
|
struct file_struct *fp = flist->sorted[j];
|
||||||
int keep, drop;
|
int keep, drop;
|
||||||
/* If one is a dir and the other is not, we want to
|
/* If one is a dir and the other is not, we want to
|
||||||
* keep the dir because it might have contents in the
|
* keep the dir because it might have contents in the
|
||||||
@@ -2030,15 +2134,15 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
|
|||||||
}
|
}
|
||||||
/* Make sure we don't lose track of a user-specified
|
/* Make sure we don't lose track of a user-specified
|
||||||
* top directory. */
|
* top directory. */
|
||||||
flist->files[keep]->flags |= flist->files[drop]->flags
|
flist->sorted[keep]->flags |= flist->sorted[drop]->flags
|
||||||
& (FLAG_TOP_DIR|FLAG_XFER_DIR);
|
& (FLAG_TOP_DIR|FLAG_XFER_DIR);
|
||||||
|
|
||||||
clear_file(flist->files[drop]);
|
clear_file(flist->sorted[drop]);
|
||||||
|
|
||||||
if (keep == i) {
|
if (keep == i) {
|
||||||
if (flist->low == drop) {
|
if (flist->low == drop) {
|
||||||
for (j = drop + 1;
|
for (j = drop + 1;
|
||||||
j < i && !F_IS_ACTIVE(flist->files[j]);
|
j < i && !F_IS_ACTIVE(flist->sorted[j]);
|
||||||
j++) {}
|
j++) {}
|
||||||
flist->low = j;
|
flist->low = j;
|
||||||
}
|
}
|
||||||
@@ -2053,7 +2157,7 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
|
|||||||
/* We need to strip off the leading slashes for relative
|
/* We need to strip off the leading slashes for relative
|
||||||
* paths, but this must be done _after_ the sorting phase. */
|
* paths, but this must be done _after_ the sorting phase. */
|
||||||
for (i = flist->low; i <= flist->high; i++) {
|
for (i = flist->low; i <= flist->high; i++) {
|
||||||
struct file_struct *file = flist->files[i];
|
struct file_struct *file = flist->sorted[i];
|
||||||
|
|
||||||
if (!file->dirname)
|
if (!file->dirname)
|
||||||
continue;
|
continue;
|
||||||
@@ -2070,7 +2174,7 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
|
|||||||
prev_i = 0; /* It's OK that this isn't really true. */
|
prev_i = 0; /* It's OK that this isn't really true. */
|
||||||
|
|
||||||
for (i = flist->low; i <= flist->high; i++) {
|
for (i = flist->low; i <= flist->high; i++) {
|
||||||
struct file_struct *fp, *file = flist->files[i];
|
struct file_struct *fp, *file = flist->sorted[i];
|
||||||
|
|
||||||
/* This temporarily abuses the F_DEPTH() value for a
|
/* This temporarily abuses the F_DEPTH() value for a
|
||||||
* directory that is in a chain that might get pruned.
|
* directory that is in a chain that might get pruned.
|
||||||
@@ -2078,7 +2182,7 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
|
|||||||
if (S_ISDIR(file->mode) && F_DEPTH(file)) {
|
if (S_ISDIR(file->mode) && F_DEPTH(file)) {
|
||||||
/* Dump empty dirs when coming back down. */
|
/* Dump empty dirs when coming back down. */
|
||||||
for (j = prev_depth; j >= F_DEPTH(file); j--) {
|
for (j = prev_depth; j >= F_DEPTH(file); j--) {
|
||||||
fp = flist->files[prev_i];
|
fp = flist->sorted[prev_i];
|
||||||
if (F_DEPTH(fp) >= 0)
|
if (F_DEPTH(fp) >= 0)
|
||||||
break;
|
break;
|
||||||
prev_i = -F_DEPTH(fp)-1;
|
prev_i = -F_DEPTH(fp)-1;
|
||||||
@@ -2089,7 +2193,7 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
|
|||||||
ALL_FILTERS)) {
|
ALL_FILTERS)) {
|
||||||
/* Keep dirs through this dir. */
|
/* Keep dirs through this dir. */
|
||||||
for (j = prev_depth-1; ; j--) {
|
for (j = prev_depth-1; ; j--) {
|
||||||
fp = flist->files[prev_i];
|
fp = flist->sorted[prev_i];
|
||||||
if (F_DEPTH(fp) >= 0)
|
if (F_DEPTH(fp) >= 0)
|
||||||
break;
|
break;
|
||||||
prev_i = -F_DEPTH(fp)-1;
|
prev_i = -F_DEPTH(fp)-1;
|
||||||
@@ -2101,7 +2205,7 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
|
|||||||
} else {
|
} else {
|
||||||
/* Keep dirs through this non-dir. */
|
/* Keep dirs through this non-dir. */
|
||||||
for (j = prev_depth; ; j--) {
|
for (j = prev_depth; ; j--) {
|
||||||
fp = flist->files[prev_i];
|
fp = flist->sorted[prev_i];
|
||||||
if (F_DEPTH(fp) >= 0)
|
if (F_DEPTH(fp) >= 0)
|
||||||
break;
|
break;
|
||||||
prev_i = -F_DEPTH(fp)-1;
|
prev_i = -F_DEPTH(fp)-1;
|
||||||
@@ -2111,7 +2215,7 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
|
|||||||
}
|
}
|
||||||
/* Dump all remaining empty dirs. */
|
/* Dump all remaining empty dirs. */
|
||||||
while (1) {
|
while (1) {
|
||||||
struct file_struct *fp = flist->files[prev_i];
|
struct file_struct *fp = flist->sorted[prev_i];
|
||||||
if (F_DEPTH(fp) >= 0)
|
if (F_DEPTH(fp) >= 0)
|
||||||
break;
|
break;
|
||||||
prev_i = -F_DEPTH(fp)-1;
|
prev_i = -F_DEPTH(fp)-1;
|
||||||
@@ -2119,12 +2223,12 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = flist->low; i <= flist->high; i++) {
|
for (i = flist->low; i <= flist->high; i++) {
|
||||||
if (F_IS_ACTIVE(flist->files[i]))
|
if (F_IS_ACTIVE(flist->sorted[i]))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
flist->low = i;
|
flist->low = i;
|
||||||
for (i = flist->high; i >= flist->low; i--) {
|
for (i = flist->high; i >= flist->low; i--) {
|
||||||
if (F_IS_ACTIVE(flist->files[i]))
|
if (F_IS_ACTIVE(flist->sorted[i]))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
flist->high = i;
|
flist->high = i;
|
||||||
@@ -2369,6 +2473,7 @@ struct file_list *get_dirlist(char *dirname, int dlen, int ignore_filter_rules)
|
|||||||
if (do_progress)
|
if (do_progress)
|
||||||
flist_count_offset += dirlist->count;
|
flist_count_offset += dirlist->count;
|
||||||
|
|
||||||
|
dirlist->sorted = dirlist->files;
|
||||||
clean_flist(dirlist, 0, 0);
|
clean_flist(dirlist, 0, 0);
|
||||||
|
|
||||||
if (verbose > 3)
|
if (verbose > 3)
|
||||||
|
|||||||
46
generator.c
46
generator.c
@@ -97,6 +97,9 @@ extern char *backup_suffix;
|
|||||||
extern int backup_suffix_len;
|
extern int backup_suffix_len;
|
||||||
extern struct file_list *cur_flist, *first_flist, *dir_flist;
|
extern struct file_list *cur_flist, *first_flist, *dir_flist;
|
||||||
extern struct filter_list_struct server_filter_list;
|
extern struct filter_list_struct server_filter_list;
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
extern int ic_ndx;
|
||||||
|
#endif
|
||||||
|
|
||||||
int ignore_perishable = 0;
|
int ignore_perishable = 0;
|
||||||
int non_perishable_cnt = 0;
|
int non_perishable_cnt = 0;
|
||||||
@@ -415,15 +418,14 @@ static void do_delayed_deletions(char *delbuf)
|
|||||||
* MAXPATHLEN buffer with the name of the directory in it (the functions we
|
* MAXPATHLEN buffer with the name of the directory in it (the functions we
|
||||||
* call will append names onto the end, but the old dir value will be restored
|
* call will append names onto the end, but the old dir value will be restored
|
||||||
* on exit). */
|
* on exit). */
|
||||||
static void delete_in_dir(struct file_list *flist, char *fbuf,
|
static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
|
||||||
struct file_struct *file, dev_t *fs_dev)
|
|
||||||
{
|
{
|
||||||
static int already_warned = 0;
|
static int already_warned = 0;
|
||||||
struct file_list *dirlist;
|
struct file_list *dirlist;
|
||||||
char delbuf[MAXPATHLEN];
|
char delbuf[MAXPATHLEN];
|
||||||
int dlen, i;
|
int dlen, i;
|
||||||
|
|
||||||
if (!flist) {
|
if (!fbuf) {
|
||||||
change_local_filter_dir(NULL, 0, 0);
|
change_local_filter_dir(NULL, 0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -467,7 +469,7 @@ static void delete_in_dir(struct file_list *flist, char *fbuf,
|
|||||||
f_name(fp, NULL));
|
f_name(fp, NULL));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (flist_find(flist, fp) < 0) {
|
if (flist_find(cur_flist, fp) < 0) {
|
||||||
f_name(fp, delbuf);
|
f_name(fp, delbuf);
|
||||||
if (delete_during == 2) {
|
if (delete_during == 2) {
|
||||||
if (!remember_delete(fp, delbuf))
|
if (!remember_delete(fp, delbuf))
|
||||||
@@ -482,7 +484,7 @@ static void delete_in_dir(struct file_list *flist, char *fbuf,
|
|||||||
|
|
||||||
/* This deletes any files on the receiving side that are not present on the
|
/* This deletes any files on the receiving side that are not present on the
|
||||||
* sending side. This is used by --delete-before and --delete-after. */
|
* sending side. This is used by --delete-before and --delete-after. */
|
||||||
static void do_delete_pass(struct file_list *flist)
|
static void do_delete_pass(void)
|
||||||
{
|
{
|
||||||
char fbuf[MAXPATHLEN];
|
char fbuf[MAXPATHLEN];
|
||||||
STRUCT_STAT st;
|
STRUCT_STAT st;
|
||||||
@@ -492,8 +494,8 @@ static void do_delete_pass(struct file_list *flist)
|
|||||||
if (dry_run > 1 || list_only)
|
if (dry_run > 1 || list_only)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (j = 0; j < flist->count; j++) {
|
for (j = 0; j < cur_flist->count; j++) {
|
||||||
struct file_struct *file = flist->files[j];
|
struct file_struct *file = cur_flist->sorted[j];
|
||||||
|
|
||||||
if (!(file->flags & FLAG_XFER_DIR))
|
if (!(file->flags & FLAG_XFER_DIR))
|
||||||
continue;
|
continue;
|
||||||
@@ -506,9 +508,9 @@ static void do_delete_pass(struct file_list *flist)
|
|||||||
|| !S_ISDIR(st.st_mode))
|
|| !S_ISDIR(st.st_mode))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
delete_in_dir(flist, fbuf, file, &st.st_dev);
|
delete_in_dir(fbuf, file, &st.st_dev);
|
||||||
}
|
}
|
||||||
delete_in_dir(NULL, NULL, NULL, &dev_zero);
|
delete_in_dir(NULL, NULL, &dev_zero);
|
||||||
|
|
||||||
if (do_progress && !am_server)
|
if (do_progress && !am_server)
|
||||||
rprintf(FINFO, " \r");
|
rprintf(FINFO, " \r");
|
||||||
@@ -1271,7 +1273,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
|||||||
}
|
}
|
||||||
else if (delete_during && f_out != -1 && !phase && dry_run < 2
|
else if (delete_during && f_out != -1 && !phase && dry_run < 2
|
||||||
&& (file->flags & FLAG_XFER_DIR))
|
&& (file->flags & FLAG_XFER_DIR))
|
||||||
delete_in_dir(cur_flist, fname, file, &real_sx.st.st_dev);
|
delete_in_dir(fname, file, &real_sx.st.st_dev);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1731,7 +1733,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
|
|||||||
/* Fix any directory permissions that were modified during the
|
/* Fix any directory permissions that were modified during the
|
||||||
* transfer and/or re-set any tweaked modified-time values. */
|
* transfer and/or re-set any tweaked modified-time values. */
|
||||||
for (i = start, j = 0; i <= end; i++) {
|
for (i = start, j = 0; i <= end; i++) {
|
||||||
file = flist->files[i];
|
file = flist->sorted[i];
|
||||||
if (!F_IS_ACTIVE(file) || !S_ISDIR(file->mode)
|
if (!F_IS_ACTIVE(file) || !S_ISDIR(file->mode)
|
||||||
|| file->flags & FLAG_MISSING_DIR)
|
|| file->flags & FLAG_MISSING_DIR)
|
||||||
continue;
|
continue;
|
||||||
@@ -1827,7 +1829,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
|
|||||||
|
|
||||||
void generate_files(int f_out, const char *local_name)
|
void generate_files(int f_out, const char *local_name)
|
||||||
{
|
{
|
||||||
int i;
|
int i, ndx;
|
||||||
char fbuf[MAXPATHLEN];
|
char fbuf[MAXPATHLEN];
|
||||||
int itemizing;
|
int itemizing;
|
||||||
enum logcode code;
|
enum logcode code;
|
||||||
@@ -1860,7 +1862,7 @@ void generate_files(int f_out, const char *local_name)
|
|||||||
rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid());
|
rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid());
|
||||||
|
|
||||||
if (delete_before && !solo_file && cur_flist->count > 0)
|
if (delete_before && !solo_file && cur_flist->count > 0)
|
||||||
do_delete_pass(cur_flist);
|
do_delete_pass();
|
||||||
if (delete_during == 2) {
|
if (delete_during == 2) {
|
||||||
deldelay_size = BIGPATHBUFLEN * 4;
|
deldelay_size = BIGPATHBUFLEN * 4;
|
||||||
deldelay_buf = new_array(char, deldelay_size);
|
deldelay_buf = new_array(char, deldelay_size);
|
||||||
@@ -1896,21 +1898,27 @@ void generate_files(int f_out, const char *local_name)
|
|||||||
dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
|
dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
|
||||||
} else
|
} else
|
||||||
dirdev = MAKEDEV(0, 0);
|
dirdev = MAKEDEV(0, 0);
|
||||||
delete_in_dir(cur_flist, f_name(fp, fbuf), fp, &dirdev);
|
delete_in_dir(f_name(fp, fbuf), fp, &dirdev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = cur_flist->low; i <= cur_flist->high; i++) {
|
for (i = cur_flist->low; i <= cur_flist->high; i++) {
|
||||||
struct file_struct *file = cur_flist->files[i];
|
struct file_struct *file = cur_flist->sorted[i];
|
||||||
|
|
||||||
if (!F_IS_ACTIVE(file))
|
if (!F_IS_ACTIVE(file))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
if (ic_ndx)
|
||||||
|
ndx = F_NDX(file);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
ndx = i + cur_flist->ndx_start;
|
||||||
|
|
||||||
if (solo_file)
|
if (solo_file)
|
||||||
strlcpy(fbuf, solo_file, sizeof fbuf);
|
strlcpy(fbuf, solo_file, sizeof fbuf);
|
||||||
else
|
else
|
||||||
f_name(file, fbuf);
|
f_name(file, fbuf);
|
||||||
recv_generator(fbuf, file, i + cur_flist->ndx_start,
|
recv_generator(fbuf, file, ndx, itemizing, code, f_out);
|
||||||
itemizing, code, f_out);
|
|
||||||
|
|
||||||
/* We need to ensure that any dirs we create have
|
/* We need to ensure that any dirs we create have
|
||||||
* writeable permissions during the time we are putting
|
* writeable permissions during the time we are putting
|
||||||
@@ -1952,7 +1960,7 @@ void generate_files(int f_out, const char *local_name)
|
|||||||
} while ((cur_flist = cur_flist->next) != NULL);
|
} while ((cur_flist = cur_flist->next) != NULL);
|
||||||
|
|
||||||
if (delete_during)
|
if (delete_during)
|
||||||
delete_in_dir(NULL, NULL, NULL, &dev_zero);
|
delete_in_dir(NULL, NULL, &dev_zero);
|
||||||
phase++;
|
phase++;
|
||||||
if (verbose > 2)
|
if (verbose > 2)
|
||||||
rprintf(FINFO, "generate_files phase=%d\n", phase);
|
rprintf(FINFO, "generate_files phase=%d\n", phase);
|
||||||
@@ -1996,7 +2004,7 @@ void generate_files(int f_out, const char *local_name)
|
|||||||
if (delete_during == 2)
|
if (delete_during == 2)
|
||||||
do_delayed_deletions(fbuf);
|
do_delayed_deletions(fbuf);
|
||||||
if (delete_after && !solo_file && file_total > 0)
|
if (delete_after && !solo_file && file_total > 0)
|
||||||
do_delete_pass(cur_flist);
|
do_delete_pass();
|
||||||
|
|
||||||
if ((need_retouch_dir_perms || need_retouch_dir_times)
|
if ((need_retouch_dir_perms || need_retouch_dir_times)
|
||||||
&& dir_tweaking && (!inc_recurse || delete_during == 2))
|
&& dir_tweaking && (!inc_recurse || delete_during == 2))
|
||||||
|
|||||||
29
hlink.c
29
hlink.c
@@ -34,11 +34,13 @@ extern int stdout_format_has_i;
|
|||||||
extern int maybe_ATTRS_REPORT;
|
extern int maybe_ATTRS_REPORT;
|
||||||
extern char *basis_dir[];
|
extern char *basis_dir[];
|
||||||
extern struct file_list *cur_flist;
|
extern struct file_list *cur_flist;
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
extern int ic_ndx;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SUPPORT_HARD_LINKS
|
#ifdef SUPPORT_HARD_LINKS
|
||||||
|
|
||||||
#define HASH_LOAD_LIMIT(size) ((size)*3/4)
|
#define HASH_LOAD_LIMIT(size) ((size)*3/4)
|
||||||
#define FPTR(i) (cur_flist->files[i])
|
|
||||||
|
|
||||||
struct ihash_table {
|
struct ihash_table {
|
||||||
int32 size;
|
int32 size;
|
||||||
@@ -200,8 +202,8 @@ void idev_destroy(void)
|
|||||||
|
|
||||||
static int hlink_compare_gnum(int *int1, int *int2)
|
static int hlink_compare_gnum(int *int1, int *int2)
|
||||||
{
|
{
|
||||||
struct file_struct *f1 = FPTR(*int1);
|
struct file_struct *f1 = cur_flist->sorted[*int1];
|
||||||
struct file_struct *f2 = FPTR(*int2);
|
struct file_struct *f2 = cur_flist->sorted[*int2];
|
||||||
int32 gnum1 = F_HL_GNUM(f1);
|
int32 gnum1 = F_HL_GNUM(f1);
|
||||||
int32 gnum2 = F_HL_GNUM(f2);
|
int32 gnum2 = F_HL_GNUM(f2);
|
||||||
|
|
||||||
@@ -221,17 +223,24 @@ static void match_gnums(int32 *ndx_list, int ndx_count)
|
|||||||
(int (*)()) hlink_compare_gnum);
|
(int (*)()) hlink_compare_gnum);
|
||||||
|
|
||||||
for (from = 0; from < ndx_count; from++) {
|
for (from = 0; from < ndx_count; from++) {
|
||||||
for (file = FPTR(ndx_list[from]), gnum = F_HL_GNUM(file), prev = -1;
|
for (file = cur_flist->sorted[ndx_list[from]], gnum = F_HL_GNUM(file), prev = -1;
|
||||||
from < ndx_count-1;
|
from < ndx_count-1;
|
||||||
file = file_next, gnum = gnum_next, prev = ndx_list[from++])
|
file = file_next, gnum = gnum_next, from++)
|
||||||
{
|
{
|
||||||
file_next = FPTR(ndx_list[from+1]);
|
file_next = cur_flist->sorted[ndx_list[from+1]];
|
||||||
gnum_next = F_HL_GNUM(file_next);
|
gnum_next = F_HL_GNUM(file_next);
|
||||||
if (gnum != gnum_next)
|
if (gnum != gnum_next)
|
||||||
break;
|
break;
|
||||||
if (prev < 0)
|
if (prev < 0)
|
||||||
file->flags |= FLAG_HLINK_FIRST;
|
file->flags |= FLAG_HLINK_FIRST;
|
||||||
F_HL_PREV(file) = prev;
|
F_HL_PREV(file) = prev;
|
||||||
|
/* The linked list must use raw ndx values. */
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
if (ic_ndx)
|
||||||
|
prev = F_NDX(file);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
prev = ndx_list[from];
|
||||||
}
|
}
|
||||||
if (prev < 0)
|
if (prev < 0)
|
||||||
file->flags &= ~FLAG_HLINKED;
|
file->flags &= ~FLAG_HLINKED;
|
||||||
@@ -255,7 +264,7 @@ void match_hard_links(void)
|
|||||||
out_of_memory("match_hard_links");
|
out_of_memory("match_hard_links");
|
||||||
|
|
||||||
for (i = 0; i < cur_flist->count; i++) {
|
for (i = 0; i < cur_flist->count; i++) {
|
||||||
if (F_IS_HLINKED(FPTR(i)))
|
if (F_IS_HLINKED(cur_flist->sorted[i]))
|
||||||
ndx_list[ndx_count++] = i;
|
ndx_list[ndx_count++] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,7 +326,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
|
|||||||
STRUCT_STAT prev_st;
|
STRUCT_STAT prev_st;
|
||||||
char prev_name[MAXPATHLEN], altbuf[MAXPATHLEN], *realname;
|
char prev_name[MAXPATHLEN], altbuf[MAXPATHLEN], *realname;
|
||||||
int alt_dest, prev_ndx = F_HL_PREV(file);
|
int alt_dest, prev_ndx = F_HL_PREV(file);
|
||||||
struct file_struct *prev_file = FPTR(prev_ndx);
|
struct file_struct *prev_file = cur_flist->files[prev_ndx];
|
||||||
|
|
||||||
/* Is the previous link is not complete yet? */
|
/* Is the previous link is not complete yet? */
|
||||||
if (!(prev_file->flags & FLAG_HLINK_DONE)) {
|
if (!(prev_file->flags & FLAG_HLINK_DONE)) {
|
||||||
@@ -338,7 +347,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
|
|||||||
if (!(prev_file->flags & FLAG_HLINK_FIRST)) {
|
if (!(prev_file->flags & FLAG_HLINK_FIRST)) {
|
||||||
/* The previous previous will be marked with FIRST. */
|
/* The previous previous will be marked with FIRST. */
|
||||||
prev_ndx = F_HL_PREV(prev_file);
|
prev_ndx = F_HL_PREV(prev_file);
|
||||||
prev_file = FPTR(prev_ndx);
|
prev_file = cur_flist->files[prev_ndx];
|
||||||
/* Update our previous pointer to point to the first. */
|
/* Update our previous pointer to point to the first. */
|
||||||
F_HL_PREV(file) = prev_ndx;
|
F_HL_PREV(file) = prev_ndx;
|
||||||
}
|
}
|
||||||
@@ -475,7 +484,7 @@ void finish_hard_link(struct file_struct *file, const char *fname,
|
|||||||
|
|
||||||
while ((ndx = prev_ndx) >= 0) {
|
while ((ndx = prev_ndx) >= 0) {
|
||||||
int val;
|
int val;
|
||||||
file = FPTR(ndx);
|
file = cur_flist->files[ndx];
|
||||||
file->flags = (file->flags & ~FLAG_HLINK_FIRST) | FLAG_HLINK_DONE;
|
file->flags = (file->flags & ~FLAG_HLINK_FIRST) | FLAG_HLINK_DONE;
|
||||||
prev_ndx = F_HL_PREV(file);
|
prev_ndx = F_HL_PREV(file);
|
||||||
prev_name = f_name(file, NULL);
|
prev_name = f_name(file, NULL);
|
||||||
|
|||||||
115
io.c
115
io.c
@@ -53,6 +53,9 @@ extern int preserve_hard_links;
|
|||||||
extern char *filesfrom_host;
|
extern char *filesfrom_host;
|
||||||
extern struct stats stats;
|
extern struct stats stats;
|
||||||
extern struct file_list *cur_flist, *first_flist;
|
extern struct file_list *cur_flist, *first_flist;
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
extern iconv_t ic_send, ic_recv;
|
||||||
|
#endif
|
||||||
|
|
||||||
const char phase_unknown[] = "unknown";
|
const char phase_unknown[] = "unknown";
|
||||||
int ignore_timeout = 0;
|
int ignore_timeout = 0;
|
||||||
@@ -91,6 +94,9 @@ static int write_batch_monitor_out = -1;
|
|||||||
static int io_filesfrom_f_in = -1;
|
static int io_filesfrom_f_in = -1;
|
||||||
static int io_filesfrom_f_out = -1;
|
static int io_filesfrom_f_out = -1;
|
||||||
static char io_filesfrom_buf[2048];
|
static char io_filesfrom_buf[2048];
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
static char iconv_buf[sizeof io_filesfrom_buf / 2];
|
||||||
|
#endif
|
||||||
static char *io_filesfrom_bp;
|
static char *io_filesfrom_bp;
|
||||||
static char io_filesfrom_lastchar;
|
static char io_filesfrom_lastchar;
|
||||||
static int io_filesfrom_buflen;
|
static int io_filesfrom_buflen;
|
||||||
@@ -111,6 +117,7 @@ static void writefd(int fd, const char *buf, size_t len);
|
|||||||
static void writefd_unbuffered(int fd, const char *buf, size_t len);
|
static void writefd_unbuffered(int fd, const char *buf, size_t len);
|
||||||
static void decrement_active_files(int ndx);
|
static void decrement_active_files(int ndx);
|
||||||
static void decrement_flist_in_progress(int ndx, int redo);
|
static void decrement_flist_in_progress(int ndx, int redo);
|
||||||
|
static void mplex_write(int fd, enum msgcode code, const char *buf, size_t len, int convert);
|
||||||
|
|
||||||
struct flist_ndx_item {
|
struct flist_ndx_item {
|
||||||
struct flist_ndx_item *next;
|
struct flist_ndx_item *next;
|
||||||
@@ -125,7 +132,7 @@ static struct flist_ndx_list redo_list, hlink_list;
|
|||||||
|
|
||||||
struct msg_list_item {
|
struct msg_list_item {
|
||||||
struct msg_list_item *next;
|
struct msg_list_item *next;
|
||||||
int len;
|
char convert;
|
||||||
char buf[1];
|
char buf[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -229,7 +236,7 @@ void set_msg_fd_out(int fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add a message to the pending MSG_* list. */
|
/* Add a message to the pending MSG_* list. */
|
||||||
static void msg_list_add(struct msg_list *lst, int code, const char *buf, int len)
|
static void msg_list_add(struct msg_list *lst, int code, const char *buf, int len, int convert)
|
||||||
{
|
{
|
||||||
struct msg_list_item *m;
|
struct msg_list_item *m;
|
||||||
int sz = len + 4 + sizeof m[0] - 1;
|
int sz = len + 4 + sizeof m[0] - 1;
|
||||||
@@ -237,7 +244,7 @@ static void msg_list_add(struct msg_list *lst, int code, const char *buf, int le
|
|||||||
if (!(m = (struct msg_list_item *)new_array(char, sz)))
|
if (!(m = (struct msg_list_item *)new_array(char, sz)))
|
||||||
out_of_memory("msg_list_add");
|
out_of_memory("msg_list_add");
|
||||||
m->next = NULL;
|
m->next = NULL;
|
||||||
m->len = len + 4;
|
m->convert = convert;
|
||||||
SIVAL(m->buf, 0, ((code+MPLEX_BASE)<<24) | len);
|
SIVAL(m->buf, 0, ((code+MPLEX_BASE)<<24) | len);
|
||||||
memcpy(m->buf + 4, buf, len);
|
memcpy(m->buf + 4, buf, len);
|
||||||
if (lst->tail)
|
if (lst->tail)
|
||||||
@@ -252,21 +259,25 @@ static void msg_flush(void)
|
|||||||
if (am_generator) {
|
if (am_generator) {
|
||||||
while (msg_queue.head && io_multiplexing_out) {
|
while (msg_queue.head && io_multiplexing_out) {
|
||||||
struct msg_list_item *m = msg_queue.head;
|
struct msg_list_item *m = msg_queue.head;
|
||||||
|
int len = IVAL(m->buf, 0) & 0xFFFFFF;
|
||||||
|
int tag = *((uchar*)m->buf+3) - MPLEX_BASE;
|
||||||
if (!(msg_queue.head = m->next))
|
if (!(msg_queue.head = m->next))
|
||||||
msg_queue.tail = NULL;
|
msg_queue.tail = NULL;
|
||||||
stats.total_written += m->len;
|
stats.total_written += len + 4;
|
||||||
defer_forwarding_messages++;
|
defer_forwarding_messages++;
|
||||||
writefd_unbuffered(sock_f_out, m->buf, m->len);
|
mplex_write(sock_f_out, tag, m->buf + 4, len, m->convert);
|
||||||
defer_forwarding_messages--;
|
defer_forwarding_messages--;
|
||||||
free(m);
|
free(m);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (msg_queue.head) {
|
while (msg_queue.head) {
|
||||||
struct msg_list_item *m = msg_queue.head;
|
struct msg_list_item *m = msg_queue.head;
|
||||||
|
int len = IVAL(m->buf, 0) & 0xFFFFFF;
|
||||||
|
int tag = *((uchar*)m->buf+3) - MPLEX_BASE;
|
||||||
if (!(msg_queue.head = m->next))
|
if (!(msg_queue.head = m->next))
|
||||||
msg_queue.tail = NULL;
|
msg_queue.tail = NULL;
|
||||||
defer_forwarding_messages++;
|
defer_forwarding_messages++;
|
||||||
writefd_unbuffered(msg_fd_out, m->buf, m->len);
|
mplex_write(msg_fd_out, tag, m->buf + 4, len, m->convert);
|
||||||
defer_forwarding_messages--;
|
defer_forwarding_messages--;
|
||||||
free(m);
|
free(m);
|
||||||
}
|
}
|
||||||
@@ -341,7 +352,7 @@ static void read_msg_fd(void)
|
|||||||
if (len >= (int)sizeof buf || !am_generator)
|
if (len >= (int)sizeof buf || !am_generator)
|
||||||
goto invalid_msg;
|
goto invalid_msg;
|
||||||
readfd(fd, buf, len);
|
readfd(fd, buf, len);
|
||||||
send_msg(MSG_DELETED, buf, len);
|
send_msg(MSG_DELETED, buf, len, 1);
|
||||||
break;
|
break;
|
||||||
case MSG_SUCCESS:
|
case MSG_SUCCESS:
|
||||||
if (len != 4 || !am_generator)
|
if (len != 4 || !am_generator)
|
||||||
@@ -349,7 +360,7 @@ static void read_msg_fd(void)
|
|||||||
readfd(fd, buf, len);
|
readfd(fd, buf, len);
|
||||||
if (remove_source_files) {
|
if (remove_source_files) {
|
||||||
decrement_active_files(IVAL(buf,0));
|
decrement_active_files(IVAL(buf,0));
|
||||||
send_msg(MSG_SUCCESS, buf, len);
|
send_msg(MSG_SUCCESS, buf, len, 0);
|
||||||
}
|
}
|
||||||
if (preserve_hard_links)
|
if (preserve_hard_links)
|
||||||
flist_ndx_push(&hlink_list, IVAL(buf,0));
|
flist_ndx_push(&hlink_list, IVAL(buf,0));
|
||||||
@@ -378,7 +389,7 @@ static void read_msg_fd(void)
|
|||||||
if (n >= sizeof buf)
|
if (n >= sizeof buf)
|
||||||
n = sizeof buf - 1;
|
n = sizeof buf - 1;
|
||||||
readfd(fd, buf, n);
|
readfd(fd, buf, n);
|
||||||
rwrite((enum logcode)tag, buf, n);
|
rwrite((enum logcode)tag, buf, n, !am_generator);
|
||||||
len -= n;
|
len -= n;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -447,14 +458,19 @@ static void decrement_flist_in_progress(int ndx, int redo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write an message to a multiplexed stream. If this fails, rsync exits. */
|
/* Write an message to a multiplexed stream. If this fails, rsync exits. */
|
||||||
static void mplex_write(int fd, enum msgcode code, const char *buf, size_t len)
|
static void mplex_write(int fd, enum msgcode code, const char *buf, size_t len, int convert)
|
||||||
{
|
{
|
||||||
char buffer[1024];
|
char buffer[BIGPATHBUFLEN]; /* Oversized for use by iconv code. */
|
||||||
size_t n = len;
|
size_t n = len;
|
||||||
|
|
||||||
SIVAL(buffer, 0, ((MPLEX_BASE + (int)code)<<24) + len);
|
SIVAL(buffer, 0, ((MPLEX_BASE + (int)code)<<24) + len);
|
||||||
|
|
||||||
if (n > sizeof buffer - 4)
|
#ifdef ICONV_OPTION
|
||||||
|
if (convert && ic_send == (iconv_t)-1)
|
||||||
|
#endif
|
||||||
|
convert = 0;
|
||||||
|
|
||||||
|
if (convert || n > 1024 - 4) /* BIGPATHBUFLEN can handle 1024 bytes */
|
||||||
n = 0;
|
n = 0;
|
||||||
else
|
else
|
||||||
memcpy(buffer + 4, buf, n);
|
memcpy(buffer + 4, buf, n);
|
||||||
@@ -464,6 +480,28 @@ static void mplex_write(int fd, enum msgcode code, const char *buf, size_t len)
|
|||||||
len -= n;
|
len -= n;
|
||||||
buf += n;
|
buf += n;
|
||||||
|
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
if (convert) {
|
||||||
|
iconv(ic_send, NULL, 0, NULL, 0);
|
||||||
|
defer_forwarding_messages++;
|
||||||
|
while (len) {
|
||||||
|
ICONV_CONST char *ibuf = (ICONV_CONST char *)buf;
|
||||||
|
char *obuf = buffer;
|
||||||
|
size_t ocnt = sizeof buffer;
|
||||||
|
while (len && iconv(ic_send, &ibuf,&len,
|
||||||
|
&obuf,&ocnt) == (size_t)-1) {
|
||||||
|
if (errno == E2BIG || !ocnt)
|
||||||
|
break;
|
||||||
|
*obuf++ = *ibuf++;
|
||||||
|
ocnt--, len--;
|
||||||
|
}
|
||||||
|
n = obuf - buffer;
|
||||||
|
writefd_unbuffered(fd, buffer, n);
|
||||||
|
}
|
||||||
|
if (!--defer_forwarding_messages)
|
||||||
|
msg_flush();
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
if (len) {
|
if (len) {
|
||||||
defer_forwarding_messages++;
|
defer_forwarding_messages++;
|
||||||
writefd_unbuffered(fd, buf, len);
|
writefd_unbuffered(fd, buf, len);
|
||||||
@@ -472,20 +510,20 @@ static void mplex_write(int fd, enum msgcode code, const char *buf, size_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int send_msg(enum msgcode code, const char *buf, int len)
|
int send_msg(enum msgcode code, const char *buf, int len, int convert)
|
||||||
{
|
{
|
||||||
if (msg_fd_out < 0) {
|
if (msg_fd_out < 0) {
|
||||||
if (!defer_forwarding_messages)
|
if (!defer_forwarding_messages)
|
||||||
return io_multiplex_write(code, buf, len);
|
return io_multiplex_write(code, buf, len, convert);
|
||||||
if (!io_multiplexing_out)
|
if (!io_multiplexing_out)
|
||||||
return 0;
|
return 0;
|
||||||
msg_list_add(&msg_queue, code, buf, len);
|
msg_list_add(&msg_queue, code, buf, len, convert);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (flist_forward_from >= 0)
|
if (flist_forward_from >= 0)
|
||||||
msg_list_add(&msg_queue, code, buf, len);
|
msg_list_add(&msg_queue, code, buf, len, convert);
|
||||||
else
|
else
|
||||||
mplex_write(msg_fd_out, code, buf, len);
|
mplex_write(msg_fd_out, code, buf, len, convert);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,7 +531,7 @@ void send_msg_int(enum msgcode code, int num)
|
|||||||
{
|
{
|
||||||
char numbuf[4];
|
char numbuf[4];
|
||||||
SIVAL(numbuf, 0, num);
|
SIVAL(numbuf, 0, num);
|
||||||
send_msg(code, numbuf, 4);
|
send_msg(code, numbuf, 4, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wait_for_receiver(void)
|
void wait_for_receiver(void)
|
||||||
@@ -719,10 +757,8 @@ static int read_timeout(int fd, char *buf, size_t len)
|
|||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* Read a line into the "fname" buffer (which must be at least MAXPATHLEN
|
||||||
* Read a line into the "fname" buffer (which must be at least MAXPATHLEN
|
* characters long). */
|
||||||
* characters long).
|
|
||||||
*/
|
|
||||||
int read_filesfrom_line(int fd, char *fname)
|
int read_filesfrom_line(int fd, char *fname)
|
||||||
{
|
{
|
||||||
char ch, *s, *eob = fname + MAXPATHLEN - 1;
|
char ch, *s, *eob = fname + MAXPATHLEN - 1;
|
||||||
@@ -833,7 +869,7 @@ void maybe_send_keepalive(void)
|
|||||||
if (protocol_version < 29)
|
if (protocol_version < 29)
|
||||||
return; /* there's nothing we can do */
|
return; /* there's nothing we can do */
|
||||||
if (protocol_version >= 30)
|
if (protocol_version >= 30)
|
||||||
send_msg(MSG_NOOP, "", 0);
|
send_msg(MSG_NOOP, "", 0, 0);
|
||||||
else {
|
else {
|
||||||
write_int(sock_f_out, cur_flist->count);
|
write_int(sock_f_out, cur_flist->count);
|
||||||
write_shortint(sock_f_out, ITEM_IS_NEW);
|
write_shortint(sock_f_out, ITEM_IS_NEW);
|
||||||
@@ -932,7 +968,30 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
|
|||||||
case MSG_DELETED:
|
case MSG_DELETED:
|
||||||
if (msg_bytes >= sizeof line)
|
if (msg_bytes >= sizeof line)
|
||||||
goto overflow;
|
goto overflow;
|
||||||
read_loop(fd, line, msg_bytes);
|
#ifdef ICONV_OPTION
|
||||||
|
if (ic_recv != (iconv_t)-1) {
|
||||||
|
ICONV_CONST char *ibuf;
|
||||||
|
char *obuf = line;
|
||||||
|
size_t icnt, ocnt = sizeof line - 1;
|
||||||
|
int add_null = 0;
|
||||||
|
iconv(ic_send, NULL, 0, NULL, 0);
|
||||||
|
while (msg_bytes) {
|
||||||
|
icnt = msg_bytes > sizeof iconv_buf
|
||||||
|
? sizeof iconv_buf : msg_bytes;
|
||||||
|
read_loop(fd, iconv_buf, icnt);
|
||||||
|
if (!(msg_bytes -= icnt) && !iconv_buf[icnt-1])
|
||||||
|
icnt--, add_null = 1;
|
||||||
|
ibuf = (ICONV_CONST char *)iconv_buf;
|
||||||
|
if (iconv(ic_send, &ibuf,&icnt,
|
||||||
|
&obuf,&ocnt) == (size_t)-1)
|
||||||
|
goto overflow; // XXX
|
||||||
|
}
|
||||||
|
if (add_null)
|
||||||
|
*obuf++ = '\0';
|
||||||
|
msg_bytes = obuf - line;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
read_loop(fd, line, msg_bytes);
|
||||||
/* A directory name was sent with the trailing null */
|
/* A directory name was sent with the trailing null */
|
||||||
if (msg_bytes > 0 && !line[msg_bytes-1])
|
if (msg_bytes > 0 && !line[msg_bytes-1])
|
||||||
log_delete(line, S_IFDIR);
|
log_delete(line, S_IFDIR);
|
||||||
@@ -967,7 +1026,7 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
|
|||||||
exit_cleanup(RERR_STREAMIO);
|
exit_cleanup(RERR_STREAMIO);
|
||||||
}
|
}
|
||||||
read_loop(fd, line, msg_bytes);
|
read_loop(fd, line, msg_bytes);
|
||||||
rwrite((enum logcode)tag, line, msg_bytes);
|
rwrite((enum logcode)tag, line, msg_bytes, 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rprintf(FERROR, "unexpected tag %d [%s]\n",
|
rprintf(FERROR, "unexpected tag %d [%s]\n",
|
||||||
@@ -1372,7 +1431,7 @@ void io_flush(int flush_it_all)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (io_multiplexing_out)
|
if (io_multiplexing_out)
|
||||||
mplex_write(sock_f_out, MSG_DATA, iobuf_out, iobuf_out_cnt);
|
mplex_write(sock_f_out, MSG_DATA, iobuf_out, iobuf_out_cnt, 0);
|
||||||
else
|
else
|
||||||
writefd_unbuffered(iobuf_f_out, iobuf_out, iobuf_out_cnt);
|
writefd_unbuffered(iobuf_f_out, iobuf_out, iobuf_out_cnt);
|
||||||
iobuf_out_cnt = 0;
|
iobuf_out_cnt = 0;
|
||||||
@@ -1684,13 +1743,13 @@ void io_start_multiplex_in(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Write an message to the multiplexed data stream. */
|
/** Write an message to the multiplexed data stream. */
|
||||||
int io_multiplex_write(enum msgcode code, const char *buf, size_t len)
|
int io_multiplex_write(enum msgcode code, const char *buf, size_t len, int convert)
|
||||||
{
|
{
|
||||||
if (!io_multiplexing_out)
|
if (!io_multiplexing_out)
|
||||||
return 0;
|
return 0;
|
||||||
io_flush(NORMAL_FLUSH);
|
io_flush(NORMAL_FLUSH);
|
||||||
stats.total_written += (len+4);
|
stats.total_written += (len+4);
|
||||||
mplex_write(sock_f_out, code, buf, len);
|
mplex_write(sock_f_out, code, buf, len, convert);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
42
log.c
42
log.c
@@ -20,15 +20,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "rsync.h"
|
#include "rsync.h"
|
||||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
|
||||||
#include <iconv.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int verbose;
|
extern int verbose;
|
||||||
extern int dry_run;
|
extern int dry_run;
|
||||||
extern int am_daemon;
|
extern int am_daemon;
|
||||||
extern int am_server;
|
extern int am_server;
|
||||||
extern int am_sender;
|
extern int am_sender;
|
||||||
|
extern int am_generator;
|
||||||
extern int local_server;
|
extern int local_server;
|
||||||
extern int quiet;
|
extern int quiet;
|
||||||
extern int module_id;
|
extern int module_id;
|
||||||
@@ -47,9 +45,12 @@ extern char *auth_user;
|
|||||||
extern char *stdout_format;
|
extern char *stdout_format;
|
||||||
extern char *logfile_format;
|
extern char *logfile_format;
|
||||||
extern char *logfile_name;
|
extern char *logfile_name;
|
||||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
#ifdef ICONV_CONST
|
||||||
extern iconv_t ic_chck;
|
extern iconv_t ic_chck;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
extern iconv_t ic_send, ic_recv;
|
||||||
|
#endif
|
||||||
extern char curr_dir[];
|
extern char curr_dir[];
|
||||||
extern unsigned int module_dirlen;
|
extern unsigned int module_dirlen;
|
||||||
|
|
||||||
@@ -234,17 +235,25 @@ static void filtered_fwrite(FILE *f, const char *buf, int len, int use_isprint)
|
|||||||
/* this is the underlying (unformatted) rsync debugging function. Call
|
/* this is the underlying (unformatted) rsync debugging function. Call
|
||||||
* it with FINFO, FERROR or FLOG. Note: recursion can happen with
|
* it with FINFO, FERROR or FLOG. Note: recursion can happen with
|
||||||
* certain fatal conditions. */
|
* certain fatal conditions. */
|
||||||
void rwrite(enum logcode code, const char *buf, int len)
|
void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
|
||||||
{
|
{
|
||||||
int trailing_CR_or_NL;
|
int trailing_CR_or_NL;
|
||||||
FILE *f = NULL;
|
FILE *f = NULL;
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
iconv_t ic = is_utf8 && ic_recv != (iconv_t)-1 ? ic_recv : ic_chck;
|
||||||
|
#else
|
||||||
|
#ifdef ICONV_CONST
|
||||||
|
iconv_t ic = ic_chck;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
exit_cleanup(RERR_MESSAGEIO);
|
exit_cleanup(RERR_MESSAGEIO);
|
||||||
|
|
||||||
if (am_server && msg_fd_out >= 0) {
|
if (am_server && msg_fd_out >= 0) {
|
||||||
|
assert(!is_utf8);
|
||||||
/* Pass the message to our sibling. */
|
/* Pass the message to our sibling. */
|
||||||
send_msg((enum msgcode)code, buf, len);
|
send_msg((enum msgcode)code, buf, len, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +286,7 @@ void rwrite(enum logcode code, const char *buf, int len)
|
|||||||
|
|
||||||
if (am_server) {
|
if (am_server) {
|
||||||
/* Pass the message to the non-server side. */
|
/* Pass the message to the non-server side. */
|
||||||
if (send_msg((enum msgcode)code, buf, len))
|
if (send_msg((enum msgcode)code, buf, len, !is_utf8))
|
||||||
return;
|
return;
|
||||||
if (am_daemon) {
|
if (am_daemon) {
|
||||||
/* TODO: can we send the error to the user somehow? */
|
/* TODO: can we send the error to the user somehow? */
|
||||||
@@ -300,18 +309,15 @@ void rwrite(enum logcode code, const char *buf, int len)
|
|||||||
trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r')
|
trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r')
|
||||||
? buf[--len] : 0;
|
? buf[--len] : 0;
|
||||||
|
|
||||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
#ifdef ICONV_CONST
|
||||||
#ifndef ICONV_CONST
|
if (ic != (iconv_t)-1) {
|
||||||
#define ICONV_CONST
|
|
||||||
#endif
|
|
||||||
if (ic_chck != (iconv_t)-1) {
|
|
||||||
char convbuf[1024];
|
char convbuf[1024];
|
||||||
ICONV_CONST char *in_buf = (ICONV_CONST char *)buf;
|
ICONV_CONST char *in_buf = (ICONV_CONST char *)buf;
|
||||||
char *out_buf = convbuf;
|
char *out_buf = convbuf;
|
||||||
size_t in_cnt = len, out_cnt = sizeof convbuf - 1;
|
size_t in_cnt = len, out_cnt = sizeof convbuf - 1;
|
||||||
|
|
||||||
iconv(ic_chck, NULL, 0, NULL, 0);
|
iconv(ic, NULL, 0, NULL, 0);
|
||||||
while (iconv(ic_chck, &in_buf,&in_cnt,
|
while (iconv(ic, &in_buf,&in_cnt,
|
||||||
&out_buf,&out_cnt) == (size_t)-1) {
|
&out_buf,&out_cnt) == (size_t)-1) {
|
||||||
if (out_buf != convbuf) {
|
if (out_buf != convbuf) {
|
||||||
filtered_fwrite(f, convbuf, out_buf - convbuf, 0);
|
filtered_fwrite(f, convbuf, out_buf - convbuf, 0);
|
||||||
@@ -373,7 +379,7 @@ void rprintf(enum logcode code, const char *format, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rwrite(code, buf, len);
|
rwrite(code, buf, len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is like rprintf, but it also tries to print some
|
/* This is like rprintf, but it also tries to print some
|
||||||
@@ -404,7 +410,7 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
|
|||||||
if (len >= sizeof buf)
|
if (len >= sizeof buf)
|
||||||
exit_cleanup(RERR_MESSAGEIO);
|
exit_cleanup(RERR_MESSAGEIO);
|
||||||
|
|
||||||
rwrite(code, buf, len);
|
rwrite(code, buf, len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rflush(enum logcode code)
|
void rflush(enum logcode code)
|
||||||
@@ -681,7 +687,7 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
|
|||||||
p = s + len;
|
p = s + len;
|
||||||
}
|
}
|
||||||
|
|
||||||
rwrite(code, buf, total);
|
rwrite(code, buf, total, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return 1 if the format escape is in the log-format string (e.g. look for
|
/* Return 1 if the format escape is in the log-format string (e.g. look for
|
||||||
@@ -758,7 +764,7 @@ void log_delete(const char *fname, int mode)
|
|||||||
else if (am_server && protocol_version >= 29 && len < MAXPATHLEN) {
|
else if (am_server && protocol_version >= 29 && len < MAXPATHLEN) {
|
||||||
if (S_ISDIR(mode))
|
if (S_ISDIR(mode))
|
||||||
len++; /* directories include trailing null */
|
len++; /* directories include trailing null */
|
||||||
send_msg(MSG_DELETED, fname, len);
|
send_msg(MSG_DELETED, fname, len, am_generator);
|
||||||
} else {
|
} else {
|
||||||
fmt = stdout_format_has_o_or_i ? stdout_format : "deleting %n";
|
fmt = stdout_format_has_o_or_i ? stdout_format : "deleting %n";
|
||||||
log_formatted(FCLIENT, fmt, "del.", &x.file, fname, &stats,
|
log_formatted(FCLIENT, fmt, "del.", &x.file, fname, &stats,
|
||||||
|
|||||||
6
main.c
6
main.c
@@ -727,7 +727,7 @@ static int do_recv(int f_in, int f_out, char *local_name)
|
|||||||
io_flush(FULL_FLUSH);
|
io_flush(FULL_FLUSH);
|
||||||
handle_stats(f_in);
|
handle_stats(f_in);
|
||||||
|
|
||||||
send_msg(MSG_DONE, "", 1);
|
send_msg(MSG_DONE, "", 1, 0);
|
||||||
write_varlong(error_pipe[1], stats.total_read, 3);
|
write_varlong(error_pipe[1], stats.total_read, 3);
|
||||||
io_flush(FULL_FLUSH);
|
io_flush(FULL_FLUSH);
|
||||||
|
|
||||||
@@ -900,7 +900,7 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
|
|||||||
|
|
||||||
io_set_sock_fds(f_in, f_out);
|
io_set_sock_fds(f_in, f_out);
|
||||||
setup_protocol(f_out, f_in);
|
setup_protocol(f_out, f_in);
|
||||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
#ifdef ICONV_CONST
|
||||||
setup_iconv();
|
setup_iconv();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -937,7 +937,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
|
|||||||
|
|
||||||
io_set_sock_fds(f_in, f_out);
|
io_set_sock_fds(f_in, f_out);
|
||||||
setup_protocol(f_out,f_in);
|
setup_protocol(f_out,f_in);
|
||||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
#ifdef ICONV_CONST
|
||||||
setup_iconv();
|
setup_iconv();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
56
options.c
56
options.c
@@ -177,6 +177,11 @@ int list_only = 0;
|
|||||||
#define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */
|
#define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */
|
||||||
char *batch_name = NULL;
|
char *batch_name = NULL;
|
||||||
|
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
int need_unsorted_flist = 0;
|
||||||
|
char *iconv_opt = ICONV_OPTION;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct chmod_mode_struct *chmod_modes = NULL;
|
struct chmod_mode_struct *chmod_modes = NULL;
|
||||||
|
|
||||||
static int daemon_opt; /* sets am_daemon after option error-reporting */
|
static int daemon_opt; /* sets am_daemon after option error-reporting */
|
||||||
@@ -205,6 +210,7 @@ static void print_rsync_version(enum logcode f)
|
|||||||
char const *acls = "no ";
|
char const *acls = "no ";
|
||||||
char const *xattrs = "no ";
|
char const *xattrs = "no ";
|
||||||
char const *links = "no ";
|
char const *links = "no ";
|
||||||
|
char const *iconv = "no ";
|
||||||
char const *ipv6 = "no ";
|
char const *ipv6 = "no ";
|
||||||
STRUCT_STAT *dumstat;
|
STRUCT_STAT *dumstat;
|
||||||
|
|
||||||
@@ -232,6 +238,9 @@ static void print_rsync_version(enum logcode f)
|
|||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
ipv6 = "";
|
ipv6 = "";
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
iconv = "";
|
||||||
|
#endif
|
||||||
|
|
||||||
rprintf(f, "%s version %s protocol version %d%s\n",
|
rprintf(f, "%s version %s protocol version %d%s\n",
|
||||||
RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
|
RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
|
||||||
@@ -245,8 +254,8 @@ static void print_rsync_version(enum logcode f)
|
|||||||
(int)(sizeof (int64) * 8));
|
(int)(sizeof (int64) * 8));
|
||||||
rprintf(f, " %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n",
|
rprintf(f, " %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n",
|
||||||
got_socketpair, hardlinks, links, ipv6, have_inplace);
|
got_socketpair, hardlinks, links, ipv6, have_inplace);
|
||||||
rprintf(f, " %sappend, %sACLs, %sxattrs\n",
|
rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv\n",
|
||||||
have_inplace, acls, xattrs);
|
have_inplace, acls, xattrs, iconv);
|
||||||
|
|
||||||
#ifdef MAINTAINER_MODE
|
#ifdef MAINTAINER_MODE
|
||||||
rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
|
rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
|
||||||
@@ -399,6 +408,9 @@ void usage(enum logcode F)
|
|||||||
rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n");
|
rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n");
|
||||||
rprintf(F," --read-batch=FILE read a batched update from FILE\n");
|
rprintf(F," --read-batch=FILE read a batched update from FILE\n");
|
||||||
rprintf(F," --protocol=NUM force an older protocol version to be used\n");
|
rprintf(F," --protocol=NUM force an older protocol version to be used\n");
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
rprintf(F," --iconv=CONVERT_SPEC request charset conversion of filesnames\n");
|
||||||
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
rprintf(F," -4, --ipv4 prefer IPv4\n");
|
rprintf(F," -4, --ipv4 prefer IPv4\n");
|
||||||
rprintf(F," -6, --ipv6 prefer IPv6\n");
|
rprintf(F," -6, --ipv6 prefer IPv6\n");
|
||||||
@@ -560,6 +572,9 @@ static struct poptOption long_options[] = {
|
|||||||
{"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
|
{"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
|
||||||
{"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
|
{"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
|
||||||
{"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
|
{"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
{"iconv", 0, POPT_ARG_STRING, &iconv_opt, 0, 0, 0 },
|
||||||
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
{"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
|
{"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
|
||||||
{"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
|
{"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
|
||||||
@@ -832,6 +847,11 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
|||||||
if (am_daemon)
|
if (am_daemon)
|
||||||
set_refuse_options("log-file*");
|
set_refuse_options("log-file*");
|
||||||
|
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
if (!am_daemon && (arg = getenv("RSYNC_ICONV")) != NULL && *arg)
|
||||||
|
iconv_opt = strdup(arg);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TODO: Call poptReadDefaultConfig; handle errors. */
|
/* TODO: Call poptReadDefaultConfig; handle errors. */
|
||||||
|
|
||||||
/* The context leaks in case of an error, but if there's a
|
/* The context leaks in case of an error, but if there's a
|
||||||
@@ -857,6 +877,9 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
|||||||
long_options, 0);
|
long_options, 0);
|
||||||
am_server = 1;
|
am_server = 1;
|
||||||
}
|
}
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
iconv_opt = NULL;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPT_SENDER:
|
case OPT_SENDER:
|
||||||
@@ -874,6 +897,9 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
|||||||
sizeof err_buf);
|
sizeof err_buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
iconv_opt = NULL;
|
||||||
|
#endif
|
||||||
poptFreeContext(pc);
|
poptFreeContext(pc);
|
||||||
pc = poptGetContext(RSYNC_NAME, *argc, *argv,
|
pc = poptGetContext(RSYNC_NAME, *argc, *argv,
|
||||||
long_daemon_options, 0);
|
long_daemon_options, 0);
|
||||||
@@ -1175,6 +1201,15 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
|||||||
exit_cleanup(0);
|
exit_cleanup(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
if (iconv_opt) {
|
||||||
|
if (!am_server && strcmp(iconv_opt, "-") == 0)
|
||||||
|
iconv_opt = NULL;
|
||||||
|
else
|
||||||
|
need_unsorted_flist = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SUPPORT_LINKS
|
#ifndef SUPPORT_LINKS
|
||||||
if (preserve_links && !am_sender) {
|
if (preserve_links && !am_sender) {
|
||||||
snprintf(err_buf, sizeof err_buf,
|
snprintf(err_buf, sizeof err_buf,
|
||||||
@@ -1655,8 +1690,6 @@ void server_options(char **args,int *argc)
|
|||||||
if (list_only == 1 && !recurse)
|
if (list_only == 1 && !recurse)
|
||||||
argstr[x++] = 'r';
|
argstr[x++] = 'r';
|
||||||
|
|
||||||
argstr[x] = '\0';
|
|
||||||
|
|
||||||
#if SUBPROTOCOL_VERSION != 0
|
#if SUBPROTOCOL_VERSION != 0
|
||||||
/* If we're speaking a pre-release version of a protocol, we tell
|
/* If we're speaking a pre-release version of a protocol, we tell
|
||||||
* the server about this by (ab)using the -e option. */
|
* the server about this by (ab)using the -e option. */
|
||||||
@@ -1666,6 +1699,8 @@ void server_options(char **args,int *argc)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
argstr[x] = '\0';
|
||||||
|
|
||||||
if (x != 1)
|
if (x != 1)
|
||||||
args[ac++] = argstr;
|
args[ac++] = argstr;
|
||||||
|
|
||||||
@@ -1704,6 +1739,19 @@ void server_options(char **args,int *argc)
|
|||||||
args[ac++] = "--log-format=X";
|
args[ac++] = "--log-format=X";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
if (iconv_opt) {
|
||||||
|
char *set = strchr(iconv_opt, ',');
|
||||||
|
if (set)
|
||||||
|
set++;
|
||||||
|
else
|
||||||
|
set = iconv_opt;
|
||||||
|
if (asprintf(&arg, "--iconv=%s", set) < 0)
|
||||||
|
goto oom;
|
||||||
|
args[ac++] = arg;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (block_size) {
|
if (block_size) {
|
||||||
if (asprintf(&arg, "-B%lu", block_size) < 0)
|
if (asprintf(&arg, "-B%lu", block_size) < 0)
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ int recv_files(int f_in, char *local_name)
|
|||||||
rprintf(FINFO, "recv_files phase=%d\n", phase);
|
rprintf(FINFO, "recv_files phase=%d\n", phase);
|
||||||
if (phase == 2 && delay_updates)
|
if (phase == 2 && delay_updates)
|
||||||
handle_delayed_updates(local_name);
|
handle_delayed_updates(local_name);
|
||||||
send_msg(MSG_DONE, "", 0);
|
send_msg(MSG_DONE, "", 0, 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
59
rsync.c
59
rsync.c
@@ -20,9 +20,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "rsync.h"
|
#include "rsync.h"
|
||||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
|
||||||
#include <iconv.h>
|
|
||||||
#endif
|
|
||||||
#if defined HAVE_LIBCHARSET_H && defined HAVE_LOCALE_CHARSET
|
#if defined HAVE_LIBCHARSET_H && defined HAVE_LOCALE_CHARSET
|
||||||
#include <libcharset.h>
|
#include <libcharset.h>
|
||||||
#elif defined HAVE_LANGINFO_H && defined HAVE_NL_LANGINFO
|
#elif defined HAVE_LANGINFO_H && defined HAVE_NL_LANGINFO
|
||||||
@@ -53,9 +50,16 @@ extern int keep_dirlinks;
|
|||||||
extern int make_backups;
|
extern int make_backups;
|
||||||
extern struct file_list *cur_flist, *first_flist, *dir_flist;
|
extern struct file_list *cur_flist, *first_flist, *dir_flist;
|
||||||
extern struct chmod_mode_struct *daemon_chmod_modes;
|
extern struct chmod_mode_struct *daemon_chmod_modes;
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
extern char *iconv_opt;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
#ifdef ICONV_CONST
|
||||||
iconv_t ic_chck = (iconv_t)-1;
|
iconv_t ic_chck = (iconv_t)-1;
|
||||||
|
#ifdef ICONV_OPTION
|
||||||
|
iconv_t ic_send = (iconv_t)-1, ic_recv = (iconv_t)-1;
|
||||||
|
int ic_ndx;
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char *default_charset(void)
|
static const char *default_charset(void)
|
||||||
{
|
{
|
||||||
@@ -70,8 +74,13 @@ static const char *default_charset(void)
|
|||||||
|
|
||||||
void setup_iconv()
|
void setup_iconv()
|
||||||
{
|
{
|
||||||
|
const char *defset = default_charset();
|
||||||
|
# ifdef ICONV_OPTION
|
||||||
|
const char *charset;
|
||||||
|
char *cp;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!am_server && !allow_8bit_chars) {
|
if (!am_server && !allow_8bit_chars) {
|
||||||
const char *defset = default_charset();
|
|
||||||
|
|
||||||
/* It's OK if this fails... */
|
/* It's OK if this fails... */
|
||||||
ic_chck = iconv_open(defset, defset);
|
ic_chck = iconv_open(defset, defset);
|
||||||
@@ -89,6 +98,44 @@ void setup_iconv()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef ICONV_OPTION
|
||||||
|
if (!iconv_opt)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((cp = strchr(iconv_opt, ',')) != NULL) {
|
||||||
|
if (am_server) /* A local transfer needs this. */
|
||||||
|
iconv_opt = cp + 1;
|
||||||
|
else
|
||||||
|
*cp = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*iconv_opt || (*iconv_opt == '.' && iconv_opt[1] == '\0'))
|
||||||
|
charset = defset;
|
||||||
|
else
|
||||||
|
charset = iconv_opt;
|
||||||
|
|
||||||
|
if ((ic_send = iconv_open(UTF8_CHARSET, charset)) == (iconv_t)-1) {
|
||||||
|
rprintf(FERROR, "iconv_open(\"%s\", \"%s\") failed\n",
|
||||||
|
UTF8_CHARSET, charset);
|
||||||
|
exit_cleanup(RERR_UNSUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ic_recv = iconv_open(charset, UTF8_CHARSET)) == (iconv_t)-1) {
|
||||||
|
rprintf(FERROR, "iconv_open(\"%s\", \"%s\") failed\n",
|
||||||
|
charset, UTF8_CHARSET);
|
||||||
|
exit_cleanup(RERR_UNSUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!am_sender)
|
||||||
|
ic_ndx = ++file_extra_cnt;
|
||||||
|
|
||||||
|
if (verbose > 1) {
|
||||||
|
rprintf(FINFO, "%s charset: %s\n",
|
||||||
|
am_server ? "server" : "client",
|
||||||
|
*charset ? charset : "[LOCALE]");
|
||||||
|
}
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -112,7 +159,7 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
|
|||||||
goto invalid_ndx;
|
goto invalid_ndx;
|
||||||
if (ndx == NDX_FLIST_EOF) {
|
if (ndx == NDX_FLIST_EOF) {
|
||||||
flist_eof = 1;
|
flist_eof = 1;
|
||||||
send_msg(MSG_FLIST_EOF, "", 0);
|
send_msg(MSG_FLIST_EOF, "", 0, 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ndx = NDX_FLIST_OFFSET - ndx;
|
ndx = NDX_FLIST_OFFSET - ndx;
|
||||||
|
|||||||
12
rsync.h
12
rsync.h
@@ -362,6 +362,15 @@ enum msgcode {
|
|||||||
# include <limits.h>
|
# include <limits.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
||||||
|
#include <iconv.h>
|
||||||
|
#ifndef ICONV_CONST
|
||||||
|
#define ICONV_CONST
|
||||||
|
#endif
|
||||||
|
#elif defined ICONV_CONST
|
||||||
|
#undef ICONV_CONST
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "lib/pool_alloc.h"
|
#include "lib/pool_alloc.h"
|
||||||
@@ -609,6 +618,7 @@ extern int preserve_xattrs;
|
|||||||
#define F_GROUP(f) REQ_EXTRA(f, preserve_gid)->unum
|
#define F_GROUP(f) REQ_EXTRA(f, preserve_gid)->unum
|
||||||
#define F_ACL(f) REQ_EXTRA(f, preserve_acls)->num
|
#define F_ACL(f) REQ_EXTRA(f, preserve_acls)->num
|
||||||
#define F_XATTR(f) REQ_EXTRA(f, preserve_xattrs)->num
|
#define F_XATTR(f) REQ_EXTRA(f, preserve_xattrs)->num
|
||||||
|
#define F_NDX(f) REQ_EXTRA(f, ic_ndx)->num
|
||||||
|
|
||||||
/* These items are per-entry optional and mutally exclusive: */
|
/* These items are per-entry optional and mutally exclusive: */
|
||||||
#define F_HL_GNUM(f) OPT_EXTRA(f, LEN64_BUMP(f))->num
|
#define F_HL_GNUM(f) OPT_EXTRA(f, LEN64_BUMP(f))->num
|
||||||
@@ -665,7 +675,7 @@ extern int preserve_xattrs;
|
|||||||
|
|
||||||
struct file_list {
|
struct file_list {
|
||||||
struct file_list *next, *prev;
|
struct file_list *next, *prev;
|
||||||
struct file_struct **files;
|
struct file_struct **files, **sorted;
|
||||||
alloc_pool_t file_pool;
|
alloc_pool_t file_pool;
|
||||||
int count, malloced;
|
int count, malloced;
|
||||||
int low, high; /* 0-relative index values excluding empties */
|
int low, high; /* 0-relative index values excluding empties */
|
||||||
|
|||||||
21
rsync.yo
21
rsync.yo
@@ -402,6 +402,7 @@ to the detailed description below for a complete description. verb(
|
|||||||
--only-write-batch=FILE like --write-batch but w/o updating dest
|
--only-write-batch=FILE like --write-batch but w/o updating dest
|
||||||
--read-batch=FILE read a batched update from FILE
|
--read-batch=FILE read a batched update from FILE
|
||||||
--protocol=NUM force an older protocol version to be used
|
--protocol=NUM force an older protocol version to be used
|
||||||
|
--iconv=CONVERT_SPEC request charset conversion of filesnames
|
||||||
--checksum-seed=NUM set block/file checksum seed (advanced)
|
--checksum-seed=NUM set block/file checksum seed (advanced)
|
||||||
-4, --ipv4 prefer IPv4
|
-4, --ipv4 prefer IPv4
|
||||||
-6, --ipv6 prefer IPv6
|
-6, --ipv6 prefer IPv6
|
||||||
@@ -1866,6 +1867,24 @@ bf(--read-batch) option, you should use "--protocol=28" when creating the
|
|||||||
batch file to force the older protocol version to be used in the batch
|
batch file to force the older protocol version to be used in the batch
|
||||||
file (assuming you can't upgrade the rsync on the reading system).
|
file (assuming you can't upgrade the rsync on the reading system).
|
||||||
|
|
||||||
|
dit(bf(--iconv=CONVERT_SPEC)) Rsync can convert filenames between character
|
||||||
|
sets using this option. Using a CONVERT_SPEC of "." tells rsync to look up
|
||||||
|
the default character-set via the locale setting. Alternately, you can
|
||||||
|
fully specify what conversion to do by giving a local and a remote charset
|
||||||
|
separated by a comma (local first), e.g. bf(--iconv=utf8,iso88591).
|
||||||
|
Finally, you can specify a CONVERT_SPEC of "-" to turn off any conversion.
|
||||||
|
The default setting of this option is site-specific, and can also be
|
||||||
|
affected via the RSYNC_ICONV environment variable.
|
||||||
|
|
||||||
|
Note that rsync does not do any conversion of names in filter files
|
||||||
|
(including include/exclude files), in a files-from file, nor those
|
||||||
|
specified on the command line. It is up to you to ensure that you're
|
||||||
|
requesting the right names from a remote server, and you can specify
|
||||||
|
extra include/exclude rules if there are filename differences on the
|
||||||
|
two sides that need to be accounted for. (In the future there may be
|
||||||
|
a way to specify a UTF-8 filter rule that gets auto-converted to the
|
||||||
|
local side's character set.)
|
||||||
|
|
||||||
dit(bf(-4, --ipv4) or bf(-6, --ipv6)) Tells rsync to prefer IPv4/IPv6
|
dit(bf(-4, --ipv4) or bf(-6, --ipv6)) Tells rsync to prefer IPv4/IPv6
|
||||||
when creating sockets. This only affects sockets that rsync has direct
|
when creating sockets. This only affects sockets that rsync has direct
|
||||||
control over, such as the outgoing socket when directly contacting an
|
control over, such as the outgoing socket when directly contacting an
|
||||||
@@ -2617,6 +2636,8 @@ startdit()
|
|||||||
dit(bf(CVSIGNORE)) The CVSIGNORE environment variable supplements any
|
dit(bf(CVSIGNORE)) The CVSIGNORE environment variable supplements any
|
||||||
ignore patterns in .cvsignore files. See the bf(--cvs-exclude) option for
|
ignore patterns in .cvsignore files. See the bf(--cvs-exclude) option for
|
||||||
more details.
|
more details.
|
||||||
|
dit(bf(RSYNC_ICONV)) Specify a default bf(--iconv) setting using this
|
||||||
|
environment variable.
|
||||||
dit(bf(RSYNC_RSH)) The RSYNC_RSH environment variable allows you to
|
dit(bf(RSYNC_RSH)) The RSYNC_RSH environment variable allows you to
|
||||||
override the default shell used as the transport for rsync. Command line
|
override the default shell used as the transport for rsync. Command line
|
||||||
options are permitted after the command name, just as in the bf(-e) option.
|
options are permitted after the command name, just as in the bf(-e) option.
|
||||||
|
|||||||
2
socket.c
2
socket.c
@@ -409,7 +409,7 @@ static int *open_socket_in(int type, int port, const char *bind_addr,
|
|||||||
* unsuccessful, or if the daemon is being run with -vv. */
|
* unsuccessful, or if the daemon is being run with -vv. */
|
||||||
for (s = 0; s < ecnt; s++) {
|
for (s = 0; s < ecnt; s++) {
|
||||||
if (!i || verbose > 1)
|
if (!i || verbose > 1)
|
||||||
rwrite(FLOG, errmsgs[s], strlen(errmsgs[s]));
|
rwrite(FLOG, errmsgs[s], strlen(errmsgs[s]), 0);
|
||||||
free(errmsgs[s]);
|
free(errmsgs[s]);
|
||||||
}
|
}
|
||||||
free(errmsgs);
|
free(errmsgs);
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ filter_outfile() {
|
|||||||
-e '/^done$/d' \
|
-e '/^done$/d' \
|
||||||
-e '/ --whole-file$/d' \
|
-e '/ --whole-file$/d' \
|
||||||
-e '/^total: /d' \
|
-e '/^total: /d' \
|
||||||
|
-e '/^client charset: /d' \
|
||||||
|
-e '/^server charset: /d' \
|
||||||
-e '/^$/,$d' \
|
-e '/^$/,$d' \
|
||||||
<"$outfile" >"$outfile.new"
|
<"$outfile" >"$outfile.new"
|
||||||
mv "$outfile.new" "$outfile"
|
mv "$outfile.new" "$outfile"
|
||||||
|
|||||||
Reference in New Issue
Block a user