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 event_nick(IRC_SERVER_REC *server, const char *data, const char *orignick) { char *params, *nick; g_return_if_fail(data != NULL); g_return_if_fail(orignick != NULL); params = event_get_params(data, 1, &nick); if (g_ascii_strcasecmp(orignick, server->nick) == 0) { /* You changed your nick */ if (server->last_nick != NULL && g_ascii_strcasecmp(server->last_nick, nick) == 0) { /* changed with /NICK - keep it as wanted nick */ g_free(server->connrec->nick); server->connrec->nick = g_strdup(nick); } server_change_nick(SERVER(server), nick); } nicklist_rename(SERVER(server), orignick, nick); g_free(params); }
static void lm_auth_cb(LmConnection *connection, gboolean success, gpointer user_data) { XMPP_SERVER_REC *server; if ((server = XMPP_SERVER(user_data)) == NULL) return; if (!success) { server_connect_failed(SERVER(server), "Authentication failed"); return; } signal_emit("xmpp server status", 2, server, "Authenticated successfully."); /* finnish connection process */ lookup_servers = g_slist_remove(lookup_servers, server); g_source_remove(server->connect_tag); server->connect_tag = -1; server->show = XMPP_PRESENCE_AVAILABLE; server->connected = TRUE; if (server->timeout_tag) { g_source_remove(server->timeout_tag); server->timeout_tag = 0; } server_connect_finished(SERVER(server)); server->real_connect_time = server->connect_time; }
static void event_whois(const char *data, IRC_SERVER_REC *server) { char *params, *nick, *realname; GSList *nicks, *tmp; NICK_REC *rec; g_return_if_fail(data != NULL); server->whois_coming = TRUE; /* first remove the gone-flag, if user is gone it will be set later.. */ params = event_get_params(data, 6, NULL, &nick, NULL, NULL, NULL, &realname); nicks = nicklist_get_same(SERVER(server), nick); for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) { rec = tmp->next->data; if (rec->realname == NULL) rec->realname = g_strdup(realname); } g_slist_free(nicks); /* reset gone and ircop status, we'll handle them in the following WHOIS replies */ nicklist_update_flags(SERVER(server), nick, FALSE, FALSE); g_free(params); }
/** * server_new_from_keyfile: * @keyfile: The keyfile with the @group in it to define the server * @group: Group name for this server * * Looks at a group within the keyfile and builds a server based on * it's type. Mostly works with a subclass based on the type. * * Return value: A new Server object or NULL if error */ Server * server_new_from_keyfile (GKeyFile * keyfile, const gchar * group) { g_return_val_if_fail(keyfile != NULL, NULL); g_return_val_if_fail(group != NULL, NULL); if (!g_key_file_has_group(keyfile, group)) { return NULL; } gchar * type = NULL; if (g_key_file_has_key(keyfile, group, CONFIG_SERVER_TYPE, NULL)) { type = g_key_file_get_string(keyfile, group, CONFIG_SERVER_TYPE, NULL); } if (g_strcmp0(type, CONFIG_SERVER_TYPE_RDP) == 0) { return SERVER(rdp_server_new_from_keyfile(keyfile, group)); } else if (g_strcmp0(type, CONFIG_SERVER_TYPE_ICA) == 0) { return SERVER(citrix_server_new_from_keyfile(keyfile, group)); } else { return SERVER(uccs_server_new_from_keyfile(keyfile, group)); } return NULL; }
/* * args0 = "Name" * args1 = "<oldnick> changed nickname to <newnick>" */ static void status_name(ICB_SERVER_REC *server, char **args) { NICK_REC *nickrec; char *oldnick, *newnick, *p; oldnick = g_strdup(args[1]); p = strchr(oldnick, ' '); if (p != NULL) *p = '\0'; p = g_strdup(args[1]); newnick = strrchr(p, ' '); if (newnick != NULL) newnick++; nickrec = nicklist_find(CHANNEL(server->group), oldnick); if (nickrec != NULL) nicklist_rename(SERVER(server), oldnick, newnick); /* Update our own nick */ if (strcmp(oldnick, server->connrec->nick) == 0) { server_change_nick(SERVER(server), newnick); g_free(server->connrec->nick); server->connrec->nick = g_strdup(newnick); } g_free(oldnick); g_free(p); printformat(server, server->group->name, MSGLEVEL_CRAP, ICBTXT_STATUS, args[0], args[1]); }
static void channel_change_topic(IRC_SERVER_REC *server, const char *channel, const char *topic, const char *setby, time_t settime) { CHANNEL_REC *chanrec; char *recoded = NULL; chanrec = channel_find(SERVER(server), channel); if (chanrec == NULL) return; /* the topic may be send out encoded, so we need to recode it back or /topic <tab> will not work properly */ recoded = recode_in(SERVER(server), topic, channel); if (topic != NULL) { g_free_not_null(chanrec->topic); chanrec->topic = recoded == NULL ? NULL : g_strdup(recoded); } g_free(recoded); g_free_not_null(chanrec->topic_by); chanrec->topic_by = g_strdup(setby); chanrec->topic_time = settime; signal_emit("channel topic changed", 1, chanrec); }
/* 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 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); }
void quassel_irssi_set_last_seen_msg(void *arg, int buffer_id, int msgid) { (void) msgid; Quassel_SERVER_REC *server = (Quassel_SERVER_REC*)arg; if(!PROTO_CHECK_CAST(SERVER(server), Quassel_SERVER_REC, chat_type, "Quassel")) return; Quassel_CHANNEL_REC* chanrec = NULL; //First find channel GSList *chans = server->channels; while(chans) { chanrec = (Quassel_CHANNEL_REC*) chans->data; if(chanrec->buffer_id == buffer_id) break; chanrec = NULL; chans = g_slist_next(chans); } if(!chanrec) return; chanrec->last_seen_msg_id = msgid; if(chanrec->init_last_seen_msg_id == -1) chanrec->init_last_seen_msg_id = msgid; //Now find windows GSList *win = windows; while(win) { WINDOW_REC* winrec = (WINDOW_REC*) win->data; if(winrec->active_server != SERVER(server) && winrec->connect_server != SERVER(server)) goto next; if(!winrec->active) goto next; if(strcmp(winrec->active->visible_name, chanrec->name)==0) { signal_emit("window dehilight", 1, winrec); if(winrec != active_win) { LINE_REC *linerec = textbuffer_view_get_bookmark(WINDOW_GUI(winrec)->view, "trackbar"); if(linerec) textbuffer_view_remove_line(WINDOW_GUI(winrec)->view, linerec); char *str = malloc(winrec->width+3); str[0] = '%'; str[1] = 'K'; for(int i=0; i<winrec->width; ++i) str[i+2]='-'; str[winrec->width+2]=0; printtext_string_window(winrec, MSGLEVEL_NEVER, str); free(str); textbuffer_view_set_bookmark_bottom(WINDOW_GUI(winrec)->view, "trackbar"); } } next: win = g_slist_next(win); } }
static Quassel_CHANNEL_REC* window2chanrec(WINDOW_REC *window) { if(!window) return NULL; WI_ITEM_REC *wi = window->active; if(!wi) return NULL; Quassel_SERVER_REC *server = (Quassel_SERVER_REC*)wi->server; if(!PROTO_CHECK_CAST(SERVER(server), Quassel_SERVER_REC, chat_type, "Quassel")) return NULL; Quassel_CHANNEL_REC *chanrec = (Quassel_CHANNEL_REC*) channel_find(SERVER(server), wi->visible_name); return chanrec; }
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 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); }
/* SYNTAX: WALL [<channel>] <message> */ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { char *channame, *msg, *args, *recoded; void *free_arg; IRC_CHANNEL_REC *chanrec; GSList *tmp, *nicks; CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, item, &channame, &msg)) return; if (*msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); chanrec = irc_channel_find(server, channame); if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND); /* See if the server has advertised support of wallchops */ if (g_hash_table_lookup(chanrec->server->isupport, "statusmsg") || g_hash_table_lookup(chanrec->server->isupport, "wallchops")) irc_send_cmdv(server, "NOTICE @%s :%s", chanrec->name, msg); else { /* Fall back to manually noticing each op */ nicks = NULL; g_hash_table_foreach(chanrec->nicks, (GHFunc) cmd_wall_hash, &nicks); args = g_strconcat(chanrec->name, " ", msg, NULL); msg = parse_special_string(settings_get_str("wall_format"), SERVER(server), item, args, NULL, 0); g_free(args); recoded = recode_out(SERVER(server), msg, channame); for (tmp = nicks; tmp != NULL; tmp = tmp->next) { NICK_REC *rec = tmp->data; if (rec != chanrec->ownnick) { irc_send_cmdv(server, "NOTICE %s :%s", rec->nick, recoded); } } g_free(recoded); g_free(msg); g_slist_free(nicks); } cmd_params_free(free_arg); }
static void msg_join(IRC_SERVER_REC *server, const char *channel, const char *nick, const char *address) { NETSPLIT_REC *split; NETJOIN_REC *netjoin; if (!IS_IRC_SERVER(server)) return; if (ignore_check(SERVER(server), nick, address, channel, NULL, MSGLEVEL_JOINS)) return; split = netsplit_find(server, nick, address); netjoin = netjoin_find(server, nick); if (split == NULL && netjoin == NULL) return; if (join_tag == -1) { join_tag = g_timeout_add(1000, (GSourceFunc) sig_check_netjoins, NULL); signal_add("print starting", (SIGNAL_FUNC) sig_print_starting); } if (netjoin == NULL) netjoin = netjoin_add(server, nick, split->channels); netjoin->now_channels = g_slist_append(netjoin->now_channels, g_strdup(channel)); signal_stop(); }
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); }
void vnode_write_queue_handle_write(work_queue_t *wq) { void *node_data = NULL; while ( (node_data = dequeue_work(wq)) != NULL ){ vnode_write_queue_entry_t *entry = (vnode_write_queue_entry_t*)node_data; session_t *session = entry->session; object_t *object = entry->object; zfree(entry); server_write_to_storage(SERVER(session), object); /* FIXME 2014-10-10 18:57:20 */ __sync_add_and_fetch(&session->finished_works, 1); /*session_response(session, RESULT_SUCCESS);*/ /*uint32_t total_committed = __sync_add_and_fetch(&vnode->total_committed, 1);*/ /*if ( total_committed > 800 ) {*/ /*__sync_sub_and_fetch(&vnode->total_committed, total_committed);*/ /*fsync(vnode->logFile);*/ /*kvdb_flush(vnode->kvdb);*/ /*}*/ /* FIXME 2014-10-10 18:56:55 */ /*session_response(session, RESULT_SUCCESS);*/ sched_yield(); } }
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); }
/* FIXME: should be moved to fe-common/core/fe-messages.c.. */ static void sig_message_mode(IRC_SERVER_REC *server, const char *channel, const char *nick, const char *addr, const char *mode) { if (nick == NULL) nick = server->real_address; if (ignore_check(SERVER(server), nick, addr, channel, mode, MSGLEVEL_MODES)) return; if (!ischannel(*channel)) { /* user mode change */ printformat(server, NULL, MSGLEVEL_MODES, IRCTXT_USERMODE_CHANGE, mode, channel); } else if (addr == NULL) { /* channel mode changed by server */ printformat(server, channel, MSGLEVEL_MODES, IRCTXT_SERVER_CHANMODE_CHANGE, channel, mode, nick); } else { /* channel mode changed by normal user */ IRC_CHANNEL_REC *chanrec; chanrec = !group_multi_mode ? NULL : irc_channel_find(server, channel); if (chanrec != NULL) msg_multi_mode(chanrec, nick, addr, mode); else { printformat(server, channel, MSGLEVEL_MODES, IRCTXT_CHANMODE_CHANGE, channel, mode, nick); } } }
static void disconnect_all(void) { GSList *tmp, *next; for (tmp = lookup_servers; tmp != NULL; tmp = next) { next = tmp->next; if (IS_XMPP_SERVER(tmp->data)) server_connect_failed(SERVER(tmp->data), NULL); } for (tmp = servers; tmp != NULL; tmp = next) { next = tmp->next; if (IS_XMPP_SERVER(tmp->data)) server_disconnect(SERVER(tmp->data)); } }
/* SYNTAX: CTCP <targets> <ctcp command> [<ctcp data>] */ static void cmd_ctcp(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { const char *target; char *ctcpcmd, *ctcpdata; void *free_arg; CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata)) return; if (strcmp(target, "*") == 0) target = item == NULL ? NULL : window_item_get_target(item); if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); g_strup(ctcpcmd); if (*ctcpdata == '\0') g_string_sprintf(tmpstr, "PRIVMSG %s :\001%s\001", target, ctcpcmd); else { char *recoded; recoded = recode_out(SERVER(server), ctcpdata, target); g_string_sprintf(tmpstr, "PRIVMSG %s :\001%s %s\001", target, ctcpcmd, recoded); g_free(recoded); } irc_send_cmd_split(server, tmpstr->str, 2, server->max_msgs_in_cmd); cmd_params_free(free_arg); }
/* SYNTAX: NOTICE <targets> <message> */ static void cmd_notice(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { const char *target, *msg; char *recoded; void *free_arg; CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &msg)) return; if (strcmp(target, "*") == 0) target = item == NULL ? NULL : window_item_get_target(item); if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); recoded = recode_out(SERVER(server), msg, target); g_string_sprintf(tmpstr, "NOTICE %s :%s", target, recoded); g_free(recoded); irc_send_cmd_split(server, tmpstr->str, 2, server->max_msgs_in_cmd); cmd_params_free(free_arg); }
/* 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); }
/* SYNTAX: PART [<channels>] [<message>] */ static void cmd_part(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { char *channame, *msg; char *recoded = NULL; void *free_arg; CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | PARAM_FLAG_OPTCHAN, item, &channame, &msg)) return; if (*channame == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*msg == '\0') msg = (char *) settings_get_str("part_message"); if (server->cmdcount > MAX_COMMANDS_ON_PART_UNTIL_PURGE) irc_server_purge_output(server, channame); if (*msg != '\0') recoded = recode_out(SERVER(server), msg, channame); irc_send_cmdv(server, ! recoded ? "PART %s" : "PART %s :%s", channame, recoded); g_free(recoded); cmd_params_free(free_arg); }
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; }
/* 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); }
static void event_no_such_channel(IRC_SERVER_REC *server, const char *data) { CHANNEL_REC *chanrec; CHANNEL_SETUP_REC *setup; char *params, *channel; params = event_get_params(data, 2, NULL, &channel); chanrec = *channel == '!' && channel[1] != '\0' ? channel_find(SERVER(server), channel) : NULL; if (chanrec != NULL) { /* !channel didn't exist, so join failed */ setup = channel_setup_find(chanrec->name, chanrec->server->connrec->chatnet); if (setup != NULL && setup->autojoin) { /* it's autojoin channel though, so create it */ irc_send_cmdv(server, "JOIN !%s", chanrec->name); g_free(params); return; } } check_join_failure(server, channel); g_free(params); }
static void event_invite(IRC_SERVER_REC *server, const char *data) { char *params, *channel, *shortchan; g_return_if_fail(data != NULL); params = event_get_params(data, 2, NULL, &channel); if (irc_channel_find(server, channel) == NULL) { /* check if we're supposed to autojoin this channel */ CHANNEL_SETUP_REC *setup; setup = channel_setup_find(channel, server->connrec->chatnet); if (setup == NULL && channel[0] == '!' && strlen(channel) > 6) { shortchan = g_strdup_printf("!%s", channel+6); setup = channel_setup_find(shortchan, server->connrec->chatnet); g_free(shortchan); } if (setup != NULL && setup->autojoin && settings_get_bool("join_auto_chans_on_invite")) server->channels_join(SERVER(server), channel, TRUE); } g_free_not_null(server->last_invite); server->last_invite = g_strdup(channel); g_free(params); }
static void sig_recv_message(XMPP_SERVER_REC *server, LmMessage *lmsg, const int type, const char *id, const char *from, const char *to) { LmMessageNode *node; if ((type != LM_MESSAGE_SUB_TYPE_NOT_SET && type != LM_MESSAGE_SUB_TYPE_HEADLINE && type != LM_MESSAGE_SUB_TYPE_NORMAL && type != LM_MESSAGE_SUB_TYPE_CHAT) || server->ischannel(SERVER(server), from)) return; node = lm_find_node(lmsg->node, "x", XMLNS, XMLNS_EVENT); if (node == NULL) { signal_emit("xmpp composing hide", 2, server, from); return; } if (lm_message_node_get_child(lmsg->node, "body") != NULL || lm_message_node_get_child(lmsg->node, "subject") != NULL) { if (lm_message_node_get_child(node, "composing") != NULL) datalist_add(composings, server, from, g_strdup(id)); else datalist_remove(composings, server, from); signal_emit("xmpp composing hide", 2, server, from); } else { if (lm_message_node_get_child(node, "composing") != NULL) signal_emit("xmpp composing show", 2, server, from); else signal_emit("xmpp composing hide", 2, server, from); } }
static void event_duplicate_channel(IRC_SERVER_REC *server, const char *data) { CHANNEL_REC *chanrec; char *params, *channel, *p; g_return_if_fail(data != NULL); params = event_get_params(data, 3, NULL, NULL, &channel); p = strchr(channel, ' '); if (p != NULL) *p = '\0'; if (channel[0] == '!' && channel[1] != '!') { chanrec = channel_find(SERVER(server), channel); if (chanrec != NULL && !chanrec->names_got) { /* duplicate channel - this should only happen when there's some sync problem with servers, rejoining after a while should help. note that this same 407 is sent when trying to create !!channel that already exists so we don't want to try rejoining then. */ channel_rejoin(server, channel); signal_stop(); } } g_free(params); }