update the checksum plugin to use the plugin config api

This commit is contained in:
Berke Viktor 2012-01-20 18:02:55 +01:00
parent a850ae6e4d
commit 83b6f548ad
1 changed files with 52 additions and 137 deletions

View File

@ -1,5 +1,5 @@
/* XChat-WDK /* XChat-WDK
* Copyright (c) 2010-2011 Berke Viktor. * Copyright (c) 2010-2012 Berke Viktor.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -31,8 +31,7 @@
#include "xchat-plugin.h" #include "xchat-plugin.h"
#define BUFSIZE 32768 #define BUFSIZE 32768
#define DEFAULT_MAX_HASH_SIZE 268435456 /* default size is 256 MB */ #define DEFAULT_LIMIT 256 /* default size is 256 MiB */
#define FILE_BUF_SIZE 512
#ifndef snprintf #ifndef snprintf
#define snprintf _snprintf #define snprintf _snprintf
@ -44,8 +43,7 @@
static xchat_plugin *ph; /* plugin handle */ static xchat_plugin *ph; /* plugin handle */
static const char name[] = "Checksum"; static const char name[] = "Checksum";
static const char desc[] = "Calculate checksum for DCC file transfers"; static const char desc[] = "Calculate checksum for DCC file transfers";
static const char version[] = "2.0"; static const char version[] = "3.0";
static int config_fail; /* variable for config availability */
/* Use of OpenSSL SHA256 interface: http://adamlamers.com/?p=5 */ /* Use of OpenSSL SHA256 interface: http://adamlamers.com/?p=5 */
static void static void
@ -114,135 +112,46 @@ sha256_file (char *path, char outputBuffer[65])
} }
static void static void
init () set_limit (char* size)
{ {
/* check whether the config file exists, if it doesn't, try to create it */ int buffer = atoi (size);
FILE * file_in;
FILE * file_out;
char buffer[FILE_BUF_SIZE];
config_fail = 0; if (buffer > 0 && buffer < INT_MAX)
snprintf (buffer, sizeof (buffer), "%s/checksum.conf", xchat_get_info (ph, "xchatdirfs"));
if ((file_in = fopen (buffer, "r")) == NULL)
{ {
if ((file_out = fopen (buffer, "w")) == NULL) if (xchat_pluginpref_set_int (ph, "limit", buffer))
{ {
config_fail = 1; xchat_printf (ph, "File size limit has successfully been set to: %d MiB\n", buffer);
} else }
{ else
fprintf (file_out, "%llu\n", (unsigned long long) DEFAULT_MAX_HASH_SIZE); {
fclose (file_out); xchat_printf (ph, "File access error while saving!\n");
} }
} else
{
fclose (file_in);
} }
else
/* nasty easter egg: if FILE_BUF_SIZE is set to 1024 and you build for x86, you can do fclose () {
at the end of init (), which is plain wrong as it will only work if fopen () != 0. */ xchat_printf (ph, "Invalid input!\n");
}
} }
static unsigned long long static int
get_max_hash_size () get_limit ()
{ {
FILE * file_in; int size = xchat_pluginpref_get_int (ph, "limit");
char buffer[FILE_BUF_SIZE];
unsigned long long max_hash_size;
if (config_fail) if (size <= -1 || size >= INT_MAX)
{ {
return (unsigned long long) DEFAULT_MAX_HASH_SIZE; return DEFAULT_LIMIT;
} else }
else
{ {
snprintf (buffer, sizeof (buffer), "%s/checksum.conf", xchat_get_info (ph, "xchatdirfs")); return size;
file_in = fopen (buffer, "r");
fscanf (file_in, "%llu", &max_hash_size);
fclose (file_in);
return max_hash_size;
} }
} }
static void static void
print_size () print_limit ()
{ {
unsigned long long size; xchat_printf (ph, "File size limit for checksums: %d MiB", get_limit ());
char suffix[3];
size = get_max_hash_size ();
if (size >= 1073741824)
{
size /= 1073741824;
snprintf (suffix, sizeof (suffix), "GB");
} else if (size >= 1048576)
{
size /= 1048576;
snprintf (suffix, sizeof (suffix), "MB");
} else if (size >= 1024)
{
size /= 1024;
snprintf (suffix, sizeof (suffix), "kB");
} else
{
snprintf (suffix, sizeof (suffix), "B");
}
xchat_printf (ph, "File size limit for checksums: %llu %s\n", size, suffix);
}
static void
increase_max_hash_size ()
{
unsigned long long size;
FILE * file_out;
char buffer[FILE_BUF_SIZE];
if (config_fail)
{
xchat_printf (ph, "Config file is unavailable, falling back to the default value\n");
print_size ();
} else
{
size = get_max_hash_size ();
if (size <= ULLONG_MAX/2)
{
size *= 2;
}
snprintf (buffer, sizeof (buffer), "%s/checksum.conf", xchat_get_info (ph, "xchatdirfs"));
file_out = fopen (buffer, "w");
fprintf (file_out, "%llu\n", size);
fclose (file_out);
print_size ();
}
}
static void
decrease_max_hash_size ()
{
unsigned long long size;
FILE * file_out;
char buffer[FILE_BUF_SIZE];
if (config_fail)
{
xchat_printf (ph, "Config file is unavailable, falling back to the default value\n");
print_size ();
} else
{
size = get_max_hash_size ();
if (size >= 2)
{
size /= 2;
}
snprintf (buffer, sizeof (buffer), "%s/checksum.conf", xchat_get_info (ph, "xchatdirfs"));
file_out = fopen (buffer, "w");
fprintf (file_out, "%llu\n", size);
fclose (file_out);
print_size ();
}
} }
static int static int
@ -255,20 +164,22 @@ dccrecv_cb (char *word[], void *userdata)
result = stat64 (word[2], &buffer); result = stat64 (word[2], &buffer);
if (result == 0) /* stat returns 0 on success */ if (result == 0) /* stat returns 0 on success */
{ {
if (buffer.st_size <= get_max_hash_size ()) if (buffer.st_size <= (unsigned long long) get_limit () * 1048576)
{ {
sha256_file (word[2], sum); /* word[2] is the full filename */ sha256_file (word[2], sum); /* word[2] is the full filename */
/* try to print the checksum in the privmsg tab of the sender */ /* try to print the checksum in the privmsg tab of the sender */
xchat_set_context (ph, xchat_find_context (ph, NULL, word[3])); xchat_set_context (ph, xchat_find_context (ph, NULL, word[3]));
xchat_printf (ph, "SHA-256 checksum for %s (local): %s\n", word[1], sum); xchat_printf (ph, "SHA-256 checksum for %s (local): %s\n", word[1], sum);
} else }
else
{ {
xchat_set_context (ph, xchat_find_context (ph, NULL, word[3])); xchat_set_context (ph, xchat_find_context (ph, NULL, word[3]));
xchat_printf (ph, "SHA-256 checksum for %s (local): (size limit reached, no checksum calculated, you can increase it with /CHECKSUM INC)\n", word[1]); xchat_printf (ph, "SHA-256 checksum for %s (local): (size limit reached, no checksum calculated, you can increase it with /CHECKSUM INC)\n", word[1]);
} }
} else }
else
{ {
xchat_printf (ph, "File access error\n"); xchat_printf (ph, "File access error!\n");
} }
return XCHAT_EAT_NONE; return XCHAT_EAT_NONE;
@ -284,18 +195,20 @@ dccoffer_cb (char *word[], void *userdata)
result = stat64 (word[3], &buffer); result = stat64 (word[3], &buffer);
if (result == 0) /* stat returns 0 on success */ if (result == 0) /* stat returns 0 on success */
{ {
if (buffer.st_size <= get_max_hash_size ()) if (buffer.st_size <= (unsigned long long) get_limit () * 1048576)
{ {
sha256_file (word[3], sum); /* word[3] is the full filename */ sha256_file (word[3], sum); /* word[3] is the full filename */
xchat_commandf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): %s", word[2], word[1], sum); xchat_commandf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): %s", word[2], word[1], sum);
} else }
else
{ {
xchat_set_context (ph, xchat_find_context (ph, NULL, word[3])); xchat_set_context (ph, xchat_find_context (ph, NULL, word[3]));
xchat_printf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): (size limit reached, no checksum calculated)", word[2], word[1]); xchat_printf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): (size limit reached, no checksum calculated)", word[2], word[1]);
} }
} else }
else
{ {
xchat_printf (ph, "File access error\n"); xchat_printf (ph, "File access error!\n");
} }
return XCHAT_EAT_NONE; return XCHAT_EAT_NONE;
@ -306,19 +219,17 @@ checksum (char *word[], void *userdata)
{ {
if (!stricmp ("GET", word[2])) if (!stricmp ("GET", word[2]))
{ {
print_size (); print_limit ();
} else if (!stricmp ("INC", word[2])) }
else if (!stricmp ("SET", word[2]))
{ {
increase_max_hash_size (); set_limit (word[3]);
} else if (!stricmp ("DEC", word[2])) }
{ else
decrease_max_hash_size ();
} else
{ {
xchat_printf (ph, "Usage: /CHECKSUM GET|INC|DEC\n"); xchat_printf (ph, "Usage: /CHECKSUM GET|INC|DEC\n");
xchat_printf (ph, " GET - print the maximum file size to be hashed\n"); xchat_printf (ph, " GET - print the maximum file size (in MiB) to be hashed\n");
xchat_printf (ph, " INC - double the maximum file size to be hashed\n"); xchat_printf (ph, " SET <filesize> - set the maximum file size (in MiB) to be hashed\n");
xchat_printf (ph, " DEC - halve the maximum file size to be hashed\n");
} }
} }
@ -331,9 +242,13 @@ xchat_plugin_init (xchat_plugin *plugin_handle, char **plugin_name, char **plugi
*plugin_desc = desc; *plugin_desc = desc;
*plugin_version = version; *plugin_version = version;
init (); /* this is required for the very first run */
if (xchat_pluginpref_get_int (ph, "limit") == -1)
{
xchat_pluginpref_set_int (ph, "limit", DEFAULT_LIMIT);
}
xchat_hook_command (ph, "CHECKSUM", XCHAT_PRI_NORM, checksum, "Usage: /CHECKSUM GET|INC|DEC", 0); xchat_hook_command (ph, "CHECKSUM", XCHAT_PRI_NORM, checksum, "Usage: /CHECKSUM GET|SET", 0);
xchat_hook_print (ph, "DCC RECV Complete", XCHAT_PRI_NORM, dccrecv_cb, NULL); xchat_hook_print (ph, "DCC RECV Complete", XCHAT_PRI_NORM, dccrecv_cb, NULL);
xchat_hook_print (ph, "DCC Offer", XCHAT_PRI_NORM, dccoffer_cb, NULL); xchat_hook_print (ph, "DCC Offer", XCHAT_PRI_NORM, dccoffer_cb, NULL);