X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a0b4c98b8aed2e0006d75adc158f526018650dba..6474416b2ec2a63ebc28548733d93bbe5aded70d:/src/unix/dialup.cpp?ds=sidebyside diff --git a/src/unix/dialup.cpp b/src/unix/dialup.cpp index 55b6355bdb..fb16e317bb 100644 --- a/src/unix/dialup.cpp +++ b/src/unix/dialup.cpp @@ -11,6 +11,10 @@ #include "wx/setup.h" +#ifdef __GNUG__ +# pragma implementation "dialup.h" +#endif + #if wxUSE_DIALUP_MANAGER #ifndef WX_PRECOMP @@ -19,11 +23,16 @@ #include "wx/string.h" #include "wx/event.h" -#include "wx/net.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/process.h" +#include "wx/intl.h" +#include "wx/app.h" +#include "wx/wxchar.h" #include @@ -62,14 +71,8 @@ class WXDLLEXPORT wxDialUpManagerImpl : public wxDialUpManager { public: - wxDialUpManagerImpl() - { - m_IsOnline = -1; // unknown - m_timer = NULL; - m_CanUseIfconfig = -1; // unknown - m_BeaconHost = WXDIALUP_MANAGER_DEFAULT_BEACONHOST; - m_BeaconPort = 80; - } + wxDialUpManagerImpl(); + ~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 @@ -101,12 +104,29 @@ public: virtual bool IsOnline() const { if( (! m_timer) // we are not polling, so test now: - || m_IsOnline == -1 + || m_IsOnline < 0 ) CheckStatus(); return m_IsOnline != 0; } + /// 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 + { return m_DialProcess != NULL; } + + // cancel dialing the number initiated with Dial(async = TRUE) + // NB: this won't result in DISCONNECTED event being sent + virtual bool CancelDialing(); + + size_t GetISPNames(class wxArrayString &) const + { return 0; } + // sometimes the built-in logic for determining the online status may fail, // so, in general, the user should be allowed to override it. This function // allows to forcefully set the online status - whatever our internal @@ -163,10 +183,16 @@ private: wxString m_ISPname; /// a timer for regular testing class AutoCheckTimer *m_timer; - friend class AutoCheckTimer; + + /// a wxProcess for dialling in background + class wxDialProcess *m_DialProcess; + /// pid of dial process + int m_DialPId; + friend class wxDialProcess; + /// determine status - void CheckStatus(void) const; + void CheckStatus(bool fromAsync = FALSE) const; /// real status check void CheckStatusInternal(void); @@ -186,7 +212,7 @@ public: { m_started = TRUE; return wxTimer::Start(millisecs, FALSE); } virtual void Notify() - { wxLogTrace("Checking dial up network status."); m_dupman->CheckStatus(); } + { wxLogTrace(wxT("Checking dial up network status.")); m_dupman->CheckStatus(); } virtual void Stop() { if ( m_started ) wxTimer::Stop(); } @@ -195,6 +221,55 @@ public: wxDialUpManagerImpl *m_dupman; }; +class wxDialProcess : public wxProcess +{ +public: + wxDialProcess(wxDialUpManagerImpl *dupman) + { + m_DupMan = dupman; + } + void Disconnect(void) { m_DupMan = NULL; } + void OnTerminate(int WXUNUSED(pid), int WXUNUSED(status)) const + { + if(m_DupMan) + { + m_DupMan->m_DialProcess = NULL; + m_DupMan->CheckStatus(TRUE); + } + } +private: + wxDialUpManagerImpl *m_DupMan; +}; + + +wxDialUpManagerImpl::wxDialUpManagerImpl() +{ + m_IsOnline = -2; // -1 or -2, unknown + m_DialProcess = NULL; + m_timer = NULL; + m_CanUseIfconfig = -1; // unknown + m_BeaconHost = WXDIALUP_MANAGER_DEFAULT_BEACONHOST; + m_BeaconPort = 80; + SetConnectCommand("pon", "poff"); // default values for Debian/GNU linux +#if 0 + wxChar * dial = wxGetenv(_T("WXDIALUP_DIALCMD")); + wxChar * hup = wxGetenv(_T("WXDIALUP_HUPCMD")); + if(dial || hup) + SetConnectCommand(dial ? wxString(dial) : m_ConnectCommand, + hup ? wxString(hup) : m_HangUpCommand); +#endif +} + +wxDialUpManagerImpl::~wxDialUpManagerImpl() +{ + if(m_timer) delete m_timer; + if(m_DialProcess) + { + m_DialProcess->Disconnect(); + m_DialProcess->Detach(); + } +} + bool wxDialUpManagerImpl::Dial(const wxString &isp, const wxString & WXUNUSED(username), @@ -206,19 +281,26 @@ wxDialUpManagerImpl::Dial(const wxString &isp, m_IsOnline = -1; m_ISPname = isp; wxString cmd; - if(m_ConnectCommand.Find("%s")) + if(m_ConnectCommand.Find(wxT("%s"))) cmd.Printf(m_ConnectCommand,m_ISPname.c_str()); else cmd = m_ConnectCommand; if ( async ) { - wxFAIL_MSG(_T("TODO")); + 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; - } } bool @@ -226,20 +308,33 @@ wxDialUpManagerImpl::HangUp(void) { if(m_IsOnline == 0) return FALSE; + if(IsDialing()) + { + wxLogError(_("Already dialling ISP.")); + return FALSE; + } m_IsOnline = -1; wxString cmd; - if(m_HangUpCommand.Find("%s")) - cmd.Printf(m_HangUpCommand,m_ISPname.c_str()); + 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() +{ + if(! IsDialing()) + return FALSE; + return kill(m_DialPId, SIGTERM) > 0; +} + bool wxDialUpManagerImpl::EnableAutoCheckOnlineStatus(size_t nSeconds) { - wxASSERT(m_timer == NULL); + DisableAutoCheckOnlineStatus(); m_timer = new AutoCheckTimer(this); bool rc = m_timer->Start(nSeconds*1000); if(! rc) @@ -253,10 +348,12 @@ wxDialUpManagerImpl::EnableAutoCheckOnlineStatus(size_t nSeconds) void wxDialUpManagerImpl::DisableAutoCheckOnlineStatus() { - wxASSERT(m_timer != NULL); - m_timer->Stop(); - delete m_timer; - m_timer = NULL; + if(m_timer != NULL) + { + m_timer->Stop(); + delete m_timer; + m_timer = NULL; + } } @@ -264,11 +361,11 @@ void wxDialUpManagerImpl::SetWellKnownHost(const wxString& hostname, int portno) { /// does hostname contain a port number? - wxString port = hostname.After(':'); + wxString port = hostname.After(wxT(':')); if(port.Length()) { - m_BeaconHost = hostname.Before(':'); - m_BeaconPort = atoi(port); + m_BeaconHost = hostname.Before(wxT(':')); + m_BeaconPort = wxAtoi(port); } else { @@ -279,7 +376,7 @@ wxDialUpManagerImpl::SetWellKnownHost(const wxString& hostname, int portno) void -wxDialUpManagerImpl::CheckStatus(void) const +wxDialUpManagerImpl::CheckStatus(bool fromAsync) const { // This function calls the CheckStatusInternal() helper function // which is OS - specific and then sends the events. @@ -288,12 +385,10 @@ wxDialUpManagerImpl::CheckStatus(void) const ( /* non-const */ (wxDialUpManagerImpl *)this)->CheckStatusInternal(); // now send the events as appropriate: - if(m_IsOnline != oldIsOnline) + if(m_IsOnline != oldIsOnline && m_IsOnline != -1 && oldIsOnline != -2) // -2: first time! { - if(m_IsOnline) - ; // send ev - else - ; // send ev + wxDialUpEvent event(m_IsOnline, ! fromAsync); + (void)wxTheApp->ProcessEvent(event); } } @@ -325,63 +420,99 @@ wxDialUpManagerImpl::CheckStatusInternal(void) m_IfconfigPath = "/usr/sbin/ifconfig"; } + 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()); wxString tmpfile = wxGetTempFileName("_wxdialuptest"); - wxString cmd = m_IfconfigPath; - cmd << " >" << tmpfile; - if(wxExecute(m_IfconfigPath,TRUE /* sync */) == 0) + wxString cmd = "/bin/sh -c \'"; + cmd << m_IfconfigPath << " >" << 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; - wxString cmd1 = "grep ppp <"+tmpfile; // PPP - wxString cmd2 = "grep sl <"+tmpfile; // SLIP - wxString cmd3 = "grep pl <"+tmpfile; // PLIP - if(wxExecute(cmd1,TRUE) == 0 - || wxExecute(cmd2,TRUE) == 0 - || wxExecute(cmd3,TRUE) == 0 - ) - m_IsOnline = 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()) + { + if(strstr(output,"ppp") // ppp + || strstr(output,"sl") // slip + || strstr(output,"pl") // plip + ) + m_IsOnline = 1; + else + m_IsOnline = 0; + } + file.Close(); + delete [] output; + } + // else m_IsOnline remains -1 as we don't know for sure } else // could not run ifconfig correctly m_CanUseIfconfig = 0; // don´t try again - wxRemoveFile(tmpfile); + (void) wxRemoveFile(tmpfile); if(m_IsOnline != -1) // we are done return; } - // second method: try to connect to well known host: + // this was supposed to work like ping(8), but doesn´t. + // second method: try to connect to a well known host: + // This can be used under Win 9x, too! struct hostent *hp; struct sockaddr_in serv_addr; - int sockfd; m_IsOnline = 0; // assume false - if((hp = gethostbyname(m_BeaconHost)) == NULL) + if((hp = gethostbyname(m_BeaconHost.mb_str())) == NULL) return; // no DNS no net - - serv_addr.sin_family = hp->h_addrtype; + + serv_addr.sin_family = hp->h_addrtype; memcpy(&serv_addr.sin_addr,hp->h_addr, hp->h_length); - serv_addr.sin_port = htons(m_BeaconPort); - if( ( sockfd = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) - { + serv_addr.sin_port = htons(m_BeaconPort); + + // PING method: + + int sockfd; + if( ( sockfd = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) + { // sys_error("cannot create socket for gw"); return; } + +#if 0 + // this "ping" method does not work. + if(sendto(sockfd, "hello", + strlen("hello"), /* flags */ 0, + (struct sockaddr *) &serv_addr, + sizeof(serv_addr)) == -1) + { + close(sockfd); + return; + } +#endif + if( connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { //sys_error("cannot connect to server"); + close(sockfd); return; } //connected! close(sockfd); + m_IsOnline = TRUE; } /* static */ wxDialUpManager * -wxDialUpManager::wxDialUpManager::Create(void) +wxDialUpManager::Create(void) { return new wxDialUpManagerImpl; }