Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 125623 | Differences between
and this patch

Collapse All | Expand All

(-)libsm/fflush.c (+1 lines)
Lines 145-150 Link Here
145
				return SM_IO_EOF;
145
				return SM_IO_EOF;
146
			}
146
			}
147
			SM_IO_WR_TIMEOUT(fp, fd, *timeout);
147
			SM_IO_WR_TIMEOUT(fp, fd, *timeout);
148
			t = 0;
148
		}
149
		}
149
	}
150
	}
150
	return 0;
151
	return 0;
(-)libsm/local.h (-8 / +10 lines)
Lines 156-162 Link Here
156
	else \
156
	else \
157
	{ \
157
	{ \
158
		(time)->tv_sec = (val) / 1000; \
158
		(time)->tv_sec = (val) / 1000; \
159
		(time)->tv_usec = ((val) - ((time)->tv_sec * 1000)) * 10; \
159
		(time)->tv_usec = ((val) - ((time)->tv_sec * 1000)) * 1000; \
160
	} \
160
	} \
161
	if ((val) == SM_TIME_FOREVER) \
161
	if ((val) == SM_TIME_FOREVER) \
162
	{ \
162
	{ \
Lines 240-246 Link Here
240
	else \
240
	else \
241
	{ \
241
	{ \
242
		sm_io_to.tv_sec = (to) / 1000; \
242
		sm_io_to.tv_sec = (to) / 1000; \
243
		sm_io_to.tv_usec = ((to) - (sm_io_to.tv_sec * 1000)) * 10; \
243
		sm_io_to.tv_usec = ((to) - (sm_io_to.tv_sec * 1000)) * 1000; \
244
	} \
244
	} \
245
	if (FD_SETSIZE > 0 && (fd) >= FD_SETSIZE) \
245
	if (FD_SETSIZE > 0 && (fd) >= FD_SETSIZE) \
246
	{ \
246
	{ \
Lines 253-260 Link Here
253
	FD_SET((fd), &sm_io_x_mask); \
253
	FD_SET((fd), &sm_io_x_mask); \
254
	if (gettimeofday(&sm_io_to_before, NULL) < 0) \
254
	if (gettimeofday(&sm_io_to_before, NULL) < 0) \
255
		return SM_IO_EOF; \
255
		return SM_IO_EOF; \
256
	sm_io_to_sel = select((fd) + 1, NULL, &sm_io_to_mask, &sm_io_x_mask, \
256
	do \
257
			      &sm_io_to); \
257
	{	\
258
		sm_io_to_sel = select((fd) + 1, NULL, &sm_io_to_mask, \
259
					&sm_io_x_mask, &sm_io_to); \
260
	} while (sm_io_to_sel < 0 && errno == EINTR); \
258
	if (sm_io_to_sel < 0) \
261
	if (sm_io_to_sel < 0) \
259
	{ \
262
	{ \
260
		/* something went wrong, errno set */ \
263
		/* something went wrong, errno set */ \
Lines 269-278 Link Here
269
	/* else loop again */ \
272
	/* else loop again */ \
270
	if (gettimeofday(&sm_io_to_after, NULL) < 0) \
273
	if (gettimeofday(&sm_io_to_after, NULL) < 0) \
271
		return SM_IO_EOF; \
274
		return SM_IO_EOF; \
272
	timersub(&sm_io_to_before, &sm_io_to_after, &sm_io_to_diff); \
275
	timersub(&sm_io_to_after, &sm_io_to_before, &sm_io_to_diff); \
273
	timersub(&sm_io_to, &sm_io_to_diff, &sm_io_to); \
276
	(to) -= (sm_io_to_diff.tv_sec * 1000); \
274
	(to) -= (sm_io_to.tv_sec * 1000); \
277
	(to) -= (sm_io_to_diff.tv_usec / 1000); \
275
	(to) -= (sm_io_to.tv_usec / 10); \
276
	if ((to) < 0) \
278
	if ((to) < 0) \
277
		(to) = 0; \
279
		(to) = 0; \
278
}
280
}
(-)libsm/refill.c (-3 / +6 lines)
Lines 76-83 Link Here
76
	FD_SET((fd), &sm_io_x_mask);					\
76
	FD_SET((fd), &sm_io_x_mask);					\
77
	if (gettimeofday(&sm_io_to_before, NULL) < 0)			\
77
	if (gettimeofday(&sm_io_to_before, NULL) < 0)			\
78
		return SM_IO_EOF;					\
78
		return SM_IO_EOF;					\
79
	(sel_ret) = select((fd) + 1, &sm_io_to_mask, NULL,		\
79
	do								\
80
			   &sm_io_x_mask, (to));			\
80
	{								\
81
		(sel_ret) = select((fd) + 1, &sm_io_to_mask, NULL,	\
82
			   	&sm_io_x_mask, (to));			\
83
	} while ((sel_ret) < 0 && errno == EINTR);			\
81
	if ((sel_ret) < 0)						\
84
	if ((sel_ret) < 0)						\
82
	{								\
85
	{								\
83
		/* something went wrong, errno set */			\
86
		/* something went wrong, errno set */			\
Lines 94-100 Link Here
94
	/* calulate wall-clock time used */				\
97
	/* calulate wall-clock time used */				\
95
	if (gettimeofday(&sm_io_to_after, NULL) < 0)			\
98
	if (gettimeofday(&sm_io_to_after, NULL) < 0)			\
96
		return SM_IO_EOF;					\
99
		return SM_IO_EOF;					\
97
	timersub(&sm_io_to_before, &sm_io_to_after, &sm_io_to_diff);	\
100
	timersub(&sm_io_to_after, &sm_io_to_before, &sm_io_to_diff);	\
98
	timersub((to), &sm_io_to_diff, (to));				\
101
	timersub((to), &sm_io_to_diff, (to));				\
99
}
102
}
(-)sendmail/collect.c (-88 / +77 lines)
Lines 17-21 Link Here
17
static void	collecttimeout __P((int));
18
static void	eatfrom __P((char *volatile, ENVELOPE *));
17
static void	eatfrom __P((char *volatile, ENVELOPE *));
19
static void	collect_doheader __P((ENVELOPE *));
18
static void	collect_doheader __P((ENVELOPE *));
20
static SM_FILE_T *collect_dfopen __P((ENVELOPE *));
19
static SM_FILE_T *collect_dfopen __P((ENVELOPE *));
Lines 263-272 Link Here
263
**		If data file cannot be created, the process is terminated.
262
**		If data file cannot be created, the process is terminated.
264
*/
263
*/
265
static jmp_buf	CtxCollectTimeout;
266
static bool	volatile CollectProgress;
267
static SM_EVENT	*volatile CollectTimeout = NULL;
268
269
/* values for input state machine */
264
/* values for input state machine */
270
#define IS_NORM		0	/* middle of line */
265
#define IS_NORM		0	/* middle of line */
271
#define IS_BOL		1	/* beginning of line */
266
#define IS_BOL		1	/* beginning of line */
Lines 288-314 Link Here
288
	register ENVELOPE *e;
283
	register ENVELOPE *e;
289
	bool rsetsize;
284
	bool rsetsize;
290
{
285
{
291
	register SM_FILE_T *volatile df;
286
	register SM_FILE_T *df;
292
	volatile bool ignrdot;
287
	bool ignrdot;
293
	volatile int dbto;
288
	int dbto;
294
	register char *volatile bp;
289
	register char *bp;
295
	volatile int c;
290
	int c;
296
	volatile bool inputerr;
291
	bool inputerr;
297
	bool headeronly;
292
	bool headeronly;
298
	char *volatile buf;
293
	char *buf;
299
	volatile int buflen;
294
	int buflen;
300
	volatile int istate;
295
	int istate;
301
	volatile int mstate;
296
	int mstate;
302
	volatile int hdrslen;
297
	int hdrslen;
303
	volatile int numhdrs;
298
	int numhdrs;
304
	volatile int afd;
299
	int afd;
305
	unsigned char *volatile pbp;
300
	unsigned char *pbp;
306
	unsigned char peekbuf[8];
301
	unsigned char peekbuf[8];
307
	char bufbuf[MAXLINE];
302
	char bufbuf[MAXLINE];
308
	df = NULL;
303
	df = NULL;
309
	ignrdot = smtpmode ? false : IgnrDot;
304
	ignrdot = smtpmode ? false : IgnrDot;
310
	dbto = smtpmode ? (int) TimeOuts.to_datablock : 0;
305
306
	/* timeout for I/O functions is in milliseconds */
307
	dbto = smtpmode ? ((int) TimeOuts.to_datablock * 1000)
308
			: SM_TIME_FOREVER;
309
	sm_io_setinfo(fp, SM_IO_WHAT_TIMEOUT, &dbto);
311
	c = SM_IO_EOF;
310
	c = SM_IO_EOF;
312
	inputerr = false;
311
	inputerr = false;
313
	headeronly = hdrp != NULL;
312
	headeronly = hdrp != NULL;
Lines 320-326 Link Here
320
	pbp = peekbuf;
319
	pbp = peekbuf;
321
	istate = IS_BOL;
320
	istate = IS_BOL;
322
	mstate = SaveFrom ? MS_HEADER : MS_UFROM;
321
	mstate = SaveFrom ? MS_HEADER : MS_UFROM;
323
	CollectProgress = false;
324
	/*
322
	/*
325
	**  Tell ARPANET to go ahead.
323
	**  Tell ARPANET to go ahead.
Lines 341-372 Link Here
341
	**	the larger picture (e.g., header versus body).
343
	**	the larger picture (e.g., header versus body).
342
	*/
344
	*/
343
	if (dbto != 0)
344
	{
345
		/* handle possible input timeout */
346
		if (setjmp(CtxCollectTimeout) != 0)
347
		{
348
			if (LogLevel > 2)
349
				sm_syslog(LOG_NOTICE, e->e_id,
350
					  "timeout waiting for input from %s during message collect",
351
					  CURHOSTNAME);
352
			errno = 0;
353
			if (smtpmode)
354
			{
355
				/*
356
				**  Override e_message in usrerr() as this
357
				**  is the reason for failure that should
358
				**  be logged for undelivered recipients.
359
				*/
360
361
				e->e_message = NULL;
362
			}
363
			usrerr("451 4.4.1 timeout waiting for input during message collect");
364
			goto readerr;
365
		}
366
		CollectTimeout = sm_setevent(dbto, collecttimeout, dbto);
367
	}
368
369
	if (rsetsize)
345
	if (rsetsize)
370
		e->e_msgsize = 0;
346
		e->e_msgsize = 0;
371
	for (;;)
347
	for (;;)
Lines 390-398 Link Here
390
						sm_io_clearerr(fp);
366
						sm_io_clearerr(fp);
391
						continue;
367
						continue;
392
					}
368
					}
369
370
					/* timeout? */
371
					if (c == SM_IO_EOF && errno == EAGAIN
372
					    && smtpmode)
373
					{
374
						/*
375
						**  Override e_message in
376
						**  usrerr() as this is the
377
						**  reason for failure that
378
						**  should be logged for
379
						**  undelivered recipients.
380
						*/
381
382
						e->e_message = NULL;
383
						errno = 0;
384
						inputerr = true;
385
						goto readabort;
386
					}
393
					break;
387
					break;
394
				}
388
				}
395
				CollectProgress = true;
396
				if (TrafficLogFile != NULL && !headeronly)
389
				if (TrafficLogFile != NULL && !headeronly)
397
				{
390
				{
398
					if (istate == IS_BOL)
391
					if (istate == IS_BOL)
Lines 538-543 Link Here
538
					buflen *= 2;
533
					buflen *= 2;
539
				else
534
				else
540
					buflen += MEMCHUNKSIZE;
535
					buflen += MEMCHUNKSIZE;
536
				if (buflen <= 0)
537
				{
538
					sm_syslog(LOG_NOTICE, e->e_id,
539
						  "header overflow from %s during message collect",
540
						  CURHOSTNAME);
541
					errno = 0;
542
					e->e_flags |= EF_CLRQUEUE;
543
					e->e_status = "5.6.0";
544
					usrerrenh(e->e_status,
545
						  "552 Headers too large");
546
					goto discard;
547
				}
541
				buf = xalloc(buflen);
548
				buf = xalloc(buflen);
542
				memmove(buf, obuf, bp - obuf);
549
				memmove(buf, obuf, bp - obuf);
543
				bp = &buf[bp - obuf];
550
				bp = &buf[bp - obuf];
Lines 581-586 Link Here
581
					usrerrenh(e->e_status,
588
					usrerrenh(e->e_status,
582
						  "552 Headers too large (%d max)",
589
						  "552 Headers too large (%d max)",
583
						  MaxHeadersLength);
590
						  MaxHeadersLength);
591
  discard:
584
					mstate = MS_DISCARD;
592
					mstate = MS_DISCARD;
585
				}
593
				}
586
			}
594
			}
Lines 620-625 Link Here
620
				sm_io_clearerr(fp);
628
				sm_io_clearerr(fp);
621
				errno = 0;
629
				errno = 0;
622
				c = sm_io_getc(fp, SM_TIME_DEFAULT);
630
				c = sm_io_getc(fp, SM_TIME_DEFAULT);
631
632
				/* timeout? */
633
				if (c == SM_IO_EOF && errno == EAGAIN
634
				    && smtpmode)
635
				{
636
					/*
637
					**  Override e_message in
638
					**  usrerr() as this is the
639
					**  reason for failure that
640
					**  should be logged for
641
					**  undelivered recipients.
642
					*/
643
644
					e->e_message = NULL;
645
					errno = 0;
646
					inputerr = true;
647
					goto readabort;
648
				}
623
			} while (c == SM_IO_EOF && errno == EINTR);
649
			} while (c == SM_IO_EOF && errno == EINTR);
624
			if (c != SM_IO_EOF)
650
			if (c != SM_IO_EOF)
625
				(void) sm_io_ungetc(fp, SM_TIME_DEFAULT, c);
651
				(void) sm_io_ungetc(fp, SM_TIME_DEFAULT, c);
Lines 629-636 Link Here
629
				continue;
655
				continue;
630
			}
656
			}
631
			/* trim off trailing CRLF or NL */
632
			SM_ASSERT(bp > buf);
657
			SM_ASSERT(bp > buf);
658
659
			/* guaranteed by isheader(buf) */
660
			SM_ASSERT(*(bp - 1) != '\n' || bp > buf + 1);
661
662
			/* trim off trailing CRLF or NL */
633
			if (*--bp != '\n' || *--bp != '\r')
663
			if (*--bp != '\n' || *--bp != '\r')
634
				bp++;
664
				bp++;
635
			*bp = '\0';
665
			*bp = '\0';
Lines 696-705 Link Here
696
		inputerr = true;
726
		inputerr = true;
697
	}
727
	}
698
	/* reset global timer */
699
	if (CollectTimeout != NULL)
700
		sm_clrevent(CollectTimeout);
701
702
	if (headeronly)
728
	if (headeronly)
703
		return;
729
		return;
Lines 786-791 Link Here
786
	}
812
	}
787
	/* An EOF when running SMTP is an error */
813
	/* An EOF when running SMTP is an error */
814
  readabort:
788
	if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
815
	if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
789
	{
816
	{
790
		char *host;
817
		char *host;
Lines 808-820 Link Here
808
				problem, host,
835
				problem, host,
809
				shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
836
				shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
810
		if (sm_io_eof(fp))
837
		if (sm_io_eof(fp))
811
			usrerr("451 4.4.1 collect: %s on connection from %s, from=%s",
838
			usrerr("421 4.4.1 collect: %s on connection from %s, from=%s",
812
				problem, host,
839
				problem, host,
813
				shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
840
				shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
814
		else
841
		else
815
			syserr("451 4.4.1 collect: %s on connection from %s, from=%s",
842
			syserr("421 4.4.1 collect: %s on connection from %s, from=%s",
816
				problem, host,
843
				problem, host,
817
				shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
844
				shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
845
		flush_errors(true);
818
		/* don't return an error indication */
846
		/* don't return an error indication */
819
		e->e_to = NULL;
847
		e->e_to = NULL;
Lines 907-945 Link Here
907
	}
935
	}
908
}
936
}
909
static void
910
collecttimeout(timeout)
911
	int timeout;
912
{
913
	int save_errno = errno;
914
915
	/*
916
	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
917
	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
918
	**	DOING.
919
	*/
920
921
	if (CollectProgress)
922
	{
923
		/* reset the timeout */
924
		CollectTimeout = sm_sigsafe_setevent(timeout, collecttimeout,
925
						     timeout);
926
		CollectProgress = false;
927
	}
928
	else
929
	{
930
		/* event is done */
931
		CollectTimeout = NULL;
932
	}
933
934
	/* if no progress was made or problem resetting event, die now */
935
	if (CollectTimeout == NULL)
936
	{
937
		errno = ETIMEDOUT;
938
		longjmp(CtxCollectTimeout, 1);
939
	}
940
	errno = save_errno;
941
}
942
/*
937
/*
943
**  DFERROR -- signal error on writing the data file.
938
**  DFERROR -- signal error on writing the data file.
944
**
939
**
(-)sendmail/conf.c (-11 / +8 lines)
Lines 5330-5337 Link Here
5330
	va_dcl
5362
	va_dcl
5331
#endif /* __STDC__ */
5363
#endif /* __STDC__ */
5332
{
5364
{
5333
	static char *buf = NULL;
5365
	char *buf;
5334
	static size_t bufsize;
5366
	size_t bufsize;
5335
	char *begin, *end;
5367
	char *begin, *end;
5336
	int save_errno;
5368
	int save_errno;
5337
	int seq = 1;
5369
	int seq = 1;
Lines 5355-5365 Link Here
5355
	else
5387
	else
5356
		idlen = strlen(id) + SyslogPrefixLen;
5388
		idlen = strlen(id) + SyslogPrefixLen;
5357
	if (buf == NULL)
5389
	buf = buf0;
5358
	{
5390
	bufsize = sizeof buf0;
5359
		buf = buf0;
5360
		bufsize = sizeof buf0;
5361
	}
5362
	for (;;)
5391
	for (;;)
5363
	{
5392
	{
Lines 5401-5408 Link Here
5401
			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
5430
			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
5402
					     "%s: %s\n", id, newstring);
5431
					     "%s: %s\n", id, newstring);
5403
#endif /* LOG */
5432
#endif /* LOG */
5404
		if (buf == buf0)
5433
		if (buf != buf0)
5405
			buf = NULL;
5434
			sm_free(buf);
5406
		errno = save_errno;
5435
		errno = save_errno;
5407
		return;
5436
		return;
5408
	}
5437
	}
Lines 5466-5473 Link Here
5466
		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
5495
		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
5467
				     "%s[%d]: %s\n", id, seq, begin);
5496
				     "%s[%d]: %s\n", id, seq, begin);
