[X2serv-cvs] [CVS] Module srvx2: Change committed
Brought to you by:
sirvulcan
From: Neil S. <sir...@us...> - 2004-08-23 15:39:40
|
Committer : Code Monkey <sir...@us...> CVSROOT : /cvsroot/x2serv Module : srvx2 Commit time: 2004-08-23 15:39:30 UTC Modified files: src/chanserv.c src/common.h src/hash.c src/hash.h src/opserv.c src/proto-common.c src/proto-p10.c src/tools.c Log message: Stage 2, exempt support ---------------------- diff included ---------------------- Index: srvx2/src/chanserv.c diff -u srvx2/src/chanserv.c:1.7 srvx2/src/chanserv.c:1.8 --- srvx2/src/chanserv.c:1.7 Thu Aug 19 15:09:58 2004 +++ srvx2/src/chanserv.c Mon Aug 23 08:39:18 2004 @@ -1786,7 +1786,7 @@ } if(new_channel) - channel = AddChannel(argv[1], now, NULL, NULL); + channel = AddChannel(argv[1], now, NULL, NULL, NULL); cData = register_channel(channel, user->handle_info->handle); scan_user_presence(add_channel_user(cData, handle, UL_OWNER, 0, NULL), NULL); @@ -1924,7 +1924,7 @@ if(!(target = GetChannel(argv[1]))) { - target = AddChannel(argv[1], now, NULL, NULL); + target = AddChannel(argv[1], now, NULL, NULL, NULL); if(!IsSuspended(channel->channel_info)) AddChannelUser(chanserv, target); } @@ -6460,7 +6460,7 @@ const char *str2 = database_get_data(conf_node, KEY_SUPPORT_CHANNEL_MODES, RECDB_QSTRING); if(!str2) str2 = "+nt"; - chan = AddChannel(strlist->list[ii], now, str2, NULL); + chan = AddChannel(strlist->list[ii], now, str2, NULL, NULL); LockChannel(chan); channelList_append(&chanserv_conf.support_channels, chan); } @@ -6471,7 +6471,7 @@ str2 = database_get_data(conf_node, KEY_SUPPORT_CHANNEL_MODES, RECDB_QSTRING); if(!str2) str2 = "+nt"; - chan = AddChannel(str, now, str2, NULL); + chan = AddChannel(str, now, str2, NULL, NULL); LockChannel(chan); channelList_append(&chanserv_conf.support_channels, chan); } @@ -6746,7 +6746,7 @@ str = database_get_data(channel, KEY_REGISTRAR, RECDB_QSTRING); if(!str) str = "<unknown>"; - cNode = AddChannel(key, now, NULL, NULL); + cNode = AddChannel(key, now, NULL, NULL, NULL); if(!cNode) { log_module(CS_LOG, LOG_ERROR, "Unable to create registered channel %s.", key); Index: srvx2/src/common.h diff -u srvx2/src/common.h:1.1.1.1 srvx2/src/common.h:1.2 --- srvx2/src/common.h:1.1.1.1 Thu Jun 3 10:13:59 2004 +++ srvx2/src/common.h Mon Aug 23 08:39:18 2004 @@ -96,6 +96,7 @@ void reg_exit_func(exit_func_t handler); void call_exit_funcs(void); +char *mysep(char **sepstr, char *delim); const char *inttobase64(char *buf, unsigned int v, unsigned int count); unsigned long base64toint(const char *s, int count); int split_line(char *line, int irc_colon, int argv_size, char *argv[]); Index: srvx2/src/hash.c diff -u srvx2/src/hash.c:1.2 srvx2/src/hash.c:1.3 --- srvx2/src/hash.c:1.2 Thu Aug 19 15:09:58 2004 +++ srvx2/src/hash.c Mon Aug 23 08:39:18 2004 @@ -309,6 +309,11 @@ free(cNode->banlist.list[nn]); cNode->banlist.used = 0; + /* remove our old exe,[t list, replace it with the new one */ + for (nn=0; nn<cNode->exemptlist.used; nn++) + free(cNode->exemptlist.list[nn]); + cNode->exemptlist.used = 0; + /* deop anybody in the channel now, but count services to reop */ for (nn=argc=0; nn<cNode->members.used; nn++) { struct modeNode *mn = cNode->members.list[nn]; @@ -340,7 +345,7 @@ } struct chanNode * -AddChannel(const char *name, time_t time_, const char *modes, char *banlist) +AddChannel(const char *name, time_t time_, const char *modes, char *banlist, char *exemptlist) { struct chanNode *cNode; char new_modes[MAXLEN], *argv[MAXNUMPARAMS]; @@ -359,6 +364,7 @@ cNode = calloc(1, sizeof(*cNode) + strlen(name)); strcpy(cNode->name, name); banList_init(&cNode->banlist); + exemptList_init(&cNode->exemptlist); modeList_init(&cNode->members); mod_chanmode(NULL, cNode, argv, nn, 0); dict_insert(channels, cNode->name, cNode); @@ -400,6 +406,23 @@ } } + /* go through list of exempts and add each one */ + if (exemptlist && (rel_age >= 0)) { + for (nn=0; exemptlist[nn];) { + char *exempt = exemptlist + nn; + struct exemptNode *en; + while (exemptlist[nn] != ' ' && exemptlist[nn]) + nn++; + while (exemptlist[nn] == ' ') + exemptlist[nn++] = 0; + en = calloc(1, sizeof(*en)); + safestrncpy(en->exempt, exempt, sizeof(en->exempt)); + safestrncpy(en->who, "<unknown>", sizeof(en->who)); + en->set = now; + exemptList_append(&cNode->exemptlist, en); + } + } + return cNode; } @@ -441,11 +464,17 @@ free(channel->banlist.list[--n]); channel->banlist.used = 0; + /* delete all channel exempts */ + for (n=channel->exemptlist.used; n>0; ) + free(channel->exemptlist.list[--n]); + channel->exemptlist.used = 0; + for (n=0; n<dcf_used; n++) dcf_list[n](channel); modeList_clean(&channel->members); banList_clean(&channel->banlist); + exemptList_clean(&channel->exemptlist); free(channel); } @@ -633,6 +662,16 @@ return 0; } +int ChannelExemptExists(struct chanNode *channel, const char *exempt) +{ + unsigned int n; + + for (n = 0; n < channel->exemptlist.used; n++) + if (match_ircglobs(channel->exemptlist.list[n]->exempt, exempt)) + return 1; + return 0; +} + static topic_func_t *tf_list; static unsigned int tf_size = 0, tf_used = 0; @@ -713,6 +752,7 @@ DEFINE_LIST(userList, struct userNode*) DEFINE_LIST(modeList, struct modeNode*) DEFINE_LIST(banList, struct banNode*) +DEFINE_LIST(exemptList, struct exemptNode*) DEFINE_LIST(channelList, struct chanNode*) DEFINE_LIST(serverList, struct server*) Index: srvx2/src/hash.h diff -u srvx2/src/hash.h:1.4 srvx2/src/hash.h:1.5 --- srvx2/src/hash.h:1.4 Thu Aug 19 15:09:58 2004 +++ srvx2/src/hash.h Mon Aug 23 08:39:18 2004 @@ -49,6 +49,7 @@ #define MODE_NOAMSG 0x00200000 /* +T no multi-target messages */ #define MODE_SSLONLY 0x00400000 /* +z ssl only */ #define MODE_HALFOP 0x00800000 /* +h USER */ +#define MODE_EXEMPT 0x01000000 /* +e exempt */ #define MODE_REMOVE 0x80000000 #define FLAGS_OPER 0x0001 /* Operator +O */ @@ -103,6 +104,7 @@ #define MAXMODEPARAMS 6 #define MAXBANS 45 +#define MAXEXEMPTS 45 /* IDLEN is 6 because it takes 5.33 Base64 digits to store 32 bytes. */ #define IDLEN 6 @@ -110,6 +112,7 @@ DECLARE_LIST(userList, struct userNode*); DECLARE_LIST(modeList, struct modeNode*); DECLARE_LIST(banList, struct banNode*); +DECLARE_LIST(exemptList, struct exemptNode*); DECLARE_LIST(channelList, struct chanNode*); DECLARE_LIST(serverList, struct server*); @@ -152,6 +155,7 @@ struct modeList members; struct banList banlist; + struct exemptList exemptlist; struct policer join_policer; unsigned int join_flooded : 1; unsigned int bad_channel : 1; @@ -167,6 +171,12 @@ time_t set; /* time ban was set */ }; +struct exemptNode { + char exempt[NICKLEN + USERLEN + HOSTLEN + 3]; /* 1 for '\0', 1 for ! and 1 for @ = 3 */ + char who[NICKLEN + 1]; /* who set exempt */ + time_t set; /* time exempt was set */ +}; + struct modeNode { struct chanNode *channel; struct userNode *user; @@ -236,7 +246,7 @@ typedef void (*del_channel_func_t) (struct chanNode *chan); void reg_del_channel_func(del_channel_func_t handler); -struct chanNode* AddChannel(const char *name, time_t time_, const char *modes, char *banlist); +struct chanNode* AddChannel(const char *name, time_t time_, const char *modes, char *banlist, char *exemptlist); void LockChannel(struct chanNode *channel); void UnlockChannel(struct chanNode *channel); @@ -253,6 +263,7 @@ void ChannelUserKicked(struct userNode* kicker, struct userNode* victim, struct chanNode* channel); int ChannelBanExists(struct chanNode *channel, const char *ban); +int ChannelExemptExists(struct chanNode *channel, const char *exempt); typedef int (*topic_func_t)(struct userNode *who, struct chanNode *chan, const char *old_topic); void reg_topic_func(topic_func_t handler); Index: srvx2/src/opserv.c diff -u srvx2/src/opserv.c:1.3 srvx2/src/opserv.c:1.4 --- srvx2/src/opserv.c:1.3 Thu Aug 19 15:09:58 2004 +++ srvx2/src/opserv.c Mon Aug 23 08:39:18 2004 @@ -249,6 +249,8 @@ { "OSMSG_CHANINFO_TOPIC_UNKNOWN", "Topic: (none / not gathered)" }, { "OSMSG_CHANINFO_BAN_COUNT", "Bans (%d):" }, { "OSMSG_CHANINFO_BAN", "%%s by %%s (%a %b %d %H:%M:%S %Y)" }, + { "OSMSG_CHANINFO_EXEMPT_COUNT", "Exempts (%d):" }, + { "OSMSG_CHANINFO_EXEMPT", "%%s by %%s (%a %b %d %H:%M:%S %Y)" }, { "OSMSG_CHANINFO_MANY_USERS", "%d users (\"/msg $S %s %s users\" for the list)" }, { "OSMSG_CHANINFO_USER_COUNT", "Users (%d):" }, { "OSMSG_CSEARCH_CHANNEL_INFO", "%s [%d users] %s %s" }, @@ -425,6 +427,7 @@ char buffer[MAXLEN]; const char *fmt; struct banNode *ban; + struct exemptNode *exempt; struct modeNode *moden; unsigned int n; @@ -454,6 +457,15 @@ send_message_type(4, user, cmd->parent->bot, buffer, ban->ban, ban->who); } } + if (channel->exemptlist.used) { + reply("OSMSG_CHANINFO_EXEMPT_COUNT", channel->exemptlist.used); + fmt = user_find_message(user, "OSMSG_CHANINFO_EXEMPT"); + for (n = 0; n < channel->exemptlist.used; n++) { + exempt = channel->exemptlist.list[n]; + strftime(buffer, sizeof(buffer), fmt, localtime(&exempt->set)); + send_message_type(4, user, cmd->parent->bot, buffer, exempt->exempt, exempt->who); + } + } if ((argc < 2) && (channel->members.used >= 50)) { /* early out unless they ask for users */ reply("OSMSG_CHANINFO_MANY_USERS", channel->members.used, argv[0], channel->name); @@ -972,7 +984,7 @@ reply("MSG_NOT_CHANNEL_NAME"); return 0; } else if (!(channel = GetChannel(argv[1]))) { - channel = AddChannel(argv[1], now, NULL, NULL); + channel = AddChannel(argv[1], now, NULL, NULL, NULL); AddChannelUser(bot, channel)->modes |= MODE_CHANOP; } else if (GetUserMode(channel, bot)) { reply("OSMSG_ALREADY_JOINED", channel->name); @@ -2367,7 +2379,7 @@ channel = GetChannel(argv[3]); if (!irccasecmp(argv[1], "JOIN")) { if (!channel - && !(channel = AddChannel(argv[3], now, NULL, NULL))) { + && !(channel = AddChannel(argv[3], now, NULL, NULL, NULL))) { reply("MSG_CHANNEL_UNKNOWN", argv[3]); return 0; } @@ -3113,7 +3125,7 @@ send_message(user, opserv, "MSG_CHANNEL_UNKNOWN", argv[i]); goto fail; } else { - discrim->channel = AddChannel(argv[i]+j, now, NULL, NULL); + discrim->channel = AddChannel(argv[i]+j, now, NULL, NULL, NULL); } } LockChannel(discrim->channel); @@ -4039,7 +4051,7 @@ str2 = database_get_data(conf_node, KEY_DEBUG_CHANNEL_MODES, RECDB_QSTRING); if (!str2) str2 = "+tinms"; - opserv_conf.debug_channel = AddChannel(str, now, str2, NULL); + opserv_conf.debug_channel = AddChannel(str, now, str2, NULL, NULL); AddChannelUser(opserv, opserv_conf.debug_channel)->modes |= MODE_CHANOP; } else { opserv_conf.debug_channel = NULL; @@ -4049,7 +4061,7 @@ str2 = database_get_data(conf_node, KEY_ALERT_CHANNEL_MODES, RECDB_QSTRING); if (!str2) str2 = "+tns"; - opserv_conf.alert_channel = AddChannel(str, now, str2, NULL); + opserv_conf.alert_channel = AddChannel(str, now, str2, NULL, NULL); AddChannelUser(opserv, opserv_conf.alert_channel)->modes |= MODE_CHANOP; } else { opserv_conf.alert_channel = NULL; @@ -4059,7 +4071,7 @@ str2 = database_get_data(conf_node, KEY_STAFF_AUTH_CHANNEL_MODES, RECDB_QSTRING); if (!str2) str2 = "+timns"; - opserv_conf.staff_auth_channel = AddChannel(str, now, str2, NULL); + opserv_conf.staff_auth_channel = AddChannel(str, now, str2, NULL, NULL); AddChannelUser(opserv, opserv_conf.staff_auth_channel)->modes |= MODE_CHANOP; } else { opserv_conf.staff_auth_channel = NULL; Index: srvx2/src/proto-common.c diff -u srvx2/src/proto-common.c:1.3 srvx2/src/proto-common.c:1.4 --- srvx2/src/proto-common.c:1.3 Thu Aug 19 15:09:58 2004 +++ srvx2/src/proto-common.c Mon Aug 23 08:39:19 2004 @@ -552,6 +552,7 @@ mod_chanmode_apply(struct userNode *who, struct chanNode *channel, struct mod_chanmode *change) { struct banNode *bn; + struct exemptNode *en; unsigned int ii, jj; assert(change->argc <= change->alloc_argc); @@ -592,6 +593,36 @@ break; } break; + case MODE_EXEMPT: + /* If any existing exempt is a subset of the new exempt, + * silently remove it. The new exempt is not allowed + * to be more specific than an existing exempt. + */ + for (jj=0; jj<channel->exemptlist.used; ++jj) { + if (match_ircglobs(change->args[ii].hostmask, channel->exemptlist.list[jj]->exempt)) { + exemptList_remove(&channel->exemptlist, channel->exemptlist.list[jj]); + free(channel->exemptlist.list[jj]); + jj--; + } + } + en = calloc(1, sizeof(*en)); + safestrncpy(en->exempt, change->args[ii].hostmask, sizeof(en->exempt)); + if (who) + safestrncpy(en->who, who->nick, sizeof(en->who)); + else + safestrncpy(en->who, "<unknown>", sizeof(en->who)); + en->set = now; + exemptList_append(&channel->exemptlist, en); + break; + case MODE_REMOVE|MODE_EXEMPT: + for (jj=0; jj<channel->exemptlist.used; ++jj) { + if (strcmp(channel->exemptlist.list[jj]->exempt, change->args[ii].hostmask)) + continue; + free(channel->exemptlist.list[jj]); + exemptList_remove(&channel->exemptlist, channel->exemptlist.list[jj]); + break; + } + break; case MODE_CHANOP: case MODE_HALFOP: case MODE_VOICE: Index: srvx2/src/proto-p10.c diff -u srvx2/src/proto-p10.c:1.4 srvx2/src/proto-p10.c:1.5 --- srvx2/src/proto-p10.c:1.4 Thu Aug 19 15:09:58 2004 +++ srvx2/src/proto-p10.c Mon Aug 23 08:39:19 2004 @@ -579,6 +579,7 @@ int pos, base_len, len; struct modeNode *mn; struct banNode *bn; + struct exemptNode *en; long last_mode=-1; unsigned int n; @@ -639,6 +640,33 @@ burst_line[pos++] = ' '; } } + if (chan->exemptlist.used) { + /* dump the exempt */ + if (pos+2+strlen(chan->exemptlist.list[0]->exempt) > 505) { + burst_line[pos-1] = 0; + putsock("%s", burst_line); + pos = base_len; + } else { + burst_line[pos++] = ' '; + } + + burst_line[pos++] = ' '; + burst_line[pos++] = '~'; + burst_line[pos++] = ' '; + base_len = pos; + for (n=0; n<chan->exemptlist.used; n++) { + en = chan->exemptlist.list[n]; + len = strlen(en->exempt); + if (pos+len+1 > 510) { + burst_line[pos-1] = 0; /* -1 to back up over the space or comma */ + putsock("%s", burst_line); + pos = base_len; + } + memcpy(burst_line+pos, en->exempt, len); + pos += len; + burst_line[pos++] = ' '; + } + } /* print the last line */ burst_line[pos] = 0; putsock("%s", burst_line); @@ -944,7 +972,7 @@ return; } - AddChannelUser(cd->user, AddChannel(name, cd->when, NULL, NULL)); + AddChannelUser(cd->user, AddChannel(name, cd->when, NULL, NULL, NULL)); } static CMD_FUNC(cmd_create) @@ -1041,18 +1069,26 @@ static CMD_FUNC(cmd_burst) { extern int rel_age; - char modes[MAXLEN], *members = "", *banlist = NULL; - unsigned int next = 3, res = 1; + char modes[MAXLEN], *members = ""; + static char exemptlist[MAXLEN], banlist[MAXLEN]; + unsigned int next = 3; + unsigned int res = 1; + int ctype = 0, echeck = 0, bcheck = 0; struct chanNode *cNode; struct userNode *un; struct modeNode *mNode; long mode; char *user, *end, sep; time_t in_timestamp; + char* parm = NULL; if (argc < 3) return 0; modes[0] = 0; + + exemptlist[0] = 0; + banlist[0] = 0; + while (next < argc) { switch (argv[next][0]) { case '+': { @@ -1066,9 +1102,52 @@ next += n_modes; break; } - case '%': banlist = argv[next++]+1; break; - default: members = argv[next++]; break; + case '%': { + for(parm = mysep(&argv[next], " "); /* parm = first param */ + parm; /* While param is not null */ + parm = mysep(&argv[next], " ") /* parm = next param */ + ) + { + switch (parm[0]) { + case '%': { + ctype = 1; + break; + } + case '~': { + ctype = 2; + break; + } + default: { + break; + } + } + if (ctype == 1) { + if (bcheck == 0) { + /* strip % char off start of very first ban */ + strncat(banlist, strtok(parm, "%"), sizeof(banlist) - 1 - strlen(banlist)); + strncat(banlist, " ", sizeof(banlist) - 1 - strlen(banlist)); + bcheck = 1; + } else { + strncat(banlist, parm, sizeof(banlist) - 1 - strlen(banlist)); + strncat(banlist, " ", sizeof(banlist) - 1 - strlen(banlist)); + } + } else if (ctype == 2) { + if (echeck == 0) { + echeck = 1; + } else { + strncat(exemptlist, parm, sizeof(exemptlist) - 1 - strlen(exemptlist)); + strncat(exemptlist, " ", sizeof(exemptlist) - 1 - strlen(exemptlist)); + } + } + } + next++; + break; + } + default: { + members = argv[next++]; + break; } + } } @@ -1078,9 +1157,10 @@ dict_remove(unbursted_channels, cNode->name); irc_burst(cNode); } - cNode = AddChannel(argv[1], in_timestamp, modes, banlist); /* Burst channel members in now. */ + cNode = AddChannel(argv[1], in_timestamp, modes, banlist, exemptlist); + for (user = members, sep = *members, mode = 0; sep; user = end) { for (end = user + 3; isalnum(*end) || *end == '[' || *end == ']'; end++) ; sep = *end++; end[-1] = 0; @@ -2174,6 +2254,16 @@ change->args[ch_arg].mode |= MODE_REMOVE; change->args[ch_arg++].hostmask = modes[in_arg++]; break; + case 'e': + if (!(flags & MCP_ALLOW_OVB)) + goto error; + if (in_arg >= argc) + goto error; + change->args[ch_arg].mode = MODE_EXEMPT; + if (!add) + change->args[ch_arg].mode |= MODE_REMOVE; + change->args[ch_arg++].hostmask = modes[in_arg++]; + break; case 'o': case 'h': case 'v': { struct userNode *victim; @@ -2308,6 +2398,9 @@ case MODE_BAN: mod_chanmode_append(&chbuf, 'b', change->args[arg].hostmask); break; + case MODE_EXEMPT: + mod_chanmode_append(&chbuf, 'e', change->args[arg].hostmask); + break; default: if (change->args[arg].mode & MODE_CHANOP) mod_chanmode_append(&chbuf, 'o', change->args[arg].member->user->numeric); @@ -2360,6 +2453,9 @@ case MODE_BAN: mod_chanmode_append(&chbuf, 'b', change->args[arg].hostmask); break; + case MODE_EXEMPT: + mod_chanmode_append(&chbuf, 'e', change->args[arg].hostmask); + break; default: if (change->args[arg].mode & MODE_CHANOP) mod_chanmode_append(&chbuf, 'o', change->args[arg].member->user->numeric); @@ -2473,6 +2569,7 @@ channel->limit = 0; break; case 'b': remove |= MODE_BAN; break; + case 'e': remove |= MODE_EXEMPT; break; case 'D': remove |= MODE_DELAYJOINS; break; case 'r': remove |= MODE_REGONLY; break; case 'c': remove |= MODE_NOCOLORS; @@ -2500,6 +2597,14 @@ channel->banlist.used = 0; } + /* If removing exempts, kill 'em all. */ + if ((remove & MODE_EXEMPT) && channel->exemptlist.used) { + unsigned int i; + for (i=0; i<channel->exemptlist.used; i++) + free(channel->exemptlist.list[i]); + channel->exemptlist.used = 0; + } + /* Remove member modes. */ if ((remove & (MODE_CHANOP | MODE_HALFOP | MODE_VOICE)) && channel->members.used) { int mask = ~(remove & (MODE_CHANOP | MODE_HALFOP | MODE_VOICE)); Index: srvx2/src/tools.c diff -u srvx2/src/tools.c:1.2 srvx2/src/tools.c:1.3 --- srvx2/src/tools.c:1.2 Thu Jun 10 13:14:33 2004 +++ srvx2/src/tools.c Mon Aug 23 08:39:19 2004 @@ -854,3 +854,26 @@ free(str_tab.list[ii]); free(str_tab.list); } + +/* mysep() is my answer to the strtok/strsep + * issue. strsep is nice but doesn't skip + * multiple dilimiters, which can really + * offset tokens and cause huge corruption + * so this function will use strsep but + * act like strtok in that sence. + */ +char *mysep(char **sepstr, char *delim) +{ + static char *retstr; + + if(!*sepstr || !**sepstr) + return(NULL); + + do + { + retstr = strsep(sepstr, delim); + }while (retstr && !(*retstr)); + + return(retstr); +} + ----------------------- End of diff ----------------------- |