if (priv->headers) {
msg_debug_milter ("cleanup headers");
- g_hash_table_remove_all (priv->headers);
+ gchar *k;
+ GArray *ar;
+
+ kh_foreach (priv->headers, k, ar, {
+ g_free (k);
+ g_array_free (ar, TRUE);
+ });
+
+ kh_clear (milter_headers_hash_t, priv->headers);
}
+
+ priv->cur_hdr = 0;
}
if (how & RSPAMD_MILTER_RESET_ADDR) {
}
if (priv->headers) {
- g_hash_table_destroy (priv->headers);
+ gchar *k;
+ GArray *ar;
+
+ kh_foreach (priv->headers, k, ar, {
+ g_free (k);
+ g_array_free (ar, TRUE);
+ });
+
+ kh_destroy (milter_headers_hash_t, priv->headers);
}
if (milter_ctx->sessions_cache) {
}
else {
if (end > zero && *(end - 1) == '\0') {
- gpointer res;
- gint num;
-
- res = g_hash_table_lookup (priv->headers, pos);
- if (res) {
- num = GPOINTER_TO_INT (res);
- num ++;
- /*
- * We need to copy as glib is totally insane about it:
- * > If you supplied a key_destroy_func when creating the
- * > GHashTable, the passed key is freed using that function.
- */
- g_hash_table_insert (priv->headers, g_strdup (pos),
- GINT_TO_POINTER (num));
+ khiter_t k;
+ gint res;
+
+ k = kh_get (milter_headers_hash_t, priv->headers, (gchar *)pos);
+
+ if (k != kh_end (priv->headers)) {
+ GArray *ar;
+
+ k = kh_put (milter_headers_hash_t, priv->headers,
+ g_strdup (pos), &res);
+ ar = g_array_new (FALSE, FALSE, sizeof (gint));
+ g_array_append_val (ar, priv->cur_hdr);
+ kh_value (priv->headers, k) = ar;
}
else {
- num = 1;
- g_hash_table_insert (priv->headers, g_strdup (pos),
- GINT_TO_POINTER (num));
+ g_array_append_val (kh_value (priv->headers, k),
+ priv->cur_hdr);
}
rspamd_printf_fstring (&session->message, "%*s: %*s\r\n",
(int)(zero - pos), pos,
(int)(end - zero - 2), zero + 1);
+ priv->cur_hdr ++;
}
else {
err = g_error_new (rspamd_milter_quark (), EINVAL, "invalid "
memcpy (priv->pool->tag.uid, pool->tag.uid, sizeof (pool->tag.uid));
}
- priv->headers = g_hash_table_new_full (rspamd_strcase_hash,
- rspamd_strcase_equal, g_free, NULL);
+ priv->headers = kh_init (milter_headers_hash_t);
+ kh_resize (milter_headers_hash_t, priv->headers, 32);
if (tv) {
memcpy (&priv->tv, tv, sizeof (*tv));
rspamd_milter_remove_header_safe (struct rspamd_milter_session *session,
const gchar *key, gint nhdr)
{
- gint saved_nhdr, i;
- gpointer found;
+ gint i;
GString *hname, *hvalue;
struct rspamd_milter_private *priv = session->priv;
+ khiter_t k;
+ GArray *ar;
- found = g_hash_table_lookup (priv->headers, key);
+ k = kh_get (milter_headers_hash_t, priv->headers, (char *)key);
- if (found) {
- saved_nhdr = GPOINTER_TO_INT (found);
+ if (k != kh_end (priv->headers)) {
+ ar = kh_val (priv->headers, k);
hname = g_string_new (key);
hvalue = g_string_new ("");
}
else if (nhdr == 0) {
/* We need to clear all headers */
- for (i = 1; i <= saved_nhdr; i ++) {
+ for (i = 1; i <= ar->len; i ++) {
rspamd_milter_send_action (session,
RSPAMD_MILTER_CHGHEADER,
i, hname, hvalue);
}
else {
/* Remove from the end */
- if (nhdr >= -saved_nhdr) {
+ if (nhdr >= -(ar->len)) {
rspamd_milter_send_action (session,
RSPAMD_MILTER_CHGHEADER,
- saved_nhdr + nhdr + 1, hname, hvalue);
+ ar->len + nhdr + 1, hname, hvalue);
}
}
if (val && ucl_object_type (val) == UCL_STRING) {
const ucl_object_t *idx_obj;
+ gboolean has_idx = FALSE;
idx_obj = ucl_object_lookup_any (cur_elt, "order",
"index", NULL);
+
if (idx_obj) {
idx = ucl_object_toint (idx_obj);
+ has_idx = TRUE;
}
hname = g_string_new (ucl_object_key (cur));
hvalue = g_string_new (ucl_object_tostring (val));
- if (idx >= 0) {
- rspamd_milter_send_action (session,
- RSPAMD_MILTER_INSHEADER,
- idx,
- hname, hvalue);
+ if (has_idx) {
+ if (idx >= 0) {
+ rspamd_milter_send_action (session,
+ RSPAMD_MILTER_INSHEADER,
+ idx,
+ hname, hvalue);
+ }
+ else {
+ /* Calculate negative offset */
+ }
}
else {
rspamd_milter_send_action (session,