summaryrefslogtreecommitdiff
path: root/updater/socket.cpp
diff options
context:
space:
mode:
authorsje <sje@4f64403b-2f21-0410-a795-97e2b3489a10>2006-11-01 14:48:34 +0000
committersje <sje@4f64403b-2f21-0410-a795-97e2b3489a10>2006-11-01 14:48:34 +0000
commitd123e0ce94bf90b2adb0a4000930eb467e293226 (patch)
treed414dea59908105c4d2f256199a610e0a69c8690 /updater/socket.cpp
parenta13e82647294da4add976a24335fec50d7bfe905 (diff)
git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@16 4f64403b-2f21-0410-a795-97e2b3489a10
Diffstat (limited to 'updater/socket.cpp')
-rw-r--r--updater/socket.cpp397
1 files changed, 397 insertions, 0 deletions
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 <string>
+
+typedef struct SettingsProcEnumParam_tag {
+ int file_id;
+ std::list<std::string> *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;
+}