static void event_privmsg(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { char *params, *target, *msg, *recoded; g_return_if_fail(data != NULL); params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg); if (nick == NULL) nick = server->real_address; if (addr == NULL) addr = ""; if (fe_channel_is_opchannel(server, target)) { /* Hybrid 6 feature, send msg to all ops in channel */ target = (char *)fe_channel_skip_prefix(server, target); recoded = recode_in(SERVER(server), msg, target); signal_emit("message irc op_public", 5, server, recoded, nick, addr, get_visible_target(server, target)); } else { recoded = recode_in(SERVER(server), msg, server_ischannel(SERVER(server), target) ? target : nick); signal_emit(server_ischannel(SERVER(server), target) ? "message public" : "message private", 5, server, recoded, nick, addr, get_visible_target(server, target)); } g_free(params); g_free(recoded); }
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_event_forward(SERVER_REC *server, const char *data, const char *nick) { IRC_CHANNEL_REC *channel; char *params, *from, *to; params = event_get_params(data, 3, NULL, &from, &to); if (from != NULL && to != NULL && server_ischannel(server, from) && server_ischannel(server, to)) { channel = irc_channel_find(server, from); if (channel != NULL && irc_channel_find(server, to) == NULL) { window_bind_add(window_item_window(channel), server->tag, to); } } g_free(params); }
const char *fe_channel_skip_prefix(IRC_SERVER_REC *server, const char *target) { const char *statusmsg; /* Quick check */ if (server == NULL || server->prefix[(int)(unsigned char)*target] == 0) return target; /* Exit early if target doesn't name a channel */ if (server_ischannel(SERVER(server), target) == FALSE) return target; statusmsg = g_hash_table_lookup(server->isupport, "statusmsg"); /* Hack: for bahamut 1.4 which sends neither STATUSMSG nor * WALLCHOPS in 005, accept @#chan and @+#chan (but not +#chan) */ if (statusmsg == NULL && *target != '@') return target; if (statusmsg == NULL) statusmsg = "@+"; /* Strip the leading statusmsg prefixes */ while (strchr(statusmsg, *target) != NULL) { target++; } return target; }
/* 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 command_set_ban(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item, int set, int ban_type) { IRC_CHANNEL_REC *chanrec; char *channel, *nicks; void *free_arg; g_return_if_fail(data != NULL); if (server == NULL || !server->connected || !IS_IRC_SERVER(server)) cmd_return_error(CMDERR_NOT_CONNECTED); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, item, &channel, &nicks)) return; if (!server_ischannel(SERVER(server), channel)) cmd_param_error(CMDERR_NOT_JOINED); if (*nicks == '\0') { if (g_strcmp0(data, "*") != 0) cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); /* /BAN * or /UNBAN * - ban/unban everyone */ nicks = (char *) data; } chanrec = irc_channel_find(server, channel); if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND); if (set) ban_set(chanrec, nicks, ban_type); else ban_remove(chanrec, nicks); cmd_params_free(free_arg); }
static int sig_autoremove(void) { SERVER_REC *server; LOG_ITEM_REC *logitem; GSList *tmp, *next; time_t removetime; removetime = time(NULL)-AUTOLOG_INACTIVITY_CLOSE; for (tmp = logs; tmp != NULL; tmp = next) { LOG_REC *log = tmp->data; next = tmp->next; if (!log->temp || log->last > removetime || log->items == NULL) continue; /* Close only logs with private messages */ logitem = log->items->data; if (logitem->servertag == NULL) continue; server = server_find_tag(logitem->servertag); if (logitem->type == LOG_ITEM_TARGET && server != NULL && !server_ischannel(server, logitem->name)) log_close(log); } return 1; }
static void sig_complete_word(GList **list, WINDOW_REC *window, const char *word, const char *linestart, int *want_space) { SERVER_REC *server; CHANNEL_REC *channel; QUERY_REC *query; char *prefix; g_return_if_fail(list != NULL); g_return_if_fail(window != NULL); g_return_if_fail(word != NULL); g_return_if_fail(linestart != NULL); server = window->active_server; if (server == NULL && servers != NULL) server = servers->data; if (server != NULL && server_ischannel(server, word)) { /* probably completing a channel name */ *list = completion_get_channels(window->active_server, word); if (*list != NULL) signal_stop(); return; } server = window->active_server; if (server == NULL || !server->connected) return; if (*linestart == '\0' && *word == '\0') { /* pressed TAB at the start of line - add /MSG */ prefix = g_strdup_printf("%cmsg", *cmdchars); *list = completion_msg(server, NULL, "", prefix); if (*list == NULL) *list = g_list_append(*list, g_strdup(prefix)); g_free(prefix); signal_stop(); return; } channel = CHANNEL(window->active); query = QUERY(window->active); if (channel == NULL && query != NULL && g_strncasecmp(word, query->name, strlen(word)) == 0) { /* completion in query */ *list = g_list_append(*list, g_strdup(query->name)); } else if (channel != NULL) { /* nick completion .. we could also be completing a nick after /MSG from nicks in channel */ const char *suffix = *linestart != '\0' ? NULL : completion_char; complete_window_nicks(list, window, word, suffix); } else if (window->level & MSGLEVEL_MSGS) { /* msgs window, complete /MSG nicks */ *list = g_list_concat(completion_msg(server, NULL, word, NULL), *list); } if (*list != NULL) signal_stop(); }
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 cmd_channel(const char *data, SERVER_REC *server, WI_ITEM_REC *item) { if (*data == '\0') cmd_channel_list_joined(); else if (server != NULL && server_ischannel(server, data)) { signal_emit("command join", 3, data, server, item); } else { command_runsub("channel", data, server, item); } }
static void sig_message_irc_ctcp(IRC_SERVER_REC *server, const char *cmd, const char *data, const char *nick, const char *addr, const char *target) { const char *oldtarget; oldtarget = target; target = fe_channel_skip_prefix(server, target); printformat(server, server_ischannel(SERVER(server), target) ? target : nick, MSGLEVEL_CTCPS, IRCTXT_CTCP_REQUESTED, nick, addr, cmd, data, oldtarget); }
static void sig_dcc_request(GET_DCC_REC *dcc, const char *nickaddr) { struct stat statbuf; const char *masks; char *str, *file, *esc_arg; int max_size; if (!IS_DCC_GET(dcc)) return; /* check if we want to autoget file offer */ if (!settings_get_bool("dcc_autoget")) return; /* check for lowports */ if (dcc->port < 1024 && !settings_get_bool("dcc_autoaccept_lowports")) return; /* check that autoget masks match */ masks = settings_get_str("dcc_autoget_masks"); if (*masks != '\0' && !masks_match(SERVER(dcc->server), masks, dcc->nick, nickaddr)) return; /* Unless specifically said in dcc_autoget_masks, don't do autogets sent to channels. */ if (*masks == '\0' && dcc->target != NULL && server_ischannel(SERVER(dcc->server), dcc->target)) return; /* don't autoget files beginning with a dot, if download dir is our home dir (stupid kludge for stupid people) */ if (*dcc->arg == '.' && g_strcmp0(settings_get_str("dcc_download_path"), "~") == 0) return; /* check file size limit, NOTE: it's still possible to send a bogus file size and then just send what ever sized file.. */ max_size = settings_get_size("dcc_autoget_max_size"); if (max_size > 0 && (uoff_t)max_size < dcc->size) return; /* ok. but do we want/need to resume? */ file = dcc_get_download_path(dcc->arg); esc_arg = escape_string(dcc->arg); str = g_strdup_printf(settings_get_bool("dcc_autoresume") && stat(file, &statbuf) == 0 ? "RESUME %s \"%s\"" : "GET %s \"%s\"", dcc->nick, esc_arg); signal_emit("command dcc", 2, str, dcc->server); g_free(esc_arg); g_free(file); g_free(str); }
static void ctcp_default_reply(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr, const char *target) { const char *ctcpdata; char *ctcp, *ptr; g_return_if_fail(data != NULL); ctcp = g_strdup(data); ptr = strchr(ctcp, ' '); if (ptr == NULL) ctcpdata = ""; else { *ptr = '\0'; ctcpdata = ptr+1; } printformat(server, server_ischannel(SERVER(server), target) ? target : nick, MSGLEVEL_CTCPS, server_ischannel(SERVER(server), target) ? IRCTXT_CTCP_REPLY_CHANNEL : IRCTXT_CTCP_REPLY, ctcp, nick, ctcpdata, target); g_free(ctcp); }
static void event_target_unavailable(IRC_SERVER_REC *server, const char *data) { char *params, *channel; g_return_if_fail(data != NULL); params = event_get_params(data, 2, NULL, &channel); if (!server_ischannel(SERVER(server), channel)) { /* nick is unavailable. */ event_nick_in_use(server, data); } g_free(params); }
static void dcc_request(GET_DCC_REC *dcc) { char *sizestr; if (!IS_DCC_GET(dcc)) return; sizestr = dcc_get_size_str(dcc->size); printformat(dcc->server, NULL, MSGLEVEL_DCC, server_ischannel(SERVER(dcc->server), dcc->target) ? IRCTXT_DCC_SEND_CHANNEL : IRCTXT_DCC_SEND, dcc->nick, dcc->addrstr, dcc->port, dcc->arg, sizestr, dcc->target); g_free(sizestr); }
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); }
static void flood_ctcp(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr, const char *target) { int level; g_return_if_fail(data != NULL); g_return_if_fail(server != NULL); if (addr == NULL || g_ascii_strcasecmp(nick, server->nick) == 0) return; level = g_ascii_strncasecmp(data, "ACTION ", 7) != 0 ? MSGLEVEL_CTCPS : (server_ischannel(SERVER(server), target) ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS); if (!ignore_check(SERVER(server), nick, addr, target, data, level)) flood_newmsg(server, level, nick, addr, target); }
static void msg_mode(IRC_SERVER_REC *server, const char *channel, const char *sender, const char *addr, const char *data) { NETJOIN_REC *rec; char *params, *mode, *nicks; char **nicklist, **nick, type, prefix; int show; g_return_if_fail(data != NULL); if (!server_ischannel(SERVER(server), channel) || addr != NULL) return; params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &mode, &nicks); /* parse server mode changes - hide operator status changes and show them in the netjoin message instead as @ before the nick */ nick = nicklist = g_strsplit(nicks, " ", -1); type = '+'; show = FALSE; for (; *mode != '\0'; mode++) { if (*mode == '+' || *mode == '-') { type = *mode; continue; } if (*nick != NULL && GET_MODE_PREFIX(server, *mode)) { /* give/remove ops */ rec = netjoin_find(server, *nick); prefix = GET_MODE_PREFIX(server, *mode); if (rec == NULL || type != '+' || prefix == '\0' || !netjoin_set_nickmode(server, rec, channel, prefix)) show = TRUE; nick++; } else { if (HAS_MODE_ARG(server, type, *mode) && *nick != NULL) nick++; show = TRUE; } } if (!show) signal_stop(); g_strfreev(nicklist); g_free(params); }
/* SYNTAX: MODE <your nick>|<channel> [<mode> [<mode parameters>]] */ static void cmd_mode(const char *data, IRC_SERVER_REC *server, IRC_CHANNEL_REC *channel) { IRC_CHANNEL_REC *chanrec; char *target, *mode; void *free_arg; CMD_IRC_SERVER(server); if (*data == '+' || *data == '-') { target = "*"; if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_GETREST, &mode)) return; } else { if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &mode)) return; } if (g_strcmp0(target, "*") == 0) { if (!IS_IRC_CHANNEL(channel)) cmd_param_error(CMDERR_NOT_JOINED); target = channel->name; } if (*target == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*mode == '\0') { chanrec = irc_channel_find(server, target); if (chanrec != NULL) target = chanrec->name; irc_send_cmdv(server, "MODE %s", target); } else if (server_ischannel(SERVER(server), target)) channel_set_mode(server, target, mode); else { if (g_ascii_strcasecmp(target, server->nick) == 0) { server_redirect_event(server, "mode user", 1, target, -1, NULL, "event mode", "requested usermode change", NULL); } irc_send_cmdv(server, "MODE %s %s", target, mode); } cmd_params_free(free_arg); }
/* SYNTAX: UNIGNORE <id>|<mask> */ static void cmd_unignore(const char *data) { IGNORE_REC *rec; GSList *tmp; char *mask, *mask_orig; void *free_arg; if (!cmd_get_params(data, &free_arg, 1, &mask)) return; if (*mask == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); /* Save the mask string here since it might be modified in the code * below and we need it to print meaningful error messages. */ mask_orig = mask; if (is_numeric(mask, ' ')) { /* with index number */ tmp = g_slist_nth(ignores, atoi(mask)-1); rec = tmp == NULL ? NULL : tmp->data; } else { /* with mask */ const char *chans[2] = { "*", NULL }; if (active_win->active_server != NULL && server_ischannel(active_win->active_server, mask)) { chans[0] = mask; mask = NULL; } rec = ignore_find_full("*", mask, NULL, (char **) chans, 0); if (rec == NULL) { rec = ignore_find_full("*", mask, NULL, (char **) chans, IGNORE_FIND_NOACT); } } if (rec != NULL) { rec->level = 0; ignore_update_rec(rec); } else { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_IGNORE_NOT_FOUND, mask_orig); } cmd_params_free(free_arg); }
static char *notice_channel_context(SERVER_REC *server, const char *msg) { if (!settings_get_bool("notice_channel_context")) return NULL; if (*msg == '[') { char *end, *channel; end = strpbrk(msg, " ,]"); if (end != NULL && *end == ']') { channel = g_strndup(msg + 1, end - msg - 1); if (server_ischannel(server, channel)) { return channel; } g_free(channel); } } return NULL; }
static void flood_privmsg(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { char *params, *target, *text; int level; g_return_if_fail(data != NULL); g_return_if_fail(server != NULL); if (addr == NULL || g_ascii_strcasecmp(nick, server->nick) == 0) return; params = event_get_params(data, 2, &target, &text); level = server_ischannel(SERVER(server), target) ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS; if (addr != NULL && !ignore_check(SERVER(server), nick, addr, target, text, level)) flood_newmsg(server, level, nick, addr, target); g_free(params); }
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 (!server_ischannel(SERVER(server), 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); }
static void sig_server_disconnected(SERVER_REC *server) { LOG_ITEM_REC *logitem; GSList *tmp, *next; for (tmp = logs; tmp != NULL; tmp = next) { LOG_REC *log = tmp->data; next = tmp->next; if (!log->temp || log->items == NULL) continue; logitem = log->items->data; if (logitem->type == LOG_ITEM_TARGET && logitem->servertag != NULL && g_ascii_strcasecmp(logitem->servertag, server->tag) == 0 && server_ischannel(server, logitem->name)) /* kludge again.. so we won't close dcc chats */ log_close(log); } }
/* 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); }
/* SYNTAX: UNIGNORE <id>|<mask> */ static void cmd_unignore(const char *data) { IGNORE_REC *rec; GSList *tmp; char *mask; void *free_arg; if (!cmd_get_params(data, &free_arg, 1, &mask)) return; if (*mask == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (is_numeric(mask, ' ')) { /* with index number */ tmp = g_slist_nth(ignores, atoi(mask)-1); rec = tmp == NULL ? NULL : tmp->data; } else { /* with mask */ const char *chans[2] = { "*", NULL }; if (active_win->active_server != NULL && server_ischannel(active_win->active_server, mask)) { chans[0] = mask; mask = NULL; } rec = ignore_find_noact("*", mask, (char **) chans, 0); if (rec == NULL) { rec = ignore_find_noact("*", mask, (char **) chans, 1); } } if (rec != NULL) { rec->level = 0; ignore_update_rec(rec); } else { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_IGNORE_NOT_FOUND, mask); } cmd_params_free(free_arg); }
static void ctcp_ping_reply(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr, const char *target) { GTimeVal tv, tv2; long usecs; g_return_if_fail(data != NULL); if (sscanf(data, "%ld %ld", &tv2.tv_sec, &tv2.tv_usec) < 1) { char *tmp = g_strconcat("PING ", data, NULL); ctcp_default_reply(server, tmp, nick, addr, target); g_free(tmp); return; } g_get_current_time(&tv); usecs = get_timeval_diff(&tv, &tv2); printformat(server, server_ischannel(SERVER(server), target) ? target : nick, MSGLEVEL_CTCPS, IRCTXT_CTCP_PING_REPLY, nick, usecs/1000, usecs%1000); }
static void ctcp_default_msg(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr, const char *target) { const char *p; char *cmd; p = strchr(data, ' '); if (p == NULL) { cmd = g_strdup(data); data = ""; } else { cmd = g_strndup(data, (int) (p-data)); data = p+1; } printformat(server, server_ischannel(SERVER(server), target) ? target : nick, MSGLEVEL_CTCPS, IRCTXT_CTCP_REQUESTED_UNKNOWN, nick, addr, cmd, data, target); g_free(cmd); }
/* SYNTAX: KICK [<channel>] <nicks> [<reason>] */ static void cmd_kick(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { char *channame, *nicks, *reason, *recoded; void *free_arg; CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST | PARAM_FLAG_OPTCHAN, item, &channame, &nicks, &reason)) return; if (*channame == '\0' || *nicks == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (!server_ischannel(SERVER(server), channame)) cmd_param_error(CMDERR_NOT_JOINED); recoded = recode_out(SERVER(server), reason, channame); g_string_printf(tmpstr, "KICK %s %s :%s", channame, nicks, recoded); g_free(recoded); irc_send_cmd_split(server, tmpstr->str, 3, server->max_kicks_in_cmd); cmd_params_free(free_arg); }
static void event_mode(IRC_SERVER_REC *server, const char *data, const char *nick) { IRC_CHANNEL_REC *chanrec; char *params, *channel, *mode; g_return_if_fail(data != NULL); params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &channel, &mode); if (!server_ischannel(SERVER(server), channel)) { /* user mode change */ parse_user_mode(server, mode); } else { /* channel mode change */ chanrec = irc_channel_find(server, channel); if (chanrec != NULL) parse_channel_modes(chanrec, nick, mode, TRUE); } g_free(params); }