Ejemplo n.º 1
0
struct t_relay_server *
relay_server_new (const char *protocol_string, enum t_relay_protocol protocol,
                  const char *protocol_args, int port, int ipv4, int ipv6,
                  int ssl)
{
    struct t_relay_server *new_server;

    if (!protocol_string)
        return NULL;

    if (relay_server_search_port (port))
    {
        dogechat_printf (NULL, _("%s%s: error: port \"%d\" is already used"),
                        dogechat_prefix ("error"),
                        RELAY_PLUGIN_NAME, port);
        return NULL;
    }

    new_server = malloc (sizeof (*new_server));
    if (new_server)
    {
        new_server->protocol_string = strdup (protocol_string);
        new_server->protocol = protocol;
        new_server->protocol_args =
            (protocol_args) ? strdup (protocol_args) : NULL;
        new_server->port = port;
        new_server->ipv4 = ipv4;
        new_server->ipv6 = ipv6;
        new_server->ssl = ssl;
        new_server->sock = -1;
        new_server->hook_fd = NULL;
        new_server->start_time = 0;
        new_server->last_client_disconnect = 0;

        relay_server_create_socket (new_server);

        new_server->prev_server = NULL;
        new_server->next_server = relay_servers;
        if (relay_servers)
            relay_servers->prev_server = new_server;
        else
            last_relay_server = new_server;
        relay_servers = new_server;
    }
    else
    {
        dogechat_printf (NULL,
                        _("%s%s: not enough memory for listening on new port"),
                        dogechat_prefix ("error"), RELAY_PLUGIN_NAME);
    }

    return new_server;
}
Ejemplo n.º 2
0
void
fifo_exec (const char *text)
{
    char *text2, *pos_msg;
    struct t_gui_buffer *ptr_buffer;

    text2 = strdup (text);
    if (!text2)
        return;

    pos_msg = NULL;
    ptr_buffer = NULL;

    /*
     * look for plugin + buffer name at beginning of text
     * text may be: "plugin.buffer *text" or "*text"
     */
    if (text2[0] == '*')
    {
        pos_msg = text2 + 1;
        ptr_buffer = dogechat_current_buffer ();
    }
    else
    {
        pos_msg = strstr (text2, " *");
        if (!pos_msg)
        {
            dogechat_printf (NULL,
                            _("%s%s: invalid text received in pipe"),
                            dogechat_prefix ("error"), FIFO_PLUGIN_NAME);
            free (text2);
            return;
        }
        pos_msg[0] = '\0';
        pos_msg += 2;
        ptr_buffer = dogechat_buffer_search ("==", text2);
        if (!ptr_buffer)
        {
            dogechat_printf (NULL,
                            _("%s%s: buffer \"%s\" not found"),
                            dogechat_prefix ("error"), FIFO_PLUGIN_NAME,
                            text2);
            free (text2);
            return;
        }
    }

    dogechat_command (ptr_buffer, pos_msg);

    free (text2);
}
Ejemplo n.º 3
0
void
dogechat_js_reload_name (const char *name)
{
    struct t_plugin_script *ptr_script;
    char *filename;

    ptr_script = plugin_script_search (dogechat_js_plugin, js_scripts, name);
    if (ptr_script)
    {
        filename = strdup (ptr_script->filename);
        if (filename)
        {
            dogechat_js_unload (ptr_script);
            if (!js_quiet)
            {
                dogechat_printf (NULL,
                                dogechat_gettext ("%s: script \"%s\" unloaded"),
                                JS_PLUGIN_NAME, name);
            }
            dogechat_js_load (filename);
            free (filename);
        }
    }
    else
    {
        dogechat_printf (NULL,
                        dogechat_gettext ("%s%s: script \"%s\" not loaded"),
                        dogechat_prefix ("error"), JS_PLUGIN_NAME, name);
    }
}
Ejemplo n.º 4
0
void
xfer_network_send_file_fork (struct t_xfer *xfer)
{
    pid_t pid;
    int rc;

    if (!xfer_network_create_pipe (xfer))
        return;

    xfer->file = open (xfer->local_filename, O_RDONLY | O_NONBLOCK, 0644);

    switch (pid = fork ())
    {
    case -1:  /* fork failed */
        dogechat_printf (NULL,
                         _("%s%s: unable to fork"),
                         dogechat_prefix ("error"), XFER_PLUGIN_NAME);
        xfer_close (xfer, XFER_STATUS_FAILED);
        xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE);
        return;
    case 0:  /* child process */
        rc = setuid (getuid ());
        (void) rc;
        close (xfer->child_read);
        switch (xfer->protocol)
        {
        case XFER_NO_PROTOCOL:
            _exit (EXIT_SUCCESS);
            break;
        case XFER_PROTOCOL_DCC:
            xfer_dcc_send_file_child (xfer);
            break;
        case XFER_NUM_PROTOCOLS:
            break;
        }
        _exit (EXIT_SUCCESS);
    }

    dogechat_printf (NULL,
                     _("%s: sending file to %s (%s, %s.%s), "
                       "name: %s (local filename: %s), %llu bytes (protocol: %s)"),
                     XFER_PLUGIN_NAME,
                     xfer->remote_nick,
                     xfer->remote_address_str,
                     xfer->plugin_name,
                     xfer->plugin_id,
                     xfer->filename,
                     xfer->local_filename,
                     xfer->size,
                     xfer_protocol_string[xfer->protocol]);

    /* parent process */
    xfer->child_pid = pid;
    close (xfer->child_write);
    xfer->child_write = -1;
    xfer->hook_fd = dogechat_hook_fd (xfer->child_read,
                                      1, 0, 0,
                                      &xfer_network_child_read_cb,
                                      xfer);
}
Ejemplo n.º 5
0
int
irc_input_data (struct t_gui_buffer *buffer, const char *input_data, int flags)
{
    const char *ptr_data;
    char *data_with_colors, *msg;

    IRC_BUFFER_GET_SERVER_CHANNEL(buffer);

    if (buffer == irc_raw_buffer)
    {
        if (dogechat_strcasecmp (input_data, "q") == 0)
            dogechat_buffer_close (buffer);
    }
    else
    {
        /*
         * if send unknown commands is enabled and that input data is a
         * command, then send this command to IRC server
         */
        if (dogechat_config_boolean (irc_config_network_send_unknown_commands)
            && !dogechat_string_input_for_buffer (input_data))
        {
            if (ptr_server)
            {
                irc_server_sendf (ptr_server, flags, NULL,
                                  "%s", dogechat_utf8_next_char (input_data));
            }
            return DOGECHAT_RC_OK;
        }

        if (ptr_channel)
        {
            ptr_data = dogechat_string_input_for_buffer (input_data);
            if (!ptr_data)
                ptr_data = input_data;
            data_with_colors = irc_color_encode (
                ptr_data,
                dogechat_config_boolean (irc_config_network_colors_send));

            msg = strdup ((data_with_colors) ? data_with_colors : ptr_data);
            if (msg)
            {
                irc_input_send_user_message (buffer, flags, NULL, msg);
                free (msg);
            }

            if (data_with_colors)
                free (data_with_colors);
        }
        else
        {
            dogechat_printf (buffer,
                            _("%s%s: this buffer is not a channel!"),
                            dogechat_prefix ("error"), IRC_PLUGIN_NAME);
        }
    }

    return DOGECHAT_RC_OK;
}
Ejemplo n.º 6
0
void
xfer_network_recv_file_fork (struct t_xfer *xfer)
{
    pid_t pid;
    int rc;

    if (!xfer_network_create_pipe (xfer))
        return;

    if (xfer->start_resume > 0)
        xfer->file = open (xfer->local_filename,
                           O_APPEND | O_WRONLY | O_NONBLOCK);
    else
        xfer->file = open (xfer->local_filename,
                           O_CREAT | O_TRUNC | O_WRONLY | O_NONBLOCK,
                           0644);

    switch (pid = fork ())
    {
    case -1:  /* fork failed */
        dogechat_printf (NULL,
                         _("%s%s: unable to fork"),
                         dogechat_prefix ("error"), XFER_PLUGIN_NAME);
        xfer_close (xfer, XFER_STATUS_FAILED);
        xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE);
        return;
    case 0:  /* child process */
        rc = setuid (getuid ());
        (void) rc;
        close (xfer->child_read);
        switch (xfer->protocol)
        {
        case XFER_NO_PROTOCOL:
            _exit (EXIT_SUCCESS);
            break;
        case XFER_PROTOCOL_DCC:
            xfer_dcc_recv_file_child (xfer);
            break;
        case XFER_NUM_PROTOCOLS:
            break;
        }
        _exit (EXIT_SUCCESS);
    }

    /* parent process */
    xfer->child_pid = pid;
    close (xfer->child_write);
    xfer->child_write = -1;
    xfer->hook_fd = dogechat_hook_fd (xfer->child_read,
                                      1, 0, 0,
                                      &xfer_network_child_read_cb,
                                      xfer);
}
Ejemplo n.º 7
0
int
xfer_command_me (void *data, struct t_gui_buffer *buffer, int argc,
                 char **argv, char **argv_eol)
{
    struct t_xfer *ptr_xfer;

    /* make C compiler happy */
    (void) data;
    (void) argc;
    (void) argv;

    ptr_xfer = xfer_search_by_buffer (buffer);

    if (!ptr_xfer)
    {
        dogechat_printf (NULL,
                        _("%s%s: can't find xfer for buffer \"%s\""),
                        dogechat_prefix ("error"), XFER_PLUGIN_NAME,
                        dogechat_buffer_get_string (buffer, "name"));
        return DOGECHAT_RC_OK;
    }

    if (!XFER_HAS_ENDED(ptr_xfer->status))
    {
        xfer_chat_sendf (ptr_xfer, "\01ACTION %s\01\r\n",
                         (argv_eol[1]) ? argv_eol[1] : "");
        dogechat_printf_tags (buffer,
                             "no_highlight",
                             "%s%s%s %s%s",
                             dogechat_prefix ("action"),
                             dogechat_color ("chat_nick_self"),
                             ptr_xfer->local_nick,
                             dogechat_color ("chat"),
                             (argv_eol[1]) ? argv_eol[1] : "");
    }

    return DOGECHAT_RC_OK;
}
Ejemplo n.º 8
0
struct t_exec_cmd *
exec_command_search_running_id (const char *id)
{
    struct t_exec_cmd *ptr_exec_cmd;

    ptr_exec_cmd = exec_search_by_id (id);
    if (!ptr_exec_cmd)
    {
        dogechat_printf (NULL, _("%s%s: command id \"%s\" not found"),
                        dogechat_prefix ("error"), EXEC_PLUGIN_NAME, id);
        return NULL;
    }

    if (!ptr_exec_cmd->hook)
    {
        dogechat_printf (NULL,
                        _("%s%s: command with id \"%s\" is not running any "
                          "more"),
                        dogechat_prefix ("error"), EXEC_PLUGIN_NAME, id);
        return NULL;
    }

    return ptr_exec_cmd;
}
Ejemplo n.º 9
0
void
irc_input_send_user_message (struct t_gui_buffer *buffer, int flags,
                             const char *tags, char *message)
{
    int number, action;
    char hash_key[32], *str_args;
    struct t_hashtable *hashtable;

    IRC_BUFFER_GET_SERVER_CHANNEL(buffer);

    if (!ptr_server || !ptr_channel || !message || !message[0])
        return;

    if (!ptr_server->is_connected)
    {
        dogechat_printf (buffer,
                        _("%s%s: you are not connected to server"),
                        dogechat_prefix ("error"), IRC_PLUGIN_NAME);
        return;
    }
    hashtable = irc_server_sendf (ptr_server,
                                  flags | IRC_SERVER_SEND_RETURN_HASHTABLE,
                                  tags,
                                  "PRIVMSG %s :%s",
                                  ptr_channel->name, message);
    if (hashtable)
    {
        action = (strncmp (message, "\01ACTION ", 8) == 0);
        number = 1;
        while (1)
        {
            snprintf (hash_key, sizeof (hash_key), "args%d", number);
            str_args = dogechat_hashtable_get (hashtable, hash_key);
            if (!str_args)
                break;
            irc_input_user_message_display (buffer, action, str_args);
            number++;
        }
        dogechat_hashtable_free (hashtable);
    }
}
Ejemplo n.º 10
0
int
xfer_network_create_pipe (struct t_xfer *xfer)
{
    int child_pipe[2];

    if (pipe (child_pipe) < 0)
    {
        dogechat_printf (NULL,
                         _("%s%s: unable to create pipe: error %d %s"),
                         dogechat_prefix ("error"), XFER_PLUGIN_NAME,
                         errno, strerror (errno));
        xfer_close (xfer, XFER_STATUS_FAILED);
        xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE);
        return 0;
    }

    xfer->child_read = child_pipe[0];
    xfer->child_write = child_pipe[1];

    return 1;
}
Ejemplo n.º 11
0
int
xfer_network_timer_cb (void *arg_xfer, int remaining_calls)
{
    struct t_xfer *xfer;

    /* make C compiler happy */
    (void) remaining_calls;

    xfer = (struct t_xfer *)arg_xfer;

    if ((xfer->status == XFER_STATUS_WAITING)
            || (xfer->status == XFER_STATUS_CONNECTING))
    {
        dogechat_printf (NULL,
                         _("%s%s: timeout for \"%s\" with %s"),
                         dogechat_prefix ("error"), XFER_PLUGIN_NAME,
                         xfer->filename, xfer->remote_nick);
        xfer_close (xfer, XFER_STATUS_FAILED);
        xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE);
    }

    return DOGECHAT_RC_OK;
}
Ejemplo n.º 12
0
char *
irc_sasl_get_key_content (struct t_irc_server *server, const char *sasl_key)
{
    const char *dogechat_dir;
    char *key_path1, *key_path2, *content;

    if (!sasl_key)
        return NULL;

    content = NULL;

    dogechat_dir = dogechat_info_get ("dogechat_dir", "");
    key_path1 = dogechat_string_replace (sasl_key, "%h", dogechat_dir);
    key_path2 = (key_path1) ?
        dogechat_string_expand_home (key_path1) : NULL;

    if (key_path2)
        content = dogechat_file_get_content (key_path2);

    if (!content)
    {
        dogechat_printf (
            server->buffer,
            _("%s%s: unable to read private key in file \"%s\""),
            dogechat_prefix ("error"),
            IRC_PLUGIN_NAME,
            (key_path2) ? key_path2 : ((key_path1) ? key_path1 : sasl_key));
    }

    if (key_path1)
        free (key_path1);
    if (key_path2)
        free (key_path2);

    return content;
}
Ejemplo n.º 13
0
int
script_action_show_source_process_cb (void *data, const char *command,
                                      int return_code, const char *out,
                                      const char *err)
{
    char *pos, *filename, *filename_loaded, line[4096], *ptr_line;
    char *diff_command;
    const char *ptr_diff_command;
    struct t_script_repo *ptr_script;
    FILE *file;
    int length, diff_made;

    /* make C compiler happy */
    (void) data;
    (void) out;

    if (return_code >= 0)
    {
        pos = strrchr (command, '/');

        if (err && err[0])
        {
            dogechat_printf (NULL,
                            _("%s%s: error downloading script \"%s\": %s"),
                            dogechat_prefix ("error"),
                            SCRIPT_PLUGIN_NAME,
                            (pos) ? pos + 1 : "?",
                            err);
            return DOGECHAT_RC_OK;
        }

        if (pos)
        {
            ptr_script = script_repo_search_by_name_ext (pos + 1);
            if (ptr_script)
            {
                filename = script_config_get_script_download_filename (ptr_script,
                                                                       ".repository");
                if (filename)
                {
                    /*
                     * read file and display content on script buffer
                     * (only if script buffer is still displaying detail of
                     * this script)
                     */
                    if (script_buffer && script_buffer_detail_script
                        && (script_buffer_detail_script == ptr_script))
                    {
                        file = fopen (filename, "r");
                        if (file)
                        {
                            while (!feof (file))
                            {
                                ptr_line = fgets (line, sizeof (line) - 1, file);
                                if (ptr_line)
                                {
                                    dogechat_printf_y (script_buffer,
                                                      script_buffer_detail_script_last_line++,
                                                      "%s", ptr_line);
                                }
                            }
                            fclose (file);
                        }
                        else
                        {
                            dogechat_printf_y (script_buffer,
                                              script_buffer_detail_script_last_line++,
                                              _("Error: file not found"));
                        }
                        dogechat_printf_y (script_buffer,
                                          script_buffer_detail_script_last_line++,
                                          "%s----------------------------------------"
                                          "----------------------------------------",
                                          dogechat_color ("lightcyan"));
                    }
                    diff_made = 0;
                    ptr_diff_command = script_config_get_diff_command ();
                    if (ptr_diff_command && ptr_diff_command[0]
                        && (ptr_script->status & SCRIPT_STATUS_NEW_VERSION))
                    {
                        /*
                         * diff command set => get the diff with a new process,
                         * file will be deleted later (in callback of this new
                         * process)
                         */
                        filename_loaded = script_repo_get_filename_loaded (ptr_script);
                        if (filename_loaded)
                        {
                            length = strlen (ptr_diff_command) + 1
                                + strlen (filename_loaded) + 1
                                + strlen (filename) + 1;
                            diff_command = malloc (length);
                            if (diff_command)
                            {
                                snprintf (diff_command, length,
                                          "%s %s %s",
                                          ptr_diff_command,
                                          filename_loaded,
                                          filename);
                                script_buffer_detail_script_last_line++;
                                script_buffer_detail_script_line_diff = script_buffer_detail_script_last_line;
                                dogechat_printf_y (script_buffer,
                                                  script_buffer_detail_script_last_line++,
                                                  "%s", diff_command);
                                dogechat_printf_y (script_buffer,
                                                  script_buffer_detail_script_last_line++,
                                                  "%s----------------------------------------"
                                                  "----------------------------------------",
                                                  dogechat_color ("magenta"));
                                dogechat_hook_process (diff_command, 10000,
                                                      &script_action_show_diff_process_cb,
                                                      filename);
                                diff_made = 1;
                                free (diff_command);
                            }
                            free (filename_loaded);
                        }
                    }
                    if (!diff_made)
                    {
                        /* no diff made: delete temporary file now */
                        unlink (filename);
                        free (filename);
                    }
                }
            }
        }
    }

    return DOGECHAT_RC_OK;
}
Ejemplo n.º 14
0
int
xfer_network_connect_chat_recv_cb (void *data, int status, int gnutls_rc,
                                   int sock, const char *error,
                                   const char *ip_address)
{
    struct t_xfer *xfer;
    int flags;

    /* make C compiler happy */
    (void) gnutls_rc;
    (void) ip_address;

    xfer = (struct t_xfer*)data;

    dogechat_unhook (xfer->hook_connect);
    xfer->hook_connect = NULL;

    /* connection OK? */
    if (status == DOGECHAT_HOOK_CONNECT_OK)
    {
        xfer->sock = sock;

        flags = fcntl (xfer->sock, F_GETFL);
        if (flags == -1)
            flags = 0;
        if (fcntl (xfer->sock, F_SETFL, flags | O_NONBLOCK) == -1)
        {
            dogechat_printf (NULL,
                             _("%s%s: unable to set option \"nonblock\" "
                               "for socket: error %d %s"),
                             dogechat_prefix ("error"), XFER_PLUGIN_NAME,
                             errno, strerror (errno));
            close (xfer->sock);
            xfer->sock = -1;
            xfer_close (xfer, XFER_STATUS_FAILED);
            xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE);
            return DOGECHAT_RC_OK;
        }

        xfer->hook_fd = dogechat_hook_fd (xfer->sock,
                                          1, 0, 0,
                                          &xfer_chat_recv_cb,
                                          xfer);

        xfer_chat_open_buffer (xfer);
        xfer->status = XFER_STATUS_ACTIVE;
        xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE);

        return DOGECHAT_RC_OK;
    }

    /* connection error */
    switch (status)
    {
    case DOGECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND:
        dogechat_printf (NULL,
                         (xfer->proxy && xfer->proxy[0]) ?
                         _("%s%s: proxy address \"%s\" not found") :
                         _("%s%s: address \"%s\" not found"),
                         dogechat_prefix ("error"), XFER_PLUGIN_NAME,
                         xfer->remote_address_str);
        break;
    case DOGECHAT_HOOK_CONNECT_IP_ADDRESS_NOT_FOUND:
        dogechat_printf (NULL,
                         (xfer->proxy && xfer->proxy[0]) ?
                         _("%s%s: proxy IP address not found") :
                         _("%s%s: IP address not found"),
                         dogechat_prefix ("error"), XFER_PLUGIN_NAME);
        break;
    case DOGECHAT_HOOK_CONNECT_CONNECTION_REFUSED:
        dogechat_printf (NULL,
                         (xfer->proxy && xfer->proxy[0]) ?
                         _("%s%s: proxy connection refused") :
                         _("%s%s: connection refused"),
                         dogechat_prefix ("error"), XFER_PLUGIN_NAME);
        break;
    case DOGECHAT_HOOK_CONNECT_PROXY_ERROR:
        dogechat_printf (NULL,
                         _("%s%s: proxy fails to establish connection to "
                           "server (check username/password if used and if "
                           "server address/port is allowed by proxy)"),
                         dogechat_prefix ("error"), XFER_PLUGIN_NAME);
        break;
    case DOGECHAT_HOOK_CONNECT_LOCAL_HOSTNAME_ERROR:
        dogechat_printf (NULL,
                         _("%s%s: unable to set local hostname/IP"),
                         dogechat_prefix ("error"), XFER_PLUGIN_NAME);
        break;
    case DOGECHAT_HOOK_CONNECT_MEMORY_ERROR:
        dogechat_printf (NULL,
                         _("%s%s: not enough memory"),
                         dogechat_prefix ("error"), XFER_PLUGIN_NAME);
        break;
    case DOGECHAT_HOOK_CONNECT_TIMEOUT:
        dogechat_printf (NULL,
                         _("%s%s: timeout"),
                         dogechat_prefix ("error"), XFER_PLUGIN_NAME);
        break;
    case DOGECHAT_HOOK_CONNECT_SOCKET_ERROR:
        dogechat_printf (NULL,
                         _("%s%s: unable to create socket"),
                         dogechat_prefix ("error"), XFER_PLUGIN_NAME);
        break;
    default:
        dogechat_printf (NULL,
                         _("%s%s: unable to connect: unexpected error (%d)"),
                         dogechat_prefix ("error"), XFER_PLUGIN_NAME,
                         status);
        break;
    }
    if (error && error[0])
    {
        dogechat_printf (NULL,
                         _("%s%s: error: %s"),
                         dogechat_prefix ("error"), XFER_PLUGIN_NAME, error);
    }

    xfer_close (xfer, XFER_STATUS_FAILED);
    xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE);

    return DOGECHAT_RC_OK;
}
Ejemplo n.º 15
0
int
script_action_install_process_cb (void *data, const char *command,
                                  int return_code, const char *out,
                                  const char *err)
{
    char *pos, *filename, *filename2, str_signal[256];
    int quiet, length;
    struct t_script_repo *ptr_script;

    /* make C compiler happy */
    (void) out;

    quiet = (data) ? 1 : 0;

    if (return_code >= 0)
    {
        pos = strrchr (command, '/');

        if (err && err[0])
        {
            dogechat_printf (NULL,
                            _("%s%s: error downloading script \"%s\": %s"),
                            dogechat_prefix ("error"),
                            SCRIPT_PLUGIN_NAME,
                            (pos) ? pos + 1 : "?",
                            err);
            return DOGECHAT_RC_OK;
        }

        if (pos)
        {
            ptr_script = script_repo_search_by_name_ext (pos + 1);
            if (ptr_script)
            {
                filename = script_config_get_script_download_filename (ptr_script,
                                                                       NULL);
                if (filename)
                {
                    length = 16 + strlen (filename) + 1;
                    filename2 = malloc (length);
                    if (filename2)
                    {
                        snprintf (filename2, length,
                                  "%s%s%s",
                                  (quiet && dogechat_config_boolean (script_config_look_quiet_actions)) ? "-q " : "",
                                  (dogechat_config_boolean (script_config_scripts_autoload)) ? "-a " : "",
                                  filename);
                        snprintf (str_signal, sizeof (str_signal),
                                  "%s_script_install",
                                  script_language[ptr_script->language]);
                        (void) dogechat_hook_signal_send (str_signal,
                                                         DOGECHAT_HOOK_SIGNAL_STRING,
                                                         filename2);
                        free (filename2);
                    }
                    free (filename);
                }

                /* schedule install of next script */
                dogechat_hook_timer (10, 0, 1,
                                    &script_action_installnext_timer_cb,
                                    (quiet) ? (void *)1 : (void *)0);
            }
        }
    }

    return DOGECHAT_RC_OK;
}
Ejemplo n.º 16
0
int
relay_server_sock_cb (void *data, int fd)
{
    struct t_relay_server *server;
    struct sockaddr_in client_addr;
    struct sockaddr_in6 client_addr6;
    socklen_t client_addr_size;
    void *ptr_addr;
    int client_fd, flags, set;
    char ipv4_address[INET_ADDRSTRLEN + 1], ipv6_address[INET6_ADDRSTRLEN + 1];
    char *ptr_ip_address;

    /* make C compiler happy */
    (void) fd;

    server = (struct t_relay_server *)data;

    if (server->ipv6)
    {
        ptr_addr = &client_addr6;
        client_addr_size = sizeof (struct sockaddr_in6);
    }
    else
    {
        ptr_addr = &client_addr;
        client_addr_size = sizeof (struct sockaddr_in);
    }

    memset (ptr_addr, 0, client_addr_size);

    client_fd = accept (server->sock, (struct sockaddr *)ptr_addr,
                        &client_addr_size);
    if (client_fd < 0)
    {
        dogechat_printf (NULL,
                        _("%s%s: cannot accept client on port %d (%s): error %d %s"),
                        dogechat_prefix ("error"), RELAY_PLUGIN_NAME,
                        server->port, server->protocol_string,
                        errno, strerror (errno));
        return DOGECHAT_RC_OK;
    }

    ptr_ip_address = NULL;
    if (server->ipv6)
    {
        if (inet_ntop (AF_INET6,
                       &(client_addr6.sin6_addr),
                       ipv6_address,
                       INET6_ADDRSTRLEN))
        {
            ptr_ip_address = ipv6_address;

            if (strncmp (ptr_ip_address, "::ffff:", 7) == 0)
            {
                /* actually an IPv4-mapped IPv6 address, so skip "::ffff:" */
                ptr_ip_address += 7;
            }
        }
    }
    else
    {
        if (inet_ntop (AF_INET,
                       &(client_addr.sin_addr),
                       ipv4_address,
                       INET_ADDRSTRLEN))
        {
            ptr_ip_address = ipv4_address;
        }
    }

    /* check if IP is allowed, if not, just close socket */
    if (relay_config_regex_allowed_ips
        && (regexec (relay_config_regex_allowed_ips, ptr_ip_address, 0, NULL, 0) != 0))
    {
        if (dogechat_relay_plugin->debug >= 1)
        {
            dogechat_printf (NULL,
                            _("%s%s: IP address \"%s\" not allowed for relay"),
                            dogechat_prefix ("error"),
                            RELAY_PLUGIN_NAME,
                            ptr_ip_address);
        }
        close (client_fd);
        return DOGECHAT_RC_OK;
    }

    /* set non-blocking mode for socket */
    flags = fcntl (client_fd, F_GETFL);
    if (flags == -1)
        flags = 0;
    fcntl (client_fd, F_SETFL, flags | O_NONBLOCK);

    /* set socket option SO_REUSEADDR */
    set = 1;
    if (setsockopt (client_fd, SOL_SOCKET, SO_REUSEADDR,
                    (void *) &set, sizeof (set)) < 0)
    {
        dogechat_printf (NULL,
                        _("%s%s: cannot set socket option \"%s\" to %d: "
                          "error %d %s"),
                        dogechat_prefix ("error"), RELAY_PLUGIN_NAME,
                        "SO_REUSEADDR", set, errno, strerror (errno));
        close (client_fd);
        return DOGECHAT_RC_OK;
    }

    /* add the client */
    relay_client_new (client_fd, ptr_ip_address, server);

    return DOGECHAT_RC_OK;
}
Ejemplo n.º 17
0
int
relay_server_create_socket (struct t_relay_server *server)
{
    int domain, set, max_clients, addr_size;
    struct sockaddr_in server_addr;
    struct sockaddr_in6 server_addr6;
    const char *bind_address;
    void *ptr_addr;

    bind_address = dogechat_config_string (relay_config_network_bind_address);

    if (server->ipv6)
    {
        domain = AF_INET6;
        memset (&server_addr6, 0, sizeof (struct sockaddr_in6));
        server_addr6.sin6_family = domain;
        server_addr6.sin6_port = htons (server->port);
        server_addr6.sin6_addr = in6addr_any;
        if (bind_address && bind_address[0])
        {
            if (!inet_pton (domain, bind_address, &server_addr6.sin6_addr))
            {
                dogechat_printf (NULL,
                                /* TRANSLATORS: second "%s" is "IPv4" or "IPv6" */
                                _("%s%s: invalid bind address \"%s\" for %s"),
                                dogechat_prefix ("error"), RELAY_PLUGIN_NAME,
                                bind_address, "IPv6");
                return 0;
            }
        }
        ptr_addr = &server_addr6;
        addr_size = sizeof (struct sockaddr_in6);
    }
    else
    {
        domain = AF_INET;
        memset (&server_addr, 0, sizeof (struct sockaddr_in));
        server_addr.sin_family = domain;
        server_addr.sin_port = htons (server->port);
        server_addr.sin_addr.s_addr = INADDR_ANY;
        if (bind_address && bind_address[0])
        {
            if (!inet_pton (domain, bind_address, &server_addr.sin_addr))
            {
                dogechat_printf (NULL,
                                /* TRANSLATORS: second "%s" is "IPv4" or "IPv6" */
                                _("%s%s: invalid bind address \"%s\" for %s"),
                                dogechat_prefix ("error"), RELAY_PLUGIN_NAME,
                                bind_address, "IPv4");
                return 0;
            }
        }
        ptr_addr = &server_addr;
        addr_size = sizeof (struct sockaddr_in);
    }

    /* create socket */
    server->sock = socket (domain, SOCK_STREAM, 0);
    if (server->sock < 0)
    {
        dogechat_printf (NULL,
                        _("%s%s: cannot create socket: error %d %s"),
                        dogechat_prefix ("error"), RELAY_PLUGIN_NAME,
                        errno, strerror (errno));
        if (errno == EAFNOSUPPORT)
        {
            dogechat_printf (NULL,
                            _("%s%s: try /set relay.network.ipv6 off"),
                            dogechat_prefix ("error"), RELAY_PLUGIN_NAME);
        }
        return 0;
    }

#ifdef IPV6_V6ONLY
    /* set option IPV6_V6ONLY to 0 or 1 */
    if (server->ipv6)
    {
        set = (server->ipv4) ? 0 : 1;
        if (setsockopt (server->sock, IPPROTO_IPV6, IPV6_V6ONLY,
                        (void *) &set, sizeof (set)) < 0)
        {
            dogechat_printf (NULL,
                            _("%s%s: cannot set socket option \"%s\" "
                              "to %d: error %d %s"),
                            dogechat_prefix ("error"), RELAY_PLUGIN_NAME,
                            "IPV6_V6ONLY", set, errno, strerror (errno));
            close (server->sock);
            server->sock = -1;
            return 0;
        }
    }
#endif /* IPV6_V6ONLY */

    /* set option SO_REUSEADDR to 1 */
    set = 1;
    if (setsockopt (server->sock, SOL_SOCKET, SO_REUSEADDR,
                    (void *) &set, sizeof (set)) < 0)
    {
        dogechat_printf (NULL,
                        _("%s%s: cannot set socket option \"%s\" to %d: "
                          "error %d %s"),
                        dogechat_prefix ("error"), RELAY_PLUGIN_NAME,
                        "SO_REUSEADDR", set, errno, strerror (errno));
        close (server->sock);
        server->sock = -1;
        return 0;
    }

    /* set option SO_KEEPALIVE to 1 */
    set = 1;
    if (setsockopt (server->sock, SOL_SOCKET, SO_KEEPALIVE,
                    (void *) &set, sizeof (set)) < 0)
    {
        dogechat_printf (NULL,
                        _("%s%s: cannot set socket option \"%s\" to %d: "
                          "error %d %s"),
                        dogechat_prefix ("error"), RELAY_PLUGIN_NAME,
                        "SO_KEEPALIVE", set, errno, strerror (errno));
        close (server->sock);
        server->sock = -1;
        return 0;
    }

    /* bind */
    if (bind (server->sock, (struct sockaddr *)ptr_addr, addr_size) < 0)
    {
        dogechat_printf (NULL,
                        _("%s%s: cannot \"bind\" on port %d (%s): error %d %s"),
                        dogechat_prefix ("error"), RELAY_PLUGIN_NAME,
                        server->port, server->protocol_string,
                        errno, strerror (errno));
        close (server->sock);
        server->sock = -1;
        return 0;
    }

    max_clients = dogechat_config_integer (relay_config_network_max_clients);

    if (listen (server->sock, max_clients) != 0)
    {
        dogechat_printf (NULL,
                        _("%s%s: cannot \"listen\" on port %d (%s): error %d %s"),
                        dogechat_prefix ("error"), RELAY_PLUGIN_NAME,
                        server->port, server->protocol_string,
                        errno, strerror (errno));
        close (server->sock);
        server->sock = -1;
        return 0;
    }

    dogechat_printf (NULL,
                    _("%s: listening on port %d (relay: %s, %s, max %d clients)"),
                    RELAY_PLUGIN_NAME,
                    server->port,
                    server->protocol_string,
                    ((server->ipv4 && server->ipv6) ? "IPv4+6" : ((server->ipv6) ? "IPv6" : "IPv4")),
                    max_clients);

    server->hook_fd = dogechat_hook_fd (server->sock,
                                       1, 0, 0,
                                       &relay_server_sock_cb,
                                       server);

    server->start_time = time (NULL);

    return 1;
}
Ejemplo n.º 18
0
void *
dogechat_js_exec (struct t_plugin_script *script,
                 int ret_type, const char *function,
                 const char *format, void **argv)
{
    struct t_plugin_script *old_js_current_script;
    DogechatJsV8 *js_v8;
    void *ret_value;
    v8::Handle<v8::Value> argv2[16], ret_js;
    int i, argc, *ret_int;

    ret_value = NULL;

    old_js_current_script = js_current_script;
    js_current_script = script;
    js_v8 = (DogechatJsV8 *)(script->interpreter);

    if (!js_v8->functionExists(function))
    {
        dogechat_printf (NULL,
                        dogechat_gettext ("%s%s: unable to run function \"%s\""),
                        dogechat_prefix ("error"), JS_PLUGIN_NAME, function);
        goto end;
    }

    argc = 0;
    if (format && format[0])
    {
        argc = strlen (format);
        for (i = 0; i < argc; i++)
        {
            switch (format[i])
            {
                case 's': /* string */
                    argv2[i] = v8::String::New((const char *)argv[i]);
                    break;
                case 'i': /* integer */
                    argv2[i] = v8::Integer::New(*((int *)argv[i]));
                    break;
                case 'h': /* hash */
                    argv2[i] = dogechat_js_hashtable_to_object (
                        (struct t_hashtable *)argv[i]);
                    break;
            }
        }
    }

    ret_js = js_v8->execFunction(function,
                                 argc,
                                 (argc > 0) ? argv2 : NULL);

    if (!ret_js.IsEmpty())
    {
        if ((ret_type == DOGECHAT_SCRIPT_EXEC_STRING) && (ret_js->IsString()))
        {
            v8::String::Utf8Value temp_str(ret_js);
            ret_value = *temp_str;
        }
        else if ((ret_type == DOGECHAT_SCRIPT_EXEC_INT) && (ret_js->IsInt32()))
        {
            ret_int = (int *)malloc (sizeof (*ret_int));
            if (ret_int)
                *ret_int = (int)(ret_js->IntegerValue());
            ret_value = ret_int;
        }
        else if ((ret_type == DOGECHAT_SCRIPT_EXEC_HASHTABLE)
                 && (ret_js->IsObject()))
        {
            ret_value = (struct t_hashtable *)dogechat_js_object_to_hashtable (
                ret_js->ToObject(),
                DOGECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE,
                DOGECHAT_HASHTABLE_STRING,
                DOGECHAT_HASHTABLE_STRING);
        }
        else
        {
            dogechat_printf (NULL,
                            dogechat_gettext ("%s%s: function \"%s\" must "
                                             "return a valid value"),
                            dogechat_prefix ("error"), JS_PLUGIN_NAME,
                            function);
        }
    }

    if (!ret_value)
    {
        dogechat_printf (NULL,
                        dogechat_gettext ("%s%s: error in function \"%s\""),
                        dogechat_prefix ("error"), JS_PLUGIN_NAME, function);
    }

end:
    js_current_script = old_js_current_script;

    return ret_value;
}
Ejemplo n.º 19
0
int
xfer_network_child_read_cb (void *arg_xfer, int fd)
{
    struct t_xfer *xfer;
    char bufpipe[1 + 1 + 32 + 1];
    int num_read;

    /* make C compiler happy */
    (void) fd;

    xfer = (struct t_xfer *)arg_xfer;

    num_read = read (xfer->child_read, bufpipe, sizeof (bufpipe));
    if (num_read > 0)
    {
        sscanf (bufpipe + 2, "%llu", &xfer->pos);
        xfer->last_activity = time (NULL);
        xfer_file_calculate_speed (xfer, 0);

        /* read error code */
        switch (bufpipe[1] - '0')
        {
        /* errors for sender */
        case XFER_ERROR_READ_LOCAL:
            dogechat_printf (NULL,
                             _("%s%s: unable to read local file"),
                             dogechat_prefix ("error"), XFER_PLUGIN_NAME);
            break;
        case XFER_ERROR_SEND_BLOCK:
            dogechat_printf (NULL,
                             _("%s%s: unable to send block to receiver"),
                             dogechat_prefix ("error"), XFER_PLUGIN_NAME);
            break;
        case XFER_ERROR_READ_ACK:
            dogechat_printf (NULL,
                             _("%s%s: unable to read ACK from receiver"),
                             dogechat_prefix ("error"), XFER_PLUGIN_NAME);
            break;
        /* errors for receiver */
        case XFER_ERROR_CONNECT_SENDER:
            dogechat_printf (NULL,
                             _("%s%s: unable to connect to sender"),
                             dogechat_prefix ("error"), XFER_PLUGIN_NAME);
            break;
        case XFER_ERROR_RECV_BLOCK:
            dogechat_printf (NULL,
                             _("%s%s: unable to receive block from sender"),
                             dogechat_prefix ("error"), XFER_PLUGIN_NAME);
            break;
        case XFER_ERROR_WRITE_LOCAL:
            dogechat_printf (NULL,
                             _("%s%s: unable to write local file"),
                             dogechat_prefix ("error"), XFER_PLUGIN_NAME);
            break;
        case XFER_ERROR_SEND_ACK:
            dogechat_printf (NULL,
                             _("%s%s: unable to send ACK to sender"),
                             dogechat_prefix ("error"), XFER_PLUGIN_NAME);
            break;
        case XFER_ERROR_HASH_MISMATCH:
            dogechat_printf (NULL,
                             _("%s%s: wrong CRC32 for file %s"),
                             dogechat_prefix ("error"), XFER_PLUGIN_NAME,
                             xfer->filename);
            xfer->hash_status = XFER_HASH_STATUS_MISMATCH;
            break;
        case XFER_ERROR_HASH_RESUME_ERROR:
            dogechat_printf (NULL,
                             _("%s%s: CRC32 error while resuming"),
                             dogechat_prefix ("error"), XFER_PLUGIN_NAME);
            xfer->hash_status = XFER_HASH_STATUS_RESUME_ERROR;
            break;
        }

        /* read new DCC status */
        switch (bufpipe[0] - '0')
        {
        case XFER_STATUS_CONNECTING:
            xfer->status = XFER_STATUS_CONNECTING;
            xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE);
            break;
        case XFER_STATUS_ACTIVE:
            if (xfer->status == XFER_STATUS_CONNECTING)
            {
                /* connection was successful by child, init transfer times */
                xfer->status = XFER_STATUS_ACTIVE;
                xfer->start_transfer = time (NULL);
                xfer->last_check_time = time (NULL);
                xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE);
            }
            else
                xfer_buffer_refresh (DOGECHAT_HOTLIST_LOW);
            break;
        case XFER_STATUS_DONE:
            xfer_close (xfer, XFER_STATUS_DONE);
            xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE);
            break;
        case XFER_STATUS_FAILED:
            xfer_close (xfer, XFER_STATUS_FAILED);
            xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE);
            break;
        case XFER_STATUS_HASHING:
            xfer->status = XFER_STATUS_HASHING;
            xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE);
            break;
        case XFER_STATUS_HASHED:
            if (bufpipe[1] - '0' == XFER_NO_ERROR)
                xfer->hash_status = XFER_HASH_STATUS_MATCH;
            xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE);
            break;
        }
    }

    return DOGECHAT_RC_OK;
}
Ejemplo n.º 20
0
void
fifo_create ()
{
    int filename_length;
    const char *fifo_option, *dogechat_home;

    fifo_option = dogechat_config_get_plugin ("fifo");
    if (!fifo_option)
    {
        dogechat_config_set_plugin ("fifo", "on");
        fifo_option = dogechat_config_get_plugin ("fifo");
    }

    dogechat_home = dogechat_info_get ("dogechat_dir", "");

    if (fifo_option && dogechat_home)
    {
        fifo_remove_old_pipes ();

        if (dogechat_strcasecmp (fifo_option, "on") == 0)
        {
            /*
             * build FIFO filename:
             *   "<dogechat_home>/dogechat_fifo_" + process PID
             */
            if (!fifo_filename)
            {
                filename_length = strlen (dogechat_home) + 64;
                fifo_filename = malloc (filename_length);
                snprintf (fifo_filename, filename_length,
                          "%s/%s%d",
                          dogechat_home, FIFO_FILENAME_PREFIX, (int) getpid());
            }

            fifo_fd = -1;

            /* create FIFO pipe, writable for user only */
            if (mkfifo (fifo_filename, 0600) == 0)
            {
                /* open FIFO pipe in read-only, non-blocking mode */
                if ((fifo_fd = open (fifo_filename,
                                     O_RDONLY | O_NONBLOCK)) != -1)
                {
                    if ((dogechat_fifo_plugin->debug >= 1) || !fifo_quiet)
                    {
                        dogechat_printf (NULL,
                                        _("%s: pipe opened (file: %s)"),
                                        FIFO_PLUGIN_NAME,
                                        fifo_filename);
                    }
                    fifo_fd_hook = dogechat_hook_fd (fifo_fd, 1, 0, 0,
                                                    &fifo_read, NULL);
                }
                else
                    dogechat_printf (NULL,
                                    _("%s%s: unable to open pipe (%s) for "
                                      "reading"),
                                    dogechat_prefix ("error"), FIFO_PLUGIN_NAME,
                                    fifo_filename);
            }
            else
            {
                dogechat_printf (NULL,
                                _("%s%s: unable to create pipe for remote "
                                  "control (%s): error %d %s"),
                                dogechat_prefix ("error"), FIFO_PLUGIN_NAME,
                                fifo_filename, errno, strerror (errno));
            }
        }
    }
}
Ejemplo n.º 21
0
int
alias_cb (void *data, struct t_gui_buffer *buffer, int argc, char **argv,
          char **argv_eol)
{
    struct t_alias *ptr_alias;
    char **commands, **ptr_cmd, **ptr_next_cmd;
    char *args_replaced, *alias_command;
    int some_args_replaced, length1, length2;

    /* make C compiler happy */
    (void) argv;

    ptr_alias = (struct t_alias *)data;

    if (ptr_alias->running)
    {
        dogechat_printf (NULL,
                        _("%s%s: error, circular reference when calling "
                          "alias \"%s\""),
                        dogechat_prefix ("error"), ALIAS_PLUGIN_NAME,
                        ptr_alias->name);
        return DOGECHAT_RC_OK;
    }
    else
    {
        /* an alias can contain many commands separated by ';' */
        commands = dogechat_string_split_command (ptr_alias->command, ';');
        if (commands)
        {
            some_args_replaced = 0;
            ptr_alias->running = 1;
            for (ptr_cmd = commands; *ptr_cmd; ptr_cmd++)
            {
                ptr_next_cmd = ptr_cmd;
                ptr_next_cmd++;

                args_replaced = alias_replace_args (*ptr_cmd,
                                                    (argc > 1) ? argv_eol[1] : "");
                if (args_replaced && (strcmp (args_replaced, *ptr_cmd) != 0))
                    some_args_replaced = 1;

                /*
                 * if alias has arguments, they are now
                 * arguments of the last command in the list (if no $1,$2,..$*)
                 * was found
                 */
                if ((*ptr_next_cmd == NULL) && argv_eol[1] && (!some_args_replaced))
                {
                    length1 = strlen (*ptr_cmd);
                    length2 = strlen (argv_eol[1]);

                    alias_command = malloc (1 + length1 + 1 + length2 + 1);
                    if (alias_command)
                    {
                        if (!dogechat_string_is_command_char (*ptr_cmd))
                            strcpy (alias_command, "/");
                        else
                            alias_command[0] = '\0';

                        strcat (alias_command, *ptr_cmd);
                        strcat (alias_command, " ");
                        strcat (alias_command, argv_eol[1]);

                        alias_run_command (&buffer,
                                           alias_command);
                        free (alias_command);
                    }
                }
                else
                {
                    if (dogechat_string_is_command_char (*ptr_cmd))
                    {
                        alias_run_command (&buffer,
                                           (args_replaced) ? args_replaced : *ptr_cmd);
                    }
                    else
                    {
                        alias_command = malloc (1 + strlen((args_replaced) ? args_replaced : *ptr_cmd) + 1);
                        if (alias_command)
                        {
                            strcpy (alias_command, "/");
                            strcat (alias_command, (args_replaced) ? args_replaced : *ptr_cmd);
                            alias_run_command (&buffer,
                                               alias_command);
                            free (alias_command);
                        }
                    }
                }

                if (args_replaced)
                    free (args_replaced);
            }
            ptr_alias->running = 0;
            dogechat_string_free_split_command (commands);
        }
    }
    return DOGECHAT_RC_OK;
}
Ejemplo n.º 22
0
int
dogechat_plugin_init (struct t_dogechat_plugin *plugin, int argc, char *argv[])
{
    int i, auto_connect, upgrading;

    dogechat_plugin = plugin;

    if (!irc_config_init ())
        return DOGECHAT_RC_ERROR;

    irc_config_read ();

    irc_command_init ();

    irc_info_init ();

    irc_redirect_init ();

    irc_notify_init ();

    /* hook some signals */
    irc_debug_init ();
    dogechat_hook_signal ("quit", &irc_signal_quit_cb, NULL);
    dogechat_hook_signal ("upgrade", &irc_signal_upgrade_cb, NULL);
    dogechat_hook_signal ("xfer_send_ready", &irc_server_xfer_send_ready_cb, NULL);
    dogechat_hook_signal ("xfer_resume_ready", &irc_server_xfer_resume_ready_cb, NULL);
    dogechat_hook_signal ("xfer_send_accept_resume", &irc_server_xfer_send_accept_resume_cb, NULL);
    dogechat_hook_signal ("irc_input_send", &irc_input_send_cb, NULL);

    /* hook hsignals for redirection */
    dogechat_hook_hsignal ("irc_redirect_pattern", &irc_redirect_pattern_hsignal_cb, NULL);
    dogechat_hook_hsignal ("irc_redirect_command", &irc_redirect_command_hsignal_cb, NULL);

    /* modifiers */
    dogechat_hook_modifier ("irc_color_decode", &irc_color_modifier_cb, NULL);
    dogechat_hook_modifier ("irc_color_encode", &irc_color_modifier_cb, NULL);
    dogechat_hook_modifier ("irc_color_decode_ansi", &irc_color_modifier_cb, NULL);

    /* hook completions */
    irc_completion_init ();

    irc_bar_item_init ();

    /* look at arguments */
    auto_connect = 1;
    upgrading = 0;
    for (i = 0; i < argc; i++)
    {
        if ((dogechat_strcasecmp (argv[i], "-a") == 0)
            || (dogechat_strcasecmp (argv[i], "--no-connect") == 0))
        {
            auto_connect = 0;
        }
        else if ((dogechat_strncasecmp (argv[i], IRC_PLUGIN_NAME, 3) == 0))
        {
            if (!irc_server_alloc_with_url (argv[i]))
            {
                dogechat_printf (
                    NULL,
                    _("%s%s: unable to add temporary server \"%s\" (check "
                      "if there is already a server with this name)"),
                    dogechat_prefix ("error"), IRC_PLUGIN_NAME, argv[i]);
            }
        }
        else if (dogechat_strcasecmp (argv[i], "--upgrade") == 0)
        {
            upgrading = 1;
        }
    }

    if (upgrading)
    {
        if (!irc_upgrade_load ())
        {
            dogechat_printf (
                NULL,
                _("%s%s: WARNING: some network connections may still be "
                  "opened and not visible, you should restart DogeChat now "
                  "(with /quit)."),
                dogechat_prefix ("error"), IRC_PLUGIN_NAME);
        }
    }
    else
    {
        irc_server_auto_connect (auto_connect);
    }

    irc_hook_timer = dogechat_hook_timer (1 * 1000, 0, 0,
                                         &irc_server_timer_cb, NULL);

    return DOGECHAT_RC_OK;
}
Ejemplo n.º 23
0
int
irc_signal_upgrade_cb (void *data, const char *signal, const char *type_data,
                       void *signal_data)
{
    struct t_irc_server *ptr_server;
    int quit, ssl_disconnected;

    /* make C compiler happy */
    (void) data;
    (void) signal;
    (void) type_data;

    irc_signal_upgrade_received = 1;

    quit = (signal_data && (strcmp (signal_data, "quit") == 0));
    ssl_disconnected = 0;

    for (ptr_server = irc_servers; ptr_server;
         ptr_server = ptr_server->next_server)
    {
        /*
         * FIXME: it's not possible to upgrade with SSL servers connected
         * (GnuTLS library can't reload data after upgrade), so we close
         * connection for all SSL servers currently connected
         */
        if (ptr_server->is_connected && (ptr_server->ssl_connected || quit))
        {
            if (!quit)
            {
                ssl_disconnected++;
                dogechat_printf (
                    ptr_server->buffer,
                    _("%s%s: disconnecting from server because upgrade can't "
                      "work for servers connected via SSL"),
                    dogechat_prefix ("error"), IRC_PLUGIN_NAME);
            }
            irc_server_disconnect (ptr_server, 0, 0);
            /*
             * schedule reconnection: DogeChat will reconnect to this server
             * after restart
             */
            ptr_server->index_current_address = 0;
            ptr_server->reconnect_delay = IRC_SERVER_OPTION_INTEGER(ptr_server, IRC_SERVER_OPTION_AUTORECONNECT_DELAY);
            ptr_server->reconnect_start = time (NULL) - ptr_server->reconnect_delay - 1;
        }
    }
    if (ssl_disconnected > 0)
    {
        dogechat_printf (
            NULL,
            /* TRANSLATORS: "%s" after "%d" is "server" or "servers" */
            _("%s%s: disconnected from %d %s (SSL connection not supported "
              "with upgrade)"),
            dogechat_prefix ("error"),
            IRC_PLUGIN_NAME,
            ssl_disconnected,
            NG_("server", "servers", ssl_disconnected));
    }

    return DOGECHAT_RC_OK;
}
Ejemplo n.º 24
0
int
exec_command_exec (void *data, struct t_gui_buffer *buffer, int argc,
                   char **argv, char **argv_eol)
{
    int i, length, count;
    char *text;
    struct t_exec_cmd *ptr_exec_cmd, *ptr_next_exec_cmd;

    /* make C compiler happy */
    (void) data;
    (void) buffer;

    /* list running commands */
    if ((argc == 1)
        || ((argc == 2) && (dogechat_strcasecmp (argv[1], "-list") == 0)))
    {
        exec_command_list ();
        return DOGECHAT_RC_OK;
    }

    /* send text to a running process */
    if (dogechat_strcasecmp (argv[1], "-in") == 0)
    {
        DOGECHAT_COMMAND_MIN_ARGS(4, "-in");
        ptr_exec_cmd = exec_command_search_running_id (argv[2]);
        if (ptr_exec_cmd && ptr_exec_cmd->hook)
        {
            length = strlen (argv_eol[3]) + 1 + 1;
            text = malloc (length);
            if (text)
            {
                snprintf (text, length, "%s\n", argv_eol[3]);
                dogechat_hook_set (ptr_exec_cmd->hook, "stdin", text);
                free (text);
            }
        }
        return DOGECHAT_RC_OK;
    }

    /* send text to a running process (if given), then close stdin */
    if (dogechat_strcasecmp (argv[1], "-inclose") == 0)
    {
        DOGECHAT_COMMAND_MIN_ARGS(3, "-inclose");
        ptr_exec_cmd = exec_command_search_running_id (argv[2]);
        if (ptr_exec_cmd && ptr_exec_cmd->hook)
        {
            if (argc > 3)
            {
                length = strlen (argv_eol[3]) + 1 + 1;
                text = malloc (length);
                if (text)
                {
                    snprintf (text, length, "%s\n", argv_eol[3]);
                    dogechat_hook_set (ptr_exec_cmd->hook, "stdin", text);
                    free (text);
                }
            }
            dogechat_hook_set (ptr_exec_cmd->hook, "stdin_close", "1");
        }
        return DOGECHAT_RC_OK;
    }

    /* send a signal to a running process */
    if (dogechat_strcasecmp (argv[1], "-signal") == 0)
    {
        DOGECHAT_COMMAND_MIN_ARGS(4, "-signal");
        ptr_exec_cmd = exec_command_search_running_id (argv[2]);
        if (ptr_exec_cmd)
            dogechat_hook_set (ptr_exec_cmd->hook, "signal", argv[3]);
        return DOGECHAT_RC_OK;
    }

    /* send a KILL signal to a running process */
    if (dogechat_strcasecmp (argv[1], "-kill") == 0)
    {
        DOGECHAT_COMMAND_MIN_ARGS(3, "-kill");
        ptr_exec_cmd = exec_command_search_running_id (argv[2]);
        if (ptr_exec_cmd)
            dogechat_hook_set (ptr_exec_cmd->hook, "signal", "kill");
        return DOGECHAT_RC_OK;
    }

    /* send a KILL signal to all running processes */
    if (dogechat_strcasecmp (argv[1], "-killall") == 0)
    {
        for (ptr_exec_cmd = exec_cmds; ptr_exec_cmd;
             ptr_exec_cmd = ptr_exec_cmd->next_cmd)
        {
            if (ptr_exec_cmd->hook)
            {
                dogechat_hook_set (ptr_exec_cmd->hook, "signal", "kill");
            }
        }
        return DOGECHAT_RC_OK;
    }

    /* set a hook property */
    if (dogechat_strcasecmp (argv[1], "-set") == 0)
    {
        DOGECHAT_COMMAND_MIN_ARGS(5, "-set");
        ptr_exec_cmd = exec_command_search_running_id (argv[2]);
        if (ptr_exec_cmd)
            dogechat_hook_set (ptr_exec_cmd->hook, argv[3], argv_eol[4]);
        return DOGECHAT_RC_OK;
    }

    /* delete terminated command(s) */
    if (dogechat_strcasecmp (argv[1], "-del") == 0)
    {
        DOGECHAT_COMMAND_MIN_ARGS(3, "-del");
        if (dogechat_strcasecmp (argv[2], "-all") == 0)
        {
            count = 0;
            ptr_exec_cmd = exec_cmds;
            while (ptr_exec_cmd)
            {
                ptr_next_exec_cmd = ptr_exec_cmd->next_cmd;
                if (!ptr_exec_cmd->hook)
                {
                    exec_free (ptr_exec_cmd);
                    count++;
                }
                ptr_exec_cmd = ptr_next_exec_cmd;
            }
            dogechat_printf (NULL, _("%d commands removed"), count);
        }
        else
        {
            for (i = 2; i < argc; i++)
            {
                ptr_exec_cmd = exec_search_by_id (argv[i]);
                if (ptr_exec_cmd)
                {
                    if (ptr_exec_cmd->hook)
                    {
                        dogechat_printf (NULL,
                                        _("%s%s: command with id \"%s\" is still "
                                          "running"),
                                        dogechat_prefix ("error"), EXEC_PLUGIN_NAME,
                                        argv[i]);
                    }
                    else
                    {
                        exec_free (ptr_exec_cmd);
                        dogechat_printf (NULL,
                                        _("Command \"%s\" removed"), argv[i]);
                    }
                }
                else
                {
                    dogechat_printf (NULL,
                                    _("%s%s: command id \"%s\" not found"),
                                    dogechat_prefix ("error"), EXEC_PLUGIN_NAME,
                                    argv[i]);
                }
            }
        }
        return DOGECHAT_RC_OK;
    }

    return exec_command_run (buffer, argc, argv, argv_eol, 1);
}
Ejemplo n.º 25
0
struct t_alias *
alias_new (const char *name, const char *command, const char *completion)
{
    struct t_alias *new_alias, *ptr_alias, *pos_alias;

    if (!alias_name_valid (name))
    {
        dogechat_printf (NULL,
                        _("%s%s: invalid alias name: \"%s\""),
                        dogechat_prefix ("error"), ALIAS_PLUGIN_NAME,
                        name);
        return NULL;
    }

    if (!command || !command[0])
        return NULL;

    while (dogechat_string_is_command_char (name))
    {
        name = dogechat_utf8_next_char (name);
    }

    ptr_alias = alias_search (name);
    if (ptr_alias)
        alias_free (ptr_alias);

    new_alias = malloc (sizeof (*new_alias));
    if (new_alias)
    {
        new_alias->hook = NULL;
        new_alias->name = strdup (name);
        new_alias->command = strdup (command);
        new_alias->completion = (completion) ? strdup (completion) : NULL;
        new_alias->running = 0;

        alias_hook_command (new_alias);

        if (alias_list)
        {
            pos_alias = alias_find_pos (name);
            if (pos_alias)
            {
                /* insert alias into the list (before alias found) */
                new_alias->prev_alias = pos_alias->prev_alias;
                new_alias->next_alias = pos_alias;
                if (pos_alias->prev_alias)
                    (pos_alias->prev_alias)->next_alias = new_alias;
                else
                    alias_list = new_alias;
                pos_alias->prev_alias = new_alias;
            }
            else
            {
                /* add alias to end of list */
                new_alias->prev_alias = last_alias;
                new_alias->next_alias = NULL;
                last_alias->next_alias = new_alias;
                last_alias = new_alias;
            }
        }
        else
        {
            new_alias->prev_alias = NULL;
            new_alias->next_alias = NULL;
            alias_list = new_alias;
            last_alias = new_alias;
        }
    }

    return new_alias;
}
Ejemplo n.º 26
0
void
irc_input_user_message_display (struct t_gui_buffer *buffer, int action,
                                const char *text)
{
    struct t_irc_nick *ptr_nick;
    char *pos, *text2, *text_decoded, str_tags[256], *str_color;
    const char *ptr_text;

    /* if message is an action, force "action" to 1 and extract message */
    if (strncmp (text, "\01ACTION ", 8) == 0)
    {
        action = 1;
        pos = strrchr (text + 8, '\01');
        if (pos)
            text2 = dogechat_strndup (text + 8, pos - text - 8);
        else
            text2 = strdup (text + 8);
    }
    else
        text2 = strdup (text);

    text_decoded = irc_color_decode (
        (text2) ? text2 : text,
        dogechat_config_boolean (irc_config_network_colors_send));

    IRC_BUFFER_GET_SERVER_CHANNEL(buffer);

    if (ptr_channel)
    {
        ptr_nick = NULL;
        if (ptr_channel->type == IRC_CHANNEL_TYPE_CHANNEL)
        {
            ptr_nick = irc_nick_search (ptr_server, ptr_channel,
                                        ptr_server->nick);
        }

        if (action)
        {
            snprintf (str_tags, sizeof (str_tags),
                      "irc_action,notify_none,no_highlight");
        }
        else
        {
            str_color = irc_color_for_tags (
                dogechat_config_color (
                    dogechat_config_get ("dogechat.color.chat_nick_self")));
            snprintf (str_tags, sizeof (str_tags),
                      "notify_none,no_highlight,prefix_nick_%s",
                      (str_color) ? str_color : "default");
            if (str_color)
                free (str_color);
        }
        ptr_text = (text_decoded) ? text_decoded : ((text2) ? text2 : text);
        if (action)
        {
            dogechat_printf_tags (
                buffer,
                irc_protocol_tags (
                    "privmsg", str_tags,
                    (ptr_nick) ? ptr_nick->name : ptr_server->nick,
                    NULL),
                "%s%s%s%s%s %s",
                dogechat_prefix ("action"),
                irc_nick_mode_for_display (ptr_server, ptr_nick, 0),
                IRC_COLOR_CHAT_NICK_SELF,
                ptr_server->nick,
                IRC_COLOR_RESET,
                ptr_text);
        }
        else
        {
            dogechat_printf_tags (
                buffer,
                irc_protocol_tags (
                    "privmsg", str_tags,
                    (ptr_nick) ? ptr_nick->name : ptr_server->nick,
                    NULL),
                "%s%s",
                irc_nick_as_prefix (
                    ptr_server,
                    (ptr_nick) ? ptr_nick : NULL,
                    (ptr_nick) ? NULL : ptr_server->nick,
                    IRC_COLOR_CHAT_NICK_SELF),
                ptr_text);
        }
    }

    if (text2)
        free (text2);
    if (text_decoded)
        free (text_decoded);
}
Ejemplo n.º 27
0
char *
irc_sasl_mechanism_ecdsa_nist256p_challenge (struct t_irc_server *server,
                                             const char *data_base64,
                                             const char *sasl_username,
                                             const char *sasl_key)
{
#if defined(HAVE_GNUTLS) && (LIBGNUTLS_VERSION_NUMBER >= 0x030015) /* 3.0.21 */
    char *data, *string, *answer_base64;
    int length_data, length_username, length, ret;
    char *str_privkey;
    gnutls_x509_privkey_t x509_privkey;
    gnutls_privkey_t privkey;
    gnutls_datum_t filedatum, decoded_data, signature;
#if LIBGNUTLS_VERSION_NUMBER >= 0x030300 /* 3.3.0 */
    gnutls_ecc_curve_t curve;
    gnutls_datum_t x, y, k;
    char *pubkey, *pubkey_base64;
#endif /* LIBGNUTLS_VERSION_NUMBER >= 0x030300 */

    answer_base64 = NULL;
    string = NULL;
    length = 0;

    if (strcmp (data_base64, "+") == 0)
    {
        /* send "username" + '\0' + "username" */
        answer_base64 = NULL;
        length_username = strlen (sasl_username);
        length = length_username + 1 + length_username;
        string = malloc (length + 1);
        if (string)
        {
            snprintf (string, length + 1, "%s|%s", sasl_username, sasl_username);
            string[length_username] = '\0';
        }
    }
    else
    {
        /* sign the challenge with the private key and return the result */

        /* decode the challenge */
        data = malloc (strlen (data_base64) + 1);
        if (!data)
            return NULL;
        length_data = dogechat_string_decode_base64 (data_base64, data);

        /* read file with private key */
        str_privkey = irc_sasl_get_key_content (server, sasl_key);
        if (!str_privkey)
        {
            free (data);
            return NULL;
        }

        /* import key */
        gnutls_x509_privkey_init (&x509_privkey);
        gnutls_privkey_init (&privkey);
        filedatum.data = (unsigned char *)str_privkey;
        filedatum.size = strlen (str_privkey);
        ret = gnutls_x509_privkey_import (x509_privkey, &filedatum,
                                          GNUTLS_X509_FMT_PEM);
        free (str_privkey);
        if (ret != GNUTLS_E_SUCCESS)
        {
            dogechat_printf (
                server->buffer,
                _("%sgnutls: invalid private key file: error %d %s"),
                dogechat_prefix ("error"),
                ret,
                gnutls_strerror (ret));
            gnutls_x509_privkey_deinit (x509_privkey);
            gnutls_privkey_deinit (privkey);
            free (data);
            return NULL;
        }

#if LIBGNUTLS_VERSION_NUMBER >= 0x030300 /* 3.3.0 */
        /* read raw values in key, to display public key */
        ret = gnutls_x509_privkey_export_ecc_raw (x509_privkey,
                                                  &curve, &x, &y, &k);
        if (ret == GNUTLS_E_SUCCESS)
        {
            pubkey = malloc (x.size + 1);
            if (pubkey)
            {
                pubkey[0] = (y.data[y.size - 1] & 1) ? 0x03 : 0x02;
                memcpy (pubkey + 1, x.data, x.size);
                pubkey_base64 = malloc ((x.size + 1 + 1) * 4);
                if (pubkey_base64)
                {
                    dogechat_string_encode_base64 (pubkey, x.size + 1,
                                                  pubkey_base64);
                    dogechat_printf (
                        server->buffer,
                        _("%s%s: signing the challenge with ECC public key: "
                          "%s"),
                        dogechat_prefix ("network"),
                        IRC_PLUGIN_NAME,
                        pubkey_base64);
                    free (pubkey_base64);
                }
                free (pubkey);
            }
            gnutls_free (x.data);
            gnutls_free (y.data);
            gnutls_free (k.data);
        }
#endif /* LIBGNUTLS_VERSION_NUMBER >= 0x030300 */

        /* import private key in an abstract key structure */
        ret = gnutls_privkey_import_x509 (privkey, x509_privkey, 0); /* gnutls >= 2.11.0 */
        if (ret != GNUTLS_E_SUCCESS)
        {
            dogechat_printf (
                server->buffer,
                _("%sgnutls: unable to import the private key: error %d %s"),
                dogechat_prefix ("error"),
                ret,
                gnutls_strerror (ret));
            gnutls_x509_privkey_deinit (x509_privkey);
            gnutls_privkey_deinit (privkey);
            free (data);
            return NULL;
        }

        decoded_data.data = (unsigned char *)data;
        decoded_data.size = length_data;
        ret = gnutls_privkey_sign_hash (privkey, GNUTLS_DIG_SHA256, 0, /* gnutls >= 2.11.0 */
                                        &decoded_data, &signature);
        if (ret != GNUTLS_E_SUCCESS)
        {
            dogechat_printf (
                server->buffer,
                _("%sgnutls: unable to sign the hashed data: error %d %s"),
                dogechat_prefix ("error"),
                ret,
                gnutls_strerror (ret));
            gnutls_x509_privkey_deinit (x509_privkey);
            gnutls_privkey_deinit (privkey);
            free (data);
            return NULL;
        }

        gnutls_x509_privkey_deinit (x509_privkey);
        gnutls_privkey_deinit (privkey);

        string = malloc (signature.size);
        if (string)
            memcpy (string, signature.data, signature.size);
        length = signature.size;

        gnutls_free (signature.data);

        free (data);
    }

    if (string && (length > 0))
    {
        answer_base64 = malloc ((length + 1) * 4);
        if (answer_base64)
            dogechat_string_encode_base64 (string, length, answer_base64);
        free (string);
    }

    return answer_base64;

#else /* no gnutls or gnutls < 3.0.21 */

    /* make C compiler happy */
    (void) data_base64;
    (void) sasl_username;
    (void) sasl_key;

    dogechat_printf (server->buffer,
                    _("%sgnutls: version >= 3.0.21 is required for SASL "
                      "\"ecdsa-nist256p-challenge\""),
                    dogechat_prefix ("error"));

    return NULL;
#endif /* defined(HAVE_GNUTLS) && (LIBGNUTLS_VERSION_NUMBER >= 0x030015) */
}
Ejemplo n.º 28
0
int
fifo_read (void *data, int fd)
{
    static char buffer[4096 + 2];
    char *buf2, *pos, *ptr_buf, *next_ptr_buf;
    int num_read;

    /* make C compiler happy */
    (void) data;
    (void) fd;

    num_read = read (fifo_fd, buffer, sizeof (buffer) - 2);
    if (num_read > 0)
    {
        buffer[num_read] = '\0';

        buf2 = NULL;
        ptr_buf = buffer;
        if (fifo_unterminated)
        {
            buf2 = malloc (strlen (fifo_unterminated) +
                           strlen (buffer) + 1);
            if (buf2)
            {
                strcpy (buf2, fifo_unterminated);
                strcat (buf2, buffer);
            }
            ptr_buf = buf2;
            free (fifo_unterminated);
            fifo_unterminated = NULL;
        }

        while (ptr_buf && ptr_buf[0])
        {
            next_ptr_buf = NULL;
            pos = strstr (ptr_buf, "\r\n");
            if (pos)
            {
                pos[0] = '\0';
                next_ptr_buf = pos + 2;
            }
            else
            {
                pos = strstr (ptr_buf, "\n");
                if (pos)
                {
                    pos[0] = '\0';
                    next_ptr_buf = pos + 1;
                }
                else
                {
                    fifo_unterminated = strdup (ptr_buf);
                    ptr_buf = NULL;
                    next_ptr_buf = NULL;
                }
            }

            if (ptr_buf)
                fifo_exec (ptr_buf);

            ptr_buf = next_ptr_buf;
        }

        if (buf2)
            free (buf2);
    }
    else
    {
        if (num_read < 0)
        {
#ifdef __CYGWIN__
            if ((errno == EAGAIN) || (errno == ECOMM))
#else
            if (errno == EAGAIN)
#endif /* __CYGWIN__ */
                return DOGECHAT_RC_OK;

            dogechat_printf (NULL,
                            _("%s%s: error reading pipe (%d %s), closing it"),
                            dogechat_prefix ("error"), FIFO_PLUGIN_NAME,
                            errno, strerror (errno));
            fifo_remove ();
        }
        else
        {
            dogechat_unhook (fifo_fd_hook);
            fifo_fd_hook = NULL;
            close (fifo_fd);
            fifo_fd = open (fifo_filename, O_RDONLY | O_NONBLOCK);
            if (fifo_fd < 0)
            {
                dogechat_printf (NULL,
                                _("%s%s: error opening file, closing it"),
                                dogechat_prefix ("error"), FIFO_PLUGIN_NAME);
                fifo_remove ();
            }
            else
                fifo_fd_hook = dogechat_hook_fd (fifo_fd, 1, 0, 0,
                                                &fifo_read, NULL);
        }
    }

    return DOGECHAT_RC_OK;
}
Ejemplo n.º 29
0
int
exec_command_run (struct t_gui_buffer *buffer,
                  int argc, char **argv, char **argv_eol, int start_arg)
{
    char str_buffer[512];
    struct t_exec_cmd *new_exec_cmd;
    struct t_exec_cmd_options cmd_options;
    struct t_hashtable *process_options;
    struct t_infolist *ptr_infolist;
    struct t_gui_buffer *ptr_new_buffer;

    /* parse command options */
    cmd_options.command_index = -1;
    cmd_options.use_shell = 0;
    cmd_options.detached = 0;
    cmd_options.pipe_stdin = 0;
    cmd_options.timeout = 0;
    cmd_options.ptr_buffer_name = NULL;
    cmd_options.ptr_buffer = buffer;
    cmd_options.output_to_buffer = 0;
    cmd_options.new_buffer = 0;
    cmd_options.new_buffer_clear = 0;
    cmd_options.switch_to_buffer = 1;
    cmd_options.line_numbers = -1;
    cmd_options.flush = 1;
    cmd_options.color = EXEC_COLOR_AUTO;
    cmd_options.display_rc = 1;
    cmd_options.ptr_command_name = NULL;
    cmd_options.pipe_command = NULL;
    cmd_options.hsignal = NULL;

    /* parse default options */
    if (!exec_command_parse_options (&cmd_options,
                                     exec_config_cmd_num_options,
                                     exec_config_cmd_options,
                                     0, 0))
    {
        dogechat_printf (NULL,
                        _("%s%s: invalid options in option "
                          "exec.command.default_options"),
                        dogechat_prefix ("error"), EXEC_PLUGIN_NAME);
        return DOGECHAT_RC_ERROR;
    }
    if (!exec_command_parse_options (&cmd_options, argc, argv, start_arg, 1))
        return DOGECHAT_RC_ERROR;

    /* options "-bg" and "-o"/"-n" are incompatible */
    if (cmd_options.detached
        && (cmd_options.output_to_buffer || cmd_options.new_buffer))
        return DOGECHAT_RC_ERROR;

    /* options "-pipe" and "-bg"/"-o"/"-n" are incompatible */
    if (cmd_options.pipe_command
        && (cmd_options.detached || cmd_options.output_to_buffer
            || cmd_options.new_buffer))
        return DOGECHAT_RC_ERROR;

    /* command not found? */
    if (cmd_options.command_index < 0)
        return DOGECHAT_RC_ERROR;

    new_exec_cmd = exec_add ();
    if (!new_exec_cmd)
        return DOGECHAT_RC_ERROR;

    /* create hashtable for dogechat_hook_process_hashtable() */
    process_options = dogechat_hashtable_new (32,
                                             DOGECHAT_HASHTABLE_STRING,
                                             DOGECHAT_HASHTABLE_STRING,
                                             NULL,
                                             NULL);
    if (!process_options)
    {
        exec_free (new_exec_cmd);
        return DOGECHAT_RC_ERROR;
    }
    /* automatically disable shell if we are downloading an URL */
    if (strncmp (argv_eol[cmd_options.command_index], "url:", 4) == 0)
        cmd_options.use_shell = 0;
    if (cmd_options.use_shell)
    {
        /* command will be: sh -c "command arguments..." */
        dogechat_hashtable_set (process_options, "arg1", "-c");
        dogechat_hashtable_set (process_options, "arg2",
                               argv_eol[cmd_options.command_index]);
    }
    if (cmd_options.pipe_stdin)
        dogechat_hashtable_set (process_options, "stdin", "1");
    if (cmd_options.detached)
        dogechat_hashtable_set (process_options, "detached", "1");
    if (cmd_options.flush)
        dogechat_hashtable_set (process_options, "buffer_flush", "1");

    /* set variables in new command (before running the command) */
    new_exec_cmd->name = (cmd_options.ptr_command_name) ?
        strdup (cmd_options.ptr_command_name) : NULL;
    new_exec_cmd->command = strdup (argv_eol[cmd_options.command_index]);
    new_exec_cmd->detached = cmd_options.detached;

    if (!cmd_options.detached && !cmd_options.pipe_command
        && !cmd_options.hsignal)
    {
        if (cmd_options.ptr_buffer_name && !cmd_options.ptr_buffer)
        {
            /* output in a new buffer using given name */
            new_exec_cmd->output_to_buffer = 0;
            snprintf (str_buffer, sizeof (str_buffer),
                      "exec.%s", cmd_options.ptr_buffer_name);
            ptr_new_buffer = exec_buffer_new (str_buffer,
                                              (cmd_options.new_buffer == 2),
                                              cmd_options.new_buffer_clear,
                                              cmd_options.switch_to_buffer);
            if (ptr_new_buffer)
            {
                new_exec_cmd->buffer_full_name =
                    strdup (dogechat_buffer_get_string (ptr_new_buffer,
                                                       "full_name"));
            }
        }
        else if (cmd_options.new_buffer)
        {
            /* output in a new buffer using automatic name */
            if (new_exec_cmd->name)
            {
                snprintf (str_buffer, sizeof (str_buffer),
                          "exec.%s", new_exec_cmd->name);
            }
            else
            {
                snprintf (str_buffer, sizeof (str_buffer),
                          "exec.%d", new_exec_cmd->number);
            }
            ptr_new_buffer = exec_buffer_new (str_buffer,
                                              (cmd_options.new_buffer == 2),
                                              cmd_options.new_buffer_clear,
                                              cmd_options.switch_to_buffer);
            if (ptr_new_buffer)
            {
                new_exec_cmd->buffer_full_name =
                    strdup (dogechat_buffer_get_string (ptr_new_buffer,
                                                       "full_name"));
            }
        }
        else if (cmd_options.ptr_buffer)
        {
            new_exec_cmd->buffer_full_name =
                strdup (dogechat_buffer_get_string (cmd_options.ptr_buffer,
                                                   "full_name"));
            if (cmd_options.switch_to_buffer)
                dogechat_buffer_set (cmd_options.ptr_buffer, "display", "1");
        }
        if (cmd_options.ptr_buffer
            && (strcmp (dogechat_buffer_get_string (cmd_options.ptr_buffer, "plugin"),
                        EXEC_PLUGIN_NAME) == 0))
        {
            cmd_options.output_to_buffer = 0;
            cmd_options.new_buffer = 1;
        }
    }
    new_exec_cmd->output_to_buffer = cmd_options.output_to_buffer;
    new_exec_cmd->line_numbers = (cmd_options.line_numbers < 0) ?
        cmd_options.new_buffer : cmd_options.line_numbers;
    new_exec_cmd->color = cmd_options.color;
    new_exec_cmd->display_rc = cmd_options.display_rc;
    new_exec_cmd->pipe_command = cmd_options.pipe_command;
    new_exec_cmd->hsignal = cmd_options.hsignal;

    /* execute the command */
    if (dogechat_exec_plugin->debug >= 1)
    {
        dogechat_printf (NULL, "%s: executing command: \"%s%s%s\"",
                        EXEC_PLUGIN_NAME,
                        (cmd_options.use_shell) ? "" : "sh -c '",
                        argv_eol[cmd_options.command_index],
                        (cmd_options.use_shell) ? "" : "'");
    }
    new_exec_cmd->hook = dogechat_hook_process_hashtable (
        (cmd_options.use_shell) ? "sh" : argv_eol[cmd_options.command_index],
        process_options,
        cmd_options.timeout * 1000,
        &exec_process_cb,
        new_exec_cmd);

    if (new_exec_cmd->hook)
    {
        /* get PID of command */
        ptr_infolist = dogechat_infolist_get ("hook", new_exec_cmd->hook, NULL);
        if (ptr_infolist)
        {
            if (dogechat_infolist_next (ptr_infolist))
            {
                new_exec_cmd->pid = dogechat_infolist_integer (ptr_infolist,
                                                              "child_pid");
            }
            dogechat_infolist_free (ptr_infolist);
        }
    }
    else
    {
        exec_free (new_exec_cmd);
        dogechat_printf (NULL,
                        _("%s%s: failed to run command \"%s\""),
                        dogechat_prefix ("error"), EXEC_PLUGIN_NAME,
                        argv_eol[cmd_options.command_index]);
    }

    dogechat_hashtable_free (process_options);

    return DOGECHAT_RC_OK;
}
Ejemplo n.º 30
0
int
dogechat_js_load (const char *filename)
{
    char *source;

    source = dogechat_file_get_content (filename);
    if (!source)
    {
        dogechat_printf (NULL,
                        dogechat_gettext ("%s%s: script \"%s\" not found"),
                        dogechat_prefix ("error"), JS_PLUGIN_NAME, filename);
        return 0;
    }

    if ((dogechat_js_plugin->debug >= 2) || !js_quiet)
    {
        dogechat_printf (NULL,
                        dogechat_gettext ("%s: loading script \"%s\""),
                        JS_PLUGIN_NAME, filename);
    }

    js_current_script = NULL;
    js_registered_script = NULL;

    js_current_interpreter = new DogechatJsV8();

    if (!js_current_interpreter)
    {
        dogechat_printf (NULL,
                        dogechat_gettext ("%s%s: unable to create new "
                                         "sub-interpreter"),
                        dogechat_prefix ("error"), JS_PLUGIN_NAME);
        free (source);
        return 0;
    }

    /* load libs */
    js_current_interpreter->loadLibs();

    js_current_script_filename = filename;

    if (!js_current_interpreter->load(source))
    {
        dogechat_printf (NULL,
                        dogechat_gettext ("%s%s: unable to load file \"%s\""),
                        dogechat_prefix ("error"), JS_PLUGIN_NAME);
        delete js_current_interpreter;
        free (source);

        /* if script was registered, remove it from list */
        if (js_current_script)
        {
            plugin_script_remove (dogechat_js_plugin,
                                  &js_scripts, &last_js_script,
                                  js_current_script);
            js_current_script = NULL;
        }

        return 0;
    }

    free (source);

    if (!js_current_interpreter->execScript())
    {
        dogechat_printf (NULL,
                        dogechat_gettext ("%s%s: unable to execute file "
                                         "\"%s\""),
                        dogechat_prefix ("error"), JS_PLUGIN_NAME, filename);
        delete js_current_interpreter;

        /* if script was registered, remove it from list */
        if (js_current_script)
        {
            plugin_script_remove (dogechat_js_plugin,
                                  &js_scripts, &last_js_script,
                                  js_current_script);
            js_current_script = NULL;
        }
        return 0;
    }

    if (!js_registered_script)
    {
        dogechat_printf (NULL,
                        dogechat_gettext ("%s%s: function \"register\" not "
                                         "found (or failed) in file \"%s\""),
                        dogechat_prefix ("error"), JS_PLUGIN_NAME, filename);
        delete js_current_interpreter;
        return 0;
    }

    js_current_script = js_registered_script;

    /*
     * set input/close callbacks for buffers created by this script
     * (to restore callbacks after upgrade)
     */
    plugin_script_set_buffer_callbacks (dogechat_js_plugin,
                                        js_scripts,
                                        js_current_script,
                                        &dogechat_js_api_buffer_input_data_cb,
                                        &dogechat_js_api_buffer_close_cb);

    dogechat_hook_signal_send ("javascript_script_loaded",
                              DOGECHAT_HOOK_SIGNAL_STRING,
                              js_current_script->filename);

    return 1;
}