var-expand.c revision 771178a5c5285aa596723591271c8936c4007f1b
/* Copyright (c) 2003-2010 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "md5.h"
#include "hash.h"
#include "hex-binary.h"
#include "hostpid.h"
#include "str.h"
#include "strescape.h"
#include "var-expand.h"
#include <stdlib.h>
#include <ctype.h>
#define TABLE_LAST(t) \
struct var_expand_context {
int offset;
unsigned int width;
bool zero_padding;
};
struct var_expand_modifier {
char key;
const char *(*func)(const char *, struct var_expand_context *);
};
static const char *
{
return t_str_lcase(str);
}
static const char *
{
return t_str_ucase(str);
}
static const char *
{
return str_escape(str);
}
static const char *
{
unsigned long long l;
return t_strdup_printf("%llx", l);
}
static const char *
{
char *p, *rev;
*p-- = *str;
return rev;
}
{
}
}
static const char *
{
unsigned char digest[16];
}
static const char *
{
while (*str) {
if (*str == '.')
else
str++;
}
return str_free_without_data(&ret);
}
static const char *
{
unsigned int len;
len--;
}
#define MAX_MODIFIER_COUNT 10
static const struct var_expand_modifier modifiers[] = {
{ 'L', m_str_lcase },
{ 'U', m_str_ucase },
{ 'E', m_str_escape },
{ 'X', m_str_hex },
{ 'R', m_str_reverse },
{ 'H', m_str_hash },
{ 'M', m_str_md5 },
{ 'D', m_str_ldap_dn },
{ 'T', m_str_trim },
{ '\0', NULL }
};
static const char *
{
const struct var_expand_table *t;
for (t = table; !TABLE_LAST(t); t++) {
}
}
/* built-in variables: */
T_BEGIN {
switch (key_len) {
case 3:
break;
case 8:
value = my_hostname;
break;
}
} T_END;
return value;
}
const struct var_expand_table *table)
{
const struct var_expand_modifier *m;
const struct var_expand_table *t;
const char *var;
struct var_expand_context ctx;
const char *(*modifier[MAX_MODIFIER_COUNT])
(const char *, struct var_expand_context *);
const char *end;
unsigned int i, len, modifier_count;
if (*str != '%')
else {
int sign = 1;
str++;
/* [<offset>.]<width>[<modifiers>]<variable> */
if (*str == '-') {
sign = -1;
str++;
}
if (*str == '0') {
str++;
}
str++;
}
if (*str == '.') {
str++;
/* if offset was prefixed with zero (or it was
plain zero), just ignore that. zero padding
is done with the width. */
if (*str == '0') {
str++;
}
str++;
}
}
modifier_count = 0;
while (modifier_count < MAX_MODIFIER_COUNT) {
/* @UNSAFE */
m->func;
str++;
break;
}
}
break;
}
if (*str == '\0')
break;
/* %{long_key} */
} else {
for (t = table; !TABLE_LAST(t); t++) {
t->value : "";
break;
}
}
}
/* not found */
if (*str == '%')
var = "%";
}
for (i = 0; i < modifier_count; i++)
/* if offset is < 0 then we want to
start at the end */
} else {
var++;
}
}
else if (!ctx.zero_padding)
else {
/* %05d -like padding. no truncation. */
}
}
}
}
}
}
char var_get_key(const char *str)
{
const struct var_expand_modifier *m;
/* [<offset>.]<width>[<modifiers>]<variable> */
str++;
if (*str == '.') {
str++;
str++;
}
do {
str++;
break;
}
}
} while (m->key != '\0');
return *str;
}
{
return FALSE;
return TRUE;
return FALSE;
}
{
char c;
str++;
c = var_get_key(str);
if (c == key)
return TRUE;
return TRUE;
}
}
}
return FALSE;
}
const struct var_expand_table *
{
struct var_expand_table *var;
}
/* 0, NULL entry */
(void)array_append_space(&variables);
}