+2000-04-09 Perry Lorier <Isomer@coders.net>
+ * include/numeric.h: Cleaned up numerics, added which ones are
+ in use by other networks and what they are in use for.
+
+ * ircd/channel.c: cleaned can_join(), allow anyone through anything
+ if /invited, simplified the function. Opers overusing OPEROVERRIDE
+ will get a message explaining to them not to cheat.
+
+ * ircd/m_join.c: cleaned up the various join functions, should be
+ a lot more efficient. Still needs work. Now assumes that s<->s
+ won't send it a JOIN 0. Service coders - note this and tread with
+ care.
+
+ * ircd/m_stats.c: added Gte-'s stats doc patch.
+
+ * ircd/m_version.c: /version now returns the 005 numeric as well.
+ as requested by Liandrin.
+
+
2000-04-07 Kevin L. Mitchell <klmitch@mit.edu>
* ircd/m_clearmode.c: add include for support.h for write_log()
#
# ChangeLog for ircu2.10.11
#
-# $Id: ChangeLog,v 1.64 2000-04-07 16:46:28 kev Exp $
+# $Id: ChangeLog,v 1.65 2000-04-09 11:53:12 isomer Exp $
#
# Insert new changes at beginning of the change list.
#
#define ERR_SILELISTFULL 511 /* Undernet extension */
/* ERR_NOTIFYFULL 512 aircd */
+/* ERR_TOOMANYWATCH 512 Numeric List: Dalnet */
#define ERR_NOSUCHGLINE 512 /* Undernet extension */
#define ERR_BADPING 513 /* Undernet extension */
+/* ERR_NEEDPONG 512 Numeric List: Dalnet */
#define ERR_NOSUCHJUPE 514 /* Undernet extension - jupe -Kev */
#define ERR_BADEXPIRE 515 /* Undernet extension - jupe -Kev */
-#define ERR_INVALID_ERROR 516
+#define ERR_DONTCHEAT 516 /* Undernet extension */
+#define ERR_LASTERROR 517
#endif /* INCLUDED_numeric_h */
{
struct SLink *lp;
int overrideJoin = 0;
+
+ /*
+ * Now a banned user CAN join if invited -- Nemesi
+ * Now a user CAN escape channel limit if invited -- bfriendly
+ * Now a user CAN escape anything if invited -- Isomer
+ */
+ for (lp = sptr->user->invited; lp; lp = lp->next)
+ if (lp->value.chptr == chptr)
+ return 0;
+
#ifdef OPER_WALK_THROUGH_LMODES
/* An oper can force a join on a local channel using "OVERRIDE" as the key.
a HACK(4) notice will be sent if he would not have been supposed
overrideJoin = MAGIC_OPER_OVERRIDE;
}
#endif
- /*
- * Now a banned user CAN join if invited -- Nemesi
- * Now a user CAN escape channel limit if invited -- bfriendly
- */
- if ((chptr->mode.mode & MODE_INVITEONLY) || (is_banned(sptr, chptr, NULL)
- || (chptr->mode.limit && chptr->users >= chptr->mode.limit)))
- {
- for (lp = sptr->user->invited; lp; lp = lp->next)
- if (lp->value.chptr == chptr)
- break;
- if (!lp)
- {
- if (chptr->mode.limit && chptr->users >= chptr->mode.limit)
- return (overrideJoin + ERR_CHANNELISFULL);
- /*
- * This can return an "Invite only" msg instead of the "You are banned"
- * if _both_ conditions are true, but who can say what is more
- * appropriate ? checking again IsBanned would be _SO_ cpu-xpensive !
- */
- return overrideJoin + ((chptr->mode.mode & MODE_INVITEONLY) ?
- ERR_INVITEONLYCHAN : ERR_BANNEDFROMCHAN);
- }
- }
+ if (chptr->mode.mode & MODE_INVITEONLY)
+ return overrideJoin + ERR_INVITEONLYCHAN;
+
+ if (chptr->mode.limit && chptr->users >= chptr->mode.limit)
+ return overrideJoin + ERR_CHANNELISFULL;
+
+ if (is_banned(sptr, chptr, NULL))
+ return overrideJoin + ERR_BANNEDFROMCHAN;
+
/*
* now using compall (above) to test against a whole key ring -Kev
*/
if (*chptr->mode.key && (EmptyString(key) || compall(chptr->mode.key, key)))
- return overrideJoin + (ERR_BADCHANNELKEY);
+ return overrideJoin + ERR_BADCHANNELKEY;
+ if (overrideJoin)
+ return ERR_DONTCHEAT;
+
return 0;
}
char* p = NULL;
char* bufptr;
- /*
- * Doesn't make sense having a server join a channel, and besides
- * the server cores.
- */
- if (IsServer(sptr))
- return 0;
if (parc < 2 || *parv[1] == '\0')
return need_more_params(sptr, "JOIN");
if (parc < 2 || *parv[1] == '\0')
return need_more_params(sptr, "JOIN");
- for (p = parv[1]; *p; p++) /* find the last "JOIN 0" in the line -Kev */
- if (*p == '0'
- && (*(p + 1) == ',' || *(p + 1) == '\0' || !IsChannelChar(*(p + 1))))
- {
- /* If it's a single "0", remember the place; we will start parsing
- the channels after the last 0 in the line -Kev */
- parv[1] = p;
- if (!*(p + 1))
- break;
- p++;
- }
- else
- { /* Step through to the next comma or until the
- end of the line, in an attempt to save CPU
- -Kev */
- while (*p != ',' && *p != '\0')
- p++;
- if (!*p)
- break;
- }
-
keysOrTS = parv[2]; /* Remember where our keys are or the TS is;
parv[2] needs to be NULL for the call to
m_names below -Kev */
for (name = ircd_strtok(&p, parv[1], ","); name; name = ircd_strtok(&p, NULL, ","))
{
size_t len;
- if (MyConnect(sptr))
- clean_channelname(name);
- else if (IsLocalChannel(name))
+ if (IsLocalChannel(name))
continue;
- if (*name == '0' && *(name + 1) == '\0')
+
+ if (!IsChannelName(name))
{
- /* Remove the user from all his channels -Kev */
- while ((member = sptr->user->channel))
- {
- chptr = member->channel;
- if (!IsZombie(member))
- sendto_channel_butserv(chptr, sptr, PartFmt2,
- parv[0], chptr->chname, "Left all channels");
- remove_user_from_channel(sptr, chptr);
- }
- /* Just in case */
- *mbuf = *jbuf = '\0';
- mlen = jlen = 0;
+ sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL), me.name, parv[0], name);
+ continue;
}
- else
- { /* not a /join 0, so treat it as
- a /join #channel -Kev */
- if (!IsChannelName(name))
- {
- if (MyUser(sptr))
- sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL), me.name, parv[0], name);
- continue;
- }
-
- if (MyConnect(sptr))
- {
-#ifdef BADCHAN
- if (bad_channel(name) && !IsAnOper(sptr))
- {
- sendto_one(sptr, err_str(ERR_BADCHANNAME), me.name, parv[0], name);
- continue;
- }
-#endif
- /*
- * Local client is first to enter previously nonexistant
- * channel so make them (rightfully) the Channel Operator.
- * This looks kind of ugly because we try to avoid calling the strlen()
- */
- if (ChannelExists(name))
- {
- flags = CHFL_DEOPPED;
- sendcreate = 0;
- }
- else if (strlen(name) > CHANNELLEN)
- {
- *(name + CHANNELLEN) = '\0';
- if (ChannelExists(name))
- {
- flags = CHFL_DEOPPED;
- sendcreate = 0;
- }
- else
- {
- flags = IsModelessChannel(name) ? CHFL_DEOPPED : CHFL_CHANOP;
- sendcreate = 1;
- }
- }
- else
- {
- flags = IsModelessChannel(name) ? CHFL_DEOPPED : CHFL_CHANOP;
- sendcreate = 1;
- }
-#ifdef OPER_NO_CHAN_LIMIT
- /*
- * Opers are allowed to join any number of channels
- */
- if (sptr->user->joined >= MAXCHANNELSPERUSER && !IsAnOper(sptr))
-#else
- if (sptr->user->joined >= MAXCHANNELSPERUSER)
-#endif
- {
- chptr = get_channel(sptr, name, CGT_NO_CREATE);
- sendto_one(sptr, err_str(ERR_TOOMANYCHANNELS),
- me.name, parv[0], chptr ? chptr->chname : name);
- /*
- * Can't return, else he won't get on ANY channels!
- * Break out of the for loop instead. -Kev
- */
- break;
- }
- }
+ chptr = get_channel(sptr, name, CGT_CREATE);
+ if (chptr && (member = find_member_link(chptr, sptr)))
+ {
+ if (!IsZombie(member))
+ continue;
+
+ /* If they are a zombie, make them really part
+ * and rejoin
+ */
+ zombie = 1;
+ flags = member->status & (CHFL_DEOPPED | CHFL_SERVOPOK);
+ remove_user_from_channel(sptr, chptr);
chptr = get_channel(sptr, name, CGT_CREATE);
- if (chptr && (member = find_member_link(chptr, sptr)))
- {
- if (IsZombie(member))
- {
- zombie = 1;
- flags = member->status & (CHFL_DEOPPED | CHFL_SERVOPOK);
- remove_user_from_channel(sptr, chptr);
- chptr = get_channel(sptr, name, CGT_CREATE);
- }
- else
- continue;
- }
- name = chptr->chname;
- if (!chptr->creationtime) /* A remote JOIN created this channel ? */
- chptr->creationtime = MAGIC_REMOTE_JOIN_TS;
- if (parc > 2)
- {
- if (chptr->creationtime == MAGIC_REMOTE_JOIN_TS)
- chptr->creationtime = atoi(keysOrTS);
- else
- parc = 2; /* Don't pass it on */
- }
- if (!zombie)
- {
- if (!MyConnect(sptr))
- flags = CHFL_DEOPPED;
- if (sptr->flags & FLAGS_TS8)
- flags |= CHFL_SERVOPOK;
- }
- if (MyConnect(sptr))
- {
- int created = chptr->users == 0;
- if (check_target_limit(sptr, chptr, chptr->chname, created))
- {
- if (created) /* Did we create the channel? */
- sub1_from_channel(chptr); /* Remove it again! */
- continue;
- }
- if ((i = can_join(sptr, chptr, keysOrTS)))
- {
- sendto_one(sptr, err_str(i), me.name, parv[0], chptr->chname);
- continue;
- }
- }
- /*
- * Complete user entry to the new channel (if any)
- */
- add_user_to_channel(chptr, sptr, flags);
-
- /*
- * Notify all other users on the new channel
- */
- sendto_channel_butserv(chptr, sptr, ":%s JOIN :%s", parv[0], name);
-
- if (MyUser(sptr))
- {
- del_invite(sptr, chptr);
- if (chptr->topic[0] != '\0')
- {
- sendto_one(sptr, rpl_str(RPL_TOPIC), me.name,
- parv[0], name, chptr->topic);
- sendto_one(sptr, rpl_str(RPL_TOPICWHOTIME), me.name, parv[0], name,
- chptr->topic_nick, chptr->topic_time);
- }
- parv[1] = name;
- m_names(cptr, sptr, 2, parv);
- }
+
+ }
+
+ name = chptr->chname;
+
+ if (!chptr->creationtime) /* A remote JOIN created this channel ? */
+ chptr->creationtime = MAGIC_REMOTE_JOIN_TS;
+
+ if (parc > 2)
+ {
+ if (chptr->creationtime == MAGIC_REMOTE_JOIN_TS)
+ chptr->creationtime = atoi(keysOrTS);
+ else
+ parc = 2; /* Don't pass it on */
+ }
+
+ if (!zombie)
+ {
+ if (sptr->flags & FLAGS_TS8)
+ flags |= CHFL_SERVOPOK;
}
+
+ /*
+ * Complete user entry to the new channel (if any)
+ */
+ add_user_to_channel(chptr, sptr, flags);
+
+ /*
+ * Notify all other users on the new channel
+ */
+ sendto_channel_butserv(chptr, sptr, ":%s JOIN :%s", parv[0], name);
/* Select proper buffer; mbuf for creation, jbuf otherwise */
bufptr = (sendcreate == 0) ? jbuf : mbuf;
buflen = (sendcreate == 0) ? &jlen : &mlen;
len = strlen(name);
+
if (*buflen < BUFSIZE - len - 2)
{
if (*bufptr)
sendto_serv_butone(cptr, "%s%s " TOK_CREATE " %s " TIME_T_FMT,
NumNick(sptr), mbuf, TStime());
- if (MyUser(sptr))
- { /* shouldn't ever set TS for remote JOIN's */
- if (*jbuf)
- { /* check for channels that need TS's */
- p = NULL;
- for (name = ircd_strtok(&p, jbuf, ","); name; name = ircd_strtok(&p, NULL, ","))
- {
- chptr = get_channel(sptr, name, CGT_NO_CREATE);
- if (chptr && chptr->mode.mode & MODE_SENDTS)
- { /* send a TS? */
- sendto_serv_butone(cptr, "%s " TOK_MODE " %s + " TIME_T_FMT, NumServ(&me),
- chptr->chname, chptr->creationtime); /* ok, send TS */
- chptr->mode.mode &= ~MODE_SENDTS; /* reset flag */
- }
- }
- }
- }
return 0;
}
#include <stdlib.h>
#include <string.h>
+/*
+ * Help info displayed when user provides no stats parameter. --Gte
+ */
+const char *statsinfo[] = {
+ "The following statistics are available:",
+ "U - Service server & nick jupes information.",
+ "u - Current uptime & highest connection count.",
+ "p - Listening ports.",
+ "i - Connection authorisation lines.",
+ "y - Connection classes.",
+ "c - Remote server connection lines.",
+ "h - Hubs information (Oper only).",
+ "d - Dynamic routing configuration.",
+ "l - Current connections information.",
+ "g - Global bans (G-lines).",
+ "k - Local bans (K-Lines).",
+ "o - Operator information.",
+ "m - Message usage information.",
+ "t - Local connection statistics (Total SND/RCV, etc).",
+ "w - Userload statistics.",
+ "M - Memory allocation & leak monitoring.",
+ "z - Memory/Structure allocation information.",
+ "r - System resource usage (Debug only).",
+ "x - List usage information (Debug only).",
+ 0,
+};
+
/*
* m_stats - generic message handler
*
struct Gline* gline;
struct ConfItem *aconf;
char stat = parc > 1 ? parv[1][0] : '\0';
+ const char **infotext = statsinfo;
int i;
/* m_stats is so obnoxiously full of special cases that the different
break;
default:
stat = '*';
+ while (*infotext) sendto_one(sptr, ":%s NOTICE %s :%s", me.name, parv[0], *infotext++);
break;
}
sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, parv[0], stat);
struct Gline* gline;
struct ConfItem *aconf;
char stat = parc > 1 ? parv[1][0] : '\0';
+ const char **infotext = statsinfo;
int i;
/* m_stats is so obnoxiously full of special cases that the different
break;
default:
stat = '*';
+ while (*infotext) sendto_one(sptr, ":%s NOTICE %s :%s", me.name, parv[0], *infotext++);
break;
}
sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, parv[0], stat);
#include "s_debug.h"
#include "s_user.h"
#include "send.h"
+#include "supported.h"
#include "version.h"
#include <assert.h>
if (hunt_server(0, cptr, sptr, "%s%s " TOK_VERSION " :%s", 1, parc, parv) ==
HUNTED_ISME)
+ {
+ char featurebuf[512];
+
+ sprintf_irc(featurebuf,FEATURES,FEATURESVALUES);
+
sendto_one(sptr, rpl_str(RPL_VERSION),
me.name, parv[0], version, debugmode, me.name, serveropts);
+ sendto_one(sptr, rpl_str(RPL_ISUPPORT),
+ me.name, parv[0], featurebuf);
+ }
return 0;
}
if (hunt_server(0, cptr, sptr, "%s%s " TOK_VERSION " :%s", 1, parc, parv) ==
HUNTED_ISME)
+ {
+ char featurebuf[512];
+
+ sprintf_irc(featurebuf,FEATURES,FEATURESVALUES);
+
sendto_one(sptr, rpl_str(RPL_VERSION),
me.name, parv[0], version, debugmode, me.name, serveropts);
+ sendto_one(sptr, rpl_str(RPL_ISUPPORT),
+ me.name, parv[0], featurebuf);
+ }
return 0;
}
/* 514 */
{ ERR_NOSUCHJUPE, "%s :No such jupe", "514" },
/* 515 */
- { ERR_BADEXPIRE, TIME_T_FMT " :Bad expire time", "515" }
+ { ERR_BADEXPIRE, TIME_T_FMT " :Bad expire time", "515" },
+/* 516 */
+ { ERR_DONTCHEAT, " :Don't Cheat.", 516 }
};
static Numeric numeric_replies[] = {
{
int num = numeric;
assert(ERR_FIRSTERROR < num);
- assert(num < ERR_INVALID_ERROR);
+ assert(num < ERR_LASTERROR);
num -= ERR_FIRSTERROR;
assert(0 != numeric_errors[num].value);