Avoid generating duplicate headers in ezmlm-send

When processing a message's headers:

 - Make note if Reply-To was seen.
 - Save off and do not copy the Cc header to the output immediately.
 - Save off and do not copy the From header to the output immediately.

At the end of the message headers, call rewrite_from().

When flagrewritefrom is set, either by the list's configuration or
because a DMARC reject policy applies to the message sender's address:

 - The From header is rewritten as before.
 - If replytolist is not enabled, a Reply-To header is only added
   if the original message did not have one. Rationale is that the
   original Reply-To header indicated where the post author is
   interested in receiving responses, not the From header.
 - When replytolist is enabled and the original message had a Cc header,
   the From address is appended to the existing Cc header.
 - When replytolist is enabled and the original message did not have a
   Cc header, generate a new one using the From address.

After rewrite_from() performs any of the applicable manipulations
described above, the resulting From and Cc headers are copied to the
output.

Update tests/551-ezmlm-send-rewritefrom:

 - Confirm Reply-To and Cc headers are not duplicated.
 - Validate behavior when replytolist is configured.
4 files changed
tree: 9c8cf8b25e5ecf56a6195cf168188c72b8dbc20e
  1. lang/
  2. tests/
  3. tools/
  4. all.do
  5. alloc.3
  6. alloc.c
  7. alloc.h
  8. alloc=l
  9. alloc_re.c
  10. altpath.c
  11. altpath.h
  12. author.c
  13. auto-ccld.sh.do
  14. auto-str.c
  15. auto-str=x
  16. auto_bin.h
  17. auto_cron.h
  18. auto_etc.h
  19. auto_lib.h
  20. auto_qmail.h
  21. auto_version.h
  22. BIN
  23. BLURB
  24. BUGS
  25. byte.h
  26. byte_chr.c
  27. byte_copy.c
  28. byte_cr.c
  29. byte_diff.c
  30. byte_rchr.c
  31. byte_zero.c
  32. case.3
  33. case.h
  34. case_diffb.c
  35. case_diffs.c
  36. case_lowerb.c
  37. case_startb.c
  38. case_starts.c
  39. cgi.h
  40. CHANGES
  41. choose.sh
  42. choose=s
  43. clean.do
  44. concatHDR.c
  45. conf-bin
  46. conf-cc
  47. conf-cclo
  48. conf-cron
  49. conf-etc
  50. conf-lang
  51. conf-ld
  52. conf-ldso
  53. conf-lib
  54. conf-man
  55. conf-qmail
  56. config.c
  57. config.h
  58. constmap.c
  59. constmap.h
  60. cookie.c
  61. cookie.h
  62. copy.c
  63. copy.h
  64. date2yyyymm.c
  65. date822fmt.c
  66. date822fmt.h
  67. dateline.c
  68. datetime.3
  69. datetime.c
  70. datetime.h
  71. decodeB.c
  72. decodeHDR.c
  73. decodeQ.c
  74. default.0.do
  75. default.a.do
  76. default.do
  77. default.lib.do
  78. default.lo.do
  79. default.o.do
  80. default.so.do
  81. die.h
  82. die_badaddr.c
  83. die_badformat.c
  84. die_dow.c
  85. die_nomem.c
  86. die_sender.c
  87. die_usage.c
  88. direntry.3
  89. direntry.h.do
  90. direntry.h1
  91. direntry.h2
  92. dmarc.c
  93. dmarc.h
  94. dns.h
  95. dns_dfd.c
  96. dns_domain.c
  97. dns_dtda.c
  98. dns_ip.c
  99. dns_ipq.c
  100. dns_mx.c
  101. dns_name.c
  102. dns_nd.c
  103. dns_packet.c
  104. dns_random.c
  105. dns_rcip.c
  106. dns_rcrw.c
  107. dns_resolve.c
  108. dns_sortip.c
  109. dns_transmit.c
  110. dns_txt.c
  111. DOWNGRADE
  112. encodeB.c
  113. encodeQ.c
  114. env.3
  115. env.c
  116. env.h
  117. envread.c
  118. error.3
  119. error.c
  120. error.h
  121. error=l
  122. error_str.3
  123. error_str.c
  124. error_temp.3
  125. ETC
  126. exit.h
  127. EXTRADIST
  128. ezcgi.css
  129. ezcgirc
  130. ezmlm-accept.1
  131. ezmlm-accept.sh
  132. ezmlm-accept=s
  133. ezmlm-archive.1
  134. ezmlm-archive.c
  135. ezmlm-archive=x
  136. ezmlm-cgi.1
  137. ezmlm-cgi.c
  138. ezmlm-cgi=x
  139. ezmlm-check.1
  140. ezmlm-check.sh
  141. ezmlm-check=s
  142. ezmlm-checksub.1
  143. ezmlm-checksub.c
  144. ezmlm-checksub=x
  145. ezmlm-clean.1
  146. ezmlm-clean.c
  147. ezmlm-clean=x
  148. ezmlm-confirm.1
  149. ezmlm-confirm.c
  150. ezmlm-confirm=x
  151. ezmlm-cron.1
  152. ezmlm-cron.c
  153. ezmlm-cron=x
  154. ezmlm-dispatch.1
  155. ezmlm-dispatch.c
  156. ezmlm-dispatch=x
  157. ezmlm-gate.1
  158. ezmlm-gate.c
  159. ezmlm-gate=x
  160. ezmlm-get.1
  161. ezmlm-get.c
  162. ezmlm-get=x
  163. ezmlm-glconf.1
  164. ezmlm-glconf.sh
  165. ezmlm-glconf=s
  166. ezmlm-idx.1
  167. ezmlm-idx.c
  168. ezmlm-idx.spec.template
  169. ezmlm-idx=x
  170. ezmlm-import.1
  171. ezmlm-import.c
  172. ezmlm-import=x
  173. ezmlm-issubn.1
  174. ezmlm-issubn.c
  175. ezmlm-issubn=x
  176. ezmlm-limit.1
  177. ezmlm-limit.c
  178. ezmlm-limit=x
  179. ezmlm-list.1
  180. ezmlm-list.c
  181. ezmlm-list=x
  182. ezmlm-make.1
  183. ezmlm-make.c
  184. ezmlm-make=x
  185. ezmlm-manage.1
  186. ezmlm-manage.c
  187. ezmlm-manage=x
  188. ezmlm-moderate.1
  189. ezmlm-moderate.c
  190. ezmlm-moderate=x
  191. ezmlm-receipt.1
  192. ezmlm-receipt.c
  193. ezmlm-receipt=x
  194. ezmlm-reject.1
  195. ezmlm-reject.c
  196. ezmlm-reject=x
  197. ezmlm-request.1
  198. ezmlm-request.c
  199. ezmlm-request=x
  200. ezmlm-return.1
  201. ezmlm-return.c
  202. ezmlm-return=x
  203. ezmlm-rmtab.1
  204. ezmlm-rmtab.c
  205. ezmlm-rmtab=x
  206. ezmlm-send.1
  207. ezmlm-send.c
  208. ezmlm-send=x
  209. ezmlm-split.1
  210. ezmlm-split.c
  211. ezmlm-split=x
  212. ezmlm-store.1
  213. ezmlm-store.c
  214. ezmlm-store=x
  215. ezmlm-sub.1
  216. ezmlm-sub.c
  217. ezmlm-sub=x
  218. ezmlm-subunsub.c
  219. ezmlm-test.1
  220. ezmlm-test.do
  221. ezmlm-to40x-mysql
  222. ezmlm-tstdig.1
  223. ezmlm-tstdig.c
  224. ezmlm-tstdig=x
  225. ezmlm-unsub.1
  226. ezmlm-unsub.c
  227. ezmlm-unsub=x
  228. ezmlm-warn.1
  229. ezmlm-warn.c
  230. ezmlm-warn=x
  231. ezmlm-weed.1
  232. ezmlm-weed.c
  233. ezmlm-weed=x
  234. ezmlm.5
  235. ezmlmglrc
  236. ezmlmglrc.5
  237. ezmlmrc.5
  238. ezmlmrc.all.do
  239. ezmlmrc.template
  240. ezmlmsubrc
  241. ezmlmsubrc.5
  242. FAQ
  243. fd.h
  244. fd_copy.3
  245. fd_copy.c
  246. fd_move.3
  247. fd_move.c
  248. FILES
  249. fill-template.sh
  250. fill-template=s
  251. find-systype.do
  252. find-systype.sh
  253. fmt.h
  254. fmt_str.c
  255. fmt_uint.c
  256. fmt_uint0.c
  257. fmt_ulong.c
  258. fork.h
  259. fs=l
  260. gen_alloc.h
  261. gen_allocdefs.h
  262. getconf.c
  263. getconf.h
  264. getconf_ulong.c
  265. getconfopt.c
  266. getconfopt.h
  267. getconfopt_copy.c
  268. getconfopt_cstr.c
  269. getconfopt_cstr_flag.c
  270. getconfopt_flag.c
  271. getconfopt_str.c
  272. getconfopt_ulong.c
  273. getconfopt_ulong_flag.c
  274. getconfopt_version.c
  275. gethdrln.c
  276. getln.3
  277. getln.c
  278. getln.h
  279. getln2.3
  280. getln2.c
  281. getln=l
  282. getopt.3
  283. hasattribute.h.do
  284. hasattribute.h1
  285. hasattribute.h2
  286. hasflock.h.do
  287. hassgact.h.do
  288. haswaitp.h.do
  289. haswaitp.h1
  290. haswaitp.h2
  291. hdr.h
  292. hdr_add.c
  293. hdr_boundary.c
  294. hdr_ctboundary.c
  295. hdr_datemsgid.c
  296. hdr_from.c
  297. hdr_listsubject.c
  298. hdr_mime.c
  299. hdr_subject.c
  300. hdr_transferenc.c
  301. HISTORY
  302. idx.h
  303. idxthread.c
  304. idxthread.h
  305. INSTALL
  306. install.do
  307. installer.c
  308. installer=x
  309. iopause.c
  310. iopause.h.do
  311. iopause.h1
  312. iopause.h2
  313. ip4.h
  314. ip4_fmt.c
  315. ip4_scan.c
  316. it.do
  317. LIB
  318. libezmlm=l
  319. LICENSE
  320. lock.h
  321. lock_ex.c
  322. lockfile.c
  323. log.c
  324. log.h
  325. make-compile.sh
  326. make-libcompile.sh
  327. make-load.sh
  328. make-makelib.sh
  329. make-makeso.sh
  330. make-messages-c.sh
  331. make-messages.sh
  332. makehash.c
  333. makehash.h
  334. makelang.sh
  335. makelang=s
  336. makepath.c
  337. MAN
  338. man.do
  339. messages-txt.c.do
  340. messages.all.do
  341. messages.c
  342. messages.h
  343. mime.h
  344. mysql.do
  345. ndelay.h
  346. ndelay_on.c
  347. now.3
  348. now.c
  349. now.h
  350. open.h
  351. open=l
  352. open_append.c
  353. open_read.c
  354. open_trunc.c
  355. open_write.c
  356. openreadclose.c
  357. openreadclose.h
  358. pgsql.do
  359. qmail-qmqpc.tar.gz
  360. qmail-verh.tar.gz
  361. qmail.c
  362. qmail.h
  363. qmail_copy.c
  364. quote.c
  365. quote.h
  366. readclose.c
  367. readclose.h
  368. README
  369. README.mysql
  370. README.pgsql
  371. README.std
  372. readwrite.h
  373. scan.h
  374. scan_8long.c
  375. scan_ulong.c
  376. seek.h
  377. seek_set.c
  378. select.h.do
  379. select.h1
  380. select.h2
  381. sender.c
  382. sender.h
  383. setup.do
  384. sgetopt.3
  385. sgetopt.c
  386. sgetopt.h
  387. sig.h
  388. sig_catch.c
  389. sig_pipe.c
  390. slurp.c
  391. slurp.h
  392. slurpclose.c
  393. slurpclose.h
  394. socket.h
  395. socket_accept.c
  396. socket_bind.c
  397. socket_conn.c
  398. socket_listen.c
  399. socket_recv.c
  400. socket_send.c
  401. socket_tcp.c
  402. socket_udp.c
  403. sqlite3.do
  404. str.h
  405. str=l
  406. str_chr.c
  407. str_cpy.c
  408. str_diff.c
  409. str_diffn.c
  410. str_len.c
  411. str_rchr.c
  412. str_start.c
  413. stralloc.3
  414. stralloc.h
  415. stralloc=l
  416. stralloc_arts.c
  417. stralloc_cat.c
  418. stralloc_catb.c
  419. stralloc_cats.c
  420. stralloc_copy.c
  421. stralloc_eady.c
  422. stralloc_num.c
  423. stralloc_opyb.c
  424. stralloc_opys.c
  425. stralloc_pend.c
  426. strerr.c
  427. strerr.h
  428. strerr=l
  429. sub-mysql.c
  430. sub-mysql=so
  431. sub-pgsql.c
  432. sub-pgsql=so
  433. sub-sqlite3.c
  434. sub-sqlite3=so
  435. sub-std.c
  436. sub-std=so
  437. sub_sql.c
  438. sub_sql.h
  439. sub_std.h
  440. subdb.c
  441. subdb.h
  442. subfd.3
  443. subfd.h
  444. subfderr.c
  445. subfdin.c
  446. subfdout.c
  447. subgetopt.3
  448. subgetopt.c
  449. subgetopt.h
  450. subhash.c
  451. subhash.h
  452. substdi.c
  453. substdio.3
  454. substdio.c
  455. substdio.h
  456. substdio=l
  457. substdio_copy.3
  458. substdio_copy.c
  459. substdio_in.3
  460. substdio_out.3
  461. substdo.c
  462. surf.3
  463. surf.c
  464. surf.h
  465. surfpcs.3
  466. surfpcs.c
  467. surfpcs.h
  468. SYSDEPS
  469. systype.do
  470. tai.h
  471. tai_add.c
  472. tai_now.c
  473. tai_pack.c
  474. tai_sub.c
  475. tai_uint.c
  476. tai_unpack.c
  477. taia.h
  478. taia_add.c
  479. taia_approx.c
  480. taia_frac.c
  481. taia_less.c
  482. taia_now.c
  483. taia_pack.c
  484. taia_sub.c
  485. taia_tai.c
  486. taia_uint.c
  487. targets.do
  488. test-getconfopt.c
  489. test-getconfopt=x
  490. THANKS
  491. TODO
  492. tryattribute.c
  493. trycpp.c
  494. trydrent.c
  495. tryflock.c
  496. trylib.c
  497. trypoll.c
  498. trysgact.c
  499. trysysel.c
  500. tryulong32.c
  501. tryulong64.c
  502. trywaitp.c
  503. uint16.h
  504. uint16_pack.c
  505. uint16_unpack.c
  506. uint32.h.do
  507. uint32.h1
  508. uint32.h2
  509. uint32_unpack.c
  510. uint64.h.do
  511. uint64.h1
  512. uint64.h2
  513. unfoldHDR.c
  514. UPGRADE
  515. VERSION
  516. wait.3
  517. wait.h
  518. wait_pid.c
  519. warn-auto.sh
  520. wrap.h
  521. wrap_chdir.c
  522. wrap_execbin.c
  523. wrap_execsh.c
  524. wrap_execv.c
  525. wrap_exitcode.c
  526. wrap_fork.c
  527. wrap_rename.c
  528. wrap_stat.c
  529. wrap_waitpid.c
  530. yyyymm.h