summaryrefslogtreecommitdiffstats
path: root/kio/misc/kpac
diff options
context:
space:
mode:
Diffstat (limited to 'kio/misc/kpac')
-rw-r--r--kio/misc/kpac/Makefile.am29
-rw-r--r--kio/misc/kpac/README9
-rw-r--r--kio/misc/kpac/README.wpad73
-rw-r--r--kio/misc/kpac/TODO1
-rw-r--r--kio/misc/kpac/configure.in.in26
-rw-r--r--kio/misc/kpac/dhcp.h78
-rw-r--r--kio/misc/kpac/discovery.cpp147
-rw-r--r--kio/misc/kpac/discovery.h55
-rw-r--r--kio/misc/kpac/downloader.cpp89
-rw-r--r--kio/misc/kpac/downloader.h64
-rw-r--r--kio/misc/kpac/eventsrc530
-rw-r--r--kio/misc/kpac/kpac_dhcp_helper.c229
-rw-r--r--kio/misc/kpac/kpactest.pac169
-rw-r--r--kio/misc/kpac/proxyscout.cpp196
-rw-r--r--kio/misc/kpac/proxyscout.desktop131
-rw-r--r--kio/misc/kpac/proxyscout.h82
-rw-r--r--kio/misc/kpac/script.cpp465
-rw-r--r--kio/misc/kpac/script.h56
18 files changed, 2429 insertions, 0 deletions
diff --git a/kio/misc/kpac/Makefile.am b/kio/misc/kpac/Makefile.am
new file mode 100644
index 000000000..173071318
--- /dev/null
+++ b/kio/misc/kpac/Makefile.am
@@ -0,0 +1,29 @@
+
+kde_module_LTLIBRARIES = kded_proxyscout.la
+bin_PROGRAMS = kpac_dhcp_helper
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/libltdl -I$(top_srcdir)/kded -I$(top_builddir)/kjs \
+ -I$(top_srcdir)/kdecore/network $(all_includes)
+METASOURCES = AUTO
+KDE_CXXFLAGS = $(USE_EXCEPTIONS)
+
+kded_proxyscout_la_SOURCES = proxyscout.skel proxyscout.cpp script.cpp \
+ downloader.cpp discovery.cpp
+kded_proxyscout_la_LDFLAGS = $(all_libraries) -module -avoid-version
+kded_proxyscout_la_LIBADD = $(LIB_KIO) $(top_builddir)/kjs/libkjs.la $(LIB_KDED)
+
+kpac_dhcp_helper_SOURCES = kpac_dhcp_helper.c
+kpac_dhcp_helper_CFLAGS = $(KDE_USE_FPIE)
+kpac_dhcp_helper_LDFLAGS = $(KDE_USE_PIE)
+kpac_dhcp_helper_LDADD = $(LIBSOCKET)
+
+noinst_HEADERS = proxyscout.h script.h downloader.h discovery.h
+
+servicesdir = $(kde_servicesdir)/kded
+services_DATA = proxyscout.desktop
+
+proxyscoutdatadir = $(kde_datadir)/proxyscout
+proxyscoutdata_DATA = eventsrc
+
+install-exec-local:
+ @(chown root $(DESTDIR)$(bindir)/kpac_dhcp_helper && chmod 4755 $(DESTDIR)$(bindir)/kpac_dhcp_helper) || echo "Please make kpac_dhcp_helper setuid root"
diff --git a/kio/misc/kpac/README b/kio/misc/kpac/README
new file mode 100644
index 000000000..d211ae07b
--- /dev/null
+++ b/kio/misc/kpac/README
@@ -0,0 +1,9 @@
+Proxy Auto Configuration is a means to use a JavaScript function to
+determine the proxy to use based on the requested URL.
+It is described in detail here:
+http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/proxy-live.html
+
+Also implemented by this library are parts of the now expired Internet Draft
+at http://www.wrec.org/Drafts/draft-cooper-webi-wpad-00.txt about WPAD
+(Web Proxy Automatic Discovery). The discovery implemented discovery methods
+are DHCP and DNS "Well known Aliases".
diff --git a/kio/misc/kpac/README.wpad b/kio/misc/kpac/README.wpad
new file mode 100644
index 000000000..f63d25764
--- /dev/null
+++ b/kio/misc/kpac/README.wpad
@@ -0,0 +1,73 @@
+Web Proxy Auto Discovery (WPAD)
+===============================
+
+This README is intended for network administrators who want to enable the
+users on their network to fully automatically find the proxy settings.
+
+Automatic proxy discovery works in two steps:
+1) Find a configuration script
+2) Determine a proxy to use by running that script
+
+The configuration script is a "PAC" (JavaScript) file just as in plain Proxy
+Auto Configuration as described here:
+http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/proxy-live.html
+
+The WPAD part of the process (#1 above) described here is about how to find
+this script without having the users enter its URL into the proxy settings.
+(All they have to do in a WPAD-enabled network is to select "Automatically
+detected script file" in KDE's proxy setup.
+
+There are two alternative ways to discover the PAC script's URL implemented
+in KDE:
+
+1. DHCP based autodiscovery
+
+ If you are running a DHCP server on your network anyway, you might
+ want to use this approach; all you have to do is to add the WPAD
+ option (numeric 252 or hex fc) as a string containing the URL to the
+ PAC script.
+
+ To do so with older versions of ISC dhcpd, add this to
+ /etc/dhcpd.conf, either globally or just for the subnets you want to
+ enable WPAD for:
+
+ option option-252 "http://example.com/path/to/proxyconfig.pac";
+
+ Or, for newer ISC dhcpd versions, add this globally:
+
+ option wpad code 252 = text;
+
+ and this either globally or for the WPAD subnets:
+
+ option wpad "http://example.com/path/to/proxyconfig.pac";
+
+ For other DHCP servers, please consult the reference manual on how
+ to add an option by number if WPAD support is not built-in.
+
+2. DNS based autodiscovery
+
+ If you don't run a DHCP server or prefer DNS based discovery, you
+ need to configure one of your hosts to have the name
+ wpad.example.com and make sure the PAC script is available as
+ http://wpad.example.com/wpad.dat If your network consists of several
+ subdomains, like a.example.com and b.example.com you can either
+ provide both http://a.example.com/wpad.dat and
+ http://b.example.com/wpad.dat or just http://example.com/wpad.dat
+ When a client searches for that script, it will search for a host
+ named "wpad" in its own domain, then in the next higher level domain
+ until success or if only the TLD is left (i.e. wpad.com will never
+ be tried)
+
+Note that DHCP is the preferred approach since it's more flexible than DNS
+as it doesn't require a well known host name nor a fixed location
+(/wpad.dat) for the PAC script. It is also the first method tried before
+resorting to DNS, so if you use DNS there will be a noticeable delay of 5
+seconds while waiting for a DHCP reply.
+
+However, DHCP requires a helper program, kpac_dhcp_helper to be installed
+suid root. If you consider this a security problem, just delete that program
+or remove its suid permissions and use DNS instead. If the helper cannot
+execute as root, the 5 seconds delay will also go away.
+
+If you have further questions or comments, please contact me: Malte
+Starostik <malte@kde.org>
diff --git a/kio/misc/kpac/TODO b/kio/misc/kpac/TODO
new file mode 100644
index 000000000..ce5cd6a11
--- /dev/null
+++ b/kio/misc/kpac/TODO
@@ -0,0 +1 @@
+* Make use of badProxy() in KProtocolManager to enable fallbacks
diff --git a/kio/misc/kpac/configure.in.in b/kio/misc/kpac/configure.in.in
new file mode 100644
index 000000000..a65b9a1c8
--- /dev/null
+++ b/kio/misc/kpac/configure.in.in
@@ -0,0 +1,26 @@
+dnl some setgroups() implementations seem to have short* instead of gid_t*
+dnl and use some flags in the fiels that follows the gids
+AC_MSG_CHECKING([for setgroups with short argument])
+AC_CACHE_VAL([kde_cv_shortsetgroups],[
+ AC_TRY_RUN([
+ int main()
+ {
+ short x[4];
+ x[0] = x[1] = 1;
+ if (getgroups(1, x) == 0) if (setgroups(1, x) == -1) exit(1);
+
+ if (getgroups(1, x) == -1) exit(1);
+ if (x[1] != 1) exit(1);
+ x[1] = 2;
+ if (getgroups(1, x) == -1) exit(1);
+ if (x[1] != 2) exit(1);
+ exit(0);
+ }
+ ],[kde_cv_shortsetgroups="yes"],[kde_cv_shortsetgroups="no"])
+])
+AC_MSG_RESULT($kde_cv_shortsetgroups)
+if test "$kde_cv_shortsetgroups" = "yes"; then
+ AC_DEFINE(HAVE_SHORTSETGROUPS,1,[if setgroups() takes short *as second arg])
+fi
+
+AC_CHECK_HEADERS(arpa/nameser8_compat.h sys/param.h)
diff --git a/kio/misc/kpac/dhcp.h b/kio/misc/kpac/dhcp.h
new file mode 100644
index 000000000..41643ae3a
--- /dev/null
+++ b/kio/misc/kpac/dhcp.h
@@ -0,0 +1,78 @@
+/* This file is part of the KDE Libraries
+ Copyright (c) 2001 Malte Starostik <malte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+
+/* See RFC 2131 for details */
+
+#ifndef __dhcp_h__
+#define __dhcp_h__
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#define DHCP_OPT_LEN 312
+
+struct dhcp_msg
+{
+#define DHCP_BOOTREQUEST 1
+#define DHCP_BOOTREPLY 2
+ uint8_t op; /* operation */
+ uint8_t htype; /* hwaddr type */
+ uint8_t hlen; /* hwaddr len */
+ uint8_t hops;
+ uint32_t xid; /* transaction id */
+ uint16_t secs; /* seconds since protocol start */
+#define DHCP_BROADCAST 1
+ uint16_t flags;
+ uint32_t ciaddr; /* client IP */
+ uint32_t yiaddr; /* "your" IP */
+ uint32_t siaddr; /* server IP */
+ uint32_t giaddr; /* gateway IP */
+ uint8_t chaddr[16]; /* client hwaddr */
+ uint8_t sname[64]; /* server name */
+ uint8_t file[128]; /* bootstrap file */
+ uint8_t options[DHCP_OPT_LEN];
+};
+
+/* first four bytes in options */
+#define DHCP_MAGIC1 0x63
+#define DHCP_MAGIC2 0x82
+#define DHCP_MAGIC3 0x53
+#define DHCP_MAGIC4 0x63
+
+/* DHCP message types */
+#define DHCP_DISCOVER 1
+#define DHCP_OFFER 2
+#define DHCP_REQUEST 3
+#define DHCP_DECLINE 4
+#define DHCP_ACK 5
+#define DHCP_NAK 6
+#define DHCP_RELEASE 7
+#define DHCP_INFORM 8
+
+/* option types */
+#define DHCP_OPT_MSGTYPE 0x35
+#define DHCP_OPT_PARAMREQ 0x37
+#define DHCP_OPT_WPAD 0xfc
+#define DHCP_OPT_END 0xff
+
+#endif
+
+/* vim: ts=4 sw=4 noet
+ */
diff --git a/kio/misc/kpac/discovery.cpp b/kio/misc/kpac/discovery.cpp
new file mode 100644
index 000000000..06709241b
--- /dev/null
+++ b/kio/misc/kpac/discovery.cpp
@@ -0,0 +1,147 @@
+/*
+ Copyright (c) 2003 Malte Starostik <malte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+
+#include "config.h"
+
+#include <netdb.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <arpa/nameser.h>
+#ifdef HAVE_ARPA_NAMESER8_COMPAT_H
+#include <arpa/nameser8_compat.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+// Basically, the BSDs need this before resolv.h
+#include <sys/param.h>
+#endif
+#include <resolv.h>
+#include <sys/utsname.h>
+
+#include <qtimer.h>
+
+#include <klocale.h>
+#include <kprocio.h>
+#include <kurl.h>
+
+#include "discovery.moc"
+
+namespace KPAC
+{
+ Discovery::Discovery( QObject* parent )
+ : Downloader( parent ),
+ m_helper( new KProcIO )
+ {
+ connect( m_helper, SIGNAL( readReady( KProcIO* ) ), SLOT( helperOutput() ) );
+ connect( m_helper, SIGNAL( processExited( KProcess* ) ), SLOT( failed() ) );
+ *m_helper << "kpac_dhcp_helper";
+
+ if ( !m_helper->start() )
+ QTimer::singleShot( 0, this, SLOT( failed() ) );
+ }
+
+ bool Discovery::initHostName()
+ {
+ struct utsname uts;
+
+ if (uname (&uts) > -1)
+ {
+ struct hostent *hent = gethostbyname (uts.nodename);
+ if (hent != 0)
+ m_hostname = QString::fromLocal8Bit( hent->h_name );
+ }
+
+ // If no hostname, try gethostname as a last resort.
+ if (m_hostname.isEmpty())
+ {
+ char buf [256];
+ if (gethostname (buf, sizeof(buf)) == 0)
+ {
+ buf[255] = '\0';
+ m_hostname = QString::fromLocal8Bit( buf );
+ }
+ }
+ return !m_hostname.isEmpty();
+ }
+
+ bool Discovery::checkDomain() const
+ {
+ // If a domain has a SOA record, don't traverse any higher.
+ // Returns true if no SOA can be found (domain is "ok" to use)
+ // Stick to old resolver interface for portability reasons.
+ union
+ {
+ HEADER header;
+ unsigned char buf[ PACKETSZ ];
+ } response;
+ int len = res_query( m_hostname.local8Bit(), C_IN, T_SOA,
+ response.buf, sizeof( response.buf ) );
+ if ( len <= int( sizeof( response.header ) ) ||
+ ntohs( response.header.ancount ) != 1 ) return true;
+ unsigned char* pos = response.buf + sizeof( response.header );
+ unsigned char* end = response.buf + len;
+ // skip query section
+ pos += dn_skipname( pos, end ) + QFIXEDSZ;
+ if ( pos >= end ) return true;
+ // skip answer domain
+ pos += dn_skipname( pos, end );
+ short type;
+ GETSHORT( type, pos );
+ return type != T_SOA;
+ }
+
+ void Discovery::failed()
+ {
+ setError( i18n( "Could not find a usable proxy configuration script" ) );
+
+ // If this is the first DNS query, initialize our host name or abort
+ // on failure. Otherwise abort if the current domain (which was already
+ // queried for a host called "wpad" contains a SOA record)
+ bool firstQuery = m_hostname.isEmpty();
+ if ( ( firstQuery && !initHostName() ) ||
+ ( !firstQuery && !checkDomain() ) )
+ {
+ emit result( false );
+ return;
+ }
+
+ int dot = m_hostname.find( '.' );
+ if ( dot >= 0 )
+ {
+ m_hostname.remove( 0, dot + 1 ); // remove one domain level
+ download( KURL( "http://wpad." + m_hostname + "./wpad.dat" ) );
+ }
+ else emit result( false );
+ }
+
+ void Discovery::helperOutput()
+ {
+ m_helper->disconnect( this );
+ QString line;
+ m_helper->readln( line );
+ download( KURL( line.stripWhiteSpace() ) );
+ }
+}
+
+// vim: ts=4 sw=4 et
diff --git a/kio/misc/kpac/discovery.h b/kio/misc/kpac/discovery.h
new file mode 100644
index 000000000..b9c657924
--- /dev/null
+++ b/kio/misc/kpac/discovery.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (c) 2003 Malte Starostik <malte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+
+#ifndef KPAC_DISCOVERY_H
+#define KPAC_DISCOVERY_H
+
+#include <qobject.h>
+
+#include "downloader.h"
+
+class KProcIO;
+
+namespace KPAC
+{
+ class Discovery : public Downloader
+ {
+ Q_OBJECT
+ public:
+ Discovery( QObject* );
+
+ protected slots:
+ virtual void failed();
+
+ private slots:
+ void helperOutput();
+
+ private:
+ bool initHostName();
+ bool checkDomain() const;
+
+ KProcIO* m_helper;
+ QString m_hostname;
+ };
+}
+
+#endif // KPAC_DISCOVERY_H
+
+// vim: ts=4 sw=4 et
diff --git a/kio/misc/kpac/downloader.cpp b/kio/misc/kpac/downloader.cpp
new file mode 100644
index 000000000..6d4e62409
--- /dev/null
+++ b/kio/misc/kpac/downloader.cpp
@@ -0,0 +1,89 @@
+/*
+ Copyright (c) 2003 Malte Starostik <malte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+
+#include <cstdlib>
+#include <cstring>
+
+#include <qtextcodec.h>
+
+#include <kcharsets.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kio/job.h>
+
+#include "downloader.moc"
+
+namespace KPAC
+{
+ Downloader::Downloader( QObject* parent )
+ : QObject( parent )
+ {
+ }
+
+ void Downloader::download( const KURL& url )
+ {
+ m_data.resize( 0 );
+ m_script = QString::null;
+ m_scriptURL = url;
+
+ KIO::TransferJob* job = KIO::get( url, false, false );
+ connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
+ SLOT( data( KIO::Job*, const QByteArray& ) ) );
+ connect( job, SIGNAL( result( KIO::Job* ) ), SLOT( result( KIO::Job* ) ) );
+ }
+
+ void Downloader::failed()
+ {
+ emit result( false );
+ }
+
+ void Downloader::setError( const QString& error )
+ {
+ m_error = error;
+ }
+
+ void Downloader::data( KIO::Job*, const QByteArray& data )
+ {
+ unsigned offset = m_data.size();
+ m_data.resize( offset + data.size() );
+ std::memcpy( m_data.data() + offset, data.data(), data.size() );
+ }
+
+ void Downloader::result( KIO::Job* job )
+ {
+ if ( !job->error() && !static_cast< KIO::TransferJob* >( job )->isErrorPage() )
+ {
+ bool dummy;
+ m_script = KGlobal::charsets()->codecForName(
+ job->queryMetaData( "charset" ), dummy )->toUnicode( m_data );
+ emit result( true );
+ }
+ else
+ {
+ if ( job->error() )
+ setError( i18n( "Could not download the proxy configuration script:\n%1" )
+ .arg( job->errorString() ) );
+ else setError( i18n( "Could not download the proxy configuration script" ) ); // error page
+ failed();
+ }
+ }
+}
+
+// vim: ts=4 sw=4 et
diff --git a/kio/misc/kpac/downloader.h b/kio/misc/kpac/downloader.h
new file mode 100644
index 000000000..7869d7102
--- /dev/null
+++ b/kio/misc/kpac/downloader.h
@@ -0,0 +1,64 @@
+/*
+ Copyright (c) 2003 Malte Starostik <malte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+
+#ifndef KPAC_DOWNLOADER_H
+#define KPAC_DOWNLOADER_H
+
+#include <qobject.h>
+
+#include <kurl.h>
+
+namespace KIO { class Job; }
+
+namespace KPAC
+{
+ class Downloader : public QObject
+ {
+ Q_OBJECT
+ public:
+ Downloader( QObject* );
+
+ void download( const KURL& );
+ const KURL& scriptURL() { return m_scriptURL; }
+ const QString& script() { return m_script; }
+ const QString& error() { return m_error; }
+
+ signals:
+ void result( bool );
+
+ protected:
+ virtual void failed();
+ void setError( const QString& );
+
+ private slots:
+ void data( KIO::Job*, const QByteArray& );
+ void result( KIO::Job* );
+
+ private:
+ QByteArray m_data;
+ KURL m_scriptURL;
+ QString m_script;
+ QString m_error;
+ };
+}
+
+#endif // KPAC_DOWNLOADER_H
+
+// vim: ts=4 sw=4 et
diff --git a/kio/misc/kpac/eventsrc b/kio/misc/kpac/eventsrc
new file mode 100644
index 000000000..c44443a03
--- /dev/null
+++ b/kio/misc/kpac/eventsrc
@@ -0,0 +1,530 @@
+[!Global!]
+IconName=proxy
+Comment=Automatic Proxy Configuration
+Comment[af]=Outomatiese Proksie Opstelling
+Comment[ar]=تهيئة آلية للخادم الوكيل
+Comment[az]=Avtomatik Vəkil Quraşdırılması
+Comment[bg]=Автоматично настройване на прокси сървъра
+Comment[bn]=স্বয়ংক্রিয় প্রক্সি কনফিগারেশন
+Comment[br]=Kefluniadur emgefreekh ar proksi
+Comment[bs]=Automatsko podešavanje proxy-ja
+Comment[ca]=Configuració automàtica del servidor d'intercanvi
+Comment[cs]=Automatické nastavení proxy
+Comment[csb]=Aùtokònfigùracëjô pòstrzédnika
+Comment[cy]=Ffurweddiad Awtomatig o'r Dirprwy
+Comment[da]=Automatisk proxy-indstilling
+Comment[de]=Autom. Proxy-Einrichtung
+Comment[el]=Αυτόματη ρύθμιση διαμεσολαβητή
+Comment[eo]=Aŭtomata Prokuragordo
+Comment[es]=Configuración automática del Proxy
+Comment[et]=Automaatne proxy konfigureerimine
+Comment[eu]=Proxy-aren konfigurazio automatikoa
+Comment[fa]=پیکربندی خودکار پیشکار
+Comment[fi]=Automaattiset proxy-asetukset
+Comment[fr]=Configuration automatique du serveur mandataire
+Comment[fy]=Automatyske proxy ynstelling
+Comment[ga]=Uathchumraíocht an tSeachfhreastalaí
+Comment[gl]=Configuración Automática do Proxy
+Comment[he]=הגדרות פרוקסי אוטומטיות
+Comment[hi]=स्वचलित प्रॉक्सी कॉन्फ़िगरेटर
+Comment[hr]=Automatsko podešavanje proxyja
+Comment[hu]=Automatikus proxybeállítás
+Comment[id]=Konfigurasi Proxi Otomatis
+Comment[is]=Sjálfvirkar stillingar milliþjóns
+Comment[it]=Configurazione automatica proxy
+Comment[ja]=自動プロキシ設定
+Comment[ka]=პროქსის თვითგამართვა
+Comment[kk]=Автоматты түрде проксиді баптау
+Comment[km]=ការ​កំណត់​រចនាសម្ព័ន្ធ​ប្រូកស៊ី​ដោយ​ស្វ័យ​ប្រវត្តិ
+Comment[ko]=스스로 프록시 설정
+Comment[lb]=Automatesch Proxy-Configuratioun
+Comment[lt]=Automatinis proxy derinimas
+Comment[mk]=Автоматска конфигурација на прокси
+Comment[mn]=Автомат итгэмжилэгчийн тохиргоо
+Comment[ms]=Penyelarasan Proksi Automatik
+Comment[nb]=Automatisk mellomtjenerinnstilling
+Comment[nds]=Proxy automaatsch instellen
+Comment[ne]=स्वचालित प्रोक्सी कन्फिगरेसन
+Comment[nl]=Automatische proxyconfiguratie
+Comment[nn]=Automatisk mellomtenaroppsett
+Comment[pa]=ਸਵੈ-ਚਾਲਤ ਪਰਾਕਸੀ ਸੰਰਚਨਾ
+Comment[pl]=Autokonfiguracja pośrednika
+Comment[pt]=Configuração Automática do 'Proxy'
+Comment[pt_BR]=Configuração Automática do Proxy
+Comment[ro]=Configurare automată "proxy"
+Comment[ru]=Автонастройка прокси
+Comment[rw]=Iboneza rya Nyabubasha Ryikoresha
+Comment[se]=Automáhtalaš gaskabálváheiveheapmi
+Comment[sk]=Automatická konfigurácia proxy
+Comment[sl]=Samodejne nastavitve posrednika
+Comment[sq]=Kofigurimi Automatik i Proxy-t
+Comment[sr]=Аутоматско подешавање проксија
+Comment[sr@Latn]=Automatsko podešavanje proksija
+Comment[sv]=Automatisk proxyinställning
+Comment[ta]=தானியக்க பதிலாள் வடிவமைப்பு
+Comment[te]=స్వయంచాలిత ప్రాక్సీ రూపకరణం
+Comment[tg]=Шакли Автоматӣ Вакил Кардашуда
+Comment[th]=ปรับแต่งพร็อกซีอัตโนมัติ
+Comment[tr]=Otomatik Vekil Sunucu Yapılandırması
+Comment[tt]=Proxy'nı Aqıllı Caylaw
+Comment[uk]=Автоматичне визначення проксі сервера
+Comment[uz]=Proksini avtomatik ravishda moslash
+Comment[uz@cyrillic]=Проксини автоматик равишда мослаш
+Comment[vi]=Cấu hình ủy nhiệm tự động.
+Comment[wa]=Apontiaedje otomatike do procsi
+Comment[zh_CN]=自动代理配置
+Comment[zh_HK]=自動代理組態
+Comment[zh_TW]=自動代理組態
+
+[script-error]
+Name=Invalid proxy script
+Name[af]=Ongeldige proksie skrip
+Name[ar]=نص برمجي غير صالح
+Name[az]=Hökmsüz vəkil skripti
+Name[bg]=Невалиден скрипт за прокси сървъра
+Name[bn]=অবৈধ প্রক্সি স্ক্রিপ্ট
+Name[br]=N'eo ket mat an urzhiaoug proksi
+Name[bs]=Neispravna proxy skripta
+Name[ca]=Script del servidor intermedi no vàlid
+Name[cs]=Neplatný proxy skript
+Name[csb]=Falszëwi skript pòstrzédnika
+Name[cy]=Sgript dirprwy annilys
+Name[da]=Ugyldigt proxy-script
+Name[de]=Ungültiges Proxy-Skript
+Name[el]=Μη έγκυρο σενάριο διαμεσολαβητή
+Name[eo]=Nevalida prokurila skripto
+Name[es]=Procedimiento inválido del proxy
+Name[et]=Vigane proxy skript
+Name[eu]=Proxy-aren script baliogabea
+Name[fa]=دست‌نوشتۀ پیشکار نامعتبر
+Name[fi]=Virheellinen proxy-skripti
+Name[fr]=Script de serveur mandataire non valable
+Name[fy]=Unjildich proxy skript
+Name[ga]=Script neamhbhailí seachfhreastalaí
+Name[gl]=Guión de proxy inválido
+Name[he]=תסריט Proxy לא תקין
+Name[hi]=अवैध प्रॉक्सी स्क्रिप्ट
+Name[hr]=Neispravna proxy skripta
+Name[hu]=Érvénytelen proxy-szkript
+Name[id]=Skrip proxi tidak sah
+Name[is]=Ógild milliþjónsskrifta
+Name[it]=Script proxy non valido
+Name[ja]=無効なプロキシスクリプト
+Name[ka]=პროქსის მცდარი სკრიპტი
+Name[kk]=Жарамсыз прокси скрипті
+Name[km]=ស្គ្រីប​ប្រូកស៊ី​មិន​ត្រឹមត្រូវ
+Name[ko]=올바르지 않은 프록시 스크립트
+Name[lb]=Ongültegt Proxy-Skript
+Name[lt]=Blogas proxy scenarijas
+Name[mk]=Невалидна прокси скрипта
+Name[mn]=Хүчингүй итгэмжилэгч скрипт
+Name[ms]=Skrip proksi tidak sah
+Name[nb]=Ugyldig mellomtjenerskript
+Name[nds]=Proxyskript gellt nich
+Name[ne]=अवैद्य प्रोक्सी स्क्रिप्ट
+Name[nl]=Ongeldig proxyscript
+Name[nn]=Ugyldig mellomtenarskript
+Name[pa]=ਗਲਤ ਪਰਾਕਸੀ ਸਕ੍ਰਿਪਟ
+Name[pl]=Niepoprawny skrypt pośrednika
+Name[pt]=Configuração de 'proxy' inválida
+Name[pt_BR]=Script de proxy inválido
+Name[ro]=Script "proxy" eronat
+Name[ru]=Неверный скрипт прокси
+Name[rw]=Inyandikoporogaramu ya Nyabubasha ntiyemewe
+Name[se]=Gustohis gaskabálváskripta
+Name[sk]=Zlý proxy skript
+Name[sl]=Neveljaven posredniški skript
+Name[sq]=Proxy Skripta është e gabuar
+Name[sr]=Неисправна прокси скрипта
+Name[sr@Latn]=Neispravna proksi skripta
+Name[sv]=Ogiltigt proxyskript
+Name[ta]=செல்லாத பதிலாள் எழுத்தாக்கம்
+Name[te]=చెల్లని ప్రాక్సీ స్క్రిప్ట్
+Name[tg]=Дастнависи вакил кардашуда ношоям
+Name[th]=สคริปต์ของพร็อกซี ไม่ถูกต้อง
+Name[tr]=Geçersiz vekil sunucu betiği
+Name[tt]=Proxy ämerlege bozıq
+Name[uk]=Неправильний скрипт для проксі
+Name[uz]=Proksi skripti haqiqiy emas
+Name[uz@cyrillic]=Прокси скрипти ҳақиқий эмас
+Name[vi]=Tập lệnh ủy nhiệm không hợp lệ
+Name[zh_CN]=无效的代理脚本
+Name[zh_HK]=不合法的代理伺服器 script
+Name[zh_TW]=不合法 proxy 命令稿檔案
+Comment=The downloaded proxy configuration script is invalid
+Comment[af]=Die proksie skipt wat afgelaai was is ongeldig
+Comment[ar]=النص البرمجي الذي تم تنزيله غير صالح
+Comment[az]=Endirilən vəkil quraşdırma skripti kökmsüzdür
+Comment[bg]=Изтегленият скрипт за настройване на прокси сървъра е невалиден
+Comment[bn]=ডাউনলোড করা প্রক্সি কনফিগারেশন স্ক্রিপ্টটি অবৈধ
+Comment[br]=N'eo ket mat urzhiaoug kefluniadur ar proksi
+Comment[bs]=Downloadovana skripta za podešavanje proxy-ja je neispravna
+Comment[ca]=L'script de configuració del servidor intermedi descarregat no és vàlid
+Comment[cs]=Stažený konfigurační skript pro proxy je neplatný
+Comment[csb]=Zladowóny skript kònfigùracëji pòstrzédnika je falszëwi
+Comment[cy]=Mae'r sgript ffurfweddu'r dirprwy a chafodd ei lawrlwytho yn annilys
+Comment[da]=Det hentede proxy-indstillingsscript er ugyldigt
+Comment[de]=Das heruntergeladene Proxy-Einrichtungsskript ist nicht verwendbar
+Comment[el]=Το σενάριο ρύθμισης διαμεσολαβητή που λήφθηκε δεν είναι έγκυρο
+Comment[eo]=La ŝarĝita prokuragordoskript estas nevalida
+Comment[es]=El procedimiento descargado para la configuración del proxy es inválido
+Comment[et]=Allalaaditud proxy seadistuse skript on vigane
+Comment[eu]=Deskargatutako proxy-aren konfigurazioko script-a baliogabea da
+Comment[fa]=دست‌نوشتۀ پیکربندی پیشکار بارگیری‌شده، نامعتبر است
+Comment[fi]=Ladattu proxy-asetusskripti on virheellinen
+Comment[fr]=Le script téléchargé de configuration du serveur mandataire n'est pas valable
+Comment[fy]=It ynladen proxy ynstellings skript is ûnjildich
+Comment[ga]=Is neamhbhailí í script chumraíocht an tseachfhreastalaí a íosluchtaíodh
+Comment[gl]=O guión de configuración descarregado do proxy non é válido
+Comment[he]=תסריט הגדרת הפרוקסי שהורד לא תקין
+Comment[hi]=ङाउनलोडेड प्रॉक्सी कॉन्फ़िगरेटर स्क्रिप्ट अवैध है।
+Comment[hr]=Preuzeta skripta konfiguriranja proxyja je neispravna
+Comment[hu]=A letöltött proxybeállító szkript érvénytelen
+Comment[id]=Skrip konfigurasi proxy yang diunduh tidak valid
+Comment[is]=Sótt milliþjónsskrifta er ógild
+Comment[it]=Lo script di configurazione proxy scaricato non è valido
+Comment[ja]=ダウンロードされたプロキシ設定スクリプトは無効です。
+Comment[ka]=პროქსის გამართვის ჩამოტვირთული სკრიპტი მცდარია
+Comment[kk]=Жүктеп алынған прокси баптау скрипті жарамсыз
+Comment[km]=ស្គ្រីប​កំណត់​រចនាសម្ព័ន្ធប្រូកស៊ី​ដែល​បាន​ទាញយក មិន​ត្រឹមត្រូវ​ឡើយ
+Comment[ko]=내려받은 프록시 설정 스크립트가 올바르지 않습니다.
+Comment[lb]=D'Proxy-Configuratiounsskript, dat erofgelude gouf, ass ongülteg
+Comment[lt]=Atsisiųstas proxy derinimo scenarijus yra blogas
+Comment[mk]=Симнатата скрипта за конфигурација на прокси е навалидна
+Comment[mn]=Татагдсан итгэмжилэгч тохируулгын скрипт хүчингүй
+Comment[ms]=Skrip penyelarasan proksi yang dimuat turun tidak sah
+Comment[nb]=Det nedlastede skriptet for mellomtjener-innstillinger er ugyldig
+Comment[nds]=Dat Skript för't Instellen vun den Proxy gellt nich
+Comment[ne]=डाउनलोड गरिएको प्रोक्सी कन्फिगरेसन स्क्रिप्ट अवैद्य छ
+Comment[nl]=Het opgehaalde proxyconfiguratiescript is ongeldig
+Comment[nn]=Det nedlasta skriptet for mellomtenaroppsett er ugyldig
+Comment[pa]=ਡਾਊਨਲੋਡ ਪਰਾਕਸੀ ਸੰਰਚਨਾ ਸਕ੍ਰਿਪਟ ਜਾਇਜ਼ ਨਹੀਂ ਹੈ
+Comment[pl]=Pobrany skrypt konfiguracji pośrednika jest nieprawidłowy
+Comment[pt]=A configuração do 'proxy' transferida é inválida
+Comment[pt_BR]=O script de configuração do proxy baixado é inválido
+Comment[ro]=Scriptul de configurare "proxy" este eronat
+Comment[ru]=Загруженный скрипт настройки прокси содержит ошибки
+Comment[rw]=inyandikoporogaramu y'iboneza rya Nyabubasha yakuruwe ntiyemewe
+Comment[se]=Viežžojuvvon gaskabálváskripta lea gustomeahttun
+Comment[sk]=Stiahnutý konfiguračný skript proxy nie je správny
+Comment[sl]=Naložen nastavitveni skript posrednika je neveljaven
+Comment[sq]=Skripta për Konfigurimin e Proxy-t ishte e gabuar
+Comment[sr]=Преузета скрипта за подешавање проксија је неисправна
+Comment[sr@Latn]=Preuzeta skripta za podešavanje proksija je neispravna
+Comment[sv]=Det nerladdade proxyinställningsskriptet är ogiltigt
+Comment[ta]=இறக்கப்பட்ட பதிலாள் வடிவமைப்பு எழுத்தாக்கம் செல்லாது
+Comment[te]=డౌన్ లోడ్ చేయబడిన్ ప్రాక్సీ రూపకరణపు స్క్రిప్ట్ చెల్లదు
+Comment[tg]=Шакли дастнависи вакил кардашуда ношоям фаровир
+Comment[th]=สคริปต์สำหรับการปรับแต่งพร็อกซีที่ดาวน์โหลดมาไม่ถูกต้อง
+Comment[tr]=Vekil sunucu yapılandırma dosyası geçersiz
+Comment[tt]=Proxy caylaw öçen iñderelgän ämerlek bozıq bulğan
+Comment[uk]=Звантажений скрипт для визначення проксі сервера неправильний
+Comment[uz]=Proksini moslash uchun yozib olingan skript haqiqiy emas
+Comment[uz@cyrillic]=Проксини мослаш учун ёзиб олинган скрипт ҳақиқий эмас
+Comment[vi]=Tập lệnh cấu hình ủy nhiệm đã được tải xuống không phải là hợp lệ.
+Comment[zh_CN]=下载的代理配置脚本是无效的
+Comment[zh_HK]=剛下載的代理伺服器組態 script 語法有誤
+Comment[zh_TW]=代理組態的 script 檔案語法有誤
+default_presentation=16
+
+[download-error]
+Name=Script download error
+Name[af]=Skrip aflaai fout
+Name[ar]=خطأ أثناء تنزيل النص البرمجي
+Name[az]=Skript endirmə xətası
+Name[be]=Памылка сцягвання сцэнара
+Name[bg]=Грешка при изтегляне на скрипта
+Name[bn]=স্ক্রিপ্ট ডাউনলোডে সমস্যা
+Name[br]=Fazi en ur enkargañ an urzhiaoug
+Name[bs]=Greška pri downloadu skripte
+Name[ca]=Error descàrrega de l'script
+Name[cs]=Chyba ve stažení skriptu
+Name[csb]=Fela zladënkù skriptu
+Name[cy]=Gwall wrth lawrlwytho'r sgript
+Name[da]=Script download-fejl
+Name[de]=Fehler beim Herunterladen des Skripts
+Name[el]=Σφάλμα λήψης σεναρίου
+Name[eo]=Skripta ŝarĝeraro
+Name[es]=Error de descarga del procedimiento
+Name[et]=Viga skripti allalaadimisel
+Name[eu]=Errorea script-a deskargatzean
+Name[fa]=خطای بارگیری دست‌نوشته
+Name[fi]=Skriptin latausvirhe
+Name[fr]=Erreur de téléchargement du script
+Name[fy]=Skript ynlaad flater
+Name[ga]=Earráid íoslódála scripte
+Name[gl]=Erro de descarga do guión
+Name[he]=שגיאה בהורדת התסריט
+Name[hi]=स्क्रिप्ट डाउनलोड त्रुटि
+Name[hr]=Pogreška pri preuzimanju skripte
+Name[hu]=Szkriptletöltési hiba
+Name[id]=Kesalahan mengambil skrip
+Name[is]=Villa við hleðslu skriftu
+Name[it]=Errore di scaricamento script
+Name[ja]=スクリプトのダウンロードエラー
+Name[ka]=სკრიპტის ჩამოტვირთვის შეცდოამ
+Name[kk]=Скриптті жүктеп алу қатесі
+Name[km]=កំហុស​ទាញយក​ស្គ្រីប
+Name[ko]=스크립트 내려받기 오류
+Name[lb]=Feeler beim Erofluede vum Skript
+Name[lt]=scenarijaus atsisiuntimo klaida
+Name[lv]=Skripta lejuplādes kļūda
+Name[mk]=Грешка при симнување на скрипта
+Name[mn]=Скрипт татахад алдаа
+Name[ms]=Ralat muat turun skrip
+Name[nb]=Skript nedlastingsfeil
+Name[nds]=Skript-Daallaadfehler
+Name[ne]=स्क्रिप्ट डाउनलोड त्रुटि
+Name[nl]=Fout bij downloaden van script
+Name[nn]=Feil ved skriptnedlasting
+Name[pa]=ਸਕ੍ਰਿਪਟ ਡਾਊਨਲੋਡ ਗਲਤੀ
+Name[pl]=Błąd pobierania skryptu
+Name[pt]=Erro de transferência da configuração
+Name[pt_BR]=Erro de download de script
+Name[ro]=Eroare de transfer a scriptului
+Name[ru]=Ошибка загрузки скрипта
+Name[rw]=Ikosa ry'ikurura inyandikoporogaramu
+Name[se]=Meattáhus skripta vieččadettiin
+Name[sk]=Chyba počas sťahovania skriptu
+Name[sl]=Napaka nalaganju skripta
+Name[sq]=Skripta nuk pat sukses të Ngarkohet
+Name[sr]=Грешка приликом преузимања скрипте
+Name[sr@Latn]=Greška prilikom preuzimanja skripte
+Name[sv]=Nerladdningsfel för skript
+Name[ta]=எழுத்தாக்கத்தை இறக்கும்போது பிழை
+Name[te]=స్క్రిప్ట్ డౌన్ లోడ్ దోషం
+Name[tg]=Хатои дастнавис фаровир
+Name[th]=ข้อผิดพลาดในการดาวน์โหลดสคริปต์
+Name[tr]=Betik indirme hatası
+Name[tt]=Ämerlek iñderü xatarı
+Name[uk]=Помилка звантаження скрипту
+Name[uz]=Skriptni yozib olishda xato roʻy berdi
+Name[uz@cyrillic]=Скриптни ёзиб олишда хато рўй берди
+Name[vi]=Lỗi tải xuống tập lệnh
+Name[zh_CN]=脚本下载错误
+Name[zh_HK]=Script 下載錯誤
+Name[zh_TW]=Script 下載錯誤
+Comment=The proxy configuration script could not be downloaded
+Comment[af]=Die proksie opstelling skrip kon nie afgelaai word nie
+Comment[ar]=تعذر تنزيل النص البرمجي لإعداد الخادم الوكيل
+Comment[az]=VƏkil qurğuları skripti endirilə bilmədi
+Comment[bg]=Скриптът за настройване на прокси сървъра не може да бъде изтеглен
+Comment[bn]=প্রক্সি কনফিগারেশন স্ক্রিপ্ট ডাউনলোড করা যায়নি
+Comment[br]=Ne m'eus ket enkargañ urzhiaoug kefluniadur ar proksi
+Comment[bs]=Nisam mogao downloadovati skriptu za podešavanje proxy-ja
+Comment[ca]=L'script de configuració del servidor intermedi no es pot descarregar
+Comment[cs]=Nelze stáhnout konfigurační skript pro proxy
+Comment[csb]=Nie je mòżno zladowac skriptu kònfiguracëji pòstrzédnika
+Comment[cy]=Y sgript ffurfweddu'r dirprwy
+Comment[da]=Proxy-indstillingsscriptet kunne ikke hentes
+Comment[de]=Das Proxy-Einrichtungsskript lässt sich nicht herunterladen
+Comment[el]=Το σενάριο ρύθμισης διαμεσολαβητή ήταν αδύνατο να ανακτηθεί
+Comment[eo]=Ne eblas ŝarĝi la prokuragordoskripton
+Comment[es]=El procedimiento de configuración del proxy no se pudo descargar
+Comment[et]=Proxy seadistuse skripti ei õnnestu alla laadida
+Comment[eu]=Proxy-aren konfigurazioko script-a ezin izan da deskargatu
+Comment[fa]=دست‌نوشتۀ پیکربندی پیشکار بارگیری نشد
+Comment[fi]=Proxyn asetusskriptiä ei voitu ladata
+Comment[fr]=Le script de configuration du serveur mandataire n'a pas pu être téléchargé
+Comment[fy]=It ynladen fan de proxy ynstellings skript is net slagge
+Comment[ga]=Níorbh fhéidir script chumraíochta an tseachfhreastalaí a íoslódáil
+Comment[gl]=Non se pudo descarregar o guión de configuración do proxy
+Comment[he]=לא יכול להוריד את תסריט הגדרות הפרוקסי
+Comment[hi]=प्रॉक्सी कॉन्फ़िगरेशन स्क्रिप्ट डाउनलोड नही की जा सकी।
+Comment[hr]=Skripta konfiguriranja proxyja nije mogla biti preuzetom s Interneta
+Comment[hu]=A proxybeállító szkript letöltése nem sikerült
+Comment[id]= Skrip konfigurasi proxy tidak dapat diunduh
+Comment[is]=Gat ekki sótt stillingaskriftu milliþjóns
+Comment[it]=Impossibile scaricare lo script di configurazione proxy
+Comment[ja]=プロキシ設定スクリプトをダウンロードできませんでした
+Comment[ka]=პროქსის გამართვის სკრიპტის ჩამოტვირთვა ვერ ხერხდება
+Comment[kk]=Бұл прокси скрипт жүктеп алынбайды
+Comment[km]=មិន​អាច​ទាញយក​ស្គ្រីប​កំណត់​រចនាសម្ព័ន្ធ​ប្រូកស៊ី
+Comment[ko]=프록시 설정 스크립트를 내려받지 못합니다
+Comment[lb]=D'Proxy-Konfiguratiounsskript konnt net erofgeluede ginn
+Comment[lt]=Proxy derinimo scenarijus negali būti atsisiųstas
+Comment[mk]=Скриптата за конфигурација на прокси не можеше да се симне
+Comment[mn]=Итгэмжилэгч тохиргооны скрипт татагдахгүй байна
+Comment[ms]=Skrip penyelarasan proksi tidak boleh dimuat turun
+Comment[nb]=Klarte ikke å laste ned skiptet for mellomtjener-innstillinger
+Comment[nds]=Dat Skript för't Instellen vun den Proxy lett sik nich daalladen
+Comment[ne]=प्रोक्सी कन्फिगरेसन स्क्रिप्ट डाउनलोड हुन सक्ने छैन
+Comment[nl]=Het proxyconfiguratiescript kon niet worden opgehaald
+Comment[nn]=Klarte ikkje lasta ned skript for mellomtenaroppsett
+Comment[pa]=ਪਰਾਕਸੀ ਸੰਰਚਨਾ ਸਕ੍ਰਿਪਟ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ
+Comment[pl]=Nie można pobrać skryptu konfiguracji pośrednika
+Comment[pt]=A configuração do 'proxy' não pôde ser transferida
+Comment[pt_BR]=O script de configuração do proxy não pode ser carregado
+Comment[ro]=Nu am putut transfera scriptul de configurare "proxy"
+Comment[ru]=Не удаётся загрузить скрипт настройки прокси
+Comment[rw]=Inyandikoporogaramu y'iboneza rya Nyabubasha ntiyashoboye gukururwa
+Comment[se]=Ii sáhttán gaskbálváheivehanskripta viežžat
+Comment[sk]=Nebolo možné stiahnúť konfiguračný skript pre proxy
+Comment[sl]=Nastavitveni skript posrednika ni mogel biti naložen
+Comment[sq]=Skripta për Konfigurimin e Proxy-t nuk pat sukses të ngarkohet
+Comment[sr]=Скрипта за подешавање проксија не може бити преузета
+Comment[sr@Latn]=Skripta za podešavanje proksija ne može biti preuzeta
+Comment[sv]=Proxyinställningsskriptet kunde inte laddas ner
+Comment[ta]=பதிலாள் வடிவமைப்பு எழுத்தாக்கத்தை இறக்க முடியவில்லை
+Comment[te]=ప్రాక్సీ రూపకరణపు స్క్రిప్ట్ ని డౌన్ లోడ్ చేయలేకపోయాం
+Comment[tg]=Шакли дастнависи вакил кардашуда фаровир наметавонад
+Comment[th]=ไม่สามารถดาวน์โหลดสคริปต์สำหรับปรับแต่งพร็อกซีได้
+Comment[tr]=Vekil sunucu yapılandırma dosyası indirilemedi
+Comment[tt]=Bu proxy caylaw ämerlegen iñderep bulmadı
+Comment[uk]=Не вдається звантажити скрипт для визначення проксі сервера
+Comment[uz]=Proksini moslash uchun skriptni yozib olib boʻlmadi
+Comment[uz@cyrillic]=Проксини мослаш учун скриптни ёзиб олиб бўлмади
+Comment[vi]=Không thể tải xuống tập lệnh cấu hình ủy nhiệm.
+Comment[zh_CN]=代理配置脚本无法下载
+Comment[zh_HK]=無法取得代理伺服器組態 script 檔案
+Comment[zh_TW]=無法取得代理組態 script 檔案
+default_presentation=16
+
+[evaluation-error]
+Name=Script evaluation error
+Name[af]=Skrip evaluasie fout
+Name[ar]=خطأ في تقييم النص البرمجي
+Name[az]=Skript icra xətası
+Name[bg]=Грешка при обработка на скрипта
+Name[bn]=স্ক্রিপ্ট চালানোয় সমস্যা
+Name[bs]=Greška pri procjeni skripte
+Name[ca]=Error en l'avaluació de l'script
+Name[cs]=Chyba v analýze skriptu
+Name[csb]=Fela zrëszëniô skriptu
+Name[cy]=Gwall wrth werthuso'r sgript
+Name[da]=Script evalueringsfejl
+Name[de]=Skript-Überprüfungsfehler
+Name[el]=Σφάλμα επικύρωσης σεναρίου
+Name[eo]=Skripta ruleraro
+Name[es]=Error de evaluación del procedimiento
+Name[et]=Viga skripti käivitamisel
+Name[eu]=Script-aren ebaluazioko errorea
+Name[fa]=خطای ارزیابی دست‌نوشته
+Name[fi]=Skriptin määritysvirhe
+Name[fr]=Erreur d'évaluation du script
+Name[fy]=Beoardiele skript flater
+Name[ga]=Earráid agus an script á luacháil
+Name[gl]=Erro de evaluación do guión
+Name[he]=שגיאת הרצה בתסריט
+Name[hi]=स्क्रिप्ट इवेल्यूएशन त्रुटि
+Name[hr]=Pogreška pri procjenjivanju skripte
+Name[hu]=Szkriptkiértékelési hiba
+Name[id]=Kesalahan menjalankan skrip
+Name[is]=Túlkunarvilla skriftu
+Name[it]=Errore di valutazione script
+Name[ja]=スクリプト評価エラー
+Name[ka]=სკრიპტის დამუშავების შეცდომა
+Name[kk]=Скрипт талдау қатесі
+Name[km]=កំហុស​វាយតម្លៃរបស់ស្គ្រីប
+Name[ko]=스크립트 평가 오류
+Name[lb]=Feeler beim Evaluéieren vum Skript
+Name[lt]=Scenarijaus analizės klaida
+Name[mk]=Грешка при евалуација на скрипта
+Name[mn]=Скрипт үнэлэхэд алдаа
+Name[ms]=Ralat penilaian skrip
+Name[nb]=Skript evalueringsfeil
+Name[nds]=Skript-Pröövfehler
+Name[ne]=स्क्रिप्ट मूल्यांकन त्रुटि
+Name[nl]=Fout bij evalueren van script
+Name[nn]=Feil ved skriptevaluering
+Name[pa]=ਸਕ੍ਰਿਪਟ ਏਵੂਲੇਸ਼ਨ ਗਲਤੀ
+Name[pl]=Błąd wykonywania skryptu
+Name[pt]=Erro de avaliação da configuração
+Name[pt_BR]=Erro de avaliação de script
+Name[ro]=Eroare de analiză a scriptului
+Name[ru]=Ошибка разбора скрипта
+Name[rw]=Ikosa ry'isuzuma ry'inyandikoporogaramu
+Name[sk]=Chyba kontroly skriptu
+Name[sl]=Napaka pri ocenjevanju skripta
+Name[sq]=Gabim i vlerësimit të skriptës
+Name[sr]=Грешка приликом израчунавања у скрипти
+Name[sr@Latn]=Greška prilikom izračunavanja u skripti
+Name[sv]=Utvärderingsfel för skript
+Name[ta]=எழுத்தாக்க மதிப்பீட்டுப் பிழை
+Name[te]=స్క్రిప్ట్ నిర్వహణ దోషం
+Name[tg]=Фикри хатои дастнавис
+Name[th]=ข้อผิดพลาดในการประเมินสคริปต์
+Name[tr]=Betik çalıştırma hatası
+Name[tt]=Ämerlek eçtälegen uqığanda xata çıqtı
+Name[uk]=Помилка виконання скрипту
+Name[uz]=Skriptni tekshirishda xato roʻy berdi
+Name[uz@cyrillic]=Скриптни текширишда хато рўй берди
+Name[vi]=Lỗi định lượng tập lệnh
+Name[zh_CN]=脚本求值错误
+Name[zh_HK]=Script 執行錯誤
+Name[zh_TW]=Script 執行錯誤
+Comment=There was an error executing the proxy configuration script
+Comment[af]=Daar was 'n fout met die uitvoer van die proksie opstell skrip
+Comment[ar]=لقد حصل خطأ كبير أدى الى خروج البرنامج
+Comment[az]=Vəkil qurğuları skripti işə salınırkən xəta baş verdi
+Comment[bg]=Грешка по време на изпълнение на скрипта за настройване на прокси сървъра
+Comment[bn]=প্রক্সি কনফিগারেশন স্ক্রিপ্ট চালাতে সমস্যা দেখা দিয়েছে
+Comment[br]=Degouezhet ez eus ur fazi en ur seveniñ urzhiaoug kefluniadur ar proksi
+Comment[bs]=Došlo je do greške pri izvršavanju skripte za podešavanje proxy-ja
+Comment[ca]=Hi ha hagut un error executant l'script de configuració del servidor intermedi
+Comment[cs]=Nastala chyba při spouštění konfiguračního skriptu proxy
+Comment[csb]=Pòkôza sã fela, òb czas zrëszëniô skriptu kònfigùracëji pòstrzédnika
+Comment[cy]=Digwyddodd gwall wrth weithredu'r sgript ffurfweddu'r dirprwy
+Comment[da]=Der opstod en fejl ved kørslen af proxy-indstillingsscriptet
+Comment[de]=Fehler beim Ausführen des Proxy-Einrichtungsskripts
+Comment[el]=Συνέβη ένα σφάλμα στην εκτέλεση του σεναρίου ρύθμισης διαμεσολαβητή
+Comment[eo]=Okazis eraro dum rulo de la prokuragordoskripto
+Comment[es]=Se produjo un error al ejecutarse el procedimiento de configuración del proxy
+Comment[et]=Ilmnes tõsine viga proxy seadistuse skripti käivitamisel
+Comment[eu]=Errorea gertatu da proxy-a konfiguratzeko script-ean
+Comment[fa]=هنگام اجرای دست‌نوشتۀ پیکربندی پیشکار، خطایی وجود داشت
+Comment[fi]=Proxy-skriptin suorittamisessa tapahtui virhe
+Comment[fr]=Une erreur s'est produite lors de l'exécution du script de configuration du serveur mandataire
+Comment[fy]=Der wie in flater by it útfoeren fan de proxy ynstellings skript
+Comment[ga]=Tharla earráid agus script chumraíocht an tseachfhreastalaí á rith
+Comment[gl]=Houbo un erro executando o guión de configuración do proxi
+Comment[he]=אירעה שגיאה בעת הרצת תסריט הגדרות בפרוקסי
+Comment[hi]=प्रॉक्सी कॉन्फ़िगरेशन स्क्रिप्ट चलाने में त्रुटि हुई
+Comment[hr]=Došlo je do pogreške pri izvršavanju konfiguracijske skripte proxyja
+Comment[hu]=Hiba történt a proxybeállító szkript végrehajtása közben
+Comment[id]=Kesalahan sewaktu menjalankan skrip konfigurasi proxy
+Comment[is]=Það kom upp villa við keyrslu stillingaskriftu milliþjóns
+Comment[it]=Si è verificato un errore durante l'esecuzione dello script di configurazione proxy
+Comment[ja]=プロキシ設定スクリプトの実行中にエラーが発生しました
+Comment[ka]=პროქსის გამართვის სკრიპტის გამოყენების შეცდომა
+Comment[kk]=Прокси баптау скриптті орындау кезінде қате пайда болды
+Comment[km]=មាន​កំហុស​មួយ​ក្នុងការប្រតិបត្តិ​ស្គ្រីបកំណត់​រចនាសម្ព័ន្ធ​ប្រូកស៊ី
+Comment[ko]=프록시 설정 스크리트를 실행하는데 문제가 있습니다
+Comment[lb]=Et gouf e Feeler beim Ausféiere vum Proxy-Konfiguratiounsskript
+Comment[lt]=Paleidžiant proxy derinimo scenarijų įvyko klaida
+Comment[mk]=Имаше грешка при извршувањето на скриптата за конфигурација на прокси
+Comment[mn]=итгэмжилэгч тохируулгын скрипт ажиллуулж байхад алдаа
+Comment[ms]=Terdapat ralat melaksanakan skrip penyelarasan proksi
+Comment[nb]=Det oppsto en alvorlig feil under kjøringen av skriptet for mellomtjener-innstillinger
+Comment[nds]=Bi't Utföhren vun dat Proxy-Instellenskript hett dat en Fehler geven
+Comment[ne]=प्रोक्सी कन्फिगरेसन स्क्रिप्ट कार्यान्वयन गर्दा त्रुटि थियो
+Comment[nl]=Er deed zich een fout voor tijdens het uitvoeren van het proxyconfiguratiescript
+Comment[nn]=Feil ved køyring av skript for mellomtenaroppsett
+Comment[pa]=ਪਰਾਕਸੀ ਸੰਰਚਨਾ ਸਕ੍ਰਿਪਟ ਚਲਾਉਣ ਵਿੱਚ ਗਲਤੀ ਆਈ ਹੈ
+Comment[pl]=Wystąpił błąd w czasie wykonywania skryptu konfiguracji pośrednika
+Comment[pt]=Ocorreu um erro ao efectuar a configuração do 'proxy'
+Comment[pt_BR]=Ocorreu um erro ao executar o script de configuração do proxy.
+Comment[ro]=A apărut o eroare la execuţia scriptului de configurare "proxy"
+Comment[ru]=Ошибка при выполнении скрипта настройки прокси
+Comment[rw]=Habaye ikosa mu gutangiza inyandikoporogaramu y'iboneza rya Nyabubasha
+Comment[se]=Meattáhus vuojedettiin gaskabálváheivehanskripta
+Comment[sk]=Vyskytla sa chyba počas spustenia konfiguračného skriptu proxy
+Comment[sl]=Prišlo je do napake pri izvajanju nastavitvenega skripta posrednika
+Comment[sq]=Është paraqitur një gabim gjatë ekzekutimit të skriptës për konfigurimin e proxy-t
+Comment[sr]=Десила се грешка приликом извршавања скрипте за подешавање проксија
+Comment[sr@Latn]=Desila se greška prilikom izvršavanja skripte za podešavanje proksija
+Comment[sv]=Fel uppstod vid körning av proxyinställningsskriptet
+Comment[ta]=பதிலாள் வடிவமைப்பு எழுத்தாக்கத்தை செயல்படுத்தும்போது ஒரு பிழை நேர்ந்தது
+Comment[te]=ప్రాక్సీ రూపకరణపు స్క్రిప్ట్ నిర్వహణలొ దోషం వున్నది
+Comment[tg]=Хато фаразани дар шакли дастнависи вакил кардашуда
+Comment[th]=เกิดข้อผิดพลาดในการสั่งให้สคริปต์ปรับแต่งพร็อกซีทำงาน
+Comment[tr]=Vekil sunucu yapılandırma dosyası çalıştırılamadı
+Comment[tt]=Proxy caylaw ämerelegen eşlätkändä xata çıqtı
+Comment[uk]=Виникла помилка при спробі виконати скрипт для визначення проксі сервера
+Comment[uz]=Proksini moslash uchun skriptni ishga tushirishda xato roʻy berdi
+Comment[uz@cyrillic]=Проксини мослаш учун скриптни ишга туширишда хато рўй берди
+Comment[vi]=Gặp lỗi khi thực hiện tập lệnh cấu hình ủy nhiệm.
+Comment[zh_CN]=执行代理配置脚本出现错误
+Comment[zh_HK]=代理伺服器組態檔案執行錯誤
+Comment[zh_TW]=proxy 代理組態檔案執行錯誤
+default_presentation=0
diff --git a/kio/misc/kpac/kpac_dhcp_helper.c b/kio/misc/kpac/kpac_dhcp_helper.c
new file mode 100644
index 000000000..906e89dfa
--- /dev/null
+++ b/kio/misc/kpac/kpac_dhcp_helper.c
@@ -0,0 +1,229 @@
+/* This file is part of the KDE Libraries
+ Copyright (c) 2001 Malte Starostik <malte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+
+#include <config.h>
+#include <sys/types.h>
+#include <grp.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <time.h>
+#include <netdb.h>
+#include <netinet/in.h>
+
+#include "dhcp.h"
+
+#ifndef INADDR_NONE /* some OSes don't define this */
+#define INADDR_NONE -1
+#endif
+
+int set_gid(gid_t);
+int set_uid(uid_t);
+int get_port(const char *);
+int init_socket(void);
+uint32_t send_request(int);
+void get_reply(int, uint32_t);
+
+int set_gid(gid_t gid)
+{
+#ifdef HAVE_SHORTSETGROUPS
+ short x[2];
+ x[0] = gid;
+ x[1] = 73; /* catch errors */
+ if (setgroups(1, x) == -1)
+ return -1;
+#else
+ if (setgroups(1, &gid) == -1)
+ return -1;
+#endif
+ return setgid(gid); /* _should_ be redundant, but on some systems it isn't */
+}
+
+int set_uid(uid_t uid)
+{
+ return setuid(uid);
+}
+
+/* All functions below do an exit(1) on the slightest error */
+
+/* Returns the UDP port number for the given service name */
+int get_port(const char *service)
+{
+ struct servent *serv = getservbyname(service, "udp");
+ if (serv == NULL)
+ exit(1);
+
+ return serv->s_port;
+}
+
+/* Opens the UDP socket, binds to the bootpc port and drops root privileges */
+int init_socket()
+{
+ struct sockaddr_in addr;
+ struct protoent *proto;
+ int sock;
+ int bcast = 1;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_ANY;
+ addr.sin_port = get_port("bootpc");
+
+ if ((proto = getprotobyname("udp")) == NULL ||
+ (sock = socket(AF_INET, SOCK_DGRAM, proto->p_proto)) == -1)
+ exit(1);
+
+ if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof(bcast)) == -1 ||
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &bcast, sizeof(bcast)) == -1 ||
+ bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1)
+ exit(1);
+
+ if (set_gid(getgid()) != 0 || /* we don't need it anymore */
+ set_uid(getuid()) != 0)
+ exit(1);
+ return sock;
+}
+
+/* Fills the DHCPINFORM request packet, returns the transaction id */
+uint32_t send_request(int sock)
+{
+ char hostname[256];
+ struct hostent *hent;
+ struct sockaddr_in addr;
+ struct dhcp_msg request;
+ uint8_t *offs = request.options;
+
+ hostname[0] = '\0';
+ hostname[255] = '\0';
+ if (gethostname(hostname, 255) == -1 ||
+ strlen(hostname) == 0 ||
+ (hent = gethostbyname(hostname)) == NULL)
+ exit(1);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_NONE;
+ addr.sin_port = get_port("bootps");
+
+ memset(&request, 0, sizeof(request));
+ request.op = DHCP_BOOTREQUEST;
+ srand(time(NULL));
+ request.xid = rand();
+ request.ciaddr = *(uint32_t*)*hent->h_addr_list;
+
+ *offs++ = DHCP_MAGIC1;
+ *offs++ = DHCP_MAGIC2;
+ *offs++ = DHCP_MAGIC3;
+ *offs++ = DHCP_MAGIC4;
+
+ *offs++ = DHCP_OPT_MSGTYPE;
+ *offs++ = 1; /* length */
+ *offs++ = DHCP_INFORM;
+
+ *offs++ = DHCP_OPT_PARAMREQ;
+ *offs++ = 1; /* length */
+ *offs++ = DHCP_OPT_WPAD;
+
+ *offs++ = DHCP_OPT_END;
+
+ if (sendto(sock, &request, sizeof(request), 0,
+ (struct sockaddr *)&addr, sizeof(addr)) != sizeof(request))
+ exit(1);
+
+ return request.xid;
+}
+
+/* Reads the reply from the socket, checks it and outputs the URL to STDOUT */
+void get_reply(int sock, uint32_t xid)
+{
+ struct dhcp_msg reply;
+ int len;
+ char wpad[DHCP_OPT_LEN + 1];
+ uint8_t wpad_len;
+ uint8_t *offs = reply.options;
+ uint8_t *end;
+
+ if ((len = recvfrom(sock, &reply, sizeof(reply), 0, NULL, NULL)) <= 0)
+ exit(1);
+
+ end = (uint8_t *)&reply + len;
+ if (end < offs + 4 ||
+ end > &reply.options[DHCP_OPT_LEN] ||
+ reply.op != DHCP_BOOTREPLY ||
+ reply.xid != xid ||
+ *offs++ != DHCP_MAGIC1 ||
+ *offs++ != DHCP_MAGIC2 ||
+ *offs++ != DHCP_MAGIC3 ||
+ *offs++ != DHCP_MAGIC4)
+ exit(1);
+
+ for ( ; offs < end - 1; offs += *offs+1)
+ {
+ switch (*offs++)
+ {
+ case DHCP_OPT_END:
+ exit(1);
+ case DHCP_OPT_MSGTYPE:
+ if (*offs != 1 || (offs >= end - 1) || *(offs + 1) != DHCP_ACK)
+ exit(1);
+ break;
+ case DHCP_OPT_WPAD:
+ memset(wpad, 0, sizeof(wpad));
+ wpad_len = *offs++;
+ if (offs >= end)
+ exit(1);
+ if (wpad_len > end - offs)
+ wpad_len = end - offs;
+ strncpy(wpad, (char *)offs, wpad_len);
+ wpad[wpad_len] = 0;
+ printf("%s\n", wpad);
+ close(sock);
+ exit(0);
+ }
+ }
+ exit(1);
+}
+
+int main()
+{
+ fd_set rfds;
+ struct timeval tv;
+ int sock;
+ uint32_t xid;
+
+ sock = init_socket();
+ xid = send_request(sock);
+
+ FD_ZERO(&rfds);
+ FD_SET(sock, &rfds);
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
+ if (select(sock + 1, &rfds, NULL, NULL, &tv) == 1 && FD_ISSET(sock, &rfds))
+ get_reply(sock, xid);
+
+ close(sock);
+ exit(1);
+}
+
+/* vim: ts=4 sw=4 noet
+ */
diff --git a/kio/misc/kpac/kpactest.pac b/kio/misc/kpac/kpactest.pac
new file mode 100644
index 000000000..69e5aaad7
--- /dev/null
+++ b/kio/misc/kpac/kpactest.pac
@@ -0,0 +1,169 @@
+// This is a script to test KPAC.
+// To use it: set this script as proxy config file and run
+// dcop kded proxyscout proxyForURL http://blah (URL doesn't matter)
+// The answer must be http://<your IP>/<test results>
+// If you see "failed" in the output, lookup the test name in the comments
+// below and let me now at <malte@kde.org> or try to fix it yourself
+
+function FindProxyForURL( url, host )
+{
+ var result = "PROXY http://" + myIPAddress();
+
+ // plainhost1
+ if ( !isPlainHostName( "foo" ) )
+ result += "/plainhost1=failed"
+ // plainhost2
+ if ( isPlainHostName( "foo.bar" ) )
+ result += "/plainhost2=failed";
+
+ // dnsdomain1
+ if ( !dnsDomainIs( "foo.bar", "bar" ) )
+ result += "/dnsdomain1=failed";
+ // dnsdomain2
+ if ( dnsDomainIs( "foo.baz", "bar" ) )
+ result += "/dnsdomain2=failed";
+
+ // localordomain1
+ if ( !localHostOrDomainIs( "foo", "bar" ) )
+ result += "/localordomain1=failed";
+ // localordomain2
+ if ( !localHostOrDomainIs( "foo.bar", "foo.bar" ) )
+ result += "/localordomain2=failed";
+ // localordomain3
+ if ( !localHostOrDomainIs( "foo", "foo.baz" ) )
+ result += "/localordomain3=failed";
+ // localordomain4
+ if ( localHostOrDomainIs( "foo.bar", "foo.baz" ) )
+ result += "/localordomain4=failed";
+
+ // isresolvable1
+ // on failure make sure you can resolve www.kde.org correctly :-)
+ if ( !isResolvable( "www.kde.org" ) ) result += "/isresolvable1=failed";
+ // isresolvable2
+ // on failure make sure dummy.invalid doesn't resolve :-)
+ if ( isResolvable( "dummy.invalid" ) ) result += "/isresolvable2=failed";
+
+ // isinnet1
+ // on failure check if localhost resolves to 127.0.0.1 as it should
+ if ( isInNet( "localhost", "1.2.3.4", "255.0.0.0" ) )
+ result += "/isinnet1=failed";
+ // isinnet2
+ if ( isInNet( "1.2.3.4", "1.2.3.5", "255.255.255.255" ) )
+ result += "/isinnet2=failed";
+ // isinnet3
+ if ( !isInNet( "1.2.3.4", "1.2.3.5", "255.255.255.0" ) )
+ result += "/isinnet3=failed";
+
+ // dnsresolve1
+ // on failure check if localhost resolves to 127.0.0.1 as it should
+ if ( dnsResolve( "localhost" ) != "127.0.0.1" )
+ result += "/dnsresolve1=failed";
+
+ // dnslevels1
+ if ( dnsDomainLevels( "foo" ) != 0 )
+ result += "/dnslevels1=failed";
+ // dnslevels2
+ if ( dnsDomainLevels( "foo.bar" ) != 1 )
+ result += "/dnslevels2=failed";
+ // dnslevels3
+ if ( dnsDomainLevels( "foo.bar.baz" ) != 2 )
+ result += "/dnslevels3=failed";
+
+ // shexp1
+ if ( !shExpMatch( "foobar", "foobar" ) )
+ result += "/shexp1=failed";
+ // shexp2
+ if ( shExpMatch( "FoObAr", "foobar" ) )
+ result += "/shexp2=failed";
+ // shexp3
+ if ( !shExpMatch( "Foobar", "?oobar" ) )
+ result += "/shexp3=failed";
+ // shexp4
+ if ( !shExpMatch( "FoObAr", "*b*" ) )
+ result += "/shexp4=failed";
+ // shexp5
+ if ( shExpMatch( "FoObAr", "*x*" ) )
+ result += "/shexp5=failed";
+ // shexp6
+ if ( shExpMatch( "www.kde.org", "*.kde" ) )
+ result += "/shexp6=failed";
+
+ var now = new Date;
+ var days = new Array( "sun", "mon", "tue", "wed", "thu", "fri", "sat" );
+ var months = new Array( "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" );
+
+ // weekday1
+ if ( !weekdayRange( "sun", "sat" ) )
+ result += "/weekday1=failed";
+ // weekday2
+ if ( !weekdayRange( "sat", "sun" ) )
+ result += "/weekday2=failed";
+ // weekday3
+ if ( !weekdayRange( days[ now.getDay() ] ) )
+ result += "/weekday3=failed";
+ // weekday4
+ if ( weekdayRange( now.getDay() ? "sun" : "mon" ) )
+ result += "/weekday4=failed";
+
+ // date1
+ if ( !dateRange( now.getDate() ) )
+ result += "/date1=failed";
+ // date2
+ if ( !dateRange( now.getDate(), 31 ) )
+ result += "/date2=failed";
+ // date3
+ if ( !dateRange( 1, now.getDate() ) )
+ result += "/date3=failed";
+ // date4
+ if ( dateRange( now.getDay() > 5 ? 1 : 6, now.getDay() > 5 ? 3 : 8 ) )
+ result += "/date4=failed";
+ // date5
+ if ( !dateRange( months[ now.getMonth() ] ) )
+ result += "/date5=failed";
+ // date6
+ if ( !dateRange( months[ now.getMonth() ], "dec" ) )
+ result += "/date6=failed";
+ // date7
+ if ( !dateRange( "dec", months[ now.getMonth() ] ) )
+ result += "/date7=failed";
+ // date8
+ if ( !dateRange( now.getFullYear() ) )
+ result += "/date8=failed";
+ // date9
+ if ( dateRange( now.getFullYear() - 1 ) )
+ result += "/date9=failed";
+ // date10
+ // if this fails, check your clock first :-)
+ if ( dateRange( 1, "jan", 1990, 31, "dec", 2000 ) )
+ result += "/date10=failed";
+ // date11
+ // if this fails, check your clock first :-)
+ if ( !dateRange( 1, "jan", 2000, 31, "dec", 3000 ) )
+ result += "/date11=failed";
+
+ // time1
+ if ( !timeRange( now.getHours() ) )
+ result += "/time1=failed";
+ // time2
+ if ( !timeRange( now.getHours(), now.getMinutes(), 0, 0 ) )
+ result += "/time2=failed";
+ // time3
+ if ( !timeRange( now.getHours(), now.getMinutes(), now.getSeconds(), 0, 0, 0 ) )
+ result += "/time3=failed";
+ // time4
+ if ( timeRange( now.getHours() > 5 ? 1 : 6, now.getHours() > 5 ? 3 : 8 ) )
+ result += "/time4=failed";
+ // time5
+ if ( now.getHours() == now.getUTCHours() )
+ result += "/time5=skipped";
+ else if ( timeRange( now.getUTCHours() ) )
+ result += "/time5=failed";
+ // time6
+ if ( now.getHours() == now.getUTCHours() )
+ result += "/time6=skipped";
+ else if ( !timeRange( now.getUTCHours(), "GMT" ) )
+ result += "/time6=failed";
+
+ return result;
+}
+
diff --git a/kio/misc/kpac/proxyscout.cpp b/kio/misc/kpac/proxyscout.cpp
new file mode 100644
index 000000000..06d860615
--- /dev/null
+++ b/kio/misc/kpac/proxyscout.cpp
@@ -0,0 +1,196 @@
+/*
+ Copyright (c) 2003 Malte Starostik <malte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+
+#include <cstdlib>
+#include <ctime>
+
+#include <dcopclient.h>
+#include <kapplication.h>
+#include <klocale.h>
+#include <knotifyclient.h>
+#include <kprotocolmanager.h>
+
+#include "proxyscout.moc"
+#include "discovery.h"
+#include "script.h"
+
+namespace KPAC
+{
+ ProxyScout::QueuedRequest::QueuedRequest( const KURL& u )
+ : transaction( kapp->dcopClient()->beginTransaction() ),
+ url( u )
+ {
+ }
+
+ ProxyScout::ProxyScout( const QCString& name )
+ : KDEDModule( name ),
+ m_instance( new KInstance( "proxyscout" ) ),
+ m_downloader( 0 ),
+ m_script( 0 ),
+ m_suspendTime( 0 )
+ {
+ }
+
+ ProxyScout::~ProxyScout()
+ {
+ delete m_script;
+ delete m_instance;
+ }
+
+ QString ProxyScout::proxyForURL( const KURL& url )
+ {
+ if ( m_suspendTime )
+ {
+ if ( std::time( 0 ) - m_suspendTime < 300 ) return "DIRECT";
+ m_suspendTime = 0;
+ }
+
+ // Never use a proxy for the script itself
+ if ( m_downloader && url.equals( m_downloader->scriptURL(), true ) ) return "DIRECT";
+
+ if ( m_script ) return handleRequest( url );
+
+ if ( m_downloader || startDownload() )
+ {
+ m_requestQueue.append( url );
+ return QString::null;
+ }
+ else return "DIRECT";
+ }
+
+ ASYNC ProxyScout::blackListProxy( const QString& proxy )
+ {
+ m_blackList[ proxy ] = std::time( 0 );
+ }
+
+ ASYNC ProxyScout::reset()
+ {
+ delete m_script;
+ m_script = 0;
+ delete m_downloader;
+ m_downloader = 0;
+ m_blackList.clear();
+ m_suspendTime = 0;
+ KProtocolManager::reparseConfiguration();
+ }
+
+ bool ProxyScout::startDownload()
+ {
+ switch ( KProtocolManager::proxyType() )
+ {
+ case KProtocolManager::WPADProxy:
+ m_downloader = new Discovery( this );
+ break;
+ case KProtocolManager::PACProxy:
+ m_downloader = new Downloader( this );
+ m_downloader->download( KURL( KProtocolManager::proxyConfigScript() ) );
+ break;
+ default:
+ return false;
+ }
+ connect( m_downloader, SIGNAL( result( bool ) ),
+ SLOT( downloadResult( bool ) ) );
+ return true;
+ }
+
+ void ProxyScout::downloadResult( bool success )
+ {
+ KNotifyClient::Instance notifyInstance( m_instance );
+ if ( success )
+ try
+ {
+ m_script = new Script( m_downloader->script() );
+ }
+ catch ( const Script::Error& e )
+ {
+ KNotifyClient::event( "script-error", i18n(
+ "The proxy configuration script is invalid:\n%1" )
+ .arg( e.message() ) );
+ success = false;
+ }
+ else KNotifyClient::event( "download-error", m_downloader->error() );
+
+ for ( RequestQueue::ConstIterator it = m_requestQueue.begin();
+ it != m_requestQueue.end(); ++it )
+ {
+ QCString type = "QString";
+ QByteArray data;
+ QDataStream ds( data, IO_WriteOnly );
+ if ( success ) ds << handleRequest( ( *it ).url );
+ else ds << QString( "DIRECT" );
+ kapp->dcopClient()->endTransaction( ( *it ).transaction, type, data );
+ }
+ m_requestQueue.clear();
+ m_downloader->deleteLater();
+ m_downloader = 0;
+ // Suppress further attempts for 5 minutes
+ if ( !success ) m_suspendTime = std::time( 0 );
+ }
+
+ QString ProxyScout::handleRequest( const KURL& url )
+ {
+ try
+ {
+ QString result = m_script->evaluate( url );
+ QStringList proxies = QStringList::split( ';', result );
+ for ( QStringList::ConstIterator it = proxies.begin();
+ it != proxies.end(); ++it )
+ {
+ QString proxy = ( *it ).stripWhiteSpace();
+ if ( proxy.left( 5 ) == "PROXY" )
+ {
+ KURL proxyURL( proxy = proxy.mid( 5 ).stripWhiteSpace() );
+ // If the URL is invalid or the URL is valid but in opaque
+ // format which indicates a port number being present in
+ // this particular case, simply calling setProtocol() on
+ // it trashes the whole URL.
+ int len = proxyURL.protocol().length();
+ if ( !proxyURL.isValid() || proxy.find( ":/", len ) != len )
+ proxy.prepend("http://");
+ BlackList::Iterator it = m_blackList.find( proxy );
+ if ( it == m_blackList.end() ) return proxy;
+ else if ( std::time( 0 ) - *it > 1800 ) // 30 minutes
+ {
+ // black listing expired
+ m_blackList.remove( it );
+ return proxy;
+ }
+ }
+ else return "DIRECT";
+ }
+ // FIXME: blacklist
+ }
+ catch ( const Script::Error& e )
+ {
+ KNotifyClient::Instance notifyInstance( m_instance );
+ KNotifyClient::event( "evaluation-error", i18n(
+ "The proxy configuration script returned an error:\n%1" )
+ .arg( e.message() ) );
+ }
+ return "DIRECT";
+ }
+
+ extern "C" KDE_EXPORT KDEDModule* create_proxyscout( const QCString& name )
+ {
+ return new ProxyScout( name );
+ }
+}
+
+// vim: ts=4 sw=4 et
diff --git a/kio/misc/kpac/proxyscout.desktop b/kio/misc/kpac/proxyscout.desktop
new file mode 100644
index 000000000..2f1b28f84
--- /dev/null
+++ b/kio/misc/kpac/proxyscout.desktop
@@ -0,0 +1,131 @@
+[Desktop Entry]
+Type=Service
+Name=Proxy Scout
+Name[af]=Proksie Verkenner
+Name[az]=Vəkil Skout
+Name[bg]=Проучване на прокси сървъри
+Name[bn]=প্রক্সি স্কাউট
+Name[ca]=Explorador del servidor intermedi
+Name[cs]=Proxy vyhledávač
+Name[csb]=Pòstrzédnik (proxy)
+Name[cy]=Arweinydd Dirprwy
+Name[de]=Automatische Proxy-Einrichtung
+Name[el]=Διαμεσολαβητής Scout
+Name[eo]=Prokurilo
+Name[es]=Explorador del proxy
+Name[fa]=پیشکار Scout
+Name[fi]=Proxy-tiedustelija
+Name[fy]=Proxy ferkenner
+Name[gl]=Proxy Explorador
+Name[he]=מחפש שרתי Proxy
+Name[hi]= प्रॉक्सी स्काउट
+Name[hr]=Proxy izvidnik
+Name[is]=Milliþjóns leitari
+Name[it]=Esploratore proxy
+Name[ja]=プロキシを探す
+Name[ka]=პროქსის თვითგამართვა
+Name[kk]=Проксиді автобапату
+Name[ko]=프록시 찾기
+Name[lb]=Proxy-Scout
+Name[lt]=Proxy paieška
+Name[mk]=Прокси скаут
+Name[mn]=Итгэмжилэгчийн зам хайгч
+Name[ms]=Scout Proksi
+Name[nb]=Mellomtjenerspeiding
+Name[ne]=प्रोक्सी स्काउट
+Name[nn]=Mellomtenarspeiding
+Name[pa]=ਪਰਾਕਸੀ ਸਕਾਊਟ
+Name[pl]=Pośrednik (proxy)
+Name[pt]=Escuteiro do 'Proxy'
+Name[pt_BR]=Saída do Proxy
+Name[ru]=Автонастройка прокси
+Name[rw]=Igifasha Nyabubasha
+Name[se]=Gaskabálvaohci
+Name[sk]=Prieskumník proxy
+Name[sr]=Прокси извиђач
+Name[sr@Latn]=Proksi izviđač
+Name[sv]=Proxy-scout
+Name[ta]=பதிலாள் தேடு
+Name[te]=ప్రాక్సీ వేగు
+Name[tg]=Разведкачӣ Вакил Кардашуда
+Name[tr]=Vekil Sunucu
+Name[tt]=Proxy Saqçısı
+Name[uk]=Розвідник проксі сервера
+Name[uz]=Proksi skaut
+Name[uz@cyrillic]=Прокси скаут
+Name[zh_CN]=代理搜索
+Comment=Automatic proxy configuration
+Comment[af]=Outomatiese proksie opstelling
+Comment[bg]=Автоматично настройване на прокси сървъра
+Comment[bn]=স্বয়ংক্রিয় প্রক্সি কনফিগারেশন
+Comment[br]=Kefluniadur emgefreekh ar proksi
+Comment[bs]=Automatsko podešavanje proxy-ja
+Comment[ca]=Configuració automàtica de l'intermediari
+Comment[cs]=Automatické nastavení proxy
+Comment[csb]=Aòtokònfigùracëjô pòstrzédnika
+Comment[cy]=Ffurweddiad Awtomatig o'r Dirprwy
+Comment[da]=Automatisk proxy-indstilling
+Comment[de]=Sucht nach einem Proxy-Server und richtet ihn ein
+Comment[el]=Αυτόματη ρύθμιση διαμεσολαβητή
+Comment[eo]=Aŭtomata Prokuragordo
+Comment[es]=Configuración automática del Proxy
+Comment[et]=Automaatne proxy konfigureerimine
+Comment[eu]=Proxy-aren konfigurazio automatikoa
+Comment[fa]=پیکربندی خودکار پیشکار
+Comment[fi]=Automaattiset proxy-asetukset
+Comment[fr]=Configuration automatique du serveur mandataire
+Comment[fy]=Automatyske proxy ynstelling
+Comment[ga]=Uathchumraíocht an tseachfhreastalaí
+Comment[gl]=Configuración Automática do Proxi
+Comment[he]=הגדרות מתווך אוטומטיות
+Comment[hi]=स्वचालित प्रॉक्सी कॉन्फ़िगरेशन
+Comment[hr]=Automatsko konfiguriranje proxyja
+Comment[hu]=Automatikus proxybeállítás
+Comment[id]=Konfigurasi proxi otomatis
+Comment[is]=Sjálfvirkar stillingar milliþjóns
+Comment[it]=Configurazione automatica proxy
+Comment[ja]=自動プロキシ設定
+Comment[ka]=პროქსის თვითგამართვა
+Comment[kk]=Проксиді автоматты түрде бапату
+Comment[km]=ការ​កំណត់​រចនាសម្ព័ន្ធ​ប្រូកស៊ី​ដោយ​ស្វ័យប្រវត្តិ
+Comment[lb]=Automatesch Proxy-Configuratioun
+Comment[lt]=Automatinis proxy derinimas
+Comment[mk]=Автоматска конфигурација на прокси
+Comment[ms]=Penyelarasan Proksi Automatik
+Comment[nb]=Automatisk mellomtjeneroppsett
+Comment[nds]=Proxy automaatsch instellen
+Comment[ne]=स्वचालित प्रोक्सी कन्फिगरेसन
+Comment[nl]=Automatische proxyconfiguratie
+Comment[nn]=Automatisk mellomtenaroppsett
+Comment[pa]=ਸਵੈ-ਚਾਲਿਤ ਪਰਾਕਸੀ ਸੰਰਚਨਾ
+Comment[pl]=Autokonfiguracja pośrednika
+Comment[pt]=Configuração automática de 'proxy'
+Comment[pt_BR]=Configuração automática do proxy
+Comment[ro]=Configurare automată pentru proxy
+Comment[ru]=Автонастройка прокси-сервера
+Comment[rw]=Iboneza rya Nyabubasha Yikoresha
+Comment[se]=Automáhtalaš gaskabálváheiveheapmi
+Comment[sk]=Automatická konfigurácia proxy
+Comment[sl]=Samodejne nastavitve posrednika
+Comment[sr]=Аутоматско подешавање проксија
+Comment[sr@Latn]=Automatsko podešavanje proksija
+Comment[sv]=Automatisk proxyinställning
+Comment[ta]=தானியக்க பதிலாள் வடிவமைப்பு
+Comment[te]=స్వయంచాలక ప్రాక్సీ రూపకరణం
+Comment[tg]=Танзими прокси бо автоматикӣ
+Comment[th]=การปรับแต่งพร็อกซีอัตโนมัติ
+Comment[tr]=Otomatik vekil sunucu yapılandırması
+Comment[tt]=Proxy'nıñ üzzihenle caylanu
+Comment[uk]=Автоматичне визначення проксі сервера
+Comment[uz]=Proksini avtomatik ravishda moslash
+Comment[uz@cyrillic]=Проксини автоматик равишда мослаш
+Comment[vi]=Cấu hình ủy nhiệm tự động.
+Comment[zh_CN]=自动代理配置
+Comment[zh_HK]=自動代理伺服器組態
+Comment[zh_TW]=自動代理組態
+ServiceTypes=KDEDModule
+X-KDE-ModuleType=Library
+X-KDE-Library=proxyscout
+X-KDE-FactoryName=proxyscout
+X-KDE-Kded-autoload=false
+X-KDE-Kded-load-on-demand=true
diff --git a/kio/misc/kpac/proxyscout.h b/kio/misc/kpac/proxyscout.h
new file mode 100644
index 000000000..afd7968ab
--- /dev/null
+++ b/kio/misc/kpac/proxyscout.h
@@ -0,0 +1,82 @@
+/*
+ Copyright (c) 2003 Malte Starostik <malte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+
+#ifndef KPAC_PROXYSCOUT_H
+#define KPAC_PROXYSCOUT_H
+
+#include <qmap.h>
+
+#include <kdedmodule.h>
+#include <kurl.h>
+
+#include <time.h>
+
+class DCOPClientTransaction;
+class KInstance;
+
+namespace KPAC
+{
+ class Downloader;
+ class Script;
+
+ class ProxyScout : public KDEDModule
+ {
+ Q_OBJECT
+ K_DCOP
+ public:
+ ProxyScout( const QCString& );
+ virtual ~ProxyScout();
+
+ k_dcop:
+ QString proxyForURL( const KURL& url );
+ ASYNC blackListProxy( const QString& proxy );
+ ASYNC reset();
+
+ private slots:
+ void downloadResult( bool );
+
+ private:
+ bool startDownload();
+ QString handleRequest( const KURL& url );
+
+ KInstance* m_instance;
+ Downloader* m_downloader;
+ Script* m_script;
+
+ struct QueuedRequest
+ {
+ QueuedRequest() : transaction( 0 ) {}
+ QueuedRequest( const KURL& );
+
+ DCOPClientTransaction* transaction;
+ KURL url;
+ };
+ typedef QValueList< QueuedRequest > RequestQueue;
+ RequestQueue m_requestQueue;
+
+ typedef QMap< QString, time_t > BlackList;
+ BlackList m_blackList;
+ time_t m_suspendTime;
+ };
+}
+
+#endif // KPAC_PROXYSCOUT_H
+
+// vim: ts=4 sw=4 et
diff --git a/kio/misc/kpac/script.cpp b/kio/misc/kpac/script.cpp
new file mode 100644
index 000000000..39d6d3f8e
--- /dev/null
+++ b/kio/misc/kpac/script.cpp
@@ -0,0 +1,465 @@
+/*
+ Copyright (c) 2003 Malte Starostik <malte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+
+#include <cstdlib>
+#include <vector>
+#include <algorithm>
+#include <ctime>
+#include <cstring>
+
+#include <netdb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+
+#include <qregexp.h>
+#include <qstring.h>
+
+#include <kurl.h>
+#include <kjs/object.h>
+#include <kresolver.h>
+
+#include "script.h"
+
+using namespace KJS;
+
+QString UString::qstring() const
+{
+ return QString( reinterpret_cast< const QChar* >( data() ), size() );
+}
+
+UString::UString( const QString &s )
+{
+ UChar* data = new UChar[ s.length() ];
+ std::memcpy( data, s.unicode(), s.length() * sizeof( UChar ) );
+ rep = Rep::create( data, s.length() );
+}
+
+namespace
+{
+ class Address
+ {
+ public:
+ struct Error {};
+ static Address resolve( const UString& host )
+ { return Address( host.qstring(), false ); }
+ static Address parse( const UString& ip )
+ { return Address( ip.qstring(), true ); }
+
+ operator in_addr_t() const {
+ const sockaddr_in* sin = m_address;
+ return sin->sin_addr.s_addr;
+ }
+
+ operator String() const { return String( m_address.ipAddress().toString() ); }
+
+ private:
+ Address( const QString& host, bool numeric )
+ {
+ int flags = 0;
+
+ if ( numeric )
+ flags = KNetwork::KResolver::NoResolve;
+
+ KNetwork::KResolverResults addresses =
+ KNetwork::KResolver::resolve( host, QString::null, flags,
+ KNetwork::KResolver::IPv4Family );
+
+ if ( addresses.isEmpty() )
+ throw Error();
+
+ m_address = addresses.first().address().asInet();
+ }
+
+ KNetwork::KInetSocketAddress m_address;
+ };
+
+ struct Function : public ObjectImp
+ {
+ struct ResolveError {};
+
+ virtual bool implementsCall() const { return true; }
+
+ static int findString( const UString& s, const char* const* values )
+ {
+ int index = 0;
+ UString lower = s.toLower();
+ for ( const char* const* p = values; *p; ++p, ++index )
+ if ( lower == *p ) return index;
+ return -1;
+ }
+
+ static const tm* getTime( ExecState* exec, const List& args )
+ {
+ time_t now = std::time( 0 );
+ if ( args[ args.size() - 1 ].toString( exec ).toLower() == "gmt" )
+ return std::gmtime( &now );
+ else return std::localtime( &now );
+ }
+
+ Boolean checkRange( int value, int min, int max )
+ {
+ return ( min <= max && value >= min && value <= max ) ||
+ ( min > max && ( value <= min || value >= max ) );
+ }
+ };
+
+ // isPlainHostName( host )
+ // @returns true if @p host doesn't contains a domain part
+ struct IsPlainHostName : public Function
+ {
+ virtual Value call( ExecState* exec, Object&, const List& args )
+ {
+ if ( args.size() != 1 ) return Undefined();
+ return Boolean( args[ 0 ].toString( exec ).find( "." ) == -1 );
+ }
+ };
+
+ // dnsDomainIs( host, domain )
+ // @returns true if the domain part of @p host matches @p domain
+ struct DNSDomainIs : public Function
+ {
+ virtual Value call( ExecState* exec, Object&, const List& args )
+ {
+ if ( args.size() != 2 ) return Undefined();
+ QString host = args[ 0 ].toString( exec ).qstring().lower();
+ QString domain = args[ 1 ].toString( exec ).qstring().lower();
+ return Boolean( host.endsWith( domain ) );
+ }
+ };
+
+ // localHostOrDomainIs( host, fqdn )
+ // @returns true if @p host is unqualified or equals @p fqdn
+ struct LocalHostOrDomainIs : public Function
+ {
+ virtual Value call( ExecState* exec, Object&, const List& args )
+ {
+ if ( args.size() != 2 ) return Undefined();
+ UString host = args[ 0 ].toString( exec ).toLower();
+ if ( host.find( "." ) == -1 ) return Boolean( true );
+ UString fqdn = args[ 1 ].toString( exec ).toLower();
+ return Boolean( host == fqdn );
+ }
+ };
+
+ // isResolvable( host )
+ // @returns true if host can be resolved via DNS
+ struct IsResolvable : public Function
+ {
+ virtual Value call( ExecState* exec, Object&, const List& args )
+ {
+ if ( args.size() != 1 ) return Undefined();
+ try { ::Address::resolve( args[ 0 ].toString( exec ) ); }
+ catch ( const Address::Error& ) { return Boolean( false ); }
+ return Boolean( true );
+ }
+ };
+
+ // isInNet( host, subnet, mask )
+ // @returns true if @p host is within the IP subnet
+ // specified via @p subnet and @p mask
+ struct IsInNet : public Function
+ {
+ virtual Value call( ExecState* exec, Object&, const List& args )
+ {
+ if ( args.size() != 3 ) return Undefined();
+ try
+ {
+ in_addr_t host = Address::resolve( args[ 0 ].toString( exec ) );
+ in_addr_t subnet = Address::parse( args[ 1 ].toString( exec ) );
+ in_addr_t mask = Address::parse( args[ 2 ].toString( exec ) );
+ return Boolean( ( host & mask ) == ( subnet & mask ) );
+ }
+ catch ( const Address::Error& )
+ {
+ return Undefined();
+ }
+ }
+ };
+
+ // dnsResolve( host )
+ // @returns the IP address of @p host in dotted quad notation
+ struct DNSResolve : public Function
+ {
+ virtual Value call( ExecState* exec, Object&, const List& args )
+ {
+ if ( args.size() != 1 ) return Undefined();
+ try { return String(Address::resolve( args[ 0 ].toString( exec ))); }
+ catch ( const Address::Error& ) { return Undefined(); }
+ }
+ };
+
+ // myIpAddress()
+ // @returns the local machine's IP address in dotted quad notation
+ struct MyIpAddress : public Function
+ {
+ virtual Value call( ExecState*, Object&, const List& args )
+ {
+ if ( args.size() ) return Undefined();
+ char hostname[ 256 ];
+ gethostname( hostname, 255 );
+ hostname[ 255 ] = 0;
+ try { return String(Address::resolve( hostname )); }
+ catch ( const Address::Error& ) { return Undefined(); }
+ }
+ };
+
+ // dnsDomainLevels( host )
+ // @returns the number of dots ('.') in @p host
+ struct DNSDomainLevels : public Function
+ {
+ virtual Value call( ExecState* exec, Object&, const List& args )
+ {
+ if ( args.size() != 1 ) return Undefined();
+ UString host = args[ 0 ].toString( exec );
+ if ( host.isNull() ) return Number( 0 );
+ return Number( std::count(
+ host.data(), host.data() + host.size(), '.' ) );
+ }
+ };
+
+ // shExpMatch( str, pattern )
+ // @returns true if @p str matches the shell @p pattern
+ struct ShExpMatch : public Function
+ {
+ virtual Value call( ExecState* exec, Object&, const List& args )
+ {
+ if ( args.size() != 2 ) return Undefined();
+ QRegExp pattern( args[ 1 ].toString( exec ).qstring(), true, true );
+ return Boolean( pattern.exactMatch(args[ 0 ].toString( exec ).qstring()) );
+ }
+ };
+
+ // weekdayRange( day [, "GMT" ] )
+ // weekdayRange( day1, day2 [, "GMT" ] )
+ // @returns true if the current day equals day or between day1 and day2 resp.
+ // If the last argument is "GMT", GMT timezone is used, otherwise local time
+ struct WeekdayRange : public Function
+ {
+ virtual Value call( ExecState* exec, Object&, const List& args )
+ {
+ if ( args.size() < 1 || args.size() > 3 ) return Undefined();
+ static const char* const days[] =
+ { "sun", "mon", "tue", "wed", "thu", "fri", "sat", 0 };
+ int d1 = findString( args[ 0 ].toString( exec ), days );
+ if ( d1 == -1 ) return Undefined();
+
+ int d2 = findString( args[ 1 ].toString( exec ), days );
+ if ( d2 == -1 ) d2 = d1;
+ return checkRange( getTime( exec, args )->tm_wday, d1, d2 );
+ }
+ };
+
+ // dateRange( day [, "GMT" ] )
+ // dateRange( day1, day2 [, "GMT" ] )
+ // dateRange( month [, "GMT" ] )
+ // dateRange( month1, month2 [, "GMT" ] )
+ // dateRange( year [, "GMT" ] )
+ // dateRange( year1, year2 [, "GMT" ] )
+ // dateRange( day1, month1, day2, month2 [, "GMT" ] )
+ // dateRange( month1, year1, month2, year2 [, "GMT" ] )
+ // dateRange( day1, month1, year1, day2, month2, year2 [, "GMT" ] )
+ // @returns true if the current date (GMT or local time according to
+ // presence of "GMT" as last argument) is within the given range
+ struct DateRange : public Function
+ {
+ virtual Value call( ExecState* exec, Object&, const List& args )
+ {
+ if ( args.size() < 1 || args.size() > 7 ) return Undefined();
+ static const char* const months[] =
+ { "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "nov", "dec", 0 };
+
+ std::vector< int > values;
+ for ( int i = 0; i < args.size(); ++i )
+ {
+ int value = -1;
+ if ( args[ i ].isA( NumberType ) )
+ value = args[ i ].toInteger( exec );
+ else value = findString( args[ i ].toString( exec ), months );
+ if ( value >= 0 ) values.push_back( value );
+ else break;
+ }
+
+ const tm* now = getTime( exec, args );
+
+ // day1, month1, year1, day2, month2, year2
+ if ( values.size() == 6 )
+ return checkRange( ( now->tm_year + 1900 ) * 372 + now->tm_mon * 31 + now->tm_mday,
+ values[ 2 ] * 372 + values[ 1 ] * 31 + values[ 0 ],
+ values[ 5 ] * 372 + values[ 4 ] * 31 + values[ 3 ] );
+
+ // day1, month1, day2, month2
+ else if ( values.size() == 4 &&
+ values[ 1 ] < 12 &&
+ values[ 3 ] < 12 )
+ return checkRange( now->tm_mon * 31 + now->tm_mday,
+ values[ 1 ] * 31 + values[ 0 ],
+ values[ 3 ] * 31 + values[ 2 ] );
+
+ // month1, year1, month2, year2
+ else if ( values.size() == 4 )
+ return checkRange( ( now->tm_year + 1900 ) * 12 + now->tm_mon,
+ values[ 1 ] * 12 + values[ 0 ],
+ values[ 3 ] * 12 + values[ 2 ] );
+
+ // year1, year2
+ else if ( values.size() == 2 &&
+ values[ 0 ] >= 1000 &&
+ values[ 1 ] >= 1000 )
+ return checkRange( now->tm_year + 1900, values[ 0 ], values[ 1 ] );
+
+ // day1, day2
+ else if ( values.size() == 2 &&
+ args[ 0 ].isA( NumberType ) &&
+ args[ 1 ].isA( NumberType ) )
+ return checkRange( now->tm_mday, values[ 0 ], values[ 1 ] );
+
+ // month1, month2
+ else if ( values.size() == 2 )
+ return checkRange( now->tm_mon, values[ 0 ], values[ 1 ] );
+
+ // year
+ else if ( values.size() == 1 && values[ 0 ] >= 1000 )
+ return checkRange( now->tm_year + 1900, values[ 0 ], values[ 0 ] );
+
+ // day
+ else if ( values.size() == 1 && args[ 0 ].isA( NumberType ) )
+ return checkRange( now->tm_mday, values[ 0 ], values[ 0 ] );
+
+ // month
+ else if ( values.size() == 1 )
+ return checkRange( now->tm_mon, values[ 0 ], values[ 0 ] );
+
+ else return Undefined();
+ }
+ };
+
+ // timeRange( hour [, "GMT" ] )
+ // timeRange( hour1, hour2 [, "GMT" ] )
+ // timeRange( hour1, min1, hour2, min2 [, "GMT" ] )
+ // timeRange( hour1, min1, sec1, hour2, min2, sec2 [, "GMT" ] )
+ // @returns true if the current time (GMT or local based on presence
+ // of "GMT" argument) is within the given range
+ struct TimeRange : public Function
+ {
+ virtual Value call( ExecState* exec, Object&, const List& args )
+ {
+ if ( args.size() < 1 || args.size() > 7 ) return Undefined();
+
+ std::vector< int > values;
+ for ( int i = 0; i < args.size(); ++i )
+ if ( args[ i ].isA( NumberType ) )
+ values.push_back( args[ i ].toInteger( exec ) );
+ else break;
+
+ const tm* now = getTime( exec, args );
+
+ // hour1, min1, sec1, hour2, min2, sec2
+ if ( values.size() == 6 )
+ return checkRange( now->tm_hour * 3600 + now->tm_min * 60 + now->tm_sec,
+ values[ 0 ] * 3600 + values[ 1 ] * 60 + values[ 2 ],
+ values[ 3 ] * 3600 + values[ 4 ] * 60 + values[ 5 ] );
+
+ // hour1, min1, hour2, min2
+ else if ( values.size() == 4 )
+ return checkRange( now->tm_hour * 60 + now->tm_min,
+ values[ 0 ] * 60 + values[ 1 ],
+ values[ 2 ] * 60 + values[ 3 ] );
+
+ // hour1, hour2
+ else if ( values.size() == 2 )
+ return checkRange( now->tm_hour, values[ 0 ], values[ 1 ] );
+
+ // hour
+ else if ( values.size() == 1 )
+ return checkRange( now->tm_hour, values[ 0 ], values[ 0 ] );
+
+ else return Undefined();
+ }
+ };
+
+ void registerFunctions( ExecState* exec, Object& global )
+ {
+ global.put( exec, "isPlainHostName",
+ Object( new IsPlainHostName ) );
+ global.put( exec, "dnsDomainIs",
+ Object( new DNSDomainIs ) );
+ global.put( exec, "localHostOrDomainIs",
+ Object( new LocalHostOrDomainIs ) );
+ global.put( exec, "isResolvable",
+ Object( new IsResolvable ) );
+ global.put( exec, "isInNet",
+ Object( new IsInNet ) );
+ global.put( exec, "dnsResolve",
+ Object( new DNSResolve ) );
+ global.put( exec, "myIpAddress",
+ Object( new MyIpAddress ) );
+ global.put( exec, "dnsDomainLevels",
+ Object( new DNSDomainLevels ) );
+ global.put( exec, "shExpMatch",
+ Object( new ShExpMatch ) );
+ global.put( exec, "weekdayRange",
+ Object( new WeekdayRange ) );
+ global.put( exec, "dateRange",
+ Object( new DateRange ) );
+ global.put( exec, "timeRange",
+ Object( new TimeRange ) );
+ }
+}
+
+namespace KPAC
+{
+ Script::Script( const QString& code )
+ {
+ ExecState* exec = m_interpreter.globalExec();
+ Object global = m_interpreter.globalObject();
+ registerFunctions( exec, global );
+
+ Completion result = m_interpreter.evaluate( code );
+ if ( result.complType() == Throw )
+ throw Error( result.value().toString( exec ).qstring() );
+ }
+
+ QString Script::evaluate( const KURL& url )
+ {
+ ExecState *exec = m_interpreter.globalExec();
+ Value findFunc = m_interpreter.globalObject().get( exec, "FindProxyForURL" );
+ Object findObj = Object::dynamicCast( findFunc );
+ if (!findObj.isValid() || !findObj.implementsCall())
+ throw Error( "No such function FindProxyForURL" );
+
+ Object thisObj;
+ List args;
+ args.append(String(url.url()));
+ args.append(String(url.host()));
+ Value retval = findObj.call( exec, thisObj, args );
+
+ if ( exec->hadException() ) {
+ Value ex = exec->exception();
+ exec->clearException();
+ throw Error( ex.toString( exec ).qstring() );
+ }
+
+ return retval.toString( exec ).qstring();
+ }
+}
+
+// vim: ts=4 sw=4 et
diff --git a/kio/misc/kpac/script.h b/kio/misc/kpac/script.h
new file mode 100644
index 000000000..2f5314e9a
--- /dev/null
+++ b/kio/misc/kpac/script.h
@@ -0,0 +1,56 @@
+/*
+ Copyright (c) 2003 Malte Starostik <malte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+
+#ifndef KPAC_SCRIPT_H
+#define KPAC_SCRIPT_H
+
+#include <qstring.h>
+
+#include <kjs/interpreter.h>
+
+class KURL;
+
+namespace KPAC
+{
+ class Script
+ {
+ public:
+ class Error
+ {
+ public:
+ Error( const QString& message )
+ : m_message( message ) {}
+ const QString& message() const { return m_message; }
+
+ private:
+ QString m_message;
+ };
+
+ Script( const QString& code );
+ QString evaluate( const KURL& );
+
+ private:
+ KJS::Interpreter m_interpreter;
+ };
+}
+
+#endif // KPAC_SCRIPT_H
+
+// vim: ts=4 sw=4 et