X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2Fhash.c;h=a55ad9ba92568bc06f6e3b031953a41bce38f273;hb=80d9ed728be4b02ac483f3339cbb184f6602d15b;hp=75769fa09706c6e4ebdf5962af50b6f0bb431c8c;hpb=2167d030c80b34f9f9cc0e2235edf47d64ce2500;p=srvx.git diff --git a/src/hash.c b/src/hash.c index 75769fa..a55ad9b 100644 --- a/src/hash.c +++ b/src/hash.c @@ -253,11 +253,14 @@ StampUser(struct userNode *user, const char *stamp, unsigned long timestamp, uns } void -assign_fakehost(struct userNode *user, const char *host, int announce) +assign_fakehost(struct userNode *user, const char *host, const char *ident, int force, int announce) { - safestrncpy(user->fakehost, host, sizeof(user->fakehost)); + if (host) + safestrncpy(user->fakehost, host, sizeof(user->fakehost)); + if (ident) + safestrncpy(user->fakeident, ident, sizeof(user->ident)); if (announce) - irc_fakehost(user, host); + irc_fakehost(user, host, ident, force); } static new_channel_func_t *ncf_list; @@ -379,6 +382,7 @@ AddChannel(const char *name, unsigned long time_, const char *modes, char *banli strcpy(cNode->name, name); banList_init(&cNode->banlist); modeList_init(&cNode->members); + userList_init(&cNode->invited); mod_chanmode(NULL, cNode, argv, nn, MCP_FROM_SERVER); dict_insert(channels, cNode->name, cNode); cNode->timestamp = time_; @@ -466,6 +470,7 @@ DelChannel(struct chanNode *channel) modeList_clean(&channel->members); banList_clean(&channel->banlist); + userList_clean(&channel->invited); free(channel); } @@ -514,6 +519,33 @@ AddChannelUser(struct userNode *user, struct chanNode* channel) return mNode; } +/* Return negative if *(struct modeNode**)pa is "less than" pb, + * positive if pa is "larger than" pb. Comparison is based on sorting + * so that non-voiced/non-opped users are first, voiced-only users are + * next, and the "strongest" oplevels are before "weaker" oplevels. + * Within those sets, ordering is arbitrary. + */ +int +modeNode_sort(const void *pa, const void *pb) +{ + struct modeNode *a = *(struct modeNode**)pa; + struct modeNode *b = *(struct modeNode**)pb; + + if (a->modes & MODE_CHANOP) { + if (!(b->modes & MODE_CHANOP)) + return -1; + else if ((b->modes & MODE_VOICE) != (a->modes & MODE_VOICE)) + return (b->modes & MODE_VOICE) - (a->modes & MODE_VOICE); + else if (a->oplevel != b->oplevel) + return a->oplevel - b->oplevel; + } else if (b->modes & MODE_CHANOP) + return 1; + else if ((b->modes & MODE_VOICE) != (a->modes & MODE_VOICE)) + return (b->modes & MODE_VOICE) - (a->modes & MODE_VOICE); + + return irccasecmp(a->user->nick, b->user->nick); +} + static part_func_t *pf_list; static unsigned int pf_size = 0, pf_used = 0; @@ -633,9 +665,9 @@ ChannelUserKicked(struct userNode* kicker, struct userNode* victim, struct chanN unsigned int n; struct modeNode *mn; - if (!victim || !channel || IsService(victim) || !GetUserMode(channel, victim)) + if (!victim || !channel || !GetUserMode(channel, victim)) return; - + /* Update the kicker's idle time (kicker may be null if it was a server) */ if (kicker && (mn = GetUserMode(channel, kicker))) mn->idle_since = now;