~ubuntu-branches/ubuntu/karmic/irssi/karmic-updates

« back to all changes in this revision

Viewing changes to src/irc/core/irc-servers.c

  • Committer: Bazaar Package Importer
  • Author(s): Andres Rodriguez
  • Date: 2009-05-05 15:50:50 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090505155050-aoqlnpes7che9rtd
Tags: 0.8.13-1ubuntu1
* Merge from debian unstable (LP: #372411), remaining changes:
  - debian/patches: 03firsttimer_text
    + Adapt it so it tells you about connecting to irc.ubuntu.com and
      joining #ubuntu instead of irc.debian.org and #debian.
  - debian/patches: 90irc-ubuntu-com
* Fixed debian/patches/90irc-ubuntu-com for new irssi.conf.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
#include "module.h"
22
22
 
23
 
#include "net-nonblock.h"
24
23
#include "net-sendbuffer.h"
25
 
#include "line-split.h"
26
24
#include "signals.h"
27
25
#include "rawlog.h"
28
26
#include "misc.h"
41
39
#include "modes.h"
42
40
 
43
41
#include "settings.h"
 
42
#include "recode.h"
44
43
 
45
44
#define DEFAULT_MAX_KICKS 1
46
45
#define DEFAULT_MAX_MODES 3
81
80
        IRC_SERVER_REC *ircserver;
82
81
        CHANNEL_REC *channel;
83
82
        char *str;
 
83
        char *recoded;
84
84
 
85
85
        ircserver = IRC_SERVER(server);
86
86
        g_return_if_fail(ircserver != NULL);
94
94
                        target = channel->name;
95
95
        }
96
96
 
97
 
        str = g_strdup_printf("PRIVMSG %s :%s", target, msg);
 
97
        recoded = recode_out(SERVER(server), msg, target);
 
98
        str = g_strdup_printf("PRIVMSG %s :%s", target, recoded);
98
99
        irc_send_cmd_split(ircserver, str, 2, ircserver->max_msgs_in_cmd);
99
100
        g_free(str);
 
101
        g_free(recoded);
100
102
}
101
103
 
102
104
static void server_init(IRC_SERVER_REC *server)
259
261
                redirect = tmp->next->data;
260
262
 
261
263
                if ((target == NULL || command_has_target(cmd, target)) &&
262
 
                    g_strncasecmp(cmd, "PONG ", 5) != 0) {
 
264
                    g_ascii_strncasecmp(cmd, "PONG ", 5) != 0) {
263
265
                        /* remove the redirection */
264
266
                        link = tmp->next;
265
267
                        server->cmdqueue =
334
336
static void sig_server_quit(IRC_SERVER_REC *server, const char *msg)
335
337
{
336
338
        char *str;
 
339
        char *recoded;
337
340
 
338
 
        if (!IS_IRC_SERVER(server) || server->handle == NULL ||
339
 
            server->buffer == NULL)
 
341
        if (!IS_IRC_SERVER(server) || !server->connected)
340
342
                return;
341
343
 
342
 
        str = g_strdup_printf("QUIT :%s", msg);
 
344
        recoded = recode_out(SERVER(server), msg, NULL);
 
345
        str = g_strdup_printf("QUIT :%s", recoded);
343
346
        irc_send_cmd_now(server, str);
344
347
        g_free(str);
 
348
        g_free(recoded);
 
349
}
 
350
 
 
351
void irc_server_send_action(IRC_SERVER_REC *server, const char *target, const char *data)
 
352
{
 
353
        char *recoded;
 
354
 
 
355
        recoded = recode_out(SERVER(server), data, target);
 
356
        irc_send_cmdv(server, "PRIVMSG %s :\001ACTION %s\001", target, recoded);
 
357
        g_free(recoded);
 
358
}
 
359
 
 
360
void irc_server_send_away(IRC_SERVER_REC *server, const char *reason)
 
361
{
 
362
        char *recoded = NULL;
 
363
 
 
364
        if (!IS_IRC_SERVER(server))
 
365
                return;
 
366
 
 
367
        if (*reason != '\0' || server->usermode_away) {
 
368
                g_free_and_null(server->away_reason);
 
369
                if (*reason != '\0') {
 
370
                        server->away_reason = g_strdup(reason);
 
371
                        reason = recoded = recode_out(SERVER(server), reason, NULL);
 
372
                }
 
373
 
 
374
                irc_send_cmdv(server, "AWAY :%s", reason);
 
375
        }
 
376
        g_free(recoded);
345
377
}
346
378
 
347
379
void irc_server_send_data(IRC_SERVER_REC *server, const char *data, int len)
366
398
        }
367
399
}
368
400
 
369
 
static void server_cmd_timeout(IRC_SERVER_REC *server, GTimeVal *now)
 
