1155835Sume/*- 2155835Sume * Copyright (c) 2006 Hajimu UMEMOTO <ume@FreeBSD.org> 3155835Sume * All rights reserved. 4155835Sume * 5155835Sume * Redistribution and use in source and binary forms, with or without 6155835Sume * modification, are permitted provided that the following conditions 7155835Sume * are met: 8155835Sume * 1. Redistributions of source code must retain the above copyright 9155835Sume * notice, this list of conditions and the following disclaimer. 10155835Sume * 2. Redistributions in binary form must reproduce the above copyright 11155835Sume * notice, this list of conditions and the following disclaimer in the 12155835Sume * documentation and/or other materials provided with the distribution. 13155835Sume * 14155835Sume * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15155835Sume * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16155835Sume * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17155835Sume * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18155835Sume * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19155835Sume * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20155835Sume * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21155835Sume * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22155835Sume * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23155835Sume * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24155835Sume * SUCH DAMAGE. 25155835Sume * 26155835Sume * $FreeBSD$ 27155835Sume */ 28155835Sume 29155835Sume#include <dlfcn.h> 30155835Sume#include <stddef.h> 31155835Sume 32155835Sume#include "iconv.h" 33155835Sume 34155835Sume#undef iconv_open 35155835Sume#undef iconv 36155835Sume#undef iconv_close 37155835Sume 38155835Sume#define ICONVLIB "libiconv.so" 39295147Sume#define ICONV_ENGINE "libiconv" 40295147Sume#define ICONV_OPEN "libiconv_open" 41295147Sume#define ICONV_CLOSE "libiconv_close" 42155835Sume 43155835Sumetypedef iconv_t iconv_open_t(const char *, const char *); 44155835Sume 45155835Sumedl_iconv_t *dl_iconv; 46155835Sumedl_iconv_close_t *dl_iconv_close; 47155835Sume 48155835Sumestatic int initialized; 49155835Sumestatic void *iconvlib; 50155835Sumestatic iconv_open_t *iconv_open; 51155835Sume 52155835Sumeiconv_t 53155835Sumedl_iconv_open(const char *tocode, const char *fromcode) 54155835Sume{ 55155835Sume if (initialized) { 56155835Sume if (iconvlib == NULL) 57155835Sume return (iconv_t)-1; 58155835Sume } else { 59155835Sume initialized = 1; 60155835Sume iconvlib = dlopen(ICONVLIB, RTLD_LAZY | RTLD_GLOBAL); 61155835Sume if (iconvlib == NULL) 62155835Sume return (iconv_t)-1; 63155835Sume iconv_open = (iconv_open_t *)dlfunc(iconvlib, ICONV_OPEN); 64198189Sume if (iconv_open == NULL) 65198189Sume goto dlfunc_err; 66155835Sume dl_iconv = (dl_iconv_t *)dlfunc(iconvlib, ICONV_ENGINE); 67198189Sume if (dl_iconv == NULL) 68198189Sume goto dlfunc_err; 69155835Sume dl_iconv_close = (dl_iconv_close_t *)dlfunc(iconvlib, 70155835Sume ICONV_CLOSE); 71198189Sume if (dl_iconv_close == NULL) 72198189Sume goto dlfunc_err; 73155835Sume } 74155835Sume return iconv_open(tocode, fromcode); 75198189Sume 76198189Sumedlfunc_err: 77198189Sume dlclose(iconvlib); 78198189Sume iconvlib = NULL; 79198189Sume return (iconv_t)-1; 80155835Sume} 81