Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/var-expand.c @ 8590:b9faf4db2a9f HEAD
Updated copyright notices to include year 2009.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 06 Jan 2009 09:25:38 -0500 |
parents | 983d38de06c9 |
children | ef7b42b237bd |
rev | line source |
---|---|
8590
b9faf4db2a9f
Updated copyright notices to include year 2009.
Timo Sirainen <tss@iki.fi>
parents:
8544
diff
changeset
|
1 /* Copyright (c) 2003-2009 Dovecot authors, see the included COPYING file */ |
1034 | 2 |
3 #include "lib.h" | |
5485 | 4 #include "array.h" |
4162
baa2f72e4010
%M modifier returns string's MD5 sum. Patch by Ben Winslow
Timo Sirainen <tss@iki.fi>
parents:
4160
diff
changeset
|
5 #include "md5.h" |
3566 | 6 #include "hash.h" |
4162
baa2f72e4010
%M modifier returns string's MD5 sum. Patch by Ben Winslow
Timo Sirainen <tss@iki.fi>
parents:
4160
diff
changeset
|
7 #include "hex-binary.h" |
1034 | 8 #include "str.h" |
2057
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
9 #include "strescape.h" |
1034 | 10 #include "var-expand.h" |
11 | |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
12 #include <stdlib.h> |
7523 | 13 #include <ctype.h> |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
14 |
8544
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
15 #define TABLE_LAST(t) \ |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
16 ((t)->key == '\0' && (t)->long_key == NULL) |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
17 |
3566 | 18 struct var_expand_context { |
4558
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
19 int offset; |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
20 unsigned int width; |
4788
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
21 bool zero_padding; |
3566 | 22 }; |
23 | |
2057
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
24 struct var_expand_modifier { |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
25 char key; |
3566 | 26 const char *(*func)(const char *, struct var_expand_context *); |
2057
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
27 }; |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
28 |
3566 | 29 static const char * |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
5485
diff
changeset
|
30 m_str_lcase(const char *str, struct var_expand_context *ctx ATTR_UNUSED) |
3566 | 31 { |
32 return t_str_lcase(str); | |
33 } | |
34 | |
35 static const char * | |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
5485
diff
changeset
|
36 m_str_ucase(const char *str, struct var_expand_context *ctx ATTR_UNUSED) |
3566 | 37 { |
4160
86fa00c163dc
%U modifier was actually lowercasing the string. Patch by Ben Winslow
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
38 return t_str_ucase(str); |
3566 | 39 } |
40 | |
41 static const char * | |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
5485
diff
changeset
|
42 m_str_escape(const char *str, struct var_expand_context *ctx ATTR_UNUSED) |
3566 | 43 { |
44 return str_escape(str); | |
45 } | |
46 | |
47 static const char * | |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
5485
diff
changeset
|
48 m_str_hex(const char *str, struct var_expand_context *ctx ATTR_UNUSED) |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
49 { |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
50 unsigned long long l; |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
51 |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
52 l = strtoull(str, NULL, 10); |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
53 return t_strdup_printf("%llx", l); |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
54 } |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
55 |
3573 | 56 static const char * |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
5485
diff
changeset
|
57 m_str_reverse(const char *str, struct var_expand_context *ctx ATTR_UNUSED) |
3573 | 58 { |
59 size_t len = strlen(str); | |
60 char *p, *rev; | |
61 | |
62 rev = t_malloc(len + 1); | |
63 rev[len] = '\0'; | |
64 | |
65 for (p = rev + len - 1; *str != '\0'; str++) | |
66 *p-- = *str; | |
67 return rev; | |
68 } | |
69 | |
3566 | 70 static const char *m_str_hash(const char *str, struct var_expand_context *ctx) |
71 { | |
72 unsigned int value = str_hash(str); | |
73 string_t *hash = t_str_new(20); | |
74 | |
75 if (ctx->width != 0) { | |
76 value %= ctx->width; | |
77 ctx->width = 0; | |
78 } | |
3572 | 79 |
3566 | 80 str_printfa(hash, "%x", value); |
4558
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
81 while ((int)str_len(hash) < ctx->offset) |
3566 | 82 str_insert(hash, 0, "0"); |
83 ctx->offset = 0; | |
84 | |
85 return str_c(hash); | |
86 } | |
87 | |
7523 | 88 static const char * |
89 m_str_md5(const char *str, struct var_expand_context *ctx ATTR_UNUSED) | |
4162
baa2f72e4010
%M modifier returns string's MD5 sum. Patch by Ben Winslow
Timo Sirainen <tss@iki.fi>
parents:
4160
diff
changeset
|
90 { |
baa2f72e4010
%M modifier returns string's MD5 sum. Patch by Ben Winslow
Timo Sirainen <tss@iki.fi>
parents:
4160
diff
changeset
|
91 unsigned char digest[16]; |
baa2f72e4010
%M modifier returns string's MD5 sum. Patch by Ben Winslow
Timo Sirainen <tss@iki.fi>
parents:
4160
diff
changeset
|
92 |
baa2f72e4010
%M modifier returns string's MD5 sum. Patch by Ben Winslow
Timo Sirainen <tss@iki.fi>
parents:
4160
diff
changeset
|
93 md5_get_digest(str, strlen(str), digest); |
baa2f72e4010
%M modifier returns string's MD5 sum. Patch by Ben Winslow
Timo Sirainen <tss@iki.fi>
parents:
4160
diff
changeset
|
94 |
baa2f72e4010
%M modifier returns string's MD5 sum. Patch by Ben Winslow
Timo Sirainen <tss@iki.fi>
parents:
4160
diff
changeset
|
95 return binary_to_hex(digest, sizeof(digest)); |
baa2f72e4010
%M modifier returns string's MD5 sum. Patch by Ben Winslow
Timo Sirainen <tss@iki.fi>
parents:
4160
diff
changeset
|
96 } |
baa2f72e4010
%M modifier returns string's MD5 sum. Patch by Ben Winslow
Timo Sirainen <tss@iki.fi>
parents:
4160
diff
changeset
|
97 |
7523 | 98 static const char * |
99 m_str_ldap_dn(const char *str, struct var_expand_context *ctx ATTR_UNUSED) | |
4693
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
100 { |
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
101 string_t *ret = t_str_new(256); |
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
102 |
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
103 while (*str) { |
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
104 if (*str == '.') |
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
105 str_append(ret, ",dc="); |
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
106 else |
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
107 str_append_c(ret, *str); |
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
108 str++; |
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
109 } |
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
110 |
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
111 return str_free_without_data(&ret); |
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
112 } |
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
113 |
7523 | 114 static const char * |
115 m_str_trim(const char *str, struct var_expand_context *ctx ATTR_UNUSED) | |
116 { | |
117 unsigned int len; | |
118 | |
119 len = strlen(str); | |
120 while (len > 0 && i_isspace(str[len-1])) | |
121 len--; | |
122 return t_strndup(str, len); | |
123 } | |
124 | |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
125 #define MAX_MODIFIER_COUNT 10 |
2057
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
126 static const struct var_expand_modifier modifiers[] = { |
3566 | 127 { 'L', m_str_lcase }, |
128 { 'U', m_str_ucase }, | |
129 { 'E', m_str_escape }, | |
130 { 'X', m_str_hex }, | |
3573 | 131 { 'R', m_str_reverse }, |
3566 | 132 { 'H', m_str_hash }, |
4162
baa2f72e4010
%M modifier returns string's MD5 sum. Patch by Ben Winslow
Timo Sirainen <tss@iki.fi>
parents:
4160
diff
changeset
|
133 { 'M', m_str_md5 }, |
4693
c28892e80d6c
Added %D modified to return "sub.domain.org" as "sub,dc=domain,dc=org" (for
Timo Sirainen <tss@iki.fi>
parents:
4558
diff
changeset
|
134 { 'D', m_str_ldap_dn }, |
7523 | 135 { 'T', m_str_trim }, |
2057
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
136 { '\0', NULL } |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
137 }; |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
138 |
1034 | 139 void var_expand(string_t *dest, const char *str, |
2057
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
140 const struct var_expand_table *table) |
1034 | 141 { |
2057
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
142 const struct var_expand_modifier *m; |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
143 const struct var_expand_table *t; |
1034 | 144 const char *var; |
3566 | 145 struct var_expand_context ctx; |
146 const char *(*modifier[MAX_MODIFIER_COUNT]) | |
147 (const char *, struct var_expand_context *); | |
8544
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
148 const char *end; |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
149 unsigned int i, len, modifier_count; |
1034 | 150 |
3566 | 151 memset(&ctx, 0, sizeof(ctx)); |
1034 | 152 for (; *str != '\0'; str++) { |
153 if (*str != '%') | |
154 str_append_c(dest, *str); | |
155 else { | |
4788
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
156 int sign = 1; |
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
157 |
2057
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
158 str++; |
4788
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
159 memset(&ctx, 0, sizeof(ctx)); |
2368
1ce02ffc7ec7
Added support for %offset.width format in variables.
Timo Sirainen <tss@iki.fi>
parents:
2057
diff
changeset
|
160 |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
161 /* [<offset>.]<width>[<modifiers>]<variable> */ |
4558
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
162 if (*str == '-') { |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
163 sign = -1; |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
164 str++; |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
165 } |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
166 if (*str == '0') { |
4788
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
167 ctx.zero_padding = TRUE; |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
168 str++; |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
169 } |
2057
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
170 while (*str >= '0' && *str <= '9') { |
3566 | 171 ctx.width = ctx.width*10 + (*str - '0'); |
1034 | 172 str++; |
173 } | |
174 | |
4788
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
175 if (*str == '.') { |
4558
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
176 ctx.offset = sign * (int)ctx.width; |
3566 | 177 ctx.width = 0; |
2368
1ce02ffc7ec7
Added support for %offset.width format in variables.
Timo Sirainen <tss@iki.fi>
parents:
2057
diff
changeset
|
178 str++; |
4788
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
179 |
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
180 /* if offset was prefixed with zero (or it was |
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
181 plain zero), just ignore that. zero padding |
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
182 is done with the width. */ |
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
183 ctx.zero_padding = FALSE; |
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
184 if (*str == '0') { |
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
185 ctx.zero_padding = TRUE; |
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
186 str++; |
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
187 } |
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
188 |
2368
1ce02ffc7ec7
Added support for %offset.width format in variables.
Timo Sirainen <tss@iki.fi>
parents:
2057
diff
changeset
|
189 while (*str >= '0' && *str <= '9') { |
3566 | 190 ctx.width = ctx.width*10 + (*str - '0'); |
2368
1ce02ffc7ec7
Added support for %offset.width format in variables.
Timo Sirainen <tss@iki.fi>
parents:
2057
diff
changeset
|
191 str++; |
1ce02ffc7ec7
Added support for %offset.width format in variables.
Timo Sirainen <tss@iki.fi>
parents:
2057
diff
changeset
|
192 } |
1ce02ffc7ec7
Added support for %offset.width format in variables.
Timo Sirainen <tss@iki.fi>
parents:
2057
diff
changeset
|
193 } |
1ce02ffc7ec7
Added support for %offset.width format in variables.
Timo Sirainen <tss@iki.fi>
parents:
2057
diff
changeset
|
194 |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
195 modifier_count = 0; |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
196 while (modifier_count < MAX_MODIFIER_COUNT) { |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
197 modifier[modifier_count] = NULL; |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
198 for (m = modifiers; m->key != '\0'; m++) { |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
199 if (m->key == *str) { |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
200 /* @UNSAFE */ |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
201 modifier[modifier_count] = |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
202 m->func; |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
203 str++; |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
204 break; |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
205 } |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
206 } |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
207 if (modifier[modifier_count] == NULL) |
2057
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
208 break; |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
209 modifier_count++; |
1034 | 210 } |
211 | |
2057
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
212 if (*str == '\0') |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
213 break; |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
214 |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
215 var = NULL; |
8544
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
216 if (*str == '{' && (end = strchr(str, '}')) != NULL) { |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
217 /* %{long_key} */ |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
218 len = end - (str + 1); |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
219 for (t = table; !TABLE_LAST(t); t++) { |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
220 if (t->long_key != NULL && |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
221 strncmp(t->long_key, str+1, |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
222 len) == 0 && |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
223 t->long_key[len] == '\0') { |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
224 var = t->value != NULL ? |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
225 t->value : ""; |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
226 str = end; |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
227 break; |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
228 } |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
229 } |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
230 } else { |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
231 for (t = table; !TABLE_LAST(t); t++) { |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
232 if (t->key == *str) { |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
233 var = t->value != NULL ? |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
234 t->value : ""; |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
235 break; |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
236 } |
2057
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
237 } |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
238 } |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
239 |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
240 if (var == NULL) { |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
241 /* not found */ |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
242 if (*str == '%') |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
243 var = "%"; |
5e0167577399
Fixed var_expand() to take a table of variables rather than a few predefined
Timo Sirainen <tss@iki.fi>
parents:
1034
diff
changeset
|
244 } |
1034 | 245 |
246 if (var != NULL) { | |
3566 | 247 for (i = 0; i < modifier_count; i++) |
248 var = modifier[i](var, &ctx); | |
4558
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
249 |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
250 if (ctx.offset < 0) { |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
251 /* if offset is < 0 then we want to |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
252 start at the end */ |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
253 size_t len = strlen(var); |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
254 |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
255 if (len > (size_t)-ctx.offset) |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
256 var += len + ctx.offset; |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
257 } else { |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
258 while (*var != '\0' && ctx.offset > 0) { |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
259 ctx.offset--; |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
260 var++; |
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
261 } |
3566 | 262 } |
263 if (ctx.width == 0) | |
1034 | 264 str_append(dest, var); |
4788
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
265 else if (!ctx.zero_padding) |
3566 | 266 str_append_n(dest, var, ctx.width); |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
267 else { |
4788
385b77e37f1f
Fixed zero padding handling and documented it. %0.1n shouldn't enable it,
Timo Sirainen <tss@iki.fi>
parents:
4693
diff
changeset
|
268 /* %05d -like padding. no truncation. */ |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
269 size_t len = strlen(var); |
3566 | 270 while (len < ctx.width) { |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
271 str_append_c(dest, '0'); |
3566 | 272 ctx.width--; |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
273 } |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
274 str_append(dest, var); |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
275 } |
1034 | 276 } |
277 } | |
278 } | |
279 } | |
2975
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
280 |
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
281 char var_get_key(const char *str) |
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
282 { |
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
283 const struct var_expand_modifier *m; |
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
284 |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
285 /* [<offset>.]<width>[<modifiers>]<variable> */ |
4558
fc58084df7b5
Negative offsets count from the end of the string. Patch by Johannes Berg.
Timo Sirainen <tss@iki.fi>
parents:
4162
diff
changeset
|
286 while ((*str >= '0' && *str <= '9') || *str == '-') |
2975
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
287 str++; |
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
288 |
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
289 if (*str == '.') { |
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
290 str++; |
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
291 while (*str >= '0' && *str <= '9') |
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
292 str++; |
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
293 } |
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
294 |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
295 do { |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
296 for (m = modifiers; m->key != '\0'; m++) { |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
297 if (m->key == *str) { |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
298 str++; |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
299 break; |
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
300 } |
2975
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
301 } |
2977
4a6788997812
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
Timo Sirainen <tss@iki.fi>
parents:
2975
diff
changeset
|
302 } while (m->key != '\0'); |
2975
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
303 |
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
304 return *str; |
c59fd95ad3ee
Auth cache key was built wrong if any modifiers were used for %vars.
Timo Sirainen <tss@iki.fi>
parents:
2368
diff
changeset
|
305 } |
5485 | 306 |
8544
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
307 bool var_has_key(const char *str, char key, const char *long_key) |
8324 | 308 { |
8544
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
309 const char *end; |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
310 char c; |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
311 |
8324 | 312 for (; *str != '\0'; str++) { |
313 if (*str == '%' && str[1] != '\0') { | |
314 str++; | |
8544
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
315 c = var_get_key(str); |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
316 if (c == key) |
8324 | 317 return TRUE; |
8544
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
318 |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
319 if (c == '{' && long_key != NULL && |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
320 (str = strchr(str, '{')) != NULL && |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
321 (end = strchr(++str, '}')) != NULL) { |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
322 if (strncmp(str, long_key, end-str) == 0 && |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
323 long_key[end-str] == '\0') |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
324 return TRUE; |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
325 str = end; |
983d38de06c9
var_expand(): Added support for long %{variable} names.
Timo Sirainen <tss@iki.fi>
parents:
8324
diff
changeset
|
326 } |
8324 | 327 } |
328 } | |
329 return FALSE; | |
330 } | |
331 | |
5485 | 332 const struct var_expand_table * |
333 var_expand_table_build(char key, const char *value, char key2, ...) | |
334 { | |
335 ARRAY_DEFINE(variables, struct var_expand_table); | |
336 struct var_expand_table *var; | |
337 va_list args; | |
338 | |
339 i_assert(key != '\0'); | |
340 | |
341 t_array_init(&variables, 16); | |
342 var = array_append_space(&variables); | |
343 var->key = key; | |
344 var->value = value; | |
345 | |
346 va_start(args, key2); | |
347 for (key = key2; key != '\0'; key = va_arg(args, int)) { | |
348 var = array_append_space(&variables); | |
349 var->key = key; | |
350 var->value = va_arg(args, const char *); | |
351 } | |
352 va_end(args); | |
353 | |
354 /* 0, NULL entry */ | |
355 (void)array_append_space(&variables); | |
356 return array_idx(&variables, 0); | |
357 } |