static GList *completion_channel_nicks(CHANNEL_REC *channel, const char *nick, const char *prefix) { GSList *nicks, *tmp; GList *list; int len; g_return_val_if_fail(channel != NULL, NULL); g_return_val_if_fail(nick != NULL, NULL); if (*nick == '\0') return NULL; /* put first the nicks who have recently said something [to you] */ list = NULL; complete_from_nicklist(&list, channel->lastownmsgs, nick, prefix); complete_from_nicklist(&list, channel->lastmsgs, nick, prefix); /* and add the rest of the nicks too */ len = strlen(nick); nicks = nicklist_getnicks(channel); for (tmp = nicks; tmp != NULL; tmp = tmp->next) { NICK_REC *rec = tmp->data; if (g_strncasecmp(rec->nick, nick, len) == 0 && glist_find_icase_string(list, rec->nick) == NULL && g_strcasecmp(rec->nick, channel->server->nick) != 0) { if (prefix == NULL || *prefix == '\0') list = g_list_append(list, g_strdup(rec->nick)); else list = g_list_append(list, g_strconcat(rec->nick, prefix, NULL)); } } g_slist_free(nicks); return list; }
void fe_channels_nicklist(CHANNEL_REC *channel, int flags) { NICK_REC *nick; GSList *tmp, *nicklist, *sorted; int nicks, normal, voices, halfops, ops; const char *nick_flags; nicks = normal = voices = halfops = ops = 0; nicklist = nicklist_getnicks(channel); sorted = NULL; nick_flags = channel->server->get_nick_flags(channel->server); /* filter (for flags) and count ops, halfops, voices */ for (tmp = nicklist; tmp != NULL; tmp = tmp->next) { nick = tmp->data; nicks++; if (nick->op) { ops++; if ((flags & CHANNEL_NICKLIST_FLAG_OPS) == 0) continue; } else if (nick->halfop) { halfops++; if ((flags & CHANNEL_NICKLIST_FLAG_HALFOPS) == 0) continue; } else if (nick->voice) { voices++; if ((flags & CHANNEL_NICKLIST_FLAG_VOICES) == 0) continue; } else { normal++; if ((flags & CHANNEL_NICKLIST_FLAG_NORMAL) == 0) continue; } sorted = g_slist_prepend(sorted, nick); } g_slist_free(nicklist); /* sort the nicklist */ sorted = g_slist_sort_with_data(sorted, (GCompareDataFunc) nicklist_compare, (void *)nick_flags); /* display the nicks */ if ((flags & CHANNEL_NICKLIST_FLAG_COUNT) == 0) { printformat(channel->server, channel->visible_name, MSGLEVEL_CLIENTCRAP, TXT_NAMES, channel->visible_name, nicks, ops, halfops, voices, normal); display_sorted_nicks(channel, sorted); } g_slist_free(sorted); printformat(channel->server, channel->visible_name, MSGLEVEL_CLIENTNOTICE, TXT_ENDOFNAMES, channel->visible_name, nicks, ops, halfops, voices, normal); }
static GList *completion_nicks_nonstrict(CHANNEL_REC *channel, const char *nick, const char *suffix) { GSList *nicks, *tmp; GList *list; char *tnick, *str, *in, *out; int len, str_len, tmplen; g_return_val_if_fail(channel != NULL, NULL); list = NULL; /* get all nicks from current channel, strip non alnum chars, compare again and add to completion list on matching */ len = strlen(nick); nicks = nicklist_getnicks(channel); str_len = 80; str = g_malloc(str_len+1); for (tmp = nicks; tmp != NULL; tmp = tmp->next) { NICK_REC *rec = tmp->data; tmplen = strlen(rec->nick); if (tmplen > str_len) { str_len = tmplen*2; str = g_realloc(str, str_len+1); } /* remove non alnum chars from nick */ in = rec->nick; out = str; while (*in != '\0') { if (i_isalnum(*in)) *out++ = *in; in++; } *out = '\0'; /* add to list if 'cleaned' nick matches */ if (g_strncasecmp(str, nick, len) == 0) { tnick = g_strconcat(rec->nick, suffix, NULL); if (completion_lowercase) g_strdown(tnick); if (glist_find_icase_string(list, tnick) == NULL) list = g_list_append(list, tnick); else g_free(tnick); } } g_free(str); g_slist_free(nicks); return list; }
static void session_save_channel_nicks(CHANNEL_REC *channel, CONFIG_REC *config, CONFIG_NODE *node) { GSList *tmp, *nicks; node = config_node_section(config, node, "nicks", NODE_TYPE_LIST); nicks = nicklist_getnicks(channel); for (tmp = nicks; tmp != NULL; tmp = tmp->next) session_save_nick(channel, tmp->data, config, node); g_slist_free(nicks); }
static void sig_channel_wholist(IRC_CHANNEL_REC *channel) { GSList *nicks, *tmp; nicks = nicklist_getnicks(CHANNEL(channel)); for (tmp = nicks; tmp != NULL; tmp = tmp->next) { NICK_REC *rec = tmp->data; notifylist_check_join(channel->server, rec->nick, rec->host, rec->realname, rec->gone); } g_slist_free(nicks); }
static void nickmatch_check_channel(CHANNEL_REC *channel, NICKMATCH_REC *rec) { GSList *nicks, *tmp; nicks = nicklist_getnicks(channel); for (tmp = nicks; tmp != NULL; tmp = tmp->next) { NICK_REC *nick = tmp->data; rec->func(rec->nicks, channel, nick); } g_slist_free(nicks); }
static void dump_join(IRC_CHANNEL_REC *channel, CLIENT_REC *client) { GSList *tmp, *nicks; GString *str; int first; proxy_outserver(client, "JOIN %s", channel->name); str = g_string_new(NULL); create_names_start(str, channel, client); first = TRUE; nicks = nicklist_getnicks(CHANNEL(channel)); for (tmp = nicks; tmp != NULL; tmp = tmp->next) { NICK_REC *nick = tmp->data; if (str->len >= 500) { g_string_append_c(str, '\n'); proxy_outdata(client, "%s", str->str); create_names_start(str, channel, client); first = TRUE; } if (first) first = FALSE; else g_string_append_c(str, ' '); if (nick->other) g_string_append_c(str, nick->other); else if (nick->op) g_string_append_c(str, '@'); else if (nick->halfop) g_string_append_c(str, '%'); else if (nick->voice) g_string_append_c(str, '+'); g_string_append(str, nick->nick); } g_slist_free(nicks); g_string_append_c(str, '\n'); proxy_outdata(client, "%s", str->str); g_string_free(str, TRUE); proxy_outdata(client, ":%s 366 %s %s :End of /NAMES list.\n", client->proxy_address, client->nick, channel->name); /* this is needed because the topic may be encoded into other charsets internaly */ if (channel->topic != NULL) { proxy_outdata(client, ":%s 332 %s %s :%s\n", client->proxy_address, client->nick, channel->name, recode_out(channel->topic, channel->name)); } }
GSList *nicklist_find_multiple(CHANNEL_REC *channel, const char *mask) { GSList *nicks, *tmp, *next; nicks = nicklist_getnicks(channel); for (tmp = nicks; tmp != NULL; tmp = next) { NICK_REC *nick = tmp->data; next = tmp->next; if (!irc_mask_match_address(mask, nick->nick, nick->host == NULL ? "" : nick->host)) nicks = g_slist_remove(nicks, tmp->data); } return nicks; }
static NICK_REC *nicklist_find_wildcards(CHANNEL_REC *channel, const char *mask) { GSList *nicks, *tmp; NICK_REC *nick; nicks = nicklist_getnicks(channel); nick = NULL; for (tmp = nicks; tmp != NULL; tmp = tmp->next) { nick = tmp->data; if (irc_mask_match_address(mask, nick->nick, nick->host == NULL ? "" : nick->host)) break; } g_slist_free(nicks); return tmp == NULL ? NULL : nick; }
static GList *completion_channel_nicks(CHANNEL_REC *channel, const char *nick, const char *suffix) { GSList *nicks, *tmp; GList *list; char *str; int len; g_return_val_if_fail(channel != NULL, NULL); g_return_val_if_fail(nick != NULL, NULL); if (*nick == '\0') return NULL; if (suffix != NULL && *suffix == '\0') suffix = NULL; /* put first the nicks who have recently said something */ list = NULL; complete_from_nicklist(&list, channel, nick, suffix); /* and add the rest of the nicks too */ len = strlen(nick); nicks = nicklist_getnicks(channel); for (tmp = nicks; tmp != NULL; tmp = tmp->next) { NICK_REC *rec = tmp->data; if (g_strncasecmp(rec->nick, nick, len) == 0 && rec != channel->ownnick) { str = g_strconcat(rec->nick, suffix, NULL); if (completion_lowercase) g_strdown(str); if (glist_find_icase_string(list, str) == NULL) list = g_list_append(list, str); else g_free(str); } } g_slist_free(nicks); /* remove non alphanum chars from nick and search again in case list is still NULL ("foo<tab>" would match "_foo_" f.e.) */ if (!completion_strict) list = g_list_concat(list, completion_nicks_nonstrict(channel, nick, suffix)); return list; }
GSList *nicklist_find_multiple(CHANNEL_REC *channel, const char *mask) { GSList *nicks, *tmp, *next; g_return_val_if_fail(IS_CHANNEL(channel), NULL); g_return_val_if_fail(mask != NULL, NULL); nicks = nicklist_getnicks(channel); for (tmp = nicks; tmp != NULL; tmp = next) { NICK_REC *nick = tmp->data; next = tmp->next; if (!mask_match_address(channel->server, mask, nick->nick, nick->host)) nicks = g_slist_remove(nicks, tmp->data); } return nicks; }
static void cmd_channel_list_joined(void) { CHANNEL_REC *channel; GString *nicks; GSList *nicklist, *tmp, *ntmp; if (channels == NULL) { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_NOT_IN_CHANNELS); return; } /* print active channel */ channel = CHANNEL(active_win->active); if (channel != NULL) printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_CURRENT_CHANNEL, channel->visible_name); /* print list of all channels, their modes, server tags and nicks */ printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_CHANLIST_HEADER); for (tmp = channels; tmp != NULL; tmp = tmp->next) { channel = tmp->data; nicklist = nicklist_getnicks(channel); nicks = g_string_new(NULL); for (ntmp = nicklist; ntmp != NULL; ntmp = ntmp->next) { NICK_REC *rec = ntmp->data; g_string_sprintfa(nicks, "%s ", rec->nick); } if (nicks->len > 1) g_string_truncate(nicks, nicks->len-1); printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_CHANLIST_LINE, channel->visible_name, channel->mode, channel->server->tag, nicks->str); g_slist_free(nicklist); g_string_free(nicks, TRUE); } }
/* channel synced - find everyone's NICK_REC's */ static void sig_channel_sync(CHANNEL_REC *channel) { USER_REC *user; USER_CHAN_REC *userchan; GSList *tmp, *nicks; g_return_if_fail(channel != NULL); nicks = nicklist_getnicks(channel); for (tmp = nicks; tmp != NULL; tmp = tmp->next) { NICK_REC *rec = tmp->data; if (rec->send_massjoin) continue; /* This will be checked in "massjoin" signal */ user = botuser_find(rec->nick, rec->host); if (user != NULL) { userchan = botuser_get_channel(user, channel->name); userchan->nickrec = rec; } } g_slist_free(nicks); }
/* * Command: nicklist_getnicks <server tag> <channel> * * Retrieve the nicks in a channel. */ int tcl_command_nicklist_getnicks(ClientData clientData, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]) { (void) clientData; if (objc != 3) { Tcl_Obj* str = Tcl_ObjPrintf("wrong # args: should be \"nicklist_getnicks" " server_tag channel\""); Tcl_SetObjResult(interp, str); return TCL_ERROR; } Tcl_Obj* const server_tag = objv[1]; Tcl_Obj* const channel_name = objv[2]; // find the server. SERVER_REC* server_rec = server_find_tag(Tcl_GetString(server_tag)); if (!server_rec) { Tcl_Obj* str = Tcl_ObjPrintf("server with tag '%s' not found", Tcl_GetString(server_tag)); Tcl_SetObjResult(interp, str); return TCL_ERROR; } // find the channel on this server. CHANNEL_REC* channel_rec = channel_find(server_rec, Tcl_GetString(channel_name)); if (!channel_rec) { Tcl_Obj* str = Tcl_ObjPrintf("channel '%s' not found on server '%s'", Tcl_GetString(channel_name), Tcl_GetString(server_tag)); Tcl_SetObjResult(interp, str); return TCL_ERROR; } // get the nicks as a list. Tcl_Obj* list = Tcl_NewListObj(0, NULL); if (!list) { Tcl_Obj* str = Tcl_ObjPrintf("failed to create list"); Tcl_SetObjResult(interp, str); return TCL_ERROR; } GSList* nicks = nicklist_getnicks(channel_rec); for (GSList* nick_ptr = nicks; nick_ptr; nick_ptr = nick_ptr->next) { NICK_REC* nick = nick_ptr->data; // TODO: encoding issues? Tcl_Obj* nick_str = Tcl_NewStringObj(nick->nick, -1); if (!nick_str) { Tcl_Obj* str = Tcl_ObjPrintf("failed to create nick string"); Tcl_SetObjResult(interp, str); __tcl_command_free_tcl_list(interp, list); g_slist_free(nicks); return TCL_ERROR; } if (Tcl_ListObjAppendElement(interp, list, nick_str) != TCL_OK) { Tcl_Obj* str = Tcl_ObjPrintf("failed to append to list: '%s'", Tcl_GetString(nick_str)); Tcl_SetObjResult(interp, str); __tcl_command_free_tcl_list(interp, list); g_slist_free(nicks); return TCL_ERROR; } } g_slist_free(nicks); Tcl_SetObjResult(interp, list); return TCL_OK; }