1/* Charset handling for GNU tar. 2 3 Copyright (C) 2004, 2006 Free Software Foundation, Inc. 4 5 This program is free software; you can redistribute it and/or modify it 6 under the terms of the GNU General Public License as published by the 7 Free Software Foundation; either version 2, or (at your option) any later 8 version. 9 10 This program is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 13 Public License for more details. 14 15 You should have received a copy of the GNU General Public License along 16 with this program; if not, write to the Free Software Foundation, Inc., 17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 18 19#include <system.h> 20#include <quotearg.h> 21#include <localcharset.h> 22#include "common.h" 23#ifdef HAVE_ICONV_H 24# include <iconv.h> 25#endif 26 27#ifndef ICONV_CONST 28# define ICONV_CONST 29#endif 30 31#ifndef HAVE_ICONV 32 33# undef iconv_open 34# define iconv_open(tocode, fromcode) ((iconv_t) -1) 35 36# undef iconv 37# define iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft) ((size_t) 0) 38 39# undef iconv_close 40# define iconv_close(cd) 0 41 42#endif 43 44 45 46 47static iconv_t conv_desc[2] = { (iconv_t) -1, (iconv_t) -1 }; 48 49static iconv_t 50utf8_init (bool to_utf) 51{ 52 if (conv_desc[(int) to_utf] == (iconv_t) -1) 53 { 54 if (to_utf) 55 conv_desc[(int) to_utf] = iconv_open ("UTF-8", locale_charset ()); 56 else 57 conv_desc[(int) to_utf] = iconv_open (locale_charset (), "UTF-8"); 58 } 59 return conv_desc[(int) to_utf]; 60} 61 62bool 63utf8_convert (bool to_utf, char const *input, char **output) 64{ 65 char ICONV_CONST *ib; 66 char *ob; 67 size_t inlen; 68 size_t outlen; 69 size_t rc; 70 iconv_t cd = utf8_init (to_utf); 71 72 if (cd == 0) 73 { 74 *output = xstrdup (input); 75 return true; 76 } 77 else if (cd == (iconv_t)-1) 78 return false; 79 80 inlen = strlen (input) + 1; 81 outlen = inlen * MB_LEN_MAX + 1; 82 ob = *output = xmalloc (outlen); 83 ib = (char ICONV_CONST *) input; 84 rc = iconv (cd, &ib, &inlen, &ob, &outlen); 85 *ob = 0; 86 return rc != -1; 87} 88 89 90bool 91string_ascii_p (char const *p) 92{ 93 for (; *p; p++) 94 if (! (0 <= *p && *p <= 127)) 95 return false; 96 return true; 97} 98