#include <sys_defs.h>
#include <errno.h>
#include <mymalloc.h>
#include <msg.h>
#include <dict.h>
typedef struct {
DICT dict;
char *reason;
} DICT_SURROGATE;
static int dict_surrogate_sequence(DICT *dict, int unused_func,
const char **key, const char **value)
{
DICT_SURROGATE *dp = (DICT_SURROGATE *) dict;
msg_warn("%s:%s is unavailable. %s",
dict->type, dict->name, dp->reason);
DICT_ERR_VAL_RETURN(dict, DICT_ERR_RETRY, DICT_STAT_ERROR);
}
static int dict_surrogate_update(DICT *dict, const char *unused_name,
const char *unused_value)
{
DICT_SURROGATE *dp = (DICT_SURROGATE *) dict;
msg_warn("%s:%s is unavailable. %s",
dict->type, dict->name, dp->reason);
DICT_ERR_VAL_RETURN(dict, DICT_ERR_RETRY, DICT_STAT_ERROR);
}
static const char *dict_surrogate_lookup(DICT *dict, const char *unused_name)
{
DICT_SURROGATE *dp = (DICT_SURROGATE *) dict;
msg_warn("%s:%s is unavailable. %s",
dict->type, dict->name, dp->reason);
DICT_ERR_VAL_RETURN(dict, DICT_ERR_RETRY, (char *) 0);
}
static int dict_surrogate_delete(DICT *dict, const char *unused_name)
{
DICT_SURROGATE *dp = (DICT_SURROGATE *) dict;
msg_warn("%s:%s is unavailable. %s",
dict->type, dict->name, dp->reason);
DICT_ERR_VAL_RETURN(dict, DICT_ERR_RETRY, DICT_STAT_ERROR);
}
static void dict_surrogate_close(DICT *dict)
{
DICT_SURROGATE *dp = (DICT_SURROGATE *) dict;
myfree((char *) dp->reason);
dict_free(dict);
}
int dict_allow_surrogate = 0;
DICT *dict_surrogate(const char *dict_type, const char *dict_name,
int open_flags, int dict_flags,
const char *fmt,...)
{
va_list ap;
DICT_SURROGATE *dp;
VSTRING *buf;
void (*log_fn) (const char *, va_list);
int saved_errno = errno;
log_fn = dict_allow_surrogate ? vmsg_error : vmsg_fatal;
va_start(ap, fmt);
log_fn(fmt, ap);
va_end(ap);
dp = (DICT_SURROGATE *) dict_alloc(dict_type, dict_name, sizeof(*dp));
dp->dict.lookup = dict_surrogate_lookup;
if (open_flags & O_RDWR) {
dp->dict.update = dict_surrogate_update;
dp->dict.delete = dict_surrogate_delete;
}
dp->dict.sequence = dict_surrogate_sequence;
dp->dict.close = dict_surrogate_close;
dp->dict.flags = dict_flags | DICT_FLAG_PATTERN;
dp->dict.owner.status = DICT_OWNER_TRUSTED;
buf = vstring_alloc(10);
errno = saved_errno;
va_start(ap, fmt);
vstring_vsprintf(buf, fmt, ap);
va_end(ap);
dp->reason = vstring_export(buf);
return (DICT_DEBUG (&dp->dict));
}