/** * Finish with TLS session * * @v tls TLS session * @v rc Status code */ static void tls_close ( struct tls_session *tls, int rc ) { /* Remove process */ process_del ( &tls->process ); /* Close ciphertext and plaintext streams */ xfer_nullify ( &tls->cipherstream.xfer ); xfer_close ( &tls->cipherstream.xfer, rc ); xfer_nullify ( &tls->plainstream.xfer ); xfer_close ( &tls->plainstream.xfer, rc ); }
void xfer_chat_sendf (struct t_xfer *xfer, const char *format, ...) { char *ptr_msg, *msg_encoded; if (!xfer || (xfer->sock < 0)) return; weechat_va_format (format); if (!vbuffer) return; msg_encoded = (xfer->charset_modifier) ? weechat_hook_modifier_exec ("charset_encode", xfer->charset_modifier, vbuffer) : NULL; ptr_msg = (msg_encoded) ? msg_encoded : vbuffer; if (xfer_chat_send (xfer, ptr_msg, strlen (ptr_msg)) <= 0) { weechat_printf (NULL, _("%s%s: error sending data to \"%s\" via xfer chat"), weechat_prefix ("error"), XFER_PLUGIN_NAME, xfer->remote_nick); xfer_close (xfer, XFER_STATUS_FAILED); } if (msg_encoded) free (msg_encoded); free (vbuffer); }
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); }
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); }
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; }
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); }
/** * Mark DNS request as complete * * @v dns DNS request * @v rc Return status code */ static void dns_done ( struct dns_request *dns, int rc ) { /* Stop the retry timer */ stop_timer ( &dns->timer ); /* Close data transfer interface */ xfer_nullify ( &dns->socket ); xfer_close ( &dns->socket, rc ); /* Mark name resolution as complete */ resolv_done ( &dns->resolv, &dns->sa, rc ); }
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); }
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); }
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; }
/** * Handle SRP session failure * * @v srp SRP device * @v rc Reason for failure */ static void srp_fail ( struct srp_device *srp, int rc ) { /* Close underlying socket */ xfer_close ( &srp->socket, rc ); /* Clear session state */ srp->state = 0; /* If we have reached the retry limit, report the failure */ if ( srp->retry_count >= SRP_MAX_RETRIES ) { srp_scsi_done ( srp, rc ); return; } /* Otherwise, increment the retry count and try to reopen the * connection */ srp->retry_count++; srp_login ( srp ); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); } }
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; }