changeset 829:9a123b171f46

[gaim-migrate @ 839] yay. i have a secret. but basically this should fix most outstanding libfaim issues in gaim. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Sat, 02 Sep 2000 02:41:57 +0000
parents 4c71c0e7f04e
children 60284aef22f0
files libfaim/CHANGES libfaim/CHANGES.gaim libfaim/aim_misc.c libfaim/aim_rxqueue.c libfaim/faim/aim.h src/conversation.c src/gtkhtml.c src/oscar.c src/plugins.c
diffstat 9 files changed, 207 insertions(+), 146 deletions(-) [+]
line wrap: on
line diff
--- a/libfaim/CHANGES	Fri Sep 01 23:45:43 2000 +0000
+++ b/libfaim/CHANGES	Sat Sep 02 02:41:57 2000 +0000
@@ -1,6 +1,16 @@
 
 No release numbers
 ------------------
+ - Fri Sep  1 23:34:28 UTC 2000
+   - Switched the read()s in rxqueue to use recv()
+     - Should fix the big message problem and the big buddy list problem
+   - Changed some values around in aim_misc to match winaim4.1
+   - Added aim_addicbmparm. dunno what it does
+   - Cleanup the login process in faimtest (can now login in less than 2sec)
+
+ - Fri Sep  1 00:13:04 UTC 2000
+   - Avoid zero-length mallocs in aim_tlv
+
  - Thu Aug 31 23:40:23 UTC 2000
    - Threw in aim_select modification from nicolas
    - Remove stray debugging printf in aim_tlv
--- a/libfaim/CHANGES.gaim	Fri Sep 01 23:45:43 2000 +0000
+++ b/libfaim/CHANGES.gaim	Sat Sep 02 02:41:57 2000 +0000
@@ -1,3 +1,12 @@
+
+Sat Sep  2 02:35:34 UTC 2000 EWarmenhoven
+	- very good news. the very-long-message DOS against libfaim was fixed.
+	  libfaim users can now send and receive Very Long Messages. GtkHTML
+	  has problems drawing them, but resizing seems to help.
+	- the fix also makes long buddy lists a non-issue.
+	- oh yeah, the login process was changed so it should go quicker now.
+	  and we don't request ads at all, so not even your packet sniffer can
+	  pick up the gifs.
 
 Mon Aug 28 05:02:39 UTC 2000 EWarmenhoven
 	- libfaim gets warnings. no blocking, just warnings.
--- a/libfaim/aim_misc.c	Fri Sep 01 23:45:43 2000 +0000
+++ b/libfaim/aim_misc.c	Sat Sep 02 02:41:57 2000 +0000
@@ -142,65 +142,61 @@
 
   struct command_tx_struct *newpacket;
 
-  int packet_login_phase3c_hi_b_len = 0;
+  int len = 0;
 
   char *localcpy = NULL;
   char *tmpptr = NULL;
 
-  packet_login_phase3c_hi_b_len = 16; /* 16b for FLAP and SNAC headers */
+  len = 10; /* 10B SNAC headers */
 
-  /* bail out if we can't make the packet */
-  if (!buddy_list) {
+  if (!buddy_list || !(localcpy = (char *) malloc(strlen(buddy_list)+1))) 
     return -1;
-  }
-
-  localcpy = (char *) malloc(strlen(buddy_list)+1);
-  memcpy(localcpy, buddy_list, strlen(buddy_list)+1);
+  strncpy(localcpy, buddy_list, strlen(buddy_list)+1);
 
   i = 0;
   tmpptr = strtok(localcpy, "&");
-  while ((tmpptr != NULL) && (i < 100))
-    {
+  while ((tmpptr != NULL) && (i < 150)) {
 #if debug > 0
-      printf("---adding %s (%d)\n", tmpptr, strlen(tmpptr));
+    printf("---adding %d: %s (%d)\n", i, tmpptr, strlen(tmpptr));
 #endif
-      packet_login_phase3c_hi_b_len += strlen(tmpptr)+1;
-      i++;
-      tmpptr = strtok(NULL, "&");
-    }
+    len += 1+strlen(tmpptr);
+    i++;
+    tmpptr = strtok(NULL, "&");
+  }
 #if debug > 0
-  printf("*** send buddy list len: %d (%x)\n", packet_login_phase3c_hi_b_len, packet_login_phase3c_hi_b_len);
+  printf("*** send buddy list len: %d (%x)\n", len, len);
 #endif
-  free(localcpy);
 
