1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file
*/
#include "lib.h"
#include "str.h"
#include "eacces-error.h"
#include "sieve-common.h"
#include "sieve-script-private.h"
#include "sieve-file-storage.h"
#include <stdio.h>
#include <dirent.h>
struct sieve_file_list_context {
struct sieve_storage_list_context context;
pool_t pool;
const char *active;
const char *dir;
DIR *dirp;
};
struct sieve_storage_list_context *sieve_file_storage_list_init
(struct sieve_storage *storage)
{
struct sieve_file_storage *fstorage =
(struct sieve_file_storage *)storage;
struct sieve_file_list_context *flctx;
const char *active = NULL;
pool_t pool;
DIR *dirp;
/* Open the directory */
if ( (dirp = opendir(fstorage->path)) == NULL ) {
switch ( errno ) {
case ENOENT:
sieve_storage_set_error(storage,
SIEVE_ERROR_NOT_FOUND,
"Script storage not found");
break;
case EACCES:
sieve_storage_set_error(storage,
SIEVE_ERROR_NO_PERMISSION,
"Script storage not accessible");
sieve_storage_sys_error(storage,
"Failed to list scripts: "
"%s", eacces_error_get("opendir", fstorage->path));
break;
default:
sieve_storage_set_critical(storage,
"Failed to list scripts: "
"opendir(%s) failed: %m", fstorage->path);
break;
}
return NULL;
}
T_BEGIN {
/* Get the name of the active script */
if ( sieve_file_storage_active_script_get_file(fstorage, &active) < 0) {
flctx = NULL;
} else {
pool = pool_alloconly_create("sieve_file_list_context", 1024);
flctx = p_new(pool, struct sieve_file_list_context, 1);
flctx->pool = pool;
flctx->dirp = dirp;
flctx->active = ( active != NULL ? p_strdup(pool, active) : NULL );
}
} T_END;
if ( flctx == NULL ) {
if ( closedir(dirp) < 0) {
sieve_storage_sys_error(storage,
"closedir(%s) failed: %m", fstorage->path);
}
return NULL;
}
return &flctx->context;
}
const char *sieve_file_storage_list_next
(struct sieve_storage_list_context *ctx, bool *active)
{
struct sieve_file_list_context *flctx =
(struct sieve_file_list_context *)ctx;
const struct sieve_file_storage *fstorage =
(const struct sieve_file_storage *)ctx->storage;
struct dirent *dp;
const char *scriptname;
*active = FALSE;
for (;;) {
if ( (dp = readdir(flctx->dirp)) == NULL )
return NULL;
scriptname = sieve_script_file_get_scriptname(dp->d_name);
if (scriptname != NULL ) {
/* Don't list our active sieve script link if the link
* resides in the script dir (generally a bad idea).
*/
i_assert( fstorage->link_path != NULL );
if ( *(fstorage->link_path) == '\0' &&
strcmp(fstorage->active_fname, dp->d_name) == 0 )
continue;
break;
}
}
if ( flctx->active != NULL && strcmp(dp->d_name, flctx->active) == 0 ) {
*active = TRUE;
flctx->active = NULL;
}
return scriptname;
}
int sieve_file_storage_list_deinit(struct sieve_storage_list_context *lctx)
{
struct sieve_file_list_context *flctx =
(struct sieve_file_list_context *)lctx;
const struct sieve_file_storage *fstorage =
(const struct sieve_file_storage *)lctx->storage;
if (closedir(flctx->dirp) < 0) {
sieve_storage_sys_error(lctx->storage,
"closedir(%s) failed: %m", fstorage->path);
}
pool_unref(&flctx->pool);
// FIXME: return error here if something went wrong during listing
return 0;
}
|