KIO
discovery.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include <netdb.h>
00024 #include <unistd.h>
00025
00026 #ifdef HAVE_SYS_TYPES_H
00027 #include <sys/types.h>
00028 #endif
00029 #ifdef HAVE_NETINET_IN_H
00030 #include <netinet/in.h>
00031 #endif
00032 #include <arpa/nameser.h>
00033 #ifdef HAVE_ARPA_NAMESER8_COMPAT_H
00034 #include <arpa/nameser8_compat.h>
00035 #endif
00036 #ifdef HAVE_SYS_PARAM_H
00037
00038 #include <sys/param.h>
00039 #endif
00040 #include <resolv.h>
00041 #include <sys/utsname.h>
00042
00043 #include <QtCore/QTimer>
00044
00045 #include <klocale.h>
00046 #include <kurl.h>
00047 #include <kstandarddirs.h>
00048 #include <kprocess.h>
00049 #include "discovery.moc"
00050
00051 namespace KPAC
00052 {
00053 Discovery::Discovery( QObject* parent )
00054 : Downloader( parent ),
00055 m_helper( new KProcess(this) )
00056 {
00057 connect( m_helper, SIGNAL( readyReadStandardOutput() ), SLOT( helperOutput() ) );
00058 connect( m_helper, SIGNAL( finished( int, QProcess::ExitStatus ) ), SLOT( failed() ) );
00059 *m_helper << KStandardDirs::findExe("kpac_dhcp_helper");
00060 m_helper->start();
00061 if ( !m_helper->waitForStarted() )
00062 QTimer::singleShot( 0, this, SLOT( failed() ) );
00063 }
00064
00065 bool Discovery::initHostName()
00066 {
00067 struct utsname uts;
00068
00069 if (uname (&uts) > -1)
00070 {
00071 struct hostent *hent = gethostbyname (uts.nodename);
00072 if (hent != 0)
00073 m_hostname = QString::fromLocal8Bit( hent->h_name );
00074 }
00075
00076
00077 if (m_hostname.isEmpty())
00078 {
00079 char buf [256];
00080 if (gethostname (buf, sizeof(buf)) == 0)
00081 {
00082 buf[255] = '\0';
00083 m_hostname = QString::fromLocal8Bit( buf );
00084 }
00085 }
00086 return !m_hostname.isEmpty();
00087 }
00088
00089 bool Discovery::checkDomain() const
00090 {
00091
00092
00093
00094 union
00095 {
00096 HEADER header;
00097 unsigned char buf[ PACKETSZ ];
00098 } response;
00099 int len = res_query( m_hostname.toLocal8Bit(), C_IN, T_SOA,
00100 response.buf, sizeof( response.buf ) );
00101 if ( len <= int( sizeof( response.header ) ) ||
00102 ntohs( response.header.ancount ) != 1 ) return true;
00103 unsigned char* pos = response.buf + sizeof( response.header );
00104 unsigned char* end = response.buf + len;
00105
00106 pos += dn_skipname( pos, end ) + QFIXEDSZ;
00107 if ( pos >= end ) return true;
00108
00109 pos += dn_skipname( pos, end );
00110 short type;
00111 GETSHORT( type, pos );
00112 return type != T_SOA;
00113 }
00114
00115 void Discovery::failed()
00116 {
00117 setError( i18n( "Could not find a usable proxy configuration script" ) );
00118
00119
00120
00121
00122 bool firstQuery = m_hostname.isEmpty();
00123 if ( ( firstQuery && !initHostName() ) ||
00124 ( !firstQuery && !checkDomain() ) )
00125 {
00126 emit result( false );
00127 return;
00128 }
00129
00130 int dot = m_hostname.indexOf( '.' );
00131 if ( dot >= 0 )
00132 {
00133 m_hostname.remove( 0, dot + 1 );
00134 download( KUrl( "http://wpad." + m_hostname + "./wpad.dat" ) );
00135 }
00136 else emit result( false );
00137 }
00138
00139 void Discovery::helperOutput()
00140 {
00141 m_helper->disconnect( this );
00142 QString line;
00143 line = QString::fromLocal8Bit( m_helper->readLine() );
00144 download( KUrl( line.trimmed() ) );
00145 }
00146 }
00147
00148