-  if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packet_login_phase3c_hi_b_len - 6)))
+  if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, len)))
     return -1;
 
   newpacket->lock = 1;
   
-  aim_putsnac(newpacket->data, 0x0003, 0x0004, 0x0000, sess->snac_nextid);
+  aim_putsnac(newpacket->data, 0x0003, 0x0004, 0x0000, 0);
 
   j = 10;  /* the next byte */
 
+  strncpy(localcpy, buddy_list, strlen(buddy_list)+1);
   i = 0;
-  tmpptr = strtok(buddy_list, "&");
-  while ((tmpptr != NULL) & (i < 100))
-    {
+  tmpptr = strtok(localcpy, "&");
+  while ((tmpptr != NULL) & (i < 150)) {
 #if debug > 0
-      printf("---adding %s (%d)\n", tmpptr, strlen(tmpptr));
+    printf("---adding %d: %s (%d)\n", i, tmpptr, strlen(tmpptr));
 #endif
-      newpacket->data[j] = strlen(tmpptr);
-      memcpy(&(newpacket->data[j+1]), tmpptr, strlen(tmpptr));
-      j += strlen(tmpptr)+1;
-      i++;
-      tmpptr = strtok(NULL, "&");
-    }
+    newpacket->data[j] = strlen(tmpptr);
+    memcpy(&(newpacket->data[j+1]), tmpptr, strlen(tmpptr));
+    j += 1+strlen(tmpptr);
+    i++;
+    tmpptr = strtok(NULL, "&");
+  }
 
   newpacket->lock = 0;
 
   aim_tx_enqueue(sess, newpacket);
 
-  return (sess->snac_nextid++);
+  free(localcpy);
+
+  return (sess->snac_nextid);
 }
 
 /* 
@@ -283,7 +279,8 @@
      0x00, 0x01,   
      0x00, 0x03, 
      0x00, 0x04, 
-     0x06, 0x86,  
+     0x07, 0xda,  
+
      0x00, 0x02, 
      0x00, 0x01,  
      0x00, 0x04, 
@@ -292,7 +289,8 @@
      0x00, 0x03, 
      0x00, 0x01,  
      0x00, 0x04, 
-     0x00, 0x01, 
+     0x00, 0x01,
+ 
      0x00, 0x04, 
      0x00, 0x01, 
      0x00, 0x04,
@@ -357,28 +355,23 @@
 			   struct aim_conn_t *conn)
 {
   struct command_tx_struct *newpacket;
-  int packlen = 18, i=0;
+  int packlen = 20, i=0;
 
-  if (conn->type != AIM_CONN_TYPE_BOS)
-    packlen += 2;
-
-  if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen)));
+  if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen)))
+    return (sess->snac_nextid);
   
   newpacket->lock = 1;
 
-  i = aim_putsnac(newpacket->data, 0x0001, 0x0008, 0x0000, sess->snac_nextid);
+  i = aim_putsnac(newpacket->data, 0x0001, 0x0008, 0x0000, 0);
   i += aimutil_put16(newpacket->data+i, 0x0001); 
   i += aimutil_put16(newpacket->data+i, 0x0002);
   i += aimutil_put16(newpacket->data+i, 0x0003);
   i += aimutil_put16(newpacket->data+i, 0x0004);
+  i += aimutil_put16(newpacket->data+i, 0x0005);
   
-  if (conn->type != AIM_CONN_TYPE_BOS) {
-    i += aimutil_put16(newpacket->data+i, 0x0005);
-  }
-
   aim_tx_enqueue(sess, newpacket);
 
-  return (sess->snac_nextid++);
+  return (sess->snac_nextid);
 }
 
 /* 
@@ -407,22 +400,7 @@
 u_long aim_bos_reqpersonalinfo(struct aim_session_t *sess,
 			       struct aim_conn_t *conn)
 {
-  struct command_tx_struct *newpacket;
-  
-  if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 12)))
-    return -1;
-
-  newpacket->lock = 1;
-
-  aim_putsnac(newpacket->data, 0x000a, 0x0001, 0x000e /* huh? */, sess->snac_nextid);
-  
-  newpacket->data[10] = 0x0d;
-  newpacket->data[11] = 0xda;
-
-  newpacket->lock = 0;
-  aim_tx_enqueue(sess, newpacket);
-
-  return (sess->snac_nextid++);
+  return aim_genericreq_n(sess, conn, 0x0001, 0x000e);
 }
 
 u_long aim_setversions(struct aim_session_t *sess,
@@ -431,7 +409,7 @@
   struct command_tx_struct *newpacket;
   int i;
 
-  if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10 + (4*11))))
+  if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10 + (4*12))))
     return -1;
 
   newpacket->lock = 1;
