From edbfaaf95dd49f3ddadb7a521351ec554e41390b Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Sat, 25 Sep 2021 09:45:03 +0200 Subject: [PATCH] JSON logging: expand user modes, snomasks, and oper login (if available) This also adds a function get_usermode_string_r(), which requires you to specify the buffer (and buffer length) for building the umode string. --- include/h.h | 3 ++- src/log.c | 21 ++++++++++++++++----- src/user.c | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/include/h.h b/include/h.h index 69e25b72d..84c0b131b 100644 --- a/include/h.h +++ b/include/h.h @@ -91,6 +91,8 @@ extern EVENT(throttling_check_expire); extern void module_loadall(void); 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 ConfigFile *config_parse(const char *filename, char *confdata); extern ConfigFile *config_parse_with_offset(const char *filename, char *confdata, unsigned int line_offset); @@ -1178,7 +1180,6 @@ extern EVENT(save_tunefile); extern void read_motd(const char *filename, MOTDFile *motd); extern int target_limit_exceeded(Client *client, void *target, const char *name); extern void make_umodestr(void); -extern const char *get_usermode_string(Client *acptr); extern void initwhowas(void); extern void uid_init(void); extern const char *uid_get(void); diff --git a/src/log.c b/src/log.c index ce945da48..88ee8d0ae 100644 --- a/src/log.c +++ b/src/log.c @@ -473,6 +473,7 @@ void json_expand_client(json_t *j, const char *key, Client *client, int detail) if (client->user) { + char buf[512]; /* client.user */ user = json_object(); json_object_set_new(child, "user", user); @@ -486,6 +487,16 @@ void json_expand_client(json_t *j, const char *key, Client *client, int detail) json_object_set_new(user, "account", json_string_unreal(client->user->account)); json_object_set_new(user, "reputation", json_integer(GetReputation(client))); json_expand_client_security_groups(user, client); + + /* user modes and snomasks */ + get_usermode_string_r(client, buf, sizeof(buf)); + json_object_set_new(user, "modes", json_string_unreal(buf+1)); + if (client->user->snomask) + json_object_set_new(user, "snomasks", json_string_unreal(client->user->snomask)); + + /* if oper then we can possibly expand a bit more */ + if (client->user->operlogin) + json_object_set_new(user, "oper_login", json_string_unreal(client->user->operlogin)); } else if (IsMe(client)) { @@ -544,7 +555,7 @@ void json_expand_client(json_t *j, const char *key, Client *client, int detail) void json_expand_channel(json_t *j, const char *key, Channel *channel, int detail) { - char modem[512], modep[512], modes[512]; + char mode1[512], mode2[512], modes[512]; json_t *child = json_object(); json_object_set_new(j, key, child); @@ -559,13 +570,13 @@ void json_expand_channel(json_t *j, const char *key, Channel *channel, int detai } /* Add "mode" too */ - channel_modes(NULL, modem, modep, sizeof(modem), sizeof(modep), channel, 0); - if (*modep) + channel_modes(NULL, mode1, mode2, sizeof(mode1), sizeof(mode2), channel, 0); + if (*mode2) { - snprintf(modes, sizeof(modes), "%s %s", modem, modep); + snprintf(modes, sizeof(modes), "%s %s", mode1+1, mode2); json_object_set_new(child, "modes", json_string_unreal(modes)); } else { - json_object_set_new(child, "modes", json_string_unreal(modem)); + json_object_set_new(child, "modes", json_string_unreal(mode1+1)); } // Possibly later: If detail is set to 1 then expand more... diff --git a/src/user.c b/src/user.c index 21299b2dc..143640150 100644 --- a/src/user.c +++ b/src/user.c @@ -269,6 +269,24 @@ const char *get_usermode_string(Client *client) return buf; } +/** Get user modes as a string - buffer is specified. + * @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) + */ +const char *get_usermode_string_r(Client *client, char *buf, size_t buflen) +{ + int i; + + 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); + + 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