Coverage Report

Created: 2026-09-01 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pigeonhole/src/lib-sieve/sieve-storage.c
Line
Count
Source
1
/* Copyright (c) Pigeonhole authors, see top-level COPYING file */
2
3
#include "lib.h"
4
#include "array.h"
5
#include "str.h"
6
#include "str-sanitize.h"
7
#include "hash.h"
8
#include "home-expand.h"
9
#include "eacces-error.h"
10
#include "mkdir-parents.h"
11
#include "ioloop.h"
12
#include "settings.h"
13
#include "settings-consts.h"
14
15
#include "sieve-common.h"
16
#include "sieve-error-private.h"
17
18
#include "sieve-script-private.h"
19
#include "sieve-storage-private.h"
20
#include "sieve-rusage.h"
21
22
#include <sys/types.h>
23
#include <sys/stat.h>
24
#include <unistd.h>
25
#include <time.h>
26
#include <utime.h>
27
28
struct event_category event_category_sieve_storage = {
29
  .parent = &event_category_sieve,
30
  .name = "sieve-storage",
31
};
32
33
/*
34
 * Storage name
35
 */
36
37
bool sieve_storage_name_is_valid(const char *name)
38
0
{
39
0
  return sieve_script_name_is_valid(name);
40
0
}
41
42
/*
43
 * Storage class
44
 */
45
46
struct sieve_storage_class_registry {
47
  ARRAY_TYPE(sieve_storage_class) storage_classes;
48
};
49
50
void sieve_storages_init(struct sieve_instance *svinst)
51
0
{
52
0
  svinst->storage_reg = p_new(svinst->pool,
53
0
            struct sieve_storage_class_registry, 1);
54
0
  p_array_init(&svinst->storage_reg->storage_classes, svinst->pool, 8);
55
56
0
  sieve_storage_class_register(svinst, &sieve_file_storage);
57
0
  sieve_storage_class_register(svinst, &sieve_dict_storage);
58
#if defined(SIEVE_BUILTIN_LDAP) || defined(PLUGIN_BUILD)
59
  sieve_storage_class_register(svinst, &sieve_ldap_storage);
60
#endif
61
0
}
62
63
void sieve_storages_deinit(struct sieve_instance *svinst ATTR_UNUSED)
64
0
{
65
  /* nothing yet */
66
0
}
67
68
void sieve_storage_class_register(struct sieve_instance *svinst,
69
          const struct sieve_storage *storage_class)
70
0
{
71
0
  struct sieve_storage_class_registry *reg = svinst->storage_reg;
72
0
  const struct sieve_storage *old_class;
73
74
0
  old_class = sieve_storage_class_find(svinst,
75
0
               storage_class->driver_name);
76
0
  if (old_class != NULL) {
77
0
    if (old_class->v.alloc == NULL) {
78
      /* replacing a "support not compiled in" storage class
79
       */
80
0
      sieve_storage_class_unregister(svinst, old_class);
81
0
    } else {
82
0
      i_panic("sieve_storage_class_register(%s): "
83
0
        "Already registered",
84
0
        storage_class->driver_name);
85
0
    }
86
0
  }
87
88
0
  array_append(&reg->storage_classes, &storage_class, 1);
89
0
}
90
91
void sieve_storage_class_unregister(struct sieve_instance *svinst,
92
            const struct sieve_storage *storage_class)
93
0
{
94
0
  struct sieve_storage_class_registry *reg = svinst->storage_reg;
95
0
  const struct sieve_storage *const *classes;
96
0
  unsigned int i, count;
97
98
0
  classes = array_get(&reg->storage_classes, &count);
99
0
  for (i = 0; i < count; i++) {
100
0
    if (classes[i] == storage_class) {
101
0
      array_delete(&reg->storage_classes, i, 1);
102
0
      break;
103
0
    }
104
0
  }
105
0
}
106
107
const struct sieve_storage *
108
sieve_storage_class_find(struct sieve_instance *svinst, const char *name)
109
0
{
110
0
  struct sieve_storage_class_registry *reg = svinst->storage_reg;
111
0
  const struct sieve_storage *const *classes;
112
0
  unsigned int i, count;
113
114
0
  i_assert(name != NULL);
115
116
0
  classes = array_get(&reg->storage_classes, &count);
117
0
  for (i = 0; i < count; i++) {
118
0
    if (strcasecmp(classes[i]->driver_name, name) == 0)
119
0
      return classes[i];
120
0
  }
121
0
  return NULL;
122
0
}
123
124
bool sieve_storage_class_exists(struct sieve_instance *svinst,
125
        const char *name)
126
0
{
127
0
  return (sieve_storage_class_find(svinst, name) != NULL);
128
0
}
129
130
/*
131
 * Storage event
132
 */
133
134
static void
135
sieve_storage_update_event_prefix(struct event *event, const char *storage_name,
136
          bool is_default)
137
0
{
138
0
  string_t *prefix = t_str_new(128);
139
140
0
  str_append(prefix, "storage");
141
0
  if (storage_name != NULL && *storage_name != '\0') {
142
0
    str_append_c(prefix, ' ');
143
0
    str_append(prefix, storage_name);
144
0
  }
145
0
  if (is_default)
146
0
    str_append(prefix, " (default)");
147
0
  str_append(prefix, ": ");
148
0
  event_set_append_log_prefix(event, str_c(prefix));
149
0
}
150
151
static struct event *
152
sieve_storage_create_event(struct sieve_instance *svinst,
153
         struct event *event_parent,
154
         const char *storage_name)
155
0
{
156
0
  struct event *event;
157
158
0
  event = event_create(event_parent == NULL ?
159
0
           svinst->event : event_parent);
160
0
  if (event_parent != svinst->event)
161
0
    event_add_category(event, &event_category_sieve);
162
0
  event_add_category(event, &event_category_sieve_storage);
163
164
0
  sieve_storage_update_event_prefix(event, storage_name, FALSE);
165
0
  return event;
166
0
}
167
168
static struct event *
169
sieve_storage_create_driver_event(struct event *event_parent,
170
          const char *driver_name)
171
0
{
172
0
  struct event *event;
173
174
0
  event = event_create(event_parent);
175
0
  event_add_str(event, "driver", driver_name);
176
0
  event_set_append_log_prefix(event,
177
0
    t_strdup_printf("%s: ", driver_name));
178
179
0
  return event;
180
0
}
181
182
/*
183
 * Storage instance
184
 */
185
186
static int
187
sieve_storage_alloc_from_class(struct sieve_instance *svinst,
188
             struct event *event,
189
             const struct sieve_storage *storage_class,
190
             const char *cause, const char *script_type,
191
             const char *storage_name,
192
             const char *script_name,
193
             enum sieve_storage_flags flags,
194
             struct sieve_storage **storage_r,
195
             enum sieve_error *error_code_r,
196
             const char **error_r)
