{ "write_rejectlog", opt_bool, &write_rejectlog }
};
+#ifndef MACRO_PREDEF
static int optionlist_config_size = nelem(optionlist_config);
+#endif
#ifdef MACRO_PREDEF
for (ai = auths_available; ai->driver_name[0]; ai++)
{
- snprintf(buf, sizeof(buf), "_DRIVER_AUTHENTICATOR_%T", ai->driver_name);
+ spf(buf, sizeof(buf), US"_DRIVER_AUTHENTICATOR_%T", ai->driver_name);
builtin_macro_create(buf);
options_from_list(ai->options, (unsigned)*ai->options_count, US"AUTHENTICATOR", ai->driver_name);
}
for (i = 0; i < *ri->options_count; i++)
{
if ((ri->options[i].type & opt_mask) != opt_stringptr) continue;
- if (p == (char *)(r->options_block) + (long int)(ri->options[i].value))
+ if (p == CS (r->options_block) + (long int)(ri->options[i].value))
return US ri->options[i].name;
}
}
optionlist * op = &ti->options[i];
if ((op->type & opt_mask) != opt_stringptr) continue;
if (p == ( op->type & opt_public
- ? (char *)t
- : (char *)t->options_block
+ ? CS t
+ : CS t->options_block
)
+ (long int)op->value)
return US op->name;
macro_item *
macro_create(const uschar * name, const uschar * val, BOOL command_line)
{
-unsigned namelen = Ustrlen(name);
macro_item * m = store_get(sizeof(macro_item));
/* fprintf(stderr, "%s: '%s' '%s'\n", __FUNCTION__, name, val); */
m->next = NULL;
m->command_line = command_line;
-m->namelen = namelen;
+m->namelen = Ustrlen(name);
+m->replen = Ustrlen(val);
m->name = name;
m->replacement = val;
mlast->next = m;
if (redef)
if (m)
+ {
+ m->replen = Ustrlen(s);
m->replacement = string_copy(s);
+ }
else
log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "can't redefine an undefined macro "
"\"%s\"", name);
if (*s != '=') s = ss; /* Not a macro definition */
}
+ /* Skip leading chars which cannot start a macro name, to avoid multiple
+ pointless rescans in Ustrstr calls. */
+
+ while (*s && !isupper(*s) && *s != '_') s++;
+
/* For each defined macro, scan the line (from after XXX= if present),
replacing all occurrences of the macro. */
macro_found = FALSE;
for (m = macros; m; m = m->next)
{
- uschar *p, *pp;
- uschar *t = s;
+ uschar * p, *pp;
+ uschar * t = s;
while ((p = Ustrstr(t, m->name)) != NULL)
{
int moveby;
- int replen = Ustrlen(m->replacement);
-/* fprintf(stderr, "%s: matched '%s' in '%s'\n", __FUNCTION__, m->name, t); */
+/* fprintf(stderr, "%s: matched '%s' in '%s'\n", __FUNCTION__, m->name, ss); */
/* Expand the buffer if necessary */
- while (newlen - m->namelen + replen + 1 > big_buffer_size)
+ while (newlen - m->namelen + m->replen + 1 > big_buffer_size)
{
int newsize = big_buffer_size + BIG_BUFFER_SIZE;
uschar *newbuffer = store_malloc(newsize);
same macro. */
pp = p + m->namelen;
- if ((moveby = replen - m->namelen) != 0)
+ if ((moveby = m->replen - m->namelen) != 0)
{
- memmove(p + replen, pp, (big_buffer + newlen) - pp + 1);
+ memmove(p + m->replen, pp, (big_buffer + newlen) - pp + 1);
newlen += moveby;
}
- Ustrncpy(p, m->replacement, replen);
- t = p + replen;
+ Ustrncpy(p, m->replacement, m->replen);
+ t = p + m->replen;
+ while (*t && !isupper(*t) && *t != '_') t++;
macro_found = TRUE;
}
}
if (ol == NULL) log_write(0, LOG_MAIN|LOG_PANIC_DIE,
"Exim internal error: missing set flag for %s", name);
return (data_block == NULL)? (BOOL *)(ol->value) :
- (BOOL *)((uschar *)data_block + (long int)(ol->value));
+ (BOOL *)(US data_block + (long int)(ol->value));
}
}
else
{
- chain = (rewrite_rule **)((uschar *)data_block + (long int)(ol2->value));
- flagptr = (int *)((uschar *)data_block + (long int)(ol3->value));
+ chain = (rewrite_rule **)(US data_block + (long int)(ol2->value));
+ flagptr = (int *)(US data_block + (long int)(ol3->value));
}
while ((p = string_nextinlist(CUSS &sptr, &sep, big_buffer, BIG_BUFFER_SIZE)))
if (data_block == NULL)
*((uschar **)(ol2->value)) = ss;
else
- *((uschar **)((uschar *)data_block + (long int)(ol2->value))) = ss;
+ *((uschar **)(US data_block + (long int)(ol2->value))) = ss;
if (ss != NULL)
{
if (data_block == NULL)
*((uid_t *)(ol->value)) = uid;
else
- *((uid_t *)((uschar *)data_block + (long int)(ol->value))) = uid;
+ *((uid_t *)(US data_block + (long int)(ol->value))) = uid;
/* Set the flag indicating a fixed value is set */
if (data_block == NULL)
*((gid_t *)(ol2->value)) = pw->pw_gid;
else
- *((gid_t *)((uschar *)data_block + (long int)(ol2->value))) = pw->pw_gid;
+ *((gid_t *)(US data_block + (long int)(ol2->value))) = pw->pw_gid;
*set_flag = TRUE;
}
}
if (data_block == NULL)
*((uschar **)(ol2->value)) = ss;
else
- *((uschar **)((uschar *)data_block + (long int)(ol2->value))) = ss;
+ *((uschar **)(US data_block + (long int)(ol2->value))) = ss;
if (ss != NULL)
{
if (data_block == NULL)
*((gid_t *)(ol->value)) = gid;
else
- *((gid_t *)((uschar *)data_block + (long int)(ol->value))) = gid;
+ *((gid_t *)(US data_block + (long int)(ol->value))) = gid;
*(get_set_flag(name, oltop, last, data_block)) = TRUE;
break;
if (data_block == NULL)
*((uid_t **)(ol->value)) = list;
else
- *((uid_t **)((uschar *)data_block + (long int)(ol->value))) = list;
+ *((uid_t **)(US data_block + (long int)(ol->value))) = list;
p = op;
while (count-- > 1)
if (data_block == NULL)
*((gid_t **)(ol->value)) = list;
else
- *((gid_t **)((uschar *)data_block + (long int)(ol->value))) = list;
+ *((gid_t **)(US data_block + (long int)(ol->value))) = list;
p = op;
while (count-- > 1)
if (data_block == NULL)
*((uschar **)(ol2->value)) = sptr;
else
- *((uschar **)((uschar *)data_block + (long int)(ol2->value))) = sptr;
+ *((uschar **)(US data_block + (long int)(ol2->value))) = sptr;
freesptr = FALSE;
break;
}
int bit = 1 << ((ol->type >> 16) & 31);
int *ptr = (data_block == NULL)?
(int *)(ol->value) :
- (int *)((uschar *)data_block + (long int)ol->value);
+ (int *)(US data_block + (long int)ol->value);
if (boolvalue) *ptr |= bit; else *ptr &= ~bit;
break;
}
if (data_block == NULL)
*((BOOL *)(ol->value)) = boolvalue;
else
- *((BOOL *)((uschar *)data_block + (long int)(ol->value))) = boolvalue;
+ *((BOOL *)(US data_block + (long int)(ol->value))) = boolvalue;
/* Verify fudge */
if (data_block == NULL)
*((BOOL *)(ol2->value)) = boolvalue;
else
- *((BOOL *)((uschar *)data_block + (long int)(ol2->value))) = boolvalue;
+ *((BOOL *)(US data_block + (long int)(ol2->value))) = boolvalue;
}
}
if (data_block == NULL)
*((BOOL *)(ol2->value)) = TRUE;
else
- *((BOOL *)((uschar *)data_block + (long int)(ol2->value))) = TRUE;
+ *((BOOL *)(US data_block + (long int)(ol2->value))) = TRUE;
}
}
break;
if (data_block == NULL)
*((int *)(ol->value)) = value;
else
- *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
+ *((int *)(US data_block + (long int)(ol->value))) = value;
break;
/* Integer held in K: again, allow octal and hex formats, and suffixes K, M
if (data_block == NULL)
*((int *)(ol->value)) = value;
else
- *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
+ *((int *)(US data_block + (long int)(ol->value))) = value;
break;
/* Fixed-point number: held to 3 decimal places. */
if (data_block == NULL)
*((int *)(ol->value)) = value;
else
- *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
+ *((int *)(US data_block + (long int)(ol->value))) = value;
break;
/* There's a special routine to read time values. */
if (data_block == NULL)
*((int *)(ol->value)) = value;
else
- *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
+ *((int *)(US data_block + (long int)(ol->value))) = value;
break;
/* A time list is a list of colon-separated times, with the first
int count = 0;
int *list = (data_block == NULL)?
(int *)(ol->value) :
- (int *)((uschar *)data_block + (long int)(ol->value));
+ (int *)(US data_block + (long int)(ol->value));
if (*s != 0) for (count = 1; count <= list[0] - 2; count++)
{
d = t % 7;
w = t/7;
-if (w > 0) { sprintf(CS p, "%dw", w); while (*p) p++; }
-if (d > 0) { sprintf(CS p, "%dd", d); while (*p) p++; }
-if (h > 0) { sprintf(CS p, "%dh", h); while (*p) p++; }
-if (m > 0) { sprintf(CS p, "%dm", m); while (*p) p++; }
+if (w > 0) p += sprintf(CS p, "%dw", w);
+if (d > 0) p += sprintf(CS p, "%dd", d);
+if (h > 0) p += sprintf(CS p, "%dh", h);
+if (m > 0) p += sprintf(CS p, "%dm", m);
if (s > 0 || p == time_buffer) sprintf(CS p, "%ds", s);
return time_buffer;
{
if ((ol->type & opt_public) == 0)
options_block = (void *)(((driver_instance *)options_block)->options_block);
- value = (void *)((uschar *)options_block + (long int)value);
+ value = (void *)(US options_block + (long int)value);
}
switch(ol->type & opt_mask)
{
void *value2 = ol2->value;
if (options_block != NULL)
- value2 = (void *)((uschar *)options_block + (long int)value2);
+ value2 = (void *)(US options_block + (long int)value2);
s = *((uschar **)value2);
if (!no_labels) printf("%s = ", name);
printf("%s\n", (s == NULL)? US"" : string_printing(s));
{
void *value2 = ol2->value;
if (options_block != NULL)
- value2 = (void *)((uschar *)options_block + (long int)value2);
+ value2 = (void *)(US options_block + (long int)value2);
s = *((uschar **)value2);
if (!no_labels) printf("%s = ", name);
printf("%s\n", (s == NULL)? US"" : string_printing(s));
{
void *value2 = ol2->value;
if (options_block != NULL)
- value2 = (void *)((uschar *)options_block + (long int)value2);
+ value2 = (void *)(US options_block + (long int)value2);
s = *((uschar **)value2);
if (s != NULL)
{
driver_info *dd;
for (dd = drivers_available; dd->driver_name[0] != 0;
- dd = (driver_info *)(((uschar *)dd) + size_of_info))
+ dd = (driver_info *)((US dd) + size_of_info))
{
if (Ustrcmp(d->driver_name, dd->driver_name) == 0)
{
int type = ol->type & opt_mask;
if (type != opt_stringptr) continue;
options_block = ((ol->type & opt_public) == 0)? d->options_block : (void *)d;
- value = *(uschar **)((uschar *)options_block + (long int)(ol->value));
+ value = *(uschar **)(US options_block + (long int)(ol->value));
if (value != NULL && (ss = Ustrstr(value, s)) != NULL)
{
if (ss <= value || (ss[-1] != '$' && ss[-1] != '{') ||
static int values[] =
{ 'A', 'M', RTEF_CTOUT, RTEF_CTOUT|'A', RTEF_CTOUT|'M' };
- for (i = 0; i < sizeof(extras)/sizeof(uschar *); i++)
+ for (i = 0; i < nelem(extras); i++)
if (strncmpic(x, extras[i], xlen) == 0)
{
*more_errno = values[i];
break;
}
- if (i >= sizeof(extras)/sizeof(uschar *))
+ if (i >= nelem(extras))
if (strncmpic(x, US"DNS", xlen) == 0)
log_write(0, LOG_MAIN|LOG_PANIC, "\"timeout_dns\" is no longer "
"available in retry rules (it has never worked) - treated as "
{
int bit;
int first = 0;
- int last = sizeof(section_list) / sizeof(uschar *);
+ int last = nelem(section_list);
int mid = last/2;
int n = Ustrlen(next_section);
this operates on a global (static) list that holds all the pre-parsed
config lines, we do no further processing here, output formatting and
honouring of <hide> or macros will be done during output */
+
static void
save_config_line(const uschar* line)
{