5468
#endif /* LOG */
5497
#endif /* LOG */
5469
	if (buf == buf0)
5498
	if (buf != buf0)
5470
		buf = NULL;
5499
		sm_free(buf);
5471
	errno = save_errno;
5500
	errno = save_errno;
5472
}
5501
}
5473
/*
5502
/*
(-)sendmail/deliver.c (-153 / +85 lines)
Lines 3257-3272 Link Here
3257
	}
3260
	}
3258
	else if (!clever)
3261
	else if (!clever)
3259
	{
3262
	{
3263
		bool ok;
3264
3260
		/*
3265
		/*
3261
		**  Format and send message.
3266
		**  Format and send message.
3262
		*/
3267
		*/
3263
		putfromline(mci, e);
3268
		rcode = EX_OK;
3264
		(*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER);
3269
		errno = 0;
3265
		(*e->e_putbody)(mci, e, NULL);
3270
		ok = putfromline(mci, e);
3271
		if (ok)
3272
			ok = (*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER);
3273
		if (ok)
3274
			ok = (*e->e_putbody)(mci, e, NULL);
3266
		/* get the exit status */
3275
		/*
3276
		**  Ignore an I/O error that was caused by EPIPE.
3277
		**  Some broken mailers don't read the entire body
3278
		**  but just exit() thus causing an I/O error.
3279
		*/
3280
3281
		if (!ok && (sm_io_error(mci->mci_out) && errno == EPIPE))
3282
			ok = true;
3283
3284
		/* (always) get the exit status */
3267
		rcode = endmailer(mci, e, pv);
3285
		rcode = endmailer(mci, e, pv);
3286
		if (!ok)
3287
			rcode = EX_TEMPFAIL;
3268
		if (rcode == EX_TEMPFAIL && SmtpError[0] == '\0')
3288
		if (rcode == EX_TEMPFAIL && SmtpError[0] == '\0')
3269
		{
3289
		{
3270
			/*
3290
			/*
Lines 4430-4442 Link Here
4430
**		e -- the envelope.
4450
**		e -- the envelope.
4431
**
4451
**
4432
**	Returns:
4452
**	Returns:
4433
**		none
4453
**		true iff line was written successfully
4434
**
4454
**
4435
**	Side Effects:
4455
**	Side Effects:
4436
**		outputs some text to fp.
4456
**		outputs some text to fp.
4437
*/
4457
*/
4438
void
4458
bool
4439
putfromline(mci, e)
4459
putfromline(mci, e)
4440
	register MCI *mci;
4460
	register MCI *mci;
4441
	ENVELOPE *e;
4461
	ENVELOPE *e;
Lines 4446-4452 Link Here
4446
	char xbuf[MAXLINE];
4466
	char xbuf[MAXLINE];
4447
	if (bitnset(M_NHDR, mci->mci_mailer->m_flags))
4467
	if (bitnset(M_NHDR, mci->mci_mailer->m_flags))
4448
		return;
4468
		return true;
4449
	mci->mci_flags |= MCIF_INHEADER;
4469
	mci->mci_flags |= MCIF_INHEADER;
Lines 4487-4494 Link Here
4487
		}
4507
		}
4488
	}
4508
	}
4489
	expand(template, buf, sizeof buf, e);
4509
	expand(template, buf, sizeof buf, e);
4490
	putxline(buf, strlen(buf), mci, PXLF_HEADER);
4510
	return putxline(buf, strlen(buf), mci, PXLF_HEADER);
4491
}
4511
}
4512
4492
/*
4513
/*
4493
**  PUTBODY -- put the body of a message.
4514
**  PUTBODY -- put the body of a message.
4494
**
4515
**
Lines 4499-4505 Link Here
4499
**			not be permitted in the resulting message.
4520
**			not be permitted in the resulting message.
4500
**
4521
**
4501
**	Returns:
4522
**	Returns:
4502
**		none.
4523
**		true iff message was written successfully
4503
**
4524
**
4504
**	Side Effects:
4525
**	Side Effects:
4505
**		The message is written onto fp.
4526
**		The message is written onto fp.
Lines 4510-4522 Link Here
4510
#define OSTATE_CR	1	/* read a carriage return */
4531
#define OSTATE_CR	1	/* read a carriage return */
4511
#define OSTATE_INLINE	2	/* putting rest of line */
4532
#define OSTATE_INLINE	2	/* putting rest of line */
4512
void
4533
bool
4513
putbody(mci, e, separator)
4534
putbody(mci, e, separator)
4514
	register MCI *mci;
4535
	register MCI *mci;
4515
	register ENVELOPE *e;
4536
	register ENVELOPE *e;
4516
	char *separator;
4537
	char *separator;
4517
{
4538
{
4518
	bool dead = false;
4539
	bool dead = false;
4540
	bool ioerr = false;
4541
	int save_errno;
4519
	char buf[MAXLINE];
4542
	char buf[MAXLINE];
4520
#if MIME8TO7
4543
#if MIME8TO7
4521
	char *boundaries[MAXMIMENESTING + 1];
4544
	char *boundaries[MAXMIMENESTING + 1];
Lines 4546-4555 Link Here
4546
	{
4569
	{
4547
		if (bitset(MCIF_INHEADER, mci->mci_flags))
4570
		if (bitset(MCIF_INHEADER, mci->mci_flags))
4548
		{
4571
		{
4549
			putline("", mci);
4572
			if (!putline("", mci))
4573
				goto writeerr;
4550
			mci->mci_flags &= ~MCIF_INHEADER;
4574
			mci->mci_flags &= ~MCIF_INHEADER;
4551
		}
4575
		}
4552
		putline("<<< No Message Collected >>>", mci);
4576
		if (!putline("<<< No Message Collected >>>", mci))
4577
			goto writeerr;
4553
		goto endofmessage;
4578
		goto endofmessage;
4554
	}
4579
	}
Lines 4578-4603 Link Here
4578
		*/
4607
		*/
4579
		/* make sure it looks like a MIME message */
4608
		/* make sure it looks like a MIME message */
4580
		if (hvalue("MIME-Version", e->e_header) == NULL)
4609
		if (hvalue("MIME-Version", e->e_header) == NULL &&
4581
			putline("MIME-Version: 1.0", mci);
4610
		    !putline("MIME-Version: 1.0", mci))
4611
			goto writeerr;
4582
		if (hvalue("Content-Type", e->e_header) == NULL)
4612
		if (hvalue("Content-Type", e->e_header) == NULL)
4583
		{
4613
		{
4584
			(void) sm_snprintf(buf, sizeof buf,
4614
			(void) sm_snprintf(buf, sizeof buf,
4585
					   "Content-Type: text/plain; charset=%s",
4615
					   "Content-Type: text/plain; charset=%s",
4586
					   defcharset(e));
4616
					   defcharset(e));
4587
			putline(buf, mci);
4617
			if (!putline(buf, mci))
4618
				goto writeerr;
4588
		}
4619
		}
4589
		/* now do the hard work */
4620
		/* now do the hard work */
4590
		boundaries[0] = NULL;
4621
		boundaries[0] = NULL;
4591
		mci->mci_flags |= MCIF_INHEADER;
4622
		mci->mci_flags |= MCIF_INHEADER;
4592
		(void) mime8to7(mci, e->e_header, e, boundaries, M87F_OUTER);
4623
		if (mime8to7(mci, e->e_header, e, boundaries, M87F_OUTER) ==
4624
								SM_IO_EOF)
4625
			goto writeerr;
4593
	}
4626
	}
4594
# if MIME7TO8
4627
# if MIME7TO8
4595
	else if (bitset(MCIF_CVT7TO8, mci->mci_flags))
4628
	else if (bitset(MCIF_CVT7TO8, mci->mci_flags))
4596
	{
4629
	{
4597
		(void) mime7to8(mci, e->e_header, e);
4630
		if (!mime7to8(mci, e->e_header, e))
4631
			goto writeerr;
4598
	}
4632
	}
4599
# endif /* MIME7TO8 */
4633
# endif /* MIME7TO8 */
4600
	else if (MaxMimeHeaderLength > 0 || MaxMimeFieldLength > 0)
4634
	else if (MaxMimeHeaderLength > 0 || MaxMimeFieldLength > 0)
Lines 4619-4626 Link Here
4619
		if (bitset(EF_DONT_MIME, e->e_flags))
4653
		if (bitset(EF_DONT_MIME, e->e_flags))
4620
			SuprErrs = true;
4654
			SuprErrs = true;
4621
		(void) mime8to7(mci, e->e_header, e, boundaries,
4655
		if (mime8to7(mci, e->e_header, e, boundaries,
4622
				M87F_OUTER|M87F_NO8TO7);
4656
				M87F_OUTER|M87F_NO8TO7) == SM_IO_EOF)
4657
			goto writeerr;
4623
		/* restore SuprErrs */
4658
		/* restore SuprErrs */
4624
		SuprErrs = oldsuprerrs;
4659
		SuprErrs = oldsuprerrs;
Lines 4640-4646 Link Here
4640
		if (bitset(MCIF_INHEADER, mci->mci_flags))
4675
		if (bitset(MCIF_INHEADER, mci->mci_flags))
4641
		{
4676
		{
4642
			putline("", mci);
4677
			if (!putline("", mci))
4678
				goto writeerr;
4643
			mci->mci_flags &= ~MCIF_INHEADER;
4679
			mci->mci_flags &= ~MCIF_INHEADER;
4644
		}
4680
		}
Lines 4731-4741 Link Here
4731
						dead = true;
4767
						dead = true;
4732
						continue;
4768
						continue;
4733
					}
4769
					}
4734
					else
4735
					{
4736
						/* record progress for DATA timeout */
4737
						DataProgress = true;
4738
					}
4739
					pos++;
4770
					pos++;
4740
				}
4771
				}
4741
				for (xp = buf; xp < bp; xp++)
4772
				for (xp = buf; xp < bp; xp++)
Lines 4748-4758 Link Here
4748
						dead = true;
4779
						dead = true;
4749
						break;
4780
						break;
4750
					}
4781
					}
4751
					else
4752
					{
4753
						/* record progress for DATA timeout */
4754
						DataProgress = true;
4755
					}
4756
				}
4782
				}
4757
				if (dead)
4783
				if (dead)
4758
					continue;
4784
					continue;
Lines 4763-4773 Link Here
4763
							mci->mci_mailer->m_eol)
4789
							mci->mci_mailer->m_eol)
4764
							== SM_IO_EOF)
4790
							== SM_IO_EOF)
4765
						break;
4791
						break;
4766
					else
4767
					{
4768
						/* record progress for DATA timeout */
4769
						DataProgress = true;
4770
					}
4771
					pos = 0;
4792
					pos = 0;
4772
				}
4793
				}
4773
				else
4794
				else
Lines 4801-4811 Link Here
4801
							mci->mci_mailer->m_eol)
4822
							mci->mci_mailer->m_eol)
4802
							== SM_IO_EOF)
4823
							== SM_IO_EOF)
4803
						continue;
4824
						continue;
4804
					else
4805
					{
4806
						/* record progress for DATA timeout */
4807
						DataProgress = true;
4808
					}
4809
					if (TrafficLogFile != NULL)
4825
					if (TrafficLogFile != NULL)
4810
					{
4826
					{
Lines 4867-4877 Link Here
4867
							dead = true;
4883
							dead = true;
4868
							continue;
4884
							continue;
4869
						}
4885
						}
4870
						else
4871
						{
4872
							/* record progress for DATA timeout */
4873
							DataProgress = true;
4874
						}
4875
						pos++;
4886
						pos++;
4876
						continue;
4887
						continue;
4877
					}
4888
					}
Lines 4887-4897 Link Here
4887
						dead = true;
4898
						dead = true;
4888
						continue;
4899
						continue;
4889
					}
4900
					}
4890
					else
4891
					{
4892
						/* record progress for DATA timeout */
4893
						DataProgress = true;
4894
					}
4895
					if (TrafficLogFile != NULL)
4901
					if (TrafficLogFile != NULL)
4896
					{
4902
					{
Lines 4917-4927 Link Here
4917
							mci->mci_mailer->m_eol)
4923
							mci->mci_mailer->m_eol)
4918
							== SM_IO_EOF)
4924
							== SM_IO_EOF)
4919
						continue;
4925
						continue;
4920
					else
4921
					{
4922
						/* record progress for DATA timeout */
4923
						DataProgress = true;
4924
					}
4925
					pos = 0;
4926
					pos = 0;
4926
					ostate = OSTATE_HEAD;
4927
					ostate = OSTATE_HEAD;
4927
				}
4928
				}
Lines 4939-4949 Link Here
4939
						dead = true;
4940
						dead = true;
4940
						continue;
4941
						continue;
4941
					}
4942
					}
4942
					else
4943
					{
4944
						/* record progress for DATA timeout */
4945
						DataProgress = true;
4946
					}
4947
					pos++;
4943
					pos++;
4948
					ostate = OSTATE_INLINE;
4944
					ostate = OSTATE_INLINE;
4949
				}
4945
				}
Lines 4970-4980 Link Here
4970
					dead = true;
4966
					dead = true;
4971
					break;
4967
					break;
4972
				}
4968
				}
4973
				else
4974
				{
4975
					/* record progress for DATA timeout */
4976
					DataProgress = true;
4977
				}
4978
			}
4969
			}
4979
			pos += bp - buf;
4970
			pos += bp - buf;
4980
		}
4971
		}
Lines 4984-4994 Link Here
4984
				(void) sm_io_fputs(TrafficLogFile,
4975
				(void) sm_io_fputs(TrafficLogFile,
4985
						   SM_TIME_DEFAULT,
4976
						   SM_TIME_DEFAULT,
4986
						   mci->mci_mailer->m_eol);
4977
						   mci->mci_mailer->m_eol);
4987
			(void) sm_io_fputs(mci->mci_out, SM_TIME_DEFAULT,
4978
			if (sm_io_fputs(mci->mci_out, SM_TIME_DEFAULT,
4988
					   mci->mci_mailer->m_eol);
4979
					   mci->mci_mailer->m_eol) == SM_IO_EOF)
4989
4980
				goto writeerr;
4990
			/* record progress for DATA timeout */
4991
			DataProgress = true;
4992
		}
4981
		}
4993
	}
4982
	}
Lines 4998-5003 Link Here
4998
		       qid_printqueue(e->e_dfqgrp, e->e_dfqdir),
4987
		       qid_printqueue(e->e_dfqgrp, e->e_dfqdir),
4999
		       DATAFL_LETTER, e->e_id);
4988
		       DATAFL_LETTER, e->e_id);
5000
		ExitStat = EX_IOERR;
4989
		ExitStat = EX_IOERR;
4990
		ioerr = true;
5001
	}
4991
	}
5002
endofmessage:
4992
endofmessage:
Lines 5012-5034 Link Here
5012
	**  offset to match.
5002
	**  offset to match.
5013
	*/
5003
	*/
5004
	save_errno = errno;
5014
	if (e->e_dfp != NULL)
5005
	if (e->e_dfp != NULL)
5015
		(void) bfrewind(e->e_dfp);
5006
		(void) bfrewind(e->e_dfp);
5016
	/* some mailers want extra blank line at end of message */
5007
	/* some mailers want extra blank line at end of message */
5017
	if (!dead && bitnset(M_BLANKEND, mci->mci_mailer->m_flags) &&
5008
	if (!dead && bitnset(M_BLANKEND, mci->mci_mailer->m_flags) &&
5018
	    buf[0] != '\0' && buf[0] != '\n')
5009
	    buf[0] != '\0' && buf[0] != '\n')
5019
		putline("", mci);
5010
	{
5011
		if (!putline("", mci))
5012
			goto writeerr;
5013
	}
5020
	(void) sm_io_flush(mci->mci_out, SM_TIME_DEFAULT);
5014
	if (!dead &&
5021
	if (sm_io_error(mci->mci_out) && errno != EPIPE)
5015
	    (sm_io_flush(mci->mci_out, SM_TIME_DEFAULT) == SM_IO_EOF ||
5016
	     (sm_io_error(mci->mci_out) && errno != EPIPE)))
5022
	{
5017
	{
5018
		save_errno = errno;
5023
		syserr("putbody: write error");
5019
		syserr("putbody: write error");
5024
		ExitStat = EX_IOERR;
5020
		ExitStat = EX_IOERR;
5021
		ioerr = true;
5025
	}
5022
	}
5026
	errno = 0;
5023
	errno = save_errno;
5024
	return !dead && !ioerr;
5025
5026
  writeerr:
5027
	return false;
5027
}
5028
}
5029
5028
/*
5030
/*
5029
**  MAILFILE -- Send a message to a file.
5031
**  MAILFILE -- Send a message to a file.
5030
**
5032
**
Lines 5559-5572 Link Here
5559
		}
5561
		}
5560
#endif /* MIME7TO8 */
5562
#endif /* MIME7TO8 */
5561
		putfromline(&mcibuf, e);
5563
		if (!putfromline(&mcibuf, e) ||
5562
		(*e->e_puthdr)(&mcibuf, e->e_header, e, M87F_OUTER);
5564
		    !(*e->e_puthdr)(&mcibuf, e->e_header, e, M87F_OUTER) ||
5563
		(*e->e_putbody)(&mcibuf, e, NULL);
5565
		    !(*e->e_putbody)(&mcibuf, e, NULL) ||
5564
		putline("\n", &mcibuf);
5566
		    !putline("\n", &mcibuf) ||
5565
		if (sm_io_flush(f, SM_TIME_DEFAULT) != 0 ||
5567
		    (sm_io_flush(f, SM_TIME_DEFAULT) != 0 ||
5566
		    (SuperSafe != SAFE_NO &&
5568
		    (SuperSafe != SAFE_NO &&
5567
		     fsync(sm_io_getinfo(f, SM_IO_WHAT_FD, NULL)) < 0) ||
5569
		     fsync(sm_io_getinfo(f, SM_IO_WHAT_FD, NULL)) < 0) ||
5568
		    sm_io_error(f))
5570
		    sm_io_error(f)))
