static int active_filecnt = 0;
static OFF_T active_bytecnt = 0;
+static char int_byte_cnt[256] = {
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 00 - 0F */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 10 - 1F */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 20 - 2F */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 30 - 3F */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 40 - 4F */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 50 - 5F */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 60 - 6F */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 70 - 7F */
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, /* 80 - 8F */
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, /* 90 - 9F */
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, /* A0 - AF */
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, /* B0 - BF */
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, /* C0 - CF */
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, /* D0 - DF */
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, /* E0 - EF */
+ 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, /* F0 - FF */
+};
+
static void read_loop(int fd, char *buf, size_t len);
struct flist_ndx_item {
}
/* Add a message to the pending MSG_* list. */
-static void msg_list_add(struct msg_list *lst, int code, char *buf, int len)
+static void msg_list_add(struct msg_list *lst, int code, const char *buf, int len)
{
struct msg_list_item *m;
int sz = len + 4 + sizeof m[0] - 1;
if (n >= sizeof buf)
n = sizeof buf - 1;
read_loop(fd, buf, n);
- rwrite(tag, buf, n);
+ rwrite((enum logcode)tag, buf, n);
len -= n;
}
break;
return 1;
}
-int send_msg(enum msgcode code, char *buf, int len)
+int send_msg(enum msgcode code, const char *buf, int len)
{
if (msg_fd_out < 0) {
if (!defer_forwarding_messages)
stats.total_read += total;
}
-int read_shortint(int f)
+unsigned short read_shortint(int f)
{
- uchar b[2];
- readfd(f, (char *)b, 2);
- return (b[1] << 8) + b[0];
+ char b[2];
+ readfd(f, b, 2);
+ return (UVAL(b, 1) << 8) + UVAL(b, 0);
}
int32 read_int(int f)
char b[4];
int32 num;
- readfd(f,b,4);
- num = IVAL(b,0);
- if (num == (int32)0xffffffff)
- return -1;
+ readfd(f, b, 4);
+ num = IVAL(b, 0);
+#if SIZEOF_INT32 > 4
+ if (num & (int32)0x80000000)
+ num |= ~(int32)0xffffffff;
+#endif
return num;
}
int64 read_longint(int f)
{
int64 num;
- char b[8];
- num = read_int(f);
+ char b[9];
- if ((int32)num != (int32)0xffffffff)
- return num;
+ if (protocol_version < 30) {
+ num = read_int(f);
+
+ if ((int32)num != (int32)0xffffffff)
+ return num;
#if SIZEOF_INT64 < 8
- rprintf(FERROR, "Integer overflow: attempted 64-bit offset\n");
- exit_cleanup(RERR_UNSUPPORTED);
+ rprintf(FERROR, "Integer overflow: attempted 64-bit offset\n");
+ exit_cleanup(RERR_UNSUPPORTED);
#else
- readfd(f,b,8);
- num = IVAL(b,0) | (((int64)IVAL(b,4))<<32);
+ readfd(f, b, 8);
+ num = IVAL(b,0) | (((int64)IVAL(b,4))<<32);
+#endif
+ } else {
+ int cnt;
+ readfd(f, b, 3);
+ cnt = int_byte_cnt[CVAL(b, 0)];
+#if SIZEOF_INT64 < 8
+ if (cnt > 5 || (cnt == 5 && (CVAL(b,0)&0x3F || CVAL(b,1)&0x80))) {
+ rprintf(FERROR, "Integer overflow: attempted 64-bit offset\n");
+ exit_cleanup(RERR_UNSUPPORTED);
+ }
+#endif
+ if (cnt > 3)
+ readfd(f, b + 3, cnt - 3);
+ switch (cnt) {
+ case 3:
+ num = NVAL3(b, 0);
+ break;
+ case 4:
+ num = NVAL4(b, 0x80);
+ break;
+ case 5:
+ num = NVAL5(b, 0xC0);
+ break;
+#if SIZEOF_INT64 >= 8
+ case 6:
+ num = NVAL6(b, 0xE0);
+ break;
+ case 7:
+ num = NVAL7(b, 0xF0);
+ break;
+ case 8:
+ num = NVAL8(b, 0xF8);
+ break;
+ case 9:
+ num = NVAL8(b+1, 0);
+ break;
#endif
+ default:
+ exit_cleanup(RERR_PROTOCOL); /* impossible... */
+ }
+ }
return num;
}
-void read_buf(int f,char *buf,size_t len)
+void read_buf(int f, char *buf, size_t len)
{
readfd(f,buf,len);
}
-void read_sbuf(int f,char *buf,size_t len)
+void read_sbuf(int f, char *buf, size_t len)
{
readfd(f, buf, len);
buf[len] = '\0';
*
* This function underlies the multiplexing system. The body of the
* application never calls this function directly. */
-static void writefd_unbuffered(int fd,char *buf,size_t len)
+static void writefd_unbuffered(int fd, const char *buf, size_t len)
{
size_t n, total = 0;
fd_set w_fds, r_fds, e_fds;
* Write an message to a multiplexed stream. If this fails then rsync
* exits.
**/
-static void mplex_write(enum msgcode code, char *buf, size_t len)
+static void mplex_write(enum msgcode code, const char *buf, size_t len)
{
char buffer[1024];
size_t n = len;
iobuf_out_cnt = 0;
}
-static void writefd(int fd,char *buf,size_t len)
+static void writefd(int fd, const char *buf, size_t len)
{
if (fd == msg_fd_out) {
rprintf(FERROR, "Internal error: wrong write used in receiver.\n");
}
}
-void write_shortint(int f, int x)
+void write_shortint(int f, unsigned short x)
{
- uchar b[2];
- b[0] = x;
- b[1] = x >> 8;
- writefd(f, (char *)b, 2);
+ char b[2];
+ b[0] = (char)x;
+ b[1] = (char)(x >> 8);
+ writefd(f, b, 2);
}
-void write_int(int f,int32 x)
+void write_int(int f, int32 x)
{
char b[4];
- SIVAL(b,0,x);
- writefd(f,b,4);
+ SIVAL(b, 0, x);
+ writefd(f, b, 4);
}
/*
*/
void write_longint(int f, int64 x)
{
- char b[8];
+ char b[12];
- if (x <= 0x7FFFFFFF) {
- write_int(f, (int)x);
- return;
+#if SIZEOF_INT64 < 8
+ if (x < 0 || x > 0x7FFFFFFF) {
+ rprintf(FERROR, "Integer overflow: attempted 64-bit offset\n");
+ exit_cleanup(RERR_UNSUPPORTED);
}
+#endif
+ if (protocol_version < 30) {
+ char * const s = b+4;
+ SIVAL(s, 0, x);
#if SIZEOF_INT64 < 8
- rprintf(FERROR, "Integer overflow: attempted 64-bit offset\n");
- exit_cleanup(RERR_UNSUPPORTED);
+ writefd(f, s, 4);
#else
- write_int(f, (int32)0xFFFFFFFF);
- SIVAL(b,0,(x&0xFFFFFFFF));
- SIVAL(b,4,((x>>32)&0xFFFFFFFF));
+ if (x <= 0x7FFFFFFF && x >= 0) {
+ writefd(f, s, 4);
+ return;
+ }
- writefd(f,b,8);
+ memset(b, 0xFF, 4);
+ SIVAL(s, 4, x >> 32);
+ writefd(f, b, 12);
+ } else if (x < 0) {
+ goto all_bits;
+#endif
+ } else if (x < ((int32)1<<(3*8-1))) {
+ b[0] = (char)(x >> 16);
+ b[1] = (char)(x >> 8);
+ b[2] = (char)x;
+ writefd(f, b, 3);
+ } else if (x < ((int64)1<<(4*8-2))) {
+ b[0] = (char)((x >> 24) | 0x80);
+ b[1] = (char)(x >> 16);
+ b[2] = (char)(x >> 8);
+ b[3] = (char)x;
+ writefd(f, b, 4);
+#if SIZEOF_INT64 < 8
+ } else {
+ b[0] = 0xC0;
+ b[1] = (char)(x >> 24);
+ b[2] = (char)(x >> 16);
+ b[3] = (char)(x >> 8);
+ b[4] = (char)x;
+ writefd(f, b, 5);
+ }
+#else
+ } else if (x < ((int64)1<<(5*8-3))) {
+ b[0] = (char)((x >> 32) | 0xC0);
+ b[1] = (char)(x >> 24);
+ b[2] = (char)(x >> 16);
+ b[3] = (char)(x >> 8);
+ b[4] = (char)x;
+ writefd(f, b, 5);
+ } else if (x < ((int64)1<<(6*8-4))) {
+ b[0] = (char)((x >> 40) | 0xE0);
+ b[1] = (char)(x >> 32);
+ b[2] = (char)(x >> 24);
+ b[3] = (char)(x >> 16);
+ b[4] = (char)(x >> 8);
+ b[5] = (char)x;
+ writefd(f, b, 6);
+ } else if (x < ((int64)1<<(7*8-5))) {
+ b[0] = (char)((x >> 48) | 0xF0);
+ b[1] = (char)(x >> 40);
+ b[2] = (char)(x >> 32);
+ b[3] = (char)(x >> 24);
+ b[4] = (char)(x >> 16);
+ b[5] = (char)(x >> 8);
+ b[6] = (char)x;
+ writefd(f, b, 7);
+ } else if (x < ((int64)1<<(8*8-6))) {
+ b[0] = (char)((x >> 56) | 0xF8);
+ b[1] = (char)(x >> 48);
+ b[2] = (char)(x >> 40);
+ b[3] = (char)(x >> 32);
+ b[4] = (char)(x >> 24);
+ b[5] = (char)(x >> 16);
+ b[6] = (char)(x >> 8);
+ b[7] = (char)x;
+ writefd(f, b, 8);
+ } else {
+ all_bits:
+ b[0] = (char)0xFC;
+ b[1] = (char)(x >> 56);
+ b[2] = (char)(x >> 48);
+ b[3] = (char)(x >> 40);
+ b[4] = (char)(x >> 32);
+ b[5] = (char)(x >> 24);
+ b[6] = (char)(x >> 16);
+ b[7] = (char)(x >> 8);
+ b[8] = (char)x;
+ writefd(f, b, 9);
+ }
#endif
}
-void write_buf(int f,char *buf,size_t len)
+void write_buf(int f, const char *buf, size_t len)
{
writefd(f,buf,len);
}
/** Write a string to the connection */
-void write_sbuf(int f, char *buf)
+void write_sbuf(int f, const char *buf)
{
writefd(f, buf, strlen(buf));
}
writefd(f, (char *)&c, 1);
}
-void write_vstring(int f, char *str, int len)
+void write_vstring(int f, const char *str, int len)
{
uchar lenbuf[3], *lb = lenbuf;
}
/** Write an message to the multiplexed data stream. */
-int io_multiplex_write(enum msgcode code, char *buf, size_t len)
+int io_multiplex_write(enum msgcode code, const char *buf, size_t len)
{
if (!io_multiplexing_out)
return 0;