Esempio n. 1
0
void
xfer_network_connect_init (struct t_xfer *xfer)
{
    if (!xfer_network_connect (xfer))
    {
        xfer_close (xfer, XFER_STATUS_FAILED);
        xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
    }
    else
    {
        /* for a file: launch child process */
        if (XFER_IS_FILE(xfer->type))
        {
            xfer->status = XFER_STATUS_CONNECTING;
            xfer_network_recv_file_fork (xfer);
        }
        else
        {
            /* for a chat => associate with buffer */
            xfer->status = XFER_STATUS_ACTIVE;
            xfer_chat_open_buffer (xfer);
        }
    }
    xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
}
Esempio n. 2
0
int
xfer_buffer_input_cb (void *data, struct t_gui_buffer *buffer,
                      const char *input_data)
{
    struct t_xfer *xfer, *ptr_xfer, *next_xfer;

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

    xfer = xfer_search_by_number (xfer_buffer_selected_line);

    /* accept xfer */
    if (weechat_strcasecmp (input_data, "a") == 0)
    {
        if (xfer && XFER_IS_RECV(xfer->type)
            && (xfer->status == XFER_STATUS_WAITING))
        {
            xfer_network_accept (xfer);
        }
    }
    /* cancel xfer */
    else if (weechat_strcasecmp (input_data, "c") == 0)
    {
        if (xfer && !XFER_HAS_ENDED(xfer->status))
        {
            xfer_close (xfer, XFER_STATUS_ABORTED);
            xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
        }
    }
    /* purge old xfer */
    else if (weechat_strcasecmp (input_data, "p") == 0)
    {
        ptr_xfer = xfer_list;
        while (ptr_xfer)
        {
            next_xfer = ptr_xfer->next_xfer;
            if (XFER_HAS_ENDED(ptr_xfer->status))
                xfer_free (ptr_xfer);
            ptr_xfer = next_xfer;
        }
        xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
    }
    /* quit xfer buffer (close it) */
    else if (weechat_strcasecmp (input_data, "q") == 0)
    {
        weechat_buffer_close (buffer);
    }
    /* remove xfer */
    else if (weechat_strcasecmp (input_data, "r") == 0)
    {
        if (xfer && XFER_HAS_ENDED(xfer->status))
        {
            xfer_free (xfer);
            xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
        }
    }

    return WEECHAT_RC_OK;
}
Esempio n. 3
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);
}
Esempio n. 4
0
void
xfer_config_refresh_cb (void *data, struct t_config_option *option)
{
    /* make C compiler happy */
    (void) data;
    (void) option;

    if (xfer_buffer)
        xfer_buffer_refresh (NULL);
}
Esempio n. 5
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 */
            weechat_printf (NULL,
                            _("%s%s: unable to fork (%s)"),
                            weechat_prefix ("error"),
                            XFER_PLUGIN_NAME,
                            strerror (errno));
            xfer_close (xfer, XFER_STATUS_FAILED);
            xfer_buffer_refresh (WEECHAT_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 = weechat_hook_fd (xfer->child_read,
                                     1, 0, 0,
                                     &xfer_network_child_read_cb,
                                     xfer, NULL);
}
Esempio n. 6
0
void
xfer_network_accept (struct t_xfer *xfer)
{
    if (XFER_IS_FILE(xfer->type) && (xfer->start_resume > 0))
    {
        xfer->status = XFER_STATUS_CONNECTING;
        xfer_send_signal (xfer, "xfer_resume_ready");
        xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
    }
    else
        xfer_network_connect_init (xfer);
}
Esempio n. 7
0
int
xfer_command_xfer (void *data, struct t_gui_buffer *buffer, int argc,
                   char **argv, char **argv_eol)
{
    /* make C compiler happy */
    (void) data;
    (void) buffer;
    (void) argv_eol;

    if ((argc > 1) && (dogechat_strcasecmp (argv[1], "list") == 0))
    {
        xfer_command_xfer_list (0);
        return DOGECHAT_RC_OK;
    }

    if ((argc > 1) && (dogechat_strcasecmp (argv[1], "listfull") == 0))
    {
        xfer_command_xfer_list (1);
        return DOGECHAT_RC_OK;
    }

    if (!xfer_buffer)
        xfer_buffer_open ();

    if (xfer_buffer)
    {
        dogechat_buffer_set (xfer_buffer, "display", "1");

        if (argc > 1)
        {
            if (strcmp (argv[1], "up") == 0)
            {
                if (xfer_buffer_selected_line > 0)
                    xfer_buffer_selected_line--;
            }
            else if (strcmp (argv[1], "down") == 0)
            {
                if (xfer_buffer_selected_line < xfer_count - 1)
                    xfer_buffer_selected_line++;
            }
        }
    }

    xfer_buffer_refresh (NULL);

    return DOGECHAT_RC_OK;
}
Esempio n. 8
0
void
xfer_network_send_file_fork (struct t_xfer *xfer)
{
    pid_t pid;
    
    if (!xfer_network_create_pipe (xfer))
        return;
    
    xfer->file = open (xfer->local_filename, O_RDONLY | O_NONBLOCK, 0644);
    
    switch (pid = fork ())
    {
        /* fork failed */
        case -1:
            weechat_printf (NULL,
                            _("%s%s: unable to fork"),
                            weechat_prefix ("error"), XFER_PLUGIN_NAME);
            xfer_close (xfer, XFER_STATUS_FAILED);
            xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
            return;
            /* child process */
        case 0:
            setuid (getuid ());
            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);
    }
    
    /* parent process */
    xfer->child_pid = pid;
    close (xfer->child_write);
    xfer->child_write = -1;
    xfer->hook_fd = weechat_hook_fd (xfer->child_read,
                                     1, 0, 0,
                                     &xfer_network_child_read_cb,
                                     xfer);
}
Esempio n. 9
0
void
xfer_network_connect_init (struct t_xfer *xfer)
{
    if (!xfer_network_connect (xfer))
    {
        xfer_close (xfer, XFER_STATUS_FAILED);
    }
    else
    {
        /* for a file: launch child process */
        if (XFER_IS_FILE(xfer->type))
            xfer_network_recv_file_fork (xfer);

        xfer->status = XFER_STATUS_CONNECTING;
    }
    xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE);
}
Esempio n. 10
0
int
xfer_network_create_pipe (struct t_xfer *xfer)
{
    int child_pipe[2];
    
    if (pipe (child_pipe) < 0)
    {
        weechat_printf (NULL,
                        _("%s%s: unable to create pipe"),
                        weechat_prefix ("error"), XFER_PLUGIN_NAME);
        xfer_close (xfer, XFER_STATUS_FAILED);
        xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
        return 0;
    }
    
    xfer->child_read = child_pipe[0];
    xfer->child_write = child_pipe[1];
    
    return 1;
}
Esempio 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))
    {
        weechat_printf (NULL,
                        _("%s%s: timeout for \"%s\" with %s"),
                        weechat_prefix ("error"), XFER_PLUGIN_NAME,
                        xfer->filename, xfer->remote_nick);
        xfer_close (xfer, XFER_STATUS_FAILED);
        xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
    }
    
    return WEECHAT_RC_OK;
}
Esempio n. 12
0
int
xfer_chat_buffer_close_cb (void *data, struct t_gui_buffer *buffer)
{
    struct t_xfer *ptr_xfer;

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

    for (ptr_xfer = xfer_list; ptr_xfer; ptr_xfer = ptr_xfer->next_xfer)
    {
        if (ptr_xfer->buffer == buffer)
        {
            if (!XFER_HAS_ENDED(ptr_xfer->status))
            {
                xfer_close (ptr_xfer, XFER_STATUS_ABORTED);
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
            }
            ptr_xfer->buffer = NULL;
        }
    }

    return WEECHAT_RC_OK;
}
Esempio n. 13
0
int
xfer_network_child_read_cb (void *arg_xfer, int fd)
{
    struct t_xfer *xfer;
    char bufpipe[1 + 1 + 12 + 1];
    int num_read;
    char *error;
    
    /* 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)
    {
        error = NULL;
        xfer->pos = (unsigned long)(strtoll (bufpipe + 2, &error, 10));
        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:
                weechat_printf (NULL,
                                _("%s%s: unable to read local file"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                break;
            case XFER_ERROR_SEND_BLOCK:
                weechat_printf (NULL,
                                _("%s%s: unable to send block to receiver"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                break;
            case XFER_ERROR_READ_ACK:
                weechat_printf (NULL,
                                _("%s%s: unable to read ACK from receiver"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                break;
            /* errors for receiver */
            case XFER_ERROR_CONNECT_SENDER:
                weechat_printf (NULL,
                                _("%s%s: unable to connect to sender"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                break;
            case XFER_ERROR_RECV_BLOCK:
                weechat_printf (NULL,
                                _("%s%s: unable to receive block from sender"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                break;
            case XFER_ERROR_WRITE_LOCAL:
                weechat_printf (NULL,
                                _("%s%s: unable to write local file"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                break;
        }
        
        /* read new DCC status */
        switch (bufpipe[0] - '0')
        {
            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 (WEECHAT_HOTLIST_MESSAGE);
                }
                else
                    xfer_buffer_refresh (WEECHAT_HOTLIST_LOW);
                break;
            case XFER_STATUS_DONE:
                xfer_close (xfer, XFER_STATUS_DONE);
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
                break;
            case XFER_STATUS_FAILED:
                xfer_close (xfer, XFER_STATUS_FAILED);
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
                break;
        }
    }
    
    return WEECHAT_RC_OK;
}
Esempio n. 14
0
void
xfer_file_find_filename (struct t_xfer *xfer)
{
    const char *dir_separator;
    char *path, *filename2;
    int length;

    if (!XFER_IS_FILE(xfer->type))
        return;

    path = weechat_string_eval_path_home (
        weechat_config_string (xfer_config_file_download_path),
        NULL, NULL, NULL);
    if (!path)
        return;

    xfer->local_filename = malloc (strlen (path) +
                                   strlen (xfer->remote_nick) +
                                   strlen (xfer->filename) + 4);
    if (!xfer->local_filename)
    {
        free (path);
        return;
    }

    strcpy (xfer->local_filename, path);
    dir_separator = weechat_info_get("dir_separator", "");
    if (dir_separator
        && (xfer->local_filename[strlen (xfer->local_filename) - 1] != dir_separator[0]))
        strcat (xfer->local_filename, dir_separator);
    if (weechat_config_boolean (xfer_config_file_use_nick_in_filename))
    {
        strcat (xfer->local_filename, xfer->remote_nick);
        strcat (xfer->local_filename, ".");
    }
    strcat (xfer->local_filename, xfer->filename);

    free (path);

    /* file already exists? */
    if (access (xfer->local_filename, F_OK) == 0)
    {
        if (xfer_file_resume (xfer, xfer->local_filename))
            return;

        /* if auto rename is not set, then abort xfer */
        if (!xfer_config_file_auto_rename)
        {
            xfer_close (xfer, XFER_STATUS_FAILED);
            xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
            return;
        }

        length = strlen (xfer->local_filename) + 16;
        filename2 = malloc (length);
        if (!filename2)
        {
            xfer_close (xfer, XFER_STATUS_FAILED);
            xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
            return;
        }
        xfer->filename_suffix = 0;
        do
        {
            xfer->filename_suffix++;
            snprintf (filename2, length, "%s.%d",
                      xfer->local_filename,
                      xfer->filename_suffix);
            if (access (filename2, F_OK) == 0)
            {
                if (xfer_file_resume (xfer, filename2))
                    break;
            }
            else
                break;
        }
        while (1);

        free (xfer->local_filename);
        xfer->local_filename = strdup (filename2);
        free (filename2);
    }
}
Esempio n. 15
0
int
xfer_network_fd_cb (const void *pointer, void *data, int fd)
{
    struct t_xfer *xfer;
    int sock, flags, error;
    struct sockaddr_storage addr;
    socklen_t length;
    char str_address[NI_MAXHOST];

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

    length = sizeof (addr);
    memset (&addr, 0, length);
    xfer = (struct t_xfer *)pointer;

    if (xfer->status == XFER_STATUS_CONNECTING)
    {
        if (xfer->type == XFER_TYPE_FILE_SEND)
        {
            xfer->last_activity = time (NULL);
            sock = accept (xfer->sock,
                           (struct sockaddr *) &addr, &length);
            error = errno;
            weechat_unhook (xfer->hook_fd);
            xfer->hook_fd = NULL;
            close (xfer->sock);
            xfer->sock = -1;
            if (sock < 0)
            {
                weechat_printf (NULL,
                                _("%s%s: unable to create socket for sending "
                                  "file: error %d %s"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME,
                                error, strerror (error));
                xfer_close (xfer, XFER_STATUS_FAILED);
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
                return WEECHAT_RC_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)
            {
                weechat_printf (NULL,
                                _("%s%s: unable to set option \"nonblock\" "
                                  "for socket: error %d %s"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME,
                                errno, strerror (errno));
                xfer_close (xfer, XFER_STATUS_FAILED);
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
                return WEECHAT_RC_OK;
            }
            error = getnameinfo ((struct sockaddr *)&addr, length, str_address,
                                 sizeof (str_address), NULL, 0, NI_NUMERICHOST);
            if (error != 0)
            {
                snprintf (str_address, sizeof (str_address),
                          "error: %s", gai_strerror (error));
            }
            xfer_set_remote_address (xfer, (struct sockaddr *)&addr, length,
                                     str_address);
            xfer->status = XFER_STATUS_ACTIVE;
            xfer->start_transfer = time (NULL);
            xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
            xfer_network_send_file_fork (xfer);
        }
    }

    if (xfer->status == XFER_STATUS_WAITING)
    {
        if (xfer->type == XFER_TYPE_CHAT_SEND)
        {
            length = sizeof (addr);
            sock = accept (xfer->sock, (struct sockaddr *) &addr, &length);
            error = errno;
            weechat_unhook (xfer->hook_fd);
            xfer->hook_fd = NULL;
            close (xfer->sock);
            xfer->sock = -1;
            if (sock < 0)
            {
                weechat_printf (NULL,
                                _("%s%s: unable to create socket for sending "
                                  "file: error %d %s"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME,
                                error, strerror (error));
                xfer_close (xfer, XFER_STATUS_FAILED);
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
                return WEECHAT_RC_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)
            {
                weechat_printf (NULL,
                                _("%s%s: unable to set option \"nonblock\" "
                                  "for socket: error %d %s"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME,
                                errno, strerror (errno));
                xfer_close (xfer, XFER_STATUS_FAILED);
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
                return WEECHAT_RC_OK;
            }
            error = getnameinfo ((struct sockaddr *)&addr, length, str_address,
                                 sizeof (str_address), NULL, 0, NI_NUMERICHOST);
            if (error != 0)
            {
                snprintf (str_address, sizeof (str_address),
                          "error: %s", gai_strerror (error));
            }
            xfer_set_remote_address (xfer, (struct sockaddr *)&addr, length,
                                     str_address);
            xfer->status = XFER_STATUS_ACTIVE;
            xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
            xfer->hook_fd = weechat_hook_fd (xfer->sock,
                                             1, 0, 0,
                                             &xfer_chat_recv_cb,
                                             xfer, NULL);
            xfer_chat_open_buffer (xfer);
        }
    }

    return WEECHAT_RC_OK;
}
Esempio n. 16
0
int
xfer_network_connect_chat_recv_cb (const void *pointer, 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) data;
    (void) gnutls_rc;
    (void) ip_address;

    xfer = (struct t_xfer*)pointer;

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

    /* connection OK? */
    if (status == WEECHAT_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)
        {
            weechat_printf (NULL,
                            _("%s%s: unable to set option \"nonblock\" "
                              "for socket: error %d %s"),
                            weechat_prefix ("error"), XFER_PLUGIN_NAME,
                            errno, strerror (errno));
            close (xfer->sock);
            xfer->sock = -1;
            xfer_close (xfer, XFER_STATUS_FAILED);
            xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
            return WEECHAT_RC_OK;
        }

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

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

        return WEECHAT_RC_OK;
    }

    /* connection error */
    switch (status)
    {
        case WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND:
            weechat_printf (NULL,
                            (xfer->proxy && xfer->proxy[0]) ?
                            _("%s%s: proxy address \"%s\" not found") :
                            _("%s%s: address \"%s\" not found"),
                            weechat_prefix ("error"), XFER_PLUGIN_NAME,
                            xfer->remote_address_str);
            break;
        case WEECHAT_HOOK_CONNECT_IP_ADDRESS_NOT_FOUND:
            weechat_printf (NULL,
                            (xfer->proxy && xfer->proxy[0]) ?
                            _("%s%s: proxy IP address not found") :
                            _("%s%s: IP address not found"),
                            weechat_prefix ("error"), XFER_PLUGIN_NAME);
            break;
        case WEECHAT_HOOK_CONNECT_CONNECTION_REFUSED:
            weechat_printf (NULL,
                            (xfer->proxy && xfer->proxy[0]) ?
                            _("%s%s: proxy connection refused") :
                            _("%s%s: connection refused"),
                            weechat_prefix ("error"), XFER_PLUGIN_NAME);
            break;
        case WEECHAT_HOOK_CONNECT_PROXY_ERROR:
            weechat_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)"),
                            weechat_prefix ("error"), XFER_PLUGIN_NAME);
            break;
        case WEECHAT_HOOK_CONNECT_LOCAL_HOSTNAME_ERROR:
            weechat_printf (NULL,
                            _("%s%s: unable to set local hostname/IP"),
                            weechat_prefix ("error"), XFER_PLUGIN_NAME);
            break;
        case WEECHAT_HOOK_CONNECT_MEMORY_ERROR:
            weechat_printf (NULL,
                            _("%s%s: not enough memory (%s)"),
                            weechat_prefix ("error"), XFER_PLUGIN_NAME,
                            (error) ? error : "-");
            break;
        case WEECHAT_HOOK_CONNECT_TIMEOUT:
            weechat_printf (NULL,
                            _("%s%s: timeout"),
                            weechat_prefix ("error"), XFER_PLUGIN_NAME);
            break;
        case WEECHAT_HOOK_CONNECT_SOCKET_ERROR:
            weechat_printf (NULL,
                            _("%s%s: unable to create socket"),
                            weechat_prefix ("error"), XFER_PLUGIN_NAME);
            break;
        default:
            weechat_printf (NULL,
                            _("%s%s: unable to connect: unexpected error (%d)"),
                            weechat_prefix ("error"), XFER_PLUGIN_NAME,
                            status);
            break;
    }
    if (error && error[0])
    {
        weechat_printf (NULL,
                        _("%s%s: error: %s"),
                        weechat_prefix ("error"), XFER_PLUGIN_NAME, error);
    }

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

    return WEECHAT_RC_OK;
}
Esempio n. 17
0
int
xfer_network_child_read_cb (const void *pointer, void *data, int fd)
{
    struct t_xfer *xfer;
    char bufpipe[1 + 1 + 32 + 1];
    int num_read;

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

    xfer = (struct t_xfer *)pointer;

    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:
                weechat_printf (NULL,
                                _("%s%s: unable to read local file"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                break;
            case XFER_ERROR_SEND_BLOCK:
                weechat_printf (NULL,
                                _("%s%s: unable to send block to receiver"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                break;
            case XFER_ERROR_READ_ACK:
                weechat_printf (NULL,
                                _("%s%s: unable to read ACK from receiver"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                break;
            /* errors for receiver */
            case XFER_ERROR_CONNECT_SENDER:
                weechat_printf (NULL,
                                _("%s%s: unable to connect to sender"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                break;
            case XFER_ERROR_RECV_BLOCK:
                weechat_printf (NULL,
                                _("%s%s: unable to receive block from sender"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                break;
            case XFER_ERROR_WRITE_LOCAL:
                weechat_printf (NULL,
                                _("%s%s: unable to write local file"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                break;
            case XFER_ERROR_SEND_ACK:
                weechat_printf (NULL,
                                _("%s%s: unable to send ACK to sender"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                break;
            case XFER_ERROR_HASH_MISMATCH:
                weechat_printf (NULL,
                                _("%s%s: wrong CRC32 for file %s"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME,
                                xfer->filename);
                xfer->hash_status = XFER_HASH_STATUS_MISMATCH;
                break;
            case XFER_ERROR_HASH_RESUME_ERROR:
                weechat_printf (NULL,
                                _("%s%s: CRC32 error while resuming"),
                                weechat_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 (WEECHAT_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 (WEECHAT_HOTLIST_MESSAGE);
                }
                else
                    xfer_buffer_refresh (WEECHAT_HOTLIST_LOW);
                break;
            case XFER_STATUS_DONE:
                xfer_close (xfer, XFER_STATUS_DONE);
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
                break;
            case XFER_STATUS_FAILED:
                xfer_close (xfer, XFER_STATUS_FAILED);
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
                break;
            case XFER_STATUS_HASHING:
                xfer->status = XFER_STATUS_HASHING;
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
                break;
            case XFER_STATUS_HASHED:
                if (bufpipe[1] - '0' == XFER_NO_ERROR)
                    xfer->hash_status = XFER_HASH_STATUS_MATCH;
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
                break;
        }
    }

    return WEECHAT_RC_OK;
}
Esempio n. 18
0
int
xfer_chat_recv_cb (void *arg_xfer, int fd)
{
    struct t_xfer *xfer;
    static char buffer[4096 + 2];
    char *buf2, *pos, *ptr_buf, *ptr_buf2, *next_ptr_buf;
    char *ptr_buf_decoded, *ptr_buf_without_weechat_colors, *ptr_buf_color;
    char str_tags[256], *str_color;
    const char *pv_tags;
    int num_read, length, ctcp_action;

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

    xfer = (struct t_xfer *)arg_xfer;

    num_read = recv (xfer->sock, buffer, sizeof (buffer) - 2, 0);
    if (num_read > 0)
    {
        buffer[num_read] = '\0';

        buf2 = NULL;
        ptr_buf = buffer;
        if (xfer->unterminated_message)
        {
            buf2 = malloc (strlen (xfer->unterminated_message) +
                                   strlen (buffer) + 1);
            if (buf2)
            {
                strcpy (buf2, xfer->unterminated_message);
                strcat (buf2, buffer);
            }
            ptr_buf = buf2;
            free (xfer->unterminated_message);
            xfer->unterminated_message = NULL;
        }

        while (ptr_buf && ptr_buf[0])
        {
            next_ptr_buf = NULL;
            pos = strstr (ptr_buf, "\n");
            if (pos)
            {
                pos[0] = '\0';
                next_ptr_buf = pos + 1;
            }
            else
            {
                xfer->unterminated_message = strdup (ptr_buf);
                ptr_buf = NULL;
                next_ptr_buf = NULL;
            }

            if (ptr_buf)
            {
                ctcp_action = 0;
                length = strlen (ptr_buf);
                if (ptr_buf[length - 1] == '\r')
                {
                    ptr_buf[length - 1] = '\0';
                    length--;
                }

                if ((ptr_buf[0] == '\01')
                    && (ptr_buf[length - 1] == '\01'))
                {
                    ptr_buf[length - 1] = '\0';
                    ptr_buf++;
                    if (strncmp (ptr_buf, "ACTION ", 7) == 0)
                    {
                        ptr_buf += 7;
                        ctcp_action = 1;
                    }
                }

                ptr_buf_decoded = (xfer->charset_modifier) ?
                    weechat_hook_modifier_exec ("charset_decode",
                                                xfer->charset_modifier,
                                                ptr_buf) : NULL;
                ptr_buf_without_weechat_colors = weechat_string_remove_color ((ptr_buf_decoded) ? ptr_buf_decoded : ptr_buf,
                                                                              "?");
                ptr_buf_color = weechat_hook_modifier_exec ("irc_color_decode",
                                                            "1",
                                                            (ptr_buf_without_weechat_colors) ?
                                                            ptr_buf_without_weechat_colors : ((ptr_buf_decoded) ? ptr_buf_decoded : ptr_buf));
                ptr_buf2 = (ptr_buf_color) ?
                    ptr_buf_color : ((ptr_buf_without_weechat_colors) ?
                                     ptr_buf_without_weechat_colors : ((ptr_buf_decoded) ? ptr_buf_decoded : ptr_buf));
                pv_tags = weechat_config_string (xfer_config_look_pv_tags);
                if (ctcp_action)
                {
                    snprintf (str_tags, sizeof (str_tags),
                              "irc_privmsg,irc_action,%s%snick_%s,log1",
                              (pv_tags && pv_tags[0]) ? pv_tags : "",
                              (pv_tags && pv_tags[0]) ? "," : "",
                              xfer->remote_nick);
                    weechat_printf_tags (xfer->buffer,
                                         str_tags,
                                         "%s%s%s%s%s%s",
                                         weechat_prefix ("action"),
                                         weechat_color ((xfer->remote_nick_color) ?
                                                        xfer->remote_nick_color : "chat_nick_other"),
                                         xfer->remote_nick,
                                         weechat_color ("chat"),
                                         (ptr_buf2[0]) ? " " : "",
                                         ptr_buf2);
                }
                else
                {
                    str_color = xfer_chat_color_for_tags (
                        (xfer->remote_nick_color) ?
                        xfer->remote_nick_color : weechat_config_color (weechat_config_get ("weechat.color.chat_nick_other")));
                    snprintf (str_tags, sizeof (str_tags),
                              "irc_privmsg,%s%sprefix_nick_%s,nick_%s,log1",
                              (pv_tags && pv_tags[0]) ? pv_tags : "",
                              (pv_tags && pv_tags[0]) ? "," : "",
                              (str_color) ? str_color : "default",
                              xfer->remote_nick);
                    if (str_color)
                        free (str_color);
                    weechat_printf_tags (xfer->buffer,
                                         str_tags,
                                         "%s%s\t%s",
                                         weechat_color ((xfer->remote_nick_color) ?
                                                        xfer->remote_nick_color : "chat_nick_other"),
                                         xfer->remote_nick,
                                         ptr_buf2);
                }
                if (ptr_buf_decoded)
                    free (ptr_buf_decoded);
                if (ptr_buf_without_weechat_colors)
                    free (ptr_buf_without_weechat_colors);
                if (ptr_buf_color)
                    free (ptr_buf_color);
            }

            ptr_buf = next_ptr_buf;
        }

        if (buf2)
            free (buf2);
    }
    else
    {
        xfer_close (xfer, XFER_STATUS_ABORTED);
        xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
    }

    return WEECHAT_RC_OK;
}
Esempio n. 19
0
int
xfer_network_fd_cb (void *arg_xfer, int fd)
{
    struct t_xfer *xfer;
    int sock;
    struct sockaddr_in addr;
    socklen_t length;
    
    /* make C compiler happy */
    (void) fd;
    
    xfer = (struct t_xfer *)arg_xfer;
    
    if (xfer->status == XFER_STATUS_CONNECTING)
    {
        if (xfer->type == XFER_TYPE_FILE_SEND)
        {
            xfer->last_activity = time (NULL);
            length = sizeof (addr);
            sock = accept (xfer->sock,
                           (struct sockaddr *) &addr, &length);
            weechat_unhook (xfer->hook_fd);
            xfer->hook_fd = NULL;
            close (xfer->sock);
            xfer->sock = -1;
            if (sock < 0)
            {
                weechat_printf (NULL,
                                _("%s%s: unable to create socket for sending "
                                  "file"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                xfer_close (xfer, XFER_STATUS_FAILED);
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
                return WEECHAT_RC_OK;
            }
            xfer->sock = sock;
            if (fcntl (xfer->sock, F_SETFL, O_NONBLOCK) == -1)
            {
                weechat_printf (NULL,
                                _("%s%s: unable to set option \"nonblock\" "
                                  "for socket"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                xfer_close (xfer, XFER_STATUS_FAILED);
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
                return WEECHAT_RC_OK;
            }
            xfer->address = ntohl (addr.sin_addr.s_addr);
            xfer->status = XFER_STATUS_ACTIVE;
            xfer->start_transfer = time (NULL);
            xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
            xfer_network_send_file_fork (xfer);
        }
        /*
        if (xfer->type == XFER_TYPE_FILE_RECV)
        {
            if (xfer->child_read != -1)
                irc_dcc_file_child_read (dcc);
        }
        */
    }
    
    if (xfer->status == XFER_STATUS_WAITING)
    {
        if (xfer->type == XFER_TYPE_CHAT_SEND)
        {
            length = sizeof (addr);
            sock = accept (xfer->sock, (struct sockaddr *) &addr, &length);
            weechat_unhook (xfer->hook_fd);
            xfer->hook_fd = NULL;
            close (xfer->sock);
            xfer->sock = -1;
            if (sock < 0)
            {
                weechat_printf (NULL,
                                _("%s%s: unable to create socket for sending "
                                  "file"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                xfer_close (xfer, XFER_STATUS_FAILED);
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
                return WEECHAT_RC_OK;
            }
            xfer->sock = sock;
            if (fcntl (xfer->sock, F_SETFL, O_NONBLOCK) == -1)
            {
                weechat_printf (NULL,
                                _("%s%s: unable to set option \"nonblock\" "
                                  "for socket"),
                                weechat_prefix ("error"), XFER_PLUGIN_NAME);
                xfer_close (xfer, XFER_STATUS_FAILED);
                xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
                return WEECHAT_RC_OK;
            }
            xfer->address = ntohl (addr.sin_addr.s_addr);
            xfer->status = XFER_STATUS_ACTIVE;
            xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
            xfer->hook_fd = weechat_hook_fd (xfer->sock,
                                             1, 0, 0,
                                             &xfer_chat_recv_cb,
                                             xfer);
            xfer_chat_open_buffer (xfer);
        }
    }
    /*
    if (xfer->status == XFER_STATUS_ACTIVE)
    {
        if (XFER_IS_CHAT(dcc->type))
        {
            irc_dcc_chat_recv (dcc);
        }
        else
            irc_dcc_file_child_read (dcc);
    }
    */
    return WEECHAT_RC_OK;
}