5569
		{
5571
		{
5570
			setstat(EX_IOERR);
5572
			setstat(EX_IOERR);
5571
#if !NOFTRUNCATE
5573
#if !NOFTRUNCATE
Lines 6128-6213 Link Here
6128
ssl_retry:
6134
ssl_retry:
6129
	if ((result = SSL_connect(clt_ssl)) <= 0)
6135
	if ((result = SSL_connect(clt_ssl)) <= 0)
6130
	{
6136
	{
6131
		int i;
6137
		int i, ssl_err;
6132
		bool timedout;
6133
		time_t left;
6134
		time_t now = curtime();
6135
		struct timeval tv;
6136
		/* what to do in this case? */
6138
		ssl_err = SSL_get_error(clt_ssl, result);
6137
		i = SSL_get_error(clt_ssl, result);
6139
		i = tls_retry(clt_ssl, rfd, wfd, tlsstart,
6140
			TimeOuts.to_starttls, ssl_err, "client");
6141
		if (i > 0)
6142
			goto ssl_retry;
6138
		/*
6139
		**  For SSL_ERROR_WANT_{READ,WRITE}:
6140
		**  There is not a complete SSL record available yet
6141
		**  or there is only a partial SSL record removed from
6142
		**  the network (socket) buffer into the SSL buffer.
6143
		**  The SSL_connect will only succeed when a full
6144
		**  SSL record is available (assuming a "real" error
6145
		**  doesn't happen). To handle when a "real" error
6146
		**  does happen the select is set for exceptions too.
6147
		**  The connection may be re-negotiated during this time
6148
		**  so both read and write "want errors" need to be handled.
6149
		**  A select() exception loops back so that a proper SSL
6150
		**  error message can be gotten.
6151
		*/
6152
6153
		left = TimeOuts.to_starttls - (now - tlsstart);
6154
		timedout = left <= 0;
6155
		if (!timedout)
6156
		{
6157
			tv.tv_sec = left;
6158
			tv.tv_usec = 0;
6159
		}
6160
6161
		if (!timedout && FD_SETSIZE > 0 &&
6162
		    (rfd >= FD_SETSIZE ||
6163
		     (i == SSL_ERROR_WANT_WRITE && wfd >= FD_SETSIZE)))
6164
		{
6165
			if (LogLevel > 5)
6166
			{
6167
				sm_syslog(LOG_ERR, e->e_id,
6168
					  "STARTTLS=client, error: fd %d/%d too large",
6169
					  rfd, wfd);
6170
			if (LogLevel > 8)
6171
				tlslogerr("client");
6172
			}
6173
			errno = EINVAL;
6174
			goto tlsfail;
6175
		}
6176
		if (!timedout && i == SSL_ERROR_WANT_READ)
6177
		{
6178
			fd_set ssl_maskr, ssl_maskx;
6179
6180
			FD_ZERO(&ssl_maskr);
6181
			FD_SET(rfd, &ssl_maskr);
6182
			FD_ZERO(&ssl_maskx);
6183
			FD_SET(rfd, &ssl_maskx);
6184
			if (select(rfd + 1, &ssl_maskr, NULL, &ssl_maskx, &tv)
6185
			    > 0)
6186
				goto ssl_retry;
6187
		}
6188
		if (!timedout && i == SSL_ERROR_WANT_WRITE)
6189
		{
6190
			fd_set ssl_maskw, ssl_maskx;
6191
6192
			FD_ZERO(&ssl_maskw);
6193
			FD_SET(wfd, &ssl_maskw);
6194
			FD_ZERO(&ssl_maskx);
6195
			FD_SET(rfd, &ssl_maskx);
6196
			if (select(wfd + 1, NULL, &ssl_maskw, &ssl_maskx, &tv)
6197
			    > 0)
6198
				goto ssl_retry;
6199
		}
6200
		if (LogLevel > 5)
6143
		if (LogLevel > 5)
6201
		{
6144
		{
6202
			sm_syslog(LOG_ERR, e->e_id,
6145
			sm_syslog(LOG_WARNING, NOQID,
6203
				  "STARTTLS=client, error: connect failed=%d, SSL_error=%d, timedout=%d, errno=%d",
6146
				  "STARTTLS=client, error: connect failed=%d, SSL_error=%d, errno=%d, retry=%d",
6204
				  result, i, (int) timedout, errno);
6147
				  result, ssl_err, errno, i);
6205
			if (LogLevel > 8)
6148
			if (LogLevel > 8)
6206
				tlslogerr("client");
6149
				tlslogerr("client");
6207
		}
6150
		}
6208
tlsfail:
6151
6209
		SSL_free(clt_ssl);
6152
		SSL_free(clt_ssl);
6210
		clt_ssl = NULL;
6153
		clt_ssl = NULL;
6211
		return EX_SOFTWARE;
6154
		return EX_SOFTWARE;
(-)sendmail/headers.c (-26 / +39 lines)
Lines 17-24 Link Here
17
static HDR	*allocheader __P((char *, char *, int, SM_RPOOL_T *));
17
static HDR	*allocheader __P((char *, char *, int, SM_RPOOL_T *));
18
static size_t	fix_mime_header __P((HDR *, ENVELOPE *));
18
static size_t	fix_mime_header __P((HDR *, ENVELOPE *));
19
static int	priencode __P((char *));
19
static int	priencode __P((char *));
20
static void	put_vanilla_header __P((HDR *, char *, MCI *));
20
static bool	put_vanilla_header __P((HDR *, char *, MCI *));
21
/*
21
/*
22
**  SETUPHEADERS -- initialize headers in symbol table
22
**  SETUPHEADERS -- initialize headers in symbol table
Lines 993-999 Link Here
993
	char *name;
993
	char *name;
994
	register char *sbp;
994
	register char *sbp;
995
	register char *p;
995
	register char *p;
996
	int l;
997
	char hbuf[MAXNAME + 1];
996
	char hbuf[MAXNAME + 1];
998
	char sbuf[MAXLINE + 1];
997
	char sbuf[MAXLINE + 1];
999
	char mbuf[MAXNAME + 1];
998
	char mbuf[MAXNAME + 1];
Lines 1002-1007 Link Here
1002
	/* XXX do we still need this? sm_syslog() replaces control chars */
1001
	/* XXX do we still need this? sm_syslog() replaces control chars */
1003
	if (msgid != NULL)
1002
	if (msgid != NULL)
1004
	{
1003
	{
1004
		size_t l;
1005
1005
		l = strlen(msgid);
1006
		l = strlen(msgid);
1006
		if (l > sizeof mbuf - 1)
1007
		if (l > sizeof mbuf - 1)
1007
			l = sizeof mbuf - 1;
1008
			l = sizeof mbuf - 1;
Lines 1541-1553 Link Here
1541
**		flags -- MIME conversion flags.
1542
**		flags -- MIME conversion flags.
1542
**
1543
**
1543
**	Returns:
1544
**	Returns:
1544
**		none.
1545
**		success
1545
**
1546
**
1546
**	Side Effects:
1547
**	Side Effects:
1547
**		none.
1548
**		none.
1548
*/
1549
*/
1549
void
1550
bool
1550
putheader(mci, hdr, e, flags)
1551
putheader(mci, hdr, e, flags)
1551
	register MCI *mci;
1552
	register MCI *mci;
1552
	HDR *hdr;
1553
	HDR *hdr;
Lines 1682-1688 Link Here
1682
		{
1683
		{
1683
			if (tTd(34, 11))
1684
			if (tTd(34, 11))
1684
				sm_dprintf("\n");
1685
				sm_dprintf("\n");
1685
			put_vanilla_header(h, p, mci);
1686
			if (!put_vanilla_header(h, p, mci))
1687
				goto writeerr;
1686
			continue;
1688
			continue;
1687
		}
1689
		}
Lines 1741-1747 Link Here
1741
				/* no other recipient headers: truncate value */
1743
				/* no other recipient headers: truncate value */
1742
				(void) sm_strlcpyn(obuf, sizeof obuf, 2,
1744
				(void) sm_strlcpyn(obuf, sizeof obuf, 2,
1743
						   h->h_field, ":");
1745
						   h->h_field, ":");
1744
				putline(obuf, mci);
1746
				if (!putline(obuf, mci))
1747
					goto writeerr;
1745
			}
1748
			}
1746
			continue;
1749
			continue;
1747
		}
1750
		}
Lines 1760-1766 Link Here
1760
		}
1763
		}
1761
		else
1764
		else
1762
		{
1765
		{
1763
			put_vanilla_header(h, p, mci);
1766
			if (!put_vanilla_header(h, p, mci))
1767
				goto writeerr;
1764
		}
1768
		}
1765
	}
1769
	}
Lines 1777-1794 Link Here
1777
	    !bitset(MCIF_CVT8TO7|MCIF_CVT7TO8|MCIF_INMIME, mci->mci_flags) &&
1781
	    !bitset(MCIF_CVT8TO7|MCIF_CVT7TO8|MCIF_INMIME, mci->mci_flags) &&
1778
	    hvalue("MIME-Version", e->e_header) == NULL)
1782
	    hvalue("MIME-Version", e->e_header) == NULL)
1779
	{
1783
	{
1780
		putline("MIME-Version: 1.0", mci);
1784
		if (!putline("MIME-Version: 1.0", mci))
1785
			goto writeerr;
1781
		if (hvalue("Content-Type", e->e_header) == NULL)
1786
		if (hvalue("Content-Type", e->e_header) == NULL)
1782
		{
1787
		{
1783
			(void) sm_snprintf(obuf, sizeof obuf,
1788
			(void) sm_snprintf(obuf, sizeof obuf,
1784
					"Content-Type: text/plain; charset=%s",
1789
					"Content-Type: text/plain; charset=%s",
1785
					defcharset(e));
1790
					defcharset(e));
1786
			putline(obuf, mci);
1791
			if (!putline(obuf, mci))
1792
				goto writeerr;
1787
		}
1793
		}
1788
		if (hvalue("Content-Transfer-Encoding", e->e_header) == NULL)
1794
		if (hvalue("Content-Transfer-Encoding", e->e_header) == NULL
1789
			putline("Content-Transfer-Encoding: 8bit", mci);
1795
		    && !putline("Content-Transfer-Encoding: 8bit", mci))
1796
			goto writeerr;
1790
	}
1797
	}
1791
#endif /* MIME8TO7 */
1798
#endif /* MIME8TO7 */
1799
	return true;
1800
1801
  writeerr:
1802
	return false;
1792
}
1803
}
1793
/*
1804
/*
1794
**  PUT_VANILLA_HEADER -- output a fairly ordinary header
1805
**  PUT_VANILLA_HEADER -- output a fairly ordinary header
Lines 1799-1808 Link Here
1799
**		mci -- the connection info for output
1810
**		mci -- the connection info for output
1800
**
1811
**
1801
**	Returns:
1812
**	Returns:
1802
**		none.
1813
**		success
1803
*/
1814
*/
1804
static void
1815
static bool
1805
put_vanilla_header(h, v, mci)
1816
put_vanilla_header(h, v, mci)
1806
	HDR *h;
1817
	HDR *h;
1807
	char *v;
1818
	char *v;
Lines 1833-1839 Link Here
1833
			l = SPACELEFT(obuf, obp) - 1;
1844
			l = SPACELEFT(obuf, obp) - 1;
1834
		(void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s", l, v);
1845
		(void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s", l, v);
1835
		putxline(obuf, strlen(obuf), mci, putflags);
1846
		if (!putxline(obuf, strlen(obuf), mci, putflags))
1847
			goto writeerr;
1836
		v += l + 1;
1848
		v += l + 1;
1837
		obp = obuf;
1849
		obp = obuf;
1838
		if (*v != ' ' && *v != '\t')
1850
		if (*v != ' ' && *v != '\t')
Lines 1843-1849 Link Here
1843
	/* XXX This is broken for SPACELEFT()==0 */
1855
	/* XXX This is broken for SPACELEFT()==0 */
1844
	(void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s",
1856
	(void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s",
1845
			   (int) (SPACELEFT(obuf, obp) - 1), v);
1857
			   (int) (SPACELEFT(obuf, obp) - 1), v);
1846
	putxline(obuf, strlen(obuf), mci, putflags);
1858
	return putxline(obuf, strlen(obuf), mci, putflags);
1859
1860
  writeerr:
1861
	return false;
1847
}
1862
}
1848
/*
1863
/*
1849
**  COMMAIZE -- output a header field, making a comma-translated list.
1864
**  COMMAIZE -- output a header field, making a comma-translated list.
Lines 1856-1868 Link Here
1856
**		e -- the envelope containing the message.
1871
**		e -- the envelope containing the message.
1857
**
1872
**
1858
**	Returns:
1873
**	Returns:
1859
**		none.
1874
**		success
1860
**
1875
**
1861
**	Side Effects:
1876
**	Side Effects:
1862
**		outputs "p" to file "fp".
1877
**		outputs "p" to file "fp".
1863
*/
1878
*/
1864
void
1879
bool
1865
commaize(h, p, oldstyle, mci, e)
1880
commaize(h, p, oldstyle, mci, e)
1866
	register HDR *h;
1881
	register HDR *h;
1867
	register char *p;
1882
	register char *p;
Lines 2001-2013 Link Here
2001
		}
2016
		}
2002
		name = denlstring(name, false, true);
2017
		name = denlstring(name, false, true);
2003
		/*
2004
		**  record data progress so DNS timeouts
2005
		**  don't cause DATA timeouts
2006
		*/
2007
2008
		DataProgress = true;
2009
2010
		/* output the name with nice formatting */
2018
		/* output the name with nice formatting */
2011
		opos += strlen(name);
2019
		opos += strlen(name);
2012
		if (!firstone)
2020
		if (!firstone)
Lines 2015-2021 Link Here
2015
		if (opos > omax && !firstone)
2023
		if (opos > omax && !firstone)
2016
		{
2024
		{
2017
			(void) sm_strlcpy(obp, ",\n", SPACELEFT(obuf, obp));
2025
			(void) sm_strlcpy(obp, ",\n", SPACELEFT(obuf, obp));
2018
			putxline(obuf, strlen(obuf), mci, putflags);
2026
			if (!putxline(obuf, strlen(obuf), mci, putflags))
2027
				goto writeerr;
2019
			obp = obuf;
2028
			obp = obuf;
2020
			(void) sm_strlcpy(obp, "        ", sizeof obuf);
2029
			(void) sm_strlcpy(obp, "        ", sizeof obuf);
2021
			opos = strlen(obp);
2030
			opos = strlen(obp);
Lines 2037-2044 Link Here
2037
		*obp = '\0';
2046
		*obp = '\0';
2038
	else
2047
	else
2039
		obuf[sizeof obuf - 1] = '\0';
2048
		obuf[sizeof obuf - 1] = '\0';
2040
	putxline(obuf, strlen(obuf), mci, putflags);
2049
	return putxline(obuf, strlen(obuf), mci, putflags);
2050
2051
  writeerr:
2052
	return false;
2041
}
2053
}
2054
2042
/*
2055
/*
2043
**  COPYHEADER -- copy header list
2056
**  COPYHEADER -- copy header list
2044
**
2057
**
(-)sendmail/mime.c (-40 / +82 lines)
Lines 86-91 Link Here
86
**		  MBT_FINAL -- the final boundary
86
**		  MBT_FINAL -- the final boundary
87
**		  MBT_INTERMED -- an intermediate boundary
87
**		  MBT_INTERMED -- an intermediate boundary
88
**		  MBT_NOTSEP -- an end of file
88
**		  MBT_NOTSEP -- an end of file
89
**		  SM_IO_EOF -- I/O error occurred
89
*/
90
*/
90
struct args
91
struct args
Lines 298-304 Link Here
298
		mci->mci_flags |= MCIF_INMIME;
299
		mci->mci_flags |= MCIF_INMIME;
299
		/* skip the early "comment" prologue */
300
		/* skip the early "comment" prologue */
300
		putline("", mci);
301
		if (!putline("", mci))
302
			goto writeerr;
301
		mci->mci_flags &= ~MCIF_INHEADER;
303
		mci->mci_flags &= ~MCIF_INHEADER;
302
		bt = MBT_FINAL;
304
		bt = MBT_FINAL;
303
		while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
305
		while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
Lines 307-314 Link Here
307
			bt = mimeboundary(buf, boundaries);
309
			bt = mimeboundary(buf, boundaries);
308
			if (bt != MBT_NOTSEP)
310
			if (bt != MBT_NOTSEP)
309
				break;
311
				break;
310
			putxline(buf, strlen(buf), mci,
312
			if (!putxline(buf, strlen(buf), mci,
311
				 PXLF_MAPFROM|PXLF_STRIP8BIT);
313
					PXLF_MAPFROM|PXLF_STRIP8BIT))
314
				goto writeerr;
312
			if (tTd(43, 99))
315
			if (tTd(43, 99))
313
				sm_dprintf("  ...%s", buf);
316
				sm_dprintf("  ...%s", buf);
314
		}
317
		}
Lines 319-337 Link Here
319
			auto HDR *hdr = NULL;
322
			auto HDR *hdr = NULL;
320
			(void) sm_strlcpyn(buf, sizeof buf, 2, "--", bbuf);
323
			(void) sm_strlcpyn(buf, sizeof buf, 2, "--", bbuf);
321
			putline(buf, mci);
324
			if (!putline(buf, mci))
325
				goto writeerr;
322
			if (tTd(43, 35))
326
			if (tTd(43, 35))
323
				sm_dprintf("  ...%s\n", buf);
327
				sm_dprintf("  ...%s\n", buf);
324
			collect(e->e_dfp, false, &hdr, e, false);
328
			collect(e->e_dfp, false, &hdr, e, false);
325
			if (tTd(43, 101))
