Avoid the long whats_supported line being mixed with output from other processes
[exim.git] / src / src / functions.h
index 0e38030d0286d0f9318af6b450f53b976b3ff344..efd039b5e940044f0a29de57fcd8a24b04b82141 100644 (file)
@@ -13,6 +13,7 @@ are in in fact in separate headers. */
 #ifndef _FUNCTIONS_H_
 #define _FUNCTIONS_H_
 
+#include <ctype.h>
 #include <sys/time.h>
 
 
@@ -118,7 +119,7 @@ extern int     auth_get_data(uschar **, const uschar *, int);
 extern int     auth_get_no64_data(uschar **, uschar *);
 extern int     auth_prompt(const uschar *);
 extern int     auth_read_input(const uschar *);
-extern void    auth_show_supported(FILE *);
+extern gstring * auth_show_supported(gstring *);
 extern uschar *auth_xtextencode(uschar *, int);
 extern int     auth_xtextdecode(uschar *, uschar **);
 
@@ -150,8 +151,13 @@ extern void    bits_set(unsigned int *, size_t, int *);
 extern void    cancel_cutthrough_connection(BOOL, const uschar *);
 extern int     check_host(void *, const uschar *, const uschar **, uschar **);
 extern uschar **child_exec_exim(int, BOOL, int *, BOOL, int, ...);
+extern pid_t   child_open_exim_function(int *, const uschar *);
+extern pid_t   child_open_exim2_function(int *, uschar *, uschar *,
+                const uschar *);
+extern pid_t   child_open_function(uschar **, uschar **, int,
+                int *, int *, BOOL, const uschar *);
 extern pid_t   child_open_uid(const uschar **, const uschar **, int,
-                uid_t *, gid_t *, int *, int *, uschar *, BOOL);
+                uid_t *, gid_t *, int *, int *, uschar *, BOOL, const uschar *);
 extern BOOL    cleanup_environment(void);
 extern void    cutthrough_data_puts(uschar *, int);
 extern void    cutthrough_data_put_nl(void);
@@ -222,10 +228,10 @@ extern void    msg_event_raise(const uschar *, const address_item *);
 
 extern int     exim_chown_failure(int, const uschar*, uid_t, gid_t);
 extern const uschar * exim_errstr(int);
-extern void    exim_exit(int, const uschar *) NORETURN;
+extern void    exim_exit(int) NORETURN;
 extern void    exim_nullstd(void);
 extern void    exim_setugid(uid_t, gid_t, BOOL, uschar *);
