assert(0 == user->channel);
MyFree(user);
+ assert(userCount>0);
--userCount;
}
}
Count_unknownbecomesclient(sptr, UserStats);
+ /*
+ * Set user's initial modes
+ */
+ tmpstr = (char*)client_get_default_umode(sptr);
+ if (tmpstr) {
+ char *umodev[] = { NULL, NULL, NULL, NULL };
+ umodev[2] = tmpstr;
+ set_user_mode(cptr, sptr, 3, umodev, ALLOWMODES_ANY);
+ }
+
SetUser(sptr);
cli_handler(sptr) = CLIENT_HANDLER;
SetLocalNumNick(sptr);
cli_info(sptr), NumNick(cptr) /* two %s's */);
IPcheck_connect_succeeded(sptr);
- /*
- * Set user's initial modes
- */
- tmpstr = (char*)client_get_default_umode(sptr);
- if (tmpstr) for (; *tmpstr; ++tmpstr) {
- switch (*tmpstr) {
- case 's':
- if (!feature_bool(FEAT_HIS_SNOTICES_OPER_ONLY)) {
- SetServNotice(sptr);
- set_snomask(sptr, SNO_DEFAULT, SNO_SET);
- }
- break;
- case 'w':
- if (!feature_bool(FEAT_WALLOPS_OPER_ONLY))
- SetWallops(sptr);
- break;
- case 'i':
- SetInvisible(sptr);
- break;
- case 'd':
- SetDeaf(sptr);
- break;
- case 'g':
- if (!feature_bool(FEAT_HIS_DEBUG_OPER_ONLY))
- SetDebug(sptr);
- break;
- }
- }
}
else {
struct Client *acptr = user->server;
- Count_newremoteclient(UserStats, acptr);
-
if (cli_from(acptr) != cli_from(sptr))
{
sendcmdto_one(&me, CMD_KILL, cptr, "%C :%s (%s != %s[%s])",
SetUser(sptr);
}
+ /* If they get both +x and an account during registration, hide
+ * their hostmask here. Calling hide_hostmask() from IAuth's
+ * account assignment causes a numeric reply during registration.
+ */
+ if (HasHiddenHost(sptr))
+ hide_hostmask(sptr, FLAG_HIDDENHOST);
if (IsInvisible(sptr))
++UserStats.inv_clients;
if (IsOper(sptr))
FlagSet(&flags, FLAG_ACCOUNT);
else
FlagClr(&flags, FLAG_ACCOUNT);
+ client_set_privs(sptr, NULL);
send_umode(cptr, sptr, &flags, ALL_UMODES);
if ((cli_snomask(sptr) != SNO_DEFAULT) && HasFlag(sptr, FLAG_SERVNOTICE))
send_reply(sptr, RPL_SNOMASK, cli_snomask(sptr), cli_snomask(sptr));
const char* nick, int parc, char* parv[])
{
if (IsServer(sptr)) {
- int i;
- const char* account = 0;
- const char* p;
/*
* A server introducing a new client, change source
cli_hopcount(new_client) = atoi(parv[2]);
cli_lastnick(new_client) = atoi(parv[3]);
- if (Protocol(cptr) > 9 && parc > 7 && *parv[6] == '+')
- {
- for (p = parv[6] + 1; *p; p++)
- {
- for (i = 0; i < USERMODELIST_SIZE; ++i)
- {
- if (userModeList[i].c == *p)
- {
- SetFlag(new_client, userModeList[i].flag);
- if (userModeList[i].flag == FLAG_ACCOUNT)
- account = parv[7];
- break;
- }
- }
- }
- }
- client_set_privs(new_client, NULL); /* set privs on user */
+
/*
* Set new nick name.
*/
ircd_strncpy(cli_user(new_client)->host, parv[5], HOSTLEN);
ircd_strncpy(cli_user(new_client)->realhost, parv[5], HOSTLEN);
ircd_strncpy(cli_info(new_client), parv[parc - 1], REALLEN);
- if (account) {
- int len = ACCOUNTLEN;
- if ((p = strchr(account, ':'))) {
- len = (p++) - account;
- cli_user(new_client)->acc_create = atoi(p);
- Debug((DEBUG_DEBUG, "Received timestamped account in user mode; "
- "account \"%s\", timestamp %Tu", account,
- cli_user(new_client)->acc_create));
- }
- ircd_strncpy(cli_user(new_client)->account, account, len);
+
+ Count_newremoteclient(UserStats, sptr);
+
+ if (parc > 7 && *parv[6] == '+') {
+ /* (parc-4) -3 for the ip, numeric nick, realname */
+ set_user_mode(cptr, new_client, parc-7, parv+4, ALLOWMODES_ANY);
}
- if (HasHiddenHost(new_client))
- ircd_snprintf(0, cli_user(new_client)->host, HOSTLEN, "%s.%s",
- cli_user(new_client)->account,
- feature_str(FEAT_HIDDEN_HOST));
return register_user(cptr, new_client);
}
assert(cli_local(sptr));
targets = cli_targets(sptr);
- /* If user is invited to channel, give him/her a free target */
- if (IsChannelName(name) && IsInvited(sptr, target))
- return 0;
-
/*
* Same target as last time?
*/
*/
if (!created) {
if (CurrentTime < cli_nexttarget(sptr)) {
+ /* If user is invited to channel, give him/her a free target */
+ if (IsChannelName(name) && IsInvited(sptr, target))
+ return 0;
+
if (cli_nexttarget(sptr) - CurrentTime < TARGET_DELAY + 8) {
/*
* No server flooding
if (is_silenced(source, dest))
return 0;
- if (cli_user(dest)->away)
- send_reply(source, RPL_AWAY, cli_name(dest), cli_user(dest)->away);
if (is_notice)
sendcmdto_one(source, CMD_NOTICE, dest, "%C :%s", dest, text);
else
+ {
+ if (cli_user(dest)->away)
+ send_reply(source, RPL_AWAY, cli_name(dest), cli_user(dest)->away);
sendcmdto_one(source, CMD_PRIVATE, dest, "%C :%s", dest, text);
+ }
return 0;
}
* @param[in] sptr Client who sent the mode change message.
* @param[in] parc Number of parameters in \a parv.
* @param[in] parv Parameters to MODE.
+ * @param[in] allow_modes ALLOWMODES_ANY for any mode, ALLOWMODES_DEFAULT for
+ * only permitting legitimate default user modes.
* @return Zero.
*/
-int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
+int set_user_mode(struct Client *cptr, struct Client *sptr, int parc,
+ char *parv[], int allow_modes)
{
char** p;
char* m;
char buf[BUFSIZE];
int prop = 0;
int do_host_hiding = 0;
+ char* account = NULL;
what = MODE_ADD;
/*
* parse mode change string(s)
*/
- for (p = &parv[2]; *p; p++) { /* p is changed in loop too */
+ for (p = &parv[2]; *p && p<&parv[parc]; p++) { /* p is changed in loop too */
for (m = *p; *m; m++) {
switch (*m) {
case '+':
if (what == MODE_ADD)
do_host_hiding = 1;
break;
+ case 'r':
+ if (*(p + 1) && (what == MODE_ADD)) {
+ account = *(++p);
+ SetAccount(sptr);
+ }
+ /* There is no -r */
+ break;
default:
send_reply(sptr, ERR_UMODEUNKNOWNFLAG, *m);
break;
ClearOper(sptr);
if (!FlagHas(&setflags, FLAG_LOCOP) && IsLocOp(sptr))
ClearLocOp(sptr);
+ if (!FlagHas(&setflags, FLAG_ACCOUNT) && IsAccount(sptr))
+ ClrFlag(sptr, FLAG_ACCOUNT);
/*
* new umode; servers can set it, local users cannot;
* prevents users from /kick'ing or /mode -o'ing
{
if ((FlagHas(&setflags, FLAG_OPER) || FlagHas(&setflags, FLAG_LOCOP)) &&
!IsAnOper(sptr))
+ {
det_confs_butmask(sptr, CONF_CLIENT & ~CONF_OPERATOR);
+ client_set_privs(sptr, NULL);
+ }
if (SendServNotice(sptr))
{
* Compare new flags with old flags and send string which
* will cause servers to update correctly.
*/
- if (!FlagHas(&setflags, FLAG_OPER) && IsOper(sptr))
- {
- /* user now oper */
- ++UserStats.opers;
- client_set_privs(sptr, NULL); /* may set propagate privilege */
- }
- /* remember propagate privilege setting */
- if (HasPriv(sptr, PRIV_PROPAGATE))
- prop = 1;
- if (FlagHas(&setflags, FLAG_OPER) && !IsOper(sptr))
- {
- /* user no longer oper */
- --UserStats.opers;
- client_set_privs(sptr, NULL); /* will clear propagate privilege */
+ if (!FlagHas(&setflags, FLAG_ACCOUNT) && IsAccount(sptr)) {
+ int len = ACCOUNTLEN;
+ char *ts;
+ if ((ts = strchr(account, ':'))) {
+ len = (ts++) - account;
+ cli_user(sptr)->acc_create = atoi(ts);
+ Debug((DEBUG_DEBUG, "Received timestamped account in user mode; "
+ "account \"%s\", timestamp %Tu", account,
+ cli_user(sptr)->acc_create));
+ }
+ ircd_strncpy(cli_user(sptr)->account, account, len);
}
- if (FlagHas(&setflags, FLAG_INVISIBLE) && !IsInvisible(sptr))
- --UserStats.inv_clients;
- if (!FlagHas(&setflags, FLAG_INVISIBLE) && IsInvisible(sptr))
- ++UserStats.inv_clients;
- if (!FlagHas(&setflags, FLAG_HIDDENHOST) && do_host_hiding)
+ if (!FlagHas(&setflags, FLAG_HIDDENHOST) && do_host_hiding && allow_modes != ALLOWMODES_DEFAULT)
hide_hostmask(sptr, FLAG_HIDDENHOST);
- send_umode_out(cptr, sptr, &setflags, prop);
+
+ if (IsRegistered(sptr)) {
+ if (!FlagHas(&setflags, FLAG_OPER) && IsOper(sptr)) {
+ /* user now oper */
+ ++UserStats.opers;
+ client_set_privs(sptr, NULL); /* may set propagate privilege */
+ }
+ /* remember propagate privilege setting */
+ if (HasPriv(sptr, PRIV_PROPAGATE)) {
+ prop = 1;
+ }
+ if (FlagHas(&setflags, FLAG_OPER) && !IsOper(sptr)) {
+ /* user no longer oper */
+ assert(UserStats.opers > 0);
+ --UserStats.opers;
+ client_set_privs(sptr, NULL); /* will clear propagate privilege */
+ }
+ if (FlagHas(&setflags, FLAG_INVISIBLE) && !IsInvisible(sptr)) {
+ assert(UserStats.inv_clients > 0);
+ --UserStats.inv_clients;
+ }
+ if (!FlagHas(&setflags, FLAG_INVISIBLE) && IsInvisible(sptr)) {
+ ++UserStats.inv_clients;
+ }
+ assert(UserStats.opers <= UserStats.clients + UserStats.unknowns);
+ assert(UserStats.inv_clients <= UserStats.clients + UserStats.unknowns);
+ send_umode_out(cptr, sptr, &setflags, prop);
+ }
return 0;
}
return 0; /* convenience return, if it's ever needed */
}
+
+/* vim: shiftwidth=2
+ */