X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/2f2dd3a5b7af190a42d45fead6230bc1bb75483d..759502e5af0acfb310b8571f056d2dbf59adb1d3:/src/src/expand.c diff --git a/src/src/expand.c b/src/src/expand.c index 4af4a3652..660fe98cf 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -589,7 +589,9 @@ static var_entry var_table[] = { { "local_part", vtype_stringptr, &deliver_localpart }, { "local_part_data", vtype_stringptr, &deliver_localpart_data }, { "local_part_prefix", vtype_stringptr, &deliver_localpart_prefix }, + { "local_part_prefix_v", vtype_stringptr, &deliver_localpart_prefix_v }, { "local_part_suffix", vtype_stringptr, &deliver_localpart_suffix }, + { "local_part_suffix_v", vtype_stringptr, &deliver_localpart_suffix_v }, { "local_part_verified", vtype_stringptr, &deliver_localpart_verified }, #ifdef HAVE_LOCAL_SCAN { "local_scan_data", vtype_stringptr, &local_scan_data }, @@ -1750,7 +1752,7 @@ return g ? g->s : NULL; static uschar * fn_queue_size(void) { -struct sockaddr_un sun = {.sun_family = AF_UNIX}; +struct sockaddr_un sa_un = {.sun_family = AF_UNIX}; uschar buf[16]; int fd; ssize_t len; @@ -1758,6 +1760,8 @@ const uschar * where; #ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS uschar * sname; #endif +fd_set fds; +struct timeval tv; if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { @@ -1766,41 +1770,49 @@ if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) } #ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS -sun.sun_path[0] = 0; /* Abstract local socket addr - Linux-specific? */ +sa_un.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()); + + snprintf(sa_un.sun_path+1, sizeof(sa_un.sun_path)-1, "exim_%d", getpid()); #else sname = string_sprintf("%s/p_%d", spool_directory, getpid()); len = offsetof(struct sockaddr_un, sun_path) - + snprintf(sun.sun_path, sizeof(sun.sun_path), "%s", sname); + + snprintf(sa_un.sun_path, sizeof(sa_un.sun_path), "%s", sname); #endif -if (bind(fd, (const struct sockaddr *)&sun, len) < 0) +if (bind(fd, (const struct sockaddr *)&sa_un, len) < 0) { where = US"bind"; goto bad; } #ifdef notdef debug_printf("local addr '%s%s'\n", - *sun.sun_path ? "" : "@", - sun.sun_path + (*sun.sun_path ? 0 : 1)); + *sa_un.sun_path ? "" : "@", + sa_un.sun_path + (*sa_un.sun_path ? 0 : 1)); #endif #ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS -sun.sun_path[0] = 0; /* Abstract local socket addr - Linux-specific? */ +sa_un.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); + + snprintf(sa_un.sun_path+1, sizeof(sa_un.sun_path)-1, "%s", NOTIFIER_SOCKET_NAME); #else len = offsetof(struct sockaddr_un, sun_path) - + snprintf(sun.sun_path, sizeof(sun.sun_path), "%s/%s", + + snprintf(sa_un.sun_path, sizeof(sa_un.sun_path), "%s/%s", spool_directory, NOTIFIER_SOCKET_NAME); #endif -if (connect(fd, (const struct sockaddr *)&sun, len) < 0) - { where = US"connect"; goto bad; } +if (connect(fd, (const struct sockaddr *)&sa_un, len) < 0) + { where = US"connect"; goto bad2; } 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; } +FD_ZERO(&fds); FD_SET(fd, &fds); +tv.tv_sec = 2; tv.tv_usec = 0; +if (select(fd + 1, (SELECT_ARG2_TYPE *)&fds, NULL, NULL, &tv) != 1) + { + DEBUG(D_expand) debug_printf("no daemon response; using local evaluation\n"); + len = snprintf(CS buf, sizeof(buf), "%u", queue_count_cached()); + } +else if ((len = recv(fd, buf, sizeof(buf), 0)) < 0) + { where = US"recv"; goto bad2; } close(fd); #ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS @@ -1808,6 +1820,10 @@ Uunlink(sname); #endif return string_copyn(buf, len); +bad2: +#ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS + Uunlink(sname); +#endif bad: close(fd); DEBUG(D_expand) debug_printf(" %s: %s\n", where, strerror(errno)); @@ -5277,7 +5293,7 @@ while (*s != 0) { client_conn_ctx cctx; int timeout = 5; - int save_ptr = yield->ptr; + int save_ptr = gstring_length(yield); FILE * fp = NULL; uschar * arg; uschar * sub_arg[4]; @@ -5510,7 +5526,7 @@ while (*s != 0) if (sigalrm_seen) { - yield->ptr = save_ptr; + if (yield) yield->ptr = save_ptr; expand_string_message = US "socket read timed out"; goto SOCK_FAIL; } @@ -5677,7 +5693,7 @@ while (*s != 0) case EITEM_TR: { - int oldptr = yield->ptr; + int oldptr = gstring_length(yield); int o2m; uschar *sub[3]; @@ -6416,7 +6432,7 @@ while (*s != 0) case EITEM_REDUCE: { int sep = 0; - int save_ptr = yield->ptr; + int save_ptr = gstring_length(yield); uschar outsep[2] = { '\0', '\0' }; const uschar *list, *expr, *temp; uschar *save_iterate_item = iterate_item; @@ -6563,7 +6579,8 @@ while (*s != 0) item of the output list, add in a space if the new item begins with the separator character, or is an empty string. */ - if (yield->ptr != save_ptr && (temp[0] == *outsep || temp[0] == 0)) + if ( yield && yield->ptr != save_ptr + && (temp[0] == *outsep || temp[0] == 0)) yield = string_catn(yield, US" ", 1); /* Add the string in "temp" to the output list that we are building, @@ -6603,7 +6620,7 @@ while (*s != 0) the redundant final separator. Even though an empty item at the end of a list does not count, this is tidier. */ - else if (yield->ptr != save_ptr) yield->ptr--; + else if (yield && yield->ptr != save_ptr) yield->ptr--; /* Restore preserved $item */ @@ -7535,7 +7552,7 @@ while (*s != 0) { uschar outsep[2] = { ':', '\0' }; uschar *address, *error; - int save_ptr = yield->ptr; + int save_ptr = gstring_length(yield); int start, end, domain; /* Not really used */ while (isspace(*sub)) sub++; @@ -7566,7 +7583,7 @@ while (*s != 0) if (address) { - if (yield->ptr != save_ptr && address[0] == *outsep) + if (yield && yield->ptr != save_ptr && address[0] == *outsep) yield = string_catn(yield, US" ", 1); for (;;) @@ -7595,7 +7612,7 @@ while (*s != 0) /* If we have generated anything, remove the redundant final separator. */ - if (yield->ptr != save_ptr) yield->ptr--; + if (yield && yield->ptr != save_ptr) yield->ptr--; f.parse_allow_group = FALSE; continue; }