member->user = who;
member->channel = chptr;
member->status = flags;
- member->oplevel = oplevel;
+ SetOpLevel(member, oplevel);
member->next_member = chptr->members;
if (member->next_member)
assert(0 != member);
/* Discourage using the Apass to get op. They should use the upass. */
- if (IsChannelManager(member) && *member->channel->mode.upass)
+ if (IsChannelManager(member) && member->channel->mode.apass[0])
return 0;
if (IsVoicedOrOpped(member))
return 1;
+
/*
* If it's moderated, and you aren't a privileged user, you can't
- * speak.
+ * speak.
*/
if (member->channel->mode.mode & MODE_MODERATED)
return 0;
}
}
+/** Helper function to clean key-like parameters. */
+static void
+clean_key(char *s)
+{
+ int t_len = KEYLEN;
+
+ while (*s > ' ' && *s != ':' && *s != ',' && t_len--)
+ s++;
+ *s = '\0';
+}
+
/*
* Helper function to convert keys
*/
static void
mode_parse_key(struct ParseState *state, int *flag_p)
{
- char *t_str, *s;
- int t_len;
+ char *t_str;
if (MyUser(state->sptr) && state->max_args <= 0) /* drop if too many args */
return;
return;
state->done |= DONE_KEY;
- t_len = KEYLEN;
-
/* clean up the key string */
- s = t_str;
- while (*s > ' ' && *s != ':' && *s != ',' && t_len--)
- s++;
- *s = '\0';
-
- if (!*t_str) { /* warn if empty */
+ clean_key(t_str);
+ if (!*t_str || *t_str == ':') { /* warn if empty */
if (MyUser(state->sptr))
need_more_params(state->sptr, state->dir == MODE_ADD ? "MODE +k" :
"MODE -k");
static void
mode_parse_upass(struct ParseState *state, int *flag_p)
{
- char *t_str, *s;
- int t_len;
+ char *t_str;
if (MyUser(state->sptr) && state->max_args <= 0) /* drop if too many args */
return;
if (*state->chptr->mode.apass) {
send_reply(state->sptr, ERR_NOTMANAGER, state->chptr->chname,
state->chptr->chname);
- } else if (TStime() - state->chptr->creationtime >= 171000) {
- send_reply(state->sptr, ERR_NOMANAGER_LONG, state->chptr->chname);
} else {
- send_reply(state->sptr, ERR_NOMANAGER_SHORT, state->chptr->chname);
+ send_reply(state->sptr, ERR_NOMANAGER, state->chptr->chname);
}
return;
}
return;
state->done |= DONE_UPASS;
- t_len = PASSLEN + 1;
-
/* clean up the upass string */
- s = t_str;
- while (*++s > ' ' && *s != ':' && --t_len)
- ;
- *s = '\0';
-
- if (!*t_str) { /* warn if empty */
+ clean_key(t_str);
+ if (!*t_str || *t_str == ':') { /* warn if empty */
if (MyUser(state->sptr))
need_more_params(state->sptr, state->dir == MODE_ADD ? "MODE +U" :
"MODE -U");
mode_parse_apass(struct ParseState *state, int *flag_p)
{
struct Membership *memb;
- char *t_str, *s;
- int t_len;
+ char *t_str;
if (MyUser(state->sptr) && state->max_args <= 0) /* drop if too many args */
return;
}
/* Don't allow to change the Apass if the channel is older than 48 hours. */
- if (TStime() - state->chptr->creationtime >= 172800 && !IsAnOper(state->sptr)) {
+ if (MyUser(state->sptr)
+ && TStime() - state->chptr->creationtime >= 172800
+ && !IsAnOper(state->sptr)) {
send_reply(state->sptr, ERR_CHANSECURED, state->chptr->chname);
return;
}
if (*state->chptr->mode.apass) {
send_reply(state->sptr, ERR_NOTMANAGER, state->chptr->chname,
state->chptr->chname);
- } else if (TStime() - state->chptr->creationtime >= 171000) {
- send_reply(state->sptr, ERR_NOMANAGER_LONG, state->chptr->chname);
} else {
- send_reply(state->sptr, ERR_NOMANAGER_SHORT, state->chptr->chname);
+ send_reply(state->sptr, ERR_NOMANAGER, state->chptr->chname);
}
return;
}
return;
state->done |= DONE_APASS;
- t_len = PASSLEN + 1;
-
/* clean up the apass string */
- s = t_str;
- while (*++s > ' ' && *s != ':' && --t_len)
- ;
- *s = '\0';
-
- if (!*t_str) { /* warn if empty */
+ clean_key(t_str);
+ if (!*t_str || *t_str == ':') { /* warn if empty */
if (MyUser(state->sptr))
need_more_params(state->sptr, state->dir == MODE_ADD ? "MODE +A" :
"MODE -A");
/* Revert everyone to MAXOPLEVEL. */
for (memb = state->chptr->members; memb; memb = memb->next_member) {
if (memb->status & MODE_CHANOP)
- memb->oplevel = MAXOPLEVEL;
+ SetOpLevel(memb, MAXOPLEVEL);
}
}
}
newban->flags = ((state->dir == MODE_ADD) ? BAN_ADD : BAN_DEL)
| (*flag_p == MODE_BAN ? 0 : BAN_EXCEPTION);
set_ban_mask(newban, collapse(pretty_mask(t_str)));
- ircd_strncpy(newban->who, cli_name(state->sptr), HOSTLEN);
+ ircd_strncpy(newban->who, IsUser(state->sptr) ? cli_name(state->sptr) : "*", NICKLEN);
newban->when = TStime();
apply_ban(&state->chptr->banlist, newban, 0);
}
/* set op-level of member being opped */
if ((state->cli_change[i].flag & (MODE_ADD | MODE_CHANOP)) ==
(MODE_ADD | MODE_CHANOP)) {
- /* If being opped by an outsider, get oplevel 0 for an apass
+ /* If being opped by an outsider, get oplevel 1 for an apass
* channel, else MAXOPLEVEL.
* Otherwise, if not an apass channel, or state->member has
* MAXOPLEVEL, get oplevel MAXOPLEVEL.
* Otherwise, get state->member's oplevel+1.
*/
if (!state->member)
- SetOpLevel(member, state->chptr->mode.apass[0] ? 0 : MAXOPLEVEL);
+ SetOpLevel(member, state->chptr->mode.apass[0] ? 1 : MAXOPLEVEL);
else if (!state->chptr->mode.apass[0] || OpLevel(state->member) == MAXOPLEVEL)
SetOpLevel(member, MAXOPLEVEL);
else
break;
case 'A': /* deal with Admin passes */
- if (feature_bool(FEAT_OPLEVELS))
+ if (IsServer(cptr) || feature_bool(FEAT_OPLEVELS))
mode_parse_apass(&state, flag_p);
break;
case 'U': /* deal with user passes */
- if (feature_bool(FEAT_OPLEVELS))
+ if (IsServer(cptr) || feature_bool(FEAT_OPLEVELS))
mode_parse_upass(&state, flag_p);
break;
/* send notification to all servers */
if (jbuf->jb_type != JOINBUF_TYPE_CREATE && !is_local)
{
- if (flags & CHFL_CHANOP)
+ if (flags & CHFL_CHANOP) {
+ assert(oplevel == 0 || oplevel == 1);
sendcmdto_serv_butone(jbuf->jb_source, CMD_JOIN, jbuf->jb_connect,
"%u:%H %Tu", oplevel, chan, chan->creationtime);
- else
+ } else
sendcmdto_serv_butone(jbuf->jb_source, CMD_JOIN, jbuf->jb_connect,
"%H %Tu", chan, chan->creationtime);
}
/* send an op, too, if needed */
if (flags & CHFL_CHANOP && (oplevel < MAXOPLEVEL || !MyUser(jbuf->jb_source)))
- sendcmdto_channel_butserv_butone((chan->mode.apass[0] ? &me : jbuf->jb_source),
+ sendcmdto_channel_butserv_butone((chan->mode.apass[0] ? &his : jbuf->jb_source),
CMD_MODE, chan, NULL, 0, "%H +o %C",
chan, jbuf->jb_source);
} else if (MyUser(jbuf->jb_source))