329
			if (tTd(43, 101))
326
				putline("+++after collect", mci);
330
				putline("+++after collect", mci);
327
			putheader(mci, hdr, e, flags);
331
			if (!putheader(mci, hdr, e, flags))
332
				goto writeerr;
328
			if (tTd(43, 101))
333
			if (tTd(43, 101))
329
				putline("+++after putheader", mci);
334
				putline("+++after putheader", mci);
330
			bt = mime8to7(mci, hdr, e, boundaries, flags);
335
			bt = mime8to7(mci, hdr, e, boundaries, flags);
336
			if (bt == SM_IO_EOF)
337
				goto writeerr;
331
		}
338
		}
332
		(void) sm_strlcpyn(buf, sizeof buf, 3, "--", bbuf, "--");
339
		(void) sm_strlcpyn(buf, sizeof buf, 3, "--", bbuf, "--");
333
		putline(buf, mci);
340
		if (!putline(buf, mci))
341
			goto writeerr;
334
		if (tTd(43, 35))
342
		if (tTd(43, 35))
335
			sm_dprintf("  ...%s\n", buf);
343
			sm_dprintf("  ...%s\n", buf);
336
		boundaries[i] = NULL;
344
		boundaries[i] = NULL;
Lines 344-351 Link Here
344
			bt = mimeboundary(buf, boundaries);
352
			bt = mimeboundary(buf, boundaries);
345
			if (bt != MBT_NOTSEP)
353
			if (bt != MBT_NOTSEP)
346
				break;
354
				break;
347
			putxline(buf, strlen(buf), mci,
355
			if (!putxline(buf, strlen(buf), mci,
348
				 PXLF_MAPFROM|PXLF_STRIP8BIT);
356
					PXLF_MAPFROM|PXLF_STRIP8BIT))
357
				goto writeerr;
349
			if (tTd(43, 99))
358
			if (tTd(43, 99))
350
				sm_dprintf("  ...%s", buf);
359
				sm_dprintf("  ...%s", buf);
351
		}
360
		}
Lines 373-390 Link Here
373
		{
382
		{
374
			auto HDR *hdr = NULL;
383
			auto HDR *hdr = NULL;
375
			putline("", mci);
384
			if (!putline("", mci))
385
				goto writeerr;
376
			mci->mci_flags |= MCIF_INMIME;
386
			mci->mci_flags |= MCIF_INMIME;
377
			collect(e->e_dfp, false, &hdr, e, false);
387
			collect(e->e_dfp, false, &hdr, e, false);
378
			if (tTd(43, 101))
388
			if (tTd(43, 101))
379
				putline("+++after collect", mci);
389
				putline("+++after collect", mci);
380
			putheader(mci, hdr, e, flags);
390
			if (!putheader(mci, hdr, e, flags))
391
				goto writeerr;
381
			if (tTd(43, 101))
392
			if (tTd(43, 101))
382
				putline("+++after putheader", mci);
393
				putline("+++after putheader", mci);
383
			if (hvalue("MIME-Version", hdr) == NULL &&
394
			if (hvalue("MIME-Version", hdr) == NULL &&
384
			    !bitset(M87F_NO8TO7, flags))
395
			    !bitset(M87F_NO8TO7, flags) &&
385
				putline("MIME-Version: 1.0", mci);
396
			    !putline("MIME-Version: 1.0", mci))
397
				goto writeerr;
386
			bt = mime8to7(mci, hdr, e, boundaries, flags);
398
			bt = mime8to7(mci, hdr, e, boundaries, flags);
387
			mci->mci_flags &= ~MCIF_INMIME;
399
			mci->mci_flags &= ~MCIF_INMIME;
388
			return bt;
400
			return bt;
Lines 480-490 Link Here
480
			(void) sm_snprintf(buf, sizeof buf,
492
			(void) sm_snprintf(buf, sizeof buf,
481
				"Content-Transfer-Encoding: %.200s", cte);
493
				"Content-Transfer-Encoding: %.200s", cte);
482
			putline(buf, mci);
494
			if (!putline(buf, mci))
495
				goto writeerr;
483
			if (tTd(43, 36))
496
			if (tTd(43, 36))
484
				sm_dprintf("  ...%s\n", buf);
497
				sm_dprintf("  ...%s\n", buf);
485
		}
498
		}
486
		putline("", mci);
499
		if (!putline("", mci))
500
			goto writeerr;
487
		mci->mci_flags &= ~MCIF_INHEADER;
501
		mci->mci_flags &= ~MCIF_INHEADER;
488
		while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
502
		while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
489
			!= NULL)
503
			!= NULL)
Lines 492-498 Link Here
492
			bt = mimeboundary(buf, boundaries);
506
			bt = mimeboundary(buf, boundaries);
493
			if (bt != MBT_NOTSEP)
507
			if (bt != MBT_NOTSEP)
494
				break;
508
				break;
495
			putline(buf, mci);
509
			if (!putline(buf, mci))
510
				goto writeerr;
496
		}
511
		}
497
		if (sm_io_eof(e->e_dfp))
512
		if (sm_io_eof(e->e_dfp))
498
			bt = MBT_FINAL;
513
			bt = MBT_FINAL;
Lines 505-516 Link Here
505
		if (tTd(43, 36))
520
		if (tTd(43, 36))
506
			sm_dprintf("  ...Content-Transfer-Encoding: base64\n");
521
			sm_dprintf("  ...Content-Transfer-Encoding: base64\n");
507
		putline("Content-Transfer-Encoding: base64", mci);
522
		if (!putline("Content-Transfer-Encoding: base64", mci))
523
			goto writeerr;
508
		(void) sm_snprintf(buf, sizeof buf,
524
		(void) sm_snprintf(buf, sizeof buf,
509
			"X-MIME-Autoconverted: from 8bit to base64 by %s id %s",
525
			"X-MIME-Autoconverted: from 8bit to base64 by %s id %s",
510
			MyHostName, e->e_id);
526
			MyHostName, e->e_id);
511
		putline(buf, mci);
527
		if (!putline(buf, mci) || !putline("", mci))
512
		putline("", mci);
528
			goto writeerr;
513
		mci->mci_flags &= ~MCIF_INHEADER;
529
		mci->mci_flags &= ~MCIF_INHEADER;
514
		while ((c1 = mime_getchar_crlf(e->e_dfp, boundaries, &bt)) !=
530
		while ((c1 = mime_getchar_crlf(e->e_dfp, boundaries, &bt)) !=
515
			SM_IO_EOF)
531
			SM_IO_EOF)
Lines 518-524 Link Here
518
			if (linelen > 71)
534
			if (linelen > 71)
519
			{
535
			{
520
				*bp = '\0';
536
				*bp = '\0';
521
				putline(buf, mci);
537
				if (!putline(buf, mci))
538
					goto writeerr;
522
				linelen = 0;
539
				linelen = 0;
523
				bp = buf;
540
				bp = buf;
524
			}
541
			}
Lines 548-554 Link Here
548
			*bp++ = Base64Code[c2 & 0x3f];
565
			*bp++ = Base64Code[c2 & 0x3f];
549
		}
566
		}
550
		*bp = '\0';
567
		*bp = '\0';
551
		putline(buf, mci);
568
		if (!putline(buf, mci))
569
			goto writeerr;
552
	}
570
	}
553
	else
571
	else
554
	{
572
	{
Lines 571-582 Link Here
571
		if (tTd(43, 36))
589
		if (tTd(43, 36))
572
			sm_dprintf("  ...Content-Transfer-Encoding: quoted-printable\n");
590
			sm_dprintf("  ...Content-Transfer-Encoding: quoted-printable\n");
573
		putline("Content-Transfer-Encoding: quoted-printable", mci);
591
		if (!putline("Content-Transfer-Encoding: quoted-printable",
592
				mci))
593
			goto writeerr;
574
		(void) sm_snprintf(buf, sizeof buf,
594
		(void) sm_snprintf(buf, sizeof buf,
575
			"X-MIME-Autoconverted: from 8bit to quoted-printable by %s id %s",
595
			"X-MIME-Autoconverted: from 8bit to quoted-printable by %s id %s",
576
			MyHostName, e->e_id);
596
			MyHostName, e->e_id);
577
		putline(buf, mci);
597
		if (!putline(buf, mci) || !putline("", mci))
578
		putline("", mci);
598
			goto writeerr;
579
		mci->mci_flags &= ~MCIF_INHEADER;
599
		mci->mci_flags &= ~MCIF_INHEADER;
580
		fromstate = 0;
600
		fromstate = 0;
581
		c2 = '\n';
601
		c2 = '\n';
Lines 598-604 Link Here
598
					*bp++ = Base16Code['.' & 0x0f];
618
					*bp++ = Base16Code['.' & 0x0f];
599
				}
619
				}
600
				*bp = '\0';
620
				*bp = '\0';
601
				putline(buf, mci);
621
				if (!putline(buf, mci))
622
					goto writeerr;
602
				linelen = fromstate = 0;
623
				linelen = fromstate = 0;
603
				bp = buf;
624
				bp = buf;
604
				c2 = c1;
625
				c2 = c1;
Lines 627-633 Link Here
627
					c2 = '\n';
648
					c2 = '\n';
628
				*bp++ = '=';
649
				*bp++ = '=';
629
				*bp = '\0';
650
				*bp = '\0';
630
				putline(buf, mci);
651
				if (!putline(buf, mci))
652
					goto writeerr;
631
				linelen = fromstate = 0;
653
				linelen = fromstate = 0;
632
				bp = buf;
654
				bp = buf;
633
				if (c2 == '.')
655
				if (c2 == '.')
Lines 665-677 Link Here
665
		if (linelen > 0 || boundaries[0] != NULL)
687
		if (linelen > 0 || boundaries[0] != NULL)
666
		{
688
		{
667
			*bp = '\0';
689
			*bp = '\0';
668
			putline(buf, mci);
690
			if (!putline(buf, mci))
691
				goto writeerr;
669
		}
692
		}
670
	}
693
	}
671
	if (tTd(43, 3))
694
	if (tTd(43, 3))
672
		sm_dprintf("\t\t\tmime8to7=>%s (basic)\n", MimeBoundaryNames[bt]);
695
		sm_dprintf("\t\t\tmime8to7=>%s (basic)\n", MimeBoundaryNames[bt]);
673
	return bt;
696
	return bt;
697
698
  writeerr:
699
	return SM_IO_EOF;
674
}
700
}
675
/*
701
/*
676
**  MIME_GETCHAR -- get a character for MIME processing
702
**  MIME_GETCHAR -- get a character for MIME processing
Lines 958-964 Link Here
958
**		e -- envelope.
984
**		e -- envelope.
959
**
985
**
960
**	Returns:
986
**	Returns:
961
**		none.
987
**		true iff body was written successfully
962
*/
988
*/
963
static char index_64[128] =
989
static char index_64[128] =
Lines 975-981 Link Here
975
# define CHAR64(c)  (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
1001
# define CHAR64(c)  (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
976
void
1002
bool
977
mime7to8(mci, header, e)
1003
mime7to8(mci, header, e)
978
	register MCI *mci;
1004
	register MCI *mci;
979
	HDR *header;
1005
	HDR *header;
Lines 1008-1032 Link Here
1008
		{
1034
		{
1009
			(void) sm_snprintf(buf, sizeof buf,
1035
			(void) sm_snprintf(buf, sizeof buf,
1010
				"Content-Transfer-Encoding: %s", p);
1036
				"Content-Transfer-Encoding: %s", p);
1011
			putline(buf, mci);
1037
			if (!putline(buf, mci))
1038
				goto writeerr;
1012
		}
1039
		}
1013
		putline("", mci);
1040
		if (!putline("", mci))
1041
			goto writeerr;
1014
		mci->mci_flags &= ~MCIF_INHEADER;
1042
		mci->mci_flags &= ~MCIF_INHEADER;
1015
		while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
1043
		while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
1016
			!= NULL)
1044
			!= NULL)
1017
			putline(buf, mci);
1045
		{
1018
		return;
1046
			if (!putline(buf, mci))
1047
				goto writeerr;
1048
		}
1049
		return true;
1019
	}
1050
	}
1020
	cataddr(pvp, NULL, buf, sizeof buf, '\0');
1051
	cataddr(pvp, NULL, buf, sizeof buf, '\0');
1021
	cte = sm_rpool_strdup_x(e->e_rpool, buf);
1052
	cte = sm_rpool_strdup_x(e->e_rpool, buf);
1022
	mci->mci_flags |= MCIF_INHEADER;
1053
	mci->mci_flags |= MCIF_INHEADER;
1023
	putline("Content-Transfer-Encoding: 8bit", mci);
1054
	if (!putline("Content-Transfer-Encoding: 8bit", mci))
1055
		goto writeerr;
1024
	(void) sm_snprintf(buf, sizeof buf,
1056
	(void) sm_snprintf(buf, sizeof buf,
1025
		"X-MIME-Autoconverted: from %.200s to 8bit by %s id %s",
1057
		"X-MIME-Autoconverted: from %.200s to 8bit by %s id %s",
1026
		cte, MyHostName, e->e_id);
1058
		cte, MyHostName, e->e_id);
1027
	putline(buf, mci);
1059
	if (!putline(buf, mci) || !putline("", mci))
1028
	putline("", mci);
1060
		goto writeerr;
1029
	mci->mci_flags &= ~MCIF_INHEADER;
1061
	mci->mci_flags &= ~MCIF_INHEADER;
1030
	/*
1062
	/*
Lines 1090-1096 Link Here
1090
		if (*fbufp++ == '\n' || fbufp >= &fbuf[MAXLINE])	\
1122
		if (*fbufp++ == '\n' || fbufp >= &fbuf[MAXLINE])	\
1091
		{							\
1123
		{							\
1092
			CHK_EOL;					\
1124
			CHK_EOL;					\
1093
			putxline((char *) fbuf, fbufp - fbuf, mci, pxflags); \
1125
			if (!putxline((char *) fbuf, fbufp - fbuf, mci, pxflags)) \
1126
				goto writeerr;				\
1094
			pxflags &= ~PXLF_NOADDEOL;			\
1127
			pxflags &= ~PXLF_NOADDEOL;			\
1095
			fbufp = fbuf;					\
1128
			fbufp = fbuf;					\
1096
		}	\
1129
		}	\
Lines 1127-1134 Link Here
1127
				continue;
1160
				continue;
1128
			if (fbufp - fbuf > 0)
1161
			if (fbufp - fbuf > 0)
1129
				putxline((char *) fbuf, fbufp - fbuf - 1, mci,
1162
			{
1130
					 pxflags);
1163
				if (!putxline((char *) fbuf, fbufp - fbuf - 1,
1164
						mci, pxflags))
1165
					goto writeerr;
1166
			}
1131
			fbufp = fbuf;
1167
			fbufp = fbuf;
1132
			if (off >= 0 && buf[off] != '\0')
1168
			if (off >= 0 && buf[off] != '\0')
1133
			{
1169
			{
Lines 1144-1150 Link Here
1144
	if (fbufp > fbuf)
1180
	if (fbufp > fbuf)
1145
	{
1181
	{
1146
		*fbufp = '\0';
1182
		*fbufp = '\0';
1147
		putxline((char *) fbuf, fbufp - fbuf, mci, pxflags);
1183
		if (!putxline((char *) fbuf, fbufp - fbuf, mci, pxflags))
1184
			goto writeerr;
1148
	}
1185
	}
1149
	/*
1186
	/*
Lines 1154-1163 Link Here
1154
	**  but so is auto-converting MIME in the first place.
1191
	**  but so is auto-converting MIME in the first place.
1155
	*/
1192
	*/
1156
	putline("", mci);
1193
	if (!putline("", mci))
1194
		goto writeerr;
1157
	if (tTd(43, 3))
1195
	if (tTd(43, 3))
1158
		sm_dprintf("\t\t\tmime7to8 => %s to 8bit done\n", cte);
1196
		sm_dprintf("\t\t\tmime7to8 => %s to 8bit done\n", cte);
1197
	return true;
1198
1199
  writeerr:
1200
	return false;
1159
}
1201
}
1160
/*
1202
/*
1161
**  The following is based on Borenstein's "codes.c" module, with simplifying
1203
**  The following is based on Borenstein's "codes.c" module, with simplifying
(-)sendmail/parseaddr.c (-6 / +6 lines)
Lines 1337-1343 Link Here
1337
					/* $&{x} replacement */
1337
					/* $&{x} replacement */
1338
					char *mval = macvalue(rp[1], e);
1338
					char *mval = macvalue(rp[1], e);
1339
					char **xpvp;
1339
					char **xpvp;
1340
					int trsize = 0;
1340
					size_t trsize = 0;
1341
					static size_t pvpb1_size = 0;
1341
					static size_t pvpb1_size = 0;
1342
					static char **pvpb1 = NULL;
1342
					static char **pvpb1 = NULL;
1343
					char pvpbuf[PSBUFSIZE];
1343
					char pvpbuf[PSBUFSIZE];
Lines 1352-1358 Link Here
1352
					/* save the remainder of the input */
1352
					/* save the remainder of the input */
1353
					for (xpvp = pvp; *xpvp != NULL; xpvp++)
1353
					for (xpvp = pvp; *xpvp != NULL; xpvp++)
1354
						trsize += sizeof *xpvp;
1354
						trsize += sizeof *xpvp;
1355
					if ((size_t) trsize > pvpb1_size)
1355
					if (trsize > pvpb1_size)
