diff --git a/configure.ac b/configure.ac index 394775b2..c7f105c2 100644 --- a/configure.ac +++ b/configure.ac @@ -561,7 +561,6 @@ then LIBS="$my_saved_LIBS" fi -AM_ICONV PKG_CHECK_MODULES([icu], [icu-uc], [ appendLib "$icu_LIBS" appendCXX "$icu_CFLAGS" @@ -599,8 +598,6 @@ AC_SUBST([MODLINK]) AC_SUBST([NOSSL]) AC_SUBST([TCL_FLAGS]) AC_SUBST([CYRUS]) -AC_SUBST([CHARSET]) -AC_SUBST([LIBICONV]) AC_SUBST([MODDIR]) AC_SUBST([DATADIR]) AC_SUBST([PERL]) @@ -638,13 +635,8 @@ if test x"$TCL_FLAGS" = "x" ; then else echo "tcl: yes" fi -if test x"$HAVE_ICONV" = "x" ; then - echo "charset: no" -else - echo "charset: yes" -fi +echo "charset: $HAVE_ICU" echo "zlib: $ZLIB" -echo "icu: $HAVE_ICU" echo "run from src: $RUNFROMSOURCE" echo echo "Now you can run \"$GNUMAKE\" to compile ZNC" diff --git a/modules/Makefile.in b/modules/Makefile.in index 6495bda9..0dea7dab 100644 --- a/modules/Makefile.in +++ b/modules/Makefile.in @@ -88,11 +88,6 @@ FILES := $(shell echo $(FILES) | sed -e "s:cyrusauth::") endif cyrusauthLDFLAGS := -lsasl2 -ifeq "@HAVE_ICONV@" "" -FILES := $(shell echo $(FILES) | sed -e "s:charset::") -endif -charsetLDFLAGS := @LIBICONV@ - TARGETS := $(addsuffix .so, $(FILES)) CLEAN += *.so *.o diff --git a/modules/charset.cpp b/modules/charset.cpp deleted file mode 100644 index 973489a7..00000000 --- a/modules/charset.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (C) 2004-2014 ZNC, see the NOTICE file for details. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#ifndef ICONV_CONST -/* configure is supposed to define this, depending on whether the second - argument to iconv is const char** or just char**, but if it isn't defined, - we default to GNU/Linux which is non-const. */ -#define ICONV_CONST -#endif - -class CCharsetMod : public CModule -{ -private: - VCString m_vsClientCharsets; - VCString m_vsServerCharsets; - bool m_bForce; // don't check whether the input string is already a - // valid string in the target charset. Instead, always apply conversion. - - size_t GetConversionLength(iconv_t& ic, const CString& sData) - { - if(sData.empty()) return 0; - - size_t uLength = 0; - char tmpbuf[1024]; - const char *pIn = sData.c_str(); - size_t uInLen = sData.size(); - bool bBreak; - - do - { - char *pOut = tmpbuf; - size_t uBufSize = sizeof(tmpbuf); - bBreak = (uInLen < 1); - - if(iconv(ic, // this is ugly, but keeps the code short: - (uInLen < 1 ? NULL : (ICONV_CONST char**)&pIn), - (uInLen < 1 ? NULL : &uInLen), - &pOut, &uBufSize) == (size_t)-1) - // explanation: iconv needs a last call with input = NULL to - // copy/convert possibly left data chunks into the output buffer. - { - if(errno == EINVAL) - { - // charset is not what we think it is. - return (size_t)-1; - } - else if(errno != E2BIG) - { - // something bad happened, internal error. - return (size_t)-2; - } - } - - uLength += sizeof(tmpbuf) - uBufSize; - } while(!bBreak); - - return uLength; - } - - bool ConvertCharset(const CString& sFrom, const CString& sTo, CString& sData) - { - if(sData.empty()) return true; - - DEBUG("charset: Trying to convert [" + sData.Escape_n(CString::EURL) + "] from [" + sFrom + "] to [" + sTo + "]..."); - - iconv_t ic = iconv_open(sTo.c_str(), sFrom.c_str()); - if(ic == (iconv_t)-1) return false; - - size_t uLength = GetConversionLength(ic, sData); - - if(uLength == (size_t)-1) - { - // incompatible input encoding. - iconv_close(ic); - return false; - } - else if(uLength == (size_t)-2) - { - // internal error, preserve errno from GetConversionLength: - int tmp_errno = errno; - iconv_close(ic); - errno = tmp_errno; - return false; - } - else - { - // no error, so let's do the actual conversion. - - iconv(ic, NULL, NULL, NULL, NULL); // reset - - // state vars for iconv: - size_t uResultBufSize = uLength + 1; - char *pResult = new char[uResultBufSize]; - memset(pResult, 0, uResultBufSize); - char *pResultWalker = pResult; - const char* pIn = sData.c_str(); - size_t uInLen = sData.size(); - - // let's fcking do it! - size_t uResult = iconv(ic, (ICONV_CONST char**)&pIn, &uInLen, &pResultWalker, &uResultBufSize); - bool bResult = (uResult != (size_t)-1); - - iconv_close(ic); - - if(bResult) - { - sData.assign(pResult, (uLength + 1) - uResultBufSize); - - DEBUG("charset: Converted: [" + sData.Escape_n(CString::EURL) + "] from [" + sFrom + "] to [" + sTo + "]!"); - } - else - { - DEBUG("Conversion failed: [" << uResult << "]"); - } - - delete[] pResult; - - return bResult; - } - } - - bool ConvertCharset(const VCString& vsFrom, const CString& sTo, CString& sData) - { - CString sDataCopy(sData); - - if(!m_bForce) - { - // check whether sData already is encoded with the right charset: - iconv_t icTest = iconv_open(sTo.c_str(), sTo.c_str()); - if(icTest != (iconv_t)-1) - { - size_t uTest = GetConversionLength(icTest, sData); - iconv_close(icTest); - - if(uTest != (size_t)-1 && uTest != (size_t)-2) - { - DEBUG("charset: [" + sData.Escape_n(CString::EURL) + "] is valid [" + sTo + "] already."); - return true; - } - } - } - - bool bConverted = false; - - // try all possible source charsets: - for(VCString::const_iterator itf = vsFrom.begin(); itf != vsFrom.end(); ++itf) - { - if(ConvertCharset(*itf, sTo, sDataCopy)) - { - // conversion successful! - sData = sDataCopy; - bConverted = true; - break; - } - else - { - // reset string and try the next charset: - sDataCopy = sData; - } - } - - return bConverted; - } - -public: - MODCONSTRUCTOR(CCharsetMod) - { - m_bForce = false; - } - - bool OnLoad(const CString& sArgs, CString& sMessage) - { - size_t uIndex = 0; - - if(sArgs.Token(0).Equals("-force")) - { - m_bForce = true; - ++uIndex; - } - - if(sArgs.Token(uIndex + 1).empty() || !sArgs.Token(uIndex + 2).empty()) - { - sMessage = "This module needs two charset lists as arguments: [-force] " - " " - ""; - return false; - // the first charset in each list is the preferred one for - // messages to the client / to the server. - } - - VCString vsFrom, vsTo; - sArgs.Token(uIndex).Split(",", vsFrom); - sArgs.Token(uIndex + 1).Split(",", vsTo); - - // probe conversions: - for(VCString::const_iterator itf = vsFrom.begin(); itf != vsFrom.end(); ++itf) - { - for(VCString::const_iterator itt = vsTo.begin(); itt != vsTo.end(); ++itt) - { - iconv_t icTest = iconv_open(itt->c_str(), itf->c_str()); - if(icTest == (iconv_t)-1) - { - sMessage = "Conversion from '" + *itf + "' to '" + *itt + "' is not possible."; - return false; - } - iconv_close(icTest); - - icTest = iconv_open(itf->c_str(), itt->c_str()); - if(icTest == (iconv_t)-1) - { - sMessage = "Conversion from '" + *itt + "' to '" + *itf + "' is not possible."; - return false; - } - iconv_close(icTest); - } - } - - m_vsClientCharsets = vsFrom; - m_vsServerCharsets = vsTo; - - return true; - } - - EModRet OnRaw(CString& sLine) - { - // convert IRC server -> client - ConvertCharset(m_vsServerCharsets, m_vsClientCharsets[0], sLine); - return CONTINUE; - } - - EModRet OnUserRaw(CString& sLine) - { - // convert client -> IRC server - ConvertCharset(m_vsClientCharsets, m_vsServerCharsets[0], sLine); - return CONTINUE; - } -}; - -template<> void TModInfo(CModInfo& Info) -{ - Info.SetWikiPage("charset"); - Info.SetHasArgs(true); - Info.SetArgsHelpText("Two charset lists: [-force] " - " " - ""); -} - -USERMODULEDEFS(CCharsetMod, "Normalizes character encodings.") diff --git a/src/User.cpp b/src/User.cpp index 4b47a75a..cf664f1b 100644 --- a/src/User.cpp +++ b/src/User.cpp @@ -408,6 +408,28 @@ bool CUser::ParseConfig(CConfig* pConfig, CString& sError) { sModName = "modules_online"; } + // XXX Legacy crap, added in 1.3 + if (sModName == "charset") { + CUtils::PrintAction("NOTICE: Charset support was moved to core, importing old charset module settings"); + size_t uIndex = 1; + if (sValue.Token(uIndex).Equals("-force")) { + uIndex++; + } + VCString vsClient, vsServer; + sValue.Token(uIndex).Split(",", vsClient); + sValue.Token(uIndex + 1).Split(",", vsServer); + if (vsClient.empty() || vsServer.empty()) { + CUtils::PrintStatus(false, "charset module was loaded with wrong parameters."); + continue; + } + SetClientEncoding(vsClient[0]); + for (vector::iterator it = m_vIRCNetworks.begin(); it != m_vIRCNetworks.end(); ++it) { + (*it)->SetEncoding(vsServer[0]); + } + CUtils::PrintStatus(true, "Using [" + vsClient[0] + "] for clients, and [" + vsServer[0] + "] for servers"); + continue; + } + CUtils::PrintAction("Loading user module [" + sModName + "]"); CString sModRet; CString sArgs = sValue.Token(1, true);