free(line);
break;
}
- if(!tll_length(*allhdrs) || ((line[0] != '\t') && (line[0] != ' '))) /* first header line or no more unfolding */
- tll_push_back(*allhdrs, line);
+ if(!allhdrs->len || ((line[0] != '\t') && (line[0] != ' '))) /* first header line or no more unfolding */
+ vec_push(allhdrs, line);
else{
- xasprintf(&tmp, "%s%s", tll_back(*allhdrs), line);
- free(tll_pop_back(*allhdrs));
- tll_push_back(*allhdrs, tmp);
+ xasprintf(&tmp, "%s%s", vec_last(allhdrs), line);
+ free(vec_pop(allhdrs));
+ vec_push(allhdrs, tmp);
}
free(line);
}
* returns 0 on success
*/
static int write_hdrs(int outfd, strlist* hdrs,off_t* unwantedmime_hdrpos) {
- tll_foreach(*hdrs, hdr) {
- if(dprintf(outfd, "%s", hdr->item) < 0){
+ vec_foreach(*hdrs, _i) {
+ if(dprintf(outfd, "%s", hdrs->d[_i]) < 0){
log_error(LOG_ARGS, "Error when dumping headers");
return -1;
}
strip = 0;
/* check if the boundary is the beginning of a new part */
if(strncmp(line + strlen(boundary),"--",2)){
- strlist hdrs = tll_init();
+ strlist hdrs = vec_init();
char* new_boundary = NULL;
/* check if this part should be stripped */
if(read_hdrs(infd, &hdrs,delmime,denymime,deny,&new_boundary) == MIME_STRIP)
return -1;
}
}
- tll_free_and_free(hdrs, free);
+ vec_free_and_free(&hdrs, free);
if(new_boundary)
free(new_boundary);
}else{
/* read a mail stripping unwanted parts */
static int dump_mail(int infd, int outfd,char* listdir) {
- strlist hdrs = tll_init();
+ strlist hdrs = vec_init();
strlist *delmime;
strlist *denymime;
char* boundary=NULL;
}
/* free mail header */
- tll_free_and_free(hdrs, free);
+ vec_free_and_free(&hdrs, free);
if(result == MIME_OK && !deny) {
/* try to parse the mail */
/* free mime types */
if(delmime) {
- tll_free_and_free(*delmime, free);
+ vec_free_and_free(delmime, free);
free(delmime);
}
if(denymime) {
- tll_free_and_free(*denymime, free);
+ vec_free_and_free(denymime, free);
free(denymime);
}
return 0;
#include "config.h"
#include <stdbool.h>
#include <time.h>
-#include <tllist.h>
+#include <vec.h>
#ifndef MLMMJ_UNUSED
#define MLMMJ_UNUSED __attribute__((__unused__))
int ctrlfd;
};
-typedef tll(char *) strlist;
+typedef vec_t(char *) strlist;
typedef enum bounce {
BOUNCE_OK,
+++ /dev/null
-#pragma once
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <assert.h>
-
-#define TLL_PASTE2( a, b) a##b
-#define TLL_PASTE( a, b) TLL_PASTE2( a, b)
-
-/* Utility macro to generate a list element struct with a unique struct tag */
-#define TLL_UNIQUE_INNER_STRUCT(TYPE, ID) \
- struct TLL_PASTE(__tllist_ , ID) { \
- TYPE item; \
- struct TLL_PASTE(__tllist_, ID) *prev; \
- struct TLL_PASTE(__tllist_, ID) *next; \
- } *head, *tail;
-
-/*
- * Defines a new typed-list type, or directly instantiate a typed-list variable
- *
- * Example a, declare a variable (list of integers):
- * tll(int) my_list;
- *
- * Example b, declare a type, and then use the type:
- * tll(int, my_list_type);
- * struct my_list_type my_list;
- */
-#define tll(TYPE) \
- struct { \
- TLL_UNIQUE_INNER_STRUCT(TYPE, __COUNTER__) \
- size_t length; \
- }
-
-/* Initializer: tll(int) my_list = tll_init(); */
-#define tll_init() {.head = NULL, .tail = NULL, .length = 0}
-
-/* Length/size of list: printf("size: %zu\n", tll_length(my_list)); */
-#define tll_length(list) (list).length
-
-/* Adds a new item to the back of the list */
-#define tll_push_back(list, new_item) \
- do { \
- tll_insert_after(list, (list).tail, new_item); \
- if ((list).head == NULL) \
- (list).head = (list).tail; \
- } while (0)
-
-/* Adds a new item to the front of the list */
-#define tll_push_front(list, new_item) \
- do { \
- tll_insert_before(list, (list).head, new_item); \
- if ((list).tail == NULL) \
- (list).tail = (list).head; \
- } while (0)
-
-/*
- * Iterates the list. <it> is an iterator pointer. You can access the
- * list item with ->item:
- *
- * tll(int) my_list = vinit();
- * tll_push_back(my_list, 5);
- *
- * tll_foreach(my_list i) {
- * printf("%d\n", i->item);
- * }
-*/
-#define tll_foreach(list, it) \
- for (__typeof__(*(list).head) *it = (list).head, \
- *it_next = it != NULL ? it->next : NULL; \
- it != NULL; \
- it = it_next, \
- it_next = it_next != NULL ? it_next->next : NULL)
-
-/* Same as tll_foreach(), but iterates backwards */
-#define tll_rforeach(list, it) \
- for (__typeof__(*(list).tail) *it = (list).tail, \
- *it_prev = it != NULL ? it->prev : NULL; \
- it != NULL; \
- it = it_prev, \
- it_prev = it_prev != NULL ? it_prev->prev : NULL)
-
-/*
- * Inserts a new item after <it>, which is an iterator. I.e. you can
- * only call this from inside a tll_foreach() or tll_rforeach() loop.
- */
-#define tll_insert_after(list, it, new_item) \
- do { \
- __typeof__((list).head) __e = malloc(sizeof(*__e)); \
- __e->item = (new_item); \
- __e->prev = (it); \
- __e->next = (it) != NULL ? (it)->next : NULL; \
- if ((it) != NULL) { \
- if ((it)->next != NULL) \
- (it)->next->prev = __e; \
- (it)->next = __e; \
- } \
- if ((it) == (list).tail) \
- (list).tail = __e; \
- (list).length++; \
- } while (0)
-
-/*
- * Inserts a new item before <it>, which is an iterator. I.e. you can
- * only call this from inside a tll_foreach() or tll_rforeach() loop.
- */
-#define tll_insert_before(list, it, new_item) \
- do { \
- __typeof__((list).head) __e = malloc(sizeof(*__e)); \
- __e->item = (new_item); \
- __e->prev = (it) != NULL ? (it)->prev : NULL; \
- __e->next = (it); \
- if ((it) != NULL) { \
- if ((it)->prev != NULL) \
- (it)->prev->next = __e; \
- (it)->prev = __e; \
- } \
- if ((it) == (list).head) \
- (list).head = __e; \
- (list).length++; \
- } while (0)
-
-/*
- * Removes an entry from the list. <it> is an iterator. I.e. you can
- * only call this from inside a tll_foreach() or tll_rforeach() loop.
- */
-#define tll_remove(list, it) \
- do { \
- assert((list).length > 0); \
- __typeof__((list).head) __prev = it->prev; \
- __typeof__((list).head) __next = it->next; \
- if (__prev != NULL) \
- __prev->next = __next; \
- else \
- (list).head = __next; \
- if (__next != NULL) \
- __next->prev = __prev; \
- else \
- (list).tail = __prev; \
- free(it); \
- (list).length--; \
- } while (0)
-
-/* Same as tll_remove(), but calls free_callback(it->item) */
-#define tll_remove_and_free(list, it, free_callback) \
- do { \
- free_callback((it)->item); \
- tll_remove((list), (it)); \
- } while (0)
-
-#define tll_front(list) (list).head->item
-#define tll_back(list) (list).tail->item
-
-/*
- * Removes the first element from the list, and returns it (note:
- * returns the *actual* item, not an iterator.
- */
-#define tll_pop_front(list) __extension__ \
- ({ \
- __typeof__((list).head) it = (list).head; \
- __typeof__((list).head->item) __ret = it->item; \
- tll_remove((list), it); \
- __ret; \
- })
-
-/* Same as tll_pop_front(), but returns/removes the *last* element */
-#define tll_pop_back(list) __extension__ \
- ({ \
- __typeof__((list).tail) it = (list).tail; \
- __typeof__((list).tail->item) __ret = it->item; \
- tll_remove((list), it); \
- __ret; \
- })
-
-/* Frees the list. This call is *not* needed if the list is already empty. */
-#define tll_free(list) \
- do { \
- tll_foreach(list, __it) \
- free(__it); \
- (list).length = 0; \
- (list).head = (list).tail = NULL; \
- } while (0)
-
-/* Same as tll_free(), but also calls free_callback(item) for every item */
-#define tll_free_and_free(list, free_callback) \
- do { \
- tll_foreach(list, __it) { \
- free_callback(__it->item); \
- free(__it); \
- } \
- (list).length = 0; \
- (list).head = (list).tail = NULL; \
- } while (0)
-
-#define tll_sort(list, cmp) \
- do { \
- __typeof((list).head) __p; \
- __typeof((list).head) __q; \
- __typeof((list).head) __e; \
- __typeof((list).head) __t; \
- int __insize, __nmerges, __p_size, __q_size; \
- if ((list).head == NULL) \
- break; \
- __insize = 1; \
- while (1) { \
- __p = (list).head; \
- (list).head = NULL; \
- __t = NULL; \
- __nmerges = 0; \
- while (__p != NULL) { \
- __nmerges++; \
- __q = __p; \
- __p_size = 0; \
- for (int _i = 0; _i < __insize; _i++) { \
- __p_size++; \
- __q = __q->next; \
- if (__q == NULL) \
- break; \
- } \
- __q_size = __insize; \
- while (__p_size > 0 || (__q_size > 0 && __q != NULL)) { \
- if (__p_size == 0) { \
- __e = __q; \
- __q = __q->next; \
- __q_size--; \
- } else if (__q_size == 0 || __q == NULL) { \
- __e = __p; \
- __p = __p->next; \
- __p_size--; \
- } else if (cmp(__p->item, __q->item) <= 0) { \
- __e = __p; \
- __p = __p->next; \
- __p_size--; \
- } else { \
- __e = __q; \
- __q = __q->next; \
- __q_size--; \
- } \
- if (__t != NULL) { \
- __t->next = __e; \
- } else { \
- (list).head = __e; \
- } \
- __e->prev = __t; \
- __t = __e; \
- } \
- __p = __q; \
- } \
- (list).tail = __t; \
- __t->next = NULL; \
- __insize *= 2; \
- if (__nmerges <= 1) \
- break; \
- } \
- } while (0)
--- /dev/null
+/*-
+ * Copyright(c) 2024-2025 Baptiste Daroussin <bapt@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef VEC_H
+#define VEC_H
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+#define vec_t(Type) \
+ struct { Type *d; size_t len, cap; }
+
+#define vec_init() \
+ { .d = NULL, .len = 0, .cap = 0 }
+
+#define vec_foreach(list, __i) \
+ for (size_t __i = 0; __i < (list).len; __i++)
+
+/* ssize_t because the value can be negative */
+#define vec_rforeach(list, __i) \
+ for (ssize_t __i = ((ssize_t)(list).len) -1 ; __i >= 0; __i--)
+
+#define vec_free(v) \
+ do { \
+ free((v)->d); \
+ memset((v), 0, sizeof(*(v))); \
+ } while (0)
+
+#define vec_free_and_free(v, free_func) \
+ do { \
+ vec_foreach(*(v), _i) { \
+ free_func((v)->d[_i]); \
+ (v)->d[_i] = NULL; \
+ } \
+ vec_free((v)); \
+ } while(0)
+
+#define vec_first(v) \
+ (v)->d[0]
+
+#define vec_last(v) \
+ (v)->d[(v)->len -1]
+
+#define vec_clear(v) \
+ (v)->len = 0
+
+#define vec_clear_and_free(v, free_func) \
+ do { \
+ vec_foreach(*(v), _i) { \
+ free_func((v)->d[_i]); \
+ (v)->d[_i] = NULL; \
+ } \
+ (v)->len = 0; \
+ } while (0)
+
+#define vec_push(v, _d) \
+ do { \
+ if ((v)->len >= (v)->cap) { \
+ if ((v)->cap == 0) \
+ (v)->cap = 1; \
+ else \
+ (v)->cap *=2; \
+ (v)->d = realloc((v)->d, (v)->cap * sizeof(*(v)->d)); \
+ if ((v)->d == NULL) \
+ abort(); \
+ } \
+ (v)->d[(v)->len++] = (_d); \
+ } while (0) \
+
+#define vec_push_front(v, _d) \
+ do { \
+ if ((v)->len >= (v)->cap) { \
+ if ((v)->cap == 0) \
+ (v)->cap = 1; \
+ else \
+ (v)->cap *= 2; \
+ (v)->d = realloc((v)->d, (v)->cap * sizeof(*(v)->d)); \
+ if ((v)->d == NULL) \
+ abort(); \
+ } \
+ for (size_t _i = (v)->len; _i > 0; _i--) \
+ (v)->d[_i] = (v)->d[_i - 1]; \
+ (v)->d[0] = (_d); \
+ (v)->len++; \
+ } while (0)
+
+#define vec_pop(v) \
+ (v)->d[--(v)->len]
+
+#define vec_pop_front(v) __extension__ \
+ ({ \
+ __typeof__(*(v)->d) _ret = (v)->d[0]; \
+ vec_remove(v, 0); \
+ _ret; \
+ })
+
+#define vec_remove(v, cnt) \
+ do { \
+ for (size_t _i = cnt; _i < (v)->len - 1; _i++) { \
+ (v)->d[_i] = (v)->d[_i + 1]; \
+ } \
+ (v)->len--; \
+ } while (0)
+
+#define vec_remove_and_free(v, cnt, free_func) \
+ do { \
+ free_func((v)->d[cnt]); \
+ vec_remove(v, cnt); \
+ } while (0)
+
+/*
+ * Remove the element at the given index and replace it with the last
+ * element in the vec. Does not preserve order, but is O(1).
+ */
+#define vec_swap_remove(v, index) \
+ do { \
+ assert((index) < (v)->len); \
+ assert((v)->len > 0); \
+ if ((index) < (v)->len - 1) { \
+ (v)->d[index] = vec_last(v); \
+ } \
+ (v)->len--; \
+ } while (0)
+
+#define vec_len(v) \
+ (v)->len
+
+#define DEFINE_VEC_INSERT_SORTED_PROTO(type, name, element_type) \
+ element_type *name##_insert_sorted(type *v, element_type el)
+
+#define DEFINE_VEC_INSERT_SORTED_FUNC(type, _name, element_type, compare_func) \
+ element_type *_name##_insert_sorted(type *v, element_type el) { \
+ /* Verify if the element already exists */ \
+ if (v->len > 0) { \
+ element_type *found = bsearch(&el, v->d, v->len, sizeof(element_type), compare_func); \
+ if (found != NULL){ \
+ return (found); \
+ } \
+ } \
+ if (v->len >= v->cap) { \
+ v->cap = (v->cap == 0) ? 1 : v->cap * 2; \
+ v->d = realloc(v->d, v->cap * sizeof(element_type)); \
+ if (v->d == NULL) \
+ abort(); \
+ } \
+ /* Find where to insert */ \
+ size_t i; \
+ for (i = v->len; i > 0 && compare_func(&v->d[i - 1], &el) > 0; i--) { \
+ v->d[i] = v->d[i - 1]; \
+ } \
+ v->d[i] = el; \
+ v->len++; \
+ return (NULL); \
+ }
+
+typedef vec_t(char *) charv_t;
+typedef vec_t(const char *) c_charv_t;
+
+#endif
unsigned int not;
regex_t regexp;
char *hdr;
- size_t i = 0;
if (msg != NULL)
*msg = NULL;
if (qualifier != NULL)
if (rules == NULL)
return (ACT_ALLOW);
- tll_foreach(*rules, it) {
- rule_ptr = it->item;
+ vec_foreach(*rules, _i) {
+ rule_ptr = rules->d[_i];
if (strncmp(rule_ptr, "allow", 5) == 0) {
rule_ptr += 5;
act = ACT_ALLOW;
} else {
errno = 0;
if (msg != NULL)
- xasprintf(msg, "Unable to parse rule #%d \"%s\":"
+ xasprintf(msg, "Unable to parse rule #%zu \"%s\":"
" Missing action keyword. Denying post from \"%s\"",
- i, it->item, from);
+ _i, rules->d[_i], from);
return ACT_DENY;
}
/* the rule is a keyword and no regexp */
if (msg != NULL)
xasprintf(msg, "access -"
- " A mail from \"%s\" was %s by rule #%d \"%s\"",
- from, action_strs[act], i, it->item);
+ " A mail from \"%s\" was %s by rule #%zu \"%s\"",
+ from, action_strs[act], _i, rules->d[_i]);
return act;
} else {
/* we must have space or end of string */
errno = 0;
if (msg != NULL)
- xasprintf(msg, "Unable to parse rule #%d \"%s\":"
+ xasprintf(msg, "Unable to parse rule #%zu \"%s\":"
" Invalid character after action keyword."
- " Denying post from \"%s\"", i, it->item, from);
+ " Denying post from \"%s\"", _i, rules->d[_i], from);
return ACT_DENY;
}
regfree(®exp);
errno = 0;
if (msg != NULL)
- xasprintf(msg, "regcomp() failed for rule #%d \"%s\""
+ xasprintf(msg, "regcomp() failed for rule #%zu \"%s\""
" (message: '%s') (expression: '%s')"
" Denying post from \"%s\"",
- i, it->item, errbuf, rule_ptr, from);
+ _i, rules->d[_i], errbuf, rule_ptr, from);
return ACT_DENY;
}
match = 0;
- tll_foreach(*headers, header) {
- if (regexec(®exp, header->item, 0, NULL, 0)
+ vec_foreach(*headers, _j) {
+ if (regexec(®exp, headers->d[_j], 0, NULL, 0)
== 0) {
match = 1;
- hdr = header->item;
+ hdr = headers->d[_j];
break;
}
}
if (msg != NULL)
xasprintf(msg, "access -"
" A mail from \"%s\" with header \"%s\" was %s by"
- " rule #%d \"%s\"", from, hdr, action_strs[act],
- i, it->item);
+ " rule #%zu \"%s\"", from, hdr, action_strs[act],
+ _i, rules->d[_i]);
} else {
if (msg != NULL)
xasprintf(msg, "access -"
- " A mail from \"%s\" was %s by rule #%d \"%s\""
+ " A mail from \"%s\" was %s by rule #%zu \"%s\""
" because no header matched.", from,
- action_strs[act], i, it->item);
+ action_strs[act], _i, rules->d[_i]);
}
return act;
}
- i++;
}
xasprintf(msg, "access -"
/* Ignore empty lines */
if (*line == '\0')
continue;
- tll_push_back(*ret, xstrdup(line));
+ vec_push(ret, xstrdup(line));
}
free(line);
fclose(f);
if (allhdrs != NULL) {
/* Snatch a copy of the header */
- tll_push_back(*allhdrs, xstrdup(hdrline));
+ vec_push(allhdrs, xstrdup(hdrline));
}
-
+
if (allunfoldeds != NULL) {
/* Snatch a copy of unfolded */
- tll_push_back(*allunfoldeds, xstrdup(unfolded));
+ vec_push(allunfoldeds, xstrdup(unfolded));
}
free(hdrline);
strlist *allhdrs, const char *prefix, int replyto)
{
char *hdrline, *unfolded, *unqp;
- strlist allunfoldeds = tll_init();
+ strlist allunfoldeds = vec_init();
char *posteraddr = NULL;
bool hdrsadded = false;
bool subject_present = false;
/* if we have custom headers , extract posteraddr from current header */
if(hdrfd >= 0) {
- strlist fromemails = tll_init();
+ strlist fromemails = vec_init();
if ( readhdrs[0].valuecount == 1 ) {
find_email_adr(readhdrs[0].values[0], &fromemails);
- if (tll_length(fromemails) > 0)
- posteraddr = xstrdup(tll_front(fromemails));
+ if (fromemails.len > 0)
+ posteraddr = xstrdup(vec_first(&fromemails));
}
- tll_free_and_free(fromemails, free);
+ vec_free_and_free(&fromemails, free);
}
/* scan all headers from allhdrs , and do the real things */
- tll_foreach(*allhdrs, a_header ) {
+ vec_foreach(*allhdrs, _i) {
/* hdrline contains the unfolded value of the header and unfolded contains the original data */
- hdrline=a_header->item ;
- unfolded=tll_pop_front(allunfoldeds) ;
+ hdrline=allhdrs->d[_i] ;
+ unfolded=xstrdup(allunfoldeds.d[_i]) ;
/* add extra headers before MIME* headers,
or after all headers */
log_error(LOG_ARGS, "Could not "
"add extra headers");
free(unfolded);
- tll_free_and_free(allunfoldeds, free);
+ vec_free_and_free(&allunfoldeds, free);
free(posteraddr);
fclose(outf);
fclose(f);
if(process_headers(hdrfd,outf,posteraddr ? posteraddr : "") < 0) {
log_error(LOG_ARGS, "Could not "
"add extra headers");
- tll_free_and_free(allunfoldeds, free);
+ vec_free_and_free(&allunfoldeds, free);
free(posteraddr);
fclose(outf);
fclose(f);
}
/* write LF */
if(fprintf(outf, "\n") < 0) {
- tll_free_and_free(allunfoldeds, free);
+ vec_free_and_free(&allunfoldeds, free);
log_error(LOG_ARGS, "Error writing hdrs.");
free(posteraddr);
fclose(outf);
fflush(outf);
fclose(outf);
- tll_free_and_free(allunfoldeds, free);
+ vec_free_and_free(&allunfoldeds, free);
lseek(infd, ftello(f), SEEK_SET);
/* Just print the rest of the mail */
adr = skin(cur);
if (adr)
- tll_push_back(*retstruct, adr);
+ vec_push(retstruct, adr);
}
free(s);
#include <string.h>
-#include "tllist.h"
#include "xmalloc.h"
#include "mlmmj.h"
#include "getaddrsfromfile.h"
chomp(line);
if (*line == '\0')
continue;
- tll_push_back(*slist, xstrdup(line));
- if (tll_length(*slist) >= max)
+ vec_push(slist, xstrdup(line));
+ if (slist->len >= max)
break;
}
if (feof(f))
#if 0
log_error(LOG_ARGS, "controlstr = [%s]\n", controlstr);
- log_error(LOG_ARGS, "tll_front(*fromemails) = [%s]\n",
- tll_front(*fromemails));
+ log_error(LOG_ARGS, "fromemails[0] = [%s]\n",
+ fromemails->d[0]);
#endif
cc = get_ctrl_command(controlstr, ¶m);
if (cc == NULL)
return (-1);
- if (tll_length(*fromemails) != 1 && cc->type != CTRL_BOUNCES) {
+ if (fromemails->len != 1 && cc->type != CTRL_BOUNCES) {
errno = 0;
log_error(LOG_ARGS, "Ignoring mail with invalid From: "
- "which was not a bounce: %d", tll_length(*fromemails));
+ "which was not a bounce: %d", fromemails->len);
return -1;
}
- if (tll_length(*fromemails) >= 1)
- lc.fromemail = tll_front(*fromemails);
+ if (fromemails->len >= 1)
+ lc.fromemail = fromemails->d[0];
lc.mlmmjsend = mlmmjsend;
/* We only need the control mail when bouncing, to save bounced msg */
return -1;
}
log_oper(ml->fd, OPLOGFNAME, "%s obstructed %s",
- tll_front(*fromemails), param);
+ fromemails->d[0], param);
free(param);
free(gatekeepfilename);
break;
/* listname+help@domain.tld */
case CTRL_HELP:
- if (!is_valid_email(tll_front(*fromemails), "A help"))
+ if (!is_valid_email(fromemails->d[0], "A help"))
return -1;
log_oper(ml->fd, OPLOGFNAME, "%s requested help",
- tll_front(*fromemails));
+ fromemails->d[0]);
txt = open_text(ml->fd, "help", NULL, NULL, NULL, "listhelp");
MY_ASSERT(txt);
register_default_unformatted(txt, ml);
queuefilename = prepstdreply(txt, ml,
- "$listowner$", tll_front(*fromemails), NULL);
+ "$listowner$", fromemails->d[0], NULL);
MY_ASSERT(queuefilename);
close_text(txt);
- send_help(ml, queuefilename, tll_front(*fromemails));
+ send_help(ml, queuefilename, fromemails->d[0]);
break;
/* listname+faq@domain.tld */
case CTRL_FAQ:
- if (!is_valid_email(tll_front(*fromemails), "A faq"))
+ if (!is_valid_email(fromemails->d[0], "A faq"))
return -1;
log_oper(ml->fd, OPLOGFNAME, "%s requested faq",
- tll_front(*fromemails));
+ fromemails->d[0]);
txt = open_text(ml->fd, "faq", NULL, NULL, NULL, "listfaq");
MY_ASSERT(txt);
register_default_unformatted(txt, ml);
queuefilename = prepstdreply(txt, ml,
- "$listowner$", tll_front(*fromemails), NULL);
+ "$listowner$", fromemails->d[0], NULL);
MY_ASSERT(queuefilename);
close_text(txt);
- send_help(ml, queuefilename, tll_front(*fromemails));
+ send_help(ml, queuefilename, fromemails->d[0]);
break;
/* listname+get-INDEX@domain.tld */
return -1;
}
if (statctrl(ml->ctrlfd, "subonlyget")) {
- if (is_subbed(ml->fd, tll_front(*fromemails), 0) ==
+ if (is_subbed(ml->fd, fromemails->d[0], 0) ==
SUB_NONE) {
errno = 0;
log_error(LOG_ARGS, "A get request was sent"
}
struct mail mail = { 0 };
char *bounceaddr;
- mail.to = tll_front(*fromemails);
+ mail.to = fromemails->d[0];
bounceaddr = get_bounce_from_adr(mail.to, ml, index);
mail.from = bounceaddr;
mail.fp = fdopen(fd, "r");
return -1;
}
log_oper(ml->fd, OPLOGFNAME, "%s got archive/%s",
- tll_front(*fromemails), param);
+ fromemails->d[0], param);
if (!send_single_mail(&mail, ml, true)) {
/* TODO: save to queue */
fclose(mail.fp);
case CTRL_LIST:
if (statctrl(ml->ctrlfd, "nolistsubsemail"))
return -1;
- const char *owner = tll_front(*fromemails);
+ const char *owner = fromemails->d[0];
if (!ctrlvalues_contains(ml->ctrlfd, "owner", owner, false)) {
errno = 0;
log_error(LOG_ARGS, "A list request was sent to the"
};
static void
-free_parsed_hdrs(struct mailhdr *readhdrs, strlist fromemails,
- strlist originalfromemails, strlist toemails, strlist ccemails,
- strlist rpemails, strlist dtemails, strlist allheaders)
+free_parsed_hdrs(struct mailhdr *readhdrs, strlist *fromemails,
+ strlist *originalfromemails, strlist *toemails, strlist *ccemails,
+ strlist *rpemails, strlist *dtemails, strlist *allheaders)
{
free_mailhdrs(readhdrs);
- tll_free_and_free(fromemails, free);
- tll_free_and_free(originalfromemails, free);
- tll_free_and_free(toemails, free);
- tll_free_and_free(ccemails, free);
- tll_free_and_free(rpemails, free);
- tll_free_and_free(dtemails, free);
- tll_free_and_free(allheaders, free);
+ vec_free_and_free(fromemails, free);
+ vec_free_and_free(originalfromemails, free);
+ vec_free_and_free(toemails, free);
+ vec_free_and_free(ccemails, free);
+ vec_free_and_free(rpemails, free);
+ vec_free_and_free(dtemails, free);
+ vec_free_and_free(allheaders, free);
}
static bool is_moderator(int listfd, const char *address,
char *envstr;
const char *efrom = "";
struct stat st;
- strlist fromemails = tll_init();
- strlist originalfromemails = tll_init();
- strlist toemails = tll_init();
- strlist ccemails = tll_init();
- strlist rpemails = tll_init();
- strlist dtemails = tll_init();
+ strlist fromemails = vec_init();
+ strlist originalfromemails = vec_init();
+ strlist toemails = vec_init();
+ strlist ccemails = vec_init();
+ strlist rpemails = vec_init();
+ strlist dtemails = vec_init();
strlist *testfrom = NULL;
strlist *access_rules = NULL;
strlist *list_rules = NULL;
strlist *delheaders = NULL;
- strlist allheaders = tll_init();
+ strlist allheaders = vec_init();
strlist *listaddrs = NULL;
struct mailhdr readhdrs[] = {
{ "From:", 0, NULL },
if (delheaders == NULL)
delheaders = xcalloc(1, sizeof(*delheaders));
- tll_push_back(*delheaders, xstrdup("From "));
- tll_push_back(*delheaders, xstrdup("Return-Path:"));
+ vec_push(delheaders, xstrdup("From "));
+ vec_push(delheaders, xstrdup("Return-Path:"));
subjectprefix = ctrlvalue(ml.ctrlfd, "prefix");
close(donemailfd);
unlink(donemailname);
free(donemailname);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_FAILURE);
}
- tll_free_and_free(*delheaders, free);
+ vec_free_and_free(delheaders, free);
close(rawmailfd);
close(donemailfd);
recipextra != NULL ? NULL : &recipextra);
}
if (listaddrs)
- tll_free_and_free(*listaddrs, free);
+ vec_free_and_free(listaddrs, free);
free(listaddrs);
if (recipextra && *recipextra == '\0') {
}
/* discard malformed mail with invalid From: unless it's a bounce */
- if (tll_length(fromemails) != 1 &&
+ if (fromemails.len != 1 &&
(recipextra == NULL ||
strncmp(recipextra, "bounces", 7) != 0)) {
- tll_foreach(fromemails, it)
+ vec_foreach(fromemails, _i)
printf("fromemails.emaillist[] = %s\n",
- it->item);
+ fromemails.d[_i]);
xasprintf(&discardname, "%s/queue/discarded/%s", ml.dir, randomstr);
log_error(LOG_ARGS, "Discarding %s due to invalid From:",
mailfile);
- tll_foreach(fromemails, it)
+ vec_foreach(fromemails, _i)
log_error(LOG_ARGS, "fromemails.emaillist[] = %s\n",
- it->item);
+ fromemails.d[_i]);
rename(mailfile, discardname);
unlink(donemailname);
free(donemailname);
free(discardname);
free(randomstr);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_SUCCESS);
}
/* The only time posteraddr will remain unset is when the mail is a
* bounce, so the mail will be processed by listcontrol() and the
* program will terminate before posteraddr is used. */
- if (tll_length(fromemails) > 0)
- posteraddr = tll_front(fromemails);
+ if (fromemails.len > 0)
+ posteraddr = fromemails.d[0];
/* Return-Path: addresses */
for(i = 0; i < readhdrs[3].valuecount; i++) {
if ((envstr = getenv("SENDER")) != NULL) {
/* qmail, postfix, exim */
efrom = envstr;
- } else if (tll_length(rpemails) >= 1) {
+ } else if (rpemails.len >= 1) {
/* the (first) Return-Path: header */
- efrom = tll_front(rpemails);
+ efrom = rpemails.d[0];
}
/* Subject: */
/* strip envelope from before resending */
int ownfd = openat(ml.ctrlfd, "owner", O_RDONLY);
xasprintf(&owner, "%d", ownfd);
- tll_push_back(*delheaders, xstrdup("From "));
- tll_push_back(*delheaders, xstrdup("Return-Path:"));
+ vec_push(delheaders, xstrdup("From "));
+ vec_push(delheaders, xstrdup("Return-Path:"));
if ((rawmailfd = open(mailfile, O_RDONLY)) < 0) {
log_error(LOG_ARGS, "could not open() "
"input mail file");
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_FAILURE);
}
if ((donemailfd = open(donemailname,
O_WRONLY|O_TRUNC)) < 0) {
log_error(LOG_ARGS, "could not open() "
"output mail file");
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_FAILURE);
}
{
- strlist ownerhdrs = tll_init();
+ strlist ownerhdrs = vec_init();
if (do_all_the_voodoo_here(rawmailfd, donemailfd, -1,
-1, delheaders,
NULL, &ownerhdrs, NULL, 0) < 0) {
log_error(LOG_ARGS, "do_all_the_voodoo_here");
- tll_free_and_free(ownerhdrs, free);
+ vec_free_and_free(&ownerhdrs, free);
close(ownfd);
close(rawmailfd);
close(donemailfd);
unlink(donemailname);
free(donemailname);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_FAILURE);
}
- tll_free_and_free(ownerhdrs, free);
+ vec_free_and_free(&ownerhdrs, free);
}
- tll_free_and_free(*delheaders, free);
+ vec_free_and_free(delheaders, free);
close(rawmailfd);
close(donemailfd);
unlink(mailfile);
efrom, "-s", owner, "-a", "-m", donemailname, NULL);
}
unlink(mailfile);
- if (tll_length(originalfromemails) > 0)
+ if (originalfromemails.len > 0)
testfrom = &originalfromemails;
else
testfrom = &fromemails;
listcontrol(testfrom, &ml, recipextra,
mlmmjsend, donemailname);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
return EXIT_SUCCESS;
}
if (errno != ENOENT) {
if (stat(donemailname, &st) < 0) {
log_error(LOG_ARGS, "stat(%s,..) failed", donemailname);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_FAILURE);
}
unlink(donemailname);
unlink(mailfile);
free(donemailname);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_SUCCESS);
}
free(donemailname);
free(discardname);
free(randomstr);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_FAILURE);
}
mailfile);
unlink(donemailname);
free(donemailname);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_SUCCESS);
}
txt = open_text(ml.fd, "deny", "post",
mailfile);
unlink(donemailname);
free(donemailname);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_SUCCESS);
}
txt = open_text(ml.fd, "deny", "post",
donemailname, discardname);
free(donemailname);
free(discardname);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_FAILURE);
}
free(donemailname);
free(discardname);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_SUCCESS);
} else if (accret == ACT_SEND) {
send = 1;
list_rules = ctrlvalues(ml.ctrlfd, "send");
if (list_rules != NULL) {
- tll_foreach(*list_rules, lr) {
- if (strcasecmp(posteraddr, lr->item) == 0) {
+ vec_foreach(*list_rules, _i) {
+ if (strcasecmp(posteraddr, list_rules->d[_i]) == 0) {
send = 1;
break;
}
/* Don't send a mail about denial to the list, but silently
* discard and exit. */
char *testaddr = posteraddr;
- if (tll_length(originalfromemails) > 0)
- testaddr = tll_front(originalfromemails);
+ if (originalfromemails.len > 0)
+ testaddr = originalfromemails.d[0];
if (strcasecmp(ml.addr, testaddr) == 0) {
log_error(LOG_ARGS, "Discarding %s because"
" there are sender restrictions but"
mailfile);
unlink(donemailname);
free(donemailname);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_SUCCESS);
}
if (subonlypost) {
mailfile);
unlink(donemailname);
free(donemailname);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_SUCCESS);
}
if (subonlypost) {
donemailname, modname);
free(modname);
close_text(txt);
- free_parsed_hdrs(readhdrs, fromemails,
- originalfromemails, toemails,
- ccemails, rpemails, dtemails,
- allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails,
+ &originalfromemails, &toemails,
+ &ccemails, &rpemails, &dtemails,
+ &allheaders);
exit(EXIT_FAILURE);
}
free(modname);
donemailname, mqueuename);
free(donemailname);
free(mqueuename);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_FAILURE);
}
free(donemailname);
omitfilename);
free(mqueuename);
free(omitfilename);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_FAILURE);
}
free(omitfilename);
log_error(LOG_ARGS,
"could not write omit file");
free(mqueuename);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_FAILURE);
}
fsync(omitfd);
}
newmoderated(&ml, mqueuename, mlmmjsend, efrom, subject,
posteraddr, modreason);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
return EXIT_SUCCESS;
}
if (noprocess) {
free(donemailname);
- free_parsed_hdrs(readhdrs, fromemails, originalfromemails,
- toemails, ccemails, rpemails, dtemails, allheaders);
+ free_parsed_hdrs(readhdrs, &fromemails, &originalfromemails,
+ &toemails, &ccemails, &rpemails, &dtemails, &allheaders);
exit(EXIT_SUCCESS);
}
if (reply2 != NULL) free(reply2);
return MLMMJ_FROM;
}
- tll_foreach(*addrs, it) {
+ vec_foreach(*addrs, _i) {
if(gotsigterm) {
log_error(LOG_ARGS, "TERM signal received, "
"shutting down.");
return -1;
}
- if(strchr(it->item, '@') == NULL) {
+ if(strchr(addrs->d[_i], '@') == NULL) {
errno = 0;
log_error(LOG_ARGS, "No @ in address, ignoring %s",
- it->item);
+ addrs->d[_i]);
continue;
}
- retval = write_rcpt_to(sockfd, it->item);
+ retval = write_rcpt_to(sockfd, addrs->d[_i]);
if(retval) {
log_error(LOG_ARGS, "Could not write RCPT TO:\n");
return retval;
const char *archivefilename)
{
int res, ret;
- strlist stl = tll_init();
+ strlist stl = vec_init();
FILE *f = fdopen(subfd, "r");
if (f == NULL) {
do {
res = getaddrsfromfile(&stl, f, maxverprecips);
- if(tll_length(stl) == maxverprecips) {
+ if(stl.len == maxverprecips) {
ret = send_mail_many_list(sockfd, mail, ml, &stl,
archivefilename);
- tll_free_and_free(stl, free);
+ vec_free_and_free(&stl, free);
if(ret < 0)
return ret;
}
} while(res > 0);
fclose(f);
- if(tll_length(stl)) {
+ if(stl.len) {
ret = send_mail_many_list(sockfd, mail, ml, &stl,
archivefilename);
- tll_free_and_free(stl, free);
+ vec_free_and_free(&stl, free);
return ret;
}
int index = archivefilename ? get_index_from_filename(archivefilename) : -1;
char *bounceaddr, *addr;
- while (tll_length(*addrs) > 0) {
- addr = tll_pop_front(*addrs);
+ while (addrs->len > 0) {
+ addr = vec_pop_front(addrs);
bounceaddr = NULL;
if(strchr(addr, '@') == NULL) {
errno = 0;
DIR *subddir;
struct dirent *dp;
struct stat st;
- strlist stl = tll_init();
+ strlist stl = vec_init();
struct sigaction sigact;
struct mail mail = { 0 };
struct ml ml;
do {
res = getaddrsfromfile(&stl, f, maxverprecips);
if(omit != NULL) {
- tll_foreach(stl, it)
- if (strcmp(it->item, omit) == 0)
- tll_remove_and_free(stl, it, free);
+ vec_foreach(stl, _j)
+ if (strcmp(stl.d[_j], omit) == 0) {
+ vec_remove_and_free(&stl, _j, free);
+ _j--;
+ }
}
- if(tll_length(stl) == maxverprecips) {
+ if(stl.len == maxverprecips) {
sockfd = newsmtp(&ml, relayhost);
if(verp) {
mail.from = verpfrom;
} else {
endsmtp(&sockfd);
}
- tll_free_and_free(stl, free);
+ vec_free_and_free(&stl, free);
}
} while(res > 0);
fclose(f);
}
- if(tll_length(stl)) {
+ if(stl.len) {
sockfd = newsmtp(&ml, relayhost);
if(verp) {
mail.from = verpfrom;
} else {
endsmtp(&sockfd);
}
- tll_free_and_free(stl, free);
+ vec_free_and_free(&stl, free);
}
free(verpfrom);
closedir(subddir);
return (NULL);
len = strlen(pattern);
- tll_foreach(*l, el) {
- char *str = el->item;
+ vec_foreach(*l, _i) {
+ char *str = l->d[_i];
if (str == NULL)
continue;
if (strncasecmp(str, pattern, len) == 0)
char *line, *hdr, *walk, *addr = NULL, *boundary = NULL;
bool quoted = false;
bool indsn = false;
- strlist emails = tll_init();
+ strlist emails = vec_init();
f = fopen(mailname, "r");
if(f == NULL) {
break;
}
find_email_adr(walk+1, &emails);
- if(tll_length(emails) > 0) {
- addr = xstrdup(tll_front(emails));
- tll_free_and_free(emails, free);
+ if(emails.len > 0) {
+ addr = xstrdup(vec_first(&emails));
+ vec_free_and_free(&emails, free);
}
break;
}
free(buf);
free(boundary);
fclose(f);
- tll_free_and_free(emails, free);
+ vec_free_and_free(&emails, free);
return addr;
}
char *reason;
char *type;
source *src;
- tll(struct substitution *) substs;
+ vec_t(struct substitution *) substs;
char *mailname;
- tll(struct formatted *) fmts;
+ vec_t(struct formatted *) fmts;
int wrapindent;
int wrapwidth;
enum wrap_mode wrapmode;
value = textcontent(listfd, token);
} else {
found = false;
- tll_foreach(txt->substs, it) {
- subst = it->item;
+ vec_foreach(txt->substs, _i) {
+ subst = txt->substs.d[_i];
if (strlen (subst->token) == len &&
strncmp(key, subst->token, len) == 0) {
fputs(subst->subst, str->fp);
token = filename_token(token + 5);
if (token != NULL) value = textcontent(listfd, token);
} else {
- tll_foreach(txt->substs, it) {
- subst = it->item;
+ vec_foreach(txt->substs, _i) {
+ subst = txt->substs.d[_i];
if(strcmp(token, subst->token) == 0) {
value = xstrdup(subst->subst);
break;
struct substitution * subst = xmalloc(sizeof(struct substitution));
subst->token = xstrdup(token);
subst->subst = xstrdup(replacement);
- tll_push_back(txt->substs, subst);
+ vec_push(&txt->substs, subst);
}
void
fmt->rew = rew;
fmt->get = get;
fmt->state = state;
- tll_push_back(txt->fmts, fmt);
+ vec_push(&txt->fmts, fmt);
}
return 0;
}
- tll_foreach(txt->fmts, it) {
- fmt = it->item;
+ vec_foreach(txt->fmts, _i) {
+ fmt = txt->fmts.d[_i];
if (strcmp(token, fmt->token) == 0) {
begin_new_formatted_source(txt, line_p, pos_p, width_p,
endpos + 1, fmt, 0);
while (txt->src != NULL) {
close_source(txt);
}
- tll_free_and_free(txt->substs, substitution_free);
+ vec_free_and_free(&txt->substs, substitution_free);
if (txt->mailname != NULL) free(txt->mailname);
- tll_free_and_free(txt->fmts, formatted_free);
+ vec_free_and_free(&txt->fmts, formatted_free);
while (txt->cond != NULL) {
cond = txt->cond;
txt->cond = txt->cond->outer;
#include "init_sockfd.h"
#include "mlmmj.h"
#include "strgen.h"
-#include "tllist.h"
#include "xmalloc.h"
#include "ctrlvalue.h"
#include "utils.h"
int addrfd, dfd;
char *dirname;
- if ((addrs == NULL || tll_length(*addrs) == 0) && addr == NULL)
+ if ((addrs == NULL || addrs->len == 0) && addr == NULL)
return (false);
xasprintf(&dirname, "requeue/%d", index);
if(mkdirat(listfd, dirname, 0750) < 0 && errno != EEXIST) {
return (false);
}
if (addrs != NULL) {
- tll_foreach(*addrs, it) {
- fprintf(addrf, "%s\n", it->item);
+ vec_foreach(*addrs, _i) {
+ fprintf(addrf, "%s\n", addrs->d[_i]);
}
}
if (addr != NULL)
if (submods == NULL)
return;
/* check to see if there's adresses in the submod control file */
- tll_foreach(*submods, it)
- a = strchr(it->item, '@');
+ vec_foreach(*submods, _i)
+ a = strchr(submods->d[_i], '@');
/* no addresses in submod control file, use owner */
if(a == NULL) {
/* free the submods struct from above */
- tll_free_and_free(*submods, free);
+ vec_free_and_free(submods, free);
free(submods);
submods = ctrlvalues(ml->ctrlfd, "owner");
modfd = openat(ml->ctrlfd, "owner", O_RDONLY);
gen_addr_cookie(replyto, ml, "permit-", cookie);
gen_addr_cookie(obstruct, ml, "obstruct-", cookie);
free(cookie);
- tll_foreach(*submods, sm) {
+ vec_foreach(*submods, _i) {
if (str == NULL)
str = xstring_new();
- fprintf(str->fp, "%s\n", sm->item);
+ fprintf(str->fp, "%s\n", submods->d[_i]);
}
moderators = xstring_get(str);
mls = init_memory_lines(moderators);
{ "From:", 0, NULL },
{ NULL, 0, NULL }
};
- strlist from = tll_init();
+ strlist from = vec_init();
FILE *f = fdopen(mailfd, "r");
if (f == NULL) {
return;
}
find_email_adr(readhdrs[0].values[0], &from);
- if (tll_length(from) == 0) {
- tll_free(from);
+ if (from.len == 0) {
+ vec_free(&from);
free_mailhdrs(readhdrs);
return;
}
- if (strchr(tll_front(from), '@') == NULL) {
- tll_free_and_free(from, free);
+ if (strchr(vec_first(&from), '@') == NULL) {
+ vec_free_and_free(&from, free);
free_mailhdrs(readhdrs);
return;
}
- subscribe_type(ml->fd, tll_front(from), typesub);
- tll_free_and_free(from, free);
+ subscribe_type(ml->fd, vec_first(&from), typesub);
+ vec_free_and_free(&from, free);
free_mailhdrs(readhdrs);
}
bool
find_email(strlist *list, strlist *matches, const char *delim, char **recipextra)
{
- tll_foreach(*list, lit) {
- tll_foreach(*matches, mit) {
- if (addrmatch(mit->item, lit->item, delim, recipextra))
+ vec_foreach(*list, _li) {
+ vec_foreach(*matches, _mi) {
+ if (addrmatch(matches->d[_mi], list->d[_li], delim, recipextra))
return true;
}
}
size_t len;
cmp_fn_t cmp = ignore_case ? strncasecmp : strncmp;
- tll_foreach(*list, it) {
- len = strlen(it->item);
- if (cmp(el, it->item, len) == 0)
+ vec_foreach(*list, _i) {
+ len = strlen(list->d[_i]);
+ if (cmp(el, list->d[_i], len) == 0)
return (true);
}
* IN THE SOFTWARE.
*/
-#include "tllist.h"
+#include "vec.h"
#if defined(__clang__)
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
ATF_TC_BODY(find_email_adr, tc)
{
- strlist c = tll_init();
- strlist c1 = tll_init();
- strlist c2 = tll_init();
- strlist c3 = tll_init();
- strlist c4 = tll_init();
- strlist c5 = tll_init();
- strlist c6 = tll_init();
- strlist c7 = tll_init();
+ strlist c = vec_init();
+ strlist c1 = vec_init();
+ strlist c2 = vec_init();
+ strlist c3 = vec_init();
+ strlist c4 = vec_init();
+ strlist c5 = vec_init();
+ strlist c6 = vec_init();
+ strlist c7 = vec_init();
find_email_adr("test@foo.bar", &c);
- ATF_REQUIRE_EQ(tll_length(c), 1);
+ ATF_REQUIRE_EQ(c.len, 1);
find_email_adr("test@foo.bar, meh@bar", &c1);
- ATF_REQUIRE_EQ(tll_length(c1), 2);
+ ATF_REQUIRE_EQ(c1.len, 2);
find_email_adr("test@foo.bar, meh@bar, nope", &c2);
- ATF_REQUIRE_EQ(tll_length(c2), 3);
+ ATF_REQUIRE_EQ(c2.len, 3);
find_email_adr("name <test@foo.com>", &c3);
- ATF_REQUIRE_EQ(tll_length(c3), 1);
- ATF_REQUIRE_STREQ(tll_front(c3), "test@foo.com");
+ ATF_REQUIRE_EQ(c3.len, 1);
+ ATF_REQUIRE_STREQ(c3.d[0], "test@foo.com");
find_email_adr("(name <test@foo.com>) test@foo.com", &c4);
- ATF_REQUIRE_EQ(tll_length(c4), 1);
- ATF_REQUIRE_STREQ(tll_front(c4), " test@foo.com");
+ ATF_REQUIRE_EQ(c4.len, 1);
+ ATF_REQUIRE_STREQ(c4.d[0], " test@foo.com");
find_email_adr("\"name <test@foo.com>\" test@foo.com", &c5);
- ATF_REQUIRE_EQ(tll_length(c5), 1);
- ATF_REQUIRE_STREQ(tll_front(c5), "name <test@foo.com> test@foo.com");
+ ATF_REQUIRE_EQ(c5.len, 1);
+ ATF_REQUIRE_STREQ(c5.d[0], "name <test@foo.com> test@foo.com");
find_email_adr("\"name <test@foo.com> test@foo.com", &c6);
- ATF_REQUIRE_EQ(tll_length(c6), 1);
- ATF_REQUIRE_STREQ(tll_front(c6), "name <test@foo.com> test@foo.com");
+ ATF_REQUIRE_EQ(c6.len, 1);
+ ATF_REQUIRE_STREQ(c6.d[0], "name <test@foo.com> test@foo.com");
find_email_adr("\"name <test@foo.com>\\ test@foo.com", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 1);
- ATF_REQUIRE_STREQ(tll_front(c7), "name <test@foo.com> test@foo.com");
+ ATF_REQUIRE_EQ(c7.len, 1);
+ ATF_REQUIRE_STREQ(c7.d[0], "name <test@foo.com> test@foo.com");
find_email_adr("\"name <test@foo.com> test@foo.com\\", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 2);
- ATF_REQUIRE_STREQ(tll_back(c7), "name <test@foo.com> test@foo.com");
+ ATF_REQUIRE_EQ(c7.len, 2);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "name <test@foo.com> test@foo.com");
find_email_adr("test at foo.com", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 3);
- ATF_REQUIRE_STREQ(tll_back(c7), "test@foo.com");
+ ATF_REQUIRE_EQ(c7.len, 3);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "test@foo.com");
find_email_adr("test atfoo.com", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 4);
- ATF_REQUIRE_STREQ(tll_back(c7), "test atfoo.com");
+ ATF_REQUIRE_EQ(c7.len, 4);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "test atfoo.com");
find_email_adr("test a t foo.com", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 5);
- ATF_REQUIRE_STREQ(tll_back(c7), "test a t foo.com");
+ ATF_REQUIRE_EQ(c7.len, 5);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "test a t foo.com");
find_email_adr("test@foo.com, \"meh\"", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 7);
- ATF_REQUIRE_STREQ(tll_back(c7), "\"meh\"");
+ ATF_REQUIRE_EQ(c7.len, 7);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "\"meh\"");
find_email_adr("test@foo.com, \"meh\\\"", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 9);
- ATF_REQUIRE_STREQ(tll_back(c7), "meh ");
+ ATF_REQUIRE_EQ(c7.len, 9);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "meh ");
find_email_adr("", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 9);
+ ATF_REQUIRE_EQ(c7.len, 9);
find_email_adr("\"meh\" , ", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 10);
- ATF_REQUIRE_STREQ(tll_back(c7), "meh");
+ ATF_REQUIRE_EQ(c7.len, 10);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "meh");
find_email_adr("\"meh , ", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 11);
- ATF_REQUIRE_STREQ(tll_back(c7), "meh ");
+ ATF_REQUIRE_EQ(c7.len, 11);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "meh ");
find_email_adr("\t,", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 11);
+ ATF_REQUIRE_EQ(c7.len, 11);
find_email_adr("\r,", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 11);
+ ATF_REQUIRE_EQ(c7.len, 11);
find_email_adr("\n,", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 11);
+ ATF_REQUIRE_EQ(c7.len, 11);
find_email_adr(", m", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 12);
+ ATF_REQUIRE_EQ(c7.len, 12);
find_email_adr(", \"m", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 13);
+ ATF_REQUIRE_EQ(c7.len, 13);
find_email_adr("bob @ foo.net", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 14);
- ATF_REQUIRE_STREQ(tll_back(c7), "bob@foo.net");
+ ATF_REQUIRE_EQ(c7.len, 14);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "bob@foo.net");
find_email_adr("bob @foo.net", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 15);
- ATF_REQUIRE_STREQ(tll_back(c7), "bob @foo.net");
+ ATF_REQUIRE_EQ(c7.len, 15);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "bob @foo.net");
find_email_adr("bob @foo.net>", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 16);
- ATF_REQUIRE_STREQ(tll_back(c7), "bob @foo.net>");
+ ATF_REQUIRE_EQ(c7.len, 16);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "bob @foo.net>");
find_email_adr("<bob @foo.net> garbage,", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 17);
- ATF_REQUIRE_STREQ(tll_back(c7), "bob @foo.net");
+ ATF_REQUIRE_EQ(c7.len, 17);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "bob @foo.net");
find_email_adr("<bob @foo.net> garbage (more garbage) ,", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 18);
- ATF_REQUIRE_STREQ(tll_back(c7), "bob @foo.net");
+ ATF_REQUIRE_EQ(c7.len, 18);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "bob @foo.net");
find_email_adr("<bob @foo.net> garbage \"more garbage\" ,", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 19);
- ATF_REQUIRE_STREQ(tll_back(c7), "bob @foo.net");
+ ATF_REQUIRE_EQ(c7.len, 19);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "bob @foo.net");
find_email_adr("<bob @foo.net> garbage \"more garbage \\ ,", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 20);
- ATF_REQUIRE_STREQ(tll_back(c7), "bob @foo.net");
+ ATF_REQUIRE_EQ(c7.len, 20);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "bob @foo.net");
/* CRLF stripping in skin() */
find_email_adr("<evil@bad\r\nBcc: victim@target>", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 21);
- ATF_REQUIRE_STREQ(tll_back(c7), "evil@badBcc: victim@target");
+ ATF_REQUIRE_EQ(c7.len, 21);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "evil@badBcc: victim@target");
find_email_adr("evil@bad\r\n", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 22);
- ATF_REQUIRE_STREQ(tll_back(c7), "evil@bad");
+ ATF_REQUIRE_EQ(c7.len, 22);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "evil@bad");
find_email_adr("test\n@foo.com", &c7);
- ATF_REQUIRE_EQ(tll_length(c7), 23);
- ATF_REQUIRE_STREQ(tll_back(c7), "test@foo.com");
+ ATF_REQUIRE_EQ(c7.len, 23);
+ ATF_REQUIRE_STREQ(c7.d[c7.len - 1], "test@foo.com");
}
ATF_TC_BODY(strtoim, tc)
ATF_TC_BODY(getaddrsfromfile, tc)
{
- strlist stl = tll_init();
+ strlist stl = vec_init();
ATF_REQUIRE_EQ(getaddrsfromfile(&stl, NULL, 2), -1);
atf_utils_create_file("list", "");
FILE *fp;
fp = fopen("list", "r");
ATF_REQUIRE_EQ(getaddrsfromfile(&stl, fp, 2), 0);
fclose(fp);
- ATF_REQUIRE_EQ_MSG(tll_length(stl), 1, "%zu is not 1", tll_length(stl));
- ATF_REQUIRE_STREQ(tll_front(stl), "mail1@fqdn");
- tll_free_and_free(stl, free);
+ ATF_REQUIRE_EQ_MSG(stl.len, 1, "%zu is not 1", stl.len);
+ ATF_REQUIRE_STREQ(stl.d[0], "mail1@fqdn");
+ vec_free_and_free(&stl, free);
fp = fopen("list", "r");
ATF_REQUIRE_EQ(getaddrsfromfile(&stl, fp, 0), -1);
atf_utils_create_file("list", "mail1@fqdn\nmail2@fqdn\nmail3@fqdn");
fp = fopen("list", "r");
ATF_REQUIRE(getaddrsfromfile(&stl, fp, 2) > 0);
- ATF_REQUIRE_EQ(tll_length(stl), 2);
- ATF_REQUIRE_STREQ(tll_front(stl), "mail1@fqdn");
- ATF_REQUIRE_STREQ(tll_back(stl), "mail2@fqdn");
- tll_free_and_free(stl, free);
+ ATF_REQUIRE_EQ(stl.len, 2);
+ ATF_REQUIRE_STREQ(stl.d[0], "mail1@fqdn");
+ ATF_REQUIRE_STREQ(stl.d[stl.len - 1], "mail2@fqdn");
+ vec_free_and_free(&stl, free);
ATF_REQUIRE_EQ(getaddrsfromfile(&stl, fp, 2), 0);
- ATF_REQUIRE_EQ_MSG(tll_length(stl), 1, "%zu is not 1", tll_length(stl));
- ATF_REQUIRE_STREQ(tll_front(stl), "mail3@fqdn");
+ ATF_REQUIRE_EQ_MSG(stl.len, 1, "%zu is not 1", stl.len);
+ ATF_REQUIRE_STREQ(stl.d[0], "mail3@fqdn");
fclose(fp);
}
atf_utils_create_file("control/val", "line1\nline2\n\nline3\n");
strlist *l = ctrlvalues(ctrlfd, "val");
ATF_REQUIRE(l != NULL);
- ATF_REQUIRE_EQ(tll_length(*l), 3);
- ATF_REQUIRE_STREQ(tll_front(*l), "line1");
- ATF_REQUIRE_STREQ(tll_back(*l), "line3");
+ ATF_REQUIRE_EQ(l->len, 3);
+ ATF_REQUIRE_STREQ(l->d[0], "line1");
+ ATF_REQUIRE_STREQ(l->d[l->len - 1], "line3");
ATF_REQUIRE_EQ(textcontent(ctrlfd, "text"), NULL);
mkdir("control/text",0755);
ATF_REQUIRE_EQ(textcontent(ctrlfd, "text"), NULL);
init_ml(true);
ml_init(&ml);
ml.dir = "list";
- strlist fromemails = tll_init();
+ strlist fromemails = vec_init();
ATF_REQUIRE(ml_open(&ml, false));
ATF_REQUIRE_EQ(listcontrol(NULL, &ml, "plop", NULL, "meh"), -1);
atf_utils_create_file("list/control/closedlist", "");
atf_utils_create_file("meh", "mail");
- tll_push_back(fromemails, "plop@test");
+ vec_push(&fromemails, "plop@test");
ATF_REQUIRE_EQ(listcontrol(&fromemails, &ml, "unsubscribe", NULL, "meh"), -1);
if (atf_utils_file_exists("me"))
atf_tc_fail("mail should have been removed");
ATF_REQUIRE_EQ(listcontrol(&fromemails, &ml, "subscribe", NULL, "meh"), -1);
/* is_valid_email: reject addresses without @ */
- strlist no_at = tll_init();
- tll_push_back(no_at, "invalid-address");
+ strlist no_at = vec_init();
+ vec_push(&no_at, "invalid-address");
ATF_REQUIRE_EQ(listcontrol(&no_at, &ml, "help", NULL, "meh"), -1);
/* is_valid_email: reject addresses with control characters */
- strlist crlf = tll_init();
- tll_push_back(crlf, "evil@bad\r\nBcc: victim");
+ strlist crlf = vec_init();
+ vec_push(&crlf, "evil@bad\r\nBcc: victim");
ATF_REQUIRE_EQ(listcontrol(&crlf, &ml, "help", NULL, "meh"), -1);
- strlist lf = tll_init();
- tll_push_back(lf, "evil@bad\n");
+ strlist lf = vec_init();
+ vec_push(&lf, "evil@bad\n");
ATF_REQUIRE_EQ(listcontrol(&lf, &ml, "help", NULL, "meh"), -1);
- strlist nul = tll_init();
- tll_push_back(nul, "evil\x01@bad");
+ strlist nul = vec_init();
+ vec_push(&nul, "evil\x01@bad");
ATF_REQUIRE_EQ(listcontrol(&nul, &ml, "help", NULL, "meh"), -1);
}
ATF_TC_BODY(requeuemail, tc)
{
- strlist l = tll_init();
+ strlist l = vec_init();
init_ml(true);
int dfd = open("list", O_DIRECTORY);
ATF_REQUIRE(!requeuemail(dfd, 1, NULL, NULL));
ATF_REQUIRE(!requeuemail(dfd, 1, NULL, NULL));
ATF_REQUIRE(!requeuemail(dfd, 1, &l, NULL));
- tll_push_back(l, "test1");
+ vec_push(&l, "test1");
rmdir("list/requeue");
ATF_REQUIRE(!requeuemail(dfd, 1, &l, NULL));
mkdir("list/requeue", 0755);
atf_tc_fail("Invalid queue content");
}
unlink("list/requeue/1/subscribers");
- tll_push_back(l, "testhey");
- tll_push_back(l, "test2");
+ vec_push(&l, "testhey");
+ vec_push(&l, "test2");
ATF_REQUIRE(requeuemail(dfd, 1, &l, NULL));
if (!atf_utils_file_exists("list/requeue/1/subscribers"))
atf_tc_fail("queue file does not exists");
/* Same with an empty addrs list instead of NULL */
unlink("list/requeue/1/subscribers");
- strlist empty = tll_init();
+ strlist empty = vec_init();
ATF_REQUIRE(requeuemail(dfd, 1, &empty, "solo@lost"));
if (!atf_utils_compare_file("list/requeue/1/subscribers", "solo@lost\n")) {
atf_utils_cat_file("list/requeue/1/subscribers", ">");
ATF_TC_BODY(find_in_list, tc)
{
- strlist bla = tll_init();
+ strlist bla = vec_init();
ATF_REQUIRE(find_in_list(NULL, NULL) == NULL);
ATF_REQUIRE(find_in_list(&bla, NULL) == NULL);
ATF_REQUIRE(find_in_list(&bla, "test") == NULL);
- tll_push_back(bla, NULL);
+ vec_push(&bla, NULL);
ATF_REQUIRE(find_in_list(&bla, "test") == NULL);
- tll_push_back(bla, "plop");
+ vec_push(&bla, "plop");
ATF_REQUIRE(find_in_list(&bla, "test") == NULL);
- tll_push_back(bla, "test");
+ vec_push(&bla, "test");
ATF_REQUIRE_STREQ(find_in_list(&bla, "test"), "test");
- tll_pop_back(bla);
- tll_push_back(bla, "test longer");
+ vec_pop(&bla);
+ vec_push(&bla, "test longer");
ATF_REQUIRE_STREQ(find_in_list(&bla, "test"), "test longer");
}
ATF_TC_BODY(parse_content_type, tc)
{
char *m, *b;
- strlist hdrs = tll_init();
+ strlist hdrs = vec_init();
parse_content_type(NULL, &m, &b);
ATF_REQUIRE(m == NULL);
ATF_REQUIRE(b == NULL);
- tll_push_back(hdrs, "From: plop");
+ vec_push(&hdrs, "From: plop");
parse_content_type(&hdrs, &m, &b);
ATF_REQUIRE(m == NULL);
ATF_REQUIRE(b == NULL);
- tll_push_back(hdrs, "Content-Type:");
+ vec_push(&hdrs, "Content-Type:");
parse_content_type(&hdrs, &m, &b);
ATF_REQUIRE(m == NULL);
ATF_REQUIRE(b == NULL);
- tll_pop_back(hdrs);
- tll_push_back(hdrs, "Content-Type: multipart/mixed");
+ vec_pop(&hdrs);
+ vec_push(&hdrs, "Content-Type: multipart/mixed");
parse_content_type(&hdrs, &m, &b);
ATF_REQUIRE_STREQ(m, "multipart/mixed");
free(m);
ATF_REQUIRE(b == NULL);
- tll_pop_back(hdrs);
- tll_push_back(hdrs, "Content-Type: multipart/mixed;");
+ vec_pop(&hdrs);
+ vec_push(&hdrs, "Content-Type: multipart/mixed;");
parse_content_type(&hdrs, &m, &b);
ATF_REQUIRE_STREQ(m, "multipart/mixed");
free(m);
ATF_REQUIRE(b == NULL);
- tll_pop_back(hdrs);
- tll_push_back(hdrs, "Content-Type: multipart/mixed;\tboundary=bla");
+ vec_pop(&hdrs);
+ vec_push(&hdrs, "Content-Type: multipart/mixed;\tboundary=bla");
parse_content_type(&hdrs, &m, &b);
ATF_REQUIRE_STREQ(m, "multipart/mixed");
free(m);
ATF_REQUIRE_STREQ(b,"bla");
free(b);
- tll_pop_back(hdrs);
- tll_push_back(hdrs, "Content-Type: multipart/mixed;\tboundary=bla;");
+ vec_pop(&hdrs);
+ vec_push(&hdrs, "Content-Type: multipart/mixed;\tboundary=bla;");
parse_content_type(&hdrs, &m, &b);
ATF_REQUIRE_STREQ(m, "multipart/mixed");
free(m);
ATF_TC_BODY(do_access, tc)
{
- strlist rules = tll_init();
- strlist headers = tll_init();
- tll_push_back(rules, "allow");
+ strlist rules = vec_init();
+ strlist headers = vec_init();
+ vec_push(&rules, "allow");
char *msg = NULL;
char *qualifier = NULL;
ATF_REQUIRE_EQ(do_access(&rules, NULL, "test@plop", &msg, &qualifier), ACT_ALLOW);
ATF_REQUIRE_STREQ(msg, "access - A mail from \"test@plop\" was allowed by rule #0 \"allow\"");
ATF_REQUIRE(qualifier == NULL);
- tll_pop_back(rules);
- tll_push_back(rules, "deny");
+ vec_pop(&rules);
+ vec_push(&rules, "deny");
ATF_REQUIRE_EQ(do_access(&rules, NULL, "test@plop", &msg, &qualifier), ACT_DENY);
ATF_REQUIRE_STREQ(msg, "access - A mail from \"test@plop\" was denied by rule #0 \"deny\"");
ATF_REQUIRE(qualifier == NULL);
- tll_pop_back(rules);
- tll_push_back(rules, "crap");
+ vec_pop(&rules);
+ vec_push(&rules, "crap");
ATF_REQUIRE_EQ(do_access(&rules, NULL, "test@plop", &msg, &qualifier), ACT_DENY);
ATF_REQUIRE_STREQ(msg, "Unable to parse rule #0 \"crap\": Missing action keyword. Denying post from \"test@plop\"");
ATF_REQUIRE(qualifier == NULL);
- tll_pop_back(rules);
- tll_push_back(headers, "from: toto@bla");
- tll_push_back(rules, "moderate ^from: toto@");
+ vec_pop(&rules);
+ vec_push(&headers, "from: toto@bla");
+ vec_push(&rules, "moderate ^from: toto@");
ATF_REQUIRE_EQ(do_access(&rules, &headers, "test@plop", &msg, &qualifier), ACT_MODERATE);
ATF_REQUIRE_STREQ(msg, "access - A mail from \"test@plop\" with header \"from: toto@bla\" was moderated by rule #0 \"moderate ^from: toto@\"");
ATF_REQUIRE(qualifier == NULL);
- tll_push_front(rules, "moderatemeh ^from: toto@");
+ vec_push_front(&rules, "moderatemeh ^from: toto@");
ATF_REQUIRE_EQ(do_access(&rules, &headers, "test@plop", &msg, &qualifier), ACT_DENY);
ATF_REQUIRE_STREQ(msg, "Unable to parse rule #0 \"moderatemeh ^from: toto@\": Invalid character after action keyword. Denying post from \"test@plop\"");
ATF_REQUIRE(qualifier == NULL);
- tll_push_front(rules, "moderate- ^from: toto@");
+ vec_push_front(&rules, "moderate- ^from: toto@");
ATF_REQUIRE_EQ(do_access(&rules, &headers, "test@plop", &msg, &qualifier), ACT_MODERATE);
ATF_REQUIRE(qualifier == NULL);
ATF_REQUIRE_STREQ(msg, "access - A mail from \"test@plop\" with header \"from: toto@bla\" was moderated by rule #0 \"moderate- ^from: toto@\"");
- tll_push_front(rules, "moderate-meh ^from: toto@");
+ vec_push_front(&rules, "moderate-meh ^from: toto@");
ATF_REQUIRE_EQ(do_access(&rules, &headers, "test@plop", &msg, &qualifier), ACT_MODERATE);
ATF_REQUIRE_STREQ(qualifier, "meh");
ATF_REQUIRE_STREQ(msg, "access - A mail from \"test@plop\" with header \"from: toto@bla\" was moderated by rule #0 \"moderate-meh ^from: toto@\"");
ATF_TC_BODY(line_startwithany, tc)
{
- strlist l = tll_init();
- tll_push_back(l, "bla");
+ strlist l = vec_init();
+ vec_push(&l, "bla");
ATF_REQUIRE(!line_startwithany("BLA", &l, false));
ATF_REQUIRE(line_startwithany("BLA", &l, true));
ATF_REQUIRE(!line_startwithany("BLOP", &l, false));
ATF_REQUIRE(!line_startwithany("BLOP", &l, true));
- tll_push_back(l, "BLOP");
+ vec_push(&l, "BLOP");
ATF_REQUIRE(line_startwithany("BLOP", &l, false));
ATF_REQUIRE(line_startwithany("BLOP", &l, true));
}
{ "Cc:", 0, NULL },
{ NULL, 0, NULL }
};
- strlist allhdrs = tll_init();
- strlist allunfoldeds = tll_init();
+ strlist allhdrs = vec_init();
+ strlist allunfoldeds = vec_init();
FILE *f;
/* Simple headers */
ATF_REQUIRE(strstr(readhdrs[2].values[0], "Test message") != NULL);
ATF_REQUIRE_EQ(readhdrs[3].valuecount, 0);
- ATF_REQUIRE_EQ(tll_length(allhdrs), 3);
- ATF_REQUIRE_EQ(tll_length(allunfoldeds), 3);
+ ATF_REQUIRE_EQ(allhdrs.len, 3);
+ ATF_REQUIRE_EQ(allunfoldeds.len, 3);
- tll_free_and_free(allhdrs, free);
- tll_free_and_free(allunfoldeds, free);
+ vec_free_and_free(&allhdrs, free);
+ vec_free_and_free(&allunfoldeds, free);
/* Folded header (continuation line) */
{
{ "Subject:", 0, NULL },
{ NULL, 0, NULL }
};
- strlist allhdrs2 = tll_init();
- strlist allunfoldeds2 = tll_init();
+ strlist allhdrs2 = vec_init();
+ strlist allunfoldeds2 = vec_init();
atf_utils_create_file("scan2.txt",
"Subject: This is a very long\n"
ATF_REQUIRE_EQ(readhdrs2[0].valuecount, 1);
/* Unfolded header should have both parts */
- ATF_REQUIRE_EQ(tll_length(allhdrs2), 1);
- ATF_REQUIRE(strstr(tll_front(allhdrs2), "subject line") != NULL);
+ ATF_REQUIRE_EQ(allhdrs2.len, 1);
+ ATF_REQUIRE(strstr(allhdrs2.d[0], "subject line") != NULL);
/* allunfoldeds keeps the original folded form */
- ATF_REQUIRE_EQ(tll_length(allunfoldeds2), 1);
- ATF_REQUIRE(strstr(tll_front(allunfoldeds2), "\n") != NULL);
+ ATF_REQUIRE_EQ(allunfoldeds2.len, 1);
+ ATF_REQUIRE(strstr(allunfoldeds2.d[0], "\n") != NULL);
- tll_free_and_free(allhdrs2, free);
- tll_free_and_free(allunfoldeds2, free);
+ vec_free_and_free(&allhdrs2, free);
+ vec_free_and_free(&allunfoldeds2, free);
}
/* Empty headers (just body) */
{ "From:", 0, NULL },
{ NULL, 0, NULL }
};
- strlist allhdrs3 = tll_init();
+ strlist allhdrs3 = vec_init();
atf_utils_create_file("scan3.txt", "\nBody only.\n");
f = fopen("scan3.txt", "r");
fclose(f);
ATF_REQUIRE_EQ(readhdrs3[0].valuecount, 0);
- ATF_REQUIRE_EQ(tll_length(allhdrs3), 0);
- tll_free_and_free(allhdrs3, free);
+ ATF_REQUIRE_EQ(allhdrs3.len, 0);
+ vec_free_and_free(&allhdrs3, free);
}
}
ATF_TC_BODY(voodoo_header_manipulation, tc)
{
- strlist allheaders = tll_init();
- strlist delhdrs = tll_init();
+ strlist allheaders = vec_init();
+ strlist delhdrs = vec_init();
struct mailhdr readhdrs[] = {
{ "From:", 0, NULL },
{ "To:", 0, NULL },
"Body text here.\n");
/* Delete Return-Path header */
- tll_push_back(delhdrs, strdup("Return-Path:"));
+ vec_push(&delhdrs, strdup("Return-Path:"));
/* Custom header to inject */
atf_utils_create_file("customhdr.txt", "X-List-ID: mylist\n");
atf_tc_fail("Body missing");
}
- tll_free_and_free(allheaders, free);
- tll_free_and_free(delhdrs, free);
+ vec_free_and_free(&allheaders, free);
+ vec_free_and_free(&delhdrs, free);
}
ATF_TC_BODY(voodoo_replyto, tc)
{
- strlist allheaders = tll_init();
- strlist delhdrs = tll_init();
+ strlist allheaders = vec_init();
+ strlist delhdrs = vec_init();
struct mailhdr readhdrs[] = {
{ "From:", 0, NULL },
{ "To:", 0, NULL },
atf_tc_fail("From header missing");
}
- tll_free_and_free(allheaders, free);
- tll_free_and_free(delhdrs, free);
+ vec_free_and_free(&allheaders, free);
+ vec_free_and_free(&delhdrs, free);
}
ATF_TC_BODY(voodoo_prefix_dedup, tc)
{
- strlist allheaders = tll_init();
- strlist delhdrs = tll_init();
+ strlist allheaders = vec_init();
+ strlist delhdrs = vec_init();
struct mailhdr readhdrs[] = {
{ "From:", 0, NULL },
{ "To:", 0, NULL },
atf_tc_fail("Subject prefix duplicated");
}
- tll_free_and_free(allheaders, free);
- tll_free_and_free(delhdrs, free);
+ vec_free_and_free(&allheaders, free);
+ vec_free_and_free(&delhdrs, free);
/* Mail without Subject: prefix should be added as new Subject */
{
- strlist allheaders2 = tll_init();
+ strlist allheaders2 = vec_init();
struct mailhdr readhdrs2[] = {
{ "From:", 0, NULL },
{ "To:", 0, NULL },
atf_tc_fail("Subject not added for mail without subject");
}
- tll_free_and_free(allheaders2, free);
+ vec_free_and_free(&allheaders2, free);
}
}
/*
* Regression test: calling do_all_the_voodoo_here() twice with the same
* allhdrs list (without clearing it) used to trigger an assertion in
- * tll_pop_front(allunfoldeds) because allhdrs had stale entries from the
+ * vec_pop_front on allunfoldeds because allhdrs had stale entries from the
* first call while allunfoldeds was freshly initialized.
* This is the code path hit when mlmmj-process handles a mail addressed
* to list+owner (recipextra == "owner").
*/
ATF_TC_BODY(voodoo_double_call, tc)
{
- strlist allheaders = tll_init();
- strlist delhdrs = tll_init();
+ strlist allheaders = vec_init();
+ strlist delhdrs = vec_init();
struct mailhdr readhdrs[] = {
{ "From:", 0, NULL },
{ "To:", 0, NULL },
"\n"
"A new user has subscribed.\n");
- tll_push_back(delhdrs, strdup("From "));
- tll_push_back(delhdrs, strdup("Return-Path:"));
+ vec_push(&delhdrs, strdup("From "));
+ vec_push(&delhdrs, strdup("Return-Path:"));
/* First call: populates allheaders (normal processing path) */
infd = open("testmail.txt", O_RDONLY);
close(infd);
close(outfd);
- ATF_REQUIRE_MSG(tll_length(allheaders) > 0,
+ ATF_REQUIRE_MSG(allheaders.len > 0,
"allheaders should be populated after first call");
/* Second call with the same allheaders, simulating the
* recipextra == "owner" path. Before the fix this would abort
* with: Assertion failed: allunfoldeds.length > 0 */
- tll_free_and_free(allheaders, free);
+ vec_free_and_free(&allheaders, free);
infd = open("testmail.txt", O_RDONLY);
ATF_REQUIRE(infd >= 0);
outfd = open("out2.txt", O_RDWR|O_CREAT|O_TRUNC, 0600);
close(infd);
close(outfd);
- tll_free_and_free(allheaders, free);
- tll_free_and_free(delhdrs, free);
+ vec_free_and_free(&allheaders, free);
+ vec_free_and_free(&delhdrs, free);
}
/*
*/
ATF_TC_BODY(voodoo_failure_cleans_queue, tc)
{
- strlist allheaders = tll_init();
+ strlist allheaders = vec_init();
struct mailhdr readhdrs[] = {
{ "From:", 0, NULL },
{ "To:", 0, NULL },
ATF_REQUIRE_MSG(access("queuefile.txt", F_OK) != 0,
"queue file should be cleaned up after voodoo failure");
- tll_free_and_free(allheaders, free);
+ vec_free_and_free(&allheaders, free);
}
ATF_TC_BODY(checkwait_smtpreply_connect, tc)