• Skip to content
  • Skip to link menu
KDE 4.7 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KIO

script.cpp
Go to the documentation of this file.
00001 /*
00002    Copyright (c) 2003 Malte Starostik <malte@kde.org>
00003    Copyright (c) 2011 Dawit Alemayehu <adawit@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018    Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "script.h"
00022 
00023 #include <QtCore/QString>
00024 #include <QtCore/QRegExp>
00025 #include <QtCore/QDateTime>
00026 #include <QtCore/QTimer>
00027 #include <QtCore/QEventLoop>
00028 
00029 #include <QtNetwork/QHostInfo>
00030 #include <QtNetwork/QHostAddress>
00031 #include <QtNetwork/QNetworkInterface>
00032 
00033 #include <QtScript/QScriptValue>
00034 #include <QtScript/QScriptEngine>
00035 #include <QtScript/QScriptProgram>
00036 #include <QtScript/QScriptContextInfo>
00037 
00038 #include <kurl.h>
00039 #include <klocalizedstring.h>
00040 #include <kio/hostinfo_p.h>
00041 
00042 #define QL1S(x)    QLatin1String(x)
00043 
00044 namespace
00045 {
00046     static int findString (const QString& s, const char* const* values)
00047     {
00048         int index = 0;
00049         const QString lower = s.toLower();
00050         for (const char* const* p = values; *p; ++p, ++index) {
00051             if (s.compare(QLatin1String(*p), Qt::CaseInsensitive) == 0) {
00052               return index;
00053             }
00054         }
00055         return -1;
00056     }
00057 
00058     static const QDateTime getTime (QScriptContext* context)
00059     {
00060         const QString tz = context->argument(context->argumentCount() - 1).toString();
00061         if (tz.compare(QLatin1String("gmt"), Qt::CaseInsensitive) == 0) {
00062             return QDateTime::currentDateTimeUtc();
00063         }
00064         return QDateTime::currentDateTime();
00065     }
00066 
00067     template <typename T>
00068     static bool checkRange (T value, T min, T max)
00069     {
00070         return ((min <= max && value >= min && value <= max) ||
00071                 (min > max && (value <= min || value >= max)));
00072     }
00073 
00074     static bool isLocalHostAddress (const QHostAddress& address)
00075     {
00076         if (address == QHostAddress::LocalHost)
00077             return true;
00078 
00079         if (address == QHostAddress::LocalHostIPv6)
00080             return true;
00081 
00082         return false;
00083     }
00084 
00085     static bool isIPv6Address (const QHostAddress& address)
00086     {
00087         return address.protocol() == QAbstractSocket::IPv6Protocol;
00088     }
00089 
00090     static bool isIPv4Address (const QHostAddress& address)
00091     {
00092         return (address.protocol() == QAbstractSocket::IPv4Protocol);
00093     }
00094 
00095     static bool isSpecialAddress(const QHostAddress& address)
00096     {
00097         // Catch all the special addresses and return false.
00098         if (address == QHostAddress::Null)
00099             return true;
00100 
00101         if (address == QHostAddress::Any)
00102             return true;
00103 
00104         if (address == QHostAddress::AnyIPv6)
00105             return true;
00106 
00107         if (address == QHostAddress::Broadcast)
00108             return true;
00109 
00110         return false;
00111     }
00112 
00113     static bool addressLessThanComparison(const QHostAddress& addr1,  const QHostAddress& addr2)
00114     {
00115         if (addr1.protocol() == QAbstractSocket::IPv4Protocol &&
00116             addr2.protocol() == QAbstractSocket::IPv4Protocol) {
00117             return addr1.toIPv4Address() < addr2.toIPv4Address();
00118         }
00119 
00120         if (addr1.protocol() == QAbstractSocket::IPv6Protocol &&
00121             addr2.protocol() == QAbstractSocket::IPv6Protocol) {
00122             const Q_IPV6ADDR ipv6addr1 = addr1.toIPv6Address();
00123             const Q_IPV6ADDR ipv6addr2 = addr2.toIPv6Address();
00124             for (int i=0; i < 16; ++i) {
00125                 if (ipv6addr1[i] != ipv6addr2[i]) {
00126                     return ((ipv6addr1[i] & 0xff) - (ipv6addr2[i] & 0xff));
00127                 }
00128             }
00129         }
00130 
00131         return false;
00132     }
00133 
00134     static QString addressListToString(const QList<QHostAddress>& addressList,
00135                                        const QHash<QString, QString>& actualEntryMap)
00136     {
00137         QString result;
00138         Q_FOREACH(const QHostAddress& address, addressList) {
00139             if (!result.isEmpty()) {
00140                 result += QLatin1Char(';');
00141             }
00142             result += actualEntryMap.value(address.toString());
00143         }
00144         return result;
00145     }
00146 
00147     class Address
00148     {
00149     public:
00150         struct Error {};
00151         static Address resolve( const QString& host )
00152         {
00153             return Address( host );
00154         }
00155 
00156         QList<QHostAddress> addresses() const
00157         {
00158             return m_addressList;
00159         }
00160 
00161         QHostAddress address() const
00162         {
00163            if (m_addressList.isEmpty())
00164               return QHostAddress();
00165 
00166            return m_addressList.first();
00167         }
00168 
00169     private:
00170         Address( const QString& host )
00171         {
00172             // Always try to see if it's already an IP first, to avoid Qt doing a
00173             // needless reverse lookup
00174             QHostAddress address ( host );
00175             if ( address.isNull() ) {
00176                 QHostInfo hostInfo = KIO::HostInfo::lookupCachedHostInfoFor(host);
00177                 if (hostInfo.hostName().isEmpty() || hostInfo.error() != QHostInfo::NoError) {
00178                     hostInfo = QHostInfo::fromName(host);
00179                     KIO::HostInfo::cacheLookup(hostInfo);
00180                 }
00181                 m_addressList = hostInfo.addresses();
00182             } else {
00183                 m_addressList.clear();
00184                 m_addressList.append(address);
00185             }
00186         }
00187 
00188         QList<QHostAddress> m_addressList;
00189     };
00190 
00191 
00192     // isPlainHostName(host)
00193     // @returns true if @p host doesn't contains a domain part
00194     QScriptValue IsPlainHostName(QScriptContext* context, QScriptEngine* engine)
00195     {
00196         if (context->argumentCount() != 1) {
00197             return engine->undefinedValue();
00198         }
00199         return engine->toScriptValue(context->argument(0).toString().indexOf(QLatin1Char('.')) == -1);
00200     }
00201 
00202     // dnsDomainIs(host, domain)
00203     // @returns true if the domain part of @p host matches @p domain
00204     QScriptValue DNSDomainIs (QScriptContext* context, QScriptEngine* engine)
00205     {
00206         if (context->argumentCount() != 2) {
00207             return engine->undefinedValue();
00208         }
00209 
00210         const QString host = context->argument(0).toString();
00211         const QString domain = context->argument(1).toString();
00212         return engine->toScriptValue(host.endsWith(domain, Qt::CaseInsensitive));
00213     }
00214 
00215     // localHostOrDomainIs(host, fqdn)
00216     // @returns true if @p host is unqualified or equals @p fqdn
00217     QScriptValue LocalHostOrDomainIs (QScriptContext* context, QScriptEngine* engine)
00218     {
00219         if (context->argumentCount() != 2) {
00220             return engine->undefinedValue();
00221         }
00222 
00223         const QString host = context->argument(0).toString();
00224         if (!host.contains(QLatin1Char('.'))) {
00225             return engine->toScriptValue(true);
00226         }
00227         const QString fqdn = context->argument(1).toString();
00228         return engine->toScriptValue((host.compare(fqdn, Qt::CaseInsensitive) == 0));
00229     }
00230 
00231     // isResolvable(host)
00232     // @returns true if host is resolvable to a IPv4 address.
00233     QScriptValue IsResolvable (QScriptContext* context, QScriptEngine* engine)
00234     {
00235         if (context->argumentCount() != 1) {
00236             return engine->undefinedValue();
00237         }
00238 
00239         try {
00240             const Address info = Address::resolve(context->argument(0).toString());
00241             bool hasResolvableIPv4Address = false;
00242 
00243             Q_FOREACH(const QHostAddress& address, info.addresses()) {
00244                 if (!isSpecialAddress(address) && isIPv4Address(address)) {
00245                     hasResolvableIPv4Address = true;
00246                     break;
00247                 }
00248             }
00249 
00250             return engine->toScriptValue(hasResolvableIPv4Address);
00251         }
00252         catch (const Address::Error&) {
00253             return engine->toScriptValue(false);
00254         }
00255     }
00256 
00257     // isInNet(host, subnet, mask)
00258     // @returns true if the IPv4 address of host is within the specified subnet
00259     // and mask, false otherwise.
00260     QScriptValue IsInNet (QScriptContext* context, QScriptEngine* engine)
00261     {
00262         if (context->argumentCount() != 3) {
00263             return engine->undefinedValue();
00264         }
00265 
00266         try {
00267             const Address info = Address::resolve(context->argument(0).toString());
00268             bool isInSubNet = false;
00269             QString subnetStr = context->argument(1).toString();
00270             subnetStr += QLatin1Char('/');
00271             subnetStr += context->argument(2).toString();
00272             const QPair<QHostAddress, int> subnet = QHostAddress::parseSubnet(subnetStr);
00273             Q_FOREACH(const QHostAddress& address, info.addresses()) {
00274                 if (!isSpecialAddress(address) && isIPv4Address(address) && address.isInSubnet(subnet)) {
00275                     isInSubNet = true;
00276                     break;
00277                 }
00278             }
00279             return engine->toScriptValue(isInSubNet);
00280         }
00281         catch (const Address::Error&) {
00282             return engine->toScriptValue(false);
00283         }
00284     }
00285 
00286     // dnsResolve(host)
00287     // @returns the IPv4 address for host or an empty string if host is not resolvable.
00288     QScriptValue DNSResolve (QScriptContext* context, QScriptEngine* engine)
00289     {
00290         if (context->argumentCount() != 1) {
00291             return engine->undefinedValue();
00292         }
00293 
00294         try {
00295             const Address info = Address::resolve(context->argument(0).toString());
00296             QString resolvedAddress (QLatin1String(""));
00297             Q_FOREACH(const QHostAddress& address, info.addresses()) {
00298                 if (!isSpecialAddress(address) && isIPv4Address(address)) {
00299                     resolvedAddress = address.toString();
00300                     break;
00301                 }
00302             }
00303             return engine->toScriptValue(resolvedAddress);
00304         }
00305         catch (const Address::Error&) {
00306             return engine->toScriptValue(QString(QLatin1String("")));
00307         }
00308     }
00309 
00310     // myIpAddress()
00311     // @returns the local machine's IPv4 address. Note that this will return
00312     // the address for the first interfaces that match its criteria even if the
00313     // machine has multiple interfaces.
00314     QScriptValue MyIpAddress (QScriptContext* context, QScriptEngine* engine)
00315     {
00316         if (context->argumentCount()) {
00317             return engine->undefinedValue();
00318         }
00319 
00320         QString ipAddress;
00321         const QList<QHostAddress> addresses = QNetworkInterface::allAddresses();
00322         Q_FOREACH(const QHostAddress address, addresses) {
00323             if (isIPv4Address(address) && !isSpecialAddress(address) && !isLocalHostAddress(address)) {
00324                 ipAddress = address.toString();
00325                 break;
00326             }
00327         }
00328 
00329         return engine->toScriptValue(ipAddress);
00330     }
00331 
00332     // dnsDomainLevels(host)
00333     // @returns the number of dots ('.') in @p host
00334     QScriptValue DNSDomainLevels (QScriptContext* context, QScriptEngine* engine)
00335     {
00336         if (context->argumentCount() != 1) {
00337             return engine->undefinedValue();
00338         }
00339 
00340         const QString host = context->argument(0).toString();
00341         if (host.isNull()) {
00342             return engine->toScriptValue(0);
00343         }
00344 
00345         return engine->toScriptValue(host.count(QLatin1Char('.')));
00346     }
00347 
00348     // shExpMatch(str, pattern)
00349     // @returns true if @p str matches the shell @p pattern
00350     QScriptValue ShExpMatch (QScriptContext* context, QScriptEngine* engine)
00351     {
00352         if (context->argumentCount() != 2) {
00353             return engine->undefinedValue();
00354         }
00355 
00356         QRegExp pattern(context->argument(1).toString(), Qt::CaseSensitive, QRegExp::Wildcard);
00357         return engine->toScriptValue(pattern.exactMatch(context->argument(0).toString()));
00358     }
00359 
00360     // weekdayRange(day [, "GMT" ])
00361     // weekdayRange(day1, day2 [, "GMT" ])
00362     // @returns true if the current day equals day or between day1 and day2 resp.
00363     // If the last argument is "GMT", GMT timezone is used, otherwise local time
00364     QScriptValue WeekdayRange (QScriptContext* context, QScriptEngine* engine)
00365     {
00366         if (context->argumentCount() < 1 || context->argumentCount() > 3) {
00367             return engine->undefinedValue();
00368         }
00369 
00370         static const char* const days[] = { "sun", "mon", "tue", "wed", "thu", "fri", "sat", 0 };
00371 
00372         const int d1 = findString(context->argument(0).toString(), days);
00373         if (d1 == -1) {
00374             return engine->undefinedValue();
00375         }
00376 
00377         int d2 = findString(context->argument(1).toString(), days);
00378         if (d2 == -1) {
00379             d2 = d1;
00380         }
00381 
00382         // Adjust the days of week coming from QDateTime since it starts
00383         // counting with Monday as 1 and ends with Sunday as day 7.
00384         int dayOfWeek = getTime(context).date().dayOfWeek();
00385         if (dayOfWeek == 7) {
00386             dayOfWeek = 0;
00387         }
00388         return engine->toScriptValue(checkRange(dayOfWeek, d1, d2));
00389     }
00390 
00391     // dateRange(day [, "GMT" ])
00392     // dateRange(day1, day2 [, "GMT" ])
00393     // dateRange(month [, "GMT" ])
00394     // dateRange(month1, month2 [, "GMT" ])
00395     // dateRange(year [, "GMT" ])
00396     // dateRange(year1, year2 [, "GMT" ])
00397     // dateRange(day1, month1, day2, month2 [, "GMT" ])
00398     // dateRange(month1, year1, month2, year2 [, "GMT" ])
00399     // dateRange(day1, month1, year1, day2, month2, year2 [, "GMT" ])
00400     // @returns true if the current date (GMT or local time according to
00401     // presence of "GMT" as last argument) is within the given range
00402     QScriptValue DateRange (QScriptContext* context, QScriptEngine* engine)
00403     {
00404         if (context->argumentCount() < 1 || context->argumentCount() > 7) {
00405             return engine->undefinedValue();
00406         }
00407 
00408         static const char* const months[] = { "jan", "feb", "mar", "apr", "may", "jun",
00409                                               "jul", "aug", "sep", "oct", "nov", "dec", 0 };
00410 
00411         QVector<int> values;
00412         for (int i = 0; i < context->argumentCount(); ++i)
00413         {
00414             int value = -1;
00415             if (context->argument(i).isNumber()) {
00416                 value = context->argument(i).toInt32();
00417             } else {
00418                 // QDate starts counting months from 1, so we add 1 here.
00419                 value = findString(context->argument(i).toString(), months) + 1;
00420             }
00421 
00422             if (value > 0) {
00423                 values.append(value);
00424             } else {
00425                 break;
00426             }
00427         }
00428 
00429         const QDate now = getTime(context).date();
00430 
00431         // day1, month1, year1, day2, month2, year2
00432         if (values.size() == 6) {
00433             const QDate d1 (values[2], values[1], values[0]);
00434             const QDate d2 (values[5], values[4], values[3]);
00435             return engine->toScriptValue(checkRange(now, d1, d2));
00436         }
00437         // day1, month1, day2, month2
00438         else if (values.size() == 4 && values[ 1 ] < 13 && values[ 3 ] < 13) {
00439             const QDate d1 (now.year(), values[1], values[0]);
00440             const QDate d2 (now.year(), values[3], values[2]);
00441             return engine->toScriptValue(checkRange(now, d1, d2));
00442         }
00443         // month1, year1, month2, year2
00444         else if (values.size() == 4) {
00445             const QDate d1 (values[1], values[0], now.day());
00446             const QDate d2 (values[3], values[2], now.day());
00447             return engine->toScriptValue(checkRange(now, d1, d2));
00448         }
00449         // year1, year2
00450         else if (values.size() == 2 && values[0] >= 1000 && values[1] >= 1000) {
00451             return engine->toScriptValue(checkRange(now.year(), values[0], values[1]));
00452         }
00453         // day1, day2
00454         else if (values.size() == 2 && context->argument(0).isNumber() && context->argument(1).isNumber()) {
00455             return engine->toScriptValue(checkRange(now.day(), values[0], values[1]));
00456         }
00457         // month1, month2
00458         else if (values.size() == 2) {
00459             return engine->toScriptValue(checkRange(now.month(), values[0], values[1]));
00460         }
00461         // year
00462         else if (values.size() == 1 && values[ 0 ] >= 1000) {
00463             return engine->toScriptValue(checkRange(now.year(), values[0], values[0]));
00464         }
00465         // day
00466         else if (values.size() == 1 && context->argument(0).isNumber()) {
00467             return engine->toScriptValue(checkRange(now.day(), values[0], values[0]));
00468         }
00469         // month
00470         else if (values.size() == 1) {
00471             return engine->toScriptValue(checkRange(now.month(), values[0], values[0]));
00472         }
00473 
00474         return engine->undefinedValue();
00475     }
00476 
00477     // timeRange(hour [, "GMT" ])
00478     // timeRange(hour1, hour2 [, "GMT" ])
00479     // timeRange(hour1, min1, hour2, min2 [, "GMT" ])
00480     // timeRange(hour1, min1, sec1, hour2, min2, sec2 [, "GMT" ])
00481     // @returns true if the current time (GMT or local based on presence
00482     // of "GMT" argument) is within the given range
00483     QScriptValue TimeRange (QScriptContext* context, QScriptEngine* engine)
00484     {
00485         if (context->argumentCount() < 1 || context->argumentCount() > 7) {
00486             return engine->undefinedValue();
00487         }
00488 
00489         QVector<int> values;
00490         for (int i = 0; i < context->argumentCount(); ++i) {
00491             if (!context->argument(i).isNumber()) {
00492                 break;
00493             }
00494             values.append(context->argument(i).toNumber());
00495         }
00496 
00497         const QTime now = getTime(context).time();
00498 
00499         // hour1, min1, sec1, hour2, min2, sec2
00500         if (values.size() == 6) {
00501             const QTime t1 (values[0], values[1], values[2]);
00502             const QTime t2 (values[3], values[4], values[5]);
00503             return engine->toScriptValue(checkRange(now, t1, t2));
00504         }
00505         // hour1, min1, hour2, min2
00506         else if (values.size() == 4) {
00507             const QTime t1 (values[0], values[1]);
00508             const QTime t2 (values[2], values[3]);
00509             return engine->toScriptValue(checkRange(now, t1, t2));
00510         }
00511         // hour1, hour2
00512         else if (values.size() == 2) {
00513             return engine->toScriptValue(checkRange(now.hour(), values[0], values[1]));
00514         }
00515         // hour
00516         else if (values.size() == 1) {
00517             return engine->toScriptValue(checkRange(now.hour(), values[0], values[0]));
00518         }
00519 
00520         return engine->undefinedValue();
00521     }
00522 
00523 
00524     /*
00525      * Implementation of Microsoft's IPv6 Extension for PAC
00526      *
00527      * Documentation:
00528      * http://msdn.microsoft.com/en-us/library/gg308477(v=vs.85).aspx
00529      * http://msdn.microsoft.com/en-us/library/gg308478(v=vs.85).aspx
00530      * http://msdn.microsoft.com/en-us/library/gg308474(v=vs.85).aspx
00531      * http://blogs.msdn.com/b/wndp/archive/2006/07/13/ipv6-pac-extensions-v0-9.aspx
00532      */
00533 
00534     // isResolvableEx(host)
00535     // @returns true if host is resolvable to an IPv4 or IPv6 address.
00536     QScriptValue IsResolvableEx (QScriptContext* context, QScriptEngine* engine)
00537     {
00538         if (context->argumentCount() != 1) {
00539             return engine->undefinedValue();
00540         }
00541 
00542         try {
00543             const Address info = Address::resolve(context->argument(0).toString());
00544             bool hasResolvableIPAddress = false;
00545             Q_FOREACH(const QHostAddress& address, info.addresses()) {
00546                 if (isIPv4Address(address) || isIPv6Address(address)) {
00547                     hasResolvableIPAddress = true;
00548                     break;
00549                 }
00550             }
00551             return engine->toScriptValue(hasResolvableIPAddress);
00552         }
00553         catch (const Address::Error&) {
00554             return engine->toScriptValue(false);
00555         }
00556     }
00557 
00558     // isInNetEx(ipAddress, ipPrefix )
00559     // @returns true if ipAddress is within the specified ipPrefix.
00560     QScriptValue IsInNetEx (QScriptContext* context, QScriptEngine* engine)
00561     {
00562         if (context->argumentCount() != 2) {
00563             return engine->undefinedValue();
00564         }
00565 
00566         try {
00567             const Address info = Address::resolve(context->argument(0).toString());
00568             bool isInSubNet = false;
00569             const QString subnetStr = context->argument(1).toString();
00570             const QPair<QHostAddress, int> subnet = QHostAddress::parseSubnet(subnetStr);
00571 
00572             Q_FOREACH(const QHostAddress& address, info.addresses()) {
00573                 if (isSpecialAddress(address)) {
00574                     continue;
00575                 }
00576 
00577                 if (address.isInSubnet(subnet)) {
00578                     isInSubNet = true;
00579                     break;
00580                 }
00581             }
00582             return engine->toScriptValue(isInSubNet);
00583         }
00584         catch (const Address::Error&) {
00585             return engine->toScriptValue(false);
00586         }
00587     }
00588 
00589     // dnsResolveEx(host)
00590     // @returns a semi-colon delimited string containing IPv6 and IPv4 addresses
00591     // for host or an empty string if host is not resolvable.
00592     QScriptValue DNSResolveEx (QScriptContext* context, QScriptEngine* engine)
00593     {
00594         if (context->argumentCount() != 1) {
00595             return engine->undefinedValue();
00596         }
00597 
00598         try {
00599             const Address info = Address::resolve (context->argument(0).toString());
00600 
00601             QStringList addressList;
00602             QString resolvedAddress (QLatin1String(""));
00603 
00604             Q_FOREACH(const QHostAddress& address, info.addresses()) {
00605                 if (!isSpecialAddress(address)) {
00606                     addressList << address.toString();
00607                 }
00608             }
00609             if (!addressList.isEmpty()) {
00610                 resolvedAddress = addressList.join(QLatin1String(";"));
00611             }
00612 
00613             return engine->toScriptValue(resolvedAddress);
00614         }
00615         catch (const Address::Error&) {
00616             return engine->toScriptValue(QString(QLatin1String("")));
00617         }
00618     }
00619 
00620     // myIpAddressEx()
00621     // @returns a semi-colon delimited string containing all IP addresses for localhost (IPv6 and/or IPv4),
00622     // or an empty string if unable to resolve localhost to an IP address.
00623     QScriptValue MyIpAddressEx (QScriptContext* context, QScriptEngine* engine)
00624     {
00625         if (context->argumentCount()) {
00626             return engine->undefinedValue();
00627         }
00628 
00629         QStringList ipAddressList;
00630         const QList<QHostAddress> addresses = QNetworkInterface::allAddresses();
00631         Q_FOREACH(const QHostAddress address, addresses) {
00632             if (!isSpecialAddress(address) && !isLocalHostAddress(address)) {
00633                 ipAddressList << address.toString();
00634             }
00635         }
00636 
00637         return engine->toScriptValue(ipAddressList.join(QLatin1String(";")));
00638     }
00639 
00640     // sortIpAddressList(ipAddressList)
00641     // @returns a sorted ipAddressList. If both IPv4 and IPv6 addresses are present in
00642     // the list. The sorted IPv6 addresses will precede the sorted IPv4 addresses.
00643     QScriptValue SortIpAddressList(QScriptContext* context, QScriptEngine* engine)
00644     {
00645         if (context->argumentCount() != 1) {
00646            return engine->undefinedValue();
00647         }
00648 
00649         QHash<QString, QString> actualEntryMap;
00650         QList<QHostAddress> ipV4List, ipV6List;
00651         const QStringList ipAddressList = context->argument(0).toString().split(QLatin1Char(';'));
00652 
00653         Q_FOREACH(const QString& ipAddress, ipAddressList) {
00654             QHostAddress address(ipAddress);
00655             switch (address.protocol()) {
00656             case QAbstractSocket::IPv4Protocol:
00657                 ipV4List << address;
00658                 actualEntryMap.insert(address.toString(), ipAddress);
00659                 break;
00660             case QAbstractSocket::IPv6Protocol:
00661                 ipV6List << address;
00662                 actualEntryMap.insert(address.toString(), ipAddress);
00663                 break;
00664             default:
00665                 break;
00666             }
00667         }
00668 
00669         QString sortedAddress (QLatin1String(""));
00670 
00671         if (!ipV6List.isEmpty()) {
00672             qSort(ipV6List.begin(), ipV6List.end(), addressLessThanComparison);
00673             sortedAddress += addressListToString(ipV6List, actualEntryMap);
00674         }
00675 
00676         if (!ipV4List.isEmpty()) {
00677             qSort(ipV4List.begin(), ipV4List.end(), addressLessThanComparison);
00678             if (!sortedAddress.isEmpty()) {
00679                 sortedAddress += QLatin1Char(';');
00680             }
00681             sortedAddress += addressListToString(ipV4List, actualEntryMap);
00682         }
00683 
00684         return engine->toScriptValue(sortedAddress);
00685 
00686     }
00687 
00688     // getClientVersion
00689     // @return the version number of this engine for future extension. We too start
00690     // this at version 1.0.
00691     QScriptValue GetClientVersion (QScriptContext* context, QScriptEngine* engine)
00692     {
00693         if (context->argumentCount()) {
00694             return engine->undefinedValue();
00695         }
00696 
00697         const QString version (QLatin1String("1.0"));
00698         return engine->toScriptValue(version);
00699     }
00700 
00701     void registerFunctions(QScriptEngine* engine)
00702     {
00703         QScriptValue value = engine->globalObject();
00704         value.setProperty(QL1S("isPlainHostName"), engine->newFunction(IsPlainHostName));
00705         value.setProperty(QL1S("dnsDomainIs"), engine->newFunction(DNSDomainIs));
00706         value.setProperty(QL1S("localHostOrDomainIs"), engine->newFunction(LocalHostOrDomainIs));
00707         value.setProperty(QL1S("isResolvable"), engine->newFunction(IsResolvable));
00708         value.setProperty(QL1S("isInNet"), engine->newFunction(IsInNet));
00709         value.setProperty(QL1S("dnsResolve"), engine->newFunction(DNSResolve));
00710         value.setProperty(QL1S("myIpAddress"), engine->newFunction(MyIpAddress));
00711         value.setProperty(QL1S("dnsDomainLevels"), engine->newFunction(DNSDomainLevels));
00712         value.setProperty(QL1S("shExpMatch"), engine->newFunction(ShExpMatch));
00713         value.setProperty(QL1S("weekdayRange"), engine->newFunction(WeekdayRange));
00714         value.setProperty(QL1S("dateRange"), engine->newFunction(DateRange));
00715         value.setProperty(QL1S("timeRange"), engine->newFunction(TimeRange));
00716 
00717         // Microsoft's IPv6 PAC Extensions...
00718         value.setProperty(QL1S("isResolvableEx"), engine->newFunction(IsResolvableEx));
00719         value.setProperty(QL1S("isInNetEx"), engine->newFunction(IsInNetEx));
00720         value.setProperty(QL1S("dnsResolveEx"), engine->newFunction(DNSResolveEx));
00721         value.setProperty(QL1S("myIpAddressEx"), engine->newFunction(MyIpAddressEx));
00722         value.setProperty(QL1S("sortIpAddressList"), engine->newFunction(SortIpAddressList));
00723         value.setProperty(QL1S("getClientVersion"), engine->newFunction(GetClientVersion));
00724     }
00725 }
00726 
00727 namespace KPAC
00728 {
00729     Script::Script(const QString& code)
00730     {
00731         m_engine = new QScriptEngine;
00732         registerFunctions(m_engine);
00733 
00734         QScriptProgram program (code);
00735         const QScriptValue result = m_engine->evaluate(program);
00736         if (m_engine->hasUncaughtException() || result.isError())
00737             throw Error(m_engine->uncaughtException().toString());
00738     }
00739 
00740     Script::~Script()
00741     {
00742         delete m_engine;
00743     }
00744 
00745     QString Script::evaluate(const KUrl& url)
00746     {
00747         QScriptValue func = m_engine->globalObject().property(QL1S("FindProxyForURL"));
00748 
00749         if (!func.isValid()) {
00750             func = m_engine->globalObject().property(QL1S("FindProxyForURLEx"));
00751             if (!func.isValid()) {
00752                 throw Error(i18n("Could not find 'FindProxyForURL' or 'FindProxyForURLEx'"));
00753                 return QString();
00754             }
00755         }
00756 
00757         QScriptValueList args;
00758         args << url.url();
00759         args << url.host();
00760 
00761         QScriptValue result = func.call(QScriptValue(), args);
00762         if (result.isError()) {
00763             throw Error(i18n("Got an invalid reply when calling %1", func.toString()));
00764         }
00765 
00766         return result.toString();
00767     }
00768 }
00769 
00770 // vim: ts=4 sw=4 et

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal