aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2006-03-31 19:55:47 +0200
committerWilmer van der Gaast <wilmer@gaast.net>2006-03-31 19:55:47 +0200
commite27661d09e8c3fc85c979d4769ba20d1d3c289e2 (patch)
tree63c11c2afb214d8a2077c78a19ee1b81ec0806ba
parentd783e48a831cf5058e2307a382e7e95a06680289 (diff)
Finished the iconv() fix. Instead of doing it every time something goes from
or to the IM-modules, it's now just done with everything that goes between BitlBee and the user. Incomparably more efficient/reliable. Plus some more cleanups. It compiles, can't test it for real yet. ;-)
-rw-r--r--bitlbee.h5
-rw-r--r--irc.c20
-rw-r--r--protocols/nogaim.c131
-rw-r--r--protocols/nogaim.h15
-rw-r--r--util.c49
-rw-r--r--util.h50
6 files changed, 143 insertions, 127 deletions
diff --git a/bitlbee.h b/bitlbee.h
index 4efdddd9..4da87ec6 100644
--- a/bitlbee.h
+++ b/bitlbee.h
@@ -110,6 +110,7 @@ extern char *CONF_FILE;
#include "help.h"
#include "query.h"
#include "sock.h"
+#include "util.h"
typedef struct global {
/* In forked mode, child processes store the fd of the IPC socket here. */
@@ -132,10 +133,6 @@ gboolean bitlbee_io_current_client_write( GIOChannel *source, GIOCondition condi
void root_command_string( irc_t *irc, user_t *u, char *command, int flags );
void root_command( irc_t *irc, char *command[] );
void bitlbee_shutdown( gpointer data );
-double gettime( void );
-G_MODULE_EXPORT void http_encode( char *s );
-G_MODULE_EXPORT void http_decode( char *s );
-G_MODULE_EXPORT char *strip_newlines(char *source);
extern global_t global;
diff --git a/irc.c b/irc.c
index b6185d85..0d308912 100644
--- a/irc.c
+++ b/irc.c
@@ -345,7 +345,7 @@ void irc_setpass (irc_t *irc, const char *pass)
void irc_process( irc_t *irc )
{
- char **lines, *temp, **cmd;
+ char **lines, *temp, **cmd, *cs;
int i;
if( irc->readbuffer != NULL )
@@ -354,6 +354,9 @@ void irc_process( irc_t *irc )
for( i = 0; *lines[i] != '\0'; i ++ )
{
+ /* [WvG] Because irc_tokenize splits at every newline, the lines[] list
+ should end with an empty string. This is why this actually works.
+ Took me a while to figure out, Maurits. :-P */
if( lines[i+1] == NULL )
{
temp = g_strdup( lines[i] );
@@ -361,7 +364,16 @@ void irc_process( irc_t *irc )
irc->readbuffer = temp;
i ++;
break;
- }
+ }
+
+ if( ( cs = set_getstr( irc, "charset" ) ) )
+ {
+ char conv[IRC_MAX_LINE+1];
+
+ conv[IRC_MAX_LINE] = 0;
+ if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) != -1 )
+ strcpy( lines[i], conv );
+ }
if( ( cmd = irc_parse_line( lines[i] ) ) == NULL )
continue;
@@ -387,6 +399,8 @@ void irc_process( irc_t *irc )
}
}
+/* Splits a long string into separate lines. The array is NULL-terminated and, unless the string
+ contains an incomplete line at the end, ends with an empty string. */
char **irc_tokenize( char *buffer )
{
int i, j;
@@ -427,6 +441,7 @@ char **irc_tokenize( char *buffer )
return( lines );
}
+/* Split an IRC-style line into little parts/arguments. */
char **irc_parse_line( char *line )
{
int i, j;
@@ -486,6 +501,7 @@ char **irc_parse_line( char *line )
return cmd;
}
+/* Converts such an array back into a command string. Mainly used for the IPC code right now. */
char *irc_build_line( char **cmd )
{
int i, len;
diff --git a/protocols/nogaim.c b/protocols/nogaim.c
index 28f76fff..dc4327f3 100644
--- a/protocols/nogaim.c
+++ b/protocols/nogaim.c
@@ -36,7 +36,6 @@
#define BITLBEE_CORE
#include "nogaim.h"
#include <ctype.h>
-#include <iconv.h>
static char *proto_away_alias[8][5] =
{
@@ -305,38 +304,29 @@ void hide_login_progress_error( struct gaim_connection *gc, char *msg )
void serv_got_crap( struct gaim_connection *gc, char *format, ... )
{
va_list params;
- char text[1024], buf[1024], *acc_id;
- char *msg;
+ char *text;
account_t *a;
va_start( params, format );
- g_vsnprintf( text, sizeof( text ), format, params );
+ text = g_strdup_vprintf( format, params );
va_end( params );
- if( g_strncasecmp( set_getstr( gc->irc, "charset" ), "none", 4 ) != 0 &&
- do_iconv( "UTF8", set_getstr( gc->irc, "charset" ), text, buf, 0, 1024 ) != -1 )
- msg = buf;
- else
- msg = text;
-
if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) ||
( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) )
- strip_html( msg );
+ strip_html( text );
/* Try to find a different connection on the same protocol. */
for( a = gc->irc->accounts; a; a = a->next )
if( a->prpl == gc->prpl && a->gc != gc )
break;
- /* If we found one, add the screenname to the acc_id. */
+ /* If we found one, include the screenname in the message. */
if( a )
- acc_id = g_strdup_printf( "%s(%s)", gc->prpl->name, gc->username );
+ irc_usermsg( gc->irc, "%s(%s) - %s", gc->prpl->name, gc->username, text );
else
- acc_id = g_strdup( gc->prpl->name );
-
- irc_usermsg( gc->irc, "%s - %s", acc_id, msg );
+ irc_usermsg( gc->irc, "%s - %s", gc->prpl->name, text );
- g_free( acc_id );
+ g_free( text );
}
static gboolean send_keepalive( gpointer d )
@@ -558,22 +548,14 @@ void signoff_blocked( struct gaim_connection *gc )
void serv_buddy_rename( struct gaim_connection *gc, char *handle, char *realname )
{
user_t *u = user_findhandle( gc, handle );
- char *name, buf[1024];
if( !u ) return;
- /* Convert all UTF-8 */
- if( g_strncasecmp( set_getstr( gc->irc, "charset" ), "none", 4 ) != 0 &&
- do_iconv( "UTF-8", set_getstr( gc->irc, "charset" ), realname, buf, 0, sizeof( buf ) ) != -1 )
- name = buf;
- else
- name = realname;
-
- if( g_strcasecmp( u->realname, name ) != 0 )
+ if( g_strcasecmp( u->realname, realname ) != 0 )
{
if( u->realname != u->nick ) g_free( u->realname );
- u->realname = g_strdup( name );
+ u->realname = g_strdup( realname );
if( ( gc->flags & OPT_LOGGED_IN ) && set_getint( gc->irc, "display_namechanges" ) )
serv_got_crap( gc, "User `%s' changed name to `%s'", u->nick, u->realname );
@@ -679,7 +661,6 @@ void serv_got_im( struct gaim_connection *gc, char *handle, char *msg, guint32 f
{
irc_t *irc = gc->irc;
user_t *u;
- char buf[8192];
u = user_findhandle( gc, handle );
@@ -721,10 +702,6 @@ void serv_got_im( struct gaim_connection *gc, char *handle, char *msg, guint32 f
( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) )
strip_html( msg );
- if( g_strncasecmp( set_getstr( irc, "charset" ), "none", 4 ) != 0 &&
- do_iconv( "UTF-8", set_getstr( irc, "charset" ), msg, buf, 0, 8192 ) != -1 )
- msg = buf;
-
while( strlen( msg ) > 425 )
{
char tmp, *nl;
@@ -821,7 +798,6 @@ void serv_got_chat_in( struct gaim_connection *gc, int id, char *who, int whispe
{
struct conversation *c;
user_t *u;
- char buf[8192];
/* Gaim sends own messages through this too. IRC doesn't want this, so kill them */
if( g_strcasecmp( who, gc->user->username ) == 0 )
@@ -834,10 +810,6 @@ void serv_got_chat_in( struct gaim_connection *gc, int id, char *who, int whispe
( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) )
strip_html( msg );
- if( g_strncasecmp( set_getstr( gc->irc, "charset" ), "none", 4 ) != 0 &&
- do_iconv( "UTF-8", set_getstr( gc->irc, "charset" ), msg, buf, 0, 8192 ) != -1 )
- msg = buf;
-
if( c && u )
irc_privmsg( gc->irc, u, "PRIVMSG", c->channel, "", msg );
else
@@ -1052,87 +1024,34 @@ char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value )
int serv_send_im( irc_t *irc, user_t *u, char *msg, int flags )
{
- char buf[8192];
+ char *buf = NULL;
+ int st;
- if( g_strncasecmp( set_getstr( irc, "charset" ), "none", 4 ) != 0 &&
- do_iconv( set_getstr( irc, "charset" ), "UTF-8", msg, buf, 0, 8192 ) != -1 )
- msg = buf;
-
if( ( u->gc->flags & OPT_CONN_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )
{
- char *html;
-
- html = escape_html( msg );
- strncpy( buf, html, 8192 );
- g_free( html );
-
+ buf = escape_html( msg );
msg = buf;
}
- return( ((struct gaim_connection *)u->gc)->prpl->send_im( u->gc, u->handle, msg, strlen( msg ), flags ) );
+ st = ((struct gaim_connection *)u->gc)->prpl->send_im( u->gc, u->handle, msg, strlen( msg ), flags );
+ g_free( buf );
+
+ return st;
}
int serv_send_chat( irc_t *irc, struct gaim_connection *gc, int id, char *msg )
{
- char buf[8192];
+ char *buf = NULL;
+ int st;
- if( g_strncasecmp( set_getstr( irc, "charset" ), "none", 4 ) != 0 &&
- do_iconv( set_getstr( irc, "charset" ), "UTF-8", msg, buf, 0, 8192 ) != -1 )
+ if( ( gc->flags & OPT_CONN_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )
+ {
+ buf = escape_html( msg );
msg = buf;
-
- if( gc->flags & OPT_CONN_HTML) {
- char * html = escape_html(msg);
- strncpy(buf, html, 8192);
- g_free(html);
}
- return( gc->prpl->chat_send( gc, id, msg ) );
-}
-
-/* Convert from one charset to another.
-
- from_cs, to_cs: Source and destination charsets
- src, dst: Source and destination strings
- size: Size if src. 0 == use strlen(). strlen() is not reliable for UNICODE/UTF16 strings though.
- maxbuf: Maximum number of bytes to write to dst
-
- Returns the number of bytes written to maxbuf or -1 on an error.
-*/
-signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf )
-{
- iconv_t cd;
- size_t res;
- size_t inbytesleft, outbytesleft;
- char *inbuf = src;
- char *outbuf = dst;
-
- cd = iconv_open( to_cs, from_cs );
- if( cd == (iconv_t) -1 )
- return( -1 );
-
- inbytesleft = size ? size : strlen( src );
- outbytesleft = maxbuf - 1;
- res = iconv( cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft );
- *outbuf = '\0';
- iconv_close( cd );
-
- if( res == (size_t) -1 )
- return( -1 );
- else
- return( outbuf - dst );
-}
-
-char *set_eval_charset( irc_t *irc, set_t *set, char *value )
-{
- iconv_t cd;
-
- if ( g_strncasecmp( value, "none", 4 ) == 0 )
- return( value );
-
- cd = iconv_open( "UTF-8", value );
- if( cd == (iconv_t) -1 )
- return( NULL );
-
- iconv_close( cd );
- return( value );
+ st = gc->prpl->chat_send( gc, id, msg );
+ g_free( buf );
+
+ return st;
}
diff --git a/protocols/nogaim.h b/protocols/nogaim.h
index 9bdbc624..60987842 100644
--- a/protocols/nogaim.h
+++ b/protocols/nogaim.h
@@ -206,9 +206,6 @@ G_MODULE_EXPORT void register_protocol(struct prpl *);
int serv_send_im(irc_t *irc, user_t *u, char *msg, int flags);
int serv_send_chat(irc_t *irc, struct gaim_connection *gc, int id, char *msg );
-G_MODULE_EXPORT signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf );
-char *set_eval_charset( irc_t *irc, set_t *set, char *value );
-
void nogaim_init();
int proto_away( struct gaim_connection *gc, char *away );
char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value );
@@ -257,18 +254,6 @@ G_MODULE_EXPORT struct conversation *serv_got_joined_chat( struct gaim_connectio
G_MODULE_EXPORT void serv_got_chat_in( struct gaim_connection *gc, int id, char *who, int whisper, char *msg, time_t mtime );
G_MODULE_EXPORT void serv_got_chat_left( struct gaim_connection *gc, int id );
-/* util.c */
-G_MODULE_EXPORT void strip_linefeed( gchar *text );
-G_MODULE_EXPORT char *add_cr( char *text );
-G_MODULE_EXPORT char *tobase64( const char *text );
-G_MODULE_EXPORT char *normalize( const char *s );
-G_MODULE_EXPORT time_t get_time( int year, int month, int day, int hour, int min, int sec );
-G_MODULE_EXPORT void strip_html( char *msg );
-G_MODULE_EXPORT char *escape_html( const char *html );
-G_MODULE_EXPORT void info_string_append(GString *str, char *newline, char *name, char *value);
-G_MODULE_EXPORT char *ipv6_wrap( char *src );
-G_MODULE_EXPORT char *ipv6_unwrap( char *src );
-
/* prefs.c */
G_MODULE_EXPORT void build_block_list();
G_MODULE_EXPORT void build_allow_list();
diff --git a/util.c b/util.c
index db783fe0..43e1c19f 100644
--- a/util.c
+++ b/util.c
@@ -38,6 +38,7 @@
#include <ctype.h>
#include <glib.h>
#include <time.h>
+#include <iconv.h>
void strip_linefeed(gchar *text)
{
@@ -444,3 +445,51 @@ char *ipv6_unwrap( char *src )
return ( src + 7 );
}
#endif
+
+/* Convert from one charset to another.
+
+ from_cs, to_cs: Source and destination charsets
+ src, dst: Source and destination strings
+ size: Size if src. 0 == use strlen(). strlen() is not reliable for UNICODE/UTF16 strings though.
+ maxbuf: Maximum number of bytes to write to dst
+
+ Returns the number of bytes written to maxbuf or -1 on an error.
+*/
+signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf )
+{
+ iconv_t cd;
+ size_t res;
+ size_t inbytesleft, outbytesleft;
+ char *inbuf = src;
+ char *outbuf = dst;
+
+ cd = iconv_open( to_cs, from_cs );
+ if( cd == (iconv_t) -1 )
+ return( -1 );
+
+ inbytesleft = size ? size : strlen( src );
+ outbytesleft = maxbuf - 1;
+ res = iconv( cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft );
+ *outbuf = '\0';
+ iconv_close( cd );
+
+ if( res == (size_t) -1 )
+ return( -1 );
+ else
+ return( outbuf - dst );
+}
+
+char *set_eval_charset( irc_t *irc, set_t *set, char *value )
+{
+ iconv_t cd;
+
+ if ( g_strncasecmp( value, "none", 4 ) == 0 )
+ return( value );
+
+ cd = iconv_open( "UTF-8", value );
+ if( cd == (iconv_t) -1 )
+ return( NULL );
+
+ iconv_close( cd );
+ return( value );
+}
diff --git a/util.h b/util.h
new file mode 100644
index 00000000..8e13d9dd
--- /dev/null
+++ b/util.h
@@ -0,0 +1,50 @@
+ /********************************************************************\
+ * BitlBee -- An IRC to other IM-networks gateway *
+ * *
+ * Copyright 2002-2004 Wilmer van der Gaast and others *
+ \********************************************************************/
+
+/* Misc. functions */
+
+/*
+ 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 with
+ the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _UTIL_H
+#define _UTIL_H
+
+G_MODULE_EXPORT void strip_linefeed( gchar *text );
+G_MODULE_EXPORT char *add_cr( char *text );
+G_MODULE_EXPORT char *strip_newlines(char *source);
+G_MODULE_EXPORT char *tobase64( const char *text );
+G_MODULE_EXPORT char *normalize( const char *s );
+G_MODULE_EXPORT void info_string_append( GString *str, char *newline, char *name, char *value );
+
+G_MODULE_EXPORT time_t get_time( int year, int month, int day, int hour, int min, int sec );
+double gettime( void );
+
+G_MODULE_EXPORT void strip_html( char *msg );
+G_MODULE_EXPORT char *escape_html( const char *html );
+G_MODULE_EXPORT void http_decode( char *s );
+G_MODULE_EXPORT void http_encode( char *s );
+
+G_MODULE_EXPORT char *ipv6_wrap( char *src );
+G_MODULE_EXPORT char *ipv6_unwrap( char *src );
+
+G_MODULE_EXPORT signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf );
+char *set_eval_charset( irc_t *irc, set_t *set, char *value );
+
+#endif