-/* $Cambridge: exim/src/src/filter.c,v 1.15 2009/11/16 19:50:37 nm4 Exp $ */
-
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
one (it can have \n anywhere). Then the file names and once_repeat, which may
not contain \n. */
-static char *mailargs[] = { /* "to" must be first, and */
- "to", /* "cc" and "bcc" must follow */
+static const char *mailargs[] = { /* "to" must be first, and */
+ "to", /* "cc" and "bcc" must follow */
"cc",
"bcc",
"from",
cond_above, cond_below, cond_errormsg, cond_firsttime,
cond_manualthaw, cond_foranyaddress };
-static char *cond_names[] = {
+static const char *cond_names[] = {
"and", "or", "personal",
"begins", "BEGINS", "ends", "ENDS",
"is", "IS", "matches", "MATCHES", "contains",
"CONTAINS", "delivered", "above", "below", "error_message",
"first_delivery", "manually_thawed", "foranyaddress" };
-static char *cond_not_names[] = {
+static const char *cond_not_names[] = {
"", "", "not personal",
"does not begin", "does not BEGIN",
"does not end", "does not END",
/* Tables of binary condition words and their corresponding types. Not easy
to amalgamate with the above because of the different variants. */
-static char *cond_words[] = {
+static const char *cond_words[] = {
"BEGIN",
"BEGINS",
"CONTAIN",
mail_command, noerror_command, pipe_command, save_command, seen_command,
testprint_command, unseen_command, vacation_command };
-static char *command_list[] = {
+static const char *command_list[] = {
"add", "defer", "deliver", "elif", "else", "endif", "finish",
"fail", "freeze", "headers", "if", "logfile", "logwrite", "mail",
"noerror", "pipe", "save", "seen", "testprint", "unseen", "vacation"
}
}
- *bp++ = string_interpret_escape(&ptr);
+ *bp++ = string_interpret_escape(CUSS &ptr);
}
}
string_item *aa;
uschar *saveptr = ptr;
ptr = nextword(ptr, buffer, sizeof(buffer), TRUE);
- if (*error_pointer != NULL) break;
+ if (*error_pointer) break;
if (Ustrcmp(buffer, "alias") != 0)
{
ptr = saveptr;
break;
}
ptr = nextitem(ptr, buffer, sizeof(buffer), TRUE);
- if (*error_pointer != NULL) break;
+ if (*error_pointer) break;
aa = store_get(sizeof(string_item));
aa->text = string_copy(buffer);
aa->next = c->left.a;
else if (Ustrcmp(buffer, "foranyaddress") == 0)
{
ptr = nextitem(ptr, buffer, sizeof(buffer), TRUE);
- if (*error_pointer != NULL) break;
+ if (*error_pointer) break;
if (*ptr != '(')
{
*error_pointer = string_sprintf("\"(\" expected after \"foranyaddress\" "
c->left.u = string_copy(buffer);
ptr = read_condition(nextsigchar(ptr+1, TRUE), &(c->right.c), FALSE);
- if (*error_pointer != NULL) break;
+ if (*error_pointer) break;
if (*ptr != ')')
{
*error_pointer = string_sprintf("expected \")\" in line %d of "
"filter file", line_number);
break;
}
- if (!testfor)
- {
- c->testfor = !c->testfor;
- testfor = TRUE;
- }
ptr = nextsigchar(ptr+1, TRUE);
}
c->left.u = string_copy(buffer);
ptr = nextword(ptr, buffer, sizeof(buffer), TRUE);
- if (*error_pointer != NULL) break;
+ if (*error_pointer) break;
/* Handle "does|is [not]", preserving the pointer after "is" in
case it isn't that, but the form "is <string>". */
if (buffer[0] == 'I') { c->type = cond_IS; isptr = ptr; }
ptr = nextword(ptr, buffer, sizeof(buffer), TRUE);
- if (*error_pointer != NULL) break;
+ if (*error_pointer) break;
if (strcmpic(buffer, US"not") == 0)
{
c->testfor = !c->testfor;
- if (isptr != NULL) isptr = ptr;
+ if (isptr) isptr = ptr;
ptr = nextword(ptr, buffer, sizeof(buffer), TRUE);
- if (*error_pointer != NULL) break;
+ if (*error_pointer) break;
}
}
if (i >= cond_word_count)
{
- if (isptr != NULL)
- {
- ptr = isptr;
- }
- else
+ if (!isptr)
{
*error_pointer = string_sprintf("unrecognized condition word \"%s\" "
"near line %d of filter file", buffer, line_number);
break;
}
+ ptr = isptr;
}
/* Get the RH argument. */
ptr = nextitem(ptr, buffer, sizeof(buffer), TRUE);
- if (*error_pointer != NULL) break;
+ if (*error_pointer) break;
c->right.u = string_copy(buffer);
}
}
{
uschar *saveptr = ptr;
ptr = nextword(ptr, buffer, sizeof(buffer), FALSE);
- if (*error_pointer != NULL) break;
+ if (*error_pointer) break;
/* "Then" terminates a toplevel condition; otherwise a closing bracket
has been omitted. Put a string terminator at the start of "then" so
if (Ustrcmp(buffer, "then") == 0)
{
if (toplevel) *saveptr = 0;
- else *error_pointer = string_sprintf("missing \")\" at end of "
+ else *error_pointer = string_sprintf("missing \")\" at end of "
"condition near line %d of filter file", line_number);
break;
}
condition_block *orc = store_get(sizeof(condition_block));
condition_block *or_parent = NULL;
- if (current_parent != NULL)
+ if (current_parent)
{
- while (current_parent->parent != NULL &&
+ while (current_parent->parent &&
current_parent->parent->type == cond_and)
current_parent = current_parent->parent;
/* If the parent has a parent, it must be an "or" parent. */
- if (current_parent->parent != NULL)
+ if (current_parent->parent)
or_parent = current_parent->parent;
}
orc->parent = or_parent;
- if (or_parent == NULL) *cond = orc; else
- or_parent->right.c = orc;
+ if (!or_parent) *cond = orc;
+ else or_parent->right.c = orc;
orc->type = cond_or;
orc->testfor = TRUE;
orc->left.c = (current_parent == NULL)? c : current_parent;
static void
print_condition(condition_block *c, BOOL toplevel)
{
-char *name = (c->testfor)? cond_names[c->type] : cond_not_names[c->type];
+const char *name = (c->testfor)? cond_names[c->type] : cond_not_names[c->type];
switch(c->type)
{
case cond_personal:
case cond_ENDS:
case cond_above:
case cond_below:
- debug_printf("%s %s %s", c->left.u, (char *)name, c->right.u);
+ debug_printf("%s %s %s", c->left.u, name, c->right.u);
break;
case cond_and:
set in a system filter and to the local address in user filters. */
addr = deliver_make_addr(expargs[0], TRUE); /* TRUE => copy s */
- addr->p.errors_address = (s == NULL)?
+ addr->prop.errors_address = (s == NULL)?
s : string_copy(s); /* Default is NULL */
if (commands->noerror) setflag(addr, af_ignore_error);
addr->next = *generated;
{
int sep = 0;
uschar *ss;
- uschar *list = s;
+ const uschar *list = s;
uschar buffer[128];
while ((ss = string_nextinlist(&list, &sep, buffer, sizeof(buffer)))
!= NULL)
DEFERFREEZEFAIL:
fmsg = expargs[0];
if (Ustrlen(fmsg) > 1024) Ustrcpy(fmsg + 1000, " ... (truncated)");
- fmsg = string_printing(fmsg);
+ fmsg = US string_printing(fmsg);
*error_pointer = fmsg;
if (filter_test != FTEST_NONE)
if (recipient != NULL)
{
- log_addr = string_cat(log_addr, &size, &ptr,
- (log_addr == NULL)? US">" : US",", 1);
- log_addr = string_cat(log_addr, &size, &ptr, recipient,
- Ustrlen(recipient));
+ log_addr = string_catn(log_addr, &size, &ptr,
+ log_addr ? US"," : US">", 1);
+ log_addr = string_cat(log_addr, &size, &ptr, recipient);
}
/* Check size */
if (ptr > 256)
{
- log_addr = string_cat(log_addr, &size, &ptr, US", ...", 5);
+ log_addr = string_catn(log_addr, &size, &ptr, US", ...", 5);
break;
}
case testprint_command:
if (filter_test != FTEST_NONE || (debug_selector & D_filter) != 0)
{
- uschar *s = string_printing(expargs[0]);
+ const uschar *s = string_printing(expargs[0]);
if (filter_test == FTEST_NONE)
debug_printf("Filter: testprint: %s\n", s);
else