2012-07-13 22:27:12 +02:00
/* HexChat
* Copyright ( c ) 2010 - 2012 Berke Viktor .
2011-02-28 18:59:32 +01:00
*
2011-11-29 02:04:08 +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
*
2011-11-29 02:04:08 +01: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>
2012-10-24 21:33:02 +02:00
# include "hexchat-plugin.h"
2011-02-28 18:59:32 +01:00
2012-10-26 13:00:09 +02:00
# define DEFAULT_DELAY 10 /* 10 seconds */
# define DEFAULT_FREQ 360 /* 6 hours */
2011-02-28 18:59:32 +01:00
static xchat_plugin * ph ; /* plugin handle */
2012-10-26 13:00:09 +02:00
static char name [ ] = " Update Checker " ;
static char desc [ ] = " Check for HexChat updates automatically " ;
static char version [ ] = " 4.0 " ;
2012-10-26 13:38:13 +02:00
static const char upd_help [ ] = " Update Checker Usage: \n /UPDCHK, check for HexChat updates \n /UPDCHK SET delay|format, set startup delay or check frequency \n " ;
2011-02-28 18:59:32 +01:00
static char *
check_version ( )
{
2012-02-08 21:52:27 +01:00
#if 0
2011-02-28 18:59:32 +01:00
HINTERNET hINet , hFile ;
hINet = InternetOpen ( " Update Checker " , INTERNET_OPEN_TYPE_PRECONFIG , NULL , NULL , 0 ) ;
2012-02-04 20:24:30 +01:00
2011-02-28 18:59:32 +01:00
if ( ! hINet )
{
return " Unknown " ;
}
2012-02-04 20:24:30 +01:00
hFile = InternetOpenUrl ( hINet ,
2012-07-12 18:39:52 +02:00
" https://raw.github.com/hexchat/hexchat/master/version.txt " ,
2012-02-04 20:24:30 +01:00
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 ) ;
2012-02-04 20:24:30 +01:00
InternetCloseHandle ( hINet ) ;
2011-02-28 18:59:32 +01:00
return buffer ;
}
2012-02-04 20:24:30 +01:00
2011-02-28 18:59:32 +01:00
InternetCloseHandle ( hINet ) ;
return " Unknown " ;
2012-02-08 21:52:27 +01:00
# endif
2012-02-04 20:24:30 +01:00
/* 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 .
2012-02-08 21:52:27 +01:00
Update : a Connection : close header seems to disable chunked encoding .
2012-02-04 20:24:30 +01:00
*/
2012-02-04 17:41:02 +01:00
HINTERNET hOpen , hConnect , hResource ;
2012-02-08 21:52:27 +01:00
hOpen = InternetOpen ( TEXT ( " Update Checker " ) ,
2012-02-04 17:41:02 +01:00
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 ,
2012-02-04 17:41:02 +01:00
NULL ,
NULL ,
INTERNET_SERVICE_HTTP ,
0 ,
0 ) ;
if ( ! hConnect )
{
InternetCloseHandle ( hOpen ) ;
return " Unknown " ;
}
hResource = HttpOpenRequest ( hConnect ,
2012-02-08 21:52:27 +01:00
TEXT ( " GET " ) ,
2012-07-12 18:39:52 +02:00
TEXT ( " /hexchat/hexchat/master/version.txt " ) ,
2012-02-08 21:52:27 +01:00
TEXT ( " HTTP/1.0 " ) ,
2012-02-04 17:41:02 +01:00
NULL ,
NULL ,
2012-07-12 18:39:52 +02:00
INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_AUTH ,
2012-02-04 17:41:02 +01:00
0 ) ;
if ( ! hResource )
{
InternetCloseHandle ( hConnect ) ;
InternetCloseHandle ( hOpen ) ;
return " Unknown " ;
}
else
{
2012-02-08 21:52:27 +01:00
static char buffer [ 1024 ] ;
DWORD dwRead ;
HttpAddRequestHeaders ( hResource , TEXT ( " Connection: close \r \n " ) , - 1L , HTTP_ADDREQ_FLAG_ADD ) ; /* workaround for GC bug */
2012-02-04 17:41:02 +01:00
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 ) ;
return buffer ;
}
2011-02-28 18:59:32 +01:00
}
2011-11-25 21:44:08 +01:00
static int
2012-10-26 13:00:09 +02:00
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-26 13:32:08 +02:00
xchat_printf ( ph , upd_help ) ;
return XCHAT_EAT_XCHAT ;
2011-02-28 18:59:32 +01:00
}
2012-10-26 13:32:08 +02:00
e lse 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 ] ) )
{
xchat_printf ( ph , " %s \t Enter a value! \n " , name ) ;
return XCHAT_EAT_XCHAT ;
}
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 )
{
prevbuf = xchat_pluginpref_get_int ( ph , " delay " ) ;
xchat_pluginpref_set_int ( ph , " delay " , convbuf ) ;
xchat_printf ( ph , " %s \t Update check startup delay is set to %d seconds (from %d). \n " , name , convbuf , prevbuf ) ;
}
else
{
xchat_printf ( ph , " %s \t Invalid input! \n " , name ) ;
}
}
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 )
{
prevbuf = xchat_pluginpref_get_int ( ph , " freq " ) ;
xchat_pluginpref_set_int ( ph , " freq " , convbuf ) ;
xchat_printf ( ph , " %s \t Update check frequency is set to %d minutes (from %d). \n " , name , convbuf , prevbuf ) ;
}
else
{
xchat_printf ( ph , " %s \t Invalid input! \n " , name ) ;
}
}
else
{
xchat_printf ( ph , " %s \t Invalid variable name! Use 'delay' or 'freq'! \n " , name ) ;
return XCHAT_EAT_XCHAT ;
}
return XCHAT_EAT_XCHAT ;
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 ( ) ;
if ( strcmp ( version , xchat_get_info ( ph , " version " ) ) = = 0 )
{
xchat_printf ( ph , " %s \t You have the latest version of HexChat installed! \n " , name ) ;
}
else if ( strcmp ( version , " Unknown " ) = = 0 )
{
xchat_printf ( ph , " %s \t Unable to check for HexChat updates! \n " , name ) ;
}
else
{
2011-11-23 02:57:45 +01:00
# ifdef _WIN64 /* use this approach, the wProcessorArchitecture method always returns 0 (=x86) for some reason */
2012-10-26 13:32:08 +02:00
xchat_printf ( ph , " %s \t A HexChat update is available! You can download it from here: \n https://github.com/downloads/hexchat/hexchat/HexChat%%20%s%%20x64.exe \n " , name , version ) ;
2011-11-23 02:57:45 +01:00
# else
2012-10-26 13:32:08 +02:00
xchat_printf ( ph , " %s \t A HexChat update is available! You can download it from here: \n https://github.com/downloads/hexchat/hexchat/HexChat%%20%s%%20x86.exe \n " , name , version ) ;
2011-11-23 02:57:45 +01:00
# endif
2012-10-26 13:32:08 +02:00
}
return XCHAT_EAT_XCHAT ;
}
else
{
xchat_printf ( ph , upd_help ) ;
return XCHAT_EAT_XCHAT ;
2011-02-28 18:59:32 +01:00
}
}
2011-11-25 21:44:08 +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-07-12 18:39:52 +02:00
if ( ! ( strcmp ( version , xchat_get_info ( ph , " version " ) ) = = 0 ) & & ! ( strcmp ( version , " Unknown " ) = = 0 ) )
2011-11-25 21:44:08 +01:00
{
# ifdef _WIN64 /* use this approach, the wProcessorArchitecture method always returns 0 (=x86) for plugins for some reason */
2012-10-26 13:32:08 +02:00
xchat_printf ( ph , " %s \t A HexChat update is available! You can download it from here: \n https://github.com/downloads/hexchat/hexchat/HexChat%%20%s%%20x64.exe \n " , name , version ) ;
2011-11-25 21:44:08 +01:00
# else
2012-10-26 13:32:08 +02:00
xchat_printf ( ph , " %s \t A HexChat update is available! You can download it from here: \n https://github.com/downloads/hexchat/hexchat/HexChat%%20%s%%20x86.exe \n " , name , version ) ;
2011-11-25 21:44:08 +01:00
# endif
/* print update url once, then stop the timer */
return 0 ;
}
/* keep checking */
return 1 ;
}
2012-10-26 13:00:09 +02:00
static int
delayed_check ( void * userdata )
{
int freq = xchat_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 */
xchat_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
xchat_plugin_init ( xchat_plugin * plugin_handle , char * * plugin_name , char * * plugin_desc , char * * plugin_version , char * arg )
{
2012-10-26 13:00:09 +02:00
int delay ;
2011-02-28 18:59:32 +01:00
ph = plugin_handle ;
2011-12-02 01:05:59 +01:00
* plugin_name = name ;
* plugin_desc = desc ;
* plugin_version = version ;
2011-02-28 18:59:32 +01:00
2012-10-26 13:00:09 +02:00
/* these are required for the very first run */
delay = xchat_pluginpref_get_int ( ph , " delay " ) ;
if ( delay = = - 1 )
2011-11-25 21:44:08 +01:00
{
2012-10-26 13:00:09 +02:00
delay = DEFAULT_DELAY ;
xchat_pluginpref_set_int ( ph , " delay " , DEFAULT_DELAY ) ;
2011-11-25 21:44:08 +01:00
}
2011-02-28 18:59:32 +01:00
2012-10-26 13:32:08 +02:00
if ( xchat_pluginpref_get_int ( ph , " freq " ) = = - 1 )
{
xchat_pluginpref_set_int ( ph , " freq " , DEFAULT_FREQ ) ;
}
xchat_hook_command ( ph , " UPDCHK " , XCHAT_PRI_NORM , print_version , upd_help , NULL ) ;
2012-10-26 13:00:09 +02:00
xchat_hook_timer ( ph , delay * 1000 , delayed_check , NULL ) ;
xchat_command ( ph , " MENU -ietc \\ download.png ADD \" Help/Check for Updates \" \" UPDCHK \" " ) ;
xchat_printf ( ph , " %s plugin loaded \n " , name ) ;
2011-02-28 18:59:32 +01:00
return 1 ; /* return 1 for success */
}
int
xchat_plugin_deinit ( void )
{
xchat_command ( ph , " MENU DEL \" Help/Check for updates \" " ) ;
2011-12-02 01:05:59 +01:00
xchat_printf ( ph , " %s plugin unloaded \n " , name ) ;
2011-02-28 18:59:32 +01:00
return 1 ;
}