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