static void event_names_list(const char *data, SERVER_REC *server) { CHANNEL_REC *chanrec; char *params, *type, *channel, *names, *ptr; g_return_if_fail(data != NULL); params = event_get_params(data, 4, NULL, &type, &channel, &names); chanrec = channel_find(server, channel); if (chanrec == NULL || chanrec->names_got) { /* unknown channel / names list already read */ g_free(params); return; } /* type = '=' = public, '*' = private, '@' = secret. This is actually pretty useless to check here, but at least we get to know if the channel is +p or +s a few seconds before we receive the MODE reply... */ if (*type == '*') parse_channel_modes(IRC_CHANNEL(chanrec), NULL, "+p"); else if (*type == '@') parse_channel_modes(IRC_CHANNEL(chanrec), NULL, "+s"); while (*names != '\0') { while (*names == ' ') names++; ptr = names; while (*names != '\0' && *names != ' ') names++; if (*names != '\0') *names++ = '\0'; if (*ptr == '@' && g_strcasecmp(server->nick, ptr+1) == 0) chanrec->chanop = TRUE; nicklist_insert(chanrec, ptr+isnickflag(*ptr), *ptr == '@', *ptr == '+', FALSE); } g_free(params); }
static int isnickflag_func(SERVER_REC *server, char flag) { IRC_SERVER_REC *irc_server = (IRC_SERVER_REC *) server; return isnickflag(irc_server, flag); }
static void print_netjoins(NETJOIN_SERVER_REC *server) { TEMP_PRINT_REC *temp; GHashTable *channels; GSList *tmp, *next, *old; g_return_if_fail(server != NULL); printing_joins = TRUE; /* save nicks to string, clear now_channels and remove the same channels from old_channels list */ channels = g_hash_table_new((GHashFunc) g_istr_hash, (GCompareFunc) g_istr_equal); for (tmp = server->netjoins; tmp != NULL; tmp = next) { NETJOIN_REC *rec = tmp->data; next = tmp->next; while (rec->now_channels != NULL) { char *channel = rec->now_channels->data; char *realchannel = channel + isnickflag(*channel); temp = g_hash_table_lookup(channels, realchannel); if (temp == NULL) { temp = g_new0(TEMP_PRINT_REC, 1); temp->nicks = g_string_new(NULL); g_hash_table_insert(channels, g_strdup(realchannel), temp); } temp->count++; if (temp->count <= netjoin_max_nicks) { if (isnickflag(*channel)) g_string_append_c(temp->nicks, *channel); g_string_sprintfa(temp->nicks, "%s, ", rec->nick); } /* remove the channel from old_channels too */ old = gslist_find_icase_string(rec->old_channels, realchannel); if (old != NULL) { g_free(old->data); rec->old_channels = g_slist_remove(rec->old_channels, old->data); } g_free(channel); rec->now_channels = g_slist_remove(rec->now_channels, channel); } if (rec->old_channels == NULL) netjoin_remove(server, rec); } g_hash_table_foreach(channels, (GHFunc) print_channel_netjoins, server); g_hash_table_destroy(channels); if (server->netjoins == NULL) netjoin_server_remove(server); printing_joins = FALSE; }
static void event_names_list(IRC_SERVER_REC *server, const char *data) { IRC_CHANNEL_REC *chanrec; NICK_REC *rec; char *params, *type, *channel, *names, *ptr, *host; int op, halfop, voice; char prefixes[MAX_USER_PREFIXES+1]; const char *nick_flags, *nick_flag_cur, *nick_flag_op; g_return_if_fail(data != NULL); params = event_get_params(data, 4, NULL, &type, &channel, &names); chanrec = irc_channel_find(server, channel); if (chanrec == NULL || chanrec->names_got) { /* unknown channel / names list already read */ g_free(params); return; } nick_flags = server->get_nick_flags(SERVER(server)); nick_flag_op = strchr(nick_flags, '@'); /* type = '=' = public, '*' = private, '@' = secret. This is actually pretty useless to check here, but at least we get to know if the channel is +p or +s a few seconds before we receive the MODE reply... If the channel key is set, assume the channel is +k also until we know better, so parse_channel_modes() won't clear the key */ if (*type == '*') { parse_channel_modes(chanrec, NULL, chanrec->key ? "+kp" : "+p", FALSE); } else if (*type == '@') { parse_channel_modes(chanrec, NULL, chanrec->key ? "+ks" : "+s", FALSE); } while (*names != '\0') { while (*names == ' ') names++; ptr = names; while (*names != '\0' && *names != ' ') names++; if (*names != '\0') *names++ = '\0'; /* some servers show ".@nick", there's also been talk about showing "@+nick" and since none of these chars are valid nick chars, just check them until a non-nickflag char is found. */ op = halfop = voice = FALSE; prefixes[0] = '\0'; while (isnickflag(server, *ptr)) { prefix_add(prefixes, *ptr, (SERVER_REC *) server); switch (*ptr) { case '@': op = TRUE; break; case '%': halfop = TRUE; break; case '+': voice = TRUE; break; default: /* If this flag is listed higher than op (in the * isupport PREFIX reply), then count this user * as an op. */ nick_flag_cur = strchr(nick_flags, *ptr); if (nick_flag_cur && nick_flag_op && nick_flag_cur < nick_flag_op) { op = TRUE; } break; } ptr++; } host = strchr(ptr, '!'); if (host != NULL) *host++ = '\0'; if (nicklist_find((CHANNEL_REC *) chanrec, ptr) == NULL) { rec = irc_nicklist_insert(chanrec, ptr, op, halfop, voice, FALSE, prefixes); if (host != NULL) nicklist_set_host(CHANNEL(chanrec), rec, host); } } g_free(params); }