-extern void    exim_underbar_exit(int, const uschar *);
+extern void    exim_underbar_exit(int) NORETURN;
 extern void    exim_wait_tick(struct timeval *, int);
 extern int     exp_bool(address_item *addr,
   uschar *mtype, uschar *mname, unsigned dgb_opt, uschar *oname, BOOL bvalue,
@@ -306,7 +312,7 @@ extern void    mainlog_close(void);
 extern int     malware(const uschar *, int);
 extern int     malware_in_file(uschar *);
 extern void    malware_init(void);
-extern void    malware_show_supported(FILE *);
+extern gstring * malware_show_supported(gstring *);
 #endif
 extern int     match_address_list(const uschar *, BOOL, BOOL, const uschar **,
                  unsigned int *, int, int, const uschar **);
@@ -430,15 +436,15 @@ extern BOOL    route_find_expanded_group(uschar *, uschar *, uschar *, gid_t *,
 extern BOOL    route_find_expanded_user(uschar *, uschar *, uschar *,
                  struct passwd **, uid_t *, uschar **);
 extern void    route_init(void);
-extern void    route_show_supported(FILE *);
+extern gstring * route_show_supported(gstring *);
 extern void    route_tidyup(void);
 
-extern uschar *search_find(void *, uschar *, uschar *, int, const uschar *, int,
-                 int, int *);
+extern uschar *search_find(void *, const uschar *, uschar *, int,
+                const uschar *, int, int, int *, const uschar *);
 extern int     search_findtype(const uschar *, int);
 extern int     search_findtype_partial(const uschar *, int *, const uschar **, int *,
-                 int *);
-extern void   *search_open(uschar *, int, int, uid_t *, gid_t *);
+                 int *, const uschar **);
+extern void   *search_open(const uschar *, int, int, uid_t *, gid_t *);
 extern void    search_tidyup(void);
 extern void    set_process_info(const char *, ...) PRINTF_FUNCTION(1,2);
 extern void    sha1_end(hctx *, const uschar *, int, uschar *);
@@ -571,7 +577,7 @@ extern void    transport_write_reset(int);
 extern BOOL    transport_write_string(int, const char *, ...);
 extern BOOL    transport_headers_send(transport_ctx *,
                  BOOL (*)(transport_ctx *, uschar *, int));
-extern void    transport_show_supported(FILE *);
+extern gstring * transport_show_supported(gstring *);
 extern BOOL    transport_write_message(transport_ctx *, int);
 extern void    tree_add_duplicate(uschar *, address_item *);
 extern void    tree_add_nonrecipient(uschar *);
@@ -661,6 +667,15 @@ return US strncpy(CS dst, CCS src, n);
 /*XXX will likely need unchecked copy also */
 
 
+/* Advance the string pointer given over any whitespace.
+Return the next char as there's enought places using it to be useful. */
+
+#define Uskip_whitespace(sp) skip_whitespace(CUSS sp)
+
+static inline uschar skip_whitespace(const uschar ** sp)
+{ while (isspace(**sp)) (*sp)++; return **sp; }
+
+
 /******************************************************************************/
 
 #if !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
@@ -1061,7 +1076,7 @@ static inline int
 exim_open2(const char *pathname, int flags)
 {
 if (!is_tainted(pathname)) return open(pathname, flags);
-log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
 errno = EACCES;
 return -1;
 }
@@ -1069,7 +1084,7 @@ static inline int
 exim_open(const char *pathname, int flags, mode_t mode)
 {
 if (!is_tainted(pathname)) return open(pathname, flags, mode);
-log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
 errno = EACCES;
 return -1;
 }
@@ -1077,7 +1092,7 @@ static inline int
 exim_openat(int dirfd, const char *pathname, int flags)
 {
 if (!is_tainted(pathname)) return openat(dirfd, pathname, flags);
-log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
 errno = EACCES;
 return -1;
 }
@@ -1085,7 +1100,7 @@ static inline int
 exim_openat4(int dirfd, const char *pathname, int flags, mode_t mode)
 {
 if (!is_tainted(pathname)) return openat(dirfd, pathname, flags, mode);
-log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
 errno = EACCES;
 return -1;
 }
@@ -1094,11 +1109,62 @@ static inline FILE *
 exim_fopen(const char *pathname, const char *mode)
 {
 if (!is_tainted(pathname)) return fopen(pathname, mode);
-log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
 errno = EACCES;
 return NULL;
 }
 
+static inline DIR *
+exim_opendir(const uschar * name)
+{
+if (!is_tainted(name)) return opendir(CCS name);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name);
+errno = EACCES;
+return NULL;
+}
+
+/******************************************************************************/
+# if !defined(COMPILE_UTILITY)
+/* Process manipulation */
+
+static inline pid_t
+exim_fork(const unsigned char * purpose)
+{
+pid_t pid;
+DEBUG(D_any) debug_printf("%s forking for %s\n", process_purpose, purpose);
+if ((pid = fork()) == 0)
+  {
+  process_purpose = purpose;
+  DEBUG(D_any) debug_printf("postfork: %s\n", purpose);
+  }
+else
+  {
+  testharness_pause_ms(100); /* let child work */
+  DEBUG(D_any) debug_printf("%s forked for %s: %d\n", process_purpose, purpose, (int)pid);
+  }
+return pid;
+}
+
+
+static inline pid_t
+child_open_exim(int * fdptr, const uschar * purpose)
+{ return child_open_exim_function(fdptr, purpose); }
+
+static inline pid_t
+child_open_exim2(int * fdptr, uschar * sender,
+  uschar * sender_auth, const uschar * purpose)
+{ return child_open_exim2_function(fdptr, sender, sender_auth, purpose); }
+
+static inline pid_t
+child_open(uschar **argv, uschar **envp, int newumask, int *infdptr,
+  int *outfdptr, BOOL make_leader, const uschar * purpose)
+{ return child_open_function(argv, envp, newumask, infdptr,
+  outfdptr, make_leader, purpose);
+}
+
+# endif        /* !COMPILE_UTILITY */
+
+/******************************************************************************/
 #endif /* !MACRO_PREDEF */
 
 #endif  /* _FUNCTIONS_H_ */