Пример #1
0
struct t_hashtable *
irc_message_split (struct t_irc_server *server, const char *message)
{
    struct t_hashtable *hashtable;
    char **argv, **argv_eol, *tags, *host, *command, *arguments, target[512];
    char *pos;
    int split_ok, argc, index_args, max_length_nick, max_length_host;

    split_ok = 0;
    tags = NULL;
    host = NULL;
    command = NULL;
    arguments = NULL;
    index_args = 0;
    argv = NULL;
    argv_eol = NULL;

    /* debug message */
    if (weechat_irc_plugin->debug >= 2)
        weechat_printf (NULL, "irc_message_split: message='%s'", message);

    hashtable = weechat_hashtable_new (32,
                                       WEECHAT_HASHTABLE_STRING,
                                       WEECHAT_HASHTABLE_STRING,
                                       NULL,
                                       NULL);
    if (!hashtable)
        return NULL;

    if (!message || !message[0])
        goto end;

    if (message[0] == '@')
    {
        pos = strchr (message, ' ');
        if (pos)
        {
            tags = weechat_strndup (message, pos - message + 1);
            message = pos + 1;
        }
    }

    argv = weechat_string_split (message, " ", 0, 0, &argc);
    argv_eol = weechat_string_split (message, " ", 2, 0, NULL);

    if (argc < 2)
        goto end;

    if (argv[0][0] == ':')
    {
        if (argc < 3)
            goto end;
        host = argv[0];
        command = argv[1];
        arguments = argv_eol[2];
        index_args = 2;
    }
    else
    {
        command = argv[0];
        arguments = argv_eol[1];
        index_args = 1;
    }

    max_length_nick = (server && (server->nick_max_length > 0)) ?
        server->nick_max_length : 16;
    max_length_host = 1 + /* ":"  */
        max_length_nick + /* nick */
        1 +               /* "!"  */
        63 +              /* host */
        1;                /* " "  */

    if ((weechat_strcasecmp (command, "ison") == 0)
        || (weechat_strcasecmp (command, "wallops") == 0))
    {
        split_ok = irc_message_split_string (hashtable, tags, host, command,
                                             NULL, ":",
                                             (argv_eol[index_args][0] == ':') ?
                                             argv_eol[index_args] + 1 : argv_eol[index_args],
                                             NULL, ' ', max_length_host);
    }
    else if (weechat_strcasecmp (command, "join") == 0)
    {
        /* split join (if it's more than 510 bytes) */
        if (strlen (message) > 510)
        {
            split_ok = irc_message_split_join (hashtable, tags, host,
                                               arguments);
        }
    }
    else if ((weechat_strcasecmp (command, "privmsg") == 0)
             || (weechat_strcasecmp (command, "notice") == 0))
    {
        /* split privmsg/notice */
        if (index_args + 1 <= argc - 1)
        {
            split_ok = irc_message_split_privmsg_notice (hashtable, tags, host,
                                                         command,
                                                         argv[index_args],
                                                         (argv_eol[index_args + 1][0] == ':') ?
                                                         argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1],
                                                         max_length_host);
        }
    }
    else if (weechat_strcasecmp (command, "005") == 0)
    {
        /* split 005 (isupport) */
        if (index_args + 1 <= argc - 1)
        {
            split_ok = irc_message_split_005 (hashtable, tags, host, command,
                                              argv[index_args],
                                              (argv_eol[index_args + 1][0] == ':') ?
                                              argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1]);
        }
    }
    else if (weechat_strcasecmp (command, "353") == 0)
    {
        /*
         * split 353 (list of users on channel):
         *   :server 353 mynick = #channel :mynick nick1 @nick2 +nick3
         */
        if (index_args + 2 <= argc - 1)
        {
            if (irc_channel_is_channel (server, argv[index_args + 1]))
            {
                snprintf (target, sizeof (target), "%s %s",
                          argv[index_args], argv[index_args + 1]);
                split_ok = irc_message_split_string (hashtable, tags, host,
                                                     command, target, ":",
                                                     (argv_eol[index_args + 2][0] == ':') ?
                                                     argv_eol[index_args + 2] + 1 : argv_eol[index_args + 2],
                                                     NULL, ' ', -1);
            }
            else
            {
                if (index_args + 3 <= argc - 1)
                {
                    snprintf (target, sizeof (target), "%s %s %s",
                              argv[index_args], argv[index_args + 1],
                              argv[index_args + 2]);
                    split_ok = irc_message_split_string (hashtable, tags, host,
                                                         command, target, ":",
                                                         (argv_eol[index_args + 3][0] == ':') ?
                                                         argv_eol[index_args + 3] + 1 : argv_eol[index_args + 3],
                                                         NULL, ' ', -1);
                }
            }
        }
    }

