Compare commits

..

1 Commits

Author SHA1 Message Date
TingPing
ba143b4260 Add alerts for invalid ssl certs
This patch was originally provided by dila in #xchat
but modified heavily since.

It will show an alert on invalid certs to add
temp or permanent exceptions per server.
2014-11-26 03:59:09 -05:00
130 changed files with 5506 additions and 3331 deletions

2
.gitignore vendored
View File

@@ -69,7 +69,6 @@ stamp-h1
*.po~
*.pot
*.patch
src/**/*.plist
# Win32 generated files
plugins/wmpa/wmpa_h.h
plugins/wmpa/wmpa_i.c
@@ -86,7 +85,6 @@ resource.h
*.sdf
*.suo
*.user
*.exe
#OSX
osx/HexChat.app
osx/.HexChat.app

View File

@@ -1,17 +1,19 @@
language: c
compiler: clang
compiler:
- gcc
- clang
before_script:
- sudo apt-get update
- sudo apt-get build-dep -qq xchat
- sudo apt-get install -qq libnotify-dev libproxy-dev libpci-dev libcanberra-dev monodevelop gnome-common
script:
- ./autogen.sh
- ./configure --enable-textfe --with-theme-manager --enable-static-analysis
- ./configure --enable-textfe --with-theme-manager
- make V=1 -j$(nproc)
notifications:
irc:
channels: "chat.freenode.net#hexchat-devel"
template: "Build %{build_url} (%{commit} in %{branch}) by %{author}: %{message}"
template: "Build #%{build_number} (%{commit}) by %{author}: %{message}"
on_success: change
matrix:
fast_finish: true

View File

@@ -38,10 +38,14 @@ AH_VERBATIM([OLD_PERL],[#undef OLD_PERL])
AH_VERBATIM([PREFIX],[#undef PREFIX])
AH_VERBATIM([HEXCHATLIBDIR],[#undef HEXCHATLIBDIR])
AH_VERBATIM([HEXCHATSHAREDIR],[#undef HEXCHATSHAREDIR])
AH_VERBATIM([SOCKS],[#undef SOCKS])
AH_VERBATIM([USE_MSPROXY],[#undef USE_MSPROXY])
AH_VERBATIM([USE_LIBPROXY],[#undef USE_LIBPROXY])
AH_VERBATIM([HAVE_ISO_CODES],[#undef HAVE_ISO_CODES])
AH_VERBATIM([HAVE_GTK_MAC],[#undef HAVE_GTK_MAC])
AH_VERBATIM([USE_LIBNOTIFY],[#undef USE_LIBNOTIFY])
AH_VERBATIM([USE_LIBCANBERRA],[#undef USE_LIBCANBERRA])
AH_VERBATIM([USE_IPV6],[#undef USE_IPV6])
AH_VERBATIM([USE_OPENSSL],[#undef USE_OPENSSL])
AH_VERBATIM([USE_PLUGIN],[#undef USE_PLUGIN])
AH_VERBATIM([USE_SIGACTION],[#undef USE_SIGACTION])
@@ -70,17 +74,18 @@ else
fi
fi
platform_win32=no
case $host_os in
*mingw*|*cygwin*|*msys*)
platform_win32=yes;;
*);;
esac
dnl *********************************************************************
dnl ** configure switches ***********************************************
dnl *********************************************************************
AC_ARG_ENABLE(socks,
[AS_HELP_STRING([--enable-socks],[link with SOCKS5 library (default: no)])],
socks=$enableval, socks=no)
AC_ARG_ENABLE(ipv6,
[AS_HELP_STRING([--disable-ipv6],[disable IPv6])],
ipv6=$enableval, ipv6=yes)
AC_ARG_ENABLE(openssl,
[AS_HELP_STRING([--enable-openssl[=PATH]],[enable use of openSSL])],
openssl=$enableval, openssl=yes)
@@ -138,6 +143,14 @@ AC_ARG_ENABLE(libcanberra,
[AS_HELP_STRING([--disable-libcanberra],[disable libcanberra support])],
libcanberra=$enableval, libcanberra=yes)
AC_ARG_ENABLE(ntlm,
[AS_HELP_STRING([--enable-ntlm],[enable Microsoft\'s NTLM auth (libntlm) library support (default: no)])],
ntlm=$enableval, ntlm=no)
AC_ARG_ENABLE(libproxy,
[AS_HELP_STRING([--disable-libproxy],[disable libproxy support (default: auto)])],
libproxy=$enableval, libproxy=auto)
AC_ARG_ENABLE(isocodes,
[AS_HELP_STRING([--disable-isocodes],[disable iso-codes with spell-check])],
isocodes=$enableval, isocodes=yes)
@@ -146,10 +159,6 @@ AC_ARG_ENABLE(minimal-flags,
[AS_HELP_STRING([--enable-minimal-flags],[only add those CFLAGS that are really needed or not intrusive (default: no)])],
minimalflags=$enableval, minimalflags=no)
AC_ARG_ENABLE(static-analysis,
[AS_HELP_STRING([--enable-static-analysis],[if using clang run static analysis during build (default: no)])],
analyze=$enableval, analyze=no)
AC_ARG_WITH(theme-manager,
[AS_HELP_STRING([--with-theme-manager],[compile theme manager (needs monodevelop, default: off)])],
theme_manager=$withval, theme_manager=no)
@@ -170,11 +179,17 @@ dnl *********************************************************************
dnl ** GLIB *************************************************************
dnl *********************************************************************
AM_PATH_GLIB_2_0([2.36.0], [], [AC_MSG_ERROR([Glib not found!])], [gmodule gobject gio])
COMMON_CFLAGS="$GLIB_CFLAGS -DG_DISABLE_SINGLE_INCLUDES"
COMMON_LIBS="$GLIB_LIBS"
AC_DEFINE([GLIB_VERSION_MIN_REQUIRED], [GLIB_VERSION_2_36], [Dont warn using older APIs])
AC_DEFINE([GLIB_VERSION_MAX_ALLOWED], [GLIB_VERSION_2_36], [Prevents using newer APIs])
AM_PATH_GLIB_2_0(2.28.0, glib=yes, glib=no)
if test "$glib" = no; then
AC_MSG_ERROR(Cannot find GLib!)
fi
PKG_CHECK_MODULES([GOBJECT], [gobject-2.0], [], [AC_MSG_ERROR(Cannot find gobject-2.0!)])
PKG_CHECK_MODULES([GIO], [gio-2.0], [], [AC_MSG_ERROR(Cannot find gio-2.0!)])
PKG_CHECK_MODULES([GMODULE], [gmodule-2.0], [], [AC_MSG_ERROR(Cannot find gmodule-2.0!)])
COMMON_CFLAGS="$GLIB_CFLAGS $GIO_CFLAGS $GOBJECT_CFLAGS $GMODULE_CFLAGS -DG_DISABLE_SINGLE_INCLUDES"
COMMON_LIBS="$GLIB_LIBS $GIO_LIBS $GOBJECT_LIBS $GMODULE_LIBS"
dnl *********************************************************************
dnl ** GTK **************************************************************
@@ -339,13 +354,16 @@ AC_CHECK_FUNC(select, ,
AC_MSG_WARN(i can not find select. you might need to help me)))))))
AC_CHECK_LIB(socket, select)
AC_CHECK_FUNCS(getaddrinfo, have_getaddrinfo=yes)
AC_MSG_CHECKING(whether IPv6 is supported)
if test "$have_getaddrinfo" = yes; then
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
AC_MSG_ERROR(ipv6 support not found!)
if test "$ipv6" = yes; then
AC_CHECK_FUNCS(getaddrinfo, have_getaddrinfo=yes)
AC_MSG_CHECKING(whether to enable IPv6 support)
if test "$have_getaddrinfo" = yes; then
AC_MSG_RESULT(yes)
AC_DEFINE(USE_IPV6)
else
ipv6=no
AC_MSG_RESULT(no)
fi
fi
dnl *********************************************************************
@@ -354,14 +372,17 @@ dnl *********************************************************************
retry=no
if test "$openssl" != no; then
PKG_CHECK_MODULES(OPENSSL, [openssl], [
AC_MSG_CHECKING(for openssl through pkg-config)
if $PKG_CONFIG openssl --exists; then
CPPFLAGS="$CPPFLAGS `$PKG_CONFIG openssl --cflags`"
LIBS="$LIBS `$PKG_CONFIG openssl --libs`"
AC_DEFINE(USE_OPENSSL)
AC_MSG_RESULT(yes)
openssl=yes
COMMON_LIBS="$COMMON_LIBS $OPENSSL_LIBS"
COMMON_CFLAGS="$COMMON_CFLAGS $OPENSSL_CFLAGS"
], [
else
AC_MSG_RESULT(no)
retry=yes
])
fi
fi
if test "$retry" = "yes"; then
@@ -370,29 +391,50 @@ if test "$retry" = "yes"; then
openssl_path=$openssl
fi
openssl=no
OPENSSL_LIBS="-lcrypto"
if test -n "$openssl_path"; then
OPENSSL_LIBS="-L$openssl_path/lib $OPENSSL_LIBS"
fi
SAVED_LIBS=$LIBS
LIBS="$LIBS $OPENSSL_LIBS"
AC_CHECK_LIB(ssl, SSL_new, [
LIBS="$LIBS -lcrypto"
if test -n "$openssl_path"; then
LIBS="-L$openssl_path/lib $LIBS"
fi
AC_CHECK_LIB(ssl, SSL_new, have_openssl=yes)
LIBS=$SAVED_LIBS
if test "$have_openssl" = yes; then
SAVED_CPPFLAGS=$CPPFLAGS
if test -n "$openssl_path"; then
OPENSSL_CFLAGS="-I$openssl_path/include"
CPPFLAGS="-I$openssl_path/include $CPPFLAGS"
fi
SAVED_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS $OPENSSL_CFLAGS"
AC_CHECK_HEADERS(openssl/ssl.h, [
AC_CHECK_HEADERS(openssl/ssl.h, have_openssl_h=yes)
if test "$have_openssl_h" = yes; then
openssl=yes
AC_DEFINE(USE_OPENSSL)
OPENSSL_LIBS="$OPENSSL_LIBS -lssl"
LIBS="$LIBS -lssl -lcrypto"
if test -n "$openssl_path"; then
LIBS="-L$openssl_path/lib $LIBS"
fi
else
CPPFLAGS=$SAVED_CPPFLAGS
fi
fi
fi
COMMON_LIBS="$COMMON_LIBS $OPENSSL_LIBS"
COMMON_CFLAGS="$COMMON_CFLAGS $OPENSSL_CFLAGS"
])
CFLAGS=$SAVED_CFLAGS
dnl *********************************************************************
dnl ** LIBPROXY *********************************************************
dnl *********************************************************************
if test "x$libproxy" = "xyes" -o "x$libproxy" = "xauto" ; then
PKG_CHECK_MODULES([LIBPROXY], [libproxy-1.0], [
COMMON_LIBS="$COMMON_LIBS $LIBPROXY_LIBS"
COMMON_CFLAGS="$COMMON_CFLAGS $LIBPROXY_CFLAGS"
AC_DEFINE(USE_LIBPROXY)
libproxy=yes
], [
if test "x$libproxy" = "xyes" ; then
AC_MSG_ERROR(Cannot find libproxy!)
fi
libproxy=no
])
LIBS=$SAVED_LIBS
else
libproxy=no
fi
dnl *********************************************************************
@@ -401,10 +443,6 @@ dnl *********************************************************************
if test "$plugin" = yes; then
AC_DEFINE(USE_PLUGIN)
PLUGIN_LDFLAGS="-avoid-version"
if test "$platform_win32" = yes; then
PLUGIN_LDFLAGS="$PLUGIN_LDFLAGS -no-undefined"
fi
fi
dnl *********************************************************************
@@ -415,8 +453,14 @@ if test "$checksum" != "no"; then
checksum=no
AC_MSG_CHECKING(for plugin interface used by Checksum)
if test "$plugin" = yes; then
checksum=yes
AC_MSG_RESULT([yes])
AC_MSG_CHECKING(for OpenSSL used by Checksum)
if test "$openssl" = yes; then
checksum=yes
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([OpenSSL cannot be found, use the --enable-openssl option])
fi
else
AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option])
fi
@@ -482,7 +526,8 @@ if test "x$dbus" = "xyes" ; then
dbus=no
])
AC_PATH_PROG(DBUS_BINDING_TOOL, dbus-binding-tool, no)
if test "x$DBUS_BINDING_TOOL" = "xno" || test "x$dbus" = "xno" ; then
AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal, no)
if test "x$DBUS_BINDING_TOOL" = "xno" || test "x$GLIB_GENMARSHAL" = "xno" || test "x$dbus" = "xno" ; then
dbus="no"
else
COMMON_LIBS="$COMMON_LIBS $DBUS_LIBS"
@@ -542,17 +587,6 @@ if test "x$isocodes" = "xyes" ; then
])
fi
dnl *********************************************************************
dnl ** Static Analysis **************************************************
dnl *********************************************************************
if test "x$analyze" = "xyes"; then
if test "$CC" != "clang"; then
AC_MSG_WARN(CC is not clang for static analysis)
analyze=no
fi
fi
dnl *********************************************************************
dnl ** CONDITIONALS *****************************************************
dnl *********************************************************************
@@ -560,6 +594,7 @@ dnl *********************************************************************
AM_CONDITIONAL(USE_OPENSSL, test "x$openssl" = "xyes")
AM_CONDITIONAL(USE_LIBNOTIFY, test "x$libnotify" = "xyes")
AM_CONDITIONAL(USE_LIBCANBERRA, test "x$libcanberra" = "xyes")
AM_CONDITIONAL(USE_MSPROXY, test "x$ntlm" = "xyes")
AM_CONDITIONAL(DO_TEXT, test "x$textfe" = "xyes")
AM_CONDITIONAL(DO_GTK, test "x$gtkfe" = "xyes")
AM_CONDITIONAL(DO_PERL, test "x$perl" = "xyes")
@@ -569,11 +604,41 @@ AM_CONDITIONAL(DO_CHECKSUM, test "x$checksum" = "xyes")
AM_CONDITIONAL(DO_DOAT, test "x$doat" = "xyes")
AM_CONDITIONAL(DO_FISHLIM, test "x$fishlim" = "xyes")
AM_CONDITIONAL(DO_SYSINFO, test "x$sysinfo" = "xyes")
AM_CONDITIONAL(DO_STATIC_ANALYSIS, test "x$analyze" = "xyes")
AM_CONDITIONAL(USE_DBUS, test "x$dbus" = "xyes")
AM_CONDITIONAL(HAVE_ISO_CODES, test "x$isocodes" = "xyes")
AM_CONDITIONAL(WITH_TM, test "x$theme_manager" != "xno")
dnl *********************************************************************
dnl ** SOCKS5 ***********************************************************
dnl *********************************************************************
if test "$socks" = yes; then
socks=no
AC_CHECK_LIB(socks5, SOCKSconnect, have_socks=yes)
if test "$have_socks" = yes; then
AC_CHECK_HEADERS(socks.h, have_socks_h=yes)
if test "$have_socks_h" = yes; then
socks=yes
AC_DEFINE(SOCKS)
LIBS="$LIBS -lsocks5"
fi
fi
fi
dnl *********************************************************************
dnl ** MS PROXY *********************************************************
dnl *********************************************************************
have_ntlm="no"
if test "x$ntlm" = "xyes" ; then
have_ntlm="no"
AC_CHECK_LIB(ntlm, ntlm_smb_encrypt, have_ntlm=yes)
if test "$have_ntlm" = yes; then
LIBS="$LIBS -lntlm"
AC_DEFINE(USE_MSPROXY)
fi
fi
dnl *********************************************************************
dnl ** GCC FLAGS ********************************************************
dnl *********************************************************************
@@ -680,7 +745,8 @@ AC_TRY_COMPILE(
],
AC_MSG_RESULT(no))
AC_CHECK_FUNCS(memrchr)
dnl if we don\'t have this, use g_snprintf instead
AC_CHECK_FUNCS(snprintf vsnprintf memrchr strtoull)
AC_CHECK_FUNC(gethostbyname, ,
AC_CHECK_LIB(resolv, gethostbyname, ,
@@ -729,12 +795,12 @@ AC_SUBST(PY_CFLAGS)
AC_SUBST(PY_LIBS)
AC_SUBST(DBUS_CFLAGS)
AC_SUBST(DBUS_LIBS)
AC_SUBST(OPENSSL_LIBS)
AC_SUBST(OPENSSL_CFLAGS)
AC_SUBST(PLUGIN_LDFLAGS)
m4_ifdef([PKG_INSTALLDIR], [PKG_INSTALLDIR], AC_SUBST([pkgconfigdir], ${libdir}/pkgconfig))
PLUGIN_INCLUDES='-I$(top_srcdir)/plugins'
AC_SUBST(PLUGIN_INCLUDES)
dnl for plugin.c and pixmaps.c
test "x$prefix" = xNONE && prefix="$ac_default_prefix"
test "x$exec_prefix" = xNONE && exec_prefix="$prefix"
@@ -792,6 +858,9 @@ echo D-Bus support ......... : $dbus
echo libnotify support ..... : $libnotify
echo libcanberra support ... : $libcanberra
echo Plugin interface ...... : $plugin
echo IPv6 support .......... : $ipv6
echo MS Proxy NTLM \(ISA\) ... : $have_ntlm
echo libproxy support ...... : $libproxy
echo
echo Perl .................. : $perl
echo Python ................ : $python

View File

@@ -1,8 +0,0 @@
analysis_verbose = $(analysis_verbose_$(V))
analysis_verbose_ = $(analysis_verbose_$(AM_DEFAULT_VERBOSITY))
analysis_verbose_0 = @echo " CCSA " $@; $(COMPILE) --analyze $< -o $@;
analysis_verbose_1 = $(COMPILE) --analyze $< -o $@;
%.plist: %.c
$(analysis_verbose)

View File

@@ -2,6 +2,6 @@ libdir = $(hexchatlibdir)
lib_LTLIBRARIES = checksum.la
checksum_la_SOURCES = checksum.c
checksum_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
checksum_la_LIBADD = $(GLIB_LIBS)
checksum_la_CFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)/src/common
checksum_la_LDFLAGS = -avoid-version -module
checksum_la_LIBADD =
AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/../../src/common

View File

@@ -20,40 +20,131 @@
* THE SOFTWARE.
*/
#include "config.h"
#ifdef __APPLE__
#define __AVAILABILITYMACROS__
#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <openssl/sha.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
#ifdef WIN32
#ifndef snprintf
#define snprintf _snprintf
#endif
#define stat _stat64
#else
/* for INT_MAX */
#include <limits.h>
#define __USE_LARGEFILE64
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#include "hexchat-plugin.h"
#define BUFSIZE 32768
#define DEFAULT_LIMIT 256 /* default size is 256 MiB */
#define SHA256_DIGEST_LENGTH 32
#define SHA256_BUFFER_LENGTH 65
static hexchat_plugin *ph; /* plugin handle */
static char name[] = "Checksum";
static char desc[] = "Calculate checksum for DCC file transfers";
static char version[] = "3.1";
/* Use of OpenSSL SHA256 interface: http://adamlamers.com/?p=5 */
static void
set_limit (char *size)
sha256_hash_string (unsigned char hash[SHA256_DIGEST_LENGTH], char outputBuffer[65])
{
int limit = atoi (size);
if (limit > 0 && limit < INT_MAX)
int i;
for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
{
if (hexchat_pluginpref_set_int (ph, "limit", limit))
hexchat_printf (ph, "Checksum: File size limit has successfully been set to: %d MiB\n", limit);
sprintf (outputBuffer + (i * 2), "%02x", hash[i]);
}
outputBuffer[64] = 0;
}
#if 0
static void
sha256 (char *string, char outputBuffer[65])
{
int i;
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init (&sha256);
SHA256_Update (&sha256, string, strlen (string));
SHA256_Final (hash, &sha256);
for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
{
sprintf (outputBuffer + (i * 2), "%02x", hash[i]);
}
outputBuffer[64] = 0;
}
#endif
static int
sha256_file (char *path, char outputBuffer[65])
{
int bytesRead;
unsigned char *buffer;
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
FILE *file = fopen (path, "rb");
if (!file)
{
return -534;
}
SHA256_Init (&sha256);
buffer = malloc (BUFSIZE);
bytesRead = 0;
if (!buffer)
{
fclose (file);
return ENOMEM;
}
while ((bytesRead = fread (buffer, 1, BUFSIZE, file)))
{
SHA256_Update (&sha256, buffer, bytesRead);
}
SHA256_Final (hash, &sha256);
sha256_hash_string (hash, outputBuffer);
fclose (file);
free (buffer);
return 0;
}
static void
set_limit (char* size)
{
int buffer = atoi (size);
if (buffer > 0 && buffer < INT_MAX)
{
if (hexchat_pluginpref_set_int (ph, "limit", buffer))
{
hexchat_printf (ph, "File size limit has successfully been set to: %d MiB\n", buffer);
}
else
hexchat_printf (ph, "Checksum: File access error while saving!\n");
{
hexchat_printf (ph, "File access error while saving!\n");
}
}
else
{
hexchat_printf (ph, "Checksum: Invalid input!\n");
hexchat_printf (ph, "Invalid input!\n");
}
}
@@ -62,152 +153,89 @@ get_limit ()
{
int size = hexchat_pluginpref_get_int (ph, "limit");
if (size <= 0 || size >= INT_MAX)
if (size <= -1 || size >= INT_MAX)
{
return DEFAULT_LIMIT;
}
else
{
return size;
}
}
static gboolean
check_limit (GFile *file)
static void
print_limit ()
{
GFileInfo *file_info;
goffset file_size;
file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE,
NULL, NULL);
if (!file_info)
return FALSE;
file_size = g_file_info_get_size (file_info);
g_object_unref (file_info);
if (file_size > get_limit () * 1048576ll)
return FALSE;
return TRUE;
}
static gboolean
sha256_from_stream (GFileInputStream *file_stream, char out_buf[])
{
GChecksum *checksum;
gssize bytes_read;
guint8 digest[SHA256_DIGEST_LENGTH];
gsize digest_len = sizeof(digest);
guchar buffer[BUFSIZE];
gsize i;
checksum = g_checksum_new (G_CHECKSUM_SHA256);
while ((bytes_read = g_input_stream_read (G_INPUT_STREAM (file_stream), buffer, sizeof (buffer), NULL, NULL)))
{
if (bytes_read == -1)
{
g_checksum_free (checksum);
return FALSE;
}
g_checksum_update (checksum, buffer, bytes_read);
}
g_checksum_get_digest (checksum, digest, &digest_len);
g_checksum_free (checksum);
for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
{
/* out_buf will be exactly SHA256_BUFFER_LENGTH including null */
g_sprintf (out_buf + (i * 2), "%02x", digest[i]);
}
return TRUE;
}
static gboolean
sha256_from_file (char *filename, char out_buf[])
{
GFileInputStream *file_stream;
char *filename_fs;
GFile *file;
filename_fs = g_filename_from_utf8 (filename, -1, NULL, NULL, NULL);
if (!filename_fs)
{
hexchat_printf (ph, "Checksum: Invalid filename (%s)\n", filename);
return FALSE;
}
file = g_file_new_for_path (filename_fs);
g_free (filename_fs);
if (!file)
{
hexchat_printf (ph, "Checksum: Failed to open %s\n", filename);
return FALSE;
}
if (!check_limit (file))
{
hexchat_printf (ph, "Checksum: %s is larger than size limit. You can increase it with /CHECKSUM SET.\n", filename);
g_object_unref (file);
return FALSE;
}
file_stream = g_file_read (file, NULL, NULL);
if (!file_stream)
{
hexchat_printf (ph, "Checksum: Failed to read file %s\n", filename);
g_object_unref (file);
return FALSE;
}
if (!sha256_from_stream (file_stream, out_buf))
{
hexchat_printf (ph, "Checksum: Failed to generate checksum for %s\n", filename);
g_object_unref (file_stream);
g_object_unref (file);
return FALSE;
}
g_object_unref (file_stream);
g_object_unref (file);
return TRUE;
hexchat_printf (ph, "File size limit for checksums: %d MiB", get_limit ());
}
static int
dccrecv_cb (char *word[], void *userdata)
{
const char *dcc_completed_dir;
char *filename, checksum[SHA256_BUFFER_LENGTH];
int result;
struct stat buffer; /* buffer for storing file info */
char sum[65]; /* buffer for checksum */
const char *file;
char *cfile;
/* Print in the privmsg tab of the sender */
hexchat_set_context (ph, hexchat_find_context (ph, NULL, word[3]));
if (hexchat_get_prefs (ph, "dcc_completed_dir", &dcc_completed_dir, NULL) == 1 && dcc_completed_dir[0] != '\0')
filename = g_build_filename (dcc_completed_dir, word[1], NULL);
else
filename = g_strdup (word[2]);
if (sha256_from_file (filename, checksum))
if (hexchat_get_prefs (ph, "dcc_completed_dir", &file, NULL) == 1 && file[0] != 0)
{
hexchat_printf (ph, "SHA-256 checksum for %s (local): %s\n", word[1], checksum);
cfile = g_strconcat (file, G_DIR_SEPARATOR_S, word[1], NULL);
}
else
{
cfile = g_strdup(word[2]);
}
g_free (filename);
result = stat (cfile, &buffer);
if (result == 0) /* stat returns 0 on success */
{
if (buffer.st_size <= (unsigned long long) get_limit () * 1048576)
{
sha256_file (cfile, sum); /* file is the full filename even if completed dir set */
/* try to print the checksum in the privmsg tab of the sender */
hexchat_set_context (ph, hexchat_find_context (ph, NULL, word[3]));
hexchat_printf (ph, "SHA-256 checksum for %s (local): %s\n", word[1], sum);
}
else
{
hexchat_set_context (ph, hexchat_find_context (ph, NULL, word[3]));
hexchat_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
{
hexchat_printf (ph, "File access error!\n");
}
g_free (cfile);
return HEXCHAT_EAT_NONE;
}
static int
dccoffer_cb (char *word[], void *userdata)
{
char checksum[SHA256_BUFFER_LENGTH];
int result;
struct stat buffer; /* buffer for storing file info */
char sum[65]; /* buffer for checksum */
/* Print in the privmsg tab of the receiver */
hexchat_set_context (ph, hexchat_find_context (ph, NULL, word[3]));
if (sha256_from_file (word[3], checksum))
result = stat (word[3], &buffer);
if (result == 0) /* stat returns 0 on success */
{
hexchat_commandf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): %s", word[2], word[1], checksum);
if (buffer.st_size <= (unsigned long long) get_limit () * 1048576)
{
sha256_file (word[3], sum); /* word[3] is the full filename */
hexchat_commandf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): %s", word[2], word[1], sum);
}
else
{
hexchat_set_context (ph, hexchat_find_context (ph, NULL, word[3]));
hexchat_printf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): (size limit reached, no checksum calculated)", word[2], word[1]);
}
}
else
{
hexchat_printf (ph, "File access error!\n");
}
return HEXCHAT_EAT_NONE;
@@ -218,7 +246,7 @@ checksum (char *word[], char *word_eol[], void *userdata)
{
if (!g_ascii_strcasecmp ("GET", word[2]))
{
hexchat_printf (ph, "File size limit for checksums: %d MiB", get_limit ());
print_limit ();
}
else if (!g_ascii_strcasecmp ("SET", word[2]))
{
@@ -231,7 +259,7 @@ checksum (char *word[], char *word_eol[], void *userdata)
hexchat_printf (ph, " SET <filesize> - set the maximum file size (in MiB) to be hashed\n");
}
return HEXCHAT_EAT_ALL;
return HEXCHAT_EAT_NONE;
}
int
@@ -249,7 +277,7 @@ hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **p
hexchat_pluginpref_set_int (ph, "limit", DEFAULT_LIMIT);
}
hexchat_hook_command (ph, "CHECKSUM", HEXCHAT_PRI_NORM, checksum, "Usage: /CHECKSUM GET|SET", NULL);
hexchat_hook_command (ph, "CHECKSUM", HEXCHAT_PRI_NORM, checksum, "Usage: /CHECKSUM GET|SET", 0);
hexchat_hook_print (ph, "DCC RECV Complete", HEXCHAT_PRI_NORM, dccrecv_cb, NULL);
hexchat_hook_print (ph, "DCC Offer", HEXCHAT_PRI_NORM, dccoffer_cb, NULL);

View File

@@ -2,7 +2,7 @@ libdir = $(hexchatlibdir)
lib_LTLIBRARIES = doat.la
doat_la_SOURCES = doat.c
doat_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
doat_la_LIBADD = $(GLIB_LIBS)
doat_la_CFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)/src/common
doat_la_LDFLAGS = -avoid-version -module
doat_la_LIBADD =
AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/../../src/common

View File

@@ -5,12 +5,9 @@
* http://sam.zoy.org/wtfpl/COPYING or http://lwsitu.com/xchat/COPYING
* for more details. */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <glib.h>
#include "hexchat-plugin.h"
static hexchat_plugin *ph;
@@ -34,7 +31,7 @@ parse_command( char *word[], char *word_eol[], void *userdata ) {
break;
}
channel = g_strdup( token );
channel = strdup( token );
delimiter = strchr( channel, '/' );
@@ -43,13 +40,13 @@ parse_command( char *word[], char *word_eol[], void *userdata ) {
*delimiter = '\0';
if( strlen( delimiter + 1 ) > 0 ) {
server = g_strdup( delimiter + 1 );
server = strdup( delimiter + 1 );
}
}
/* /Network form */
if( strlen( channel ) == 0 ) {
g_free( channel );
free( channel );
channel = NULL;
}
@@ -61,8 +58,13 @@ parse_command( char *word[], char *word_eol[], void *userdata ) {
}
}
g_free( channel );
g_free( server );
if( channel != NULL ) {
free( channel );
}
if( server != NULL ) {
free( server );
}
}
}
return HEXCHAT_EAT_HEXCHAT;

View File

@@ -62,7 +62,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DOAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@@ -70,8 +70,6 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>doat.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
@@ -82,7 +80,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;DOAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@@ -90,8 +88,6 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>doat.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>

View File

@@ -3,7 +3,7 @@ EXTRA_DIST = INSTALL LICENSE
libdir = $(hexchatlibdir)
lib_LTLIBRARIES = fishlim.la
fishlim_la_SOURCES = fish.c irc.c keystore.c plugin_hexchat.c
fishlim_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
fishlim_la_LIBADD = $(GLIB_LIBS) $(OPENSSL_LIBS)
fishlim_la_CFLAGS = $(GLIB_CFLAGS) $(OPENSSL_CFLAGS) -I$(top_srcdir)/src/common
fishlim_la_SOURCES = fish.c irc.c keystore.c misc.c plugin_hexchat.c
fishlim_la_LDFLAGS = -avoid-version -module
fishlim_la_LIBADD =
AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/../../src/common

View File

@@ -39,17 +39,17 @@ static const char fish_base64[64] = "./0123456789abcdefghijklmnopqrstuvwxyzABCDE
static const signed char fish_unbase64[256] = {
IB,IB,IB,IB,IB,IB,IB,IB, IB,IB,IB,IB,IB,IB,IB,IB,
IB,IB,IB,IB,IB,IB,IB,IB, IB,IB,IB,IB,IB,IB,IB,IB,
/* ! " # $ % & ' ( ) * + , - . / */
// ! " # $ % & ' ( ) * + , - . /
IB,IB,IB,IB,IB,IB,IB,IB, IB,IB,IB,IB,IB,IB, 0, 1,
/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
2, 3, 4, 5, 6, 7, 8, 9, 10,11,IB,IB,IB,IB,IB,IB,
/* @ A B C D E F G H I J K L M N O */
// @ A B C D E F G H I J K L M N O
IB,38,39,40,41,42,43,44, 45,46,47,48,49,50,51,52,
/* P Q R S T U V W X Y Z [ \ ] ^ _*/
// P Q R S T U V W X Y Z [ \ ] ^ _
53,54,55,56,57,58,59,60, 61,62,63,IB,IB,IB,IB,IB,
/* ` a b c d e f g h i j k l m n o */
// ` a b c d e f g h i j k l m n o
IB,12,13,14,15,16,17,18, 19,20,21,22,23,24,25,26,
/* p q r s t u v w x y z { | } ~ <del> */
// p q r s t u v w x y z { | } ~ <del>
27,28,29,30,31,32,33,34, 35,36,37,IB,IB,IB,IB,IB,
};
@@ -75,11 +75,12 @@ char *fish_encrypt(const char *key, size_t keylen, const char *message) {
messagelen = strlen(message);
if (messagelen == 0) return NULL;
encrypted = g_malloc(((messagelen - 1) / 8) * 12 + 12 + 1); /* each 8-byte block becomes 12 bytes */
encrypted = malloc(((messagelen-1)/8)*12 + 12 + 1); // each 8-byte block becomes 12 bytes
end = encrypted;
if (!encrypted) return NULL;
while (*message) {
/* Read 8 bytes (a Blowfish block) */
// Read 8 bytes (a Blowfish block)
BF_LONG binary[2] = { 0, 0 };
unsigned char c;
for (i = 0; i < 8; i++) {
@@ -89,10 +90,10 @@ char *fish_encrypt(const char *key, size_t keylen, const char *message) {
}
message += 8;
/* Encrypt block */
// Encrypt block
BF_encrypt(binary, &bfkey);
/* Emit FiSH-BASE64 */
// Emit FiSH-BASE64
bit = 0;
word = 1;
for (j = 0; j < 12; j++) {
@@ -105,7 +106,7 @@ char *fish_encrypt(const char *key, size_t keylen, const char *message) {
}
}
/* Stop if a null terminator was found */
// Stop if a null terminator was found
if (c == '\0') break;
}
*end = '\0';
@@ -123,11 +124,12 @@ char *fish_decrypt(const char *key, size_t keylen, const char *data) {
unsigned char d;
BF_set_key(&bfkey, keylen, (const unsigned char*)key);
decrypted = g_malloc(strlen(data) + 1);
decrypted = malloc(strlen(data)+1);
end = decrypted;
if (!decrypted) return NULL;
while (*data) {
/* Convert from FiSH-BASE64 */
// Convert from FiSH-BASE64
BF_LONG binary[2] = { 0, 0 };
bit = 0;
word = 1;
@@ -142,10 +144,10 @@ char *fish_decrypt(const char *key, size_t keylen, const char *data) {
}
}
/* Decrypt block */
// Decrypt block
BF_decrypt(binary, &bfkey);
/* Copy to buffer */
// Copy to buffer
GET_BYTES(end, binary[0]);
GET_BYTES(end, binary[1]);
}
@@ -163,14 +165,14 @@ char *fish_encrypt_for_nick(const char *nick, const char *data) {
char *key;
char *encrypted;
/* Look for key */
// Look for key
key = keystore_get_key(nick);
if (!key) return NULL;
/* Encrypt */
// Encrypt
encrypted = fish_encrypt(key, strlen(key), data);
g_free(key);
free(key);
return encrypted;
}
@@ -181,14 +183,14 @@ char *fish_encrypt_for_nick(const char *nick, const char *data) {
char *fish_decrypt_from_nick(const char *nick, const char *data) {
char *key;
char *decrypted;
/* Look for key */
// Look for key
key = keystore_get_key(nick);
if (!key) return NULL;
/* Decrypt */
// Decrypt
decrypted = fish_decrypt(key, strlen(key), data);
g_free(key);
free(key);
return decrypted;
}

View File

@@ -25,10 +25,9 @@
#ifndef FISH_H
#define FISH_H
#include <stdbool.h>
#include <stddef.h>
#include <glib.h>
char *fish_encrypt(const char *key, size_t keylen, const char *message);
char *fish_decrypt(const char *key, size_t keylen, const char *data);
char *fish_encrypt_for_nick(const char *nick, const char *data);

View File

@@ -103,12 +103,14 @@
<ClInclude Include="fish.h" />
<ClInclude Include="irc.h" />
<ClInclude Include="keystore.h" />
<ClInclude Include="misc.h" />
<ClInclude Include="plugin_hexchat.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="fish.c" />
<ClCompile Include="irc.c" />
<ClCompile Include="keystore.c" />
<ClCompile Include="misc.c" />
<ClCompile Include="plugin_hexchat.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@@ -32,6 +32,9 @@
<ClInclude Include="keystore.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="misc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="plugin_hexchat.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -46,6 +49,9 @@
<ClCompile Include="keystore.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="misc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="plugin_hexchat.c">
<Filter>Source Files</Filter>
</ClCompile>

View File

@@ -22,9 +22,8 @@
*/
#include "config.h"
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include "irc.h"
/**
@@ -32,26 +31,26 @@
* at spaces. The prefix and command is extracted from the message, and
* parameters_offset is set to the index of the first parameter.
*/
gboolean irc_parse_message(const char *words[],
bool irc_parse_message(const char *words[],
const char **prefix, const char **command,
size_t *parameters_offset) {
size_t w = 1;
if (prefix) *prefix = NULL;
if (command) *command = NULL;
/* See if the message starts with a prefix (sender user) */
// See if the message starts with a prefix (sender user)
if (words[w][0] == ':') {
if (prefix) *prefix = &words[w][1];
w++;
}
/* Check command */
if (words[w][0] == '\0') return FALSE;
// Check command
if (words[w][0] == '\0') return false;
if (command) *command = words[w];
w++;
*parameters_offset = w;
return TRUE;
return true;
}
@@ -66,15 +65,48 @@ gboolean irc_parse_message(const char *words[],
*/
char *irc_prefix_get_nick(const char *prefix) {
const char *end;
char *nick;
size_t length;
if (!prefix) return NULL;
/* Find end of nick */
// Find end of nick
end = prefix;
while (*end != '\0' && *end != '!' && *end != '@') end++;
/* Allocate string */
// Allocate string
length = end - prefix;
return g_strndup (prefix, length);
nick = malloc(length+1);
if (!nick) return NULL;
// Copy to string
memcpy(nick, prefix, length);
nick[length] = '\0';
return nick;
}
/**
* Compares two nick names. Return 0 if equal. Otherwise the return value is
* less than zero if a is less than b or greater than zero if a is greater
* than b.
*/
int irc_nick_cmp(const char *a, const char *b) {
char ac;
char bc;
char diff;
for (;;) {
ac = *(a++);
bc = *(b++);
// Change into IRC uppercase (see RFC 2812 section 2.2)
if (ac >= 'a' && ac <= '~') ac &= ~0x20;
if (bc >= 'a' && bc <= '~') bc &= ~0x20;
diff = ac - bc;
if (diff) return diff;
if (!ac) return 0;
}
}

View File

@@ -25,13 +25,14 @@
#ifndef IRC_H
#define IRC_H
#include <stdbool.h>
#include <stddef.h>
#include <glib.h>
gboolean irc_parse_message(const char *words[],
bool irc_parse_message(const char *words[],
const char **prefix, const char **command,
size_t *parameters_offset);
char *irc_prefix_get_nick(const char *prefix);
int irc_nick_cmp(const char *a, const char *b);
#endif

View File

@@ -22,13 +22,12 @@
*/
#include "config.h"
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include "irc.h"
#include "fish.h"
#include "misc.h"
#include "keystore.h"
#include "plugin_hexchat.h"
@@ -58,7 +57,7 @@ static GKeyFile *getConfigFile() {
static const char *get_keystore_password() {
return (keystore_password != NULL ?
keystore_password :
/* Silly default value... */
// Silly default value...
"blowinikey");
}
@@ -88,17 +87,17 @@ static gchar *get_nick_value(GKeyFile *keyfile, const char *nick, const char *it
* Extracts a key from the key store file.
*/
char *keystore_get_key(const char *nick) {
/* Get the key */
// Get the key
GKeyFile *keyfile = getConfigFile();
gchar *value = get_nick_value(keyfile, nick, "key");
g_key_file_free(keyfile);
if (!value) return NULL;
if (strncmp(value, "+OK ", 4) != 0) {
/* Key is stored in plaintext */
return value;
// Key is stored in plaintext
return import_glib_string(value);
} else {
/* Key is encrypted */
// Key is encrypted
const char *encrypted = value+4;
const char *password = get_keystore_password();
char *decrypted = fish_decrypt(password, strlen(password), encrypted);
@@ -110,10 +109,10 @@ char *keystore_get_key(const char *nick) {
/**
* Deletes a nick and the associated key in the key store file.
*/
static gboolean delete_nick(GKeyFile *keyfile, const char *nick) {
static bool delete_nick(GKeyFile *keyfile, const char *nick) {
gchar **group;
gchar **groups = g_key_file_get_groups(keyfile, NULL);
gboolean ok = FALSE;
bool ok = false;
for (group = groups; *group != NULL; group++) {
if (!irc_nick_cmp(*group, nick)) {
@@ -126,77 +125,58 @@ static gboolean delete_nick(GKeyFile *keyfile, const char *nick) {
return ok;
}
#if !GLIB_CHECK_VERSION(2,40,0)
/**
* Writes the key store file to disk.
*/
static gboolean keyfile_save_to_file (GKeyFile *keyfile, char *filename) {
gboolean ok;
/* Serialize */
static bool save_keystore(GKeyFile *keyfile) {
char *filename;
bool ok;
// Serialize
gsize file_length;
gchar *file_data = g_key_file_to_data(keyfile, &file_length, NULL);
if (!file_data)
return FALSE;
/* Write to file */
ok = g_file_set_contents (filename, file_data, file_length, NULL);
g_free(file_data);
return ok;
}
#endif
/**
* Writes the key store file to disk.
*/
static gboolean save_keystore(GKeyFile *keyfile) {
char *filename;
gboolean ok;
if (!file_data) return false;
// Write to file
filename = get_config_filename();
#if !GLIB_CHECK_VERSION(2,40,0)
ok = keyfile_save_to_file (keyfile, filename);
#else
ok = g_key_file_save_to_file (keyfile, filename, NULL);
#endif
g_free (filename);
ok = g_file_set_contents(filename, file_data, file_length, NULL);
g_free(filename);
g_free(file_data);
return ok;
}
/**
* Sets a key in the key store file.
*/
gboolean keystore_store_key(const char *nick, const char *key) {
bool keystore_store_key(const char *nick, const char *key) {
const char *password;
char *encrypted;
char *wrapped;
gboolean ok = FALSE;
bool ok = false;
GKeyFile *keyfile = getConfigFile();
/* Remove old key */
// Remove old key
delete_nick(keyfile, nick);
/* Add new key */
// Add new key
password = get_keystore_password();
if (password) {
/* Encrypt the password */
// Encrypt the password
encrypted = fish_encrypt(password, strlen(password), key);
if (!encrypted) goto end;
/* Prepend "+OK " */
// Prepend "+OK "
wrapped = g_strconcat("+OK ", encrypted, NULL);
g_free(encrypted);
/* Store encrypted in file */
// Store encrypted in file
g_key_file_set_string(keyfile, nick, "key", wrapped);
g_free(wrapped);
free(wrapped);
} else {
/* Store unencrypted in file */
// Store unencrypted in file
g_key_file_set_string(keyfile, nick, "key", key);
}
/* Save key store file */
// Save key store file
ok = save_keystore(keyfile);
end:
@@ -207,15 +187,23 @@ gboolean keystore_store_key(const char *nick, const char *key) {
/**
* Deletes a nick from the key store.
*/
gboolean keystore_delete_nick(const char *nick) {
bool keystore_delete_nick(const char *nick) {
GKeyFile *keyfile = getConfigFile();
/* Delete entry */
gboolean ok = delete_nick(keyfile, nick);
// Delete entry
bool ok = delete_nick(keyfile, nick);
/* Save */
// Save
if (ok) save_keystore(keyfile);
g_key_file_free(keyfile);
return ok;
}
void keystore_secure_free(void *ptr, size_t size) {
secure_erase(ptr, size);
free(ptr);
}

View File

@@ -25,13 +25,14 @@
#ifndef KEYSTORE_H
#define KEYSTORE_H
#include <stdbool.h>
#include <stddef.h>
#include <glib.h>
char *keystore_get_key(const char *nick);
gboolean keystore_store_key(const char *nick, const char *key);
gboolean keystore_delete_nick(const char *nick);
bool keystore_store_key(const char *nick, const char *key);
bool keystore_delete_nick(const char *nick);
void keystore_secure_free(void *ptr, size_t size);
#endif

54
plugins/fishlim/misc.c Normal file
View File

@@ -0,0 +1,54 @@
/*
Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se>
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:
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.
*/
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include "misc.h"
void secure_erase(void *ptr, size_t size) {
// "volatile" prevents this code from being optimized away
volatile char* volptr = ptr;
while (size--) *volptr++ = 0;
}
/**
* Re-allocates a string with the native allocator.
*/
char *import_glib_string(gchar *gstr) {
size_t size;
char *native;
if (g_mem_is_system_malloc()) return gstr;
size = strlen(gstr)+1;
native = malloc(size);
memcpy(native, gstr, size);
secure_erase(gstr, size);
g_free(gstr);
return native;
}

36
plugins/fishlim/misc.h Normal file
View File

@@ -0,0 +1,36 @@
/*
Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se>
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:
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.
*/
#ifndef MISC_H
#define MISC_H
void secure_erase(void *ptr, size_t size);
#ifdef __G_LIB_H__
char *import_glib_string(gchar *gstr);
#endif
#endif

View File

@@ -22,14 +22,17 @@
*/
#include "config.h"
#include <glib.h>
#include <stdlib.h>
#include <string.h>
// #pragma GCC visibility push(default)
#include "hexchat-plugin.h"
#define HEXCHAT_MAX_WORDS 32
// #pragma GCC visibility pop
//#define EXPORT __attribute((visibility("default")))
//#define EXPORT
#include "fish.h"
#include "keystore.h"
@@ -49,19 +52,27 @@ static hexchat_plugin *ph;
* Returns the path to the key store file.
*/
gchar *get_config_filename() {
char *filename_fs, *filename_utf8;
filename_utf8 = g_build_filename(hexchat_get_info(ph, "configdir"), "addon_fishlim.conf", NULL);
filename_fs = g_filename_from_utf8 (filename_utf8, -1, NULL, NULL, NULL);
g_free (filename_utf8);
return filename_fs;
return g_build_filename(hexchat_get_info(ph, "configdir"), "addon_fishlim.conf", NULL);
}
int irc_nick_cmp(const char *a, const char *b) {
return hexchat_nickcmp (ph, a, b);
/**
* Appends data to a string. Returns true if there was sufficient memory.
* Frees *s and returns false if an error occurs.
*/
static bool append(char **s, size_t *length, const char *data) {
size_t datalen = strlen(data);
char *extended = realloc(*s, *length + datalen + 1);
if (!extended) {
free(*s);
return false;
}
memcpy(extended + *length, data, datalen + 1);
*s = extended;
*length += datalen;
return true;
}
/*static int handle_debug(char *word[], char *word_eol[], void *userdata) {
hexchat_printf(ph, "debug incoming: ");
for (size_t i = 1; word[i] != NULL && word[i][0] != '\0'; i++) {
@@ -76,26 +87,26 @@ int irc_nick_cmp(const char *a, const char *b) {
*/
static int handle_outgoing(char *word[], char *word_eol[], void *userdata) {
const char *own_nick;
/* Encrypt the message if possible */
// Encrypt the message if possible
const char *channel = hexchat_get_info(ph, "channel");
char *encrypted = fish_encrypt_for_nick(channel, word_eol[1]);
if (!encrypted) return HEXCHAT_EAT_NONE;
/* Display message */
// Display message
own_nick = hexchat_get_info(ph, "nick");
hexchat_emit_print(ph, "Your Message", own_nick, word_eol[1], NULL);
/* Send message */
// Send message
hexchat_commandf(ph, "PRIVMSG %s :+OK %s", channel, encrypted);
g_free(encrypted);
free(encrypted);
return HEXCHAT_EAT_HEXCHAT;
}
/**
* Called when a channel message or private message is received.
*/
static int handle_incoming(char *word[], char *word_eol[], hexchat_event_attrs *attrs, void *userdata) {
static int handle_incoming(char *word[], char *word_eol[], void *userdata) {
const char *prefix;
const char *command;
const char *recipient;
@@ -103,19 +114,20 @@ static int handle_incoming(char *word[], char *word_eol[], hexchat_event_attrs *
const char *peice;
char *sender_nick;
char *decrypted;
char *message;
size_t w;
size_t ew;
size_t uw;
size_t length;
char prefix_char = 0;
GString *message;
if (!irc_parse_message((const char **)word, &prefix, &command, &w))
return HEXCHAT_EAT_NONE;
/* Topic (command 332) has an extra parameter */
// Topic (command 332) has an extra parameter
if (!strcmp(command, "332")) w++;
/* Look for encrypted data */
// Look for encrypted data
for (ew = w+1; ew < HEXCHAT_MAX_WORDS-1; ew++) {
const char *s = (ew == w+1 ? word[ew]+1 : word[ew]);
if (*s && (s[1] == '+' || s[1] == 'm')) { prefix_char = *(s++); }
@@ -124,70 +136,61 @@ static int handle_incoming(char *word[], char *word_eol[], hexchat_event_attrs *
}
return HEXCHAT_EAT_NONE;
has_encrypted_data: ;
/* Extract sender nick and recipient nick/channel */
// Extract sender nick and recipient nick/channel
sender_nick = irc_prefix_get_nick(prefix);
recipient = word[w];
/* Try to decrypt with these (the keys are searched for in the key store) */
// Try to decrypt with these (the keys are searched for in the key store)
encrypted = word[ew+1];
decrypted = fish_decrypt_from_nick(recipient, encrypted);
if (!decrypted) decrypted = fish_decrypt_from_nick(sender_nick, encrypted);
/* Check for error */
// Check for error
if (!decrypted) goto decrypt_error;
/* Build unecrypted message */
message = g_string_sized_new (100); /* TODO: more accurate estimation of size */
g_string_append (message, "RECV");
if (attrs->server_time_utc)
{
GTimeVal tv = { (glong)attrs->server_time_utc, 0 };
char *timestamp = g_time_val_to_iso8601 (&tv);
g_string_append (message, " @time=");
g_string_append (message, timestamp);
g_free (timestamp);
}
// Build unecrypted message
message = NULL;
length = 0;
if (!append(&message, &length, "RECV")) goto decrypt_error;
for (uw = 1; uw < HEXCHAT_MAX_WORDS; uw++) {
if (word[uw][0] != '\0')
g_string_append_c (message, ' ');
if (word[uw][0] != '\0' && !append(&message, &length, " ")) goto decrypt_error;
if (uw == ew) {
/* Add the encrypted data */
// Add the encrypted data
peice = decrypted;
uw++; /* Skip "OK+" */
uw++; // Skip "OK+"
if (ew == w+1) {
/* Prefix with colon, which gets stripped out otherwise */
g_string_append_c (message, ':');
// Prefix with colon, which gets stripped out otherwise
if (!append(&message, &length, ":")) goto decrypt_error;
}
if (prefix_char) {
g_string_append_c (message, prefix_char);
char prefix_str[2] = { prefix_char, '\0' };
if (!append(&message, &length, prefix_str)) goto decrypt_error;
}
} else {
/* Add unencrypted data (for example, a prefix from a bouncer or bot) */
// Add unencrypted data (for example, a prefix from a bouncer or bot)
peice = word[uw];
}
g_string_append (message, peice);
if (!append(&message, &length, peice)) goto decrypt_error;
}
g_free(decrypted);
free(decrypted);
/* Simulate unencrypted message */
/* hexchat_printf(ph, "simulating: %s\n", message->str); */
hexchat_command(ph, message->str);
g_string_free (message, TRUE);
g_free(sender_nick);
// Simulate unencrypted message
//hexchat_printf(ph, "simulating: %s\n", message);
hexchat_command(ph, message);
free(message);
free(sender_nick);
return HEXCHAT_EAT_HEXCHAT;
decrypt_error:
g_free(decrypted);
g_free(sender_nick);
free(decrypted);
free(sender_nick);
return HEXCHAT_EAT_NONE;
}
@@ -198,23 +201,23 @@ static int handle_setkey(char *word[], char *word_eol[], void *userdata) {
const char *nick;
const char *key;
/* Check syntax */
// Check syntax
if (*word[2] == '\0') {
hexchat_printf(ph, "%s\n", usage_setkey);
return HEXCHAT_EAT_HEXCHAT;
}
if (*word[3] == '\0') {
/* /setkey password */
// /setkey password
nick = hexchat_get_info(ph, "channel");
key = word_eol[2];
} else {
/* /setkey #channel password */
// /setkey #channel password
nick = word[2];
key = word_eol[3];
}
/* Set password */
// Set password
if (keystore_store_key(nick, key)) {
hexchat_printf(ph, "Stored key for %s\n", nick);
} else {
@@ -230,15 +233,15 @@ static int handle_setkey(char *word[], char *word_eol[], void *userdata) {
static int handle_delkey(char *word[], char *word_eol[], void *userdata) {
const char *nick;
/* Check syntax */
// Check syntax
if (*word[2] == '\0' || *word[3] != '\0') {
hexchat_printf(ph, "%s\n", usage_delkey);
return HEXCHAT_EAT_HEXCHAT;
}
nick = g_strstrip (word_eol[2]);
nick = word_eol[2];
/* Delete the given nick from the key store */
// Delete the given nick from the key store
if (keystore_delete_nick(nick)) {
hexchat_printf(ph, "Deleted key for %s\n", nick);
} else {
@@ -279,11 +282,11 @@ int hexchat_plugin_init(hexchat_plugin *plugin_handle,
/* Add handlers */
hexchat_hook_command(ph, "", HEXCHAT_PRI_NORM, handle_outgoing, NULL, NULL);
hexchat_hook_server_attrs(ph, "NOTICE", HEXCHAT_PRI_NORM, handle_incoming, NULL);
hexchat_hook_server_attrs(ph, "PRIVMSG", HEXCHAT_PRI_NORM, handle_incoming, NULL);
/* hexchat_hook_server(ph, "RAW LINE", HEXCHAT_PRI_NORM, handle_debug, NULL); */
hexchat_hook_server_attrs(ph, "TOPIC", HEXCHAT_PRI_NORM, handle_incoming, NULL);
hexchat_hook_server_attrs(ph, "332", HEXCHAT_PRI_NORM, handle_incoming, NULL);
hexchat_hook_server(ph, "NOTICE", HEXCHAT_PRI_NORM, handle_incoming, NULL);
hexchat_hook_server(ph, "PRIVMSG", HEXCHAT_PRI_NORM, handle_incoming, NULL);
//hexchat_hook_server(ph, "RAW LINE", HEXCHAT_PRI_NORM, handle_debug, NULL);
hexchat_hook_server(ph, "TOPIC", HEXCHAT_PRI_NORM, handle_incoming, NULL);
hexchat_hook_server(ph, "332", HEXCHAT_PRI_NORM, handle_incoming, NULL);
hexchat_printf(ph, "%s plugin loaded\n", plugin_name);
/* Return success */

View File

@@ -26,7 +26,6 @@
#define PLUGIN_HEXCHAT_H
gchar *get_config_filename();
int irc_nick_cmp (const char *, const char *);
#endif

View File

@@ -47,7 +47,7 @@ static int decrypt(int nick_count, char *nicks[]) {
return 1;
success:
fprintf(stderr, "Decrypted text >>>%s<<<\n", msg);
g_free(msg);
free(msg);
}
return 0;
}
@@ -64,7 +64,7 @@ static int encrypt(int nick_count, char *nicks[]) {
char *encrypted = fish_encrypt_for_nick(nicks[i], message);
if (encrypted) {
fprintf(stderr, "Encrypted [%s]: >>>%s<<<\n", nicks[i], encrypted);
g_free(encrypted);
free(encrypted);
} else {
error = true;
}

View File

@@ -14,27 +14,54 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <glib.h>
/*
typedef int (*MYPROC)(HWND,HWND,char*,char*,BOOL,BOOL);
char *split(char *text, char separator)
int dllProc(char *name, char *data){
HINSTANCE hinstLib;
hinstLib = LoadLibrary("mpcinfo");
//MYPROC proc;
int res;
if (hinstLib != NULL){
//proc = ;
if ((MYPROC) GetProcAddress(hinstLib, name)!=NULL){
res=(MYPROC)(NULL,NULL,data,NULL,TRUE,TRUE);
}
else{fprintf(stderr,"can't get proc: %s\n",name);res=-2;}
}
else{fprintf(stderr,"can't access dll\n");return -1;}
FreeLibrary(hinstLib);
return res;
}
*/
/*
int dllProc(char *name, char *data)
{
int pos = -1;
size_t i;
for (i = 0; i < strlen(text); i++)
static HMODULE lib = NULL;
if (!lib)
{
if (text[i] == separator) {
pos = i;
i = strlen(text) + 1;
lib = LoadLibraryA ("mpcinfo");
if (!lib)
{
return FALSE;
}
FreeLibrary (lib);
}
if (pos == -1)
{
return text;
}
return TRUE;
}
*/
text[pos] = 0;
return &(text[pos + 1]);
char *split(char *text, char seperator){
//if (DEBUG==1) putlog("splitting");
int i;int pos=-1;
for (i=0;i<strlen(text);i++){
if (text[i]==seperator){pos=i;i=strlen(text)+1;}
}
if (pos==-1) return text;
text[pos]=0;
return &(text[pos+1]);
}
int endsWith(char *text, char *suffix){
@@ -44,32 +71,21 @@ int endsWith(char *text, char *suffix){
return 0;
}
int inStr(char *s1, size_t sl1, char *s2)
{
size_t i;
for (i = 0; i < sl1 - strlen(s2); i++)
{
size_t j;
for (j = 0; j < strlen(s2); j++)
{
if (s1[i + j] != s2[j])
{
j = strlen(s2) + 2;
}
}
if (j == strlen(s2))
{
return i;
int inStr(char *s1, int sl1, char *s2){
//if (DEBUG==1) putlog("checking instr");
int i;int j;
for(i=0;i<sl1-strlen(s2);i++){
for (j=0;j<strlen(s2);j++){
if (s1[i+j]!=s2[j]) j=strlen(s2)+2;
}
if (j==strlen(s2)) return i;
}
return -1;
}
static char *subString(char *text, int first, int length, int spcKill){
//if (DEBUG==1) putlog("creating substring");
char *ret = g_new (char, length + 1);
char *ret=(char*) calloc (length+1,sizeof(char)); //malloc(sizeof(char)*(length+1));
int i;
ret[length]=0;
for (i=0;i<length;i++){
@@ -91,7 +107,7 @@ static char *substring(char *text, int first, int length){return subString(text,
char *readLine(FILE *f){
//if (DEBUG==1) putlog("reading line from file");
char *buffer = g_new (char, 1024);
char *buffer=(char*)calloc(1024,sizeof(char)); //malloc(sizeof(char)*1024);
int pos=0;
int cc=0;
while((cc!=EOF)&&(pos<1024)&&(cc!=10)){
@@ -105,19 +121,14 @@ char *readLine(FILE *f){
return buffer;
}
char *toUpper(char *text)
{
char *ret = (char*) calloc(strlen(text) + 1, sizeof(char));
size_t i;
for (i = 0; i < strlen(text); i++)
{
ret[i] = toupper(text[i]);
}
ret[strlen(text)] = 0;
return ret;
char *toUpper(char *text){
//if (DEBUG==1) putlog("converting text to upper case");
char *ret=(char*) calloc(strlen(text)+1,sizeof(char));
int i;
for (i=0;i<strlen(text);i++) ret[i]=toupper(text[i]);
ret[strlen(text)]=0;
//if (DEBUG==1) putlog("uc done");
return ret;
}
static char *str3cat(char *s1, char *s2, char *s3){

View File

@@ -75,25 +75,62 @@ static char MODES [][13]={"Stereo","Joint-Stereo","Dual-Channel","Mono"};
int iPow(int x, int y){return (int)(pow((double)x,(double) y));}
int str2int(char *text)
{
int ret = 0;
size_t i;
for (i = 1; i <= strlen(text); i++)
{
if ((text[strlen(text) - i] > 57) || (text[strlen(text) - i] < 48))
{
hexchat_printf(ph, "invalid char in string: %i", (int) text[strlen(text) - i]);
return 255;
int str2int(char *text){
//if (DEBUG==1) putlog("converting string to int");
int i;
int ret=0;
for (i=1;i<=strlen(text);i++){
if ((text[strlen(text)-i]>57)||(text[strlen(text)-i]<48)){
hexchat_printf(ph,"invalid char in string: %i",text[strlen(text)-i]);
return 255;
}
ret+=((int)text[strlen(text)-i]-48)*iPow(10,i-1);
}
//hexchat_printf(ph, "str2int(%s)=%i",text,ret);
//if (DEBUG==1) putlog("int converted");
return ret;
}
/*
static int getSize(char *file){
//if (DEBUG==1) putlog("reading filesize");
struct stat info;
if (stat(file,&info)!=0) return -1;
return info.st_size;
}*/
/*
int inStr(char *s1, int sl1, char *s2){
//if (DEBUG==1) putlog("checking instr");
int i;int j;
for(i=0;i<sl1-strlen(s2);i++){
for (j=0;j<strlen(s2);j++){
if (s1[i+j]!=s2[j]) j=strlen(s2)+2;
}
ret += ((int) text[strlen(text) - i] - 48)*iPow(10, i - 1);
if (j==strlen(s2)) return i;
}
return -1;
}
static char *subString(char *text, int first, int length, int spcKill){
//if (DEBUG==1) putlog("creating substring");
char *ret=(char*) calloc (length+1,sizeof(char)); //malloc(sizeof(char)*(length+1));
ret[length]=0;int i;
for (i=0;i<length;i++){
ret[i]=text[i+first];
//if (ret[i]==0) ret[i]='0';
}
if (spcKill==1){
for (i=length-1;i>=0;i--){
if (ret[i]==32) ret[i]=0;
else i=-1;
}
}
//if (DEBUG==1) putlog("substring created");
return ret;
}
static char *substring(char *text, int first, int length){return subString(text,first,length,0);} //1
*/
static char *tagExtract(char *tag, int tagLen, char* info){
//if (DEBUG==1) putlog("extracting tag");
int pos, len, i;
@@ -167,28 +204,23 @@ struct tagInfo readID3V1(char *file){
return ret;
}
char *extractID3Genre(char *tag)
{
if (tag[strlen(tag) - 1] == ')')
{
tag[strlen(tag) - 1] = 0;
tag = &tag[1];
return GENRES[str2int(tag)];
}
else
{
size_t i;
for (i = 0; i < strlen(tag); i++)
{
if (tag[i] == ')')
{
tag = &tag[i] + 1;
return tag;
}
}
}
return "[152] failed";
char *extractID3Genre(char *tag){
//if (DEBUG==1) putlog("extracting id3 genre");
if (tag[strlen(tag)-1]==')'){
tag[strlen(tag)-1]=0;
tag=&tag[1];
return GENRES[str2int(tag)];
//return tag;
}
else{
int i;
//hexchat_print(ph, "Using 2 criteria");
for (i=0;i<strlen(tag);i++){
if (tag[i]==')'){ tag=&tag[i]+1;return tag;}
//return tag;
}
}
return "[152] failed";
}
struct tagInfo readID3V2(char *file){

View File

@@ -48,20 +48,12 @@ static int mpc_tell(char *word[], char *word_eol[], void *userdata){
HWND hwnd = FindWindow("MediaPlayerClassicW",NULL);
if (hwnd==0) {hexchat_print(ph, randomLine(notRunTheme));return HEXCHAT_EAT_ALL;}
tTitle = g_new(char, 1024);
tTitle=(char*)malloc(sizeof(char)*1024);
GetWindowText(hwnd, tTitle, 1024);
zero = strstr (tTitle, " - Media Player Classic");
if (zero != NULL)
{
zero[0] = 0;
}
else
{
g_free(tTitle);
hexchat_print(ph, "pattern not found");
return HEXCHAT_EAT_ALL;
}
zero=strstr(tTitle," - Media Player Classic");
if (zero!=NULL) zero[0]=0;
else hexchat_print(ph,"pattern not found");
if ((tTitle[1]==':')&&(tTitle[2]=='\\')){
//hexchat_print(ph,"seams to be full path");
if (endsWith(tTitle,".mp3")==1){
@@ -90,8 +82,7 @@ static int mpc_tell(char *word[], char *word_eol[], void *userdata){
//mp3Line=intReplace(mp3Line,"%perc",perc);
//mp3Line=replace(mp3Line,"%plTitle",title);
mp3Line=replace(mp3Line,"%file",tTitle);
g_free(tTitle);
hexchat_command(ph, mp3Line);
hexchat_command(ph, mp3Line);
return HEXCHAT_EAT_ALL;
}
}
@@ -120,16 +111,14 @@ static int mpc_tell(char *word[], char *word_eol[], void *userdata){
//oggLine=intReplace(oggLine,"%perc",perc);
//oggLine=replace(oggLine,"%plTitle",title);
oggLine=replace(oggLine,"%file",tTitle);
g_free(tTitle);
hexchat_command(ph, oggLine);
hexchat_command(ph, oggLine);
return HEXCHAT_EAT_ALL;
}
}
}
line=randomLine(titleTheme);
line=replace(line,"%title", tTitle);
g_free(tTitle);
hexchat_command(ph, line);
hexchat_command(ph,line);
return HEXCHAT_EAT_ALL;
}

View File

@@ -63,15 +63,13 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MPCINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>mpcinfo.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
@@ -83,15 +81,13 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;MPCINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>mpcinfo.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>

View File

@@ -25,18 +25,14 @@ static int getOggInt(char *buff, int beg, int bytes){
return ret;
}
static char *upperStr(char *text)
{
char *ret = (char*) malloc(sizeof(char)*(strlen(text) + 1));
size_t i;
for (i = 0; i < strlen(text); i++)
{
ret[i] = toupper(text[i]);
}
ret[strlen(text)] = 0;
static char *upperStr(char *text){
//if (DEBUG==1) putlog("converting text to uc");
//printf("upperStr(%s)\n",text);
int i;
char *ret=(char*) malloc(sizeof(char)*(strlen(text)+1));
ret[strlen(text)]=0;
for (i=0;i<strlen(text);i++) ret[i]=toupper(text[i]);
//printf("Result: %s\n",ret);
return ret;
}

View File

@@ -49,32 +49,24 @@ void printThemes(){
hexchat_printf(ph,"\nTitle-Theme:\n");printTheme(titleTheme);
}
void cbFix(char *line)
{
size_t i;
for (i = 0; i < strlen(line); i++)
{
size_t j;
void cbFix(char *line){
//if (DEBUG==1) putlog("cbfix");
int i, j;
for (i=0;i<strlen(line);i++){
if (line[i]=='%'){
if ((line[i+1]=='C')||(line[i+1]=='B')||(line[i+1]=='U')||(line[i+1]=='O')||(line[i+1]=='R')){
if(line[i+1]=='C') line[i]=3;
if(line[i+1]=='B') line[i]=2;
if(line[i+1]=='U') line[i]=37;
if(line[i+1]=='O') line[i]=17;
if(line[i+1]=='R') line[i]=26;
if (line[i] == '%')
{
if ((line[i + 1] == 'C') || (line[i + 1] == 'B') || (line[i + 1] == 'U') || (line[i + 1] == 'O') || (line[i + 1] == 'R'))
{
if (line[i + 1] == 'C') line[i] = 3;
if (line[i + 1] == 'B') line[i] = 2;
if (line[i + 1] == 'U') line[i] = 37;
if (line[i + 1] == 'O') line[i] = 17;
if (line[i + 1] == 'R') line[i] = 26;
for (j = i + 1; j < strlen(line) - 1; j++)
{
line[j] = line[j + 1];
}
line[strlen(line) - 1] = 0;
}
}
}
for (j=i+1;j<strlen(line)-1;j++) line[j]=line[j+1];
line[strlen(line)-1]=0;
}
}
}
//if (DEBUG==1) putlog("cbfix done");
}
struct theme themeAdd(struct theme data, char *info){

View File

@@ -6,13 +6,12 @@ libdir = $(hexchatlibdir)
lib_LTLIBRARIES = perl.la
perl_la_SOURCES = perl.c
perl_la_LDFLAGS = $(PERL_LDFLAGS) $(PLUGIN_LDFLAGS) -module
perl_la_LIBADD = $(PERL_LIBS) $(GLIB_LIBS)
perl_la_CFLAGS = $(PERL_CFLAGS) $(GLIB_CFLAGS) -I$(top_srcdir)/src/common
perl_la_LDFLAGS = -avoid-version -module
perl_la_LIBADD = $(PERL_LDFLAGS)
BUILT_SOURCES = hexchat.pm.h irc.pm.h
CLEANFILES = $(BUILT_SOURCES)
#CFLAGS = @CFLAGS@ -Wno-unused
AM_CPPFLAGS = $(PERL_CFLAGS) $(COMMON_CFLAGS) -I$(srcdir)/../../src/common
CLEANFILES = hexchat.pm.h irc.pm.h
hexchat.pm.h irc.pm.h: lib/HexChat.pm lib/Xchat.pm lib/HexChat/Embed.pm \
lib/HexChat/List/Network.pm lib/HexChat/List/Network/Entry.pm \
lib/HexChat/List/Network/AutoJoin.pm lib/IRC.pm

View File

@@ -16,8 +16,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -33,9 +31,8 @@
#include <dirent.h>
#endif
#include <glib.h>
#undef PACKAGE
#include "../../config.h"
#include "hexchat-plugin.h"
@@ -78,26 +75,37 @@ thread_mbox (char *str)
static void
perl_auto_load_from_path (const char *path)
{
char *search_path = g_build_filename (path, "*.pl", NULL);
WIN32_FIND_DATAA find_data;
HANDLE find_handle = FindFirstFileA (search_path, &find_data);
WIN32_FIND_DATA find_data;
HANDLE find_handle;
char *search_path;
int path_len = strlen (path);
/* +6 for \*.pl and \0 */
search_path = malloc(path_len + 6);
sprintf (search_path, "%s\\*.pl", path);
find_handle = FindFirstFile (search_path, &find_data);
if (find_handle != INVALID_HANDLE_VALUE)
{
do
{
if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 && (find_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0)
if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
||find_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
{
char *full_path = g_build_filename (path, find_data.cFileName, NULL);
char *full_path =
malloc (path_len + strlen (find_data.cFileName) + 2);
sprintf (full_path, "%s\\%s", path, find_data.cFileName);
perl_load_file (full_path);
g_free (full_path);
free (full_path);
}
}
while (FindNextFileA (find_handle, &find_data) != 0);
while (FindNextFile (find_handle, &find_data) != 0);
FindClose (find_handle);
}
g_free (search_path);
free (search_path);
}
#else
static void
@@ -107,16 +115,14 @@ perl_auto_load_from_path (const char *path)
struct dirent *ent;
dir = opendir (path);
if (dir)
{
while ((ent = readdir (dir)))
{
if (dir) {
while ((ent = readdir (dir))) {
int len = strlen (ent->d_name);
if (len > 3 && strcasecmp (".pl", ent->d_name + len - 3) == 0)
{
char *file = g_build_filename (path, ent->d_name, NULL);
if (len > 3 && strcasecmp (".pl", ent->d_name + len - 3) == 0) {
char *file = malloc (len + strlen (path) + 2);
sprintf (file, "%s/%s", path, ent->d_name);
perl_load_file (file);
g_free (file);
free (file);
}
}
closedir (dir);
@@ -139,10 +145,31 @@ perl_auto_load (void *unused)
/* don't pollute the filesystem with script files, this only causes misuse of the folders
* only use ~/.config/hexchat/addons/ and %APPDATA%\HexChat\addons */
sub_dir = g_build_filename (xdir, "addons", NULL);
perl_auto_load_from_path (sub_dir);
g_free (sub_dir);
#if 0
/* autoload from ~/.config/hexchat/ or %APPDATA%\HexChat\ on win32 */
perl_auto_load_from_path (xdir);
#endif
sub_dir = malloc (strlen (xdir) + 8);
strcpy (sub_dir, xdir);
strcat (sub_dir, "/addons");
perl_auto_load_from_path (sub_dir);
free (sub_dir);
#if 0
#ifdef WIN32
/* autoload from C:\Program Files\HexChat\plugins\ */
sub_dir = malloc (1025 + 9);
copied = GetModuleFileName( 0, sub_dir, 1024 );
sub_dir[copied] = '\0';
slash = strrchr( sub_dir, '\\' );
if( slash != NULL ) {
*slash = '\0';
}
perl_auto_load_from_path ( strncat (sub_dir, "\\plugins", 9));
free (sub_dir);
#endif
#endif
return 0;
}
@@ -261,19 +288,7 @@ list_item_to_sv ( hexchat_list *list, const char *const *fields )
field_value = newSVuv (hexchat_list_int (ph, list, field_name));
break;
case 't':
/* From perldoc for Perl's own timelocal() and timegm():
* <quote>
* On perl versions older than 5.12.0, the range of dates that can be actually be handled depends on the size of time_t (usually a signed integer) on the given platform.
* As of version 5.12.0, perl has stopped using the underlying time library of the operating system it's running on and has its own implementation of those routines with a
* safe range of at least +/ 2**52 (about 142 million years).
* </quote>
*
* This is further confirmed from looking at the source for Time::Local - it's a Perl module and the implementations of timelocal() and timegm() use simple addition and
* subtraction of numbers. Perl automatically promotes numbers from int32_t (IV) to uint32_t (UV) to 64-bit IEEE754 double (NV) as required.
*
* This means that using a double (NV) for our own time_t suffers from the same assumptions that Perl's own functions do.
*/
field_value = newSVnv ((const NV) hexchat_list_time (ph, list, field_name));
field_value = newSVnv (hexchat_list_time (ph, list, field_name));
break;
default:
field_value = &PL_sv_undef;
@@ -357,7 +372,7 @@ fd_cb (int fd, int flags, void *userdata)
if (data->userdata) {
SvREFCNT_dec (data->userdata);
}
g_free (data);
free (data);
}
}
@@ -721,7 +736,7 @@ XS (XS_HexChat_send_modes)
if (SvROK (ST (0))) {
p_targets = (AV*) SvRV (ST (0));
target_count = av_len (p_targets) + 1;
targets = g_new (const char *, target_count);
targets = malloc (target_count * sizeof (char *));
for (i = 0; i < target_count; i++ ) {
elem = av_fetch (p_targets, i, 0);
@@ -732,13 +747,13 @@ XS (XS_HexChat_send_modes)
}
}
} else{
targets = g_new (const char *, 1);
targets = malloc (sizeof (char *));
targets[0] = SvPV_nolen (ST (0));
target_count = 1;
}
if (target_count == 0) {
g_free ((char**) targets);
free (targets);
XSRETURN_EMPTY;
}
@@ -750,7 +765,7 @@ XS (XS_HexChat_send_modes)
}
hexchat_send_modes (ph, targets, target_count, modes_per_line, sign, mode);
g_free ((char**) targets);
free (targets);
}
}
static
@@ -868,7 +883,11 @@ XS (XS_HexChat_hook_server)
userdata = ST (3);
package = ST (4);
data = NULL;
data = g_new (HookData, 1);
data = malloc (sizeof (HookData));
if (data == NULL) {
XSRETURN_UNDEF;
}
data->callback = newSVsv (callback);
data->userdata = newSVsv (userdata);
data->depth = 0;
@@ -913,7 +932,11 @@ XS (XS_HexChat_hook_command)
package = ST (5);
data = NULL;
data = g_new (HookData, 1);
data = malloc (sizeof (HookData));
if (data == NULL) {
XSRETURN_UNDEF;
}
data->callback = newSVsv (callback);
data->userdata = newSVsv (userdata);
data->depth = 0;
@@ -949,7 +972,11 @@ XS (XS_HexChat_hook_print)
userdata = ST (3);
package = ST (4);
data = g_new (HookData, 1);
data = malloc (sizeof (HookData));
if (data == NULL) {
XSRETURN_UNDEF;
}
data->callback = newSVsv (callback);
data->userdata = newSVsv (userdata);
data->depth = 0;
@@ -983,7 +1010,11 @@ XS (XS_HexChat_hook_timer)
userdata = ST (2);
package = ST (3);
data = g_new (HookData, 1);
data = malloc (sizeof (HookData));
if (data == NULL) {
XSRETURN_UNDEF;
}
data->callback = newSVsv (callback);
data->userdata = newSVsv (userdata);
data->ctx = hexchat_get_context (ph);
@@ -1033,7 +1064,11 @@ XS (XS_HexChat_hook_fd)
}
#endif
data = g_new (HookData, 1);
data = malloc (sizeof (HookData));
if (data == NULL) {
XSRETURN_UNDEF;
}
data->callback = newSVsv (callback);
data->userdata = newSVsv (userdata);
data->depth = 0;
@@ -1073,7 +1108,7 @@ XS (XS_HexChat_unhook)
SvREFCNT_dec (userdata->package);
}
g_free (userdata);
free (userdata);
}
XSRETURN (retCount);
}

View File

@@ -62,7 +62,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PERL520_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..;$(PerlPath)\lib\CORE;$(IntDir);..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(PerlPath)\lib\CORE;$(IntDir);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@@ -70,8 +70,8 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(OutDir);$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(PerlLib).lib;$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(PerlLib).lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>perl.def</ModuleDefinitionFile>
<DelayLoadDLLs>$(PerlLib).dll;%(DelayLoadDLLs)</DelayLoadDLLs>
</Link>
@@ -91,7 +91,7 @@ move hexchat.pm.h "$(IntDir)"</Command>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;PERL520_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..;$(PerlPath)\lib\CORE;$(IntDir);..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(PerlPath)\lib\CORE;$(IntDir);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@@ -99,8 +99,8 @@ move hexchat.pm.h "$(IntDir)"</Command>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(OutDir);$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(PerlLib).lib;$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(PerlLib).lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>perl.def</ModuleDefinitionFile>
<DelayLoadDLLs>$(PerlLib).dll;%(DelayLoadDLLs)</DelayLoadDLLs>
</Link>
@@ -122,4 +122,4 @@ move hexchat.pm.h "$(IntDir)"</Command>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@@ -1,8 +1,10 @@
EXTRA_DIST =
libdir = $(hexchatlibdir)
lib_LTLIBRARIES = python.la
python_la_SOURCES = python.c
python_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
python_la_LIBADD = $(PY_LIBS) $(GLIB_LIBS)
python_la_CFLAGS = $(PY_CFLAGS) $(GLIB_CFLAGS) -I$(top_srcdir)/src/common
python_la_LDFLAGS = -avoid-version -module
python_la_LIBADD = $(PY_LIBS)
AM_CPPFLAGS = $(PY_CFLAGS) $(COMMON_CFLAGS) -I$(srcdir)/../../src/common

View File

@@ -51,8 +51,6 @@
*
*/
#include "config.h"
#include <glib.h>
#include <glib/gstdio.h>
#include <string.h>
@@ -66,9 +64,9 @@
#include <dirent.h>
#endif
#include "../../config.h"
#include "hexchat-plugin.h"
#undef _POSIX_C_SOURCE /* Avoid warnings from /usr/include/features.h */
#undef _XOPEN_SOURCE
#undef _POSIX_C_SOURCE /* Avoid warning: also in /usr/include/features.h from glib.h */
#include <Python.h>
#include <structmember.h>
#include <pythread.h>
@@ -451,8 +449,10 @@ Util_BuildEOLList(char *word[])
PyList_SetItem(list, i - 1, uni_part);
}
g_free (last);
g_free (accum);
if (last)
g_free (last);
if (accum)
g_free (accum);
return list;
}
@@ -802,7 +802,9 @@ Callback_ThreadTimer(void *userdata)
/* We keep this information global, so we can reset it when the
* deinit function is called. */
/* XXX This should be somehow bound to the printing context. */
static GString *xchatout_buffer = NULL;
static char *xchatout_buffer = NULL;
static int xchatout_buffer_size = 0;
static int xchatout_buffer_pos = 0;
static PyObject *
XChatOut_New()
@@ -826,42 +828,76 @@ XChatOut_dealloc(PyObject *self)
static PyObject *
XChatOut_write(PyObject *self, PyObject *args)
{
gboolean add_space;
int new_buffer_pos, data_size, print_limit, add_space;
char *data, *pos;
if (!PyArg_ParseTuple(args, "s:write", &data))
if (!PyArg_ParseTuple(args, "s#:write", &data, &data_size))
return NULL;
if (!data || !*data) {
Py_RETURN_NONE;
if (!data_size) {
Py_INCREF(Py_None);
return Py_None;
}
BEGIN_XCHAT_CALLS(RESTORE_CONTEXT|ALLOW_THREADS);
if (((XChatOutObject *)self)->softspace) {
add_space = TRUE;
add_space = 1;
((XChatOutObject *)self)->softspace = 0;
} else {
add_space = FALSE;
}
g_string_append (xchatout_buffer, data);
/* If not end of line add space to continue buffer later */
if (add_space && xchatout_buffer->str[xchatout_buffer->len - 1] != '\n')
{
g_string_append_c (xchatout_buffer, ' ');
}
/* If there is an end of line print up to that */
if ((pos = strrchr (xchatout_buffer->str, '\n')))
{
*pos = '\0';
hexchat_print (ph, xchatout_buffer->str);
/* Then remove it from buffer */
g_string_erase (xchatout_buffer, 0, pos - xchatout_buffer->str + 1);
add_space = 0;
}
if (xchatout_buffer_size-xchatout_buffer_pos < data_size+add_space) {
char *new_buffer;
/* This buffer grows whenever needed, and does not
* shrink. If we ever implement unloading of the
* python interface, we must find some way to free
* this buffer as well. */
xchatout_buffer_size += data_size*2+16;
new_buffer = g_realloc(xchatout_buffer, xchatout_buffer_size);
if (new_buffer == NULL) {
hexchat_print(ph, "Not enough memory to print");
/* The system is out of resources. Let's help. */
g_free(xchatout_buffer);
xchatout_buffer = NULL;
xchatout_buffer_size = 0;
xchatout_buffer_pos = 0;
/* Return something valid, since we have
* already warned the user, and he probably
* won't be able to notice this exception. */
goto exit;
}
xchatout_buffer = new_buffer;
}
memcpy(xchatout_buffer+xchatout_buffer_pos, data, data_size);
print_limit = new_buffer_pos = xchatout_buffer_pos+data_size;
pos = xchatout_buffer+print_limit;
if (add_space && *(pos-1) != '\n') {
*pos = ' ';
*(pos+1) = 0;
new_buffer_pos++;
}
while (*pos != '\n' && print_limit > xchatout_buffer_pos) {
pos--;
print_limit--;
}
if (*pos == '\n') {
/* Crop it, inserting the string limiter there. */
*pos = 0;
hexchat_print(ph, xchatout_buffer);
if (print_limit < new_buffer_pos) {
/* There's still data to be printed. */
print_limit += 1; /* Include the limiter. */
xchatout_buffer_pos = new_buffer_pos-print_limit;
memmove(xchatout_buffer, xchatout_buffer+print_limit,
xchatout_buffer_pos);
} else {
xchatout_buffer_pos = 0;
}
} else {
xchatout_buffer_pos = new_buffer_pos;
}
exit:
END_XCHAT_CALLS();
Py_RETURN_NONE;
Py_INCREF(Py_None);
return Py_None;
}
#define OFF(x) offsetof(XChatOutObject, x)
@@ -1013,7 +1049,8 @@ Context_set(ContextObject *self, PyObject *args)
{
PyObject *plugin = Plugin_GetCurrent();
Plugin_SetContext(plugin, self->context);
Py_RETURN_NONE;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
@@ -1026,7 +1063,8 @@ Context_command(ContextObject *self, PyObject *args)
hexchat_set_context(ph, self->context);
hexchat_command(ph, text);
END_XCHAT_CALLS();
Py_RETURN_NONE;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
@@ -1039,7 +1077,8 @@ Context_prnt(ContextObject *self, PyObject *args)
hexchat_set_context(ph, self->context);
hexchat_print(ph, text);
END_XCHAT_CALLS();
Py_RETURN_NONE;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
@@ -1084,7 +1123,8 @@ Context_get_info(ContextObject *self, PyObject *args)
info = hexchat_get_info(ph, name);
END_XCHAT_CALLS();
if (info == NULL) {
Py_RETURN_NONE;
Py_INCREF(Py_None);
return Py_None;
}
return PyUnicode_FromString(info);
}
@@ -1367,7 +1407,11 @@ static Hook *
Plugin_AddHook(int type, PyObject *plugin, PyObject *callback,
PyObject *userdata, char *name, void *data)
{
Hook *hook = g_new(Hook, 1);
Hook *hook = (Hook *) g_malloc(sizeof(Hook));
if (hook == NULL) {
PyErr_NoMemory();
return NULL;
}
hook->type = type;
hook->plugin = plugin;
Py_INCREF(callback);
@@ -1421,7 +1465,8 @@ Plugin_RemoveHook(PyObject *plugin, Hook *hook)
hook));
Py_DECREF(hook->callback);
Py_DECREF(hook->userdata);
g_free(hook->name);
if (hook->name)
g_free(hook->name);
g_free(hook);
}
}
@@ -1440,7 +1485,8 @@ Plugin_RemoveAllHooks(PyObject *plugin)
}
Py_DECREF(hook->callback);
Py_DECREF(hook->userdata);
g_free(hook->name);
if (hook->name)
g_free(hook->name);
g_free(hook);
list = list->next;
}
@@ -1669,7 +1715,8 @@ Module_hexchat_command(PyObject *self, PyObject *args)
BEGIN_XCHAT_CALLS(RESTORE_CONTEXT|ALLOW_THREADS);
hexchat_command(ph, text);
END_XCHAT_CALLS();
Py_RETURN_NONE;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
@@ -1681,7 +1728,8 @@ Module_xchat_prnt(PyObject *self, PyObject *args)
BEGIN_XCHAT_CALLS(RESTORE_CONTEXT|ALLOW_THREADS);
hexchat_print(ph, text);
END_XCHAT_CALLS();
Py_RETURN_NONE;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
@@ -1724,7 +1772,8 @@ Module_hexchat_get_info(PyObject *self, PyObject *args)
info = hexchat_get_info(ph, name);
END_XCHAT_CALLS();
if (info == NULL) {
Py_RETURN_NONE;
Py_INCREF(Py_None);
return Py_None;
}
if (strcmp (name, "gtkwin_ptr") == 0)
return PyUnicode_FromFormat("%p", info); /* format as pointer */
@@ -1777,7 +1826,8 @@ Module_hexchat_get_context(PyObject *self, PyObject *args)
return NULL;
ctxobj = Context_FromContext(Plugin_GetContext(plugin));
if (ctxobj == NULL) {
Py_RETURN_NONE;
Py_INCREF(Py_None);
return Py_None;
}
return ctxobj;
}
@@ -1794,7 +1844,8 @@ Module_hexchat_find_context(PyObject *self, PyObject *args, PyObject *kwargs)
return NULL;
ctxobj = Context_FromServerAndChannel(server, channel);
if (ctxobj == NULL) {
Py_RETURN_NONE;
Py_INCREF(Py_None);
return Py_None;
}
return ctxobj;
}
@@ -1840,7 +1891,7 @@ Module_hexchat_pluginpref_get(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s:get_pluginpref", &var))
return NULL;
/* This will always return numbers as integers. */
// This will always return numbers as integers.
BEGIN_XCHAT_CALLS(NONE);
result = hexchat_pluginpref_get_str(prefph, var, retstr);
END_XCHAT_CALLS();
@@ -2174,7 +2225,8 @@ Module_hexchat_unhook(PyObject *self, PyObject *args)
Plugin_RemoveHook(plugin, hook);
}
Py_RETURN_NONE;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
@@ -2482,8 +2534,11 @@ IInterp_Exec(char *command)
}
d = PyModule_GetDict(m);
len = strlen(command);
buffer = g_malloc(len + 2);
buffer = (char *) g_malloc(len+2);
if (buffer == NULL) {
hexchat_print(ph, "Not enough memory for command buffer");
goto fail;
}
memcpy(buffer, command, len);
buffer[len] = '\n';
buffer[len+1] = 0;
@@ -2729,7 +2784,6 @@ hexchat_plugin_init(hexchat_plugin *plugin_handle,
Py_Initialize();
PySys_SetArgv(1, argv);
xchatout_buffer = g_string_new (NULL);
xchatout = XChatOut_New();
if (xchatout == NULL) {
hexchat_print(ph, "Can't allocate xchatout object");
@@ -2800,8 +2854,10 @@ hexchat_plugin_deinit()
plugin_list = NULL;
/* Reset xchatout buffer. */
g_string_free (xchatout_buffer, TRUE);
g_free(xchatout_buffer);
xchatout_buffer = NULL;
xchatout_buffer_size = 0;
xchatout_buffer_pos = 0;
if (interp_plugin) {
Py_DECREF(interp_plugin);

View File

@@ -1,7 +1,7 @@
libdir = $(hexchatlibdir)
lib_LTLIBRARIES = sysinfo.la
sysinfo_la_SOURCES = match.c parse.c pci.c xsys.c
sysinfo_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
sysinfo_la_LIBADD = $(LIBPCI_LIBS) $(GLIB_LIBS)
sysinfo_la_CFLAGS = $(LIBPCI_CFLAGS) $(GLIB_CFLAGS) -I$(srcdir)/../../src/common
sysinfo_la_SOURCES = hwmon.c match.c parse.c pci.c xsys.c
sysinfo_la_LDFLAGS = -avoid-version -module
sysinfo_la_LIBADD = -lpci
AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/../../src/common

64
plugins/sysinfo/hwmon.c Normal file
View File

@@ -0,0 +1,64 @@
/*
* hwmon.c - Hardware monitoring functions for X-Sys
* Copyright (C) 2005 Tony Vroon
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include "xsys.h"
int hwmon_chip_present()
{
FILE *fp = fopen("/sys/class/hwmon/hwmon0/device/name", "r");
if(fp != NULL) {
fclose(fp);
return 1;
}
return 0;
}
#if 0
void get_hwmon_chip_name(char *name)
{
char *position, buffer[bsize];
FILE *fp = fopen("/sys/class/hwmon/hwmon0/device/name", "r");
if(fp != NULL) {
if(fgets(buffer, bsize, fp) != NULL) {
position = strstr(buffer, "\n");
*(position) = '\0';
snprintf(name, sizeof(name), "%s", buffer);
}
fclose(fp);
}
}
#endif
void get_hwmon_temp(unsigned int *value, unsigned int *sensor)
{
char buffer[bsize];
FILE *fp;
snprintf(buffer, bsize, "/sys/class/hwmon/hwmon0/device/temp%i_input", *sensor);
fp = fopen(buffer, "r");
if(fp != NULL) {
if(fgets(buffer, bsize, fp) != NULL)
*value = atoi(buffer);
fclose(fp);
}
}

28
plugins/sysinfo/hwmon.h Normal file
View File

@@ -0,0 +1,28 @@
/*
* hwmon.h - Hardware monitoring header for X-Sys
* Copyright (C) 2005 Tony Vroon
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _HWMON_H_
#define _HWMON_H_
int hwmon_chip_present();
void get_hwmon_chip_name(char *name);
void get_hwmon_temp(unsigned int *value, unsigned int *sensor);
#endif

View File

@@ -22,7 +22,6 @@
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <glib.h>
#include "xsys.h"
float percentage(unsigned long long *free, unsigned long long *total)
@@ -38,13 +37,13 @@ char *pretty_freespace(const char *desc, unsigned long long *free_k, unsigned lo
double free_space, total_space;
free_space = *free_k;
total_space = *total_k;
result = g_new(char, bsize);
result = malloc(bsize * sizeof(char));
if (total_space == 0)
{
g_snprintf(result, bsize, "%s: none", desc);
snprintf(result, bsize, "%s: none", desc);
return result;
}
quantity = quantities;
quantity = quantities;
while (total_space > 1023 && *(quantity + 1))
{
quantity++;
@@ -52,11 +51,11 @@ char *pretty_freespace(const char *desc, unsigned long long *free_k, unsigned lo
total_space = total_space / 1024;
}
if (sysinfo_get_percent () != 0)
g_snprintf(result, bsize, "%s: %.1f%s, %.1f%% free",
snprintf(result, bsize, "%s: %.1f%s, %.1f%% free",
desc, total_space, *quantity,
percentage(free_k, total_k));
else
g_snprintf(result, bsize, "%s: %.1f%s/%.1f%s free",
snprintf(result, bsize, "%s: %.1f%s/%.1f%s free",
desc, free_space, *quantity, total_space, *quantity);
return result;
}
@@ -64,15 +63,28 @@ char *pretty_freespace(const char *desc, unsigned long long *free_k, unsigned lo
void remove_leading_whitespace(char *buffer)
{
char *p;
char *buffer2 = NULL;
int i = 0, j = 0, ews = 0;
if (buffer == NULL)
buffer2 = (char*)malloc(strlen(buffer) * sizeof(char));
if (buffer2 == NULL)
return;
for (p = buffer; *p && isspace (*p); p++)
;
memmove (buffer, p, strlen (p) + 1);
memset (buffer2, (char)0, strlen(buffer));
while (i < strlen(buffer))
{
/* count tabs, spaces as whitespace. */
if (!(buffer[i] == (char)32 || buffer[i] == (char)9) || ews == 1)
{
ews = 1;
buffer2[j] = buffer[i];
j++;
}
i++;
}
memset (buffer, (char)0, strlen(buffer));
strcpy (buffer, buffer2);
free (buffer2);
}
char *decruft_filename(char *buffer)

View File

@@ -29,10 +29,10 @@
#include <dirent.h>
#include <sys/types.h>
#include <pci/header.h>
#include <glib.h>
#include "pci.h"
#include "match.h"
#include "hwmon.h"
#include "xsys.h"
#include "parse.h"
@@ -47,8 +47,7 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned
FILE *fp = fopen("/proc/cpuinfo", "r");
if(fp == NULL)
return 1;
*count = 0;
if(count != NULL) *count = 0;
strcpy(cache,"unknown\0");
#if defined(__i386__) || defined(__x86_64__)
@@ -123,7 +122,7 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned
while ((entry = readdir(dir)) != NULL)
if (strncmp(entry->d_name,"SUNW,UltraSPARC",15) == 0)
{
g_snprintf(buffer,bsize,"/proc/openprom/%s/ecache-size",entry->d_name);
snprintf(buffer,bsize,"/proc/openprom/%s/ecache-size",entry->d_name);
fp2 = fopen(buffer, "r");
if (fp2 == NULL) break;
fscanf(fp2,"%16s",cache);
@@ -172,7 +171,7 @@ int xs_parse_os(char *user, char *host, char *kernel)
strncpy(user, usern, bsize);
strcpy(host, hostn);
g_snprintf(kernel, bsize, "%s %s %s", osinfo.sysname, osinfo.release, osinfo.machine);
snprintf(kernel, bsize, "%s %s %s", osinfo.sysname, osinfo.release, osinfo.machine);
return 0;
}
@@ -203,9 +202,9 @@ int xs_parse_sound(char *snd_card)
pos = strstr(buffer, ":");
card_id = strtoll(buffer, NULL, 0);
if (card_id == 0)
g_snprintf(card_buf, bsize, "%s", pos+2);
snprintf(card_buf, bsize, "%s", pos+2);
else
g_snprintf(card_buf, bsize, "%ld: %s", card_id, pos+2);
snprintf(card_buf, bsize, "%ld: %s", card_id, pos+2);
pos = strstr(card_buf, "\n");
*pos = '\0';
strcat(cards, card_buf);
@@ -269,11 +268,11 @@ int xs_parse_netdev(const char *device, unsigned long long *bytes_recv, unsigned
fclose(fp);
pos = strstr(buffer, ":");
pos++;
*bytes_recv = g_ascii_strtoull (pos, &pos, 0);
*bytes_recv = strtoull(pos, &pos, 0);
for(i=0;i<7;i++) g_ascii_strtoull (pos, &pos, 0);
for(i=0;i<7;i++) strtoull(pos, &pos, 0);
*bytes_sent = g_ascii_strtoull (pos, NULL, 0);
*bytes_sent = strtoull(pos, NULL, 0);
return 0;
}
@@ -299,15 +298,15 @@ int xs_parse_df(const char *mount_point, char *result)
for(;isspace(*pos);pos++);
if(mount_point == NULL)
{
total_k += g_ascii_strtoull (pos, &pos, 0);
g_ascii_strtoull(pos, &pos, 0);
free_k += g_ascii_strtoull (pos, &pos, 0);
total_k += strtoull(pos, &pos, 0);
strtoull(pos, &pos, 0);
free_k += strtoull(pos, &pos, 0);
continue;
}
total_k = g_ascii_strtoull (pos, &pos, 0);
g_ascii_strtoull(pos, &pos, 0);
free_k = g_ascii_strtoull (pos, &pos, 0);
g_ascii_strtoull (pos, &pos, 0);
total_k = strtoull(pos, &pos, 0);
strtoull(pos, &pos, 0);
free_k = strtoull(pos, &pos, 0);
strtoull(pos, &pos, 0);
for(;isspace(*pos);pos++);
for(;*pos!='/';pos++);
for(i=0;*(buffer+i)!='\n';i++);
@@ -318,16 +317,16 @@ int xs_parse_df(const char *mount_point, char *result)
char *tmp_buf = pretty_freespace(pos, &free_k, &total_k);
strcat(tmp_buf, " | ");
strcat(result, tmp_buf);
g_free(tmp_buf);
free(tmp_buf);
}
else if(strncmp(mount_point, pos, strlen(mount_point)) == 0)
{
char *tmp_buf = pretty_freespace(mount_point, &free_k, &total_k);
strncpy(result, tmp_buf, bsize);
g_free(tmp_buf);
free(tmp_buf);
break;
}
else g_snprintf(result, bsize, "Mount point %s not found!", mount_point);
else snprintf(result, bsize, "Mount point %s not found!", mount_point);
}
if(mount_point != NULL && strncasecmp(mount_point, "ALL", 3)==0)
@@ -337,7 +336,7 @@ int xs_parse_df(const char *mount_point, char *result)
{
char *tmp_buf = pretty_freespace("Total", &free_k, &total_k);
strncpy(result, tmp_buf, bsize);
g_free(tmp_buf);
free(tmp_buf);
}
pclose(pipe);
return 0;
@@ -389,9 +388,9 @@ int xs_parse_distro(char *name)
find_match_char(buffer, "ACCEPT_KEYWORDS", keywords);
/* cppcheck-suppress uninitvar */
if (strstr(keywords, "\"") == NULL)
g_snprintf(buffer, bsize, "Gentoo Linux (stable)");
snprintf(buffer, bsize, "Gentoo Linux (stable)");
else
g_snprintf(buffer, bsize, "Gentoo Linux %s", keywords);
snprintf(buffer, bsize, "Gentoo Linux %s", keywords);
}
else if((fp = fopen("/etc/redhat-release", "r")) != NULL)
fgets(buffer, bsize, fp);
@@ -406,7 +405,7 @@ int xs_parse_distro(char *name)
else if((fp = fopen("/etc/turbolinux-release", "r")) != NULL)
fgets(buffer, bsize, fp);
else if((fp = fopen("/etc/arch-release", "r")) != NULL)
g_snprintf(buffer, bsize, "ArchLinux");
snprintf(buffer, bsize, "ArchLinux");
else if((fp = fopen("/etc/lsb-release", "r")) != NULL)
{
char id[bsize], codename[bsize], release[bsize];
@@ -419,16 +418,16 @@ int xs_parse_distro(char *name)
find_match_char(buffer, "DISTRIB_CODENAME", codename);
find_match_char(buffer, "DISTRIB_RELEASE", release);
}
g_snprintf(buffer, bsize, "%s \"%s\" %s", id, codename, release);
snprintf(buffer, bsize, "%s \"%s\" %s", id, codename, release);
}
else if((fp = fopen("/etc/debian_version", "r")) != NULL)
{
char release[bsize];
fgets(release, bsize, fp);
g_snprintf(buffer, bsize, "Debian %s", release);
snprintf(buffer, bsize, "Debian %s", release);
}
else
g_snprintf(buffer, bsize, "Unknown Distro");
snprintf(buffer, bsize, "Unknown Distro");
if(fp != NULL) fclose(fp);
pos=strchr(buffer, '\n');
@@ -436,3 +435,28 @@ int xs_parse_distro(char *name)
strcpy(name, buffer);
return 0;
}
int xs_parse_hwmon_chip(char *chip)
{
if (!hwmon_chip_present())
return 1;
#if 0
else
get_hwmon_chip_name(chip);
#endif
return 0;
}
int xs_parse_hwmon_temp(char *temp, unsigned int *sensor)
{
unsigned int value;
float celsius;
if (!hwmon_chip_present())
return 1;
else
get_hwmon_temp(&value, sensor);
celsius = (float)value;
snprintf(temp, bsize, "%.1fC", celsius/1000.0);
return 0;
}

View File

@@ -34,5 +34,7 @@ int xs_parse_video(char *vid_card);
int xs_parse_agpbridge(char *agp_bridge);
int xs_parse_ether(char *ethernet_card);
int xs_parse_distro(char *name);
int xs_parse_hwmon_chip(char *chip);
int xs_parse_hwmon_temp(char *temp, unsigned int *sensor);
#endif

View File

@@ -25,8 +25,6 @@
#include <ctype.h>
#include <unistd.h>
#include <pci/pci.h>
#include <glib.h>
#include "xsys.h"
static struct pci_filter filter; /* Device filter */
@@ -49,7 +47,8 @@ static struct device *scan_device(struct pci_dev *p)
if (!pci_filter_match(&filter, p))
return NULL;
d = g_new0 (struct device, 1);
d = malloc(sizeof(struct device));
bzero(d, sizeof(*d));
d->dev = p;
if (!pci_read_block(p, 0, d->config, how_much))
exit(1);
@@ -99,8 +98,8 @@ int pci_find_by_class(u16 *class, char *vendor, char *device)
/* Acquire vendor & device ID if the class matches */
if(get_conf_word(d, PCI_CLASS_DEVICE) == *class) {
nomatch = 0;
g_snprintf(vendor,7,"%04x",p->vendor_id);
g_snprintf(device,7,"%04x",p->device_id);
snprintf(vendor,7,"%04x",p->vendor_id);
snprintf(device,7,"%04x",p->device_id);
break;
}
}
@@ -122,7 +121,7 @@ void pci_find_fullname(char *fullname, char *vendor, char *device)
fp = fopen (buffer, "r");
if(fp == NULL) {
g_snprintf(fullname, bsize, "%s:%s", vendor, device);
snprintf(fullname, bsize, "%s:%s", vendor, device);
sysinfo_print_error ("pci.ids file not found! You might want to adjust your pciids setting with /SYSINFO SET pciids (you can query its current value with /SYSINFO LIST).\n");
return;
}
@@ -151,8 +150,8 @@ void pci_find_fullname(char *fullname, char *vendor, char *device)
}
}
if (cardfound == 1)
g_snprintf(fullname, bsize, "%s %s", vendorname, devicename);
snprintf(fullname, bsize, "%s %s", vendorname, devicename);
else
g_snprintf(fullname, bsize, "%s:%s", vendor, device);
snprintf(fullname, bsize, "%s:%s", vendor, device);
fclose(fp);
}

View File

@@ -155,7 +155,7 @@ getOsName (void)
static char *
getCpuName (void)
{
/* Get extended ids. */
// Get extended ids.
unsigned int nExIds;
unsigned int i;
int CPUInfo[4] = {-1};

View File

@@ -22,7 +22,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
@@ -87,7 +86,6 @@ print_summary (int announce, char* format)
char os_host[bsize];
char os_user[bsize];
char os_kernel[bsize];
char *free_space;
unsigned long long mem_total;
unsigned long long mem_free;
unsigned int count;
@@ -100,7 +98,7 @@ print_summary (int announce, char* format)
int seconds;
sysinfo[0] = '\0';
g_snprintf (buffer, bsize, "%s", hexchat_get_info (ph, "version"));
snprintf (buffer, bsize, "%s", hexchat_get_info (ph, "version"));
format_output ("HexChat", buffer, format);
strcat (sysinfo, "\017 ");
strncat (sysinfo, buffer, bsize - strlen (sysinfo));
@@ -112,7 +110,7 @@ print_summary (int announce, char* format)
return HEXCHAT_EAT_ALL;
}
g_snprintf (buffer, bsize, "%s", os_kernel);
snprintf (buffer, bsize, "%s", os_kernel);
format_output ("OS", buffer, format);
strcat (sysinfo, "\017 ");
strncat (sysinfo, buffer, bsize - strlen (sysinfo));
@@ -142,11 +140,11 @@ print_summary (int announce, char* format)
if (giga)
{
g_snprintf (buffer, bsize, "%u x %s (%s) @ %.2fGHz", count, cpu_model, cpu_vendor, cpu_freq);
snprintf (buffer, bsize, "%u x %s (%s) @ %.2fGHz", count, cpu_model, cpu_vendor, cpu_freq);
}
else
{
g_snprintf (buffer, bsize, "%u x %s (%s) @ %.0fMHz", count, cpu_model, cpu_vendor, cpu_freq);
snprintf (buffer, bsize, "%u x %s (%s) @ %.0fMHz", count, cpu_model, cpu_vendor, cpu_freq);
}
format_output ("CPU", buffer, format);
@@ -160,9 +158,7 @@ print_summary (int announce, char* format)
return HEXCHAT_EAT_ALL;
}
free_space = pretty_freespace ("Physical", &mem_free, &mem_total);
g_snprintf (buffer, bsize, "%s", free_space);
g_free (free_space);
snprintf (buffer, bsize, "%s", pretty_freespace ("Physical", &mem_free, &mem_total));
format_output ("RAM", buffer, format);
strcat (sysinfo, "\017 ");
strncat (sysinfo, buffer, bsize - strlen (sysinfo));
@@ -224,21 +220,21 @@ print_summary (int announce, char* format)
{
if (weeks != 0)
{
g_snprintf (buffer, bsize, "%dw %dd %dh %dm %ds", weeks, days, hours, minutes, seconds);
snprintf (buffer, bsize, "%dw %dd %dh %dm %ds", weeks, days, hours, minutes, seconds);
}
else
{
g_snprintf (buffer, bsize, "%dd %dh %dm %ds", days, hours, minutes, seconds);
snprintf (buffer, bsize, "%dd %dh %dm %ds", days, hours, minutes, seconds);
}
}
else
{
g_snprintf (buffer, bsize, "%dh %dm %ds", hours, minutes, seconds);
snprintf (buffer, bsize, "%dh %dm %ds", hours, minutes, seconds);
}
}
else
{
g_snprintf (buffer, bsize, "%dm %ds", minutes, seconds);
snprintf (buffer, bsize, "%dm %ds", minutes, seconds);
}
}
@@ -272,7 +268,7 @@ print_os (int announce, char* format)
return HEXCHAT_EAT_ALL;
}
g_snprintf (buffer, bsize, "%s@%s, %s", user, host, kernel);
snprintf (buffer, bsize, "%s@%s, %s", user, host, kernel);
format_output ("OS", buffer, format);
if (announce)
@@ -336,11 +332,11 @@ print_cpu (int announce, char* format)
if (giga)
{
g_snprintf (buffer, bsize, "%u x %s (%s) @ %.2fGHz w/ %s L2 Cache", count, model, vendor, freq, cache);
snprintf (buffer, bsize, "%u x %s (%s) @ %.2fGHz w/ %s L2 Cache", count, model, vendor, freq, cache);
}
else
{
g_snprintf (buffer, bsize, "%u x %s (%s) @ %.0fMHz w/ %s L2 Cache", count, model, vendor, freq, cache);
snprintf (buffer, bsize, "%u x %s (%s) @ %.0fMHz w/ %s L2 Cache", count, model, vendor, freq, cache);
}
format_output ("CPU", buffer, format);
@@ -377,7 +373,7 @@ print_ram (int announce, char* format)
return HEXCHAT_EAT_ALL;
}
g_snprintf (string, bsize, "%s - %s", pretty_freespace ("Physical", &mem_free, &mem_total), pretty_freespace ("Swap", &swap_free, &swap_total));
snprintf (string, bsize, "%s - %s", pretty_freespace ("Physical", &mem_free, &mem_total), pretty_freespace ("Swap", &swap_free, &swap_total));
format_output ("RAM", string, format);
if (announce)
@@ -452,11 +448,11 @@ print_vga (int announce, char* format)
if (xs_parse_agpbridge (agp_bridge) != 0)
{
g_snprintf (buffer, bsize, "%s", vid_card);
snprintf (buffer, bsize, "%s", vid_card);
}
else
{
g_snprintf (buffer, bsize, "%s @ %s", vid_card, agp_bridge);
snprintf (buffer, bsize, "%s @ %s", vid_card, agp_bridge);
}
format_output ("VGA", buffer, format);
@@ -547,21 +543,21 @@ print_uptime (int announce, char* format)
{
if (weeks != 0)
{
g_snprintf (buffer, bsize, "%dw %dd %dh %dm %ds", weeks, days, hours, minutes, seconds);
snprintf (buffer, bsize, "%dw %dd %dh %dm %ds", weeks, days, hours, minutes, seconds);
}
else
{
g_snprintf (buffer, bsize, "%dd %dh %dm %ds", days, hours, minutes, seconds);
snprintf (buffer, bsize, "%dd %dh %dm %ds", days, hours, minutes, seconds);
}
}
else
{
g_snprintf (buffer, bsize, "%dh %dm %ds", hours, minutes, seconds);
snprintf (buffer, bsize, "%dh %dm %ds", hours, minutes, seconds);
}
}
else
{
g_snprintf (buffer, bsize, "%dm %ds", minutes, seconds);
snprintf (buffer, bsize, "%dm %ds", minutes, seconds);
}
}
@@ -602,7 +598,7 @@ netdata_cb (char *word[], char *word_eol[], void *userdata)
bytes_recv /= 1024;
bytes_sent /= 1024;
g_snprintf (netdata, bsize, "%s: %.1f MB Received, %.1f MB Sent", word[2], (double)bytes_recv/1024.0, (double)bytes_sent/1024.0);
snprintf (netdata, bsize, "%s: %.1f MB Received, %.1f MB Sent", word[2], (double)bytes_recv/1024.0, (double)bytes_sent/1024.0);
hexchat_pluginpref_get_str (ph, "format", format);
format_output ("Netdata", netdata, format);
@@ -658,24 +654,24 @@ netstream_cb (char *word[], char *word_eol[], void *userdata)
if (bytes_recv > 1024)
{
bytes_recv /= 1024;
g_snprintf (mag_r, 5, "KB/s");
snprintf (mag_r, 5, "KB/s");
}
else
{
g_snprintf (mag_r, 5, "B/s");
snprintf (mag_r, 5, "B/s");
}
if (bytes_sent > 1024)
{
bytes_sent /= 1024;
g_snprintf (mag_s, 5, "KB/s");
snprintf (mag_s, 5, "KB/s");
}
else
{
g_snprintf (mag_s, 5, "B/s");
snprintf (mag_s, 5, "B/s");
}
g_snprintf (netstream, bsize, "%s: Receiving %llu %s, Sending %llu %s", word[2], bytes_recv, mag_r, bytes_sent, mag_s);
snprintf (netstream, bsize, "%s: Receiving %llu %s, Sending %llu %s", word[2], bytes_recv, mag_r, bytes_sent, mag_s);
hexchat_pluginpref_get_str (ph, "format", format);
format_output ("Netstream", netstream, format);

View File

@@ -10,7 +10,6 @@ src/common/inbound.c
src/common/notify.c
src/common/outbound.c
src/common/plugin.c
src/common/plugin-identd.c
src/common/plugin-timer.c
src/common/server.c
src/common/servlist.c

View File

@@ -1,7 +1,5 @@
## Process this file with automake to produce Makefile.in
include $(top_srcdir)/m4/clang-analyze.am
noinst_LIBRARIES = libhexchatcommon.a
AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(top_srcdir)
@@ -22,11 +20,11 @@ EXTRA_DIST = \
inet.h \
make-te.c \
modes.h \
msproxy.h \
network.h \
notify.h \
outbound.h \
plugin.h \
plugin-identd.h \
plugin-timer.h \
proto-irc.h \
server.h \
@@ -46,6 +44,10 @@ if USE_OPENSSL
ssl_c = ssl.c
endif
if USE_MSPROXY
msproxy_c = msproxy.c
endif
if USE_DBUS
dbusdir = dbus
libhexchatcommon_a_LIBADD = \
@@ -60,9 +62,10 @@ endif
noinst_PROGRAMS = make-te
libhexchatcommon_a_SOURCES = cfgfiles.c chanopt.c ctcp.c dcc.c hexchat.c \
history.c ignore.c inbound.c marshal.c modes.c network.c notify.c \
outbound.c plugin.c plugin-identd.c plugin-timer.c proto-irc.c server.c servlist.c \
history.c ignore.c inbound.c marshal.c modes.c $(msproxy_c) network.c notify.c \
outbound.c plugin.c plugin-timer.c proto-irc.c server.c servlist.c \
$(ssl_c) text.c tree.c url.c userlist.c util.c
libhexchatcommon_a_CFLAGS = $(LIBPROXY_CFLAGS)
textenums.h: textevents.h
@@ -76,12 +79,6 @@ marshal.c: $(srcdir)/marshalers.list
$(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=_hexchat_marshal --body $< > $@
if DO_STATIC_ANALYSIS
analyze_plists = $(libhexchatcommon_a_SOURCES:%.c=%.plist)
all-local: $(analyze_plists)
MOSTLYCLEANFILES = $(analyze_plists)
endif
BUILT_SOURCES = textenums.h textevents.h marshal.c marshal.h
CLEANFILES = $(BUILT_SOURCES)

View File

@@ -61,7 +61,7 @@ list_addentry (GSList ** list, char *cmd, char *name)
cmd_len = strlen (cmd) + 1;
name_len = strlen (name) + 1;
pop = g_malloc (sizeof (struct popup) + cmd_len + name_len);
pop = malloc (sizeof (struct popup) + cmd_len + name_len);
pop->name = (char *) pop + sizeof (struct popup);
pop->cmd = pop->name + name_len;
@@ -133,13 +133,13 @@ list_loadconf (char *file, GSList ** list, char *defaultconf)
abort ();
}
ibuf = g_malloc (st.st_size);
ibuf = malloc (st.st_size);
read (fd, ibuf, st.st_size);
close (fd);
list_load_from_data (list, ibuf, st.st_size);
g_free (ibuf);
free (ibuf);
}
void
@@ -149,7 +149,7 @@ list_free (GSList ** list)
while (*list)
{
data = (void *) (*list)->data;
g_free (data);
free (data);
*list = g_slist_remove (*list, data);
}
}
@@ -166,7 +166,7 @@ list_delentry (GSList ** list, char *name)
if (!g_ascii_strcasecmp (name, pop->name))
{
*list = g_slist_remove (*list, pop);
g_free (pop);
free (pop);
return 1;
}
alist = alist->next;
@@ -207,10 +207,10 @@ cfg_get_str (char *cfg, const char *var, char *dest, int dest_len)
while (*cfg != 0 && *cfg != '\n')
cfg++;
if (*cfg == 0)
return NULL;
return 0;
cfg++;
if (*cfg == 0)
return NULL;
return 0;
}
}
@@ -220,7 +220,7 @@ cfg_put_str (int fh, char *var, char *value)
char buf[512];
int len;
g_snprintf (buf, sizeof buf, "%s = %s\n", var, value);
snprintf (buf, sizeof buf, "%s = %s\n", var, value);
len = strlen (buf);
return (write (fh, buf, len) == len);
}
@@ -231,7 +231,7 @@ cfg_put_color (int fh, int r, int g, int b, char *var)
char buf[400];
int len;
g_snprintf (buf, sizeof buf, "%s = %04x %04x %04x\n", var, r, g, b);
snprintf (buf, sizeof buf, "%s = %04x %04x %04x\n", var, r, g, b);
len = strlen (buf);
return (write (fh, buf, len) == len);
}
@@ -245,7 +245,7 @@ cfg_put_int (int fh, int value, char *var)
if (value == -1)
value = 1;
g_snprintf (buf, sizeof buf, "%s = %d\n", var, value);
snprintf (buf, sizeof buf, "%s = %d\n", var, value);
len = strlen (buf);
return (write (fh, buf, len) == len);
}
@@ -308,7 +308,9 @@ get_xdir (void)
if (portable_mode () || SHGetKnownFolderPath (&FOLDERID_RoamingAppData, 0, NULL, &roaming_path_wide) != S_OK)
{
char *path = g_win32_get_package_installation_directory_of_module (NULL);
char *path;
path = g_win32_get_package_installation_directory_of_module (NULL);
if (path)
{
xdir = g_build_filename (path, "config", NULL);
@@ -434,7 +436,6 @@ const struct prefs vars[] =
{"gui_tab_dots", P_OFFINT (hex_gui_tab_dots), TYPE_BOOL},
{"gui_tab_icons", P_OFFINT (hex_gui_tab_icons), TYPE_BOOL},
{"gui_tab_layout", P_OFFINT (hex_gui_tab_layout), TYPE_INT},
{"gui_tab_middleclose", P_OFFINT (hex_gui_tab_middleclose), TYPE_BOOL},
{"gui_tab_newtofront", P_OFFINT (hex_gui_tab_newtofront), TYPE_INT},
{"gui_tab_pos", P_OFFINT (hex_gui_tab_pos), TYPE_INT},
{"gui_tab_scrollchans", P_OFFINT (hex_gui_tab_scrollchans), TYPE_BOOL},
@@ -477,7 +478,6 @@ const struct prefs vars[] =
{"gui_win_width", P_OFFINT (hex_gui_win_width), TYPE_INT},
{"identd", P_OFFINT (hex_identd), TYPE_BOOL},
{"identd_port", P_OFFINT (hex_identd_port), TYPE_INT},
{"input_balloon_chans", P_OFFINT (hex_input_balloon_chans), TYPE_BOOL},
{"input_balloon_hilight", P_OFFINT (hex_input_balloon_hilight), TYPE_BOOL},
@@ -529,7 +529,9 @@ const struct prefs vars[] =
{"irc_whois_front", P_OFFINT (hex_irc_whois_front), TYPE_BOOL},
{"net_auto_reconnect", P_OFFINT (hex_net_auto_reconnect), TYPE_BOOL},
#ifndef WIN32 /* FIXME fix reconnect crashes and remove this ifdef! */
{"net_auto_reconnectonfail", P_OFFINT (hex_net_auto_reconnectonfail), TYPE_BOOL},
#endif
{"net_bind_host", P_OFFSET (hex_net_bind_host), TYPE_STR},
{"net_ping_timeout", P_OFFINT (hex_net_ping_timeout), TYPE_INT},
{"net_proxy_auth", P_OFFINT (hex_net_proxy_auth), TYPE_BOOL},
@@ -584,10 +586,10 @@ const struct prefs vars[] =
{0, 0, 0},
};
static const char *
static char *
convert_with_fallback (const char *str, const char *fallback)
{
const char *utf;
char *utf;
#ifndef WIN32
/* On non-Windows, g_get_user_name and g_get_real_name return a string in system locale, so convert it to utf-8. */
@@ -646,7 +648,7 @@ get_default_language (void)
if (lang_no >= 0)
{
g_free (lang);
free (lang);
return lang_no;
}
@@ -655,7 +657,7 @@ get_default_language (void)
lang_no = find_language_number (lang);
g_free (lang);
free (lang);
return lang_no >= 0 ? lang_no : find_language_number ("en");
}
@@ -697,8 +699,8 @@ get_default_spell_languages (void)
}
}
}
g_free (last);
if (last != NULL)
g_free(last);
if (lang_list[0])
return g_strdup (ret);
@@ -759,7 +761,6 @@ load_default_config(void)
prefs.hex_gui_tab_chans = 1;
prefs.hex_gui_tab_dialogs = 1;
prefs.hex_gui_tab_icons = 1;
prefs.hex_gui_tab_middleclose = 1;
prefs.hex_gui_tab_server = 1;
prefs.hex_gui_tab_sort = 1;
prefs.hex_gui_topicbar = 1;
@@ -771,6 +772,7 @@ load_default_config(void)
prefs.hex_gui_ulist_resizable = 1;
prefs.hex_gui_ulist_style = 1;
prefs.hex_gui_win_save = 1;
prefs.hex_identd = 1;
prefs.hex_input_flash_hilight = 1;
prefs.hex_input_flash_priv = 1;
prefs.hex_input_tray_hilight = 1;
@@ -841,7 +843,7 @@ load_default_config(void)
#ifdef WIN32
if (portable_mode () || SHGetKnownFolderPath (&FOLDERID_Downloads, 0, NULL, &roaming_path_wide) != S_OK)
{
g_snprintf (prefs.hex_dcc_dir, sizeof (prefs.hex_dcc_dir), "%s\\downloads", get_xdir ());
snprintf (prefs.hex_dcc_dir, sizeof (prefs.hex_dcc_dir), "%s\\downloads", get_xdir ());
}
else
{
@@ -855,36 +857,34 @@ load_default_config(void)
#else
if (g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD))
{
safe_strcpy (prefs.hex_dcc_dir, g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD), sizeof(prefs.hex_dcc_dir));
strcpy (prefs.hex_dcc_dir, g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD));
}
else
{
char *download_dir = g_build_filename (g_get_home_dir (), "Downloads", NULL);
safe_strcpy (prefs.hex_dcc_dir, download_dir, sizeof(prefs.hex_dcc_dir));
g_free (download_dir);
strcpy (prefs.hex_dcc_dir, g_build_filename (g_get_home_dir (), "Downloads", NULL));
}
#endif
strcpy (prefs.hex_gui_ulist_doubleclick, "QUERY %s");
strcpy (prefs.hex_input_command_char, "/");
strcpy (prefs.hex_irc_logmask, "%n"G_DIR_SEPARATOR_S"%c.log");
safe_strcpy (prefs.hex_irc_nick1, username, sizeof(prefs.hex_irc_nick1));
safe_strcpy (prefs.hex_irc_nick2, username, sizeof(prefs.hex_irc_nick2));
g_strlcat (prefs.hex_irc_nick2, "_", sizeof(prefs.hex_irc_nick2));
safe_strcpy (prefs.hex_irc_nick3, username, sizeof(prefs.hex_irc_nick3));
g_strlcat (prefs.hex_irc_nick3, "__", sizeof(prefs.hex_irc_nick3));
strcpy (prefs.hex_irc_logmask, g_build_filename ("%n", "%c.log", NULL));
strcpy (prefs.hex_irc_nick1, username);
strcpy (prefs.hex_irc_nick2, username);
strcat (prefs.hex_irc_nick2, "_");
strcpy (prefs.hex_irc_nick3, username);
strcat (prefs.hex_irc_nick3, "__");
strcpy (prefs.hex_irc_no_hilight, "NickServ,ChanServ,InfoServ,N,Q");
safe_strcpy (prefs.hex_irc_part_reason, _("Leaving"), sizeof(prefs.hex_irc_part_reason));
safe_strcpy (prefs.hex_irc_quit_reason, prefs.hex_irc_part_reason, sizeof(prefs.hex_irc_quit_reason));
safe_strcpy (prefs.hex_irc_real_name, realname, sizeof(prefs.hex_irc_real_name));
safe_strcpy (prefs.hex_irc_user_name, username, sizeof(prefs.hex_irc_user_name));
strcpy (prefs.hex_irc_part_reason, _("Leaving"));
strcpy (prefs.hex_irc_quit_reason, prefs.hex_irc_part_reason);
strcpy (prefs.hex_irc_real_name, realname);
strcpy (prefs.hex_irc_user_name, username);
strcpy (prefs.hex_stamp_log_format, "%b %d %H:%M:%S ");
strcpy (prefs.hex_stamp_text_format, "[%H:%M:%S] ");
font = fe_get_default_font ();
if (font)
{
safe_strcpy (prefs.hex_text_font, font, sizeof(prefs.hex_text_font));
safe_strcpy (prefs.hex_text_font_main, font, sizeof(prefs.hex_text_font_main));
strcpy (prefs.hex_text_font, font);
strcpy (prefs.hex_text_font_main, font);
}
else
{
@@ -894,7 +894,7 @@ load_default_config(void)
strcpy (prefs.hex_text_font_alternative, DEF_FONT_ALTER);
langs = get_default_spell_languages ();
safe_strcpy (prefs.hex_text_spell_langs, langs, sizeof(prefs.hex_text_spell_langs));
strcpy (prefs.hex_text_spell_langs, langs);
/* private variables */
@@ -1224,7 +1224,7 @@ cmd_set (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if (erase || *val)
{
/* save the previous value until we print it out */
prev_string = g_malloc (vars[i].len + 1);
prev_string = (char*) malloc (vars[i].len + 1);
strncpy (prev_string, (char *) &prefs + vars[i].offset, vars[i].len);
/* update the variable */
@@ -1236,7 +1236,7 @@ cmd_set (struct session *sess, char *tbuf, char *word[], char *word_eol[])
PrintTextf (sess, "%s set to: %s (was: %s)\n", var, (char *) &prefs + vars[i].offset, prev_string);
}
g_free (prev_string);
free (prev_string);
}
else
{

View File

@@ -119,7 +119,7 @@ chanopt_command (session *sess, char *tbuf, char *word[], char *word_eol[])
if (!quiet)
PrintTextf (sess, "\002Network\002: %s \002Channel\002: %s\n",
sess->server->network ? server_get_network (sess->server, TRUE) : _("<none>"),
sess->session_name[0] ? sess->session_name : _("<none>"));
sess->channel[0] ? sess->channel : _("<none>"));
while (i < sizeof (chanopt) / sizeof (channel_options))
{
@@ -208,7 +208,7 @@ chanopt_find (char *network, char *channel, gboolean add_new)
return NULL;
/* allocate a new one */
co = g_new0 (chanopt_in_memory, 1);
co = g_malloc0 (sizeof (chanopt_in_memory));
co->channel = g_strdup (channel);
co->network = g_strdup (network);
@@ -298,7 +298,7 @@ chanopt_load (session *sess)
chanopt_in_memory *co;
char *network;
if (sess->session_name[0] == 0)
if (sess->channel[0] == 0)
return;
network = server_get_network (sess->server, FALSE);
@@ -311,7 +311,7 @@ chanopt_load (session *sess)
chanopt_load_all ();
}
co = chanopt_find (network, sess->session_name, FALSE);
co = chanopt_find (network, sess->channel, FALSE);
if (!co)
return;
@@ -334,7 +334,7 @@ chanopt_save (session *sess)
chanopt_in_memory *co;
char *network;
if (sess->session_name[0] == 0)
if (sess->channel[0] == 0)
return;
network = server_get_network (sess->server, FALSE);
@@ -343,7 +343,7 @@ chanopt_save (session *sess)
/* 2. reconcile sess with what we loaded from disk */
co = chanopt_find (network, sess->session_name, TRUE);
co = chanopt_find (network, sess->channel, TRUE);
i = 0;
while (i < sizeof (chanopt) / sizeof (channel_options))
@@ -368,10 +368,10 @@ chanopt_save_one_channel (chanopt_in_memory *co, int fh)
char buf[256];
guint8 val;
g_snprintf (buf, sizeof (buf), "%s = %s\n", "network", co->network);
snprintf (buf, sizeof (buf), "%s = %s\n", "network", co->network);
write (fh, buf, strlen (buf));
g_snprintf (buf, sizeof (buf), "%s = %s\n", "channel", co->channel);
snprintf (buf, sizeof (buf), "%s = %s\n", "channel", co->channel);
write (fh, buf, strlen (buf));
i = 0;
@@ -380,7 +380,7 @@ chanopt_save_one_channel (chanopt_in_memory *co, int fh)
val = G_STRUCT_MEMBER (guint8, co, chanopt[i].offset);
if (val != SET_DEFAULT)
{
g_snprintf (buf, sizeof (buf), "%s = %d\n", chanopt[i].name, val);
snprintf (buf, sizeof (buf), "%s = %d\n", chanopt[i].name, val);
write (fh, buf, strlen (buf));
}
i++;

View File

@@ -20,15 +20,16 @@
<ClInclude Include="dcc.h" />
<ClInclude Include="fe.h" />
<ClInclude Include="history.h" />
<ClInclude Include="identd.h" />
<ClInclude Include="ignore.h" />
<ClInclude Include="inbound.h" />
<ClInclude Include="inet.h" />
<ClInclude Include="marshal.h" />
<ClInclude Include="modes.h" />
<ClInclude Include="msproxy.h" />
<ClInclude Include="network.h" />
<ClInclude Include="notify.h" />
<ClInclude Include="outbound.h" />
<ClInclude Include="plugin-identd.h" />
<ClInclude Include="plugin-timer.h" />
<ClInclude Include="plugin.h" />
<ClInclude Include="proto-irc.h" />
@@ -53,11 +54,12 @@
<ClCompile Include="ctcp.c" />
<ClCompile Include="dcc.c" />
<ClCompile Include="history.c" />
<ClCompile Include="plugin-identd.c" />
<ClCompile Include="identd.c" />
<ClCompile Include="ignore.c" />
<ClCompile Include="inbound.c" />
<ClCompile Include="marshal.c" />
<ClCompile Include="modes.c" />
<ClCompile Include="msproxy.c" />
<ClCompile Include="network.c" />
<ClCompile Include="notify.c" />
<ClCompile Include="outbound.c" />
@@ -165,4 +167,4 @@ powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..
]]></Command>
</PreBuildEvent>
</ItemDefinitionGroup>
</Project>
</Project>

View File

@@ -29,6 +29,9 @@
<ClInclude Include="history.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="identd.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ignore.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -41,6 +44,9 @@
<ClInclude Include="modes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="msproxy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="network.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -107,9 +113,6 @@
<ClInclude Include="marshal.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="plugin-identd.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="cfgfiles.c">
@@ -127,6 +130,9 @@
<ClCompile Include="history.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="identd.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ignore.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -136,6 +142,9 @@
<ClCompile Include="modes.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="msproxy.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="network.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -184,11 +193,8 @@
<ClCompile Include="marshal.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="plugin-identd.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\win32\config.h.tt" />
</ItemGroup>
</Project>
</Project>

View File

@@ -44,12 +44,12 @@ ctcp_reply (session *sess, char *nick, char *word[], char *word_eol[],
{
char tbuf[4096]; /* can receive 2048 from IRC, so this is enough */
conf = g_strdup (conf);
conf = strdup (conf);
/* process %C %B etc */
check_special_chars (conf, TRUE);
auto_insert (tbuf, sizeof (tbuf), conf, word, word_eol, "", "", word_eol[5],
server_get_network (sess->server, TRUE), "", "", nick, "");
g_free (conf);
free (conf);
handle_command (sess, tbuf, FALSE);
}
@@ -139,10 +139,10 @@ ctcp_handle (session *sess, char *to, char *nick, char *ip,
if (!g_ascii_strcasecmp (msg, "VERSION") && !prefs.hex_irc_hide_version)
{
#ifdef WIN32
g_snprintf (outbuf, sizeof (outbuf), "VERSION HexChat "PACKAGE_VERSION" [x%d] / %s",
snprintf (outbuf, sizeof (outbuf), "VERSION HexChat "PACKAGE_VERSION" [x%d] / %s",
get_cpu_arch (), get_sys_str (1));
#else
g_snprintf (outbuf, sizeof (outbuf), "VERSION HexChat "PACKAGE_VERSION" / %s",
snprintf (outbuf, sizeof (outbuf), "VERSION HexChat "PACKAGE_VERSION" / %s",
get_sys_str (1));
#endif
serv->p_nctcp (serv, nick, outbuf);

View File

@@ -19,8 +19,6 @@
* xclaesse@gmail.com
*/
#include "config.h"
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#include <dbus/dbus-glib.h>
#include "dbus-client.h"
@@ -93,7 +91,7 @@ hexchat_remote (void)
g_object_unref (dbus);
if (!hexchat_running) {
/* dbus_g_connection_unref (connection); */
//dbus_g_connection_unref (connection);
return;
}

File diff suppressed because it is too large Load Diff

View File

@@ -39,6 +39,17 @@
#define CPS_AVG_WINDOW 10
/* can we do 64-bit dcc? */
#if defined(G_GINT64_FORMAT) && defined(HAVE_STRTOULL)
#define USE_DCC64
/* we really get only 63 bits, since st_size is signed */
#define DCC_SIZE gint64
#define DCC_SFMT G_GINT64_FORMAT
#else
#define DCC_SIZE unsigned int
#define DCC_SFMT "u"
#endif
struct DCC
{
struct server *serv;
@@ -51,21 +62,21 @@ struct DCC
int wiotag; /* writing/sending io tag */
int port;
int pasvid; /* mIRC's passive DCC id */
gint64 cps;
int cps;
int resume_error;
int resume_errno;
GTimeVal lastcpstv, firstcpstv;
goffset lastcpspos;
gint64 maxcps;
DCC_SIZE lastcpspos;
int maxcps;
unsigned char ack_buf[4]; /* buffer for reading 4-byte ack */
int ack_pos;
guint64 size;
guint64 resumable;
guint64 ack;
guint64 pos;
DCC_SIZE size;
DCC_SIZE resumable;
DCC_SIZE ack;
DCC_SIZE pos;
time_t starttime;
time_t offertime;
time_t lasttime;
@@ -114,7 +125,7 @@ void dcc_check_timeouts (void);
void dcc_change_nick (server *serv, char *oldnick, char *newnick);
void dcc_notify_kill (struct server *serv);
struct DCC *dcc_write_chat (char *nick, char *text);
void dcc_send (struct session *sess, char *to, char *file, gint64 maxcps, int passive);
void dcc_send (struct session *sess, char *to, char *file, int maxcps, int passive);
struct DCC *find_dcc (char *nick, char *file, int type);
void dcc_get_nick (struct session *sess, char *nick);
void dcc_chat (session *sess, char *nick, int passive);
@@ -123,6 +134,5 @@ void handle_dcc (session *sess, char *nick, char *word[], char *word_eol[],
void dcc_show_list (session *sess);
guint32 dcc_get_my_address (void);
void dcc_get_with_destfile (struct DCC *dcc, char *utf8file);
char *net_ip (guint32 addr);
#endif

View File

@@ -88,10 +88,11 @@ void fe_progressbar_start (struct session *sess);
void fe_progressbar_end (struct server *serv);
void fe_print_text (struct session *sess, char *text, time_t stamp,
gboolean no_activity);
void fe_userlist_insert (struct session *sess, struct User *newuser, gboolean sel);
void fe_userlist_insert (struct session *sess, struct User *newuser, int row, int sel);
int fe_userlist_remove (struct session *sess, struct User *user);
void fe_userlist_rehash (struct session *sess, struct User *user);
void fe_userlist_update (struct session *sess, struct User *user);
void fe_userlist_move (struct session *sess, struct User *user, int new_row);
void fe_userlist_numbers (struct session *sess);
void fe_userlist_clear (struct session *sess);
void fe_userlist_set_selected (struct session *sess);
@@ -102,6 +103,7 @@ void fe_dcc_remove (struct DCC *dcc);
int fe_dcc_open_recv_win (int passive);
int fe_dcc_open_send_win (int passive);
int fe_dcc_open_chat_win (int passive);
void fe_sslalert_open (struct server *serv, void (*callback)(int, void *), void *callback_data);
void fe_clear_channel (struct session *sess);
void fe_session_callback (struct session *sess);
void fe_server_callback (struct server *serv);

View File

@@ -42,7 +42,6 @@
#include "ignore.h"
#include "hexchat-plugin.h"
#include "plugin.h"
#include "plugin-identd.h"
#include "plugin-timer.h"
#include "notify.h"
#include "server.h"
@@ -56,6 +55,14 @@
#include <glib-object.h> /* for g_type_init() */
#endif
#ifdef USE_MSPROXY
#include "msproxy.h"
#endif
#ifdef USE_LIBPROXY
#include <proxy.h>
#endif
GSList *popup_list = 0;
GSList *button_list = 0;
GSList *dlgbutton_list = 0;
@@ -106,6 +113,10 @@ struct session *current_tab;
struct session *current_sess = 0;
struct hexchatprefs prefs;
#ifdef USE_LIBPROXY
pxProxyFactory *libproxy_factory;
#endif
/*
* Update the priority queue of the "interesting sessions"
* (sess_list_by_lastact).
@@ -201,7 +212,7 @@ find_dialog (server *serv, char *nick)
}
list = list->next;
}
return NULL;
return 0;
}
session *
@@ -212,14 +223,14 @@ find_channel (server *serv, char *chan)
while (list)
{
sess = list->data;
if ((serv == sess->server) && sess->type == SESS_CHANNEL)
if ((!serv || serv == sess->server) && sess->type == SESS_CHANNEL)
{
if (!serv->p_cmp (chan, sess->channel))
return sess;
}
list = list->next;
}
return NULL;
return 0;
}
static void
@@ -249,7 +260,7 @@ lag_check (void)
unsigned long tim;
char tbuf[128];
time_t now = time (0);
time_t lag;
int lag;
tim = make_ping_time ();
@@ -259,17 +270,16 @@ lag_check (void)
if (serv->connected && serv->end_of_motd)
{
lag = now - serv->ping_recv;
if (prefs.hex_net_ping_timeout != 0 && lag > prefs.hex_net_ping_timeout && lag > 0)
if (prefs.hex_net_ping_timeout && lag > prefs.hex_net_ping_timeout && lag > 0)
{
sprintf (tbuf, "%" G_GINT64_FORMAT, (gint64) lag);
sprintf (tbuf, "%d", lag);
EMIT_SIGNAL (XP_TE_PINGTIMEOUT, serv->server_session, tbuf, NULL,
NULL, NULL, 0);
if (prefs.hex_net_auto_reconnect)
serv->auto_reconnect (serv, FALSE, -1);
}
else
} else
{
g_snprintf (tbuf, sizeof (tbuf), "LAG%lu", tim);
snprintf (tbuf, sizeof (tbuf), "LAG%lu", tim);
serv->p_ping (serv, "", tbuf);
if (!serv->lag_sent)
@@ -349,6 +359,9 @@ static int
hexchat_misc_checks (void) /* this gets called every 1/2 second */
{
static int count = 0;
#ifdef USE_MSPROXY
static int count2 = 0;
#endif
count++;
@@ -364,6 +377,15 @@ hexchat_misc_checks (void) /* this gets called every 1/2 second */
count = 0;
}
#ifdef USE_MSPROXY
count2++;
if (count2 >= 720) /* 720 every 6 minutes */
{
msproxy_keepalive ();
count2 = 0;
}
#endif
return 1;
}
@@ -374,6 +396,7 @@ irc_init (session *sess)
{
static int done_init = FALSE;
char *buf;
int i;
if (done_init)
return;
@@ -381,7 +404,6 @@ irc_init (session *sess)
done_init = TRUE;
plugin_add (sess, NULL, NULL, timer_plugin_init, NULL, NULL, FALSE);
plugin_add (sess, NULL, NULL, identd_plugin_init, identd_plugin_deinit, NULL, FALSE);
#ifdef USE_PLUGIN
if (!arg_skip_plugins)
@@ -409,8 +431,7 @@ irc_init (session *sess)
if (arg_urls != NULL)
{
guint i;
for (i = 0; i < g_strv_length (arg_urls); i++)
for (i = 0; i < g_strv_length(arg_urls); i++)
{
buf = g_strdup_printf ("%s %s", i==0? "server" : "newserver", arg_urls[i]);
handle_command (sess, buf, FALSE);
@@ -434,7 +455,12 @@ session_new (server *serv, char *from, int type, int focus)
{
session *sess;
sess = g_new0 (struct session, 1);
sess = malloc (sizeof (struct session));
if (sess == NULL)
{
return NULL;
}
memset (sess, 0, sizeof (struct session));
sess->server = serv;
sess->logfd = -1;
@@ -453,10 +479,7 @@ session_new (server *serv, char *from, int type, int focus)
sess->lastact_idx = LACT_NONE;
if (from != NULL)
{
safe_strcpy(sess->channel, from, CHANLEN);
safe_strcpy(sess->session_name, from, CHANLEN);
}
safe_strcpy (sess->channel, from, CHANLEN);
sess_list = g_slist_prepend (sess_list, sess);
@@ -516,8 +539,9 @@ exec_notify_kill (session * sess)
waitpid (re->childpid, NULL, WNOHANG);
fe_input_remove (re->iotag);
close (re->myfd);
g_free(re->linebuf);
g_free (re);
if (re->linebuf)
free(re->linebuf);
free (re);
}
#endif
}
@@ -623,8 +647,10 @@ session_free (session *killsess)
send_quit_or_part (killsess);
history_free (&killsess->history);
g_free (killsess->topic);
g_free (killsess->current_modes);
if (killsess->topic)
free (killsess->topic);
if (killsess->current_modes)
free (killsess->current_modes);
fe_session_callback (killsess);
@@ -635,7 +661,7 @@ session_free (session *killsess)
current_sess = sess_list->data;
}
g_free (killsess);
free (killsess);
if (!sess_list && !in_hexchat_exit)
hexchat_exit (); /* sess_list is empty, quit! */
@@ -754,11 +780,15 @@ xchat_init (void)
#ifdef WIN32
WSADATA wsadata;
#ifdef USE_IPV6
if (WSAStartup(0x0202, &wsadata) != 0)
{
MessageBox (NULL, "Cannot find winsock 2.2+", "Error", MB_OK);
exit (0);
}
#else
WSAStartup(0x0101, &wsadata);
#endif /* !USE_IPV6 */
#endif /* !WIN32 */
#ifdef USE_SIGACTION
@@ -795,7 +825,7 @@ xchat_init (void)
notify_load ();
ignore_load ();
g_snprintf (buf, sizeof (buf),
snprintf (buf, sizeof (buf),
"NAME %s~%s~\n" "CMD query %%s\n\n"\
"NAME %s~%s~\n" "CMD send %%s\n\n"\
"NAME %s~%s~\n" "CMD whois %%s %%s\n\n"\
@@ -851,7 +881,7 @@ xchat_init (void)
list_loadconf ("popup.conf", &popup_list, buf);
g_snprintf (buf, sizeof (buf),
snprintf (buf, sizeof (buf),
"NAME %s\n" "CMD part\n\n"
"NAME %s\n" "CMD getstr # join \"%s\"\n\n"
"NAME %s\n" "CMD quote LINKS\n\n"
@@ -865,7 +895,7 @@ xchat_init (void)
_("Hide Version"));
list_loadconf ("usermenu.conf", &usermenu_list, buf);
g_snprintf (buf, sizeof (buf),
snprintf (buf, sizeof (buf),
"NAME %s\n" "CMD op %%a\n\n"
"NAME %s\n" "CMD deop %%a\n\n"
"NAME %s\n" "CMD ban %%s\n\n"
@@ -882,7 +912,7 @@ xchat_init (void)
_("Dialog"));
list_loadconf ("buttons.conf", &button_list, buf);
g_snprintf (buf, sizeof (buf),
snprintf (buf, sizeof (buf),
"NAME %s\n" "CMD whois %%s %%s\n\n"
"NAME %s\n" "CMD send %%s\n\n"
"NAME %s\n" "CMD dcc chat %%s\n\n"
@@ -903,6 +933,7 @@ xchat_init (void)
defaultconf_urlhandlers);
servlist_init (); /* load server list */
_SSL_certlist_init (); /* load known certificate fingerprints */
/* if we got a URL, don't open the server list GUI */
if (!prefs.hex_gui_slist_skip && !arg_url && !arg_urls)
@@ -982,33 +1013,29 @@ main (int argc, char *argv[])
int i;
int ret;
srand ((unsigned int) time (NULL)); /* CL: do this only once! */
srand (time (0)); /* CL: do this only once! */
/* We must check for the config dir parameter, otherwise load_config() will behave incorrectly.
* load_config() must come before fe_args() because fe_args() calls gtk_init() which needs to
* know the language which is set in the config. The code below is copy-pasted from fe_args()
* for the most part. */
if (argc >= 2)
if (argc >= 3)
{
for (i = 1; i < argc; i++)
for (i = 1; i < argc - 1; i++)
{
if ((strcmp (argv[i], "-d") == 0 || strcmp (argv[i], "--cfgdir") == 0)
&& i + 1 < argc)
if (strcmp (argv[i], "-d") == 0)
{
xdir = g_strdup (argv[i + 1]);
}
else if (strncmp (argv[i], "--cfgdir=", 9) == 0)
{
xdir = g_strdup (argv[i] + 9);
}
if (xdir)
{
g_free (xdir);
}
xdir = strdup (argv[i + 1]);
if (xdir != NULL)
{
if (xdir[strlen (xdir) - 1] == G_DIR_SEPARATOR)
{
xdir[strlen (xdir) - 1] = 0;
}
break;
}
}
}
@@ -1032,6 +1059,10 @@ main (int argc, char *argv[])
/* we MUST do this after load_config () AND before fe_init (thus gtk_init) otherwise it will fail */
set_locale ();
#ifdef SOCKS
SOCKSinit (argv[0]);
#endif
ret = fe_args (argc, argv);
if (ret != -1)
return ret;
@@ -1040,6 +1071,10 @@ main (int argc, char *argv[])
hexchat_remote ();
#endif
#ifdef USE_LIBPROXY
libproxy_factory = px_proxy_factory_new();
#endif
fe_init ();
/* This is done here because cfgfiles.c is too early in
@@ -1067,6 +1102,10 @@ main (int argc, char *argv[])
fe_main ();
#ifdef USE_LIBPROXY
px_proxy_factory_free(libproxy_factory);
#endif
#ifdef WIN32
WSACleanup ();
#endif

View File

@@ -22,7 +22,6 @@
#include <glib.h>
#include <glib/gstdio.h>
#include <glib/gi18n.h>
#include <gio/gio.h>
#include <time.h> /* need time_t */
@@ -37,10 +36,26 @@
#endif
#include "history.h"
#include "tree.h"
#ifndef HAVE_SNPRINTF
#define snprintf g_snprintf
#endif
#ifndef HAVE_VSNPRINTF
#define vsnprintf _vsnprintf
#endif
#ifdef SOCKS
#ifdef __sgi
#include <sys/time.h>
#define INCLUDE_PROTOTYPES 1
#endif
#include <socks.h>
#endif
#ifdef USE_OPENSSL
#include <openssl/ssl.h> /* SSL_() */
#include "ssl.h"
#endif
#ifdef __EMX__ /* for o/s 2 */
@@ -248,7 +263,6 @@ struct hexchatprefs
int hex_gui_search_pos;
int hex_gui_slist_select;
int hex_gui_tab_layout;
int hex_gui_tab_middleclose;
int hex_gui_tab_newtofront;
int hex_gui_tab_pos;
int hex_gui_tab_small;
@@ -264,7 +278,6 @@ struct hexchatprefs
int hex_gui_win_state;
int hex_gui_win_top;
int hex_gui_win_width;
int hex_identd_port;
int hex_input_balloon_time;
int hex_irc_ban_type;
int hex_irc_join_delay;
@@ -370,12 +383,12 @@ typedef struct session
guint8 text_strip;
struct server *server;
tree *usertree; /* alphabetical tree */
void *usertree_alpha; /* pure alphabetical tree */
void *usertree; /* ordered with Ops first */
struct User *me; /* points to myself in the usertree */
char channel[CHANLEN];
char waitchannel[CHANLEN]; /* waiting to join channel (/join sent) */
char willjoinchannel[CHANLEN]; /* will issue /join for this channel */
char session_name[CHANLEN]; /* the name of the session, should not modified */
char channelkey[64]; /* XXX correct max length? */
int limit; /* channel user limit */
int logfd;
@@ -422,6 +435,14 @@ typedef struct session
void (*scrollback_replay_marklast) (struct session *sess);
} session;
struct msproxy_state_t
{
gint32 clientid;
gint32 serverid;
unsigned char seq_recv; /* seq number of last packet recv. */
unsigned char seq_sent; /* seq number of last packet sent. */
};
/* SASL Mechanisms */
#define MECH_PLAIN 0
#define MECH_BLOWFISH 1
@@ -471,10 +492,15 @@ typedef struct server
int (*p_raw)(struct server *, char *raw);
int (*p_cmp)(const char *s1, const char *s2);
guint16 port;
GSocket *sok; /* is equal to sok4 or sok6 (the one we are using) */
GSocket *sok4; /* tcp4 socket */
GSocket *sok6; /* tcp6 socket */
int port;
int sok; /* is equal to sok4 or sok6 (the one we are using) */
int sok4; /* tcp4 socket */
int sok6; /* tcp6 socket */
int proxy_type;
int proxy_sok; /* Additional information for MS Proxy beast */
int proxy_sok4;
int proxy_sok6;
struct msproxy_state_t msp_state;
int id; /* unique ID number (for plugin API) */
#ifdef USE_OPENSSL
SSL_CTX *ctx;
@@ -483,7 +509,9 @@ typedef struct server
#else
void *ssl;
#endif
GCancellable *cancellable; /* to cancel connecting thread */
int childread;
int childwrite;
int childpid;
int iotag;
int recondelay_tag; /* reconnect delay timeout */
int joindelay_tag; /* waiting before we send JOIN */
@@ -570,6 +598,7 @@ typedef struct server
#ifdef USE_OPENSSL
unsigned int use_ssl:1; /* is server SSL capable? */
unsigned int accept_invalid_cert:1;/* ignore result of server's cert. verify */
struct cert_info *cert_info;
#endif
} server;
@@ -605,4 +634,7 @@ struct popup
/* CL: get a random int in the range [0..n-1]. DON'T use rand() % n, it gives terrible results. */
#define RAND_INT(n) ((int)(rand() / (RAND_MAX + 1.0) * (n)))
#define hexchat_filename_from_utf8 g_filename_from_utf8
#define hexchat_filename_to_utf8 g_filename_to_utf8
#endif

View File

@@ -18,14 +18,14 @@
#include <string.h>
#include <stdlib.h>
#include <glib.h>
#include "history.h"
void
history_add (struct history *his, char *text)
{
g_free (his->lines[his->realpos]);
his->lines[his->realpos] = g_strdup (text);
if (his->lines[his->realpos])
free (his->lines[his->realpos]);
his->lines[his->realpos] = strdup (text);
his->realpos++;
if (his->realpos == HISTORY_SIZE)
his->realpos = 0;
@@ -40,7 +40,7 @@ history_free (struct history *his)
{
if (his->lines[i])
{
g_free (his->lines[i]);
free (his->lines[i]);
his->lines[i] = 0;
}
}
@@ -52,7 +52,7 @@ history_down (struct history *his)
int next;
if (his->pos == his->realpos) /* allow down only after up */
return NULL;
return 0;
if (his->realpos == 0)
{
if (his->pos == HISTORY_SIZE - 1)
@@ -79,7 +79,7 @@ history_down (struct history *his)
return his->lines[his->pos];
}
return NULL;
return 0;
}
char *
@@ -90,11 +90,11 @@ history_up (struct history *his, char *current_text)
if (his->realpos == HISTORY_SIZE - 1)
{
if (his->pos == 0)
return NULL;
return 0;
} else
{
if (his->pos == his->realpos + 1)
return NULL;
return 0;
}
next = HISTORY_SIZE - 1;
@@ -117,5 +117,5 @@ history_up (struct history *his, char *current_text)
return his->lines[his->pos];
}
return NULL;
return 0;
}

201
src/common/identd.c Normal file
View File

@@ -0,0 +1,201 @@
/* HexChat
* Copyright (C) 1998-2010 Peter Zelezny.
* Copyright (C) 2009-2013 Berke Viktor.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* simple identd server for HexChat under Win32 */
#include "inet.h"
#include "hexchat.h"
#include "hexchatc.h"
#include "text.h"
static int identd_is_running = FALSE;
#ifdef USE_IPV6
static int identd_ipv6_is_running = FALSE;
#endif
static int
identd (char *username)
{
int sok, read_sok, len;
char *p;
char buf[256];
char outbuf[256];
char ipbuf[INET_ADDRSTRLEN];
struct sockaddr_in addr;
sok = socket (AF_INET, SOCK_STREAM, 0);
if (sok == INVALID_SOCKET)
{
free (username);
return 0;
}
len = 1;
setsockopt (sok, SOL_SOCKET, SO_REUSEADDR, (char *) &len, sizeof (len));
memset (&addr, 0, sizeof (addr));
addr.sin_family = AF_INET;
addr.sin_port = htons (113);
if (bind (sok, (struct sockaddr *) &addr, sizeof (addr)) == SOCKET_ERROR)
{
closesocket (sok);
free (username);
return 0;
}
if (listen (sok, 1) == SOCKET_ERROR)
{
closesocket (sok);
free (username);
return 0;
}
len = sizeof (addr);
read_sok = accept (sok, (struct sockaddr *) &addr, &len);
closesocket (sok);
if (read_sok == INVALID_SOCKET)
{
free (username);
return 0;
}
identd_is_running = FALSE;
#if 0 /* causes random crashes, probably due to CreateThread */
EMIT_SIGNAL (XP_TE_IDENTD, current_sess, inet_ntoa (addr.sin_addr), username, NULL, NULL, 0);
#endif
inet_ntop (AF_INET, &addr.sin_addr, ipbuf, sizeof (ipbuf));
snprintf (outbuf, sizeof (outbuf), "*\tServicing ident request from %s as %s\n", ipbuf, username);
PrintText (current_sess, outbuf);
recv (read_sok, buf, sizeof (buf) - 1, 0);
buf[sizeof (buf) - 1] = 0; /* ensure null termination */
p = strchr (buf, ',');
if (p)
{
snprintf (outbuf, sizeof (outbuf) - 1, "%d, %d : USERID : UNIX : %s\r\n",
atoi (buf), atoi (p + 1), username);
outbuf[sizeof (outbuf) - 1] = 0; /* ensure null termination */
send (read_sok, outbuf, strlen (outbuf), 0);
}
sleep (1);
closesocket (read_sok);
free (username);
return 0;
}
#ifdef USE_IPV6
static int
identd_ipv6 (char *username)
{
int sok, read_sok, len;
char *p;
char buf[256];
char outbuf[256];
char ipbuf[INET6_ADDRSTRLEN];
struct sockaddr_in6 addr;
sok = socket (AF_INET6, SOCK_STREAM, 0);
if (sok == INVALID_SOCKET)
{
free (username);
return 0;
}
len = 1;
setsockopt (sok, SOL_SOCKET, SO_REUSEADDR, (char *) &len, sizeof (len));
memset (&addr, 0, sizeof (addr));
addr.sin6_family = AF_INET6;
addr.sin6_port = htons (113);
if (bind (sok, (struct sockaddr *) &addr, sizeof (addr)) == SOCKET_ERROR)
{
closesocket (sok);
free (username);
return 0;
}
if (listen (sok, 1) == SOCKET_ERROR)
{
closesocket (sok);
free (username);
return 0;
}
len = sizeof (addr);
read_sok = accept (sok, (struct sockaddr *) &addr, &len);
closesocket (sok);
if (read_sok == INVALID_SOCKET)
{
free (username);
return 0;
}
identd_ipv6_is_running = FALSE;
inet_ntop (AF_INET6, &addr.sin6_addr, ipbuf, sizeof (ipbuf));
snprintf (outbuf, sizeof (outbuf), "*\tServicing ident request from %s as %s\n", ipbuf, username);
PrintText (current_sess, outbuf);
recv (read_sok, buf, sizeof (buf) - 1, 0);
buf[sizeof (buf) - 1] = 0; /* ensure null termination */
p = strchr (buf, ',');
if (p)
{
snprintf (outbuf, sizeof (outbuf) - 1, "%d, %d : USERID : UNIX : %s\r\n", atoi (buf), atoi (p + 1), username);
outbuf[sizeof (outbuf) - 1] = 0; /* ensure null termination */
send (read_sok, outbuf, strlen (outbuf), 0);
}
sleep (1);
closesocket (read_sok);
free (username);
return 0;
}
#endif
void
identd_start (char *username)
{
DWORD tid;
#ifdef USE_IPV6
DWORD tidv6;
if (identd_ipv6_is_running == FALSE)
{
identd_ipv6_is_running = TRUE;
CloseHandle (CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) identd_ipv6,
strdup (username), 0, &tidv6));
}
#endif
if (identd_is_running == FALSE)
{
identd_is_running = TRUE;
CloseHandle (CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) identd,
strdup (username), 0, &tid));
}
}

View File

@@ -17,12 +17,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef HEXCHAT_PLUGIN_IDENTD_H
#define HEXCHAT_PLUGIN_IDENTD_H
#ifndef HEXCHAT_IDENTD_H
#define HEXCHAT_IDENTD_H
int identd_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name,
char **plugin_desc, char **plugin_version, char *arg);
int identd_plugin_deinit ();
void identd_start (char *username);
#endif

View File

@@ -53,7 +53,7 @@ static int ignored_total = 0;
struct ignore *
ignore_exists (char *mask)
{
struct ignore *ig = NULL;
struct ignore *ig = 0;
GSList *list;
list = ignore_list;
@@ -79,7 +79,7 @@ ignore_exists (char *mask)
int
ignore_add (char *mask, int type, gboolean overwrite)
{
struct ignore *ig = NULL;
struct ignore *ig = 0;
int change_only = FALSE;
/* first check if it's already ignored */
@@ -88,9 +88,12 @@ ignore_add (char *mask, int type, gboolean overwrite)
change_only = TRUE;
if (!change_only)
ig = g_new (struct ignore, 1);
ig = malloc (sizeof (struct ignore));
ig->mask = g_strdup (mask);
if (!ig)
return 0;
ig->mask = strdup (mask);
if (!overwrite && change_only)
ig->type |= type;
@@ -122,7 +125,7 @@ ignore_showlist (session *sess)
ig = list->data;
i++;
g_snprintf (tbuf, sizeof (tbuf), " %-25s ", ig->mask);
snprintf (tbuf, sizeof (tbuf), " %-25s ", ig->mask);
if (ig->type & IG_PRIV)
strcat (tbuf, _("YES "));
else
@@ -189,8 +192,8 @@ ignore_del (char *mask, struct ignore *ig)
if (ig)
{
ignore_list = g_slist_remove (ignore_list, ig);
g_free (ig->mask);
g_free (ig);
free (ig->mask);
free (ig);
fe_ignore_update (1);
return TRUE;
}
@@ -262,7 +265,7 @@ ignore_read_next_entry (char *my_cfg, struct ignore *ignore)
my_cfg = cfg_get_str (my_cfg, "mask", tbuf, sizeof (tbuf));
if (!my_cfg)
return NULL;
ignore->mask = g_strdup (tbuf);
ignore->mask = strdup (tbuf);
}
if (my_cfg)
{
@@ -278,7 +281,7 @@ ignore_load ()
struct ignore *ignore;
struct stat st;
char *cfg, *my_cfg;
int fh;
int fh, i;
fh = hexchat_open_file ("ignore.conf", O_RDONLY, 0, 0);
if (fh != -1)
@@ -286,18 +289,22 @@ ignore_load ()
fstat (fh, &st);
if (st.st_size)
{
cfg = g_malloc0 (st.st_size + 1);
read (fh, cfg, st.st_size);
cfg = malloc (st.st_size + 1);
cfg[0] = '\0';
i = read (fh, cfg, st.st_size);
if (i >= 0)
cfg[i] = '\0';
my_cfg = cfg;
while (my_cfg)
{
ignore = g_new0 (struct ignore, 1);
ignore = malloc (sizeof (struct ignore));
memset (ignore, 0, sizeof (struct ignore));
if ((my_cfg = ignore_read_next_entry (my_cfg, ignore)))
ignore_list = g_slist_prepend (ignore_list, ignore);
else
g_free (ignore);
free (ignore);
}
g_free (cfg);
free (cfg);
}
close (fh);
}
@@ -319,7 +326,7 @@ ignore_save ()
ig = (struct ignore *) temp->data;
if (!(ig->type & IG_NOSAVE))
{
g_snprintf (buf, sizeof (buf), "mask = %s\ntype = %u\n\n",
snprintf (buf, sizeof (buf), "mask = %s\ntype = %u\n\n",
ig->mask, ig->type);
write (fh, buf, strlen (buf));
}
@@ -372,9 +379,9 @@ flood_check (char *nick, char *ip, server *serv, session *sess, int what) /*0=ct
for (i = 0; i < 128; i++)
if (ip[i] == '@')
break;
g_snprintf (real_ip, sizeof (real_ip), "*!*%s", &ip[i]);
snprintf (real_ip, sizeof (real_ip), "*!*%s", &ip[i]);
g_snprintf (buf, sizeof (buf),
snprintf (buf, sizeof (buf),
_("You are being CTCP flooded from %s, ignoring %s\n"),
nick, real_ip);
PrintText (sess, buf);
@@ -399,7 +406,7 @@ flood_check (char *nick, char *ip, server *serv, session *sess, int what) /*0=ct
serv->msg_counter++;
if (serv->msg_counter == prefs.hex_flood_msg_num) /*if we reached the maximun numbers of ctcp in the seconds limits */
{
g_snprintf (buf, sizeof (buf),
snprintf (buf, sizeof (buf),
_("You are being MSG flooded from %s, setting gui_autoopen_dialog OFF.\n"),
ip);
PrintText (sess, buf);

View File

@@ -33,6 +33,8 @@
#define WANTDNS
#include "inet.h"
#include <gio/gio.h>
#include "hexchat.h"
#include "util.h"
#include "ignore.h"
@@ -62,7 +64,7 @@ clear_channel (session *sess)
if (sess->current_modes)
{
g_free (sess->current_modes);
free (sess->current_modes);
sess->current_modes = NULL;
}
@@ -81,8 +83,9 @@ clear_channel (session *sess)
void
set_topic (session *sess, char *topic, char *stripped_topic)
{
g_free (sess->topic);
sess->topic = g_strdup (stripped_topic);
if (sess->topic)
free (sess->topic);
sess->topic = strdup (stripped_topic);
fe_set_topic (sess, topic, stripped_topic);
}
@@ -118,7 +121,7 @@ find_session_from_nick (char *nick, server *serv)
}
list = list->next;
}
return NULL;
return 0;
}
static session *
@@ -184,7 +187,7 @@ inbound_privmsg (server *serv, char *from, char *ip, char *text, int id,
(!sess->topic || strcmp(sess->topic, ip)))
{
char tbuf[1024];
g_snprintf (tbuf, sizeof (tbuf), "[%s has address %s]\n", from, ip);
snprintf (tbuf, sizeof (tbuf), "[%s has address %s]\n", from, ip);
write (sess->logfd, tbuf, strlen (tbuf));
}
set_topic (sess, ip, ip);
@@ -555,7 +558,7 @@ find_unused_session (server *serv)
}
list = list->next;
}
return NULL;
return 0;
}
static session *
@@ -573,7 +576,7 @@ find_session_from_waitchannel (char *chan, struct server *serv)
}
list = list->next;
}
return NULL;
return 0;
}
void
@@ -679,8 +682,7 @@ inbound_nameslist (server *serv, char *chan, char *names,
char **name_list;
char *host, *nopre_name;
char name[NICKLEN];
int i;
size_t offset;
int i, offset;
sess = find_channel (serv, chan);
if (!sess)
@@ -914,7 +916,7 @@ inbound_ping_reply (session *sess, char *timestring, char *from,
tags_data->timestamp);
} else
{
g_snprintf (outbuf, sizeof (outbuf), "%ld.%03ld", dif / 1000, dif % 1000);
snprintf (outbuf, sizeof (outbuf), "%ld.%03ld", dif / 1000, dif % 1000);
EMIT_SIGNAL_TIMESTAMP (XP_TE_PINGREP, sess, from, outbuf, NULL, NULL, 0,
tags_data->timestamp);
}
@@ -932,7 +934,7 @@ find_session_from_type (int type, server *serv)
return sess;
list = list->next;
}
return NULL;
return 0;
}
void
@@ -967,14 +969,14 @@ inbound_notice (server *serv, char *to, char *nick, char *msg, char *ip, int id,
/* guess where chanserv meant to post this -sigh- */
if (!g_ascii_strcasecmp (nick, "ChanServ") && !find_dialog (serv, nick))
{
char *dest = g_strdup (msg + 1);
char *dest = strdup (msg + 1);
char *end = strchr (dest, ']');
if (end)
{
*end = 0;
sess = find_channel (serv, dest);
}
g_free (dest);
free (dest);
}
}
if (!sess)
@@ -1453,7 +1455,8 @@ inbound_user_info (session *sess, char *chan, char *user, char *host,
if (user && host)
{
uhost = g_strdup_printf ("%s@%s", user, host);
uhost = g_malloc (strlen (user) + strlen (host) + 2);
sprintf (uhost, "%s@%s", user, host);
}
if (chan)

View File

@@ -47,9 +47,13 @@
#else
#include "config.h"
#include "../../config.h"
#ifdef USE_IPV6
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <winsock2.h>
#endif
#define set_blocking(sok) { \
unsigned long zero = 0; \

View File

@@ -87,11 +87,9 @@ int main(void)
if (i + 1 < max)
{
fprintf(stderr, "\t%s,\t\t%s,\n", defines[i], defines[i+1]);
free (defines[i]);
i++;
} else
fprintf(stderr, "\t%s,\n", defines[i]);
free (defines[i]);
i++;
}
fprintf(stderr, "\tNUM_XP\n};\n");

View File

@@ -331,7 +331,7 @@ record_chan_mode (session *sess, char sign, char mode, char *arg)
current = g_string_erase(current, argument_offset+1, argument_length-1);
current = g_string_insert(current, argument_offset+1, arg);
g_free(sess->current_modes);
free(sess->current_modes);
sess->current_modes = g_string_free(current, FALSE);
}
}
@@ -348,7 +348,7 @@ record_chan_mode (session *sess, char sign, char mode, char *arg)
current = g_string_append(current, arg);
}
g_free(sess->current_modes);
free(sess->current_modes);
sess->current_modes = g_string_free(current, FALSE);
}
}
@@ -361,7 +361,7 @@ record_chan_mode (session *sess, char sign, char mode, char *arg)
/* remove the mode character */
current = g_string_erase(current, mode_pos, 1);
g_free(sess->current_modes);
free(sess->current_modes);
sess->current_modes = g_string_free(current, FALSE);
}
}
@@ -374,13 +374,12 @@ mode_cat (char *str, char *addition)
if (str)
{
len = strlen (str) + strlen (addition) + 2;
str = g_realloc (str, len);
str = realloc (str, len);
strcat (str, " ");
strcat (str, addition);
}
else
} else
{
str = g_strdup (addition);
str = strdup (addition);
}
return str;
@@ -561,12 +560,12 @@ handle_single_mode (mode_run *mr, char sign, char mode, char *nick,
{
if (*arg)
{
char *buf = g_strdup_printf ("%s %s", chan, arg);
char *buf = malloc (strlen (chan) + strlen (arg) + 2);
sprintf (buf, "%s %s", chan, arg);
EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANMODEGEN, sess, nick, outbuf,
outbuf + 2, buf, 0, tags_data->timestamp);
g_free (buf);
}
else
free (buf);
} else
EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANMODEGEN, sess, nick, outbuf,
outbuf + 2, chan, 0, tags_data->timestamp);
}
@@ -636,7 +635,7 @@ mode_print_grouped (session *sess, char *nick, mode_run *mr,
{
EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANOP, sess, nick, mr->op, NULL, NULL, 0,
tags_data->timestamp);
g_free(mr->op);
free (mr->op);
mr->op = NULL;
}
@@ -644,7 +643,7 @@ mode_print_grouped (session *sess, char *nick, mode_run *mr,
{
EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANDEOP, sess, nick, mr->deop, NULL, NULL,
0, tags_data->timestamp);
g_free(mr->deop);
free (mr->deop);
mr->deop = NULL;
}
@@ -652,7 +651,7 @@ mode_print_grouped (session *sess, char *nick, mode_run *mr,
{
EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANVOICE, sess, nick, mr->voice, NULL, NULL,
0, tags_data->timestamp);
g_free(mr->voice);
free (mr->voice);
mr->voice = NULL;
}
@@ -660,7 +659,7 @@ mode_print_grouped (session *sess, char *nick, mode_run *mr,
{
EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANDEVOICE, sess, nick, mr->devoice, NULL,
NULL, 0, tags_data->timestamp);
g_free(mr->devoice);
free (mr->devoice);
mr->devoice = NULL;
}
}
@@ -678,10 +677,10 @@ handle_mode (server * serv, char *word[], char *word_eol[],
char *argstr;
char sign;
int len;
size_t arg;
size_t i, num_args;
int arg;
int i, num_args;
int num_modes;
size_t offset = 3;
int offset = 3;
int all_modes_have_args = FALSE;
int using_front_tab = FALSE;
mode_run mr;
@@ -718,8 +717,9 @@ handle_mode (server * serv, char *word[], char *word_eol[],
if (numeric_324 && !using_front_tab)
{
g_free (sess->current_modes);
sess->current_modes = g_strdup (word_eol[offset+1]);
if (sess->current_modes)
free (sess->current_modes);
sess->current_modes = strdup (word_eol[offset+1]);
}
sign = *modes;
@@ -762,7 +762,7 @@ handle_mode (server * serv, char *word[], char *word_eol[],
break;
default:
argstr = "";
if ((all_modes_have_args || mode_has_arg (serv, sign, *modes)) && arg < (num_args + 1))
if ((all_modes_have_args || mode_has_arg (serv, sign, *modes)) && arg < (num_args+1))
{
arg++;
argstr = word[arg + offset];
@@ -799,29 +799,30 @@ inbound_005 (server * serv, char *word[], const message_tags_data *tags_data)
serv->modes_per_line = atoi (word[w] + 6);
} else if (strncmp (word[w], "CHANTYPES=", 10) == 0)
{
g_free (serv->chantypes);
serv->chantypes = g_strdup (word[w] + 10);
free (serv->chantypes);
serv->chantypes = strdup (word[w] + 10);
} else if (strncmp (word[w], "CHANMODES=", 10) == 0)
{
g_free (serv->chanmodes);
serv->chanmodes = g_strdup (word[w] + 10);
free (serv->chanmodes);
serv->chanmodes = strdup (word[w] + 10);
} else if (strncmp (word[w], "PREFIX=", 7) == 0)
{
pre = strchr (word[w] + 7, ')');
if (pre)
{
pre[0] = 0; /* NULL out the ')' */
g_free (serv->nick_prefixes);
g_free (serv->nick_modes);
serv->nick_prefixes = g_strdup (pre + 1);
serv->nick_modes = g_strdup (word[w] + 8);
free (serv->nick_prefixes);
free (serv->nick_modes);
serv->nick_prefixes = strdup (pre + 1);
serv->nick_modes = strdup (word[w] + 8);
} else
{
/* bad! some ircds don't give us the modes. */
/* in this case, we use it only to strip /NAMES */
serv->bad_prefix = TRUE;
g_free (serv->bad_nick_prefixes);
serv->bad_nick_prefixes = g_strdup (word[w] + 7);
if (serv->bad_nick_prefixes)
free (serv->bad_nick_prefixes);
serv->bad_nick_prefixes = strdup (word[w] + 7);
}
} else if (strncmp (word[w], "WATCH=", 6) == 0)
{
@@ -831,6 +832,10 @@ inbound_005 (server * serv, char *word[], const message_tags_data *tags_data)
serv->supports_monitor = TRUE;
} else if (strncmp (word[w], "NETWORK=", 8) == 0)
{
/* if (serv->networkname)
free (serv->networkname);
serv->networkname = strdup (word[w] + 8);*/
if (serv->server_session->type == SESS_SERVER)
{
safe_strcpy (serv->server_session->channel, word[w] + 8, CHANLEN);

470
src/common/msproxy.c Normal file
View File

@@ -0,0 +1,470 @@
/* X-Chat
* Copyright (C) 1998 Peter Zelezny.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* MS Proxy (ISA server) support is (c) 2006 Pavel Fedin <sonic_amiga@rambler.ru>
* based on Dante source code
* Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
* Inferno Nettverk A/S, Norway. All rights reserved.
*/
/*#define DEBUG_MSPROXY*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#ifndef WIN32
#include <unistd.h>
#endif
#define WANTSOCKET
#define WANTARPA
#include "inet.h"
#include "hexchat.h"
#include "network.h"
#include "hexchatc.h"
#include "server.h"
#include "msproxy.h"
#ifdef USE_MSPROXY
#include <ntlm.h>
static int
send_msprequest(s, state, request, end)
int s;
struct msproxy_state_t *state;
struct msproxy_request_t *request;
char *end;
{
ssize_t w;
size_t l;
request->magic25 = htonl(MSPROXY_VERSION);
request->serverack = state->seq_recv;
/* don't start incrementing sequence until we are acking packet #2. */
request->sequence = (unsigned char)(request->serverack >= 2 ? state->seq_sent + 1 : 0);
memcpy(request->RWSP, "RWSP", sizeof(request->RWSP));
l = end - (char *)request;
/* all requests must be atleast MSPROXY_MINLENGTH it seems. */
if (l < MSPROXY_MINLENGTH) {
bzero(end, (size_t)(MSPROXY_MINLENGTH - l));
l = MSPROXY_MINLENGTH;
}
if ((w = send(s, request, l, 0)) != l) {
#ifdef DEBUG_MSPROXY
printf ("send_msprequest(): send() failed (%ld bytes sent instead of %Iu\n", w, l);
perror ("Error is");
#endif
return -1;
}
state->seq_sent = request->sequence;
return w;
}
static int
recv_mspresponse(s, state, response)
int s;
struct msproxy_state_t *state;
struct msproxy_response_t *response;
{
ssize_t r;
do {
if ((r = recv (s, response, sizeof (*response), 0)) < MSPROXY_MINLENGTH) {
#ifdef DEBUG_MSPROXY
printf ("recv_mspresponse(): expected to read atleast %d, read %ld\n", MSPROXY_MINLENGTH, r);
#endif
return -1;
}
if (state->seq_recv == 0)
break; /* not started incrementing yet. */
#ifdef DEBUG_MSPROXY
if (response->sequence == state->seq_recv)
printf ("seq_recv: %d, dup response, seqnumber: 0x%x\n", state->seq_recv, response->sequence);
#endif
} while (response->sequence == state->seq_recv);
state->seq_recv = response->sequence;
return r;
}
int
traverse_msproxy (int sok, char *serverAddr, int port, struct msproxy_state_t *state, netstore *ns_proxy, int csok4, int csok6, int *csok, char bound)
{
struct msproxy_request_t req;
struct msproxy_response_t res;
char *data, *p;
char hostname[NT_MAXNAMELEN];
char ntdomain[NT_MAXNAMELEN];
char challenge[8];
netstore *ns_client;
int clientport;
guint32 destaddr;
guint32 flags;
if (!prefs.hex_net_proxy_auth || !prefs.hex_net_proxy_user[0] || !prefs.hex_net_proxy_pass[0] )
return 1;
/* MS proxy protocol implementation currently doesn't support IPv6 */
destaddr = net_getsockaddr_v4 (ns_proxy);
if (!destaddr)
return 1;
state->seq_recv = 0;
state->seq_sent = 0;
#ifdef DEBUG_MSPROXY
printf ("Connecting to %s:%d via MS proxy\n", serverAddr, port);
#endif
gethostname (hostname, NT_MAXNAMELEN);
p = strchr (hostname, '.');
if (p)
*p = '\0';
bzero (&req, sizeof(req));
req.clientid = htonl(0x0a000000); /* Initial client ID is always 0x0a */
req.command = htons(MSPROXY_HELLO); /* HELLO command */
req.packet.hello.magic5 = htons(0x4b00); /* Fill in magic values */
req.packet.hello.magic10 = htons(0x1400);
req.packet.hello.magic15 = htons(0x0400);
req.packet.hello.magic20 = htons(0x5704);
req.packet.hello.magic25 = htons(0x0004);
req.packet.hello.magic30 = htons(0x0100);
req.packet.hello.magic35 = htons(0x4a02);
req.packet.hello.magic40 = htons(0x3000);
req.packet.hello.magic45 = htons(0x4400);
req.packet.hello.magic50 = htons(0x3900);
data = req.packet.hello.data;
strcpy (data, prefs.hex_net_proxy_user); /* Append a username */
data += strlen (prefs.hex_net_proxy_user)+2; /* +2 automatically creates second empty string */
strcpy (data, MSPROXY_EXECUTABLE); /* Append an application name */
data += strlen (MSPROXY_EXECUTABLE)+1;
strcpy (data, hostname); /* Append a hostname */
data += strlen (hostname)+1;
if (send_msprequest(sok, state, &req, data) == -1)
return 1;
if (recv_mspresponse(sok, state, &res) == -1)
return 1;
if (strcmp(res.RWSP, "RWSP") != 0) {
#ifdef DEBUG_MSPROXY
printf ("Received mailformed packet (no RWSP signature)\n");
#endif
return 1;
}
if (ntohs(res.command) >> 8 != 0x10) {
#ifdef DEBUG_MSPROXY
printf ("expected res.command = 10??, is %x", ntohs(res.command));
#endif
return 1;
}
state->clientid = htonl(rand());
state->serverid = res.serverid;
#ifdef DEBUG_MSPROXY
printf ("clientid: 0x%x, serverid: 0x%0x\n", state->clientid, state->serverid);
printf ("packet #2\n");
#endif
/* almost identical. */
req.clientid = state->clientid;
req.serverid = state->serverid;
if (send_msprequest(sok, state, &req, data) == -1)
return 1;
if (recv_mspresponse(sok, state, &res) == -1)
return 1;
if (res.serverid != state->serverid) {
#ifdef DEBUG_MSPROXY
printf ("expected serverid = 0x%x, is 0x%x\n",state->serverid, res.serverid);
#endif
return 1;
}
if (res.sequence != 0x01) {
#ifdef DEBUG_MSPROXY
printf ("expected res.sequence = 0x01, is 0x%x\n", res.sequence);
#endif
return 1;
}
if (ntohs(res.command) != MSPROXY_USERINFO_ACK) {
#ifdef DEBUG_MSPROXY
printf ("expected res.command = 0x%x, is 0x%x\n", MSPROXY_USERINFO_ACK, ntohs(res.command));
#endif
return 1;
}
#ifdef DEBUG_MSPROXY
printf ("packet #3\n");
#endif
bzero(&req, sizeof(req));
req.clientid = state->clientid;
req.serverid = state->serverid;
req.command = htons(MSPROXY_AUTHENTICATE);
memcpy(req.packet.auth.NTLMSSP, "NTLMSSP", sizeof("NTLMSSP"));
req.packet.auth.bindaddr = htonl(0x02000000);
req.packet.auth.msgtype = htonl(0x01000000);
/* NTLM flags: 0x80000000 Negotiate LAN Manager key
0x10000000 Negotiate sign
0x04000000 Request target
0x02000000 Negotiate OEM
0x00800000 Always sign
0x00020000 Negotiate NTLM
*/
req.packet.auth.flags = htonl(0x06020000);
if (send_msprequest(sok, state, &req, &req.packet.auth.data) == -1)
return 1;
if (recv_mspresponse(sok, state, &res) == -1)
return 1;
if (res.serverid != state->serverid) {
#ifdef DEBUG_MSPROXY
printf ("expected serverid = 0x%x, is 0x%x\n", state->serverid, res.serverid);
#endif
return 1;
}
if (ntohs(res.command) != MSPROXY_AUTHENTICATE_ACK) {
#ifdef DEBUG_MSPROXY
printf ("expected res.command = 0x%x, is 0x%x\n", MSPROXY_AUTHENTICATE_ACK, ntohs(res.command));
#endif
return 1;
}
flags = res.packet.auth.flags & htonl(0x00020000); /* Remember if the server supports NTLM */
memcpy(challenge, &res.packet.auth.challenge, sizeof(challenge));
memcpy(ntdomain, &res.packet.auth.NTLMSSP[res.packet.auth.target.offset], res.packet.auth.target.len);
ntdomain[res.packet.auth.target.len] = 0;
#ifdef DEBUG_MSPROXY
printf ("ntdomain: \"%s\"\n", ntdomain);
printf ("packet #4\n");
#endif
bzero(&req, sizeof(req));
req.clientid = state->clientid;
req.serverid = state->serverid;
req.command = htons(MSPROXY_AUTHENTICATE_2); /* Authentication response */
req.packet.auth2.magic3 = htons(0x0200); /* Something */
memcpy(req.packet.auth2.NTLMSSP, "NTLMSSP", sizeof("NTLMSSP")); /* Start of NTLM message */
req.packet.auth2.msgtype = htonl(0x03000000); /* Message type 2 */
req.packet.auth2.flags = flags | htonl(0x02000000); /* Choose authentication method */
data = req.packet.auth2.data;
if (flags) {
req.packet.auth2.lm_resp.len = 0; /* We are here if NTLM is supported, */
req.packet.auth2.lm_resp.alloc = 0; /* Do not fill in insecure LM response */
req.packet.auth2.lm_resp.offset = data - req.packet.auth2.NTLMSSP;
req.packet.auth2.ntlm_resp.len = 24; /* Fill in NTLM response security buffer */
req.packet.auth2.ntlm_resp.alloc = 24;
req.packet.auth2.ntlm_resp.offset = data - req.packet.auth2.NTLMSSP;
ntlm_smb_nt_encrypt(prefs.hex_net_proxy_pass, challenge, data); /* Append an NTLM response */
data += 24;
} else {
req.packet.auth2.lm_resp.len = 24; /* Fill in LM response security buffer */
req.packet.auth2.lm_resp.alloc = 24;
req.packet.auth2.lm_resp.offset = data - req.packet.auth2.NTLMSSP;
ntlm_smb_encrypt(prefs.hex_net_proxy_pass, challenge, data); /* Append an LM response */
data += 24;
req.packet.auth2.ntlm_resp.len = 0; /* NTLM response is empty */
req.packet.auth2.ntlm_resp.alloc = 0;
req.packet.auth2.ntlm_resp.offset = data - req.packet.auth2.NTLMSSP;
}
req.packet.auth2.ntdomain_buf.len = strlen(ntdomain); /* Domain name */
req.packet.auth2.ntdomain_buf.alloc = req.packet.auth2.ntdomain_buf.len;
req.packet.auth2.ntdomain_buf.offset = data - req.packet.auth2.NTLMSSP;
strcpy(data, ntdomain);
data += req.packet.auth2.ntdomain_buf.len;
req.packet.auth2.username_buf.len = strlen(prefs.hex_net_proxy_user); /* Username */
req.packet.auth2.username_buf.alloc = req.packet.auth2.username_buf.len;
req.packet.auth2.username_buf.offset = data - req.packet.auth2.NTLMSSP;
strcpy(data, prefs.hex_net_proxy_user);
data += req.packet.auth2.username_buf.len;
req.packet.auth2.clienthost_buf.len = strlen(hostname); /* Hostname */
req.packet.auth2.clienthost_buf.alloc = req.packet.auth2.clienthost_buf.len;
req.packet.auth2.clienthost_buf.offset = data - req.packet.auth2.NTLMSSP;
strcpy(data, hostname);
data += req.packet.auth2.clienthost_buf.len;
req.packet.auth2.sessionkey_buf.len = 0; /* Session key (we don't use it) */
req.packet.auth2.sessionkey_buf.alloc = 0;
req.packet.auth2.sessionkey_buf.offset = data - req.packet.auth2.NTLMSSP;
if (send_msprequest(sok, state, &req, data) == -1)
return 1;
if (recv_mspresponse(sok, state, &res) == -1)
return 1;
if (res.serverid != state->serverid) {
#ifdef DEBUG_MSPROXY
printf ("expected res.serverid = 0x%x, is 0x%x\n", state->serverid, res.serverid);
#endif
return 1;
}
if (res.clientack != 0x01) {
#ifdef DEBUG_MSPROXY
printf ("expected res.clientack = 0x01, is 0x%x\n", res.clientack);
#endif
return 1;
}
if (ntohs(res.command) >> 8 != 0x47) {
#ifdef DEBUG_MSPROXY
printf ("expected res.command = 47??, is 0x%x\n", ntohs(res.command));
#endif
return 1;
}
if (ntohs(res.command) == MSPROXY_AUTHENTICATE_2_NAK) {
#ifdef DEBUG_MSPROXY
printf ("Authentication failed\n");
#endif
return -1;
}
#ifdef DEBUG_MSPROXY
printf ("packet #5\n");
#endif
bzero(&req, sizeof(req));
req.clientid = state->clientid;
req.serverid = state->serverid;
req.command = htons(MSPROXY_CONNECT);
req.packet.connect.magic2 = htons(0x0200);
req.packet.connect.magic6 = htons(0x0200);
req.packet.connect.destport = htons(port);
req.packet.connect.destaddr = destaddr;
data = req.packet.connect.executable;
strcpy(data, MSPROXY_EXECUTABLE);
data += strlen(MSPROXY_EXECUTABLE) + 1;
/*
* need to tell server what port we will connect from, so we bind our sockets.
*/
ns_client = net_store_new ();
if (!bound) {
net_store_fill_any (ns_client);
net_bind(ns_client, csok4, csok6);
#ifdef DEBUG_MSPROXY
perror ("bind() result");
#endif
}
clientport = net_getsockport(csok4, csok6);
if (clientport == -1) {
#ifdef DEBUG_MSPROXY
printf ("Unable to obtain source port\n");
#endif
return 1;
}
req.packet.connect.srcport = clientport;
if (send_msprequest(sok, state, &req, data) == -1)
return 1;
if (recv_mspresponse(sok, state, &res) == -1)
return 1;
if (ntohs(res.command) != MSPROXY_CONNECT_ACK) {
#ifdef DEBUG_MSPROXY
printf ("expected res.command = 0x%x, is 0x%x\n",MSPROXY_CONNECT_ACK, ntohs(res.command));
#endif
return 1;
}
net_store_fill_v4 (ns_client, res.packet.connect.clientaddr, res.packet.connect.clientport);
#ifdef DEBUG_MSPROXY
printf ("Connecting...\n");
#endif
if (net_connect (ns_client, csok4, csok6, csok) != 0) {
#ifdef DEBUG_MSPROXY
printf ("Failed to connect to port %d\n", htons(res.packet.connect.clientport));
#endif
net_store_destroy (ns_client);
return 1;
}
net_store_destroy (ns_client);
#ifdef DEBUG_MSPROXY
printf ("packet #6\n");
#endif
req.clientid = state->clientid;
req.serverid = state->serverid;
req.command = htons(MSPROXY_USERINFO_ACK);
if (send_msprequest(sok, state, &req, req.packet.connack.data) == -1)
return 1;
return 0;
}
void
msproxy_keepalive (void)
{
server *serv;
GSList *list = serv_list;
struct msproxy_request_t req;
struct msproxy_response_t res;
while (list)
{
serv = list->data;
if (serv->connected && (serv->proxy_sok != -1))
{
#ifdef DEBUG_MSPROXY
printf ("sending MS proxy keepalive packet\n");
#endif
bzero(&req, sizeof(req));
req.clientid = serv->msp_state.clientid;
req.serverid = serv->msp_state.serverid;
req.command = htons(MSPROXY_HELLO);
if (send_msprequest(serv->proxy_sok, &serv->msp_state, &req, req.packet.hello.data) == -1)
continue;
recv_mspresponse(serv->proxy_sok, &serv->msp_state, &res);
#ifdef DEBUG_MSPROXY
if (ntohs(res.command) != MSPROXY_USERINFO_ACK)
printf ("expected res.command = 0x%x, is 0x%x\n", MSPROXY_USERINFO_ACK, ntohs(res.command));
#endif
}
list = list->next;
}
}
#endif

262
src/common/msproxy.h Normal file
View File

@@ -0,0 +1,262 @@
/* X-Chat
* Copyright (C) 1998 Peter Zelezny.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* MS Proxy (ISA server) support is (c) 2006 Pavel Fedin <sonic_amiga@rambler.ru>
* based on Dante source code
* Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
* Inferno Nettverk A/S, Norway. All rights reserved.
*/
#ifndef HEXCHAT_MSPROXY_H
#define HEXCHAT_MSPROXY_H
#include "network.h"
#define MSPROXY_EXECUTABLE "hexchat.exe" /* This probably can be used for access control on the server side */
#define MSPROXY_MINLENGTH 172 /* minimum length of packet. */
#define NT_MAXNAMELEN 17 /* maximum name length (domain etc), comes from NetBIOS */
#define MSPROXY_VERSION 0x00010200 /* MS Proxy v2 ? */
/* Commands / responses */
#define MSPROXY_HELLO 0x0500 /* packet 1 from client. */
#define MSPROXY_HELLO_ACK 0x1000 /* packet 1 from server. */
#define MSPROXY_USERINFO_ACK 0x0400 /* packet 2 from server. */
#define MSPROXY_AUTHENTICATE 0x4700 /* authentication request */
#define MSPROXY_AUTHENTICATE_ACK 0x4714 /* authentication challenge */
#define MSPROXY_AUTHENTICATE_2 0x4701 /* authentication response */
#define MSPROXY_AUTHENTICATE_2_ACK 0x4715 /* authentication passed */
#define MSPROXY_AUTHENTICATE_2_NAK 0x4716 /* authentication failure */
#define MSPROXY_CONNECT 0x071e /* connect request. */
#define MSPROXY_CONNECT_ACK 0x0703 /* connect request accepted. */
#pragma pack(1)
struct ntlm_buffer {
guint16 len;
guint16 alloc;
guint32 offset;
};
struct msproxy_request_t {
guint32 clientid; /* 1-4 */
guint32 magic25; /* 5-8 */
guint32 serverid; /* 9-12 */
unsigned char serverack; /* 13: ack of last server packet */
char pad10[3]; /* 14-16 */
unsigned char sequence; /* 17: sequence # of this packet. */
char pad11[7]; /* 18-24 */
char RWSP[4]; /* 25-28: 0x52,0x57,0x53,0x50 */
char pad15[8]; /* 29-36 */
guint16 command; /* 37-38 */
/* packet specifics start at 39. */
union {
struct {
char pad1[18]; /* 39-56 */
guint16 magic3; /* 57-58 */
char pad3[114]; /* 59-172 */
guint16 magic5; /* 173-174: 0x4b, 0x00 */
char pad5[2]; /* 175-176 */
guint16 magic10; /* 177-178: 0x14, 0x00 */
char pad6[2]; /* 179-180 */
guint16 magic15; /* 181-182: 0x04, 0x00 */
char pad10[2]; /* 183-184 */
guint16 magic16; /* 185-186 */
char pad11[2]; /* 187-188 */
guint16 magic20; /* 189-190: 0x57, 0x04 */
guint16 magic25; /* 191-192: 0x00, 0x04 */
guint16 magic30; /* 193-194: 0x01, 0x00 */
char pad20[2]; /* 195-196: 0x4a, 0x02 */
guint16 magic35; /* 197-198: 0x4a, 0x02 */
char pad30[10]; /* 199-208 */
guint16 magic40; /* 209-210: 0x30, 0x00 */
char pad40[2]; /* 211-212 */
guint16 magic45; /* 213-214: 0x44, 0x00 */
char pad45[2]; /* 215-216 */
guint16 magic50; /* 217-218: 0x39, 0x00 */
char pad50[2]; /* 219-220 */
char data[256]; /* 221-EOP: a sequence of NULL-terminated strings:
- username;
- empty string (just a NULL);
- application name;
- hostname */
} hello;
struct {
char pad1[4]; /* 39-42 */
guint16 magic2; /* 43-44 */
char pad10[12]; /* 45-56 */
guint32 bindaddr; /* 57-60: address to bind. */
guint16 bindport; /* 61-62: port to bind. */
char pad15[2]; /* 63-64 */
guint16 magic3; /* 65-66 */
guint16 boundport; /* 67-68 */
char pad20[104]; /* 69-172 */
char NTLMSSP[sizeof("NTLMSSP")]; /* 173-180: "NTLMSSP" */
guint32 msgtype; /* 181-184: NTLM message type = 1 */
guint32 flags; /* 185-188: NTLM message flags */
guint16 magic20; /* 189-190: 0x28, 0x00 */
char pad30[2]; /* 191-192 */
guint16 magic25; /* 193-194: 0x96, 0x82 */
guint16 magic30; /* 195-196: 0x01, 0x00 */
char pad40[12]; /* 197-208 */
guint16 magic50; /* 209-210: 0x30, 0x00 */
char pad50[6]; /* 211-216 */
guint16 magic55; /* 217-218: 0x30, 0x00 */
char pad55[2]; /* 219-220 */
char data[0]; /* Dummy end marker, no real data required */
} auth;
struct {
char pad1[4]; /* 39-42 */
guint16 magic1; /* 43-44 */
guint32 magic2; /* 45-48 */
char pad2[8]; /* 49-56 */
guint16 magic3; /* 57-58 */
char pad3[6]; /* 59-64 */
guint16 magic4; /* 65-66 */
guint16 boundport; /* 67-68 */
char pad4[104]; /* 69-172 */
char NTLMSSP[sizeof("NTLMSSP")]; /* 173-180: "NTLMSSP" */
guint32 msgtype; /* 181-184: NTLM message type = 3 */
struct ntlm_buffer lm_resp; /* 185-192: LM response security buffer */
struct ntlm_buffer ntlm_resp; /* 193-200: NTLM response security buffer */
struct ntlm_buffer ntdomain_buf; /* 201-208: domain name security buffer */
struct ntlm_buffer username_buf; /* 209-216: username security buffer */
struct ntlm_buffer clienthost_buf; /* 217-224: hostname security buffer */
struct ntlm_buffer sessionkey_buf; /* 225-232: session key security buffer */
guint32 flags; /* 233-236: message flags */
char data[1024]; /* 237-EOP: data area */
} auth2;
struct {
guint16 magic1; /* 39-40 */
char pad1[2]; /* 41-42 */
guint16 magic2; /* 43-44 */
guint32 magic3; /* 45-48 */
char pad5[8]; /* 48-56 */
guint16 magic6; /* 57-58: 0x0200 */
guint16 destport; /* 59-60 */
guint32 destaddr; /* 61-64 */
char pad10[4]; /* 65-68 */
guint16 magic10; /* 69-70 */
char pad15[2]; /* 71-72 */
guint16 srcport; /* 73-74: port client connects from */
char pad20[82]; /* 75-156 */
char executable[256]; /* 76-EOP: application name */
} connect;
struct {
guint16 magic1; /* 39-40 */
char pad5[2]; /* 41-42 */
guint16 magic5; /* 43-44 */
guint32 magic10; /* 45-48 */
char pad10[2]; /* 49-50 */
guint16 magic15; /* 51-52 */
guint32 magic16; /* 53-56 */
guint16 magic20; /* 57-58 */
guint16 clientport; /* 59-60: forwarded port. */
guint32 clientaddr; /* 61-64: forwarded address. */
guint32 magic30; /* 65-68 */
guint32 magic35; /* 69-72 */
guint16 serverport; /* 73-74: port server will connect to us from. */
guint16 srcport; /* 75-76: connect request; port used on client behalf. */
guint16 boundport; /* 77-78: bind request; port used on client behalf. */
guint32 boundaddr; /* 79-82: addr used on client behalf */
char pad30[90]; /* 83-172 */
char data[0]; /* End marker */
} connack;
} packet;
};
struct msproxy_response_t {
guint32 packetid; /* 1-4 */
guint32 magic5; /* 5-8 */
guint32 serverid; /* 9-12 */
char clientack; /* 13: ack of last client packet. */
char pad5[3]; /* 14-16 */
unsigned char sequence; /* 17: sequence # of this packet. */
char pad10[7]; /* 18-24 */
char RWSP[4]; /* 25-28: 0x52,0x57,0x53,0x50 */
char pad15[8]; /* 29-36 */
guint16 command; /* 37-38 */
union {
struct {
char pad5[18]; /* 39-56 */
guint16 magic20; /* 57-58: 0x02, 0x00 */
char pad10[6]; /* 59-64 */
guint16 magic30; /* 65-66: 0x74, 0x01 */
char pad15[2]; /* 67-68 */
guint16 magic35; /* 69-70: 0x0c, 0x00 */
char pad20[6]; /* 71-76 */
guint16 magic50; /* 77-78: 0x04, 0x00 */
char pad30[6]; /* 79-84 */
guint16 magic60; /* 85-86: 0x65, 0x05 */
char pad35[2]; /* 87-88 */
guint16 magic65; /* 89-90: 0x02, 0x00 */
char pad40[8]; /* 91-98 */
guint16 udpport; /* 99-100 */
guint32 udpaddr; /* 101-104 */
} hello;
struct {
char pad1[6]; /* 39-44 */
guint32 magic10; /* 45-48 */
char pad3[10]; /* 49-58 */
guint16 boundport; /* 59-60: port server bound for us. */
guint32 boundaddr; /* 61-64: addr server bound for us. */
char pad10[4]; /* 65-68 */
guint16 magic15; /* 69-70 */
char pad15[102]; /* 70-172 */
char NTLMSSP[sizeof("NTLMSSP")]; /* 173-180: "NTLMSSP" */
guint32 msgtype; /* 181-184: NTLM message type = 2 */
struct ntlm_buffer target; /* 185-192: target security buffer */
guint32 flags; /* 193-196: NTLM message flags */
char challenge[8]; /* 197-204: NTLM challenge request */
char context[8]; /* 205-212: NTLM context */
char data[1024]; /* 213-EOP: target information data */
} auth;
struct {
guint16 magic1; /* 39-40 */
char pad5[18]; /* 41-58 */
guint16 clientport; /* 59-60: forwarded port. */
guint32 clientaddr; /* 61-64: forwarded address. */
guint32 magic10; /* 65-68 */
guint32 magic15; /* 69-72 */
guint16 serverport; /* 73-74: port server will connect to us from. */
guint16 srcport; /* 75-76: connect request; port used on client behalf. */
guint16 boundport; /* 77-78: bind request; port used on client behalf. */
guint32 boundaddr; /* 79-82: addr used on client behalf */
char pad10[90]; /* 83-172 */
} connect;
} packet;
};
#pragma pack()
int traverse_msproxy (int sok, char *serverAddr, int port, struct msproxy_state_t *state, netstore *ns_proxy, int csok4, int csok6, int *csok, char bound);
void msproxy_keepalive (void);
#endif

View File

@@ -18,231 +18,368 @@
/* ipv4 and ipv6 networking functions with a common interface */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <glib.h>
#include <gio/gio.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include "../../config.h"
#define WANTSOCKET
#define WANTARPA
#define WANTDNS
#include "inet.h"
#define NETWORK_PRIVATE
#include "network.h"
void
net_store_destroy (netstore *ns)
{
g_return_if_fail (ns != NULL);
#define RAND_INT(n) ((int)(rand() / (RAND_MAX + 1.0) * (n)))
g_resolver_free_addresses (ns->addrs);
g_free (ns);
/* ================== COMMON ================= */
static void
net_set_socket_options (int sok)
{
socklen_t sw;
sw = 1;
setsockopt (sok, SOL_SOCKET, SO_REUSEADDR, (char *) &sw, sizeof (sw));
sw = 1;
setsockopt (sok, SOL_SOCKET, SO_KEEPALIVE, (char *) &sw, sizeof (sw));
}
char *
net_ip (guint32 addr)
{
struct in_addr ia;
ia.s_addr = htonl (addr);
return inet_ntoa (ia);
}
void
net_store_destroy (netstore * ns)
{
#ifdef USE_IPV6
if (ns->ip6_hostent)
freeaddrinfo (ns->ip6_hostent);
#endif
free (ns);
}
netstore *
net_store_new (void)
{
return g_new0 (netstore, 1);
netstore *ns;
ns = malloc (sizeof (netstore));
memset (ns, 0, sizeof (netstore));
return ns;
}
#ifndef USE_IPV6
/* =================== IPV4 ================== */
/*
A note about net_resolve and lookupd:
Many IRC networks rely on round-robin DNS for load balancing, rotating the list
of IP address on each query. However, this method breaks when DNS queries are
cached. Mac OS X and Darwin handle DNS lookups through the lookupd daemon, which
caches queries in its default configuration: thus, if we always pick the first
address, we will be stuck with the same host (which might be down!) until the
TTL reaches 0 or lookupd is reset (typically, at reboot). Therefore, we need to
pick a random address from the result list, instead of always using the first.
*/
char *
net_resolve (netstore *ns, char *hostname, char **real_host, GError **error)
net_resolve (netstore * ns, char *hostname, int port, char **real_host)
{
GResolver *res;
GList *addrs;
GInetAddress *addr;
char *ipstring;
res = g_resolver_get_default ();
// todo: lookup by irc service?
addrs = g_resolver_lookup_by_name (res, hostname, NULL, error);
if (!addrs)
{
g_object_unref (res);
ns->ip4_hostent = gethostbyname (hostname);
if (!ns->ip4_hostent)
return NULL;
}
ns->addrs = addrs;
addr = G_INET_ADDRESS(addrs->data);
ipstring = g_inet_address_to_string (addr);
memset (&ns->addr, 0, sizeof (ns->addr));
#ifdef LOOKUPD
int count = 0;
while (ns->ip4_hostent->h_addr_list[count]) count++;
memcpy (&ns->addr.sin_addr,
ns->ip4_hostent->h_addr_list[RAND_INT(count)],
ns->ip4_hostent->h_length);
#else
memcpy (&ns->addr.sin_addr, ns->ip4_hostent->h_addr,
ns->ip4_hostent->h_length);
#endif
ns->addr.sin_port = htons (port);
ns->addr.sin_family = AF_INET;
if (real_host)
{
if (!(*real_host = g_resolver_lookup_by_address (res, addr, NULL, NULL)))
*real_host = g_strdup (hostname);
}
*real_host = strdup (ns->ip4_hostent->h_name);
return strdup (inet_ntoa (ns->addr.sin_addr));
}
g_object_unref (res);
int
net_connect (netstore * ns, int sok4, int sok6, int *sok_return)
{
*sok_return = sok4;
return connect (sok4, (struct sockaddr *) &ns->addr, sizeof (ns->addr));
}
return ipstring;
void
net_bind (netstore * tobindto, int sok4, int sok6)
{
bind (sok4, (struct sockaddr *) &tobindto->addr, sizeof (tobindto->addr));
}
void
net_sockets (int *sok4, int *sok6)
{
*sok4 = socket (AF_INET, SOCK_STREAM, 0);
*sok6 = -1;
net_set_socket_options (*sok4);
}
void
udp_sockets (int *sok4, int *sok6)
{
*sok4 = socket (AF_INET, SOCK_DGRAM, 0);
*sok6 = -1;
}
void
net_store_fill_any (netstore *ns)
{
ns->addr.sin_family = AF_INET;
ns->addr.sin_addr.s_addr = INADDR_ANY;
ns->addr.sin_port = 0;
}
void
net_store_fill_v4 (netstore *ns, guint32 addr, int port)
{
ns->addr.sin_family = AF_INET;
ns->addr.sin_addr.s_addr = addr;
ns->addr.sin_port = port;
}
guint32
net_getsockaddr_v4 (netstore *ns)
{
return ns->addr.sin_addr.s_addr;
}
int
net_getsockport (int sok4, int sok6)
{
struct sockaddr_in addr;
int len = sizeof (addr);
if (getsockname (sok4, (struct sockaddr *)&addr, &len) == -1)
return -1;
return addr.sin_port;
}
#else
/* =================== IPV6 ================== */
char *
net_resolve (netstore * ns, char *hostname, int port, char **real_host)
{
struct addrinfo hints;
char ipstring[MAX_HOSTNAME];
char portstring[MAX_HOSTNAME];
int ret;
/* if (ns->ip6_hostent)
freeaddrinfo (ns->ip6_hostent);*/
sprintf (portstring, "%d", port);
memset (&hints, 0, sizeof (struct addrinfo));
hints.ai_family = PF_UNSPEC; /* support ipv6 and ipv4 */
hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
hints.ai_socktype = SOCK_STREAM;
if (port == 0)
ret = getaddrinfo (hostname, NULL, &hints, &ns->ip6_hostent);
else
ret = getaddrinfo (hostname, portstring, &hints, &ns->ip6_hostent);
if (ret != 0)
return NULL;
#ifdef LOOKUPD /* See note about lookupd above the IPv4 version of net_resolve. */
struct addrinfo *tmp;
int count = 0;
for (tmp = ns->ip6_hostent; tmp; tmp = tmp->ai_next)
count ++;
count = RAND_INT(count);
while (count--) ns->ip6_hostent = ns->ip6_hostent->ai_next;
#endif
/* find the numeric IP number */
ipstring[0] = 0;
getnameinfo (ns->ip6_hostent->ai_addr, ns->ip6_hostent->ai_addrlen,
ipstring, sizeof (ipstring), NULL, 0, NI_NUMERICHOST);
if (ns->ip6_hostent->ai_canonname)
*real_host = strdup (ns->ip6_hostent->ai_canonname);
else
*real_host = strdup (hostname);
return strdup (ipstring);
}
/* the only thing making this interface unclean, this shitty sok4, sok6 business */
GSocket *
net_connect (netstore *ns, guint16 port, GSocket *sok4, GSocket *sok6, GError **error)
int
net_connect (netstore * ns, int sok4, int sok6, int *sok_return)
{
GSocket *sok;
GList *addrs;
gboolean success;
struct addrinfo *res, *res0;
int error = -1;
for (addrs = ns->addrs; addrs; addrs = g_list_next (addrs))
res0 = ns->ip6_hostent;
for (res = res0; res; res = res->ai_next)
{
GInetAddress *inet_addr = G_INET_ADDRESS(addrs->data);
GSocketAddress *sok_addr;
g_clear_error (error); /* Last failed attempt set */
sok_addr = g_inet_socket_address_new (inet_addr, port);
if (g_socket_address_get_family (sok_addr) == G_SOCKET_FAMILY_IPV4)
sok = sok4;
else
sok = sok6;
success = g_socket_connect (sok, sok_addr, NULL, error);
g_object_unref (sok_addr);
if (success)
return sok;
}
return NULL;
}
gboolean
net_bind (netstore *ns, GSocket *sok4, GSocket *sok6, GError **error4, GError **error6)
{
GInetAddress *inet_addr = G_INET_ADDRESS(ns->addrs->data);
GSocketAddress *sok_addr;
gboolean success;
sok_addr = g_inet_socket_address_new (inet_addr, 0);
success = g_socket_bind (sok4, sok_addr, TRUE, error4);
success &= g_socket_bind (sok6, sok_addr, TRUE, error6);
g_object_unref (sok_addr);
return success;
}
void
net_sockets (GSocket **sok4, GSocket **sok6, GError **error4, GError **error6)
{
*sok4 = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, error4);
*sok6 = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, error6);
if (!*sok4 || !*sok6)
{
g_warning ("Creating sockets failed\n");
return;
}
g_socket_set_keepalive (*sok4, TRUE);
g_socket_set_keepalive (*sok6, TRUE);
}
char *
net_resolve_proxy (const char *hostname, guint16 port, GError **error)
{
GProxyResolver *res;
char *uri;
char **proxies;
char *proxy = NULL;
guint i;
res = g_proxy_resolver_get_default ();
if (!res)
return NULL;
// FIXME: ircs also
uri = g_strdup_printf ("irc://%s:%d", hostname, port);
proxies = g_proxy_resolver_lookup (res, uri, NULL, error);
g_free (uri);
if (g_strv_length (proxies) == 0)
return NULL;
for (i = 0; i < g_strv_length (proxies); i++)
{
int type;
net_parse_proxy_uri (proxies[i], NULL, NULL, &type);
if (type != -1)
/* sok = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
if (sok < 0)
continue;*/
switch (res->ai_family)
{
proxy = g_strdup (proxies[i]);
case AF_INET:
error = connect (sok4, res->ai_addr, res->ai_addrlen);
*sok_return = sok4;
break;
case AF_INET6:
error = connect (sok6, res->ai_addr, res->ai_addrlen);
*sok_return = sok6;
break;
default:
error = 1;
}
if (error == 0)
break;
}
g_strfreev (proxies);
if (!proxy) /* FIXME: error code */
*error = g_error_new_literal (0, 0, "No system proxy found that is supported");
return proxy;
return error;
}
void
net_parse_proxy_uri (const char *proxy_uri, char **host, guint16 *port, int *type)
net_bind (netstore * tobindto, int sok4, int sok6)
{
if (type)
{
char *scheme = g_uri_parse_scheme (proxy_uri);
if (!strcmp (scheme, "direct"))
*type = 0;
else if (!strcmp (scheme, "http"))
*type = 4;
else if (!strcmp (scheme, "socks5"))
*type = 3;
else if (!strcmp (scheme, "socks"))
*type = 2;
else
*type = -1;
g_free (scheme);
}
if (host)
{
char *c1, *c2;
c1 = strchr (proxy_uri, ':') + 3;
if (c1)
{
c2 = strrchr (c1, ':');
if (c2)
*host = g_strndup (c1, c2 - c1);
else
*host = g_strdup (c1);
}
else
*host = NULL;
}
if (port)
{
char *c;
guint64 p;
c = strrchr (proxy_uri, ':');
if (c)
{
p = g_ascii_strtoull (c + 1, NULL, 0);
if (p <= G_MAXUINT16)
*port = (guint16)p;
}
else
*port = 0;
}
bind (sok4, tobindto->ip6_hostent->ai_addr,
tobindto->ip6_hostent->ai_addrlen);
bind (sok6, tobindto->ip6_hostent->ai_addr,
tobindto->ip6_hostent->ai_addrlen);
}
guint16
net_get_local_port (GSocket *sok)
void
net_sockets (int *sok4, int *sok6)
{
GSocketAddress *addr;
guint16 port;
addr = g_socket_get_local_address (sok, NULL);
if (!addr)
return 0;
port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS(addr));
g_object_unref (addr);
return port;
*sok4 = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
*sok6 = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP);
net_set_socket_options (*sok4);
net_set_socket_options (*sok6);
}
void
udp_sockets (int *sok4, int *sok6)
{
*sok4 = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
*sok6 = socket (AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
}
/* the following functions are used only by MSPROXY and are not
proper ipv6 implementations - do not use in new code! */
void
net_store_fill_any (netstore *ns)
{
struct addrinfo *ai;
struct sockaddr_in *sin;
ai = ns->ip6_hostent;
if (!ai) {
ai = malloc (sizeof (struct addrinfo));
memset (ai, 0, sizeof (struct addrinfo));
ns->ip6_hostent = ai;
}
sin = (struct sockaddr_in *)ai->ai_addr;
if (!sin) {
sin = malloc (sizeof (struct sockaddr_in));
memset (sin, 0, sizeof (struct sockaddr_in));
ai->ai_addr = (struct sockaddr *)sin;
}
ai->ai_family = AF_INET;
ai->ai_addrlen = sizeof(struct sockaddr_in);
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = INADDR_ANY;
sin->sin_port = 0;
ai->ai_next = NULL;
}
void
net_store_fill_v4 (netstore *ns, guint32 addr, int port)
{
struct addrinfo *ai;
struct sockaddr_in *sin;
ai = ns->ip6_hostent;
if (!ai) {
ai = malloc (sizeof (struct addrinfo));
memset (ai, 0, sizeof (struct addrinfo));
ns->ip6_hostent = ai;
}
sin = (struct sockaddr_in *)ai->ai_addr;
if (!sin) {
sin = malloc (sizeof (struct sockaddr_in));
memset (sin, 0, sizeof (struct sockaddr_in));
ai->ai_addr = (struct sockaddr *)sin;
}
ai->ai_family = AF_INET;
ai->ai_addrlen = sizeof(struct sockaddr_in);
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = addr;
sin->sin_port = port;
ai->ai_next = NULL;
}
guint32
net_getsockaddr_v4 (netstore *ns)
{
struct addrinfo *ai;
struct sockaddr_in *sin;
ai = ns->ip6_hostent;
while (ai->ai_family != AF_INET) {
ai = ai->ai_next;
if (!ai)
return 0;
}
sin = (struct sockaddr_in *)ai->ai_addr;
return sin->sin_addr.s_addr;
}
int
net_getsockport (int sok4, int sok6)
{
struct sockaddr_in addr;
int len = sizeof (addr);
if (getsockname (sok4, (struct sockaddr *)&addr, &len) == -1)
return -1;
return addr.sin_port;
}
#endif

View File

@@ -22,18 +22,32 @@
typedef struct netstore_
{
GList *addrs;
#ifdef NETWORK_PRIVATE
#ifdef USE_IPV6
struct addrinfo *ip6_hostent;
#else
struct hostent *ip4_hostent;
struct sockaddr_in addr;
#endif
#else
int _dummy; /* some compilers don't like empty structs */
#endif
} netstore;
#define MAX_HOSTNAME 128
netstore *net_store_new (void);
void net_store_destroy (netstore *ns);
GSocket *net_connect (netstore *ns, guint16 port, GSocket *sok4, GSocket *sok6, GError **error);
char *net_resolve (netstore *ns, char *hostname, char **real_host, GError **error);
char * net_resolve_proxy (const char *hostname, guint16 port, GError **error);
gboolean net_bind (netstore *ns, GSocket *sok4, GSocket *sok6, GError **error4, GError **error6);
void net_sockets (GSocket **sok4, GSocket **sok6, GError **error4, GError **error6);
void net_parse_proxy_uri (const char *proxy_uri, char **host, guint16 *port, int *type);
guint16 net_get_local_port (GSocket *sok);
int net_connect (netstore *ns, int sok4, int sok6, int *sok_return);
char *net_resolve (netstore *ns, char *hostname, int port, char **real_host);
void net_bind (netstore *tobindto, int sok4, int sok6);
char *net_ip (guint32 addr);
void net_sockets (int *sok4, int *sok6);
/* functions for MSPROXY only! */
void udp_sockets (int *sok4, int *sok6);
void net_store_fill_any (netstore *ns);
void net_store_fill_v4 (netstore *ns, guint32 addr, int port);
guint32 net_getsockaddr_v4 (netstore *ns);
int net_getsockport(int sok4, int sok6);
#endif

View File

@@ -47,7 +47,7 @@ int notify_tag = 0;
static char *
despacify_dup (char *str)
{
char *p, *res = g_malloc (strlen (str) + 1);
char *p, *res = malloc (strlen (str) + 1);
p = res;
while (1)
@@ -70,11 +70,11 @@ notify_netcmp (char *str, void *serv)
if (rfc_casecmp (str, net) == 0)
{
g_free (net);
free (net);
return 0; /* finish & return FALSE from token_foreach() */
}
g_free (net);
free (net);
return 1; /* keep going... */
}
@@ -111,10 +111,14 @@ notify_find_server_entry (struct notify *notify, struct server *serv)
if (!notify_do_network (notify, serv))
return NULL;
servnot = g_new0 (struct notify_per_server, 1);
servnot->server = serv;
servnot->notify = notify;
notify->server_list = g_slist_prepend (notify->server_list, servnot);
servnot = malloc (sizeof (struct notify_per_server));
if (servnot)
{
memset (servnot, 0, sizeof (struct notify_per_server));
servnot->server = serv;
servnot->notify = notify;
notify->server_list = g_slist_prepend (notify->server_list, servnot);
}
return servnot;
}
@@ -196,7 +200,7 @@ notify_find (server *serv, char *nick)
list = list->next;
}
return NULL;
return 0;
}
static void
@@ -243,9 +247,10 @@ notify_announce_online (server * serv, struct notify_per_server *servnot,
/* Let's do whois with idle time (like in /quote WHOIS %s %s) */
char *wii_str = g_strdup_printf ("%s %s", nick, nick);
char *wii_str = malloc (strlen (nick) * 2 + 2);
sprintf (wii_str, "%s %s", nick, nick);
serv->p_whois (serv, wii_str);
g_free (wii_str);
free (wii_str);
}
}
@@ -341,9 +346,9 @@ notify_watch (server * serv, char *nick, int add)
addchar = '-';
if (serv->supports_monitor)
g_snprintf (tbuf, sizeof (tbuf), "MONITOR %c %s", addchar, nick);
snprintf (tbuf, sizeof (tbuf), "MONITOR %c %s", addchar, nick);
else if (serv->supports_watch)
g_snprintf (tbuf, sizeof (tbuf), "WATCH %c%s", addchar, nick);
snprintf (tbuf, sizeof (tbuf), "WATCH %c%s", addchar, nick);
else
return;
@@ -556,9 +561,9 @@ notify_showlist (struct session *sess, const message_tags_data *tags_data)
notify = (struct notify *) list->data;
servnot = notify_find_server_entry (notify, sess->server);
if (servnot && servnot->ison)
g_snprintf (outbuf, sizeof (outbuf), _(" %-20s online\n"), notify->name);
snprintf (outbuf, sizeof (outbuf), _(" %-20s online\n"), notify->name);
else
g_snprintf (outbuf, sizeof (outbuf), _(" %-20s offline\n"), notify->name);
snprintf (outbuf, sizeof (outbuf), _(" %-20s offline\n"), notify->name);
PrintTextTimeStamp (sess, outbuf, tags_data->timestamp);
list = list->next;
}
@@ -591,13 +596,14 @@ notify_deluser (char *name)
servnot = (struct notify_per_server *) notify->server_list->data;
notify->server_list =
g_slist_remove (notify->server_list, servnot);
g_free (servnot);
free (servnot);
}
notify_list = g_slist_remove (notify_list, notify);
notify_watch_all (notify, FALSE);
g_free (notify->networks);
g_free (notify->name);
g_free (notify);
if (notify->networks)
free (notify->networks);
free (notify->name);
free (notify);
fe_notify_update (0);
return 1;
}
@@ -609,18 +615,27 @@ notify_deluser (char *name)
void
notify_adduser (char *name, char *networks)
{
struct notify *notify = g_new0 (struct notify, 1);
notify->name = g_strndup (name, NICKLEN - 1);
if (networks != NULL)
notify->networks = despacify_dup (networks);
notify->server_list = 0;
notify_list = g_slist_prepend (notify_list, notify);
notify_checklist ();
fe_notify_update (notify->name);
fe_notify_update (0);
notify_watch_all (notify, TRUE);
struct notify *notify = malloc (sizeof (struct notify));
if (notify)
{
memset (notify, 0, sizeof (struct notify));
if (strlen (name) >= NICKLEN)
{
notify->name = malloc (NICKLEN);
safe_strcpy (notify->name, name, NICKLEN);
} else
{
notify->name = strdup (name);
}
if (networks)
notify->networks = despacify_dup (networks);
notify->server_list = 0;
notify_list = g_slist_prepend (notify_list, notify);
notify_checklist ();
fe_notify_update (notify->name);
fe_notify_update (0);
notify_watch_all (notify, TRUE);
}
}
gboolean
@@ -699,7 +714,7 @@ notify_cleanup ()
{
notify->server_list =
g_slist_remove (notify->server_list, servnot);
g_free (servnot);
free (servnot);
nslist = notify->server_list;
} else
{

View File

@@ -90,7 +90,7 @@ random_line (char *file_name)
{
nofile:
/* reason is not a file, an actual reason! */
return g_strdup (file_name);
return strdup (file_name);
}
/* count number of lines in file */
@@ -111,7 +111,7 @@ random_line (char *file_name)
}
while (lines > ran);
fclose (fh);
return g_strdup (buf);
return strdup (buf);
}
void
@@ -121,7 +121,7 @@ server_sendpart (server * serv, char *channel, char *reason)
{
reason = random_line (prefs.hex_irc_part_reason);
serv->p_part (serv, channel, reason);
g_free (reason);
free (reason);
} else
{
/* reason set by /quit, /close argument */
@@ -136,12 +136,12 @@ server_sendquit (session * sess)
if (!sess->quitreason)
{
colrea = g_strdup (prefs.hex_irc_quit_reason);
colrea = strdup (prefs.hex_irc_quit_reason);
check_special_chars (colrea, FALSE);
rea = random_line (colrea);
g_free (colrea);
free (colrea);
sess->server->p_quit (sess->server, rea);
g_free (rea);
free (rea);
} else
{
/* reason set by /quit, /close argument */
@@ -269,7 +269,7 @@ cmd_addserver (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if (!network)
{
network = servlist_net_add (word[2], "", TRUE);
network->encoding = g_strdup (IRC_DEFAULT_CHARSET);
network->encoding = strdup (IRC_DEFAULT_CHARSET);
}
/* if we had the network already, check if the given server already exists */
else if (servlist_server_find (network, word_eol[3], NULL))
@@ -379,10 +379,11 @@ cmd_away (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if (sess->server->last_away_reason != reason)
{
g_free (sess->server->last_away_reason);
if (sess->server->last_away_reason)
free (sess->server->last_away_reason);
if (reason == word_eol[2])
sess->server->last_away_reason = g_strdup (reason);
sess->server->last_away_reason = strdup (reason);
else
sess->server->last_away_reason = reason;
}
@@ -405,7 +406,8 @@ cmd_back (struct session *sess, char *tbuf, char *word[], char *word_eol[])
PrintText (sess, _("Already marked back.\n"));
}
g_free (sess->server->last_away_reason);
if (sess->server->last_away_reason)
free (sess->server->last_away_reason);
sess->server->last_away_reason = NULL;
return TRUE;
@@ -481,19 +483,19 @@ create_mask (session * sess, char *mask, char *mode, char *typestr, int deop)
switch (type)
{
case 0:
g_snprintf (buf, sizeof (buf), "%s %s *!*@%s.*", mode, p2, domain);
snprintf (buf, sizeof (buf), "%s %s *!*@%s.*", mode, p2, domain);
break;
case 1:
g_snprintf (buf, sizeof (buf), "%s %s *!*@%s", mode, p2, fullhost);
snprintf (buf, sizeof (buf), "%s %s *!*@%s", mode, p2, fullhost);
break;
case 2:
g_snprintf (buf, sizeof (buf), "%s %s *!%s@%s.*", mode, p2, username, domain);
snprintf (buf, sizeof (buf), "%s %s *!%s@%s.*", mode, p2, username, domain);
break;
case 3:
g_snprintf (buf, sizeof (buf), "%s %s *!%s@%s", mode, p2, username, fullhost);
snprintf (buf, sizeof (buf), "%s %s *!%s@%s", mode, p2, username, fullhost);
break;
}
} else
@@ -501,26 +503,26 @@ create_mask (session * sess, char *mask, char *mode, char *typestr, int deop)
switch (type)
{
case 0:
g_snprintf (buf, sizeof (buf), "%s %s *!*@*%s", mode, p2, domain);
snprintf (buf, sizeof (buf), "%s %s *!*@*%s", mode, p2, domain);
break;
case 1:
g_snprintf (buf, sizeof (buf), "%s %s *!*@%s", mode, p2, fullhost);
snprintf (buf, sizeof (buf), "%s %s *!*@%s", mode, p2, fullhost);
break;
case 2:
g_snprintf (buf, sizeof (buf), "%s %s *!%s@*%s", mode, p2, username, domain);
snprintf (buf, sizeof (buf), "%s %s *!%s@*%s", mode, p2, username, domain);
break;
case 3:
g_snprintf (buf, sizeof (buf), "%s %s *!%s@%s", mode, p2, username, fullhost);
snprintf (buf, sizeof (buf), "%s %s *!%s@%s", mode, p2, username, fullhost);
break;
}
}
} else
{
g_snprintf (buf, sizeof (buf), "%s %s", mode, mask);
snprintf (buf, sizeof (buf), "%s %s", mode, mask);
}
return g_strdup (buf);
@@ -907,7 +909,7 @@ cmd_debug (struct session *sess, char *tbuf, char *word[], char *word_eol[])
{
v = (struct server *) list->data;
sprintf (tbuf, "%p %-5d %s\n",
v, g_socket_get_fd (v->sok), v->servername);
v, v->sok, v->servername);
PrintText (sess, tbuf);
list = list->next;
}
@@ -1000,14 +1002,14 @@ mdehop_cb (struct User *user, multidata *data)
static int
cmd_mdehop (struct session *sess, char *tbuf, char *word[], char *word_eol[])
{
char **nicks = g_new0 (char *, sess->hops);
char **nicks = malloc (sizeof (char *) * sess->hops);
multidata data;
data.nicks = nicks;
data.i = 0;
tree_foreach (sess->usertree, (tree_traverse_func *)mdehop_cb, &data);
send_channel_modes (sess, tbuf, nicks, 0, data.i, '-', 'h', 0);
g_free (nicks);
free (nicks);
return TRUE;
}
@@ -1026,14 +1028,14 @@ mdeop_cb (struct User *user, multidata *data)
static int
cmd_mdeop (struct session *sess, char *tbuf, char *word[], char *word_eol[])
{
char **nicks = g_new0(char *, sess->ops);
char **nicks = malloc (sizeof (char *) * sess->ops);
multidata data;
data.nicks = nicks;
data.i = 0;
tree_foreach (sess->usertree, (tree_traverse_func *)mdeop_cb, &data);
send_channel_modes (sess, tbuf, nicks, 0, data.i, '-', 'o', 0);
g_free (nicks);
free (nicks);
return TRUE;
}
@@ -1043,13 +1045,18 @@ GSList *menu_list = NULL;
static void
menu_free (menu_entry *me)
{
g_free (me->path);
g_free (me->label);
g_free (me->cmd);
g_free (me->ucmd);
g_free (me->group);
g_free (me->icon);
g_free (me);
free (me->path);
if (me->label)
free (me->label);
if (me->cmd)
free (me->cmd);
if (me->ucmd)
free (me->ucmd);
if (me->group)
free (me->group);
if (me->icon)
free (me->icon);
free (me);
}
/* strings equal? but ignore underscores */
@@ -1108,9 +1115,9 @@ menu_del_children (char *path, char *label)
if (!label)
label = "";
if (path[0])
g_snprintf (buf, sizeof (buf), "%s/%s", path, label);
snprintf (buf, sizeof (buf), "%s/%s", path, label);
else
g_snprintf (buf, sizeof (buf), "%s", label);
snprintf (buf, sizeof (buf), "%s", label);
list = menu_list;
while (list)
@@ -1161,9 +1168,7 @@ menu_is_mainmenu_root (char *path, gint16 *offset)
{
if (!strncmp (path, menus[i] + 1, menus[i][0]))
{
*offset = menus[i][0]; /* number of bytes to offset the root */
if (path[*offset] != '\0')
*offset += 1;
*offset = menus[i][0] + 1; /* number of bytes to offset the root */
return 0; /* is not main menu */
}
}
@@ -1188,7 +1193,7 @@ menu_add (char *path, char *label, char *cmd, char *ucmd, int pos, int state, in
return;
}
me = g_new (menu_entry, 1);
me = malloc (sizeof (menu_entry));
me->pos = pos;
me->modifier = mod;
me->is_main = menu_is_mainmenu_root (path, &me->root_offset);
@@ -1196,26 +1201,31 @@ menu_add (char *path, char *label, char *cmd, char *ucmd, int pos, int state, in
me->markup = markup;
me->enable = enable;
me->key = key;
me->path = g_strdup (path);
me->path = strdup (path);
me->label = NULL;
me->cmd = NULL;
me->ucmd = NULL;
me->group = NULL;
me->icon = NULL;
me->label = g_strdup (label);
me->cmd = g_strdup (cmd);
me->ucmd = g_strdup (ucmd);
me->group = g_strdup (group);
me->icon = g_strdup (icon);
if (label)
me->label = strdup (label);
if (cmd)
me->cmd = strdup (cmd);
if (ucmd)
me->ucmd = strdup (ucmd);
if (group)
me->group = strdup (group);
if (icon)
me->icon = strdup (icon);
menu_list = g_slist_append (menu_list, me);
label = fe_menu_add (me);
if (label)
{
/* FE has given us a stripped label */
g_free (me->label);
me->label = g_strdup (label);
free (me->label);
me->label = strdup (label);
g_free (label); /* this is from pango */
}
}
@@ -1311,7 +1321,7 @@ cmd_menu (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if (markup)
{
char *p; /* to force pango closing tags through */
for (p = label; p && *p; p++)
for (p = label; *p; p++)
if (*p == 3)
*p = '/';
}
@@ -1444,7 +1454,7 @@ exec_check_process (struct session *sess)
{
close (sess->running_exec->myfd);
fe_input_remove (sess->running_exec->iotag);
g_free (sess->running_exec);
free (sess->running_exec);
sess->running_exec = NULL;
}
}
@@ -1521,10 +1531,11 @@ cmd_execw (struct session *sess, char *tbuf, char *word[], char *word_eol[])
return FALSE;
}
len = strlen(word_eol[2]);
temp = g_strconcat (word_eol[2], "\n", NULL);
temp = malloc(len + 2);
sprintf(temp, "%s\n", word_eol[2]);
PrintText(sess, temp);
write(sess->running_exec->myfd, temp, len + 1);
g_free(temp);
free(temp);
return TRUE;
}
@@ -1548,7 +1559,7 @@ exec_handle_colors (char *buf, int len)
if (strchr (buf, 27) == 0)
return;
nbuf = g_malloc (len + 1);
nbuf = malloc (len + 1);
while (i < len)
{
@@ -1642,7 +1653,7 @@ norm: nbuf[j] = buf[i];
nbuf[j] = 0;
memcpy (buf, nbuf, j + 1);
g_free (nbuf);
free (nbuf);
}
#ifndef HAVE_MEMRCHR
@@ -1654,7 +1665,7 @@ memrchr (const void *block, int c, size_t size)
for (p = (unsigned char *)block + size; p != block; p--)
if (*p == c)
return p;
return NULL;
return 0;
}
#endif
@@ -1668,14 +1679,14 @@ exec_data (GIOChannel *source, GIOCondition condition, struct nbexec *s)
len = s->buffill;
if (len) {
/* append new data to buffered incomplete line */
buf = g_malloc (len + 2050);
buf = malloc(len + 2050);
memcpy(buf, s->linebuf, len);
readpos = buf + len;
g_free (s->linebuf);
free(s->linebuf);
s->linebuf = NULL;
}
else
readpos = buf = g_malloc (2050);
readpos = buf = malloc(2050);
rd = read (sok, readpos, 2048);
if (rd < 1)
@@ -1696,12 +1707,12 @@ exec_data (GIOChannel *source, GIOCondition condition, struct nbexec *s)
else
PrintText (s->sess, buf);
}
g_free(buf);
free(buf);
waitpid (s->childpid, NULL, 0);
s->sess->running_exec = NULL;
fe_input_remove (s->iotag);
close (sok);
g_free (s);
free (s);
return TRUE;
}
len += rd;
@@ -1714,7 +1725,7 @@ exec_data (GIOChannel *source, GIOCondition condition, struct nbexec *s)
rest = buf;
if (*rest) {
s->buffill = len - (rest - buf); /* = strlen(rest) */
s->linebuf = g_malloc (s->buffill + 1);
s->linebuf = malloc(s->buffill + 1);
memcpy(s->linebuf, rest, s->buffill);
*rest = '\0';
len -= s->buffill; /* possibly 0 */
@@ -1730,7 +1741,7 @@ exec_data (GIOChannel *source, GIOCondition condition, struct nbexec *s)
PrintText (s->sess, buf);
}
g_free (buf);
free(buf);
return TRUE;
}
@@ -1792,7 +1803,8 @@ cmd_exec (struct session *sess, char *tbuf, char *word[], char *word_eol[])
return FALSE;
}
#endif
s = g_new0 (struct nbexec, 1);
s = (struct nbexec *) malloc (sizeof (struct nbexec));
memset(s, 0, sizeof(*s));
s->myfd = fds[0];
s->tochannel = tochannel;
s->sess = sess;
@@ -1839,9 +1851,8 @@ cmd_exec (struct session *sess, char *tbuf, char *word[], char *word_eol[])
PrintText (sess, "Error in fork(2)\n");
close(fds[0]);
close(fds[1]);
g_free (s);
}
else
free (s);
} else
{
/* Parent path */
close(fds[1]);
@@ -1929,12 +1940,12 @@ get_bool_cb (int val, getvalinfo *info)
{
char buf[512];
g_snprintf (buf, sizeof (buf), "%s %d", info->cmd, val);
snprintf (buf, sizeof (buf), "%s %d", info->cmd, val);
if (is_session (info->sess))
handle_command (info->sess, buf, FALSE);
g_free (info->cmd);
g_free (info);
free (info->cmd);
free (info);
}
static int
@@ -1945,8 +1956,8 @@ cmd_getbool (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if (!word[4][0])
return FALSE;
info = g_new (getvalinfo, 1);
info->cmd = g_strdup (word[2]);
info = malloc (sizeof (*info));
info->cmd = strdup (word[2]);
info->sess = sess;
fe_get_bool (word[3], word_eol[4], get_bool_cb, info);
@@ -1961,13 +1972,13 @@ get_int_cb (int cancel, int val, getvalinfo *info)
if (!cancel)
{
g_snprintf (buf, sizeof (buf), "%s %d", info->cmd, val);
snprintf (buf, sizeof (buf), "%s %d", info->cmd, val);
if (is_session (info->sess))
handle_command (info->sess, buf, FALSE);
}
g_free (info->cmd);
g_free (info);
free (info->cmd);
free (info);
}
static int
@@ -1978,8 +1989,8 @@ cmd_getint (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if (!word[4][0])
return FALSE;
info = g_new (getvalinfo, 1);
info->cmd = g_strdup (word[3]);
info = malloc (sizeof (*info));
info->cmd = strdup (word[3]);
info->sess = sess;
fe_get_int (word[4], atoi (word[2]), get_int_cb, info);
@@ -1996,13 +2007,13 @@ get_file_cb (char *cmd, char *file)
no args */
if (file)
{
g_snprintf (buf, sizeof (buf), "%s %s", cmd, file);
snprintf (buf, sizeof (buf), "%s %s", cmd, file);
handle_command (current_sess, buf, FALSE);
}
else
{
handle_command (current_sess, cmd, FALSE);
g_free (cmd);
free (cmd);
}
}
@@ -2033,7 +2044,7 @@ cmd_getfile (struct session *sess, char *tbuf, char *word[], char *word_eol[])
idx++;
}
fe_get_file (word[idx+1], word[idx+2], (void *)get_file_cb, g_strdup (word[idx]), flags);
fe_get_file (word[idx+1], word[idx+2], (void *)get_file_cb, strdup (word[idx]), flags);
return TRUE;
}
@@ -2045,13 +2056,13 @@ get_str_cb (int cancel, char *val, getvalinfo *info)
if (!cancel)
{
g_snprintf (buf, sizeof (buf), "%s %s", info->cmd, val);
snprintf (buf, sizeof (buf), "%s %s", info->cmd, val);
if (is_session (info->sess))
handle_command (info->sess, buf, FALSE);
}
g_free (info->cmd);
g_free (info);
free (info->cmd);
free (info);
}
static int
@@ -2062,8 +2073,8 @@ cmd_getstr (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if (!word[4][0])
return FALSE;
info = g_new (getvalinfo, 1);
info->cmd = g_strdup (word[3]);
info = malloc (sizeof (*info));
info->cmd = strdup (word[3]);
info->sess = sess;
fe_get_str (word[4], word[2], get_str_cb, info);
@@ -2189,7 +2200,7 @@ cmd_help (struct session *sess, char *tbuf, char *word[], char *word_eol[])
} else
{
struct popup *pop;
char *buf = g_malloc (4096);
char *buf = malloc (4096);
help_list hl;
hl.longfmt = longfmt;
@@ -2234,7 +2245,7 @@ cmd_help (struct session *sess, char *tbuf, char *word[], char *word_eol[])
plugin_command_foreach (sess, &hl, (void *)show_help_line);
strcat (buf, "\n");
PrintText (sess, buf);
g_free (buf);
free (buf);
PrintTextf (sess, "\n%s\n\n", _("Type /HELP <command> for more information, or /HELP -l"));
}
@@ -2282,7 +2293,7 @@ cmd_ignore (struct session *sess, char *tbuf, char *word[], char *word_eol[])
strchr (mask, '*') == NULL)
{
mask = tbuf;
g_snprintf (tbuf, TBUFSIZE, "%s!*@*", word[2]);
snprintf (tbuf, TBUFSIZE, "%s!*@*", word[2]);
}
i = ignore_add (mask, type, TRUE);
@@ -2538,7 +2549,7 @@ cmd_load (struct session *sess, char *tbuf, char *word[], char *word_eol[])
PrintText (sess, errorstring (errno));
g_free (buf);
}
g_free (file);
free (file);
return TRUE;
}
@@ -2551,7 +2562,7 @@ cmd_load (struct session *sess, char *tbuf, char *word[], char *word_eol[])
file = expand_homedir (word[2]);
error = plugin_load (sess, file, arg);
g_free (file);
free (file);
if (error)
PrintText (sess, error);
@@ -2640,7 +2651,7 @@ cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[])
return TRUE;
}
g_snprintf (tbuf, TBUFSIZE, "\001ACTION %s\001\r", act);
snprintf (tbuf, TBUFSIZE, "\001ACTION %s\001\r", act);
/* first try through DCC CHAT */
if (dcc_write_chat (sess->channel, tbuf))
{
@@ -2663,7 +2674,7 @@ cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if (*split_text)
offset += strlen(split_text);
g_free (split_text);
g_free(split_text);
}
sess->server->p_action (sess->server, sess->channel, act + offset);
@@ -2710,7 +2721,7 @@ mop_cb (struct User *user, multidata *data)
static int
cmd_mop (struct session *sess, char *tbuf, char *word[], char *word_eol[])
{
char **nicks = g_new0 (char *, sess->total - sess->ops);
char **nicks = malloc (sizeof (char *) * (sess->total - sess->ops));
multidata data;
data.nicks = nicks;
@@ -2718,7 +2729,7 @@ cmd_mop (struct session *sess, char *tbuf, char *word[], char *word_eol[])
tree_foreach (sess->usertree, (tree_traverse_func *)mop_cb, &data);
send_channel_modes (sess, tbuf, nicks, 0, data.i, '+', 'o', 0);
g_free (nicks);
free (nicks);
return TRUE;
}
@@ -2769,7 +2780,7 @@ cmd_msg (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if (*split_text)
offset += strlen(split_text);
g_free (split_text);
g_free(split_text);
}
sess->server->p_message (sess->server, nick, msg + offset);
offset = 0;
@@ -2790,7 +2801,7 @@ cmd_msg (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if (*split_text)
offset += strlen(split_text);
g_free (split_text);
g_free(split_text);
}
inbound_chanmsg (newsess->server, NULL, newsess->channel,
newsess->server->nick, msg + offset, TRUE, FALSE,
@@ -2884,7 +2895,7 @@ cmd_notice (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if (*split_text)
offset += strlen(split_text);
g_free (split_text);
g_free(split_text);
}
sess->server->p_notice (sess->server, word[2], text + offset);
@@ -2980,7 +2991,7 @@ cmd_ping (struct session *sess, char *tbuf, char *word[], char *word_eol[])
tim = make_ping_time ();
g_snprintf (timestring, sizeof (timestring), "%lu", tim);
snprintf (timestring, sizeof (timestring), "%lu", tim);
sess->server->p_ping (sess->server, to, timestring);
return TRUE;
@@ -3043,7 +3054,7 @@ cmd_query (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if (*split_text)
offset += strlen(split_text);
g_free (split_text);
g_free(split_text);
}
sess->server->p_message (sess->server, nick, msg + offset);
inbound_chanmsg (nick_sess->server, nick_sess, nick_sess->channel,
@@ -3205,7 +3216,7 @@ cmd_send (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if (!word[2][0])
return FALSE;
#if 0
addr = dcc_get_my_address ();
if (addr == 0)
{
@@ -3220,10 +3231,10 @@ cmd_send (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if ((addr & 0xffff0000) == 0xc0a80000 || /* 192.168.x.x */
(addr & 0xff000000) == 0x0a000000) /* 10.x.x.x */
/* we got a private net address, let's PSEND or it'll fail */
g_snprintf (tbuf, 512, "DCC PSEND %s", word_eol[2]);
snprintf (tbuf, 512, "DCC PSEND %s", word_eol[2]);
else
g_snprintf (tbuf, 512, "DCC SEND %s", word_eol[2]);
#endif
snprintf (tbuf, 512, "DCC SEND %s", word_eol[2]);
handle_command (sess, tbuf, FALSE);
return TRUE;
@@ -3522,7 +3533,7 @@ cmd_unignore (struct session *sess, char *tbuf, char *word[],
if (strchr (mask, '?') == NULL && strchr (mask, '*') == NULL)
{
mask = tbuf;
g_snprintf (tbuf, TBUFSIZE, "%s!*@*", word[2]);
snprintf (tbuf, TBUFSIZE, "%s!*@*", word[2]);
}
if (ignore_del (mask, NULL))
@@ -4085,7 +4096,7 @@ usercommand_show_help (session *sess, char *name)
pop = (struct popup *) list->data;
if (!g_ascii_strcasecmp (pop->name, name))
{
g_snprintf (buf, sizeof(buf), _("User Command for: %s\n"), pop->cmd);
snprintf (buf, sizeof(buf), _("User Command for: %s\n"), pop->cmd);
PrintText (sess, buf);
found = TRUE;
@@ -4112,7 +4123,7 @@ help (session *sess, char *tbuf, char *helpcmd, int quiet)
{
if (cmd->help)
{
g_snprintf (tbuf, TBUFSIZE, _("Usage: %s\n"), _(cmd->help));
snprintf (tbuf, TBUFSIZE, _("Usage: %s\n"), _(cmd->help));
PrintText (sess, tbuf);
} else
{
@@ -4134,7 +4145,7 @@ help (session *sess, char *tbuf, char *helpcmd, int quiet)
* - this beast is used for UserCommands, UserlistButtons and CTCP replies */
int
auto_insert (char *dest, gsize destlen, unsigned char *src, char *word[],
auto_insert (char *dest, int destlen, unsigned char *src, char *word[],
char *word_eol[], char *a, char *c, char *d, char *e, char *h,
char *n, char *s, char *u)
{
@@ -4206,7 +4217,7 @@ auto_insert (char *dest, gsize destlen, unsigned char *src, char *word[],
switch (src[0])
{
case '%':
if ((dest - orig) + 2u >= destlen)
if ((dest - orig) + 2 >= destlen)
return 2;
dest[0] = '%';
dest[1] = 0;
@@ -4241,7 +4252,7 @@ auto_insert (char *dest, gsize destlen, unsigned char *src, char *word[],
case 'y':
now = time (0);
tm_ptr = localtime (&now);
g_snprintf (buf, sizeof (buf), "%4d%02d%02d", 1900 +
snprintf (buf, sizeof (buf), "%4d%02d%02d", 1900 +
tm_ptr->tm_year, 1 + tm_ptr->tm_mon, tm_ptr->tm_mday);
utf = buf;
break;
@@ -4300,78 +4311,81 @@ check_special_chars (char *cmd, int do_ascii) /* check for %X */
if (!len)
return;
buf = g_malloc (len + 1);
buf = malloc (len + 1);
while (cmd[j])
if (buf)
{
switch (cmd[j])
while (cmd[j])
{
case '%':
occur++;
if ( do_ascii &&
j + 3 < len &&
(isdigit ((unsigned char) cmd[j + 1]) && isdigit ((unsigned char) cmd[j + 2]) &&
isdigit ((unsigned char) cmd[j + 3])))
switch (cmd[j])
{
tbuf[0] = cmd[j + 1];
tbuf[1] = cmd[j + 2];
tbuf[2] = cmd[j + 3];
tbuf[3] = 0;
buf[i] = atoi (tbuf);
utf = g_locale_to_utf8 (buf + i, 1, 0, &utf_len, 0);
if (utf)
case '%':
occur++;
if ( do_ascii &&
j + 3 < len &&
(isdigit ((unsigned char) cmd[j + 1]) && isdigit ((unsigned char) cmd[j + 2]) &&
isdigit ((unsigned char) cmd[j + 3])))
{
memcpy (buf + i, utf, utf_len);
g_free (utf);
i += (utf_len - 1);
}
j += 3;
} else
{
switch (cmd[j + 1])
tbuf[0] = cmd[j + 1];
tbuf[1] = cmd[j + 2];
tbuf[2] = cmd[j + 3];
tbuf[3] = 0;
buf[i] = atoi (tbuf);
utf = g_locale_to_utf8 (buf + i, 1, 0, &utf_len, 0);
if (utf)
{
memcpy (buf + i, utf, utf_len);
g_free (utf);
i += (utf_len - 1);
}
j += 3;
} else
{
case 'R':
buf[i] = '\026';
break;
case 'U':
buf[i] = '\037';
break;
case 'B':
buf[i] = '\002';
break;
case 'I':
buf[i] = '\035';
break;
case 'C':
buf[i] = '\003';
break;
case 'O':
buf[i] = '\017';
break;
case 'H': /* CL: invisible text code */
buf[i] = HIDDEN_CHAR;
break;
case '%':
buf[i] = '%';
break;
default:
buf[i] = '%';
j--;
switch (cmd[j + 1])
{
case 'R':
buf[i] = '\026';
break;
case 'U':
buf[i] = '\037';
break;
case 'B':
buf[i] = '\002';
break;
case 'I':
buf[i] = '\035';
break;
case 'C':
buf[i] = '\003';
break;
case 'O':
buf[i] = '\017';
break;
case 'H': /* CL: invisible text code */
buf[i] = HIDDEN_CHAR;
break;
case '%':
buf[i] = '%';
break;
default:
buf[i] = '%';
j--;
break;
}
j++;
break;
default:
buf[i] = cmd[j];
}
j++;
break;
default:
buf[i] = cmd[j];
}
j++;
i++;
}
j++;
i++;
buf[i] = 0;
if (occur)
strcpy (cmd, buf);
free (buf);
}
buf[i] = 0;
if (occur)
strcpy (cmd, buf);
g_free (buf);
}
typedef struct
@@ -4394,7 +4408,7 @@ nick_comp_cb (struct User *user, nickdata *data)
lenu = strlen (user->nick);
if (lenu == data->len)
{
g_snprintf (data->tbuf, TBUFSIZE, "%s%s", user->nick, data->space);
snprintf (data->tbuf, TBUFSIZE, "%s%s", user->nick, data->space);
data->len = -1;
return FALSE;
} else if (lenu < data->bestlen)
@@ -4438,7 +4452,7 @@ perform_nick_completion (struct session *sess, char *cmd, char *tbuf)
if (data.best)
{
g_snprintf (tbuf, TBUFSIZE, "%s%s", data.best->nick, space - 1);
snprintf (tbuf, TBUFSIZE, "%s%s", data.best->nick, space - 1);
return;
}
}
@@ -4471,10 +4485,12 @@ handle_say (session *sess, char *text, int check_spch)
struct DCC *dcc;
char *word[PDIWORDS+1];
char *word_eol[PDIWORDS+1];
char *pdibuf;
char *newcmd;
char pdibuf_static[1024];
char newcmd_static[1024];
char *pdibuf = pdibuf_static;
char *newcmd = newcmd_static;
int len;
int newcmdlen;
int newcmdlen = sizeof newcmd_static;
message_tags_data no_tags = MESSAGE_TAGS_DATA_INIT;
if (strcmp (sess->channel, "(lastlog)") == 0)
@@ -4484,9 +4500,11 @@ handle_say (session *sess, char *text, int check_spch)
}
len = strlen (text);
pdibuf = g_malloc (len + 1);
newcmdlen = MAX(len + NICKLEN + 1, TBUFSIZE);
newcmd = g_malloc (newcmdlen);
if (len >= sizeof pdibuf_static)
pdibuf = malloc (len + 1);
if (len + NICKLEN >= newcmdlen)
newcmd = malloc (newcmdlen = len + NICKLEN + 1);
if (check_spch && prefs.hex_input_perc_color)
check_special_chars (text, prefs.hex_input_perc_ascii);
@@ -4547,7 +4565,7 @@ handle_say (session *sess, char *text, int check_spch)
if (*split_text)
offset += strlen(split_text);
g_free (split_text);
g_free(split_text);
}
inbound_chanmsg (sess->server, sess, sess->channel, sess->server->nick,
@@ -4559,9 +4577,11 @@ handle_say (session *sess, char *text, int check_spch)
}
xit:
g_free (pdibuf);
if (pdibuf != pdibuf_static)
free (pdibuf);
g_free (newcmd);
if (newcmd != newcmd_static)
free (newcmd);
}
char *
@@ -4655,6 +4675,8 @@ handle_command (session *sess, char *cmd, int check_spch)
char *word_eol[PDIWORDS+1];
static int command_level = 0;
struct commands *int_cmd;
char pdibuf_static[1024];
char tbuf_static[TBUFSIZE];
char *pdibuf;
char *tbuf;
int len;
@@ -4669,8 +4691,23 @@ handle_command (session *sess, char *cmd, int check_spch)
/* anything below MUST DEC command_level before returning */
len = strlen (cmd);
pdibuf = g_malloc (len + 1);
tbuf = g_malloc (MAX(TBUFSIZE, (len * 2) + 1));
if (len >= sizeof (pdibuf_static))
{
pdibuf = malloc (len + 1);
}
else
{
pdibuf = pdibuf_static;
}
if ((len * 2) >= sizeof (tbuf_static))
{
tbuf = malloc ((len * 2) + 1);
}
else
{
tbuf = tbuf_static;
}
/* split the text into words and word_eol */
process_data_init (pdibuf, cmd, word, word_eol, TRUE, TRUE);
@@ -4763,8 +4800,15 @@ handle_command (session *sess, char *cmd, int check_spch)
xit:
command_level--;
g_free (pdibuf);
g_free (tbuf);
if (pdibuf != pdibuf_static)
{
free (pdibuf);
}
if (tbuf != tbuf_static)
{
free (tbuf);
}
return ret;
}

View File

@@ -25,7 +25,7 @@
extern const struct commands xc_cmds[];
extern GSList *menu_list;
int auto_insert (char *dest, gsize destlen, unsigned char *src, char *word[], char *word_eol[],
int auto_insert (char *dest, int destlen, unsigned char *src, char *word[], char *word_eol[],
char *a, char *c, char *d, char *e, char *h, char *n, char *s, char *u);
char *command_insert_vars (session *sess, char *cmd);
int handle_command (session *sess, char *cmd, int check_spch);

View File

@@ -1,216 +0,0 @@
/* HexChat
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <string.h>
#include <gio/gio.h>
#include "hexchat-plugin.h"
#define _(x) hexchat_gettext(ph,x)
static hexchat_plugin *ph;
static GSocketService *service;
static GHashTable *responses;
struct ident_info
{
GSocketConnection *conn;
gchar *username;
gchar read_buf[16];
} typedef ident_info;
static int
identd_cleanup_response_cb (gpointer userdata)
{
g_return_val_if_fail (responses != NULL, 0);
g_hash_table_remove (responses, userdata);
return 0;
}
static int
identd_command_cb (char *word[], char *word_eol[], void *userdata)
{
g_return_val_if_fail (responses != NULL, HEXCHAT_EAT_ALL);
if (word[2] && *word[2] && word[3] && *word[3])
{
guint64 port = g_ascii_strtoull (word[2], NULL, 0);
if (port && port <= G_MAXUINT16)
{
g_hash_table_insert (responses, GINT_TO_POINTER (port), g_strdup (word[3]));
/* Automatically remove entry after 30 seconds */
hexchat_hook_timer (ph, 30000, identd_cleanup_response_cb, GINT_TO_POINTER (port));
}
}
else
{
hexchat_command (ph, "HELP IDENTD");
}
return HEXCHAT_EAT_HEXCHAT;
}
static void
identd_write_ready (GOutputStream *stream, GAsyncResult *res, ident_info *info)
{
g_output_stream_write_finish (stream, res, NULL);
g_free (info->username);
g_object_unref (info->conn);
g_free (info);
}
static void
identd_read_ready (GInputStream *in_stream, GAsyncResult *res, ident_info *info)
{
GSocketAddress *sok_addr;
GOutputStream *out_stream;
guint64 local, remote;
gchar buf[512], *p;
if (g_input_stream_read_finish (in_stream, res, NULL))
{
local = g_ascii_strtoull (info->read_buf, NULL, 0);
p = strchr (info->read_buf, ',');
if (!p)
goto cleanup;
remote = g_ascii_strtoull (p + 1, NULL, 0);
if (!local || !remote || local > G_MAXUINT16 || remote > G_MAXUINT16)
goto cleanup;
info->username = g_strdup (g_hash_table_lookup (responses, GINT_TO_POINTER (local)));
if (!info->username)
goto cleanup;
g_hash_table_remove (responses, GINT_TO_POINTER (local));
if ((sok_addr = g_socket_connection_get_remote_address (info->conn, NULL)))
{
GInetAddress *inet_addr;
gchar *addr;
inet_addr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (sok_addr));
addr = g_inet_address_to_string (inet_addr);
hexchat_printf (ph, _("*\tServicing ident request from %s as %s"), addr, info->username);
g_object_unref (sok_addr);
g_object_unref (inet_addr);
g_free (addr);
}
g_snprintf (buf, sizeof (buf), "%"G_GUINT16_FORMAT", %"G_GUINT16_FORMAT" : USERID : UNIX : %s\r\n", (guint16)local, (guint16)remote, info->username);
out_stream = g_io_stream_get_output_stream (G_IO_STREAM (info->conn));
g_output_stream_write_async (out_stream, buf, strlen (buf), G_PRIORITY_DEFAULT,
NULL, (GAsyncReadyCallback)identd_write_ready, info);
}
return;
cleanup:
g_object_unref (info->conn);
g_free (info);
}
static gboolean
identd_incoming_cb (GSocketService *service, GSocketConnection *conn,
GObject *source, gpointer userdata)
{
GInputStream *stream;
ident_info *info;
info = g_new0 (ident_info, 1);
info->conn = conn;
g_object_ref (conn);
stream = g_io_stream_get_input_stream (G_IO_STREAM (conn));
g_input_stream_read_async (stream, info->read_buf, sizeof (info->read_buf), G_PRIORITY_DEFAULT,
NULL, (GAsyncReadyCallback)identd_read_ready, info);
return TRUE;
}
static gboolean
identd_start_server (void)
{
GError *error = NULL;
int enabled, port = 113;
if (hexchat_get_prefs (ph, "identd", NULL, &enabled) == 3 && enabled)
{
if (!enabled)
return TRUE; /*...*/
}
if (hexchat_get_prefs (ph, "identd_port", NULL, &port) == 2 && (port <= 0 || port > G_MAXUINT16))
{
port = 113;
}
service = g_socket_service_new ();
g_socket_listener_add_inet_port (G_SOCKET_LISTENER (service), port, NULL, &error);
if (error)
{
hexchat_printf (ph, _("*\tError starting identd server: %s"), error->message);
g_object_unref (service);
return FALSE;
}
/*hexchat_printf (ph, "*\tIdentd listening on port: %d", port); */
g_signal_connect (G_OBJECT (service), "incoming", G_CALLBACK(identd_incoming_cb), NULL);
g_socket_service_start (service);
return TRUE;
}
int
identd_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name,
char **plugin_desc, char **plugin_version, char *arg)
{
ph = plugin_handle;
*plugin_name = "";
*plugin_desc = "";
*plugin_version = "";
responses = g_hash_table_new_full (NULL, NULL, NULL, g_free);
hexchat_hook_command (ph, "IDENTD", HEXCHAT_PRI_NORM, identd_command_cb,
_("IDENTD <port> <username>"), NULL);
return identd_start_server ();
}
int
identd_plugin_deinit (void)
{
if (service)
{
g_socket_service_stop (service);
g_object_unref (service);
}
g_hash_table_destroy (responses);
return 1;
}

View File

@@ -17,8 +17,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
@@ -45,7 +43,7 @@ typedef struct
char *command;
int ref;
int repeat;
int timeout;
float timeout;
unsigned int forever:1;
} timer;
@@ -53,9 +51,9 @@ static void
timer_del (timer *tim)
{
timer_list = g_slist_remove (timer_list, tim);
g_free (tim->command);
free (tim->command);
hexchat_unhook (ph, tim->hook);
g_free (tim);
free (tim);
}
static void
@@ -101,7 +99,7 @@ timeout_cb (timer *tim)
}
static void
timer_add (int ref, int timeout, int repeat, char *command)
timer_add (int ref, float timeout, int repeat, char *command)
{
timer *tim;
GSList *list;
@@ -119,18 +117,18 @@ timer_add (int ref, int timeout, int repeat, char *command)
}
}
tim = g_new (timer, 1);
tim = malloc (sizeof (timer));
tim->ref = ref;
tim->repeat = repeat;
tim->timeout = timeout;
tim->command = g_strdup (command);
tim->command = strdup (command);
tim->context = hexchat_get_context (ph);
tim->forever = FALSE;
if (repeat == 0)
tim->forever = TRUE;
tim->hook = hexchat_hook_timer (ph, timeout, (void *)timeout_cb, tim);
tim->hook = hexchat_hook_timer (ph, timeout * 1000.0, (void *)timeout_cb, tim);
timer_list = g_slist_append (timer_list, tim);
}
@@ -152,7 +150,7 @@ timer_showlist (void)
while (list)
{
tim = list->data;
hexchat_printf (ph, _("%5d %8.1f %7d %s\n"), tim->ref, tim->timeout / 1000.0f,
hexchat_printf (ph, _("%5d %8.1f %7d %s\n"), tim->ref, tim->timeout,
tim->repeat, tim->command);
list = list->next;
}
@@ -162,7 +160,7 @@ static int
timer_cb (char *word[], char *word_eol[], void *userdata)
{
int repeat = 1;
double timeout;
float timeout;
int offset = 0;
int ref = 0;
int quiet = FALSE;
@@ -201,10 +199,10 @@ timer_cb (char *word[], char *word_eol[], void *userdata)
timeout = atof (word[2 + offset]);
command = word_eol[3 + offset];
if (timeout < 0.1 || timeout * 1000 > INT_MAX || !command[0])
if (timeout < 0.1 || !command[0])
hexchat_print (ph, HELP);
else
timer_add (ref, (int) timeout * 1000, repeat, command);
timer_add (ref, timeout, repeat, command);
return HEXCHAT_EAT_HEXCHAT;
}

View File

@@ -161,12 +161,16 @@ plugin_free (hexchat_plugin *pl, int do_deinit, int allow_refuse)
xit:
if (pl->free_strings)
{
g_free (pl->name);
g_free (pl->desc);
g_free (pl->version);
if (pl->name)
free (pl->name);
if (pl->desc)
free (pl->desc);
if (pl->version)
free (pl->version);
}
g_free ((char *)pl->filename);
g_free (pl);
if (pl->filename)
free ((char *)pl->filename);
free (pl);
plugin_list = g_slist_remove (plugin_list, pl);
@@ -184,7 +188,7 @@ plugin_list_add (hexchat_context *ctx, char *filename, const char *name,
{
hexchat_plugin *pl;
pl = g_new (hexchat_plugin, 1);
pl = malloc (sizeof (hexchat_plugin));
pl->handle = handle;
pl->filename = filename;
pl->context = ctx;
@@ -235,7 +239,9 @@ plugin_add (session *sess, char *filename, void *handle, void *init_func,
hexchat_plugin *pl;
char *file;
file = g_strdup (filename);
file = NULL;
if (filename)
file = strdup (filename);
pl = plugin_list_add (sess, file, file, NULL, NULL, handle, deinit_func,
fake, FALSE);
@@ -590,7 +596,7 @@ xit:
if (!hook || hook->type == HOOK_DELETED)
{
hook_list = g_slist_remove (hook_list, hook);
g_free (hook);
free (hook);
}
list = next;
}
@@ -609,7 +615,13 @@ plugin_emit_command (session *sess, char *name, char *word[], char *word_eol[])
hexchat_event_attrs *
hexchat_event_attrs_create (hexchat_plugin *ph)
{
return g_new0 (hexchat_event_attrs, 1);
hexchat_event_attrs *attrs;
attrs = g_malloc (sizeof (*attrs));
attrs->server_time_utc = (time_t) 0;
return attrs;
}
void
@@ -784,11 +796,15 @@ plugin_add_hook (hexchat_plugin *pl, int type, int pri, const char *name,
{
hexchat_hook *hook;
hook = g_new0 (hexchat_hook, 1);
hook = malloc (sizeof (hexchat_hook));
memset (hook, 0, sizeof (hexchat_hook));
hook->type = type;
hook->pri = pri;
hook->name = g_strdup (name);
hook->help_text = g_strdup (help_text);
if (name)
hook->name = strdup (name);
if (help_text)
hook->help_text = strdup (help_text);
hook->callback = callb;
hook->pl = pl;
hook->userdata = userdata;
@@ -876,8 +892,10 @@ hexchat_unhook (hexchat_plugin *ph, hexchat_hook *hook)
hook->type = HOOK_DELETED; /* expunge later */
g_free (hook->name); /* NULL for timers & fds */
g_free (hook->help_text); /* NULL for non-commands */
if (hook->name)
free (hook->name); /* NULL for timers & fds */
if (hook->help_text)
free (hook->help_text); /* NULL for non-commands */
return hook->userdata;
}
@@ -971,7 +989,7 @@ void
hexchat_command (hexchat_plugin *ph, const char *command)
{
char *conv;
gssize len = -1;
int len = -1;
if (!is_session (ph->context))
{
@@ -1245,7 +1263,8 @@ hexchat_list_get (hexchat_plugin *ph, const char *name)
{
hexchat_list *list;
list = g_new0 (hexchat_list, 1);
list = malloc (sizeof (hexchat_list));
list->pos = NULL;
switch (str_hash (name))
{
@@ -1280,7 +1299,7 @@ hexchat_list_get (hexchat_plugin *ph, const char *name)
} /* fall through */
default:
g_free (list);
free (list);
return NULL;
}
@@ -1292,7 +1311,7 @@ hexchat_list_free (hexchat_plugin *ph, hexchat_list *xlist)
{
if (xlist->type == LIST_USERS)
g_slist_free (xlist->head);
g_free (xlist);
free (xlist);
}
int
@@ -1512,14 +1531,7 @@ hexchat_list_int (hexchat_plugin *ph, hexchat_list *xlist, const char *name)
case 0x34207553: /* address32 */
return ((struct DCC *)data)->addr;
case 0x181a6: /* cps */
{
gint64 cps = ((struct DCC *)data)->cps;
if (cps <= INT_MAX)
{
return (int) cps;
}
return INT_MAX;
}
return ((struct DCC *)data)->cps;
case 0x349881: /* port */
return ((struct DCC *)data)->port;
case 0x1b254: /* pos */
@@ -1557,7 +1569,7 @@ hexchat_list_int (hexchat_plugin *ph, hexchat_list *xlist, const char *name)
case 0x5cfee87: /* flags */
/* used if text_strip is unset */ /* 16 */
tmp <<= 1;
tmp |= ((struct session *)data)->text_strip; /* 15 */
tmp = ((struct session *)data)->text_strip; /* 15 */
tmp <<= 1;
/* used if text_scrollback is unset */ /* 14 */
tmp <<= 1;
@@ -1632,8 +1644,8 @@ hexchat_plugingui_add (hexchat_plugin *ph, const char *filename,
const char *version, char *reserved)
{
#ifdef USE_PLUGIN
ph = plugin_list_add (NULL, g_strdup (filename), g_strdup (name), g_strdup (desc),
g_strdup (version), NULL, NULL, TRUE, TRUE);
ph = plugin_list_add (NULL, strdup (filename), strdup (name), strdup (desc),
strdup (version), NULL, NULL, TRUE, TRUE);
fe_pluginlist_update ();
#endif
@@ -1759,8 +1771,6 @@ hexchat_pluginpref_set_str_real (hexchat_plugin *pl, const char *var, const char
{
g_free (confname);
g_free (confname_tmp);
if (fpIn)
fclose (fpIn);
return 0;
}
else if (fpIn == NULL) /* no previous config file, no parsing */
@@ -1898,6 +1908,7 @@ hexchat_pluginpref_get_str_real (hexchat_plugin *pl, const char *var, char *dest
g_free (confname);
return 0;
}
g_free (confname);
if (!cfg_get_str (cfg, var, buf, sizeof(buf)))
@@ -1926,7 +1937,7 @@ hexchat_pluginpref_set_int (hexchat_plugin *pl, const char *var, int value)
{
char buffer[12];
g_snprintf (buffer, sizeof (buffer), "%d", value);
snprintf (buffer, sizeof (buffer), "%d", value);
return hexchat_pluginpref_set_str_real (pl, var, buffer, 1);
}

View File

@@ -429,7 +429,7 @@ irc_raw (server *serv, char *raw)
len = strlen (raw);
if (len < sizeof (tbuf) - 3)
{
len = g_snprintf (tbuf, sizeof (tbuf), "%s\r\n", raw);
len = snprintf (tbuf, sizeof (tbuf), "%s\r\n", raw);
tcp_send_len (serv, tbuf, len);
} else
{
@@ -590,7 +590,7 @@ process_numeric (session * sess, int n,
char *tim;
char outbuf[64];
g_snprintf (outbuf, sizeof (outbuf),
snprintf (outbuf, sizeof (outbuf),
"%02ld:%02ld:%02ld", idle / 3600, (idle / 60) % 60,
idle % 60);
if (timestamp == 0)
@@ -816,7 +816,10 @@ process_numeric (session * sess, int n,
case 349: /* end of exemption list */
sess = find_channel (serv, word[4]);
if (!sess)
{
sess = serv->front_session;
goto def;
}
if (!fe_ban_list_end (sess, 349))
goto def;
break;
@@ -841,7 +844,10 @@ process_numeric (session * sess, int n,
case 368:
sess = find_channel (serv, word[4]);
if (!sess)
{
sess = serv->front_session;
goto def;
}
if (!fe_ban_list_end (sess, 368))
goto def;
break;
@@ -1349,8 +1355,8 @@ process_named_servermsg (session *sess, char *buf, char *rawname, char *word_eol
/* Returns the timezone offset. This should be the same as the variable
* "timezone" in time.h, but *BSD doesn't have it.
*/
static time_t
get_timezone (void)
static int
get_timezone(void)
{
struct tm tm_utc, tm_local;
time_t t, time_utc, time_local;
@@ -1475,10 +1481,13 @@ irc_inline (server *serv, char *buf, int len)
char *type, *text;
char *word[PDIWORDS+1];
char *word_eol[PDIWORDS+1];
char *pdibuf;
char pdibuf_static[522]; /* 1 line can potentially be 512*6 in utf8 */
char *pdibuf = pdibuf_static;
message_tags_data tags_data = MESSAGE_TAGS_DATA_INIT;
pdibuf = g_malloc (len + 1);
/* need more than 522? fall back to malloc */
if (len >= sizeof (pdibuf_static))
pdibuf = malloc (len + 1);
sess = serv->front_session;
@@ -1500,7 +1509,7 @@ irc_inline (server *serv, char *buf, int len)
handle_message_tags(serv, tags, &tags_data);
}
url_check_line (buf);
url_check_line (buf, len);
/* split line into words and words_to_end_of_line */
process_data_init (pdibuf, buf, word, word_eol, FALSE, FALSE);
@@ -1557,7 +1566,8 @@ irc_inline (server *serv, char *buf, int len)
}
xit:
g_free (pdibuf);
if (pdibuf != pdibuf_static)
free (pdibuf);
}
void

File diff suppressed because it is too large Load Diff

View File

@@ -67,6 +67,12 @@ static const struct defaultserver def[] =
{0, "eu.afternet.org"},
{"Aitvaras", 0},
#ifdef USE_IPV6
#ifdef USE_OPENSSL
{0, "irc6.ktu.lt/+7668"},
#endif
{0, "irc6.ktu.lt/7666"},
#endif
#ifdef USE_OPENSSL
{0, "irc.data.lt/+6668"},
{0, "irc.omnitel.net/+6668"},
@@ -186,6 +192,12 @@ static const struct defaultserver def[] =
{0, "irc.entropynet.net/+6697"},
#endif
{0, "irc.entropynet.net"},
#ifdef USE_IPV6
#ifdef USE_OPENSSL
{0, "irc6.entropynet.net/+6697"},
#endif
{0, "irc6.entropynet.net"},
#endif
{"EsperNet", 0, 0, 0, LOGIN_SASL},
#ifdef USE_OPENSSL
@@ -314,6 +326,9 @@ static const struct defaultserver def[] =
{0, "as.link-net.org/+7000"},
{0, "eu.link-net.org/+7000"},
{0, "us.link-net.org/+7000"},
#ifdef USE_IPV6
{0, "irc6.link-net.org/+7000"},
#endif
#endif
{"MindForge", 0},
@@ -551,7 +566,9 @@ servlist_favchan_copy (favchannel *fav)
{
favchannel *newfav;
newfav = g_new (favchannel, 1);
newfav = malloc (sizeof (favchannel));
memset (newfav, 0, sizeof (favchannel));
newfav->name = g_strdup (fav->name);
newfav->key = g_strdup (fav->key); /* g_strdup() can handle NULLs so no need to check it */
@@ -907,8 +924,9 @@ servlist_server_add (ircnet *net, char *name)
{
ircserver *serv;
serv = g_new (ircserver, 1);
serv->hostname = g_strdup (name);
serv = malloc (sizeof (ircserver));
memset (serv, 0, sizeof (ircserver));
serv->hostname = strdup (name);
net->servlist = g_slist_append (net->servlist, serv);
@@ -920,8 +938,9 @@ servlist_command_add (ircnet *net, char *cmd)
{
commandentry *entry;
entry = g_new (commandentry, 1);
entry->command = g_strdup (cmd);
entry = malloc (sizeof (commandentry));
memset (entry, 0, sizeof (commandentry));
entry->command = strdup (cmd);
net->commandlist = g_slist_append (net->commandlist, entry);
@@ -933,7 +952,9 @@ servlist_favchan_listadd (GSList *chanlist, char *channel, char *key)
{
favchannel *chan;
chan = g_new (favchannel, 1);
chan = malloc (sizeof (favchannel));
memset (chan, 0, sizeof (favchannel));
chan->name = g_strdup (channel);
chan->key = g_strdup (key);
chanlist = g_slist_append (chanlist, chan);
@@ -969,8 +990,8 @@ servlist_favchan_add (ircnet *net, char *channel)
void
servlist_server_remove (ircnet *net, ircserver *serv)
{
g_free (serv->hostname);
g_free (serv);
free (serv->hostname);
free (serv);
net->servlist = g_slist_remove (net->servlist, serv);
}
@@ -1023,7 +1044,7 @@ free_and_clear (char *str)
char *orig = str;
while (*str)
*str++ = 0;
g_free (orig);
free (orig);
}
}
@@ -1051,18 +1072,25 @@ servlist_net_remove (ircnet *net)
servlist_server_remove_all (net);
network_list = g_slist_remove (network_list, net);
g_free (net->nick);
g_free (net->nick2);
g_free (net->user);
g_free (net->real);
if (net->nick)
free (net->nick);
if (net->nick2)
free (net->nick2);
if (net->user)
free (net->user);
if (net->real)
free (net->real);
free_and_clear (net->pass);
if (net->favchanlist)
g_slist_free_full (net->favchanlist, (GDestroyNotify) servlist_favchan_free);
if (net->commandlist)
g_slist_free_full (net->commandlist, (GDestroyNotify) servlist_command_free);
g_free (net->encoding);
g_free (net->name);
g_free (net);
if (net->comment)
free (net->comment);
if (net->encoding)
free (net->encoding);
free (net->name);
free (net);
/* for safety */
list = serv_list;
@@ -1082,8 +1110,10 @@ servlist_net_add (char *name, char *comment, int prepend)
{
ircnet *net;
net = g_new0 (ircnet, 1);
net->name = g_strdup (name);
net = malloc (sizeof (ircnet));
memset (net, 0, sizeof (ircnet));
net->name = strdup (name);
/* net->comment = strdup (comment);*/
net->flags = FLAG_CYCLE | FLAG_USE_GLOBAL | FLAG_USE_PROXY;
if (prepend)
@@ -1180,25 +1210,25 @@ servlist_load (void)
switch (buf[0])
{
case 'I':
net->nick = g_strdup (buf + 2);
net->nick = strdup (buf + 2);
break;
case 'i':
net->nick2 = g_strdup (buf + 2);
net->nick2 = strdup (buf + 2);
break;
case 'U':
net->user = g_strdup (buf + 2);
net->user = strdup (buf + 2);
break;
case 'R':
net->real = g_strdup (buf + 2);
net->real = strdup (buf + 2);
break;
case 'P':
net->pass = g_strdup (buf + 2);
net->pass = strdup (buf + 2);
break;
case 'L':
net->logintype = atoi (buf + 2);
break;
case 'E':
net->encoding = g_strdup (buf + 2);
net->encoding = strdup (buf + 2);
break;
case 'F':
net->flags = atoi (buf + 2);
@@ -1228,7 +1258,7 @@ servlist_load (void)
case 'A':
if (!net->pass)
{
net->pass = g_strdup (buf + 2);
net->pass = strdup (buf + 2);
if (!net->logintype)
{
net->logintype = LOGIN_SASL;
@@ -1237,7 +1267,7 @@ servlist_load (void)
case 'B':
if (!net->pass)
{
net->pass = g_strdup (buf + 2);
net->pass = strdup (buf + 2);
if (!net->logintype)
{
net->logintype = LOGIN_NICKSERV;

View File

@@ -45,6 +45,7 @@ typedef struct ircnet
char *real;
char *pass;
int logintype;
char *comment;
char *encoding;
GSList *servlist;
GSList *commandlist;

View File

@@ -29,9 +29,11 @@
#ifdef WIN32
#include <openssl/rand.h> /* RAND_seed() */
#endif
#include "config.h"
#include "../../config.h"
#include <time.h> /* asctime() */
#include <string.h> /* strncpy() */
#include "hexchat.h"
#include "cfgfiles.h"
#include "ssl.h" /* struct cert_info */
#include <glib.h>
@@ -44,10 +46,6 @@
#define SSL_OP_SINGLE_ECDH_USE 0
#endif
#ifndef SSL_OP_NO_COMPRESSION
#define SSL_OP_NO_COMPRESSION 0
#endif
/* globals */
static struct chiper_info chiper_info; /* static buffer for _SSL_get_cipher_info() */
static char err_buf[256]; /* generic error buffer */
@@ -99,10 +97,6 @@ _SSL_context_init (void (*info_cb_func), int server)
|SSL_OP_NO_TICKET
|SSL_OP_CIPHER_SERVER_PREFERENCE);
#if OPENSSL_VERSION_NUMBER >= 0x00908000L /* workaround for OpenSSL 0.9.8 */
sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
#endif
/* used in SSL_connect(), SSL_accept() */
SSL_CTX_set_info_callback (ctx, info_cb_func);
@@ -169,12 +163,15 @@ _SSL_get_cert_info (struct cert_info *cert_info, SSL * ssl)
/* EVP_PKEY *tmp_pkey; */
char notBefore[64];
char notAfter[64];
unsigned char digest[EVP_MAX_MD_SIZE]; /* SHA-256 fingerprint of the certificate */
int digest_length;
int alg;
int sign_alg;
int i;
if (!(peer_cert = SSL_get_peer_certificate (ssl)))
return (1); /* FATAL? */
return 1; /* FATAL? */
X509_NAME_oneline (X509_get_subject_name (peer_cert), cert_info->subject,
sizeof (cert_info->subject));
@@ -206,6 +203,17 @@ _SSL_get_cert_info (struct cert_info *cert_info, SSL * ssl)
EVP_PKEY_free (peer_pkey);
/* compute the fingerprint and make it pretty */
X509_digest (peer_cert, EVP_sha256(), digest, &digest_length);
cert_info->fingerprint[0] = '\0';
for (i = 0; i < digest_length; ++i)
{
char digits[4];
g_snprintf (digits, sizeof(digits), (i?":%02x":"%02x"), digest[i]);
g_strlcat (cert_info->fingerprint, digits, sizeof(cert_info->fingerprint));
}
/* SSL_SESSION_print_fp(stdout, SSL_get_session(ssl)); */
/*
if (ssl->session->sess_cert->peer_rsa_tmp) {
@@ -220,7 +228,7 @@ _SSL_get_cert_info (struct cert_info *cert_info, SSL * ssl)
X509_free (peer_cert);
return (0);
return 0;
}
@@ -237,10 +245,62 @@ _SSL_get_cipher_info (SSL * ssl)
sizeof (chiper_info.chiper));
SSL_CIPHER_get_bits (c, &chiper_info.chiper_bits);
return (&chiper_info);
return &chiper_info;
}
/*
* returns zero on success, non-zero on failure.
* "*.freenode.com" matches "ssl.freenode.com" and "irc.freenode.com" but not "chat.irc.freenode.com"
*/
int
_SSL_verify_cert_hostname (struct server *serv, struct cert_info *cert)
{
int i;
for (i = 0; cert->subject_word[i]; i++)
{
char *cname = cert->subject_word[i];
if (strstr (cname, "CN=") == cname)
{
char *host = serv->hostname;
cname += strlen ("CN=");
while (*host && *cname)
{
switch (*cname)
{
case '*': /* wildcard matching */
switch (*host)
{
case '.':
cname++; /* wildcard ends */
break;
default:
host++; /* wildcard continues */
if (!*host)
{
cname++; /* wildcard ends */
}
break;
}
break;
default: /* regular strcmp */
if (*host++ != *cname++)
{
return 1; /* error: mismatch */
}
break;
}
}
if (*host || *cname)
{
return 1; /* error: failed to process both strings completely */
}
return 0; /* success: match */
}
}
return 1; /* error: no CNAME field */
}
int
_SSL_send (SSL * ssl, char *buf, int len)
{
@@ -265,7 +325,7 @@ _SSL_send (SSL * ssl, char *buf, int len)
break;
}
return (num);
return num;
}
@@ -294,7 +354,7 @@ _SSL_recv (SSL * ssl, char *buf, int len)
break;
}
return (num);
return num;
}
@@ -314,7 +374,7 @@ _SSL_socket (SSL_CTX *ctx, int sd)
else
SSL_set_accept_state(ssl);
return (ssl);
return ssl;
}
@@ -324,7 +384,7 @@ _SSL_set_verify (SSL_CTX *ctx, void *verify_callback, char *cacert)
if (!SSL_CTX_set_default_verify_paths (ctx))
{
__SSL_fill_err_buf ("SSL_CTX_set_default_verify_paths");
return (err_buf);
return err_buf;
}
/*
if (cacert)
@@ -332,13 +392,13 @@ _SSL_set_verify (SSL_CTX *ctx, void *verify_callback, char *cacert)
if (!SSL_CTX_load_verify_locations (ctx, cacert, NULL))
{
__SSL_fill_err_buf ("SSL_CTX_load_verify_locations");
return (err_buf);
return err_buf;
}
}
*/
SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER, verify_callback);
return (NULL);
return NULL;
}
@@ -350,6 +410,7 @@ _SSL_close (SSL * ssl)
ERR_remove_state (0); /* free state buffer */
}
/* Hostname validation code based on OpenBSD's libtls. */
static int
@@ -504,7 +565,9 @@ _SSL_check_common_name (X509 *cert, const char *host)
if (common_name_len < 0)
return -1;
common_name = g_malloc0 (common_name_len + 1);
common_name = calloc (common_name_len + 1, 1);
if (common_name == NULL)
return -1;
X509_NAME_get_text_by_NID (name, NID_commonName, common_name, common_name_len + 1);
@@ -533,7 +596,7 @@ _SSL_check_common_name (X509 *cert, const char *host)
rv = 0;
out:
g_free(common_name);
free(common_name);
return rv;
}
@@ -548,3 +611,149 @@ _SSL_check_hostname (X509 *cert, const char *host)
return _SSL_check_common_name (cert, host);
}
/* Cert list */
static GSList *ssl_certlist = NULL; /* loaded at startup, saved on shutdown */
typedef struct ssl_certlist_item {
char *hostname;
char *fingerprint;
} ssl_certlist_item;
static void
_SSL_certlist_item_free (ssl_certlist_item *item)
{
g_return_if_fail (item != NULL);
if (item->hostname)
g_free (item->hostname);
if (item->fingerprint)
g_free (item->fingerprint);
g_free (item);
}
/* append a new hostname+fingerprint to the certificate list */
static void
_SSL_certlist_item_add (char *hostname, char *fingerprint)
{
int hn_length = strlen (hostname);
int fp_length = strlen (fingerprint);
ssl_certlist_item *item = g_malloc0 (sizeof (ssl_certlist_item));
if (item)
{
item->hostname = g_malloc0 (hn_length + 1);
item->fingerprint = g_malloc0 (fp_length + 1);
if (!item->hostname || !item->fingerprint)
{
_SSL_certlist_item_free (item);
return;
}
g_strlcpy (item->hostname, hostname, hn_length);
g_strlcpy (item->fingerprint, fingerprint, fp_length);
ssl_certlist = g_slist_append (ssl_certlist, item);
}
}
/*
* parse a simple new-line/whitepsace delimited text file of hostname+fingerprint combinations.
* it is not a problem if the file does not exist - we just end up with a empty list.
* it should be pretty safe against corrupted input. example file contents follows:
*
* irc.something.com 01:22:1a:c3:43:e6:35:ff:73:76:17:98:68:2f:2c:00:07:ae:1b:b8:81:a3:8d:0f:a6:a5:bd:dc:80:03:6c:33
* ssl.someircserver.com 02:22:1a:c3:43:e6:35:ff:73:76:17:98:68:2f:2c:00:07:ae:1b:b8:81:a3:8d:0f:a6:a5:bd:dc:80:03:6c:33
* another.com 03:22:1a:c3:43:e6:35:ff:73:76:17:98:68:2f:2c:00:07:ae:1b:b8:81:a3:8d:0f:a6:a5:bd:dc:80:03:6c:33
*/
void
_SSL_certlist_init ()
{
char buf[1024];
char *space, *host, *fp;
FILE *fh;
fh = hexchat_fopen_file ("sslcerts.conf", "r", 0);
if (!fh)
return;
while (fgets (buf, sizeof(buf), fh))
{
space = strchr (buf, ' ');
if (!space)
continue;
*space = '\0';
host = buf;
fp = g_strchomp (space + 1);
if (host[0] && fp[0])
_SSL_certlist_item_add (host, fp);
}
fclose (fh);
}
void
_SSL_certlist_save ()
{
/* write the list back out to disk. if there are no items an empty file is created. */
GSList *list;
ssl_certlist_item *item;
FILE *fh;
fh = hexchat_fopen_file ("sslcerts.conf", "w", 0);
if (fh)
{
list = ssl_certlist;
while (list)
{
item = (ssl_certlist_item*)list->data;
fprintf (fh, "%s %s\n", item->hostname, item->fingerprint);
list = g_slist_next (list);
}
fclose (fh);
}
}
/*
* a "computer" is a hostname + certificate combination. we extract these details
* from the input structures and make an O(n) (worst-case) pass over the list to find
* a match. if the computer is known to us we return 1, and 0 otherwise.
*/
int
_SSL_certlist_cert_check (struct server *serv, struct cert_info *cert)
{
GSList *list;
ssl_certlist_item *item;
if (serv && cert)
{
list = ssl_certlist;
while (list)
{
item = (ssl_certlist_item*)list->data;
if (!g_ascii_strcasecmp (serv->hostname, item->hostname)
&& !g_ascii_strcasecmp (cert->fingerprint, item->fingerprint))
{
return 1; /* the user trusts this computer */
}
list = g_slist_next (list);
}
}
return 0; /* the user does NOT trust this computer */
}
void
_SSL_certlist_cert_add (struct server *serv, struct cert_info *cert)
{
/* called from server.c when the user decides that they want to remember a computer */
_SSL_certlist_item_add (serv->hostname, cert->fingerprint);
}

View File

@@ -31,10 +31,25 @@ struct cert_info {
int sign_algorithm_bits;
char notbefore[32];
char notafter[32];
char fingerprint[128];
int rsa_tmp_bits;
};
enum
{
SSLALERT_RESPONSE_ABORT = 0,
SSLALERT_RESPONSE_ACCEPT = 1,
SSLALERT_RESPONSE_SAVE = 2
};
typedef struct ssl_alert_context
{
struct server *serv;
struct cert_info cert;
int verify_error;
} ssl_alert_context;
struct chiper_info {
char version[16];
char chiper[48];
@@ -55,6 +70,7 @@ void _SSL_close (SSL * ssl);
int _SSL_check_hostname(X509 *cert, const char *host);
int _SSL_get_cert_info (struct cert_info *cert_info, SSL * ssl);
struct chiper_info *_SSL_get_cipher_info (SSL * ssl);
int _SSL_verify_cert_hostname (struct server *serv, struct cert_info *cert);
/*char *_SSL_add_keypair (SSL_CTX *ctx, char *privkey, char *cert);*/
/*void _SSL_add_random_keypair(SSL_CTX *ctx, int bits);*/
@@ -82,4 +98,10 @@ int _SSL_recv (SSL * ssl, char *buf, int len);
/*int _SSL_verify_x509(X509 *x509);*/
/* functions for managing the SSL certificate/fingerprint cache */
void _SSL_certlist_init ();
void _SSL_certlist_save ();
int _SSL_certlist_cert_check (struct server *serv, struct cert_info *cert);
void _SSL_certlist_cert_add (struct server *serv, struct cert_info *cert);
#endif

View File

@@ -83,7 +83,7 @@ scrollback_get_filename (session *sess)
buf = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "scrollback" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S "%s.txt", get_xdir (), net, chan);
else
buf = NULL;
g_free (chan);
free (chan);
return buf;
}
@@ -177,7 +177,7 @@ scrollback_shrink (session *sess)
g_free (file);
if (fh == -1)
{
g_free (buf);
free (buf);
return;
}
@@ -200,7 +200,7 @@ scrollback_shrink (session *sess)
}
close (fh);
g_free (buf);
free (buf);
}
static void
@@ -319,9 +319,9 @@ scrollback_load (session *sess)
if (buf[0] == 'T')
{
if (sizeof (time_t) == 4)
stamp = g_ascii_strtoull (buf + 2, NULL, 10);
stamp = strtoul (buf + 2, NULL, 10);
else
stamp = g_ascii_strtoull (buf + 2, NULL, 10); /* in case time_t is 64 bits */
stamp = strtoull (buf + 2, NULL, 10); /* in case time_t is 64 bits */
text = strchr (buf + 3, ' ');
if (text && text[1])
{
@@ -383,7 +383,7 @@ log_close (session *sess)
{
currenttime = time (NULL);
write (sess->logfd, obuf,
g_snprintf (obuf, sizeof (obuf) - 1, _("**** ENDING LOGGING AT %s\n"),
snprintf (obuf, sizeof (obuf) - 1, _("**** ENDING LOGGING AT %s\n"),
ctime (&currenttime)));
close (sess->logfd);
sess->logfd = -1;
@@ -393,7 +393,9 @@ log_close (session *sess)
static void
mkdir_p (char *filename)
{
char *dirname = g_path_get_dirname (filename);
char *dirname;
dirname = g_path_get_dirname (filename);
g_mkdir_with_parents (dirname, 0700);
@@ -406,7 +408,7 @@ log_create_filename (char *channame)
char *tmp, *ret;
int mbl;
ret = tmp = g_strdup (channame);
ret = tmp = strdup (channame);
while (*tmp)
{
mbl = g_utf8_skip[((unsigned char *)tmp)[0]];
@@ -542,7 +544,7 @@ log_create_pathname (char *servname, char *channame, char *netname)
if (!netname)
{
netname = g_strdup ("NETWORK");
netname = strdup ("NETWORK");
}
else
{
@@ -552,7 +554,7 @@ log_create_pathname (char *servname, char *channame, char *netname)
/* first, everything is in UTF-8 */
if (!rfc_casecmp (channame, servname))
{
channame = g_strdup ("server");
channame = strdup ("server");
}
else
{
@@ -560,8 +562,8 @@ log_create_pathname (char *servname, char *channame, char *netname)
}
log_insert_vars (fname, sizeof (fname), prefs.hex_irc_logmask, channame, netname, servname);
g_free (channame);
g_free (netname);
free (channame);
free (netname);
/* insert time/date */
now = time (NULL);
@@ -570,17 +572,17 @@ log_create_pathname (char *servname, char *channame, char *netname)
/* create final path/filename */
if (logmask_is_fullpath ())
{
g_snprintf (fname, sizeof (fname), "%s", fnametime);
snprintf (fname, sizeof (fname), "%s", fnametime);
}
else /* relative path */
{
g_snprintf (fname, sizeof (fname), "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s", get_xdir (), fnametime);
snprintf (fname, sizeof (fname), "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s", get_xdir (), fnametime);
}
/* create all the subdirectories */
mkdir_p (fname);
return g_strdup (fname);
return g_strdup(fname);
}
static int
@@ -606,7 +608,7 @@ log_open_file (char *servname, char *channame, char *netname)
return -1;
currenttime = time (NULL);
write (fd, buf,
g_snprintf (buf, sizeof (buf), _("**** BEGIN LOGGING AT %s\n"),
snprintf (buf, sizeof (buf), _("**** BEGIN LOGGING AT %s\n"),
ctime (&currenttime)));
return fd;
@@ -623,15 +625,14 @@ log_open (session *sess)
if (!log_error && sess->logfd == -1)
{
char *filename = log_create_pathname (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE));
char *message = g_strdup_printf (_("* Can't open log file(s) for writing. Check the\npermissions on %s"), filename);
char *message;
g_free (filename);
message = g_strdup_printf (_("* Can't open log file(s) for writing. Check the\npermissions on %s"),
log_create_pathname (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE)));
fe_message (message, FE_MSG_WAIT | FE_MSG_ERROR);
g_free (message);
log_error = TRUE;
}
}
@@ -682,7 +683,8 @@ get_stamp_str (char *fmt, time_t tim, char **ret)
*ret = g_locale_to_utf8 (dest, len, 0, &len, 0);
}
g_free (loc);
if (loc)
g_free (loc);
return len;
}
@@ -710,13 +712,15 @@ log_write (session *sess, char *text, time_t ts)
log_open (sess);
/* change to a different log file? */
file = log_create_pathname (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE));
file = log_create_pathname (sess->server->servername, sess->channel,
server_get_network (sess->server, FALSE));
if (file)
{
if (g_access (file, F_OK) != 0)
{
close (sess->logfd);
sess->logfd = log_open_file (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE));
sess->logfd = log_open_file (sess->server->servername, sess->channel,
server_get_network (sess->server, FALSE));
}
g_free (file);
}
@@ -803,6 +807,8 @@ iso_8859_1_to_utf8 (unsigned char *text, int len, gsize *bytes_written)
/* worst case scenario: every byte turns into 3 bytes */
res = output = g_malloc ((len * 3) + 1);
if (!output)
return NULL;
while (len)
{
@@ -846,7 +852,7 @@ iso_8859_1_to_utf8 (unsigned char *text, int len, gsize *bytes_written)
}
char *
text_validate (char **text, gssize *len)
text_validate (char **text, int *len)
{
char *utf;
gsize utf_len;
@@ -900,10 +906,9 @@ PrintTextTimeStamp (session *sess, char *text, time_t timestamp)
{
text = "\n";
conv = NULL;
}
else
} else
{
gssize len = -1;
int len = -1;
conv = text_validate ((char **)&text, &len);
}
@@ -911,7 +916,8 @@ PrintTextTimeStamp (session *sess, char *text, time_t timestamp)
scrollback_save (sess, text);
fe_print_text (sess, text, timestamp, FALSE);
g_free (conv);
if (conv)
g_free (conv);
}
void
@@ -998,7 +1004,7 @@ PrintTextTimeStampf (session *sess, time_t timestamp, const char *format, ...)
Each XP_TE_* signal is hard coded to call text_emit which calls
display_event which decodes the data
This means that this system *should be faster* than g_snprintf because
This means that this system *should be faster* than snprintf because
it always 'knows' that format of the string (basically is preparses much
of the work)
@@ -1563,13 +1569,14 @@ pevent_load_defaults ()
for (i = 0; i < NUM_XP; i++)
{
g_free (pntevts_text[i]);
if (pntevts_text[i])
free (pntevts_text[i]);
/* make-te.c sets this 128 flag (DON'T call gettext() flag) */
if (te[i].num_args & 128)
pntevts_text[i] = g_strdup (te[i].def);
pntevts_text[i] = strdup (te[i].def);
else
pntevts_text[i] = g_strdup (_(te[i].def));
pntevts_text[i] = strdup (_(te[i].def));
}
}
@@ -1581,18 +1588,19 @@ pevent_make_pntevts ()
for (i = 0; i < NUM_XP; i++)
{
g_free (pntevts[i]);
if (pntevts[i] != NULL)
free (pntevts[i]);
if (pevt_build_string (pntevts_text[i], &(pntevts[i]), &m) != 0)
{
g_snprintf (out, sizeof (out),
snprintf (out, sizeof (out),
_("Error parsing event %s.\nLoading default."), te[i].name);
fe_message (out, FE_MSG_WARN);
g_free (pntevts_text[i]);
free (pntevts_text[i]);
/* make-te.c sets this 128 flag (DON'T call gettext() flag) */
if (te[i].num_args & 128)
pntevts_text[i] = g_strdup (te[i].def);
pntevts_text[i] = strdup (te[i].def);
else
pntevts_text[i] = g_strdup (_(te[i].def));
pntevts_text[i] = strdup (_(te[i].def));
if (pevt_build_string (pntevts_text[i], &(pntevts[i]), &m) != 0)
{
fprintf (stderr,
@@ -1614,17 +1622,22 @@ pevent_make_pntevts ()
static void
pevent_trigger_load (int *i_penum, char **i_text, char **i_snd)
{
int penum = *i_penum;
int penum = *i_penum, len;
char *text = *i_text, *snd = *i_snd;
if (penum != -1 && text != NULL)
{
g_free (pntevts_text[penum]);
pntevts_text[penum] = g_strdup (text);
len = strlen (text) + 1;
if (pntevts_text[penum])
free (pntevts_text[penum]);
pntevts_text[penum] = malloc (len);
memcpy (pntevts_text[penum], text, len);
}
g_free (text);
g_free (snd);
if (text)
free (text);
if (snd)
free (snd);
*i_text = NULL;
*i_snd = NULL;
*i_penum = 0;
@@ -1677,7 +1690,7 @@ pevent_load (char *filename)
close (fd);
return 1;
}
ibuf = g_malloc (st.st_size);
ibuf = malloc (st.st_size);
read (fd, ibuf, st.st_size);
close (fd);
@@ -1693,6 +1706,8 @@ pevent_load (char *filename)
continue;
*ofs = 0;
ofs++;
/*if (*ofs == 0)
continue;*/
if (strcmp (buf, "event_name") == 0)
{
@@ -1702,16 +1717,53 @@ pevent_load (char *filename)
continue;
} else if (strcmp (buf, "event_text") == 0)
{
g_free (text);
text = g_strdup (ofs);
if (text)
free (text);
#if 0
/* This allows updating of old strings. We don't use new defaults
if the user has customized the strings (.e.g a text theme).
Hash of the old default is enough to identify and replace it.
This only works in English. */
switch (g_str_hash (ofs))
{
case 0x526743a4:
/* %C08,02 Hostmask PRIV NOTI CHAN CTCP INVI UNIG %O */
text = strdup (te[XP_TE_IGNOREHEADER].def);
break;
case 0xe91bc9c2:
/* %C08,02 %O */
text = strdup (te[XP_TE_IGNOREFOOTER].def);
break;
case 0x1fbfdf22:
/* -%C10-%C11-%O$tDCC RECV: Cannot open $1 for writing - aborting. */
text = strdup (te[XP_TE_DCCFILEERR].def);
break;
default:
text = strdup (ofs);
}
#else
text = strdup (ofs);
#endif
continue;
}
}/* else if (strcmp (buf, "event_sound") == 0)
{
if (snd)
free (snd);
snd = strdup (ofs);
continue;
}*/
continue;
}
pevent_trigger_load (&penum, &text, &snd);
g_free (ibuf);
free (ibuf);
return 0;
}
@@ -1725,13 +1777,13 @@ pevent_check_all_loaded ()
if (pntevts_text[i] == NULL)
{
/*printf ("%s\n", te[i].name);
g_snprintf(out, sizeof(out), "The data for event %s failed to load. Reverting to defaults.\nThis may be because a new version of HexChat is loading an old config file.\n\nCheck all print event texts are correct", evtnames[i]);
snprintf(out, sizeof(out), "The data for event %s failed to load. Reverting to defaults.\nThis may be because a new version of HexChat is loading an old config file.\n\nCheck all print event texts are correct", evtnames[i]);
gtkutil_simpledialog(out); */
/* make-te.c sets this 128 flag (DON'T call gettext() flag) */
if (te[i].num_args & 128)
pntevts_text[i] = g_strdup (te[i].def);
pntevts_text[i] = strdup (te[i].def);
else
pntevts_text[i] = g_strdup (_(te[i].def));
pntevts_text[i] = strdup (_(te[i].def));
}
}
}
@@ -1756,10 +1808,9 @@ load_text_events ()
#define ARG_FLAG(argn) (1 << (argn))
void
format_event (session *sess, int index, char **args, char *o, gsize sizeofo, unsigned int stripcolor_args)
format_event (session *sess, int index, char **args, char *o, int sizeofo, unsigned int stripcolor_args)
{
int len, ii, numargs;
gsize oi;
int len, oi, ii, numargs;
char *i, *ar, d, a, done_all = FALSE;
i = pntevts[index];
@@ -1817,10 +1868,19 @@ format_event (session *sess, int index, char **args, char *o, gsize sizeofo, uns
done_all = TRUE;
continue;
case 3:
if (prefs.hex_text_indent)
o[oi++] = '\t';
else
o[oi++] = ' ';
/* if (sess->type == SESS_DIALOG)
{
if (prefs.dialog_indent_nicks)
o[oi++] = '\t';
else
o[oi++] = ' ';
} else
{*/
if (prefs.hex_text_indent)
o[oi++] = '\t';
else
o[oi++] = ' ';
/*}*/
break;
}
}
@@ -1848,7 +1908,7 @@ pevt_build_string (const char *input, char **output, int *max_arg)
int oi, ii, max = -1, len, x;
len = strlen (input);
i = g_malloc (len + 1);
i = malloc (len + 1);
memcpy (i, input, len + 1);
check_special_chars (i, TRUE);
@@ -1873,14 +1933,14 @@ pevt_build_string (const char *input, char **output, int *max_arg)
}
if (oi > 0)
{
s = g_new (struct pevt_stage1, 1);
s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1));
if (base == NULL)
base = s;
if (last != NULL)
last->next = s;
last = s;
s->next = NULL;
s->data = g_malloc (oi + sizeof (int) + 1);
s->data = malloc (oi + sizeof (int) + 1);
s->len = oi + sizeof (int) + 1;
clen += oi + sizeof (int) + 1;
s->data[0] = 0;
@@ -1891,12 +1951,12 @@ pevt_build_string (const char *input, char **output, int *max_arg)
if (ii == len)
{
fe_message ("String ends with a $", FE_MSG_WARN);
goto err;
return 1;
}
d = i[ii++];
if (d == 'a')
{
/* Hex value */
{ /* Hex value */
x = 0;
if (ii == len)
goto a_len_error;
d = i[ii++];
@@ -1917,24 +1977,24 @@ pevt_build_string (const char *input, char **output, int *max_arg)
o[oi++] = x;
continue;
a_len_error:
a_len_error:
fe_message ("String ends in $a", FE_MSG_WARN);
goto err;
a_range_error:
return 1;
a_range_error:
fe_message ("$a value is greater than 255", FE_MSG_WARN);
goto err;
return 1;
}
if (d == 't')
{
/* Tab - if tabnicks is set then write '\t' else ' ' */
s = g_new (struct pevt_stage1, 1);
s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1));
if (base == NULL)
base = s;
if (last != NULL)
last->next = s;
last = s;
s->next = NULL;
s->data = g_malloc (1);
s->data = malloc (1);
s->len = 1;
clen += 1;
s->data[0] = 3;
@@ -1943,21 +2003,21 @@ pevt_build_string (const char *input, char **output, int *max_arg)
}
if (d < '1' || d > '9')
{
g_snprintf (o, sizeof (o), "Error, invalid argument $%c\n", d);
snprintf (o, sizeof (o), "Error, invalid argument $%c\n", d);
fe_message (o, FE_MSG_WARN);
goto err;
return 1;
}
d -= '0';
if (max < d)
max = d;
s = g_new (struct pevt_stage1, 1);
s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1));
if (base == NULL)
base = s;
if (last != NULL)
last->next = s;
last = s;
s->next = NULL;
s->data = g_malloc (2);
s->data = malloc (2);
s->len = 2;
clen += 2;
s->data[0] = 1;
@@ -1965,14 +2025,14 @@ pevt_build_string (const char *input, char **output, int *max_arg)
}
if (oi > 0)
{
s = g_new (struct pevt_stage1, 1);
s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1));
if (base == NULL)
base = s;
if (last != NULL)
last->next = s;
last = s;
s->next = NULL;
s->data = g_malloc (oi + sizeof (int) + 1);
s->data = malloc (oi + sizeof (int) + 1);
s->len = oi + sizeof (int) + 1;
clen += oi + sizeof (int) + 1;
s->data[0] = 0;
@@ -1980,54 +2040,39 @@ pevt_build_string (const char *input, char **output, int *max_arg)
memcpy (&(s->data[1 + sizeof (int)]), o, oi);
oi = 0;
}
s = g_new (struct pevt_stage1, 1);
s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1));
if (base == NULL)
base = s;
if (last != NULL)
last->next = s;
last = s;
s->next = NULL;
s->data = g_malloc (1);
s->data = malloc (1);
s->len = 1;
clen += 1;
s->data[0] = 2;
oi = 0;
s = base;
obuf = g_malloc (clen);
obuf = malloc (clen);
while (s)
{
next = s->next;
memcpy (&obuf[oi], s->data, s->len);
oi += s->len;
g_free (s->data);
g_free (s);
free (s->data);
free (s);
s = next;
}
g_free (i);
free (i);
if (max_arg)
*max_arg = max;
if (output)
*output = obuf;
else
g_free (obuf);
return 0;
err:
while (s)
{
next = s->next;
g_free (s->data);
g_free (s);
s = next;
}
g_free(i);
return 1;
}
@@ -2062,7 +2107,7 @@ text_emit (int index, session *sess, char *a, char *b, char *c, char *d,
if (prefs.hex_text_color_nicks && (index == XP_TE_CHANACTION || index == XP_TE_CHANMSG))
{
g_snprintf (tbuf, sizeof (tbuf), "\003%d%s", text_color_of (a), a);
snprintf (tbuf, sizeof (tbuf), "\003%d%s", text_color_of (a), a);
a = tbuf;
stripcolor_args &= ~ARG_FLAG(1); /* don't strip color from this argument */
}
@@ -2194,9 +2239,9 @@ pevent_save (char *fn)
for (i = 0; i < NUM_XP; i++)
{
write (fd, buf, g_snprintf (buf, sizeof (buf),
write (fd, buf, snprintf (buf, sizeof (buf),
"event_name=%s\n", te[i].name));
write (fd, buf, g_snprintf (buf, sizeof (buf),
write (fd, buf, snprintf (buf, sizeof (buf),
"event_text=%s\n\n", pntevts_text[i]));
}
@@ -2318,8 +2363,9 @@ sound_load_event (char *evt, char *file)
if (file[0] && pevent_find (evt, &i) != -1)
{
g_free (sound_files[i]);
sound_files[i] = g_strdup (file);
if (sound_files[i])
free (sound_files[i]);
sound_files[i] = strdup (file);
}
}
@@ -2371,9 +2417,9 @@ sound_save ()
{
if (sound_files[i] && sound_files[i][0])
{
write (fd, buf, g_snprintf (buf, sizeof (buf),
write (fd, buf, snprintf (buf, sizeof (buf),
"event=%s\n", te[i].name));
write (fd, buf, g_snprintf (buf, sizeof (buf),
write (fd, buf, snprintf (buf, sizeof (buf),
"sound=%s\n\n", sound_files[i]));
}
}

View File

@@ -57,9 +57,9 @@ void text_emit (int index, session *sess, char *a, char *b, char *c, char *d,
time_t timestamp);
int text_emit_by_name (char *name, session *sess, time_t timestamp,
char *a, char *b, char *c, char *d);
char *text_validate (char **text, gssize *len);
char *text_validate (char **text, int *len);
int get_stamp_str (char *fmt, time_t tim, char **ret);
void format_event (session *sess, int index, char **args, char *o, gsize sizeofo, unsigned int stripcolor_args);
void format_event (session *sess, int index, char **args, char *o, int sizeofo, unsigned int stripcolor_args);
char *text_find_format_string (char *name);
void sound_play (const char *file, gboolean quiet);

View File

@@ -751,8 +751,8 @@ n2
Stop Connection
XP_TE_STOPCONNECT
pevt_sconnect_help
%C23*%O$tStopped previous connection attempt
0
%C23*%O$tStopped previous connection attempt (%C24$1%O)
1
Topic
XP_TE_TOPIC

View File

@@ -42,7 +42,7 @@ struct _tree
tree *
tree_new (tree_cmp_func *cmp, void *data)
{
tree *t = g_new0 (tree, 1);
tree *t = calloc (1, sizeof (tree));
t->cmp = cmp;
t->data = data;
return t;
@@ -53,8 +53,9 @@ tree_destroy (tree *t)
{
if (t)
{
g_free (t->array);
g_free (t);
if (t->array)
free (t->array);
free (t);
}
}

View File

@@ -20,8 +20,6 @@
#ifndef HEXCHAT_TREE_H
#define HEXCHAT_TREE_H
#include <glib.h>
typedef struct _tree tree;
typedef int (tree_cmp_func) (const void *keya, const void *keyb, void *data);

View File

@@ -53,7 +53,7 @@ static gboolean match_path (const char *word, int *start, int *end);
static int
url_free (char *url, void *data)
{
g_free (url);
free (url);
return TRUE;
}
@@ -124,7 +124,13 @@ url_add (char *urltext, int len)
return;
}
data = g_strndup (urltext, len);
data = malloc (len + 1);
if (!data)
{
return;
}
memcpy (data, urltext, len);
data[len] = 0;
if (data[len - 1] == '.') /* chop trailing dot */
{
@@ -145,7 +151,7 @@ url_add (char *urltext, int len)
/* the URL is saved already, only continue if we need the URL grabber too */
if (!prefs.hex_url_grabber)
{
g_free (data);
free (data);
return;
}
@@ -157,7 +163,7 @@ url_add (char *urltext, int len)
if (url_find (data))
{
g_free (data);
free (data);
return;
}
@@ -174,7 +180,7 @@ url_add (char *urltext, int len)
pos = tree_remove_at_pos (url_tree, 0);
g_tree_remove (url_btree, pos);
g_free (pos);
free (pos);
}
}
@@ -326,7 +332,7 @@ static char *commands[] = {
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
void
url_check_line (char *buf)
url_check_line (char *buf, int len)
{
GRegex *re(void);
GMatchInfo *gmi;
@@ -409,7 +415,7 @@ regex_match (const GRegex *re, const char *word, int *start, int *end)
}
/* Miscellaneous description --- */
#define DOMAIN "[_\\pL\\pN\\pS][-_\\pL\\pN\\pS]*(\\.[-_\\pL\\pN\\pS]+)*"
#define DOMAIN "[_\\pL\\pN][-_\\pL\\pN]*(\\.[-_\\pL\\pN]+)*"
#define TLD "\\.[\\pL][-\\pL\\pN]*[\\pL]"
#define IPADDR "[0-9]{1,3}(\\.[0-9]{1,3}){3}"
#define IPV6GROUP "([0-9a-f]{0,4})"
@@ -581,14 +587,18 @@ re_url (void)
if (uri[i].flags & URI_PATH)
{
char *sep_escaped = g_regex_escape_string (uri[i].path_sep, strlen(uri[i].path_sep));
char *sep_escaped;
sep_escaped = g_regex_escape_string (uri[i].path_sep,
strlen(uri[i].path_sep));
g_string_append_printf (grist_gstr, "(" "%s" PATH ")?", sep_escaped);
g_string_append_printf(grist_gstr, "(" "%s" PATH ")?",
sep_escaped);
g_free (sep_escaped);
g_free(sep_escaped);
}
g_string_append (grist_gstr, ")");
g_string_append(grist_gstr, ")");
}
grist = g_string_free (grist_gstr, FALSE);

View File

@@ -36,6 +36,6 @@ void url_clear (void);
void url_save_tree (const char *fname, const char *mode, gboolean fullpath);
int url_last (int *, int *);
int url_check_word (const char *word);
void url_check_line (char *buf);
void url_check_line (char *buf, int len);
#endif

View File

@@ -29,7 +29,7 @@
#include "util.h"
int
static int
nick_cmp_az_ops (server *serv, struct User *user1, struct User *user2)
{
unsigned int access1 = user1->access;
@@ -52,12 +52,30 @@ nick_cmp_az_ops (server *serv, struct User *user1, struct User *user2)
return serv->p_cmp (user1->nick, user2->nick);
}
int
static int
nick_cmp_alpha (struct User *user1, struct User *user2, server *serv)
{
return serv->p_cmp (user1->nick, user2->nick);
}
static int
nick_cmp (struct User *user1, struct User *user2, server *serv)
{
switch (prefs.hex_gui_ulist_sort)
{
case 0:
return nick_cmp_az_ops (serv, user1, user2);
case 1:
return serv->p_cmp (user1->nick, user2->nick);
case 2:
return -1 * nick_cmp_az_ops (serv, user1, user2);
case 3:
return -1 * serv->p_cmp (user1->nick, user2->nick);
default:
return -1;
}
}
/*
insert name in appropriate place in linked list. Returns row number or:
-1: duplicate
@@ -68,9 +86,11 @@ userlist_insertname (session *sess, struct User *newuser)
{
if (!sess->usertree)
{
sess->usertree = tree_new ((tree_cmp_func *)nick_cmp_alpha, sess->server);
sess->usertree = tree_new ((tree_cmp_func *)nick_cmp, sess->server);
sess->usertree_alpha = tree_new ((tree_cmp_func *)nick_cmp_alpha, sess->server);
}
tree_insert (sess->usertree_alpha, newuser);
return tree_insert (sess->usertree, newuser);
}
@@ -101,12 +121,13 @@ userlist_set_account (struct session *sess, char *nick, char *account)
user = userlist_find (sess, nick);
if (user)
{
g_free (user->account);
if (user->account)
free (user->account);
if (strcmp (account, "*") == 0)
user->account = NULL;
else
user->account = g_strdup (account);
user->account = strdup (account);
/* gui doesnt currently reflect login status, maybe later
fe_userlist_rehash (sess, user); */
@@ -127,14 +148,14 @@ userlist_add_hostname (struct session *sess, char *nick, char *hostname,
{
if (prefs.hex_gui_ulist_show_hosts)
do_rehash = TRUE;
user->hostname = g_strdup (hostname);
user->hostname = strdup (hostname);
}
if (!user->realname && realname && *realname)
user->realname = g_strdup (realname);
user->realname = strdup (realname);
if (!user->servername && servername)
user->servername = g_strdup (servername);
user->servername = strdup (servername);
if (!user->account && account && strcmp (account, "0") != 0)
user->account = g_strdup (account);
user->account = strdup (account);
if (away != 0xff)
{
if (user->away != away)
@@ -154,11 +175,15 @@ userlist_add_hostname (struct session *sess, char *nick, char *hostname,
static int
free_user (struct User *user, gpointer data)
{
g_free (user->realname);
g_free (user->hostname);
g_free (user->servername);
g_free (user->account);
g_free (user);
if (user->realname)
free (user->realname);
if (user->hostname)
free (user->hostname);
if (user->servername)
free (user->servername);
if (user->account)
free (user->account);
free (user);
return TRUE;
}
@@ -168,8 +193,10 @@ userlist_free (session *sess)
{
tree_foreach (sess->usertree, (tree_traverse_func *)free_user, NULL);
tree_destroy (sess->usertree);
tree_destroy (sess->usertree_alpha);
sess->usertree = NULL;
sess->usertree_alpha = NULL;
sess->me = NULL;
sess->ops = 0;
@@ -197,8 +224,8 @@ userlist_find (struct session *sess, const char *name)
{
int pos;
if (sess->usertree)
return tree_find (sess->usertree, name,
if (sess->usertree_alpha)
return tree_find (sess->usertree_alpha, name,
(tree_cmp_func *)find_cmp, sess->server, &pos);
return NULL;
@@ -221,7 +248,7 @@ userlist_find_global (struct server *serv, char *name)
}
list = list->next;
}
return NULL;
return 0;
}
static void
@@ -261,7 +288,7 @@ userlist_update_mode (session *sess, char *name, char mode, char sign)
/* remove from binary trees, before we loose track of it */
tree_remove (sess->usertree, user, &pos);
fe_userlist_remove (sess, user);
tree_remove (sess->usertree_alpha, user, &pos);
/* which bit number is affected? */
access = mode_access (sess->server, mode, &prefix);
@@ -291,8 +318,11 @@ userlist_update_mode (session *sess, char *name, char mode, char sign)
update_counts (sess, user, prefix, level, offset);
/* insert it back into its new place */
tree_insert (sess->usertree, user);
fe_userlist_insert (sess, user, FALSE);
tree_insert (sess->usertree_alpha, user);
pos = tree_insert (sess->usertree, user);
/* let GTK move it too */
fe_userlist_move (sess, user, pos);
fe_userlist_numbers (sess);
}
@@ -305,12 +335,14 @@ userlist_change (struct session *sess, char *oldname, char *newname)
if (user)
{
tree_remove (sess->usertree, user, &pos);
fe_userlist_remove (sess, user);
tree_remove (sess->usertree_alpha, user, &pos);
safe_strcpy (user->nick, newname, NICKLEN);
tree_insert (sess->usertree, user);
fe_userlist_insert (sess, user, FALSE);
tree_insert (sess->usertree_alpha, user);
fe_userlist_move (sess, user, tree_insert (sess->usertree, user));
fe_userlist_numbers (sess);
return 1;
}
@@ -349,6 +381,7 @@ userlist_remove_user (struct session *sess, struct User *user)
sess->me = NULL;
tree_remove (sess->usertree, user, &pos);
tree_remove (sess->usertree_alpha, user, &pos);
free_user (user, NULL);
}
@@ -364,7 +397,8 @@ userlist_add (struct session *sess, char *name, char *hostname,
notify_set_online (sess->server, name + prefix_chars, tags_data);
user = g_new0 (struct User, 1);
user = malloc (sizeof (struct User));
memset (user, 0, sizeof (struct User));
user->access = acc;
@@ -374,7 +408,7 @@ userlist_add (struct session *sess, char *name, char *hostname,
/* add it to our linked list */
if (hostname)
user->hostname = g_strdup (hostname);
user->hostname = strdup (hostname);
safe_strcpy (user->nick, name + prefix_chars, NICKLEN);
/* is it me? */
if (!sess->server->p_cmp (user->nick, sess->server->nick))
@@ -383,9 +417,9 @@ userlist_add (struct session *sess, char *name, char *hostname,
if (sess->server->have_extjoin)
{
if (account && *account)
user->account = g_strdup (account);
user->account = strdup (account);
if (realname && *realname)
user->realname = g_strdup (realname);
user->realname = strdup (realname);
}
row = userlist_insertname (sess, user);
@@ -393,10 +427,13 @@ userlist_add (struct session *sess, char *name, char *hostname,
/* duplicate? some broken servers trigger this */
if (row == -1)
{
g_free (user->hostname);
g_free (user->account);
g_free (user->realname);
g_free (user);
if (user->hostname)
free (user->hostname);
if (user->account)
free (user->account);
if (user->realname)
free (user->realname);
free (user);
return;
}
@@ -414,7 +451,7 @@ userlist_add (struct session *sess, char *name, char *hostname,
if (user->me)
sess->me = user;
fe_userlist_insert (sess, user, FALSE);
fe_userlist_insert (sess, user, row, FALSE);
fe_userlist_numbers (sess);
}
@@ -428,7 +465,7 @@ rehash_cb (struct User *user, session *sess)
void
userlist_rehash (session *sess)
{
tree_foreach (sess->usertree, (tree_traverse_func *)rehash_cb, sess);
tree_foreach (sess->usertree_alpha, (tree_traverse_func *)rehash_cb, sess);
}
static int
@@ -443,7 +480,7 @@ userlist_flat_list (session *sess)
{
GSList *list = NULL;
tree_foreach (sess->usertree, (tree_traverse_func *)flat_cb, &list);
tree_foreach (sess->usertree_alpha, (tree_traverse_func *)flat_cb, &list);
return g_slist_reverse (list);
}
@@ -459,6 +496,6 @@ userlist_double_list(session *sess)
{
GList *list = NULL;
tree_foreach (sess->usertree, (tree_traverse_func *)double_cb, &list);
tree_foreach (sess->usertree_alpha, (tree_traverse_func *)double_cb, &list);
return list;
}

View File

@@ -61,7 +61,5 @@ void userlist_update_mode (session *sess, char *name, char mode, char sign);
GSList *userlist_flat_list (session *sess);
GList *userlist_double_list (session *sess);
void userlist_rehash (session *sess);
int nick_cmp_az_ops (server *serv, struct User *user1, struct User *user2);
int nick_cmp_alpha (struct User *user1, struct User *user2, server *serv);
#endif

View File

@@ -31,6 +31,7 @@
#ifdef WIN32
#include <sys/timeb.h>
#include <process.h>
#include <io.h>
#include <VersionHelpers.h>
#else
@@ -40,7 +41,7 @@
#include <sys/utsname.h>
#endif
#include "config.h"
#include "../../config.h"
#include <fcntl.h>
#include <errno.h>
#include "hexchat.h"
@@ -51,6 +52,9 @@
#if defined (USING_FREEBSD) || defined (__APPLE__)
#include <sys/sysctl.h>
#endif
#ifdef SOCKS
#include <socks.h>
#endif
/* SASL mechanisms */
#ifdef USE_OPENSSL
@@ -63,6 +67,10 @@
#endif
#endif
#ifndef HAVE_SNPRINTF
#define snprintf g_snprintf
#endif
char *
file_part (char *file)
{
@@ -207,6 +215,34 @@ waitline (int sok, char *buf, int bufsize, int use_recv)
}
}
#ifdef WIN32
/* waitline2 using win32 file descriptor and glib instead of _read. win32 can't _read() sok! */
int
waitline2 (GIOChannel *source, char *buf, int bufsize)
{
int i = 0;
gsize len;
GError *error = NULL;
while (1)
{
g_io_channel_set_buffered (source, FALSE);
g_io_channel_set_encoding (source, NULL, &error);
if (g_io_channel_read_chars (source, &buf[i], 1, &len, &error) != G_IO_STATUS_NORMAL)
{
return -1;
}
if (buf[i] == '\n' || bufsize == i + 1)
{
buf[i] = 0;
return i;
}
i++;
}
}
#endif
/* checks for "~" in a file and expands */
char *
@@ -334,13 +370,13 @@ strip_hidden_attribute (char *src, char *dst)
return len;
}
#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__) || defined (__CYGWIN__)
#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__)
static void
get_cpu_info (double *mhz, int *cpus)
{
#if defined(USING_LINUX) || defined (__CYGWIN__)
#ifdef USING_LINUX
char buf[256];
int fh;
@@ -574,7 +610,7 @@ get_sys_str (int with_cpu)
char *
get_sys_str (int with_cpu)
{
#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__) || defined (__CYGWIN__)
#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__)
double mhz;
#endif
int cpus = 1;
@@ -584,24 +620,24 @@ get_sys_str (int with_cpu)
if (buf)
return buf;
buf = malloc (128);
uname (&un);
#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__) || defined (__CYGWIN__)
#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__)
get_cpu_info (&mhz, &cpus);
if (mhz && with_cpu)
{
double cpuspeed = ( mhz > 1000 ) ? mhz / 1000 : mhz;
const char *cpuspeedstr = ( mhz > 1000 ) ? "GHz" : "MHz";
buf = g_strdup_printf (
(cpus == 1) ? "%s %s [%s/%.2f%s]" : "%s %s [%s/%.2f%s/SMP]",
un.sysname, un.release, un.machine,
cpuspeed, cpuspeedstr);
snprintf (buf, 128,
(cpus == 1) ? "%s %s [%s/%.2f%s]" : "%s %s [%s/%.2f%s/SMP]",
un.sysname, un.release, un.machine,
cpuspeed, cpuspeedstr);
}
else
buf = g_strdup_printf ("%s %s", un.sysname, un.release);
#else
buf = g_strdup_printf ("%s %s", un.sysname, un.release);
#endif
snprintf (buf, 128, "%s %s", un.sysname, un.release);
return buf;
}
@@ -1181,6 +1217,80 @@ const unsigned char rfc_tolowertab[] =
0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
/*static unsigned char touppertab[] =
{ 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
0x1e, 0x1f,
' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
'*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
':', ';', '<', '=', '>', '?',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
0x5f,
'`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};*/
/*static int
rename_utf8 (char *oldname, char *newname)
{
int sav, res;
char *fso, *fsn;
fso = hexchat_filename_from_utf8 (oldname, -1, 0, 0, 0);
if (!fso)
return FALSE;
fsn = hexchat_filename_from_utf8 (newname, -1, 0, 0, 0);
if (!fsn)
{
g_free (fso);
return FALSE;
}
res = rename (fso, fsn);
sav = errno;
g_free (fso);
g_free (fsn);
errno = sav;
return res;
}
static int
unlink_utf8 (char *fname)
{
int res;
char *fs;
fs = hexchat_filename_from_utf8 (fname, -1, 0, 0, 0);
if (!fs)
return FALSE;
res = unlink (fs);
g_free (fs);
return res;
}*/
static gboolean
file_exists (char *fname)
{
@@ -1468,7 +1578,7 @@ parse_dh (char *str, DH **dh_out, unsigned char **secret_out, int *keysize_out)
{
DH *dh;
guchar *data, *decoded_data;
guchar *secret = NULL;
guchar *secret;
gsize data_len;
guint size;
guint16 size16;
@@ -1520,7 +1630,7 @@ parse_dh (char *str, DH **dh_out, unsigned char **secret_out, int *keysize_out)
if (!(DH_generate_key (dh)))
goto fail;
secret = g_malloc (DH_size (dh));
secret = (unsigned char*)malloc (DH_size(dh));
key_size = DH_compute_key (secret, pubkey, dh);
if (key_size == -1)
goto fail;
@@ -1533,9 +1643,8 @@ parse_dh (char *str, DH **dh_out, unsigned char **secret_out, int *keysize_out)
return 1;
fail:
g_free (secret);
g_free (decoded_data);
if (decoded_data)
g_free (decoded_data);
return 0;
}
@@ -1543,7 +1652,7 @@ char *
encode_sasl_pass_blowfish (char *user, char *pass, char *data)
{
DH *dh;
char *response, *ret = NULL;
char *response, *ret;
unsigned char *secret;
unsigned char *encrypted_pass;
char *plain_pass;
@@ -1558,8 +1667,10 @@ encode_sasl_pass_blowfish (char *user, char *pass, char *data)
return NULL;
BF_set_key (&key, key_size, secret);
encrypted_pass = g_malloc0 (pass_len);
plain_pass = g_malloc0 (pass_len);
encrypted_pass = (guchar*)malloc (pass_len);
memset (encrypted_pass, 0, pass_len);
plain_pass = (char*)malloc (pass_len);
memset (plain_pass, 0, pass_len);
memcpy (plain_pass, pass, strlen(pass));
out_ptr = (char*)encrypted_pass;
in_ptr = (char*)plain_pass;
@@ -1569,7 +1680,7 @@ encode_sasl_pass_blowfish (char *user, char *pass, char *data)
/* Create response */
length = 2 + BN_num_bytes (dh->pub_key) + pass_len + user_len + 1;
response = g_malloc0 (length);
response = (char*)malloc (length);
out_ptr = response;
/* our key */
@@ -1588,12 +1699,11 @@ encode_sasl_pass_blowfish (char *user, char *pass, char *data)
ret = g_base64_encode ((const guchar*)response, length);
g_free (response);
DH_free(dh);
g_free (plain_pass);
g_free (encrypted_pass);
g_free (secret);
DH_free (dh);
free (plain_pass);
free (encrypted_pass);
free (secret);
free (response);
return ret;
}
@@ -1619,8 +1729,10 @@ encode_sasl_pass_aes (char *user, char *pass, char *data)
if (!parse_dh (data, &dh, &secret, &key_size))
return NULL;
encrypted_userpass = g_malloc0 (userpass_len);
plain_userpass = g_malloc0 (userpass_len);
encrypted_userpass = (guchar*)malloc (userpass_len);
memset (encrypted_userpass, 0, userpass_len);
plain_userpass = (guchar*)malloc (userpass_len);
memset (plain_userpass, 0, userpass_len);
/* create message */
/* format of: <username>\0<password>\0<padding> */
@@ -1651,7 +1763,7 @@ encode_sasl_pass_aes (char *user, char *pass, char *data)
/* Create response */
/* format of: <size pubkey><pubkey><iv (always 16 bytes)><ciphertext> */
length = 2 + key_size + sizeof(iv) + userpass_len;
response = g_malloc (length);
response = (char*)malloc (length);
out_ptr = response;
/* our key */
@@ -1672,10 +1784,11 @@ encode_sasl_pass_aes (char *user, char *pass, char *data)
end:
DH_free (dh);
g_free (plain_userpass);
g_free (encrypted_userpass);
g_free (secret);
g_free (response);
free (plain_userpass);
free (encrypted_userpass);
free (secret);
if (response)
free (response);
return ret;
}
@@ -1753,7 +1866,9 @@ challengeauth_response (char *username, char *password, char *challenge)
g_string_append_printf (buf, "%02x", (unsigned int) digest[i]);
}
return g_string_free (buf, FALSE);
digest = (unsigned char *) g_string_free (buf, FALSE);
return (char *) digest;
}
#endif

View File

@@ -61,7 +61,10 @@ int strip_hidden_attribute (char *src, char *dst);
char *errorstring (int err);
int waitline (int sok, char *buf, int bufsize, int);
#ifdef WIN32
int waitline2 (GIOChannel *source, char *buf, int bufsize);
int get_cpu_arch (void);
#else
#define waitline2(source,buf,size) waitline(serv->childread,buf,size,0)
#endif
unsigned long make_ping_time (void);
void move_file (char *src_dir, char *dst_dir, char *fname, int dccpermissions);

View File

@@ -198,13 +198,13 @@
* only defined for compatibility. These macros should always return false
* on Windows.
*/
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
/* Return the exact length of d_namlen without zero terminator */
#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
@@ -305,7 +305,6 @@ _wopendir(
{
_WDIR *dirp = NULL;
int error;
DWORD n;
/* Must have directory name */
if (dirname == NULL || dirname[0] == '\0') {
@@ -314,58 +313,73 @@ _wopendir(
}
/* Allocate new _WDIR structure */
dirp = (_WDIR*) g_new (struct _WDIR, 1);
/* Reset _WDIR structure */
dirp->handle = INVALID_HANDLE_VALUE;
dirp->patt = NULL;
dirp->cached = 0;
dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
if (dirp != NULL) {
DWORD n;
/* Compute the length of full path plus zero terminator */
n = GetFullPathNameW (dirname, 0, NULL, NULL);
/* Reset _WDIR structure */
dirp->handle = INVALID_HANDLE_VALUE;
dirp->patt = NULL;
dirp->cached = 0;
/* Allocate room for absolute directory name and search pattern */
dirp->patt = g_malloc (sizeof (wchar_t) * n + 16);
/*
* Convert relative directory name to an absolute one. This
* allows rewinddir() to function correctly even when current
* working directory is changed between opendir() and rewinddir().
*/
n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
if (n > 0) {
wchar_t *p;
/* Compute the length of full path plus zero terminator */
n = GetFullPathNameW (dirname, 0, NULL, NULL);
/* Append search pattern \* to the directory name */
p = dirp->patt + n;
if (dirp->patt < p) {
switch (p[-1]) {
case '\\':
case '/':
case ':':
/* Directory ends in path separator, e.g. c:\temp\ */
/*NOP*/;
break;
/* Allocate room for absolute directory name and search pattern */
dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
if (dirp->patt) {
default:
/* Directory name doesn't end in path separator */
*p++ = '\\';
/*
* Convert relative directory name to an absolute one. This
* allows rewinddir() to function correctly even when current
* working directory is changed between opendir() and rewinddir().
*/
n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
if (n > 0) {
wchar_t *p;
/* Append search pattern \* to the directory name */
p = dirp->patt + n;
if (dirp->patt < p) {
switch (p[-1]) {
case '\\':
case '/':
case ':':
/* Directory ends in path separator, e.g. c:\temp\ */
/*NOP*/;
break;
default:
/* Directory name doesn't end in path separator */
*p++ = '\\';
}
}
*p++ = '*';
*p = '\0';
/* Open directory stream and retrieve the first entry */
if (dirent_first (dirp)) {
/* Directory stream opened successfully */
error = 0;
} else {
/* Cannot retrieve first entry */
error = 1;
dirent_set_errno (ENOENT);
}
} else {
/* Cannot retrieve full path name */
dirent_set_errno (ENOENT);
error = 1;
}
}
*p++ = '*';
*p = '\0';
/* Open directory stream and retrieve the first entry */
if (dirent_first (dirp)) {
/* Directory stream opened successfully */
error = 0;
} else {
/* Cannot retrieve first entry */
/* Cannot allocate memory for search pattern */
error = 1;
dirent_set_errno (ENOENT);
}
} else {
/* Cannot retrieve full path name */
dirent_set_errno (ENOENT);
/* Cannot allocate _WDIR structure */
error = 1;
}
@@ -458,11 +472,13 @@ _wclosedir(
}
/* Release search pattern */
g_free (dirp->patt);
dirp->patt = NULL;
if (dirp->patt) {
free (dirp->patt);
dirp->patt = NULL;
}
/* Release directory structure */
g_free (dirp);
free (dirp);
ok = /*success*/0;
} else {
@@ -563,8 +579,6 @@ opendir(
{
struct DIR *dirp;
int error;
wchar_t wname[PATH_MAX + 1];
size_t n;
/* Must have directory name */
if (dirname == NULL || dirname[0] == '\0') {
@@ -573,36 +587,44 @@ opendir(
}
/* Allocate memory for DIR structure */
dirp = (DIR*) g_new (struct DIR, 1);
dirp = (DIR*) malloc (sizeof (struct DIR));
if (dirp) {
wchar_t wname[PATH_MAX + 1];
size_t n;
/* Convert directory name to wide-character string */
error = dirent_mbstowcs_s(
&n, wname, PATH_MAX + 1, dirname, PATH_MAX);
if (!error) {
/* Convert directory name to wide-character string */
error = dirent_mbstowcs_s(
&n, wname, PATH_MAX + 1, dirname, PATH_MAX);
if (!error) {
/* Open directory stream using wide-character name */
dirp->wdirp = _wopendir (wname);
if (dirp->wdirp) {
/* Directory stream opened */
error = 0;
} else {
/* Failed to open directory stream */
error = 1;
}
/* Open directory stream using wide-character name */
dirp->wdirp = _wopendir (wname);
if (dirp->wdirp) {
/* Directory stream opened */
error = 0;
} else {
/* Failed to open directory stream */
/*
* Cannot convert file name to wide-character string. This
* occurs if the string contains invalid multi-byte sequences or
* the output buffer is too small to contain the resulting
* string.
*/
error = 1;
}
} else {
/*
* Cannot convert file name to wide-character string. This
* occurs if the string contains invalid multi-byte sequences or
* the output buffer is too small to contain the resulting
* string.
*/
/* Cannot allocate DIR structure */
error = 1;
}
/* Clean up in case of error */
if (error != 0) {
g_free (dirp);
if (error && dirp) {
free (dirp);
dirp = NULL;
}
@@ -711,14 +733,14 @@ closedir(
DIR *dirp)
{
int ok;
if (dirp != NULL) {
if (dirp) {
/* Close wide-character directory stream */
ok = _wclosedir (dirp->wdirp);
dirp->wdirp = NULL;
/* Release multi-byte character version */
g_free (dirp);
free (dirp);
} else {

View File

@@ -1,6 +1,3 @@
include $(top_srcdir)/m4/clang-analyze.am
localedir = $(datadir)/locale
bin_PROGRAMS = hexchat
@@ -33,14 +30,8 @@ hexchat_SOURCES = ascii.c banlist.c chanlist.c chanview.c custom-list.c \
dccgui.c editlist.c fe-gtk.c fkeys.c gtkutil.c ignoregui.c joind.c menu.c \
maingui.c notifygui.c palette.c pixmaps.c plugin-tray.c $(plugingui_c) \
rawlog.c resources.c servlistgui.c setup.c $(iso_codes_c) \
sexy-spell-entry.c textgui.c urlgrab.c userlistgui.c xtext.c
sslalert.c sexy-spell-entry.c textgui.c urlgrab.c userlistgui.c xtext.c
hexchat_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/src/common
resources.c: $(top_srcdir)/data/hexchat.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(top_srcdir)/data --generate-dependencies $(top_srcdir)/data/hexchat.gresource.xml)
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(top_srcdir)/data --generate-source $<
if DO_STATIC_ANALYSIS
analyze_plists = $(hexchat_SOURCES:%.c=%.plist)
all-local: $(analyze_plists)
MOSTLYCLEANFILES = $(analyze_plists)
endif

View File

@@ -491,7 +491,7 @@ banlist_unban_inner (gpointer none, banlist_info *banl, int mode_num)
if (!gtk_tree_model_get_iter_first (model, &iter))
return 0;
masks = g_new (char *, banl->line_ct);
masks = g_malloc (sizeof (char *) * banl->line_ct);
num_sel = 0;
do
{
@@ -577,17 +577,17 @@ static void
banlist_add_selected_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
GSList **lp = data;
GSList *list = NULL;
GtkTreeIter *copy;
if (lp == NULL)
{
return;
}
copy = g_new (GtkTreeIter, 1);
if (!lp) return;
list = *lp;
copy = g_malloc (sizeof (GtkTreeIter));
g_return_if_fail (copy != NULL);
*copy = *iter;
*lp = g_slist_append (*lp, copy);
list = g_slist_append (list, copy);
*(GSList **)data = list;
}
static void
@@ -786,9 +786,14 @@ banlist_opengui (struct session *sess)
return;
}
if (sess->res->banlist == NULL)
if (!sess->res->banlist)
{
sess->res->banlist = g_new0 (banlist_info, 1);
sess->res->banlist = g_malloc0 (sizeof (banlist_info));
if (!sess->res->banlist)
{
fe_message (_("Banlist initialization failed."), FE_MSG_ERROR);
return;
}
}
banl = sess->res->banlist;
if (banl->window)

View File

@@ -94,7 +94,7 @@ chanlist_update_caption (server *serv)
{
gchar tbuf[256];
g_snprintf (tbuf, sizeof tbuf,
snprintf (tbuf, sizeof tbuf,
_("Displaying %d/%d users on %d/%d channels."),
serv->gui->chanlist_users_shown_count,
serv->gui->chanlist_users_found_count,
@@ -148,7 +148,7 @@ chanlist_data_free (server *serv)
data = rows->data;
g_free (data->topic);
g_free (data->collation_key);
g_free (data);
free (data);
}
g_slist_free (serv->gui->chanlist_data_stored_rows);
@@ -370,7 +370,7 @@ fe_add_chan_list (server *serv, char *chan, char *users, char *topic)
int len = strlen (chan) + 1;
/* we allocate the struct and channel string in one go */
next_row = g_malloc (sizeof (chanlistrow) + len);
next_row = malloc (sizeof (chanlistrow) + len);
memcpy (((char *)next_row) + sizeof (chanlistrow), chan, len);
next_row->topic = strip_color (topic, -1, STRIP_ALL);
next_row->collation_key = g_utf8_collate_key (chan, len-1);
@@ -456,7 +456,7 @@ chanlist_join (GtkWidget * wid, server *serv)
{
if (serv->connected && (strcmp (chan, "*") != 0))
{
g_snprintf (tbuf, sizeof (tbuf), "join %s", chan);
snprintf (tbuf, sizeof (tbuf), "join %s", chan);
handle_command (serv->server_session, tbuf, FALSE);
} else
gdk_beep ();
@@ -482,7 +482,7 @@ chanlist_filereq_done (server *serv, char *file)
if (fh == -1)
return;
g_snprintf (buf, sizeof buf, "HexChat Channel List: %s - %s\n",
snprintf (buf, sizeof buf, "HexChat Channel List: %s - %s\n",
serv->servername, ctime (&t));
write (fh, buf, strlen (buf));
@@ -494,7 +494,7 @@ chanlist_filereq_done (server *serv, char *file)
COL_CHANNEL, &chan,
COL_USERS, &users,
COL_TOPIC, &topic, -1);
g_snprintf (buf, sizeof buf, "%-16s %-5d%s\n", chan, users, topic);
snprintf (buf, sizeof buf, "%-16s %-5d%s\n", chan, users, topic);
g_free (chan);
g_free (topic);
write (fh, buf, strlen (buf));
@@ -717,7 +717,7 @@ chanlist_opengui (server *serv, int do_refresh)
return;
}
g_snprintf (tbuf, sizeof tbuf, _(DISPLAY_NAME": Channel List (%s)"),
snprintf (tbuf, sizeof tbuf, _(DISPLAY_NAME": Channel List (%s)"),
server_get_network (serv, TRUE));
serv->gui->chanlist_pending_rows = NULL;

View File

@@ -142,7 +142,7 @@ tab_scroll_left_up_clicked (GtkWidget *widget, chanview *cv)
gfloat new_value;
GtkWidget *inner;
GdkWindow *parent_win;
gdouble i;
gfloat i;
inner = ((tabview *)cv)->inner;
parent_win = gtk_widget_get_window (gtk_widget_get_parent (inner));
@@ -191,7 +191,7 @@ tab_scroll_right_down_clicked (GtkWidget *widget, chanview *cv)
gfloat new_value;
GtkWidget *inner;
GdkWindow *parent_win;
gdouble i;
gfloat i;
inner = ((tabview *)cv)->inner;
parent_win = gtk_widget_get_window (gtk_widget_get_parent (inner));

View File

@@ -111,8 +111,9 @@ truncate_tab_name (char *name, int max)
if (max > 2 && g_utf8_strlen (name, -1) > max)
{
/* truncate long channel names */
buf = g_malloc (strlen (name) + 4);
g_utf8_strncpy (buf, name, max);
buf = malloc (strlen (name) + 4);
strcpy (buf, name);
g_utf8_offset_to_pointer (buf, max)[0] = 0;
strcat (buf, "..");
return buf;
}
@@ -230,7 +231,7 @@ chanview_free_ch (chanview *cv, GtkTreeIter *iter)
chan *ch;
gtk_tree_model_get (GTK_TREE_MODEL (cv->store), iter, COL_CHAN, &ch, -1);
g_free (ch);
free (ch);
}
static void
@@ -250,7 +251,7 @@ chanview_destroy (chanview *cv)
gtk_widget_destroy (cv->box);
chanview_destroy_store (cv);
g_free (cv);
free (cv);
}
static void
@@ -266,7 +267,7 @@ chanview_new (int type, int trunc_len, gboolean sort, gboolean use_icons,
{
chanview *cv;
cv = g_new0 (chanview, 1);
cv = calloc (1, sizeof (chanview));
cv->store = gtk_tree_store_new (4, G_TYPE_STRING, G_TYPE_POINTER,
PANGO_TYPE_ATTR_LIST, GDK_TYPE_PIXBUF);
cv->style = style;
@@ -367,7 +368,7 @@ chanview_add_real (chanview *cv, char *name, void *family, void *userdata,
if (!ch)
{
ch = g_new0 (chan, 1);
ch = calloc (1, sizeof (chan));
ch->userdata = userdata;
ch->family = family;
ch->cv = cv;
@@ -400,7 +401,7 @@ chanview_add (chanview *cv, char *name, void *family, void *userdata, gboolean a
ret = chanview_add_real (cv, new_name, family, userdata, allow_closure, tag, icon, NULL, NULL);
if (new_name != name)
g_free (new_name);
free (new_name);
return ret;
}
@@ -491,7 +492,7 @@ chan_rename (chan *ch, char *name, int trunc_len)
ch->cv->trunc_len = trunc_len;
if (new_name != name)
g_free (new_name);
free (new_name);
}
/* this thing is overly complicated */
@@ -644,7 +645,7 @@ chan_remove (chan *ch, gboolean force)
ch->cv->size--;
gtk_tree_store_remove (ch->cv->store, &ch->iter);
g_free (ch);
free (ch);
return TRUE;
}

View File

@@ -134,6 +134,7 @@ custom_list_get_type (void)
return custom_list_type;
/* Some boilerplate type registration stuff */
if (1)
{
static const GTypeInfo custom_list_info = {
sizeof (CustomListClass),
@@ -153,6 +154,7 @@ custom_list_get_type (void)
}
/* Here we register our GtkTreeModel interface with the type system */
if (1)
{
static const GInterfaceInfo tree_model_info = {
(GInterfaceInitFunc) custom_list_tree_model_init,
@@ -165,6 +167,7 @@ custom_list_get_type (void)
}
/* Add GtkTreeSortable interface */
if (1)
{
static const GInterfaceInfo tree_sortable_info = {
(GInterfaceInitFunc) custom_list_sortable_init,
@@ -333,7 +336,7 @@ custom_list_get_iter (GtkTreeModel * tree_model,
gint n;
n = gtk_tree_path_get_indices (path)[0];
if (n < 0 || (guint) n >= custom_list->num_rows)
if (n >= custom_list->num_rows || n < 0)
return FALSE;
record = custom_list->rows[n];
@@ -530,7 +533,7 @@ custom_list_iter_nth_child (GtkTreeModel * tree_model,
return FALSE;
/* special case: if parent == NULL, set iter to n-th top-level row */
if (n < 0 || (guint) n >= custom_list->num_rows)
if (n >= custom_list->num_rows)
return FALSE;
iter->user_data = custom_list->rows[n];
@@ -727,7 +730,7 @@ custom_list_resort (CustomList * custom_list)
custom_list);
/* let other objects know about the new order */
neworder = g_new (gint, custom_list->num_rows);
neworder = malloc (sizeof (gint) * custom_list->num_rows);
for (i = custom_list->num_rows - 1; i >= 0; i--)
{
@@ -744,7 +747,7 @@ custom_list_resort (CustomList * custom_list)
gtk_tree_model_rows_reordered (GTK_TREE_MODEL (custom_list), path, NULL,
neworder);
gtk_tree_path_free (path);
g_free (neworder);
free (neworder);
}
void

View File

@@ -77,10 +77,10 @@ struct _CustomList
{
GObject parent;
guint num_rows; /* number of rows that we have used */
guint num_alloc; /* number of rows allocated */
chanlistrow **rows; /* a dynamically allocated array of pointers to the
* CustomRecord structure for each row */
guint num_rows; /* number of rows that we have used */
guint num_alloc; /* number of rows allocated */
chanlistrow **rows; /* a dynamically allocated array of pointers to the
* CustomRecord structure for each row */
gint n_columns;
GType column_types[CUSTOM_LIST_N_COLUMNS];

View File

@@ -88,7 +88,7 @@ struct my_dcc_send
{
struct session *sess;
char *nick;
gint64 maxcps;
int maxcps;
int passive;
};
@@ -105,7 +105,7 @@ static short view_mode; /* 1=download 2=upload 3=both */
static void
proper_unit (guint64 size, char *buf, size_t buf_len)
proper_unit (DCC_SIZE size, char *buf, int buf_len)
{
gchar *formatted_str;
GFormatSizeFlags format_flags = G_FORMAT_SIZE_DEFAULT;
@@ -117,7 +117,7 @@ proper_unit (guint64 size, char *buf, size_t buf_len)
format_flags = G_FORMAT_SIZE_IEC_UNITS;
#endif
formatted_str = g_format_size_full (size, format_flags);
formatted_str = g_format_size_full ((guint64)size, format_flags);
g_strlcpy (buf, formatted_str, buf_len);
g_free (formatted_str);
@@ -130,45 +130,45 @@ dcc_send_filereq_file (struct my_dcc_send *mdc, char *file)
dcc_send (mdc->sess, mdc->nick, file, mdc->maxcps, mdc->passive);
else
{
g_free (mdc->nick);
g_free (mdc);
free (mdc->nick);
free (mdc);
}
}
void
fe_dcc_send_filereq (struct session *sess, char *nick, int maxcps, int passive)
{
char* tbuf = g_strdup_printf (_("Send file to %s"), nick);
struct my_dcc_send *mdc = g_new (struct my_dcc_send, 1);
char tbuf[128];
struct my_dcc_send *mdc;
mdc = malloc (sizeof (*mdc));
mdc->sess = sess;
mdc->nick = g_strdup (nick);
mdc->nick = strdup (nick);
mdc->maxcps = maxcps;
mdc->passive = passive;
snprintf (tbuf, sizeof tbuf, _("Send file to %s"), nick);
gtkutil_file_req (tbuf, dcc_send_filereq_file, mdc, prefs.hex_dcc_dir, NULL, FRF_MULTIPLE|FRF_FILTERISINITIAL);
g_free (tbuf);
}
static void
dcc_prepare_row_chat (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
gboolean update_only)
{
static char pos[16], size[16];
static char pos[16], siz[16];
char *date;
date = ctime (&dcc->starttime);
date[strlen (date) - 1] = 0; /* remove the \n */
proper_unit (dcc->pos, pos, sizeof (pos));
proper_unit (dcc->size, size, sizeof (size));
proper_unit (dcc->size, siz, sizeof (siz));
gtk_list_store_set (store, iter,
CCOL_STATUS, _(dccstat[dcc->dccstat].name),
CCOL_NICK, dcc->nick,
CCOL_RECV, pos,
CCOL_SENT, size,
CCOL_SENT, siz,
CCOL_START, date,
CCOL_DCC, dcc,
CCOL_COLOR,
@@ -194,12 +194,13 @@ dcc_prepare_row_send (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
per = (float) ((dcc->ack * 100.00) / dcc->size);
proper_unit (dcc->size, size, sizeof (size));
proper_unit (dcc->pos, pos, sizeof (pos));
g_snprintf (kbs, sizeof (kbs), "%.1f", ((float)dcc->cps) / 1024);
g_snprintf (perc, sizeof (perc), "%.0f%%", per);
snprintf (kbs, sizeof (kbs), "%.1f", ((float)dcc->cps) / 1024);
/* proper_unit (dcc->ack, ack, sizeof (ack));*/
snprintf (perc, sizeof (perc), "%.0f%%", per);
if (dcc->cps != 0)
{
to_go = (dcc->size - dcc->ack) / dcc->cps;
g_snprintf (eta, sizeof (eta), "%.2d:%.2d:%.2d",
snprintf (eta, sizeof (eta), "%.2d:%.2d:%.2d",
to_go / 3600, (to_go / 60) % 60, to_go % 60);
} else
strcpy (eta, "--:--:--");
@@ -252,14 +253,14 @@ dcc_prepare_row_recv (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
proper_unit (dcc->resumable, pos, sizeof (pos));
else
proper_unit (dcc->pos, pos, sizeof (pos));
g_snprintf (kbs, sizeof (kbs), "%.1f", ((float)dcc->cps) / 1024);
snprintf (kbs, sizeof (kbs), "%.1f", ((float)dcc->cps) / 1024);
/* percentage recv'ed */
per = (float) ((dcc->pos * 100.00) / dcc->size);
g_snprintf (perc, sizeof (perc), "%.0f%%", per);
snprintf (perc, sizeof (perc), "%.0f%%", per);
if (dcc->cps != 0)
{
to_go = (dcc->size - dcc->pos) / dcc->cps;
g_snprintf (eta, sizeof (eta), "%.2d:%.2d:%.2d",
snprintf (eta, sizeof (eta), "%.2d:%.2d:%.2d",
to_go / 3600, (to_go / 60) % 60, to_go % 60);
} else
strcpy (eta, "--:--:--");
@@ -525,7 +526,7 @@ resume_clicked (GtkWidget * wid, gpointer none)
fe_message (_("That file is not resumable."), FE_MSG_ERROR);
break;
case 1:
g_snprintf (buf, sizeof (buf),
snprintf (buf, sizeof (buf),
_( "Cannot access file: %s\n"
"%s.\n"
"Resuming not possible."), dcc->destfile,
@@ -606,7 +607,7 @@ browse_folder (char *dir)
#else
char buf[512];
g_snprintf (buf, sizeof (buf), "file://%s", dir);
snprintf (buf, sizeof (buf), "file://%s", dir);
fe_open_url (buf);
#endif
}
@@ -639,7 +640,7 @@ dcc_details_populate (struct DCC *dcc)
gtk_label_set_text (GTK_LABEL (dccfwin.file_label), dcc->file);
/* address and port */
g_snprintf (buf, sizeof (buf), "%s : %d", net_ip (dcc->addr), dcc->port);
snprintf (buf, sizeof (buf), "%s : %d", net_ip (dcc->addr), dcc->port);
gtk_label_set_text (GTK_LABEL (dccfwin.address_label), buf);
}
@@ -737,7 +738,7 @@ dcc_detail_label (char *text, GtkWidget *box, int num)
char buf[64];
label = gtk_label_new (NULL);
g_snprintf (buf, sizeof (buf), "<b>%s</b>", text);
snprintf (buf, sizeof (buf), "<b>%s</b>", text);
gtk_label_set_markup (GTK_LABEL (label), buf);
gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
gtk_table_attach (GTK_TABLE (box), label, 0, 1, 0 + num, 1 + num, GTK_FILL, GTK_FILL, 0, 0);

Some files were not shown because too many files have changed in this diff Show More