THEME_REC *theme_create(const char *path, const char *name) { THEME_REC *rec; g_return_val_if_fail(path != NULL, NULL); g_return_val_if_fail(name != NULL, NULL); rec = g_new0(THEME_REC, 1); rec->refcount = 1; rec->path = g_strdup(path); rec->name = g_strdup(name); rec->abstracts = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal); rec->modules = g_hash_table_new((GHashFunc) g_istr_hash, (GCompareFunc) g_istr_equal); themes = g_slist_append(themes, rec); signal_emit("theme created", 1, rec); return rec; }
static void sig_connected(XMPP_SERVER_REC *server) { LmMessage *lmsg; char *str; if (!IS_XMPP_SERVER(server) || (server->connrec->reconnection && xmpp_presence_changed(server->connrec->show, server->show, server->connrec->away_reason, server->away_reason, server->connrec->priority, server->priority))) return; /* set presence available */ lmsg = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_PRESENCE, LM_MESSAGE_SUB_TYPE_AVAILABLE); str = g_strdup_printf("%d", server->priority); lm_message_node_add_child(lmsg->node, "priority", str); g_free(str); signal_emit("xmpp send presence", 2, server, lmsg); lm_message_unref(lmsg); }
static void event_notice(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr) { char *params, *target, *ptr, *msg; g_return_if_fail(data != NULL); params = event_get_params(data, 2, &target, &msg); /* handle only ctcp replies */ if (*msg == 1) { ptr = strrchr(++msg, 1); if (ptr != NULL) *ptr = '\0'; signal_emit("ctcp reply", 5, msg, server, nick, addr, target); signal_stop(); } g_free(params); }
void query_destroy(QUERY_REC *query) { g_return_if_fail(IS_QUERY(query)); if (query->destroying) return; query->destroying = TRUE; queries = g_slist_remove(queries, query); if (query->server != NULL) { query->server->queries = g_slist_remove(query->server->queries, query); } signal_emit("query destroyed", 1, query); MODULE_DATA_DEINIT(query); g_free_not_null(query->server_tag); g_free_not_null(query->address); g_free(query->name); g_free(query); }
static void gui_window_destroyed(WINDOW_REC *window) { MAIN_WINDOW_REC *parent; GUI_WINDOW_REC *gui; g_return_if_fail(window != NULL); gui = WINDOW_GUI(window); parent = gui->parent; gui_window_set_unsticky(window); signal_emit("gui window destroyed", 1, window); gui_window_deinit(gui); window->gui_data = NULL; if (parent->active == window) mainwindow_change_active(parent, window); }
static NETSPLIT_SERVER_REC *netsplit_server_create(IRC_SERVER_REC *server, const char *servername, const char *destserver) { NETSPLIT_SERVER_REC *rec; rec = netsplit_server_find(server, servername, destserver); if (rec != NULL) { rec->last = time(NULL); return rec; } rec = g_new0(NETSPLIT_SERVER_REC, 1); rec->last = time(NULL); rec->server = g_strdup(servername); rec->destserver = g_strdup(destserver); server->split_servers = g_slist_append(server->split_servers, rec); signal_emit("netsplit new server", 2, server, rec); return rec; }
NOTIFYLIST_REC *notifylist_add(const char *mask, const char *ircnets, int away_check, int idle_check_time) { NOTIFYLIST_REC *rec; g_return_val_if_fail(mask != NULL, NULL); rec = g_new0(NOTIFYLIST_REC, 1); rec->mask = g_strdup(mask); rec->ircnets = ircnets == NULL || *ircnets == '\0' ? NULL : g_strsplit(ircnets, " ", -1); rec->away_check = away_check; rec->idle_check_time = idle_check_time; notifylist_add_config(rec); notifies = g_slist_append(notifies, rec); signal_emit("notifylist new", 1, rec); return rec; }
/* SYNTAX: PING <nicks> */ static void cmd_ping(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { GTimeVal tv; char *str; CMD_IRC_SERVER(server); if (*data == '\0' || strcmp(data, "*") == 0) { if (!IS_IRC_ITEM(item)) cmd_return_error(CMDERR_NOT_JOINED); data = window_item_get_target(item); } g_get_current_time(&tv); str = g_strdup_printf("%s PING %ld %ld", data, tv.tv_sec, tv.tv_usec); signal_emit("command ctcp", 3, str, server, item); g_free(str); }
static void dcc_chat_connect(DCC_REC *dcc) { g_return_if_fail(dcc != NULL); if (dcc->addrstr[0] == '\0' || dcc->starttime != 0) { /* already sent a chat request / already chatting */ return; } dcc->handle = net_connect_ip(&dcc->addr, dcc->port, source_host_ok ? source_host_ip : NULL); if (dcc->handle != -1) { dcc->tagread = g_input_add(dcc->handle, G_INPUT_WRITE|G_INPUT_READ|G_INPUT_EXCEPTION, (GInputFunction) sig_chat_connected, dcc); } else { /* error connecting */ signal_emit("dcc error connect", 1, dcc); dcc_destroy(dcc); } }
static void sig_req_usermode_change(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { char *params, *target, *mode; g_return_if_fail(data != NULL); params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &mode); if (!ischannel(*target)) { /* we requested a user mode change, save this */ mode = modes_join(NULL, server->wanted_usermode, mode, FALSE); g_free_not_null(server->wanted_usermode); server->wanted_usermode = mode; } g_free(params); signal_emit("event mode", 4, server, data, nick, addr); }
void channel_destroy(CHANNEL_REC *channel) { g_return_if_fail(IS_CHANNEL(channel)); if (channel->destroying) return; channel->destroying = TRUE; channels = g_slist_remove(channels, channel); if (channel->server != NULL) channel->server->channels = g_slist_remove(channel->server->channels, channel); signal_emit("channel destroyed", 1, channel); MODULE_DATA_DEINIT(channel); g_free_not_null(channel->topic); g_free_not_null(channel->topic_by); g_free_not_null(channel->key); g_free(channel->mode); g_free(channel->name); g_free(channel); }
MAIN_WINDOW_REC *mainwindow_create(void) { MAIN_WINDOW_REC *rec, *parent; int space; rec = g_new0(MAIN_WINDOW_REC, 1); rec->dirty = TRUE; rec->width = term_width; if (mainwindows == NULL) { active_mainwin = rec; rec->first_line = screen_reserved_top; rec->last_line = term_height-1 - screen_reserved_bottom; rec->height = rec->last_line-rec->first_line+1; } else { parent = WINDOW_MAIN(active_win); if (MAIN_WINDOW_TEXT_HEIGHT(parent) < WINDOW_MIN_SIZE+NEW_WINDOW_SIZE) parent = find_window_with_room(); if (parent == NULL) return NULL; /* not enough space */ space = parent->height / 2; rec->first_line = parent->first_line; rec->last_line = rec->first_line + space; rec->height = rec->last_line-rec->first_line+1; parent->first_line = rec->last_line+1; parent->height = parent->last_line-parent->first_line+1; mainwindow_resize(parent, 0, -space-1); } rec->screen_win = mainwindow_create_screen(rec); term_refresh(NULL); mainwindows = g_slist_append(mainwindows, rec); signal_emit("mainwindow created", 1, rec); return rec; }
static void sig_listen(LISTEN_REC *listen) { CLIENT_REC *rec; IPADDR ip; NET_SENDBUF_REC *sendbuf; GIOChannel *handle; char host[MAX_IP_LEN]; int port; g_return_if_fail(listen != NULL); /* accept connection */ handle = net_accept(listen->handle, &ip, &port); if (handle == NULL) return; net_ip2host(&ip, host); sendbuf = net_sendbuffer_create(handle, 0); rec = g_new0(CLIENT_REC, 1); rec->listen = listen; rec->handle = sendbuf; rec->host = g_strdup(host); rec->port = port; if (g_strcmp0(listen->ircnet, "*") == 0) { rec->proxy_address = g_strdup("irc.proxy"); rec->server = servers == NULL ? NULL : IRC_SERVER(servers->data); } else { rec->proxy_address = g_strdup_printf("%s.proxy", listen->ircnet); rec->server = servers == NULL ? NULL : IRC_SERVER(server_find_chatnet(listen->ircnet)); } rec->recv_tag = g_input_add(handle, G_INPUT_READ, (GInputFunction) sig_listen_client, rec); proxy_clients = g_slist_prepend(proxy_clients, rec); rec->listen->clients = g_slist_prepend(rec->listen->clients, rec); signal_emit("proxy client connecting", 1, rec); printtext(rec->server, NULL, MSGLEVEL_CLIENTNOTICE, "Proxy: New client %s:%d on port %d (%s)", rec->host, rec->port, listen->port, listen->ircnet); }
/* Destroy all perl scripts and deinitialize perl interpreter */ void perl_scripts_deinit(void) { if (my_perl == NULL) return; /* unload all scripts */ while (perl_scripts != NULL) perl_script_unload(perl_scripts->data); signal_emit("perl scripts deinit", 0); perl_signals_stop(); perl_sources_stop(); perl_common_stop(); /* Unload all perl libraries loaded with dynaloader */ perl_eval_pv("foreach my $lib (@DynaLoader::dl_modules) { if ($lib =~ /^Irssi\\b/) { $lib .= '::deinit();'; eval $lib; } }", TRUE); #if PERL_STATIC_LIBS == 1 /* If perl is statically built we should manually deinit the modules which are booted in boot_Irssi_Core above */ perl_eval_pv("foreach my $lib (qw(" "Irssi" " " "Irssi::Irc" " " "Irssi::UI" " " "Irssi::TextUI" ")) { eval $lib . '::deinit();'; }", TRUE); #endif /* We could unload all libraries .. but this crashes with some libraries, probably because we don't call some deinit function.. Anyway, this would free some memory with /SCRIPT RESET, but it leaks memory anyway. */ /*perl_eval_pv("eval { foreach my $lib (@DynaLoader::dl_librefs) { DynaLoader::dl_unload_file($lib); } }", TRUE);*/ /* perl interpreter */ PL_perl_destruct_level = 1; perl_destruct(my_perl); perl_free(my_perl); my_perl = NULL; }
/* `optlist' should contain only one unknown key - the server tag. returns NULL if there was unknown -option */ static int cmd_options_get_signal(const char *cmd, GHashTable *optlist) { GSList *list, *tmp, *next; char *signame; int signum; /* get all the options, then remove the known ones. there should be only one left - the signal */ list = hashtable_get_keys(optlist); if (cmd != NULL) { for (tmp = list; tmp != NULL; tmp = next) { char *option = tmp->data; next = tmp->next; if (command_have_option(cmd, option)) list = g_slist_remove(list, option); } } if (list == NULL) return -1; signame = list->data; signum = -1; signum = is_numeric(signame, 0) ? atol(signame) : signal_name_to_id(signame); if (signum == -1 || list->next != NULL) { /* unknown option (not a signal) */ signal_emit("error command", 2, GINT_TO_POINTER(CMDERR_OPTION_UNKNOWN), signum == -1 ? list->data : list->next->data); signal_stop(); return -2; } g_slist_free(list); return signum; }
static int perl_script_eval(PERL_SCRIPT_REC *script) { dSP; char *error; int retcount; SV *ret; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(new_pv(script->path != NULL ? script->path : script->data))); XPUSHs(sv_2mortal(new_pv(script->name))); PUTBACK; retcount = perl_call_pv(script->path != NULL ? "Irssi::Core::eval_file" : "Irssi::Core::eval_data", G_EVAL|G_SCALAR); SPAGAIN; error = NULL; if (SvTRUE(ERRSV)) { error = SvPV(ERRSV, PL_na); if (error != NULL) { error = g_strdup(error); signal_emit("script error", 2, script, error); g_free(error); } } else if (retcount > 0) { ret = POPs; } PUTBACK; FREETMPS; LEAVE; return error == NULL; }
/* execute the commands in string - commands can be split with ';' */ void eval_special_string(const char *cmd, const char *data, SERVER_REC *server, void *item) { const char *cmdchars; char *orig, *str, *start, *ret; int arg_used; cmdchars = settings_get_str("cmdchars"); orig = start = str = g_strdup(cmd); do { if (is_split_char(str, start)) *str++ = '\0'; else if (*str != '\0') { str++; continue; } ret = parse_special_string(start, server, item, data, &arg_used); if (strchr(cmdchars, *ret) == NULL) { /* no command char - let's put it there.. */ char *old = ret; ret = g_strdup_printf("%c%s", *cmdchars, old); g_free(old); } if (!arg_used && *data != '\0') { /* append the string with all the arguments */ char *old = ret; ret = g_strconcat(old, " ", data, NULL); g_free(old); } signal_emit("send command", 3, ret, server, item); g_free(ret); start = str; } while (*start != '\0'); g_free(orig); }
static void mainwindows_resize_smaller(int ychange, int xchange) { GSList *sorted, *tmp; int space; space = 0; for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) { MAIN_WINDOW_REC *rec = tmp->data; space += rec->lines-WINDOW_MIN_SIZE; } if (space < -ychange) { /* not enough space, use different algorithm */ mainwindows_resize_too_small(ychange, xchange); return; } /* resize windows that have space */ sorted = mainwindows_get_sorted(TRUE); for (tmp = sorted; tmp != NULL && ychange < 0; tmp = tmp->next) { MAIN_WINDOW_REC *rec = tmp->data; space = rec->lines-WINDOW_MIN_SIZE; if (space <= 0) { rec->first_line += ychange; rec->last_line += ychange; signal_emit("mainwindow moved", 1, rec); continue; } if (space <= 0) space = 1; if (space > -ychange) space = -ychange; rec->last_line += ychange; ychange += space; rec->first_line += ychange; mainwindow_resize(rec, -space, xchange); } g_slist_free(sorted); }
void window_item_remove(WI_ITEM_REC *item) { WINDOW_REC *window; g_return_if_fail(item != NULL); window = window_item_window(item); if (window == NULL) return; item->window = NULL; window->items = g_slist_remove(window->items, item); if (window->active == item) { window_item_set_active(window, window->items == NULL ? NULL : window->items->data); } signal_emit("window item remove", 2, window, item); }
static void gui_window_created(WINDOW_REC *window) { MAIN_WINDOW_REC *parent; g_return_if_fail(window != NULL); parent = window_create_override != 0 && active_win != NULL && WINDOW_GUI(active_win) != NULL ? WINDOW_GUI(active_win)->parent : mainwindow_create(); if (parent == NULL) { /* not enough space for new window, but we really can't abort creation of the window anymore, so create hidden window instead. */ parent = WINDOW_GUI(active_win)->parent; } window_create_override = -1; if (parent->active == NULL) parent->active = window; window->gui_data = gui_window_init(window, parent); signal_emit("gui window created", 1, window); }
static void event_privmsg(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { char *params, *target, *msg, *ptr; g_return_if_fail(data != NULL); params = event_get_params(data, 2, &target, &msg); /* handle only ctcp messages.. */ if (*msg == 1) { /* remove the later \001 */ ptr = strrchr(++msg, 1); if (ptr != NULL) *ptr = '\0'; signal_emit("ctcp msg", 5, server, msg, nick, addr, target); signal_stop(); } g_free(params); }
QUERY_REC *query_create(IRC_SERVER_REC *server, const char *nick, int automatic) { QUERY_REC *rec; g_return_val_if_fail(nick != NULL, NULL); rec = g_new0(QUERY_REC, 1); queries = g_slist_append(queries, rec); if (server != NULL) server->queries = g_slist_append(server->queries, rec); MODULE_DATA_INIT(rec); rec->type = module_get_uniq_id("IRC", WI_IRC_QUERY); rec->nick = g_strdup(nick); if (server != NULL) { rec->server_tag = g_strdup(server->tag); rec->server = server; } signal_emit("query created", 2, rec, GINT_TO_POINTER(automatic)); return rec; }
static void process_destroy(PROCESS_REC *rec, int status) { processes = g_slist_remove(processes, rec); signal_emit("exec remove", 2, rec, GINT_TO_POINTER(status)); if (rec->read_tag != -1) g_source_remove(rec->read_tag); if (rec->target_item != NULL) exec_wi_destroy(rec->target_item); line_split_free(rec->databuf); g_io_channel_close(rec->in); g_io_channel_unref(rec->in); net_sendbuffer_destroy(rec->out, TRUE); g_free_not_null(rec->name); g_free_not_null(rec->target); g_free(rec->args); g_free(rec); }
/* CTCP: DCC RESUME - requesting to resume DCC SEND */ static void ctcp_msg_dcc_resume(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr, const char *target, DCC_REC *chat) { FILE_DCC_REC *dcc; char *str; long size; if (!dcc_ctcp_resume_parse(DCC_SEND_TYPE, data, nick, &dcc, &size)) { signal_emit("dcc error ctcp", 5, "RESUME", data, nick, addr, target); } else if (dcc != NULL && dcc_resume_file_check(dcc, server, size)) { str = g_strdup_printf(DCC_SEND(dcc)->file_quoted ? "DCC ACCEPT \"%s\" %d %lu" : "DCC ACCEPT %s %d %lu", dcc->arg, dcc->port, dcc->transfd); dcc_ctcp_message(dcc->server, dcc->nick, dcc->chat, FALSE, str); g_free(str); } }
static void netsplit_destroy(IRC_SERVER_REC *server, NETSPLIT_REC *rec) { GSList *tmp; g_return_if_fail(rec != NULL); signal_emit("netsplit remove", 1, rec); for (tmp = rec->channels; tmp != NULL; tmp = tmp->next) { NETSPLIT_CHAN_REC *rec = tmp->data; g_free(rec->name); g_free(rec); } if (--rec->server->count == 0) netsplit_destroy_server(server, rec->server); g_free(rec->nick); g_free(rec->address); g_free(rec); }
void reconnect_save_status(SERVER_CONNECT_REC *conn, SERVER_REC *server) { g_free_not_null(conn->tag); conn->tag = g_strdup(server->tag); g_free_not_null(conn->away_reason); conn->away_reason = !server->usermode_away ? NULL : g_strdup(server->away_reason); if (!server->connected) { /* default to channels/usermode from connect record since server isn't fully connected yet */ /* XXX when is reconnect_save_status() called with * server->connected==FALSE? */ g_free_not_null(conn->channels); conn->channels = server->connrec->no_autojoin_channels ? NULL : g_strdup(server->connrec->channels); } signal_emit("server reconnect save status", 2, conn, server); }
static void cmd_notice(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { const char *target, *msg; void *free_arg; CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &msg)) return; if (g_strcmp0(target, "*") == 0) target = item == NULL ? "" : window_item_get_target(item); if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); signal_emit("message irc own_notice", 3, server, msg, target); cmd_params_free(free_arg); }
static void dcc_chat_connect(CHAT_DCC_REC *dcc) { g_return_if_fail(IS_DCC_CHAT(dcc)); if (dcc->addrstr[0] == '\0' || dcc->starttime != 0 || dcc->handle != NULL) { /* already sent a chat request / already chatting */ return; } dcc->handle = dcc_connect_ip(&dcc->addr, dcc->port); if (dcc->handle != NULL) { dcc->tagconn = g_input_add(dcc->handle, G_INPUT_WRITE | G_INPUT_READ, (GInputFunction) sig_chat_connected, dcc); } else { /* error connecting */ signal_emit("dcc error connect", 1, dcc); dcc_destroy(DCC(dcc)); } }
static void send_composing_event(XMPP_SERVER_REC *server, const char *dest, const char *id, gboolean composing) { LmMessage *lmsg; LmMessageNode *node; char *recoded; recoded = xmpp_recode_out(dest); lmsg = lm_message_new_with_sub_type(recoded, LM_MESSAGE_TYPE_MESSAGE, LM_MESSAGE_SUB_TYPE_CHAT); g_free(recoded); node = lm_message_node_add_child(lmsg->node, "x", NULL); lm_message_node_set_attribute(node, XMLNS, XMLNS_EVENT); if (composing) lm_message_node_add_child(node, "composing", NULL); if (id != NULL) lm_message_node_add_child(node, "id", id); signal_emit("xmpp send message", 2, server, lmsg); lm_message_unref(lmsg); }
/* SYNTAX: ALIAS [[-]<alias> [<command>]] */ static void cmd_alias(const char *data) { char *alias, *value; void *free_arg; g_return_if_fail(data != NULL); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &alias, &value)) return; if (*alias == '-') { if (alias[1] != '\0') alias_remove(alias+1); } else if (*alias == '\0' || *value == '\0') show_aliases(alias); else { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_ALIAS_ADDED, alias); iconfig_set_str("aliases", alias, value); signal_emit("alias added", 2, alias, value); } cmd_params_free(free_arg); }