From d123e0ce94bf90b2adb0a4000930eb467e293226 Mon Sep 17 00:00:00 2001 From: sje Date: Wed, 1 Nov 2006 14:48:34 +0000 Subject: git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@16 4f64403b-2f21-0410-a795-97e2b3489a10 --- updater/socket.cpp | 397 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 397 insertions(+) create mode 100644 updater/socket.cpp (limited to 'updater/socket.cpp') diff --git a/updater/socket.cpp b/updater/socket.cpp new file mode 100644 index 0000000..9a609e6 --- /dev/null +++ b/updater/socket.cpp @@ -0,0 +1,397 @@ +#include "common.h" +#include "socket.h" + +/* +#include + +typedef struct SettingsProcEnumParam_tag { + int file_id; + std::list *list; + char *current_filename; + char *temp_folder; +} SettingsProcEnumParam; + +int SettingsEnumProc(const char *szSetting,LPARAM lParam) { + SettingsProcEnumParam *param = (SettingsProcEnumParam *)lParam; + + if(strcmp(szSetting, param->current_filename) != 0) { + int file_id = DBGetContactSettingDword(0, MODULE, szSetting, -1); + if(file_id == param->file_id) { + std::string new_file_name(param->temp_folder); + new_file_name += "\\"; + new_file_name += szSetting; + param->list->push_back(new_file_name); + } + } + + return 0; +} +*/ + + +void ShowAndLogError(TCHAR *message) { +} + +bool GetFile(char *url, TCHAR *temp_folder, char *plugin_name, char *version, bool dlls_only, int recurse_count /*=0*/) { + if(recurse_count > MAX_REDIRECT_RECURSE) { + NLog("GetFile: error, too many redirects"); + return false; + } + + TCHAR save_file[MAX_PATH]; + + if(url == 0 || temp_folder == 0 || plugin_name == 0) + return false; + + // ensure temp_folder exists + if(!CreatePath(options.temp_folder)) { + DWORD err = GetLastError(); + char buff[128]; + sprintf(buff, "GetFile: error creating temp folder, code %d", (unsigned)err); + NLog(buff); + return false; + } + + // ensure zip_folder exists, if necessary + if(options.save_zips && !CreatePath(options.zip_folder)) { + DWORD err = GetLastError(); + char buff[128]; + sprintf(buff, "GetFile: error creating zip folder, code %d", (unsigned)err); + NLog(buff); + return false; + } + + _tcscpy(save_file, temp_folder); + _tcscat(save_file, _T("\\")); + TCHAR *temp_str = GetTString(plugin_name); + _tcscat(save_file, temp_str); + free(temp_str); + if(version) { + temp_str = GetTString(version); + _tcscat(save_file, _T("_")); + _tcscat(save_file, temp_str); + free(temp_str); + } + // copt extension from url + char *ext = strrchr(url, '.'); + if(ext && *ext && strcmp(ext, ".dll") == 0) { + _tcscat(save_file, _T(".dll")); + } else { // default to zip extension (e.g. miranda fl) + _tcscat(save_file, _T(".zip")); + ext = ".zip"; + } + + NETLIBHTTPREQUEST req = {0}; + + req.cbSize = sizeof(req); + req.requestType = REQUEST_GET; + req.szUrl = url; + req.flags = 0; + + NETLIBHTTPREQUEST *resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUser, (LPARAM)&req); + + if(resp) { + if(resp->resultCode == 200) { + HANDLE hSaveFile = CreateFile(save_file, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + if(hSaveFile != INVALID_HANDLE_VALUE) { + unsigned long bytes_written = 0; + if(WriteFile(hSaveFile, resp->pData, resp->dataLength, &bytes_written, NULL) == TRUE) { + CloseHandle(hSaveFile); + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + resp = 0; + + if(ext && *ext && strcmp(ext, ".zip") == 0) { + + char *ans_save_file = GetAString(save_file), *ans_temp_folder = GetAString(temp_folder); + //MessageBoxA(0, ans_temp_folder, ans_save_file, MB_OK); + unzip_file(ans_save_file, ans_temp_folder); + free(ans_save_file); + free(ans_temp_folder); + + if(options.save_zips) { + TCHAR save_archive[MAX_PATH]; + _tcscpy(save_archive, options.zip_folder); + _tcscat(save_archive, _T("\\")); + _tcscat(save_archive, save_file + _tcslen(temp_folder) + 1); + + DeleteFile(save_archive); + if(!MoveFile(save_file, save_archive)) { + char buff[128]; + sprintf(buff, "GetFile: could not move file, code: %d", (unsigned)GetLastError()); + NLog(buff); + if(!DeleteFile(save_file)) { + char buff[128]; + sprintf(buff, "GetFile: error deleting file, code: %d", (unsigned)GetLastError()); + NLog(buff); + } + } + + } else { + if(!DeleteFile(save_file)) { + char buff[128]; + sprintf(buff, "GetFile: error deleting file, code: %d", (unsigned)GetLastError()); + NLog(buff); + } + } + + if(dlls_only) { + NLog("Deleting non-dlls"); + DeleteNonDlls(temp_folder); + } + + } + return true; + + } else { + char buff[128]; + sprintf(buff, "GetFile: error writing file, code %d", (unsigned)GetLastError()); + NLog(buff); + } + CloseHandle(hSaveFile); + } else { + char buff[128]; + sprintf(buff, "GetFile: error creating file, code %d", (unsigned)GetLastError()); + NLog(buff); + } + } else if(resp->resultCode >= 300 && resp->resultCode < 400) { + // get new location + bool ret = false; + for(int i = 0; i < resp->headersCount; i++) { + //MessageBox(0, resp->headers[i].szValue, resp->headers[i].szName, MB_OK); + if(strcmp(resp->headers[i].szName, "Location") == 0) { + ret = GetFile(resp->headers[i].szValue, temp_folder, plugin_name, version, dlls_only, recurse_count + 1); + break; + } + } + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + resp = 0; + return ret; + } else { + TCHAR buff[1024]; + _stprintf(buff, TranslateT("Failed to download \"%s\" - Invalid response, code %d"), plugin_name, resp->resultCode); + + ShowError(buff); + char *ts = GetAString(buff); + NLog(ts); + free(ts); + + } + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + resp = 0; + } else { + int err = GetLastError(); + if(err) { + TCHAR buff[1024]; + _stprintf(buff, TranslateT("Failed to download \"%s\": "), plugin_name); + int len = _tcslen(buff); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, err, 0, buff + len, 512 - len, 0); + + ShowError(buff); + char *ts = GetAString(buff); + NLog(ts); + free(ts); + } + } + + return false; +} + +char *CheckVersionURL(char *url, BYTE *pbPrefixBytes, int cpbPrefixBytes, BYTE *pbVersionBytes, int cpbVersionBytes) { + + /* + bool check = false; + + if(strncmp((char *)pbPrefixBytes, "My Details ", cpbPrefixBytes) == 0) { + //MessageBox(0, "Checking version URL", "Updater -> My Details", MB_OK); + check = true; + } + */ + + if(url == 0 || pbPrefixBytes == 0 || cpbPrefixBytes == 0 || pbVersionBytes == 0 || cpbVersionBytes == 0) + return 0; + + /* + if(check) { + MessageBox(0, "Real URL check", "CheckVersionURL", MB_OK); + MessageBox(0, url, "URL", MB_OK); + MessageBox(0, (char *)pbPrefixBytes, "Prefix", MB_OK); + MessageBox(0, (char *)pbVersionBytes, "Version", MB_OK); + } + */ + + NETLIBHTTPREQUEST req = {0}; + + req.cbSize = sizeof(req); + req.requestType = REQUEST_GET; + req.szUrl = url; + req.flags = NLHRF_DUMPASTEXT; //NLHRF_SMARTREMOVEHOST | NLHRF_SMARTAUTHHEADER; + + NETLIBHTTPREQUEST *resp = (NETLIBHTTPREQUEST_tag *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUser, (LPARAM)&req); + + if(resp) { + if(resp->resultCode == 200) { + // find the location of the prefix + int index, index2; + for(int i = 0; i < resp->dataLength; i++) { + index = 0; + while(index < cpbPrefixBytes && i + index < resp->dataLength && (BYTE)resp->pData[i + index] == pbPrefixBytes[index]) index++; + if(index == cpbPrefixBytes) { + // we found the prefix - now compare the following bytes + // i + index the first byte after the prefix + index2 = 0; + while(index2 + i + index < resp->dataLength && index2 < cpbVersionBytes && resp->pData[i + index + index2] == pbVersionBytes[index2]) index2++; + if(index2 == cpbVersionBytes) { + // same version as current + //if(check) + //MessageBox(0, "same version", "check url", MB_OK); + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + resp = 0; + return 0; + } else { + DWORD ver_current, ver_potential; + char *buff = (char *)malloc(cpbVersionBytes + 1); + strncpy(buff, (char *)pbVersionBytes, cpbVersionBytes); + buff[cpbVersionBytes] = 0; + + // this is safe because pData finishes with a zero always (according to m_netlib.h docs) + if(VersionFromString(buff, &ver_current) && VersionFromString(&resp->pData[i + index], &ver_potential)) + { + switch(options.ver_req) { + case VR_MAJOR: + ver_current &= 0xFF000000; + ver_potential &= 0xFF000000; + break; + case VR_MINOR: + ver_current &= 0xFFFF0000; + ver_potential &= 0xFFFF0000; + break; + case VR_RELEASE: + ver_current &= 0xFFFFFF00; + ver_potential &= 0xFFFFFF00; + break; + case VR_BUILD: + break; + } + //if(check) MessageBox(0, (char *)resp->pData[i + index], buff, MB_OK); + free(buff); + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + resp = 0; + // we can covert the versions to DWORDS, so compare... + if(ver_current < ver_potential) { + char buff2[16]; + CreateVersionString(ver_potential, buff2); + return _strdup(buff2); + } else + return 0; + } else { // invalid version(s), but different from current - assume it's an update + free(buff); + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + resp = 0; + return _strdup(Translate("Yes")); + } + } + } + } + } else if(resp->resultCode == 302) { // redirect + char *ret = 0; + // get new location + for(int i = 0; i < resp->headersCount; i++) { + //MessageBox(0, resp->headers[i].szValue, resp->headers[i].szName, MB_OK); + if(strcmp(resp->headers[i].szName, "Location") == 0) { + ret = CheckVersionURL(resp->headers[i].szValue, pbPrefixBytes, cpbPrefixBytes, pbVersionBytes, cpbVersionBytes); + break; + } + } + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + resp = 0; + + return ret; + } else { + char buff[128]; + sprintf(buff, "CheckVersionURL: error, http result code %d", resp->resultCode); + NLog(buff); + } + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + resp = 0; + } else { + int err = GetLastError(); + if(err) { + char buff[128]; + sprintf(buff, "CheckVersionURL: error code %d", err); + NLog(buff); + return 0; + } + } + + return 0; +} + +char *UpdateRequired(UpdateInternal *update_internal, bool *beta) { + // determine whether update is required + + char *ret = 0, *ret_beta = 0; + + if(options.use_xml_backend && update_internal->file_id != -1) { + if(update_internal->cat == MC_UNKNOWN) { + if(XMLDataAvailable(MC_PLUGINS) + && (ret = FindVersion(update_internal->file_id, update_internal->update.pbVersion, update_internal->update.cpbVersion, MC_PLUGINS))) + { + update_internal->cat = MC_PLUGINS; + if(strcmp(ret, "same") == 0) { + free(ret); + ret = 0; + } + } else if(XMLDataAvailable(MC_LOCALIZATION) + && (ret = FindVersion(update_internal->file_id, update_internal->update.pbVersion, update_internal->update.cpbVersion, MC_LOCALIZATION))) + { + update_internal->cat = MC_LOCALIZATION; + if(strcmp(ret, "same") == 0) { + free(ret); + ret = 0; + } + } + } else { + ret = FindVersion(update_internal->file_id, update_internal->update.pbVersion, update_internal->update.cpbVersion, update_internal->cat); + if(ret && strcmp(ret, "same") == 0) { + free(ret); + ret = 0; + } + } + } else { + ret = CheckVersionURL(update_internal->update.szVersionURL, update_internal->update.pbVersionPrefix, + update_internal->update.cpbVersionPrefix, update_internal->update.pbVersion, update_internal->update.cpbVersion); + } + + if(update_internal->update_options.use_beta) { + ret_beta = CheckVersionURL(update_internal->update.szBetaVersionURL, update_internal->update.pbBetaVersionPrefix, + update_internal->update.cpbBetaVersionPrefix, update_internal->update.pbVersion, update_internal->update.cpbVersion); + } + + if(ret && !ret_beta) { + if(beta) *beta = false; + return ret; + } else if(!ret && ret_beta) { + if(beta) *beta = true; + return ret_beta; + } else if(ret && ret_beta) { + // find highest version of ret and ret_beta + + //MessageBox(0, ret, ret_beta, MB_OK); + + DWORD vRet, vRetBeta; + VersionFromString(ret, &vRet); + VersionFromString(ret_beta, &vRetBeta); + + if(vRetBeta > vRet) { + free(ret); + if(beta) *beta = true; + return ret_beta; + } else { + free(ret_beta); + if(beta) *beta = false; + return ret; + } + } + + return 0; +} -- cgit v1.2.3