@@ -468,6 +446,9 @@
   i += aimutil_put16(newpacket->data+i, 0x000c);
   i += aimutil_put16(newpacket->data+i, 0x0001);
 
+  i += aimutil_put16(newpacket->data+i, 0x0013);
+  i += aimutil_put16(newpacket->data+i, 0x0001);
+
   i += aimutil_put16(newpacket->data+i, 0x0015);
   i += aimutil_put16(newpacket->data+i, 0x0001);
 
@@ -694,3 +675,31 @@
   return aim_genericreq_n(sess, conn, 0x0004, 0x0004);
 }
 
+/*
+ * Add ICBM parameter? Huh?
+ */
+unsigned long aim_addicbmparam(struct aim_session_t *sess,
+			       struct aim_conn_t *conn)
+{
+  struct command_tx_struct *newpacket;
+  int packlen = 10+16, i=0;
+
+  if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen)))
+    return (sess->snac_nextid);
+  
+  newpacket->lock = 1;
+
+  i = aim_putsnac(newpacket->data, 0x0004, 0x0002, 0x0000, sess->snac_nextid);
+  i += aimutil_put16(newpacket->data+i, 0x0000); 
+  i += aimutil_put16(newpacket->data+i, 0x0000);
+  i += aimutil_put16(newpacket->data+i, 0x0003);
+  i += aimutil_put16(newpacket->data+i, 0x1f40);
+  i += aimutil_put16(newpacket->data+i, 0x03e7);
+  i += aimutil_put16(newpacket->data+i, 0x03e7);
+  i += aimutil_put16(newpacket->data+i, 0x0000); 
+  i += aimutil_put16(newpacket->data+i, 0x0000); 
+  
+  aim_tx_enqueue(sess, newpacket);
+
+  return (sess->snac_nextid);
+}
--- a/libfaim/aim_rxqueue.c	Fri Sep 01 23:45:43 2000 +0000
+++ b/libfaim/aim_rxqueue.c	Sat Sep 02 02:41:57 2000 +0000
@@ -41,7 +41,8 @@
    *   4 short -- Number of data bytes that follow.
    */
   faim_mutex_lock(&conn->active);
