static uschar * fn_recipients(void);
typedef uschar * stringptr_fn_t(void);
+static uschar * fn_queue_size(void);
/* This table must be kept in alphabetical order. */
{ "qualify_domain", vtype_stringptr, &qualify_domain_sender },
{ "qualify_recipient", vtype_stringptr, &qualify_domain_recipient },
{ "queue_name", vtype_stringptr, &queue_name },
+ { "queue_size", vtype_string_func, &fn_queue_size },
{ "rcpt_count", vtype_int, &rcpt_count },
{ "rcpt_defer_count", vtype_int, &rcpt_defer_count },
{ "rcpt_fail_count", vtype_int, &rcpt_fail_count },
/* Trim the header roughly if we're approaching limits */
inc = t - s;
- if ((g ? g->ptr : 0) + inc > header_insert_maxlen)
- inc = header_insert_maxlen - (g ? g->ptr : 0);
+ if (gstring_length(g) + inc > header_insert_maxlen)
+ inc = header_insert_maxlen - gstring_length(g);
/* For raw just copy the data; for a list, add the data as a colon-sep
list-element; for comma-list add as an unchecked comma,newline sep
if (flags & FH_WANT_LIST)
g = string_append_listele_n(g, ':', s, (unsigned)inc);
else if (flags & FH_WANT_RAW)
- {
g = string_catn(g, s, (unsigned)inc);
- (void) string_from_gstring(g);
- }
else if (inc > 0)
- if (comma)
- g = string_append2_listele_n(g, US",\n", s, (unsigned)inc);
- else
- g = string_append2_listele_n(g, US"\n", s, (unsigned)inc);
+ g = string_append2_listele_n(g, comma ? US",\n" : US"\n",
+ s, (unsigned)inc);
- if (g && g->ptr >= header_insert_maxlen) break;
+ if (gstring_length(g) >= header_insert_maxlen) break;
}
if (!found) return NULL; /* No header found */
*newsize = g->size;
if (flags & FH_WANT_RAW)
- return g->s;
+ return string_from_gstring(g);
/* Otherwise do RFC 2047 decoding, translating the charset if requested.
The rfc2047_decode2() function can return an error with decoded data if the
else
{
- uschar *decoded, *error;
-
- decoded = rfc2047_decode2(g->s, check_rfc2047_length, charset, '?', NULL,
- newsize, &error);
+ uschar * error, * decoded = rfc2047_decode2(string_from_gstring(g),
+ check_rfc2047_length, charset, '?', NULL, newsize, &error);
if (error)
- {
DEBUG(D_any) debug_printf("*** error in RFC 2047 decoding: %s\n"
" input was: %s\n", error, g->s);
- }
- return decoded ? decoded : g->s;
+ return decoded ? decoded : string_from_gstring(g);
}
}
}
+/*************************************************
+* Return size of queue *
+*************************************************/
+/* Ask the daemon for the queue size */
+
+static uschar *
+fn_queue_size(void)
+{
+struct sockaddr_un sun = {.sun_family = AF_UNIX};
+uschar buf[16];
+int fd;
+ssize_t len;
+const uschar * where;
+
+if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
+ {
+ DEBUG(D_expand) debug_printf(" socket: %s\n", strerror(errno));
+ return NULL;
+ }
+
+#define ABSTRACT_CLIENT
+#ifdef ABSTRACT_CLIENT
+sun.sun_path[0] = 0; /* Abstract local socket addr - Linux-specific? */
+len = offsetof(struct sockaddr_un, sun_path) + 1
+ + snprintf(sun.sun_path+1, sizeof(sun.sun_path)-1, "exim_%d", getpid());
+#else
+len = offsetof(struct sockaddr_un, sun_path)
+ + snprintf(sun.sun_path, sizeof(sun.sun_path), "%s/p_%d",
+ spool_directory, getpid());
+#endif
+
+if (bind(fd, &sun, len) < 0) { where = US"bind"; goto bad; }
+
+#ifdef notdef
+debug_printf("local%s '%s'\n", *sun.sun_path ? "" : " abstract",
+ sun.sun_path+ (*sun.sun_path ? 0 : 1));
+#endif
+
+sun.sun_path[0] = 0; /* Abstract local socket addr - Linux-specific? */
+len = offsetof(struct sockaddr_un, sun_path) + 1
+ + snprintf(sun.sun_path+1, sizeof(sun.sun_path)-1, "%s", NOTIFIER_SOCKET_NAME);
+
+if (connect(fd, &sun, len) < 0) { where = US"connect"; goto bad; }
+
+buf[0] = NOTIFY_QUEUE_SIZE_REQ;
+if (send(fd, buf, 1, 0) < 0) { where = US"send"; goto bad; }
+
+if ((len = recv(fd, buf, sizeof(buf), 0)) < 0) { where = US"recv"; goto bad; }
+
+close(fd);
+return string_copyn(buf, len);
+
+bad:
+ close(fd);
+ DEBUG(D_expand) debug_printf(" %s: %s\n", where, strerror(errno));
+ return NULL;
+}
+
+
/*************************************************
* Find value of a variable *
*************************************************/