Commit d8a7290f authored by Wayne Davison's avatar Wayne Davison

Give iconvbufs() an ICB_INIT flag.

parent 3b8f8192
......@@ -731,7 +731,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
INIT_CONST_XBUF(outbuf, thisname);
INIT_XBUF(inbuf, lastname, basename_len, (size_t)-1);
if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) {
if (iconvbufs(ic_recv, &inbuf, &outbuf, ICB_INIT) < 0) {
io_error |= IOERR_GENERAL;
rprintf(FERROR_UTF8,
"[%s] cannot convert filename: %s (%s)\n",
......@@ -1049,7 +1049,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
read_sbuf(f, inbuf.buf, inbuf.len);
INIT_XBUF(outbuf, bp, 0, alloc_len);
if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) {
if (iconvbufs(ic_recv, &inbuf, &outbuf, ICB_INIT) < 0) {
io_error |= IOERR_GENERAL;
rprintf(FERROR_XFER,
"[%s] cannot convert symlink data for: %s (%s)\n",
......@@ -1464,14 +1464,14 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
if (file->dirname) {
INIT_XBUF_STRLEN(inbuf, (char*)file->dirname);
outbuf.size -= 2; /* Reserve room for '/' & 1 more char. */
if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0)
if (iconvbufs(ic_send, &inbuf, &outbuf, ICB_INIT) < 0)
goto convert_error;
outbuf.size += 2;
fbuf[outbuf.len++] = '/';
}
INIT_XBUF_STRLEN(inbuf, (char*)file->basename);
if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) {
if (iconvbufs(ic_send, &inbuf, &outbuf, ICB_INIT) < 0) {
convert_error:
io_error |= IOERR_GENERAL;
rprintf(FERROR_XFER,
......@@ -1485,7 +1485,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
if (symlink_len && sender_symlink_iconv) {
INIT_XBUF(inbuf, (char*)symlink_name, symlink_len, (size_t)-1);
INIT_CONST_XBUF(outbuf, symlink_buf);
if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) {
if (iconvbufs(ic_send, &inbuf, &outbuf, ICB_INIT) < 0) {
io_error |= IOERR_GENERAL;
f_name(file, fbuf);
rprintf(FERROR_XFER,
......
......@@ -378,7 +378,7 @@ static void forward_filesfrom_data(void)
}
if (len) {
char *f = x.buf + x.pos;
char *t = f; /* Keep any non-zero offset to avoid iconv reset. */
char *t = x.buf;
char *eob = f + len;
/* Eliminate any multi-'\0' runs. */
while (f != eob) {
......@@ -393,7 +393,7 @@ static void forward_filesfrom_data(void)
if (filesfrom_convert) {
/* TODO would it help to translate each string between nulls separately? */
x.len = len;
iconvbufs(ic_send, &x, &iobuf.out, ICB_INCLUDE_BAD|ICB_INCLUDE_INCOMPLETE|ICB_CIRCULAR_OUT);
iconvbufs(ic_send, &x, &iobuf.out, ICB_INCLUDE_BAD|ICB_INCLUDE_INCOMPLETE|ICB_CIRCULAR_OUT|ICB_INIT);
} else
#endif
if (len) {
......@@ -803,7 +803,7 @@ int send_msg(enum msgcode code, const char *buf, size_t len, int convert)
len = iobuf.msg.len;
iconvbufs(ic_send, &inbuf, &iobuf.msg,
ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE | ICB_CIRCULAR_OUT);
ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE | ICB_CIRCULAR_OUT | ICB_INIT);
if (inbuf.len > 0) {
rprintf(FERROR, "overflowed iobuf.msg buffer in send_msg");
exit_cleanup(RERR_UNSUPPORTED);
......@@ -1039,7 +1039,7 @@ int read_line(int fd, char *buf, size_t bufsiz, int flags)
iconv_buf.pos = 0;
iconv_buf.len = s - iconv_buf.buf;
iconvbufs(ic_recv, &iconv_buf, &outbuf,
ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE);
ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE | ICB_INIT);
outbuf.buf[outbuf.len] = '\0';
return outbuf.len;
}
......@@ -1301,13 +1301,14 @@ static void read_a_msg(void)
INIT_XBUF(inbuf, ibuf, 0, (size_t)-1);
while (msg_bytes) {
inbuf.pos = 0;
inbuf.len = msg_bytes > sizeof ibuf ? sizeof ibuf : msg_bytes;
memcpy(inbuf.buf, perform_io(inbuf.len, PIO_INPUT_AND_CONSUME), inbuf.len);
if (!(msg_bytes -= inbuf.len)
&& !ibuf[inbuf.len-1])
inbuf.len--, add_null = 1;
if (iconvbufs(ic_send, &inbuf, &outbuf,
ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE) < 0)
ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE | ICB_INIT) < 0)
goto overflow;
}
if (add_null) {
......
......@@ -359,7 +359,7 @@ output_msg:
INIT_XBUF(inbuf, (char*)buf, len, (size_t)-1);
while (inbuf.len) {
iconvbufs(ic, &inbuf, &outbuf, 0);
iconvbufs(ic, &inbuf, &outbuf, inbuf.pos ? 0 : ICB_INIT);
ierrno = errno;
if (outbuf.len) {
filtered_fwrite(f, convbuf, outbuf.len, 0);
......
......@@ -160,8 +160,8 @@ static void wrap_overflow(xbuf *out, int siz)
* "flags", any badly-encoded chars are included verbatim in the "out" xbuf,
* so EILSEQ will not be returned. Likewise for ICB_INCLUDE_INCOMPLETE with
* respect to an incomplete multi-byte char at the end, which ensures that
* EINVAL is not returned. Anytime "in.pos" is 0 we will reset the iconv()
* state prior to processing the characters. */
* EINVAL is not returned. If ICB_INIT is set, the iconv() conversion state
* is initialized prior to processing the characters. */
int iconvbufs(iconv_t ic, xbuf *in, xbuf *out, int flags)
{
ICONV_CONST char *ibuf;
......@@ -171,7 +171,7 @@ int iconvbufs(iconv_t ic, xbuf *in, xbuf *out, int flags)
if (!out->size && flags & ICB_EXPAND_OUT)
alloc_xbuf(out, 1024);
if (!in->pos)
if (flags & ICB_INIT)
iconv(ic, NULL, 0, NULL, 0);
ibuf = in->buf + in->pos;
......@@ -265,7 +265,7 @@ void send_protected_args(int fd, char *args[])
else if (convert) {
INIT_XBUF_STRLEN(inbuf, args[i]);
iconvbufs(ic_send, &inbuf, &outbuf,
ICB_EXPAND_OUT | ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE);
ICB_EXPAND_OUT | ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE | ICB_INIT);
outbuf.buf[outbuf.len] = '\0';
write_buf(fd, outbuf.buf, outbuf.len + 1);
outbuf.len = 0;
......
......@@ -901,6 +901,7 @@ typedef struct {
#define ICB_INCLUDE_BAD (1<<1)
#define ICB_INCLUDE_INCOMPLETE (1<<2)
#define ICB_CIRCULAR_OUT (1<<3)
#define ICB_INIT (1<<4)
#define RL_EOL_NULLS (1<<0)
#define RL_DUMP_COMMENTS (1<<1)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment