static void sig_channel_destroyed(CHANNEL_REC *channel) { void *data = MODULE_DATA(channel); g_free(data); MODULE_DATA_UNSET(channel); }
static void complete_from_nicklist(GList **outlist, CHANNEL_REC *channel, const char *nick, const char *suffix) { MODULE_CHANNEL_REC *mchannel; GSList *tmp; GList *ownlist; char *str; int len; /* go through the last x nicks who have said something in the channel. nicks of all the "own messages" are placed before others */ ownlist = NULL; len = strlen(nick); mchannel = MODULE_DATA(channel); for (tmp = mchannel->lastmsgs; tmp != NULL; tmp = tmp->next) { LAST_MSG_REC *rec = tmp->data; if (g_strncasecmp(rec->nick, nick, len) == 0 && glist_find_icase_string(*outlist, rec->nick) == NULL) { str = g_strconcat(rec->nick, suffix, NULL); if (completion_lowercase) g_strdown(str); if (rec->own) ownlist = g_list_append(ownlist, str); else *outlist = g_list_append(*outlist, str); } } *outlist = g_list_concat(ownlist, *outlist); }
/* Complete /MSG from specified server, or from global_lastmsgs if server is NULL */ static void completion_msg_server(GSList **list, SERVER_REC *server, const char *nick, const char *prefix) { LAST_MSG_REC *msg; GSList *tmp; int len; g_return_if_fail(nick != NULL); len = strlen(nick); tmp = server == NULL ? global_lastmsgs : ((MODULE_SERVER_REC *) MODULE_DATA(server))->lastmsgs; for (; tmp != NULL; tmp = tmp->next) { LAST_MSG_REC *rec = tmp->data; if (len != 0 && g_strncasecmp(rec->nick, nick, len) != 0) continue; msg = g_new(LAST_MSG_REC, 1); msg->time = rec->time; msg->nick = prefix == NULL || *prefix == '\0' ? g_strdup(rec->nick) : g_strconcat(prefix, " ", rec->nick, NULL); *list = g_slist_insert_sorted(*list, msg, (GCompareFunc) last_msg_cmp); } }
static void sig_erase_complete_msg(WINDOW_REC *window, const char *word, const char *line) { SERVER_REC *server; MODULE_SERVER_REC *mserver; GSList *tmp; server = line_get_server(line); if (server == NULL){ server = window->active_server; if (server == NULL) return; } if (*word == '\0') return; /* check from global list */ completion_last_message_remove(word); /* check from server specific list */ if (server != NULL) { mserver = MODULE_DATA(server); for (tmp = mserver->lastmsgs; tmp != NULL; tmp = tmp->next) { LAST_MSG_REC *rec = tmp->data; if (g_strcasecmp(rec->nick, word) == 0) { last_msg_destroy(&mserver->lastmsgs, rec); break; } } } }
static void event_ison(IRC_SERVER_REC *server, const char *data) { MODULE_SERVER_REC *mserver; char *params, *online; g_return_if_fail(data != NULL); g_return_if_fail(server != NULL); params = event_get_params(data, 2, NULL, &online); mserver = MODULE_DATA(server); ison_save_users(mserver, online); if (--mserver->ison_count > 0) { /* wait for the rest of the /ISON replies */ g_free(params); return; } ison_check_joins(server); ison_check_parts(server); /* free memory used by temp list */ g_slist_foreach(mserver->ison_tempusers, (GFunc) g_free, NULL); g_slist_free(mserver->ison_tempusers); mserver->ison_tempusers = NULL; g_free(params); }
WINDOW_REC *window_find_item(WINDOW_REC *window, const char *name) { WINDOW_REC *rec; WI_ITEM_REC *item; g_return_val_if_fail(name != NULL, NULL); rec = window_find_name(name); if (rec != NULL) return rec; item = window == NULL ? NULL : window_item_find(window->active_server, name); if (item == NULL && window->active_server != NULL) { /* not found from the active server - any server? */ item = window_item_find(NULL, name); } if (item == NULL) { char *chan; /* still nothing? maybe user just left the # in front of channel, try again with it.. */ chan = g_strdup_printf("#%s", name); item = window == NULL ? NULL : window_item_find(window->active_server, chan); if (item == NULL) item = window_item_find(NULL, chan); g_free(chan); } if (item == NULL) return 0; return MODULE_DATA(item); }
static void sig_nick_removed(CHANNEL_REC *channel, NICK_REC *nick) { MODULE_CHANNEL_REC *mchannel; LAST_MSG_REC *rec; mchannel = MODULE_DATA(channel); rec = last_msg_find(mchannel->lastmsgs, nick->nick); if (rec != NULL) last_msg_destroy(&mchannel->lastmsgs, rec); }
GSList *server_autoignores(IRC_SERVER_REC *server) { MODULE_SERVER_REC *rec; g_return_val_if_fail(server != NULL, NULL); rec = MODULE_DATA(server); return rec->ignorelist; }
static void sig_server_disconnected(SERVER_REC *server) { MODULE_SERVER_REC *mserver; g_return_if_fail(server != NULL); mserver = MODULE_DATA(server); while (mserver->lastmsgs) last_msg_destroy(&mserver->lastmsgs, mserver->lastmsgs->data); }
static void autoignore_init_server(IRC_SERVER_REC *server) { MODULE_SERVER_REC *mserver; g_return_if_fail(server != NULL); mserver = MODULE_DATA(server); mserver->ignorelist = NULL; mserver->ignore_lastcheck = time(NULL)-AUTOIGNORE_TIMECHECK; }
static void autoignore_deinit_server(IRC_SERVER_REC *server) { MODULE_SERVER_REC *mserver; g_return_if_fail(server != NULL); mserver = MODULE_DATA(server); while (mserver->ignorelist != NULL) autoignore_remove_rec(server, (AUTOIGNORE_REC *) mserver->ignorelist->data); }
/* All messages should go through here.. */ static void flood_newmsg(IRC_SERVER_REC *server, int level, const char *nick, const char *host, const char *target) { MODULE_SERVER_REC *mserver; FLOOD_REC *flood; FLOOD_ITEM_REC *rec; time_t now, *ttime; GSList *times, *tnext; g_return_if_fail(server != NULL); g_return_if_fail(nick != NULL); mserver = MODULE_DATA(server); flood = g_hash_table_lookup(mserver->floodlist, nick); rec = flood == NULL ? NULL : flood_find(flood, level, target); if (rec != NULL) { now = time(NULL); for (times = rec->msgtimes; times != NULL; times = tnext) { time_t *data = times->data; tnext = times->next; if (now - *data >= flood_timecheck) { rec->msgtimes = g_slist_remove(rec->msgtimes, data); g_free(data); } else break; } ttime = g_new(time_t, 1); *ttime = now; rec->msgtimes = g_slist_append(rec->msgtimes, ttime); if (g_slist_length(rec->msgtimes) > flood_max_msgs) { /* flooding! */ signal_emit("flood", 5, server, nick, host, GINT_TO_POINTER(rec->level), target); } return; } if (flood == NULL) { flood = g_new0(FLOOD_REC, 1); flood->nick = g_strdup(nick); g_hash_table_insert(mserver->floodlist, flood->nick, flood); } rec = g_new0(FLOOD_ITEM_REC, 1); rec->level = level; rec->msgtimes = NULL; ttime = g_new(time_t, 1); *ttime = time(NULL); rec->msgtimes = g_slist_append(rec->msgtimes, ttime); rec->target = g_strdup(target); flood->items = g_slist_append(flood->items, rec); }
void window_item_change_server(WI_ITEM_REC *item, void *server) { WINDOW_REC *window; g_return_if_fail(item != NULL); window = MODULE_DATA(item); item->server = server; signal_emit("window item server changed", 2, window, item); if (window->active == item) window_change_server(window, item->server); }
static void sig_channel_destroyed(CHANNEL_REC *channel) { MODULE_CHANNEL_REC *mchannel; g_return_if_fail(channel != NULL); mchannel = MODULE_DATA(channel); while (mchannel->lastmsgs != NULL) { last_msg_destroy(&mchannel->lastmsgs, mchannel->lastmsgs->data); } }
static void sig_nick_changed(CHANNEL_REC *channel, NICK_REC *nick, const char *oldnick) { MODULE_CHANNEL_REC *mchannel; LAST_MSG_REC *rec; mchannel = MODULE_DATA(channel); rec = last_msg_find(mchannel->lastmsgs, oldnick); if (rec != NULL) { g_free(rec->nick); rec->nick = g_strdup(nick->nick); } }
NOTIFY_NICK_REC *notify_nick_create(IRC_SERVER_REC *server, const char *nick) { MODULE_SERVER_REC *mserver; NOTIFY_NICK_REC *rec; mserver = MODULE_DATA(server); rec = g_new0(NOTIFY_NICK_REC, 1); rec->nick = g_strdup(nick); mserver->notify_users = g_slist_append(mserver->notify_users, rec); return rec; }
void notifylist_left(IRC_SERVER_REC *server, NOTIFY_NICK_REC *rec) { MODULE_SERVER_REC *mserver; mserver = MODULE_DATA(server); mserver->notify_users = g_slist_remove(mserver->notify_users, rec); if (rec->host_ok && rec->away_ok) { signal_emit("notifylist left", 6, server, rec->nick, rec->user, rec->host, rec->realname, rec->awaymsg); } }
/* Deinitialize flood protection */ static void flood_deinit_server(IRC_SERVER_REC *server) { MODULE_SERVER_REC *mserver; g_return_if_fail(server != NULL); mserver = MODULE_DATA(server); if (mserver != NULL && mserver->floodlist != NULL) { flood_timecheck = 0; g_hash_table_foreach(mserver->floodlist, (GHFunc) flood_hash_destroy, NULL); g_hash_table_destroy(mserver->floodlist); } g_free(mserver); }
static void autoignore_remove_rec(IRC_SERVER_REC *server, AUTOIGNORE_REC *rec) { MODULE_SERVER_REC *mserver; g_return_if_fail(server != NULL); g_return_if_fail(rec != NULL); signal_emit("autoignore remove", 2, server, rec); g_free(rec->nick); g_free(rec); mserver = MODULE_DATA(server); mserver->ignorelist = g_slist_remove(mserver->ignorelist, rec); }
static void notifylist_deinit_server(IRC_SERVER_REC *server) { MODULE_SERVER_REC *mserver; NOTIFY_NICK_REC *rec; g_return_if_fail(server != NULL); mserver = MODULE_DATA(server); while (mserver->notify_users != NULL) { rec = mserver->notify_users->data; mserver->notify_users = g_slist_remove(mserver->notify_users, rec); notify_nick_destroy(rec); } g_free(mserver); }
static void ison_send(IRC_SERVER_REC *server, GString *cmd) { MODULE_SERVER_REC *mserver; mserver = MODULE_DATA(server); mserver->ison_count++; g_string_truncate(cmd, cmd->len-1); g_string_prepend(cmd, "ISON :"); server_redirect_event(server, "ison", 1, NULL, -1, NULL, "event 303", "notifylist event", NULL); irc_send_cmd(server, cmd->str); g_string_truncate(cmd, 0); }
NOTIFY_NICK_REC *notify_nick_find(IRC_SERVER_REC *server, const char *nick) { MODULE_SERVER_REC *mserver; NOTIFY_NICK_REC *rec; GSList *tmp; mserver = MODULE_DATA(server); for (tmp = mserver->notify_users; tmp != NULL; tmp = tmp->next) { rec = tmp->data; if (g_strcasecmp(rec->nick, nick) == 0) return rec; } return NULL; }
static int flood_timeout(void) { MODULE_SERVER_REC *mserver; GSList *tmp; time_t now; /* remove the old people from flood lists */ now = time(NULL); for (tmp = servers; tmp != NULL; tmp = tmp->next) { IRC_SERVER_REC *rec = tmp->data; mserver = MODULE_DATA(rec); g_hash_table_foreach_remove(mserver->floodlist, (GHRFunc) flood_hash_check_remove, GINT_TO_POINTER((int) now)); } return 1; }
static void ison_check_parts(IRC_SERVER_REC *server) { MODULE_SERVER_REC *mserver; GSList *tmp, *next; mserver = MODULE_DATA(server); for (tmp = mserver->notify_users; tmp != NULL; tmp = next) { NOTIFY_NICK_REC *rec = tmp->data; next = tmp->next; if (gslist_find_icase_string(mserver->ison_tempusers, rec->nick) != NULL) continue; notifylist_left(server, rec); } }
static AUTOIGNORE_REC *autoignore_find(IRC_SERVER_REC *server, const char *mask) { MODULE_SERVER_REC *mserver; GSList *tmp; g_return_val_if_fail(server != NULL, NULL); g_return_val_if_fail(mask != NULL, NULL); mserver = MODULE_DATA(server); for (tmp = mserver->ignorelist; tmp != NULL; tmp = tmp->next) { AUTOIGNORE_REC *rec = tmp->data; if (g_strcasecmp(rec->nick, mask) == 0) return rec; } return NULL; }
/* All WHOIS replies got, now announce all the changes at once. */ static void event_whois_end(IRC_SERVER_REC *server, const char *data) { MODULE_SERVER_REC *mserver; NOTIFYLIST_REC *notify; NOTIFY_NICK_REC *rec; GSList *tmp; const char *event; int away_ok; mserver = MODULE_DATA(server); for (tmp = mserver->notify_users; tmp != NULL; tmp = tmp->next) { rec = tmp->data; if (rec->realname == NULL) continue; notify = notifylist_find(rec->nick, server->connrec->chatnet); if (notify == NULL) continue; away_ok = !notify->away_check || !rec->away; event = NULL; if (!rec->join_announced) { rec->join_announced = TRUE; rec->idle_time = 0; if (away_ok) event = "notifylist joined"; } else if (notify->away_check && rec->away_ok == rec->away) event = "notifylist away changed"; else if (notify->idle_check_time > 0 && rec->idle_changed) event = "notifylist unidle"; if (event != NULL) { signal_emit(event, 6, server, rec->nick, rec->user != NULL ? rec->user : "******", rec->host != NULL ? rec->host : "??", rec->realname != NULL ? rec->realname : "??", rec->awaymsg); } rec->idle_ok = notify->idle_check_time <= 0 || rec->idle_time <= notify->idle_check_time; rec->idle_changed = FALSE; rec->away_ok = away_ok; } }
void autoignore_add(IRC_SERVER_REC *server, const char *nick, int level) { MODULE_SERVER_REC *mserver; AUTOIGNORE_REC *rec; IGNORE_REC *irec; int igtime; g_return_if_fail(server != NULL); g_return_if_fail(nick != NULL); if (level == 0) return; igtime = settings_get_int("autoignore_time"); if (igtime <= 0) return; irec = ignore_find_server(server, nick); if (irec == NULL) { irec = g_new0(IGNORE_REC, 1); irec->servertag = g_strdup(server->tag); irec->mask = g_strdup(nick); irec->level = level; ignore_add_rec(irec); } else { irec->level |= level; ignore_update_rec(irec); } rec = autoignore_find(server, nick); if (rec != NULL) { /* already being ignored */ rec->timeleft = igtime; return; } rec = g_new(AUTOIGNORE_REC, 1); rec->nick = g_strdup(nick); rec->timeleft = igtime; rec->level = level; mserver = MODULE_DATA(server); mserver->ignorelist = g_slist_append(mserver->ignorelist, rec); signal_emit("autoignore new", 2, server, rec); }
/* timeout function: send /ISON commands to server to check if someone in notify list is in IRC */ static void notifylist_timeout_server(IRC_SERVER_REC *server) { MODULE_SERVER_REC *mserver; GSList *tmp; GString *cmd; char *nick, *ptr; int len; g_return_if_fail(server != NULL); if (!IS_IRC_SERVER(server)) return; mserver = MODULE_DATA(server); if (mserver->ison_count > 0) { /* still not received all replies to previous /ISON commands.. */ return; } cmd = g_string_new(NULL); for (tmp = notifies; tmp != NULL; tmp = tmp->next) { NOTIFYLIST_REC *rec = tmp->data; if (!notifylist_ircnets_match(rec, server->connrec->chatnet)) continue; nick = g_strdup(rec->mask); ptr = strchr(nick, '!'); if (ptr != NULL) *ptr = '\0'; len = strlen(nick); if (cmd->len+len+1 > 510) ison_send(server, cmd); g_string_sprintfa(cmd, "%s ", nick); g_free(nick); } if (cmd->len > 0) ison_send(server, cmd); g_string_free(cmd, TRUE); }
/* All messages should go through here.. */ static void flood_newmsg(IRC_SERVER_REC *server, int level, const char *nick, const char *host, const char *target) { MODULE_SERVER_REC *mserver; FLOOD_REC *flood; FLOOD_ITEM_REC *rec; time_t *ttime; g_return_if_fail(server != NULL); g_return_if_fail(nick != NULL); mserver = MODULE_DATA(server); flood = g_hash_table_lookup(mserver->floodlist, nick); rec = flood == NULL ? NULL : flood_find(flood, level, target); if (rec != NULL) { ttime = g_new(time_t, 1); *ttime = time(NULL); rec->msgtimes = g_slist_append(rec->msgtimes, ttime); if (g_slist_length(rec->msgtimes) > flood_max_msgs) { /* flooding! */ signal_emit("flood", 5, server, nick, host, GINT_TO_POINTER(rec->level), target); } return; } if (flood == NULL) { flood = g_new0(FLOOD_REC, 1); flood->nick = g_strdup(nick); g_hash_table_insert(mserver->floodlist, flood->nick, flood); } rec = g_new0(FLOOD_ITEM_REC, 1); rec->level = level; rec->msgtimes = NULL; ttime = g_new(time_t, 1); *ttime = time(NULL); rec->msgtimes = g_slist_append(rec->msgtimes, ttime); rec->target = g_strdup(target); flood->items = g_slist_append(flood->items, rec); }
static void ison_check_joins(IRC_SERVER_REC *server) { MODULE_SERVER_REC *mserver; NOTIFYLIST_REC *notify; NOTIFY_NICK_REC *rec; GSList *tmp, *newnicks; int send_whois; time_t now; mserver = MODULE_DATA(server); now = time(NULL); newnicks = NULL; for (tmp = mserver->ison_tempusers; tmp != NULL; tmp = tmp->next) { char *nick = tmp->data; notify = notifylist_find(nick, server->connrec->chatnet); send_whois = notify != NULL && (notify->away_check || notify->idle_check_time > 0); rec = notify_nick_find(server, nick); if (rec != NULL) { /* check if we want to send WHOIS yet.. */ if (now-rec->last_whois < notify_whois_time) continue; } else { rec = notify_nick_create(server, nick); if (!send_whois) newnicks = g_slist_append(newnicks, nick); } if (send_whois) { /* we need away message or idle time - send the WHOIS reply to the nick's server */ rec->last_whois = now; whois_send_server(server, nick); } } whois_list_send(server, newnicks); g_slist_free(newnicks); }