]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
d4205751 LP |
2 | /*** |
3 | This file is part of systemd. | |
4 | ||
5 | Copyright 2012 Lennart Poettering | |
844ec79b | 6 | Copyright 2013 Zbigniew Jędrzejewski-Szmek |
d4205751 LP |
7 | ***/ |
8 | ||
844ec79b | 9 | #include <errno.h> |
2d5bdf5b | 10 | #include <fcntl.h> |
cf0fbc49 TA |
11 | #include <locale.h> |
12 | #include <unistd.h> | |
d4205751 | 13 | |
07630cea LP |
14 | #include "sd-messages.h" |
15 | ||
b5efdb8a | 16 | #include "alloc-util.h" |
3ffd4af2 LP |
17 | #include "catalog.h" |
18 | #include "fd-util.h" | |
0d39fa9c | 19 | #include "fileio.h" |
d4205751 | 20 | #include "log.h" |
844ec79b | 21 | #include "macro.h" |
07630cea | 22 | #include "string-util.h" |
3ffd4af2 | 23 | #include "util.h" |
d4205751 | 24 | |
143bfdaf HHPF |
25 | static const char *catalog_dirs[] = { |
26 | CATALOG_DIR, | |
27 | NULL, | |
28 | }; | |
29 | ||
30 | static const char *no_catalog_dirs[] = { | |
31 | "/bin/hopefully/with/no/catalog", | |
32 | NULL | |
33 | }; | |
34 | ||
9d85882a | 35 | static Hashmap * test_import(const char* contents, ssize_t size, int code) { |
844ec79b ZJS |
36 | int r; |
37 | char name[] = "/tmp/test-catalog.XXXXXX"; | |
2d5bdf5b | 38 | _cleanup_close_ int fd; |
9d85882a SW |
39 | Hashmap *h; |
40 | ||
41 | if (size < 0) | |
42 | size = strlen(contents); | |
43 | ||
44 | assert_se(h = hashmap_new(&catalog_hash_ops)); | |
2d5bdf5b | 45 | |
646853bd | 46 | fd = mkostemp_safe(name); |
787784c4 | 47 | assert_se(fd >= 0); |
844ec79b ZJS |
48 | assert_se(write(fd, contents, size) == size); |
49 | ||
dbae138d | 50 | r = catalog_import_file(h, name); |
787784c4 | 51 | assert_se(r == code); |
844ec79b ZJS |
52 | |
53 | unlink(name); | |
844ec79b | 54 | |
9d85882a SW |
55 | return h; |
56 | } | |
844ec79b | 57 | |
9d85882a SW |
58 | static void test_catalog_import_invalid(void) { |
59 | _cleanup_hashmap_free_free_free_ Hashmap *h = NULL; | |
844ec79b | 60 | |
9d85882a | 61 | h = test_import("xxx", -1, -EINVAL); |
787784c4 | 62 | assert_se(hashmap_isempty(h)); |
9d85882a | 63 | } |
844ec79b | 64 | |
9d85882a SW |
65 | static void test_catalog_import_badid(void) { |
66 | _cleanup_hashmap_free_free_free_ Hashmap *h = NULL; | |
67 | const char *input = | |
844ec79b ZJS |
68 | "-- 0027229ca0644181a76c4e92458afaff dededededededededededededededede\n" \ |
69 | "Subject: message\n" \ | |
70 | "\n" \ | |
9d85882a SW |
71 | "payload\n"; |
72 | h = test_import(input, -1, -EINVAL); | |
73 | } | |
844ec79b | 74 | |
9d85882a SW |
75 | static void test_catalog_import_one(void) { |
76 | _cleanup_hashmap_free_free_free_ Hashmap *h = NULL; | |
77 | char *payload; | |
78 | Iterator j; | |
844ec79b | 79 | |
9d85882a | 80 | const char *input = |
844ec79b ZJS |
81 | "-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \ |
82 | "Subject: message\n" \ | |
83 | "\n" \ | |
9d85882a SW |
84 | "payload\n"; |
85 | const char *expect = | |
86 | "Subject: message\n" \ | |
87 | "\n" \ | |
88 | "payload\n"; | |
844ec79b | 89 | |
9d85882a | 90 | h = test_import(input, -1, 0); |
787784c4 | 91 | assert_se(hashmap_size(h) == 1); |
d4205751 | 92 | |
9d85882a | 93 | HASHMAP_FOREACH(payload, h, j) { |
06466a7f ZJS |
94 | printf("expect: %s\n", expect); |
95 | printf("actual: %s\n", payload); | |
9d85882a SW |
96 | assert_se(streq(expect, payload)); |
97 | } | |
844ec79b ZJS |
98 | } |
99 | ||
c059b62f SW |
100 | static void test_catalog_import_merge(void) { |
101 | _cleanup_hashmap_free_free_free_ Hashmap *h = NULL; | |
102 | char *payload; | |
103 | Iterator j; | |
104 | ||
105 | const char *input = | |
106 | "-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \ | |
107 | "Subject: message\n" \ | |
108 | "Defined-By: me\n" \ | |
109 | "\n" \ | |
110 | "payload\n" \ | |
111 | "\n" \ | |
112 | "-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \ | |
113 | "Subject: override subject\n" \ | |
114 | "X-Header: hello\n" \ | |
115 | "\n" \ | |
116 | "override payload\n"; | |
117 | ||
118 | const char *combined = | |
119 | "Subject: override subject\n" \ | |
120 | "X-Header: hello\n" \ | |
121 | "Subject: message\n" \ | |
122 | "Defined-By: me\n" \ | |
123 | "\n" \ | |
124 | "override payload\n"; | |
125 | ||
126 | h = test_import(input, -1, 0); | |
127 | assert_se(hashmap_size(h) == 1); | |
128 | ||
129 | HASHMAP_FOREACH(payload, h, j) { | |
130 | assert_se(streq(combined, payload)); | |
131 | } | |
132 | } | |
133 | ||
134 | static void test_catalog_import_merge_no_body(void) { | |
135 | _cleanup_hashmap_free_free_free_ Hashmap *h = NULL; | |
136 | char *payload; | |
137 | Iterator j; | |
138 | ||
139 | const char *input = | |
140 | "-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \ | |
141 | "Subject: message\n" \ | |
142 | "Defined-By: me\n" \ | |
143 | "\n" \ | |
144 | "payload\n" \ | |
145 | "\n" \ | |
146 | "-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \ | |
147 | "Subject: override subject\n" \ | |
148 | "X-Header: hello\n" \ | |
149 | "\n"; | |
150 | ||
151 | const char *combined = | |
152 | "Subject: override subject\n" \ | |
153 | "X-Header: hello\n" \ | |
154 | "Subject: message\n" \ | |
155 | "Defined-By: me\n" \ | |
156 | "\n" \ | |
157 | "payload\n"; | |
158 | ||
159 | h = test_import(input, -1, 0); | |
160 | assert_se(hashmap_size(h) == 1); | |
161 | ||
162 | HASHMAP_FOREACH(payload, h, j) { | |
163 | assert_se(streq(combined, payload)); | |
164 | } | |
165 | } | |
166 | ||
844ec79b ZJS |
167 | static const char* database = NULL; |
168 | ||
169 | static void test_catalog_update(void) { | |
2d5bdf5b | 170 | static char name[] = "/tmp/test-catalog.XXXXXX"; |
844ec79b | 171 | int r; |
844ec79b | 172 | |
646853bd | 173 | r = mkostemp_safe(name); |
787784c4 | 174 | assert_se(r >= 0); |
844ec79b ZJS |
175 | |
176 | database = name; | |
177 | ||
178 | /* Test what happens if there are no files. */ | |
179 | r = catalog_update(database, NULL, NULL); | |
787784c4 | 180 | assert_se(r >= 0); |
844ec79b | 181 | |
143bfdaf HHPF |
182 | /* Test what happens if there are no files in the directory. */ |
183 | r = catalog_update(database, NULL, no_catalog_dirs); | |
787784c4 | 184 | assert_se(r >= 0); |
143bfdaf HHPF |
185 | |
186 | /* Make sure that we at least have some files loaded or the | |
187 | catalog_list below will fail. */ | |
188 | r = catalog_update(database, NULL, catalog_dirs); | |
787784c4 | 189 | assert_se(r >= 0); |
844ec79b ZJS |
190 | } |
191 | ||
c7332b08 | 192 | static void test_catalog_file_lang(void) { |
4b8268f8 | 193 | _cleanup_free_ char *lang = NULL, *lang2 = NULL, *lang3 = NULL, *lang4 = NULL; |
c7332b08 ZJS |
194 | |
195 | assert_se(catalog_file_lang("systemd.de_DE.catalog", &lang) == 1); | |
196 | assert_se(streq(lang, "de_DE")); | |
197 | ||
198 | assert_se(catalog_file_lang("systemd..catalog", &lang2) == 0); | |
199 | assert_se(lang2 == NULL); | |
200 | ||
201 | assert_se(catalog_file_lang("systemd.fr.catalog", &lang2) == 1); | |
202 | assert_se(streq(lang2, "fr")); | |
203 | ||
204 | assert_se(catalog_file_lang("systemd.fr.catalog.gz", &lang3) == 0); | |
205 | assert_se(lang3 == NULL); | |
206 | ||
207 | assert_se(catalog_file_lang("systemd.01234567890123456789012345678901.catalog", &lang3) == 0); | |
208 | assert_se(lang3 == NULL); | |
209 | ||
210 | assert_se(catalog_file_lang("systemd.0123456789012345678901234567890.catalog", &lang3) == 1); | |
211 | assert_se(streq(lang3, "0123456789012345678901234567890")); | |
4b8268f8 ZJS |
212 | |
213 | assert_se(catalog_file_lang("/x/y/systemd.catalog", &lang4) == 0); | |
214 | assert_se(lang4 == NULL); | |
215 | ||
216 | assert_se(catalog_file_lang("/x/y/systemd.ru_RU.catalog", &lang4) == 1); | |
217 | assert_se(streq(lang4, "ru_RU")); | |
c7332b08 ZJS |
218 | } |
219 | ||
844ec79b | 220 | int main(int argc, char *argv[]) { |
d4205751 | 221 | _cleanup_free_ char *text = NULL; |
844ec79b | 222 | int r; |
d4205751 LP |
223 | |
224 | setlocale(LC_ALL, "de_DE.UTF-8"); | |
225 | ||
e3b9d9c8 ZJS |
226 | log_parse_environment(); |
227 | log_open(); | |
d4205751 | 228 | |
4b8268f8 ZJS |
229 | test_catalog_file_lang(); |
230 | ||
9d85882a SW |
231 | test_catalog_import_invalid(); |
232 | test_catalog_import_badid(); | |
233 | test_catalog_import_one(); | |
c059b62f SW |
234 | test_catalog_import_merge(); |
235 | test_catalog_import_merge_no_body(); | |
d4205751 | 236 | |
844ec79b | 237 | test_catalog_update(); |
54b7254c | 238 | |
844ec79b ZJS |
239 | r = catalog_list(stdout, database, true); |
240 | assert_se(r >= 0); | |
d4205751 | 241 | |
844ec79b ZJS |
242 | r = catalog_list(stdout, database, false); |
243 | assert_se(r >= 0); | |
d4205751 | 244 | |
844ec79b | 245 | assert_se(catalog_get(database, SD_MESSAGE_COREDUMP, &text) >= 0); |
d4205751 LP |
246 | printf(">>>%s<<<\n", text); |
247 | ||
844ec79b ZJS |
248 | if (database) |
249 | unlink(database); | |
d4205751 LP |
250 | |
251 | return 0; | |
252 | } |