-// -*- c++ -*- ///////////////////////////////////////////////////////////////
-// Name: unix/dialup.cpp
-// Purpose: Network related wxWindows classes and functions
-// Author: Karsten Ballüder
+// -*- c++ -*- ////////////////////////////////////////////////////////////////
+// Name: src/unix/dialup.cpp
+// Purpose: Network related wxWidgets classes and functions
+// Author: Karsten Ballüder
// Modified by:
// Created: 03.10.99
// RCS-ID: $Id$
-// Copyright: (c) Karsten Ballüder
+// Copyright: (c) Karsten Ballüder
// Licence: wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
-#include "wx/setup.h"
-
-#ifdef __GNUG__
-# pragma implementation "dialup.h"
-#endif
+// for compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
#if wxUSE_DIALUP_MANAGER
+#include "wx/dialup.h"
+
#ifndef WX_PRECOMP
-# include "wx/defs.h"
+ #include "wx/string.h"
+ #include "wx/intl.h"
+ #include "wx/log.h"
+ #include "wx/event.h"
+ #include "wx/app.h"
+ #include "wx/utils.h"
+ #include "wx/timer.h"
#endif // !PCH
-#include "wx/string.h"
-#include "wx/event.h"
-#include "wx/dialup.h"
-#include "wx/timer.h"
-#include "wx/filefn.h"
-#include "wx/utils.h"
-#include "wx/log.h"
-#include "wx/file.h"
+#include "wx/filename.h"
+#include "wx/ffile.h"
#include "wx/process.h"
-#include "wx/intl.h"
-#include "wx/app.h"
-#include "wx/wxchar.h"
+#include "wx/crt.h"
#include <stdlib.h>
#include <arpa/inet.h>
#include <errno.h>
+wxDEFINE_EVENT( wxEVT_DIALUP_CONNECTED, wxDialUpEvent );
+wxDEFINE_EVENT( wxEVT_DIALUP_DISCONNECTED, wxDialUpEvent );
+
// ----------------------------------------------------------------------------
// A class which groups functions dealing with connecting to the network from a
// workstation using dial-up access to the net. There is at most one instance
{
public:
wxDialUpManagerImpl();
- ~wxDialUpManagerImpl();
+ virtual ~wxDialUpManagerImpl();
/** Could the dialup manager be initialized correctly? If this function
- returns FALSE, no other functions will work neither, so it's a good idea
+ returns false, no other functions will work neither, so it's a good idea
to call this function and check its result before calling any other
wxDialUpManager methods.
*/
virtual bool IsOk() const
- { return TRUE; }
+ { return true; }
/** The simplest way to initiate a dial up: this function dials the given
ISP (exact meaning of the parameter depends on the platform), returns
- TRUE on success or FALSE on failure and logs the appropriate error
+ true on success or false on failure and logs the appropriate error
message in the latter case.
@param nameOfISP optional paramater for dial program
@param username unused
const wxString& WXUNUSED(password),
bool async);
- /// Hang up the currently active dial up connection.
+ // Hang up the currently active dial up connection.
virtual bool HangUp();
- // returns TRUE if the computer is connected to the network: under Windows,
+ // returns true if the computer is connected to the network: under Windows,
// this just means that a RAS connection exists, under Unix we check that
// the "well-known host" (as specified by SetWellKnownHost) is reachable
virtual bool IsOnline() const
{
- if( (! m_timer) // we are not polling, so test now:
- || m_IsOnline < 0
- )
- CheckStatus();
- return m_IsOnline != 0;
+ CheckStatus();
+ return m_IsOnline == Net_Connected;
}
- /// do we have a constant net connection? -- GUESS!
- bool IsAlwaysOnline() const
- {
- ((wxDialUpManagerImpl *) this)->HangUp(); // brutal but necessary
- return IsOnline();
- }
- /// returns TRUE if (async) dialing is in progress
- inline virtual bool IsDialing() const
+ // do we have a constant net connection?
+ virtual bool IsAlwaysOnline() const;
+
+ // returns true if (async) dialing is in progress
+ virtual bool IsDialing() const
{ return m_DialProcess != NULL; }
- // cancel dialing the number initiated with Dial(async = TRUE)
+ // cancel dialing the number initiated with Dial(async = true)
// NB: this won't result in DISCONNECTED event being sent
virtual bool CancelDialing();
// so, in general, the user should be allowed to override it. This function
// allows to forcefully set the online status - whatever our internal
// algorithm may think about it.
- virtual void SetOnlineStatus(bool isOnline = TRUE)
- { m_IsOnline = isOnline; }
+ virtual void SetOnlineStatus(bool isOnline = true)
+ { m_IsOnline = isOnline ? Net_Connected : Net_No; }
// set misc wxDialUpManager options
// --------------------------------
// Windows, the notification about the change of connection status is
// instantenous.
//
- // Returns FALSE if couldn't set up automatic check for online status.
+ // Returns false if couldn't set up automatic check for online status.
virtual bool EnableAutoCheckOnlineStatus(size_t nSeconds);
// disable automatic check for connection status change - notice that the
virtual void SetConnectCommand(const wxString &command, const wxString &hupcmd)
{ m_ConnectCommand = command; m_HangUpCommand = hupcmd; }
+//private: -- Sun CC 4.2 objects to using NetConnection enum as the return
+// type if it is declared private
+
+ // the possible results of testing for Online() status
+ enum NetConnection
+ {
+ Net_Unknown = -1, // we couldn't learn anything
+ Net_No, // no network connection [currently]
+ Net_Connected // currently connected
+ };
+
+ // the possible net connection types
+ enum NetDeviceType
+ {
+ NetDevice_None = 0x0000, // no network devices (authoritative)
+ NetDevice_Unknown = 0x0001, // test doesn't work on this OS
+ NetDevice_Modem = 0x0002, // we have a modem
+ NetDevice_LAN = 0x0004 // a network card
+ };
+
private:
- /// -1: don´t know, 0 = no, 1 = yes
- int m_IsOnline;
+ // the current status
+ NetConnection m_IsOnline;
+
+ // the connection we have with the network card
+ NetConnection m_connCard;
- /// Can we use ifconfig to list active devices?
+ // Can we use ifconfig to list active devices?
int m_CanUseIfconfig;
- /// The path to ifconfig
+
+ // The path to ifconfig
wxString m_IfconfigPath;
- /// Can we use ping to find hosts?
+ // Can we use ping to find hosts?
int m_CanUsePing;
- /// The path to ping program
+ // The path to ping program
wxString m_PingPath;
- /// beacon host:
+ // beacon host:
wxString m_BeaconHost;
- /// beacon host portnumber for connect:
+ // beacon host portnumber for connect:
int m_BeaconPort;
- /// command to connect to network
+ // command to connect to network
wxString m_ConnectCommand;
- /// command to hang up
+ // command to hang up
wxString m_HangUpCommand;
- /// name of ISP
+ // name of ISP
wxString m_ISPname;
- /// a timer for regular testing
+ // a timer for regular testing
class AutoCheckTimer *m_timer;
friend class AutoCheckTimer;
- /// a wxProcess for dialling in background
+ // a wxProcess for dialling in background
class wxDialProcess *m_DialProcess;
- /// pid of dial process
+ // pid of dial process
int m_DialPId;
friend class wxDialProcess;
- /// determine status
- void CheckStatus(bool fromAsync = FALSE) const;
+ // determine status
+ void CheckStatus(bool fromAsync = false) const;
+
+ // real status check
+ void CheckStatusInternal();
+
+ // check /proc/net (Linux only) for ppp/eth interfaces, returns the bit
+ // mask of NetDeviceType constants
+ int CheckProcNet();
- /// real status check
- void CheckStatusInternal(void);
+ // check output of ifconfig command for PPP/SLIP/PLIP devices, returns the
+ // bit mask of NetDeviceType constants
+ int CheckIfconfig();
- /// Check output of ifconfig command for PPP/SLIP/PLIP devices
- int CheckIfconfig(void);
- /// Ping a host: 1 on success, -1 if it cannot be used, 0 if unreachable
- int CheckPing(void);
- /// Check by connecting to host on given port.
- int CheckConnect(void);
+ // combines the 2 possible checks for determining the connection status
+ NetConnection CheckConnectAndPing();
+ // pings a host
+ NetConnection CheckPing();
+
+ // check by connecting to host on given port.
+ NetConnection CheckConnect();
};
{
public:
AutoCheckTimer(wxDialUpManagerImpl *dupman)
- {
- m_dupman = dupman;
- m_started = FALSE;
- }
-
- virtual bool Start( int millisecs = -1, bool WXUNUSED(one_shot) = FALSE )
- { m_started = TRUE; return wxTimer::Start(millisecs, FALSE); }
+ {
+ m_dupman = dupman;
+ }
virtual void Notify()
- { wxLogTrace(wxT("Checking dial up network status.")); m_dupman->CheckStatus(); }
+ {
+ wxLogTrace(wxT("dialup"), wxT("Checking dial up network status."));
+
+ m_dupman->CheckStatus();
+ }
- virtual void Stop()
- { if ( m_started ) wxTimer::Stop(); }
public:
- bool m_started;
wxDialUpManagerImpl *m_dupman;
};
{
m_DupMan = dupman;
}
- void Disconnect(void) { m_DupMan = NULL; }
+ void Disconnect() { m_DupMan = NULL; }
virtual void OnTerminate(int WXUNUSED(pid), int WXUNUSED(status))
{
if(m_DupMan)
{
m_DupMan->m_DialProcess = NULL;
- m_DupMan->CheckStatus(TRUE);
+ m_DupMan->CheckStatus(true);
}
}
private:
wxDialUpManagerImpl::wxDialUpManagerImpl()
{
- /* The isOnline flag can have the following values internally:
- 0 : not connected
- 1 : connected
- -1 : unknown/undefined status
- */
- m_IsOnline = -1;
+ m_IsOnline =
+ m_connCard = Net_Unknown;
m_DialProcess = NULL;
m_timer = NULL;
m_CanUseIfconfig = -1; // unknown
m_BeaconPort = 80;
#ifdef __SGI__
- m_ConnectCommand = _T("/usr/etc/ppp");
+ m_ConnectCommand = wxT("/usr/etc/ppp");
#elif defined(__LINUX__)
// default values for Debian/GNU linux
- m_ConnectCommand = _T("pon");
- m_HangUpCommand = _T("poff");
+ m_ConnectCommand = wxT("pon");
+ m_HangUpCommand = wxT("poff");
#endif
- wxChar * dial = wxGetenv(_T("WXDIALUP_DIALCMD"));
- wxChar * hup = wxGetenv(_T("WXDIALUP_HUPCMD"));
+ wxChar * dial = wxGetenv(wxT("WXDIALUP_DIALCMD"));
+ wxChar * hup = wxGetenv(wxT("WXDIALUP_HUPCMD"));
SetConnectCommand(dial ? wxString(dial) : m_ConnectCommand,
hup ? wxString(hup) : m_HangUpCommand);
}
const wxString & WXUNUSED(password),
bool async)
{
- if(m_IsOnline == 1)
- return FALSE;
- m_ISPname = isp;
- wxString cmd;
- if(m_ConnectCommand.Find(wxT("%s")))
- cmd.Printf(m_ConnectCommand,m_ISPname.c_str());
- else
- cmd = m_ConnectCommand;
-
- if ( async )
- {
- m_DialProcess = new wxDialProcess(this);
- m_DialPId = wxExecute(cmd, FALSE, m_DialProcess);
- if(m_DialPId == 0)
- {
- delete m_DialProcess;
- m_DialProcess = NULL;
- return FALSE;
- }
- else
- return TRUE;
- }
- else
- return wxExecute(cmd, /* sync */ TRUE) == 0;
+ if(m_IsOnline == Net_Connected)
+ return false;
+ m_ISPname = isp;
+ wxString cmd;
+ if(m_ConnectCommand.Find(wxT("%s")))
+ cmd.Printf(m_ConnectCommand,m_ISPname.c_str());
+ else
+ cmd = m_ConnectCommand;
+
+ if ( async )
+ {
+ m_DialProcess = new wxDialProcess(this);
+ m_DialPId = (int)wxExecute(cmd, false, m_DialProcess);
+ if(m_DialPId == 0)
+ {
+ wxDELETE(m_DialProcess);
+ return false;
+ }
+ else
+ return true;
+ }
+ else
+ return wxExecute(cmd, /* sync */ true) == 0;
}
-bool
-wxDialUpManagerImpl::HangUp(void)
+bool wxDialUpManagerImpl::HangUp()
{
- if(m_IsOnline == 0)
- return FALSE;
- if(IsDialing())
- {
- wxLogError(_("Already dialling ISP."));
- return FALSE;
- }
- wxString cmd;
- if(m_HangUpCommand.Find(wxT("%s")))
- cmd.Printf(m_HangUpCommand,m_ISPname.c_str(), m_DialProcess);
- else
- cmd = m_HangUpCommand;
- return wxExecute(cmd, /* sync */ TRUE) == 0;
+ if(m_IsOnline == Net_No)
+ return false;
+ if(IsDialing())
+ {
+ wxLogError(_("Already dialling ISP."));
+ return false;
+ }
+ wxString cmd;
+ if(m_HangUpCommand.Find(wxT("%s")))
+ cmd.Printf(m_HangUpCommand,m_ISPname.c_str(), m_DialProcess);
+ else
+ cmd = m_HangUpCommand;
+ return wxExecute(cmd, /* sync */ true) == 0;
}
-bool
-wxDialUpManagerImpl::CancelDialing()
+bool wxDialUpManagerImpl::CancelDialing()
{
if(! IsDialing())
- return FALSE;
+ return false;
return kill(m_DialPId, SIGTERM) > 0;
}
-bool
-wxDialUpManagerImpl::EnableAutoCheckOnlineStatus(size_t nSeconds)
+bool wxDialUpManagerImpl::EnableAutoCheckOnlineStatus(size_t nSeconds)
{
DisableAutoCheckOnlineStatus();
m_timer = new AutoCheckTimer(this);
bool rc = m_timer->Start(nSeconds*1000);
if(! rc)
{
- delete m_timer;
- m_timer = NULL;
+ wxDELETE(m_timer);
}
return rc;
}
-void
-wxDialUpManagerImpl::DisableAutoCheckOnlineStatus()
+void wxDialUpManagerImpl::DisableAutoCheckOnlineStatus()
{
if(m_timer != NULL)
{
m_timer->Stop();
- delete m_timer;
- m_timer = NULL;
+ wxDELETE(m_timer);
}
}
-void
-wxDialUpManagerImpl::SetWellKnownHost(const wxString& hostname, int portno)
+void wxDialUpManagerImpl::SetWellKnownHost(const wxString& hostname, int portno)
{
- /// does hostname contain a port number?
+ if( hostname.empty() )
+ {
+ m_BeaconHost = WXDIALUP_MANAGER_DEFAULT_BEACONHOST;
+ m_BeaconPort = 80;
+ return;
+ }
+
+ // does hostname contain a port number?
wxString port = hostname.After(wxT(':'));
- if(port.Length())
+ if( !port.empty() )
{
m_BeaconHost = hostname.Before(wxT(':'));
m_BeaconPort = wxAtoi(port);
}
-void
-wxDialUpManagerImpl::CheckStatus(bool fromAsync) const
+void wxDialUpManagerImpl::CheckStatus(bool fromAsync) const
{
- // This function calls the CheckStatusInternal() helper function
- // which is OS - specific and then sends the events.
-
- int oldIsOnline = m_IsOnline;
- ( /* non-const */ (wxDialUpManagerImpl *)this)->CheckStatusInternal();
-
- // now send the events as appropriate:
- if(m_IsOnline != oldIsOnline // it changed
- && ( m_IsOnline == 1 // and it is a defined status
- || m_IsOnline == 0)
- // only send events for well defined transitions
- && ( oldIsOnline == 1 || oldIsOnline == 0)
- )
- {
- wxDialUpEvent event(m_IsOnline, ! fromAsync);
- (void)wxTheApp->ProcessEvent(event);
- }
+ // This function calls the CheckStatusInternal() helper function
+ // which is OS - specific and then sends the events.
+
+ NetConnection oldIsOnline = m_IsOnline;
+ ( /* non-const */ (wxDialUpManagerImpl *)this)->CheckStatusInternal();
+
+ // now send the events as appropriate: i.e. if the status changed and
+ // if we're in defined state
+ if(m_IsOnline != oldIsOnline
+ && m_IsOnline != Net_Unknown
+ && oldIsOnline != Net_Unknown )
+ {
+ wxDialUpEvent event(m_IsOnline == Net_Connected, ! fromAsync);
+ (void)wxTheApp->ProcessEvent(event);
+ }
}
/*
- We have three methods that we can use:
+ We first try to find out if ppp interface is active. If it is, we assume
+ that we're online but don't have a permanent connection (this is false if a
+ networked machine uses modem to connect to somewhere else, but we can't do
+ anything in this case anyhow).
+
+ If no ppp interface is detected, we check for eth interface. If it is
+ found, we check that we can, indeed, connect to an Internet host. The logic
+ here is that connection check should be fast enough in this case and we
+ don't want to give false positives in a (common) case of a machine on a LAN
+ which is not connected to the outside.
+
+ If we didn't find either ppp or eth interfaces, we stop here and decide
+ that we're connected. However, if couldn't check for this, we try to ping a
+ remote host just in case.
- 1. test via /sbin/ifconfig and grep for "sl", "ppp", "pl"
- --> should be fast enough for regular polling
- 2. test if we can reach the well known beacon host
- --> too slow for polling
- 3. check /proc/net/dev on linux??
- This method should be preferred, if possible. Need to do more
- testing.
+ NB1: Checking for the interface presence can be done in 2 ways
+ a) reading /proc/net/dev under Linux
+ b) spawning ifconfig under any OS
+ The first method is faster but only works under Linux.
+
+ NB2: pinging, actually, means that we first try to connect "manually" to
+ a port on remove machine and if it fails, we run ping.
*/
-void
-wxDialUpManagerImpl::CheckStatusInternal(void)
+void wxDialUpManagerImpl::CheckStatusInternal()
+{
+ m_IsOnline = Net_Unknown;
+
+ // first do quick checks to determine what kind of network devices do we
+ // have
+ int netDeviceType = CheckProcNet();
+ if ( netDeviceType == NetDevice_Unknown )
+ {
+ // nothing found, try ifconfig too
+ netDeviceType = CheckIfconfig();
+ }
+
+ switch ( netDeviceType )
+ {
+ case NetDevice_None:
+ // no network devices, no connection
+ m_IsOnline = Net_No;
+ break;
+
+ case NetDevice_LAN:
+ // we still do ping to confirm that we're connected but we only do
+ // it once and hope that the purpose of the network card (i.e.
+ // whether it used for connecting to the Internet or just to a
+ // LAN) won't change during the program lifetime
+ if ( m_connCard == Net_Unknown )
+ {
+ m_connCard = CheckConnectAndPing();
+ }
+ m_IsOnline = m_connCard;
+ break;
+
+ case NetDevice_Unknown:
+ // try to ping just in case
+ m_IsOnline = CheckConnectAndPing();
+ break;
+
+ case NetDevice_LAN + NetDevice_Modem:
+ case NetDevice_Modem:
+ // assume we're connected
+ m_IsOnline = Net_Connected;
+ break;
+
+ default:
+ wxFAIL_MSG(wxT("Unexpected netDeviceType"));
+ }
+}
+
+bool wxDialUpManagerImpl::IsAlwaysOnline() const
{
- m_IsOnline = -1;
+ wxDialUpManagerImpl *self = wxConstCast(this, wxDialUpManagerImpl);
+
+ int netDeviceType = self->CheckProcNet();
+ if ( netDeviceType == NetDevice_Unknown )
+ {
+ // nothing found, try ifconfig too
+ netDeviceType = self->CheckIfconfig();
+ }
+
+ if ( netDeviceType == NetDevice_Unknown )
+ {
+ // this is the only thing we can do unfortunately...
+ self->HangUp();
+ return IsOnline();
+ }
+ else
+ {
+ // we are only permanently online if we have a network card
+ return (netDeviceType & NetDevice_LAN) != 0;
+ }
+}
+
+wxDialUpManagerImpl::NetConnection wxDialUpManagerImpl::CheckConnectAndPing()
+{
+ NetConnection conn;
- int testResult;
+ // first try connecting - faster
+ conn = CheckConnect();
+ if ( conn == Net_Unknown )
+ {
+ // try pinging too
+ conn = CheckPing();
+ }
- testResult = CheckConnect();
- if(testResult == -1)
- testResult = CheckIfconfig();
- if(testResult == -1)
- testResult = CheckPing();
- m_IsOnline = testResult;
+ return conn;
}
-int
-wxDialUpManagerImpl::CheckConnect(void)
+wxDialUpManagerImpl::NetConnection wxDialUpManagerImpl::CheckConnect()
{
// second method: try to connect to a well known host:
// This can be used under Win 9x, too!
struct sockaddr_in serv_addr;
if((hp = gethostbyname(m_BeaconHost.mb_str())) == NULL)
- return 0; // no DNS no net
+ return Net_No; // no DNS no net
serv_addr.sin_family = hp->h_addrtype;
memcpy(&serv_addr.sin_addr,hp->h_addr, hp->h_length);
int sockfd;
if( ( sockfd = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0)
{
- return -1; // no info
+ return Net_Unknown; // no info
}
if( connect(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) >= 0)
{
close(sockfd);
- return 1; // we cant connect, so we have a network!
+ return Net_Connected; // we can connect, so we have a network!
+ }
+ else // failed to connect
+ {
+#ifdef ENETUNREACH
+ if(errno == ENETUNREACH)
+ return Net_No; // network is unreachable
+ else
+#endif
+ return Net_Unknown; // connect failed, but don't know why
}
- //connected!
- close(sockfd);
- if(errno == ENETUNREACH)
- return 0; // network is unreachable
- // connect failed, but don't know why
- return -1;
}
+
int
-wxDialUpManagerImpl::CheckIfconfig(void)
+wxDialUpManagerImpl::CheckProcNet()
{
- int rc = -1;
+ // assume that the test doesn't work
+ int netDevice = NetDevice_Unknown;
+
+#ifdef __LINUX__
+ if (wxFileExists(wxT("/proc/net/route")))
+ {
+ // cannot use wxFile::Length because file doesn't support seeking, so
+ // use stdio directly
+ FILE *f = fopen("/proc/net/route", "rt");
+ if (f != NULL)
+ {
+ // now we know that we will find all devices we may have
+ netDevice = NetDevice_None;
+
+ char output[256];
+
+ while (fgets(output, 256, f) != NULL)
+ {
+ // Test for the known network interface names
+ if ( strstr(output, "eth")
+ || strstr(output, "wlan")
+ || strstr(output, "ath") )
+ {
+ netDevice |= NetDevice_LAN;
+ }
+ else if (strstr(output,"ppp") // ppp
+ || strstr(output,"sl") // slip
+ || strstr(output,"pl")) // plip
+ {
+ netDevice |= NetDevice_Modem;
+ }
+ }
- // First time check for ifconfig location. We only use the variant which
- // does not take arguments, a la GNU.
- if ( m_CanUseIfconfig == -1 ) // unknown
- {
- static const wxChar *ifconfigLocations[] =
- {
- _T("/sbin"), // Linux, FreeBSD
- _T("/usr/sbin"), // SunOS, Solaris, AIX, HP-UX
- _T("/usr/etc"), // IRIX
- };
-
- for ( size_t n = 0; n < WXSIZEOF(ifconfigLocations); n++ )
- {
- wxString path(ifconfigLocations[n]);
- path << _T("/ifconfig");
-
- if ( wxFileExists(path) )
- {
- m_IfconfigPath = path;
- break;
- }
- }
- }
+ fclose(f);
+ }
+ }
+#endif // __LINUX__
- wxLogNull ln; // suppress all error messages
- // Let´s try the ifconfig method first, should be fastest:
- if(m_CanUseIfconfig != 0) // unknown or yes
- {
- wxASSERT(m_IfconfigPath.length());
+ return netDevice;
+}
- wxString tmpfile = wxGetTempFileName("_wxdialuptest");
- wxString cmd = "/bin/sh -c \'";
- cmd << m_IfconfigPath;
-#if defined(__SOLARIS__) || defined (__SUNOS__)
- // need to add -a flag
- cmd << " -a";
-#elif defined(__LINUX__) || defined (__FREEBSD__) || defined(__SGI__)
- // nothing to be added to ifconfig
+
+int
+wxDialUpManagerImpl::CheckIfconfig()
+{
+#ifdef __VMS
+ m_CanUseIfconfig = 0;
+ return -1;
#else
-# pragma warning "No ifconfig information for this OS."
- m_CanUseIfconfig = 0;
- return -1;
+ // assume that the test doesn't work
+ int netDevice = NetDevice_Unknown;
+
+ // first time check for ifconfig location
+ if ( m_CanUseIfconfig == -1 ) // unknown
+ {
+ static const wxChar *const ifconfigLocations[] =
+ {
+ wxT("/sbin"), // Linux, FreeBSD, Darwin
+ wxT("/usr/sbin"), // SunOS, Solaris, AIX, HP-UX
+ wxT("/usr/etc"), // IRIX
+ wxT("/etc"), // AIX 5
+ };
+
+ for ( size_t n = 0; n < WXSIZEOF(ifconfigLocations); n++ )
+ {
+ wxString path(ifconfigLocations[n]);
+ path << wxT("/ifconfig");
+
+ if ( wxFileExists(path) )
+ {
+ m_IfconfigPath = path;
+ break;
+ }
+ }
+ }
+
+ if ( m_CanUseIfconfig != 0 ) // unknown or yes
+ {
+ wxLogNull ln; // suppress all error messages
+
+ wxASSERT_MSG( !m_IfconfigPath.empty(),
+ wxT("can't use ifconfig if it wasn't found") );
+
+ wxString tmpfile = wxFileName::CreateTempFileName( wxT("_wxdialuptest") );
+ wxString cmd = wxT("/bin/sh -c \'");
+ cmd << m_IfconfigPath;
+#if defined(__AIX__) || \
+ defined(__NETBSD__) || \
+ defined(__OSF__) || \
+ defined(__SOLARIS__) || defined (__SUNOS__)
+ // need to add -a flag
+ cmd << wxT(" -a");
+#elif defined(__LINUX__) || defined(__SGI__) || defined(__OPENBSD__)
+ // nothing to be added to ifconfig
+#elif defined(__FREEBSD__) || defined(__DARWIN__) || defined(__QNX__)
+ // add -l flag
+ cmd << wxT(" -l");
+#elif defined(__HPUX__)
+ // VZ: a wild guess (but without it, ifconfig fails completely)
+ cmd << wxT(" ppp0");
+#else
+ #if defined(__GNUG__)
+ #warning "No ifconfig information for this OS."
+ #else
+ #pragma warning "No ifconfig information for this OS."
+ #endif
+
+ m_CanUseIfconfig = 0;
+ return -1;
#endif
- cmd << " >" << tmpfile << '\'';
- /* I tried to add an option to wxExecute() to not close stdout,
- so we could let ifconfig write directly to the tmpfile, but
- this does not work. That should be faster, as it doesn´t call
- the shell first. I have no idea why. :-( (KB) */
- if(wxExecute(cmd,TRUE /* sync */) == 0)
- {
- m_CanUseIfconfig = 1;
- wxFile file;
- if( file.Open(tmpfile) )
- {
- char *output = new char [file.Length()+1];
- output[file.Length()] = '\0';
- if(file.Read(output,file.Length()) == file.Length())
+ cmd << wxT(" >") << tmpfile << wxT('\'');
+ /* I tried to add an option to wxExecute() to not close stdout,
+ so we could let ifconfig write directly to the tmpfile, but
+ this does not work. That should be faster, as it doesn't call
+ the shell first. I have no idea why. :-( (KB) */
+ if ( wxExecute(cmd,true /* sync */) == 0 )
+ {
+ m_CanUseIfconfig = 1;
+ wxFFile file;
+ if( file.Open(tmpfile) )
{
- // FIXME shouldn't we grep for "^ppp"? (VZ)
+ wxString output;
+ if ( file.ReadAll(&output) )
+ {
+ // FIXME shouldn't we grep for "^ppp"? (VZ)
+
+ bool hasModem = false,
+ hasLAN = false;
#if defined(__SOLARIS__) || defined (__SUNOS__)
- // dialup device under SunOS/Solaris
- rc = strstr(output,"ipdptp") != (char *)NULL;
-#elif defined(__LINUX__) || defined (__FREEBSD__)
- rc = strstr(output,"ppp") // ppp
- || strstr(output,"sl") // slip
- || strstr(output,"pl"); // plip
+ // dialup device under SunOS/Solaris
+ hasModem = strstr(output.fn_str(),"ipdptp") != NULL;
+ hasLAN = strstr(output.fn_str(), "hme") != NULL;
+#elif defined(__LINUX__) || defined (__FREEBSD__) || defined (__QNX__) || \
+ defined(__OPENBSD__)
+ hasModem = strstr(output.fn_str(),"ppp") // ppp
+ || strstr(output.fn_str(),"sl") // slip
+ || strstr(output.fn_str(),"pl"); // plip
+ hasLAN = strstr(output.fn_str(), "eth") != NULL;
#elif defined(__SGI__) // IRIX
- rc = strstr(output, "ppp"); // PPP
+ hasModem = strstr(output.fn_str(), "ppp") != NULL; // PPP
+#elif defined(__HPUX__)
+ // if could run ifconfig on interface, then it exists
+ hasModem = true;
#endif
+
+ netDevice = NetDevice_None;
+ if ( hasModem )
+ netDevice |= NetDevice_Modem;
+ if ( hasLAN )
+ netDevice |= NetDevice_LAN;
+ }
+ //else: error reading the file
}
- file.Close();
- delete [] output;
- }
- // else rc remains -1 as we don't know for sure
- }
- else // could not run ifconfig correctly
- m_CanUseIfconfig = 0; // don´t try again
- (void) wxRemoveFile(tmpfile);
- }
- return rc;
-}
+ //else: error opening the file
+ }
+ else // could not run ifconfig correctly
+ {
+ m_CanUseIfconfig = 0; // don't try again
+ }
-int
-wxDialUpManagerImpl::CheckPing(void)
-{
- if(! m_CanUsePing)
- return -1;
+ (void) wxRemoveFile(tmpfile);
+ }
- // First time check for ping location. We only use the variant
- // which does not take arguments, a la GNU.
- if(m_CanUsePing == -1) // unknown
- {
- if(wxFileExists("/bin/ping"))
- m_PingPath = "/bin/ping";
- else if(wxFileExists("/usr/sbin/ping"))
- m_PingPath = "/usr/sbin/ping";
- if(! m_PingPath)
- {
- m_CanUsePing = 0;
- return -1;
- }
- }
+ return netDevice;
+#endif
+}
- wxLogNull ln; // suppress all error messages
- wxASSERT(m_PingPath.length());
- wxString cmd;
- cmd << m_PingPath << ' ';
+wxDialUpManagerImpl::NetConnection wxDialUpManagerImpl::CheckPing()
+{
+ // First time check for ping location. We only use the variant
+ // which does not take arguments, a la GNU.
+ if(m_CanUsePing == -1) // unknown
+ {
+#ifdef __VMS
+ if (wxFileExists( wxT("SYS$SYSTEM:TCPIP$PING.EXE") ))
+ m_PingPath = wxT("$SYS$SYSTEM:TCPIP$PING");
+#elif defined(__AIX__)
+ m_PingPath = wxT("/etc/ping");
+#elif defined(__SGI__)
+ m_PingPath = wxT("/usr/etc/ping");
+#else
+ if (wxFileExists( wxT("/bin/ping") ))
+ m_PingPath = wxT("/bin/ping");
+ else if (wxFileExists( wxT("/usr/sbin/ping") ))
+ m_PingPath = wxT("/usr/sbin/ping");
+#endif
+ if (!m_PingPath)
+ {
+ m_CanUsePing = 0;
+ }
+ }
+
+ if(! m_CanUsePing)
+ {
+ // we didn't find ping
+ return Net_Unknown;
+ }
+
+ wxLogNull ln; // suppress all error messages
+ wxASSERT(m_PingPath.length());
+ wxString cmd;
+ cmd << m_PingPath << wxT(' ');
#if defined(__SOLARIS__) || defined (__SUNOS__)
- // nothing to add to ping command
-#elif defined(__LINUX__)
- cmd << "-c 1 "; // only ping once
+ // nothing to add to ping command
+#elif defined(__AIX__) || \
+ defined (__BSD__) || \
+ defined(__LINUX__) || \
+ defined(__OSF__) || \
+ defined(__SGI__) || \
+ defined(__VMS) || \
+ defined(__QNX__)
+ cmd << wxT("-c 1 "); // only ping once
+#elif defined(__HPUX__)
+ cmd << wxT("64 1 "); // only ping once (need also specify the packet size)
#else
-# pragma warning "No Ping information for this OS."
- m_CanUsePing = 0;
- return -1;
+ #if defined(__GNUG__)
+ #warning "No Ping information for this OS."
+ #else
+ #pragma warning "No Ping information for this OS."
+ #endif
+
+ m_CanUsePing = 0;
+ return Net_Unknown;
#endif
- cmd << m_BeaconHost;
- if(wxExecute(cmd, TRUE /* sync */) == 0)
- return 1;
- else
- return 0;
+ cmd << m_BeaconHost;
+ if(wxExecute(cmd, true /* sync */) == 0)
+ return Net_Connected;
+ else
+ return Net_No;
}
/* static */
-wxDialUpManager *
-wxDialUpManager::Create(void)
+wxDialUpManager *wxDialUpManager::Create()
{
return new wxDialUpManagerImpl;
}