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",
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",
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,
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,
}
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) {
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) {
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);
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;
}
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) {
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);
* "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;
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;
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;
#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)