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/>.
24 #include "system/filesys.h"
25 #include "popt_common.h"
29 process_block (smb_iconv_t cd
, const char *addr
, size_t len
, FILE *output
)
31 #define OUTBUF_SIZE 32768
32 const char *start
= addr
;
33 char outbuf
[OUTBUF_SIZE
];
42 n
= smb_iconv (cd
, &addr
, &len
, &outptr
, &outlen
);
46 /* We have something to write out. */
47 int errno_save
= errno
;
49 if (fwrite (outbuf
, 1, outptr
- outbuf
, output
)
50 < (size_t) (outptr
- outbuf
)
53 /* Error occurred while printing the result. */
54 DEBUG (0, ("conversion stopped due to problem in writing the output"));
63 /* iconv() ran into a problem. */
67 DEBUG(0,("illegal input sequence at position %ld",
68 (long) (addr
- start
)));
72 incomplete character or shift sequence at end of buffer"));
75 DEBUG(0, ("internal error (illegal descriptor)"));
78 DEBUG(0, ("unknown iconv() error %d", errno
));
91 process_fd (smb_iconv_t cd
, int fd
, FILE *output
)
93 /* we have a problem with reading from a descriptor since we must not
94 provide the iconv() function an incomplete character or shift
95 sequence at the end of the buffer. Since we have to deal with
96 arbitrary encodings we must read the whole text in a buffer and
97 process it in one step. */
98 static char *inbuf
= NULL
;
99 static size_t maxlen
= 0;
103 while (actlen
< maxlen
)
105 ssize_t n
= read (fd
, inptr
, maxlen
- actlen
);
108 /* No more text to read. */
113 /* Error while reading. */
114 DEBUG(0, ("error while reading the input"));
122 if (actlen
== maxlen
)
128 /* Increase the buffer. */
129 new_inbuf
= (char *) realloc (inbuf
, maxlen
+ 32768);
130 if (new_inbuf
== NULL
)
132 DEBUG(0, ("unable to allocate buffer for input"));
137 inptr
= inbuf
+ actlen
;
141 n
= read (fd
, inptr
, maxlen
- actlen
);
144 /* No more text to read. */
149 /* Error while reading. */
150 DEBUG(0, ("error while reading the input"));
157 while (actlen
< maxlen
);
160 /* Break again so we leave both loops. */
164 /* Now we have all the input in the buffer. Process it in one run. */
165 return process_block (cd
, inbuf
, actlen
, output
);
170 int main(int argc
, char *argv
[])
172 const char *file
= NULL
;
173 const char *from
= "";
176 const char *preload_modules
[] = {NULL
, NULL
};
181 /* make sure the vars that get altered (4th field) are in
182 a fixed location or certain compilers complain */
184 struct poptOption long_options
[] = {
186 { "from-code", 'f', POPT_ARG_STRING
, &from
, 0, "Encoding of original text" },
187 { "to-code", 't', POPT_ARG_STRING
, &to
, 0, "Encoding for output" },
188 { "output", 'o', POPT_ARG_STRING
, &output
, 0, "Write output to this file" },
189 { "preload-modules", 'p', POPT_ARG_STRING
, &preload_modules
[0], 0, "Modules to load" },
196 pc
= poptGetContext("smbiconv", argc
, (const char **) argv
,
199 poptSetOtherOptionHelp(pc
, "[FILE] ...");
201 while(poptGetNextOpt(pc
) != -1);
203 /* the following functions are part of the Samba debugging
204 facilities. See lib/debug.c */
205 setup_logging("smbiconv", DEBUG_STDOUT
);
207 if (preload_modules
[0]) smb_load_modules(preload_modules
);
210 out
= fopen(output
, "w");
213 DEBUG(0, ("Can't open output file '%s': %s, exiting...\n", output
, strerror(errno
)));
218 cd
= smb_iconv_open(to
, from
);
219 if (cd
== (smb_iconv_t
)-1) {
220 DEBUG(0,("unable to find from or to encoding, exiting...\n"));
221 if (out
!= stdout
) fclose(out
);
225 while((file
= poptGetArg(pc
))) {
226 if(strcmp(file
, "-") == 0) fd
= 0;
228 fd
= open(file
, O_RDONLY
);
231 DEBUG(0, ("Can't open input file '%s': %s, ignoring...\n", file
, strerror(errno
)));
236 /* Loop thru all arguments */
237 process_fd(cd
, fd
, out
);