]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/basic/hash-funcs.c
logind: Don't match non-leader processes for utmp TTY determination (#38027)
[thirdparty/systemd.git] / src / basic / hash-funcs.c
... / ...
CommitLineData
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3#include <stdlib.h>
4#include <string.h>
5#include <sys/sysmacros.h>
6
7#include "hash-funcs.h"
8#include "path-util.h"
9#include "siphash24.h"
10#include "strv.h"
11
12void string_hash_func(const char *p, struct siphash *state) {
13 siphash24_compress(p, strlen(p) + 1, state);
14}
15
16DEFINE_HASH_OPS(string_hash_ops,
17 char, string_hash_func, string_compare_func);
18DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
19 string_hash_ops_free,
20 char, string_hash_func, string_compare_func, free);
21DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
22 string_hash_ops_value_free,
23 char, string_hash_func, string_compare_func,
24 void, free);
25DEFINE_HASH_OPS_FULL(
26 string_hash_ops_free_free,
27 char, string_hash_func, string_compare_func, free,
28 void, free);
29DEFINE_HASH_OPS_FULL(
30 string_hash_ops_free_strv_free,
31 char, string_hash_func, string_compare_func, free,
32 char*, strv_free);
33
34void path_hash_func(const char *q, struct siphash *state) {
35 bool add_slash = false;
36
37 assert(q);
38 assert(state);
39
40 /* Calculates a hash for a path in a way this duplicate inner slashes don't make a differences, and also
41 * whether there's a trailing slash or not. This fits well with the semantics of path_compare(), which does
42 * similar checks and also doesn't care for trailing slashes. Note that relative and absolute paths (i.e. those
43 * which begin in a slash or not) will hash differently though. */
44
45 /* if path is absolute, add one "/" to the hash. */
46 if (path_is_absolute(q))
47 siphash24_compress_byte('/', state);
48
49 for (;;) {
50 const char *e;
51 int r;
52
53 r = path_find_first_component(&q, true, &e);
54 if (r == 0)
55 return;
56
57 if (add_slash)
58 siphash24_compress_byte('/', state);
59
60 if (r < 0) {
61 /* if a component is invalid, then add remaining part as a string. */
62 string_hash_func(q, state);
63 return;
64 }
65
66 /* Add this component to the hash. */
67 siphash24_compress(e, r, state);
68
69 add_slash = true;
70 }
71}
72
73DEFINE_HASH_OPS(path_hash_ops,
74 char, path_hash_func, path_compare);
75DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
76 path_hash_ops_free,
77 char, path_hash_func, path_compare, free);
78DEFINE_HASH_OPS_FULL(
79 path_hash_ops_free_free,
80 char, path_hash_func, path_compare, free,
81 void, free);
82
83void trivial_hash_func(const void *p, struct siphash *state) {
84 siphash24_compress_typesafe(p, state);
85}
86
87int trivial_compare_func(const void *a, const void *b) {
88 return CMP(a, b);
89}
90
91DEFINE_HASH_OPS(trivial_hash_ops,
92 void, trivial_hash_func, trivial_compare_func);
93DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
94 trivial_hash_ops_free,
95 void, trivial_hash_func, trivial_compare_func, free);
96DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
97 trivial_hash_ops_value_free,
98 void, trivial_hash_func, trivial_compare_func,
99 void, free);
100DEFINE_HASH_OPS_FULL(
101 trivial_hash_ops_free_free,
102 void, trivial_hash_func, trivial_compare_func, free,
103 void, free);
104
105void uint64_hash_func(const uint64_t *p, struct siphash *state) {
106 siphash24_compress_typesafe(*p, state);
107}
108
109int uint64_compare_func(const uint64_t *a, const uint64_t *b) {
110 return CMP(*a, *b);
111}
112
113DEFINE_HASH_OPS(uint64_hash_ops,
114 uint64_t, uint64_hash_func, uint64_compare_func);
115DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
116 uint64_hash_ops_value_free,
117 uint64_t, uint64_hash_func, uint64_compare_func,
118 void, free);
119
120#if SIZEOF_DEV_T != 8
121void devt_hash_func(const dev_t *p, struct siphash *state) {
122 siphash24_compress_typesafe(*p, state);
123}
124#endif
125
126int devt_compare_func(const dev_t *a, const dev_t *b) {
127 int r;
128
129 r = CMP(major(*a), major(*b));
130 if (r != 0)
131 return r;
132
133 return CMP(minor(*a), minor(*b));
134}
135
136DEFINE_HASH_OPS(devt_hash_ops, dev_t, devt_hash_func, devt_compare_func);