1356
					{
1356
					{
1357
						if (pvpb1 != NULL)
1357
						if (pvpb1 != NULL)
1358
							sm_free(pvpb1);
1358
							sm_free(pvpb1);
Lines 1407-1413 Link Here
1407
		{
1407
		{
1408
			char **hbrvp;
1408
			char **hbrvp;
1409
			char **xpvp;
1409
			char **xpvp;
1410
			int trsize;
1410
			size_t trsize;
1411
			char *replac;
1411
			char *replac;
1412
			int endtoken;
1412
			int endtoken;
1413
			STAB *map;
1413
			STAB *map;
Lines 1509-1515 Link Here
1509
				*++arg_rvp = NULL;
1509
				*++arg_rvp = NULL;
1510
			/* save the remainder of the input string */
1510
			/* save the remainder of the input string */
1511
			trsize = (int) (avp - rvp + 1) * sizeof *rvp;
1511
			trsize = (avp - rvp + 1) * sizeof *rvp;
1512
			memmove((char *) pvpb1, (char *) rvp, trsize);
1512
			memmove((char *) pvpb1, (char *) rvp, trsize);
1513
			/* look it up */
1513
			/* look it up */
Lines 2949-2955 Link Here
2949
	char *logid;
2949
	char *logid;
2950
{
2950
{
2951
	char *volatile buf;
2951
	char *volatile buf;
2952
	int bufsize;
2952
	size_t bufsize;
2953
	int saveexitstat;
2953
	int saveexitstat;
2954
	int volatile rstat = EX_OK;
2954
	int volatile rstat = EX_OK;
2955
	char **pvp;
2955
	char **pvp;
Lines 3163-3169 Link Here
3163
	int size;
3163
	int size;
3164
{
3164
{
3165
	char *volatile buf;
3165
	char *volatile buf;
3166
	int bufsize;
3166
	size_t bufsize;
3167
	int volatile rstat = EX_OK;
3167
	int volatile rstat = EX_OK;
3168
	int rsno;
3168
	int rsno;
3169
	bool saveQuickAbort = QuickAbort;
3169
	bool saveQuickAbort = QuickAbort;
(-)sendmail/savemail.c (-95 / +160 lines)
Lines 17-21 Link Here
17
static void	errbody __P((MCI *, ENVELOPE *, char *));
17
static bool	errbody __P((MCI *, ENVELOPE *, char *));
18
static bool	pruneroute __P((char *));
18
static bool	pruneroute __P((char *));
19
/*
19
/*
Lines 432-443 Link Here
432
			p = macvalue('g', e);
432
			p = macvalue('g', e);
433
			macdefine(&e->e_macro, A_PERM, 'g', e->e_sender);
433
			macdefine(&e->e_macro, A_PERM, 'g', e->e_sender);
434
			putfromline(&mcibuf, e);
434
			if (!putfromline(&mcibuf, e) ||
435
			(*e->e_puthdr)(&mcibuf, e->e_header, e, M87F_OUTER);
435
			    !(*e->e_puthdr)(&mcibuf, e->e_header, e,
436
			(*e->e_putbody)(&mcibuf, e, NULL);
436
					M87F_OUTER) ||
437
			putline("\n", &mcibuf); /* XXX EOL from FileMailer? */
437
			    !(*e->e_putbody)(&mcibuf, e, NULL) ||
438
			(void) sm_io_flush(fp, SM_TIME_DEFAULT);
438
			    !putline("\n", &mcibuf) ||
439
			if (sm_io_error(fp) ||
439
			    sm_io_flush(fp, SM_TIME_DEFAULT) == SM_IO_EOF ||
440
			    sm_io_error(fp) ||
440
			    sm_io_close(fp, SM_TIME_DEFAULT) < 0)
441
			    sm_io_close(fp, SM_TIME_DEFAULT) < 0)
441
				state = ESM_PANIC;
442
				state = ESM_PANIC;
442
			else
443
			else
Lines 732-745 Link Here
732
**		separator -- any possible MIME separator (unused).
733
**		separator -- any possible MIME separator (unused).
733
**
734
**
734
**	Returns:
735
**	Returns:
735
**		none
736
**		success
736
**
737
**
737
**	Side Effects:
738
**	Side Effects:
738
**		Outputs the body of an error message.
739
**		Outputs the body of an error message.
739
*/
740
*/
740
/* ARGSUSED2 */
741
/* ARGSUSED2 */
741
static void
742
static bool
742
errbody(mci, e, separator)
743
errbody(mci, e, separator)
743
	register MCI *mci;
744
	register MCI *mci;
744
	register ENVELOPE *e;
745
	register ENVELOPE *e;
Lines 757-770 Link Here
757
	if (bitset(MCIF_INHEADER, mci->mci_flags))
758
	if (bitset(MCIF_INHEADER, mci->mci_flags))
758
	{
759
	{
759
		putline("", mci);
760
		if (!putline("", mci))
761
			goto writeerr;
760
		mci->mci_flags &= ~MCIF_INHEADER;
762
		mci->mci_flags &= ~MCIF_INHEADER;
761
	}
763
	}
762
	if (e->e_parent == NULL)
764
	if (e->e_parent == NULL)
763
	{
765
	{
764
		syserr("errbody: null parent");
766
		syserr("errbody: null parent");
765
		putline("   ----- Original message lost -----\n", mci);
767
		if (!putline("   ----- Original message lost -----\n", mci))
766
		return;
768
			goto writeerr;
769
		return true;
767
	}
770
	}
768
	/*
771
	/*
Lines 773-783 Link Here
773
	if (e->e_msgboundary != NULL)
776
	if (e->e_msgboundary != NULL)
774
	{
777
	{
775
		putline("This is a MIME-encapsulated message", mci);
776
		putline("", mci);
777
		(void) sm_strlcpyn(buf, sizeof buf, 2, "--", e->e_msgboundary);
778
		(void) sm_strlcpyn(buf, sizeof buf, 2, "--", e->e_msgboundary);
778
		putline(buf, mci);
779
		if (!putline("This is a MIME-encapsulated message", mci) ||
779
		putline("", mci);
780
		    !putline("", mci) ||
781
		    !putline(buf, mci) ||
782
		    !putline("", mci))
783
			goto writeerr;
780
	}
784
	}
781
	/*
785
	/*
Lines 799-829 Link Here
799
	if (!pm_notify && q == NULL &&
803
	if (!pm_notify && q == NULL &&
800
	    !bitset(EF_FATALERRS|EF_SENDRECEIPT, e->e_parent->e_flags))
804
	    !bitset(EF_FATALERRS|EF_SENDRECEIPT, e->e_parent->e_flags))
801
	{
805
	{
802
		putline("    **********************************************",
806
		if (!putline("    **********************************************",
803
			mci);
807
			mci) ||
804
		putline("    **      THIS IS A WARNING MESSAGE ONLY      **",
808
		    !putline("    **      THIS IS A WARNING MESSAGE ONLY      **",
805
			mci);
809
			mci) ||
806
		putline("    **  YOU DO NOT NEED TO RESEND YOUR MESSAGE  **",
810
		    !putline("    **  YOU DO NOT NEED TO RESEND YOUR MESSAGE  **",
807
			mci);
811
			mci) ||
808
		putline("    **********************************************",
812
		    !putline("    **********************************************",
809
			mci);
813
			mci) ||
810
		putline("", mci);
814
		    !putline("", mci))
815
			goto writeerr;
811
	}
816
	}
812
	(void) sm_snprintf(buf, sizeof buf,
817
	(void) sm_snprintf(buf, sizeof buf,
813
		"The original message was received at %s",
818
		"The original message was received at %s",
814
		arpadate(ctime(&e->e_parent->e_ctime)));
819
		arpadate(ctime(&e->e_parent->e_ctime)));
815
	putline(buf, mci);
820
	if (!putline(buf, mci))
821
		goto writeerr;
816
	expand("from \201_", buf, sizeof buf, e->e_parent);
822
	expand("from \201_", buf, sizeof buf, e->e_parent);
817
	putline(buf, mci);
823
	if (!putline(buf, mci))
824
		goto writeerr;
818
	/* include id in postmaster copies */
825
	/* include id in postmaster copies */
819
	if (pm_notify && e->e_parent->e_id != NULL)
826
	if (pm_notify && e->e_parent->e_id != NULL)
820
	{
827
	{
821
		(void) sm_strlcpyn(buf, sizeof buf, 2, "with id ",
828
		(void) sm_strlcpyn(buf, sizeof buf, 2, "with id ",
822
			e->e_parent->e_id);
829
			e->e_parent->e_id);
823
		putline(buf, mci);
830
		if (!putline(buf, mci))
831
			goto writeerr;
824
	}
832
	}
825
	putline("", mci);
833
	if (!putline("", mci))
834
		goto writeerr;
826
	/*
835
	/*
827
	**  Output error message header (if specified and available).
836
	**  Output error message header (if specified and available).
Lines 849-865 Link Here
849
				{
858
				{
850
					translate_dollars(buf);
859
					translate_dollars(buf);
851
					expand(buf, buf, sizeof buf, e);
860
					expand(buf, buf, sizeof buf, e);
852
					putline(buf, mci);
861
					if (!putline(buf, mci))
862
						goto writeerr;
853
				}
863
				}
854
				(void) sm_io_close(xfile, SM_TIME_DEFAULT);
864
				(void) sm_io_close(xfile, SM_TIME_DEFAULT);
855
				putline("\n", mci);
865
				if (!putline("\n", mci))
866
					goto writeerr;
856
			}
867
			}
857
		}
868
		}
858
		else
869
		else
859
		{
870
		{
860
			expand(ErrMsgFile, buf, sizeof buf, e);
871
			expand(ErrMsgFile, buf, sizeof buf, e);
861
			putline(buf, mci);
872
			if (!putline(buf, mci) || !putline("", mci))
862
			putline("", mci);
873
				goto writeerr;
863
		}
874
		}
864
	}
875
	}
Lines 877-897 Link Here
877
		if (printheader)
888
		if (printheader)
878
		{
889
		{
879
			putline("   ----- The following addresses had permanent fatal errors -----",
890
			if (!putline("   ----- The following addresses had permanent fatal errors -----",
880
				mci);
891
					mci))
892
				goto writeerr;
881
			printheader = false;
893
			printheader = false;
882
		}
894
		}
883
		(void) sm_strlcpy(buf, shortenstring(q->q_paddr, MAXSHORTSTR),
895
		(void) sm_strlcpy(buf, shortenstring(q->q_paddr, MAXSHORTSTR),
884
				  sizeof buf);
896
				  sizeof buf);
885
		putline(buf, mci);
897
		if (!putline(buf, mci))
898
			goto writeerr;
886
		if (q->q_rstatus != NULL)
899
		if (q->q_rstatus != NULL)
887
		{
900
		{
888
			(void) sm_snprintf(buf, sizeof buf,
901
			(void) sm_snprintf(buf, sizeof buf,
889
				"    (reason: %s)",
902
				"    (reason: %s)",
890
				shortenstring(exitstat(q->q_rstatus),
903
				shortenstring(exitstat(q->q_rstatus),
891
					      MAXSHORTSTR));
904
					      MAXSHORTSTR));
892
			putline(buf, mci);
905
			if (!putline(buf, mci))
906
				goto writeerr;
893
		}
907
		}
894
		if (q->q_alias != NULL)
908
		if (q->q_alias != NULL)
895
		{
909
		{
Lines 899-909 Link Here
899
				"    (expanded from: %s)",
913
				"    (expanded from: %s)",
900
				shortenstring(q->q_alias->q_paddr,
914
				shortenstring(q->q_alias->q_paddr,
901
					      MAXSHORTSTR));
915
					      MAXSHORTSTR));
902
			putline(buf, mci);
916
			if (!putline(buf, mci))
917
				goto writeerr;
903
		}
918
		}
904
	}
919
	}
905
	if (!printheader)
920
	if (!printheader && !putline("", mci))
906
		putline("", mci);
921
		goto writeerr;
907
	/* transient non-fatal errors */
922
	/* transient non-fatal errors */
908
	printheader = true;
923
	printheader = true;
Lines 917-941 Link Here
917
		if (printheader)
932
		if (printheader)
918
		{
933
		{
919
			putline("   ----- The following addresses had transient non-fatal errors -----",
934
			if (!putline("   ----- The following addresses had transient non-fatal errors -----",
920
				mci);
935
					mci))
936
				goto writeerr;
921
			printheader = false;
937
			printheader = false;
922
		}
938
		}
923
		(void) sm_strlcpy(buf, shortenstring(q->q_paddr, MAXSHORTSTR),
939
		(void) sm_strlcpy(buf, shortenstring(q->q_paddr, MAXSHORTSTR),
924
				  sizeof buf);
940
				  sizeof buf);
925
		putline(buf, mci);
941
		if (!putline(buf, mci))
942
			goto writeerr;
926
		if (q->q_alias != NULL)
943
		if (q->q_alias != NULL)
927
		{
944
		{
928
			(void) sm_snprintf(buf, sizeof buf,
945
			(void) sm_snprintf(buf, sizeof buf,
929
				"    (expanded from: %s)",
946
				"    (expanded from: %s)",
930
				shortenstring(q->q_alias->q_paddr,
947
				shortenstring(q->q_alias->q_paddr,
931
					      MAXSHORTSTR));
948
					      MAXSHORTSTR));
932
			putline(buf, mci);
949
			if (!putline(buf, mci))
950
				goto writeerr;
933
		}
951
		}
934
	}
952
	}
935
	if (!printheader)
953
	if (!printheader && !putline("", mci))
936
		putline("", mci);
954
		goto writeerr;
937
	/* successful delivery notifications */
955
	/* successful delivery notifications */
938
	printheader = true;
956
	printheader = true;
Lines 968-992 Link Here
968
		if (printheader)
986
		if (printheader)
969
		{
987
		{
970
			putline("   ----- The following addresses had successful delivery notifications -----",
988
			if (!putline("   ----- The following addresses had successful delivery notifications -----",
971
				mci);
989
					mci))
990
				goto writeerr;
972
			printheader = false;
991
			printheader = false;
973
		}
992
		}
974
		(void) sm_snprintf(buf, sizeof buf, "%s  (%s)",
993
		(void) sm_snprintf(buf, sizeof buf, "%s  (%s)",
975
			 shortenstring(q->q_paddr, MAXSHORTSTR), p);
994
			 shortenstring(q->q_paddr, MAXSHORTSTR), p);
976
		putline(buf, mci);
995
		if (!putline(buf, mci))
996
			goto writeerr;
977
		if (q->q_alias != NULL)
997
		if (q->q_alias != NULL)
978
		{
998
		{
979
			(void) sm_snprintf(buf, sizeof buf,
999
			(void) sm_snprintf(buf, sizeof buf,
980
				"    (expanded from: %s)",
1000
				"    (expanded from: %s)",
981
				shortenstring(q->q_alias->q_paddr,
1001
				shortenstring(q->q_alias->q_paddr,
982
					      MAXSHORTSTR));
1002
					      MAXSHORTSTR));
983
			putline(buf, mci);
1003
			if (!putline(buf, mci))
1004
				goto writeerr;
984
		}
1005
		}
985
	}
1006
	}
986
	if (!printheader)
1007
	if (!printheader && !putline("", mci))
987
		putline("", mci);
1008
		goto writeerr;
988
	/*
1009
	/*
989
	**  Output transcript of errors
1010
	**  Output transcript of errors
Lines 995-1002 Link Here
995
	(void) sm_io_flush(smioout, SM_TIME_DEFAULT);
1016
	(void) sm_io_flush(smioout, SM_TIME_DEFAULT);
996
	if (e->e_parent->e_xfp == NULL)
1017
	if (e->e_parent->e_xfp == NULL)
997
	{
1018
	{
998
		putline("   ----- Transcript of session is unavailable -----\n",
1019
		if (!putline("   ----- Transcript of session is unavailable -----\n",
999
			mci);
1020
				mci))
1021
			goto writeerr;
1000
	}
1022
	}
1001
	else
1023
	else
1002
	{
1024
	{
Lines 1007-1017 Link Here
1007
		while (sm_io_fgets(e->e_parent->e_xfp, SM_TIME_DEFAULT, buf,
1029
		while (sm_io_fgets(e->e_parent->e_xfp, SM_TIME_DEFAULT, buf,
1008
				   sizeof buf) != NULL)
1030
				   sizeof buf) != NULL)
1009
		{
1031
		{
1010
			if (printheader)
1032
			if (printheader && !putline("   ----- Transcript of session follows -----\n",
1011
				putline("   ----- Transcript of session follows -----\n",
1033
						mci))
1012
					mci);
1034
				goto writeerr;
1013
			printheader = false;
1035
			printheader = false;
1014
			putline(buf, mci);
1036
			if (!putline(buf, mci))
1037
				goto writeerr;
1015
		}
1038
		}
1016
	}
1039
	}
1017
	errno = 0;
1040
	errno = 0;
Lines 1023-1033 Link Here
1023
	if (e->e_msgboundary != NULL)
1046
	if (e->e_msgboundary != NULL)
1024
	{
1047
	{
1025
		putline("", mci);
1026
		(void) sm_strlcpyn(buf, sizeof buf, 2, "--", e->e_msgboundary);
1048
		(void) sm_strlcpyn(buf, sizeof buf, 2, "--", e->e_msgboundary);
1027
		putline(buf, mci);
1049
		if (!putline("", mci) ||
1028
		putline("Content-Type: message/delivery-status", mci);
1050
		    !putline(buf, mci) ||
1029
		putline("", mci);
1051
		    !putline("Content-Type: message/delivery-status", mci) ||
1052
		    !putline("", mci))
1053
			goto writeerr;
1030
		/*
1054
		/*
1031
		**  Output per-message information.
1055
		**  Output per-message information.
Lines 1039-1051 Link Here
1039
			(void) sm_snprintf(buf, sizeof buf,
1063
			(void) sm_snprintf(buf, sizeof buf,
1040
					"Original-Envelope-Id: %.800s",
1064
					"Original-Envelope-Id: %.800s",
1041
					xuntextify(e->e_parent->e_envid));
1065
					xuntextify(e->e_parent->e_envid));
1042
			putline(buf, mci);
1066
			if (!putline(buf, mci))
1067
				goto writeerr;
1043
		}
1068
		}
1044
		/* Reporting-MTA: is us (required) */
1069
		/* Reporting-MTA: is us (required) */
1045
		(void) sm_snprintf(buf, sizeof buf,
1070
		(void) sm_snprintf(buf, sizeof buf,
1046
				   "Reporting-MTA: dns; %.800s", MyHostName);
1071
				   "Reporting-MTA: dns; %.800s", MyHostName);
1047
		putline(buf, mci);
1072
		if (!putline(buf, mci))
1073
			goto writeerr;
1048
		/* DSN-Gateway: not relevant since we are not translating */
1074
		/* DSN-Gateway: not relevant since we are not translating */
Lines 1059-1071 Link Here
1059
			(void) sm_snprintf(buf, sizeof buf,
1085
			(void) sm_snprintf(buf, sizeof buf,
1060
					"Received-From-MTA: %s; %.800s",
1086
					"Received-From-MTA: %s; %.800s",
1061
					p, RealHostName);
1087
					p, RealHostName);
1062
			putline(buf, mci);
1088
			if (!putline(buf, mci))
1089
				goto writeerr;
1063
		}
1090
		}
1064
		/* Arrival-Date: -- when it arrived here */
1091
		/* Arrival-Date: -- when it arrived here */
1065
		(void) sm_strlcpyn(buf, sizeof buf, 2, "Arrival-Date: ",
1092
		(void) sm_strlcpyn(buf, sizeof buf, 2, "Arrival-Date: ",
1066
				arpadate(ctime(&e->e_parent->e_ctime)));
1093
				arpadate(ctime(&e->e_parent->e_ctime)));
1067
		putline(buf, mci);
1094
		if (!putline(buf, mci))
1095
			goto writeerr;
1068
		/* Deliver-By-Date: -- when it should have been delivered */
1096
		/* Deliver-By-Date: -- when it should have been delivered */
1069
		if (IS_DLVR_BY(e->e_parent))
1097
		if (IS_DLVR_BY(e->e_parent))
Lines 1076-1082 Link Here
1076
			(void) sm_strlcpyn(buf, sizeof buf, 2,
1104
			(void) sm_strlcpyn(buf, sizeof buf, 2,
1077
					"Deliver-By-Date: ",
1105
					"Deliver-By-Date: ",
1078
					arpadate(ctime(&dbyd)));
1106
					arpadate(ctime(&dbyd)));
1079
			putline(buf, mci);
1107
			if (!putline(buf, mci))
1108
				goto writeerr;
1080
		}