401
static int server_cmd_timeout(IRC_SERVER_REC *server, GTimeVal *now)
370
402
{
371
403
        REDIRECT_REC *redirect;
372
404
        GSList *link;
375
407
        int len;
376
408
 
377
409
        if (!IS_IRC_SERVER(server))
378
 
                return;
 
410
                return 0;
379
411
 
380
412
        if (server->cmdcount == 0 && server->cmdqueue == NULL)
381
 
                return;
 
413
                return 0;
382
414
 
383
415
        if (g_timeval_cmp(now, &server->wait_cmd) == -1)
384
 
                return;
 
416
                return 1;
385
417
 
386
418
        usecs = get_timeval_diff(now, &server->last_cmd);
387
419
        if (usecs < server->cmd_queue_speed)
388
 
                return;
 
420
                return 1;
389
421
 
390
422
        server->cmdcount--;
391
 
        if (server->cmdqueue == NULL) return;
 
423
        if (server->cmdqueue == NULL) return 1;
392
424
 
393
425
        /* get command */
394
426
        cmd = server->cmdqueue->data;
398
430
        len = strlen(cmd);
399
431
        irc_server_send_data(server, cmd, len);
400
432
 
401
 
        /* add to rawlog without [CR+]LF (/RAWQUOTE might not have
402
 
           added the CR) */
 
433
        /* add to rawlog without [CR+]LF */
403
434
        if (len > 2 && cmd[len-2] == '\r')
404
435
                cmd[len-2] = '\0';
405
436
        else if (cmd[len-1] == '\n')
414
445
        link = server->cmdqueue;
415
446
        server->cmdqueue = g_slist_remove_link(server->cmdqueue, link);
416
447
        g_slist_free_1(link);
 
448
        return 1;
417
449
}
418
450
 
419
451
/* check every now and then if there's data to be sent in command buffer */
420
452
static int servers_cmd_timeout(void)
421
453
{
422
454
        GTimeVal now;
 
455
        GSList *tmp;
 
456
        int keep = 0;
423
457
 
424
458
        g_get_current_time(&now);
425
 
        g_slist_foreach(servers, (GFunc) server_cmd_timeout, &now);
426
 
        return 1;
 
459
        for (tmp = servers; tmp != NULL; tmp = tmp->next) {
 
460
                keep |= server_cmd_timeout(tmp->data, &now);
 
461
        }
 
462
        if (keep)
 
463
                return 1;
 
464
        else {
 
465
                cmd_tag = -1;
 
466
                return 0;
 
467
        }
 
468
}
 
469
 
 
470
/* Start the timeout for sending data later and decreasing cmdcount again */
 
471
void irc_servers_start_cmd_timeout(void)
 
472
{
 
473
        if (cmd_tag == -1)
 
474
                cmd_tag = g_timeout_add(500, (GSourceFunc) servers_cmd_timeout, NULL);
427
475
}
428
476
 
429
477
/* Return a string of all channels (and keys, if any have them) in server,
445
493
        for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
446
494
                CHANNEL_REC *channel = tmp->data;
447
495
 
448
 
                g_string_sprintfa(chans, "%s,", channel->name);
449
 
                g_string_sprintfa(keys, "%s,", channel->key == NULL ? "x" :
 
496
                g_string_append_printf(chans, "%s,", channel->name);
 
497
                g_string_append_printf(keys, "%s,", channel->key == NULL ? "x" :
450
498
                                  channel->key);
451
499
                if (channel->key != NULL)
452
500
                        use_keys = TRUE;
456
504
        for (tmp = server->rejoin_channels; tmp != NULL; tmp = tmp->next) {
457
505
                REJOIN_REC *rec = tmp->data;
458
506
 
459
 
                g_string_sprintfa(chans, "%s,", rec->channel);
460
 
                g_string_sprintfa(keys, "%s,", rec->key == NULL ? "x" :
 
507
                g_string_append_printf(chans, "%s,", rec->channel);
 
508
                g_string_append_printf(keys, "%s,", rec->key == NULL ? "x" :
461
509
                                  rec->key);
462
510
                if (rec->key != NULL) use_keys = TRUE;
463
511
        }
465
513
        if (chans->len > 0) {
466
514
                g_string_truncate(chans, chans->len-1);
467
515
                g_string_truncate(keys, keys->len-1);
468
 
                if (use_keys) g_string_sprintfa(chans, " %s", keys->str);
 
516
                if (use_keys) g_string_append_printf(chans, " %s", keys->str);
469
517
        }
470
518
 
471
519
        ret = chans->str;
475
523
        return ret;
476
524
}
477
525
 
478
 
static int sig_set_user_mode(IRC_SERVER_REC *server)
479
 
{
480
 
        const char *mode;
481
 
        char *newmode, *args;
482
 
 
483
 
        if (!IS_IRC_SERVER(server) || g_slist_find(servers, server) == NULL)
484
 
                return 0; /* not an irc server or got disconnected */
