$OpenBSD: patch-irc_c,v 1.4 2007/01/14 21:53:01 simon Exp $
--- irc.c.orig	Sat Jun 24 17:00:43 2006
+++ irc.c	Fri Dec 15 21:21:27 2006
@@ -59,7 +59,7 @@ irc_t *irc_new( int fd )
 	irc->userhash = g_hash_table_new( g_str_hash, g_str_equal );
 	irc->watches = g_hash_table_new( g_str_hash, g_str_equal );
 	
-	strcpy( irc->umode, UMODE );
+	strlcpy( irc->umode, UMODE, sizeof(irc->umode) );
 	irc->mynick = g_strdup( ROOT_NICK );
 	irc->channel = g_strdup( ROOT_CHAN );
 	
@@ -117,9 +117,9 @@ irc_t *irc_new( int fd )
 	set_add( irc, "buddy_sendbuffer_delay", "200", set_eval_int );
 	set_add( irc, "charset", "iso8859-1", set_eval_charset );
 	set_add( irc, "debug", "false", set_eval_bool );
-	set_add( irc, "default_target", "root", NULL );
+	set_add( irc, "default_target", ROOT_NICK, NULL );
 	set_add( irc, "display_namechanges", "false", set_eval_bool );
-	set_add( irc, "handle_unknown", "root", NULL );
+	set_add( irc, "handle_unknown", ROOT_NICK, NULL );
 	set_add( irc, "lcnicks", "true", set_eval_bool );
 	set_add( irc, "ops", "both", set_eval_ops );
 	set_add( irc, "private", "true", set_eval_bool );
@@ -621,7 +621,7 @@ int irc_exec( irc_t *irc, char **cmd )
 				
 				if( g_strcasecmp( t, "last" ) == 0 && irc->last_target )
 					cmd[1] = irc->last_target;
-				else if( g_strcasecmp( t, "root" ) == 0 )
+				else if( g_strcasecmp( t, ROOT_NICK ) == 0  || g_strcasecmp( t, "root" ) == 0 )
 					cmd[1] = irc->mynick;
 				
 				for( i = 0; i < strlen( cmd[2] ); i ++ )
@@ -708,8 +708,8 @@ int irc_exec( irc_t *irc, char **cmd )
 					if( lenleft < 0 )
 						break;
 					
-					strcat( buff, u->nick );
-					strcat( buff, " " );
+					strlcat( buff, u->nick, sizeof(buff) );
+					strlcat( buff, " ", sizeof(buff) );
 				}
 				
 				if( next )
@@ -869,7 +869,7 @@ void irc_reply( irc_t *irc, int code, ch
 	va_list params;
 	
 	va_start( params, format );
-	g_vsnprintf( text, IRC_MAX_LINE, format, params );
+	g_vsnprintf( text, sizeof(text), format, params );
 	va_end( params );
 	irc_write( irc, ":%s %03d %s %s", irc->myhost, code, irc->nick?irc->nick:"*", text );
 	
@@ -923,14 +923,14 @@ void irc_vawrite( irc_t *irc, char *form
 		
 		conv[IRC_MAX_LINE] = 0;
 		if( do_iconv( "UTF-8", cs, line, conv, 0, IRC_MAX_LINE - 2 ) != -1 )
-			strcpy( line, conv );
+			strlcpy( line, conv, sizeof(line) );
 	}
-	strcat( line, "\r\n" );
+	strlcat( line, "\r\n", sizeof(line) );
 	
 	if( irc->sendbuffer != NULL ) {
-		size = strlen( irc->sendbuffer ) + strlen( line );
-		irc->sendbuffer = g_renew ( char, irc->sendbuffer, size + 1 );
-		strcpy( ( irc->sendbuffer + strlen( irc->sendbuffer ) ), line );
+		size = strlen( irc->sendbuffer ) + strlen( line ) + 1;
+		irc->sendbuffer = g_renew ( char, irc->sendbuffer, size );
+		strlcat( irc->sendbuffer, line, size);
 	}
 	else 
 		irc->sendbuffer = g_strdup(line);	
@@ -1000,7 +1000,7 @@ void irc_names( irc_t *irc, char *channe
 			}
 			else if( !u->gc )
 			{
-				if( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( set_getstr( irc, "ops" ), "root" ) == 0 || strcmp( set_getstr( irc, "ops" ), "both" ) == 0 ) )
+				if( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( set_getstr( irc, "ops" ), ROOT_NICK ) == 0 || strcmp( set_getstr( irc, "ops" ), "root" ) == 0 || strcmp( set_getstr( irc, "ops" ), "both" ) == 0 ) )
 					s = "@";
 				else if( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( set_getstr( irc, "ops" ), "user" ) == 0 || strcmp( set_getstr( irc, "ops" ), "both" ) == 0 ) )
 					s = "@";
@@ -1120,15 +1120,19 @@ void irc_motd( irc_t *irc )
 		irc_reply( irc, 375, ":- %s Message Of The Day - ", irc->myhost );
 		while( read( fd, linebuf + len, 1 ) == 1 )
 		{
-			if( linebuf[len] == '\n' || len == max )
+			/* If we have a LF, output the line and START AGAIN */
+			if( linebuf[len] == '\n')
 			{
 				linebuf[len] = 0;
 				irc_reply( irc, 372, ":- %s", linebuf );
 				len = 0;
+				continue;
 			}
-			else if( linebuf[len] == '%' )
+
+			if( linebuf[len] == '%' )
 			{
-				read( fd, linebuf + len, 1 );
+				if (read( fd, linebuf + len, 1 ) != 1)
+					break;
 				if( linebuf[len] == 'h' )
 					add = irc->myhost;
 				else if( linebuf[len] == 'v' )
@@ -1137,14 +1141,30 @@ void irc_motd( irc_t *irc )
 					add = irc->nick;
 				else
 					add = "%";
-				
-				strncpy( linebuf + len, add, max - len );
+
+				/* If the expanded string would be too long, output the line */
+				if ((len + strlen(add)) > max) {
+					linebuf[len] = 0;
+					irc_reply( irc, 372, ":- %s", linebuf );
+					len = 0;
+				}
+
+				/* Append the string to the line */
+				strlcpy( linebuf + len, add, max - len );
 				while( linebuf[++len] );
 			}
-			else if( len < max )
+			else
 			{
 				len ++;
 			}
+
+			/* If we have reached the maximum, output the line */
+			if( len == max )
+			{
+				linebuf[len] = 0;
+				irc_reply( irc, 372, ":- %s", linebuf );
+				len = 0;
+			}
 		}
 		irc_reply( irc, 376, ":End of MOTD" );
 		close( fd );
@@ -1475,8 +1495,8 @@ int buddy_send_handler( irc_t *irc, user
 			u->sendbuf = g_renew ( char, u->sendbuf, u->sendbuf_len );
 		}
 		
-		strcat( u->sendbuf, msg );
-		strcat( u->sendbuf, "\n" );
+		strlcat( u->sendbuf, msg, u->sendbuf_len );
+		strlcat( u->sendbuf, "\n", u->sendbuf_len );
 		
 		delay = set_getint( irc, "buddy_sendbuffer_delay" );
 		if( delay <= 5 )
