3131GSList * child_list = NULL ;
3232
3333
34- static int ipc_master_cmd_die ( irc_t * irc , char * * cmd )
34+ static int ipc_master_cmd_client ( irc_t * data , char * * cmd )
35+ {
36+ struct bitlbee_child * child = (void * ) data ;
37+
38+ child -> host = g_strdup ( cmd [1 ] );
39+ child -> nick = g_strdup ( cmd [2 ] );
40+ child -> realname = g_strdup ( cmd [3 ] );
41+
42+ ipc_to_children_str ( "OPERMSG :Client connecting (PID=%d): %s@%s (%s)\r\n" ,
43+ child -> pid , child -> nick , child -> host , child -> realname );
44+
45+ return 1 ;
46+ }
47+
48+ static int ipc_master_cmd_die ( irc_t * data , char * * cmd )
3549{
3650 if ( global .conf -> runmode == RUNMODE_FORKDAEMON )
3751 ipc_to_children_str ( "DIE\r\n" );
@@ -41,7 +55,7 @@ static int ipc_master_cmd_die( irc_t *irc, char **cmd )
4155 return 1 ;
4256}
4357
44- static int ipc_master_cmd_rehash ( irc_t * irc , char * * cmd )
58+ static int ipc_master_cmd_rehash ( irc_t * data , char * * cmd )
4559{
4660 runmode_t oldmode ;
4761
@@ -63,9 +77,11 @@ static int ipc_master_cmd_rehash( irc_t *irc, char **cmd )
6377}
6478
6579static const command_t ipc_master_commands [] = {
80+ { "client" , 3 , ipc_master_cmd_client , 0 },
6681 { "die" , 0 , ipc_master_cmd_die , 0 },
6782 { "wallops" , 1 , NULL , IPC_CMD_TO_CHILDREN },
6883 { "lilo" , 1 , NULL , IPC_CMD_TO_CHILDREN },
84+ { "opermsg" , 1 , NULL , IPC_CMD_TO_CHILDREN },
6985 { "rehash" , 0 , ipc_master_cmd_rehash , 0 },
7086 { "kill" , 2 , NULL , IPC_CMD_TO_CHILDREN },
7187 { NULL }
@@ -74,7 +90,10 @@ static const command_t ipc_master_commands[] = {
7490
7591static int ipc_child_cmd_die ( irc_t * irc , char * * cmd )
7692{
77- bitlbee_shutdown ( NULL );
93+ if ( irc -> status >= USTATUS_LOGGED_IN )
94+ irc_write ( irc , "ERROR :Operator requested server shutdown, bye bye!" );
95+
96+ irc_abort ( irc );
7897
7998 return 1 ;
8099}
@@ -101,6 +120,17 @@ static int ipc_child_cmd_lilo( irc_t *irc, char **cmd )
101120 return 1 ;
102121}
103122
123+ static int ipc_child_cmd_opermsg ( irc_t * irc , char * * cmd )
124+ {
125+ if ( irc -> status < USTATUS_LOGGED_IN )
126+ return 1 ;
127+
128+ if ( strchr ( irc -> umode , 'o' ) )
129+ irc_write ( irc , ":%s NOTICE %s :*** OperMsg *** %s" , irc -> myhost , irc -> nick , cmd [1 ] );
130+
131+ return 1 ;
132+ }
133+
104134static int ipc_child_cmd_rehash ( irc_t * irc , char * * cmd )
105135{
106136 runmode_t oldmode ;
@@ -134,6 +164,7 @@ static const command_t ipc_child_commands[] = {
134164 { "die" , 0 , ipc_child_cmd_die , 0 },
135165 { "wallops" , 1 , ipc_child_cmd_wallops , 0 },
136166 { "lilo" , 1 , ipc_child_cmd_lilo , 0 },
167+ { "opermsg" , 1 , ipc_child_cmd_opermsg , 0 },
137168 { "rehash" , 0 , ipc_child_cmd_rehash , 0 },
138169 { "kill" , 2 , ipc_child_cmd_kill , 0 },
139170 { NULL }
@@ -216,12 +247,8 @@ void ipc_master_read( gpointer data, gint source, GaimInputCondition cond )
216247 c = l -> data ;
217248 if ( c -> ipc_fd == source )
218249 {
219- close ( c -> ipc_fd );
220- gaim_input_remove ( c -> ipc_inpa );
221- g_free ( c );
222-
223- child_list = g_slist_remove ( child_list , l );
224-
250+ ipc_master_free_one ( c );
251+ child_list = g_slist_remove ( child_list , c );
225252 break ;
226253 }
227254 }
@@ -252,7 +279,7 @@ void ipc_to_master( char **cmd )
252279 if ( global .conf -> runmode == RUNMODE_FORKDAEMON )
253280 {
254281 char * s = irc_build_line ( cmd );
255- ipc_to_master_str ( s );
282+ ipc_to_master_str ( "%s" , s );
256283 g_free ( s );
257284 }
258285 else if ( global .conf -> runmode == RUNMODE_DAEMON )
@@ -261,33 +288,41 @@ void ipc_to_master( char **cmd )
261288 }
262289}
263290
264- void ipc_to_master_str ( char * msg_buf )
291+ void ipc_to_master_str ( char * format , ... )
265292{
266- if ( global .conf -> runmode == RUNMODE_FORKDAEMON )
293+ char * msg_buf ;
294+ va_list params ;
295+
296+ va_start ( params , format );
297+ msg_buf = g_strdup_vprintf ( format , params );
298+ va_end ( params );
299+
300+ if ( strlen ( msg_buf ) > 512 )
301+ {
302+ /* Don't send it, it's too long... */
303+ }
304+ else if ( global .conf -> runmode == RUNMODE_FORKDAEMON )
267305 {
268306 write ( global .listen_socket , msg_buf , strlen ( msg_buf ) );
269307 }
270308 else if ( global .conf -> runmode == RUNMODE_DAEMON )
271309 {
272- char * s , * * cmd ;
273-
274- /* irc_parse_line() wants a read-write string, so get it one: */
275- s = g_strdup ( msg_buf );
276- cmd = irc_parse_line ( s );
310+ char * * cmd ;
277311
312+ cmd = irc_parse_line ( msg_buf );
278313 ipc_command_exec ( NULL , cmd , ipc_master_commands );
279-
280314 g_free ( cmd );
281- g_free ( s );
282315 }
316+
317+ g_free ( msg_buf );
283318}
284319
285320void ipc_to_children ( char * * cmd )
286321{
287322 if ( global .conf -> runmode == RUNMODE_FORKDAEMON )
288323 {
289324 char * msg_buf = irc_build_line ( cmd );
290- ipc_to_children_str ( msg_buf );
325+ ipc_to_children_str ( "%s" , msg_buf );
291326 g_free ( msg_buf );
292327 }
293328 else if ( global .conf -> runmode == RUNMODE_DAEMON )
@@ -299,9 +334,20 @@ void ipc_to_children( char **cmd )
299334 }
300335}
301336
302- void ipc_to_children_str ( char * msg_buf )
337+ void ipc_to_children_str ( char * format , ... )
303338{
304- if ( global .conf -> runmode == RUNMODE_FORKDAEMON )
339+ char * msg_buf ;
340+ va_list params ;
341+
342+ va_start ( params , format );
343+ msg_buf = g_strdup_vprintf ( format , params );
344+ va_end ( params );
345+
346+ if ( strlen ( msg_buf ) > 512 )
347+ {
348+ /* Don't send it, it's too long... */
349+ }
350+ else if ( global .conf -> runmode == RUNMODE_FORKDAEMON )
305351 {
306352 int msg_len = strlen ( msg_buf );
307353 GSList * l ;
@@ -314,15 +360,34 @@ void ipc_to_children_str( char *msg_buf )
314360 }
315361 else if ( global .conf -> runmode == RUNMODE_DAEMON )
316362 {
317- char * s , * * cmd ;
318-
319- /* irc_parse_line() wants a read-write string, so get it one: */
320- s = g_strdup ( msg_buf );
321- cmd = irc_parse_line ( s );
363+ char * * cmd ;
322364
365+ cmd = irc_parse_line ( msg_buf );
323366 ipc_to_children ( cmd );
324-
325367 g_free ( cmd );
326- g_free ( s );
327368 }
369+
370+ g_free ( msg_buf );
371+ }
372+
373+ void ipc_master_free_one ( struct bitlbee_child * c )
374+ {
375+ gaim_input_remove ( c -> ipc_inpa );
376+ closesocket ( c -> ipc_fd );
377+
378+ g_free ( c -> host );
379+ g_free ( c -> nick );
380+ g_free ( c -> realname );
381+ g_free ( c );
382+ }
383+
384+ void ipc_master_free_all ()
385+ {
386+ GSList * l ;
387+
388+ for ( l = child_list ; l ; l = l -> next )
389+ ipc_master_free_one ( l -> data );
390+
391+ g_slist_free ( child_list );
392+ child_list = NULL ;
328393}
0 commit comments