00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "kidna.h"
00023
00024
#include <qstringlist.h>
00025
#include <kdebug.h>
00026
00027
#include "ltdl.h"
00028
#include <stdlib.h>
00029
00030
#define IDNA_SUCCESS 0
00031
00032
static lt_dlhandle KIDNA_lib;
00033
static bool KIDNA_lib_load_failed;
00034
00035
typedef int (*KIDNA_utf8_to_ace_t)(
const char *,
char **,
int);
00036
typedef int (*KIDNA_utf8ace_to_utf8_t)(
const char *,
char **,
int);
00037
00038
static KIDNA_utf8_to_ace_t KIDNA_utf8_to_ace;
00039
static KIDNA_utf8ace_to_utf8_t KIDNA_utf8ace_to_utf8;
00040
00041
static void KIDNA_load_lib()
00042 {
00043 KIDNA_lib_load_failed =
true;
00044 KIDNA_lib = lt_dlopen(
"/usr/local/lib/libidn.la");
00045
if (!KIDNA_lib)
00046 {
00047 KIDNA_lib = lt_dlopen(
"/usr/lib/libidn.la");
00048 }
00049
00050
if (!KIDNA_lib)
00051
return;
00052
00053 KIDNA_utf8_to_ace = (KIDNA_utf8_to_ace_t) lt_dlsym(KIDNA_lib,
"idna_to_ascii_8z");
00054
if (!KIDNA_utf8_to_ace)
00055 {
00056 kdWarning() <<
"Symbol idna_utf8_to_ace not found." <<
endl;
00057
return;
00058 }
00059
00060 KIDNA_utf8ace_to_utf8 = (KIDNA_utf8ace_to_utf8_t) lt_dlsym(KIDNA_lib,
"idna_to_unicode_8z8z");
00061
if (!KIDNA_utf8ace_to_utf8)
00062 {
00063 kdWarning() <<
"Symbol idna_utf8ace_to_utf8 not found." <<
endl;
00064
return;
00065 }
00066 KIDNA_lib_load_failed =
false;
00067 }
00068
00069
static QStringList *KIDNA_idnDomains = 0;
00070
00071
static bool idnSupportForHost(
const QString &host)
00072 {
00073
if (!KIDNA_idnDomains)
00074 {
00075
const char *kde_use_idn = getenv(
"KDE_USE_IDN");
00076
if (!kde_use_idn)
00077 kde_use_idn =
"at:ch:cn:de:dk:kr:jp:li:no:se:tw";
00078 KIDNA_idnDomains =
new QStringList(QStringList::split(
':', QString::fromLatin1(kde_use_idn).lower()));
00079 }
00080
00081
QString tld = host.
mid(host.
findRev(
'.')+1).lower();
00082
return KIDNA_idnDomains->contains(tld);
00083 }
00084
00085
QCString KIDNA::toAsciiCString(
const QString &idna)
00086 {
00087
int l = idna.
length();
00088
const QChar *u = idna.
unicode();
00089
bool needConversion =
false;
00090
for(;l--;)
00091 {
00092
if ((*u++).unicode() > 127)
00093 {
00094 needConversion =
true;
00095
break;
00096 }
00097 }
00098
if (!needConversion)
00099
return idna.
lower().latin1();
00100
00101
if (!KIDNA_lib && !KIDNA_lib_load_failed)
00102 {
00103 KIDNA_load_lib();
00104 }
00105
00106
if (KIDNA_lib_load_failed || !idnSupportForHost(idna))
00107 {
00108
return 0;
00109 }
00110
else
00111 {
00112
00113
00114
bool bStartsWithDot = (idna[0] ==
'.');
00115
char *pOutput;
00116
if ((*KIDNA_utf8_to_ace)(idna.utf8().data()+(bStartsWithDot ? 1: 0), &pOutput, 0) == IDNA_SUCCESS)
00117 {
00118
QCString result = pOutput;
00119 free(pOutput);
00120
if (bStartsWithDot)
00121
return "."+result;
00122
return result;
00123 }
00124
else
00125 {
00126
return 0;
00127 }
00128 }
00129 }
00130
00131
QString KIDNA::toAscii(
const QString &idna)
00132 {
00133
int l = idna.
length();
00134
const QChar *u = idna.
unicode();
00135
bool needConversion =
false;
00136
for(;l--;)
00137 {
00138
if ((*u++).unicode() > 127)
00139 {
00140 needConversion =
true;
00141
break;
00142 }
00143 }
00144
if (!needConversion)
00145
return idna.
lower();
00146
00147
if (!KIDNA_lib && !KIDNA_lib_load_failed)
00148 {
00149 KIDNA_load_lib();
00150 }
00151
00152
if (KIDNA_lib_load_failed || !idnSupportForHost(idna))
00153 {
00154
return QString::null;
00155 }
00156
else
00157 {
00158
00159
00160
bool bStartsWithDot = (idna[0] ==
'.');
00161
char *pOutput;
00162
if ((*KIDNA_utf8_to_ace)(idna.utf8().data()+(bStartsWithDot ? 1: 0), &pOutput, 0) == IDNA_SUCCESS)
00163 {
00164
QString result(pOutput);
00165 free(pOutput);
00166
if (bStartsWithDot)
00167
return "."+result;
00168
return result;
00169 }
00170
else
00171 {
00172
return QString::null;
00173 }
00174 }
00175 }
00176
00177
QString KIDNA::toUnicode(
const QString &idna)
00178 {
00179
if (!KIDNA_lib && !KIDNA_lib_load_failed)
00180 {
00181 KIDNA_load_lib();
00182 }
00183
00184
if (KIDNA_lib_load_failed || !idnSupportForHost(idna))
00185 {
00186
return idna.
lower();
00187 }
00188
else
00189 {
00190
char *pOutput;
00191
if ((*KIDNA_utf8ace_to_utf8)(idna.
utf8(), &pOutput, 0) == IDNA_SUCCESS)
00192 {
00193
QString result =
QString::fromUtf8(pOutput);
00194 free(pOutput);
00195
return result;
00196 }
00197
else
00198 {
00199
return idna.
lower();
00200 }
00201 }
00202 }