1109
		}
1081
		/*
1110
		/*
Lines 1119-1125 Link Here
1119
			else
1148
			else
1120
				continue;
1149
				continue;
1121
			putline("", mci);
1150
			if (!putline("", mci))
1151
				goto writeerr;
1122
			/* Original-Recipient: -- passed from on high */
1152
			/* Original-Recipient: -- passed from on high */
1123
			if (q->q_orcpt != NULL)
1153
			if (q->q_orcpt != NULL)
Lines 1127-1133 Link Here
1127
				(void) sm_snprintf(buf, sizeof buf,
1157
				(void) sm_snprintf(buf, sizeof buf,
1128
						"Original-Recipient: %.800s",
1158
						"Original-Recipient: %.800s",
1129
						q->q_orcpt);
1159
						q->q_orcpt);
1130
				putline(buf, mci);
1160
				if (!putline(buf, mci))
1161
					goto writeerr;
1131
			}
1162
			}
1132
			/* Figure out actual recipient */
1163
			/* Figure out actual recipient */
Lines 1176-1182 Link Here
1176
				(void) sm_snprintf(buf, sizeof buf,
1207
				(void) sm_snprintf(buf, sizeof buf,
1177
						   "Final-Recipient: %s",
1208
						   "Final-Recipient: %s",
1178
						   q->q_finalrcpt);
1209
						   q->q_finalrcpt);
1179
				putline(buf, mci);
1210
				if (!putline(buf, mci))
1211
					goto writeerr;
1180
			}
1212
			}
1181
			/* X-Actual-Recipient: -- the real problem address */
1213
			/* X-Actual-Recipient: -- the real problem address */
Lines 1190-1202 Link Here
1190
				(void) sm_snprintf(buf, sizeof buf,
1222
				(void) sm_snprintf(buf, sizeof buf,
1191
						   "X-Actual-Recipient: %s",
1223
						   "X-Actual-Recipient: %s",
1192
						   actual);
1224
						   actual);
1193
				putline(buf, mci);
1225
				if (!putline(buf, mci))
1226
					goto writeerr;
1194
			}
1227
			}
1195
			/* Action: -- what happened? */
1228
			/* Action: -- what happened? */
1196
			(void) sm_strlcpyn(buf, sizeof buf, 2, "Action: ",
1229
			(void) sm_strlcpyn(buf, sizeof buf, 2, "Action: ",
1197
				action);
1230
				action);
1198
			putline(buf, mci);
1231
			if (!putline(buf, mci))
1232
				goto writeerr;
1199
			/* Status: -- what _really_ happened? */
1233
			/* Status: -- what _really_ happened? */
1200
			if (q->q_status != NULL)
1234
			if (q->q_status != NULL)
Lines 1208-1214 Link Here
1208
			else
1242
			else
1209
				p = "2.0.0";
1243
				p = "2.0.0";
1210
			(void) sm_strlcpyn(buf, sizeof buf, 2, "Status: ", p);
1244
			(void) sm_strlcpyn(buf, sizeof buf, 2, "Status: ", p);
1211
			putline(buf, mci);
1245
			if (!putline(buf, mci))
1246
				goto writeerr;
1212
			/* Remote-MTA: -- who was I talking to? */
1247
			/* Remote-MTA: -- who was I talking to? */
1213
			if (q->q_statmta != NULL)
1248
			if (q->q_statmta != NULL)
Lines 1222-1228 Link Here
1222
				p = &buf[strlen(buf) - 1];
1257
				p = &buf[strlen(buf) - 1];
1223
				if (*p == '.')
1258
				if (*p == '.')
1224
					*p = '\0';
1259
					*p = '\0';
1225
				putline(buf, mci);
1260
				if (!putline(buf, mci))
1261
					goto writeerr;
1226
			}
1262
			}
1227
			/* Diagnostic-Code: -- actual result from other end */
1263
			/* Diagnostic-Code: -- actual result from other end */
Lines 1234-1240 Link Here
1234
				(void) sm_snprintf(buf, sizeof buf,
1270
				(void) sm_snprintf(buf, sizeof buf,
1235
						"Diagnostic-Code: %s; %.800s",
1271
						"Diagnostic-Code: %s; %.800s",
1236
						p, q->q_rstatus);
1272
						p, q->q_rstatus);
1237
				putline(buf, mci);
1273
				if (!putline(buf, mci))
1274
					goto writeerr;
1238
			}
1275
			}
1239
			/* Last-Attempt-Date: -- fine granularity */
1276
			/* Last-Attempt-Date: -- fine granularity */
Lines 1243-1249 Link Here
1243
			(void) sm_strlcpyn(buf, sizeof buf, 2,
1280
			(void) sm_strlcpyn(buf, sizeof buf, 2,
1244
					"Last-Attempt-Date: ",
1281
					"Last-Attempt-Date: ",
1245
					arpadate(ctime(&q->q_statdate)));
1282
					arpadate(ctime(&q->q_statdate)));
1246
			putline(buf, mci);
1283
			if (!putline(buf, mci))
1284
				goto writeerr;
1247
			/* Will-Retry-Until: -- for delayed messages only */
1285
			/* Will-Retry-Until: -- for delayed messages only */
1248
			if (QS_IS_QUEUEUP(q->q_state))
1286
			if (QS_IS_QUEUEUP(q->q_state))
Lines 1255-1261 Link Here
1255
				(void) sm_strlcpyn(buf, sizeof buf, 2,
1293
				(void) sm_strlcpyn(buf, sizeof buf, 2,
1256
					 "Will-Retry-Until: ",
1294
					 "Will-Retry-Until: ",
1257
					 arpadate(ctime(&xdate)));
1295
					 arpadate(ctime(&xdate)));
1258
				putline(buf, mci);
1296
				if (!putline(buf, mci))
1297
					goto writeerr;
1259
			}
1298
			}
1260
		}
1299
		}
1261
	}
1300
	}
Lines 1265-1271 Link Here
1265
	**  Output text of original message
1304
	**  Output text of original message
1266
	*/
1305
	*/
1267
	putline("", mci);
1306
	if (!putline("", mci))
1307
		goto writeerr;
1268
	if (bitset(EF_HAS_DF, e->e_parent->e_flags))
1308
	if (bitset(EF_HAS_DF, e->e_parent->e_flags))
1269
	{
1309
	{
1270
		sendbody = !bitset(EF_NO_BODY_RETN, e->e_parent->e_flags) &&
1310
		sendbody = !bitset(EF_NO_BODY_RETN, e->e_parent->e_flags) &&
Lines 1273-1293 Link Here
1273
		if (e->e_msgboundary == NULL)
1313
		if (e->e_msgboundary == NULL)
1274
		{
1314
		{
1275
			if (sendbody)
1315
			if (!putline(
1276
				putline("   ----- Original message follows -----\n", mci);
1316
				sendbody
1277
			else
1317
				? "   ----- Original message follows -----\n"
1278
				putline("   ----- Message header follows -----\n", mci);
1318
				: "   ----- Message header follows -----\n",
1319
				mci))
1320
			{
1321
				goto writeerr;
1322
			}
1279
		}
1323
		}
1280
		else
1324
		else
1281
		{
1325
		{
1282
			(void) sm_strlcpyn(buf, sizeof buf, 2, "--",
1326
			(void) sm_strlcpyn(buf, sizeof buf, 2, "--",
1283
					e->e_msgboundary);
1327
					e->e_msgboundary);
1284
			putline(buf, mci);
1328
			if (!putline(buf, mci))
1329
				goto writeerr;
1285
			(void) sm_strlcpyn(buf, sizeof buf, 2, "Content-Type: ",
1330
			(void) sm_strlcpyn(buf, sizeof buf, 2, "Content-Type: ",
1286
					sendbody ? "message/rfc822"
1331
					sendbody ? "message/rfc822"
1287
						 : "text/rfc822-headers");
1332
						 : "text/rfc822-headers");
1288
			putline(buf, mci);
1333
			if (!putline(buf, mci))
1334
				goto writeerr;
1289
			p = hvalue("Content-Transfer-Encoding",
1335
			p = hvalue("Content-Transfer-Encoding",
1290
				   e->e_parent->e_header);
1336
				   e->e_parent->e_header);
Lines 1301-1343 Link Here
1301
				(void) sm_snprintf(buf, sizeof buf,
1347
				(void) sm_snprintf(buf, sizeof buf,
1302
						"Content-Transfer-Encoding: %s",
1348
						"Content-Transfer-Encoding: %s",
1303
						p);
1349
						p);
1304
				putline(buf, mci);
1350
				if (!putline(buf, mci))
1351
					goto writeerr;
1305
			}
1352
			}
1306
		}
1353
		}
1307
		putline("", mci);
1354
		if (!putline("", mci))
1355
			goto writeerr;
1308
		save_errno = errno;
1356
		save_errno = errno;
1309
		putheader(mci, e->e_parent->e_header, e->e_parent, M87F_OUTER);
1357
		if (!putheader(mci, e->e_parent->e_header, e->e_parent,
1358
				M87F_OUTER))
1359
			goto writeerr;
1310
		errno = save_errno;
1360
		errno = save_errno;
1311
		if (sendbody)
1361
		if (sendbody)
1312
			putbody(mci, e->e_parent, e->e_msgboundary);
1362
		{
1363
			if (!putbody(mci, e->e_parent, e->e_msgboundary))
1364
				goto writeerr;
1365
		}
1313
		else if (e->e_msgboundary == NULL)
1366
		else if (e->e_msgboundary == NULL)
1314
		{
1367
		{
1315
			putline("", mci);
1368
			if (!putline("", mci) ||
1316
			putline("   ----- Message body suppressed -----", mci);
1369
			    !putline("   ----- Message body suppressed -----",
1370
					mci))
1371
			{
1372
				goto writeerr;
1373
			}
1317
		}
1374
		}
1318
	}
1375
	}
1319
	else if (e->e_msgboundary == NULL)
1376
	else if (e->e_msgboundary == NULL)
1320
	{
1377
	{
1321
		putline("  ----- No message was collected -----\n", mci);
1378
		if (!putline("  ----- No message was collected -----\n", mci))
1379
			goto writeerr;
1322
	}
1380
	}
1323
	if (e->e_msgboundary != NULL)
1381
	if (e->e_msgboundary != NULL)
1324
	{
1382
	{
1325
		putline("", mci);
1326
		(void) sm_strlcpyn(buf, sizeof buf, 3, "--", e->e_msgboundary,
1383
		(void) sm_strlcpyn(buf, sizeof buf, 3, "--", e->e_msgboundary,
1327
				   "--");
1384
				   "--");
1328
		putline(buf, mci);
1385
		if (!putline("", mci) || !putline(buf, mci))
1386
			goto writeerr;
1329
	}
1387
	}
1330
	putline("", mci);
1388
	if (!putline("", mci) ||
1331
	(void) sm_io_flush(mci->mci_out, SM_TIME_DEFAULT);
1389
	    sm_io_flush(mci->mci_out, SM_TIME_DEFAULT) == SM_IO_EOF)
1390
			goto writeerr;
1332
	/*
1391
	/*
1333
	**  Cleanup and exit
1392
	**  Cleanup and exit
1334
	*/
1393
	*/
1335
	if (errno != 0)
1394
	if (errno != 0)
1395
	{
1396
  writeerr:
1336
		syserr("errbody: I/O error");
1397
		syserr("errbody: I/O error");
1398
		return false;
1399
	}
1400
	return true;
1337
}
1401
}
1402
1338
/*
1403
/*
1339
**  SMTPTODSN -- convert SMTP to DSN status code
1404
**  SMTPTODSN -- convert SMTP to DSN status code
1340
**
1405
**
(-)sendmail/sendmail.h (-10 / +9 lines)
Lines 809-821 Link Here
809
/* functions */
809
/* functions */
810
extern void	addheader __P((char *, char *, int, ENVELOPE *));
810
extern void	addheader __P((char *, char *, int, ENVELOPE *));
811
extern unsigned long	chompheader __P((char *, int, HDR **, ENVELOPE *));
811
extern unsigned long	chompheader __P((char *, int, HDR **, ENVELOPE *));
812
extern void	commaize __P((HDR *, char *, bool, MCI *, ENVELOPE *));
812
extern bool	commaize __P((HDR *, char *, bool, MCI *, ENVELOPE *));
813
extern HDR	*copyheader __P((HDR *, SM_RPOOL_T *));
813
extern HDR	*copyheader __P((HDR *, SM_RPOOL_T *));
814
extern void	eatheader __P((ENVELOPE *, bool, bool));
814
extern void	eatheader __P((ENVELOPE *, bool, bool));
815
extern char	*hvalue __P((char *, HDR *));
815
extern char	*hvalue __P((char *, HDR *));
816
extern void	insheader __P((int, char *, char *, int, ENVELOPE *));
816
extern void	insheader __P((int, char *, char *, int, ENVELOPE *));
817
extern bool	isheader __P((char *));
817
extern bool	isheader __P((char *));
818
extern void	putfromline __P((MCI *, ENVELOPE *));
818
extern bool	putfromline __P((MCI *, ENVELOPE *));
819
extern void	setupheaders __P((void));
819
extern void	setupheaders __P((void));
820
/*
820
/*
Lines 870-878 Link Here
870
	short		e_sendmode;	/* message send mode */
870
	short		e_sendmode;	/* message send mode */
871
	short		e_errormode;	/* error return mode */
871
	short		e_errormode;	/* error return mode */
872
	short		e_timeoutclass;	/* message timeout class */
872
	short		e_timeoutclass;	/* message timeout class */
873
	void		(*e_puthdr)__P((MCI *, HDR *, ENVELOPE *, int));
873
	bool		(*e_puthdr)__P((MCI *, HDR *, ENVELOPE *, int));
874
					/* function to put header of message */
874
					/* function to put header of message */
875
	void		(*e_putbody)__P((MCI *, ENVELOPE *, char *));
875
	bool		(*e_putbody)__P((MCI *, ENVELOPE *, char *));
876
					/* function to put body of message */
876
					/* function to put body of message */
877
	ENVELOPE	*e_parent;	/* the message this one encloses */
877
	ENVELOPE	*e_parent;	/* the message this one encloses */
878
	ENVELOPE	*e_sibling;	/* the next envelope of interest */
878
	ENVELOPE	*e_sibling;	/* the next envelope of interest */
