200 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			200 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/* fnxform - use iconv(3) to transform strings to and from "filename" format */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Copyright (C) 2009-2010 Free Software Foundation, Inc.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   This file is part of GNU Bash, the Bourne Again SHell.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   Bash is free software: you can redistribute it and/or modify
							 | 
						||
| 
								 | 
							
								   it under the terms of the GNU General Public License as published by
							 | 
						||
| 
								 | 
							
								   the Free Software Foundation, either version 3 of the License, or
							 | 
						||
| 
								 | 
							
								   (at your option) any later version.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   Bash is distributed in the hope that it will be useful,
							 | 
						||
| 
								 | 
							
								   but WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						||
| 
								 | 
							
								   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
							 | 
						||
| 
								 | 
							
								   GNU General Public License for more details.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   You should have received a copy of the GNU General Public License
							 | 
						||
| 
								 | 
							
								   along with Bash.  If not, see <http://www.gnu.org/licenses/>.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <config.h>
							 | 
						||
| 
								 | 
							
								#if defined (HAVE_UNISTD_H)
							 | 
						||
| 
								 | 
							
								#  include <unistd.h>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#include "bashansi.h"
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								#include "bashtypes.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "stdc.h"
							 | 
						||
| 
								 | 
							
								#include "bashintl.h"
							 | 
						||
| 
								 | 
							
								#include <xmalloc.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined (HAVE_ICONV)
							 | 
						||
| 
								 | 
							
								#  include <iconv.h>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined (HAVE_LOCALE_CHARSET)
							 | 
						||
| 
								 | 
							
								extern const char *locale_charset __P((void));
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								extern char *get_locale_var __P((char *));
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined (HAVE_ICONV)
							 | 
						||
| 
								 | 
							
								static iconv_t conv_fromfs = (iconv_t)-1;
							 | 
						||
| 
								 | 
							
								static iconv_t conv_tofs = (iconv_t)-1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define OUTLEN_MAX 4096
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static char *outbuf = 0;
							 | 
						||
| 
								 | 
							
								static size_t outlen = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static char *curencoding __P((void));
							 | 
						||
| 
								 | 
							
								static void init_tofs __P((void));
							 | 
						||
| 
								 | 
							
								static void init_fromfs __P((void));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static char *
							 | 
						||
| 
								 | 
							
								curencoding ()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  char *loc;
							 | 
						||
| 
								 | 
							
								#if defined (HAVE_LOCALE_CHARSET)
							 | 
						||
| 
								 | 
							
								  loc = (char *)locale_charset ();
							 | 
						||
| 
								 | 
							
								  return loc;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								  char *dot, *mod;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  loc = get_locale_var ("LC_CTYPE");
							 | 
						||
| 
								 | 
							
								  if (loc == 0 || *loc == 0)
							 | 
						||
| 
								 | 
							
								    return "";
							 | 
						||
| 
								 | 
							
								  dot = strchr (loc, '.');
							 | 
						||
| 
								 | 
							
								  if (dot == 0)
							 | 
						||
| 
								 | 
							
								    return loc;
							 | 
						||
| 
								 | 
							
								  mod = strchr (dot, '@');
							 | 
						||
| 
								 | 
							
								  if (mod)
							 | 
						||
| 
								 | 
							
								    *mod = '\0';
							 | 
						||
| 
								 | 
							
								  return ++dot;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void
							 | 
						||
| 
								 | 
							
								init_tofs ()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  char *cur;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  cur = curencoding ();
							 | 
						||
| 
								 | 
							
								  conv_tofs = iconv_open ("UTF-8-MAC", cur);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void
							 | 
						||
| 
								 | 
							
								init_fromfs ()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  char *cur;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  cur = curencoding ();
							 | 
						||
| 
								 | 
							
								  conv_fromfs = iconv_open (cur, "UTF-8-MAC");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								char *
							 | 
						||
| 
								 | 
							
								fnx_tofs (string, len)
							 | 
						||
| 
								 | 
							
								     char *string;
							 | 
						||
| 
								 | 
							
								     size_t len;
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#ifdef MACOSX
							 | 
						||
| 
								 | 
							
								  ICONV_CONST char *inbuf;
							 | 
						||
| 
								 | 
							
								  char *tempbuf;
							 | 
						||
| 
								 | 
							
								  size_t templen;
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  if (conv_tofs == (iconv_t)-1)
							 | 
						||
| 
								 | 
							
								    init_tofs ();
							 | 
						||
| 
								 | 
							
								  if (conv_tofs == (iconv_t)-1)
							 | 
						||
| 
								 | 
							
								    return string;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Free and reallocate outbuf if it's *too* big */
							 | 
						||
| 
								 | 
							
								  if (outlen >= OUTLEN_MAX && len < OUTLEN_MAX - 8)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      free (outbuf);
							 | 
						||
| 
								 | 
							
								      outbuf = 0;
							 | 
						||
| 
								 | 
							
								      outlen = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  inbuf = string;
							 | 
						||
| 
								 | 
							
								  if (outbuf == 0 || outlen < len + 8)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      outlen = len + 8;
							 | 
						||
| 
								 | 
							
								      outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  tempbuf = outbuf;
							 | 
						||
| 
								 | 
							
								  templen = outlen;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  iconv (conv_tofs, NULL, NULL, NULL, NULL);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (iconv (conv_tofs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1)
							 | 
						||
| 
								 | 
							
								    return string;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  *tempbuf = '\0';
							 | 
						||
| 
								 | 
							
								  return outbuf;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								  return string;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								char *
							 | 
						||
| 
								 | 
							
								fnx_fromfs (string, len)
							 | 
						||
| 
								 | 
							
								     char *string;
							 | 
						||
| 
								 | 
							
								     size_t len;
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#ifdef MACOSX
							 | 
						||
| 
								 | 
							
								  ICONV_CONST char *inbuf;
							 | 
						||
| 
								 | 
							
								  char *tempbuf;
							 | 
						||
| 
								 | 
							
								  size_t templen;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (conv_fromfs == (iconv_t)-1)
							 | 
						||
| 
								 | 
							
								    init_fromfs ();
							 | 
						||
| 
								 | 
							
								  if (conv_fromfs == (iconv_t)-1)
							 | 
						||
| 
								 | 
							
								    return string;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Free and reallocate outbuf if it's *too* big */
							 | 
						||
| 
								 | 
							
								  if (outlen >= OUTLEN_MAX && len < OUTLEN_MAX - 8)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      free (outbuf);
							 | 
						||
| 
								 | 
							
								      outbuf = 0;
							 | 
						||
| 
								 | 
							
								      outlen = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  inbuf = string;
							 | 
						||
| 
								 | 
							
								  if (outbuf == 0 || outlen < (len + 8))
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      outlen = len + 8;
							 | 
						||
| 
								 | 
							
								      outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  tempbuf = outbuf;
							 | 
						||
| 
								 | 
							
								  templen = outlen;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  iconv (conv_fromfs, NULL, NULL, NULL, NULL);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (iconv (conv_fromfs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1)
							 | 
						||
| 
								 | 
							
								    return string;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  *tempbuf = '\0';
							 | 
						||
| 
								 | 
							
								  return outbuf;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								  return string;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								char *
							 | 
						||
| 
								 | 
							
								fnx_tofs (string)
							 | 
						||
| 
								 | 
							
								     char *string;
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  return string;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								char *
							 | 
						||
| 
								 | 
							
								fnx_fromfs (string)
							 | 
						||
| 
								 | 
							
								     char *string;
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  return string;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif
							 |