Changeset 6c2404e
- Timestamp:
- 2010-07-06T21:44:52Z (14 years ago)
- Branches:
- master
- Children:
- 0b09da0
- Parents:
- 006a84f
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
bitlbee.c
r006a84f r6c2404e 318 318 struct bitlbee_child *child; 319 319 320 /* TODO: Stuff like this belongs in ipc.c. */ 320 321 child = g_new0( struct bitlbee_child, 1 ); 321 322 child->pid = client_pid; 322 323 child->ipc_fd = fds[0]; 323 324 child->ipc_inpa = b_input_add( child->ipc_fd, B_EV_IO_READ, ipc_master_read, child ); 325 child->to_fd = -1; 324 326 child_list = g_slist_append( child_list, child ); 325 327 -
bitlbee.h
r006a84f r6c2404e 163 163 void root_command_string( irc_t *irc, char *command ); 164 164 void root_command( irc_t *irc, char *command[] ); 165 gboolean cmd_identify_finish( gpointer data, gint fd, b_input_condition cond ); 165 166 gboolean bitlbee_shutdown( gpointer data, gint fd, b_input_condition cond ); 166 167 -
ipc.c
r006a84f r6c2404e 110 110 global.restart = -1; 111 111 bitlbee_shutdown( NULL, -1, 0 ); 112 } 113 114 void ipc_master_cmd_identify( irc_t *data, char **cmd ) 115 { 116 struct bitlbee_child *child = (void*) data, *old = NULL; 117 GSList *l; 118 119 if( strcmp( child->nick, cmd[1] ) != 0 ) 120 return; 121 122 g_free( child->password ); 123 child->password = g_strdup( cmd[2] ); 124 125 for( l = child_list; l; l = l->next ) 126 { 127 old = l->data; 128 if( nick_cmp( old->nick, child->nick ) == 0 && child != old && 129 old->password && strcmp( old->password, child->password ) ) 130 break; 131 } 132 133 if( old == NULL ) 134 return; 135 136 child->to_child = old; 112 137 } 113 138 … … 123 148 { "kill", 2, NULL, IPC_CMD_TO_CHILDREN }, 124 149 { "restart", 0, ipc_master_cmd_restart, 0 }, 150 { "identify", 2, ipc_master_cmd_identify, 0 }, 125 151 { NULL } 126 152 }; … … 202 228 }; 203 229 230 static gboolean ipc_send_fd( int fd, int send_fd ); 231 232 gboolean ipc_child_identify( irc_t *irc ) 233 { 234 if( global.conf->runmode == RUNMODE_FORKDAEMON ) 235 { 236 if( !ipc_send_fd( global.listen_socket, irc->fd ) ) 237 ipc_child_disable(); 238 239 ipc_to_master_str( "IDENTIFY %s :%s\r\n", irc->user->nick, irc->password ); 240 241 return TRUE; 242 } 243 else 244 return FALSE; 245 } 204 246 205 247 static void ipc_command_exec( void *data, char **cmd, const command_t *commands ) … … 230 272 /* Return just one line. Returns NULL if something broke, an empty string 231 273 on temporary "errors" (EAGAIN and friends). */ 232 static char *ipc_readline( int fd ) 233 { 274 static char *ipc_readline( int fd, int *recv_fd ) 275 { 276 struct msghdr msg; 277 struct iovec iov; 278 char ccmsg[CMSG_SPACE(sizeof(recv_fd))]; 279 struct cmsghdr *cmsg; 234 280 char buf[513], *eol; 235 281 int size; … … 253 299 size = eol - buf + 2; 254 300 255 if( recv( fd, buf, size, 0 ) != size ) 301 iov.iov_base = buf; 302 iov.iov_len = size; 303 304 memset( &msg, 0, sizeof( msg ) ); 305 msg.msg_iov = &iov; 306 msg.msg_iovlen = 1; 307 msg.msg_control = ccmsg; 308 msg.msg_controllen = sizeof( ccmsg ); 309 310 if( recvmsg( fd, &msg, 0 ) != size ) 256 311 return NULL; 257 else 258 return g_strndup( buf, size - 2 ); 312 313 if( recv_fd ) 314 for( cmsg = CMSG_FIRSTHDR( &msg ); cmsg; cmsg = CMSG_NXTHDR( &msg, cmsg ) ) 315 if( cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS ) 316 { 317 /* Getting more than one shouldn't happen but if it does, 318 make sure we don't leave them around. */ 319 if( *recv_fd != -1 ) 320 close( *recv_fd ); 321 322 *recv_fd = *(int*) CMSG_DATA( cmsg ); 323 } 324 325 return g_strndup( buf, size - 2 ); 259 326 } 260 327 261 328 gboolean ipc_master_read( gpointer data, gint source, b_input_condition cond ) 262 329 { 330 struct bitlbee_child *child = data; 263 331 char *buf, **cmd; 264 332 265 if( ( buf = ipc_readline( source ) ) )333 if( ( buf = ipc_readline( source, &child->to_fd ) ) ) 266 334 { 267 335 cmd = irc_parse_line( buf ); 268 336 if( cmd ) 269 337 { 270 ipc_command_exec( data, cmd, ipc_master_commands );338 ipc_command_exec( child, cmd, ipc_master_commands ); 271 339 g_free( cmd ); 272 340 } … … 284 352 { 285 353 char *buf, **cmd; 286 287 if( ( buf = ipc_readline( source ) ) ) 354 int recv_fd = -1; 355 356 if( ( buf = ipc_readline( source, &recv_fd ) ) ) 288 357 { 289 358 cmd = irc_parse_line( buf ); … … 413 482 } 414 483 484 static gboolean ipc_send_fd( int fd, int send_fd ) 485 { 486 struct msghdr msg; 487 struct iovec iov; 488 char ccmsg[CMSG_SPACE(sizeof(fd))]; 489 struct cmsghdr *cmsg; 490 491 memset( &msg, 0, sizeof( msg ) ); 492 iov.iov_base = "0x90\r\n"; 493 iov.iov_len = 6; 494 msg.msg_iov = &iov; 495 msg.msg_iovlen = 1; 496 497 msg.msg_control = ccmsg; 498 msg.msg_controllen = sizeof( ccmsg ); 499 cmsg = CMSG_FIRSTHDR( &msg ); 500 cmsg->cmsg_level = SOL_SOCKET; 501 cmsg->cmsg_type = SCM_RIGHTS; 502 cmsg->cmsg_len = CMSG_LEN( sizeof( send_fd ) ); 503 *(int*)CMSG_DATA( cmsg ) = send_fd; 504 msg.msg_controllen = cmsg->cmsg_len; 505 506 return sendmsg( fd, &msg, 0 ) == 6; 507 } 508 415 509 void ipc_master_free_one( struct bitlbee_child *c ) 416 510 { 417 511 b_event_remove( c->ipc_inpa ); 418 512 closesocket( c->ipc_fd ); 513 514 if( c->to_fd != -1 ) 515 close( c->to_fd ); 419 516 420 517 g_free( c->host ); 421 518 g_free( c->nick ); 422 519 g_free( c->realname ); 520 g_free( c->password ); 423 521 g_free( c ); 424 522 } … … 506 604 struct bitlbee_child *child = g_new0( struct bitlbee_child, 1 ); 507 605 606 child->to_fd = -1; 508 607 child->ipc_fd = accept( serversock, NULL, 0 ); 509 510 608 if( child->ipc_fd == -1 ) 511 609 { … … 516 614 child->ipc_inpa = b_input_add( child->ipc_fd, B_EV_IO_READ, ipc_master_read, child ); 517 615 518 child_list = g_slist_ append( child_list, child );616 child_list = g_slist_prepend( child_list, child ); 519 617 520 618 return TRUE; … … 598 696 } 599 697 child->ipc_inpa = b_input_add( child->ipc_fd, B_EV_IO_READ, ipc_master_read, child ); 600 601 child_list = g_slist_append( child_list, child ); 698 child->to_fd = -1; 699 700 child_list = g_slist_prepend( child_list, child ); 602 701 } 603 702 -
ipc.h
r006a84f r6c2404e 37 37 char *nick; 38 38 char *realname; 39 40 char *password; 41 42 /* For takeovers: */ 43 struct bitlbee_child *to_child; 44 int to_fd; 39 45 }; 40 46 -
irc.h
r006a84f r6c2404e 87 87 gint w_watch_source_id; 88 88 gint ping_source_id; 89 gint login_source_id; /* To slightly delay some events at login time. */ 89 90 90 91 struct bee *b; -
root_commands.c
r006a84f r6c2404e 105 105 { 106 106 storage_status_t status; 107 char *account_on[] = { "account", "on", NULL };108 107 gboolean load = TRUE; 109 108 char *password = cmd[1]; … … 158 157 irc_umode_set( irc, "+R", 1 ); 159 158 irc_channel_auto_joins( irc, NULL ); 160 if( load && set_getbool( &irc->b->set, "auto_connect" ) ) 161 cmd_account( irc, account_on ); 159 160 if( ipc_child_identify( irc ) ) 161 { 162 if( load && set_getbool( &irc->b->set, "auto_connect" ) ) 163 irc->login_source_id = b_timeout_add( 200, 164 cmd_identify_finish, irc ); 165 } 166 else if( load && set_getbool( &irc->b->set, "auto_connect" ) ) 167 cmd_identify_finish( irc, 0, 0 ); 168 162 169 break; 163 170 case STORAGE_OTHER_ERROR: … … 166 173 break; 167 174 } 175 } 176 177 gboolean cmd_identify_finish( gpointer data, gint fd, b_input_condition cond ) 178 { 179 char *account_on[] = { "account", "on", NULL }; 180 irc_t *irc = data; 181 182 cmd_account( irc, account_on ); 183 184 return FALSE; 168 185 } 169 186 … … 672 689 else if( iu == irc->user ) 673 690 { 674 irc_usermsg( irc, " Nick `%s' can't be changed", cmd[1]);691 irc_usermsg( irc, "Use /nick to change your own nickname" ); 675 692 } 676 693 else if( !nick_ok( cmd[2] ) )
Note: See TracChangeset
for help on using the changeset viewer.