dsn_envid = NULL;
}
+static void *
+fgets_big_buffer(FILE *fp)
+{
+int len = 0;
+
+big_buffer[0] = 0;
+if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) return NULL;
+
+while ((len = Ustrlen(big_buffer)) == big_buffer_size-1
+ && big_buffer[len-1] != '\n')
+ {
+ uschar *newbuffer;
+ int newsize;
+
+ if (big_buffer_size >= BIG_BUFFER_SIZE * 4) return NULL;
+ newsize = big_buffer_size * 2;
+ newbuffer = store_get_perm(newsize, FALSE);
+ memcpy(newbuffer, big_buffer, len);
+
+ big_buffer = newbuffer;
+ big_buffer_size = newsize;
+ if (Ufgets(big_buffer + len, big_buffer_size - len, fp) == NULL) return NULL;
+ }
+
+if (len <= 0 || big_buffer[len-1] != '\n') return NULL;
+return big_buffer;
+}
+
+
/*************************************************
* Read spool header file *
if (sscanf(CS big_buffer, TIME_T_FMT " %d", &received_time.tv_sec, &warning_count) != 2)
goto SPOOL_FORMAT_ERROR;
received_time.tv_usec = 0;
+received_time_complete = received_time;
+
message_age = time(NULL) - received_time.tv_sec;
#ifndef COMPILE_UTILITY
for (;;)
{
- int len;
BOOL tainted;
uschar * var;
const uschar * p;
- if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) goto SPOOL_READ_ERROR;
+ if (fgets_big_buffer(fp) == NULL) goto SPOOL_READ_ERROR;
if (big_buffer[0] != '-') break;
- while ( (len = Ustrlen(big_buffer)) == big_buffer_size-1
- && big_buffer[len-1] != '\n'
- )
- { /* buffer not big enough for line; certs make this possible */
- uschar * buf;
- if (big_buffer_size >= BIG_BUFFER_SIZE*4) goto SPOOL_READ_ERROR;
- buf = store_get_perm(big_buffer_size *= 2, FALSE);
- memcpy(buf, big_buffer, --len);
- big_buffer = buf;
- if (Ufgets(big_buffer+len, big_buffer_size-len, fp) == NULL)
- goto SPOOL_READ_ERROR;
- }
- big_buffer[len-1] = 0;
+ big_buffer[Ustrlen(big_buffer)-1] = 0;
tainted = big_buffer[1] == '-';
var = big_buffer + (tainted ? 2 : 1);
{
unsigned usec;
if (sscanf(CS var + 20, "%u", &usec) == 1)
+ {
received_time.tv_usec = usec;
+ if (!received_time_complete.tv_sec) received_time_complete.tv_usec = usec;
+ }
+ }
+ else if (Ustrncmp(p, "eceived_time_complete", 21) == 0)
+ {
+ unsigned sec, usec;
+ if (sscanf(CS var + 23, "%u.%u", &sec, &usec) == 2)
+ {
+ received_time_complete.tv_sec = sec;
+ received_time_complete.tv_usec = usec;
+ }
}
break;
uschar *errors_to = NULL;
uschar *p;
- if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) goto SPOOL_READ_ERROR;
+ if (fgets_big_buffer(fp) == NULL) goto SPOOL_READ_ERROR;
nn = Ustrlen(big_buffer);
if (nn < 2) goto SPOOL_FORMAT_ERROR;
return inheader? spool_read_hdrerror : spool_read_enverror;
}
+
+#ifndef COMPILE_UTILITY
+/* Read out just the (envelope) sender string from the spool -H file.
+Remove the <> wrap and return it in allocated store. Return NULL on error.
+
+We assume that message_subdir is already set.
+*/
+
+uschar *
+spool_sender_from_msgid(const uschar * id)
+{
+uschar * name = string_sprintf("%s-H", id);
+FILE * fp;
+int n;
+uschar * yield = NULL;
+
+if (!(fp = Ufopen(spool_fname(US"input", message_subdir, name, US""), "rb")))
+ return NULL;
+
+DEBUG(D_deliver) debug_printf_indent("reading spool file %s\n", name);
+
+/* Skip the line with the copy of the filename, then the line with login/uid/gid.
+Read the next line, which should be the envelope sender.
+Do basic validation on that. */
+
+if ( Ufgets(big_buffer, big_buffer_size, fp) != NULL
+ && Ufgets(big_buffer, big_buffer_size, fp) != NULL
+ && Ufgets(big_buffer, big_buffer_size, fp) != NULL
+ && (n = Ustrlen(big_buffer)) >= 3
+ && big_buffer[0] == '<' && big_buffer[n-2] == '>'
+ )
+ {
+ yield = store_get(n-2, TRUE); /* tainted */
+ Ustrncpy(yield, big_buffer+1, n-3);
+ yield[n-3] = 0;
+ }
+fclose(fp);
+return yield;
+}
+#endif /* COMPILE_UTILITY */
+
/* vi: aw ai sw=2
*/
/* End of spool_in.c */