end:
    if (!split_ok
        || (weechat_hashtable_get_integer (hashtable, "items_count") == 0))
    {
        irc_message_split_add (hashtable, 1, tags, message, arguments);
    }

    if (tags)
        free (tags);
    if (argv)
        weechat_string_free_split (argv);
    if (argv_eol)
        weechat_string_free_split (argv_eol);

    return hashtable;
}
Пример #2
0
struct t_hashtable *
irc_message_split (struct t_irc_server *server, const char *message)
{
    struct t_hashtable *hashtable;
    char **argv, **argv_eol, *tags, *host, *command, *arguments, target[512];
    char *pos, monitor_action[3];
    int split_ok, argc, index_args, max_length_nick, max_length_host;

    split_ok = 0;
    tags = NULL;
    host = NULL;
    command = NULL;
    arguments = NULL;
    index_args = 0;
    argv = NULL;
    argv_eol = NULL;

    /* debug message */
    if (weechat_irc_plugin->debug >= 2)
        weechat_printf (NULL, "irc_message_split: message='%s'", message);

    hashtable = weechat_hashtable_new (32,
                                       WEECHAT_HASHTABLE_STRING,
                                       WEECHAT_HASHTABLE_STRING,
                                       NULL,
                                       NULL);
    if (!hashtable)
        return NULL;

    if (!message || !message[0])
        goto end;

    if (message[0] == '@')
    {
        pos = strchr (message, ' ');
        if (pos)
        {
            tags = weechat_strndup (message, pos - message + 1);
            message = pos + 1;
        }
    }

    argv = weechat_string_split (message, " ", 0, 0, &argc);
    argv_eol = weechat_string_split (message, " ", 2, 0, NULL);

    if (argc < 2)
        goto end;

    if (argv[0][0] == ':')
    {
        if (argc < 3)
            goto end;
        host = argv[0];
        command = argv[1];
        arguments = argv_eol[2];
        index_args = 2;
    }
    else
    {
        command = argv[0];
        arguments = argv_eol[1];
        index_args = 1;
    }

    max_length_nick = (server && (server->nick_max_length > 0)) ?
        server->nick_max_length : 16;
    max_length_host = 1 + /* ":"  */
        max_length_nick + /* nick */
        1 +               /* "!"  */
        63 +              /* host */
        1;                /* " "  */

    if ((weechat_strcasecmp (command, "ison") == 0)
        || (weechat_strcasecmp (command, "wallops") == 0))
    {
        /*
         * ISON :nick1 nick2 nick3
         * WALLOPS :some text here
         */
        split_ok = irc_message_split_string (
            hashtable, tags, host, command, NULL, ":",
            (argv_eol[index_args][0] == ':') ?
            argv_eol[index_args] + 1 : argv_eol[index_args],
            NULL, ' ', max_length_host);
    }
    else if (weechat_strcasecmp (command, "monitor") == 0)
    {
        /*
         * MONITOR + nick1,nick2,nick3
         * MONITOR - nick1,nick2,nick3
         */
        if (((argv_eol[index_args][0] == '+') || (argv_eol[index_args][0] == '-'))
            && (argv_eol[index_args][1] == ' '))
        {
            snprintf (monitor_action, sizeof (monitor_action),
                      "%c ", argv_eol[index_args][0]);
            split_ok = irc_message_split_string (
                hashtable, tags, host, command, NULL, monitor_action,
                argv_eol[index_args] + 2, NULL, ',', max_length_host);
        }
        else
        {
            split_ok = irc_message_split_string (
                hashtable, tags, host, command, NULL, ":",
                (argv_eol[index_args][0] == ':') ?
                argv_eol[index_args] + 1 : argv_eol[index_args],
                NULL, ',', max_length_host);
        }
    }
    else if (weechat_strcasecmp (command, "join") == 0)
    {
        /* JOIN #channel1,#channel2,#channel3 key1,key2 */
        if (strlen (message) > 510)
        {
            /* split join if it's more than 510 bytes */
            split_ok = irc_message_split_join (hashtable, tags, host,
                                               arguments);
        }
    }
    else if ((weechat_strcasecmp (command, "privmsg") == 0)
             || (weechat_strcasecmp (command, "notice") == 0))
    {
        /*
         * PRIVMSG target :some text here
         * NOTICE target :some text here
         */
        if (index_args + 1 <= argc - 1)
        {
            split_ok = irc_message_split_privmsg_notice (
                hashtable, tags, host, command, argv[index_args],
                (argv_eol[index_args + 1][0] == ':') ?
                argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1],
                max_length_host);
        }
    }
    else if (weechat_strcasecmp (command, "005") == 0)
    {
        /* :server 005 nick MODES=4 CHANLIMIT=#:20 NICKLEN=16 USERLEN=10 ... */
        if (index_args + 1 <= argc - 1)
        {
            split_ok = irc_message_split_005 (
                hashtable, tags, host, command, argv[index_args],
                (argv_eol[index_args + 1][0] == ':') ?
                argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1]);
        }
    }
    else if (weechat_strcasecmp (command, "353") == 0)
    {
        /*
         * list of users on channel:
         *   :server 353 mynick = #channel :mynick nick1 @nick2 +nick3
         */
        if (index_args + 2 <= argc - 1)
        {
            if (irc_channel_is_channel (server, argv[index_args + 1]))
            {
                snprintf (target, sizeof (target), "%s %s",
                          argv[index_args], argv[index_args + 1]);
                split_ok = irc_message_split_string (
                    hashtable, tags, host, command, target, ":",
                    (argv_eol[index_args + 2][0] == ':') ?
                    argv_eol[index_args + 2] + 1 : argv_eol[index_args + 2],
                    NULL, ' ', -1);
            }
            else
            {
                if (index_args + 3 <= argc - 1)
                {
                    snprintf (target, sizeof (target), "%s %s %s",
                              argv[index_args], argv[index_args + 1],
                              argv[index_args + 2]);
                    split_ok = irc_message_split_string (
                        hashtable, tags, host, command, target, ":",
                        (argv_eol[index_args + 3][0] == ':') ?
                        argv_eol[index_args + 3] + 1 : argv_eol[index_args + 3],
                        NULL, ' ', -1);
                }
            }
        }
    }

end:
    if (!split_ok
        || (weechat_hashtable_get_integer (hashtable, "items_count") == 0))
    {
        irc_message_split_add (hashtable, 1, tags, message, arguments);
    }

    if (tags)
        free (tags);
    if (argv)
        weechat_string_free_split (argv);
    if (argv_eol)
        weechat_string_free_split (argv_eol);

    return hashtable;
}