Changes in / [a4dc9f7:8e419cb]
- Files:
-
- 2 added
- 5 deleted
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
ra4dc9f7 r8e419cb 10 10 11 11 # Program variables 12 objects = account.o bitlbee.o c rypting.o help.o ini.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o storage_text.o url.o user.o util.o12 objects = account.o bitlbee.o commands.o crypting.o help.o ini.o irc.o nick.o query.o set.o storage.o storage_text.o url.o user.o util.o 13 13 subdirs = protocols 14 14 -
bitlbee.c
ra4dc9f7 r8e419cb 29 29 #include "protocols/nogaim.h" 30 30 #include "help.h" 31 #include "ipc.h"32 31 #include <signal.h> 33 32 #include <stdio.h> 34 33 #include <errno.h> 35 34 36 gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data ); 35 gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data ) 36 { 37 size_t size = sizeof( struct sockaddr_in ); 38 struct sockaddr_in conn_info; 39 int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size ); 40 pid_t client_pid = 0; 41 42 if( global.conf->runmode == RUNMODE_FORKDAEMON ) 43 client_pid = fork(); 44 45 if( client_pid == 0 ) 46 { 47 log_message( LOGLVL_INFO, "Creating new connection with fd %d.", new_socket ); 48 irc_new( new_socket ); 49 50 if( global.conf->runmode == RUNMODE_FORKDAEMON ) 51 { 52 /* Close the listening socket, we're a client. */ 53 close( global.listen_socket ); 54 g_source_remove( global.listen_watch_source_id ); 55 } 56 } 57 else 58 { 59 /* We don't need this one, only the client does. */ 60 close( new_socket ); 61 62 /* Or maybe we didn't even get a child process... */ 63 if( client_pid == -1 ) 64 log_message( LOGLVL_ERROR, "Failed to fork() subprocess for client: %s", strerror( errno ) ); 65 } 66 67 return TRUE; 68 } 69 70 37 71 38 72 int bitlbee_daemon_init() … … 45 79 int i; 46 80 GIOChannel *ch; 47 FILE *fp;48 81 49 82 log_link( LOGLVL_ERROR, LOGOUTPUT_SYSLOG ); … … 56 89 return( -1 ); 57 90 } 58 59 /* TIME_WAIT (?) sucks.. */60 i = 1;61 setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) );62 91 63 92 #ifdef IPV6 … … 105 134 else if( i != 0 ) 106 135 exit( 0 ); 107 136 close( 0 ); 137 close( 1 ); 138 close( 2 ); 108 139 chdir( "/" ); 109 110 /* Sometimes std* are already closed (for example when we're in a RESTARTed111 BitlBee process. So let's only close TTY-fds. */112 if( isatty( 0 ) ) close( 0 );113 if( isatty( 0 ) ) close( 1 );114 if( isatty( 0 ) ) close( 2 );115 140 } 116 141 #endif 117 118 if( global.conf->runmode == RUNMODE_FORKDAEMON )119 ipc_master_load_state();120 121 if( global.conf->runmode == RUNMODE_DAEMON ||122 global.conf->runmode == RUNMODE_FORKDAEMON )123 ipc_master_listen_socket();124 125 if( ( fp = fopen( global.conf->pidfile, "w" ) ) )126 {127 fprintf( fp, "%d\n", (int) getpid() );128 fclose( fp );129 }130 else131 {132 log_message( LOGLVL_WARNING, "Warning: Couldn't write PID to `%s'", global.conf->pidfile );133 }134 142 135 143 return( 0 ); … … 152 160 if( condition & G_IO_ERR || condition & G_IO_HUP ) 153 161 { 154 irc_ abort( irc, 1, "Read error");162 irc_free( irc ); 155 163 return FALSE; 156 164 } … … 159 167 if( st == 0 ) 160 168 { 161 irc_ abort( irc, 1, "Connection reset by peer");169 irc_free( irc ); 162 170 return FALSE; 163 171 } … … 170 178 else 171 179 { 172 irc_ abort( irc, 1, "Read error: %s", strerror( errno ));180 irc_free( irc ); 173 181 return FALSE; 174 182 } … … 186 194 } 187 195 188 irc_process( irc ); 189 190 /* Normally, irc_process() shouldn't call irc_free() but irc_abort(). Just in case: */ 191 if( !g_slist_find( irc_connection_list, irc ) ) 192 { 193 log_message( LOGLVL_WARNING, "Abnormal termination of connection with fd %d.", irc->fd ); 196 if( !irc_process( irc ) ) 197 { 198 log_message( LOGLVL_INFO, "Destroying connection with fd %d.", irc->fd ); 199 irc_free( irc ); 194 200 return FALSE; 195 201 } … … 198 204 if( irc->readbuffer && ( strlen( irc->readbuffer ) > 1024 ) ) 199 205 { 200 irc_abort( irc, 0, "Maximum line length exceeded" ); 206 log_message( LOGLVL_ERROR, "Maximum line length exceeded." ); 207 irc_free( irc ); 201 208 return FALSE; 202 209 } … … 217 224 st = write( irc->fd, irc->sendbuffer, size ); 218 225 219 if( st == 0 || ( st < 0 && !sockerr_again() ) ) 220 { 221 irc_abort( irc, 1, "Write error: %s", strerror( errno ) ); 222 return FALSE; 223 } 224 else if( st < 0 ) /* && sockerr_again() */ 225 { 226 return TRUE; 226 if( st <= 0 ) 227 { 228 if( sockerr_again() ) 229 { 230 return TRUE; 231 } 232 else 233 { 234 irc_free( irc ); 235 return FALSE; 236 } 227 237 } 228 238 … … 231 241 g_free( irc->sendbuffer ); 232 242 irc->sendbuffer = NULL; 243 233 244 irc->w_watch_source_id = 0; 234 235 if( irc->status == USTATUS_SHUTDOWN )236 irc_free( irc );237 238 245 return( FALSE ); 239 246 } … … 248 255 } 249 256 250 gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data )251 {252 size_t size = sizeof( struct sockaddr_in );253 struct sockaddr_in conn_info;254 int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size );255 pid_t client_pid = 0;256 257 if( new_socket == -1 )258 {259 log_message( LOGLVL_WARNING, "Could not accept new connection: %s", strerror( errno ) );260 return TRUE;261 }262 263 if( global.conf->runmode == RUNMODE_FORKDAEMON )264 {265 int fds[2];266 267 if( socketpair( AF_UNIX, SOCK_STREAM, 0, fds ) == -1 )268 {269 log_message( LOGLVL_WARNING, "Could not create IPC socket for client: %s", strerror( errno ) );270 fds[0] = fds[1] = -1;271 }272 273 sock_make_nonblocking( fds[0] );274 sock_make_nonblocking( fds[1] );275 276 client_pid = fork();277 278 if( client_pid > 0 && fds[0] != -1 )279 {280 struct bitlbee_child *child;281 282 child = g_new0( struct bitlbee_child, 1 );283 child->pid = client_pid;284 child->ipc_fd = fds[0];285 child->ipc_inpa = gaim_input_add( child->ipc_fd, GAIM_INPUT_READ, ipc_master_read, child );286 child_list = g_slist_append( child_list, child );287 288 log_message( LOGLVL_INFO, "Creating new subprocess with pid %d.", client_pid );289 290 /* Close some things we don't need in the parent process. */291 close( new_socket );292 close( fds[1] );293 }294 else if( client_pid == 0 )295 {296 irc_t *irc;297 298 /* Close the listening socket, we're a client. */299 close( global.listen_socket );300 g_source_remove( global.listen_watch_source_id );301 302 /* Make the connection. */303 irc = irc_new( new_socket );304 305 /* We can store the IPC fd there now. */306 global.listen_socket = fds[1];307 global.listen_watch_source_id = gaim_input_add( fds[1], GAIM_INPUT_READ, ipc_child_read, irc );308 309 close( fds[0] );310 311 ipc_master_free_all();312 }313 }314 else315 {316 log_message( LOGLVL_INFO, "Creating new connection with fd %d.", new_socket );317 irc_new( new_socket );318 }319 320 return TRUE;321 }322 323 257 void bitlbee_shutdown( gpointer data ) 324 258 { -
bitlbee.h
ra4dc9f7 r8e419cb 109 109 #include "sock.h" 110 110 111 typedef struct global { 112 /* In forked mode, child processes store the fd of the IPC socket here. */ 111 typedef struct global_t { 113 112 int listen_socket; 114 113 gint listen_watch_source_id; … … 118 117 char *helpfile; 119 118 GMainLoop *loop; 120 int restart;121 119 } global_t; 122 120 … … 127 125 gboolean bitlbee_io_current_client_write( GIOChannel *source, GIOCondition condition, gpointer data ); 128 126 129 voidroot_command_string( irc_t *irc, user_t *u, char *command, int flags );130 voidroot_command( irc_t *irc, char *command[] );127 int root_command_string( irc_t *irc, user_t *u, char *command, int flags ); 128 int root_command( irc_t *irc, char *command[] ); 131 129 void bitlbee_shutdown( gpointer data ); 132 130 double gettime( void ); -
commands.h
ra4dc9f7 r8e419cb 29 29 #include "bitlbee.h" 30 30 31 typedef struct command 31 typedef struct command_t 32 32 { 33 33 char *command; 34 34 int required_parameters; 35 void (*execute)(irc_t *, char **args); 36 int flags; 35 int (*execute)(irc_t *, char **args); 37 36 } command_t; 37 38 int cmd_account( irc_t *irc, char **cmd ); 39 int cmd_help( irc_t *irc, char **args); 40 int cmd_info( irc_t *irc, char **args); 41 int cmd_add( irc_t *irc, char **args) ; 42 int cmd_rename( irc_t *irc, char **args ); 43 int cmd_remove( irc_t *irc, char **args ); 44 int cmd_block( irc_t *irc, char **args ); 45 int cmd_allow( irc_t *irc, char **args ); 46 int cmd_save( irc_t *irc, char **args ); 47 int cmd_set( irc_t *irc, char **args ); 48 int cmd_yesno( irc_t *irc, char **args ); 49 int cmd_identify( irc_t *irc, char **args ); 50 int cmd_register( irc_t *irc, char **args ); 51 int cmd_drop( irc_t *irc, char **args ); 52 int cmd_blist( irc_t *irc, char **cmd ); 53 int cmd_nick( irc_t *irc, char **cmd ); 54 int cmd_qlist( irc_t *irc, char **cmd ); 55 int cmd_import_buddies( irc_t *irc, char **cmd ); 56 int cmd_dump( irc_t *irc, char **cmd ); 38 57 39 58 extern const command_t commands[]; 40 59 41 #define IRC_CMD_PRE_LOGIN 142 #define IRC_CMD_LOGGED_IN 243 #define IRC_CMD_OPER_ONLY 444 #define IRC_CMD_TO_MASTER 845 46 #define IPC_CMD_TO_CHILDREN 147 48 60 #endif -
conf.c
ra4dc9f7 r8e419cb 32 32 #include "ini.h" 33 33 #include "url.h" 34 #include "ipc.h"35 34 36 35 #include "protocols/proxy.h" … … 62 61 conf->configdir = g_strdup( CONFIG ); 63 62 conf->plugindir = g_strdup( PLUGINDIR ); 64 conf->pidfile = g_strdup( "/var/run/bitlbee.pid" );65 63 conf->motdfile = g_strdup( ETCDIR "/motd.txt" ); 66 64 conf->ping_interval = 180; 67 65 conf->ping_timeout = 300; 68 proxytype = 0;69 66 70 67 i = conf_loadini( conf, CONF_FILE ); … … 79 76 } 80 77 81 while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:" ) ) >= 0 ) 82 /* ^^^^ Just to make sure we skip this step from the REHASH handler. */ 78 while( ( opt = getopt( argc, argv, "i:p:nvIDFc:d:h" ) ) >= 0 ) 83 79 { 84 80 if( opt == 'i' ) … … 95 91 conf->port = i; 96 92 } 97 else if( opt == 'p' )98 {99 g_free( conf->pidfile );100 conf->pidfile = g_strdup( optarg );101 }102 93 else if( opt == 'n' ) 103 conf->nofork =1;94 conf->nofork=1; 104 95 else if( opt == 'v' ) 105 conf->verbose =1;96 conf->verbose=1; 106 97 else if( opt == 'I' ) 107 conf->runmode =RUNMODE_INETD;98 conf->runmode=RUNMODE_INETD; 108 99 else if( opt == 'D' ) 109 conf->runmode =RUNMODE_DAEMON;100 conf->runmode=RUNMODE_DAEMON; 110 101 else if( opt == 'F' ) 111 conf->runmode =RUNMODE_FORKDAEMON;102 conf->runmode=RUNMODE_FORKDAEMON; 112 103 else if( opt == 'c' ) 113 104 { … … 117 108 CONF_FILE = g_strdup( optarg ); 118 109 g_free( conf ); 119 /* Re-evaluate arguments. Don't use this option twice,120 you'll end up in an infinite loop! Hope this trick121 works with all libcs BTW.. */122 optind = 1;123 110 return( conf_load( argc, argv ) ); 124 111 } … … 139 126 " -D Daemon mode. (Still EXPERIMENTAL!)\n" 140 127 " -F Forking daemon. (one process per client)\n" 141 " -P Specify PID-file (not for inetd mode)\n"142 128 " -i Specify the interface (by IP address) to listen on.\n" 143 129 " (Default: 0.0.0.0 (any interface))\n" … … 150 136 return( NULL ); 151 137 } 152 else if( opt == 'R' )153 {154 /* We can't load the statefile yet (and should make very sure we do this155 only once), so set the filename here and load the state information156 when initializing ForkDaemon. (This option only makes sense in that157 mode anyway!) */158 ipc_master_set_statefile( optarg );159 }160 138 } 161 139 … … 191 169 else 192 170 conf->runmode = RUNMODE_INETD; 193 }194 else if( g_strcasecmp( ini->key, "pidfile" ) == 0 )195 {196 g_free( conf->pidfile );197 conf->pidfile = g_strdup( ini->value );198 171 } 199 172 else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 ) -
conf.h
ra4dc9f7 r8e419cb 43 43 char *configdir; 44 44 char *plugindir; 45 char *pidfile;46 45 char *motdfile; 47 46 char *primary_storage; -
configure
ra4dc9f7 r8e419cb 14 14 datadir='$prefix/share/bitlbee/' 15 15 config='/var/lib/bitlbee/' 16 pidfile='/var/run/bitlbee.pid'17 ipcsocket='/var/run/bitlbee'18 16 plugindir='$prefix/lib/bitlbee' 19 17 … … 48 46 --datadir=... $datadir 49 47 --plugindir=... $plugindir 50 --pidfile=... $pidfile51 48 --config=... $config 52 --ipcsocket=... $ipcsocket53 49 54 50 --msn=0/1 Disable/enable MSN part $msn … … 78 74 config=`eval echo "$config/" | sed 's/\/\{1,\}/\//g'` 79 75 plugindir=`eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g'` 80 pidfile=`eval echo "$pidfile" | sed 's/\/\{1,\}/\//g'`81 ipcsocket=`eval echo "$ipcsocket" | sed 's/\/\{1,\}/\//g'`82 76 83 77 cat<<EOF>Makefile.settings … … 90 84 PLUGINDIR=$plugindir 91 85 CONFIG=$config 92 IPCSOCKET=$ipcsocket93 86 94 87 ARCH=$arch … … 111 104 #define VARDIR "$datadir" 112 105 #define PLUGINDIR "$plugindir" 113 #define PIDFILE "$pidfile"114 #define IPCSOCKET "$ipcsocket"115 106 #define ARCH "$arch" 116 107 #define CPU "$cpu" -
doc/README
ra4dc9f7 r8e419cb 50 50 51 51 These days, MSN Messenger clients have to connect to the MS Passport servers 52 through HTTPS. BitlBee can use se veral SSL libraries for this: GnuTLS, NSS52 through HTTPS. BitlBee can use serveral SSL libraries for this: GnuTLS, NSS 53 53 (which comes with Mozilla) and OpenSSL. OpenSSL is not GPL-compatible in some 54 54 situations, so using GnuTLS or NSS is preferred. However, especially on *BSD, -
irc.c
ra4dc9f7 r8e419cb 27 27 #include "bitlbee.h" 28 28 #include "crypting.h" 29 #include "ipc.h"30 29 31 30 static gboolean irc_userping( gpointer _irc ); … … 152 151 } 153 152 154 /* immed=1 makes this function pretty much equal to irc_free(), except that155 this one will "log". In case the connection is already broken and we156 shouldn't try to write to it. */157 void irc_abort( irc_t *irc, int immed, char *format, ... )158 {159 if( format != NULL )160 {161 va_list params;162 char *reason;163 164 va_start( params, format );165 reason = g_strdup_vprintf( format, params );166 va_end( params );167 168 if( !immed )169 irc_write( irc, "ERROR :Closing link: %s", reason );170 171 ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n",172 irc->nick ? irc->nick : "(NONE)", irc->host, reason );173 174 g_free( reason );175 }176 else177 {178 if( !immed )179 irc_write( irc, "ERROR :Closing link" );180 181 ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n",182 irc->nick ? irc->nick : "(NONE)", irc->host, "No reason given" );183 }184 185 irc->status = USTATUS_SHUTDOWN;186 if( irc->sendbuffer && !immed )187 {188 /* We won't read from this socket anymore. Instead, we'll connect a timer189 to it that should shut down the connection in a second, just in case190 bitlbee_.._write doesn't do it first. */191 192 g_source_remove( irc->r_watch_source_id );193 irc->r_watch_source_id = g_timeout_add_full( G_PRIORITY_HIGH, 1000, (GSourceFunc) irc_free, irc, NULL );194 }195 else196 {197 irc_free( irc );198 }199 }200 201 153 static gboolean irc_free_userhash( gpointer key, gpointer value, gpointer data ) 202 154 { … … 220 172 if( storage_save( irc, TRUE ) != STORAGE_OK ) 221 173 irc_usermsg( irc, "Error while saving settings!" ); 222 223 closesocket( irc->fd );224 174 225 175 if( irc->ping_source_id > 0 ) … … 341 291 } 342 292 343 voidirc_process( irc_t *irc )344 { 345 char **lines, *temp , **cmd;293 int irc_process( irc_t *irc ) 294 { 295 char **lines, *temp; 346 296 int i; 347 297 348 if( irc->readbuffer != NULL ) 349 { 350 lines = irc_tokenize( irc->readbuffer ); 351 352 for( i = 0; *lines[i] != '\0'; i ++ ) 353 { 354 if( lines[i+1] == NULL ) 355 { 298 if( irc->readbuffer != NULL ) { 299 lines = irc_tokenize(irc->readbuffer ); 300 for( i = 0; *lines[i] != '\0'; i++ ) { 301 if( lines[i+1] == NULL ) { 356 302 temp = g_strdup( lines[i] ); 357 303 g_free( irc->readbuffer ); 358 304 irc->readbuffer = temp; 359 i 305 i++; 360 306 break; 361 307 } 362 363 if( ( cmd = irc_parse_line( lines[i] ) ) == NULL ) 364 continue; 365 irc_exec( irc, cmd ); 366 367 g_free( cmd ); 368 369 /* Shouldn't really happen, but just in case... */ 370 if( !g_slist_find( irc_connection_list, irc ) ) 371 { 308 if (!irc_process_line(irc, lines[i])) { 372 309 g_free( lines ); 373 return; 374 } 375 } 376 377 if( lines[i] != NULL ) 378 { 379 g_free( irc->readbuffer ); 380 irc->readbuffer = NULL; 381 } 382 310 return 0; 311 } 312 } 313 if(lines[i]!=NULL) { 314 g_free(irc->readbuffer); 315 irc->readbuffer=NULL; 316 } 383 317 g_free( lines ); 384 318 } 319 return 1; 385 320 } 386 321 … … 391 326 392 327 /* Count the number of elements we're gonna need. */ 393 for( i = 0, j = 1; buffer[i] != '\0'; i ++ ) 394 { 395 if( buffer[i] == '\n' ) 396 if( buffer[i+1] != '\r' && buffer[i+1] != '\n' ) 397 j ++; 328 for(i=0, j=1; buffer[i]!='\0'; i++ ) { 329 if(buffer[i]=='\n' ) 330 if(buffer[i+1]!='\r' && buffer[i+1]!='\n') 331 j++; 398 332 } 399 333 400 334 /* Allocate j+1 elements. */ 401 lines = g_new( char *, j + 1);335 lines=g_new (char *, j+1); 402 336 403 337 /* NULL terminate our list. */ 404 lines[j] =NULL;405 406 lines[0] =buffer;338 lines[j]=NULL; 339 340 lines[0]=buffer; 407 341 408 342 /* Split the buffer in several strings, using \r\n as our seperator, where \r is optional. 409 343 * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too. 410 344 */ 411 for( i = 0, j = 0; buffer[i] != '\0'; i ++) 412 { 413 if( buffer[i] == '\n' ) 414 { 415 buffer[i] = '\0'; 416 417 if( i > 0 && buffer[i-1] == '\r' ) 418 buffer[i-1] = '\0'; 419 if( buffer[i+1] != '\r' && buffer[i+1] != '\n' ) 420 lines[++j] = buffer + i + 1; 421 } 422 } 423 424 return( lines ); 425 } 426 427 char **irc_parse_line( char *line ) 345 for( i=0, j=0; buffer[i]!='\0'; i++) { 346 if(buffer[i]=='\n') { 347 buffer[i]='\0'; 348 349 /* We dont want to read 1 byte before our buffer 350 * and (in rare cases) generate a SIGSEGV. 351 */ 352 if(i!=0) 353 if(buffer[i-1]=='\r') 354 buffer[i-1]='\0'; 355 if(buffer[i+1]!='\r'&&buffer[i+1]!='\n') 356 lines[++j]=buffer+i+1; 357 } 358 } 359 360 return(lines); 361 } 362 363 int irc_process_line( irc_t *irc, char *line ) 428 364 { 429 365 int i, j; … … 431 367 432 368 /* Move the line pointer to the start of the command, skipping spaces and the optional prefix. */ 433 if( line[0] == ':' ) 434 { 435 for( i = 0; line[i] != ' '; i ++ ); 436 line = line + i; 437 } 438 for( i = 0; line[i] == ' '; i ++ ); 439 line = line + i; 440 369 if(line[0]==':') { 370 for(i=0; line[i]!=32; i++); 371 line=line+i; 372 } 373 for(i=0; line[i]==32; i++); 374 line=line+i; 375 441 376 /* If we're already at the end of the line, return. If not, we're going to need at least one element. */ 442 if( line[0] == '\0') 443 return NULL; 444 445 /* Count the number of char **cmd elements we're going to need. */ 446 j = 1; 447 for( i = 0; line[i] != '\0'; i ++ ) 448 { 449 if( line[i] == ' ' ) 450 { 451 j ++; 377 if(line[0]=='\0') 378 return 1; 379 else 380 j=1; 381 382 /* Count the number of char **cmd elements we're going to need. */ 383 for(i=0; line[i]!='\0'; i++) { 384 if((line[i]==32) && (line[i+1]!=32) && (line[i+1]!='\0') && (line[i+1]!=':')) 385 j++; 386 else if((line[i]==':') && (line[i+1]!='\0') && (line[i-1]==32)) { 387 j++; 388 break; 389 } 452 390 453 if( line[i+1] == ':' )454 break;455 }456 391 } 457 392 458 393 /* Allocate the space we need. */ 459 cmd = g_new( char *, j + 1);460 cmd[j] =NULL;394 cmd=g_new(char *, j+1); 395 cmd[j]=NULL; 461 396 462 397 /* Do the actual line splitting, format is: … … 465 400 */ 466 401 467 cmd[0] = line; 468 for( i = 0, j = 0; line[i] != '\0'; i ++ ) 469 { 470 if( line[i] == ' ' ) 471 { 472 line[i] = '\0'; 473 cmd[++j] = line + i + 1; 402 cmd[0]=line; 403 for(i=0, j=0; line[i]!='\0'; i++) { 404 if((line[i]==32)) { 405 line[i]='\0'; 406 if((line[i+1]!=32) && (line[i+1]!='\0') && (line[i+1]!=':')) 407 cmd[++j]=line+i+1; 408 } 409 else if((line[i]==':') && (line[i+1]!='\0') && (line[i-1]=='\0')) { 410 cmd[++j]=line+i+1; 411 break; 412 } 413 } 414 415 i=irc_exec(irc, cmd); 416 g_free(cmd); 417 418 return(i); 419 } 420 421 int irc_exec( irc_t *irc, char **cmd ) 422 { 423 int i; 424 425 if( (global.conf)->authmode == AUTHMODE_CLOSED && irc->status < USTATUS_AUTHORIZED ) 426 { 427 if( g_strcasecmp( cmd[0], "PASS" ) == 0 ) 428 { 429 if( !cmd[1] ) 430 { 431 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 432 } 433 else if( strcmp( cmd[1], (global.conf)->auth_pass ) == 0 ) 434 { 435 irc->status = USTATUS_AUTHORIZED; 436 } 437 else 438 { 439 irc_reply( irc, 464, ":Nope, maybe you should try it again..." ); 440 } 441 } 442 else 443 { 444 irc_reply( irc, 464, ":Uhh, fine, but I want the password first." ); 445 } 446 447 return( 1 ); 448 } 449 450 if( g_strcasecmp( cmd[0], "USER" ) == 0 ) 451 { 452 if( !( cmd[1] && cmd[2] && cmd[3] && cmd[4] ) ) 453 { 454 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 455 } 456 else if( irc->user ) 457 { 458 irc_reply( irc, 462, ":You can't change your nick/userinfo" ); 459 } 460 else 461 { 462 irc->user = g_strdup( cmd[1] ); 463 irc->realname = g_strdup( cmd[4] ); 464 if( irc->nick ) irc_login( irc ); 465 } 466 return( 1 ); 467 } 468 else if( g_strcasecmp( cmd[0], "NICK" ) == 0 ) 469 { 470 if( !cmd[1] ) 471 { 472 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 473 } 474 else if( irc->nick ) 475 { 476 irc_reply( irc, 438, ":The hand of the deity is upon thee, thy nick may not change" ); 477 } 478 /* This is not clean, but for now it'll have to be like this... */ 479 else if( ( nick_cmp( cmd[1], irc->mynick ) == 0 ) || ( nick_cmp( cmd[1], NS_NICK ) == 0 ) ) 480 { 481 irc_reply( irc, 433, ":This nick is already in use" ); 482 } 483 else if( !nick_ok( cmd[1] ) ) 484 { 485 /* [SH] Invalid characters. */ 486 irc_reply( irc, 432, ":This nick contains invalid characters" ); 487 } 488 else 489 { 490 irc->nick = g_strdup( cmd[1] ); 491 if( irc->user ) irc_login( irc ); 492 } 493 return( 1 ); 494 } 495 else if( g_strcasecmp( cmd[0], "QUIT" ) == 0 ) 496 { 497 irc_write( irc, "ERROR :%s%s", cmd[1]?"Quit: ":"", cmd[1]?cmd[1]:"Client Quit" ); 498 g_io_channel_close( irc->io_channel ); 499 return( 0 ); 500 } 501 502 if( !irc->user || !irc->nick ) 503 { 504 irc_reply( irc, 451, ":Register first" ); 505 return( 1 ); 506 } 507 508 if( g_strcasecmp( cmd[0], "PING" ) == 0 ) 509 { 510 irc_write( irc, ":%s PONG %s :%s", irc->myhost, irc->myhost, cmd[1]?cmd[1]:irc->myhost ); 511 } 512 else if( g_strcasecmp( cmd[0], "OPER" ) == 0 ) 513 { 514 if( !cmd[2] ) 515 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 516 else if( strcmp( cmd[2], global.conf->oper_pass ) == 0 ) 517 irc_umode_set( irc, "+o", 1 ); 518 // else 519 /* FIXME/TODO: Find out which reply to send now. */ 520 } 521 else if( g_strcasecmp( cmd[0], "MODE" ) == 0 ) 522 { 523 if( !cmd[1] ) 524 { 525 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 526 } 527 else if( *cmd[1] == '#' || *cmd[1] == '&' ) 528 { 529 if( cmd[2] ) 530 { 531 if( *cmd[2] == '+' || *cmd[2] == '-' ) 532 irc_reply( irc, 477, "%s :Can't change channel modes", cmd[1] ); 533 else if( *cmd[2] == 'b' ) 534 irc_reply( irc, 368, "%s :No bans possible", cmd[1] ); 535 } 536 else 537 irc_reply( irc, 324, "%s +%s", cmd[1], CMODE ); 538 } 539 else 540 { 541 if( nick_cmp( cmd[1], irc->nick ) == 0 ) 542 { 543 if( cmd[2] ) 544 irc_umode_set( irc, cmd[2], 0 ); 545 } 546 else 547 irc_reply( irc, 502, ":Don't touch their modes" ); 548 } 549 } 550 else if( g_strcasecmp( cmd[0], "NAMES" ) == 0 ) 551 { 552 irc_names( irc, cmd[1]?cmd[1]:irc->channel ); 553 } 554 else if( g_strcasecmp( cmd[0], "PART" ) == 0 ) 555 { 556 struct conversation *c; 557 558 if( !cmd[1] ) 559 { 560 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 561 } 562 else if( g_strcasecmp( cmd[1], irc->channel ) == 0 ) 563 { 564 user_t *u = user_find( irc, irc->nick ); 474 565 475 if( line[i+1] == ':' ) 476 { 477 cmd[j] ++; 566 /* Not allowed to leave control channel */ 567 irc_part( irc, u, irc->channel ); 568 irc_join( irc, u, irc->channel ); 569 } 570 else if( ( c = conv_findchannel( cmd[1] ) ) ) 571 { 572 user_t *u = user_find( irc, irc->nick ); 573 574 irc_part( irc, u, c->channel ); 575 576 if( c->gc && c->gc->prpl ) 577 { 578 c->joined = 0; 579 c->gc->prpl->chat_leave( c->gc, c->id ); 580 } 581 } 582 else 583 { 584 irc_reply( irc, 403, "%s :No such channel", cmd[1] ); 585 } 586 } 587 else if( g_strcasecmp( cmd[0], "JOIN" ) == 0 ) 588 { 589 if( !cmd[1] ) 590 { 591 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 592 } 593 else if( g_strcasecmp( cmd[1], irc->channel ) == 0 ) 594 ; /* Dude, you're already there... 595 RFC doesn't have any reply for that though? */ 596 else if( cmd[1] ) 597 { 598 if( ( cmd[1][0] == '#' || cmd[1][0] == '&' ) && cmd[1][1] ) 599 { 600 user_t *u = user_find( irc, cmd[1] + 1 ); 601 602 if( u && u->gc && u->gc->prpl && u->gc->prpl->chat_open ) 603 { 604 irc_reply( irc, 403, "%s :Initializing groupchat in a different channel", cmd[1] ); 605 606 if( !u->gc->prpl->chat_open( u->gc, u->handle ) ) 607 { 608 irc_usermsg( irc, "Could not open a groupchat with %s, maybe you don't have a connection to him/her yet?", u->nick ); 609 } 610 } 611 else 612 { 613 irc_reply( irc, 403, "%s :Groupchats are not possible with %s", cmd[1], cmd[1]+1 ); 614 } 615 } 616 else 617 { 618 irc_reply( irc, 403, "%s :No such channel", cmd[1] ); 619 } 620 } 621 } 622 else if( g_strcasecmp( cmd[0], "INVITE" ) == 0 ) 623 { 624 if( cmd[1] && cmd[2] ) 625 irc_invite( irc, cmd[1], cmd[2] ); 626 else 627 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 628 } 629 else if( g_strcasecmp( cmd[0], "PRIVMSG" ) == 0 || g_strcasecmp( cmd[0], "NOTICE" ) == 0 ) 630 { 631 if( !cmd[1] ) 632 { 633 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 634 } 635 else if ( !cmd[2] ) 636 { 637 irc_reply( irc, 412, ":No text to send" ); 638 } 639 else if ( irc->nick && g_strcasecmp( cmd[1], irc->nick ) == 0 ) 640 { 641 irc_write( irc, ":%s!%s@%s %s %s :%s", irc->nick, irc->user, irc->host, cmd[0], cmd[1], cmd[2] ); 642 } 643 else 644 { 645 if( g_strcasecmp( cmd[1], irc->channel ) == 0 ) 646 { 647 unsigned int i; 648 char *t = set_getstr( irc, "default_target" ); 649 650 if( g_strcasecmp( t, "last" ) == 0 && irc->last_target ) 651 cmd[1] = irc->last_target; 652 else if( g_strcasecmp( t, "root" ) == 0 ) 653 cmd[1] = irc->mynick; 654 655 for( i = 0; i < strlen( cmd[2] ); i ++ ) 656 { 657 if( cmd[2][i] == ' ' ) break; 658 if( cmd[2][i] == ':' || cmd[2][i] == ',' ) 659 { 660 cmd[1] = cmd[2]; 661 cmd[2] += i; 662 *cmd[2] = 0; 663 while( *(++cmd[2]) == ' ' ); 664 break; 665 } 666 } 667 668 irc->is_private = 0; 669 670 if( cmd[1] != irc->last_target ) 671 { 672 if( irc->last_target ) 673 g_free( irc->last_target ); 674 irc->last_target = g_strdup( cmd[1] ); 675 } 676 } 677 else 678 { 679 irc->is_private = 1; 680 } 681 irc_send( irc, cmd[1], cmd[2], ( g_strcasecmp( cmd[0], "NOTICE" ) == 0 ) ? IM_FLAG_AWAY : 0 ); 682 } 683 } 684 else if( g_strcasecmp( cmd[0], "WHO" ) == 0 ) 685 { 686 irc_who( irc, cmd[1] ); 687 } 688 else if( g_strcasecmp( cmd[0], "USERHOST" ) == 0 ) 689 { 690 user_t *u; 691 692 if( !cmd[1] ) 693 { 694 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 695 } 696 /* [TV] Usable USERHOST-implementation according to 697 RFC1459. Without this, mIRC shows an error 698 while connecting, and the used way of rejecting 699 breaks standards. 700 */ 701 702 for( i = 1; cmd[i]; i ++ ) 703 if( ( u = user_find( irc, cmd[i] ) ) ) 704 { 705 if( u->online && u->away ) 706 irc_reply( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host ); 707 else 708 irc_reply( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host ); 709 } 710 } 711 else if( g_strcasecmp( cmd[0], "ISON" ) == 0 ) 712 { 713 user_t *u; 714 char buff[IRC_MAX_LINE]; 715 int lenleft; 716 717 buff[0] = '\0'; 718 719 /* [SH] Leave room for : and \0 */ 720 lenleft = IRC_MAX_LINE - 2; 721 722 for( i = 1; cmd[i]; i ++ ) 723 { 724 if( ( u = user_find( irc, cmd[i] ) ) && u->online ) 725 { 726 /* [SH] Make sure we don't use too much buffer space. */ 727 lenleft -= strlen( u->nick ) + 1; 728 729 if( lenleft < 0 ) 730 { 731 break; 732 } 733 734 /* [SH] Add the nick to the buffer. Note 735 * that an extra space is always added. Even 736 * if it's the last nick in the list. Who 737 * cares? 738 */ 739 740 strcat( buff, u->nick ); 741 strcat( buff, " " ); 742 } 743 } 744 745 /* [WvG] Well, maybe someone cares, so why not remove it? */ 746 if( strlen( buff ) > 0 ) 747 buff[strlen(buff)-1] = '\0'; 748 749 /* [SH] By the way, that really *was* WvG talking. */ 750 /* [WvG] Really? */ 751 /* [SH] Yeah... But *this* is WvG talking too. ;-P */ 752 /* [WvG] *sigh* */ 753 754 irc_reply( irc, 303, ":%s", buff ); 755 } 756 else if( g_strcasecmp( cmd[0], "WATCH" ) == 0 ) 757 { 758 /* Obviously we could also mark a user structure as being 759 watched, but what if the WATCH command is sent right 760 after connecting? The user won't exist yet then... */ 761 for( i = 1; cmd[i]; i ++ ) 762 { 763 char *nick; 764 user_t *u; 765 766 if( !cmd[i][0] || !cmd[i][1] ) 478 767 break; 479 } 480 } 481 } 482 483 return cmd; 484 } 485 486 char *irc_build_line( char **cmd ) 487 { 488 int i, len; 489 char *s; 490 491 if( cmd[0] == NULL ) 492 return NULL; 493 494 len = 1; 495 for( i = 0; cmd[i]; i ++ ) 496 len += strlen( cmd[i] ) + 1; 497 498 if( strchr( cmd[i-1], ' ' ) != NULL ) 499 len ++; 500 501 s = g_new0( char, len + 1 ); 502 for( i = 0; cmd[i]; i ++ ) 503 { 504 if( cmd[i+1] == NULL && strchr( cmd[i], ' ' ) != NULL ) 505 strcat( s, ":" ); 506 507 strcat( s, cmd[i] ); 508 509 if( cmd[i+1] ) 510 strcat( s, " " ); 511 } 512 strcat( s, "\r\n" ); 513 514 return s; 768 769 nick = g_strdup( cmd[i] + 1 ); 770 nick_lc( nick ); 771 772 u = user_find( irc, nick ); 773 774 if( cmd[i][0] == '+' ) 775 { 776 if( !g_hash_table_lookup( irc->watches, nick ) ) 777 g_hash_table_insert( irc->watches, nick, nick ); 778 779 if( u && u->online ) 780 irc_reply( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, time( NULL ), "is online" ); 781 else 782 irc_reply( irc, 605, "%s %s %s %d :%s", nick, "*", "*", time( NULL ), "is offline" ); 783 } 784 else if( cmd[i][0] == '-' ) 785 { 786 gpointer okey, ovalue; 787 788 if( g_hash_table_lookup_extended( irc->watches, nick, &okey, &ovalue ) ) 789 { 790 g_free( okey ); 791 g_hash_table_remove( irc->watches, okey ); 792 793 irc_reply( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" ); 794 } 795 } 796 } 797 } 798 else if( g_strcasecmp( cmd[0], "TOPIC" ) == 0 ) 799 { 800 if( cmd[1] && cmd[2] ) 801 irc_reply( irc, 482, "%s :Cannot change topic", cmd[1] ); 802 else if( cmd[1] ) 803 irc_topic( irc, cmd[1] ); 804 else 805 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 806 } 807 else if( g_strcasecmp( cmd[0], "AWAY" ) == 0 ) 808 { 809 irc_away( irc, cmd[1] ); 810 } 811 else if( g_strcasecmp( cmd[0], "WHOIS" ) == 0 ) 812 { 813 if( cmd[1] ) 814 { 815 irc_whois( irc, cmd[1] ); 816 } 817 else 818 { 819 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 820 } 821 } 822 else if( g_strcasecmp( cmd[0], "WHOWAS" ) == 0 ) 823 { 824 /* For some reason irssi tries a whowas when whois fails. We can 825 ignore this, but then the user never gets a "user not found" 826 message from irssi which is a bit annoying. So just respond 827 with not-found and irssi users will get better error messages */ 828 829 if( cmd[1] ) 830 { 831 irc_reply( irc, 406, "%s :Nick does not exist", cmd[1] ); 832 irc_reply( irc, 369, "%s :End of WHOWAS", cmd[1] ); 833 } 834 else 835 { 836 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 837 } 838 } 839 else if( ( g_strcasecmp( cmd[0], "NICKSERV" ) == 0 ) || ( g_strcasecmp( cmd[0], "NS" ) == 0 ) ) 840 { 841 /* [SH] This aliases the NickServ command to PRIVMSG root */ 842 /* [TV] This aliases the NS command to PRIVMSG root as well */ 843 root_command( irc, cmd + 1 ); 844 } 845 else if( g_strcasecmp( cmd[0], "MOTD" ) == 0 ) 846 { 847 irc_motd( irc ); 848 } 849 else if( g_strcasecmp( cmd[0], "PONG" ) == 0 ) 850 { 851 /* We could check the value we get back from the user, but in 852 fact we don't care, we're just happy he's still alive. */ 853 irc->last_pong = gettime(); 854 irc->pinging = 0; 855 } 856 else if( g_strcasecmp( cmd[0], "COMPLETIONS" ) == 0 ) 857 { 858 user_t *u = user_find( irc, irc->mynick ); 859 help_t *h; 860 set_t *s; 861 int i; 862 863 irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "OK" ); 864 865 for( i = 0; commands[i].command; i ++ ) 866 irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", commands[i].command ); 867 868 for( h = global.help; h; h = h->next ) 869 irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS help ", h->string ); 870 871 for( s = irc->set; s; s = s->next ) 872 irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS set ", s->key ); 873 874 irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "END" ); 875 } 876 else if( set_getint( irc, "debug" ) ) 877 { 878 irc_usermsg( irc, "\002--- Unknown command:" ); 879 for( i = 0; cmd[i]; i ++ ) irc_usermsg( irc, "%s", cmd[i] ); 880 irc_usermsg( irc, "\002--------------------" ); 881 } 882 883 return( 1 ); 515 884 } 516 885 … … 671 1040 } 672 1041 673 int irc_check_login( irc_t *irc ) 674 { 675 if( irc->user && irc->nick ) 676 { 677 if( global.conf->authmode == AUTHMODE_CLOSED && irc->status < USTATUS_AUTHORIZED ) 678 { 679 irc_reply( irc, 464, ":This server is password-protected." ); 680 return 0; 681 } 682 else 683 { 684 irc_login( irc ); 685 return 1; 686 } 687 } 688 else 689 { 690 /* More information needed. */ 691 return 0; 692 } 1042 void irc_who( irc_t *irc, char *channel ) 1043 { 1044 user_t *u = irc->users; 1045 struct conversation *c; 1046 GList *l; 1047 1048 if( !channel || *channel == '0' || *channel == '*' || !*channel ) 1049 while( u ) 1050 { 1051 irc_reply( irc, 352, "%s %s %s %s %s %c :0 %s", u->online ? irc->channel : "*", u->user, u->host, irc->myhost, u->nick, u->online ? ( u->away ? 'G' : 'H' ) : 'G', u->realname ); 1052 u = u->next; 1053 } 1054 else if( g_strcasecmp( channel, irc->channel ) == 0 ) 1055 while( u ) 1056 { 1057 if( u->online ) 1058 irc_reply( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->away ? 'G' : 'H', u->realname ); 1059 u = u->next; 1060 } 1061 else if( ( c = conv_findchannel( channel ) ) ) 1062 for( l = c->in_room; l; l = l->next ) 1063 { 1064 if( ( u = user_findhandle( c->gc, l->data ) ) ) 1065 irc_reply( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->away ? 'G' : 'H', u->realname ); 1066 } 1067 else if( ( u = user_find( irc, channel ) ) ) 1068 irc_reply( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->online ? ( u->away ? 'G' : 'H' ) : 'G', u->realname ); 1069 1070 irc_reply( irc, 315, "%s :End of /WHO list.", channel?channel:"**" ); 693 1071 } 694 1072 … … 725 1103 u->realname = g_strdup( irc->realname ); 726 1104 u->online = 1; 1105 // u->send_handler = msg_echo; 727 1106 irc_spawn( irc, u ); 728 1107 729 1108 irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\nIf you've never used BitlBee before, please do read the help information using the \x02help\x02 command. Lots of FAQ's are answered there." ); 730 731 if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON )732 ipc_to_master_str( "CLIENT %s %s :%s\r\n", irc->host, irc->nick, irc->realname );733 1109 734 1110 irc->status = USTATUS_LOGGED_IN; … … 783 1159 } 784 1160 irc_reply( irc, 376, ":End of MOTD" ); 785 close ( fd );1161 closesocket( fd ); 786 1162 } 787 1163 } … … 804 1180 } 805 1181 1182 void irc_whois( irc_t *irc, char *nick ) 1183 { 1184 user_t *u = user_find( irc, nick ); 1185 1186 if( u ) 1187 { 1188 irc_reply( irc, 311, "%s %s %s * :%s", u->nick, u->user, u->host, u->realname ); 1189 1190 if( u->gc ) 1191 irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->gc->user->username, 1192 *u->gc->user->proto_opt[0] ? u->gc->user->proto_opt[0] : "", u->gc->prpl->name ); 1193 else 1194 irc_reply( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO ); 1195 1196 if( !u->online ) 1197 irc_reply( irc, 301, "%s :%s", u->nick, "User is offline" ); 1198 else if( u->away ) 1199 irc_reply( irc, 301, "%s :%s", u->nick, u->away ); 1200 1201 irc_reply( irc, 318, "%s :End of /WHOIS list", nick ); 1202 } 1203 else 1204 { 1205 irc_reply( irc, 401, "%s :Nick does not exist", nick ); 1206 } 1207 } 1208 1209 806 1210 void irc_umode_set( irc_t *irc, char *s, int allow_priv ) 807 1211 { … … 833 1237 } 834 1238 1239 int irc_away( irc_t *irc, char *away ) 1240 { 1241 user_t *u = user_find( irc, irc->nick ); 1242 GSList *c = get_connections(); 1243 1244 if( !u ) return( 0 ); 1245 1246 if( away && *away ) 1247 { 1248 int i, j; 1249 1250 /* Copy away string, but skip control chars. Mainly because 1251 Jabber really doesn't like them. */ 1252 u->away = g_malloc( strlen( away ) + 1 ); 1253 for( i = j = 0; away[i]; i ++ ) 1254 if( ( u->away[j] = away[i] ) >= ' ' ) 1255 j ++; 1256 u->away[j] = 0; 1257 1258 irc_reply( irc, 306, ":You're now away: %s", u->away ); 1259 /* irc_umode_set( irc, irc->myhost, "+a" ); */ 1260 } 1261 else 1262 { 1263 if( u->away ) g_free( u->away ); 1264 u->away = NULL; 1265 /* irc_umode_set( irc, irc->myhost, "-a" ); */ 1266 irc_reply( irc, 305, ":Welcome back" ); 1267 } 1268 1269 while( c ) 1270 { 1271 if( ((struct gaim_connection *)c->data)->flags & OPT_LOGGED_IN ) 1272 proto_away( c->data, u->away ); 1273 1274 c = c->next; 1275 } 1276 1277 return( 1 ); 1278 } 1279 835 1280 void irc_spawn( irc_t *irc, user_t *u ) 836 1281 { … … 884 1329 } 885 1330 g_free( nick ); 1331 } 1332 1333 void irc_invite( irc_t *irc, char *nick, char *channel ) 1334 { 1335 struct conversation *c = conv_findchannel( channel ); 1336 user_t *u = user_find( irc, nick ); 1337 1338 if( u && c && ( u->gc == c->gc ) ) 1339 if( c->gc && c->gc->prpl && c->gc->prpl->chat_invite ) 1340 { 1341 c->gc->prpl->chat_invite( c->gc, c->id, "", u->handle ); 1342 irc_reply( irc, 341, "%s %s", nick, channel ); 1343 return; 1344 } 1345 1346 irc_reply( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel ); 886 1347 } 887 1348 … … 974 1435 975 1436 if( u->send_handler ) 976 { 977 u->send_handler( irc, u, s, flags ); 978 return 1; 979 } 1437 return( u->send_handler( irc, u, s, flags ) ); 980 1438 } 981 1439 else if( c && c->gc && c->gc->prpl ) … … 1003 1461 } 1004 1462 1005 voidbuddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags )1006 { 1007 if( !u || !u->gc ) return ;1463 int buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ) 1464 { 1465 if( !u || !u->gc ) return( 0 ); 1008 1466 1009 1467 if( set_getint( irc, "buddy_sendbuffer" ) && set_getint( irc, "buddy_sendbuffer_delay" ) > 0 ) … … 1041 1499 g_source_remove( u->sendbuf_timer ); 1042 1500 u->sendbuf_timer = g_timeout_add( delay, buddy_send_handler_delayed, u ); 1501 1502 return( 1 ); 1043 1503 } 1044 1504 else 1045 1505 { 1046 serv_send_im( irc, u, msg, flags);1506 return( serv_send_im( irc, u, msg, flags ) ); 1047 1507 } 1048 1508 } … … 1149 1609 if( rv > 0 ) 1150 1610 { 1151 irc_abort( irc, 0, "Ping Timeout: %d seconds", rv ); 1611 irc_write( irc, "ERROR :Closing Link: Ping Timeout: %d seconds", rv ); 1612 irc_free( irc ); 1152 1613 return FALSE; 1153 1614 } -
irc.h
ra4dc9f7 r8e419cb 33 33 #define IRC_PING_STRING "PinglBee" 34 34 35 #define UMODES "ias w"35 #define UMODES "ias" 36 36 #define UMODES_PRIV "Ro" 37 37 #define CMODES "nt" … … 41 41 typedef enum 42 42 { 43 USTATUS_OFFLINE = 0,43 USTATUS_OFFLINE, 44 44 USTATUS_AUTHORIZED, 45 45 USTATUS_LOGGED_IN, 46 USTATUS_IDENTIFIED, 47 USTATUS_SHUTDOWN = -1 46 USTATUS_IDENTIFIED 48 47 } irc_status_t; 49 48 … … 105 104 106 105 irc_t *irc_new( int fd ); 107 void irc_abort( irc_t *irc, int immed, char *format, ... );108 106 void irc_free( irc_t *irc ); 109 107 110 void irc_exec( irc_t *irc, char **cmd ); 111 void irc_process( irc_t *irc ); 112 char **irc_parse_line( char *line ); 113 char *irc_build_line( char **cmd ); 108 int irc_exec( irc_t *irc, char **cmd ); 109 int irc_process( irc_t *irc ); 110 int irc_process_line( irc_t *irc, char *line ); 114 111 115 112 void irc_vawrite( irc_t *irc, char *format, va_list params ); … … 121 118 122 119 void irc_login( irc_t *irc ); 123 int irc_check_login( irc_t *irc );124 120 void irc_motd( irc_t *irc ); 125 121 void irc_names( irc_t *irc, char *channel ); … … 134 130 void irc_invite( irc_t *irc, char *nick, char *channel ); 135 131 void irc_whois( irc_t *irc, char *nick ); 132 int irc_away( irc_t *irc, char *away ); 136 133 void irc_setpass( irc_t *irc, const char *pass ); /* USE WITH CAUTION! */ 137 134 … … 141 138 int irc_noticefrom( irc_t *irc, char *nick, char *msg ); 142 139 143 voidbuddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags );140 int buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ); 144 141 145 142 #endif -
log.c
ra4dc9f7 r8e419cb 38 38 openlog("bitlbee", LOG_PID, LOG_DAEMON); 39 39 40 logoutput.informational =&log_null;41 logoutput.warning =&log_null;42 logoutput.error =&log_null;40 logoutput.informational=&log_null; 41 logoutput.warning=&log_null; 42 logoutput.error=&log_null; 43 43 #ifdef DEBUG 44 logoutput.debug =&log_null;44 logoutput.debug=&log_null; 45 45 #endif 46 46 … … 51 51 /* I know it's ugly, but it works and I didn't feel like messing with pointer to function pointers */ 52 52 53 if(level ==LOGLVL_INFO) {54 if(output ==LOGOUTPUT_NULL)55 logoutput.informational =&log_null;56 else if(output ==LOGOUTPUT_IRC)57 logoutput.informational =&log_irc;58 else if(output ==LOGOUTPUT_SYSLOG)59 logoutput.informational =&log_syslog;60 else if(output ==LOGOUTPUT_CONSOLE)61 logoutput.informational =&log_console;53 if(level==LOGLVL_INFO) { 54 if(output==LOGOUTPUT_NULL) 55 logoutput.informational=&log_null; 56 else if(output==LOGOUTPUT_IRC) 57 logoutput.informational=&log_irc; 58 else if(output==LOGOUTPUT_SYSLOG) 59 logoutput.informational=&log_syslog; 60 else if(output==LOGOUTPUT_CONSOLE) 61 logoutput.informational=&log_console; 62 62 } 63 else if(level ==LOGLVL_WARNING) {64 if(output ==LOGOUTPUT_NULL)65 logoutput.warning =&log_null;66 else if(output ==LOGOUTPUT_IRC)67 logoutput.warning =&log_irc;68 else if(output ==LOGOUTPUT_SYSLOG)69 logoutput.warning =&log_syslog;70 else if(output ==LOGOUTPUT_CONSOLE)71 logoutput.warning =&log_console;63 else if(level==LOGLVL_WARNING) { 64 if(output==LOGOUTPUT_NULL) 65 logoutput.warning=&log_null; 66 else if(output==LOGOUTPUT_IRC) 67 logoutput.warning=&log_irc; 68 else if(output==LOGOUTPUT_SYSLOG) 69 logoutput.warning=&log_syslog; 70 else if(output==LOGOUTPUT_CONSOLE) 71 logoutput.warning=&log_console; 72 72 } 73 else if(level ==LOGLVL_ERROR) {74 if(output ==LOGOUTPUT_NULL)75 logoutput.error =&log_null;76 else if(output ==LOGOUTPUT_IRC)77 logoutput.error =&log_irc;78 else if(output ==LOGOUTPUT_SYSLOG)79 logoutput.error =&log_syslog;80 else if(output ==LOGOUTPUT_CONSOLE)81 logoutput.error =&log_console;73 else if(level==LOGLVL_ERROR) { 74 if(output==LOGOUTPUT_NULL) 75 logoutput.error=&log_null; 76 else if(output==LOGOUTPUT_IRC) 77 logoutput.error=&log_irc; 78 else if(output==LOGOUTPUT_SYSLOG) 79 logoutput.error=&log_syslog; 80 else if(output==LOGOUTPUT_CONSOLE) 81 logoutput.error=&log_console; 82 82 } 83 83 #ifdef DEBUG 84 else if(level ==LOGLVL_DEBUG) {85 if(output ==LOGOUTPUT_NULL)86 logoutput.debug =&log_null;87 else if(output ==LOGOUTPUT_IRC)88 logoutput.debug =&log_irc;89 else if(output ==LOGOUTPUT_SYSLOG)90 logoutput.debug =&log_syslog;91 else if(output ==LOGOUTPUT_CONSOLE)92 logoutput.debug =&log_console;84 else if(level==LOGLVL_DEBUG) { 85 if(output==LOGOUTPUT_NULL) 86 logoutput.debug=&log_null; 87 else if(output==LOGOUTPUT_IRC) 88 logoutput.debug=&log_irc; 89 else if(output==LOGOUTPUT_SYSLOG) 90 logoutput.debug=&log_syslog; 91 else if(output==LOGOUTPUT_CONSOLE) 92 logoutput.debug=&log_console; 93 93 } 94 94 #endif … … 106 106 va_end(ap); 107 107 108 if(level ==LOGLVL_INFO)108 if(level==LOGLVL_INFO) 109 109 (*(logoutput.informational))(level, msgstring); 110 if(level ==LOGLVL_WARNING)110 if(level==LOGLVL_WARNING) 111 111 (*(logoutput.warning))(level, msgstring); 112 if(level ==LOGLVL_ERROR)112 if(level==LOGLVL_ERROR) 113 113 (*(logoutput.error))(level, msgstring); 114 114 #ifdef DEBUG 115 if(level ==LOGLVL_DEBUG)115 if(level==LOGLVL_DEBUG) 116 116 (*(logoutput.debug))(level, msgstring); 117 117 #endif … … 133 133 134 134 static void log_irc(int level, char *message) { 135 if(level ==LOGLVL_ERROR)135 if(level==LOGLVL_ERROR) 136 136 irc_write_all(1, "ERROR :Error: %s", message); 137 if(level ==LOGLVL_WARNING)137 if(level==LOGLVL_WARNING) 138 138 irc_write_all(0, "ERROR :Warning: %s", message); 139 if(level ==LOGLVL_INFO)139 if(level==LOGLVL_INFO) 140 140 irc_write_all(0, "ERROR :Informational: %s", message); 141 141 #ifdef DEBUG 142 if(level ==LOGLVL_DEBUG)142 if(level==LOGLVL_DEBUG) 143 143 irc_write_all(0, "ERROR :Debug: %s", message); 144 144 #endif … … 148 148 149 149 static void log_syslog(int level, char *message) { 150 if(level ==LOGLVL_ERROR)150 if(level==LOGLVL_ERROR) 151 151 syslog(LOG_ERR, "%s", message); 152 if(level ==LOGLVL_WARNING)152 if(level==LOGLVL_WARNING) 153 153 syslog(LOG_WARNING, "%s", message); 154 if(level ==LOGLVL_INFO)154 if(level==LOGLVL_INFO) 155 155 syslog(LOG_INFO, "%s", message); 156 156 #ifdef DEBUG 157 if(level ==LOGLVL_DEBUG)157 if(level==LOGLVL_DEBUG) 158 158 syslog(LOG_DEBUG, "%s", message); 159 159 #endif … … 162 162 163 163 static void log_console(int level, char *message) { 164 if(level ==LOGLVL_ERROR)164 if(level==LOGLVL_ERROR) 165 165 fprintf(stderr, "Error: %s\n", message); 166 if(level ==LOGLVL_WARNING)166 if(level==LOGLVL_WARNING) 167 167 fprintf(stderr, "Warning: %s\n", message); 168 if(level ==LOGLVL_INFO)168 if(level==LOGLVL_INFO) 169 169 fprintf(stdout, "Informational: %s\n", message); 170 170 #ifdef DEBUG 171 if(level ==LOGLVL_DEBUG)171 if(level==LOGLVL_DEBUG) 172 172 fprintf(stdout, "Debug: %s\n", message); 173 173 #endif -
protocols/jabber/jabber.c
ra4dc9f7 r8e419cb 413 413 if (jd->die) 414 414 signoff(GJ_GC(gjc)); 415 } else if (len == 0 || (len < 0 && (!sockerr_again() || gjc->ssl))) {415 } else if (len < 0 || errno != EAGAIN) { 416 416 STATE_EVT(JCONN_STATE_OFF) 417 417 } -
protocols/msn/msn.c
ra4dc9f7 r8e419cb 84 84 { 85 85 m = l->data; 86 87 serv_got_crap( gc, "Warning: Closing down MSN connection with unsent message to %s, you'll have to resend it.", m->who );88 86 g_free( m->who ); 89 87 g_free( m->text ); … … 91 89 } 92 90 g_slist_free( md->msgq ); 91 92 serv_got_crap( gc, "Warning: Closing down MSN connection with unsent message(s), you'll have to resend them." ); 93 93 } 94 94 -
protocols/msn/sb.c
ra4dc9f7 r8e419cb 213 213 { 214 214 m = l->data; 215 216 215 g_free( m->who ); 217 216 g_free( m->text ); … … 220 219 g_slist_free( sb->msgq ); 221 220 222 serv_got_crap( gc, "Warning: Closing down MSN switchboard connection with " 223 "unsent message to %s, you'll have to resend it.", 224 m->who ? m->who : "(unknown)" ); 221 serv_got_crap( gc, "Warning: Closing down MSN switchboard connection with unsent message(s), you'll have to resend them." ); 225 222 } 226 223 -
protocols/oscar/oscar.c
ra4dc9f7 r8e419cb 608 608 return; 609 609 } 610 /* [WvG] Wheeeee! Who needs error checking anyway? ;-) */611 610 read(pos->fd, m, 16); 612 611 m[16] = '\0'; -
protocols/oscar/rxqueue.c
ra4dc9f7 r8e419cb 353 353 return -1; /* its a aim_conn_close()'d connection */ 354 354 355 /* KIDS, THIS IS WHAT HAPPENS IF YOU USE CODE WRITTEN FOR GUIS IN A DAEMON! 356 357 And wouldn't it make sense to return something that prevents this function 358 from being called again IMMEDIATELY (and making the program suck up all 359 CPU time)?... 360 361 if (conn->fd < 3) 355 if (conn->fd < 3) /* can happen when people abuse the interface */ 362 356 return 0; 363 */364 357 365 358 if (conn->status & AIM_CONN_STATUS_INPROGRESS) -
protocols/oscar/service.c
ra4dc9f7 r8e419cb 736 736 737 737 tlvlen = aim_addtlvtochain32(&tl, 0x0006, data); 738 739 printf("%d\n", tlvlen); 738 740 739 741 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 8))) -
protocols/ssl_openssl.c
ra4dc9f7 r8e419cb 5 5 \********************************************************************/ 6 6 7 /* SSL module - OpenTLS version */7 /* SSL module - GnuTLS version */ 8 8 9 9 /* … … 41 41 struct scd 42 42 { 43 SslInputFunction func;43 ssl_input_function func; 44 44 gpointer data; 45 45 int fd; 46 46 gboolean established; 47 47 48 int inpa; 49 int lasterr; /* Necessary for SSL_get_error */ 48 50 SSL *ssl; 49 51 SSL_CTX *ssl_ctx; … … 54 56 55 57 56 void *ssl_connect( char *host, int port, SslInputFunction func, gpointer data )58 void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data ) 57 59 { 58 60 struct scd *conn = g_new0( struct scd, 1 ); … … 93 95 } 94 96 97 static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond ); 98 95 99 static void ssl_connected( gpointer data, gint source, GaimInputCondition cond ) 96 100 { … … 98 102 99 103 if( source == -1 ) 100 goto ssl_connected_failure; 101 104 return ssl_handshake( data, -1, cond ); 105 106 /* Make it non-blocking at least during the handshake... */ 107 sock_make_nonblocking( conn->fd ); 102 108 SSL_set_fd( conn->ssl, conn->fd ); 103 109 104 if( SSL_connect( conn->ssl ) < 0 ) 105 goto ssl_connected_failure; 110 return ssl_handshake( data, source, cond ); 111 } 112 113 static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond ) 114 { 115 struct scd *conn = data; 116 int st; 117 118 if( conn->inpa != -1 ) 119 { 120 gaim_input_remove( conn->inpa ); 121 conn->inpa = -1; 122 } 123 124 if( ( st = SSL_connect( conn->ssl ) ) < 0 ) 125 { 126 conn->lasterr = SSL_get_error( conn->ssl, st ); 127 if( conn->lasterr != SSL_ERROR_WANT_READ && conn->lasterr != SSL_ERROR_WANT_WRITE ) 128 goto ssl_connected_failure; 129 130 conn->inpa = gaim_input_add( conn->fd, ssl_getdirection( conn ), ssl_handshake, data ); 131 return; 132 } 106 133 107 134 conn->established = TRUE; 135 sock_make_blocking( conn->fd ); /* For now... */ 108 136 conn->func( conn->data, conn, cond ); 109 137 return; … … 127 155 int ssl_read( void *conn, char *buf, int len ) 128 156 { 157 int st; 158 129 159 if( !((struct scd*)conn)->established ) 130 return( 0 ); 131 132 return( SSL_read( ((struct scd*)conn)->ssl, buf, len ) ); 160 { 161 ssl_errno = SSL_NOHANDSHAKE; 162 return -1; 163 } 164 165 st = SSL_read( ((struct scd*)conn)->ssl, buf, len ); 166 167 ssl_errno = SSL_OK; 168 if( st <= 0 ) 169 { 170 ((struct scd*)conn)->lasterr = SSL_get_error( ((struct scd*)conn)->ssl, st ); 171 if( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ) 172 ssl_errno = SSL_AGAIN; 173 } 174 175 return st; 133 176 } 134 177 135 178 int ssl_write( void *conn, const char *buf, int len ) 136 179 { 180 int st; 181 137 182 if( !((struct scd*)conn)->established ) 138 return( 0 ); 139 140 return( SSL_write( ((struct scd*)conn)->ssl, buf, len ) ); 183 { 184 ssl_errno = SSL_NOHANDSHAKE; 185 return -1; 186 } 187 188 st = SSL_write( ((struct scd*)conn)->ssl, buf, len ); 189 190 ssl_errno = SSL_OK; 191 if( st <= 0 ) 192 { 193 ((struct scd*)conn)->lasterr = SSL_get_error( ((struct scd*)conn)->ssl, st ); 194 if( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ) 195 ssl_errno = SSL_AGAIN; 196 } 197 198 return st; 141 199 } 142 200 … … 144 202 { 145 203 struct scd *conn = conn_; 204 205 if( conn->inpa != -1 ) 206 gaim_input_remove( conn->inpa ); 146 207 147 208 if( conn->established ) … … 159 220 return( ((struct scd*)conn)->fd ); 160 221 } 222 223 GaimInputCondition ssl_getdirection( void *conn ) 224 { 225 return( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ? GAIM_INPUT_WRITE : GAIM_INPUT_READ ); 226 } -
protocols/yahoo/Makefile
ra4dc9f7 r8e419cb 10 10 11 11 # [SH] Program variables 12 objects = yahoo.o crypt.o libyahoo2.o yahoo_fn.o yahoo_httplib.o yahoo_ util.o12 objects = yahoo.o crypt.o libyahoo2.o yahoo_fn.o yahoo_httplib.o yahoo_list.o yahoo_util.o 13 13 14 14 CFLAGS += -Wall -DSTDC_HEADERS -DHAVE_STRING_H -DHAVE_STRCHR -DHAVE_MEMCPY -DHAVE_GLIB -
protocols/yahoo/yahoo.c
ra4dc9f7 r8e419cb 189 189 { 190 190 struct byahoo_data *yd = (struct byahoo_data *) gc->proto_data; 191 191 192 192 gc->away = NULL; 193 194 if ( msg)193 194 if (msg) 195 195 { 196 196 yd->current_status = YAHOO_STATUS_CUSTOM; 197 197 gc->away = ""; 198 198 } 199 if( state)199 else if (state) 200 200 { 201 201 gc->away = ""; 202 if( g_strcasecmp( 202 if( g_strcasecmp(state, "Available" ) == 0 ) 203 203 { 204 204 yd->current_status = YAHOO_STATUS_AVAILABLE; … … 235 235 } 236 236 } 237 else if ( gc->is_idle )237 else if ( gc->is_idle ) 238 238 yd->current_status = YAHOO_STATUS_IDLE; 239 239 else 240 240 yd->current_status = YAHOO_STATUS_AVAILABLE; 241 241 242 if( yd->current_status == YAHOO_STATUS_INVISIBLE ) 243 yahoo_set_away( yd->y2_id, yd->current_status, NULL, gc->away != NULL ); 244 else 245 yahoo_set_away( yd->y2_id, yd->current_status, msg, gc->away != NULL ); 242 yahoo_set_away( yd->y2_id, yd->current_status, msg, gc->away != NULL ); 246 243 } 247 244 -
protocols/yahoo/yahoo_list.h
ra4dc9f7 r8e419cb 21 21 */ 22 22 23 /* 24 * This is a replacement for the GList. It only provides functions that 25 * we use in Ayttm. Thanks to Meredyyd from everybuddy dev for doing 26 * most of it. 27 */ 28 23 29 #ifndef __YLIST_H__ 24 30 #define __YLIST_H__ 25 31 26 /* GLib has linked list already, so I don't see why libyahoo2 has to copy this... */ 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 27 35 28 typedef GList YList; 36 typedef struct _YList { 37 struct _YList *next; 38 struct _YList *prev; 39 void *data; 40 } YList; 29 41 30 #define y_list_append g_list_append 31 #define y_list_concat g_list_concat 32 #define y_list_copy g_list_copy 33 #define y_list_empty g_list_empty 34 #define y_list_find g_list_find 35 #define y_list_find_custom g_list_find_custom 36 #define y_list_foreach g_list_foreach 37 #define y_list_free g_list_free 38 #define y_list_free_1 g_list_free_1 39 #define y_list_insert_sorted g_list_insert_sorted 40 #define y_list_length g_list_length 41 #define y_list_next g_list_next 42 #define y_list_nth g_list_nth 43 #define y_list_prepend g_list_prepend 44 #define y_list_remove g_list_remove 45 #define y_list_remove_link g_list_remove_link 46 #define y_list_singleton g_list_singleton 42 typedef int (*YListCompFunc) (const void *, const void *); 43 typedef void (*YListFunc) (void *, void *); 47 44 45 YList *y_list_append(YList * list, void *data); 46 YList *y_list_prepend(YList * list, void *data); 47 YList *y_list_remove_link(YList * list, const YList * link); 48 YList *y_list_remove(YList * list, void *data); 49 50 YList *y_list_insert_sorted(YList * list, void * data, YListCompFunc comp); 51 52 YList *y_list_copy(YList * list); 53 54 YList *y_list_concat(YList * list, YList * add); 55 56 YList *y_list_find(YList * list, const void *data); 57 YList *y_list_find_custom(YList * list, const void *data, YListCompFunc comp); 58 59 YList *y_list_nth(YList * list, int n); 60 61 void y_list_foreach(YList * list, YListFunc fn, void *user_data); 62 63 void y_list_free_1(YList * list); 64 void y_list_free(YList * list); 65 int y_list_length(const YList * list); 66 int y_list_empty(const YList * list); 67 int y_list_singleton(const YList * list); 68 69 #define y_list_next(list) list->next 70 71 #ifdef __cplusplus 72 } 48 73 #endif 74 #endif -
unix.c
ra4dc9f7 r8e419cb 29 29 #include "protocols/nogaim.h" 30 30 #include "help.h" 31 #include "ipc.h"32 31 #include <signal.h> 33 32 #include <unistd.h> … … 39 38 static void sighandler( int signal ); 40 39 41 int main( int argc, char *argv[] , char **envp)40 int main( int argc, char *argv[] ) 42 41 { 43 42 int i = 0; 44 char *old_cwd = NULL;45 43 struct sigaction sig, old; 46 44 … … 81 79 else if( global.conf->runmode == RUNMODE_FORKDAEMON ) 82 80 { 83 /* In case the operator requests a restart, we need this. */84 old_cwd = g_malloc( 256 );85 if( getcwd( old_cwd, 255 ) == NULL )86 {87 log_message( LOGLVL_WARNING, "Could not save current directory: %s", strerror( errno ) );88 g_free( old_cwd );89 old_cwd = NULL;90 }91 92 81 i = bitlbee_daemon_init(); 93 82 log_message( LOGLVL_INFO, "Bitlbee %s starting in forking daemon mode.", BITLBEE_VERSION ); … … 124 113 125 114 g_main_run( global.loop ); 126 127 if( global.restart )128 {129 char *fn = ipc_master_save_state();130 char **args;131 int n, i;132 133 chdir( old_cwd );134 135 n = 0;136 args = g_new0( char *, argc + 3 );137 args[n++] = argv[0];138 if( fn )139 {140 args[n++] = "-R";141 args[n++] = fn;142 }143 for( i = 1; argv[i] && i < argc; i ++ )144 {145 if( strcmp( argv[i], "-R" ) == 0 )146 i += 2;147 148 args[n++] = argv[i];149 }150 151 close( global.listen_socket );152 153 execve( args[0], args, envp );154 }155 115 156 116 return( 0 ); -
url.c
ra4dc9f7 r8e419cb 40 40 else 41 41 { 42 if( g_strncasecmp( set_url, "http", i - set_url ) == 0 ) 42 if( g_strncasecmp( set_url, "https", i - set_url ) == 0 ) 43 url->proto = PROTO_HTTPS; 44 else if( g_strncasecmp( set_url, "http", i - set_url ) == 0 ) 43 45 url->proto = PROTO_HTTP; 44 else if( g_strncasecmp( set_url, "https", i - set_url ) == 0 )45 url->proto = PROTO_HTTPS;46 46 else if( g_strncasecmp( set_url, "socks4", i - set_url ) == 0 ) 47 47 url->proto = PROTO_SOCKS4; -
user.h
ra4dc9f7 r8e419cb 45 45 int sendbuf_flags; 46 46 47 void(*send_handler) ( irc_t *irc, struct __USER *u, char *msg, int flags );47 int (*send_handler) ( irc_t *irc, struct __USER *u, char *msg, int flags ); 48 48 49 49 struct __USER *next;
Note: See TracChangeset
for help on using the changeset viewer.