197
0
{
198
0
  struct sieve_storage *storage;
199
200
0
  i_assert(svinst->username != NULL);
201
202
0
  if (storage_class->v.alloc == NULL) {
203
0
    e_error(event, "Support not compiled in for this driver");
204
0
    sieve_error_create_script_not_found(
205
0
      script_name, error_code_r, error_r);
206
0
    return -1;
207
0
  }
208
209
0
  if ((flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0 &&
210
0
      !storage_class->allows_synchronization) {
211
0
    e_error(event, "Storage does not support synchronization");
212
0
    sieve_error_create_internal(error_code_r, error_r);
213
0
    return -1;
214
0
  }
215
0
  if ((flags & SIEVE_STORAGE_FLAG_READWRITE) != 0 &&
216
0
      storage_class->v.save_init == NULL) {
217
0
    e_error(event, "Storage does not support write access");
218
0
    sieve_error_create_internal(error_code_r, error_r);
219
0
    return -1;
220
0
  }
221
222
0
  storage = storage_class->v.alloc();
223
0
  storage->storage_class = storage_class;
224
0
  storage->refcount = 1;
225
0
  storage->svinst = svinst;
226
0
  storage->cause = p_strdup(storage->pool, cause);
227
0
  storage->type = p_strdup(storage->pool, script_type);
228
0
  storage->script_name = p_strdup(storage->pool, script_name);
229
0
  storage->flags = flags;
230
231
0
  if (storage_name != NULL && *storage_name != '\0')
232
0
    storage->name = p_strdup(storage->pool, storage_name);
233
0
  else {
234
0
    storage->name = p_strconcat(
235
0
      storage->pool, "auto:", storage->type, NULL);
236
0
  }
237
238
0
  if (strcasecmp(script_type, SIEVE_STORAGE_TYPE_PERSONAL) == 0)
239
0
    storage->is_personal = TRUE;
240
241
0
  storage->event = event;
242
0
  event_ref(event);
243
244
0
  *storage_r = storage;
245
0
  return 0;
246
0
}
247
248
int sieve_storage_alloc(struct sieve_instance *svinst,
249
      struct event *event_parent,
250
      const struct sieve_storage *storage_class,
251
      const char *cause, const char *script_type,
252
      const char *storage_name, const char *script_name,
253
      enum sieve_storage_flags flags,
254
      struct sieve_storage **storage_r,
255
      enum sieve_error *error_code_r, const char **error_r)
256
0
{
257
0
  struct event *storage_event, *event;
258
0
  int ret;
259
260
0
  *storage_r = NULL;
261
0
  sieve_error_args_init(&error_code_r, &error_r);
262
263
0
  storage_event = sieve_storage_create_event(svinst, event_parent,
264
0
               storage_name);
265
0
  event = sieve_storage_create_driver_event(storage_event,
266
0
              storage_class->driver_name);
267
0
  event_unref(&storage_event);
268
269
0
  ret = sieve_storage_alloc_from_class(svinst, event, storage_class,
270
0
               cause, script_type,
271
0
               storage_name, script_name, flags,
272
0
               storage_r, error_code_r, error_r);
273
274
0
  event_unref(&event);
275
276
0
  return ret;
277
0
}
278
279
int sieve_storage_alloc_with_settings(struct sieve_instance *svinst,
280
              struct event *event_parent,
281
              const struct sieve_storage *storage_class,
282
              const char *cause,
283
              const struct sieve_storage_settings *set,
284
              enum sieve_storage_flags flags,
285
              struct sieve_storage **storage_r,
286
              enum sieve_error *error_code_r,
287
              const char **error_r)
288
0
{
289
0
  struct sieve_storage *storage;
290
0
  int ret;
291
292
0
  *storage_r = NULL;
293
0
  sieve_error_args_init(&error_code_r, &error_r);
294
295
0
  ret = sieve_storage_alloc_from_class(svinst, event_parent,
296
0
               storage_class,
297
0
               cause, set->script_type,
298
0
               set->script_storage,
299
0
               set->script_name, flags,
300
0
               &storage, error_code_r, error_r);
301
0
  if (ret < 0)
302
0
    return -1;
303
304
0
  const char *bin_path = set->script_bin_path;
305
306
0
  if (sieve_storage_get_full_path(storage, bin_path, &bin_path) < 0) {
307
0
    sieve_storage_set_critical(
308
0
      storage,
309
0
      "Binary storage path '%s' is relative to home directory, "
310
0
      "but home directory is not available.", bin_path);
311
0
    return -1;
312
0
  }
313
314
0
  storage->bin_path = p_strdup_empty(storage->pool, bin_path);
315
0
  storage->max_storage = set->quota_storage_size;
316
0
  storage->max_scripts = set->quota_script_count;
317
318
0
  if (storage->bin_path != NULL) {
319
0
    e_debug(storage->event, "Directory for binaries: %s",
320
0
      storage->bin_path);
321
0
  }
322
0
  if (storage->max_storage != SET_SIZE_UNLIMITED) {
323
0
    e_debug(storage->event, "quota: "
324
0
      "Storage limit: %"PRIuUOFF_T" bytes",
325
0
      storage->max_storage);
326
0
  }
327
0
  if (storage->max_scripts != SET_UINT_UNLIMITED) {
328
0
    e_debug(storage->event, "quota: "
329
0
      "Script count limit: %u scripts",
330
0
      storage->max_scripts);
331
0
  }
332
333
0
  *storage_r = storage;
334
0
  return 0;
335
0
}
336
337
static int
338
sieve_storage_alloc_from_settings(struct sieve_instance *svinst,
339
          struct event *event_parent, const char *cause,
340
          const struct sieve_storage_settings *set,
341
          enum sieve_storage_flags flags,
342
          struct sieve_storage **storage_r,
343
          enum sieve_error *error_code_r,
344
          const char **error_r)
345
0
{
346
0
  const struct sieve_storage *storage_class;
347
0
  struct event *event = event_parent;
348
0
  int ret;
349
350
0
  *storage_r = NULL;
351
352
0
  if (!sieve_storage_settings_match_script_cause(set, cause))
353
0
    return 0;
354
355
0
  storage_class = sieve_storage_class_find(svinst, set->script_driver);
356
  // FIXME: add support for automatic module loading (no such modules yet)
357
0
  if (storage_class == NULL) {
358
0
    e_error(event, "Unknown storage driver: %s",
359
0
      set->script_driver);
360
0
    sieve_error_create_script_not_found(set->script_name,
361
0
                error_code_r, error_r);
362
0
    event_unref(&event);
363
0
    return -1;
364
0
  }
365
366
0
  event = sieve_storage_create_driver_event(event_parent,
367
0
              storage_class->driver_name);
368
369
0
  ret = sieve_storage_alloc_with_settings(svinst, event, storage_class,
370
0
            cause, set, flags,
371
0
            storage_r, error_code_r,
372
0
            error_r);
373
374
0
  event_unref(&event);
375
376
0
  if (ret < 0)
377
0
    return -1;
378
0
  return 1;
379
0
}
380
381
static int
382
sieve_storage_autodetect(struct sieve_instance *svinst, struct event *event,
383
       const char *cause, const char *type,
384
       const struct sieve_storage_settings *set,
385
       enum sieve_storage_flags flags,
386
       struct sieve_storage **storage_r,
387
       enum sieve_error *error_code_r, const char **error_r)
388
0
{
389
0
  struct sieve_storage_class_registry *reg = svinst->storage_reg;
390
0
  int ret;
391
392
0
  *storage_r = NULL;
393
0
  sieve_error_args_init(&error_code_r, &error_r);
394
395
0
  if (!sieve_storage_settings_match_script_cause(set, cause))
396
0
    return 0;
397
0
  if (!sieve_storage_settings_match_script_type(set, type))
398
0
    return 0;
399
400
0
  const struct sieve_storage *const *classes;
401
0
  unsigned int i, count;
402
403
0
  classes = array_get(&reg->storage_classes, &count);
404
0
  ret = 0;
405
0
  for (i = 0; i < count; i++) {
406
0
    if (classes[i]->v.autodetect == NULL)
407
0
      continue;
408
0
    if (set->script_driver[0] != '\0' &&
409
0
        strcasecmp(set->script_driver,
410
0
             classes[i]->driver_name) != 0)
411
0
      continue;
412
413
0
    struct event *driver_event =
414
0
      sieve_storage_create_driver_event(
415
0
        event, classes[i]->driver_name);
416
417
0
    *storage_r = NULL;
418
0
    ret = classes[i]->v.autodetect(svinst, driver_event,
419
0
                 cause, set, flags,
420
0
                 storage_r, error_code_r,
421
0
                 error_r);
422
423
0
    event_unref(&driver_event);
424
425
0
    if (ret < 0) {
426
0
      i_assert(*error_code_r != SIEVE_ERROR_NONE);
427
0
      i_assert(*error_r != NULL);
428
0
      if (*error_code_r == SIEVE_ERROR_NOT_FOUND) {
429
0
        *error_code_r = SIEVE_ERROR_NONE;
430
0
        *error_r = NULL;
431
0
        ret = 0;
432
0
      }
433
0
    }
434
0
    i_assert(ret <= 0 || *storage_r != NULL);
435
0
    if (ret != 0)
436
0
      break;
437
0
  }
438
439
0
  if (ret == 0)
440
0
    e_debug(event, "Autodetection failed");
441
0
  return ret;
442
0
}
443
444
static int
445
sieve_storage_autodetect_any(struct sieve_instance *svinst,
446
           struct event *event_parent,
447
           const char *cause, const char *type,
448
           const struct sieve_storage_settings *set,
449
           enum sieve_storage_flags flags,
450
           struct sieve_storage **storage_r,
451
           enum sieve_error *error_code_r,
452
           const char **error_r)
453
0
{
454
0
  struct event *event;
455
0
  int ret;
456
457
0
  event = sieve_storage_create_event(svinst, event_parent, NULL);
458
459
0
  ret = sieve_storage_autodetect(svinst, event, cause, type, set,
460
0
               flags, storage_r, error_code_r, error_r);
461
462
0
  event_unref(&event);
463
0
  return ret;
464
0
}
465
466
static int
467
sieve_storage_init_real(struct sieve_instance *svinst, struct event *event,
468
      const char *cause, const char *type,
469
      const char *storage_name, bool try,
470
      enum sieve_storage_flags flags,
471
      struct sieve_storage **storage_r,
472
      enum sieve_error *error_code_r, const char **error_r)
473
0
{
474
0
  const struct sieve_storage_settings *set;
475
0
  struct sieve_storage *storage;
476
0
  const char *error;
477
0
  int ret;
478
479
0
  if (try) {
480
0
    ret = settings_try_get_filter(
481
0
      event, "sieve_script", storage_name,
482
0
      &sieve_storage_setting_parser_info, 0,
483
0
      &set, &error);
484
0
    if (ret == 0)
485
0
      return 0;
486
0
  } else {
487
0
    ret = settings_get_filter(
488
0
      event, "sieve_script", storage_name,
489
0
      &sieve_storage_setting_parser_info, 0,
490
0
      &set, &error);
491
0
  }
492
0
  if (ret < 0) {
493
0
    e_error(event, "%s", error);
494
0
    sieve_error_create_internal(error_code_r, error_r);
495
0
    return -1;
496
0
  }
497
498
0
  if (!sieve_storage_settings_match_script_type(set, type)) {
499
0
    settings_free(set);
500
0
    return 0;
501
0
  }
502
503
0
  event_add_str(event, "sieve_script", storage_name);
504
0
  settings_event_add_list_filter_name(event, "sieve_script",
505
0
              storage_name);
506
507
0
  if (set->script_driver[0] == '\0') {
508
0
    ret = sieve_storage_autodetect(svinst, event, cause, type,
509
0
                 set, flags, storage_r,
510
0
                 error_code_r, error_r);
511
0
    if (ret != 0) {
512
0
      settings_free(set);
513
0
      return ret;
514
0
    }
515
0
    e_error(event, "sieve_script_driver is empty");
516
0
    sieve_error_create_script_not_found(set->script_name,
517
0
                error_code_r, error_r);
518
0
    settings_free(set);
519
0
    return -1;
520
0
  }
521
522
0
  ret = sieve_storage_alloc_from_settings(svinst, event, cause,
523
0
            set, flags, &storage,
524
0
            error_code_r, error_r);
525
0
  settings_free(set);
526
0
  if (ret <= 0)
527
0
    return ret;
528
0
  i_assert(storage != NULL);
529
0
  i_assert(storage->v.init != NULL);
530
531
0
  T_BEGIN {
532
0
    ret = storage->v.init(storage);
533
0
    i_assert(ret <= 0);
534
0
  } T_END;
535
0
  if (ret < 0) {
536
0
    i_assert(storage->error_code != SIEVE_ERROR_NONE);
537
0
    i_assert(storage->error != NULL);
538
0
    *error_code_r = storage->error_code;
539
0
    *error_r = t_strdup(storage->error);
540
0
    sieve_storage_unref(&storage);
541
0
    return -1;
542
0
  }
543
0
  *storage_r = storage;
544
0
  return 1;
545
0
}
546
547
static int
548
sieve_storage_init(struct sieve_instance *svinst, struct event *event_parent,
549
       const char *cause, const char *type,
550
       const char *storage_name, bool try,
551
       enum sieve_storage_flags flags,
552
       struct sieve_storage **storage_r,
553
       enum sieve_error *error_code_r, const char **error_r)
554
0
{
555
0
  struct event *event;
556
0
  int ret;
557
558
0
  *storage_r = NULL;
559
560
0
  event = sieve_storage_create_event(svinst, event_parent, storage_name);
561
562
0
  ret = sieve_storage_init_real(svinst, event, cause, type,
563
0
              storage_name, try, flags,
564
0
              storage_r, error_code_r, error_r);
565
566
0
  event_unref(&event);
567
568
0
  return ret;
569
0
}
570
571
int sieve_storage_create(struct sieve_instance *svinst,
572
       struct event *event, const char *cause,
573
       const char *storage_name,
574
       enum sieve_storage_flags flags,
575
       struct sieve_storage **storage_r,
576
       enum sieve_error *error_code_r, const char **error_r)
577
0
{
578
0
  struct sieve_storage *storage;
579
0
  int ret;
580
581
0
  *storage_r = NULL;
582
0
  sieve_error_args_init(&error_code_r, &error_r);
583
584
0
  ret = sieve_storage_init(svinst, event, cause, SIEVE_STORAGE_TYPE_ANY,
585
0
         storage_name, TRUE, flags,
586
0
         &storage, error_code_r, error_r);
587
0
  if (ret < 0) {
588
0
    if (*error_code_r != SIEVE_ERROR_NOT_FOUND)
589
0
      return -1;
590
0
    ret = 0;
591
0
  }
592
0
  if (ret == 0) {
593
0
    e_debug(event, "Sieve script storage '%s' not found (cause=%s)",
594
0
      storage_name, cause);
595
0
    sieve_error_create_script_not_found(
596
0
      NULL, error_code_r, error_r);
597
0
    return -1;
598
0
  }
599
0
  i_assert(storage != NULL);
600
0
  *storage_r = storage;
601
0
  return 0;
602
0
}
603
604
int sieve_storage_create_auto(struct sieve_instance *svinst,
605
            struct event *event,
606
            const char *cause, const char *type,
607
            enum sieve_storage_flags flags,
608
            struct sieve_storage **storage_r,
609
            enum sieve_error *error_code_r,
610
            const char **error_r)
611
0
{
612
0
  const struct sieve_storage_settings *storage_set;
613
0
  const char *const *storage_names;
614
0
  unsigned int i, count;
615
0
  const char *error;
616
617
0
  *storage_r = NULL;
618
0
  sieve_error_args_init(&error_code_r, &error_r);
619
620
0
  if (settings_get(event, &sieve_storage_setting_parser_info,
621
0
       SETTINGS_GET_FLAG_SORT_FILTER_ARRAYS,
622
0
       &storage_set, &error) < 0) {
623
0
    e_error(event, "%s", error);
624
0
    sieve_error_create_internal(error_code_r, error_r);
625
0
    return -1;
626
0
  }
627
0
  if (array_is_created(&storage_set->storages))
628
0
    storage_names = array_get(&storage_set->storages, &count);
629
0
  else {
630
0
    storage_names = NULL;
631
0
    count = 0;
632
0
  }
633
634
0
  struct sieve_storage *storage = NULL;
635
0
  int ret = 0;
636
637
0
  for (i = 0; i < count; i++) {
638
0
    ret = sieve_storage_init(svinst, event, cause, type,
639
0
           storage_names[i], FALSE, flags,
640
0
           &storage, error_code_r, error_r);
641
0
    if (ret < 0 && *error_code_r != SIEVE_ERROR_NOT_FOUND) {
642
0
      settings_free(storage_set);
643
0
      return -1;
644
0
    }
645
0
    if (ret > 0) {
646
0
      i_assert(storage != NULL);
647
0
      break;
648
0
    }
649
0
  }
650
0
  if (ret <= 0) {
651
0
    ret = sieve_storage_autodetect_any(svinst, event, cause, type,
652
0
               storage_set, flags, &storage,
653
0
               error_code_r, error_r);
654
0
    if (ret < 0) {
655
0
      settings_free(storage_set);
656
0
      return -1;
657
0
    }
658
0
  }
659
0
  settings_free(storage_set);
660
0
  if (ret <= 0) {
661
0
    e_debug(event,
662
0
      "storage: No matching Sieve storage configured "
663
0
      "(type=%s and cause=%s)",
664
0
      type, cause);
665
0
    sieve_error_create_script_not_found(
666
0
      NULL, error_code_r, error_r);
667
0
    return -1;
668
0
  }
669
0
  i_assert(storage != NULL);
670
0
  *storage_r = storage;
671
0
  return 0;
672
0
}
673
674
static int
675
sieve_storage_create_default(struct sieve_instance *svinst,
676
           struct event *event, const char *cause,
677
           enum sieve_storage_flags flags,
678
           struct sieve_storage **storage_r,
679
           enum sieve_error *error_code_r,
680
           const char **error_r)
681
0
{
682
0
  struct sieve_storage *storage;
683
0
  enum sieve_error error_code;
684
0
  int ret;
685
686
0
  *storage_r = NULL;
687
0
  sieve_error_args_init(&error_code_r, &error_r);
688
689
0
  ret = sieve_storage_create_auto(svinst, event, cause,
690
0
          SIEVE_STORAGE_TYPE_DEFAULT, flags,
691
0
          &storage, &error_code, error_r);
692
0
  if (ret >= 0) {
693
0
    storage->is_default = TRUE;
694
0
    sieve_storage_update_event_prefix(
695
0
      event_get_parent(storage->event), storage->name, TRUE);
696
0
  } else {
697
0
    switch (error_code) {
698
0
    case SIEVE_ERROR_NOT_FOUND:
699
0
      e_debug(event, "storage: "
700
0
        "Default script not found");
701
0
      break;
702
0
    case SIEVE_ERROR_TEMP_FAILURE:
703
0
      e_error(event, "storage: "
704
0
        "Failed to access default script "
705
0
        "(temporary failure)");
706
0
      break;
707
0
    default:
708
0
      e_error(event, "storage: "
709
0
        "Failed to access default script");
710
0
      break;
711
0
    }
712
0
    *error_code_r = error_code;
713
0
  }
714
715
0
  *storage_r = storage;
716
0
  return ret;
717
0
}
718
719
static int
720
sieve_storage_create_default_for(struct sieve_storage *storage,
721
         struct sieve_storage **storage_r,
722
         enum sieve_error *error_code_r,
723
         const char **error_r)
724
0
{
725
0
  *storage_r = NULL;
726
0
  sieve_error_args_init(&error_code_r, &error_r);
727
728
0
  if (storage->default_storage != NULL) {
729
0
    sieve_storage_ref(storage->default_storage);
730
0
    *storage_r = storage->default_storage;
731
0
    return 0;
732
0
  }
733
734
0
  struct sieve_instance *svinst = storage->svinst;
735
0
  enum sieve_error error_code;
736
0
  const char *error;
737
738
0
  i_assert(storage->default_storage_for == NULL);
739
0
  if (sieve_storage_create_default(svinst, svinst->event,
740
0
           storage->cause, 0,
741
0
           &storage->default_storage,
742
0
           &error_code, &error) < 0) {
743
0
    sieve_storage_set_error(storage, error_code, "%s", error);
744
0
    *error_code_r = storage->error_code;
745
0
    *error_r = storage->error;
746
0
    return -1;
747
0
  }
748
749
0
  storage->default_storage->default_storage_for = storage;
750
0
  sieve_storage_ref(storage);
751
752
0
  *storage_r = storage->default_storage;
753
0
  return 0;
754
0
}
755
756
int sieve_storage_create_personal(struct sieve_instance *svinst,
757
          struct mail_user *user, const char *cause,
758
          enum sieve_storage_flags flags,
759
          struct sieve_storage **storage_r,
760
          enum sieve_error *error_code_r)
761
0
{
762
0
  struct sieve_storage *storage;
763
0
  int ret;
764
765
0
  *storage_r = NULL;
766
0
  sieve_error_args_init(&error_code_r, NULL);
767
768
  /* Check whether Sieve is disabled for this user */
769
0
  if (!svinst->set->enabled) {
770
0
    e_debug(svinst->event,
771
0
      "Sieve is disabled for this user");
772
0
    *error_code_r = SIEVE_ERROR_NOT_POSSIBLE;
773
0
    return -1;
774
0
  }
775
776
  /* Attempt to locate user's main storage */
777
0
  ret = sieve_storage_create_auto(svinst, svinst->event, cause,
778
0
          SIEVE_STORAGE_TYPE_PERSONAL, flags,
779
0
          &storage, error_code_r, NULL);
780
0
  if (ret == 0) {
781
0
    i_assert(storage->is_personal);
782
0
    (void)sieve_storage_sync_init(storage, user);
783
0
    sieve_rusage_storage_init(storage, user);
784
0
  } else if (*error_code_r != SIEVE_ERROR_TEMP_FAILURE &&
785
0
       (flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0 &&
786
0
       (flags & SIEVE_STORAGE_FLAG_READWRITE) == 0) {
787
788
    /* Failed; try using default script location
789
       (not for temporary failures, read/write access, or dsync) */
790
0
    ret = sieve_storage_create_default(svinst, svinst->event,
791
0
               cause, flags, &storage,
792
0
               error_code_r, NULL);
793
0
  }
794
0
  *storage_r = storage;
795
0
  return ret;
796
0
}
797
798
void sieve_storage_ref(struct sieve_storage *storage)
799
0
{
800
0
  storage->refcount++;
801
0
}
802
803
void sieve_storage_unref(struct sieve_storage **_storage)
804
0
{
805
0
  struct sieve_storage *storage = *_storage;
806
807
0
  if (storage == NULL)
808
0
    return;
809
0
  *_storage = NULL;
810
811
0
  i_assert(storage->refcount > 0);
812
0
  if (--storage->refcount != 0)
813
0
    return;
814
815
0
  if (storage->default_storage_for != NULL) {
816
0
    i_assert(storage->is_default);
817
0
    storage->default_storage_for->default_storage = NULL;
818
0
    sieve_storage_unref(&storage->default_storage_for);
819
0
  }
820
821
0
  sieve_storage_sync_deinit(storage);
822
823
0
  if (storage->v.destroy != NULL)
824
0
    storage->v.destroy(storage);
825
826
0
  i_free(storage->error);
827
0
  event_unref(&storage->event);
828
0
  pool_unref(&storage->pool);
829
0
}
830
831
/*
832
 * Utility
833
 */
834
835
int sieve_storage_get_full_path(struct sieve_storage *storage,
836
        const char *path, const char **path_r)
837
0
{
838
0
  struct sieve_instance *svinst = storage->svinst;
839
840
0
  *path_r = path;
841
842
0
  if (path == NULL || *path == '\0')
843
0
    return 0;
844
0
  if ((path[0] != '~' || (path[1] != '/' && path[1] != '\0')) &&
845
0
      ((svinst->flags & SIEVE_FLAG_HOME_RELATIVE) == 0 ||
846
0
       path[0] == '/'))
847
0
    return 0;
848
849
  /* Home-relative path. change to absolute. */
850
0
  const char *home = sieve_environment_get_homedir(svinst);
851
852
0
  if (home == NULL)
853
0
    return -1;
854
855
0
  if (path[0] == '~' && (path[1] == '/' || path[1] == '\0'))
856
0
    *path_r = home_expand_tilde(path, home);
857
0
  else
858
0
    *path_r = t_strconcat(home, "/", path, NULL);
859
0
  return 0;
860
0
}
861
862
/*
863
 * Binary
864
 */
865
866
int sieve_storage_setup_bin_path(struct sieve_storage *storage, mode_t mode)
867
0
{
868
0
  const char *bin_path = storage->bin_path;
869
0
  struct stat st;
870
871
0
  if (bin_path == NULL) {
872
0
    sieve_storage_set_critical(
873
0
      storage, "script_bin_path not configured for storage");
874
0
    return -1;
875
0
  }
876
877
0
  if (stat(bin_path, &st) == 0) {
878
0
    e_debug(storage->event,
879
0
      "Directory for saving binary already exists");
880
0
    return 0;
881
0
  }
882
883
0
  if (errno == EACCES) {
884
0
    sieve_storage_set_critical(storage,
885
0
      "Failed to setup directory for binaries: "
886
0
      "%s", eacces_error_get("stat", bin_path));
887
0
    return -1;
888
0
  } else if (errno != ENOENT) {
889
0
    sieve_storage_set_critical(storage,
890
0
      "Failed to setup directory for binaries: "
891
0
      "stat(%s) failed: %m",
892
0
      bin_path);
893
0
    return -1;
894
0
  }
895
896
0
  if (mkdir_parents(bin_path, mode) == 0) {
897
0
    e_debug(storage->event,
898
0
      "Created directory for binaries: %s", bin_path);
899
0
    return 1;
900
0
  }
901
902
0
  switch (errno) {
903
0
  case EEXIST:
904
0
    return 0;
905
0
  case ENOENT:
906
0
    sieve_storage_set_critical(storage,
907
0
      "Directory for binaries was deleted while it was being created");
908
0
    break;
909
0
  case EACCES:
910
0
    sieve_storage_set_critical(storage,
911
0
      "%s", eacces_error_get_creating("mkdir_parents_chgrp",
912
0
              bin_path));
913
0
    break;
914
0
  default:
915
0
    sieve_storage_set_critical(storage,
916
0
      "mkdir_parents_chgrp(%s) failed: %m", bin_path);
917
0
    break;
918
0
  }
919
920
0
  return -1;
921
0
}
922
923
/*
924
 * Properties
925
 */
926
927
int sieve_storage_is_singular(struct sieve_storage *storage)
928
0
{
929
0
  if (storage->v.is_singular == NULL)
930
0
    return 1;
931
0
  return storage->v.is_singular(storage);
932
0
}
933
934
int sieve_storage_get_last_change(struct sieve_storage *storage,
935
          time_t *last_change_r)
936
0
{
937
0
  i_assert(storage->v.get_last_change != NULL);
938
0
  return storage->v.get_last_change(storage, last_change_r);
939
0
}
940
941
void sieve_storage_set_modified(struct sieve_storage *storage, time_t mtime)
942
0
{
943
0
  if (storage->v.set_modified == NULL)
944
0
    return;
945
946
0
  storage->v.set_modified(storage, mtime);
947
0
}
948
949
/*
950
 * Comparison
951
 */
952
953
int sieve_storage_cmp(const struct sieve_storage *storage1,
954
          const struct sieve_storage *storage2)
955
0
{
956
0
  int ret;
957
958
0
  if (storage1 == storage2)
959
0
    return 0;
960
0
  if (storage1 == NULL || storage2 == NULL)
961
0
    return (storage1 == NULL ? -1 : 1);
962
0
  if (storage1->storage_class != storage2->storage_class) {
963
0
    return (storage1->storage_class > storage2->storage_class ?
964
0
      1 : -1);
965
0
  }
966
0
  ret = null_strcmp(storage1->type, storage2->type);
967
0
  if (ret != 0)
968
0
    return (ret > 0 ? 1 : -1);
969
0
  return null_strcmp(storage1->name, storage2->name);
970
0
}
971
972
unsigned int sieve_storage_hash(const struct sieve_storage *storage)
973
0
{
974
0
  unsigned int hash = 0;
975
976
0
  hash ^= POINTER_CAST_TO(storage->storage_class, unsigned int);
977
0
  hash ^= str_hash(storage->type);
978
0
  hash ^= str_hash(storage->name);
979
980
0
  return hash;
981
0
}
982
983
/*
984
 * Script access
985
 */
986
987
int sieve_storage_get_script_direct(struct sieve_storage *storage,
988
            const char *name,
989
            struct sieve_script **script_r,
990
            enum sieve_error *error_code_r)
991
0
{
992
0
  int ret;
993
994
  /* Validate script name */
995
0
  if (name != NULL && !sieve_script_name_is_valid(name)) {
996
0
    sieve_storage_set_error(storage,
997
0
      SIEVE_ERROR_BAD_PARAMS,
998
0
      "Invalid script name '%s'.",
999
0
      str_sanitize(name, 80));
1000
0
    *error_code_r = storage->error_code;
1001
0
    return -1;
1002
0
  }
1003
0
  if (name == NULL)
1004
0
    name = storage->script_name;
1005
1006
0
  i_assert(storage->v.get_script != NULL);
1007
0
  ret = storage->v.get_script(storage, name, script_r);
1008
0
  i_assert(ret <= 0);
1009
0
  if (ret < 0) {
1010
0
    i_assert(storage->error_code != SIEVE_ERROR_NONE);
1011
0
    i_assert(storage->error != NULL);
1012
0
    *error_code_r = storage->error_code;
1013
0
  }
1014
0
  return ret;
1015
0
}
1016
1017
static int
1018
sieve_storage_get_default_script(struct sieve_storage *storage,
1019
         const char *name,
1020
         struct sieve_script **script_r,
1021
         enum sieve_error *error_code_r)
1022
0
{
1023
0
  struct sieve_storage *def_storage;
1024
0
  int ret;
1025
1026
0
  if (*error_code_r != SIEVE_ERROR_NOT_FOUND ||
1027
0
      (storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0 ||
1028
0
      !storage->is_personal)
1029
0
    return -1;
1030
1031
  /* Not found; if this name maps to the default script,
1032
     try to access that instead */
1033
0
  e_debug(storage->event, "Trying default script instead");
1034
1035
  /* Failed; try using default script location
1036
     (not for temporary failures, read/write access, or dsync) */
1037
0
  ret = sieve_storage_create_default_for(storage, &def_storage,
1038
0
                 error_code_r, NULL);
1039
0
  if (ret < 0)
1040
0
    return -1;
1041
1042
0
  if (strcmp(def_storage->script_name, name) != 0) {
1043
0
    sieve_storage_set_error(storage,
1044
0
      SIEVE_ERROR_NOT_FOUND,
1045
0
      "Default script '%s' not found",
1046
0
      str_sanitize(name, 80));
1047
0
    *error_code_r = storage->error_code;
1048
0
    sieve_storage_unref(&def_storage);
1049
0
    return -1;
1050
0
  }
1051
1052
0
  struct sieve_script *def_script;
1053
1054
0
  ret = sieve_storage_get_script_direct(def_storage, name,
1055
0
                &def_script, error_code_r);
1056
0
  if (ret < 0)
1057
0
    sieve_storage_copy_error(storage, def_storage);
1058
0
  sieve_storage_unref(&def_storage);
1059
0
  if (ret < 0)
1060
0
    return -1;
1061
0
  i_assert(def_script != NULL);
1062
1063
0
  *script_r = def_script;
1064
0
  return 0;
1065
0
}
1066
1067
int sieve_storage_get_script(struct sieve_storage *storage, const char *name,
1068
           struct sieve_script **script_r,
1069
           enum sieve_error *error_code_r)
1070
0
{
1071
0
  *script_r = NULL;
1072
0
  sieve_error_args_init(&error_code_r, NULL);
1073
0
  sieve_storage_clear_error(storage);
1074
1075
0
  if (sieve_storage_get_script_direct(storage, name,
1076
0
              script_r, error_code_r) >= 0)
1077
0
    return 0;
1078
1079
  /* Try default instead if appropriate */
1080
1081
0
  return sieve_storage_get_default_script(storage, name,
1082
0
            script_r, error_code_r);
1083
0
}
1084
1085
int sieve_storage_open_script(struct sieve_storage *storage, const char *name,
1086
            struct sieve_script **script_r,
1087
            enum sieve_error *error_code_r)
1088
0
{
1089
0
  struct sieve_script *script;
1090
1091
0
  *script_r = NULL;
1092
0
  sieve_error_args_init(&error_code_r, NULL);
1093
0
  sieve_storage_clear_error(storage);
1094
1095
0
  if (sieve_storage_get_script(storage, name, &script, error_code_r) < 0)
1096
0
    return -1;
1097
0
  if (sieve_script_open(script, error_code_r) == 0) {
1098
0
    *script_r = script;
1099
0
    return 0;
1100
0
  }
1101
0
  sieve_script_unref(&script);
1102
1103
  /* Try default instead if appropriate */
1104
1105
0
  if (sieve_storage_get_default_script(storage, name,
1106
0
               &script, error_code_r) < 0)
1107
0
    return -1;
1108
0
  if (sieve_script_open(script, error_code_r) < 0) {
1109
0
    sieve_script_unref(&script);
1110
0
    return -1;
1111
0
  }
1112
0
  *script_r = script;
1113
0
  return 0;
1114
0
}
1115
1116
static int
1117
sieve_storage_check_script_direct(struct sieve_storage *storage,
1118
          const char *name,
1119
          enum sieve_error *error_code_r)
1120
0
{
1121
0
  struct sieve_script *script;
1122
0
  int ret;
1123
1124
0
  sieve_error_args_init(&error_code_r, NULL);
1125
0
  sieve_storage_clear_error(storage);
1126
1127
0
  if (sieve_storage_get_script_direct(storage, name,
1128
0
              &script, error_code_r) < 0)
1129
0
    return (*error_code_r == SIEVE_ERROR_NOT_FOUND ? 0 : -1);
1130
1131
0
  ret = sieve_script_open(script, error_code_r);
1132
0
  sieve_script_unref(&script);
1133
0
  return (ret >= 0 ? 1 :
1134
0
    (*error_code_r == SIEVE_ERROR_NOT_FOUND ? 0 : -1));
1135
0
}
1136
1137
int sieve_storage_check_script(struct sieve_storage *storage, const char *name,
1138
             enum sieve_error *error_code_r)
1139
0
{
1140
0
  struct sieve_script *script;
1141
1142
0
  sieve_error_args_init(&error_code_r, NULL);
1143
0
  sieve_storage_clear_error(storage);
1144
1145
0
  if (sieve_storage_open_script(storage, name, &script, error_code_r) < 0)
1146
0
    return (*error_code_r == SIEVE_ERROR_NOT_FOUND ? 0 : -1);
1147
1148
0
  sieve_script_unref(&script);
1149
0
  return 1;
1150
0
}
1151
1152
/*
1153
 * Active script
1154
 */
1155
1156
static int
1157
sieve_storage_active_script_do_get_name(struct sieve_storage *storage,
1158
          const char **name_r, bool *default_r)
1159
          ATTR_NULL(3)
1160
0
{
1161
0
  int ret;
1162
1163
0
  i_assert(storage->is_personal);
1164
1165
0
  if (default_r != NULL)
1166
0
    *default_r = FALSE;
1167
1168
0
  i_assert(storage->v.active_script_get_name != NULL);
1169
0
  ret = storage->v.active_script_get_name(storage, name_r);
1170
0
  if (ret < 0) {
1171
0
    i_assert(storage->error_code != SIEVE_ERROR_NONE);
1172
0
    i_assert(storage->error != NULL);
1173
0
    if (storage->error_code == SIEVE_ERROR_NOT_FOUND) {
1174
0
      sieve_storage_clear_error(storage);
1175
0
      ret = 0;
1176
0
    }
1177
0
  }
1178
1179
0
  if (ret != 0 ||
1180
0
      (storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0)
1181
0
    return ret;
1182
1183
0
  struct sieve_storage *def_storage;
1184
1185
  /* Failed; try using default script location
1186
     (not for temporary failures, read/write access, or dsync) */
1187
0
  ret = sieve_storage_create_default_for(storage, &def_storage,
1188
0
                 NULL, NULL);
1189
0
  if (ret < 0)
1190
0
    return -1;
1191
1192
0
  *name_r = def_storage->script_name;
1193
1194
0
  ret = sieve_storage_check_script(def_storage,
1195
0
           def_storage->script_name, NULL);
1196
0
  if (ret < 0) {
1197
0
    sieve_storage_copy_error(storage, def_storage);
1198
0
    i_assert(storage->error_code != SIEVE_ERROR_NONE);
1199
0
    i_assert(storage->error != NULL);
1200
0
  }
1201
0
  sieve_storage_unref(&def_storage);
1202
0
  if (ret <= 0)
1203
0
    return ret;
1204
1205
0
  if (default_r != NULL)
1206
0
    *default_r = TRUE;
1207
0
  return 1;
1208
0
}
1209
1210
int sieve_storage_active_script_get_name(struct sieve_storage *storage,
1211
           const char **name_r)
1212
0
{
1213
0
  return sieve_storage_active_script_do_get_name(storage, name_r, NULL);
1214
0
}
1215
1216
int sieve_storage_active_script_is_default(struct sieve_storage *storage)
1217
0
{
1218
0
  const char *name;
1219
0
  bool is_default = FALSE;
1220
0
  int ret;
1221
1222
0
  i_assert(storage->is_personal);
1223
0
  ret = sieve_storage_active_script_do_get_name(storage, &name,
1224
0
                  &is_default);
1225
0
  return (ret < 0 ? -1 : (is_default ? 1 : 0));
1226
0
}
1227
1228
int sieve_storage_active_script_open(struct sieve_storage *storage,
1229
             struct sieve_script **script_r,
1230
             enum sieve_error *error_code_r)
1231
0
{
1232
0
  struct sieve_script *script = NULL;
1233
0
  int ret;
1234
1235
  /* When called for non-personal (default) storage, just open the primary
1236
     script by explicit path or name. */
1237
0
  if (!storage->is_personal) {
1238
0
    return sieve_storage_open_script(storage, NULL,
1239
0
             script_r, error_code_r);
1240
0
  }
1241
1242
0
  *script_r = NULL;
1243
0
  sieve_error_args_init(&error_code_r, NULL);
1244
0
  sieve_storage_clear_error(storage);
1245
1246
0
  i_assert(storage->v.active_script_open != NULL);
1247
0
  ret = storage->v.active_script_open(storage, &script);
1248
0
  i_assert(ret <= 0);
1249
0
  i_assert(ret == 0 ||
1250
0
     (storage->error_code != SIEVE_ERROR_NONE &&
1251
0
      storage->error != NULL));
1252
1253
0
  if (ret == 0 || storage->error_code != SIEVE_ERROR_NOT_FOUND ||
1254
0
      (storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0) {
1255
0
    if (ret < 0)
1256
0
      *error_code_r = storage->error_code;
1257
0
    *script_r = script;
1258
0
    return ret;
1259
0
  }
1260
1261
0
  struct sieve_storage *def_storage;
1262
1263
  /* Try default script location */
1264
0
  ret = sieve_storage_create_default_for(storage, &def_storage,
1265
0
                 error_code_r, NULL);
1266
0
  if (ret < 0)
1267
0
    return -1;
1268
1269
0
  ret = sieve_storage_open_script(def_storage, NULL,
1270
0
          script_r, error_code_r);
1271
0
  if (ret < 0)
1272
0
    sieve_storage_copy_error(storage, def_storage);
1273
0
  sieve_storage_unref(&def_storage);
1274
0
  return ret;
1275
0
}
1276
1277
int sieve_storage_deactivate(struct sieve_storage *storage, time_t mtime)
1278
0
{
1279
0
  int ret;
1280
1281
0
  i_assert(storage->is_personal);
1282
0
  i_assert((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0);
1283
1284
0
  sieve_storage_clear_error(storage);
1285
1286
0
  i_assert(storage->v.deactivate != NULL);
1287
0
  ret = storage->v.deactivate(storage);
1288
1289
0
  if (ret >= 0) {
1290
0
    struct event_passthrough *e =
1291
0
      event_create_passthrough(storage->event)->
1292
0
      set_name("sieve_storage_deactivated");
1293
0
    e_debug(e->event(), "Storage deactivated");
1294
1295
0
    sieve_storage_set_modified(storage, mtime);
1296
0
    (void)sieve_storage_sync_deactivate(storage);
1297
0
  } else {
1298
0
    i_assert(storage->error_code != SIEVE_ERROR_NONE);
1299
0
    i_assert(storage->error != NULL);
1300
1301
0
    struct event_passthrough *e =
1302
0
      event_create_passthrough(storage->event)->
1303
0
      add_str("error", storage->error)->
1304
0
      set_name("sieve_storage_deactivated");
1305
0
    e_debug(e->event(), "Failed to deactivate storage: %s",
1306
0
      storage->error);
1307
0
  }
1308
1309
0
  return ret;
1310
0
}
1311
1312
int sieve_storage_active_script_get_last_change(struct sieve_storage *storage,
1313
            time_t *last_change_r)
1314
0
{
1315
0
  i_assert(storage->is_personal);
1316
0
  i_assert(storage->v.active_script_get_last_change != NULL);
1317
1318
0
  return storage->v.active_script_get_last_change(storage, last_change_r);
1319
0
}
1320
1321
/*
1322
 * Listing scripts
1323
 */
1324
1325
int sieve_storage_list_init(struct sieve_storage *storage,
1326
          struct sieve_storage_list_context **lctx_r)
1327
0
{
1328
0
  struct sieve_storage_list_context *lctx;
1329
1330
0
  *lctx_r = NULL;
1331
0
  sieve_storage_clear_error(storage);
1332
1333
0
  i_assert(storage->v.list_init != NULL);
1334
0
  if (storage->v.list_init(storage, &lctx) < 0) {
1335
0
    i_assert(storage->error_code != SIEVE_ERROR_NONE);
1336
0
    i_assert(storage->error != NULL);
1337
0
    return -1;
1338
0
  }
1339
1340
0
  lctx->storage = storage;
1341
0
  sieve_storage_ref(storage);
1342
1343
0
  if ((storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0) {
1344
    /* No default script involved; return right away */
1345
0
    *lctx_r = lctx;
1346
0
    return 0;
1347
0
  }
1348
1349
  /* May need to list default script as well */
1350
1351
0
  enum sieve_error error_code;
1352
1353
0
  if (sieve_storage_create_default_for(storage, &lctx->def_storage,
1354
0
               &error_code, NULL) < 0 &&
1355
0
      error_code != SIEVE_ERROR_NOT_FOUND)
1356
0
    return -1;
1357
1358
0
  *lctx_r = lctx;
1359
0
  return 0;
1360
0
}
1361
1362
const char *
1363
sieve_storage_list_next(struct sieve_storage_list_context *lctx, bool *active_r)
1364
0
{
1365
0
  struct sieve_storage *storage = lctx->storage;
1366
0
  const char *scriptname;
1367
0
  bool script_active = FALSE;
1368
1369
0
  sieve_storage_clear_error(storage);
1370
1371
0
  i_assert(storage->v.list_next != NULL);
1372
0
  scriptname = storage->v.list_next(lctx, &script_active);
1373
1374
0
  i_assert(!script_active || !lctx->seen_active);
1375
0
  if (script_active)
1376
0
    lctx->seen_active = TRUE;
1377
1378
0
  struct sieve_storage *def_storage = lctx->def_storage;
1379
0
  bool have_default = (def_storage != NULL &&
1380
0
           def_storage->script_name != NULL);
1381
1382
0
  if (scriptname != NULL) {
1383
    /* Remember when we see that the storage has its own script for
1384
       default */
1385
0
    if (have_default &&
1386
0
        strcmp(scriptname, def_storage->script_name) == 0)
1387
0
      lctx->seen_default = TRUE;
1388
1389
0
  } else if (have_default && !lctx->seen_default &&
1390
0
       sieve_storage_check_script(def_storage, NULL, NULL) > 0) {
1391
1392
    /* Return default script at the end if it was not listed
1393
       thus far (storage backend has no script under default
1394
       name) */
1395
0
    scriptname = def_storage->script_name;
1396
0
    lctx->seen_default = TRUE;
1397
1398
    /* Mark default as active if no normal script is active */
1399
0
    if (!lctx->seen_active) {
1400
0
      script_active = TRUE;
1401
0
      lctx->seen_active = TRUE;
1402
0
    }
1403
0
  }
1404
1405
0
  if (active_r != NULL)
1406
0
    *active_r = script_active;
1407
0
  return scriptname;
1408
0
}
1409
1410
int sieve_storage_list_deinit(struct sieve_storage_list_context **_lctx)
1411
0
{
1412
0
  struct sieve_storage_list_context *lctx = *_lctx;
1413
1414
0
  if (lctx == NULL)
1415
0
    return 0;
1416
0
  *_lctx = NULL;
1417
1418
0
  struct sieve_storage *storage = lctx->storage;
1419
0
  struct sieve_storage *def_storage = lctx->def_storage;
1420
0
  int ret;
1421
1422
0
  i_assert(storage->v.list_deinit != NULL);
1423
0
  ret = storage->v.list_deinit(lctx);
1424
0
  i_assert(ret >= 0 ||
1425
0
     (storage->error_code != SIEVE_ERROR_NONE &&
1426
0
      storage->error != NULL));
1427
1428
0
  sieve_storage_unref(&def_storage);
1429
0
  sieve_storage_unref(&storage);
1430
0
  return ret;
1431
0
}
1432
1433
/*
1434
 * Saving scripts
1435
 */
1436
1437
static struct event *
1438
sieve_storage_save_create_event(struct sieve_storage *storage,
1439
        const char *scriptname) ATTR_NULL(2)
1440
0
{
1441
0
  struct event *event;
1442
1443
0
  event = event_create(storage->event);
1444
0
  event_add_str(event, "script_name", scriptname);
1445
0
  if (scriptname == NULL) {
1446
0
    event_set_append_log_prefix(event, "save: ");
1447
0
  } else {
1448
0
    event_set_append_log_prefix(
1449
0
      event, t_strdup_printf("script '%s': save: ",
1450
0
                 scriptname));
1451
0
  }
1452
1453
0
  return event;
1454
0
}
1455
1456
static void sieve_storage_save_cleanup(struct sieve_storage_save_context *sctx)
1457
0
{
1458
0
  sieve_script_unref(&sctx->scriptobject);
1459
0
}
1460
1461
static void sieve_storage_save_deinit(struct sieve_storage_save_context **_sctx)
1462
0
{
1463
0
  struct sieve_storage_save_context *sctx = *_sctx;
1464
1465
0
  *_sctx = NULL;
1466
0
  if (sctx == NULL)
1467
0
    return;
1468
1469
0
  sieve_storage_save_cleanup(sctx);
1470
0
  event_unref(&sctx->event);
1471
0
  pool_unref(&sctx->pool);
1472
0
}
1473
1474
struct sieve_storage_save_context *
1475
sieve_storage_save_init(struct sieve_storage *storage, const char *scriptname,
1476
      struct istream *input)
1477
0
{
1478
0
  struct sieve_storage_save_context *sctx;
1479
1480
0
  sieve_storage_clear_error(storage);
1481
1482
0
  if (scriptname != NULL) {
1483
    /* Validate script name */
1484
0
    if (!sieve_script_name_is_valid(scriptname)) {
1485
0
      sieve_storage_set_error(storage,
1486
0
        SIEVE_ERROR_BAD_PARAMS,
1487
0
        "Invalid Sieve script name '%s'.",
1488
0
        str_sanitize(scriptname, 80));
1489
0
      return NULL;
1490
0
    }
1491
0
  }
1492
1493
0
  i_assert((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0);
1494
1495
0
  i_assert(storage->v.save_alloc != NULL);
1496
0
  sctx = storage->v.save_alloc(storage);
1497
0
  sctx->storage = storage;
1498
1499
0
  sctx->event = sieve_storage_save_create_event(storage, scriptname);
1500
1501
0
  struct event_passthrough *e =
1502
0
    event_create_passthrough(sctx->event)->
1503
0
    set_name("sieve_storage_save_started");
1504
0
  e_debug(e->event(), "Started saving script");
1505
1506
0
  i_assert(storage->v.save_init != NULL);
1507
0
  if ((storage->v.save_init(sctx, scriptname, input)) < 0) {
1508
0
    i_assert(storage->error_code != SIEVE_ERROR_NONE);
1509
0
    i_assert(storage->error != NULL);
1510
1511
0
    struct event_passthrough *e =
1512
0
      event_create_passthrough(sctx->event)->
1513
0
      add_str("error", storage->error)->
1514
0
      set_name("sieve_storage_save_finished");
1515
0
    e_debug(e->event(), "Failed to save script: %s",
1516
0
      storage->error);
1517
1518
0
    sieve_storage_save_deinit(&sctx);
1519
0
    return NULL;
1520
0
  }
1521
1522
0
  sctx->mtime = (time_t)-1;
1523
1524
0
  i_assert(sctx->input != NULL);
1525
1526
0
  return sctx;
1527
0
}
1528
1529
int sieve_storage_save_continue(struct sieve_storage_save_context *sctx)
1530
0
{
1531
0
  struct sieve_storage *storage = sctx->storage;
1532
0
  int ret;
1533
1534
0
  sieve_storage_clear_error(storage);
1535
1536
0
  i_assert(storage->v.save_continue != NULL);
1537
0
  ret = storage->v.save_continue(sctx);
1538
0
  if (ret < 0) {
1539
0
    i_assert(storage->error_code != SIEVE_ERROR_NONE);
1540
0
    i_assert(storage->error != NULL);
1541
0
    sctx->failed = TRUE;
1542
0
  }
1543
0
  return ret;
1544
0
}
1545
1546
int sieve_storage_save_finish(struct sieve_storage_save_context *sctx)
1547
0
{
1548
0
  struct sieve_storage *storage = sctx->storage;
1549
0
  bool was_failed = sctx->failed;
1550
0
  int ret;
1551
1552
0
  if (!was_failed)
1553
0
    sieve_storage_clear_error(storage);
1554
1555
0
  i_assert(!sctx->finished);
1556
0
  sctx->finished = TRUE;
1557
1558
0
  i_assert(storage->v.save_finish != NULL);
1559
0
  ret = storage->v.save_finish(sctx);
1560
0
  if (ret < 0 && !was_failed) {
1561
0
    i_assert(storage->error_code != SIEVE_ERROR_NONE);
1562
0
    i_assert(storage->error != NULL);
1563
1564
0
    struct event_passthrough *e =
1565
0
      event_create_passthrough(sctx->event)->
1566
0
      add_str("error", storage->error)->
1567
0
      set_name("sieve_storage_save_finished");
1568
0
    e_debug(e->event(), "Failed to upload script: %s",
1569
0
      storage->error);
1570
1571
0
    sctx->failed = TRUE;
1572
0
  }
1573
0
  return ret;
1574
0
}
1575
1576
void sieve_storage_save_set_mtime(struct sieve_storage_save_context *sctx,
1577
          time_t mtime)
1578
0
{
1579
0
  sctx->mtime = mtime;
1580
0
}
1581
1582
struct sieve_script *
1583
sieve_storage_save_get_tempscript(struct sieve_storage_save_context *sctx)
1584
0
{
1585
0
  struct sieve_storage *storage = sctx->storage;
1586
1587
0
  if (sctx->failed)
1588
0
    return NULL;
1589
1590
0
  if (sctx->scriptobject != NULL)
1591
0
    return sctx->scriptobject;
1592
1593
0
  sieve_storage_clear_error(storage);
1594
1595
0
  i_assert(storage->v.save_get_tempscript != NULL);
1596
0
  sctx->scriptobject = storage->v.save_get_tempscript(sctx);
1597
1598
0
  i_assert(sctx->scriptobject != NULL ||
1599
0
     (storage->error_code != SIEVE_ERROR_NONE &&
1600
0
      storage->error != NULL));
1601
0
  return sctx->scriptobject;
1602
0
}
1603
1604
bool sieve_storage_save_will_activate(struct sieve_storage_save_context *sctx)
1605
0
{
1606
0
  struct sieve_storage *storage = sctx->storage;
1607
1608
0
  if (sctx->scriptname == NULL)
1609
0
    return FALSE;
1610
1611
0
  sieve_storage_clear_error(storage);
1612
1613
0
  if (sctx->active_scriptname == NULL) {
1614
0
    const char *scriptname;
1615
1616
0
    if (sieve_storage_active_script_get_name(sctx->storage,
1617
0
               &scriptname) > 0) {
1618
0
      sctx->active_scriptname =
1619
0
        p_strdup(sctx->pool, scriptname);
1620
0
    }
1621
0
  }
1622
1623
  /* Is the requested script active? */
1624
0
  return (sctx->active_scriptname != NULL &&
1625
0
    strcmp(sctx->scriptname, sctx->active_scriptname) == 0);
1626
0
}
1627
1628
static int
1629
sieve_storage_save_is_activating_default(
1630
  struct sieve_storage_save_context *sctx)
1631
0
{
1632
0
  struct sieve_storage *storage = sctx->storage;
1633
1634
0
  if ((storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0)
1635
0
    return 0;
1636
0
  if (!sieve_storage_save_will_activate(sctx))
1637
0
    return 0;
1638
1639
0
  struct sieve_storage *def_storage;
1640
0
  enum sieve_error error_code;
1641
0
  int ret = 0;
1642
1643
0
  if (sieve_storage_create_default_for(storage, &def_storage,
1644
0
               &error_code, NULL) < 0) {
1645
0
    if (error_code == SIEVE_ERROR_NOT_FOUND)
1646
0
      return 0;
1647
0
    return -1;
1648
0
  }
1649
1650
0
  if (strcmp(sctx->scriptname, def_storage->script_name) == 0) {
1651
0
    ret = sieve_storage_check_script_direct(
1652
0
      storage, def_storage->script_name, &error_code);
1653
0
    if (ret == 0 ||
1654
0
        (ret < 0 && error_code == SIEVE_ERROR_NOT_FOUND))
1655
0
      ret = 1;
1656
0
    else if (ret > 0)
1657
0
      ret = 0;
1658
0
  }
1659
1660
0
  sieve_storage_unref(&def_storage);
1661
0
  return ret;
1662
0
}
1663
1664
int sieve_storage_save_commit(struct sieve_storage_save_context **_sctx)
1665
0
{
1666
0
  struct sieve_storage_save_context *sctx = *_sctx;
1667
0
  struct sieve_storage *storage;
1668
0
  const char *scriptname;
1669
0
  bool default_activate = FALSE;
1670
0
  int ret;
1671
1672
0
  *_sctx = NULL;
1673
0
  if (sctx == NULL)
1674
0
    return 0;
1675
1676
0
  storage = sctx->storage;
1677
0
  scriptname = sctx->scriptname;
1678
0
  sieve_storage_clear_error(storage);
1679
1680
0
  i_assert(!sctx->failed);
1681
0
  i_assert(sctx->finished);
1682
0
  i_assert(sctx->scriptname != NULL);
1683
1684
  /* Check whether we're replacing the default active script */
1685
0
  ret = sieve_storage_save_is_activating_default(sctx);
1686
0
  if (ret < 0)
1687
0
    return -1;
1688
0
  default_activate = (ret > 0);
1689
1690
0
  sieve_storage_save_cleanup(sctx);
1691
1692
0
  i_assert(storage->v.save_commit != NULL);
1693
0
  ret = storage->v.save_commit(sctx);
1694
0
  i_assert(ret >= 0 ||
1695
0
     (storage->error_code != SIEVE_ERROR_NONE &&
1696
0
      storage->error != NULL));
1697
1698
  /* Implicitly activate it when we're replacing the default
1699
     active script */
1700
0
  if (ret >= 0 && default_activate) {
1701
0
    struct sieve_script *script;
1702
0
    enum sieve_error error_code;
1703
1704
0
    if (sieve_storage_open_script(storage, scriptname,
1705
0
                &script, &error_code) < 0) {
1706
      /* Somehow not actually saved */
1707
0
      ret = (error_code == SIEVE_ERROR_NOT_FOUND ? 0 : -1);
1708
0
    } else if (sieve_script_activate(script, (time_t)-1) < 0) {
1709
      /* Failed to activate; roll back */
1710
0
      ret = -1;
1711
0
      (void)sieve_script_delete(script, TRUE);
1712
0
    }
1713
0
    sieve_script_unref(&script);
1714
1715
0
    if (ret < 0) {
1716
0
      e_error(sctx->event,
1717
0
        "Failed to implicitly activate script '%s' "
1718
0
        "while replacing the default active script",
1719
0
        scriptname);
1720
0
    }
1721
0
  }
1722
1723
0
  if (ret >= 0) {
1724
0
    struct event_passthrough *e =
1725
0
      event_create_passthrough(sctx->event)->
1726
0
      set_name("sieve_storage_save_finished");
1727
0
    e_debug(e->event(), "Finished saving script");
1728
1729
    /* set INBOX mailbox attribute */
1730
0
    (void)sieve_storage_sync_script_save(storage, scriptname);
1731
0
  } else {
1732
0
    struct event_passthrough *e =
1733
0
      event_create_passthrough(sctx->event)->
1734
0
      add_str("error", storage->error)->
1735
0
      set_name("sieve_storage_save_finished");
1736
1737
0
    e_debug(e->event(), "Failed to save script: %s",
1738
0
      storage->error);
1739
0
  }
1740
1741
0
  sieve_storage_save_deinit(&sctx);
1742
0
  return ret;
1743
0
}
1744
1745
void sieve_storage_save_cancel(struct sieve_storage_save_context **_sctx)
1746
0
{
1747
0
  struct sieve_storage_save_context *sctx = *_sctx;
1748
0
  struct sieve_storage *storage;
1749
1750
0
  *_sctx = NULL;
1751
0
  if (sctx == NULL)
1752
0
    return;
1753
1754
0
  storage = sctx->storage;
1755
1756
0
  sctx->failed = TRUE;
1757
1758
0
  sieve_storage_save_cleanup(sctx);
1759
1760
0
  if (!sctx->finished)
1761
0
    (void)sieve_storage_save_finish(sctx);
1762
1763
0
  struct event_passthrough *e =
1764
0
    event_create_passthrough(sctx->event)->
1765
0
    add_str("error", "Canceled")->
1766
0
    set_name("sieve_storage_save_finished");
1767
0
  e_debug(e->event(), "Canceled saving script");
1768
1769
0
  i_assert(storage->v.save_cancel != NULL);
1770
0
  storage->v.save_cancel(sctx);
1771
1772
0
  sieve_storage_save_deinit(&sctx);
1773
0
}
1774
1775
int sieve_storage_save_as_active(struct sieve_storage *storage,
1776
         struct istream *input, time_t mtime)
1777
0
{
1778
0
  struct event *event;
1779
0
  int ret;
1780
1781
0
  sieve_storage_clear_error(storage);
1782
1783
0
  event = event_create(storage->event);
1784
0
  event_set_append_log_prefix(event, "active script: save: ");
1785
1786
0
  struct event_passthrough *e =
1787
0
    event_create_passthrough(event)->
1788
0
    set_name("sieve_storage_save_started");
1789
0
  e_debug(e->event(), "Started saving active script");
1790
1791
0
  i_assert(storage->v.save_as_active != NULL);
1792
0
  ret = storage->v.save_as_active(storage, input, mtime);
1793
1794
0
  if (ret >= 0) {
1795
0
    struct event_passthrough *e =
1796
0
      event_create_passthrough(event)->
1797
0
      set_name("sieve_storage_save_finished");
1798
0
    e_debug(e->event(), "Finished saving active script");
1799
0
  } else {
1800
0
    i_assert(storage->error_code != SIEVE_ERROR_NONE);
1801
0
    i_assert(storage->error != NULL);
1802
1803
0
    struct event_passthrough *e =
1804
0
      event_create_passthrough(event)->
1805
0
      add_str("error", storage->error)->
1806
0
      set_name("sieve_storage_save_finished");
1807
0
    e_debug(e->event(), "Failed to save active script: %s",
1808
0
      storage->error);
1809
0
  }
1810
1811
0
  event_unref(&event);
1812
0
  return ret;
1813
0
}
1814
1815
int sieve_storage_save_as(struct sieve_storage *storage, struct istream *input,
1816
        const char *name)
1817
0
{
1818
0
  struct event *event;
1819
0
  int ret;
1820
1821
0
  sieve_storage_clear_error(storage);
1822
1823
0
  event = sieve_storage_save_create_event(storage, name);
1824
1825
0
  struct event_passthrough *e =
1826
0
    event_create_passthrough(event)->
1827
0
    set_name("sieve_storage_save_started");
1828
0
  e_debug(e->event(), "Started saving script");
1829
1830
0
  i_assert(storage->v.save_as != NULL);
1831
0
  ret = storage->v.save_as(storage, input, name);
1832
1833
0
  if (ret >= 0) {
1834
0
    struct event_passthrough *e =
1835
0
      event_create_passthrough(event)->
1836
0
      set_name("sieve_storage_save_finished");
1837
0
    e_debug(e->event(), "Finished saving sieve script");
1838
0
  } else {
1839
0
    i_assert(storage->error_code != SIEVE_ERROR_NONE);
1840
0
    i_assert(storage->error != NULL);
1841
1842
0
    struct event_passthrough *e =
1843
0
      event_create_passthrough(event)->
1844
0
      add_str("error", storage->error)->
1845
0
      set_name("sieve_storage_save_finished");
1846
0
    e_debug(e->event(), "Failed to save script: %s",
1847
0
      storage->error);
1848
0
  }
1849
1850
0
  event_unref(&event);
1851
0
  return ret;
1852
0
}
1853
1854
/*
1855
 * Checking quota
1856
 */
1857
1858
bool sieve_storage_quota_validsize(struct sieve_storage *storage, size_t size,
1859
           uint64_t *limit_r)
1860
0
{
1861
0
  uint64_t max_size;
1862
1863
0
  max_size = sieve_max_script_size(storage->svinst);
1864
0
  if (max_size > 0 && size > max_size) {
1865
0
    *limit_r = max_size;
1866
0
    return FALSE;
1867
0
  }
1868
1869
0
  return TRUE;
1870
0
}
1871
1872
uint64_t sieve_storage_quota_max_script_size(struct sieve_storage *storage)
1873
0
{
1874
0
  return sieve_max_script_size(storage->svinst);
1875
0
}
1876
1877
int sieve_storage_quota_havespace(struct sieve_storage *storage,
1878
          const char *scriptname, size_t size,
1879
          enum sieve_storage_quota *quota_r,
1880
          uint64_t *limit_r)
1881
0
{
1882
0
  *quota_r = SIEVE_STORAGE_QUOTA_NONE;
1883
0
  *limit_r = 0;
1884
1885
  /* Check the script size */
1886
0
  if (!sieve_storage_quota_validsize(storage, size, limit_r)) {
1887
0
    *quota_r = SIEVE_STORAGE_QUOTA_MAXSIZE;
1888
0
    return 0;
1889
0
  }
1890
1891
  /* Do we need to scan the storage (quota enabled) ? */
1892
0
  if (storage->max_scripts == 0 && storage->max_storage == 0)
1893
0
    return 1;
1894
1895
0
  if (storage->v.quota_havespace == NULL)
1896
0
    return 1;
1897
1898
0
  return storage->v.quota_havespace(storage, scriptname, size,
1899
0
            quota_r, limit_r);
1900
0
}
1901
1902
/*
1903
 * Properties
1904
 */
1905
1906
const char *sieve_storage_name(const struct sieve_storage *storage)
1907
0
{
1908
0
  return storage->name;
1909
0
}
1910
1911
bool sieve_storage_is_default(const struct sieve_storage *storage)
1912
0
{
1913
0
  return storage->is_default;
1914
0
}
1915
1916
bool sieve_storage_is_personal(struct sieve_storage *storage)
1917
0
{
1918
0
  return storage->is_personal;
1919
0
}
1920
1921
/*
1922
 * Error handling
1923
 */
1924
1925
void sieve_storage_clear_error(struct sieve_storage *storage)
1926
0
{
1927
0
  i_free(storage->error);
1928
0
  storage->error_code = SIEVE_ERROR_NONE;
1929
0
  storage->error = NULL;
1930
0
}
1931
1932
void sieve_storage_set_error(struct sieve_storage *storage,
1933
           enum sieve_error error_code, const char *fmt, ...)
1934
0
{
1935
0
  va_list va;
1936
1937
0
  sieve_storage_clear_error(storage);
1938
1939
0
  if (fmt != NULL) {
1940
0
    va_start(va, fmt);
1941
0
    storage->error = i_strdup_vprintf(fmt, va);
1942
0
    va_end(va);
1943
0
  }
1944
1945
0
  storage->error_code = error_code;
1946
0
}
1947
1948
void sieve_storage_copy_error(struct sieve_storage *storage,
1949
            const struct sieve_storage *source)
1950
0
{
1951
0
  sieve_storage_clear_error(storage);
1952
0
  storage->error = i_strdup(source->error);
1953
0
  storage->error_code = source->error_code;
1954
0
}
1955
1956
void sieve_storage_set_internal_error(struct sieve_storage *storage)
1957
0
{
1958
0
  const char *error;
1959
1960
0
  sieve_storage_clear_error(storage);
1961
0
  sieve_error_create_internal(&storage->error_code, &error);
1962
0
  storage->error = i_strdup(error);
1963
0
}
1964
1965
void sieve_storage_set_critical(struct sieve_storage *storage,
1966
        const char *fmt, ...)
1967
0
{
1968
0
  va_list va;
1969
1970
0
  if (fmt != NULL) {
1971
0
    if ((storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0) {
1972
0
      va_start(va, fmt);
1973
0
      e_error(storage->svinst->event, "%s storage: %s",
1974
0
        storage->driver_name,
1975
0
        t_strdup_vprintf(fmt, va));
1976
0
      va_end(va);
1977
1978
0
      sieve_storage_set_internal_error(storage);
1979
1980
0
    } else {
1981
0
      sieve_storage_clear_error(storage);
1982
1983
      /* no user is involved while synchronizing, so do it the
1984
         normal way */
1985
0
      va_start(va, fmt);
1986
0
      storage->error = i_strdup_vprintf(fmt, va);
1987
0
      va_end(va);
1988
1989
0
      storage->error_code = SIEVE_ERROR_TEMP_FAILURE;
1990
0
    }
1991
0
  }
1992
0
}
1993
1994
void sieve_storage_set_not_found_error(struct sieve_storage *storage,
1995
               const char *name)
1996
0
{
1997
0
  enum sieve_error error_code;
1998
0
  const char *error;
1999
2000
0
  sieve_storage_clear_error(storage);
2001
0
  name = (name == NULL || *name == '\0' ? storage->script_name : name);
2002
0
  sieve_error_create_script_not_found(name, &error_code, &error);
2003
0
  storage->error_code = error_code;
2004
0
  storage->error = i_strdup(error);
2005
0
}
2006
2007
const char *
2008
sieve_storage_get_last_error(struct sieve_storage *storage,
2009
           enum sieve_error *error_code_r)
2010
0
{
2011
  /* We get here only in error situations, so we have to return some
2012
     error. If storage->error is NULL, it means we forgot to set it at
2013
     some point..
2014
   */
2015
2016
0
  if (error_code_r != NULL)
2017
0
    *error_code_r = storage->error_code;
2018
2019
0
  return storage->error != NULL ? storage->error : "Unknown error";
2020
0
}
2021
2022
/*
2023
 * Storage sequence
2024
 */
2025
2026
int sieve_storage_sequence_create(struct sieve_instance *svinst,
2027
          struct event *event_parent,
2028
          const char *cause, const char *type,
2029
          struct sieve_storage_sequence **sseq_r,
2030
          enum sieve_error *error_code_r,
2031
          const char **error_r)
2032
0
{
2033
0
  const struct sieve_storage_settings *storage_set;
2034
0
  const char *const *storage_names;
2035
0
  unsigned int storage_count;
2036
0
  const char *error;
2037
2038
0
  *sseq_r = NULL;
2039
0
  sieve_error_args_init(&error_code_r, &error_r);
2040
2041
0
  if (settings_get(event_parent, &sieve_storage_setting_parser_info,
2042
0
       SETTINGS_GET_FLAG_SORT_FILTER_ARRAYS,
2043
0
       &storage_set, &error) < 0) {
2044
0
    e_error(event_parent, "%s", error);
2045
0
    sieve_error_create_internal(error_code_r, error_r);
2046
0
    return -1;
2047
0
  }
2048
0
  if (array_is_created(&storage_set->storages))
2049
0
    storage_names = array_get(&storage_set->storages,
2050
0
            &storage_count);
2051
0
  else {
2052
0
    storage_names = empty_str_array;
2053
0
    storage_count = 0;
2054
0
  }
2055
2056
0
  struct sieve_storage_sequence *sseq;
2057
2058
0
  sseq = i_new(struct sieve_storage_sequence, 1);
2059
0
  sseq->svinst = svinst;
2060
0
  sseq->cause = i_strdup(cause);
2061
0
  sseq->type = i_strdup(type);
2062
0
  sseq->storage_set = storage_set;
2063
0
  sseq->storage_names = storage_names;
2064
0
  sseq->storage_count = storage_count;
2065
2066
0
  sseq->event_parent = event_parent;
2067
0
  event_ref(event_parent);
2068
2069
0
  *sseq_r = sseq;
2070
0
  return 0;
2071
0
}
2072
2073
int sieve_storage_sequence_next(struct sieve_storage_sequence *sseq,
2074
        struct sieve_storage **storage_r,
2075
        enum sieve_error *error_code_r,
2076
        const char **error_r)
2077
0
{
2078
0
  struct sieve_instance *svinst = sseq->svinst;
2079
0
  int ret;
2080
2081
0
  *storage_r = NULL;
2082
0
  sieve_error_args_init(&error_code_r, &error_r);
2083
2084
0
  while (sseq->storage_index < sseq->storage_count) {
2085
0
    unsigned int index = sseq->storage_index++;
2086
2087
0
    ret = sieve_storage_init(svinst, sseq->event_parent,
2088
0
           sseq->cause, sseq->type,
2089
0
           sseq->storage_names[index], TRUE, 0,
2090
0
           storage_r, error_code_r, error_r);
2091
0
    if (ret < 0) {
2092
0
      if (*error_code_r == SIEVE_ERROR_NOT_FOUND) {
2093
0
        *error_code_r = SIEVE_ERROR_NONE;
2094
0
        *error_r = NULL;
2095
0
        continue;
2096
0
      }
2097
0
      return -1;
2098
0
    }
2099
0
    if (ret > 0) {
2100
0
      i_assert(*storage_r != NULL);
2101
0
      return 1;
2102
0
    }
2103
0
  }
2104
2105
0
  return 0;
2106
0
}
2107
2108
void sieve_storage_sequence_free(struct sieve_storage_sequence **_sseq)
2109
0
{
2110
0
  struct sieve_storage_sequence *sseq = *_sseq;
2111
2112
0
  if (sseq == NULL)
2113
0
    return;
2114
0
  *_sseq = NULL;
2115
2116
0
  event_unref(&sseq->event_parent);
2117
0
  i_free(sseq->cause);
2118
0
  i_free(sseq->type);
2119
0
  settings_free(sseq->storage_set);
2120
  i_free(sseq);
2121
0
}