00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "includes.h"
00025
00026 static int
00027 process_block (smb_iconv_t cd, const char *addr, size_t len, FILE *output)
00028 {
00029 #define OUTBUF_SIZE 32768
00030 const char *start = addr;
00031 char outbuf[OUTBUF_SIZE];
00032 char *outptr;
00033 size_t outlen;
00034 size_t n;
00035
00036 while (len > 0)
00037 {
00038 outptr = outbuf;
00039 outlen = OUTBUF_SIZE;
00040 n = smb_iconv (cd, &addr, &len, &outptr, &outlen);
00041
00042 if (outptr != outbuf)
00043 {
00044
00045 int errno_save = errno;
00046
00047 if (fwrite (outbuf, 1, outptr - outbuf, output)
00048 < (size_t) (outptr - outbuf)
00049 || ferror (output))
00050 {
00051
00052 DEBUG (0, ("conversion stopped due to problem in writing the output"));
00053 return -1;
00054 }
00055
00056 errno = errno_save;
00057 }
00058
00059 if (errno != E2BIG)
00060 {
00061
00062 switch (errno)
00063 {
00064 case EILSEQ:
00065 DEBUG(0,("illegal input sequence at position %ld",
00066 (long) (addr - start)));
00067 break;
00068 case EINVAL:
00069 DEBUG(0, ("\
00070 incomplete character or shift sequence at end of buffer"));
00071 break;
00072 case EBADF:
00073 DEBUG(0, ("internal error (illegal descriptor)"));
00074 break;
00075 default:
00076 DEBUG(0, ("unknown iconv() error %d", errno));
00077 break;
00078 }
00079
00080 return -1;
00081 }
00082 }
00083
00084 return 0;
00085 }
00086
00087
00088 static int
00089 process_fd (iconv_t cd, int fd, FILE *output)
00090 {
00091
00092
00093
00094
00095
00096 static char *inbuf = NULL;
00097 static size_t maxlen = 0;
00098 char *inptr = NULL;
00099 size_t actlen = 0;
00100
00101 while (actlen < maxlen)
00102 {
00103 ssize_t n = read (fd, inptr, maxlen - actlen);
00104
00105 if (n == 0)
00106
00107 break;
00108
00109 if (n == -1)
00110 {
00111
00112 DEBUG(0, ("error while reading the input"));
00113 return -1;
00114 }
00115
00116 inptr += n;
00117 actlen += n;
00118 }
00119
00120 if (actlen == maxlen)
00121 while (1)
00122 {
00123 ssize_t n;
00124 char *new_inbuf;
00125
00126
00127 new_inbuf = (char *) realloc (inbuf, maxlen + 32768);
00128 if (new_inbuf == NULL)
00129 {
00130 DEBUG(0, ("unable to allocate buffer for input"));
00131 return -1;
00132 }
00133 inbuf = new_inbuf;
00134 maxlen += 32768;
00135 inptr = inbuf + actlen;
00136
00137 do
00138 {
00139 n = read (fd, inptr, maxlen - actlen);
00140
00141 if (n == 0)
00142
00143 break;
00144
00145 if (n == -1)
00146 {
00147
00148 DEBUG(0, ("error while reading the input"));
00149 return -1;
00150 }
00151
00152 inptr += n;
00153 actlen += n;
00154 }
00155 while (actlen < maxlen);
00156
00157 if (n == 0)
00158
00159 break;
00160 }
00161
00162
00163 return process_block (cd, inbuf, actlen, output);
00164 }
00165
00166
00167
00168 int main(int argc, char *argv[])
00169 {
00170 const char *file = NULL;
00171 char *from = "";
00172 char *to = "";
00173 char *output = NULL;
00174 const char *preload_modules[] = {NULL, NULL};
00175 FILE *out = stdout;
00176 int fd;
00177 smb_iconv_t cd;
00178
00179
00180
00181 poptContext pc;
00182 struct poptOption long_options[] = {
00183 POPT_AUTOHELP
00184 { "from-code", 'f', POPT_ARG_STRING, &from, 0, "Encoding of original text" },
00185 { "to-code", 't', POPT_ARG_STRING, &to, 0, "Encoding for output" },
00186 { "output", 'o', POPT_ARG_STRING, &output, 0, "Write output to this file" },
00187 { "preload-modules", 'p', POPT_ARG_STRING, &preload_modules[0], 0, "Modules to load" },
00188 POPT_COMMON_SAMBA
00189 POPT_TABLEEND
00190 };
00191
00192 setlinebuf(stdout);
00193
00194 pc = poptGetContext("smbiconv", argc, (const char **) argv,
00195 long_options, 0);
00196
00197 poptSetOtherOptionHelp(pc, "[FILE] ...");
00198
00199 while(poptGetNextOpt(pc) != -1);
00200
00201
00202
00203 setup_logging("smbiconv", True);
00204
00205 if (preload_modules[0]) smb_load_modules(preload_modules);
00206
00207 if(output) {
00208 out = fopen(output, "w");
00209
00210 if(!out) {
00211 DEBUG(0, ("Can't open output file '%s': %s, exiting...\n", output, strerror(errno)));
00212 return 1;
00213 }
00214 }
00215
00216 cd = smb_iconv_open(to, from);
00217 if((int)cd == -1) {
00218 DEBUG(0,("unable to find from or to encoding, exiting...\n"));
00219 return 1;
00220 }
00221
00222 while((file = poptGetArg(pc))) {
00223 if(strcmp(file, "-") == 0) fd = 0;
00224 else {
00225 fd = open(file, O_RDONLY);
00226
00227 if(!fd) {
00228 DEBUG(0, ("Can't open input file '%s': %s, ignoring...\n", file, strerror(errno)));
00229 continue;
00230 }
00231 }
00232
00233
00234 process_fd(cd, fd, out);
00235
00236 close(fd);
00237 }
00238 poptFreeContext(pc);
00239
00240 fclose(out);
00241
00242 return 0;
00243 }