diff options
Diffstat (limited to 'src/triplet.c')
-rw-r--r-- | src/triplet.c | 104 |
1 files changed, 97 insertions, 7 deletions
diff --git a/src/triplet.c b/src/triplet.c index 79ca8c2..05b7536 100644 --- a/src/triplet.c +++ b/src/triplet.c | |||
@@ -29,13 +29,13 @@ hash_triplet_hasher (void *data, unsigned long n_buckets) | |||
29 | /* Compare two strings for equality. */ | 29 | /* Compare two strings for equality. */ |
30 | static int | 30 | static int |
31 | hash_triplet_compare (void const *data1, void const *data2) | 31 | hash_triplet_compare (void const *data1, void const *data2) |
32 | { | 32 | { |
33 | struct file_triplet const *t1 = data1; | 33 | struct file_triplet const *t1 = data1; |
34 | struct file_triplet const *t2 = data2; | 34 | struct file_triplet const *t2 = data2; |
35 | return strcmp (t1->name, t2->name); | 35 | return t1->spool == t2->spool && strcmp (t1->name, t2->name); |
36 | } | 36 | } |
37 | 37 | ||
38 | /* Reclaim memory storage associated with a table entry */ | 38 | /* Reclaim memory storage associated with a table entry */ |
39 | void | 39 | void |
40 | hash_triplet_free (void *data) | 40 | hash_triplet_free (void *data) |
41 | { | 41 | { |
@@ -95,12 +95,13 @@ register_file (struct file_info *finfo, const struct spool *spool) | |||
95 | grecs_alloc_die (); | 95 | grecs_alloc_die (); |
96 | } | 96 | } |
97 | 97 | ||
98 | key.name = grecs_malloc (finfo->root_len + 1); | 98 | key.name = grecs_malloc (finfo->root_len + 1); |
99 | memcpy (key.name, finfo->name, finfo->root_len); | 99 | memcpy (key.name, finfo->name, finfo->root_len); |
100 | key.name[finfo->root_len] = 0; | 100 | key.name[finfo->root_len] = 0; |
101 | key.spool = spool; | ||
101 | 102 | ||
102 | ret = grecs_symtab_lookup_or_install (triplet_table, &key, &install); | 103 | ret = grecs_symtab_lookup_or_install (triplet_table, &key, &install); |
103 | if (!ret) | 104 | if (!ret) |
104 | grecs_alloc_die (); | 105 | grecs_alloc_die (); |
105 | free (key.name); | 106 | free (key.name); |
106 | if (install) | 107 | if (install) |
@@ -108,12 +109,34 @@ register_file (struct file_info *finfo, const struct spool *spool) | |||
108 | ret->spool = spool; | 109 | ret->spool = spool; |
109 | ret->acc = txtacc_create (); | 110 | ret->acc = txtacc_create (); |
110 | } | 111 | } |
111 | ret->file[finfo->type] = *finfo; | 112 | ret->file[finfo->type] = *finfo; |
112 | } | 113 | } |
113 | 114 | ||
115 | struct file_triplet * | ||
116 | triplet_lookup (struct spool *spool, const char *name) | ||
117 | { | ||
118 | struct file_triplet key, *ret; | ||
119 | struct file_info finfo; | ||
120 | |||
121 | if (!triplet_table) | ||
122 | return NULL; | ||
123 | |||
124 | parse_file_name (name, &finfo); | ||
125 | |||
126 | key.name = grecs_malloc (finfo.root_len + 1); | ||
127 | memcpy (key.name, finfo.name, finfo.root_len); | ||
128 | key.name[finfo.root_len] = 0; | ||
129 | key.spool = spool; | ||
130 | |||
131 | ret = grecs_symtab_lookup_or_install (triplet_table, &key, NULL); | ||
132 | file_info_cleanup (&finfo); | ||
133 | |||
134 | return ret; | ||
135 | } | ||
136 | |||
114 | /* Return true if any part of the triplet TRP was modified more than | 137 | /* Return true if any part of the triplet TRP was modified more than |
115 | TTL seconds ago */ | 138 | TTL seconds ago */ |
116 | static int | 139 | static int |
117 | triplet_expired_p (struct file_triplet *trp, time_t ttl) | 140 | triplet_expired_p (struct file_triplet *trp, time_t ttl) |
118 | { | 141 | { |
119 | int i; | 142 | int i; |
@@ -144,27 +167,26 @@ enum triplet_state | |||
144 | triplet_incomplete, /* Incomplete triplet: some files are missing */ | 167 | triplet_incomplete, /* Incomplete triplet: some files are missing */ |
145 | triplet_bad, /* Bad triplet. Should be removed immediately. */ | 168 | triplet_bad, /* Bad triplet. Should be removed immediately. */ |
146 | }; | 169 | }; |
147 | 170 | ||
148 | 171 | ||
149 | static enum triplet_state | 172 | static enum triplet_state |
150 | check_triplet_state (struct file_triplet *trp) | 173 | check_triplet_state (struct file_triplet *trp, int noauth) |
151 | { | 174 | { |
152 | if (trp->file[file_directive].name) | 175 | if (trp->file[file_directive].name) |
153 | { | 176 | { |
154 | if (verify_directive_file (trp)) | 177 | if (verify_directive_file (trp, noauth)) |
155 | return triplet_bad; | 178 | return triplet_bad; |
156 | 179 | ||
157 | if (trp->file[file_dist].name == 0 | 180 | if (trp->file[file_dist].name == 0 |
158 | && trp->file[file_signature].name == 0) | 181 | && trp->file[file_signature].name == 0) |
159 | { | 182 | { |
160 | if (directive_get_value (trp, "filename", NULL)) | 183 | if (directive_get_value (trp, "filename", NULL)) |
161 | return triplet_directive; | 184 | return triplet_directive; |
162 | } | 185 | } |
163 | else if (trp->file[file_dist].name | 186 | else if (trp->file[file_dist].name && trp->file[file_signature].name) |
164 | && trp->file[file_signature].name) | ||
165 | { | 187 | { |
166 | if (trp->file[file_dist].sb.st_uid == | 188 | if (trp->file[file_dist].sb.st_uid == |
167 | trp->file[file_signature].sb.st_uid | 189 | trp->file[file_signature].sb.st_uid |
168 | && trp->file[file_dist].sb.st_uid == | 190 | && trp->file[file_dist].sb.st_uid == |
169 | trp->file[file_directive].sb.st_uid) | 191 | trp->file[file_directive].sb.st_uid) |
170 | return triplet_complete; | 192 | return triplet_complete; |
@@ -209,13 +231,13 @@ triplet_processor (void *data, void *proc_data) | |||
209 | logmsg (LOG_DEBUG, "FILE %s, DIST=%s, SIG=%s, DIRECTIVE=%s", | 231 | logmsg (LOG_DEBUG, "FILE %s, DIST=%s, SIG=%s, DIRECTIVE=%s", |
210 | trp->name, | 232 | trp->name, |
211 | SP (trp->file[file_dist].name), | 233 | SP (trp->file[file_dist].name), |
212 | SP (trp->file[file_signature].name), | 234 | SP (trp->file[file_signature].name), |
213 | SP (trp->file[file_directive].name)); | 235 | SP (trp->file[file_directive].name)); |
214 | 236 | ||
215 | switch (check_triplet_state (trp)) | 237 | switch (check_triplet_state (trp, 0)) |
216 | { | 238 | { |
217 | case triplet_directive: | 239 | case triplet_directive: |
218 | case triplet_complete: | 240 | case triplet_complete: |
219 | if (debug_level) | 241 | if (debug_level) |
220 | logmsg (LOG_DEBUG, _("processing triplet `%s'"), trp->name); | 242 | logmsg (LOG_DEBUG, _("processing triplet `%s'"), trp->name); |
221 | if (process_directives (trp)) | 243 | if (process_directives (trp)) |
@@ -243,17 +265,19 @@ triplet_processor (void *data, void *proc_data) | |||
243 | 265 | ||
244 | return 0; | 266 | return 0; |
245 | } | 267 | } |
246 | 268 | ||
247 | /* Process all triplets from the table according to the SPOOL */ | 269 | /* Process all triplets from the table according to the SPOOL */ |
248 | void | 270 | void |
249 | enumerate_triplets (const struct spool *spool) | 271 | spool_commit_triplets (struct spool *spool) |
250 | { | 272 | { |
251 | if (debug_level) | 273 | if (debug_level) |
252 | logmsg (LOG_DEBUG, _("processing spool %s (%s)"), | 274 | logmsg (LOG_DEBUG, _("processing spool %s (%s)"), |
253 | spool->tag, mu_url_to_string (spool->dest_url)); | 275 | spool->tag, mu_url_to_string (spool->dest_url)); |
276 | if (spool_open_dictionaries (spool)) | ||
277 | return; | ||
254 | if (triplet_table) | 278 | if (triplet_table) |
255 | { | 279 | { |
256 | grecs_symtab_enumerate (triplet_table, triplet_processor, NULL); | 280 | grecs_symtab_enumerate (triplet_table, triplet_processor, NULL); |
257 | grecs_symtab_clear (triplet_table); | 281 | grecs_symtab_clear (triplet_table); |
258 | } | 282 | } |
259 | } | 283 | } |
@@ -261,12 +285,78 @@ enumerate_triplets (const struct spool *spool) | |||
261 | size_t | 285 | size_t |
262 | count_collected_triplets () | 286 | count_collected_triplets () |
263 | { | 287 | { |
264 | return triplet_table ? grecs_symtab_count_entries (triplet_table) : 0; | 288 | return triplet_table ? grecs_symtab_count_entries (triplet_table) : 0; |
265 | } | 289 | } |
266 | 290 | ||
291 | static int | ||
292 | triplet_counter (void *data, void *proc_data) | ||
293 | { | ||
294 | struct file_triplet *trp = data; | ||
295 | size_t *cp = proc_data; | ||
296 | |||
297 | if (debug_level) | ||
298 | logmsg (LOG_DEBUG, "FILE %s, DIST=%s, SIG=%s, DIRECTIVE=%s", | ||
299 | trp->name, | ||
300 | SP (trp->file[file_dist].name), | ||
301 | SP (trp->file[file_signature].name), | ||
302 | SP (trp->file[file_directive].name)); | ||
303 | |||
304 | switch (check_triplet_state (trp, 1)) | ||
305 | { | ||
306 | case triplet_directive: | ||
307 | case triplet_complete: | ||
308 | case triplet_bad: | ||
309 | ++*cp; | ||
310 | case triplet_incomplete: | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | if (triplet_expired_p (trp, trp->spool->file_sweep_time)) | ||
315 | ++*cp;//FIXME | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | size_t | ||
321 | count_processable_triplets () | ||
322 | { | ||
323 | size_t count = 0; | ||
324 | if (triplet_table) | ||
325 | grecs_symtab_enumerate (triplet_table, triplet_counter, &count); | ||
326 | return count; | ||
327 | } | ||
328 | |||
329 | void | ||
330 | triplet_remove_file (struct spool *spool, const char *name) | ||
331 | { | ||
332 | struct file_triplet *tp = triplet_lookup (spool, name); | ||
333 | int i, n = 0; | ||
334 | |||
335 | if (!tp) | ||
336 | return; | ||
337 | |||
338 | for (i = 0; i < FILE_TYPE_COUNT; i++) | ||
339 | { | ||
340 | if (!tp->file[i].name) | ||
341 | /* nothing */; | ||
342 | else if (strcmp (tp->file[i].name, name) == 0) | ||
343 | file_info_cleanup (&tp->file[i]); | ||
344 | else | ||
345 | n++; | ||
346 | } | ||
347 | |||
348 | if (!n) | ||
349 | { | ||
350 | if (debug_level > 0) | ||
351 | logmsg (LOG_DEBUG, "deleting empty triplet (%s/%s)", | ||
352 | spool->source_dir, name); | ||
353 | grecs_symtab_remove (triplet_table, tp); | ||
354 | } | ||
355 | } | ||
356 | |||
267 |