+/* Return 1 if fd is usable per pollbits, else 0 */
+static inline int
+poll_one_fd(int fd, short pollbits, int tmo_millisec)
+{
+struct pollfd p = {.fd = fd, .events = pollbits};
+return poll(&p, 1, tmo_millisec);
+}
+
+/******************************************************************************/
+/* Client-side smtp log string, for debug */
+
+static inline void
+smtp_debug_cmd_log_init(void)
+{
+# ifndef DISABLE_CLIENT_CMD_LOG
+int old_pool = store_pool;
+store_pool = POOL_PERM;
+client_cmd_log = string_get_tainted(56, GET_TAINTED);
+*client_cmd_log->s = '\0';
+store_pool = old_pool;
+# endif
+}
+
+
+static inline void
+smtp_debug_cmd(const uschar * buf, int mode)
+{
+HDEBUG(D_transport|D_acl|D_v) debug_printf_indent(" SMTP%c> %s\n",
+ mode == SCMD_BUFFER ? '|' : mode == SCMD_MORE ? '+' : '>', buf);
+
+# ifndef DISABLE_CLIENT_CMD_LOG
+ {
+ int len = Ustrcspn(buf, " \n"), old_pool = store_pool;
+ store_pool = POOL_PERM; /* Main pool ACL allocations eg. callouts get released */
+ client_cmd_log = string_append_listele_n(client_cmd_log, ':', buf, MIN(len, 8));
+ if (mode == SCMD_BUFFER)
+ client_cmd_log = string_catn(client_cmd_log, US"|", 1);
+ else if (mode == SCMD_MORE)
+ client_cmd_log = string_catn(client_cmd_log, US"+", 1);
+ store_pool = old_pool;
+ }
+# endif
+}
+
+
+/* This might be called both due to callout and then from delivery.
+Use memory that will not be released between those phases.
+*/
+static inline void
+smtp_debug_resp(const uschar * buf)
+{
+# ifndef DISABLE_CLIENT_CMD_LOG
+int old_pool = store_pool;
+store_pool = POOL_PERM;
+client_cmd_log = string_append_listele_n(client_cmd_log, ':', buf,
+ buf[3] == '-' ? 4 : 3);
+store_pool = old_pool;
+# endif
+}
+
+
+static inline void
+smtp_debug_cmd_report(void)
+{
+# ifndef DISABLE_CLIENT_CMD_LOG
+if (client_cmd_log && *client_cmd_log->s)
+ {
+ debug_printf("cmdlog: '%Y'\n", client_cmd_log);
+ gstring_reset(client_cmd_log);
+ }
+else
+ debug_printf("cmdlog: (unset)\n");
+# endif
+}
+
+
+
+static inline int
+expand_max_rcpt(const uschar * str_max_rcpt)
+{
+const uschar * s = expand_cstring(str_max_rcpt);
+int res;
+return !s || !*s || (res = Uatoi(s)) == 0 ? UNLIMITED_ADDRS : res;
+}
+
+/******************************************************************************/
+/* Queue-runner operations */
+
+static inline BOOL
+is_onetime_qrun(void)
+{
+return qrunners && !qrunners->next && qrunners->interval == 0;
+}
+
+static inline BOOL
+is_multiple_qrun(void)
+{
+return qrunners && (qrunners->interval > 0 || qrunners->next);
+}
+
+