00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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 &, const List &args)
00062 {
00063 Value result = Undefined();
00064 switch (m_id)
00065 {
00066 case IsPlainHostName:
00067
00068
00069 if (args.size() == 1)
00070 result = Boolean(args[0].toString(exec).find(".") == -1);
00071 break;
00072 case DNSDomainIs:
00073
00074
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
00088
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
00107
00108 if (args.size() == 1)
00109 result = Boolean(!dnsResolve(args[0].toString(exec)).isNull());
00110 break;
00111 case IsInNet:
00112
00113
00114
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
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
00135
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
00147
00148 if (args.size() == 0)
00149 {
00150 char hostname[256];
00151 gethostname(hostname, 255);
00152 UString addr = dnsResolve(hostname);
00153 if (addr.isNull())
00154 result = Undefined();
00155 else
00156 result = String(addr);
00157 }
00158 break;
00159 case DNSDomainLevels:
00160
00161
00162 if (args.size() == 1)
00163 {
00164 UString host = args[0].toString(exec);
00165 int p = -1, count = 0;
00166 while ((p = host.find(".", p+1)) != -1)
00167 count++;
00168 result = Number(count);
00169 }
00170 break;
00171 case ShExpMatch:
00172
00173
00174 if (args.size() == 2)
00175 {
00176 QRegExp rex(args[1].toString(exec).qstring(), true, true);
00177 result = Boolean(rex.search(args[0].toString(exec).qstring(), 0) != -1);
00178 }
00179 break;
00180 case WeekdayRange:
00181
00182
00183
00184
00185
00186 if (args.size() >= 1 && args.size() <= 3)
00187 {
00188 static const char *weekdays[] = {"son", "mon", "tue", "wed", "thu", "fri", "sat", 0};
00189 int day1 = findString(args[0].toString(exec).qstring().lower(), weekdays);
00190 if (day1 == -1)
00191 break;
00192 int day2 = args.size() > 1 ?
00193 findString(args[1].toString(exec).qstring().lower(), weekdays) : -1;
00194 if (day2 == -1)
00195 day2 = day1;
00196 const struct tm *now = getTime(exec,args);
00197 result = Boolean(checkRange(now->tm_wday, day1, day2));
00198 }
00199 break;
00200 case DateRange:
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 if (args.size() >= 1 && args.size() <= 7)
00217 {
00218 static const char *months[] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "nov", "dec", 0};
00219 int values[6] = {-1, -1, -1, -1, -1, -1};
00220 for (int i = 0; i < 6 && i < args.size(); ++i)
00221 {
00222 if (args[i].isA(NumberType))
00223 values[i] = (args[i].toInteger(exec));
00224 else
00225 values[i] = findString(args[i].toString(exec).qstring().lower(), months);
00226 }
00227 int min, max, current;
00228 const struct tm *now = getTime(exec,args);
00229 if (values[5] != -1)
00230 {
00231 min = values[2] * 372 + values[1] * 31 + values[0];
00232 max = values[5] * 372 + values[4] * 31 + values[3];
00233 current = now->tm_year * 372 + now->tm_mon * 31 + now->tm_mday;
00234 }
00235 else if (values[3] != -1 && args[0].isA(NumberType))
00236 {
00237 min = values[1] * 31 + values[0];
00238 max = values[3] * 31 + values[2];
00239 current = now->tm_mon * 31 + now->tm_mday;
00240 }
00241 else if (values[3] != -1)
00242 {
00243 min = values[1] * 12 + values[0];
00244 max = values[3] * 12 + values[2];
00245 current = now->tm_year * 12 + now->tm_mon;
00246 }
00247 else
00248 {
00249 min = values[0];
00250 max = values[1] != -1 ? values[1] : values[0];
00251 if (!args[0].isA(NumberType))
00252 current = now->tm_mon;
00253 else if (values[0] <= 31)
00254 current = now->tm_mday;
00255 else
00256 current = now->tm_year;
00257 }
00258 result = Boolean(checkRange(current, min, max));
00259 }
00260 break;
00261 case TimeRange:
00262
00263
00264
00265
00266
00267 if (args.size() >= 1 && args.size() <= 7)
00268 {
00269 int values[6] = {-1, -1, -1, -1, -1, -1};
00270 for (int i = 0; i < args.size(); ++i)
00271 {
00272 if (!args[i].isA(NumberType))
00273 break;
00274 values[i] = (args[i].toInteger(exec));
00275 }
00276 if (values[0] == -1)
00277 break;
00278 int min, max;
00279 if (values[5] != -1)
00280 {
00281 min = values[0] * 3600 + values[1] * 60 + values[2];
00282 max = values[3] * 3600 + values[4] * 60 + values[5];
00283 }
00284 else if (values[3] != -1)
00285 {
00286 min = values[0] * 3600 + values[1] * 60;
00287 max = values[2] * 3600 + values[3] * 60 + 59;
00288 }
00289 else if (values[1] != -1)
00290 {
00291 min = values[0] * 3600;
00292 max = values[1] * 3600 + 3559;
00293 }
00294 else
00295 {
00296 min = values[0] * 3600;
00297 max = values[0] * 3600 + 3559;
00298 }
00299 const struct tm *now = getTime(exec,args);
00300 result = Boolean(checkRange(now->tm_hour * 3600 + now->tm_min * 60 + now->tm_sec, min, max));
00301 }
00302 break;
00303 }
00304 return result;
00305 }
00306
00307 const UString KProxyFunc::dnsResolve(const UString &host) const
00308 {
00309 struct hostent *info = gethostbyname(host.ascii());
00310 if (!info)
00311 return UString();
00312
00313 return UString(inet_ntoa(*((struct in_addr *) info->h_addr_list[0])));
00314 }
00315
00316 const struct tm *KProxyFunc::getTime(ExecState *exec, const List &args) const
00317 {
00318 time_t now = time(0);
00319 return args[args.size() -1].toString(exec).qstring().lower() == "gmt" ?
00320 gmtime(&now) : localtime(&now);
00321 }
00322
00323 int KProxyFunc::findString(const QString &str, const char **list) const
00324 {
00325 for (int i = 0; list[i]; ++i)
00326 {
00327 if (list[i] == str)
00328 return i;
00329 }
00330 return -1;
00331 }
00332
00333 bool KProxyFunc::checkRange(int value, int min, int max) const
00334 {
00335 return (min <= max && value >= min && value <= max)
00336 || (min > max && (value >= min || value <= max));
00337 }
00338
00339
00340 void KProxyFunc::init(ExecState *exec, Object &global)
00341 {
00342 global.put(exec, "ProxyConfig", global);
00343 global.put(exec, "isPlainHostName", Object(new KProxyFunc(KProxyFunc::IsPlainHostName)));
00344 global.put(exec, "dnsDomainIs", Object(new KProxyFunc(KProxyFunc::DNSDomainIs)));
00345 global.put(exec, "localHostOrDomainIs", Object(new KProxyFunc(KProxyFunc::LocalHostOrDomainIs)));
00346 global.put(exec, "isResolvable", Object(new KProxyFunc(KProxyFunc::IsResolvable)));
00347 global.put(exec, "isInNet", Object(new KProxyFunc(KProxyFunc::IsInNet)));
00348 global.put(exec, "dnsResolve", Object(new KProxyFunc(KProxyFunc::DNSResolve)));
00349 global.put(exec, "myIpAddress", Object(new KProxyFunc(KProxyFunc::MyIPAddress)));
00350 global.put(exec, "dnsDomainLevels", Object(new KProxyFunc(KProxyFunc::DNSDomainLevels)));
00351 global.put(exec, "shExpMatch", Object(new KProxyFunc(KProxyFunc::ShExpMatch)));
00352 global.put(exec, "weekdayRange", Object(new KProxyFunc(KProxyFunc::WeekdayRange)));
00353 global.put(exec, "dateRange", Object(new KProxyFunc(KProxyFunc::DateRange)));
00354 global.put(exec, "timeRange", Object(new KProxyFunc(KProxyFunc::TimeRange)));
00355 }
00356
00357