void alias_free (struct t_alias *alias) { struct t_alias *new_alias_list; /* remove alias from list */ if (last_alias == alias) last_alias = alias->prev_alias; if (alias->prev_alias) { (alias->prev_alias)->next_alias = alias->next_alias; new_alias_list = alias_list; } else new_alias_list = alias->next_alias; if (alias->next_alias) (alias->next_alias)->prev_alias = alias->prev_alias; /* free data */ if (alias->hook) dogechat_unhook (alias->hook); if (alias->name) free (alias->name); if (alias->command) free (alias->command); if (alias->completion) free (alias->completion); free (alias); alias_list = new_alias_list; }
void alias_update_completion (struct t_alias *alias, const char *completion) { /* update completion in alias */ if (alias->completion) free (alias->completion); alias->completion = (completion) ? strdup (completion) : NULL; /* unhook and hook again command, with new completion */ dogechat_unhook (alias->hook); alias->hook = NULL; alias_hook_command (alias); }
void exec_free (struct t_exec_cmd *exec_cmd) { int i; if (!exec_cmd) return; /* remove command from commands list */ if (exec_cmd->prev_cmd) (exec_cmd->prev_cmd)->next_cmd = exec_cmd->next_cmd; if (exec_cmd->next_cmd) (exec_cmd->next_cmd)->prev_cmd = exec_cmd->prev_cmd; if (exec_cmds == exec_cmd) exec_cmds = exec_cmd->next_cmd; if (last_exec_cmd == exec_cmd) last_exec_cmd = exec_cmd->prev_cmd; /* free data */ if (exec_cmd->hook) dogechat_unhook (exec_cmd->hook); if (exec_cmd->name) free (exec_cmd->name); if (exec_cmd->command) free (exec_cmd->command); if (exec_cmd->buffer_full_name) free (exec_cmd->buffer_full_name); for (i = 0; i < 2; i++) { if (exec_cmd->output[i]) free (exec_cmd->output[i]); } if (exec_cmd->pipe_command) free (exec_cmd->pipe_command); if (exec_cmd->hsignal) free (exec_cmd->hsignal); free (exec_cmd); exec_cmds_count--; }
void relay_server_close_socket (struct t_relay_server *server) { if (server->hook_fd) { dogechat_unhook (server->hook_fd); server->hook_fd = NULL; } if (server->sock >= 0) { close (server->sock); server->sock = -1; if (!relay_signal_upgrade_received) { dogechat_printf (NULL, _("%s: socket closed for %s (port %d)"), RELAY_PLUGIN_NAME, server->protocol_string, server->port); } } }
void fifo_remove () { /* remove fd hook */ if (fifo_fd_hook) { dogechat_unhook (fifo_fd_hook); fifo_fd_hook = NULL; } /* close FIFO pipe */ if (fifo_fd != -1) { close (fifo_fd); fifo_fd = -1; } /* remove FIFO from disk */ if (fifo_filename) unlink (fifo_filename); /* remove any unterminated message */ if (fifo_unterminated) { free (fifo_unterminated); fifo_unterminated = NULL; } /* free filename */ if (fifo_filename) { free (fifo_filename); fifo_filename = NULL; } dogechat_printf (NULL, _("%s: pipe closed"), FIFO_PLUGIN_NAME); }
int dogechat_plugin_end (struct t_dogechat_plugin *plugin) { /* make C compiler happy */ (void) plugin; if (irc_hook_timer) dogechat_unhook (irc_hook_timer); if (irc_signal_upgrade_received) { irc_config_write (1); irc_upgrade_save (); } else { irc_config_write (0); irc_server_disconnect_all (); } irc_ignore_free_all (); irc_raw_message_free_all (); irc_server_free_all (); irc_config_free (); irc_notify_end (); irc_redirect_end (); irc_color_end (); return DOGECHAT_RC_OK; }
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; }
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; }
int xfer_network_fd_cb (void *arg_xfer, 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) fd; length = sizeof (addr); memset (&addr, 0, length); xfer = (struct t_xfer *)arg_xfer; 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; dogechat_unhook (xfer->hook_fd); xfer->hook_fd = NULL; close (xfer->sock); xfer->sock = -1; if (sock < 0) { dogechat_printf (NULL, _("%s%s: unable to create socket for sending " "file: error %d %s"), dogechat_prefix ("error"), XFER_PLUGIN_NAME, error, strerror (error)); xfer_close (xfer, XFER_STATUS_FAILED); xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE); return DOGECHAT_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) { dogechat_printf (NULL, _("%s%s: unable to set option \"nonblock\" " "for socket: 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 DOGECHAT_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 (DOGECHAT_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; dogechat_unhook (xfer->hook_fd); xfer->hook_fd = NULL; close (xfer->sock); xfer->sock = -1; if (sock < 0) { dogechat_printf (NULL, _("%s%s: unable to create socket for sending " "file: error %d %s"), dogechat_prefix ("error"), XFER_PLUGIN_NAME, error, strerror (error)); xfer_close (xfer, XFER_STATUS_FAILED); xfer_buffer_refresh (DOGECHAT_HOTLIST_MESSAGE); return DOGECHAT_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) { dogechat_printf (NULL, _("%s%s: unable to set option \"nonblock\" " "for socket: 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 DOGECHAT_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 (DOGECHAT_HOTLIST_MESSAGE); xfer->hook_fd = dogechat_hook_fd (xfer->sock, 1, 0, 0, &xfer_chat_recv_cb, xfer); xfer_chat_open_buffer (xfer); } } return DOGECHAT_RC_OK; }