X-Git-Url: http://git.madism.org/?a=blobdiff_plain;f=postlicyd%2Fquery.c;h=f24a5d2e5c8d08907feef5f85110650206ca9dd9;hb=8847829f22135d594241a9c51877966e7cb0716a;hp=4a4ae9ca8a80e6fb75f19bf03341efe3f5a5b1eb;hpb=c00b60854ba8968b9e91da74096d913c084139c5;p=apps%2Fpfixtools.git diff --git a/postlicyd/query.c b/postlicyd/query.c index 4a4ae9c..f24a5d2 100644 --- a/postlicyd/query.c +++ b/postlicyd/query.c @@ -38,17 +38,20 @@ #include "policy_tokens.h" #include "str.h" -const char *smtp_state_names[SMTP_count] = { - "CONNECT", - "HELO", - "MAIL", - "RCPT", - "DATA", - "END-OF-MESSAGE", - "VRFY", - "ETRN", +const static_str_t smtp_state_names[SMTP_count] = { + { "CONNECT", 7 }, + { "HELO", 4 }, + { "MAIL", 4 }, + { "RCPT", 4 }, + { "DATA", 4 }, + { "END-OF-MESSAGE", 14 }, + { "VRFY", 4 }, + { "ETRN", 4 }, }; +static const static_str_t static_ESMTP = { "ESMTP", 5 }; +static const static_str_t static_SMTP = { "SMTP", 4 }; + bool query_parse(query_t *query, char *p) { #define PARSE_CHECK(expr, error, ...) \ @@ -81,7 +84,7 @@ bool query_parse(query_t *query, char *p) vtk = policy_tokenize(v, vlen); switch (policy_tokenize(k, klen)) { -#define CASE(up, low) case PTK_##up: query->low = v; v[vlen] = '\0'; break; +#define CASE(up, low) case PTK_##up: query->low.str = v; query->low.len = vlen; v[vlen] = '\0'; break; CASE(HELO_NAME, helo_name); CASE(QUEUE_ID, queue_id); CASE(RECIPIENT_COUNT, recipient_count); @@ -104,20 +107,27 @@ bool query_parse(query_t *query, char *p) #undef CASE case PTK_SENDER: - query->sender = v; + query->sender.str = v; + query->sender.len = vlen; v[vlen] = '\0'; - query->sender_domain = memchr(query->sender, '@', vlen); - if (query->sender_domain != NULL) { - ++query->sender_domain; + query->sender_domain.str = memchr(query->sender.str, '@', vlen); + if (query->sender_domain.str != NULL) { + ++query->sender_domain.str; + query->sender_domain.len = query->sender.len + - (query->sender_domain.str - query->sender.str); } break; case PTK_RECIPIENT: - query->recipient = v; + query->recipient.str = v; + query->recipient.len = vlen; v[vlen] = '\0'; - query->recipient_domain = memchr(query->recipient, '@', vlen); - if (query->recipient_domain != NULL) { - ++query->recipient_domain; + query->recipient_domain.str = memchr(query->recipient.str, '@', vlen); + if (query->recipient_domain.str != NULL) { + ++query->recipient_domain.str; + query->recipient_domain.len = query->recipient.len + - (query->recipient_domain.str - query->recipient.str); + } break; @@ -161,11 +171,11 @@ bool query_parse(query_t *query, char *p) #undef PARSE_CHECK } -const char *query_field_for_id(const query_t *query, postlicyd_token id) +const static_str_t *query_field_for_id(const query_t *query, postlicyd_token id) { switch (id) { #define CASE(Up, Low) \ - case PTK_ ## Up: return query->Low; + case PTK_ ## Up: return &query->Low; CASE(HELO_NAME, helo_name) CASE(QUEUE_ID, queue_id) CASE(SENDER, sender) @@ -191,16 +201,16 @@ const char *query_field_for_id(const query_t *query, postlicyd_token id) CASE(STRESS, stress) #undef CASE case PTK_PROTOCOL_NAME: - return query->esmtp ? "ESMTP" : "SMTP"; + return query->esmtp ? &static_ESMTP : &static_SMTP; case PTK_PROTOCOL_STATE: - return smtp_state_names[query->state]; + return &smtp_state_names[query->state]; default: return NULL; } } -const char *query_field_for_name(const query_t *query, const char *name) +const static_str_t *query_field_for_name(const query_t *query, const char *name) { postlicyd_token id = policy_tokenize(name, strlen(name)); if (id == PTK_UNKNOWN) { @@ -214,7 +224,6 @@ ssize_t query_format(char *dest, size_t len, const char *fmt, const query_t *que { size_t written = 0; size_t pos = 0; - const char *end = fmt + m_strlen(fmt); #define WRITE(Src, Len) \ do { \ @@ -227,9 +236,12 @@ ssize_t query_format(char *dest, size_t len, const char *fmt, const query_t *que pos += __len; \ } while (0) while (*fmt != '\0') { - const char *next_format = strstr(fmt, "${"); + const char *next_format = strchr(fmt, '$'); + while (next_format != NULL && next_format[1] != '{') { + next_format = strchr(next_format + 1, '$'); + } if (next_format == NULL) { - next_format = end; + next_format = fmt + m_strlen(fmt); } WRITE(fmt, next_format - fmt); fmt = next_format; @@ -244,11 +256,12 @@ ssize_t query_format(char *dest, size_t len, const char *fmt, const query_t *que if (tok == PTK_UNKNOWN) { warn("unknown field name \"%.*s\"", (int)(next_format - fmt), fmt); } - const char *field = query == NULL ? NULL : query_field_for_id(query, tok); + const static_str_t *field = query == NULL ? NULL + : query_field_for_id(query, tok); if (field == NULL) { WRITE("(null)", 6); } else { - WRITE(field, m_strlen(field)); + WRITE(field->str, field->len); } fmt = next_format + 1; } @@ -259,3 +272,24 @@ ssize_t query_format(char *dest, size_t len, const char *fmt, const query_t *que } return pos; } + +bool query_format_buffer(buffer_t *buf, const char *fmt, const query_t *query) +{ + buffer_ensure(buf, m_strlen(fmt) + 64); + + ssize_t size = array_free_space(*buf); + ssize_t format_size = query_format(array_end(*buf), + size, fmt, query); + if (format_size == -1) { + return false; + } else if (format_size > size) { + buffer_ensure(buf, format_size + 1); + query_format(array_end(*buf), + array_free_space(*buf), + fmt, query); + array_len(*buf) += format_size; + } else { + array_len(*buf) += format_size; + } + return true; +}