Mercurial > dovecot > core-2.2
view src/auth/auth-stream.c @ 14159:98d696965c91
auth: Added auth_proxy_self setting to specify IPs that are considered as "self" for proxy_maybe.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 25 Feb 2012 05:42:05 +0200 |
parents | 52e8a1346d2e |
children | fc8031c5e691 |
line wrap: on
line source
/* Copyright (c) 2005-2012 Dovecot authors, see the included COPYING file */ #include "auth-common.h" #include "str.h" #include "strescape.h" #include "ostream.h" #include "auth-request.h" #include "auth-stream.h" struct auth_stream_reply { string_t *str; }; struct auth_stream_reply *auth_stream_reply_init(pool_t pool) { struct auth_stream_reply *reply; reply = p_new(pool, struct auth_stream_reply, 1); reply->str = str_new(pool, 128); return reply; } void auth_stream_reply_add(struct auth_stream_reply *reply, const char *key, const char *value) { if (str_len(reply->str) > 0) str_append_c(reply->str, '\t'); if (key != NULL) { i_assert(*key != '\0'); i_assert(strchr(key, '\t') == NULL && strchr(key, '\n') == NULL); str_append(reply->str, key); if (value != NULL) str_append_c(reply->str, '='); } if (value != NULL) { /* escape dangerous characters in the value */ str_tabescape_write(reply->str, value); } } static bool auth_stream_reply_find_area(struct auth_stream_reply *reply, const char *key, unsigned int *idx_r, unsigned int *len_r) { const char *str = str_c(reply->str); unsigned int i, start, key_len = strlen(key); i = 0; while (str[i] != '\0') { start = i; for (; str[i] != '\0'; i++) { if (str[i] == '\t') break; } if (strncmp(str+start, key, key_len) == 0 && (str[start+key_len] == '=' || str[start+key_len] == '\t' || str[start+key_len] == '\0')) { *idx_r = start; *len_r = i - start; return TRUE; } if (str[i] == '\t') i++; } return FALSE; } void auth_stream_reply_remove(struct auth_stream_reply *reply, const char *key) { unsigned int idx, len; if (!auth_stream_reply_find_area(reply, key, &idx, &len)) return; if (idx == 0 && str_len(reply->str) == len) { /* removing the only item */ } else if (str_len(reply->str) == idx + len) { /* removing the last item -> remove the preceding tab */ len++; idx--; } else { /* remove the trailing tab */ len++; } str_delete(reply->str, idx, len); } const char *auth_stream_reply_find(struct auth_stream_reply *reply, const char *key) { unsigned int idx, len, keylen; if (!auth_stream_reply_find_area(reply, key, &idx, &len)) return NULL; else { keylen = strlen(key); if (len == keylen) { /* key without =value */ return ""; } i_assert(len > keylen); idx += keylen + 1; len -= keylen + 1; return t_strndup(str_c(reply->str) + idx, len); } } bool auth_stream_reply_exists(struct auth_stream_reply *reply, const char *key) { unsigned int idx, len; return auth_stream_reply_find_area(reply, key, &idx, &len); } void auth_stream_reply_reset(struct auth_stream_reply *reply) { str_truncate(reply->str, 0); } void auth_stream_reply_import(struct auth_stream_reply *reply, const char *str) { if (str_len(reply->str) > 0) str_append_c(reply->str, '\t'); str_append(reply->str, str); } const char *auth_stream_reply_export(struct auth_stream_reply *reply) { return str_c(reply->str); } bool auth_stream_is_empty(struct auth_stream_reply *reply) { return reply == NULL || str_len(reply->str) == 0; } const char *const *auth_stream_split(struct auth_stream_reply *reply) { return t_strsplit(str_c(reply->str), "\t"); } string_t *auth_stream_reply_get_str(struct auth_stream_reply *reply) { return reply->str; }