/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
*/
/*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
/*
* iconv(1) command.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <iconv.h>
#include <libintl.h>
#include <langinfo.h>
#include <locale.h>
#include "charmap.h"
#include <assert.h>
const char *progname;
char *from_cs;
char *to_cs;
int debug;
void iconv_file(FILE *, const char *);
extern int list_codesets(void);
{
}
void
usage(void)
{
"usage: %s [-cs] [-f from-codeset] [-t to-codeset] "
"[file ...]\n"), progname);
exit(1);
}
int
{
int c;
yydebug = 0;
progname = getprogname();
#if !defined(TEXT_DOMAIN)
#endif
(void) textdomain(TEXT_DOMAIN);
switch (c) {
case 'c':
cflag++;
break;
case 'd':
debug++;
break;
case 'l':
lflag++;
break;
case 's':
sflag++;
break;
case 'f':
break;
case 't':
break;
case '?':
usage();
}
}
if (lflag) {
usage();
exit(list_codesets());
}
/*
* If either "from" or "to" contains a slash,
* then we're using charmaps.
*/
if (debug)
charmap_dump();
} else {
switch (errno) {
case EINVAL:
_("Not supported %s to %s\n"),
break;
default:
_("iconv_open failed: %s\n"),
break;
}
exit(1);
}
}
}
exit(1);
}
}
}
/*
* Conversion buffer sizes:
*
* The input buffer has room to prepend one mbs character if needed for
* handling a left-over at the end of a previous conversion buffer.
*
* Conversions may grow or shrink data, so using a larger output buffer
* to reduce the likelihood of leftover input buffer data in each pass.
*/
void
{
const char *iptr;
char *optr;
int iconv_errno;
offset = 0;
ileft = 0;
/*
* Note: the *pconv function is either iconv(3c) or our
* private equivalent when using charmaps. Both update
* ileft, oleft etc. even when conversion stops due to
* an illegal sequence or whatever, so we need to copy
* the partially converted buffer even on error.
*/
iconv_errno = errno;
if (ocnt > 0) {
perror("fwrite");
exit(1);
}
}
switch (iconv_errno) {
case E2BIG: /* no room in output buffer */
goto iconv_again;
case EINVAL: /* incomplete sequence on input */
if (debug) {
_("Incomplete sequence in %s at offset %lld\n"),
}
/*
* Copy the remainder to the space reserved
* at the start of the input buffer.
*/
if (ileft <= MB_LEN_MAX) {
iptr = p;
continue; /* read again */
}
/*
* Should not see ileft > MB_LEN_MAX,
* but if we do, handle as EILSEQ.
*/
/* FALLTHROUGH */
case EILSEQ: /* invalid sequence on input */
if (!sflag) {
_("Illegal sequence in %s at offset %lld\n"),
_("bad seq: \\x%02x\\x%02x\\x%02x\n"),
iptr[0] & 0xff,
}
/* skip one */
iptr++;
ileft--;
if (!cflag) {
*optr++ = '?';
oleft--;
}
goto iconv_again;
default:
_("iconv error (%s) in file $s at offset %lld\n"),
break;
}
}
/* normal iconv return */
ileft = 0;
}
/*
* End of file
* Flush any shift encodings.
*/
ileft = 0;
if (ocnt > 0) {
perror("fwrite");
exit(1);
}
}
}