Lines 965-972 Link Here
965
extern ENVELOPE	*newenvelope __P((ENVELOPE *, ENVELOPE *, SM_RPOOL_T *));
965
extern ENVELOPE	*newenvelope __P((ENVELOPE *, ENVELOPE *, SM_RPOOL_T *));
966
extern void	clrsessenvelope __P((ENVELOPE *));
966
extern void	clrsessenvelope __P((ENVELOPE *));
967
extern void	printenvflags __P((ENVELOPE *));
967
extern void	printenvflags __P((ENVELOPE *));
968
extern void	putbody __P((MCI *, ENVELOPE *, char *));
968
extern bool	putbody __P((MCI *, ENVELOPE *, char *));
969
extern void	putheader __P((MCI *, HDR *, ENVELOPE *, int));
969
extern bool	putheader __P((MCI *, HDR *, ENVELOPE *, int));
970
/*
970
/*
971
**  Message priority classes.
971
**  Message priority classes.
Lines 1651-1657 Link Here
1651
#define M87F_NO8TO7		0x0004	/* don't do 8->7 bit conversions */
1654
#define M87F_NO8TO7		0x0004	/* don't do 8->7 bit conversions */
1652
/* functions */
1655
/* functions */
1653
extern void	mime7to8 __P((MCI *, HDR *, ENVELOPE *));
1656
extern bool	mime7to8 __P((MCI *, HDR *, ENVELOPE *));
1654
extern int	mime8to7 __P((MCI *, HDR *, ENVELOPE *, char **, int));
1657
extern int	mime8to7 __P((MCI *, HDR *, ENVELOPE *, char **, int));
1655
/*
1658
/*
Lines 2153-2159 Link Here
2153
#if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_)
2153
#if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_)
2154
EXTERN bool	ConfigFileRead;	/* configuration file has been read */
2154
EXTERN bool	ConfigFileRead;	/* configuration file has been read */
2155
#endif /* !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) */
2155
#endif /* !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) */
2156
EXTERN bool	volatile DataProgress;	/* have we sent anything since last check */
2157
EXTERN bool	DisConnected;	/* running with OutChannel redirect to transcript file */
2156
EXTERN bool	DisConnected;	/* running with OutChannel redirect to transcript file */
2158
EXTERN bool	DontExpandCnames;	/* do not $[...$] expand CNAMEs */
2157
EXTERN bool	DontExpandCnames;	/* do not $[...$] expand CNAMEs */
2159
EXTERN bool	DontInitGroups;	/* avoid initgroups() because of NIS cost */
2158
EXTERN bool	DontInitGroups;	/* avoid initgroups() because of NIS cost */
Lines 2520-2527 Link Here
2520
extern void	printqueue __P((void));
2537
extern void	printqueue __P((void));
2521
extern void	printrules __P((void));
2538
extern void	printrules __P((void));
2522
extern pid_t	prog_open __P((char **, int *, ENVELOPE *));
2539
extern pid_t	prog_open __P((char **, int *, ENVELOPE *));
2523
extern void	putline __P((char *, MCI *));
2540
extern bool	putline __P((char *, MCI *));
2524
extern void	putxline __P((char *, size_t, MCI *, int));
2541
extern bool	putxline __P((char *, size_t, MCI *, int));
2525
extern void	queueup_macros __P((int, SM_FILE_T *, ENVELOPE *));
2542
extern void	queueup_macros __P((int, SM_FILE_T *, ENVELOPE *));
2526
extern void	readcf __P((char *, bool, ENVELOPE *));
2543
extern void	readcf __P((char *, bool, ENVELOPE *));
2527
extern SIGFUNC_DECL	reapchild __P((int));
2544
extern SIGFUNC_DECL	reapchild __P((int));
(-)sendmail/sfsasl.c (-41 / +181 lines)
Lines 549-554 Link Here
549
# define MAX_TLS_IOS	4
549
# define MAX_TLS_IOS	4
550
/*
550
/*
551
**  TLS_RETRY -- check whether a failed SSL operation can be retried
552
**
553
**	Parameters:
554
**		ssl -- TLS structure
555
**		rfd -- read fd
556
**		wfd -- write fd
557
**		tlsstart -- start time of TLS operation
558
**		timeout -- timeout for TLS operation
559
**		err -- SSL error
560
**		where -- description of operation
561
**
562
**	Results:
563
**		>0 on success
564
**		0 on timeout
565
**		<0 on error
566
*/
567
568
int
569
tls_retry(ssl, rfd, wfd, tlsstart, timeout, err, where)
570
	SSL *ssl;
571
	int rfd;
572
	int wfd;
573
	time_t tlsstart;
574
	int timeout;
575
	int err;
576
	const char *where;
577
{
578
	int ret;
579
	time_t left;
580
	time_t now = curtime();
581
	struct timeval tv;
582
583
	ret = -1;
584
585
	/*
586
	**  For SSL_ERROR_WANT_{READ,WRITE}:
587
	**  There is not a complete SSL record available yet
588
	**  or there is only a partial SSL record removed from
589
	**  the network (socket) buffer into the SSL buffer.
590
	**  The SSL_connect will only succeed when a full
591
	**  SSL record is available (assuming a "real" error
592
	**  doesn't happen). To handle when a "real" error
593
	**  does happen the select is set for exceptions too.
594
	**  The connection may be re-negotiated during this time
595
	**  so both read and write "want errors" need to be handled.
596
	**  A select() exception loops back so that a proper SSL
597
	**  error message can be gotten.
598
	*/
599
600
	left = timeout - (now - tlsstart);
601
	if (left <= 0)
602
		return 0;	/* timeout */
603
	tv.tv_sec = left;
604
	tv.tv_usec = 0;
605
606
	if (LogLevel > 14)
607
	{
608
		sm_syslog(LOG_INFO, NOQID,
609
			  "STARTTLS=%s, info: fds=%d/%d, err=%d",
610
			  where, rfd, wfd, err);
611
	}
612
613
	if (FD_SETSIZE > 0 &&
614
	    ((err == SSL_ERROR_WANT_READ && rfd >= FD_SETSIZE) ||
615
	     (err == SSL_ERROR_WANT_WRITE && wfd >= FD_SETSIZE)))
616
	{
617
		if (LogLevel > 5)
618
		{
619
			sm_syslog(LOG_ERR, NOQID,
620
				  "STARTTLS=%s, error: fd %d/%d too large",
621
				  where, rfd, wfd);
622
		if (LogLevel > 8)
623
			tlslogerr(where);
624
		}
625
		errno = EINVAL;
626
	}
627
	else if (err == SSL_ERROR_WANT_READ)
628
	{
629
		fd_set ssl_maskr, ssl_maskx;
630
631
		FD_ZERO(&ssl_maskr);
632
		FD_SET(rfd, &ssl_maskr);
633
		FD_ZERO(&ssl_maskx);
634
		FD_SET(rfd, &ssl_maskx);
635
		do
636
		{
637
			ret = select(rfd + 1, &ssl_maskr, NULL, &ssl_maskx,
638
					&tv);
639
		} while (ret < 0 && errno == EINTR);
640
		if (ret < 0 && errno > 0)
641
			ret = -errno;
642
	}
643
	else if (err == SSL_ERROR_WANT_WRITE)
644
	{
645
		fd_set ssl_maskw, ssl_maskx;
646
647
		FD_ZERO(&ssl_maskw);
648
		FD_SET(wfd, &ssl_maskw);
649
		FD_ZERO(&ssl_maskx);
650
		FD_SET(rfd, &ssl_maskx);
651
		do
652
		{
653
			ret = select(wfd + 1, NULL, &ssl_maskw, &ssl_maskx,
654
					&tv);
655
		} while (ret < 0 && errno == EINTR);
656
		if (ret < 0 && errno > 0)
657
			ret = -errno;
658
	}
659
	return ret;
660
}
661
662
/* errno to force refill() etc to stop (see IS_IO_ERROR()) */
663
#ifdef ETIMEDOUT
664
# define SM_ERR_TIMEOUT	ETIMEDOUT
665
#else /* ETIMEDOUT */
666
# define SM_ERR_TIMEOUT	EIO
667
#endif /* ETIMEDOUT */
668
669
/*
551
**  TLS_READ -- read secured information for the caller
670
**  TLS_READ -- read secured information for the caller
552
**
671
**
553
**	Parameters:
672
**	Parameters:
Lines 569-606 Link Here
569
	char *buf;
688
	char *buf;
570
	size_t size;
689
	size_t size;
571
{
690
{
572
	int r;
691
	int r, rfd, wfd, try, ssl_err;
573
	static int again = MAX_TLS_IOS;
574
	struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
692
	struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
693
	time_t tlsstart;
575
	char *err;
694
	char *err;
695
	try = 99;
696
	err = NULL;
697
	tlsstart = curtime();
698
699
  retry:
576
	r = SSL_read(so->con, (char *) buf, size);
700
	r = SSL_read(so->con, (char *) buf, size);
577
	if (r > 0)
701
	if (r > 0)
578
	{
579
		again = MAX_TLS_IOS;
580
		return r;
702
		return r;
581
	}
582
	err = NULL;
703
	err = NULL;
583
	switch (SSL_get_error(so->con, r))
704
	switch (ssl_err = SSL_get_error(so->con, r))
584
	{
705
	{
585
	  case SSL_ERROR_NONE:
706
	  case SSL_ERROR_NONE:
586
	  case SSL_ERROR_ZERO_RETURN:
707
	  case SSL_ERROR_ZERO_RETURN:
587
		again = MAX_TLS_IOS;
588
		break;
708
		break;
589
	  case SSL_ERROR_WANT_WRITE:
709
	  case SSL_ERROR_WANT_WRITE:
590
		if (--again <= 0)
710
		err = "read W BLOCK";
591
			err = "read W BLOCK";
711
		/* FALLTHROUGH */
592
		else
593
			errno = EAGAIN;
594
		break;
595
	  case SSL_ERROR_WANT_READ:
712
	  case SSL_ERROR_WANT_READ:
596
		if (--again <= 0)
713
		if (err == NULL)
597
			err = "read R BLOCK";
714
			err = "read R BLOCK";
598
		else
715
		rfd = SSL_get_rfd(so->con);
599
			errno = EAGAIN;
716
		wfd = SSL_get_wfd(so->con);
717
		try = tls_retry(so->con, rfd, wfd, tlsstart,
718
				TimeOuts.to_datablock, ssl_err, "read");
719
		if (try > 0)
720
			goto retry;
721
		errno = SM_ERR_TIMEOUT;
600
		break;
722
		break;
723
601
	  case SSL_ERROR_WANT_X509_LOOKUP:
724
	  case SSL_ERROR_WANT_X509_LOOKUP:
602
		err = "write X BLOCK";
725
		err = "write X BLOCK";
603
		break;
726
		break;
Lines 633-647 Link Here
633
		int save_errno;
756
		int save_errno;
634
		save_errno = (errno == 0) ? EIO : errno;
757
		save_errno = (errno == 0) ? EIO : errno;
635
		again = MAX_TLS_IOS;
758
		if (try == 0 && save_errno == SM_ERR_TIMEOUT)
636
		if (LogLevel > 9)
759
		{
760
			if (LogLevel > 7)
761
				sm_syslog(LOG_WARNING, NOQID,
762
					  "STARTTLS: read error=timeout");
763
		}
764
		else if (LogLevel > 8)
637
			sm_syslog(LOG_WARNING, NOQID,
765
			sm_syslog(LOG_WARNING, NOQID,
638
				  "STARTTLS: read error=%s (%d), errno=%d, get_error=%s",
766
				  "STARTTLS: read error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
639
				  err, r, errno,
767
				  err, r, errno,
640
				  ERR_error_string(ERR_get_error(), NULL));
768
				  ERR_error_string(ERR_get_error(), NULL), try,
769
				  ssl_err);
641
		else if (LogLevel > 7)
770
		else if (LogLevel > 7)
642
			sm_syslog(LOG_WARNING, NOQID,
771
			sm_syslog(LOG_WARNING, NOQID,
643
				  "STARTTLS: read error=%s (%d)", err, r);
772
				  "STARTTLS: read error=%s (%d), retry=%d, ssl_err=%d",
773
				  err, r, errno, try, ssl_err);
644
		errno = save_errno;
774
		errno = save_errno;
645
	}
775
	}
646
	return r;
776
	return r;
Lines 668-703 Link Here
668
	const char *buf;
798
	const char *buf;
669
	size_t size;
799
	size_t size;
670
{
800
{
671
	int r;
801
	int r, rfd, wfd, try, ssl_err;
672
	static int again = MAX_TLS_IOS;
673
	struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
802
	struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
803
	time_t tlsstart;
674
	char *err;
804
	char *err;
805
	try = 99;
806
	err = NULL;
807
	tlsstart = curtime();
808
809
  retry:
675
	r = SSL_write(so->con, (char *) buf, size);
810
	r = SSL_write(so->con, (char *) buf, size);
676
	if (r > 0)
811
	if (r > 0)
677
	{
678
		again = MAX_TLS_IOS;
679
		return r;
812
		return r;
680
	}
681
	err = NULL;
813
	err = NULL;
682
	switch (SSL_get_error(so->con, r))
814
	switch (ssl_err = SSL_get_error(so->con, r))
683
	{
815
	{
684
	  case SSL_ERROR_NONE:
816
	  case SSL_ERROR_NONE:
685
	  case SSL_ERROR_ZERO_RETURN:
817
	  case SSL_ERROR_ZERO_RETURN:
686
		again = MAX_TLS_IOS;
687
		break;
818
		break;
688
	  case SSL_ERROR_WANT_WRITE:
819
	  case SSL_ERROR_WANT_WRITE:
689
		if (--again <= 0)
820
		err = "read W BLOCK";
690
			err = "write W BLOCK";
821
		/* FALLTHROUGH */
691
		else
692
			errno = EAGAIN;
693
		break;
694
	  case SSL_ERROR_WANT_READ:
822
	  case SSL_ERROR_WANT_READ:
695
		if (--again <= 0)
823
		if (err == NULL)
696
			err = "write R BLOCK";
824
			err = "read R BLOCK";
697
		else
825
		rfd = SSL_get_rfd(so->con);
698
			errno = EAGAIN;
826
		wfd = SSL_get_wfd(so->con);
827
		try = tls_retry(so->con, rfd, wfd, tlsstart,
828
				DATA_PROGRESS_TIMEOUT, ssl_err, "write");
829
		if (try > 0)
830
			goto retry;
831
		errno = SM_ERR_TIMEOUT;
699
		break;
832
		break;
700
	  case SSL_ERROR_WANT_X509_LOOKUP:
833
	  case SSL_ERROR_WANT_X509_LOOKUP:
701
		err = "write X BLOCK";
834
		err = "write X BLOCK";
Lines 730-744 Link Here
730
		int save_errno;
863
		int save_errno;
731
		save_errno = (errno == 0) ? EIO : errno;
864
		save_errno = (errno == 0) ? EIO : errno;
732
		again = MAX_TLS_IOS;
865
		if (try == 0 && save_errno == SM_ERR_TIMEOUT)
733
		if (LogLevel > 9)
866
		{
867
			if (LogLevel > 7)
868
				sm_syslog(LOG_WARNING, NOQID,
869
					  "STARTTLS: write error=timeout");
870
		}
871
		else if (LogLevel > 8)
734
			sm_syslog(LOG_WARNING, NOQID,
872
			sm_syslog(LOG_WARNING, NOQID,
735
				  "STARTTLS: write error=%s (%d), errno=%d, get_error=%s",
873
				  "STARTTLS: write error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
736
				  err, r, errno,
874
				  err, r, errno,
737
				  ERR_error_string(ERR_get_error(), NULL));
875
				  ERR_error_string(ERR_get_error(), NULL), try,
876
				  ssl_err);
738
		else if (LogLevel > 7)
877
		else if (LogLevel > 7)
739
			sm_syslog(LOG_WARNING, NOQID,
878
			sm_syslog(LOG_WARNING, NOQID,
740
				  "STARTTLS: write error=%s (%d)", err, r);
879
				  "STARTTLS: write error=%s (%d), errno=%d, retry=%d, ssl_err=%d",
880
				  err, r, errno, try, ssl_err);
741
		errno = save_errno;
881
		errno = save_errno;
742
	}
882
	}
743
	return r;
883
	return r;
(-)sendmail/sfsasl.h (+2 lines)
Lines 17-22 Link Here
17
#endif /* SASL */
17
#endif /* SASL */
18
# if STARTTLS
18
# if STARTTLS
19
extern int	tls_retry __P((SSL *, int, int, time_t, int, int,
20
				const char *));
19
extern int	sfdctls __P((SM_FILE_T **, SM_FILE_T **, SSL *));
21
extern int	sfdctls __P((SM_FILE_T **, SM_FILE_T **, SSL *));
20
# endif /* STARTTLS */
22
# endif /* STARTTLS */
(-)sendmail/srvrsmtp.c (-84 / +9 lines)
Lines 505-511 Link Here
505
#endif /* SASL */
523
#endif /* SASL */
506
	int r;
524
	int r;
507
#if STARTTLS
525
#if STARTTLS
508
	int fdfl;
509
	int rfd, wfd;
526
	int rfd, wfd;
510
	volatile bool tls_active = false;
527
	volatile bool tls_active = false;
511
	volatile bool smtps = bitnset(D_SMTPS, d_flags);
528
	volatile bool smtps = bitnset(D_SMTPS, d_flags);
Lines 1713-1809 Link Here
1713
#  define SSL_ACC(s)	SSL_accept(s)
1743
#  define SSL_ACC(s)	SSL_accept(s)
1714
			tlsstart = curtime();
1744
			tlsstart = curtime();
1715
			fdfl = fcntl(rfd, F_GETFL);
1716
			if (fdfl != -1)
1717
				fcntl(rfd, F_SETFL, fdfl|O_NONBLOCK);
1718
  ssl_retry:
1745
  ssl_retry:
1719
			if ((r = SSL_ACC(srv_ssl)) <= 0)
1746
			if ((r = SSL_ACC(srv_ssl)) <= 0)
1720
			{
1747
			{
1721
				int i;
1748
				int i, ssl_err;
1722
				bool timedout;
1723
				time_t left;
1724
				time_t now = curtime();
1725
				struct timeval tv;
1726
1727
				/* what to do in this case? */
1728
				i = SSL_get_error(srv_ssl, r);
1729
1730
				/*
1731
				**  For SSL_ERROR_WANT_{READ,WRITE}:
1732
				**  There is no SSL record available yet
1733
				**  or there is only a partial SSL record
1734
				**  removed from the network (socket) buffer
1735
				**  into the SSL buffer. The SSL_accept will
1736
				**  only succeed when a full SSL record is
1737
				**  available (assuming a "real" error
1738
				**  doesn't happen). To handle when a "real"
1739
				**  error does happen the select is set for
1740
				**  exceptions too.
1741
				**  The connection may be re-negotiated
1742
				**  during this time so both read and write
1743
				**  "want errors" need to be handled.
1744
				**  A select() exception loops back so that
1745
				**  a proper SSL error message can be gotten.
1746
				*/
1747
1748
				left = TimeOuts.to_starttls - (now - tlsstart);
1749
				timedout = left <= 0;
1750
				if (!timedout)
1751
				{
1752
					tv.tv_sec = left;
1753
					tv.tv_usec = 0;
1754
				}
1755
				if (!timedout && FD_SETSIZE > 0 &&
1749
				ssl_err = SSL_get_error(srv_ssl, r);
1756
				    (rfd >= FD_SETSIZE ||
1750
				i = tls_retry(srv_ssl, rfd, wfd, tlsstart,
1757
				     (i == SSL_ERROR_WANT_WRITE &&
1751
						TimeOuts.to_starttls, ssl_err,
1758
				      wfd >= FD_SETSIZE)))
1752
						"server");
1759
				{
1753
				if (i > 0)
1760
					if (LogLevel > 5)
1754
					goto ssl_retry;
1761
					{
1762
						sm_syslog(LOG_ERR, NOQID,
1763
							  "STARTTLS=server, error: fd %d/%d too large",
1764
							  rfd, wfd);
1765
						if (LogLevel > 8)
1766
							tlslogerr("server");
1767
					}
1768
					goto tlsfail;
1769
				}
1770
1771
				/* XXX what about SSL_pending() ? */
1772
				if (!timedout && i == SSL_ERROR_WANT_READ)
1773
				{
1774
					fd_set ssl_maskr, ssl_maskx;
1775
1776
					FD_ZERO(&ssl_maskr);
1777
					FD_SET(rfd, &ssl_maskr);
1778
					FD_ZERO(&ssl_maskx);
1779
					FD_SET(rfd, &ssl_maskx);
1780
					if (select(rfd + 1, &ssl_maskr, NULL,
1781
						   &ssl_maskx, &tv) > 0)
1782
						goto ssl_retry;
1783
				}
1784
				if (!timedout && i == SSL_ERROR_WANT_WRITE)
1785
				{
1786
					fd_set ssl_maskw, ssl_maskx;
1787
					FD_ZERO(&ssl_maskw);
1788
					FD_SET(wfd, &ssl_maskw);
1789
					FD_ZERO(&ssl_maskx);
1790
					FD_SET(rfd, &ssl_maskx);
1791
					if (select(wfd + 1, NULL, &ssl_maskw,
1792
						   &ssl_maskx, &tv) > 0)
1793
						goto ssl_retry;
1794
				}
1795
				if (LogLevel > 5)
1755
				if (LogLevel > 5)
1796
				{
1756
				{
1797
					sm_syslog(LOG_WARNING, NOQID,
1757
					sm_syslog(LOG_WARNING, NOQID,
1798
						  "STARTTLS=server, error: accept failed=%d, SSL_error=%d, timedout=%d, errno=%d",
1758
						  "STARTTLS=server, error: accept failed=%d, SSL_error=%d, errno=%d, retry=%d",
1799
						  r, i, (int) timedout, errno);
1759
						  r, ssl_err, errno, i);
1800
					if (LogLevel > 8)
1760
					if (LogLevel > 8)
1801
						tlslogerr("server");
1761
						tlslogerr("server");
1802
				}
1762
				}
1803
tlsfail:
1804
				tls_ok_srv = false;
1763
				tls_ok_srv = false;
1805
				SSL_free(srv_ssl);
1764
				SSL_free(srv_ssl);
1806
				srv_ssl = NULL;
1765
				srv_ssl = NULL;
Lines 1818-1826 Link Here
1818
				goto doquit;
1777
				goto doquit;
1819
			}
1778
			}
1820
			if (fdfl != -1)
1821
				fcntl(rfd, F_SETFL, fdfl);
1822
1823
			/* ignore return code for now, it's in {verify} */
1779
			/* ignore return code for now, it's in {verify} */
1824
			(void) tls_get_info(srv_ssl, true,
1780
			(void) tls_get_info(srv_ssl, true,
1825
					    CurSmtpClient,
1781
					    CurSmtpClient,
(-)sendmail/usersmtp.c (-72 / +24 lines)
Lines 18-25 Link Here
18
#include <sysexits.h>
18
#include <sysexits.h>
19
static void	datatimeout __P((int));
20
static void	esmtp_check __P((char *, bool, MAILER *, MCI *, ENVELOPE *));
19
static void	esmtp_check __P((char *, bool, MAILER *, MCI *, ENVELOPE *));
21
static void	helo_options __P((char *, bool, MAILER *, MCI *, ENVELOPE *));
20
static void	helo_options __P((char *, bool, MAILER *, MCI *, ENVELOPE *));
22
static int	smtprcptstat __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *));
21
static int	smtprcptstat __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *));
Lines 2491-2499 Link Here
2491
**		exit status corresponding to DATA command.
2489
**		exit status corresponding to DATA command.
2492
*/
2490
*/
2493
static jmp_buf	CtxDataTimeout;
2494
static SM_EVENT	*volatile DataTimeout = NULL;
2495
2496
int
2491
int
2497
smtpdata(m, mci, e, ctladdr, xstart)
2492
smtpdata(m, mci, e, ctladdr, xstart)
2498
	MAILER *m;
