/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999-2021 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not, see
. */
#ifdef HAVE_CONFIG_H
# include
#endif
#include
#include
#include
#include
#include
int
mu_sieve_registry_require (mu_sieve_machine_t mach, const char *name,
enum mu_sieve_record type)
{
mu_sieve_registry_t *reg;
reg = mu_sieve_registry_lookup (mach, name, type);
if (!reg)
{
void *handle = mu_sieve_load_ext (mach, name);
if (!handle)
return 1;
reg = mu_sieve_registry_lookup (mach, name, type);
if (!reg)
return 1;
reg->handle = handle;
}
reg->required = 1;
return 0;
}
static void
regunload (void *data)
{
mu_sieve_registry_t *reg = data;
mu_sieve_unload_ext (reg->handle);
}
static int
regcmp (void const *a, void const *b)
{
mu_sieve_registry_t const *rega = a;
mu_sieve_registry_t const *regb = b;
if (rega->type != regb->type)
return rega->type - regb->type;
return strcmp (rega->name, regb->name);
}
mu_sieve_registry_t *
mu_sieve_registry_add (mu_sieve_machine_t mach, const char *name)
{
mu_sieve_registry_t *reg;
int rc;
if (!mach->registry)
{
rc = mu_list_create (&mach->registry);
if (rc)
{
mu_sieve_error (mach, "mu_list_create: %s", mu_strerror (rc));
mu_sieve_abort (mach);
}
mu_list_set_destroy_item (mach->registry, regunload);
mu_list_set_comparator (mach->registry, regcmp);
}
reg = mu_sieve_malloc (mach, sizeof (*reg));
reg->name = name;
reg->handle = NULL;
reg->required = 0;
memset (®->v, 0, sizeof reg->v);
rc = mu_list_append (mach->registry, reg);
if (rc)
{
mu_sieve_error (mach, "mu_list_append: %s", mu_strerror (rc));
mu_sieve_abort (mach);
}
return reg;
}
mu_sieve_registry_t *
mu_sieve_registry_lookup (mu_sieve_machine_t mach, const char *name,
enum mu_sieve_record type)
{
mu_sieve_registry_t key, *reg;
int rc;
key.name = name;
key.type = type;
rc = mu_list_locate (mach->registry, &key, (void**) ®);
if (rc == MU_ERR_NOENT)
return NULL;
else if (rc)
{
mu_sieve_error (mach, _("registry lookup failed: %s"), mu_strerror (rc));
mu_sieve_abort (mach);
}
return reg;
}
void
mu_sieve_register_test_ext (mu_sieve_machine_t mach,
const char *name, mu_sieve_handler_t handler,
mu_sieve_data_type *req_args,
mu_sieve_data_type *opt_args,
mu_sieve_tag_group_t *tags, int required)
{
mu_sieve_registry_t *reg = mu_sieve_registry_add (mach, name);
reg->type = mu_sieve_record_test;
reg->required = required;
reg->v.command.handler = handler;
reg->v.command.req_args = req_args;
reg->v.command.opt_args = opt_args;
reg->v.command.tags = tags;
}
void
mu_sieve_register_test (mu_sieve_machine_t mach,
const char *name, mu_sieve_handler_t handler,
mu_sieve_data_type *arg_types,
mu_sieve_tag_group_t *tags, int required)
{
return mu_sieve_register_test_ext (mach, name, handler,
arg_types, NULL,
tags,
required);
}
void
mu_sieve_register_action_ext (mu_sieve_machine_t mach,
const char *name, mu_sieve_handler_t handler,
mu_sieve_data_type *req_args,
mu_sieve_data_type *opt_args,
mu_sieve_tag_group_t *tags, int required)
{
mu_sieve_registry_t *reg = mu_sieve_registry_add (mach, name);
reg->type = mu_sieve_record_action;
reg->required = required;
reg->v.command.handler = handler;
reg->v.command.req_args = req_args;
reg->v.command.opt_args = opt_args;
reg->v.command.tags = tags;
}
void
mu_sieve_register_action (mu_sieve_machine_t mach,
const char *name, mu_sieve_handler_t handler,
mu_sieve_data_type *arg_types,
mu_sieve_tag_group_t *tags, int required)
{
return mu_sieve_register_action_ext (mach, name, handler,
arg_types, NULL,
tags,
required);
}