1 /* iconv.c - Convert character encoding 2 * 3 * Copyright 2014 Felix Janda <felix.janda (at) posteo.de> 4 * 5 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/iconv.html 6 7 USE_ICONV(NEWTOY(iconv, "cst:f:", TOYFLAG_USR|TOYFLAG_BIN)) 8 9 config ICONV 10 bool "iconv" 11 default n 12 depends on TOYBOX_ICONV 13 help 14 usage: iconv [-f FROM] [-t TO] [FILE...] 15 16 Convert character encoding of files. 17 18 -f convert from (default utf8) 19 -t convert to (default utf8) 20 */ 21 22 #define FOR_iconv 23 #include "toys.h" 24 #include <iconv.h> 25 26 GLOBALS( 27 char *from; 28 char *to; 29 30 void *ic; 31 ) 32 33 static void do_iconv(int fd, char *name) 34 { 35 char *outstart = toybuf+2048; 36 size_t inleft = 0; 37 int len = 1; 38 39 do { 40 size_t outleft = 2048; 41 char *in = toybuf+inleft, *out = outstart; 42 43 len = read(fd, in, 2048-inleft); 44 45 if (len < 0) { 46 perror_msg("read '%s'"); 47 return; 48 } 49 inleft += len; 50 51 do { 52 if (iconv(TT.ic, &in, &inleft, &out, &outleft) == -1 53 && (errno == EILSEQ || (in == toybuf+inleft-len && errno == EINVAL))) 54 { 55 if (outleft) { 56 // Skip first byte of illegal sequence to avoid endless loops 57 *(out++) = *(in++); 58 inleft--; 59 } 60 } 61 xwrite(1, outstart, out-outstart); 62 // Top off input buffer 63 memmove(in, toybuf, inleft); 64 } while (len < 1 && inleft); 65 } while (len > 0); 66 } 67 68 void iconv_main(void) 69 { 70 TT.ic = iconv_open(TT.to ? TT.to : "utf8", TT.from ? TT.from : "utf8"); 71 if (TT.ic == (iconv_t)-1) error_exit("bad encoding"); 72 loopfiles(toys.optargs, do_iconv); 73 if (CFG_TOYBOX_FREE) iconv_close(TT.ic); 74 } 75