c.sexchat/plugins/upd/upd.c

349 lines
9.5 KiB
C
Raw Normal View History

2012-07-13 22:27:12 +02:00
/* HexChat
* Copyright (c) 2010-2012 Berke Viktor.
2011-02-28 18:59:32 +01:00
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
2011-08-11 08:12:35 +02:00
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
2011-02-28 18:59:32 +01:00
*/
#include <windows.h>
#include <wininet.h>
#include <glib.h>
2012-10-24 21:33:02 +02:00
#include "hexchat-plugin.h"
2011-02-28 18:59:32 +01:00
#define DEFAULT_DELAY 10 /* 10 seconds */
#define DEFAULT_FREQ 360 /* 6 hours */
2012-10-30 08:42:48 +01:00
static hexchat_plugin *ph; /* plugin handle */
static char name[] = "Update Checker";
static char desc[] = "Check for HexChat updates automatically";
static char version[] = "4.0";
2012-12-18 02:24:09 +01:00
static const char upd_help[] = "Update Checker Usage:\n /UPDCHK, check for HexChat updates\n /UPDCHK SET delay|freq, set startup delay or check frequency\n";
static int legacy_os = 0;
2011-02-28 18:59:32 +01:00
static char*
check_version ()
{
#if 0
2011-02-28 18:59:32 +01:00
HINTERNET hINet, hFile;
hINet = InternetOpen ("Update Checker", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
2011-02-28 18:59:32 +01:00
if (!hINet)
{
return "Unknown";
}
hFile = InternetOpenUrl (hINet,
"https://raw.github.com/hexchat/hexchat/master/win32/version.txt",
NULL,
0,
INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD,
0);
2011-02-28 18:59:32 +01:00
if (hFile)
{
static char buffer[1024];
DWORD dwRead;
while (InternetReadFile (hFile, buffer, 1023, &dwRead))
{
if (dwRead == 0)
{
break;
}
buffer[dwRead] = 0;
}
InternetCloseHandle (hFile);
InternetCloseHandle (hINet);
2012-12-23 05:42:49 +01:00
if (strlen (buffer) == 5)
return buffer;
else
return "Unknown";
2011-02-28 18:59:32 +01:00
}
2011-02-28 18:59:32 +01:00
InternetCloseHandle (hINet);
return "Unknown";
#endif
/* Google Code's messing up with requests, use HTTP/1.0 as suggested. More info:
http://code.google.com/p/support/issues/detail?id=6095
Of course it would be still too simple, coz IE will override settings, so
you have to disable HTTP/1.1 manually and globally. More info:
http://support.microsoft.com/kb/258425
So this code's basically useless since disabling HTTP/1.1 will work with the
above code too.
Update: a Connection: close header seems to disable chunked encoding.
*/
HINTERNET hOpen, hConnect, hResource;
hOpen = InternetOpen (TEXT ("Update Checker"),
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
0);
if (!hOpen)
{
return "Unknown";
}
hConnect = InternetConnect (hOpen,
2012-07-12 18:39:52 +02:00
TEXT ("raw.github.com"),
INTERNET_DEFAULT_HTTPS_PORT,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0,
0);
if (!hConnect)
{
InternetCloseHandle (hOpen);
return "Unknown";
}
if (legacy_os)
{
hResource = HttpOpenRequest (hConnect,
TEXT ("GET"),
TEXT ("/hexchat/hexchat/master/win32/version-xp.txt"),
TEXT ("HTTP/1.0"),
NULL,
NULL,
INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_AUTH,
0);
}
else
{
hResource = HttpOpenRequest (hConnect,
TEXT ("GET"),
TEXT ("/hexchat/hexchat/master/win32/version.txt"),
TEXT ("HTTP/1.0"),
NULL,
NULL,
INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_AUTH,
0);
}
if (!hResource)
{
InternetCloseHandle (hConnect);
InternetCloseHandle (hOpen);
return "Unknown";
}
else
{
static char buffer[1024];
DWORD dwRead;
HttpAddRequestHeaders (hResource, TEXT ("Connection: close\r\n"), -1L, HTTP_ADDREQ_FLAG_ADD); /* workaround for GC bug */
HttpSendRequest (hResource, NULL, 0, NULL, 0);
while (InternetReadFile (hResource, buffer, 1023, &dwRead))
{
if (dwRead == 0)
{
break;
}
buffer[dwRead] = 0;
}
InternetCloseHandle (hResource);
InternetCloseHandle (hConnect);
InternetCloseHandle (hOpen);
2013-01-18 00:57:02 +01:00
if (strlen (buffer) == 5)
return buffer;
else
return "Unknown";
}
2011-02-28 18:59:32 +01:00
}
static int
print_version (char *word[], char *word_eol[], void *userdata)
2011-02-28 18:59:32 +01:00
{
2012-10-26 13:32:08 +02:00
char *version;
int prevbuf;
int convbuf;
2011-02-28 18:59:32 +01:00
2012-10-26 13:32:08 +02:00
if (!g_ascii_strcasecmp ("HELP", word[2]))
2011-02-28 18:59:32 +01:00
{
2012-10-30 08:42:48 +01:00
hexchat_printf (ph, upd_help);
2012-10-30 10:42:37 +01:00
return HEXCHAT_EAT_HEXCHAT;
2011-02-28 18:59:32 +01:00
}
2012-10-26 13:32:08 +02:00
else if (!g_ascii_strcasecmp ("SET", word[2]))
2011-02-28 18:59:32 +01:00
{
2012-10-26 13:32:08 +02:00
if (!g_ascii_strcasecmp ("", word_eol[4]))
{
2012-10-30 08:42:48 +01:00
hexchat_printf (ph, "%s\tEnter a value!\n", name);
2012-10-30 10:42:37 +01:00
return HEXCHAT_EAT_HEXCHAT;
2012-10-26 13:32:08 +02:00
}
if (!g_ascii_strcasecmp ("delay", word[3]))
{
convbuf = atoi (word[4]); /* don't use word_eol, numbers must not contain spaces */
if (convbuf > 0 && convbuf < INT_MAX)
{
2012-10-30 08:42:48 +01:00
prevbuf = hexchat_pluginpref_get_int (ph, "delay");
hexchat_pluginpref_set_int (ph, "delay", convbuf);
hexchat_printf (ph, "%s\tUpdate check startup delay is set to %d seconds (from %d).\n", name, convbuf, prevbuf);
2012-10-26 13:32:08 +02:00
}
else
{
2012-10-30 08:42:48 +01:00
hexchat_printf (ph, "%s\tInvalid input!\n", name);
2012-10-26 13:32:08 +02:00
}
}
else if (!g_ascii_strcasecmp ("freq", word[3]))
{
convbuf = atoi (word[4]); /* don't use word_eol, numbers must not contain spaces */
if (convbuf > 0 && convbuf < INT_MAX)
{
2012-10-30 08:42:48 +01:00
prevbuf = hexchat_pluginpref_get_int (ph, "freq");
hexchat_pluginpref_set_int (ph, "freq", convbuf);
hexchat_printf (ph, "%s\tUpdate check frequency is set to %d minutes (from %d).\n", name, convbuf, prevbuf);
2012-10-26 13:32:08 +02:00
}
else
{
2012-10-30 08:42:48 +01:00
hexchat_printf (ph, "%s\tInvalid input!\n", name);
2012-10-26 13:32:08 +02:00
}
}
else
{
2012-10-30 08:42:48 +01:00
hexchat_printf (ph, "%s\tInvalid variable name! Use 'delay' or 'freq'!\n", name);
2012-10-30 10:42:37 +01:00
return HEXCHAT_EAT_HEXCHAT;
2012-10-26 13:32:08 +02:00
}
2012-10-30 10:42:37 +01:00
return HEXCHAT_EAT_HEXCHAT;
2011-02-28 18:59:32 +01:00
}
2012-10-26 13:32:08 +02:00
else if (!g_ascii_strcasecmp ("", word[2]))
2011-02-28 18:59:32 +01:00
{
2012-10-26 13:32:08 +02:00
version = check_version ();
2012-10-30 08:42:48 +01:00
if (strcmp (version, hexchat_get_info (ph, "version")) == 0)
2012-10-26 13:32:08 +02:00
{
2012-10-30 08:42:48 +01:00
hexchat_printf (ph, "%s\tYou have the latest version of HexChat installed!\n", name);
2012-10-26 13:32:08 +02:00
}
2012-12-23 05:42:49 +01:00
else if (strcmp (version, "Unknown") == 0)
2012-10-26 13:32:08 +02:00
{
2012-10-30 08:42:48 +01:00
hexchat_printf (ph, "%s\tUnable to check for HexChat updates!\n", name);
2012-10-26 13:32:08 +02:00
}
else
{
#ifdef _WIN64 /* use this approach, the wProcessorArchitecture method always returns 0 (=x86) for some reason */
2013-02-04 21:31:24 +01:00
hexchat_printf (ph, "%s\tA HexChat update is available! You can download it from here:\nhttp://dl.hexchat.org/hexchat/HexChat%%20%s%%20x64.exe\n", name, version);
#else
2013-02-04 21:31:24 +01:00
hexchat_printf (ph, "%s\tA HexChat update is available! You can download it from here:\nhttp://dl.hexchat.org/hexchat/HexChat%%20%s%%20x86.exe\n", name, version);
#endif
2012-10-26 13:32:08 +02:00
}
2012-10-30 10:42:37 +01:00
return HEXCHAT_EAT_HEXCHAT;
2012-10-26 13:32:08 +02:00
}
else
{
2012-10-30 08:42:48 +01:00
hexchat_printf (ph, upd_help);
2012-10-30 10:42:37 +01:00
return HEXCHAT_EAT_HEXCHAT;
2011-02-28 18:59:32 +01:00
}
}
static int
print_version_quiet (void *userdata)
{
char *version = check_version ();
/* if it's not the current version AND not network error */
2012-10-30 08:42:48 +01:00
if (!(strcmp (version, hexchat_get_info (ph, "version")) == 0) && !(strcmp (version, "Unknown") == 0))
{
#ifdef _WIN64 /* use this approach, the wProcessorArchitecture method always returns 0 (=x86) for plugins for some reason */
2012-10-30 08:42:48 +01:00
hexchat_printf (ph, "%s\tA HexChat update is available! You can download it from here:\nhttps://github.com/downloads/hexchat/hexchat/HexChat%%20%s%%20x64.exe\n", name, version);
#else
2012-10-30 08:42:48 +01:00
hexchat_printf (ph, "%s\tA HexChat update is available! You can download it from here:\nhttps://github.com/downloads/hexchat/hexchat/HexChat%%20%s%%20x86.exe\n", name, version);
#endif
/* print update url once, then stop the timer */
return 0;
}
/* keep checking */
return 1;
}
static int
delayed_check (void *userdata)
{
2012-10-30 08:42:48 +01:00
int freq = hexchat_pluginpref_get_int (ph, "freq");
/* only start the timer if there's no update available during startup */
if (print_version_quiet (NULL))
{
/* check for updates, every 6 hours by default */
2012-10-30 08:42:48 +01:00
hexchat_hook_timer (ph, freq * 1000 * 60, print_version_quiet, NULL);
}
return 0; /* run delayed_check() only once */
}
2011-02-28 18:59:32 +01:00
int
2012-10-30 08:42:48 +01:00
hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg)
2011-02-28 18:59:32 +01:00
{
int delay;
OSVERSIONINFOEX osvi;
2011-02-28 18:59:32 +01:00
ph = plugin_handle;
*plugin_name = name;
*plugin_desc = desc;
*plugin_version = version;
2011-02-28 18:59:32 +01:00
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
GetVersionEx ((OSVERSIONINFO*) &osvi);
if (osvi.dwMajorVersion == 5)
{
legacy_os = 1;
}
/* these are required for the very first run */
2012-10-30 08:42:48 +01:00
delay = hexchat_pluginpref_get_int (ph, "delay");
if (delay == -1)
{
delay = DEFAULT_DELAY;
2012-10-30 08:42:48 +01:00
hexchat_pluginpref_set_int (ph, "delay", DEFAULT_DELAY);
}
2011-02-28 18:59:32 +01:00
2012-10-30 08:42:48 +01:00
if (hexchat_pluginpref_get_int (ph, "freq") == -1)
2012-10-26 13:32:08 +02:00
{
2012-10-30 08:42:48 +01:00
hexchat_pluginpref_set_int (ph, "freq", DEFAULT_FREQ);
2012-10-26 13:32:08 +02:00
}
2012-10-30 08:42:48 +01:00
hexchat_hook_command (ph, "UPDCHK", HEXCHAT_PRI_NORM, print_version, upd_help, NULL);
hexchat_hook_timer (ph, delay * 1000, delayed_check, NULL);
hexchat_command (ph, "MENU -ietc\\download.png ADD \"Help/Check for Updates\" \"UPDCHK\"");
hexchat_printf (ph, "%s plugin loaded\n", name);
2011-02-28 18:59:32 +01:00
return 1; /* return 1 for success */
}
int
2012-10-30 08:42:48 +01:00
hexchat_plugin_deinit (void)
2011-02-28 18:59:32 +01:00
{
2012-10-30 08:42:48 +01:00
hexchat_command (ph, "MENU DEL \"Help/Check for updates\"");
hexchat_printf (ph, "%s plugin unloaded\n", name);
2011-02-28 18:59:32 +01:00
return 1;
}