mgsingletask.cpp
来自「一款LINUX下的下载软件」· C++ 代码 · 共 878 行 · 第 1/2 页
CPP
878 行
/***************************************************************************
* mgsingletask.cpp
*
* Thu Sep 7 19:46:43 2006
* Copyright 2006 liubin, China
* Email multiget@gmail.com
****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef WIN32
#include <winsock2.h>
#endif
#include "mgsingletask.h"
#include "mgfilemanager.h"
#include "mgurlparser.h"
#include "showtablewindow.h" //for ui feedback
#include "threadinfowindow.h"
#include "taskmanager.h" //for ui feedback
#include "mainframe.h"
#include "mgapp.h"
#include "mgftpants.h"
#include "mghttpants.h"
#include "mgftpinfo.h"
#include "mghttpinfo.h"
//#include "mgtaskinit.h"
#include "proants.h"
#include <string>
#define _MGSTR(s) wxGetApp().GetStr(s)
using namespace std;
extern void gfTaskLog( int ntaskid, std::string info, _MSGTYPE ntype, int ntime );
CMgSingleTask::CMgSingleTask(
CTaskManager* parent,
std::string url,
std::string savepath,
std::string savename,
int taskid,
int ants,
int retry,
int retrywait,
std::string refer
)
{
m_pFM = NULL;
for ( int i = 0;i < 10;i++ )
{
m_pAnts[ i ] = NULL;
}
m_pShowTableWin = NULL;
m_pThreadInfoWin = NULL;
m_pFtpInfo = NULL;
m_pHttpInfo = NULL;
m_pParent = parent;
m_nFileLen = -1;
m_nTaskID = taskid;
m_nRetry = retry;
m_nRetryWait = retrywait;
m_nError = 0;
m_bUI = false;
m_nMsgOutThreadId = 0;
m_nLastFinishByte = 0L;
m_sFilename = savename;
m_sUrl = url;
m_Refer = refer;
m_sSavePath = savepath;
m_nRunningAnts = 0;
m_nStatus = _TASK_RUNNING;
if ( ants < 0 )
m_nAnts = 1;
else if ( ants > 10 )
m_nAnts = 10;
else
m_nAnts = ants;
pthread_mutex_init ( &m_AntsMutex, NULL );
pthread_mutex_init ( &m_QuitMutex, NULL );
//socks proxy
m_bUseProxy = false;
m_ProxyPort = 0;
m_ProxyVersion = V5;
//HTTP proxy
m_bUseHttpProxy = false;
m_HttpProxyPort = 0;
//FTP proxy
m_bUseFtpProxy = false;
m_FtpProxyPort = 0;
m_bInitAlive = false;
m_InitThread = NULL; m_bInitAnts = false;
}
CMgSingleTask::~CMgSingleTask()
{
pthread_mutex_lock( &m_QuitMutex );
pthread_cancel( m_nInitThread );
pthread_join( m_nInitThread, NULL );
pthread_mutex_unlock( &m_QuitMutex );
if ( m_pFM != NULL )
m_pFM->Stop();
for ( int i = 0;i < 10;i++ )
{
if ( m_pAnts[ i ] != NULL )
{
delete m_pAnts[ i ];
m_pAnts[ i ] = NULL;
}
}
if ( m_pFM != NULL )
{
delete m_pFM;
m_pFM = NULL;
}
if ( m_pFtpInfo != NULL )
{
delete m_pFtpInfo;
m_pFtpInfo = NULL;
}
if ( m_pHttpInfo != NULL )
{
delete m_pHttpInfo;
m_pHttpInfo = NULL;
}
}
void CMgSingleTask::ThreadQuit( int tid )
{
pthread_mutex_lock( &m_AntsMutex );
--m_nRunningAnts;
if ( m_nRunningAnts <= 0 )
{
//get last filesize from fm,sometime can't get the size ahead
if ( m_pFM->IsTaskFinish( m_nFileLen ) )
FinishTask( _TASK_FINISH );
else
FinishTask( _TASK_ERROR );
}
pthread_mutex_unlock( &m_AntsMutex );
}
//swap to the init thread
void* CMgSingleTask::SwapInitThread( void* pthis )
{
((CMgSingleTask*)pthis)->InitThread();
return NULL;
}
void CMgSingleTask::FinishTask( _SINGLE_TASK_STATUS status )
{
m_nStatus = status;
LogError(); //记录一些日志,有利于查找问题
pthread_mutex_lock( &m_QuitMutex );
wxCommandEvent event( mgEVT_TASK_FINISH, m_nTaskID );
MainFrame *mainwin = ( MainFrame* ) ( wxGetApp().GetTopWindow() );
mainwin->AddPendingEvent( event );
//wxPostEvent( mainwin, event );
pthread_mutex_unlock( &m_QuitMutex );
}
void CMgSingleTask::InitThread()
{
OutMsg( -1, _MGSTR ( _S_SINGLETASK_JOBRUN ), MSG_INFO );
pthread_setcanceltype ( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
CUrlParser upar;
if ( !m_Refer.empty() )
upar.SetRefer( m_Refer );
int oldstate;
vector<string> cookie; //for http
again:
OutMsg( -1, _MGSTR ( _S_SINGLETASK_ANALYSISURL ), MSG_INFO );
if ( !upar.SetUrl( m_sUrl ) )
{
OutMsg( -1, _MGSTR ( _S_SINGLETASK_NOTSUPPORTURL ) + m_sUrl, MSG_ERROR );
FinishTask( _TASK_ERROR );
pthread_exit( 0 );
}
OutMsg( -1, _MGSTR ( _S_SINGLETASK_TASKURLOK ), MSG_INFO );
//任务参数
m_Server = upar.GetServer();
m_ServerPort = upar.GetPort();
m_Username = upar.GetUser();
m_Password = upar.GetPass();
m_EscFilePathName = upar.GetEscFilePathName(); //文件名
if ( upar.GetUrlType() == FTP_PROTOCOL ) //ftp
{
OutMsg( -1, _MGSTR( _S_SINGLETASK_URLISFTP ), MSG_INFO );
m_pFtpInfo = new CMgFtpInfo(
this,
m_sUrl,
m_nRetry,
m_nRetryWait,
-1
);
//set proxy here
if ( m_bUseProxy )
{
OutMsg( -1, _MGSTR ( _S_SINGLETASK_USESOCKSPROXY ), MSG_INFO );
m_pFtpInfo->SetProxy( m_Proxy, m_ProxyPort, m_ProxyUser, m_ProxyPass, m_ProxyVersion );
}
if ( m_bUseFtpProxy )
{
OutMsg( -1, _MGSTR ( _S_SINGLETASK_USEFTPPROXY ), MSG_INFO );
m_pFtpInfo->SetFtpProxy( m_FtpProxy, m_FtpProxyPort );
}
//go
if ( !m_pFtpInfo->GetInfo() )
{ //error when get info. 2006/09/21
OutMsg( -1, _MGSTR ( _S_SINGLETASK_GETFILEINFOERROR ), MSG_ERROR );
pthread_setcancelstate ( PTHREAD_CANCEL_DISABLE, &oldstate );
delete m_pFtpInfo;
m_pFtpInfo = NULL;
pthread_setcancelstate ( oldstate, NULL );
FinishTask( _TASK_ERROR );
pthread_exit( 0 );
}
m_nFileLen = m_pFtpInfo->FileSize();
bool bresume = m_pFtpInfo->IsResume();
pthread_setcancelstate ( PTHREAD_CANCEL_DISABLE, &oldstate );
delete m_pFtpInfo;
m_pFtpInfo = NULL;
pthread_setcancelstate ( oldstate, NULL );
if ( m_nFileLen == -1 || !bresume )
{
if ( m_nFileLen == -1 )
{
OutMsg( -1, _MGSTR ( _S_SINGLETASK_NOFILELENGTH ), MSG_WARNNING );
}
if ( !bresume )
{
OutMsg( -1, _MGSTR ( _S_SINGLETASK_NOTSUPPORTRESUME ), MSG_WARNNING );
}
m_nAnts = 1;
//FinishTask(_TASK_ERROR);
//InitThreadQuit();
}
} //main url ftp
else if ( upar.GetUrlType() == HTTP_PROTOCOL )
{ //http
OutMsg( -1, _MGSTR ( _S_SINGLETASK_URLISHTTP ), MSG_INFO );
m_pHttpInfo =
new CMgHttpInfo(
this,
m_sUrl,
m_nRetry,
m_nRetryWait,
upar.GetRefer(),
-1
);
//if need proxy, make here
if ( m_bUseProxy )
{
OutMsg( -1, _MGSTR ( _S_SINGLETASK_USESOCKSPROXY ), MSG_INFO );
m_pHttpInfo->SetProxy( m_Proxy, m_ProxyPort, m_ProxyUser, m_ProxyPass, m_ProxyVersion );
}
if ( m_bUseHttpProxy )
{
OutMsg( -1, _MGSTR ( _S_SINGLETASK_USEHTTPPROXY ), MSG_INFO );
m_pHttpInfo->SetHttpProxy( m_HttpProxy, m_HttpProxyPort );
}
if ( !m_pHttpInfo->GetInfo() )
{ //error when get info.
OutMsg( -1, _MGSTR ( _S_SINGLETASK_GETFILEINFOERROR ), MSG_ERROR );
pthread_setcancelstate ( PTHREAD_CANCEL_DISABLE, &oldstate );
delete m_pHttpInfo;
m_pHttpInfo = NULL;
pthread_setcancelstate ( oldstate, NULL );
FinishTask( _TASK_ERROR );
pthread_exit( 0 );
}
if ( m_pHttpInfo->IsRedirect() )
{
upar.SetRefer( m_sUrl );
m_sUrl = m_pHttpInfo->GetRedirect();
pthread_setcancelstate ( PTHREAD_CANCEL_DISABLE, &oldstate );
delete m_pHttpInfo;
m_pHttpInfo = NULL;
pthread_setcancelstate ( oldstate, NULL );
//跳转后就不再用原来的名字了。
if ( upar.SetUrl( m_sUrl ) )
{
if ( upar.GetFileName() != string( "" ) )
m_sFilename = upar.GetFileName();
}
goto again;
}
// for( int coo=0; coo < m_pHttpInfo->GetCookieNum(); coo++)
// {
//
// cookie.push_back( m_pHttpInfo->GetCookie( coo ) );
// }
m_nFileLen = m_pHttpInfo->GetFileSize();
pthread_setcancelstate ( PTHREAD_CANCEL_DISABLE, &oldstate );
delete m_pHttpInfo;
m_pHttpInfo = NULL;
pthread_setcancelstate ( oldstate, NULL );
if ( m_nFileLen == -1 )
{
OutMsg( -1, _MGSTR ( _S_SINGLETASK_NOFILELENGTH ), MSG_WARNNING );
m_nAnts = 1;
}
} //http
else
{
OutMsg( -1, _MGSTR ( _S_SINGLETASK_NOTSUPPORTURL ) + m_sUrl, MSG_ERROR );
FinishTask( _TASK_ERROR );
pthread_exit( 0 );
}
//create file manager
pthread_setcancelstate ( PTHREAD_CANCEL_DISABLE, &oldstate );
m_pFM = new CMgFileManager ( this, m_sUrl, m_sFilename, m_sSavePath, m_nFileLen, upar.GetRefer() );
pthread_setcancelstate ( oldstate, NULL );
//check file
if ( !m_pFM->CheckFile() )
{
pthread_setcancelstate ( PTHREAD_CANCEL_DISABLE, &oldstate );
delete m_pFM;
m_pFM = NULL;
pthread_setcancelstate ( oldstate, NULL );
FinishTask( _TASK_ERROR );
pthread_exit( 0 );
}
//input mirror url
std::vector<std::string>::const_iterator it;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?