-  if (read(conn->fd, generic, 6) < 6){
+  if (recv(conn->fd, generic, 6, MSG_WAITALL) < 6){
+    printf("faim: flap: read underflow (header)\n");
     aim_conn_close(conn);
     faim_mutex_unlock(&conn->active);
     return -1;
@@ -89,7 +90,8 @@
   }
 
   /* read the data portion of the packet */
-  if (read(conn->fd, newrx->data, newrx->commandlen) < newrx->commandlen){
+  if (recv(conn->fd, newrx->data, newrx->commandlen, MSG_WAITALL) < newrx->commandlen){
+    printf("faim: flap: read underflow (payload)\n");
     free(newrx->data);
     free(newrx);
     aim_conn_close(conn);
--- a/libfaim/faim/aim.h	Fri Sep 01 23:45:43 2000 +0000
+++ b/libfaim/faim/aim.h	Sat Sep 02 02:41:57 2000 +0000
@@ -510,6 +510,7 @@
 u_long aim_bos_reqbuddyrights(struct aim_session_t *, struct aim_conn_t *);
 u_long aim_bos_reqlocaterights(struct aim_session_t *, struct aim_conn_t *);
 u_long aim_bos_reqicbmparaminfo(struct aim_session_t *, struct aim_conn_t *);
+unsigned long aim_addicbmparam(struct aim_session_t *sess,struct aim_conn_t *conn);
 u_long aim_setversions(struct aim_session_t *sess, struct aim_conn_t *conn);
 
 struct aim_fileheader_t *aim_getlisting(struct aim_session_t*);
--- a/src/conversation.c	Fri Sep 01 23:45:43 2000 +0000
+++ b/src/conversation.c	Sat Sep 02 02:41:57 2000 +0000
@@ -1059,31 +1059,32 @@
 void write_html_with_smileys(GtkWidget *window, GtkWidget *html, char *what)
 {
 	int y = 0;
-	char buf2[BUF_LONG];
+	char *buf2 = g_strdup(what);
 	int i;
 	GdkPixmap *face;
 
-			for (i = 0; i < strlen(what); i++)
-        		{
-				int len;
-				if ((face = is_smiley(window, &what[i], &len)) != NULL) {
-					buf2[y] = 0;
-					gtk_html_append_text(GTK_HTML(html), buf2, (display_options & OPT_DISP_IGNORE_COLOUR) ? HTML_OPTION_NO_COLOURS : 0);
-					gtk_html_add_pixmap(GTK_HTML(html), face, 0, 0);
-					y = 0;
-					i += len - 1;
-				} else {
-	               			buf2[y] = what[i];
-	               			y++;
+	for (i = 0; i < strlen(what); i++)
+	{
+		int len;
+		if ((face = is_smiley(window, &what[i], &len)) != NULL) {
+			buf2[y] = 0;
+			gtk_html_append_text(GTK_HTML(html), buf2, (display_options & OPT_DISP_IGNORE_COLOUR) ? HTML_OPTION_NO_COLOURS : 0);
+			gtk_html_add_pixmap(GTK_HTML(html), face, 0, 0);
+			y = 0;
+			i += len - 1;
+		} else {
+			buf2[y] = what[i];
+			y++;
 
-				}
-        		}
+		}
+	}
 
-			if (y)
-			{
-				buf2[y] = 0;
-				gtk_html_append_text(GTK_HTML(html), buf2, (display_options & OPT_DISP_IGNORE_COLOUR) ? HTML_OPTION_NO_COLOURS : 0);
-			}				
+	if (y)
+	{
+		buf2[y] = 0;
+		gtk_html_append_text(GTK_HTML(html), buf2, (display_options & OPT_DISP_IGNORE_COLOUR) ? HTML_OPTION_NO_COLOURS : 0);
+	}
+	g_free(buf2);
 }
 
 /* this is going to be interesting since the conversation could either be a
--- a/src/gtkhtml.c	Fri Sep 01 23:45:43 2000 +0000
+++ b/src/gtkhtml.c	Sat Sep 02 02:41:57 2000 +0000
@@ -2896,6 +2896,9 @@
 	 * HTK_SCROLLED_WINDOW(GTK_WIDGET(layout)->parent)->vscrollbar->allocation.width) - 8; 
 	 */
 
+	/* FIXME: gtk_text_measure can overflow if the text is too long. hopefully that will
+	 * never happen though. but it is very possible. NOTE: this is not a buffer overflow,
+	 * it just means it won't display text properly. */
 	while (gdk_text_measure(cfont, text, num) > maxwidth)
 	{
 		if (num > 1)
@@ -3107,7 +3110,7 @@
 	GdkColormap *map;
 	GdkFont *cfont;
 	GdkRectangle area;
-	char ws[BUF_LONG],
+	char *ws,
 	  tag[BUF_LONG],
 	 *c,
 	 *url = NULL;
@@ -3151,6 +3154,7 @@
 	cfont = getfont(current->font, bold, italic, fixed, current->size);
 	c = text;
 
+	ws = g_malloc(strlen(text) + 2);
 
 	while (*c)
 	{
@@ -3594,6 +3598,7 @@
 */	}
 
 
+	g_free(ws);
 
 	gdk_window_get_size(html->html_area, NULL, &height);
 	area.height = height;
--- a/src/oscar.c	Fri Sep 01 23:45:43 2000 +0000
+++ b/src/oscar.c	Sat Sep 02 02:41:57 2000 +0000
@@ -88,6 +88,8 @@
 static int gaim_parse_msgack     (struct aim_session_t *, struct command_rx_struct *, ...);
 static int gaim_parse_ratechange (struct aim_session_t *, struct command_rx_struct *, ...);
 static int gaim_parse_evilnotify (struct aim_session_t *, struct command_rx_struct *, ...);
+static int gaim_bosrights        (struct aim_session_t *, struct command_rx_struct *, ...);
+static int gaim_rateresp         (struct aim_session_t *, struct command_rx_struct *, ...);
 
 static int gaim_directim_incoming(struct aim_session_t *, struct command_rx_struct *, ...);
 static int gaim_directim_typing  (struct aim_session_t *, struct command_rx_struct *, ...);
@@ -305,6 +307,8 @@
 		return -1;
 	}
 
+	aim_conn_addhandler(sess, bosconn, 0x0009, 0x0003, gaim_bosrights, 0);
+	aim_conn_addhandler(sess, bosconn, 0x0001, 0x0007, gaim_rateresp, 0); /* rate info */
 	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ACK, AIM_CB_ACK_ACK, NULL, 0);
 	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, gaim_server_ready, 0);
 	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATEINFO, NULL, 0);
