/* received msg to all ops in channel */ static void sig_message_irc_op_public(SERVER_REC *server, const char *msg, const char *nick, const char *address, const char *target) { char *nickmode, *optarget, *prefix; const char *cleantarget; /* only skip here so the difference can be stored in prefix */ cleantarget = fe_channel_skip_prefix(IRC_SERVER(server), target); prefix = g_strndup(target, cleantarget - target); /* and clean the rest here */ cleantarget = get_visible_target(IRC_SERVER(server), cleantarget); nickmode = channel_get_nickmode(channel_find(server, cleantarget), nick); optarget = g_strconcat(prefix, cleantarget, NULL); printformat_module("fe-common/core", server, cleantarget, MSGLEVEL_PUBLIC, TXT_PUBMSG_CHANNEL, nick, optarget, msg, nickmode); g_free(nickmode); g_free(optarget); g_free(prefix); }
/* function for finding IRC channels - adds support for !channels */ static CHANNEL_REC *irc_channel_find_server(SERVER_REC *server, const char *channel) { GSList *tmp; char *fmt_channel; /* if 'channel' has no leading # this lookup is going to fail, add a * octothorpe in front of it to handle this case. */ fmt_channel = server_ischannel(SERVER(server), channel) ? g_strdup(channel) : g_strdup_printf("#%s", channel); for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { CHANNEL_REC *rec = tmp->data; if (rec->chat_type != server->chat_type) continue; /* check both !ABCDEchannel and !channel */ if (IRC_SERVER(server)->nick_comp_func(fmt_channel, rec->name) == 0) { g_free(fmt_channel); return rec; } if (IRC_SERVER(server)->nick_comp_func(fmt_channel, rec->visible_name) == 0) { g_free(fmt_channel); return rec; } } g_free(fmt_channel); return NULL; }
static void send_message(SERVER_REC *server, const char *target, const char *msg, int target_type) { IRC_SERVER_REC *ircserver; CHANNEL_REC *channel; char *str; char *recoded; ircserver = IRC_SERVER(server); g_return_if_fail(ircserver != NULL); g_return_if_fail(target != NULL); g_return_if_fail(msg != NULL); if (*target == '!') { /* !chan -> !12345chan */ channel = channel_find(server, target); if (channel != NULL && g_ascii_strcasecmp(channel->name, target) != 0) target = channel->name; } recoded = recode_out(SERVER(server), msg, target); str = g_strdup_printf("PRIVMSG %s :%s", target, recoded); irc_send_cmd_split(ircserver, str, 2, ircserver->max_msgs_in_cmd); g_free(str); g_free(recoded); }
/* SYNTAX: WAIT [-<server tag>] <milliseconds> */ static void cmd_wait(const char *data, IRC_SERVER_REC *server) { GHashTable *optlist; char *msecs; void *free_arg; int n; CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST, NULL, &optlist, &msecs)) return; if (*msecs == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); /* -<server tag> */ server = IRC_SERVER(cmd_options_get_server(NULL, optlist, SERVER(server))); n = atoi(msecs); if (server != NULL && n > 0) { g_get_current_time(&server->wait_cmd); server->wait_cmd.tv_sec += n/1000; server->wait_cmd.tv_usec += n%1000; if (server->wait_cmd.tv_usec >= 1000) { server->wait_cmd.tv_sec++; server->wait_cmd.tv_usec -= 1000; } } cmd_params_free(free_arg); }
static void sig_message_own_public(SERVER_REC *server, const char *msg, const char *target, const char *origtarget) { const char *oldtarget; char *nickmode; if (!IS_IRC_SERVER(server)) return; oldtarget = target; target = fe_channel_skip_prefix(IRC_SERVER(server), target); if (target != oldtarget) { /* Hybrid 6 / Bahamut feature, send msg to all ops / ops+voices in channel */ nickmode = channel_get_nickmode(channel_find(server, target), server->nick); printformat_module("fe-common/core", server, target, MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT, TXT_OWN_MSG_CHANNEL, server->nick, oldtarget, msg, nickmode); g_free(nickmode); signal_stop(); } }
/* SYNTAX: ACTION [-<server tag>] <target> <message> */ static void cmd_action(const char *data, IRC_SERVER_REC *server) { GHashTable *optlist; const char *target, *text; char *subtext; char **splittexts; int n = 0; void *free_arg; CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST, "action", &optlist, &target, &text)) return; if (*target == '\0' || *text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); server = IRC_SERVER(cmd_options_get_server("action", optlist, SERVER(server))); if (server == NULL || !server->connected) cmd_param_error(CMDERR_NOT_CONNECTED); splittexts = irc_server_split_action(server, target, text); while ((subtext = splittexts[n++])) { irc_server_send_action(server, target, subtext); signal_emit("message irc own_action", 3, server, subtext, target); } g_strfreev(splittexts); cmd_params_free(free_arg); }
/* SYNTAX: ACTION [-<server tag>] <target> <message> */ static void cmd_action(const char *data, IRC_SERVER_REC *server) { GHashTable *optlist; const char *target, *text; char *recoded; void *free_arg; CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST, "action", &optlist, &target, &text)) return; if (*target == '\0' || *text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); server = IRC_SERVER(cmd_options_get_server("action", optlist, SERVER(server))); if (server == NULL || !server->connected) cmd_param_error(CMDERR_NOT_CONNECTED); recoded = recode_out(SERVER(server), text, target); irc_send_cmdv(server, "PRIVMSG %s :\001ACTION %s\001", target, recoded); signal_emit("message irc own_action", 3, server, recoded, target); g_free(recoded); cmd_params_free(free_arg); }
static void dcc_queue_send_next(int queue) { IRC_SERVER_REC *server; DCC_QUEUE_REC *qrec; int send_started = FALSE; while ((qrec = dcc_queue_get_next(queue)) != NULL && !send_started) { server = qrec->servertag == NULL ? NULL : IRC_SERVER(server_find_tag(qrec->servertag)); if (server == NULL && qrec->chat == NULL) { /* no way to send this request */ signal_emit("dcc error send no route", 2, qrec->nick, qrec->file); } else { send_started = dcc_send_one_file(queue, qrec->nick, qrec->file, server, qrec->chat); } dcc_queue_remove_head(queue); } if (!send_started) { /* no files in queue anymore, remove it */ dcc_queue_free(queue); } }
static void sig_message_irc_action(IRC_SERVER_REC *server, const char *msg, const char *nick, const char *address, const char *target) { void *item; const char *oldtarget; char *freemsg = NULL; int level; int own = FALSE; oldtarget = target; target = fe_channel_skip_prefix(IRC_SERVER(server), target); level = MSGLEVEL_ACTIONS | (server_ischannel(SERVER(server), target) ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS); if (ignore_check_plus(SERVER(server), nick, address, target, msg, &level, TRUE)) return; if (server_ischannel(SERVER(server), target)) { item = irc_channel_find(server, target); } else { own = (!g_strcmp0(nick, server->nick)); item = privmsg_get_query(SERVER(server), own ? target : nick, FALSE, level); } if (settings_get_bool("emphasis")) msg = freemsg = expand_emphasis(item, msg); if (server_ischannel(SERVER(server), target)) { /* channel action */ if (window_item_is_active(item) && target == oldtarget) { /* message to active channel in window */ printformat(server, target, level, IRCTXT_ACTION_PUBLIC, nick, msg); } else { /* message to not existing/active channel, or to @/+ */ printformat(server, target, level, IRCTXT_ACTION_PUBLIC_CHANNEL, nick, oldtarget, msg); } } else { if (own) { /* own action bounced */ printformat(server, target, MSGLEVEL_ACTIONS | MSGLEVEL_MSGS, item != NULL && oldtarget == target ? IRCTXT_OWN_ACTION : IRCTXT_OWN_ACTION_TARGET, server->nick, msg, oldtarget); } else { /* private action */ printformat(server, nick, MSGLEVEL_ACTIONS | MSGLEVEL_MSGS, item == NULL ? IRCTXT_ACTION_PRIVATE : IRCTXT_ACTION_PRIVATE_QUERY, nick, address == NULL ? "" : address, msg); } } g_free_not_null(freemsg); }
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); }
/* function for finding IRC channels - adds support for !channels */ static CHANNEL_REC *irc_channel_find_server(SERVER_REC *server, const char *channel) { GSList *tmp; for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { CHANNEL_REC *rec = tmp->data; if (rec->chat_type != server->chat_type) continue; /* check both !ABCDEchannel and !channel */ if (IRC_SERVER(server)->nick_comp_func(channel, rec->name) == 0) return rec; if (IRC_SERVER(server)->nick_comp_func(channel, rec->visible_name) == 0) return rec; } return NULL; }
static void sig_message_irc_action(IRC_SERVER_REC *server, const char *msg, const char *nick, const char *address, const char *target) { void *item; const char *oldtarget; char *freemsg = NULL; int level; oldtarget = target; target = skip_target(IRC_SERVER(server), target); level = MSGLEVEL_ACTIONS | (ischannel(*target) ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS); if (ignore_check(SERVER(server), nick, address, target, msg, level)) return; if (ignore_check(SERVER(server), nick, address, target, msg, level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; if (ischannel(*target)) item = irc_channel_find(server, target); else item = privmsg_get_query(SERVER(server), nick, FALSE, level); if (settings_get_bool("emphasis")) msg = freemsg = expand_emphasis(item, msg); if (ischannel(*target)) { /* channel action */ if (window_item_is_active(item) && target == oldtarget) { /* message to active channel in window */ printformat(server, target, level, IRCTXT_ACTION_PUBLIC, nick, msg); } else { /* message to not existing/active channel, or to @/+ */ printformat(server, target, level, IRCTXT_ACTION_PUBLIC_CHANNEL, nick, oldtarget, msg); } } else { /* private action */ printformat(server, nick, MSGLEVEL_ACTIONS | MSGLEVEL_MSGS, item == NULL ? IRCTXT_ACTION_PRIVATE : IRCTXT_ACTION_PRIVATE_QUERY, nick, address == NULL ? "" : address, msg); } g_free_not_null(freemsg); }
static void test_server_destroy_flood(ServerDestroyFloodData *fixture, const void *data) { SERVER_REC *server; /* = g_new0(IRC_SERVER_REC, 1); */ CHAT_PROTOCOL_REC *proto; SERVER_CONNECT_REC *conn; GLogLevelFlags loglev; g_test_bug("796"); /* for the purpose of this exercise, we are ignoring the errors of g_hash_table_lookup failure */ loglev = g_log_set_always_fatal(G_LOG_FATAL_MASK); proto = chat_protocol_find("IRC"); conn = server_create_conn(proto->id, "localhost", 0, "", "", "user"); server = proto->server_init_connect(conn); server->session_reconnect = TRUE; server->tag = g_strdup("testserver"); g_test_message("created server: %p", server); /* we skip some initialisations that would try to send data */ /* irc_servers_deinit(); */ irc_session_deinit(); irc_irc_deinit(); server_connect_finished(server); /* make up for the skipped session init */ irc_server_init_bare_minimum(IRC_SERVER(server)); irc_irc_init(); irc_session_init(); /* irc_servers_init(); */ /* simulate failing irc_server_send_data() */ server->connection_lost = TRUE; /* chat_completion_deinit(); fe_messages_deinit(); irc_notifylist_deinit(); */ server_ref(server); signal_emit("event privmsg", 4, server, "#someroom :test message", "nick", "user@host"); server_unref(server); g_log_set_always_fatal(loglev); }
static void sig_message_irc_notice(SERVER_REC *server, const char *msg, const char *nick, const char *address, const char *target) { const char *oldtarget; int level = MSGLEVEL_NOTICES; oldtarget = target; target = fe_channel_skip_prefix(IRC_SERVER(server), target); if (address == NULL || *address == '\0') { level = MSGLEVEL_SNOTES; /* notice from server */ if (!ignore_check_plus(server, nick, "", target, msg, &level, TRUE)) { printformat(server, target, level, IRCTXT_NOTICE_SERVER, nick, msg); } return; } if (ignore_check_plus(server, nick, address, server_ischannel(SERVER(server), target) ? target : NULL, msg, &level, TRUE)) return; if (server_ischannel(SERVER(server), target)) { /* notice in some channel */ printformat(server, target, level, IRCTXT_NOTICE_PUBLIC, nick, oldtarget, msg); } else { char *channel; /* check if this is a cnotice */ channel = notice_channel_context(server, msg); if (channel == NULL) { /* private notice */ privmsg_get_query(SERVER(server), nick, FALSE, MSGLEVEL_NOTICES); } printformat(server, channel == NULL ? nick : channel, level, IRCTXT_NOTICE_PRIVATE, nick, address, msg); g_free(channel); } }
static void sig_message_irc_notice(SERVER_REC *server, const char *msg, const char *nick, const char *address, const char *target) { const char *oldtarget; int level = MSGLEVEL_NOTICES; oldtarget = target; target = skip_target(IRC_SERVER(server), target); if (address == NULL || *address == '\0') { /* notice from server */ if (!ignore_check(server, nick, "", target, msg, MSGLEVEL_SNOTES)) { printformat(server, target, MSGLEVEL_SNOTES, IRCTXT_NOTICE_SERVER, nick, msg); } return; } if (ignore_check(server, nick, address, ischannel(*target) ? target : NULL, msg, level)) return; if (ignore_check(server, nick, address, ischannel(*target) ? target : NULL, msg, level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; if (ischannel(*target)) { /* notice in some channel */ printformat(server, target, level, IRCTXT_NOTICE_PUBLIC, nick, oldtarget, msg); } else { /* private notice */ privmsg_get_query(SERVER(server), nick, FALSE, MSGLEVEL_NOTICES); printformat(server, nick, level, IRCTXT_NOTICE_PRIVATE, nick, address, msg); } }
/* something is going to be printed to screen, print our current netsplit message before it. */ static void sig_print_starting(TEXT_DEST_REC *dest) { NETJOIN_SERVER_REC *rec; if (printing_joins) return; if (!IS_IRC_SERVER(dest->server)) return; if (!(dest->level & MSGLEVEL_PUBLIC)) return; if (!server_ischannel(dest->server, dest->target)) return; rec = netjoin_find_server(IRC_SERVER(dest->server)); if (rec != NULL && rec->netjoins != NULL) print_netjoins(rec, dest->target); }
/* your /userhost $N address (user@host) */ static char *expando_userhost(SERVER_REC *server, void *item, int *free_ret) { IRC_SERVER_REC *ircserver; const char *username; char hostname[100]; ircserver = IRC_SERVER(server); /* prefer the _real_ /userhost reply */ if (ircserver != NULL && ircserver->userhost != NULL) return ircserver->userhost; /* haven't received userhost reply yet. guess something */ *free_ret = TRUE; if (ircserver == NULL) username = settings_get_str("user_name"); else username = ircserver->connrec->username; if (gethostname(hostname, sizeof(hostname)) != 0 || *hostname == '\0') strcpy(hostname, "??"); return g_strconcat(username, "@", hostname, NULL);; }
/* DCC CLOSE CHAT <nick> - check only from chat_ids in open DCC chats, the default handler will check from DCC chat requests */ static void cmd_dcc_close(char *data, SERVER_REC *server) { GSList *tmp, *next; char *nick; void *free_arg; int found; g_return_if_fail(data != NULL); if (g_ascii_strncasecmp(data, "CHAT ", 5) != 0 || !cmd_get_params(data, &free_arg, 2, NULL, &nick)) return; if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); found = FALSE; for (tmp = dcc_conns; tmp != NULL; tmp = next) { CHAT_DCC_REC *dcc = tmp->data; next = tmp->next; if (IS_DCC_CHAT(dcc) && dcc->id != NULL && g_ascii_strcasecmp(dcc->id, nick) == 0) { found = TRUE; if (!dcc_is_connected(dcc) && IS_IRC_SERVER(server)) dcc_reject(DCC(dcc), IRC_SERVER(server)); else { /* don't send DCC REJECT after DCC chat is already open */ dcc_close(DCC(dcc)); } } } if (found) signal_stop(); cmd_params_free(free_arg); }
static void sig_message_own_action(IRC_SERVER_REC *server, const char *msg, const char *target) { void *item; const char *oldtarget; char *freemsg = NULL; oldtarget = target; target = fe_channel_skip_prefix(IRC_SERVER(server), target); if (server_ischannel(SERVER(server), target)) item = irc_channel_find(server, target); else item = irc_query_find(server, target); if (settings_get_bool("emphasis")) msg = freemsg = expand_emphasis(item, msg); printformat(server, target, MSGLEVEL_ACTIONS | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT | (server_ischannel(SERVER(server), target) ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS), item != NULL && oldtarget == target ? IRCTXT_OWN_ACTION : IRCTXT_OWN_ACTION_TARGET, server->nick, msg, oldtarget); g_free_not_null(freemsg); }
/* your hostname address (host) */ static char *expando_hostname(SERVER_REC *server, void *item, int *free_ret) { IRC_SERVER_REC *ircserver; char hostname[HOST_NAME_MAX]; char **list; char *hostname_split; ircserver = IRC_SERVER(server); *free_ret = TRUE; /* prefer the _real_ /userhost reply */ if (ircserver != NULL && ircserver->userhost != NULL) { list = g_strsplit(ircserver->userhost, "@", -1); hostname_split = g_strdup(list[1]); g_strfreev(list); return hostname_split; } /* haven't received userhost reply yet. guess something */ if (gethostname(hostname, sizeof(hostname)) != 0 || *hostname == '\0') strcpy(hostname, "(none)"); return g_strdup(hostname); }
/* current server name */ static char *expando_servername(SERVER_REC *server, void *item, int *free_ret) { IRC_SERVER_REC *ircserver = IRC_SERVER(server); return ircserver == NULL ? "" : ircserver->real_address; }
/* SYNTAX: SERVER [-ircnet <ircnet>] [-host <hostname>] [+]<address>|<ircnet> [<port> [<password> [<nick>]]] */ static void cmd_server(const char *data, IRC_SERVER_REC *server, void *item) { GHashTable *optlist; IRC_SERVER_CONNECT_REC *conn; char *addr, *port, *channels, *away_reason, *usermode, *ircnet; void *free_arg; int no_old_server; g_return_if_fail(data != NULL); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS, "connect", &optlist, &addr, &port)) return; if (*addr == '\0' || strcmp(addr, "+") == 0) cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); conn = server == NULL ? NULL : server->connrec; if (*addr != '+' && conn == NULL) { /* check if there's a server waiting for removal in reconnection queue.. */ RECONNECT_REC *rec; rec = find_reconnect_server(addr, atoi(port)); if (rec != NULL) { /* remove the reconnection.. */ conn = (IRC_SERVER_CONNECT_REC *) rec->conn; server_reconnect_destroy(rec, FALSE); } } no_old_server = server == NULL; ircnet = conn == NULL ? NULL : g_strdup(conn->chatnet); if (*addr == '+' || conn == NULL) { channels = away_reason = usermode = NULL; } else if (server != NULL) { channels = irc_server_get_channels((IRC_SERVER_REC *) server); if (*channels == '\0') g_free_and_null(channels); away_reason = !server->usermode_away ? NULL : g_strdup(server->away_reason); usermode = g_strdup(server->usermode); signal_emit("command disconnect", 3, "* Changing server", server, item); } else { channels = g_strdup(conn->channels); away_reason = g_strdup(conn->away_reason); usermode = g_strdup(conn->usermode); } server = IRC_SERVER(irc_connect_server(data)); if (*addr == '+' || server == NULL || (ircnet != NULL && server->connrec->chatnet != NULL && g_strcasecmp(ircnet, server->connrec->chatnet) != 0)) { g_free_not_null(channels); g_free_not_null(usermode); g_free_not_null(away_reason); } else if (server != NULL && conn != NULL) { server->connrec->reconnection = TRUE; server->connrec->channels = channels; server->connrec->usermode = usermode; server->connrec->away_reason = away_reason; if (no_old_server) server_connect_free(SERVER_CONNECT(conn)); } g_free_not_null(ircnet); cmd_params_free(free_arg); }
/* SYNTAX: WHOIS [-<server tag>] [<server>] [<nicks>] */ static void cmd_whois(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { GHashTable *optlist; char *qserver, *query, *event_402, *str; void *free_arg; int free_nick; CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_UNKNOWN_OPTIONS, "whois", &optlist, &qserver, &query)) return; /* -<server tag> */ server = IRC_SERVER(cmd_options_get_server("whois", optlist, SERVER(server))); if (server == NULL) { cmd_params_free(free_arg); return; } if (*query == '\0') { query = qserver; qserver = ""; } if (*query == '\0') { QUERY_REC *queryitem = QUERY(item); if (queryitem == NULL) query = server->nick; else query = qserver = queryitem->name; } if (strcmp(query, "*") == 0 && g_hash_table_lookup(optlist, "yes") == NULL) cmd_param_error(CMDERR_NOT_GOOD_IDEA); event_402 = "event 402"; if (*qserver == '\0') g_string_sprintf(tmpstr, "WHOIS %s", query); else { g_string_sprintf(tmpstr, "WHOIS %s %s", qserver, query); if (g_strcasecmp(qserver, query) == 0) event_402 = "whois event not found"; } query = get_redirect_nicklist(query, &free_nick); str = g_strconcat(qserver, " ", query, NULL); server_redirect_event(server, "whois", 1, str, TRUE, NULL, "event 318", "whois end", "event 402", event_402, "event 301", "whois away", /* 301 can come as a reply to /MSG, /WHOIS or /WHOWAS */ "event 313", "whois oper", "event 401", (settings_get_bool("auto_whowas") ? "whois try whowas" : "whois event not found"), "event 311", "whois event", "", "whois default event", NULL); g_free(str); server->whois_found = FALSE; irc_send_cmd_split(server, tmpstr->str, 2, server->max_whois_in_cmd); if (free_nick) g_free(query); cmd_params_free(free_arg); }
static void irc_channels_join(IRC_SERVER_REC *server, const char *data, int automatic) { CHANNEL_SETUP_REC *schannel; IRC_CHANNEL_REC *chanrec; GString *outchans, *outkeys; char *channels, *keys, *key; char **chanlist, **keylist, **tmp, **tmpkey, *channel, *channame; void *free_arg; int use_keys; g_return_if_fail(data != NULL); g_return_if_fail(IS_IRC_SERVER(server) && server->connected); if (*data == '\0') return; if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &channels, &keys)) return; chanlist = g_strsplit(channels, ",", -1); keylist = g_strsplit(keys, ",", -1); outchans = g_string_new(NULL); outkeys = g_string_new(NULL); use_keys = *keys != '\0'; tmpkey = keylist; for (tmp = chanlist; *tmp != NULL; tmp++) { channel = ischannel(**tmp) ? g_strdup(*tmp) : g_strdup_printf("#%s", *tmp); chanrec = irc_channel_find(server, channel); if (chanrec == NULL) { schannel = channel_setup_find(channel, server->connrec->chatnet); g_string_sprintfa(outchans, "%s,", channel); if (*tmpkey != NULL && **tmpkey != '\0') key = *tmpkey; else if (schannel != NULL && schannel->password != NULL) { /* get password from setup record */ use_keys = TRUE; key = schannel->password; } else key = NULL; g_string_sprintfa(outkeys, "%s,", get_join_key(key)); channame = channel + (channel[0] == '!' && channel[1] == '!'); chanrec = irc_channel_create(server, channame, automatic); if (key != NULL) chanrec->key = g_strdup(key); } g_free(channel); if (*tmpkey != NULL) tmpkey++; } if (outchans->len > 0) { g_string_truncate(outchans, outchans->len-1); g_string_truncate(outkeys, outkeys->len-1); irc_send_cmdv(IRC_SERVER(server), use_keys ? "JOIN %s %s" : "JOIN %s", outchans->str, outkeys->str); } g_string_free(outchans, TRUE); g_string_free(outkeys, TRUE); g_strfreev(chanlist); g_strfreev(keylist); cmd_params_free(free_arg); }
/* redraw nick */ static void statusbar_nick(SBAR_ITEM_REC *item, int ypos) { CHANNEL_REC *channel; SERVER_REC *server; IRC_SERVER_REC *ircserver; NICK_REC *nickrec; int size_needed; int umode_size; char nick[10]; server = active_win == NULL ? NULL : active_win->active_server; ircserver = IRC_SERVER(server); umode_size = ircserver == NULL || ircserver->usermode == NULL || ircserver->usermode[0] == '\0' ? 0 : strlen(ircserver->usermode)+3; /* nick */ if (server == NULL || server->nick == NULL) { nick[0] = '\0'; nickrec = NULL; } else { strncpy(nick, server->nick, 9); nick[9] = '\0'; channel = CHANNEL(active_win->active); nickrec = channel == NULL ? NULL : nicklist_find(channel, server->nick); } size_needed = 2 + strlen(nick) + umode_size + (server != NULL && server->usermode_away ? 7 : 0) + (nickrec != NULL && (nickrec->op || nickrec->voice) ? 1 : 0); /* @ + */ if (item->size != size_needed) { /* we need more (or less..) space! */ statusbar_item_resize(item, size_needed); return; } /* size ok, draw the nick */ move(ypos, item->xpos); set_color(stdscr, sbar_color_dim); addch('['); if (nickrec != NULL && (nickrec->op || nickrec->voice)) { set_color(stdscr, sbar_color_bold); addch(nickrec->op ? '@' : '+'); } set_color(stdscr, sbar_color_normal); addstr(nick); if (umode_size) { set_color(stdscr, sbar_color_bold); addch('('); set_color(stdscr, sbar_color_dim); addch('+'); set_color(stdscr, sbar_color_normal); addstr(ircserver->usermode); set_color(stdscr, sbar_color_bold); addch(')'); } if (server != NULL && server->usermode_away) { set_color(stdscr, sbar_color_normal); addstr(" ("); set_color(stdscr, sbar_color_away); addstr("zZzZ"); set_color(stdscr, sbar_color_normal); addch(')'); } set_color(stdscr, sbar_color_dim); addch(']'); screen_refresh(NULL); }
/* user mode in active server */ static char *expando_usermode(SERVER_REC *server, void *item, int *free_ret) { return IS_IRC_SERVER(server) ? IRC_SERVER(server)->usermode : ""; }
static void irc_channels_join(IRC_SERVER_REC *server, const char *data, int automatic) { CHANNEL_SETUP_REC *schannel; IRC_CHANNEL_REC *chanrec; GString *outchans, *outkeys; char *channels, *keys, *key, *space; char **chanlist, **keylist, **tmp, **tmpkey, **tmpstr, *channel, *channame; void *free_arg; int use_keys, cmdlen; g_return_if_fail(data != NULL); g_return_if_fail(IS_IRC_SERVER(server) && server->connected); if (*data == '\0') return; if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &channels, &keys)) return; /* keys shouldn't contain space */ space = strchr(keys, ' '); if (space != NULL) { *space = '\0'; } chanlist = g_strsplit(channels, ",", -1); keylist = g_strsplit(keys, ",", -1); outchans = g_string_new(NULL); outkeys = g_string_new(NULL); use_keys = *keys != '\0'; tmpkey = keylist; tmp = chanlist; for (;; tmp++) { if (*tmp != NULL) { channel = ischannel(**tmp) ? g_strdup(*tmp) : g_strdup_printf("#%s", *tmp); chanrec = irc_channel_find(server, channel); if (chanrec == NULL) { schannel = channel_setup_find(channel, server->connrec->chatnet); g_string_sprintfa(outchans, "%s,", channel); if (*tmpkey != NULL && **tmpkey != '\0') key = *tmpkey; else if (schannel != NULL && schannel->password != NULL) { /* get password from setup record */ use_keys = TRUE; key = schannel->password; } else key = NULL; g_string_sprintfa(outkeys, "%s,", get_join_key(key)); channame = channel + (channel[0] == '!' && channel[1] == '!'); chanrec = irc_channel_create(server, channame, NULL, automatic); if (key != NULL) chanrec->key = g_strdup(key); } g_free(channel); if (*tmpkey != NULL) tmpkey++; tmpstr = tmp; tmpstr++; cmdlen = outchans->len-1; if (use_keys) cmdlen += outkeys->len; if (*tmpstr != NULL) cmdlen += ischannel(**tmpstr) ? strlen(*tmpstr) : strlen(*tmpstr)+1; if (*tmpkey != NULL) cmdlen += strlen(*tmpkey); /* don't try to send too long lines make sure it's not longer than 510 so 510 - strlen("JOIN ") = 505 */ if (cmdlen < 505) continue; } if (outchans->len > 0) { g_string_truncate(outchans, outchans->len-1); g_string_truncate(outkeys, outkeys->len-1); irc_send_cmdv(IRC_SERVER(server), use_keys ? "JOIN %s %s" : "JOIN %s", outchans->str, outkeys->str); } cmdlen = 0; g_string_truncate(outchans,0); g_string_truncate(outkeys,0); if (*tmp == NULL || tmp[1] == NULL) break; } g_string_free(outchans, TRUE); g_string_free(outkeys, TRUE); g_strfreev(chanlist); g_strfreev(keylist); cmd_params_free(free_arg); }