mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-07-03 22:03:13 +02:00
Get rid of Usermode_Table[] and use a linked list called usermodes.
Just like already done for Channelmode_Table[] -> channelmodes.
This commit is contained in:
@@ -94,6 +94,7 @@ extern long set_usermode(const char *umode);
|
||||
extern const char *get_usermode_string(Client *acptr);
|
||||
extern const char *get_usermode_string_r(Client *client, char *buf, size_t buflen);
|
||||
extern const char *get_usermode_string_raw(long umodes);
|
||||
extern const char *get_usermode_string_raw_r(long umodes, char *buf, size_t buflen);
|
||||
extern ConfigFile *config_parse(const char *filename, char *confdata);
|
||||
extern ConfigFile *config_parse_with_offset(const char *filename, char *confdata, unsigned int line_offset);
|
||||
extern void config_error(FORMAT_STRING(const char *format), ...) __attribute__((format(printf,1,2)));
|
||||
|
||||
+10
-8
@@ -109,14 +109,16 @@ typedef enum ModuleObjectType {
|
||||
MOBJ_HISTORY_BACKEND = 18,
|
||||
} ModuleObjectType;
|
||||
|
||||
typedef struct {
|
||||
long mode; /**< Mode mask */
|
||||
char letter; /**< Mode character */
|
||||
int unset_on_deoper; /**< When set to 1 then this user mode will be unset on de-oper */
|
||||
int (*allowed)(Client *client, int what); /**< The 'is this user allowed to set this mode?' routine */
|
||||
char unloaded; /**< Internal flag to indicate module is being unloaded */
|
||||
Module *owner; /**< Module that owns this user mode */
|
||||
} Umode;
|
||||
typedef struct Umode Umode;
|
||||
struct Umode {
|
||||
Umode *prev, *next;
|
||||
long mode; /**< Mode mask */
|
||||
char letter; /**< Mode character */
|
||||
int unset_on_deoper; /**< When set to 1 then this user mode will be unset on de-oper */
|
||||
int (*allowed)(Client *client, int what); /**< The 'is this user allowed to set this mode?' routine */
|
||||
char unloaded; /**< Internal flag to indicate module is being unloaded */
|
||||
Module *owner; /**< Module that owns this user mode */
|
||||
};
|
||||
|
||||
typedef enum ModDataType {
|
||||
MODDATATYPE_LOCAL_VARIABLE = 1,
|
||||
|
||||
+1
-2
@@ -1191,8 +1191,7 @@ struct CommandOverride {
|
||||
OverrideCmdFunc func;
|
||||
};
|
||||
|
||||
extern MODVAR Umode *Usermode_Table;
|
||||
extern MODVAR int Usermode_highest;
|
||||
extern MODVAR Umode *usermodes;
|
||||
extern MODVAR Cmode *channelmodes;
|
||||
|
||||
extern Umode *UmodeAdd(Module *module, char ch, int options, int unset_on_deoper, int (*allowed)(Client *client, int what), long *mode);
|
||||
|
||||
+155
-128
@@ -24,10 +24,9 @@
|
||||
|
||||
char umodestring[UMODETABLESZ+1];
|
||||
|
||||
Umode *Usermode_Table = NULL;
|
||||
int Usermode_highest = 0;
|
||||
/** User modes and their handlers */
|
||||
Umode *usermodes = NULL;
|
||||
|
||||
/* client->umodes (32 bits): 26 used, 6 free */
|
||||
long UMODE_INVISIBLE = 0L; /* makes user invisible */
|
||||
long UMODE_OPER = 0L; /* Operator */
|
||||
long UMODE_REGNICK = 0L; /* Nick set by services as registered */
|
||||
@@ -59,20 +58,11 @@ long SendUmodes; /* All umodes which are sent to other servers (global umodes) *
|
||||
|
||||
/* Forward declarations */
|
||||
int umode_hidle_allow(Client *client, int what);
|
||||
static void unload_usermode_commit(Umode *m);
|
||||
|
||||
void umode_init(void)
|
||||
void umode_init(void)
|
||||
{
|
||||
long val = 1;
|
||||
int i;
|
||||
Usermode_Table = safe_alloc(sizeof(Umode) * UMODETABLESZ);
|
||||
for (i = 0; i < UMODETABLESZ; i++)
|
||||
{
|
||||
Usermode_Table[i].mode = val;
|
||||
val *= 2;
|
||||
}
|
||||
Usermode_highest = 0;
|
||||
|
||||
/* Set up modes */
|
||||
/* Some built-in modes */
|
||||
UmodeAdd(NULL, 'i', UMODE_GLOBAL, 0, umode_allow_all, &UMODE_INVISIBLE);
|
||||
UmodeAdd(NULL, 'o', UMODE_GLOBAL, 1, umode_allow_opers, &UMODE_OPER);
|
||||
UmodeAdd(NULL, 'r', UMODE_GLOBAL, 0, umode_allow_none, &UMODE_REGNICK);
|
||||
@@ -87,16 +77,13 @@ void umode_init(void)
|
||||
|
||||
void make_umodestr(void)
|
||||
{
|
||||
int i;
|
||||
char *m;
|
||||
Umode *um;
|
||||
char *p = umodestring;
|
||||
|
||||
m = umodestring;
|
||||
for (i = 0; i <= Usermode_highest; i++)
|
||||
{
|
||||
if (Usermode_Table[i].letter)
|
||||
*m++ = Usermode_Table[i].letter;
|
||||
}
|
||||
*m = '\0';
|
||||
for (um=usermodes; um; um = um->next)
|
||||
if (um->letter)
|
||||
*p++ = um->letter;
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
static char previous_umodestring[256];
|
||||
@@ -125,101 +112,134 @@ void umodes_check_for_changes(void)
|
||||
strlcpy(previous_umodestring, umodestring, sizeof(previous_umodestring));
|
||||
}
|
||||
|
||||
void usermode_add_sorted(Umode *n)
|
||||
{
|
||||
Umode *m;
|
||||
|
||||
if (usermodes == NULL)
|
||||
{
|
||||
usermodes = n;
|
||||
return;
|
||||
}
|
||||
|
||||
for (m = usermodes; m; m = m->next)
|
||||
{
|
||||
if (m->letter == '\0')
|
||||
abort();
|
||||
if (sort_character_lowercase_before_uppercase(n->letter, m->letter))
|
||||
{
|
||||
/* Insert us before */
|
||||
if (m->prev)
|
||||
m->prev->next = n;
|
||||
else
|
||||
usermodes = n; /* new head */
|
||||
n->prev = m->prev;
|
||||
|
||||
n->next = m;
|
||||
m->prev = n;
|
||||
return;
|
||||
}
|
||||
if (!m->next)
|
||||
{
|
||||
/* Append us at end */
|
||||
m->next = n;
|
||||
n->prev = m;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* UmodeAdd:
|
||||
* Add a usermode with character 'ch', if global is set to 1 the usermode is global
|
||||
* (sent to other servers) otherwise it's a local usermode
|
||||
*/
|
||||
Umode *UmodeAdd(Module *module, char ch, int global, int unset_on_deoper, int (*allowed)(Client *client, int what), long *mode)
|
||||
{
|
||||
short i = 0;
|
||||
short j = 0;
|
||||
short save = -1;
|
||||
while (i < UMODETABLESZ)
|
||||
Umode *um;
|
||||
int existing = 0;
|
||||
|
||||
for (um=usermodes; um; um = um->next)
|
||||
{
|
||||
if (!Usermode_Table[i].letter && save == -1)
|
||||
save = i;
|
||||
else if (Usermode_Table[i].letter == ch)
|
||||
if (um->letter == ch)
|
||||
{
|
||||
if (Usermode_Table[i].unloaded)
|
||||
if (um->unloaded)
|
||||
{
|
||||
save = i;
|
||||
Usermode_Table[i].unloaded = 0;
|
||||
um->unloaded = 0;
|
||||
existing = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (module)
|
||||
module->errorcode = MODERR_EXISTS;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i = save;
|
||||
if (i != UMODETABLESZ)
|
||||
|
||||
if (!um)
|
||||
{
|
||||
Usermode_Table[i].letter = ch;
|
||||
Usermode_Table[i].allowed = allowed;
|
||||
Usermode_Table[i].unset_on_deoper = unset_on_deoper;
|
||||
/* Update usermode table highest */
|
||||
for (j = 0; j < UMODETABLESZ; j++)
|
||||
if (Usermode_Table[i].letter)
|
||||
if (i > Usermode_highest)
|
||||
Usermode_highest = i;
|
||||
make_umodestr();
|
||||
AllUmodes |= Usermode_Table[i].mode;
|
||||
if (global)
|
||||
SendUmodes |= Usermode_Table[i].mode;
|
||||
*mode = Usermode_Table[i].mode;
|
||||
Usermode_Table[i].owner = module;
|
||||
if (module)
|
||||
/* Not found, create */
|
||||
long l, found = 0;
|
||||
for (l = 1; l < INT_MAX/2; l *= 2)
|
||||
{
|
||||
ModuleObject *umodeobj = safe_alloc(sizeof(ModuleObject));
|
||||
umodeobj->object.umode = &(Usermode_Table[i]);
|
||||
umodeobj->type = MOBJ_UMODE;
|
||||
AddListItem(umodeobj, module->objects);
|
||||
module->errorcode = MODERR_NOERROR;
|
||||
found = 0;
|
||||
for (um=usermodes; um; um = um->next)
|
||||
{
|
||||
if (um->mode == l)
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
break;
|
||||
}
|
||||
return &(Usermode_Table[i]);
|
||||
/* If 'found' is still true, then we are out of space */
|
||||
if (found)
|
||||
{
|
||||
unreal_log(ULOG_ERROR, "module", "USER_MODE_OUT_OF_SPACE", NULL,
|
||||
"UmodeAdd: out of space!!!");
|
||||
if (module)
|
||||
module->errorcode = MODERR_NOSPACE;
|
||||
return NULL;
|
||||
}
|
||||
um = safe_alloc(sizeof(Umode));
|
||||
um->letter = ch;
|
||||
um->mode = l;
|
||||
usermode_add_sorted(um);
|
||||
}
|
||||
else
|
||||
|
||||
um->letter = ch;
|
||||
um->allowed = allowed;
|
||||
um->unset_on_deoper = unset_on_deoper;
|
||||
make_umodestr();
|
||||
AllUmodes |= um->mode;
|
||||
if (global)
|
||||
SendUmodes |= um->mode;
|
||||
*mode = um->mode;
|
||||
um->owner = module;
|
||||
if (module)
|
||||
{
|
||||
unreal_log(ULOG_ERROR, "module", "USER_MODE_OUT_OF_SPACE", NULL,
|
||||
"UmodeAdd: out of space!!!");
|
||||
if (module)
|
||||
module->errorcode = MODERR_NOSPACE;
|
||||
return NULL;
|
||||
ModuleObject *umodeobj = safe_alloc(sizeof(ModuleObject));
|
||||
umodeobj->object.umode = um;
|
||||
umodeobj->type = MOBJ_UMODE;
|
||||
AddListItem(umodeobj, module->objects);
|
||||
module->errorcode = MODERR_NOERROR;
|
||||
}
|
||||
return um;
|
||||
}
|
||||
|
||||
|
||||
void UmodeDel(Umode *umode)
|
||||
{
|
||||
if (loop.rehashing)
|
||||
umode->unloaded = 1;
|
||||
else
|
||||
/* Always free the module object */
|
||||
if (umode->owner)
|
||||
{
|
||||
Client *client;
|
||||
list_for_each_entry(client, &client_list, client_node)
|
||||
{
|
||||
long oldumode = 0;
|
||||
if (!IsUser(client))
|
||||
continue;
|
||||
oldumode = client->umodes;
|
||||
client->umodes &= ~umode->mode;
|
||||
if (MyUser(client))
|
||||
send_umode_out(client, 1, oldumode);
|
||||
}
|
||||
umode->letter = '\0';
|
||||
AllUmodes &= ~(umode->mode);
|
||||
SendUmodes &= ~(umode->mode);
|
||||
make_umodestr();
|
||||
}
|
||||
|
||||
if (umode->owner) {
|
||||
ModuleObject *umodeobj;
|
||||
for (umodeobj = umode->owner->objects; umodeobj; umodeobj = umodeobj->next) {
|
||||
if (umodeobj->type == MOBJ_UMODE && umodeobj->object.umode == umode) {
|
||||
for (umodeobj = umode->owner->objects; umodeobj; umodeobj = umodeobj->next)
|
||||
{
|
||||
if (umodeobj->type == MOBJ_UMODE && umodeobj->object.umode == umode)
|
||||
{
|
||||
DelListItem(umodeobj, umode->owner->objects);
|
||||
safe_free(umodeobj);
|
||||
break;
|
||||
@@ -227,7 +247,13 @@ void UmodeDel(Umode *umode)
|
||||
}
|
||||
umode->owner = NULL;
|
||||
}
|
||||
return;
|
||||
|
||||
/* Whether we can actually (already) free the Umode depends... */
|
||||
|
||||
if (loop.rehashing)
|
||||
umode->unloaded = 1;
|
||||
else
|
||||
unload_usermode_commit(umode);
|
||||
}
|
||||
|
||||
int umode_allow_all(Client *client, int what)
|
||||
@@ -270,41 +296,45 @@ int umode_hidle_allow(Client *client, int what)
|
||||
return 0; /* if set::hide-idle-time is 'never' or 'always' then +I makes no sense */
|
||||
}
|
||||
|
||||
void unload_all_unused_umodes(void)
|
||||
static void unload_usermode_commit(Umode *um)
|
||||
{
|
||||
long removed_umode = 0;
|
||||
int i;
|
||||
Client *client;
|
||||
for (i = 0; i < UMODETABLESZ; i++)
|
||||
{
|
||||
if (Usermode_Table[i].unloaded)
|
||||
removed_umode |= Usermode_Table[i].mode;
|
||||
}
|
||||
if (!removed_umode) /* Nothing was unloaded */
|
||||
long removed_umode;
|
||||
|
||||
if (!um)
|
||||
return;
|
||||
|
||||
removed_umode = um->mode;
|
||||
|
||||
/* First send the -mode regarding all users */
|
||||
list_for_each_entry(client, &lclient_list, lclient_node)
|
||||
{
|
||||
long oldumode = 0;
|
||||
if (!IsUser(client))
|
||||
continue;
|
||||
oldumode = client->umodes;
|
||||
client->umodes &= ~(removed_umode);
|
||||
if (MyUser(client))
|
||||
send_umode_out(client, 1, oldumode);
|
||||
}
|
||||
for (i = 0; i < UMODETABLESZ; i++)
|
||||
{
|
||||
if (Usermode_Table[i].unloaded)
|
||||
if (MyUser(client) && (client->umodes & removed_umode))
|
||||
{
|
||||
AllUmodes &= ~(Usermode_Table[i].mode);
|
||||
SendUmodes &= ~(Usermode_Table[i].mode);
|
||||
Usermode_Table[i].letter = '\0';
|
||||
Usermode_Table[i].unloaded = 0;
|
||||
long oldumode = client->umodes;
|
||||
client->umodes &= ~(removed_umode);
|
||||
send_umode_out(client, 1, oldumode);
|
||||
}
|
||||
}
|
||||
|
||||
/* Then unload the mode */
|
||||
DelListItem(um, usermodes);
|
||||
safe_free(um);
|
||||
make_umodestr();
|
||||
}
|
||||
|
||||
void unload_all_unused_umodes(void)
|
||||
{
|
||||
Umode *um, *um_next;
|
||||
|
||||
for (um=usermodes; um; um = um_next)
|
||||
{
|
||||
um_next = um->next;
|
||||
if (um->letter && um->unloaded)
|
||||
unload_usermode_commit(um);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function removes any oper-only snomasks when the user is no
|
||||
* longer an IRC Operator.
|
||||
@@ -323,14 +353,12 @@ void remove_all_snomasks(Client *client)
|
||||
*/
|
||||
void remove_oper_modes(Client *client)
|
||||
{
|
||||
int i;
|
||||
Umode *um;
|
||||
|
||||
for (i = 0; i <= Usermode_highest; i++)
|
||||
for (um = usermodes; um; um = um->next)
|
||||
{
|
||||
if (!Usermode_Table[i].letter)
|
||||
continue;
|
||||
if (Usermode_Table[i].unset_on_deoper)
|
||||
client->umodes &= ~Usermode_Table[i].mode;
|
||||
if (um->unset_on_deoper)
|
||||
client->umodes &= ~um->mode;
|
||||
}
|
||||
|
||||
/* Bit of a hack, since this is a dynamic permission umode */
|
||||
@@ -350,15 +378,14 @@ void remove_oper_privileges(Client *client, int broadcast_mode_change)
|
||||
}
|
||||
|
||||
/** Return long integer mode for a user mode character (eg: 'x' -> 0x10) */
|
||||
long find_user_mode(char flag)
|
||||
long find_user_mode(char letter)
|
||||
{
|
||||
int i;
|
||||
Umode *um;
|
||||
|
||||
for (um = usermodes; um; um = um->next)
|
||||
if ((um->letter == letter) && !um->unloaded)
|
||||
return um->mode;
|
||||
|
||||
for (i = 0; i < UMODETABLESZ; i++)
|
||||
{
|
||||
if ((Usermode_Table[i].letter == flag) && !(Usermode_Table[i].unloaded))
|
||||
return Usermode_Table[i].mode;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+16
-23
@@ -1079,7 +1079,7 @@ void _set_mode(Channel *channel, Client *client, int parc, const char *parv[], u
|
||||
*/
|
||||
CMD_FUNC(_cmd_umode)
|
||||
{
|
||||
int i;
|
||||
Umode *um;
|
||||
const char *m;
|
||||
Client *acptr;
|
||||
int what;
|
||||
@@ -1120,10 +1120,7 @@ CMD_FUNC(_cmd_umode)
|
||||
|
||||
userhost_save_current(client); /* save host, in case we do any +x/-x or similar */
|
||||
|
||||
/* find flags already set for user */
|
||||
for (i = 0; i <= Usermode_highest; i++)
|
||||
if ((client->umodes & Usermode_Table[i].mode))
|
||||
oldumodes |= Usermode_Table[i].mode;
|
||||
oldumodes = client->umodes;
|
||||
|
||||
if (RESTRICT_USERMODES && MyUser(client) && !ValidatePermissionsForPath("immune:restrict-usermodes",client,NULL,NULL,NULL))
|
||||
chk_restrict = 1;
|
||||
@@ -1238,24 +1235,23 @@ CMD_FUNC(_cmd_umode)
|
||||
break;
|
||||
default:
|
||||
def:
|
||||
for (i = 0; i <= Usermode_highest; i++)
|
||||
for (um = usermodes; um; um = um->next)
|
||||
{
|
||||
if (*m == Usermode_Table[i].letter)
|
||||
if (um->letter == *m)
|
||||
{
|
||||
if (Usermode_Table[i].allowed)
|
||||
if (!Usermode_Table[i].allowed(client,what))
|
||||
if (um->allowed && !um->allowed(client,what))
|
||||
break;
|
||||
if (what == MODE_ADD)
|
||||
client->umodes |= Usermode_Table[i].mode;
|
||||
client->umodes |= um->mode;
|
||||
else
|
||||
client->umodes &= ~Usermode_Table[i].mode;
|
||||
client->umodes &= ~um->mode;
|
||||
break;
|
||||
}
|
||||
else if (i == Usermode_highest && MyConnect(client) && !rpterror)
|
||||
{
|
||||
sendnumeric(client, ERR_UMODEUNKNOWNFLAG);
|
||||
rpterror = 1;
|
||||
}
|
||||
}
|
||||
if (!um && MyConnect(client) && !rpterror)
|
||||
{
|
||||
sendnumeric(client, ERR_UMODEUNKNOWNFLAG);
|
||||
rpterror = 1;
|
||||
}
|
||||
break;
|
||||
} /* switch */
|
||||
@@ -1273,19 +1269,16 @@ CMD_FUNC(_cmd_umode)
|
||||
int i;
|
||||
|
||||
/* MODES */
|
||||
for (i = 0; i <= Usermode_highest; i++)
|
||||
for (um = usermodes; um; um = um->next)
|
||||
{
|
||||
if (!Usermode_Table[i].letter)
|
||||
continue;
|
||||
if (Usermode_Table[i].unset_on_deoper)
|
||||
if (um->unset_on_deoper)
|
||||
{
|
||||
/* This is an oper mode. Is it set now and wasn't earlier?
|
||||
* then it needs to be stripped, as setting it is not
|
||||
* permitted.
|
||||
*/
|
||||
long m = Usermode_Table[i].mode;
|
||||
if ((client->umodes & m) && !(oldumodes & m))
|
||||
client->umodes &= ~Usermode_Table[i].mode; /* remove */
|
||||
if ((client->umodes & um->mode) && !(oldumodes & um->mode))
|
||||
client->umodes &= ~um->mode; /* remove */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-13
@@ -83,19 +83,7 @@ CMD_FUNC(cmd_sendumode)
|
||||
|
||||
sendto_server(client, 0, 0, mtags, ":%s SENDUMODE %s :%s", client->id, parv[1], message);
|
||||
|
||||
for (p = parv[1]; *p; p++)
|
||||
{
|
||||
for(i = 0; i <= Usermode_highest; i++)
|
||||
{
|
||||
if (!Usermode_Table[i].letter)
|
||||
continue;
|
||||
if (Usermode_Table[i].letter == *p)
|
||||
{
|
||||
umode_s |= Usermode_Table[i].mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
umode_s = set_usermode(parv[1]);
|
||||
|
||||
list_for_each_entry(acptr, &oper_list, special_node)
|
||||
{
|
||||
|
||||
+11
-16
@@ -317,11 +317,11 @@ void channel_svsmode(Client *client, int parc, const char *parv[])
|
||||
*/
|
||||
void do_svsmode(Client *client, MessageTag *recv_mtags, int parc, const char *parv[], int show_change)
|
||||
{
|
||||
int i;
|
||||
Umode *um;
|
||||
const char *m;
|
||||
Client *target;
|
||||
int what;
|
||||
long setflags = 0;
|
||||
long oldumodes = 0;
|
||||
|
||||
if (!IsULine(client))
|
||||
return;
|
||||
@@ -342,10 +342,7 @@ void do_svsmode(Client *client, MessageTag *recv_mtags, int parc, const char *pa
|
||||
|
||||
userhost_save_current(target);
|
||||
|
||||
/* initialize setflag to be the user's pre-SVSMODE flags */
|
||||
for (i = 0; i <= Usermode_highest; i++)
|
||||
if (Usermode_Table[i].letter && (target->umodes & Usermode_Table[i].mode))
|
||||
setflags |= Usermode_Table[i].mode;
|
||||
oldumodes = target->umodes;
|
||||
|
||||
/* parse mode change string(s) */
|
||||
for (m = parv[2]; *m; m++)
|
||||
@@ -505,16 +502,14 @@ void do_svsmode(Client *client, MessageTag *recv_mtags, int parc, const char *pa
|
||||
break;
|
||||
default:
|
||||
setmodex:
|
||||
for (i = 0; i <= Usermode_highest; i++)
|
||||
for (um = usermodes; um; um = um->next)
|
||||
{
|
||||
if (!Usermode_Table[i].letter)
|
||||
continue;
|
||||
if (*m == Usermode_Table[i].letter)
|
||||
if (um->letter == *m)
|
||||
{
|
||||
if (what == MODE_ADD)
|
||||
target->umodes |= Usermode_Table[i].mode;
|
||||
target->umodes |= um->mode;
|
||||
else
|
||||
target->umodes &= ~Usermode_Table[i].mode;
|
||||
target->umodes &= ~um->mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -531,15 +526,15 @@ void do_svsmode(Client *client, MessageTag *recv_mtags, int parc, const char *pa
|
||||
parv[1], parv[2]);
|
||||
|
||||
/* Here we trigger the same hooks that cmd_mode does and, likewise,
|
||||
only if the old flags (setflags) are different than the newly-
|
||||
only if the old flags (oldumodes) are different than the newly-
|
||||
set ones */
|
||||
if (setflags != target->umodes)
|
||||
RunHook(HOOKTYPE_UMODE_CHANGE, target, setflags, target->umodes);
|
||||
if (oldumodes != target->umodes)
|
||||
RunHook(HOOKTYPE_UMODE_CHANGE, target, oldumodes, target->umodes);
|
||||
|
||||
if (show_change)
|
||||
{
|
||||
char buf[BUFSIZE];
|
||||
build_umode_string(target, setflags, ALL_UMODES, buf);
|
||||
build_umode_string(target, oldumodes, ALL_UMODES, buf);
|
||||
if (MyUser(target) && *buf)
|
||||
sendto_one(target, NULL, ":%s MODE %s :%s", client->name, target->name, buf);
|
||||
}
|
||||
|
||||
+1
-11
@@ -330,17 +330,7 @@ static int parse_who_options(Client *client, int argc, const char **argv)
|
||||
else
|
||||
umodes = &wfl.umodes_dontwant;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i <= Usermode_highest; i++)
|
||||
if (*s == Usermode_Table[i].letter)
|
||||
{
|
||||
*umodes |= Usermode_Table[i].mode;
|
||||
break;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*umodes = set_usermode(s);
|
||||
|
||||
if (!IsOper(client))
|
||||
*umodes = *umodes & UMODE_OPER; /* these are usermodes regular users may search for. just oper now. */
|
||||
|
||||
+4
-4
@@ -295,7 +295,7 @@ CMD_FUNC(cmd_whox)
|
||||
|
||||
while (*s)
|
||||
{
|
||||
int i;
|
||||
Umode *um;
|
||||
|
||||
switch (*s)
|
||||
{
|
||||
@@ -317,11 +317,11 @@ CMD_FUNC(cmd_whox)
|
||||
else
|
||||
umodes = &fmt.noumodes;
|
||||
|
||||
for (i = 0; i <= Usermode_highest; i++)
|
||||
for (um = usermodes; um; um = um->next)
|
||||
{
|
||||
if (*s == Usermode_Table[i].letter)
|
||||
if (um->letter == *s)
|
||||
{
|
||||
*umodes |= Usermode_Table[i].mode;
|
||||
*umodes |= um->mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-11
@@ -736,22 +736,13 @@ void sendto_umode_global(int umodes, FORMAT_STRING(const char *pattern), ...)
|
||||
{
|
||||
va_list vl;
|
||||
Client *acptr;
|
||||
Umode *um;
|
||||
char nbuf[1024];
|
||||
int i;
|
||||
char modestr[128];
|
||||
char *p;
|
||||
|
||||
/* Convert 'umodes' (int) to 'modestr' (string) */
|
||||
*modestr = '\0';
|
||||
p = modestr;
|
||||
for(i = 0; i <= Usermode_highest; i++)
|
||||
{
|
||||
if (!Usermode_Table[i].letter)
|
||||
continue;
|
||||
if (umodes & Usermode_Table[i].mode)
|
||||
*p++ = Usermode_Table[i].letter;
|
||||
}
|
||||
*p = '\0';
|
||||
get_usermode_string_raw_r(umodes, modestr, sizeof(modestr));
|
||||
|
||||
list_for_each_entry(acptr, &lclient_list, lclient_node)
|
||||
{
|
||||
|
||||
+71
-60
@@ -82,43 +82,43 @@ void iNAH_host(Client *client, const char *host)
|
||||
*/
|
||||
long set_usermode(const char *umode)
|
||||
{
|
||||
int newumode;
|
||||
int what;
|
||||
Umode *um;
|
||||
int newumode;
|
||||
int what;
|
||||
const char *m;
|
||||
int i;
|
||||
|
||||
newumode = 0;
|
||||
what = MODE_ADD;
|
||||
for (m = umode; *m; m++)
|
||||
{
|
||||
switch (*m)
|
||||
{
|
||||
case '+':
|
||||
what = MODE_ADD;
|
||||
break;
|
||||
case '-':
|
||||
what = MODE_DEL;
|
||||
break;
|
||||
case ' ':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\t':
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i <= Usermode_highest; i++)
|
||||
{
|
||||
if (!Usermode_Table[i].letter)
|
||||
continue;
|
||||
if (*m == Usermode_Table[i].letter)
|
||||
{
|
||||
if (what == MODE_ADD)
|
||||
newumode |= Usermode_Table[i].mode;
|
||||
else
|
||||
newumode &= ~Usermode_Table[i].mode;
|
||||
}
|
||||
}
|
||||
case '+':
|
||||
what = MODE_ADD;
|
||||
break;
|
||||
case '-':
|
||||
what = MODE_DEL;
|
||||
break;
|
||||
case ' ':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\t':
|
||||
break;
|
||||
default:
|
||||
for (um = usermodes; um; um = um->next)
|
||||
{
|
||||
if (um->letter == *m)
|
||||
{
|
||||
if (what == MODE_ADD)
|
||||
newumode |= um->mode;
|
||||
else
|
||||
newumode &= ~um->mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (newumode);
|
||||
return newumode;
|
||||
}
|
||||
|
||||
/** Convert a target pointer to an 8 bit hash, used for target limiting. */
|
||||
@@ -257,15 +257,13 @@ char *canonize(const char *buffer)
|
||||
const char *get_usermode_string(Client *client)
|
||||
{
|
||||
static char buf[128];
|
||||
int i;
|
||||
char *m;
|
||||
Umode *um;
|
||||
|
||||
strlcpy(buf, "+", sizeof(buf));
|
||||
for (um = usermodes; um; um = um->next)
|
||||
if (client->umodes & um->mode)
|
||||
strlcat_letter(buf, um->letter, sizeof(buf));
|
||||
|
||||
m = buf;
|
||||
*m++ = '+';
|
||||
for (i = 0; (i <= Usermode_highest) && (m - buf < sizeof(buf) - 4); i++)
|
||||
if (Usermode_Table[i].letter && (client->umodes & Usermode_Table[i].mode))
|
||||
*m++ = Usermode_Table[i].letter;
|
||||
*m = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -273,21 +271,20 @@ const char *get_usermode_string(Client *client)
|
||||
* @param client The client
|
||||
* @param buf The buffer to write to
|
||||
* @param buflen The size of the buffer
|
||||
* @returns string of user modes (temporary storage)
|
||||
* @returns string of user modes (buf)
|
||||
*/
|
||||
const char *get_usermode_string_r(Client *client, char *buf, size_t buflen)
|
||||
{
|
||||
int i;
|
||||
Umode *um;
|
||||
|
||||
strlcpy(buf, "+", buflen);
|
||||
for (i = 0; i <= Usermode_highest; i++)
|
||||
if (Usermode_Table[i].letter && (client->umodes & Usermode_Table[i].mode))
|
||||
strlcat_letter(buf, Usermode_Table[i].letter, buflen);
|
||||
for (um = usermodes; um; um = um->next)
|
||||
if (client->umodes & um->mode)
|
||||
strlcat_letter(buf, um->letter, buflen);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/** Get user modes as a string - this one does not work on 'client' but directly on 'umodes'.
|
||||
* @param umodes The user modes that are set
|
||||
* @returns string of user modes (temporary storage)
|
||||
@@ -295,19 +292,35 @@ const char *get_usermode_string_r(Client *client, char *buf, size_t buflen)
|
||||
const char *get_usermode_string_raw(long umodes)
|
||||
{
|
||||
static char buf[128];
|
||||
int i;
|
||||
char *m;
|
||||
Umode *um;
|
||||
|
||||
strlcpy(buf, "+", sizeof(buf));
|
||||
for (um = usermodes; um; um = um->next)
|
||||
if (umodes & um->mode)
|
||||
strlcat_letter(buf, um->letter, sizeof(buf));
|
||||
|
||||
m = buf;
|
||||
*m++ = '+';
|
||||
for (i = 0; (i <= Usermode_highest) && (m - buf < sizeof(buf) - 4); i++)
|
||||
|
||||
if (Usermode_Table[i].letter && (umodes & Usermode_Table[i].mode))
|
||||
*m++ = Usermode_Table[i].letter;
|
||||
*m = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
/** Get user modes as a string - this one does not work on 'client' but directly on 'umodes'.
|
||||
* @param umodes The user modes that are set
|
||||
* @param buf The buffer to write to
|
||||
* @param buflen The size of the buffer
|
||||
* @returns string of user modes (buf)
|
||||
*/
|
||||
const char *get_usermode_string_raw_r(long umodes, char *buf, size_t buflen)
|
||||
{
|
||||
Umode *um;
|
||||
|
||||
strlcpy(buf, "+", buflen);
|
||||
for (um = usermodes; um; um = um->next)
|
||||
if (umodes & um->mode)
|
||||
strlcat_letter(buf, um->letter, buflen);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/** Set a new snomask on the user.
|
||||
* The user is not informed of the change by this function.
|
||||
* @param client The client
|
||||
@@ -355,7 +368,7 @@ void set_snomask(Client *client, const char *snomask)
|
||||
*/
|
||||
void build_umode_string(Client *client, long old, long sendmask, char *umode_buf)
|
||||
{
|
||||
int i;
|
||||
Umode *um;
|
||||
long flag;
|
||||
char *m;
|
||||
int what = MODE_NULL;
|
||||
@@ -366,33 +379,31 @@ void build_umode_string(Client *client, long old, long sendmask, char *umode_buf
|
||||
*/
|
||||
m = umode_buf;
|
||||
*m = '\0';
|
||||
for (i = 0; i <= Usermode_highest; i++)
|
||||
for (um = usermodes; um; um = um->next)
|
||||
{
|
||||
if (!Usermode_Table[i].letter)
|
||||
continue;
|
||||
flag = Usermode_Table[i].mode;
|
||||
flag = um->mode;
|
||||
if (MyUser(client) && !(flag & sendmask))
|
||||
continue;
|
||||
if ((flag & old) && !(client->umodes & flag))
|
||||
{
|
||||
if (what == MODE_DEL)
|
||||
*m++ = Usermode_Table[i].letter;
|
||||
*m++ = um->letter;
|
||||
else
|
||||
{
|
||||
what = MODE_DEL;
|
||||
*m++ = '-';
|
||||
*m++ = Usermode_Table[i].letter;
|
||||
*m++ = um->letter;
|
||||
}
|
||||
}
|
||||
else if (!(flag & old) && (client->umodes & flag))
|
||||
{
|
||||
if (what == MODE_ADD)
|
||||
*m++ = Usermode_Table[i].letter;
|
||||
*m++ = um->letter;
|
||||
else
|
||||
{
|
||||
what = MODE_ADD;
|
||||
*m++ = '+';
|
||||
*m++ = Usermode_Table[i].letter;
|
||||
*m++ = um->letter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user