envelope.c (302408) | envelope.c (38032) |
---|---|
1/* | 1/* |
2 * Copyright (c) 1998-2003, 2006 Proofpoint, Inc. and its suppliers. 3 * All rights reserved. | 2 * Copyright (c) 1998 Sendmail, Inc. All rights reserved. |
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5 * Copyright (c) 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * By using this file, you agree to the terms and conditions set 9 * forth in the LICENSE file which can be found at the top level of 10 * the sendmail distribution. 11 * 12 */ 13 | 3 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 4 * Copyright (c) 1988, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * By using this file, you agree to the terms and conditions set 8 * forth in the LICENSE file which can be found at the top level of 9 * the sendmail distribution. 10 * 11 */ 12 |
14#include <sendmail.h> | 13#ifndef lint 14static char sccsid[] = "@(#)envelope.c 8.117 (Berkeley) 6/4/98"; 15#endif /* not lint */ |
15 | 16 |
16SM_RCSID("@(#)$Id: envelope.c,v 8.313 2013-11-22 20:51:55 ca Exp $") | 17#include "sendmail.h" |
17 18/* | 18 19/* |
19** CLRSESSENVELOPE -- clear session oriented data in an envelope | 20** NEWENVELOPE -- allocate a new envelope |
20** | 21** |
21** Parameters: 22** e -- the envelope to clear. 23** 24** Returns: 25** none. 26*/ 27 28void 29clrsessenvelope(e) 30 ENVELOPE *e; 31{ 32#if SASL 33 macdefine(&e->e_macro, A_PERM, macid("{auth_type}"), ""); 34 macdefine(&e->e_macro, A_PERM, macid("{auth_authen}"), ""); 35 macdefine(&e->e_macro, A_PERM, macid("{auth_author}"), ""); 36 macdefine(&e->e_macro, A_PERM, macid("{auth_ssf}"), ""); 37#endif /* SASL */ 38#if STARTTLS 39 macdefine(&e->e_macro, A_PERM, macid("{cert_issuer}"), ""); 40 macdefine(&e->e_macro, A_PERM, macid("{cert_subject}"), ""); 41 macdefine(&e->e_macro, A_PERM, macid("{cipher_bits}"), ""); 42 macdefine(&e->e_macro, A_PERM, macid("{cipher}"), ""); 43 macdefine(&e->e_macro, A_PERM, macid("{tls_version}"), ""); 44 macdefine(&e->e_macro, A_PERM, macid("{verify}"), ""); 45 macdefine(&e->e_macro, A_PERM, macid("{alg_bits}"), ""); 46 macdefine(&e->e_macro, A_PERM, macid("{cn_issuer}"), ""); 47 macdefine(&e->e_macro, A_PERM, macid("{cn_subject}"), ""); 48#endif /* STARTTLS */ 49} 50 51/* 52** NEWENVELOPE -- fill in a new envelope 53** | |
54** Supports inheritance. 55** 56** Parameters: 57** e -- the new envelope to fill in. 58** parent -- the envelope to be the parent of e. | 22** Supports inheritance. 23** 24** Parameters: 25** e -- the new envelope to fill in. 26** parent -- the envelope to be the parent of e. |
59** rpool -- either NULL, or a pointer to a resource pool 60** from which envelope memory is allocated, and 61** to which envelope resources are attached. | |
62** 63** Returns: 64** e. 65** 66** Side Effects: 67** none. 68*/ 69 70ENVELOPE * | 27** 28** Returns: 29** e. 30** 31** Side Effects: 32** none. 33*/ 34 35ENVELOPE * |
71newenvelope(e, parent, rpool) | 36newenvelope(e, parent) |
72 register ENVELOPE *e; 73 register ENVELOPE *parent; | 37 register ENVELOPE *e; 38 register ENVELOPE *parent; |
74 SM_RPOOL_T *rpool; | |
75{ | 39{ |
76 int sendmode; 77 78 /* 79 ** This code used to read: 80 ** if (e == parent && e->e_parent != NULL) 81 ** parent = e->e_parent; 82 ** So if e == parent && e->e_parent == NULL then we would 83 ** set e->e_parent = e, which creates a loop in the e_parent chain. 84 ** This meant macvalue() could go into an infinite loop. 85 */ 86 87 if (parent != NULL) 88 sendmode = parent->e_sendmode; 89 else 90 sendmode = DM_NOTSET; 91 92 if (e == parent) | 40 if (e == parent && e->e_parent != NULL) |
93 parent = e->e_parent; | 41 parent = e->e_parent; |
94 clearenvelope(e, true, rpool); | 42 clearenvelope(e, TRUE); |
95 if (e == CurEnv) | 43 if (e == CurEnv) |
96 memmove((char *) &e->e_from, 97 (char *) &NullAddress, 98 sizeof(e->e_from)); | 44 bcopy((char *) &NullAddress, (char *) &e->e_from, sizeof e->e_from); |
99 else | 45 else |
100 memmove((char *) &e->e_from, 101 (char *) &CurEnv->e_from, 102 sizeof(e->e_from)); | 46 bcopy((char *) &CurEnv->e_from, (char *) &e->e_from, sizeof e->e_from); |
103 e->e_parent = parent; | 47 e->e_parent = parent; |
104 assign_queueid(e); | |
105 e->e_ctime = curtime(); | 48 e->e_ctime = curtime(); |
106#if _FFR_SESSID 107 e->e_sessid = e->e_id; 108#endif /* _FFR_SESSID */ | |
109 if (parent != NULL) | 49 if (parent != NULL) |
110 { | |
111 e->e_msgpriority = parent->e_msgsize; | 50 e->e_msgpriority = parent->e_msgsize; |
112#if _FFR_SESSID 113 if (parent->e_sessid != NULL) 114 e->e_sessid = sm_rpool_strdup_x(rpool, 115 parent->e_sessid); 116#endif /* _FFR_SESSID */ 117 118 if (parent->e_quarmsg == NULL) 119 { 120 e->e_quarmsg = NULL; 121 macdefine(&e->e_macro, A_PERM, 122 macid("{quarantine}"), ""); 123 } 124 else 125 { 126 e->e_quarmsg = sm_rpool_strdup_x(rpool, 127 parent->e_quarmsg); 128 macdefine(&e->e_macro, A_PERM, 129 macid("{quarantine}"), e->e_quarmsg); 130 } 131 } | |
132 e->e_puthdr = putheader; 133 e->e_putbody = putbody; 134 if (CurEnv->e_xfp != NULL) | 51 e->e_puthdr = putheader; 52 e->e_putbody = putbody; 53 if (CurEnv->e_xfp != NULL) |
135 (void) sm_io_flush(CurEnv->e_xfp, SM_TIME_DEFAULT); 136 if (sendmode != DM_NOTSET) 137 set_delivery_mode(sendmode, e); | 54 (void) fflush(CurEnv->e_xfp); |
138 | 55 |
139 return e; | 56 return (e); |
140} | 57} |
141 142/* values for msg_timeout, see also IS_* below for usage (bit layout) */ 143#define MSG_T_O 0x01 /* normal timeout */ 144#define MSG_T_O_NOW 0x02 /* NOW timeout */ 145#define MSG_NOT_BY 0x04 /* Deliver-By time exceeded, mode R */ 146#define MSG_WARN 0x10 /* normal queue warning */ 147#define MSG_WARN_BY 0x20 /* Deliver-By time exceeded, mode N */ 148 149#define IS_MSG_ERR(x) (((x) & 0x0f) != 0) /* return an error */ 150 151/* immediate return */ 152#define IS_IMM_RET(x) (((x) & (MSG_T_O_NOW|MSG_NOT_BY)) != 0) 153#define IS_MSG_WARN(x) (((x) & 0xf0) != 0) /* return a warning */ 154 155/* | 58/* |
156** DROPENVELOPE -- deallocate an envelope. 157** 158** Parameters: 159** e -- the envelope to deallocate. 160** fulldrop -- if set, do return receipts. | 59** DROPENVELOPE -- deallocate an envelope. 60** 61** Parameters: 62** e -- the envelope to deallocate. 63** fulldrop -- if set, do return receipts. |
161** split -- if true, split by recipient if message is queued up | |
162** 163** Returns: | 64** 65** Returns: |
164** EX_* status (currently: 0: success, EX_IOERR on panic) | 66** none. |
165** 166** Side Effects: 167** housekeeping necessary to dispose of an envelope. 168** Unlocks this queue file. 169*/ 170 | 67** 68** Side Effects: 69** housekeeping necessary to dispose of an envelope. 70** Unlocks this queue file. 71*/ 72 |
171int 172dropenvelope(e, fulldrop, split) | 73void 74dropenvelope(e, fulldrop) |
173 register ENVELOPE *e; 174 bool fulldrop; | 75 register ENVELOPE *e; 76 bool fulldrop; |
175 bool split; | |
176{ | 77{ |
177 bool panic = false; 178 bool queueit = false; 179 int msg_timeout = 0; 180 bool failure_return = false; 181 bool delay_return = false; 182 bool success_return = false; 183 bool pmnotify = bitset(EF_PM_NOTIFY, e->e_flags); 184 bool done = false; | 78 bool queueit = FALSE; 79 bool message_timeout = FALSE; 80 bool failure_return = FALSE; 81 bool delay_return = FALSE; 82 bool success_return = FALSE; |
185 register ADDRESS *q; 186 char *id = e->e_id; | 83 register ADDRESS *q; 84 char *id = e->e_id; |
187 time_t now; | |
188 char buf[MAXLINE]; 189 190 if (tTd(50, 1)) 191 { | 85 char buf[MAXLINE]; 86 87 if (tTd(50, 1)) 88 { |
192 sm_dprintf("dropenvelope %p: id=", e); 193 xputs(sm_debug_file(), e->e_id); 194 sm_dprintf(", flags="); | 89 extern void printenvflags __P((ENVELOPE *)); 90 91 printf("dropenvelope %lx: id=", (u_long) e); 92 xputs(e->e_id); 93 printf(", flags="); |
195 printenvflags(e); 196 if (tTd(50, 10)) 197 { | 94 printenvflags(e); 95 if (tTd(50, 10)) 96 { |
198 sm_dprintf("sendq="); 199 printaddr(sm_debug_file(), e->e_sendqueue, true); | 97 printf("sendq="); 98 printaddr(e->e_sendqueue, TRUE); |
200 } 201 } 202 203 if (LogLevel > 84) 204 sm_syslog(LOG_DEBUG, id, | 99 } 100 } 101 102 if (LogLevel > 84) 103 sm_syslog(LOG_DEBUG, id, |
205 "dropenvelope, e_flags=0x%lx, OpMode=%c, pid=%d", 206 e->e_flags, OpMode, (int) CurrentPid); | 104 "dropenvelope, e_flags=0x%x, OpMode=%c, pid=%d", 105 e->e_flags, OpMode, getpid()); |
207 208 /* we must have an id to remove disk files */ 209 if (id == NULL) | 106 107 /* we must have an id to remove disk files */ 108 if (id == NULL) |
210 return EX_OK; | 109 return; |
211 212 /* if verify-only mode, we can skip most of this */ 213 if (OpMode == MD_VERIFY) 214 goto simpledrop; 215 | 110 111 /* if verify-only mode, we can skip most of this */ 112 if (OpMode == MD_VERIFY) 113 goto simpledrop; 114 |
216 if (tTd(92, 2)) 217 sm_dprintf("dropenvelope: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n", 218 e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel); | |
219 if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) 220 logsender(e, NULL); 221 e->e_flags &= ~EF_LOGSENDER; 222 223 /* post statistics */ 224 poststats(StatFile); 225 226 /* 227 ** Extract state information from dregs of send list. 228 */ 229 | 115 if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) 116 logsender(e, NULL); 117 e->e_flags &= ~EF_LOGSENDER; 118 119 /* post statistics */ 120 poststats(StatFile); 121 122 /* 123 ** Extract state information from dregs of send list. 124 */ 125 |
230 now = curtime(); 231 if (now >= e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass]) 232 msg_timeout = MSG_T_O; 233 if (IS_DLVR_RETURN(e) && e->e_deliver_by > 0 && 234 now >= e->e_ctime + e->e_deliver_by && 235 !bitset(EF_RESPONSE, e->e_flags)) 236 { 237 msg_timeout = MSG_NOT_BY; 238 e->e_flags |= EF_FATALERRS|EF_CLRQUEUE; 239 } 240 else if (TimeOuts.to_q_return[e->e_timeoutclass] == NOW && 241 !bitset(EF_RESPONSE, e->e_flags)) 242 { 243 msg_timeout = MSG_T_O_NOW; 244 e->e_flags |= EF_FATALERRS|EF_CLRQUEUE; 245 } | 126 if (curtime() > e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass]) 127 message_timeout = TRUE; |
246 | 128 |
247#if _FFR_PROXY 248 if (tTd(87, 2)) 249 { 250 q = e->e_sendqueue; 251 sm_dprintf("dropenvelope: mode=%c, e=%p, sibling=%p, nrcpts=%d, sendqueue=%p, next=%p, state=%d\n", 252 e->e_sendmode, e, e->e_sibling, e->e_nrcpts, q, 253 (q == NULL) ? (void *)0 : q->q_next, 254 (q == NULL) ? -1 : q->q_state); 255 } 256#endif /* _FFR_PROXY */ 257 | |
258 e->e_flags &= ~EF_QUEUERUN; 259 for (q = e->e_sendqueue; q != NULL; q = q->q_next) 260 { | 129 e->e_flags &= ~EF_QUEUERUN; 130 for (q = e->e_sendqueue; q != NULL; q = q->q_next) 131 { |
261 if (QS_IS_UNDELIVERED(q->q_state)) 262 queueit = true; | 132 if (bitset(QQUEUEUP, q->q_flags) && 133 bitset(QDONTSEND, q->q_flags)) 134 { 135 /* I'm not sure how this happens..... */ 136 if (tTd(50, 2)) 137 { 138 printf("Bogus flags: "); 139 printaddr(q, FALSE); 140 } 141 q->q_flags &= ~QDONTSEND; 142 } 143 if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags)) 144 queueit = TRUE; 145#if XDEBUG 146 else if (bitset(QQUEUEUP, q->q_flags)) 147 sm_syslog(LOG_DEBUG, e->e_id, 148 "dropenvelope: q_flags = %x, paddr = %s", 149 q->q_flags, q->q_paddr); 150#endif |
263 | 151 |
264#if _FFR_PROXY 265 if (queueit && e->e_sendmode == SM_PROXY) 266 queueit = false; 267#endif /* _FFR_PROXY */ 268 | |
269 /* see if a notification is needed */ 270 if (bitset(QPINGONFAILURE, q->q_flags) && | 152 /* see if a notification is needed */ 153 if (bitset(QPINGONFAILURE, q->q_flags) && |
271 ((IS_MSG_ERR(msg_timeout) && 272 QS_IS_UNDELIVERED(q->q_state)) || 273 QS_IS_BADADDR(q->q_state) || 274 IS_IMM_RET(msg_timeout))) | 154 ((message_timeout && bitset(QQUEUEUP, q->q_flags)) || 155 bitset(QBADADDR, q->q_flags))) |
275 { | 156 { |
276 failure_return = true; 277 if (!done && q->q_owner == NULL && 278 !emptyaddr(&e->e_from)) 279 { | 157 failure_return = TRUE; 158 if (q->q_owner == NULL && !emptyaddr(&e->e_from)) |
280 (void) sendtolist(e->e_from.q_paddr, NULLADDR, 281 &e->e_errorqueue, 0, e); | 159 (void) sendtolist(e->e_from.q_paddr, NULLADDR, 160 &e->e_errorqueue, 0, e); |
282 done = true; 283 } | |
284 } | 161 } |
285 else if ((bitset(QPINGONSUCCESS, q->q_flags) && 286 ((QS_IS_SENT(q->q_state) && 287 bitnset(M_LOCALMAILER, q->q_mailer->m_flags)) || 288 bitset(QRELAYED|QEXPANDED|QDELIVERED, q->q_flags))) || 289 bitset(QBYTRACE, q->q_flags) || 290 bitset(QBYNRELAY, q->q_flags)) | 162 else if (bitset(QPINGONSUCCESS, q->q_flags) && 163 ((bitset(QSENT, q->q_flags) && 164 bitnset(M_LOCALMAILER, q->q_mailer->m_flags)) || 165 bitset(QRELAYED|QEXPANDED|QDELIVERED, q->q_flags))) |
291 { | 166 { |
292 success_return = true; | 167 success_return = TRUE; |
293 } 294 } 295 296 if (e->e_class < 0) 297 e->e_flags |= EF_NO_BODY_RETN; 298 299 /* 300 ** See if the message timed out. 301 */ 302 303 if (!queueit) | 168 } 169 } 170 171 if (e->e_class < 0) 172 e->e_flags |= EF_NO_BODY_RETN; 173 174 /* 175 ** See if the message timed out. 176 */ 177 178 if (!queueit) |
304 /* EMPTY */ | |
305 /* nothing to do */ ; | 179 /* nothing to do */ ; |
306 else if (IS_MSG_ERR(msg_timeout)) | 180 else if (message_timeout) |
307 { 308 if (failure_return) 309 { | 181 { 182 if (failure_return) 183 { |
310 if (msg_timeout == MSG_NOT_BY) 311 { 312 (void) sm_snprintf(buf, sizeof(buf), 313 "delivery time expired %lds", 314 e->e_deliver_by); 315 } 316 else 317 { 318 (void) sm_snprintf(buf, sizeof(buf), 319 "Cannot send message for %s", 320 pintvl(TimeOuts.to_q_return[e->e_timeoutclass], 321 false)); 322 } 323 324 /* don't free, allocated from e_rpool */ 325 e->e_message = sm_rpool_strdup_x(e->e_rpool, buf); | 184 (void) snprintf(buf, sizeof buf, 185 "Cannot send message within %s", 186 pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); 187 if (e->e_message != NULL) 188 free(e->e_message); 189 e->e_message = newstr(buf); |
326 message(buf); 327 e->e_flags |= EF_CLRQUEUE; 328 } | 190 message(buf); 191 e->e_flags |= EF_CLRQUEUE; 192 } |
329 if (msg_timeout == MSG_NOT_BY) 330 { 331 (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 332 "Delivery time (%lds) expired\n", 333 e->e_deliver_by); 334 } 335 else 336 (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 337 "Message could not be delivered for %s\n", 338 pintvl(TimeOuts.to_q_return[e->e_timeoutclass], 339 false)); 340 (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 341 "Message will be deleted from queue\n"); | 193 fprintf(e->e_xfp, "Message could not be delivered for %s\n", 194 pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); 195 fprintf(e->e_xfp, "Message will be deleted from queue\n"); |
342 for (q = e->e_sendqueue; q != NULL; q = q->q_next) 343 { | 196 for (q = e->e_sendqueue; q != NULL; q = q->q_next) 197 { |
344 if (QS_IS_UNDELIVERED(q->q_state)) | 198 if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags)) |
345 { | 199 { |
346 q->q_state = QS_BADADDR; 347 if (msg_timeout == MSG_NOT_BY) 348 q->q_status = "5.4.7"; 349 else 350 q->q_status = "4.4.7"; | 200 q->q_flags |= QBADADDR; 201 q->q_status = "4.4.7"; |
351 } 352 } 353 } | 202 } 203 } 204 } |
354 else | 205 else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 && 206 curtime() > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass]) |
355 { | 207 { |
356 if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 && 357 now >= e->e_ctime + 358 TimeOuts.to_q_warning[e->e_timeoutclass]) 359 msg_timeout = MSG_WARN; 360 else if (IS_DLVR_NOTIFY(e) && 361 e->e_deliver_by > 0 && 362 now >= e->e_ctime + e->e_deliver_by) 363 msg_timeout = MSG_WARN_BY; 364 365 if (IS_MSG_WARN(msg_timeout)) | 208 if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && 209 e->e_class >= 0 && 210 e->e_from.q_paddr != NULL && 211 strcmp(e->e_from.q_paddr, "<>") != 0 && 212 strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 && 213 (strlen(e->e_from.q_paddr) <= (SIZE_T) 8 || 214 strcasecmp(&e->e_from.q_paddr[strlen(e->e_from.q_paddr) - 8], "-request") != 0)) |
366 { | 215 { |
367 if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && 368 e->e_class >= 0 && 369 e->e_from.q_paddr != NULL && 370 strcmp(e->e_from.q_paddr, "<>") != 0 && 371 sm_strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 && 372 (strlen(e->e_from.q_paddr) <= 8 || 373 sm_strcasecmp(&e->e_from.q_paddr[strlen(e->e_from.q_paddr) - 8], 374 "-request") != 0)) | 216 for (q = e->e_sendqueue; q != NULL; q = q->q_next) |
375 { | 217 { |
376 for (q = e->e_sendqueue; q != NULL; 377 q = q->q_next) | 218 if (bitset(QQUEUEUP, q->q_flags) && 219 bitset(QPINGONDELAY, q->q_flags)) |
378 { | 220 { |
379 if (QS_IS_UNDELIVERED(q->q_state) 380#if _FFR_NODELAYDSN_ON_HOLD 381 && !bitnset(M_HOLD, 382 q->q_mailer->m_flags) 383#endif /* _FFR_NODELAYDSN_ON_HOLD */ 384 ) 385 { 386 if (msg_timeout == 387 MSG_WARN_BY && 388 (bitset(QPINGONDELAY, 389 q->q_flags) || 390 !bitset(QHASNOTIFY, 391 q->q_flags)) 392 ) 393 { 394 q->q_flags |= QBYNDELAY; 395 delay_return = true; 396 } 397 if (bitset(QPINGONDELAY, 398 q->q_flags)) 399 { 400 q->q_flags |= QDELAYED; 401 delay_return = true; 402 } 403 } | 221 q->q_flags |= QDELAYED; 222 delay_return = TRUE; |
404 } 405 } | 223 } 224 } |
406 if (delay_return) 407 { 408 if (msg_timeout == MSG_WARN_BY) 409 { 410 (void) sm_snprintf(buf, sizeof(buf), 411 "Warning: Delivery time (%lds) exceeded", 412 e->e_deliver_by); 413 } 414 else 415 (void) sm_snprintf(buf, sizeof(buf), 416 "Warning: could not send message for past %s", 417 pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], 418 false)); 419 420 /* don't free, allocated from e_rpool */ 421 e->e_message = sm_rpool_strdup_x(e->e_rpool, 422 buf); 423 message(buf); 424 e->e_flags |= EF_WARNING; 425 } 426 if (msg_timeout == MSG_WARN_BY) 427 { 428 (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 429 "Warning: Delivery time (%lds) exceeded\n", 430 e->e_deliver_by); 431 } 432 else 433 (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 434 "Warning: message still undelivered after %s\n", 435 pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], 436 false)); 437 (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 438 "Will keep trying until message is %s old\n", 439 pintvl(TimeOuts.to_q_return[e->e_timeoutclass], 440 false)); | |
441 } | 225 } |
226 if (delay_return) 227 { 228 (void) snprintf(buf, sizeof buf, 229 "Warning: could not send message for past %s", 230 pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE)); 231 if (e->e_message != NULL) 232 free(e->e_message); 233 e->e_message = newstr(buf); 234 message(buf); 235 e->e_flags |= EF_WARNING; 236 } 237 fprintf(e->e_xfp, 238 "Warning: message still undelivered after %s\n", 239 pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE)); 240 fprintf(e->e_xfp, "Will keep trying until message is %s old\n", 241 pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); |
|
442 } 443 444 if (tTd(50, 2)) | 242 } 243 244 if (tTd(50, 2)) |
445 sm_dprintf("failure_return=%d delay_return=%d success_return=%d queueit=%d\n", | 245 printf("failure_return=%d delay_return=%d success_return=%d queueit=%d\n", |
446 failure_return, delay_return, success_return, queueit); 447 448 /* 449 ** If we had some fatal error, but no addresses are marked as 450 ** bad, mark them _all_ as bad. 451 */ 452 453 if (bitset(EF_FATALERRS, e->e_flags) && !failure_return) 454 { 455 for (q = e->e_sendqueue; q != NULL; q = q->q_next) 456 { | 246 failure_return, delay_return, success_return, queueit); 247 248 /* 249 ** If we had some fatal error, but no addresses are marked as 250 ** bad, mark them _all_ as bad. 251 */ 252 253 if (bitset(EF_FATALERRS, e->e_flags) && !failure_return) 254 { 255 for (q = e->e_sendqueue; q != NULL; q = q->q_next) 256 { |
457 if ((QS_IS_OK(q->q_state) || 458 QS_IS_VERIFIED(q->q_state)) && | 257 if (!bitset(QDONTSEND, q->q_flags) && |
459 bitset(QPINGONFAILURE, q->q_flags)) 460 { | 258 bitset(QPINGONFAILURE, q->q_flags)) 259 { |
461 failure_return = true; 462 q->q_state = QS_BADADDR; | 260 failure_return = TRUE; 261 q->q_flags |= QBADADDR; |
463 } 464 } 465 } 466 467 /* 468 ** Send back return receipts as requested. 469 */ 470 471 if (success_return && !failure_return && !delay_return && fulldrop && 472 !bitset(PRIV_NORECEIPTS, PrivacyFlags) && 473 strcmp(e->e_from.q_paddr, "<>") != 0) 474 { 475 auto ADDRESS *rlist = NULL; 476 477 if (tTd(50, 8)) | 262 } 263 } 264 } 265 266 /* 267 ** Send back return receipts as requested. 268 */ 269 270 if (success_return && !failure_return && !delay_return && fulldrop && 271 !bitset(PRIV_NORECEIPTS, PrivacyFlags) && 272 strcmp(e->e_from.q_paddr, "<>") != 0) 273 { 274 auto ADDRESS *rlist = NULL; 275 276 if (tTd(50, 8)) |
478 sm_dprintf("dropenvelope(%s): sending return receipt\n", 479 id); | 277 printf("dropenvelope(%s): sending return receipt\n", id); |
480 e->e_flags |= EF_SENDRECEIPT; 481 (void) sendtolist(e->e_from.q_paddr, NULLADDR, &rlist, 0, e); 482 (void) returntosender("Return receipt", rlist, RTSF_NO_BODY, e); 483 } 484 e->e_flags &= ~EF_SENDRECEIPT; 485 486 /* 487 ** Arrange to send error messages if there are fatal errors. 488 */ 489 490 if ((failure_return || delay_return) && e->e_errormode != EM_QUIET) 491 { | 278 e->e_flags |= EF_SENDRECEIPT; 279 (void) sendtolist(e->e_from.q_paddr, NULLADDR, &rlist, 0, e); 280 (void) returntosender("Return receipt", rlist, RTSF_NO_BODY, e); 281 } 282 e->e_flags &= ~EF_SENDRECEIPT; 283 284 /* 285 ** Arrange to send error messages if there are fatal errors. 286 */ 287 288 if ((failure_return || delay_return) && e->e_errormode != EM_QUIET) 289 { |
290 extern void savemail __P((ENVELOPE *, bool)); 291 |
|
492 if (tTd(50, 8)) | 292 if (tTd(50, 8)) |
493 sm_dprintf("dropenvelope(%s): saving mail\n", id); 494 panic = savemail(e, !bitset(EF_NO_BODY_RETN, e->e_flags)); | 293 printf("dropenvelope(%s): saving mail\n", id); 294 savemail(e, !bitset(EF_NO_BODY_RETN, e->e_flags)); |
495 } 496 497 /* 498 ** Arrange to send warning messages to postmaster as requested. 499 */ 500 | 295 } 296 297 /* 298 ** Arrange to send warning messages to postmaster as requested. 299 */ 300 |
501 if ((failure_return || pmnotify) && | 301 if ((failure_return || bitset(EF_PM_NOTIFY, e->e_flags)) && |
502 PostMasterCopy != NULL && | 302 PostMasterCopy != NULL && |
503 !bitset(EF_RESPONSE, e->e_flags) && 504 e->e_class >= 0) | 303 !bitset(EF_RESPONSE, e->e_flags) && e->e_class >= 0) |
505 { 506 auto ADDRESS *rlist = NULL; | 304 { 305 auto ADDRESS *rlist = NULL; |
507 char pcopy[MAXNAME]; | |
508 | 306 |
509 if (failure_return) 510 { 511 expand(PostMasterCopy, pcopy, sizeof(pcopy), e); 512 513 if (tTd(50, 8)) 514 sm_dprintf("dropenvelope(%s): sending postmaster copy to %s\n", 515 id, pcopy); 516 (void) sendtolist(pcopy, NULLADDR, &rlist, 0, e); 517 } 518 if (pmnotify) 519 (void) sendtolist("postmaster", NULLADDR, 520 &rlist, 0, e); 521 (void) returntosender(e->e_message, rlist, 522 RTSF_PM_BOUNCE|RTSF_NO_BODY, e); | 307 if (tTd(50, 8)) 308 printf("dropenvelope(%s): sending postmaster copy\n", id); 309 (void) sendtolist(PostMasterCopy, NULLADDR, &rlist, 0, e); 310 (void) returntosender(e->e_message, rlist, RTSF_PM_BOUNCE, e); |
523 } 524 525 /* 526 ** Instantiate or deinstantiate the queue. 527 */ 528 529simpledrop: 530 if (tTd(50, 8)) | 311 } 312 313 /* 314 ** Instantiate or deinstantiate the queue. 315 */ 316 317simpledrop: 318 if (tTd(50, 8)) |
531 sm_dprintf("dropenvelope(%s): at simpledrop, queueit=%d\n", | 319 printf("dropenvelope(%s): at simpledrop, queueit=%d\n", |
532 id, queueit); 533 if (!queueit || bitset(EF_CLRQUEUE, e->e_flags)) 534 { 535 if (tTd(50, 1)) 536 { | 320 id, queueit); 321 if (!queueit || bitset(EF_CLRQUEUE, e->e_flags)) 322 { 323 if (tTd(50, 1)) 324 { |
537 sm_dprintf("\n===== Dropping queue files for %s... queueit=%d, e_flags=", | 325 extern void printenvflags __P((ENVELOPE *)); 326 327 printf("\n===== Dropping [dq]f%s... queueit=%d, e_flags=", |
538 e->e_id, queueit); 539 printenvflags(e); 540 } | 328 e->e_id, queueit); 329 printenvflags(e); 330 } |
541 if (!panic) 542 { 543 if (e->e_dfp != NULL) 544 { 545 (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); 546 e->e_dfp = NULL; 547 } 548 (void) xunlink(queuename(e, DATAFL_LETTER)); 549 } 550 if (panic && QueueMode == QM_LOST) 551 { 552 /* 553 ** leave the Qf file behind as 554 ** the delivery attempt failed. 555 */ | 331 xunlink(queuename(e, 'd')); 332 xunlink(queuename(e, 'q')); |
556 | 333 |
557 /* EMPTY */ 558 } 559 else 560 if (xunlink(queuename(e, ANYQFL_LETTER)) == 0) 561 { 562 /* add to available space in filesystem */ 563 updfs(e, -1, panic ? 0 : -1, "dropenvelope"); 564 } 565 566 if (e->e_ntries > 0 && LogLevel > 9) 567 sm_syslog(LOG_INFO, id, "done; delay=%s, ntries=%d", 568 pintvl(curtime() - e->e_ctime, true), 569 e->e_ntries); | 334 if (LogLevel > 10) 335 sm_syslog(LOG_INFO, id, "done"); |
570 } 571 else if (queueit || !bitset(EF_INQUEUE, e->e_flags)) 572 { | 336 } 337 else if (queueit || !bitset(EF_INQUEUE, e->e_flags)) 338 { |
573 if (!split) 574 queueup(e, false, true); 575 else 576 { 577 ENVELOPE *oldsib; 578 ENVELOPE *ee; 579 580 /* 581 ** Save old sibling and set it to NULL to avoid 582 ** queueing up the same envelopes again. 583 ** This requires that envelopes in that list have 584 ** been take care of before (or at some other place). 585 */ 586 587 oldsib = e->e_sibling; 588 e->e_sibling = NULL; 589 if (!split_by_recipient(e) && 590 bitset(EF_FATALERRS, e->e_flags)) 591 { 592 syserr("!dropenvelope(%s): cannot commit data file %s, uid=%ld", 593 e->e_id, queuename(e, DATAFL_LETTER), 594 (long) geteuid()); 595 } 596 for (ee = e->e_sibling; ee != NULL; ee = ee->e_sibling) 597 queueup(ee, false, true); 598 queueup(e, false, true); 599 600 /* clean up */ 601 for (ee = e->e_sibling; ee != NULL; ee = ee->e_sibling) 602 { 603 /* now unlock the job */ 604 if (tTd(50, 8)) 605 sm_dprintf("dropenvelope(%s): unlocking job\n", 606 ee->e_id); 607 closexscript(ee); 608 unlockqueue(ee); 609 610 /* this envelope is marked unused */ 611 if (ee->e_dfp != NULL) 612 { 613 (void) sm_io_close(ee->e_dfp, 614 SM_TIME_DEFAULT); 615 ee->e_dfp = NULL; 616 } 617 ee->e_id = NULL; 618 ee->e_flags &= ~EF_HAS_DF; 619 } 620 e->e_sibling = oldsib; 621 } | 339#if QUEUE 340 queueup(e, FALSE); 341#else /* QUEUE */ 342 syserr("554 dropenvelope: queueup"); 343#endif /* QUEUE */ |
622 } 623 624 /* now unlock the job */ 625 if (tTd(50, 8)) | 344 } 345 346 /* now unlock the job */ 347 if (tTd(50, 8)) |
626 sm_dprintf("dropenvelope(%s): unlocking job\n", id); | 348 printf("dropenvelope(%s): unlocking job\n", id); |
627 closexscript(e); 628 unlockqueue(e); 629 630 /* make sure that this envelope is marked unused */ 631 if (e->e_dfp != NULL) | 349 closexscript(e); 350 unlockqueue(e); 351 352 /* make sure that this envelope is marked unused */ 353 if (e->e_dfp != NULL) |
632 { 633 (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); 634 e->e_dfp = NULL; 635 } | 354 (void) xfclose(e->e_dfp, "dropenvelope df", e->e_id); 355 e->e_dfp = NULL; |
636 e->e_id = NULL; 637 e->e_flags &= ~EF_HAS_DF; | 356 e->e_id = NULL; 357 e->e_flags &= ~EF_HAS_DF; |
638 if (panic) 639 return EX_IOERR; 640 return EX_OK; | |
641} | 358} |
642 643/* | 359/* |
644** CLEARENVELOPE -- clear an envelope without unlocking 645** 646** This is normally used by a child process to get a clean 647** envelope without disturbing the parent. 648** 649** Parameters: 650** e -- the envelope to clear. 651** fullclear - if set, the current envelope is total 652** garbage and should be ignored; otherwise, 653** release any resources it may indicate. | 360** CLEARENVELOPE -- clear an envelope without unlocking 361** 362** This is normally used by a child process to get a clean 363** envelope without disturbing the parent. 364** 365** Parameters: 366** e -- the envelope to clear. 367** fullclear - if set, the current envelope is total 368** garbage and should be ignored; otherwise, 369** release any resources it may indicate. |
654** rpool -- either NULL, or a pointer to a resource pool 655** from which envelope memory is allocated, and 656** to which envelope resources are attached. | |
657** 658** Returns: 659** none. 660** 661** Side Effects: 662** Closes files associated with the envelope. 663** Marks the envelope as unallocated. 664*/ 665 666void | 370** 371** Returns: 372** none. 373** 374** Side Effects: 375** Closes files associated with the envelope. 376** Marks the envelope as unallocated. 377*/ 378 379void |
667clearenvelope(e, fullclear, rpool) | 380clearenvelope(e, fullclear) |
668 register ENVELOPE *e; 669 bool fullclear; | 381 register ENVELOPE *e; 382 bool fullclear; |
670 SM_RPOOL_T *rpool; | |
671{ 672 register HDR *bh; 673 register HDR **nhp; 674 extern ENVELOPE BlankEnvelope; | 383{ 384 register HDR *bh; 385 register HDR **nhp; 386 extern ENVELOPE BlankEnvelope; |
675 char **p; | |
676 677 if (!fullclear) 678 { 679 /* clear out any file information */ 680 if (e->e_xfp != NULL) | 387 388 if (!fullclear) 389 { 390 /* clear out any file information */ 391 if (e->e_xfp != NULL) |
681 (void) sm_io_close(e->e_xfp, SM_TIME_DEFAULT); | 392 (void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id); |
682 if (e->e_dfp != NULL) | 393 if (e->e_dfp != NULL) |
683 (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); | 394 (void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_id); |
684 e->e_xfp = e->e_dfp = NULL; 685 } 686 | 395 e->e_xfp = e->e_dfp = NULL; 396 } 397 |
687 /* 688 ** Copy BlankEnvelope into *e. 689 ** It is not safe to simply copy pointers to strings; 690 ** the strings themselves must be copied (or set to NULL). 691 ** The problem is that when we assign a new string value to 692 ** a member of BlankEnvelope, we free the old string. 693 ** We did not need to do this copying in sendmail 8.11 :-( 694 ** and it is a potential performance hit. Reference counted 695 ** strings are one way out. 696 */ 697 698 *e = BlankEnvelope; | 398 /* now clear out the data */ 399 STRUCTCOPY(BlankEnvelope, *e); |
699 e->e_message = NULL; | 400 e->e_message = NULL; |
700 e->e_qfletter = '\0'; 701 e->e_quarmsg = NULL; 702 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), ""); 703 704 /* 705 ** Copy the macro table. 706 ** We might be able to avoid this by zeroing the macro table 707 ** and always searching BlankEnvelope.e_macro after e->e_macro 708 ** in macvalue(). 709 */ 710 711 for (p = &e->e_macro.mac_table[0]; 712 p <= &e->e_macro.mac_table[MAXMACROID]; 713 ++p) 714 { 715 if (*p != NULL) 716 *p = sm_rpool_strdup_x(rpool, *p); 717 } 718 719 /* 720 ** XXX There are many strings in the envelope structure 721 ** XXX that we are not attempting to copy here. 722 ** XXX Investigate this further. 723 */ 724 725 e->e_rpool = rpool; 726 e->e_macro.mac_rpool = rpool; | |
727 if (Verbose) | 401 if (Verbose) |
728 set_delivery_mode(SM_DELIVER, e); | 402 e->e_sendmode = SM_DELIVER; |
729 bh = BlankEnvelope.e_header; 730 nhp = &e->e_header; 731 while (bh != NULL) 732 { | 403 bh = BlankEnvelope.e_header; 404 nhp = &e->e_header; 405 while (bh != NULL) 406 { |
733 *nhp = (HDR *) sm_rpool_malloc_x(rpool, sizeof(*bh)); 734 memmove((char *) *nhp, (char *) bh, sizeof(*bh)); | 407 *nhp = (HDR *) xalloc(sizeof *bh); 408 bcopy((char *) bh, (char *) *nhp, sizeof *bh); |
735 bh = bh->h_link; 736 nhp = &(*nhp)->h_link; 737 } | 409 bh = bh->h_link; 410 nhp = &(*nhp)->h_link; 411 } |
738#if _FFR_MILTER_ENHSC 739 e->e_enhsc[0] = '\0'; 740#endif /* _FFR_MILTER_ENHSC */ | |
741} | 412} |
742/* | 413/* |
743** INITSYS -- initialize instantiation of system 744** 745** In Daemon mode, this is done in the child. 746** 747** Parameters: | 414** INITSYS -- initialize instantiation of system 415** 416** In Daemon mode, this is done in the child. 417** 418** Parameters: |
748** e -- the envelope to use. | 419** none. |
749** 750** Returns: 751** none. 752** 753** Side Effects: 754** Initializes the system macros, some global variables, 755** etc. In particular, the current time in various 756** forms is set. 757*/ 758 759void 760initsys(e) 761 register ENVELOPE *e; 762{ | 420** 421** Returns: 422** none. 423** 424** Side Effects: 425** Initializes the system macros, some global variables, 426** etc. In particular, the current time in various 427** forms is set. 428*/ 429 430void 431initsys(e) 432 register ENVELOPE *e; 433{ |
763 char buf[10]; | 434 char cbuf[5]; /* holds hop count */ 435 char pbuf[10]; /* holds pid */ |
764#ifdef TTYNAME 765 static char ybuf[60]; /* holds tty id */ 766 register char *p; 767 extern char *ttyname(); 768#endif /* TTYNAME */ | 436#ifdef TTYNAME 437 static char ybuf[60]; /* holds tty id */ 438 register char *p; 439 extern char *ttyname(); 440#endif /* TTYNAME */ |
441 extern void settime __P((ENVELOPE *)); |
|
769 770 /* 771 ** Give this envelope a reality. 772 ** I.e., an id, a transcript, and a creation time. | 442 443 /* 444 ** Give this envelope a reality. 445 ** I.e., an id, a transcript, and a creation time. |
773 ** We don't select the queue until all of the recipients are known. | |
774 */ 775 776 openxscript(e); 777 e->e_ctime = curtime(); | 446 */ 447 448 openxscript(e); 449 e->e_ctime = curtime(); |
778 e->e_qfletter = '\0'; | |
779 780 /* 781 ** Set OutChannel to something useful if stdout isn't it. 782 ** This arranges that any extra stuff the mailer produces 783 ** gets sent back to the user on error (because it is 784 ** tucked away in the transcript). 785 */ 786 787 if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) && 788 e->e_xfp != NULL) 789 OutChannel = e->e_xfp; 790 791 /* 792 ** Set up some basic system macros. 793 */ 794 795 /* process id */ | 450 451 /* 452 ** Set OutChannel to something useful if stdout isn't it. 453 ** This arranges that any extra stuff the mailer produces 454 ** gets sent back to the user on error (because it is 455 ** tucked away in the transcript). 456 */ 457 458 if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) && 459 e->e_xfp != NULL) 460 OutChannel = e->e_xfp; 461 462 /* 463 ** Set up some basic system macros. 464 */ 465 466 /* process id */ |
796 (void) sm_snprintf(buf, sizeof(buf), "%d", (int) CurrentPid); 797 macdefine(&e->e_macro, A_TEMP, 'p', buf); | 467 (void) snprintf(pbuf, sizeof pbuf, "%d", getpid()); 468 define('p', newstr(pbuf), e); |
798 799 /* hop count */ | 469 470 /* hop count */ |
800 (void) sm_snprintf(buf, sizeof(buf), "%d", e->e_hopcount); 801 macdefine(&e->e_macro, A_TEMP, 'c', buf); | 471 (void) snprintf(cbuf, sizeof cbuf, "%d", e->e_hopcount); 472 define('c', newstr(cbuf), e); |
802 803 /* time as integer, unix time, arpa time */ 804 settime(e); 805 | 473 474 /* time as integer, unix time, arpa time */ 475 settime(e); 476 |
806 /* Load average */ 807 sm_getla(); 808 | |
809#ifdef TTYNAME 810 /* tty name */ 811 if (macvalue('y', e) == NULL) 812 { 813 p = ttyname(2); 814 if (p != NULL) 815 { 816 if (strrchr(p, '/') != NULL) 817 p = strrchr(p, '/') + 1; | 477#ifdef TTYNAME 478 /* tty name */ 479 if (macvalue('y', e) == NULL) 480 { 481 p = ttyname(2); 482 if (p != NULL) 483 { 484 if (strrchr(p, '/') != NULL) 485 p = strrchr(p, '/') + 1; |
818 (void) sm_strlcpy(ybuf, sizeof(ybuf), p); 819 macdefine(&e->e_macro, A_PERM, 'y', ybuf); | 486 snprintf(ybuf, sizeof ybuf, "%s", p); 487 define('y', ybuf, e); |
820 } 821 } 822#endif /* TTYNAME */ 823} | 488 } 489 } 490#endif /* TTYNAME */ 491} |
824/* | 492/* |
825** SETTIME -- set the current time. 826** 827** Parameters: | 493** SETTIME -- set the current time. 494** 495** Parameters: |
828** e -- the envelope in which the macros should be set. | 496** none. |
829** 830** Returns: 831** none. 832** 833** Side Effects: 834** Sets the various time macros -- $a, $b, $d, $t. 835*/ 836 837void 838settime(e) 839 register ENVELOPE *e; 840{ 841 register char *p; 842 auto time_t now; | 497** 498** Returns: 499** none. 500** 501** Side Effects: 502** Sets the various time macros -- $a, $b, $d, $t. 503*/ 504 505void 506settime(e) 507 register ENVELOPE *e; 508{ 509 register char *p; 510 auto time_t now; |
843 char buf[30]; | 511 char tbuf[20]; /* holds "current" time */ 512 char dbuf[30]; /* holds ctime(tbuf) */ |
844 register struct tm *tm; | 513 register struct tm *tm; |
514 extern struct tm *gmtime(); |
|
845 846 now = curtime(); | 515 516 now = curtime(); |
847 (void) sm_snprintf(buf, sizeof(buf), "%ld", (long) now); 848 macdefine(&e->e_macro, A_TEMP, macid("{time}"), buf); | |
849 tm = gmtime(&now); | 517 tm = gmtime(&now); |
850 (void) sm_snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d", 851 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 852 tm->tm_hour, tm->tm_min); 853 macdefine(&e->e_macro, A_TEMP, 't', buf); 854 (void) sm_strlcpy(buf, ctime(&now), sizeof(buf)); 855 p = strchr(buf, '\n'); | 518 (void) snprintf(tbuf, sizeof tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900, 519 tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min); 520 define('t', newstr(tbuf), e); 521 (void) strcpy(dbuf, ctime(&now)); 522 p = strchr(dbuf, '\n'); |
856 if (p != NULL) 857 *p = '\0'; | 523 if (p != NULL) 524 *p = '\0'; |
858 macdefine(&e->e_macro, A_TEMP, 'd', buf); 859 macdefine(&e->e_macro, A_TEMP, 'b', arpadate(buf)); | 525 define('d', newstr(dbuf), e); 526 p = arpadate(dbuf); 527 p = newstr(p); |
860 if (macvalue('a', e) == NULL) | 528 if (macvalue('a', e) == NULL) |
861 macdefine(&e->e_macro, A_PERM, 'a', macvalue('b', e)); | 529 define('a', p, e); 530 define('b', p, e); |
862} | 531} |
863/* | 532/* |
864** OPENXSCRIPT -- Open transcript file 865** 866** Creates a transcript file for possible eventual mailing or 867** sending back. 868** 869** Parameters: 870** e -- the envelope to create the transcript in/for. 871** 872** Returns: 873** none 874** 875** Side Effects: 876** Creates the transcript file. 877*/ 878 879#ifndef O_APPEND | 533** OPENXSCRIPT -- Open transcript file 534** 535** Creates a transcript file for possible eventual mailing or 536** sending back. 537** 538** Parameters: 539** e -- the envelope to create the transcript in/for. 540** 541** Returns: 542** none 543** 544** Side Effects: 545** Creates the transcript file. 546*/ 547 548#ifndef O_APPEND |
880# define O_APPEND 0 881#endif /* ! O_APPEND */ | 549#define O_APPEND 0 550#endif |
882 883void 884openxscript(e) 885 register ENVELOPE *e; 886{ 887 register char *p; | 551 552void 553openxscript(e) 554 register ENVELOPE *e; 555{ 556 register char *p; |
557 int fd; |
|
888 889 if (e->e_xfp != NULL) 890 return; | 558 559 if (e->e_xfp != NULL) 560 return; |
891 892#if 0 893 if (e->e_lockfp == NULL && bitset(EF_INQUEUE, e->e_flags)) 894 syserr("openxscript: job not locked"); 895#endif /* 0 */ 896 897 p = queuename(e, XSCRPT_LETTER); 898 e->e_xfp = bfopen(p, FileMode, XscriptFileBufferSize, 899 SFF_NOTEXCL|SFF_OPENASROOT); 900 901 if (e->e_xfp == NULL) | 561 p = queuename(e, 'x'); 562 fd = open(p, O_WRONLY|O_CREAT|O_APPEND, FileMode); 563 if (fd < 0) |
902 { 903 syserr("Can't create transcript file %s", p); | 564 { 565 syserr("Can't create transcript file %s", p); |
904 e->e_xfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, 905 SM_PATH_DEVNULL, SM_IO_RDWR, NULL); 906 if (e->e_xfp == NULL) 907 syserr("!Can't open %s", SM_PATH_DEVNULL); | 566 fd = open("/dev/null", O_WRONLY, 0644); 567 if (fd < 0) 568 syserr("!Can't open /dev/null"); |
908 } | 569 } |
909 (void) sm_io_setvbuf(e->e_xfp, SM_TIME_DEFAULT, NULL, SM_IO_LBF, 0); | 570 e->e_xfp = fdopen(fd, "a"); 571 if (e->e_xfp == NULL) 572 syserr("!Can't create transcript stream %s", p); 573#ifdef HASSETVBUF 574 setvbuf(e->e_xfp, NULL, _IOLBF, 0); 575#else 576 setlinebuf(e->e_xfp); 577#endif |
910 if (tTd(46, 9)) 911 { | 578 if (tTd(46, 9)) 579 { |
912 sm_dprintf("openxscript(%s):\n ", p); 913 dumpfd(sm_io_getinfo(e->e_xfp, SM_IO_WHAT_FD, NULL), true, 914 false); | 580 printf("openxscript(%s):\n ", p); 581 dumpfd(fileno(e->e_xfp), TRUE, FALSE); |
915 } 916} | 582 } 583} |
917/* | 584/* |
918** CLOSEXSCRIPT -- close the transcript file. 919** 920** Parameters: 921** e -- the envelope containing the transcript to close. 922** 923** Returns: 924** none. 925** 926** Side Effects: 927** none. 928*/ 929 930void 931closexscript(e) 932 register ENVELOPE *e; 933{ 934 if (e->e_xfp == NULL) 935 return; | 585** CLOSEXSCRIPT -- close the transcript file. 586** 587** Parameters: 588** e -- the envelope containing the transcript to close. 589** 590** Returns: 591** none. 592** 593** Side Effects: 594** none. 595*/ 596 597void 598closexscript(e) 599 register ENVELOPE *e; 600{ 601 if (e->e_xfp == NULL) 602 return; |
936#if 0 937 if (e->e_lockfp == NULL) 938 syserr("closexscript: job not locked"); 939#endif /* 0 */ 940 (void) sm_io_close(e->e_xfp, SM_TIME_DEFAULT); | 603 (void) xfclose(e->e_xfp, "closexscript", e->e_id); |
941 e->e_xfp = NULL; 942} | 604 e->e_xfp = NULL; 605} |
943/* | 606/* |
944** SETSENDER -- set the person who this message is from 945** 946** Under certain circumstances allow the user to say who 947** s/he is (using -f or -r). These are: 948** 1. The user's uid is zero (root). 949** 2. The user's login name is in an approved list (typically 950** from a network server). 951** 3. The address the user is trying to claim has a --- 32 unchanged lines hidden (view full) --- 984 char *from; 985 register ENVELOPE *e; 986 char **delimptr; 987 int delimchar; 988 bool internal; 989{ 990 register char **pvp; 991 char *realname = NULL; | 607** SETSENDER -- set the person who this message is from 608** 609** Under certain circumstances allow the user to say who 610** s/he is (using -f or -r). These are: 611** 1. The user's uid is zero (root). 612** 2. The user's login name is in an approved list (typically 613** from a network server). 614** 3. The address the user is trying to claim has a --- 32 unchanged lines hidden (view full) --- 647 char *from; 648 register ENVELOPE *e; 649 char **delimptr; 650 int delimchar; 651 bool internal; 652{ 653 register char **pvp; 654 char *realname = NULL; |
655 register struct passwd *pw; |
|
992 char *bp; 993 char buf[MAXNAME + 2]; 994 char pvpbuf[PSBUFSIZE]; 995 extern char *FullName; 996 997 if (tTd(45, 1)) | 656 char *bp; 657 char buf[MAXNAME + 2]; 658 char pvpbuf[PSBUFSIZE]; 659 extern char *FullName; 660 661 if (tTd(45, 1)) |
998 sm_dprintf("setsender(%s)\n", from == NULL ? "" : from); | 662 printf("setsender(%s)\n", from == NULL ? "" : from); |
999 | 663 |
1000 /* may be set from earlier calls */ 1001 macdefine(&e->e_macro, A_PERM, 'x', ""); 1002 | |
1003 /* 1004 ** Figure out the real user executing us. 1005 ** Username can return errno != 0 on non-errors. 1006 */ 1007 1008 if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP || 1009 OpMode == MD_ARPAFTP || OpMode == MD_DAEMON) 1010 realname = from; 1011 if (realname == NULL || realname[0] == '\0') 1012 realname = username(); 1013 1014 if (ConfigLevel < 2) | 664 /* 665 ** Figure out the real user executing us. 666 ** Username can return errno != 0 on non-errors. 667 */ 668 669 if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP || 670 OpMode == MD_ARPAFTP || OpMode == MD_DAEMON) 671 realname = from; 672 if (realname == NULL || realname[0] == '\0') 673 realname = username(); 674 675 if (ConfigLevel < 2) |
1015 SuprErrs = true; | 676 SuprErrs = TRUE; |
1016 | 677 |
1017 macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "e s"); 1018 1019 /* preset state for then clause in case from == NULL */ 1020 e->e_from.q_state = QS_BADADDR; 1021 e->e_from.q_flags = 0; | 678 e->e_from.q_flags = QBADADDR; |
1022 if (from == NULL || 1023 parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR, | 679 if (from == NULL || 680 parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR, |
1024 delimchar, delimptr, e, false) == NULL || 1025 QS_IS_BADADDR(e->e_from.q_state) || | 681 delimchar, delimptr, e) == NULL || 682 bitset(QBADADDR, e->e_from.q_flags) || |
1026 e->e_from.q_mailer == ProgMailer || 1027 e->e_from.q_mailer == FileMailer || 1028 e->e_from.q_mailer == InclMailer) 1029 { 1030 /* log garbage addresses for traceback */ 1031 if (from != NULL && LogLevel > 2) 1032 { 1033 char *p; 1034 char ebuf[MAXNAME * 2 + 2]; 1035 1036 p = macvalue('_', e); 1037 if (p == NULL) 1038 { 1039 char *host = RealHostName; 1040 1041 if (host == NULL) 1042 host = MyHostName; | 683 e->e_from.q_mailer == ProgMailer || 684 e->e_from.q_mailer == FileMailer || 685 e->e_from.q_mailer == InclMailer) 686 { 687 /* log garbage addresses for traceback */ 688 if (from != NULL && LogLevel > 2) 689 { 690 char *p; 691 char ebuf[MAXNAME * 2 + 2]; 692 693 p = macvalue('_', e); 694 if (p == NULL) 695 { 696 char *host = RealHostName; 697 698 if (host == NULL) 699 host = MyHostName; |
1043 (void) sm_snprintf(ebuf, sizeof(ebuf), 1044 "%.*s@%.*s", MAXNAME, 1045 realname, MAXNAME, host); | 700 (void) snprintf(ebuf, sizeof ebuf, "%.*s@%.*s", 701 MAXNAME, realname, 702 MAXNAME, host); |
1046 p = ebuf; 1047 } 1048 sm_syslog(LOG_NOTICE, e->e_id, | 703 p = ebuf; 704 } 705 sm_syslog(LOG_NOTICE, e->e_id, |
1049 "setsender: %s: invalid or unparsable, received from %s", 1050 shortenstring(from, 83), p); | 706 "setsender: %s: invalid or unparseable, received from %s", 707 shortenstring(from, 83), p); |
1051 } 1052 if (from != NULL) 1053 { | 708 } 709 if (from != NULL) 710 { |
1054 if (!QS_IS_BADADDR(e->e_from.q_state)) | 711 if (!bitset(QBADADDR, e->e_from.q_flags)) |
1055 { 1056 /* it was a bogus mailer in the from addr */ 1057 e->e_status = "5.1.7"; | 712 { 713 /* it was a bogus mailer in the from addr */ 714 e->e_status = "5.1.7"; |
1058 usrerrenh(e->e_status, 1059 "553 Invalid sender address"); | 715 usrerr("553 Invalid sender address"); |
1060 } | 716 } |
1061 SuprErrs = true; | 717 SuprErrs = TRUE; |
1062 } 1063 if (from == realname || | 718 } 719 if (from == realname || |
1064 parseaddr(from = realname, 1065 &e->e_from, RF_COPYALL|RF_SENDERADDR, ' ', 1066 NULL, e, false) == NULL) | 720 parseaddr(from = newstr(realname), &e->e_from, 721 RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL) |
1067 { 1068 char nbuf[100]; 1069 | 722 { 723 char nbuf[100]; 724 |
1070 SuprErrs = true; 1071 expand("\201n", nbuf, sizeof(nbuf), e); 1072 from = sm_rpool_strdup_x(e->e_rpool, nbuf); 1073 if (parseaddr(from, &e->e_from, RF_COPYALL, ' ', 1074 NULL, e, false) == NULL && | 725 SuprErrs = TRUE; 726 expand("\201n", nbuf, sizeof nbuf, e); 727 if (parseaddr(from = newstr(nbuf), &e->e_from, 728 RF_COPYALL, ' ', NULL, e) == NULL && |
1075 parseaddr(from = "postmaster", &e->e_from, | 729 parseaddr(from = "postmaster", &e->e_from, |
1076 RF_COPYALL, ' ', NULL, e, false) == NULL) 1077 syserr("553 5.3.0 setsender: can't even parse postmaster!"); | 730 RF_COPYALL, ' ', NULL, e) == NULL) 731 syserr("553 setsender: can't even parse postmaster!"); |
1078 } 1079 } 1080 else | 732 } 733 } 734 else |
1081 FromFlag = true; 1082 e->e_from.q_state = QS_SENDER; | 735 FromFlag = TRUE; 736 e->e_from.q_flags |= QDONTSEND; |
1083 if (tTd(45, 5)) 1084 { | 737 if (tTd(45, 5)) 738 { |
1085 sm_dprintf("setsender: QS_SENDER "); 1086 printaddr(sm_debug_file(), &e->e_from, false); | 739 printf("setsender: QDONTSEND "); 740 printaddr(&e->e_from, FALSE); |
1087 } | 741 } |
1088 SuprErrs = false; | 742 SuprErrs = FALSE; |
1089 | 743 |
1090#if USERDB | 744# if USERDB |
1091 if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags)) 1092 { 1093 register char *p; | 745 if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags)) 746 { 747 register char *p; |
748 extern char *udbsender __P((char *)); |
|
1094 | 749 |
1095 p = udbsender(e->e_from.q_user, e->e_rpool); | 750 p = udbsender(e->e_from.q_user); |
1096 if (p != NULL) 1097 from = p; 1098 } | 751 if (p != NULL) 752 from = p; 753 } |
1099#endif /* USERDB */ | 754# endif /* USERDB */ |
1100 1101 if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags)) 1102 { | 755 756 if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags)) 757 { |
1103 SM_MBDB_T user; 1104 | |
1105 if (!internal) 1106 { 1107 /* if the user already given fullname don't redefine */ 1108 if (FullName == NULL) 1109 FullName = macvalue('x', e); | 758 if (!internal) 759 { 760 /* if the user already given fullname don't redefine */ 761 if (FullName == NULL) 762 FullName = macvalue('x', e); |
1110 if (FullName != NULL) 1111 { 1112 if (FullName[0] == '\0') 1113 FullName = NULL; 1114 else 1115 FullName = newstr(FullName); 1116 } | 763 if (FullName != NULL && FullName[0] == '\0') 764 FullName = NULL; |
1117 } 1118 1119 if (e->e_from.q_user[0] != '\0' && | 765 } 766 767 if (e->e_from.q_user[0] != '\0' && |
1120 sm_mbdb_lookup(e->e_from.q_user, &user) == EX_OK) | 768 (pw = sm_getpwnam(e->e_from.q_user)) != NULL) |
1121 { 1122 /* 1123 ** Process passwd file entry. 1124 */ 1125 1126 /* extract home directory */ | 769 { 770 /* 771 ** Process passwd file entry. 772 */ 773 774 /* extract home directory */ |
1127 if (*user.mbdb_homedir == '\0') 1128 e->e_from.q_home = NULL; 1129 else if (strcmp(user.mbdb_homedir, "/") == 0) 1130 e->e_from.q_home = ""; | 775 if (strcmp(pw->pw_dir, "/") == 0) 776 e->e_from.q_home = newstr(""); |
1131 else | 777 else |
1132 e->e_from.q_home = sm_rpool_strdup_x(e->e_rpool, 1133 user.mbdb_homedir); 1134 macdefine(&e->e_macro, A_PERM, 'z', e->e_from.q_home); | 778 e->e_from.q_home = newstr(pw->pw_dir); 779 define('z', e->e_from.q_home, e); |
1135 1136 /* extract user and group id */ | 780 781 /* extract user and group id */ |
1137 if (user.mbdb_uid != SM_NO_UID) 1138 { 1139 e->e_from.q_uid = user.mbdb_uid; 1140 e->e_from.q_gid = user.mbdb_gid; 1141 e->e_from.q_flags |= QGOODUID; 1142 } | 782 e->e_from.q_uid = pw->pw_uid; 783 e->e_from.q_gid = pw->pw_gid; 784 e->e_from.q_flags |= QGOODUID; |
1143 1144 /* extract full name from passwd file */ | 785 786 /* extract full name from passwd file */ |
1145 if (FullName == NULL && !internal && 1146 user.mbdb_fullname[0] != '\0' && 1147 strcmp(user.mbdb_name, e->e_from.q_user) == 0) | 787 if (FullName == NULL && pw->pw_gecos != NULL && 788 strcmp(pw->pw_name, e->e_from.q_user) == 0 && 789 !internal) |
1148 { | 790 { |
1149 FullName = newstr(user.mbdb_fullname); | 791 buildfname(pw->pw_gecos, e->e_from.q_user, buf, sizeof buf); 792 if (buf[0] != '\0') 793 FullName = newstr(buf); |
1150 } 1151 } 1152 else 1153 { | 794 } 795 } 796 else 797 { |
1154 e->e_from.q_home = NULL; | 798 e->e_from.q_home = "/no/such/directory"; |
1155 } 1156 if (FullName != NULL && !internal) | 799 } 800 if (FullName != NULL && !internal) |
1157 macdefine(&e->e_macro, A_TEMP, 'x', FullName); | 801 define('x', FullName, e); |
1158 } | 802 } |
1159 else if (!internal && OpMode != MD_DAEMON && OpMode != MD_SMTP) | 803 else if (!internal && OpMode != MD_DAEMON) |
1160 { 1161 if (e->e_from.q_home == NULL) 1162 { 1163 e->e_from.q_home = getenv("HOME"); | 804 { 805 if (e->e_from.q_home == NULL) 806 { 807 e->e_from.q_home = getenv("HOME"); |
1164 if (e->e_from.q_home != NULL) 1165 { 1166 if (*e->e_from.q_home == '\0') 1167 e->e_from.q_home = NULL; 1168 else if (strcmp(e->e_from.q_home, "/") == 0) 1169 e->e_from.q_home++; 1170 } | 808 if (e->e_from.q_home != NULL && 809 strcmp(e->e_from.q_home, "/") == 0) 810 e->e_from.q_home++; |
1171 } 1172 e->e_from.q_uid = RealUid; 1173 e->e_from.q_gid = RealGid; 1174 e->e_from.q_flags |= QGOODUID; 1175 } 1176 1177 /* 1178 ** Rewrite the from person to dispose of possible implicit 1179 ** links in the net. 1180 */ 1181 | 811 } 812 e->e_from.q_uid = RealUid; 813 e->e_from.q_gid = RealGid; 814 e->e_from.q_flags |= QGOODUID; 815 } 816 817 /* 818 ** Rewrite the from person to dispose of possible implicit 819 ** links in the net. 820 */ 821 |
1182 pvp = prescan(from, delimchar, pvpbuf, sizeof(pvpbuf), NULL, 1183 IntTokenTab, false); | 822 pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL, NULL); |
1184 if (pvp == NULL) 1185 { 1186 /* don't need to give error -- prescan did that already */ 1187 if (LogLevel > 2) 1188 sm_syslog(LOG_NOTICE, e->e_id, | 823 if (pvp == NULL) 824 { 825 /* don't need to give error -- prescan did that already */ 826 if (LogLevel > 2) 827 sm_syslog(LOG_NOTICE, e->e_id, |
1189 "cannot prescan from (%s)", 1190 shortenstring(from, MAXSHORTSTR)); 1191 finis(true, true, ExitStat); | 828 "cannot prescan from (%s)", 829 shortenstring(from, MAXSHORTSTR)); 830 finis(); |
1192 } | 831 } |
1193 (void) REWRITE(pvp, 3, e); 1194 (void) REWRITE(pvp, 1, e); 1195 (void) REWRITE(pvp, 4, e); 1196 macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), NULL); | 832 (void) rewrite(pvp, 3, 0, e); 833 (void) rewrite(pvp, 1, 0, e); 834 (void) rewrite(pvp, 4, 0, e); |
1197 bp = buf + 1; | 835 bp = buf + 1; |
1198 cataddr(pvp, NULL, bp, sizeof(buf) - 2, '\0', false); | 836 cataddr(pvp, NULL, bp, sizeof buf - 2, '\0'); |
1199 if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags)) 1200 { 1201 /* heuristic: route-addr: add angle brackets */ | 837 if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags)) 838 { 839 /* heuristic: route-addr: add angle brackets */ |
1202 (void) sm_strlcat(bp, ">", sizeof(buf) - 1); | 840 strcat(bp, ">"); |
1203 *--bp = '<'; 1204 } | 841 *--bp = '<'; 842 } |
1205 e->e_sender = sm_rpool_strdup_x(e->e_rpool, bp); 1206 macdefine(&e->e_macro, A_PERM, 'f', e->e_sender); | 843 e->e_sender = newstr(bp); 844 define('f', e->e_sender, e); |
1207 1208 /* save the domain spec if this mailer wants it */ 1209 if (e->e_from.q_mailer != NULL && 1210 bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags)) 1211 { 1212 char **lastat; | 845 846 /* save the domain spec if this mailer wants it */ 847 if (e->e_from.q_mailer != NULL && 848 bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags)) 849 { 850 char **lastat; |
851 extern char **copyplist __P((char **, bool)); |
|
1213 1214 /* get rid of any pesky angle brackets */ | 852 853 /* get rid of any pesky angle brackets */ |
1215 macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "e s"); 1216 (void) REWRITE(pvp, 3, e); 1217 (void) REWRITE(pvp, 1, e); 1218 (void) REWRITE(pvp, 4, e); 1219 macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), NULL); | 854 (void) rewrite(pvp, 3, 0, e); 855 (void) rewrite(pvp, 1, 0, e); 856 (void) rewrite(pvp, 4, 0, e); |
1220 1221 /* strip off to the last "@" sign */ 1222 for (lastat = NULL; *pvp != NULL; pvp++) | 857 858 /* strip off to the last "@" sign */ 859 for (lastat = NULL; *pvp != NULL; pvp++) |
1223 { | |
1224 if (strcmp(*pvp, "@") == 0) 1225 lastat = pvp; | 860 if (strcmp(*pvp, "@") == 0) 861 lastat = pvp; |
1226 } | |
1227 if (lastat != NULL) 1228 { | 862 if (lastat != NULL) 863 { |
1229 e->e_fromdomain = copyplist(lastat, true, e->e_rpool); | 864 e->e_fromdomain = copyplist(lastat, TRUE); |
1230 if (tTd(45, 3)) 1231 { | 865 if (tTd(45, 3)) 866 { |
1232 sm_dprintf("Saving from domain: "); 1233 printav(sm_debug_file(), e->e_fromdomain); | 867 printf("Saving from domain: "); 868 printav(e->e_fromdomain); |
1234 } 1235 } 1236 } 1237} | 869 } 870 } 871 } 872} |
1238/* | 873/* |
1239** PRINTENVFLAGS -- print envelope flags for debugging 1240** 1241** Parameters: 1242** e -- the envelope with the flags to be printed. 1243** 1244** Returns: 1245** none. 1246*/ 1247 1248struct eflags 1249{ | 874** PRINTENVFLAGS -- print envelope flags for debugging 875** 876** Parameters: 877** e -- the envelope with the flags to be printed. 878** 879** Returns: 880** none. 881*/ 882 883struct eflags 884{ |
1250 char *ef_name; 1251 unsigned long ef_bit; | 885 char *ef_name; 886 u_long ef_bit; |
1252}; 1253 | 887}; 888 |
1254static struct eflags EnvelopeFlags[] = | 889struct eflags EnvelopeFlags[] = |
1255{ 1256 { "OLDSTYLE", EF_OLDSTYLE }, 1257 { "INQUEUE", EF_INQUEUE }, 1258 { "NO_BODY_RETN", EF_NO_BODY_RETN }, 1259 { "CLRQUEUE", EF_CLRQUEUE }, 1260 { "SENDRECEIPT", EF_SENDRECEIPT }, 1261 { "FATALERRS", EF_FATALERRS }, 1262 { "DELETE_BCC", EF_DELETE_BCC }, --- 9 unchanged lines hidden (view full) --- 1272 { "NORECEIPT", EF_NORECEIPT }, 1273 { "HAS8BIT", EF_HAS8BIT }, 1274 { "NL_NOT_EOL", EF_NL_NOT_EOL }, 1275 { "CRLF_NOT_EOL", EF_CRLF_NOT_EOL }, 1276 { "RET_PARAM", EF_RET_PARAM }, 1277 { "HAS_DF", EF_HAS_DF }, 1278 { "IS_MIME", EF_IS_MIME }, 1279 { "DONT_MIME", EF_DONT_MIME }, | 890{ 891 { "OLDSTYLE", EF_OLDSTYLE }, 892 { "INQUEUE", EF_INQUEUE }, 893 { "NO_BODY_RETN", EF_NO_BODY_RETN }, 894 { "CLRQUEUE", EF_CLRQUEUE }, 895 { "SENDRECEIPT", EF_SENDRECEIPT }, 896 { "FATALERRS", EF_FATALERRS }, 897 { "DELETE_BCC", EF_DELETE_BCC }, --- 9 unchanged lines hidden (view full) --- 907 { "NORECEIPT", EF_NORECEIPT }, 908 { "HAS8BIT", EF_HAS8BIT }, 909 { "NL_NOT_EOL", EF_NL_NOT_EOL }, 910 { "CRLF_NOT_EOL", EF_CRLF_NOT_EOL }, 911 { "RET_PARAM", EF_RET_PARAM }, 912 { "HAS_DF", EF_HAS_DF }, 913 { "IS_MIME", EF_IS_MIME }, 914 { "DONT_MIME", EF_DONT_MIME }, |
1280 { "DISCARD", EF_DISCARD }, 1281 { "TOOBIG", EF_TOOBIG }, 1282 { "SPLIT", EF_SPLIT }, 1283 { "UNSAFE", EF_UNSAFE }, 1284 { NULL, 0 } | 915 { NULL } |
1285}; 1286 1287void 1288printenvflags(e) 1289 register ENVELOPE *e; 1290{ 1291 register struct eflags *ef; | 916}; 917 918void 919printenvflags(e) 920 register ENVELOPE *e; 921{ 922 register struct eflags *ef; |
1292 bool first = true; | 923 bool first = TRUE; |
1293 | 924 |
1294 sm_dprintf("%lx", e->e_flags); | 925 printf("%lx", e->e_flags); |
1295 for (ef = EnvelopeFlags; ef->ef_name != NULL; ef++) 1296 { 1297 if (!bitset(ef->ef_bit, e->e_flags)) 1298 continue; 1299 if (first) | 926 for (ef = EnvelopeFlags; ef->ef_name != NULL; ef++) 927 { 928 if (!bitset(ef->ef_bit, e->e_flags)) 929 continue; 930 if (first) |
1300 sm_dprintf("<%s", ef->ef_name); | 931 printf("<%s", ef->ef_name); |
1301 else | 932 else |
1302 sm_dprintf(",%s", ef->ef_name); 1303 first = false; | 933 printf(",%s", ef->ef_name); 934 first = FALSE; |
1304 } 1305 if (!first) | 935 } 936 if (!first) |
1306 sm_dprintf(">\n"); | 937 printf(">\n"); |
1307} | 938} |