* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2016 */
+/* Copyright (c) University of Cambridge 1995 - 2017 */
/* See the file NOTICE for conditions of use and distribution. */
"If the string is not recognised, you'll get this help (on stderr).\n"
"\n"
" exim -bI:help this information\n"
-" exim -bI:dscp dscp value keywords known\n"
-" exim -bI:sieve list of supported sieve extensions, one per line.\n"
+" exim -bI:dscp list of known dscp value keywords\n"
+" exim -bI:sieve list of supported sieve extensions\n"
);
return;
case CMDINFO_SIEVE:
}
+/*************************************************
+* Expansion testing *
+*************************************************/
+
+/* Expand and print one item, doing macro-processing.
+
+Arguments:
+ item line for expansion
+*/
+
+static void
+expansion_test_line(uschar * line)
+{
+int len;
+BOOL dummy_macexp;
+
+Ustrncpy(big_buffer, line, big_buffer_size);
+big_buffer[big_buffer_size-1] = '\0';
+len = Ustrlen(big_buffer);
+
+(void) macros_expand(0, &len, &dummy_macexp);
+
+if (isupper(big_buffer[0]))
+ {
+ if (macro_read_assignment(big_buffer))
+ printf("Defined macro '%s'\n", mlast->name);
+ }
+else
+ if ((line = expand_string(big_buffer))) printf("%s\n", CS line);
+ else printf("Failed: %s\n", expand_string_message);
+}
+
+
/*************************************************
* Entry point and high-level code *
*************************************************/
which sets the host protocol and host name */
if (*argrest == 0)
- {
- if (i+1 < argc) argrest = argv[++i]; else
+ if (i+1 < argc)
+ argrest = argv[++i];
+ else
{ badarg = TRUE; break; }
- }
if (*argrest != 0)
{
hn = Ustrchr(argrest, ':');
if (hn == NULL)
- {
received_protocol = argrest;
- }
else
{
int old_pool = store_pool;
directory to "/"! Later we change to $spool_directory. We do it there, because
during readconf_main() some expansion takes place already. */
-/* Store the initial cwd before we change directories */
-if ((initial_cwd = os_getcwd(NULL, 0)) == NULL)
- {
- perror("exim: can't get the current working directory");
- exit(EXIT_FAILURE);
- }
+/* Store the initial cwd before we change directories. Can be NULL if the
+dir has already been unlinked. */
+initial_cwd = os_getcwd(NULL, 0);
/* checking:
-be[m] expansion test -
}
/* At this point, we know if the user is privileged and some command-line
-options become possibly imperssible, depending upon the configuration file. */
+options become possibly impermissible, depending upon the configuration file. */
if (checking && commandline_checks_require_admin && !admin_user) {
fprintf(stderr, "exim: those command-line flags are set to require admin\n");
/* Read a test message from a file. We fudge it up to be on stdin, saving
stdin itself for later reading of expansion strings. */
- else if (expansion_test_message != NULL)
+ else if (expansion_test_message)
{
int save_stdin = dup(0);
int fd = Uopen(expansion_test_message, O_RDONLY, 0);
clearerr(stdin); /* Required by Darwin */
}
+ /* Only admin users may see config-file macros this way */
+
+ if (!admin_user) macros = mlast = NULL;
+
/* Allow $recipients for this testing */
enable_dollar_recipients = TRUE;
/* Expand command line items */
if (recipients_arg < argc)
- {
while (recipients_arg < argc)
- {
- uschar *s = argv[recipients_arg++];
- uschar *ss = expand_string(s);
- if (ss == NULL) printf ("Failed: %s\n", expand_string_message);
- else printf("%s\n", CS ss);
- }
- }
+ expansion_test_line(argv[recipients_arg++]);
/* Read stdin */
{
char *(*fn_readline)(const char *) = NULL;
void (*fn_addhist)(const char *) = NULL;
+ uschar * s;
- #ifdef USE_READLINE
+#ifdef USE_READLINE
void *dlhandle = set_readline(&fn_readline, &fn_addhist);
- #endif
+#endif
- for (;;)
- {
- uschar *ss;
- uschar *source = get_stdinput(fn_readline, fn_addhist);
- if (source == NULL) break;
- ss = expand_string(source);
- if (ss == NULL)
- printf ("Failed: %s\n", expand_string_message);
- else printf("%s\n", CS ss);
- }
+ while (s = get_stdinput(fn_readline, fn_addhist))
+ expansion_test_line(s);
- #ifdef USE_READLINE
- if (dlhandle != NULL) dlclose(dlhandle);
- #endif
+#ifdef USE_READLINE
+ if (dlhandle) dlclose(dlhandle);
+#endif
}
/* The data file will be open after -Mset */
deliver_datafile = -1;
}
- exim_exit(EXIT_SUCCESS, US"main");
+ exim_exit(EXIT_SUCCESS, US"main: expansion test");
}
return 0; /* To stop compiler warning */
}
-/*************************************************
-* read as much as requested *
-*************************************************/
-
-/* The syscall read(2) doesn't always returns as much as we want. For
-several reasons it might get less. (Not talking about signals, as syscalls
-are restartable). When reading from a network or pipe connection the sender
-might send in smaller chunks, with delays between these chunks. The read(2)
-may return such a chunk.
-
-The more the writer writes and the smaller the pipe between write and read is,
-the more we get the chance of reading leass than requested. (See bug 2130)
-
-This function read(2)s until we got all the data we *requested*.
-
-Note: This function may block. Use it only if you're sure about the
-amount of data you will get.
-
-Argument:
- fd the file descriptor to read from
- buffer pointer to a buffer of size len
- len the requested(!) amount of bytes
-
-Returns: the amount of bytes read
-*/
-ssize_t
-readn(int fd, void *buffer, size_t len)
-{
- void *next = buffer;
- void *end = buffer + len;
-
- while (next < end)
- {
- ssize_t got = read(fd, next, end - next);
-
- /* I'm not sure if there are signals that can interrupt us,
- for now I assume the worst */
- if (got == -1 && errno == EINTR) continue;
- if (got <= 0) return next - buffer;
- next += got;
- }
-
- return len;
-}
-
/* End of exim.c */