diff --git a/include/privilege.h b/include/privilege.h index 555eb868..5f26a22f 100644 --- a/include/privilege.h +++ b/include/privilege.h @@ -61,6 +61,12 @@ struct PrivilegeSet { int refs; }; +struct privset_diff { + const struct PrivilegeSet *unchanged; + const struct PrivilegeSet *added; + const struct PrivilegeSet *removed; +}; + bool privilegeset_in_set(const struct PrivilegeSet *set, const char *priv); const char **privilegeset_privs(const struct PrivilegeSet *set); struct PrivilegeSet *privilegeset_set_new(const char *name, const char *privs, PrivilegeFlags flags); @@ -72,6 +78,6 @@ void privilegeset_prepare_rehash(void); void privilegeset_cleanup_rehash(void); void privilegeset_report(struct Client *source_p); -const struct PrivilegeSet **privilegeset_diff(const struct PrivilegeSet *, const struct PrivilegeSet *); +struct privset_diff privilegeset_diff(const struct PrivilegeSet *, const struct PrivilegeSet *); #endif diff --git a/ircd/privilege.c b/ircd/privilege.c index 2264efae..7da649b1 100644 --- a/ircd/privilege.c +++ b/ircd/privilege.c @@ -319,7 +319,7 @@ privilegeset_unref(struct PrivilegeSet *set) } } -const struct PrivilegeSet ** +struct privset_diff privilegeset_diff(const struct PrivilegeSet *old, const struct PrivilegeSet *new) { static const char *no_privs[] = { NULL }; @@ -327,16 +327,15 @@ privilegeset_diff(const struct PrivilegeSet *old, const struct PrivilegeSet *new static struct PrivilegeSet *set_unchanged = NULL, *set_added = NULL, *set_removed = NULL; - static const struct PrivilegeSet *result_sets[3]; static size_t n_privs = 0; size_t new_size = n_privs ? n_privs : 32; size_t i = 0, j = 0; - if (result_sets[0] == NULL) + if (set_unchanged == NULL) { - result_sets[0] = set_unchanged = privilegeset_new_orphan(""); - result_sets[1] = set_added = privilegeset_new_orphan(""); - result_sets[2] = set_removed = privilegeset_new_orphan(""); + set_unchanged = privilegeset_new_orphan(""); + set_added = privilegeset_new_orphan(""); + set_removed = privilegeset_new_orphan(""); } if (old == NULL) @@ -390,7 +389,11 @@ privilegeset_diff(const struct PrivilegeSet *old, const struct PrivilegeSet *new set_added->size = res_added - set_added->privs; set_removed->size = res_removed - set_removed->privs; - return result_sets; + return (struct privset_diff){ + .unchanged = set_unchanged, + .added = set_added, + .removed = set_removed, + }; } void diff --git a/ircd/s_user.c b/ircd/s_user.c index 4c4103ac..e39ed93e 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -975,19 +975,15 @@ report_and_set_user_flags(struct Client *source_p, struct ConfItem *aconf) void report_priv_change(struct Client *client, struct PrivilegeSet *old, struct PrivilegeSet *new) { - const struct PrivilegeSet *added, *removed, *unchanged; - const struct PrivilegeSet **result = privilegeset_diff(old, new); - unchanged = result[0]; - added = result[1]; - removed = result[2]; + struct privset_diff diff = privilegeset_diff(old, new); hook_data_priv_change hdata = { .client = client, .new = new, .old = old, - .unchanged = unchanged, - .added = added, - .removed = removed, + .unchanged = diff.unchanged, + .added = diff.added, + .removed = diff.removed, }; call_hook(h_priv_change, &hdata); } diff --git a/tests/privilege1.c b/tests/privilege1.c index e2d77db2..38209673 100644 --- a/tests/privilege1.c +++ b/tests/privilege1.c @@ -84,23 +84,19 @@ static void test_privset_diff(void) { struct PrivilegeSet *old = privilegeset_set_new("old", "foo bar", 0); struct PrivilegeSet *new = privilegeset_set_new("new", "foo qux", 0); - const struct PrivilegeSet *added, *removed, *unchanged; - const struct PrivilegeSet **result = privilegeset_diff(old, new); - unchanged = result[0]; - added = result[1]; - removed = result[2]; + struct privset_diff diff = privilegeset_diff(old, new); - is_bool(true, privilegeset_in_set(unchanged, "foo"), MSG); - is_bool(false, privilegeset_in_set(added, "foo"), MSG); - is_bool(false, privilegeset_in_set(removed, "foo"), MSG); + is_bool(true, privilegeset_in_set(diff.unchanged, "foo"), MSG); + is_bool(false, privilegeset_in_set(diff.added, "foo"), MSG); + is_bool(false, privilegeset_in_set(diff.removed, "foo"), MSG); - is_bool(false, privilegeset_in_set(unchanged, "bar"), MSG); - is_bool(false, privilegeset_in_set(added, "bar"), MSG); - is_bool(true, privilegeset_in_set(removed, "bar"), MSG); + is_bool(false, privilegeset_in_set(diff.unchanged, "bar"), MSG); + is_bool(false, privilegeset_in_set(diff.added, "bar"), MSG); + is_bool(true, privilegeset_in_set(diff.removed, "bar"), MSG); - is_bool(false, privilegeset_in_set(unchanged, "qux"), MSG); - is_bool(true, privilegeset_in_set(added, "qux"), MSG); - is_bool(false, privilegeset_in_set(removed, "qux"), MSG); + is_bool(false, privilegeset_in_set(diff.unchanged, "qux"), MSG); + is_bool(true, privilegeset_in_set(diff.added, "qux"), MSG); + is_bool(false, privilegeset_in_set(diff.removed, "qux"), MSG); cleanup(); } @@ -108,44 +104,37 @@ static void test_privset_diff(void) static void test_privset_diff_rehash(void) { struct PrivilegeSet *set = privilegeset_set_new("test", "foo bar", 0); - const struct PrivilegeSet *added, *removed, *unchanged; - const struct PrivilegeSet **result; + struct privset_diff diff; privilegeset_ref(set); privilegeset_prepare_rehash(); /* should have changed from foo, bar to nothing, i.e. -foo -bar */ - result = privilegeset_diff(set->shadow, set); - unchanged = result[0]; - added = result[1]; - removed = result[2]; + diff = privilegeset_diff(set->shadow, set); - is_bool(false, privilegeset_in_set(unchanged, "foo"), MSG); - is_bool(false, privilegeset_in_set(added, "foo"), MSG); - is_bool(true, privilegeset_in_set(removed, "foo"), MSG); + is_bool(false, privilegeset_in_set(diff.unchanged, "foo"), MSG); + is_bool(false, privilegeset_in_set(diff.added, "foo"), MSG); + is_bool(true, privilegeset_in_set(diff.removed, "foo"), MSG); - is_bool(false, privilegeset_in_set(unchanged, "bar"), MSG); - is_bool(false, privilegeset_in_set(added, "bar"), MSG); - is_bool(true, privilegeset_in_set(removed, "bar"), MSG); + is_bool(false, privilegeset_in_set(diff.unchanged, "bar"), MSG); + is_bool(false, privilegeset_in_set(diff.added, "bar"), MSG); + is_bool(true, privilegeset_in_set(diff.removed, "bar"), MSG); privilegeset_set_new("test", "foo qux", 0); - result = privilegeset_diff(set->shadow, set); - unchanged = result[0]; - added = result[1]; - removed = result[2]; + diff = privilegeset_diff(set->shadow, set); /* should have changed from foo, bar to foo, qux, i.e. =foo -bar +qux */ - is_bool(true, privilegeset_in_set(unchanged, "foo"), MSG); - is_bool(false, privilegeset_in_set(added, "foo"), MSG); - is_bool(false, privilegeset_in_set(removed, "foo"), MSG); + is_bool(true, privilegeset_in_set(diff.unchanged, "foo"), MSG); + is_bool(false, privilegeset_in_set(diff.added, "foo"), MSG); + is_bool(false, privilegeset_in_set(diff.removed, "foo"), MSG); - is_bool(false, privilegeset_in_set(unchanged, "bar"), MSG); - is_bool(false, privilegeset_in_set(added, "bar"), MSG); - is_bool(true, privilegeset_in_set(removed, "bar"), MSG); + is_bool(false, privilegeset_in_set(diff.unchanged, "bar"), MSG); + is_bool(false, privilegeset_in_set(diff.added, "bar"), MSG); + is_bool(true, privilegeset_in_set(diff.removed, "bar"), MSG); - is_bool(false, privilegeset_in_set(unchanged, "qux"), MSG); - is_bool(true, privilegeset_in_set(added, "qux"), MSG); - is_bool(false, privilegeset_in_set(removed, "qux"), MSG); + is_bool(false, privilegeset_in_set(diff.unchanged, "qux"), MSG); + is_bool(true, privilegeset_in_set(diff.added, "qux"), MSG); + is_bool(false, privilegeset_in_set(diff.removed, "qux"), MSG); privilegeset_cleanup_rehash();