# kio Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# kproxybindings.cpp

    00001 /*
    00002  *  $Id: kproxybindings.cpp,v 1.15.2.1 2003/04/07 14:32:39 mutz Exp $
    00003  *  KJS-Bindings for Proxy Auto Configuration
    00004  *
    00005  *  Copyright (C) 2000 Malte Starostik <malte@kde.org>
    00006  *
    00007  *  This library is free software; you can redistribute it and/or
    00008  *  modify it under the terms of the GNU Library General Public
    00009  *  License as published by the Free Software Foundation; either
    00010  *  version 2 of the License, or (at your option) any later version.
    00011  *
    00012  *  This library is distributed in the hope that it will be useful,
    00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00015  *  Library General Public License for more details.
    00016  *
    00017  *  You should have received a copy of the GNU Library General Public License
    00018  *  along with this library; see the file COPYING.LIB.  If not, write to
    00019  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00020  *  Boston, MA 02111-1307, USA.
    00021  */
    00022
    00023 #include <unistd.h>
    00024 #include <sys/types.h>
    00025 #include <sys/socket.h>
    00026
    00027 #include <netinet/in.h>
    00028 #include <arpa/inet.h>
    00029
    00030 #include <netdb.h>
    00031 #include <time.h>
    00032
    00033 #include <qstring.h>
    00034 #include <qregexp.h>
    00035
    00036 #include "kproxybindings.h"
    00037
    00038 // e.g. Solaris doesn't have that, but uses -1 for inet_addr() error-handling
    00039 #ifndef INADDR_NONE
    00040 #define INADDR_NONE -1
    00041 #endif
    00042
    00043 using namespace KJS;
    00044
    00046 QString UString::qstring() const
    00047 {
    00048     return QString((QChar*) data(), size());
    00049 }
    00050
    00051 KProxyFunc::KProxyFunc(int id)
    00052 {
    00053     m_id = id;
    00054 }
    00055
    00056 bool KProxyFunc::implementsCall() const
    00057 {
    00058   return true;
    00059 }
    00060
    00061 Value KProxyFunc::call(ExecState *exec, Object &/*thisObj*/, const List &args)
    00062 {
    00063     Value result = Undefined();
    00064     switch (m_id)
    00065     {
    00066         case IsPlainHostName:
    00067             // isPlainHostName(host)
    00068             // true if host does not contain a domain.
    00069             if (args.size() == 1)
    00070                 result = Boolean(args[0].toString(exec).find(".") == -1);
    00071             break;
    00072         case DNSDomainIs:
    00073             // dnsDomainIs(host, domain)
    00074             // true is host ends in domain
    00075             if (args.size() == 2)
    00076             {
    00077                 QString host = args[0].toString(exec).qstring().lower();
    00078                 QString domain = args[1].toString(exec).qstring().lower();
    00079                 int p = host.find(domain);
    00080                 if (p >= 0)
    00081                     result = Boolean(host.mid(p) == domain);
    00082                 else
    00083                     result = Boolean(false);
    00084             }
    00085             break;
    00086         case LocalHostOrDomainIs:
    00087             // localHostOrDomainIs(host, domain)
    00088             // true if host ends in domain or does not contain any dots.
    00089             if (args.size() == 2)
    00090             {
    00091                 QString host = args[0].toString(exec).qstring().lower();
    00092                 if (host.find(".") == -1)
    00093                     result = Boolean(true);
    00094                 else
    00095                 {
    00096                     QString domain = args[1].toString(exec).qstring().lower();
    00097                     int p = host.find(domain);
    00098                     if (p >= 0)
    00099                         result = Boolean(host.mid(p) == domain);
    00100                     else
    00101                         result = Boolean(false);
    00102                 }
    00103             }
    00104             break;
    00105         case IsResolvable:
    00106             // isResolvable(host)
    00107             // true if host can be resolved to an IP
    00108             if (args.size() == 1)
    00109                 result = Boolean(!dnsResolve(args[0].toString(exec)).isNull());
    00110             break;
    00111         case IsInNet:
    00112             // isInNet(host, pattern, mask)
    00113             // true if host (after DNS lookup) is inside the subnet
    00114             // given by pattern/mask, both dotted quads
    00115             if (args.size() == 3)
    00116             {
    00117                 UString host = dnsResolve(args[0].toString(exec));
    00118                 if (host.isNull())
    00119                     result = Boolean(false);
    00120                 else
    00121                 {
    00122                     unsigned long ip, pattern = 0, mask = 0;
    00123                     // unfortunately inet_aton is not available on Solaris (malte)
    00124                     if ((ip = inet_addr(host.ascii())) == INADDR_NONE
    00125                         || (pattern = inet_addr(args[1].toString(exec).ascii())) == INADDR_NONE
    00126                         || (mask = inet_addr(args[2].toString(exec).ascii())) == INADDR_NONE)
    00127                         result = Boolean(false);
    00128                     else
    00129                         result = Boolean((ip & mask) == (pattern & mask));
    00130                 }
    00131             }
    00132             break;
    00133         case DNSResolve:
    00134             // dnsResolve(host)
    00135             // returns the IP of host
    00136             if (args.size() == 1)
    00137             {
    00138                 UString addr = dnsResolve(args[0].toString(exec));
    00139                 if (addr.isNull())
    00140                     result = Undefined();
    00141                 else
    00142                     result = String(addr);
    00143             }
    00144             break;
    00145         case MyIPAddress:
    00146             // myIpAddress()
    00147             // returns the IP of the client
    00148             if (args.size() == 0)
    00149             {
    00150                 char hostname[256];
    00151                 hostname[0] = '\0';
    00152                 if(!gethostname(hostname, sizeof(hostname)))
    00153                     hostname[sizeof(hostname)-1] = '\0';
    00154                 UString addr = dnsResolve(hostname);
    00155                 if (addr.isNull())
    00156                     result = Undefined();
    00157                 else
    00158                     result = String(addr);
    00159             }
    00160             break;
    00161         case DNSDomainLevels:
    00162             // dnsDomainLevels(host)
    00163             // counts the dots in host
    00164             if (args.size() == 1)
    00165             {
    00166                 UString host = args[0].toString(exec);
    00167                 int p = -1, count = 0;
    00168                 while ((p = host.find(".", p+1)) != -1)
    00169                     count++;
    00170                 result = Number(count);
    00171             }
    00172             break;
    00173         case ShExpMatch:
    00174             // shExpMatch(string, glob)
    00175             // true if string matches the shell-glob-like pattern glob
    00176             if (args.size() == 2)
    00177             {
    00178                 QRegExp rex(args[1].toString(exec).qstring(), true, true);
    00179                 result = Boolean(rex.search(args[0].toString(exec).qstring(), 0) != -1);
    00180             }
    00181             break;
    00182         case WeekdayRange:
    00183             // weekdayRange(day [, "GMT"])
    00184             // weekdayRange(day1, day2 [, "GMT"])
    00185             // true if the current day is day or between day1 and day2
    00186             // if the additional parameter "GMT" is given, compares
    00187             // to the current time in GMT, otherwise to localtime
    00188             if (args.size() >= 1 && args.size() <= 3)
    00189             {
    00190                 static const char *weekdays[] = {"son", "mon", "tue", "wed", "thu", "fri", "sat", 0};
    00191                 int day1 = findString(args[0].toString(exec).qstring().lower(), weekdays);
    00192                 if (day1 == -1)
    00193                     break;
    00194                 int day2 = args.size() > 1 ?
    00195                     findString(args[1].toString(exec).qstring().lower(), weekdays) : -1;
    00196                 if (day2 == -1)
    00197                     day2 = day1;
    00198                 const struct tm *now = getTime(exec,args);
    00199                 result = Boolean(checkRange(now->tm_wday, day1, day2));
    00200             }
    00201             break;
    00202         case DateRange:
    00203             // dateRange(day [, "GMT"])
    00204             // dateRange(day1, day2 [, "GMT"])
    00205             // dateRange(month [, "GMT"])
    00206             // dateRange(month1, month2 [, "GMT"])
    00207             // dateRange(year [, "GMT"])
    00208             // dateRange(year1, year2 [, "GMT"])
    00209             // dateRange(day1, month1, day2, month2 [, "GMT"])
    00210             // dateRange(month1, year1, month2, year2 [, "GMT"])
    00211             // dateRange(day1, month1, year1, day2, month2, year2 [, "GMT"])
    00212             // true if the current is day or between day1 and day2
    00213             // in the month month or between month1 and month2
    00214             // in the year year or between year1 and year2
    00215             // days are given as numbers from 1 to 31
    00216             // months are given as three-letter-names
    00217             // years are given with four digits
    00218             if (args.size() >= 1 && args.size() <= 7)
    00219             {
    00220                 static const char *months[] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "nov", "dec", 0};
    00221                 int values[6] = {-1, -1, -1, -1, -1, -1};
    00222                 for (int i = 0; i < 6 && i < args.size(); ++i)
    00223                 {
    00224                     if (args[i].isA(NumberType))
    00225                         values[i] = (args[i].toInteger(exec));
    00226                     else
    00227                         values[i] = findString(args[i].toString(exec).qstring().lower(), months);
    00228                 }
    00229                 int min, max, current;
    00230                 const struct tm *now = getTime(exec,args);
    00231                 if (values[5] != -1) // day1, month1, year1, day2, month2, year2
    00232                 {
    00233                     min = values[2] * 372 + values[1] * 31 + values[0];
    00234                     max = values[5] * 372 + values[4] * 31 + values[3];
    00235                     current = now->tm_year * 372 + now->tm_mon * 31 + now->tm_mday;
    00236                 }
    00237                 else if (values[3] != -1 && args[0].isA(NumberType)) // day1, month1, day2, month2
    00238                 {
    00239                     min = values[1] * 31 + values[0];
    00240                     max = values[3] * 31 + values[2];
    00241                     current = now->tm_mon * 31 + now->tm_mday;
    00242                 }
    00243                 else if (values[3] != -1) // month1, year1, month2, year2
    00244                 {
    00245                     min = values[1] * 12 + values[0];
    00246                     max = values[3] * 12 + values[2];
    00247                     current = now->tm_year * 12 + now->tm_mon;
    00248                 }
    00249                 else
    00250                 {
    00251                     min = values[0];
    00252                     max = values[1] != -1 ? values[1] : values[0];
    00253                     if (!args[0].isA(NumberType)) // month[1, month2]
    00254                         current = now->tm_mon;
    00255                     else if (values[0] <= 31) // day[1, day2]
    00256                         current = now->tm_mday;
    00257                     else // year[1, year2]
    00258                         current = now->tm_year;
    00259                 }
    00260                 result = Boolean(checkRange(current, min, max));
    00261             }
    00262             break;
    00263         case TimeRange:
    00264             // timeRange(hour [, "GMT"])
    00265             // timeRange(hour1, hour2 [, "GMT"])
    00266             // timeRange(hour1, min1, hour2, min2 [, "GMT"])
    00267             // timeRange(hour1, min1, sec1, hour2, min2, sec2 [, "GMT"])
    00268             // true if the current time is in the given range
    00269             if (args.size() >= 1 && args.size() <= 7)
    00270             {
    00271                 int values[6] = {-1, -1, -1, -1, -1, -1};
    00272                 for (int i = 0; i < args.size(); ++i)
    00273                 {
    00274                     if (!args[i].isA(NumberType))
    00275                         break;
    00276                     values[i] = (args[i].toInteger(exec));
    00277                 }
    00278                 if (values[0] == -1)
    00279                     break;
    00280                 int min, max;
    00281                 if (values[5] != -1) // hour1, min1, sec1, hour2, min2, sec2
    00282                 {
    00283                     min = values[0] * 3600 + values[1] * 60 + values[2];
    00284                     max = values[3] * 3600 + values[4] * 60 + values[5];
    00285                 }
    00286                 else if (values[3] != -1) // hour1, min1, hour2, min2
    00287                 {
    00288                     min = values[0] * 3600 + values[1] * 60;
    00289                     max = values[2] * 3600 + values[3] * 60 + 59;
    00290                 }
    00291                 else if (values[1] != -1) // hour1, hour2
    00292                 {
    00293                     min = values[0] * 3600;
    00294                     max = values[1] * 3600 + 3559;
    00295                 }
    00296                 else // hour1
    00297                 {
    00298                     min = values[0] * 3600;
    00299                     max = values[0] * 3600 + 3559;
    00300                 }
    00301                 const struct tm *now = getTime(exec,args);
    00302                 result = Boolean(checkRange(now->tm_hour * 3600 + now->tm_min * 60 + now->tm_sec, min, max));
    00303             }
    00304             break;
    00305     }
    00306     return result;
    00307 }
    00308
    00309 const UString KProxyFunc::dnsResolve(const UString &host) const
    00310 {
    00311     struct hostent *info = gethostbyname(host.ascii());
    00312     if (!info)
    00313         return UString();
    00314     // FIXME is this cast okay (malte)?
    00315     return UString(inet_ntoa(*((struct in_addr *) info->h_addr_list[0])));
    00316 }
    00317
    00318 const struct tm *KProxyFunc::getTime(ExecState *exec, const List &args) const
    00319 {
    00320     time_t now = time(0);
    00321     return args[args.size() -1].toString(exec).qstring().lower() == "gmt" ?
    00322         gmtime(&now) : localtime(&now);
    00323 }
    00324
    00325 int KProxyFunc::findString(const QString &str, const char **list) const
    00326 {
    00327     for (int i = 0; list[i]; ++i)
    00328     {
    00329         if (list[i] == str)
    00330             return i;
    00331     }
    00332     return -1;
    00333 }
    00334
    00335 bool KProxyFunc::checkRange(int value, int min, int max) const
    00336 {
    00337     return (min <= max && value >= min && value <= max)
    00338         || (min > max && (value >= min || value <= max));
    00339 }
    00340
    00341
    00342 void KProxyFunc::init(ExecState *exec, Object &global)
    00343 {
    00344     global.put(exec, "ProxyConfig", global);
    00345     global.put(exec, "isPlainHostName", Object(new KProxyFunc(KProxyFunc::IsPlainHostName)));
    00346     global.put(exec, "dnsDomainIs", Object(new KProxyFunc(KProxyFunc::DNSDomainIs)));
    00347     global.put(exec, "localHostOrDomainIs", Object(new KProxyFunc(KProxyFunc::LocalHostOrDomainIs)));
    00348     global.put(exec, "isResolvable", Object(new KProxyFunc(KProxyFunc::IsResolvable)));
    00349     global.put(exec, "isInNet", Object(new KProxyFunc(KProxyFunc::IsInNet)));
    00350     global.put(exec, "dnsResolve", Object(new KProxyFunc(KProxyFunc::DNSResolve)));
    00351     global.put(exec, "myIpAddress", Object(new KProxyFunc(KProxyFunc::MyIPAddress)));
    00352     global.put(exec, "dnsDomainLevels", Object(new KProxyFunc(KProxyFunc::DNSDomainLevels)));
    00353     global.put(exec, "shExpMatch", Object(new KProxyFunc(KProxyFunc::ShExpMatch)));
    00354     global.put(exec, "weekdayRange", Object(new KProxyFunc(KProxyFunc::WeekdayRange)));
    00355     global.put(exec, "dateRange", Object(new KProxyFunc(KProxyFunc::DateRange)));
    00356     global.put(exec, "timeRange", Object(new KProxyFunc(KProxyFunc::TimeRange)));
    00357 }
    00358
    00359 // vim: ts=4 sw=4 et

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:14:13 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001