2493
	MAILER *m;
Lines 2629-2671 Link Here
2629
	**  factor.  The main thing is that it should not be infinite.
2624
	**  factor.  The main thing is that it should not be infinite.
2630
	*/
2625
	*/
2631
	if (setjmp(CtxDataTimeout) != 0)
2632
	{
2633
		mci->mci_errno = errno;
2634
		mci->mci_state = MCIS_ERROR;
2635
		mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL);
2636
2637
		/*
2638
		**  If putbody() couldn't finish due to a timeout,
2639
		**  rewind it here in the timeout handler.  See
2640
		**  comments at the end of putbody() for reasoning.
2641
		*/
2642
2643
		if (e->e_dfp != NULL)
2644
			(void) bfrewind(e->e_dfp);
2645
2646
		errno = mci->mci_errno;
2647
		syserr("451 4.4.1 timeout writing message to %s", CurHostName);
2648
		smtpquit(m, mci, e);
2649
		return EX_TEMPFAIL;
2650
	}
2651
2652
	if (tTd(18, 101))
2626
	if (tTd(18, 101))
2653
	{
2627
	{
2654
		/* simulate a DATA timeout */
2628
		/* simulate a DATA timeout */
2655
		timeout = 1;
2629
		timeout = 10;
2656
	}
2630
	}
2657
	else
2631
	else
2658
		timeout = DATA_PROGRESS_TIMEOUT;
2632
		timeout = DATA_PROGRESS_TIMEOUT * 1000;
2659
2633
	sm_io_setinfo(mci->mci_out, SM_IO_WHAT_TIMEOUT, &timeout);
2660
	DataTimeout = sm_setevent(timeout, datatimeout, 0);
2661
	/*
2634
	/*
2662
	**  Output the actual message.
2635
	**  Output the actual message.
2663
	*/
2636
	*/
2664
	(*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER);
2637
	if (!(*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER))
2638
		goto writeerr;
2665
	if (tTd(18, 101))
2639
	if (tTd(18, 101))
2666
	{
2640
	{
Lines 2673-2686 Link Here
2673
		(void) sleep(2);
2647
		(void) sleep(2);
2674
	}
2648
	}
2675
	(*e->e_putbody)(mci, e, NULL);
2649
	if (!(*e->e_putbody)(mci, e, NULL))
2650
		goto writeerr;
2676
	/*
2651
	/*
2677
	**  Cleanup after sending message.
2652
	**  Cleanup after sending message.
2678
	*/
2653
	*/
2679
	if (DataTimeout != NULL)
2680
		sm_clrevent(DataTimeout);
2681
#if PIPELINING
2654
#if PIPELINING
2682
	}
2655
	}
Lines 2720-2726 Link Here
2720
	}
2693
	}
2721
	/* terminate the message */
2694
	/* terminate the message */
2722
	(void) sm_io_fprintf(mci->mci_out, SM_TIME_DEFAULT, ".%s", m->m_eol);
2695
	if (sm_io_fprintf(mci->mci_out, SM_TIME_DEFAULT, ".%s", m->m_eol) ==
2696
								SM_IO_EOF)
2697
		goto writeerr;
2723
	if (TrafficLogFile != NULL)
2698
	if (TrafficLogFile != NULL)
2724
		(void) sm_io_fprintf(TrafficLogFile, SM_TIME_DEFAULT,
2699
		(void) sm_io_fprintf(TrafficLogFile, SM_TIME_DEFAULT,
2725
				     "%05d >>> .\n", (int) CurrentPid);
2700
				     "%05d >>> .\n", (int) CurrentPid);
Lines 2771-2821 Link Here
2771
			  shortenstring(SmtpReplyBuffer, 403));
2746
			  shortenstring(SmtpReplyBuffer, 403));
2772
	}
2747
	}
2773
	return rstat;
2748
	return rstat;
2774
}
2749
  writeerr:
2775
static void
2750
	mci->mci_errno = errno;
2776
datatimeout(ignore)
2751
	mci->mci_state = MCIS_ERROR;
2777
	int ignore;
2752
	mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL);
2778
{
2779
	int save_errno = errno;
2780
	/*
2753
	/*
2781
	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
2754
	**  If putbody() couldn't finish due to a timeout,
2782
	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
2755
	**  rewind it here in the timeout handler.  See
2783
	**	DOING.
2756
	**  comments at the end of putbody() for reasoning.
2784
	*/
2757
	*/
2785
	if (DataProgress)
2758
	if (e->e_dfp != NULL)
2786
	{
2759
		(void) bfrewind(e->e_dfp);
2787
		time_t timeout;
2788
2789
		/* check back again later */
2790
		if (tTd(18, 101))
2791
		{
2792
			/* simulate a DATA timeout */
2793
			timeout = 1;
2794
		}
2795
		else
2796
			timeout = DATA_PROGRESS_TIMEOUT;
2797
2798
		/* reset the timeout */
2799
		DataTimeout = sm_sigsafe_setevent(timeout, datatimeout, 0);
2800
		DataProgress = false;
2801
	}
2802
	else
2803
	{
2804
		/* event is done */
2805
		DataTimeout = NULL;
2806
	}
2807
	/* if no progress was made or problem resetting event, die now */
2760
	errno = mci->mci_errno;
2808
	if (DataTimeout == NULL)
2761
	syserr("451 4.4.1 timeout writing message to %s", CurHostName);
2809
	{
2762
	smtpquit(m, mci, e);
2810
		errno = ETIMEDOUT;
2763
	return EX_TEMPFAIL;
2811
		longjmp(CtxDataTimeout, 1);
2812
	}
2813
	errno = save_errno;
2814
}
2764
}
2765
2815
/*
2766
/*
2816
**  SMTPGETSTAT -- get status code from DATA in LMTP
2767
**  SMTPGETSTAT -- get status code from DATA in LMTP
2817
**
2768
**
(-)sendmail/util.c (-49 / +19 lines)
Lines 456-461 Link Here
456
{
456
{
457
	register char *p;
457
	register char *p;
458
	SM_REQUIRE(sz >= 0);
459
458
	/* some systems can't handle size zero mallocs */
460
	/* some systems can't handle size zero mallocs */
459
	if (sz <= 0)
461
	if (sz <= 0)
460
		sz = 1;
462
		sz = 1;
Lines 970-987 Link Here
970
**		mci -- the mailer connection information.
972
**		mci -- the mailer connection information.
971
**
973
**
972
**	Returns:
974
**	Returns:
973
**		none
975
**		true iff line was written successfully
974
**
976
**
975
**	Side Effects:
977
**	Side Effects:
976
**		output of l to mci->mci_out.
978
**		output of l to mci->mci_out.
977
*/
979
*/
978
void
980
bool
979
putline(l, mci)
981
putline(l, mci)
980
	register char *l;
982
	register char *l;
981
	register MCI *mci;
983
	register MCI *mci;
982
{
984
{
983
	putxline(l, strlen(l), mci, PXLF_MAPFROM);
985
	return putxline(l, strlen(l), mci, PXLF_MAPFROM);
984
}
986
}
985
/*
987
/*
986
**  PUTXLINE -- putline with flags bits.
988
**  PUTXLINE -- putline with flags bits.
Lines 1000-1012 Link Here
1000
**		    PXLF_NOADDEOL -- don't add an EOL if one wasn't present.
1002
**		    PXLF_NOADDEOL -- don't add an EOL if one wasn't present.
1001
**
1003
**
1002
**	Returns:
1004
**	Returns:
1003
**		none
1005
**		true iff line was written successfully
1004
**
1006
**
1005
**	Side Effects:
1007
**	Side Effects:
1006
**		output of l to mci->mci_out.
1008
**		output of l to mci->mci_out.
1007
*/
1009
*/
1008
void
1010
bool
1009
putxline(l, len, mci, pxflags)
1011
putxline(l, len, mci, pxflags)
1010
	register char *l;
1012
	register char *l;
1011
	size_t len;
1013
	size_t len;
Lines 1058-1068 Link Here
1058
				if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
1060
				if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
1059
					       '.') == SM_IO_EOF)
1061
					       '.') == SM_IO_EOF)
1060
					dead = true;
1062
					dead = true;
1061
				else
1062
				{
1063
					/* record progress for DATA timeout */
1064
					DataProgress = true;
1065
				}
1066
				if (TrafficLogFile != NULL)
1063
				if (TrafficLogFile != NULL)
1067
					(void) sm_io_putc(TrafficLogFile,
1064
					(void) sm_io_putc(TrafficLogFile,
1068
							  SM_TIME_DEFAULT, '.');
1065
							  SM_TIME_DEFAULT, '.');
Lines 1075-1085 Link Here
1075
				if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
1072
				if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
1076
					       '>') == SM_IO_EOF)
1073
					       '>') == SM_IO_EOF)
1077
					dead = true;
1074
					dead = true;
1078
				else
1079
				{
1080
					/* record progress for DATA timeout */
1081
					DataProgress = true;
1082
				}
1083
				if (TrafficLogFile != NULL)
1075
				if (TrafficLogFile != NULL)
1084
					(void) sm_io_putc(TrafficLogFile,
1076
					(void) sm_io_putc(TrafficLogFile,
1085
							  SM_TIME_DEFAULT,
1077
							  SM_TIME_DEFAULT,
Lines 1091-1106 Link Here
1091
			while (l < q)
1083
			while (l < q)
1092
			{
1084
			{
1093
				if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
1085
				if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
1094
					       (unsigned char) *l++) == SM_IO_EOF)
1086
				       (unsigned char) *l++) == SM_IO_EOF)
1095
				{
1087
				{
1096
					dead = true;
1088
					dead = true;
1097
					break;
1089
					break;
1098
				}
1090
				}
1099
				else
1100
				{
1101
					/* record progress for DATA timeout */
1102
					DataProgress = true;
1103
				}
1104
			}
1091
			}
1105
			if (dead)
1092
			if (dead)
1106
				break;
1093
				break;
Lines 1116-1126 Link Here
1116
				dead = true;
1103
				dead = true;
1117
				break;
1104
				break;
1118
			}
1105
			}
1119
			else
1120
			{
1121
				/* record progress for DATA timeout */
1122
				DataProgress = true;
1123
			}
1124
			if (TrafficLogFile != NULL)
1106
			if (TrafficLogFile != NULL)
1125
			{
1107
			{
1126
				for (l = l_base; l < q; l++)
1108
				for (l = l_base; l < q; l++)
Lines 1144-1154 Link Here
1144
		{
1126
		{
1145
			if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT, '.') ==
1127
			if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT, '.') ==
1146
			    SM_IO_EOF)
1128
			    SM_IO_EOF)
1147
				break;
1148
			else
1149
			{
1129
			{
1150
				/* record progress for DATA timeout */
1130
				dead = true;
1151
				DataProgress = true;
1131
				break;
1152
			}
1132
			}
1153
			if (TrafficLogFile != NULL)
1133
			if (TrafficLogFile != NULL)
1154
				(void) sm_io_putc(TrafficLogFile,
1134
				(void) sm_io_putc(TrafficLogFile,
Lines 1161-1171 Link Here
1161
		{
1141
		{
1162
			if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT, '>') ==
1142
			if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT, '>') ==
1163
			    SM_IO_EOF)
1143
			    SM_IO_EOF)
1164
				break;
1165
			else
1166
			{
1144
			{
1167
				/* record progress for DATA timeout */
1145
				dead = true;
1168
				DataProgress = true;
1146
				break;
1169
			}
1147
			}
1170
			if (TrafficLogFile != NULL)
1148
			if (TrafficLogFile != NULL)
1171
				(void) sm_io_putc(TrafficLogFile,
1149
				(void) sm_io_putc(TrafficLogFile,
Lines 1183-1193 Link Here
1183
				dead = true;
1161
				dead = true;
1184
				break;
1162
				break;
1185
			}
1163
			}
1186
			else
1187
			{
1188
				/* record progress for DATA timeout */
1189
				DataProgress = true;
1190
			}
1191
		}
1164
		}
1192
		if (dead)
1165
		if (dead)
1193
			break;
1166
			break;
Lines 1198-1208 Link Here
1198
		if ((!bitset(PXLF_NOADDEOL, pxflags) || !noeol) &&
1171
		if ((!bitset(PXLF_NOADDEOL, pxflags) || !noeol) &&
1199
		    sm_io_fputs(mci->mci_out, SM_TIME_DEFAULT,
1172
		    sm_io_fputs(mci->mci_out, SM_TIME_DEFAULT,
1200
				mci->mci_mailer->m_eol) == SM_IO_EOF)
1173
				mci->mci_mailer->m_eol) == SM_IO_EOF)
1201
			break;
1202
		else
1203
		{
1174
		{
1204
			/* record progress for DATA timeout */
1175
			dead = true;
1205
			DataProgress = true;
1176
			break;
1206
		}
1177
		}
1207
		if (l < end && *l == '\n')
1178
		if (l < end && *l == '\n')
1208
		{
1179
		{
Lines 1211-1221 Link Here
1211
			{
1182
			{
1212
				if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
1183
				if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
1213
					       ' ') == SM_IO_EOF)
1184
					       ' ') == SM_IO_EOF)
1214
					break;
1215
				else
1216
				{
1185
				{
1217
					/* record progress for DATA timeout */
1186
					dead = true;
1218
					DataProgress = true;
1187
					break;
1219
				}
1188
				}
1220
				if (TrafficLogFile != NULL)
1189
				if (TrafficLogFile != NULL)
Lines 1224-1233 Link Here
1224
			}
1193
			}
1225
		}
1194
		}
1226
		/* record progress for DATA timeout */
1227
		DataProgress = true;
1228
	} while (l < end);
1195
	} while (l < end);
1196
	return !dead;
1229
}
1197
}
1198
1230
/*
1199
/*
1231
**  XUNLINK -- unlink a file, doing logging as appropriate.
1200
**  XUNLINK -- unlink a file, doing logging as appropriate.
1232
**
1201
**
Lines 2433-2438 Link Here
2433
				*h++ = 'r';
2405
				*h++ = 'r';
2434
				break;
2406
				break;
2435
			  default:
2407
			  default:
2408
				SM_ASSERT(l >= 2);
2436
				(void) sm_snprintf(h, l, "%03o",
2409
				(void) sm_snprintf(h, l, "%03o",
2437
					(unsigned int)((unsigned char) c));
2410
					(unsigned int)((unsigned char) c));

Return to bug 125623