X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a0b4c98b8aed2e0006d75adc158f526018650dba..2131a664df3b033d513f0810de38c893f183dbe4:/src/unix/dialup.cpp?ds=sidebyside diff --git a/src/unix/dialup.cpp b/src/unix/dialup.cpp index 55b6355bdb..4985bd9ef7 100644 --- a/src/unix/dialup.cpp +++ b/src/unix/dialup.cpp @@ -19,11 +19,15 @@ #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 @@ -62,15 +66,9 @@ 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 to call this function and check its result before calling any other @@ -107,6 +105,14 @@ public: return m_IsOnline != 0; } + /// returns TRUE if (async) dialing is in progress + inline virtual bool IsDialling() 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(); + // 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 +169,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); @@ -195,6 +207,39 @@ public: wxDialUpManagerImpl *m_dupman; }; +class wxDialProcess : public wxProcess +{ +public: + wxDialProcess(wxDialUpManagerImpl *dupman) + { + m_DupMan = dupman; + } + void OnTerminate(int pid, int status) const + { + m_DupMan->m_DialProcess = NULL; + m_DupMan->CheckStatus(TRUE); + } +private: + wxDialUpManagerImpl *m_DupMan; +}; + + +wxDialUpManagerImpl::wxDialUpManagerImpl() +{ + m_IsOnline = -1; // unknown + m_DialProcess = NULL; + m_timer = NULL; + m_CanUseIfconfig = -1; // unknown + m_BeaconHost = WXDIALUP_MANAGER_DEFAULT_BEACONHOST; + m_BeaconPort = 80; +} + +wxDialUpManagerImpl::~wxDialUpManagerImpl() +{ + if(m_timer) delete m_timer; + if(m_DialProcess) m_DialProcess->Detach(); +} + bool wxDialUpManagerImpl::Dial(const wxString &isp, const wxString & WXUNUSED(username), @@ -213,12 +258,19 @@ wxDialUpManagerImpl::Dial(const wxString &isp, 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,16 +278,29 @@ wxDialUpManagerImpl::HangUp(void) { if(m_IsOnline == 0) return FALSE; + if(IsDialling()) + { + wxLogError(_("Already dialling ISP.")); + return FALSE; + } m_IsOnline = -1; wxString cmd; if(m_HangUpCommand.Find("%s")) - cmd.Printf(m_HangUpCommand,m_ISPname.c_str()); + cmd.Printf(m_HangUpCommand,m_ISPname.c_str(), m_DialProcess); else cmd = m_HangUpCommand; return wxExecute(cmd, /* sync */ TRUE) == 0; } +bool +wxDialUpManagerImpl::CancelDialing() +{ + if(! IsDialling()) + return FALSE; + return kill(m_DialPId, SIGTERM) > 0; +} + bool wxDialUpManagerImpl::EnableAutoCheckOnlineStatus(size_t nSeconds) { @@ -279,7 +344,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. @@ -290,10 +355,8 @@ wxDialUpManagerImpl::CheckStatus(void) const // now send the events as appropriate: if(m_IsOnline != oldIsOnline) { - if(m_IsOnline) - ; // send ev - else - ; // send ev + wxDialUpEvent event(m_IsOnline, ! fromAsync); + (void)wxTheApp->ProcessEvent(event); } } @@ -325,52 +388,93 @@ 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 0 + // temporarily redirect stdout/stderr: + int + new_stdout = dup(STDOUT_FILENO), + new_stderr = dup(STDERR_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + + int + // new stdout: + output_fd = open(tmpfile, O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR), + // new stderr: + null_fd = open("/dev/null", O_CREAT, S_IRUSR|S_IWUSR); + // verify well behaved unix behaviour: + wxASSERT(output_fd == STDOUT_FILENO); + wxASSERT(null_fd == STDERR_FILENO); + int rc = wxExecute(m_IfconfigPath,TRUE /* sync */,NULL ,wxEXECUTE_DONT_CLOSE_FDS); + close(null_fd); close(output_fd); + // restore old stdout, stderr: + int test; + test = dup(new_stdout); close(new_stdout); wxASSERT(test == STDOUT_FILENO); + test = dup(new_stderr); close(new_stderr); wxASSERT(test == STDERR_FILENO); + if(rc == 0) +#endif + 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 can be used under Win 9x, too! struct hostent *hp; struct sockaddr_in serv_addr; - int sockfd; + int sockfd; m_IsOnline = 0; // assume false if((hp = gethostbyname(m_BeaconHost)) == 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); + if( ( sockfd = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) + { // sys_error("cannot create socket for gw"); return; } if( connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) - { + { //sys_error("cannot connect to server"); return; }