* Copyright (C) 1996-2001 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2013 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
*
* 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
extern int am_sender;
extern int am_receiver;
extern int am_generator;
+extern int local_server;
extern int msgs2stderr;
extern int inc_recurse;
extern int io_error;
+extern int batch_fd;
extern int eol_nulls;
extern int flist_eof;
extern int file_total;
extern int compat_flags;
extern int protect_args;
extern int checksum_seed;
+extern int daemon_connection;
extern int protocol_version;
extern int remove_source_files;
extern int preserve_hard_links;
extern BOOL extra_flist_sending_enabled;
extern BOOL flush_ok_after_signal;
extern struct stats stats;
+extern time_t stop_at_utime;
extern struct file_list *cur_flist;
#ifdef ICONV_OPTION
extern int filesfrom_convert;
int csum_length = SHORT_SUM_LENGTH; /* initial value */
int allowed_lull = 0;
-int batch_fd = -1;
int msgdone_cnt = 0;
int forward_flist_data = 0;
BOOL flist_receiving_enabled = False;
int64 total_data_read = 0;
int64 total_data_written = 0;
+char num_dev_ino_buf[4 + 8 + 8];
+
static struct {
xbuf in, out, msg;
int in_fd;
cnt = select(fd+1, &r_fds, NULL, &e_fds, &tv);
if (cnt <= 0) {
if (cnt < 0 && errno == EBADF) {
- rsyserr(FERROR, errno, "safe_read select failed [%s]",
- who_am_i());
+ rsyserr(FERROR, errno, "safe_read select failed");
exit_cleanup(RERR_FILEIO);
}
check_timeout(1, MSK_ALLOW_FLUSH);
rprintf(FINFO, "select exception on fd %d\n", fd); */
if (FD_ISSET(fd, &r_fds)) {
- int n = read(fd, buf + got, len - got);
- if (DEBUG_GTE(IO, 2))
- rprintf(FINFO, "[%s] safe_read(%d)=%ld\n", who_am_i(), fd, (long)n);
+ ssize_t n = read(fd, buf + got, len - got);
+ if (DEBUG_GTE(IO, 2)) {
+ rprintf(FINFO, "[%s] safe_read(%d)=%" SIZE_T_FMT_MOD "d\n",
+ who_am_i(), fd, (SIZE_T_FMT_CAST)n);
+ }
if (n == 0)
break;
if (n < 0) {
if (errno == EINTR)
continue;
- rsyserr(FERROR, errno, "safe_read failed to read %ld bytes [%s]",
- (long)len, who_am_i());
+ rsyserr(FERROR, errno, "safe_read failed to read %" SIZE_T_FMT_MOD "d bytes",
+ (SIZE_T_FMT_CAST)len);
exit_cleanup(RERR_STREAMIO);
}
if ((got += (size_t)n) == len)
* is not used on the socket except very early in the transfer. */
static void safe_write(int fd, const char *buf, size_t len)
{
- int n;
+ ssize_t n;
assert(fd != iobuf.out_fd);
if (errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN) {
write_failed:
rsyserr(FERROR, errno,
- "safe_write failed to write %ld bytes to %s [%s]",
- (long)len, what_fd_is(fd), who_am_i());
+ "safe_write failed to write %" SIZE_T_FMT_MOD "d bytes to %s",
+ (SIZE_T_FMT_CAST)len, what_fd_is(fd));
exit_cleanup(RERR_STREAMIO);
}
} else {
cnt = select(fd + 1, NULL, &w_fds, NULL, &tv);
if (cnt <= 0) {
if (cnt < 0 && errno == EBADF) {
- rsyserr(FERROR, errno, "safe_write select failed on %s [%s]",
- what_fd_is(fd), who_am_i());
+ rsyserr(FERROR, errno, "safe_write select failed on %s", what_fd_is(fd));
exit_cleanup(RERR_FILEIO);
}
if (io_timeout)
* a chunk of data and put it into the output buffer. */
static void forward_filesfrom_data(void)
{
- int len;
+ ssize_t len;
len = read(ff_forward_fd, ff_xb.buf + ff_xb.len, ff_xb.size - ff_xb.len);
if (len <= 0) {
free_xbuf(&ff_xb);
if (ff_reenable_multiplex >= 0)
io_start_multiplex_out(ff_reenable_multiplex);
+ free_implied_include_partial_string();
}
return;
}
- if (DEBUG_GTE(IO, 2))
- rprintf(FINFO, "[%s] files-from read=%ld\n", who_am_i(), (long)len);
+ if (DEBUG_GTE(IO, 2)) {
+ rprintf(FINFO, "[%s] files-from read=%" SIZE_T_FMT_MOD "d\n",
+ who_am_i(), (SIZE_T_FMT_CAST)len);
+ }
#ifdef ICONV_OPTION
len += ff_xb.len;
while (s != eob) {
if (*s++ == '\0') {
ff_xb.len = s - sob - 1;
+ add_implied_include(sob, 0);
if (iconvbufs(ic_send, &ff_xb, &iobuf.out, flags) < 0)
exit_cleanup(RERR_PROTOCOL); /* impossible? */
write_buf(iobuf.out_fd, s-1, 1); /* Send the '\0'. */
ff_lastchar = '\0';
else {
/* Handle a partial string specially, saving any incomplete chars. */
+ implied_include_partial_string(sob, s);
flags &= ~ICB_INCLUDE_INCOMPLETE;
if (iconvbufs(ic_send, &ff_xb, &iobuf.out, flags) < 0) {
if (errno == E2BIG)
char *f = ff_xb.buf + ff_xb.pos;
char *t = ff_xb.buf;
char *eob = f + len;
+ char *cur = t;
/* Eliminate any multi-'\0' runs. */
while (f != eob) {
if (!(*t++ = *f++)) {
+ add_implied_include(cur, 0);
+ cur = t;
while (f != eob && *f == '\0')
f++;
}
}
+ implied_include_partial_string(cur, t);
ff_lastchar = f[-1];
if ((len = t - ff_xb.buf) != 0) {
/* This will not circle back to perform_io() because we only get
{
if (new_size < out->size) {
/* Avoid weird buffer interactions by only outputting this to stderr. */
- if (msgs2stderr && DEBUG_GTE(IO, 4)) {
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 4)) {
const char *name = out == &iobuf.out ? "iobuf.out"
: out == &iobuf.msg ? "iobuf.msg"
: NULL;
if (IOBUF_WAS_REDUCED(out->size)) {
size_t new_size = IOBUF_RESTORE_SIZE(out->size);
/* Avoid weird buffer interactions by only outputting this to stderr. */
- if (msgs2stderr && DEBUG_GTE(IO, 4)) {
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 4)) {
const char *name = out == &iobuf.out ? "iobuf.out"
: out == &iobuf.msg ? "iobuf.msg"
: NULL;
case PIO_NEED_INPUT:
/* We never resize the circular input buffer. */
if (iobuf.in.size < needed) {
- rprintf(FERROR, "need to read %ld bytes, iobuf.in.buf is only %ld bytes.\n",
- (long)needed, (long)iobuf.in.size);
+ rprintf(FERROR, "need to read %" SIZE_T_FMT_MOD "d bytes,"
+ " iobuf.in.buf is only %" SIZE_T_FMT_MOD "d bytes.\n",
+ (SIZE_T_FMT_CAST)needed, (SIZE_T_FMT_CAST)iobuf.in.size);
exit_cleanup(RERR_PROTOCOL);
}
- if (msgs2stderr && DEBUG_GTE(IO, 3)) {
- rprintf(FINFO, "[%s] perform_io(%ld, %sinput)\n",
- who_am_i(), (long)needed, flags & PIO_CONSUME_INPUT ? "consume&" : "");
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
+ rprintf(FINFO, "[%s] perform_io(%" SIZE_T_FMT_MOD "d, %sinput)\n",
+ who_am_i(), (SIZE_T_FMT_CAST)needed, flags & PIO_CONSUME_INPUT ? "consume&" : "");
}
break;
case PIO_NEED_OUTROOM:
/* We never resize the circular output buffer. */
if (iobuf.out.size - iobuf.out_empty_len < needed) {
- fprintf(stderr, "need to write %ld bytes, iobuf.out.buf is only %ld bytes.\n",
- (long)needed, (long)(iobuf.out.size - iobuf.out_empty_len));
+ fprintf(stderr, "need to write %" SIZE_T_FMT_MOD "d bytes,"
+ " iobuf.out.buf is only %" SIZE_T_FMT_MOD "d bytes.\n",
+ (SIZE_T_FMT_CAST)needed, (SIZE_T_FMT_CAST)(iobuf.out.size - iobuf.out_empty_len));
exit_cleanup(RERR_PROTOCOL);
}
- if (msgs2stderr && DEBUG_GTE(IO, 3)) {
- rprintf(FINFO, "[%s] perform_io(%ld, outroom) needs to flush %ld\n",
- who_am_i(), (long)needed,
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
+ rprintf(FINFO, "[%s] perform_io(%" SIZE_T_FMT_MOD "d,"
+ " outroom) needs to flush %" SIZE_T_FMT_MOD "d\n",
+ who_am_i(), (SIZE_T_FMT_CAST)needed,
iobuf.out.len + needed > iobuf.out.size
- ? (long)(iobuf.out.len + needed - iobuf.out.size) : 0L);
+ ? (SIZE_T_FMT_CAST)(iobuf.out.len + needed - iobuf.out.size) : (SIZE_T_FMT_CAST)0);
}
break;
case PIO_NEED_MSGROOM:
/* We never resize the circular message buffer. */
if (iobuf.msg.size < needed) {
- fprintf(stderr, "need to write %ld bytes, iobuf.msg.buf is only %ld bytes.\n",
- (long)needed, (long)iobuf.msg.size);
+ fprintf(stderr, "need to write %" SIZE_T_FMT_MOD "d bytes,"
+ " iobuf.msg.buf is only %" SIZE_T_FMT_MOD "d bytes.\n",
+ (SIZE_T_FMT_CAST)needed, (SIZE_T_FMT_CAST)iobuf.msg.size);
exit_cleanup(RERR_PROTOCOL);
}
- if (msgs2stderr && DEBUG_GTE(IO, 3)) {
- rprintf(FINFO, "[%s] perform_io(%ld, msgroom) needs to flush %ld\n",
- who_am_i(), (long)needed,
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
+ rprintf(FINFO, "[%s] perform_io(%" SIZE_T_FMT_MOD "d,"
+ " msgroom) needs to flush %" SIZE_T_FMT_MOD "d\n",
+ who_am_i(), (SIZE_T_FMT_CAST)needed,
iobuf.msg.len + needed > iobuf.msg.size
- ? (long)(iobuf.msg.len + needed - iobuf.msg.size) : 0L);
+ ? (SIZE_T_FMT_CAST)(iobuf.msg.len + needed - iobuf.msg.size) : (SIZE_T_FMT_CAST)0);
}
break;
case 0:
- if (msgs2stderr && DEBUG_GTE(IO, 3))
- rprintf(FINFO, "[%s] perform_io(%ld, %d)\n", who_am_i(), (long)needed, flags);
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
+ rprintf(FINFO, "[%s] perform_io(%" SIZE_T_FMT_MOD "d, %d)\n",
+ who_am_i(), (SIZE_T_FMT_CAST)needed, flags);
+ }
break;
default:
SIVAL(iobuf.out.buf + iobuf.raw_data_header_pos, 0,
((MPLEX_BASE + (int)MSG_DATA)<<24) + iobuf.out.len - 4);
- if (msgs2stderr && DEBUG_GTE(IO, 1)) {
- rprintf(FINFO, "[%s] send_msg(%d, %ld)\n",
- who_am_i(), (int)MSG_DATA, (long)iobuf.out.len - 4);
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 1)) {
+ rprintf(FINFO, "[%s] send_msg(%d, %" SIZE_T_FMT_MOD "d)\n",
+ who_am_i(), (int)MSG_DATA, (SIZE_T_FMT_CAST)iobuf.out.len - 4);
}
/* reserve room for the next MSG_DATA header */
if (iobuf.in_fd >= 0 && FD_ISSET(iobuf.in_fd, &r_fds)) {
size_t len, pos = iobuf.in.pos + iobuf.in.len;
- int n;
+ ssize_t n;
if (pos >= iobuf.in.size) {
pos -= iobuf.in.size;
len = iobuf.in.size - iobuf.in.len;
exit_cleanup(RERR_SOCKETIO);
}
}
- if (msgs2stderr && DEBUG_GTE(IO, 2))
- rprintf(FINFO, "[%s] recv=%ld\n", who_am_i(), (long)n);
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
+ rprintf(FINFO, "[%s] recv=%" SIZE_T_FMT_MOD "d\n",
+ who_am_i(), (SIZE_T_FMT_CAST)n);
+ }
if (io_timeout) {
last_io_in = time(NULL);
- if (flags & PIO_NEED_INPUT)
+ if (io_timeout && flags & PIO_NEED_INPUT)
maybe_send_keepalive(last_io_in, 0);
}
stats.total_read += n;
iobuf.in.len += n;
}
+ if (stop_at_utime && time(NULL) >= stop_at_utime) {
+ rprintf(FERROR, "stopping at requested limit\n");
+ exit_cleanup(RERR_TIMEOUT);
+ }
+
if (out && FD_ISSET(iobuf.out_fd, &w_fds)) {
size_t len = iobuf.raw_flushing_ends_before ? iobuf.raw_flushing_ends_before - out->pos : out->len;
- int n;
+ ssize_t n;
if (bwlimit_writemax && len > bwlimit_writemax)
len = bwlimit_writemax;
msgs2stderr = 1;
iobuf.out_fd = -2;
iobuf.out.len = iobuf.msg.len = iobuf.raw_flushing_ends_before = 0;
- rsyserr(FERROR_SOCKET, errno, "[%s] write error", who_am_i());
+ rsyserr(FERROR_SOCKET, errno, "write error");
drain_multiplex_messages();
exit_cleanup(RERR_SOCKETIO);
}
}
- if (msgs2stderr && DEBUG_GTE(IO, 2)) {
- rprintf(FINFO, "[%s] %s sent=%ld\n",
- who_am_i(), out == &iobuf.out ? "out" : "msg", (long)n);
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
+ rprintf(FINFO, "[%s] %s sent=%" SIZE_T_FMT_MOD "d\n",
+ who_am_i(), out == &iobuf.out ? "out" : "msg", (SIZE_T_FMT_CAST)n);
}
if (io_timeout)
if (!iobuf.in.buf || !iobuf.out.buf || iobuf.in_fd < 0 || iobuf.out_fd < 0 || kluge_around_eof)
return;
+ /* If we're talking to a daemon over a socket, don't short-circuit this logic */
+ if (msgs2stderr && daemon_connection >= 0)
+ return;
+
kluge_around_eof = 2;
/* Setting an I/O timeout ensures that if something inexplicably weird
* happens, we won't hang around forever. */
{
char *hdr;
size_t needed, pos;
- BOOL want_debug = DEBUG_GTE(IO, 1) && convert >= 0 && (msgs2stderr || code != MSG_INFO);
+ BOOL want_debug = DEBUG_GTE(IO, 1) && convert >= 0 && (msgs2stderr == 1 || code != MSG_INFO);
if (!OUT_MULTIPLEXED)
return 0;
- if (want_debug)
- rprintf(FINFO, "[%s] send_msg(%d, %ld)\n", who_am_i(), (int)code, (long)len);
+ if (want_debug) {
+ rprintf(FINFO, "[%s] send_msg(%d, %" SIZE_T_FMT_MOD "d)\n",
+ who_am_i(), (int)code, (SIZE_T_FMT_CAST)len);
+ }
/* When checking for enough free space for this message, we need to
* make sure that there is space for the 4-byte header, plus we'll
} else
#endif
needed = len + 4 + 3;
- if (iobuf.msg.len + needed > iobuf.msg.size)
- perform_io(needed, PIO_NEED_MSGROOM);
+ if (iobuf.msg.len + needed > iobuf.msg.size) {
+ if (am_sender)
+ perform_io(needed, PIO_NEED_MSGROOM);
+ else { /* We sometimes allow the iobuf.msg size to increase to avoid a deadlock. */
+ size_t old_size = iobuf.msg.size;
+ restore_iobuf_size(&iobuf.msg);
+ realloc_xbuf(&iobuf.msg, iobuf.msg.size * 2);
+ if (iobuf.msg.pos + iobuf.msg.len > old_size)
+ memcpy(iobuf.msg.buf + old_size, iobuf.msg.buf, iobuf.msg.pos + iobuf.msg.len - old_size);
+ }
+ }
pos = iobuf.msg.pos + iobuf.msg.len; /* Must be set after any flushing. */
if (pos >= iobuf.msg.size)
SIVAL(hdr, 0, ((MPLEX_BASE + (int)code)<<24) + len);
- if (want_debug && convert > 0)
- rprintf(FINFO, "[%s] converted msg len=%ld\n", who_am_i(), (long)len);
+ if (want_debug && convert > 0) {
+ rprintf(FINFO, "[%s] converted msg len=%" SIZE_T_FMT_MOD "d\n",
+ who_am_i(), (SIZE_T_FMT_CAST)len);
+ }
return 1;
}
send_msg(code, numbuf, 4, -1);
}
+void send_msg_success(const char *fname, int num)
+{
+ if (local_server) {
+ STRUCT_STAT st;
+
+ if (DEBUG_GTE(IO, 1))
+ rprintf(FINFO, "[%s] send_msg_success(%d)\n", who_am_i(), num);
+
+ if (stat(fname, &st) < 0)
+ memset(&st, 0, sizeof (STRUCT_STAT));
+ SIVAL(num_dev_ino_buf, 0, num);
+ SIVAL64(num_dev_ino_buf, 4, st.st_dev);
+ SIVAL64(num_dev_ino_buf, 4+8, st.st_ino);
+ send_msg(MSG_SUCCESS, num_dev_ino_buf, sizeof num_dev_ino_buf, -1);
+ } else
+ send_msg_int(MSG_SUCCESS, num);
+}
+
static void got_flist_entry_status(enum festatus status, int ndx)
{
struct file_list *flist = flist_for_ndx(ndx, "got_flist_entry_status");
switch (status) {
case FES_SUCCESS:
- if (remove_source_files)
- send_msg_int(MSG_SUCCESS, ndx);
+ if (remove_source_files) {
+ if (local_server)
+ send_msg(MSG_SUCCESS, num_dev_ino_buf, sizeof num_dev_ino_buf, -1);
+ else
+ send_msg_int(MSG_SUCCESS, ndx);
+ }
/* FALL THROUGH */
case FES_NO_SEND:
#ifdef SUPPORT_HARD_LINKS
}
if (saw_d) {
- rprintf(FWARNING,
- "*** Try using \"--old-d\" if remote rsync is <= 2.6.3 ***\n");
+ rprintf(FWARNING, "*** Try using \"--old-d\" if remote rsync is <= 2.6.3 ***\n");
}
}
#ifdef ICONV_OPTION
if (flags & RL_CONVERT && iconv_buf.size < bufsiz)
- realloc_xbuf(&iconv_buf, bufsiz + 1024);
+ realloc_xbuf(&iconv_buf, ROUND_UP_1024(bufsiz) + 1024);
#endif
start:
rl_flags |= (protect_args && ic_recv != (iconv_t)-1 ? RL_CONVERT : 0);
#endif
- if (!(argv = new_array(char *, maxargs)))
- out_of_memory("read_args");
+ argv = new_array(char *, maxargs);
if (mod_name && !protect_args)
argv[argc++] = "rsyncd";
if (argc == maxargs-1) {
maxargs += MAX_ARGS;
- if (!(argv = realloc_array(argv, char *, maxargs)))
- out_of_memory("read_args");
+ argv = realloc_array(argv, char *, maxargs);
}
if (dot_pos) {
int len = strlen(buf);
if (request_len)
request_p[0][request_len++] = ' ';
- if (!(*request_p = realloc_array(*request_p, char, request_len + len + 1)))
- out_of_memory("read_args");
+ *request_p = realloc_array(*request_p, char, request_len + len + 1);
memcpy(*request_p + request_len, buf, len + 1);
request_len += len;
}
else
glob_expand(buf, &argv, &argc, &maxargs);
} else {
- if (!(p = strdup(buf)))
- out_of_memory("read_args");
+ p = strdup(buf);
argv[argc++] = p;
if (*p == '.' && p[1] == '\0')
dot_pos = argc;
BOOL io_start_buffering_out(int f_out)
{
- if (msgs2stderr && DEBUG_GTE(IO, 2))
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_start_buffering_out(%d)\n", who_am_i(), f_out);
if (iobuf.out.buf) {
BOOL io_start_buffering_in(int f_in)
{
- if (msgs2stderr && DEBUG_GTE(IO, 2))
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_start_buffering_in(%d)\n", who_am_i(), f_in);
if (iobuf.in.buf) {
void io_end_buffering_in(BOOL free_buffers)
{
- if (msgs2stderr && DEBUG_GTE(IO, 2)) {
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
rprintf(FINFO, "[%s] io_end_buffering_in(IOBUF_%s_BUFS)\n",
who_am_i(), free_buffers ? "FREE" : "KEEP");
}
void io_end_buffering_out(BOOL free_buffers)
{
- if (msgs2stderr && DEBUG_GTE(IO, 2)) {
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
rprintf(FINFO, "[%s] io_end_buffering_out(IOBUF_%s_BUFS)\n",
who_am_i(), free_buffers ? "FREE" : "KEEP");
}
msg_bytes = tag & 0xFFFFFF;
tag = (tag >> 24) - MPLEX_BASE;
- if (DEBUG_GTE(IO, 1) && msgs2stderr)
- rprintf(FINFO, "[%s] got msg=%d, len=%ld\n", who_am_i(), (int)tag, (long)msg_bytes);
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 1)) {
+ rprintf(FINFO, "[%s] got msg=%d, len=%" SIZE_T_FMT_MOD "d\n",
+ who_am_i(), (int)tag, (SIZE_T_FMT_CAST)msg_bytes);
+ }
switch (tag) {
case MSG_DATA:
}
break;
case MSG_SUCCESS:
- if (msg_bytes != 4) {
+ if (msg_bytes != (local_server ? 4+8+8 : 4)) {
invalid_msg:
rprintf(FERROR, "invalid multi-message %d:%lu [%s%s]\n",
tag, (unsigned long)msg_bytes, who_am_i(),
inc_recurse ? "/inc" : "");
exit_cleanup(RERR_STREAMIO);
}
- val = raw_read_int();
+ raw_read_buf(num_dev_ino_buf, msg_bytes);
+ val = IVAL(num_dev_ino_buf, 0);
iobuf.in_multiplexed = 1;
if (am_generator)
got_flist_entry_status(FES_SUCCESS, val);
else
goto invalid_msg;
iobuf.in_multiplexed = 1;
- if (DEBUG_GTE(EXIT, 3))
- rprintf(FINFO, "[%s] got MSG_ERROR_EXIT with %ld bytes\n", who_am_i(), (long)msg_bytes);
+ if (DEBUG_GTE(EXIT, 3)) {
+ rprintf(FINFO, "[%s] got MSG_ERROR_EXIT with %" SIZE_T_FMT_MOD "d bytes\n",
+ who_am_i(), (SIZE_T_FMT_CAST)msg_bytes);
+ }
if (msg_bytes == 0) {
if (!am_sender && !am_generator) {
if (DEBUG_GTE(EXIT, 3)) {
rprintf(FINFO, "[%s] receiving flist for dir %d\n",
who_am_i(), ndx);
}
- flist = recv_file_list(iobuf.in_fd);
+ flist = recv_file_list(iobuf.in_fd, ndx);
flist->parent_ndx = ndx;
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links)
return num;
}
+uint32 read_uint(int f)
+{
+ char b[4];
+ read_buf(f, b, 4);
+ return IVAL(b, 0);
+}
+
int32 read_varint(int f)
{
union {
#if SIZEOF_INT64 < 8
u.x = IVAL(u.b,0);
#elif CAREFUL_ALIGNMENT
- u.x = IVAL(u.b,0) | (((int64)IVAL(u.b,4))<<32);
+ u.x = IVAL64(u.b,0);
#endif
return u.x;
}
#endif
}
+/* Debugging note: this will be named read_buf_() when using an external zlib. */
void read_buf(int f, char *buf, size_t len)
{
if (f != iobuf.in_fd) {
total_written = (sleep_usec - elapsed_usec) * bwlimit / (ONE_SEC/1024);
}
-void io_flush(int flush_it_all)
+void io_flush(int flush_type)
{
if (iobuf.out.len > iobuf.out_empty_len) {
- if (flush_it_all) /* FULL_FLUSH: flush everything in the output buffers */
+ if (flush_type == FULL_FLUSH) /* flush everything in the output buffers */
perform_io(iobuf.out.size - iobuf.out_empty_len, PIO_NEED_OUTROOM);
- else /* NORMAL_FLUSH: flush at least 1 byte */
+ else if (flush_type == NORMAL_FLUSH) /* flush at least 1 byte */
perform_io(iobuf.out.size - iobuf.out.len + 1, PIO_NEED_OUTROOM);
+ /* MSG_FLUSH: flush iobuf.msg only */
}
if (iobuf.msg.len)
perform_io(iobuf.msg.size, PIO_NEED_MSGROOM);
{
char b[5];
uchar bit;
- int cnt = 4;
+ int cnt;
SIVAL(b, 1, x);
- while (cnt > 1 && b[cnt] == 0)
- cnt--;
+ for (cnt = 4; cnt > 1 && b[cnt] == 0; cnt--) {}
bit = ((uchar)1<<(7-cnt+1));
+
if (CVAL(b, cnt) >= bit) {
cnt++;
*b = ~(bit-1);
} else if (cnt > 1)
*b = b[cnt] | ~(bit*2-1);
else
- *b = b[cnt];
+ *b = b[1];
write_buf(f, b, cnt);
}
uchar bit;
int cnt = 8;
- SIVAL(b, 1, x);
#if SIZEOF_INT64 >= 8
- SIVAL(b, 5, x >> 32);
+ SIVAL64(b, 1, x);
#else
+ SIVAL(b, 1, x);
if (x <= 0x7FFFFFFF && x >= 0)
memset(b + 5, 0, 4);
else {
if (len < 0)
exit_cleanup(RERR_PROTOCOL);
- if (len > (int)sizeof buf) {
+ if (len >= (int)sizeof buf) {
rprintf(FERROR, "io_printf() was too long for the buffer.\n");
exit_cleanup(RERR_PROTOCOL);
}
{
io_flush(FULL_FLUSH);
- if (msgs2stderr && DEBUG_GTE(IO, 2))
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_start_multiplex_out(%d)\n", who_am_i(), fd);
if (!iobuf.msg.buf)
/* Setup for multiplexing a MSG_* stream with the data stream. */
void io_start_multiplex_in(int fd)
{
- if (msgs2stderr && DEBUG_GTE(IO, 2))
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_start_multiplex_in(%d)\n", who_am_i(), fd);
iobuf.in_multiplexed = 1; /* See also IN_MULTIPLEXED */
{
int ret = iobuf.in_multiplexed ? iobuf.in_fd : -1;
- if (msgs2stderr && DEBUG_GTE(IO, 2))
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_end_multiplex_in(mode=%d)\n", who_am_i(), mode);
iobuf.in_multiplexed = 0;
{
int ret = iobuf.out_empty_len ? iobuf.out_fd : -1;
- if (msgs2stderr && DEBUG_GTE(IO, 2))
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_end_multiplex_out(mode=%d)\n", who_am_i(), mode);
if (mode != MPLX_TO_BUFFERED)
* is involved. */
write_int(batch_fd, protocol_version);
if (protocol_version >= 30)
- write_byte(batch_fd, compat_flags);
+ write_varint(batch_fd, compat_flags);
write_int(batch_fd, checksum_seed);
if (am_sender)