485
 
 
486
 
        mode = server->connrec->usermode;
487
 
        newmode = server->usermode == NULL ? NULL :
488
 
                modes_join(NULL, server->usermode, mode, FALSE);
489
 
 
490
 
        if (newmode == NULL || strcmp(newmode, server->usermode) != 0) {
491
 
                /* change the user mode. we used to do some trickery to
492
 
                   get rid of unwanted modes at reconnect time, but that's
493
 
                   more trouble than worth. (eg. we don't want to remove
494
 
                   some good default server modes, but we don't want to
495
 
                   set back +r, etc..) */
496
 
                args = g_strdup_printf((*mode == '+' || *mode == '-') ? "%s %s" : 
497
 
                                       "%s +%s", server->nick, mode);
498
 
                signal_emit("command mode", 3, args, server, NULL);
499
 
                g_free(args);
500
 
        }
501
 
 
502
 
        g_free_not_null(newmode);
503
 
        return 0;
504
 
}
505
 
 
506
526
static void event_connected(IRC_SERVER_REC *server, const char *data, const char *from)
507
527
{
508
528
        char *params, *nick;
533
553
        memcpy(&server->wait_cmd, &now, sizeof(GTimeVal));
534
554
 
535
555
        if (server->connrec->usermode != NULL) {
536
 
                /* wait a second and then send the user mode */
537
 
                g_timeout_add(1000, (GSourceFunc) sig_set_user_mode, server);
 
556
                /* Send the user mode, before the autosendcmd.
 
557
                 * Do not pass this through cmd_mode because it
 
558
                 * is not known whether the resulting MODE message
 
559
                 * (if any) is the initial umode or a reply to this.
 
560
                 */
 
561
                irc_send_cmdv(server, "MODE %s %s", server->nick,
 
562
                                server->connrec->usermode);
 
563
                g_free_not_null(server->wanted_usermode);
 
564
                server->wanted_usermode = g_strdup(server->connrec->usermode);
538
565
        }
539
566
 
540
567
        signal_emit("event connected", 1, server);
807
834
                else
808
835
                        server->nick_comp_func = irc_nickcmp_ascii;
809
836
        }
 
837
 
 
838
        if ((sptr = g_hash_table_lookup(server->isupport, "TARGMAX"))) {
 
839
                char *p = sptr;
 
840
                server->max_kicks_in_cmd = 1;
 
841
                server->max_msgs_in_cmd = 1;
 
842
                /* Not doing WHOIS here until it is clear what it means. */
 
843
                while (*p != '\0') {
 
844
                        if (!g_ascii_strncasecmp(p, "KICK:", 5)) {
 
845
                                server->max_kicks_in_cmd = atoi(p + 5);
 
846
                                if (server->max_kicks_in_cmd <= 0)
 
847
                                        server->max_kicks_in_cmd = 30;
 
848
                        } else if (!g_ascii_strncasecmp(p, "PRIVMSG:", 8)) {
 
849
                                server->max_msgs_in_cmd = atoi(p + 8);
 
850
                                if (server->max_msgs_in_cmd <= 0)
 
851
                                        server->max_msgs_in_cmd = 30;
 
852
                        }
 
853
                        p = strchr(p, ',');
 
854
                        if (p == NULL)
 
855
                                break;
 
856
                        p++;
 
857
                }
 
858
        } else if ((sptr = g_hash_table_lookup(server->isupport, "MAXTARGETS"))) {
 
859
                server->max_msgs_in_cmd = atoi(sptr);
 
860
                if (server->max_msgs_in_cmd <= 0)
 
861
                        server->max_msgs_in_cmd = 1;
 
862
        }
810
863
}
811
864
 
812
865
void irc_servers_init(void)
815
868
        settings_add_time("flood", "cmd_queue_speed", DEFAULT_CMD_QUEUE_SPEED);
816
869
        settings_add_int("flood", "cmds_max_at_once", DEFAULT_CMDS_MAX_AT_ONCE);
817
870
 
818
 
        cmd_tag = g_timeout_add(500, (GSourceFunc) servers_cmd_timeout, NULL);
 
871
        cmd_tag = -1;
819
872
 
820
873
        signal_add_first("server connected", (SIGNAL_FUNC) sig_connected);
821
874
        signal_add_last("server disconnected", (SIGNAL_FUNC) sig_disconnected);
841
894
 
842
895
void irc_servers_deinit(void)
843
896
{
844
 
        g_source_remove(cmd_tag);
 
897
        if (cmd_tag != -1)
 
898
                g_source_remove(cmd_tag);
845
899
 
846
900
        signal_remove("server connected", (SIGNAL_FUNC) sig_connected);
847
901
        signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected);