Changeset a4dc9f7
- Timestamp:
- 2006-03-01T22:48:37Z (19 years ago)
- Branches:
- master
- Children:
- 46ad029
- Parents:
- 8e419cb (diff), 9a1555d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 4 added
- 1 deleted
- 24 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
Makefile
r8e419cb ra4dc9f7 10 10 11 11 # Program variables 12 objects = account.o bitlbee.o c ommands.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.o12 objects = account.o bitlbee.o crypting.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.o 13 13 subdirs = protocols 14 14 -
bitlbee.c
r8e419cb ra4dc9f7 29 29 #include "protocols/nogaim.h" 30 30 #include "help.h" 31 #include "ipc.h" 31 32 #include <signal.h> 32 33 #include <stdio.h> 33 34 #include <errno.h> 34 35 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 36 gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data ); 71 37 72 38 int bitlbee_daemon_init() … … 79 45 int i; 80 46 GIOChannel *ch; 47 FILE *fp; 81 48 82 49 log_link( LOGLVL_ERROR, LOGOUTPUT_SYSLOG ); … … 89 56 return( -1 ); 90 57 } 58 59 /* TIME_WAIT (?) sucks.. */ 60 i = 1; 61 setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) ); 91 62 92 63 #ifdef IPV6 … … 134 105 else if( i != 0 ) 135 106 exit( 0 ); 136 close( 0 ); 137 close( 1 ); 138 close( 2 ); 107 139 108 chdir( "/" ); 109 110 /* Sometimes std* are already closed (for example when we're in a RESTARTed 111 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 ); 140 115 } 141 116 #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 else 131 { 132 log_message( LOGLVL_WARNING, "Warning: Couldn't write PID to `%s'", global.conf->pidfile ); 133 } 142 134 143 135 return( 0 ); … … 160 152 if( condition & G_IO_ERR || condition & G_IO_HUP ) 161 153 { 162 irc_ free( irc);154 irc_abort( irc, 1, "Read error" ); 163 155 return FALSE; 164 156 } … … 167 159 if( st == 0 ) 168 160 { 169 irc_ free( irc);161 irc_abort( irc, 1, "Connection reset by peer" ); 170 162 return FALSE; 171 163 } … … 178 170 else 179 171 { 180 irc_ free( irc);172 irc_abort( irc, 1, "Read error: %s", strerror( errno ) ); 181 173 return FALSE; 182 174 } … … 194 186 } 195 187 196 if( !irc_process( irc ) ) 197 { 198 log_message( LOGLVL_INFO, "Destroying connection with fd %d.", irc->fd ); 199 irc_free( irc ); 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 ); 200 194 return FALSE; 201 195 } … … 204 198 if( irc->readbuffer && ( strlen( irc->readbuffer ) > 1024 ) ) 205 199 { 206 log_message( LOGLVL_ERROR, "Maximum line length exceeded." ); 207 irc_free( irc ); 200 irc_abort( irc, 0, "Maximum line length exceeded" ); 208 201 return FALSE; 209 202 } … … 224 217 st = write( irc->fd, irc->sendbuffer, size ); 225 218 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 } 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; 237 227 } 238 228 … … 241 231 g_free( irc->sendbuffer ); 242 232 irc->sendbuffer = NULL; 243 244 233 irc->w_watch_source_id = 0; 234 235 if( irc->status == USTATUS_SHUTDOWN ) 236 irc_free( irc ); 237 245 238 return( FALSE ); 246 239 } … … 255 248 } 256 249 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 else 315 { 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 257 323 void bitlbee_shutdown( gpointer data ) 258 324 { -
bitlbee.h
r8e419cb ra4dc9f7 109 109 #include "sock.h" 110 110 111 typedef struct global_t { 111 typedef struct global { 112 /* In forked mode, child processes store the fd of the IPC socket here. */ 112 113 int listen_socket; 113 114 gint listen_watch_source_id; … … 117 118 char *helpfile; 118 119 GMainLoop *loop; 120 int restart; 119 121 } global_t; 120 122 … … 125 127 gboolean bitlbee_io_current_client_write( GIOChannel *source, GIOCondition condition, gpointer data ); 126 128 127 introot_command_string( irc_t *irc, user_t *u, char *command, int flags );128 introot_command( irc_t *irc, char *command[] );129 void root_command_string( irc_t *irc, user_t *u, char *command, int flags ); 130 void root_command( irc_t *irc, char *command[] ); 129 131 void bitlbee_shutdown( gpointer data ); 130 132 double gettime( void ); -
commands.h
r8e419cb ra4dc9f7 29 29 #include "bitlbee.h" 30 30 31 typedef struct command _t31 typedef struct command 32 32 { 33 33 char *command; 34 34 int required_parameters; 35 int (*execute)(irc_t *, char **args); 35 void (*execute)(irc_t *, char **args); 36 int flags; 36 37 } 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 );57 38 58 39 extern const command_t commands[]; 59 40 41 #define IRC_CMD_PRE_LOGIN 1 42 #define IRC_CMD_LOGGED_IN 2 43 #define IRC_CMD_OPER_ONLY 4 44 #define IRC_CMD_TO_MASTER 8 45 46 #define IPC_CMD_TO_CHILDREN 1 47 60 48 #endif -
conf.c
r8e419cb ra4dc9f7 32 32 #include "ini.h" 33 33 #include "url.h" 34 #include "ipc.h" 34 35 35 36 #include "protocols/proxy.h" … … 61 62 conf->configdir = g_strdup( CONFIG ); 62 63 conf->plugindir = g_strdup( PLUGINDIR ); 64 conf->pidfile = g_strdup( "/var/run/bitlbee.pid" ); 63 65 conf->motdfile = g_strdup( ETCDIR "/motd.txt" ); 64 66 conf->ping_interval = 180; 65 67 conf->ping_timeout = 300; 68 proxytype = 0; 66 69 67 70 i = conf_loadini( conf, CONF_FILE ); … … 76 79 } 77 80 78 while( ( opt = getopt( argc, argv, "i:p:nvIDFc:d:h" ) ) >= 0 ) 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. */ 79 83 { 80 84 if( opt == 'i' ) … … 91 95 conf->port = i; 92 96 } 97 else if( opt == 'p' ) 98 { 99 g_free( conf->pidfile ); 100 conf->pidfile = g_strdup( optarg ); 101 } 93 102 else if( opt == 'n' ) 94 conf->nofork =1;103 conf->nofork = 1; 95 104 else if( opt == 'v' ) 96 conf->verbose =1;105 conf->verbose = 1; 97 106 else if( opt == 'I' ) 98 conf->runmode =RUNMODE_INETD;107 conf->runmode = RUNMODE_INETD; 99 108 else if( opt == 'D' ) 100 conf->runmode =RUNMODE_DAEMON;109 conf->runmode = RUNMODE_DAEMON; 101 110 else if( opt == 'F' ) 102 conf->runmode =RUNMODE_FORKDAEMON;111 conf->runmode = RUNMODE_FORKDAEMON; 103 112 else if( opt == 'c' ) 104 113 { … … 108 117 CONF_FILE = g_strdup( optarg ); 109 118 g_free( conf ); 119 /* Re-evaluate arguments. Don't use this option twice, 120 you'll end up in an infinite loop! Hope this trick 121 works with all libcs BTW.. */ 122 optind = 1; 110 123 return( conf_load( argc, argv ) ); 111 124 } … … 126 139 " -D Daemon mode. (Still EXPERIMENTAL!)\n" 127 140 " -F Forking daemon. (one process per client)\n" 141 " -P Specify PID-file (not for inetd mode)\n" 128 142 " -i Specify the interface (by IP address) to listen on.\n" 129 143 " (Default: 0.0.0.0 (any interface))\n" … … 136 150 return( NULL ); 137 151 } 152 else if( opt == 'R' ) 153 { 154 /* We can't load the statefile yet (and should make very sure we do this 155 only once), so set the filename here and load the state information 156 when initializing ForkDaemon. (This option only makes sense in that 157 mode anyway!) */ 158 ipc_master_set_statefile( optarg ); 159 } 138 160 } 139 161 … … 169 191 else 170 192 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 ); 171 198 } 172 199 else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 ) -
conf.h
r8e419cb ra4dc9f7 43 43 char *configdir; 44 44 char *plugindir; 45 char *pidfile; 45 46 char *motdfile; 46 47 char *primary_storage; -
configure
r8e419cb ra4dc9f7 14 14 datadir='$prefix/share/bitlbee/' 15 15 config='/var/lib/bitlbee/' 16 pidfile='/var/run/bitlbee.pid' 17 ipcsocket='/var/run/bitlbee' 16 18 plugindir='$prefix/lib/bitlbee' 17 19 … … 46 48 --datadir=... $datadir 47 49 --plugindir=... $plugindir 50 --pidfile=... $pidfile 48 51 --config=... $config 52 --ipcsocket=... $ipcsocket 49 53 50 54 --msn=0/1 Disable/enable MSN part $msn … … 74 78 config=`eval echo "$config/" | sed 's/\/\{1,\}/\//g'` 75 79 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'` 76 82 77 83 cat<<EOF>Makefile.settings … … 84 90 PLUGINDIR=$plugindir 85 91 CONFIG=$config 92 IPCSOCKET=$ipcsocket 86 93 87 94 ARCH=$arch … … 104 111 #define VARDIR "$datadir" 105 112 #define PLUGINDIR "$plugindir" 113 #define PIDFILE "$pidfile" 114 #define IPCSOCKET "$ipcsocket" 106 115 #define ARCH "$arch" 107 116 #define CPU "$cpu" -
doc/README
r8e419cb ra4dc9f7 50 50 51 51 These days, MSN Messenger clients have to connect to the MS Passport servers 52 through HTTPS. BitlBee can use se rveral SSL libraries for this: GnuTLS, NSS52 through HTTPS. BitlBee can use several 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
r8e419cb ra4dc9f7 27 27 #include "bitlbee.h" 28 28 #include "crypting.h" 29 #include "ipc.h" 29 30 30 31 static gboolean irc_userping( gpointer _irc ); … … 151 152 } 152 153 154 /* immed=1 makes this function pretty much equal to irc_free(), except that 155 this one will "log". In case the connection is already broken and we 156 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 else 177 { 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 timer 189 to it that should shut down the connection in a second, just in case 190 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 else 196 { 197 irc_free( irc ); 198 } 199 } 200 153 201 static gboolean irc_free_userhash( gpointer key, gpointer value, gpointer data ) 154 202 { … … 172 220 if( storage_save( irc, TRUE ) != STORAGE_OK ) 173 221 irc_usermsg( irc, "Error while saving settings!" ); 222 223 closesocket( irc->fd ); 174 224 175 225 if( irc->ping_source_id > 0 ) … … 291 341 } 292 342 293 intirc_process( irc_t *irc )294 { 295 char **lines, *temp ;343 void irc_process( irc_t *irc ) 344 { 345 char **lines, *temp, **cmd; 296 346 int i; 297 347 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 ) { 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 { 302 356 temp = g_strdup( lines[i] ); 303 357 g_free( irc->readbuffer ); 304 358 irc->readbuffer = temp; 305 i ++;359 i ++; 306 360 break; 307 361 } 308 if (!irc_process_line(irc, lines[i])) { 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 { 309 372 g_free( lines ); 310 return 0;373 return; 311 374 } 312 375 } 313 if(lines[i]!=NULL) { 314 g_free(irc->readbuffer); 315 irc->readbuffer=NULL; 316 } 376 377 if( lines[i] != NULL ) 378 { 379 g_free( irc->readbuffer ); 380 irc->readbuffer = NULL; 381 } 382 317 383 g_free( lines ); 318 384 } 319 return 1;320 385 } 321 386 … … 326 391 327 392 /* Count the number of elements we're gonna need. */ 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++; 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 ++; 332 398 } 333 399 334 400 /* Allocate j+1 elements. */ 335 lines =g_new (char *, j+1);401 lines = g_new( char *, j + 1 ); 336 402 337 403 /* NULL terminate our list. */ 338 lines[j] =NULL;339 340 lines[0] =buffer;404 lines[j] = NULL; 405 406 lines[0] = buffer; 341 407 342 408 /* Split the buffer in several strings, using \r\n as our seperator, where \r is optional. 343 409 * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too. 344 410 */ 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 ) 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 ) 364 428 { 365 429 int i, j; … … 367 431 368 432 /* Move the line pointer to the start of the command, skipping spaces and the optional prefix. */ 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 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 376 441 /* If we're already at the end of the line, return. If not, we're going to need at least one element. */ 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 } 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 ++; 390 452 453 if( line[i+1] == ':' ) 454 break; 455 } 391 456 } 392 457 393 458 /* Allocate the space we need. */ 394 cmd =g_new(char *, j+1);395 cmd[j] =NULL;459 cmd = g_new( char *, j + 1 ); 460 cmd[j] = NULL; 396 461 397 462 /* Do the actual line splitting, format is: … … 400 465 */ 401 466 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] ) 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; 474 475 if( line[i+1] == ':' ) 430 476 { 431 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 477 cmd[j] ++; 478 break; 432 479 } 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 ); 565 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] ) 767 break; 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 ); 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; 884 515 } 885 516 … … 1040 671 } 1041 672 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:"**" ); 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 } 1071 693 } 1072 694 … … 1103 725 u->realname = g_strdup( irc->realname ); 1104 726 u->online = 1; 1105 // u->send_handler = msg_echo;1106 727 irc_spawn( irc, u ); 1107 728 1108 729 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 ); 1109 733 1110 734 irc->status = USTATUS_LOGGED_IN; … … 1159 783 } 1160 784 irc_reply( irc, 376, ":End of MOTD" ); 1161 close socket( fd );785 close( fd ); 1162 786 } 1163 787 } … … 1180 804 } 1181 805 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 else1194 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 else1204 {1205 irc_reply( irc, 401, "%s :Nick does not exist", nick );1206 }1207 }1208 1209 1210 806 void irc_umode_set( irc_t *irc, char *s, int allow_priv ) 1211 807 { … … 1237 833 } 1238 834 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 because1251 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 else1262 {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 1280 835 void irc_spawn( irc_t *irc, user_t *u ) 1281 836 { … … 1329 884 } 1330 885 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 );1347 886 } 1348 887 … … 1435 974 1436 975 if( u->send_handler ) 1437 return( u->send_handler( irc, u, s, flags ) ); 976 { 977 u->send_handler( irc, u, s, flags ); 978 return 1; 979 } 1438 980 } 1439 981 else if( c && c->gc && c->gc->prpl ) … … 1461 1003 } 1462 1004 1463 intbuddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags )1464 { 1465 if( !u || !u->gc ) return ( 0 );1005 void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ) 1006 { 1007 if( !u || !u->gc ) return; 1466 1008 1467 1009 if( set_getint( irc, "buddy_sendbuffer" ) && set_getint( irc, "buddy_sendbuffer_delay" ) > 0 ) … … 1499 1041 g_source_remove( u->sendbuf_timer ); 1500 1042 u->sendbuf_timer = g_timeout_add( delay, buddy_send_handler_delayed, u ); 1501 1502 return( 1 );1503 1043 } 1504 1044 else 1505 1045 { 1506 return( serv_send_im( irc, u, msg, flags ));1046 serv_send_im( irc, u, msg, flags ); 1507 1047 } 1508 1048 } … … 1609 1149 if( rv > 0 ) 1610 1150 { 1611 irc_write( irc, "ERROR :Closing Link: Ping Timeout: %d seconds", rv ); 1612 irc_free( irc ); 1151 irc_abort( irc, 0, "Ping Timeout: %d seconds", rv ); 1613 1152 return FALSE; 1614 1153 } -
irc.h
r8e419cb ra4dc9f7 33 33 #define IRC_PING_STRING "PinglBee" 34 34 35 #define UMODES "ias "35 #define UMODES "iasw" 36 36 #define UMODES_PRIV "Ro" 37 37 #define CMODES "nt" … … 41 41 typedef enum 42 42 { 43 USTATUS_OFFLINE ,43 USTATUS_OFFLINE = 0, 44 44 USTATUS_AUTHORIZED, 45 45 USTATUS_LOGGED_IN, 46 USTATUS_IDENTIFIED 46 USTATUS_IDENTIFIED, 47 USTATUS_SHUTDOWN = -1 47 48 } irc_status_t; 48 49 … … 104 105 105 106 irc_t *irc_new( int fd ); 107 void irc_abort( irc_t *irc, int immed, char *format, ... ); 106 108 void irc_free( irc_t *irc ); 107 109 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 ); 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 ); 111 114 112 115 void irc_vawrite( irc_t *irc, char *format, va_list params ); … … 118 121 119 122 void irc_login( irc_t *irc ); 123 int irc_check_login( irc_t *irc ); 120 124 void irc_motd( irc_t *irc ); 121 125 void irc_names( irc_t *irc, char *channel ); … … 130 134 void irc_invite( irc_t *irc, char *nick, char *channel ); 131 135 void irc_whois( irc_t *irc, char *nick ); 132 int irc_away( irc_t *irc, char *away );133 136 void irc_setpass( irc_t *irc, const char *pass ); /* USE WITH CAUTION! */ 134 137 … … 138 141 int irc_noticefrom( irc_t *irc, char *nick, char *msg ); 139 142 140 intbuddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags );143 void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ); 141 144 142 145 #endif -
log.c
r8e419cb ra4dc9f7 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
r8e419cb ra4dc9f7 413 413 if (jd->die) 414 414 signoff(GJ_GC(gjc)); 415 } else if (len < 0 || errno != EAGAIN) {415 } else if (len == 0 || (len < 0 && (!sockerr_again() || gjc->ssl))) { 416 416 STATE_EVT(JCONN_STATE_OFF) 417 417 } -
protocols/msn/msn.c
r8e419cb ra4dc9f7 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 ); 86 88 g_free( m->who ); 87 89 g_free( m->text ); … … 89 91 } 90 92 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
r8e419cb ra4dc9f7 213 213 { 214 214 m = l->data; 215 215 216 g_free( m->who ); 216 217 g_free( m->text ); … … 219 220 g_slist_free( sb->msgq ); 220 221 221 serv_got_crap( gc, "Warning: Closing down MSN switchboard connection with unsent message(s), you'll have to resend them." ); 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)" ); 222 225 } 223 226 -
protocols/oscar/oscar.c
r8e419cb ra4dc9f7 608 608 return; 609 609 } 610 /* [WvG] Wheeeee! Who needs error checking anyway? ;-) */ 610 611 read(pos->fd, m, 16); 611 612 m[16] = '\0'; -
protocols/oscar/rxqueue.c
r8e419cb ra4dc9f7 353 353 return -1; /* its a aim_conn_close()'d connection */ 354 354 355 if (conn->fd < 3) /* can happen when people abuse the interface */ 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) 356 362 return 0; 363 */ 357 364 358 365 if (conn->status & AIM_CONN_STATUS_INPROGRESS) -
protocols/oscar/service.c
r8e419cb ra4dc9f7 736 736 737 737 tlvlen = aim_addtlvtochain32(&tl, 0x0006, data); 738 739 printf("%d\n", tlvlen);740 738 741 739 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 8))) -
protocols/ssl_openssl.c
r8e419cb ra4dc9f7 5 5 \********************************************************************/ 6 6 7 /* SSL module - GnuTLS version */7 /* SSL module - OpenTLS version */ 8 8 9 9 /* … … 41 41 struct scd 42 42 { 43 ssl_input_function func;43 SslInputFunction 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 */50 48 SSL *ssl; 51 49 SSL_CTX *ssl_ctx; … … 56 54 57 55 58 void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )56 void *ssl_connect( char *host, int port, SslInputFunction func, gpointer data ) 59 57 { 60 58 struct scd *conn = g_new0( struct scd, 1 ); … … 95 93 } 96 94 97 static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond );98 99 95 static void ssl_connected( gpointer data, gint source, GaimInputCondition cond ) 100 96 { … … 102 98 103 99 if( source == -1 ) 104 return ssl_handshake( data, -1, cond );100 goto ssl_connected_failure; 105 101 106 /* Make it non-blocking at least during the handshake... */107 sock_make_nonblocking( conn->fd );108 102 SSL_set_fd( conn->ssl, conn->fd ); 109 103 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 } 104 if( SSL_connect( conn->ssl ) < 0 ) 105 goto ssl_connected_failure; 133 106 134 107 conn->established = TRUE; 135 sock_make_blocking( conn->fd ); /* For now... */136 108 conn->func( conn->data, conn, cond ); 137 109 return; … … 155 127 int ssl_read( void *conn, char *buf, int len ) 156 128 { 157 int st; 129 if( !((struct scd*)conn)->established ) 130 return( 0 ); 158 131 159 if( !((struct scd*)conn)->established ) 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; 132 return( SSL_read( ((struct scd*)conn)->ssl, buf, len ) ); 176 133 } 177 134 178 135 int ssl_write( void *conn, const char *buf, int len ) 179 136 { 180 int st; 137 if( !((struct scd*)conn)->established ) 138 return( 0 ); 181 139 182 if( !((struct scd*)conn)->established ) 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; 140 return( SSL_write( ((struct scd*)conn)->ssl, buf, len ) ); 199 141 } 200 142 … … 202 144 { 203 145 struct scd *conn = conn_; 204 205 if( conn->inpa != -1 )206 gaim_input_remove( conn->inpa );207 146 208 147 if( conn->established ) … … 220 159 return( ((struct scd*)conn)->fd ); 221 160 } 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
r8e419cb ra4dc9f7 10 10 11 11 # [SH] Program variables 12 objects = yahoo.o crypt.o libyahoo2.o yahoo_fn.o yahoo_httplib.o yahoo_ list.o yahoo_util.o12 objects = yahoo.o crypt.o libyahoo2.o yahoo_fn.o yahoo_httplib.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
r8e419cb ra4dc9f7 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 else if (state)199 if( state ) 200 200 { 201 201 gc->away = ""; 202 if( g_strcasecmp( state, "Available" ) == 0 )202 if( g_strcasecmp( state, "Available" ) == 0 ) 203 203 { 204 204 yd->current_status = YAHOO_STATUS_AVAILABLE; … … 235 235 } 236 236 } 237 else if 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 yahoo_set_away( yd->y2_id, yd->current_status, msg, gc->away != NULL ); 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 ); 243 246 } 244 247 -
protocols/yahoo/yahoo_list.h
r8e419cb ra4dc9f7 21 21 */ 22 22 23 /*24 * This is a replacement for the GList. It only provides functions that25 * we use in Ayttm. Thanks to Meredyyd from everybuddy dev for doing26 * most of it.27 */28 29 23 #ifndef __YLIST_H__ 30 24 #define __YLIST_H__ 31 25 32 #ifdef __cplusplus 33 extern "C" { 26 /* GLib has linked list already, so I don't see why libyahoo2 has to copy this... */ 27 28 typedef GList YList; 29 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 47 34 48 #endif 35 36 typedef struct _YList {37 struct _YList *next;38 struct _YList *prev;39 void *data;40 } YList;41 42 typedef int (*YListCompFunc) (const void *, const void *);43 typedef void (*YListFunc) (void *, void *);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->next70 71 #ifdef __cplusplus72 }73 #endif74 #endif -
root_commands.c
r8e419cb ra4dc9f7 32 32 #include <string.h> 33 33 34 const command_t commands[] = { 35 { "help", 0, cmd_help }, 36 { "identify", 1, cmd_identify }, 37 { "register", 1, cmd_register }, 38 { "drop", 1, cmd_drop }, 39 { "account", 1, cmd_account }, 40 { "add", 2, cmd_add }, 41 { "info", 1, cmd_info }, 42 { "rename", 2, cmd_rename }, 43 { "remove", 1, cmd_remove }, 44 { "block", 1, cmd_block }, 45 { "allow", 1, cmd_allow }, 46 { "save", 0, cmd_save }, 47 { "set", 0, cmd_set }, 48 { "yes", 0, cmd_yesno }, 49 { "no", 0, cmd_yesno }, 50 { "blist", 0, cmd_blist }, 51 { "nick", 1, cmd_nick }, 52 { "import_buddies", 1, cmd_import_buddies }, 53 { "qlist", 0, cmd_qlist }, 54 { NULL } 55 }; 56 57 int root_command_string( irc_t *irc, user_t *u, char *command, int flags ) 34 void root_command_string( irc_t *irc, user_t *u, char *command, int flags ) 58 35 { 59 36 char *cmd[IRC_MAX_ARGS]; … … 87 64 cmd[k] = NULL; 88 65 89 r eturn( root_command( irc, cmd ));90 } 91 92 introot_command( irc_t *irc, char *cmd[] )66 root_command( irc, cmd ); 67 } 68 69 void root_command( irc_t *irc, char *cmd[] ) 93 70 { 94 71 int i; 95 72 96 73 if( !cmd[0] ) 97 return ( 0 );74 return; 98 75 99 76 for( i = 0; commands[i].command; i++ ) … … 103 80 { 104 81 irc_usermsg( irc, "Not enough parameters given (need %d)", commands[i].required_parameters ); 105 return ( 0 );82 return; 106 83 } 107 84 commands[i].execute( irc, cmd ); 108 return ( 1 );85 return; 109 86 } 110 87 111 88 irc_usermsg( irc, "Unknown command: %s. Please use \x02help commands\x02 to get a list of available commands.", cmd[0] ); 112 113 return( 1 ); 114 } 115 116 int cmd_help( irc_t *irc, char **cmd ) 89 } 90 91 static void cmd_help( irc_t *irc, char **cmd ) 117 92 { 118 93 char param[80]; … … 134 109 irc_usermsg( irc, "%s", s ); 135 110 g_free( s ); 136 return( 1 );137 111 } 138 112 else 139 113 { 140 114 irc_usermsg( irc, "Error opening helpfile." ); 141 return( 0 ); 142 } 143 } 144 145 int cmd_identify( irc_t *irc, char **cmd ) 115 } 116 } 117 118 static void cmd_identify( irc_t *irc, char **cmd ) 146 119 { 147 120 storage_status_t status = storage_load( irc->nick, cmd[1], irc ); … … 162 135 break; 163 136 } 164 165 return( 0 ); 166 } 167 168 int cmd_register( irc_t *irc, char **cmd ) 137 } 138 139 static void cmd_register( irc_t *irc, char **cmd ) 169 140 { 170 141 if( global.conf->authmode == AUTHMODE_REGISTERED ) 171 142 { 172 143 irc_usermsg( irc, "This server does not allow registering new accounts" ); 173 return ( 0 );144 return; 174 145 } 175 146 … … 189 160 break; 190 161 } 191 192 return( 0 ); 193 } 194 195 int cmd_drop( irc_t *irc, char **cmd ) 162 } 163 164 static void cmd_drop( irc_t *irc, char **cmd ) 196 165 { 197 166 storage_status_t status; … … 201 170 case STORAGE_NO_SUCH_USER: 202 171 irc_usermsg( irc, "That account does not exist" ); 203 return( 0 );172 break; 204 173 case STORAGE_INVALID_PASSWORD: 205 174 irc_usermsg( irc, "Password invalid" ); 206 return( 0 );175 break; 207 176 case STORAGE_OK: 208 177 irc_setpass( irc, NULL ); … … 210 179 irc_umode_set( irc, "-R", 1 ); 211 180 irc_usermsg( irc, "Account `%s' removed", irc->nick ); 212 return( 0 );181 break; 213 182 default: 214 183 irc_usermsg( irc, "Error: '%d'", status ); 215 return( 0 );216 } 217 } 218 219 intcmd_account( irc_t *irc, char **cmd )184 break; 185 } 186 } 187 188 static void cmd_account( irc_t *irc, char **cmd ) 220 189 { 221 190 account_t *a; … … 224 193 { 225 194 irc_usermsg( irc, "This server only accepts registered users" ); 226 return ( 0 );195 return; 227 196 } 228 197 … … 234 203 { 235 204 irc_usermsg( irc, "Not enough parameters" ); 236 return ( 0 );205 return; 237 206 } 238 207 … … 242 211 { 243 212 irc_usermsg( irc, "Unknown protocol" ); 244 return ( 0 );213 return; 245 214 } 246 215 … … 304 273 { 305 274 irc_usermsg( irc, "Account already online" ); 306 return ( 0 );275 return; 307 276 } 308 277 else … … 314 283 { 315 284 irc_usermsg( irc, "Invalid account" ); 316 return ( 0 );285 return; 317 286 } 318 287 } … … 360 329 { 361 330 irc_usermsg( irc, "Account already offline" ); 362 return ( 0 );331 return; 363 332 } 364 333 } … … 366 335 { 367 336 irc_usermsg( irc, "Invalid account" ); 368 return ( 0 );337 return; 369 338 } 370 339 } … … 373 342 irc_usermsg( irc, "Unknown command: account %s. Please use \x02help commands\x02 to get a list of available commands.", cmd[1] ); 374 343 } 375 376 return( 1 ); 377 } 378 379 int cmd_add( irc_t *irc, char **cmd ) 344 } 345 346 static void cmd_add( irc_t *irc, char **cmd ) 380 347 { 381 348 account_t *a; … … 384 351 { 385 352 irc_usermsg( irc, "Invalid account" ); 386 return ( 1 );353 return; 387 354 } 388 355 else if( !( a->gc && ( a->gc->flags & OPT_LOGGED_IN ) ) ) 389 356 { 390 357 irc_usermsg( irc, "That account is not on-line" ); 391 return ( 1 );358 return; 392 359 } 393 360 … … 397 364 { 398 365 irc_usermsg( irc, "The requested nick `%s' is invalid", cmd[3] ); 399 return ( 0 );366 return; 400 367 } 401 368 else if( user_find( irc, cmd[3] ) ) 402 369 { 403 370 irc_usermsg( irc, "The requested nick `%s' already exists", cmd[3] ); 404 return ( 0 );371 return; 405 372 } 406 373 else … … 413 380 414 381 irc_usermsg( irc, "User `%s' added to your contact list as `%s'", cmd[2], user_findhandle( a->gc, cmd[2] )->nick ); 415 416 return( 0 ); 417 } 418 419 int cmd_info( irc_t *irc, char **cmd ) 382 } 383 384 static void cmd_info( irc_t *irc, char **cmd ) 420 385 { 421 386 struct gaim_connection *gc; … … 428 393 { 429 394 irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] ); 430 return ( 1 );395 return; 431 396 } 432 397 gc = u->gc; … … 436 401 { 437 402 irc_usermsg( irc, "Invalid account" ); 438 return ( 1 );403 return; 439 404 } 440 405 else if( !( ( gc = a->gc ) && ( a->gc->flags & OPT_LOGGED_IN ) ) ) 441 406 { 442 407 irc_usermsg( irc, "That account is not on-line" ); 443 return ( 1 );408 return; 444 409 } 445 410 … … 447 412 { 448 413 irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] ); 449 return( 1 );450 }451 gc->prpl->get_info( gc, cmd[2] );452 453 return( 0 );454 } 455 456 intcmd_rename( irc_t *irc, char **cmd )414 } 415 else 416 { 417 gc->prpl->get_info( gc, cmd[2] ); 418 } 419 } 420 421 static void cmd_rename( irc_t *irc, char **cmd ) 457 422 { 458 423 user_t *u; … … 461 426 { 462 427 irc_usermsg( irc, "Nick `%s' can't be changed", cmd[1] ); 463 return( 1 ); 464 } 465 if( user_find( irc, cmd[2] ) && ( nick_cmp( cmd[1], cmd[2] ) != 0 ) ) 428 } 429 else if( user_find( irc, cmd[2] ) && ( nick_cmp( cmd[1], cmd[2] ) != 0 ) ) 466 430 { 467 431 irc_usermsg( irc, "Nick `%s' already exists", cmd[2] ); 468 return( 1 ); 469 } 470 if( !nick_ok( cmd[2] ) ) 432 } 433 else if( !nick_ok( cmd[2] ) ) 471 434 { 472 435 irc_usermsg( irc, "Nick `%s' is invalid", cmd[2] ); 473 return( 1 ); 474 } 475 if( !( u = user_find( irc, cmd[1] ) ) ) 436 } 437 else if( !( u = user_find( irc, cmd[1] ) ) ) 476 438 { 477 439 irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] ); 478 return( 1 );479 }480 user_rename( irc, cmd[1], cmd[2] );481 irc_write( irc, ":%s!%s@%s NICK %s", cmd[1], u->user, u->host, cmd[2] );482 if( g_strcasecmp( cmd[1], irc->mynick ) == 0 )483 {484 g_free( irc->mynick );485 irc->mynick = g_strdup( cmd[2]);486 }487 else if( u->send_handler == buddy_send_handler )488 {489 nick_set( irc, u->handle, u->gc->prpl, cmd[2] );490 }491 492 irc_usermsg( irc, "Nick successfully changed" );493 494 return( 0 );495 } 496 497 intcmd_remove( irc_t *irc, char **cmd )440 } 441 else 442 { 443 user_rename( irc, cmd[1], cmd[2] ); 444 irc_write( irc, ":%s!%s@%s NICK %s", cmd[1], u->user, u->host, cmd[2] ); 445 if( g_strcasecmp( cmd[1], irc->mynick ) == 0 ) 446 { 447 g_free( irc->mynick ); 448 irc->mynick = g_strdup( cmd[2] ); 449 } 450 else if( u->send_handler == buddy_send_handler ) 451 { 452 nick_set( irc, u->handle, u->gc->prpl, cmd[2] ); 453 } 454 455 irc_usermsg( irc, "Nick successfully changed" ); 456 } 457 } 458 459 static void cmd_remove( irc_t *irc, char **cmd ) 498 460 { 499 461 user_t *u; … … 503 465 { 504 466 irc_usermsg( irc, "Buddy `%s' not found", cmd[1] ); 505 return ( 1 );467 return; 506 468 } 507 469 s = g_strdup( u->handle ); … … 514 476 g_free( s ); 515 477 516 return ( 0 );517 } 518 519 intcmd_block( irc_t *irc, char **cmd )478 return; 479 } 480 481 static void cmd_block( irc_t *irc, char **cmd ) 520 482 { 521 483 struct gaim_connection *gc; … … 528 490 { 529 491 irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] ); 530 return ( 1 );492 return; 531 493 } 532 494 gc = u->gc; … … 536 498 { 537 499 irc_usermsg( irc, "Invalid account" ); 538 return ( 1 );500 return; 539 501 } 540 502 else if( !( ( gc = a->gc ) && ( a->gc->flags & OPT_LOGGED_IN ) ) ) 541 503 { 542 504 irc_usermsg( irc, "That account is not on-line" ); 543 return ( 1 );505 return; 544 506 } 545 507 … … 554 516 irc_usermsg( irc, "Buddy `%s' moved from your permit- to your deny-list", cmd[2] ); 555 517 } 556 557 return( 0 ); 558 } 559 560 int cmd_allow( irc_t *irc, char **cmd ) 518 } 519 520 static void cmd_allow( irc_t *irc, char **cmd ) 561 521 { 562 522 struct gaim_connection *gc; … … 569 529 { 570 530 irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] ); 571 return ( 1 );531 return; 572 532 } 573 533 gc = u->gc; … … 577 537 { 578 538 irc_usermsg( irc, "Invalid account" ); 579 return ( 1 );539 return; 580 540 } 581 541 else if( !( ( gc = a->gc ) && ( a->gc->flags & OPT_LOGGED_IN ) ) ) 582 542 { 583 543 irc_usermsg( irc, "That account is not on-line" ); 584 return ( 1 );544 return; 585 545 } 586 546 … … 596 556 irc_usermsg( irc, "Buddy `%s' moved from your deny- to your permit-list", cmd[2] ); 597 557 } 598 599 return( 0 ); 600 } 601 602 int cmd_yesno( irc_t *irc, char **cmd ) 558 } 559 560 static void cmd_yesno( irc_t *irc, char **cmd ) 603 561 { 604 562 query_t *q = NULL; … … 608 566 { 609 567 irc_usermsg( irc, "Did I ask you something?" ); 610 return ( 0 );568 return; 611 569 } 612 570 … … 618 576 { 619 577 irc_usermsg( irc, "Invalid query number" ); 620 return ( 0 );578 return; 621 579 } 622 580 … … 628 586 { 629 587 irc_usermsg( irc, "Uhm, I never asked you something like that..." ); 630 return ( 0 );588 return; 631 589 } 632 590 } … … 636 594 else if( g_strcasecmp( cmd[0], "no" ) == 0 ) 637 595 query_answer( irc, q, 0 ); 638 639 return( 1 ); 640 } 641 642 int cmd_set( irc_t *irc, char **cmd ) 596 } 597 598 static void cmd_set( irc_t *irc, char **cmd ) 643 599 { 644 600 if( cmd[1] && cmd[2] ) 645 601 { 646 602 set_setstr( irc, cmd[1], cmd[2] ); 603 604 if( ( strcmp( cmd[2], "=" ) ) == 0 && cmd[3] ) 605 irc_usermsg( irc, "Warning: Correct syntax: \002set <variable> <value>\002 (without =)" ); 647 606 } 648 607 if( cmd[1] ) /* else 'forgotten' on purpose.. Must show new value after changing */ … … 662 621 } 663 622 } 664 665 return( 0 ); 666 } 667 668 int cmd_save( irc_t *irc, char **cmd ) 623 } 624 625 static void cmd_save( irc_t *irc, char **cmd ) 669 626 { 670 627 if( storage_save( irc, TRUE ) == STORAGE_OK ) … … 672 629 else 673 630 irc_usermsg( irc, "Configuration could not be saved!" ); 674 675 return( 0 ); 676 } 677 678 int cmd_blist( irc_t *irc, char **cmd ) 631 } 632 633 static void cmd_blist( irc_t *irc, char **cmd ) 679 634 { 680 635 int online = 0, away = 0, offline = 0; … … 718 673 719 674 irc_usermsg( irc, "%d buddies (%d available, %d away, %d offline)", n_online + n_away + n_offline, n_online, n_away, n_offline ); 720 721 return( 0 ); 722 } 723 724 int cmd_nick( irc_t *irc, char **cmd ) 675 } 676 677 static void cmd_nick( irc_t *irc, char **cmd ) 725 678 { 726 679 account_t *a; … … 754 707 a->gc->prpl->set_info( a->gc, cmd[2] ); 755 708 } 756 757 return( 1 ); 758 } 759 760 int cmd_qlist( irc_t *irc, char **cmd ) 709 } 710 711 static void cmd_qlist( irc_t *irc, char **cmd ) 761 712 { 762 713 query_t *q = irc->queries; … … 766 717 { 767 718 irc_usermsg( irc, "There are no pending questions." ); 768 return ( 0 );719 return; 769 720 } 770 721 … … 776 727 else 777 728 irc_usermsg( irc, "%d, BitlBee: %s", num, q->question ); 778 779 return( 0 ); 780 } 781 782 int cmd_import_buddies( irc_t *irc, char **cmd ) 729 } 730 731 static void cmd_import_buddies( irc_t *irc, char **cmd ) 783 732 { 784 733 struct gaim_connection *gc; … … 789 738 { 790 739 irc_usermsg( irc, "Invalid account" ); 791 return ( 0 );740 return; 792 741 } 793 742 else if( !( ( gc = a->gc ) && ( a->gc->flags & OPT_LOGGED_IN ) ) ) 794 743 { 795 744 irc_usermsg( irc, "That account is not on-line" ); 796 return ( 0 );745 return; 797 746 } 798 747 … … 815 764 { 816 765 irc_usermsg( irc, "Invalid argument: %s", cmd[2] ); 817 return ( 0 );766 return; 818 767 } 819 768 } … … 829 778 830 779 irc_usermsg( irc, "Sent all add requests. Please wait for a while, the server needs some time to handle all the adds." ); 831 832 return( 0 ); 833 } 780 } 781 782 const command_t commands[] = { 783 { "help", 0, cmd_help, 0 }, 784 { "identify", 1, cmd_identify, 0 }, 785 { "register", 1, cmd_register, 0 }, 786 { "drop", 1, cmd_drop, 0 }, 787 { "account", 1, cmd_account, 0 }, 788 { "add", 2, cmd_add, 0 }, 789 { "info", 1, cmd_info, 0 }, 790 { "rename", 2, cmd_rename, 0 }, 791 { "remove", 1, cmd_remove, 0 }, 792 { "block", 1, cmd_block, 0 }, 793 { "allow", 1, cmd_allow, 0 }, 794 { "save", 0, cmd_save, 0 }, 795 { "set", 0, cmd_set, 0 }, 796 { "yes", 0, cmd_yesno, 0 }, 797 { "no", 0, cmd_yesno, 0 }, 798 { "blist", 0, cmd_blist, 0 }, 799 { "nick", 1, cmd_nick, 0 }, 800 { "import_buddies", 1, cmd_import_buddies, 0 }, 801 { "qlist", 0, cmd_qlist, 0 }, 802 { NULL } 803 }; -
unix.c
r8e419cb ra4dc9f7 29 29 #include "protocols/nogaim.h" 30 30 #include "help.h" 31 #include "ipc.h" 31 32 #include <signal.h> 32 33 #include <unistd.h> … … 38 39 static void sighandler( int signal ); 39 40 40 int main( int argc, char *argv[] )41 int main( int argc, char *argv[], char **envp ) 41 42 { 42 43 int i = 0; 44 char *old_cwd = NULL; 43 45 struct sigaction sig, old; 44 46 … … 79 81 else if( global.conf->runmode == RUNMODE_FORKDAEMON ) 80 82 { 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 81 92 i = bitlbee_daemon_init(); 82 93 log_message( LOGLVL_INFO, "Bitlbee %s starting in forking daemon mode.", BITLBEE_VERSION ); … … 114 125 g_main_run( global.loop ); 115 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 116 156 return( 0 ); 117 157 } -
url.c
r8e419cb ra4dc9f7 40 40 else 41 41 { 42 if( g_strncasecmp( set_url, "https", i - set_url ) == 0 ) 42 if( g_strncasecmp( set_url, "http", i - set_url ) == 0 ) 43 url->proto = PROTO_HTTP; 44 else if( g_strncasecmp( set_url, "https", i - set_url ) == 0 ) 43 45 url->proto = PROTO_HTTPS; 44 else if( g_strncasecmp( set_url, "http", i - set_url ) == 0 )45 url->proto = PROTO_HTTP;46 46 else if( g_strncasecmp( set_url, "socks4", i - set_url ) == 0 ) 47 47 url->proto = PROTO_SOCKS4; -
user.h
r8e419cb ra4dc9f7 45 45 int sendbuf_flags; 46 46 47 int(*send_handler) ( irc_t *irc, struct __USER *u, char *msg, int flags );47 void (*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.