@@ -352,11 +356,8 @@
 	static int id = 1;
 	switch (command->conn->type) {
 	case AIM_CONN_TYPE_BOS:
-		aim_bos_reqrate(sess, command->conn);
-		aim_bos_ackrateresp(sess, command->conn);
-		aim_bos_setprivacyflags(sess, command->conn, AIM_PRIVFLAGS_ALLOWIDLE | AIM_PRIVFLAGS_ALLOWMEMBERSINCE);
-		aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_ADS);
-		aim_bos_setgroupperm(sess, command->conn, AIM_CLASS_ALLUSERS);
+		aim_setversions(sess, command->conn);
+		aim_bos_reqrate(sess, command->conn); /* request rate info */
 		debug_print("done with BOS ServerReady\n");
 		break;
 	case AIM_CONN_TYPE_CHATNAV:
@@ -402,47 +403,6 @@
 	cookie    = va_arg(ap, char *);
 
 	switch(serviceid) {
-	case 0x0005: /* Ads */
-		debug_print("Received Ads, finishing login\n");
-		aim_bos_setprofile(sess, command->conn, current_user->user_info,
-					NULL, gaim_caps);
-		aim_seticbmparam(sess, command->conn);
-		aim_conn_setlatency(command->conn, 1);
-
-		gtk_widget_hide(mainwindow);
-		show_buddy_list();
-#ifdef USE_APPLET
-		if (general_options & OPT_GEN_APP_BUDDY_SHOW) {
-			refresh_buddy_window();
-			createOnlinePopup();
-			applet_buddy_show = TRUE;
-		} else {
-			gtk_widget_hide(blist);
-			applet_buddy_show = FALSE;
-		}
-		set_user_state(online);
-#else
-		refresh_buddy_window();
-#endif
-
-		serv_finish_login();
-		gaim_setup();
-
-		/* I'm sufficiently convinced that this is not the problem with
-		 * signing on, because it happens no matter where I place it. */
-		if (bud_list_cache_exists())
-			do_import(NULL, 0);
-
-		debug_print("buddy list loaded\n");
-
-		setup_buddy_chats();
-
-		aim_bos_clientready(sess, command->conn);
-		debug_print("Roger that, all systems go\n");
-
-		aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_CHATNAV);
-
-		break;
 	case 0x7: /* Authorizer */
 		debug_print("Reconnecting with authorizor...\n");
 		{
@@ -997,6 +957,70 @@
 	return 1;
 }
 
+int gaim_rateresp(struct aim_session_t *sess, struct command_rx_struct *command, ...) {
+	switch (command->conn->type) {
+	case AIM_CONN_TYPE_BOS:
+		aim_bos_ackrateresp(sess, command->conn);
+		aim_bos_reqpersonalinfo(sess, command->conn);
+		aim_bos_reqlocaterights(sess, command->conn);
+		aim_bos_setprofile(sess, command->conn, current_user->user_info,
+					NULL, gaim_caps);
+		aim_bos_reqbuddyrights(sess, command->conn);
+
+		gtk_widget_hide(mainwindow);
+		show_buddy_list();
+
+#ifdef USE_APPLET
+		if (general_options & OPT_GEN_APP_BUDDY_SHOW) {
+			refresh_buddy_window();
+			createOnlinePopup();
+			applet_buddy_show = TRUE;
+		} else {
+			gtk_widget_hide(blist);
+			applet_buddy_show = FALSE;
+		}
+		set_user_state(online);
+#else
+		refresh_buddy_window();
+#endif
+
+		serv_finish_login();
+		gaim_setup();
+
+		if (bud_list_cache_exists())
+			do_import(NULL, 0);
+
+		debug_print("buddy list loaded\n");
+
+		setup_buddy_chats();
+
+		aim_addicbmparam(sess, command->conn);
+		aim_bos_reqicbmparaminfo(sess, command->conn);
+
+		aim_bos_reqrights(sess, command->conn);
+		aim_bos_setgroupperm(sess, command->conn, AIM_CLASS_ALLUSERS);
+		aim_bos_setprivacyflags(sess, command->conn, AIM_PRIVFLAGS_ALLOWIDLE |
+							     AIM_PRIVFLAGS_ALLOWMEMBERSINCE);
+
+		break;
+	default:
+		sprintf(debug_buff, "got rate response for unhandled connection type %04x\n",
+				command->conn->type);
+		debug_print(debug_buff);
+		break;
+	}
+
+	return 1;
+}
+
+int gaim_bosrights(struct aim_session_t *sess, struct command_rx_struct *command, ...) {
+	aim_bos_clientready(sess, command->conn);
+
+	aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_CHATNAV);
+
+	return 1;
+}
+
 int gaim_directim_incoming(struct aim_session_t *sess, struct command_rx_struct *command, ...) {
 	va_list ap;
 	char *sn = NULL, *msg = NULL;
--- a/src/plugins.c	Fri Sep 01 23:45:43 2000 +0000
+++ b/src/plugins.c	Sat Sep 02 02:41:57 2000 +0000
@@ -728,64 +728,64 @@
 			buf[0] = 0;
 			break;
 		case event_im_recv:
-			sprintf(buf, "\"%s\" %s", *(char **)arg1, *(char **)arg2);
+			g_snprintf(buf, sizeof buf, "\"%s\" %s", *(char **)arg1, *(char **)arg2);
 			break;
 		case event_im_send:
-			sprintf(buf, "\"%s\" %s", (char *)arg1, *(char **)arg2);
+			g_snprintf(buf, sizeof buf, "\"%s\" %s", (char *)arg1, *(char **)arg2);
 			break;
 		case event_buddy_signon:
-			sprintf(buf, "\"%s\"", (char *)arg1);
+			g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg1);
 			break;
 		case event_buddy_signoff:
