📄 updatemanager.cpp
字号:
/*____________________________________________________________________________
FreeAmp - The Free MP3 Player
Portions Copyright (C) 1999 EMusic.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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: updatemanager.cpp,v 1.16 2000/09/01 10:57:59 ijr Exp $
____________________________________________________________________________*/
// The debugger can't handle symbols more than 255 characters long.
// STL often creates symbols longer than that.
// When symbols are longer than 255 characters, the warning is disabled.
#ifdef WIN32
#pragma warning(disable:4786)
#endif
#include <assert.h>
#ifdef WIN32
#include <io.h>
#else
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#endif
#if defined(unix) || defined(__BEOS__)
#define SOCKET int
#endif
#if defined(unix)
#include <arpa/inet.h>
#define closesocket(x) close(x)
#define O_BINARY 0
#endif
#if !defined(WIN32)
#include <strstream>
typedef ostrstream ostringstream;
#else
#include <sstream>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <iostream>
#include <algorithm>
#include "config.h"
#include "facontext.h"
#include "errors.h"
#include "updatemanager.h"
#include "utility.h"
#include "event.h"
#include "eventdata.h"
#include "zlib.h"
#include "mutex.h"
#include "semaphore.h"
const char* kUpdateServer = BRANDING_UPDATE_SERVER;
const char* kUpdatePath = BRANDING_UPDATE_PATH;
const char* kUpdateFile = BRANDING_UPDATE_PATH"/version_info.xml";
const char* kUpdateRequest = "GET %s HTTP/1.0\r\n"
"Host: %s\r\n"
"User-Agent: FreeAmp/%s\r\n" // we do not want to change this for branding
"\n";
const uint8 kUpdatePort = 80;
UpdateManager::UpdateManager(FAContext* context)
{
m_runUpdateThread = true;
m_context = context;
m_currentPlatform = "UNKNOWN";
m_currentArchitecture = "UNKNOWN";
}
UpdateManager::~UpdateManager()
{
uint32 index = 0;
uint32 size = 0;
UpdateItem* item = NULL;
m_runUpdateThread = false;
m_quitMutex.Acquire();
size = m_itemList.size();
for(index = 0; index < size; index++)
{
item = m_itemList[index];
if(item)
{
delete item;
}
}
}
// Functions for adding items to Update Manager
Error UpdateManager::AddItem(UpdateItem* item)
{
Error result = kError_InvalidParam;
m_mutex.Acquire();
assert(item);
if(item)
{
m_itemList.push_back(item);
//SendItemAddedMessage(item);
result = kError_NoErr;
}
m_mutex.Release();
return result;
}
Error UpdateManager::RetrieveLatestVersionInfo(UMCallBackFunction function,
void* cookie)
{
Error result = kError_AlreadyUpdating;
if(m_mutex.Acquire(0))
{
result = InternalRetrieveLatestVersionInfo(function, cookie);
if(IsntError(result))
{
if(function)
{
UMEvent event;
memset(&event, 0x00, sizeof(UMEvent));
event.type = kUMEvent_Done;
event.eventString = "Received latest version info from server.";
function(&event, cookie);
}
}
else if(result != kError_UserCancel)
{
if(function)
{
UMEvent event;
memset(&event, 0x00, sizeof(UMEvent));
event.type = kUMEvent_Error;
event.data.errorData.errorCode = result;
function(&event, cookie);
}
}
m_mutex.Release();
}
return result;
}
Error UpdateManager::InternalRetrieveLatestVersionInfo(
UMCallBackFunction function,
void* cookie)
{
Error result;
string info;
if(function)
{
UMEvent event;
memset(&event, 0x00, sizeof(UMEvent));
event.type = kUMEvent_Status;
event.eventString = "Retrieving latest version info from server...";
function(&event, cookie);
}
result = DownloadInfo(info, function, cookie);
if(IsntError(result))
{
result = ParseString(info);
}
return result;
}
bool UpdateManager::IsUpdateAvailable()
{
bool result = false;
if(m_mutex.Acquire(0))
{
UpdateItem* item;
vector<UpdateItem*>::iterator i = m_itemList.begin();
for (; i != m_itemList.end(); i++)
{
uint32 localMajorVersion, currentMajorVersion;
uint32 localMinorVersion, currentMinorVersion;
uint32 localRevisionVersion, currentRevisionVersion;
uint32 localFileVersion, currentFileVersion;
int32 numFields;
item = *i;
if(item->GetLocalFileTime().size())
{
time_t localFileTime, currentFileTime;
uint32 month, day, year;
numFields = sscanf(item->GetLocalFileTime().c_str(),
"%lu-%lu-%lu",&year,&month,&day);
struct tm fileTime;
memset(&fileTime, 0x00, sizeof(struct tm));
fileTime.tm_mon = month;
fileTime.tm_mday = day;
fileTime.tm_year = year - 1900;
localFileTime = mktime(&fileTime);
numFields = sscanf(item->GetCurrentFileTime().c_str(),
"%lu-%lu-%lu",&year,&month,&day);
fileTime.tm_mon = month;
fileTime.tm_mday = day;
fileTime.tm_year = year - 1900;
currentFileTime = mktime(&fileTime);
// is the version on the server more recent?
if(currentFileTime > localFileTime)
{
result = true;
break;
}
}
else
{
numFields = sscanf(item->GetLocalFileVersion().c_str(),
"%lu.%lu.%lu.%lu",
&localMajorVersion,&localMinorVersion,
&localRevisionVersion, &localFileVersion);
if(numFields < 4)
localFileVersion = 0;
if(numFields < 3)
localRevisionVersion = 0;
if(numFields < 2)
localMinorVersion = 0;
if(numFields < 1)
localMajorVersion = 0;
numFields = sscanf(item->GetCurrentFileVersion().c_str(),
"%lu.%lu.%lu.%lu",
¤tMajorVersion,¤tMinorVersion,
¤tRevisionVersion, ¤tFileVersion);
if(numFields < 4)
currentFileVersion = 0;
if(numFields < 3)
currentRevisionVersion = 0;
if(numFields < 2)
currentMinorVersion = 0;
if(numFields < 1)
currentMajorVersion = 0;
// is the version on the server more recent?
if( (currentMajorVersion > localMajorVersion) ||
(currentMajorVersion == localMajorVersion &&
currentMinorVersion > localMinorVersion) ||
(currentMajorVersion == localMajorVersion &&
currentMinorVersion == localMinorVersion &&
currentRevisionVersion > localRevisionVersion) ||
(currentMajorVersion == localMajorVersion &&
currentMinorVersion == localMinorVersion &&
currentRevisionVersion == localRevisionVersion &&
currentFileVersion > localFileVersion))
{
result = true;
break;
}
}
}
}
return result;
}
Error UpdateManager::UpdateComponents(UMCallBackFunction function,
void* cookie)
{
Error result = kError_AlreadyUpdating;
if(m_mutex.Acquire(0))
{
uint32 downloadCount = 0;
// make sure we have latest info
//result = InternalRetrieveLatestVersionInfo(function, cookie);
result = kError_NoErr;
if(IsntError(result))
{
UpdateItem* item;
vector<UpdateItem*>::iterator i = m_itemList.begin();
// go thru list of components and see if
// there are newer versions
for (; i != m_itemList.end(); i++)
{
bool currentVersionMoreRecent = false;
uint32 localMajorVersion, currentMajorVersion;
uint32 localMinorVersion, currentMinorVersion;
uint32 localRevisionVersion, currentRevisionVersion;
uint32 localFileVersion, currentFileVersion;
int32 numFields;
item = *i;
if(item->GetLocalFileTime().size())
{
time_t localFileTime, currentFileTime;
uint32 month, day, year;
numFields = sscanf(item->GetLocalFileTime().c_str(),
"%lu-%lu-%lu",&year,&month,&day);
struct tm fileTime;
memset(&fileTime, 0x00, sizeof(struct tm));
fileTime.tm_mon = month;
fileTime.tm_mday = day;
fileTime.tm_year = year - 1900;
localFileTime = mktime(&fileTime);
numFields = sscanf(item->GetCurrentFileTime().c_str(),
"%lu-%lu-%lu",&year,&month,&day);
fileTime.tm_mon = month;
fileTime.tm_mday = day;
fileTime.tm_year = year - 1900;
currentFileTime = mktime(&fileTime);
// is the version on the server more recent?
if(currentFileTime > localFileTime)
{
currentVersionMoreRecent = true;
}
}
else
{
numFields = sscanf(item->GetLocalFileVersion().c_str(),
"%lu.%lu.%lu.%lu",
&localMajorVersion,&localMinorVersion,
&localRevisionVersion, &localFileVersion);
if(numFields < 4)
localFileVersion = 0;
if(numFields < 3)
localRevisionVersion = 0;
if(numFields < 2)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -