2
Unix SMB/CIFS implementation.
5
Copyright (C) Jelmer Vernooij 2003
6
Based on iconv/icon_prog.c from the GNU C Library,
7
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 3 of the License, or
12
(at your option) any later version.
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License for more details.
19
You should have received a copy of the GNU General Public License
20
along with this program. If not, see <http://www.gnu.org/licenses/>.
27
process_block (smb_iconv_t cd, const char *addr, size_t len, FILE *output)
29
#define OUTBUF_SIZE 32768
30
const char *start = addr;
31
char outbuf[OUTBUF_SIZE];
40
n = smb_iconv (cd, &addr, &len, &outptr, &outlen);
44
/* We have something to write out. */
45
int errno_save = errno;
47
if (fwrite (outbuf, 1, outptr - outbuf, output)
48
< (size_t) (outptr - outbuf)
51
/* Error occurred while printing the result. */
52
DEBUG (0, ("conversion stopped due to problem in writing the output"));
61
/* iconv() ran into a problem. */
65
DEBUG(0,("illegal input sequence at position %ld",
66
(long) (addr - start)));
70
incomplete character or shift sequence at end of buffer"));
73
DEBUG(0, ("internal error (illegal descriptor)"));
76
DEBUG(0, ("unknown iconv() error %d", errno));
89
process_fd (smb_iconv_t cd, int fd, FILE *output)
91
/* we have a problem with reading from a descriptor since we must not
92
provide the iconv() function an incomplete character or shift
93
sequence at the end of the buffer. Since we have to deal with
94
arbitrary encodings we must read the whole text in a buffer and
95
process it in one step. */
96
static char *inbuf = NULL;
97
static size_t maxlen = 0;
101
while (actlen < maxlen)
103
ssize_t n = read (fd, inptr, maxlen - actlen);
106
/* No more text to read. */
111
/* Error while reading. */
112
DEBUG(0, ("error while reading the input"));
120
if (actlen == maxlen)
126
/* Increase the buffer. */
127
new_inbuf = (char *) realloc (inbuf, maxlen + 32768);
128
if (new_inbuf == NULL)
130
DEBUG(0, ("unable to allocate buffer for input"));
135
inptr = inbuf + actlen;
139
n = read (fd, inptr, maxlen - actlen);
142
/* No more text to read. */
147
/* Error while reading. */
148
DEBUG(0, ("error while reading the input"));
155
while (actlen < maxlen);
158
/* Break again so we leave both loops. */
162
/* Now we have all the input in the buffer. Process it in one run. */
163
return process_block (cd, inbuf, actlen, output);
168
int main(int argc, char *argv[])
170
const char *file = NULL;
171
const char *from = "";
174
const char *preload_modules[] = {NULL, NULL};
179
/* make sure the vars that get altered (4th field) are in
180
a fixed location or certain compilers complain */
182
struct poptOption long_options[] = {
184
{ "from-code", 'f', POPT_ARG_STRING, &from, 0, "Encoding of original text" },
185
{ "to-code", 't', POPT_ARG_STRING, &to, 0, "Encoding for output" },
186
{ "output", 'o', POPT_ARG_STRING, &output, 0, "Write output to this file" },
187
{ "preload-modules", 'p', POPT_ARG_STRING, &preload_modules[0], 0, "Modules to load" },
194
pc = poptGetContext("smbiconv", argc, (const char **) argv,
197
poptSetOtherOptionHelp(pc, "[FILE] ...");
199
while(poptGetNextOpt(pc) != -1);
201
/* the following functions are part of the Samba debugging
202
facilities. See lib/debug.c */
203
setup_logging("smbiconv", True);
205
if (preload_modules[0]) smb_load_modules(preload_modules);
208
out = fopen(output, "w");
211
DEBUG(0, ("Can't open output file '%s': %s, exiting...\n", output, strerror(errno)));
216
cd = smb_iconv_open(to, from);
217
if (cd == (smb_iconv_t)-1) {
218
DEBUG(0,("unable to find from or to encoding, exiting...\n"));
219
if (out != stdout) fclose(out);
223
while((file = poptGetArg(pc))) {
224
if(strcmp(file, "-") == 0) fd = 0;
226
fd = open(file, O_RDONLY);
229
DEBUG(0, ("Can't open input file '%s': %s, ignoring...\n", file, strerror(errno)));
234
/* Loop thru all arguments */
235
process_fd(cd, fd, out);