-			sprintf(buf, "\"%s\"", (char *)arg1);
+			g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg1);
 			break;
 		case event_buddy_away:
-			sprintf(buf, "\"%s\"", (char *)arg1);
+			g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg1);
 			break;
 		case event_buddy_back:
-			sprintf(buf, "\"%s\"", (char *)arg1);
+			g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg1);
 			break;
 		case event_blist_update:
 			buf[0] = 0;
 			break;
 		case event_chat_invited:
-			sprintf(buf, "\"%s\" \"%s\" %s", (char *)arg1, (char *)arg2, (char *)arg3);
+			g_snprintf(buf, sizeof buf, "\"%s\" \"%s\" %s", (char *)arg1, (char *)arg2, (char *)arg3);
 			break;
 		case event_chat_join:
-			sprintf(buf, "\"%s\"", (char *)arg1);
+			g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg1);
 			break;
 		case event_chat_leave:
-			sprintf(buf, "\"%s\"", (char *)arg1);
+			g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg1);
 			break;
 		case event_chat_buddy_join:
-			sprintf(buf, "\"%s\" \"%s\"", (char *)arg1, (char *)arg2);
+			g_snprintf(buf, sizeof buf, "\"%s\" \"%s\"", (char *)arg1, (char *)arg2);
 			break;
 		case event_chat_buddy_leave:
-			sprintf(buf, "\"%s\" \"%s\"", (char *)arg1, (char *)arg2);
+			g_snprintf(buf, sizeof buf, "\"%s\" \"%s\"", (char *)arg1, (char *)arg2);
 			break;
 		case event_chat_recv:
-			sprintf(buf, "\"%s\" \"%s\" %s", (char *)arg1, (char *)arg2, (char *)arg3);
+			g_snprintf(buf, sizeof buf, "\"%s\" \"%s\" %s", (char *)arg1, (char *)arg2, (char *)arg3);
 			break;
 		case event_chat_send:
-			sprintf(buf, "\"%s\" %s", (char *)arg1, *(char **)arg2);
+			g_snprintf(buf, sizeof buf, "\"%s\" %s", (char *)arg1, *(char **)arg2);
 			break;
 		case event_warned:
-			sprintf(buf, "\"%s\" %d", (char *)arg1, (int)arg2);
+			g_snprintf(buf, sizeof buf, "\"%s\" %d", (char *)arg1, (int)arg2);
 			break;
 		case event_error:
-			sprintf(buf, "%d", (int)arg1);
+			g_snprintf(buf, sizeof buf, "%d", (int)arg1);
 			break;
 		case event_quit:
 			buf[0] = 0;
 			break;
 		case event_new_conversation:
-			sprintf(buf, "\"%s\"", (char *)arg1);
+			g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg1);
 			break;
 		default:
 			break;
 	}
 	tmp = event_name(event);
-	sprintf(debug_buff, "%s: %s\n", tmp, buf);
+	g_snprintf(debug_buff, sizeof debug_buff, "%s: %s\n", tmp, buf);
 	debug_print(debug_buff);
 	perl_event(tmp, buf);
 #endif