1 /* $NetBSD: header_opts.c,v 1.1.1.1 2009/06/23 10:08:46 tron Exp $ */ 2 3 /*++ 4 /* NAME 5 /* header_opts 3 6 /* SUMMARY 7 /* message header classification 8 /* SYNOPSIS 9 /* #include <header_opts.h> 10 /* 11 /* const HEADER_OPTS *header_opts_find(string) 12 /* const char *string; 13 /* DESCRIPTION 14 /* header_opts_find() takes a message header line and looks up control 15 /* information for the corresponding header type. 16 /* DIAGNOSTICS 17 /* Panic: input is not a valid header line. The result is a pointer 18 /* to HEADER_OPTS in case of success, a null pointer when the header 19 /* label was not recognized. 20 /* SEE ALSO 21 /* header_opts(3h) the gory details 22 /* LICENSE 23 /* .ad 24 /* .fi 25 /* The Secure Mailer license must be distributed with this software. 26 /* AUTHOR(S) 27 /* Wietse Venema 28 /* IBM T.J. Watson Research 29 /* P.O. Box 704 30 /* Yorktown Heights, NY 10598, USA 31 /*--*/ 32 33 /* System library. */ 34 35 #include <sys_defs.h> 36 #include <ctype.h> 37 38 /* Utility library. */ 39 40 #include <msg.h> 41 #include <htable.h> 42 #include <vstring.h> 43 #include <stringops.h> 44 45 /* Global library. */ 46 47 #include "header_opts.h" 48 49 /* 50 * Header names are given in the preferred capitalization. The lookups are 51 * case-insensitive. 52 * 53 * XXX Removing Return-Path: headers should probably be done only with mail 54 * that enters via a non-SMTP channel. Changing this now could break other 55 * software. See also comments in bounce_notify_util.c. 56 */ 57 static const HEADER_OPTS header_opts[] = { 58 "Apparently-To", HDR_APPARENTLY_TO, HDR_OPT_RECIP, 59 "Bcc", HDR_BCC, HDR_OPT_DROP | HDR_OPT_XRECIP, 60 "Cc", HDR_CC, HDR_OPT_XRECIP, 61 "Content-Description", HDR_CONTENT_DESCRIPTION, HDR_OPT_MIME, 62 "Content-Disposition", HDR_CONTENT_DISPOSITION, HDR_OPT_MIME, 63 "Content-ID", HDR_CONTENT_ID, HDR_OPT_MIME, 64 "Content-Length", HDR_CONTENT_LENGTH, HDR_OPT_DROP, 65 "Content-Transfer-Encoding", HDR_CONTENT_TRANSFER_ENCODING, HDR_OPT_MIME, 66 "Content-Type", HDR_CONTENT_TYPE, HDR_OPT_MIME, 67 "Delivered-To", HDR_DELIVERED_TO, 0, 68 "Disposition-Notification-To", HDR_DISP_NOTIFICATION, HDR_OPT_SENDER, 69 "Date", HDR_DATE, 0, 70 "Errors-To", HDR_ERRORS_TO, HDR_OPT_SENDER, 71 "From", HDR_FROM, HDR_OPT_SENDER, 72 "Mail-Followup-To", HDR_MAIL_FOLLOWUP_TO, HDR_OPT_SENDER, 73 "Message-Id", HDR_MESSAGE_ID, 0, 74 "MIME-Version", HDR_MIME_VERSION, HDR_OPT_MIME, 75 "Received", HDR_RECEIVED, 0, 76 "Reply-To", HDR_REPLY_TO, HDR_OPT_SENDER, 77 "Resent-Bcc", HDR_RESENT_BCC, HDR_OPT_DROP | HDR_OPT_XRECIP | HDR_OPT_RR, 78 "Resent-Cc", HDR_RESENT_CC, HDR_OPT_XRECIP | HDR_OPT_RR, 79 "Resent-Date", HDR_RESENT_DATE, HDR_OPT_RR, 80 "Resent-From", HDR_RESENT_FROM, HDR_OPT_SENDER | HDR_OPT_RR, 81 "Resent-Message-Id", HDR_RESENT_MESSAGE_ID, HDR_OPT_RR, 82 "Resent-Reply-To", HDR_RESENT_REPLY_TO, HDR_OPT_RECIP | HDR_OPT_RR, 83 "Resent-Sender", HDR_RESENT_SENDER, HDR_OPT_SENDER | HDR_OPT_RR, 84 "Resent-To", HDR_RESENT_TO, HDR_OPT_XRECIP | HDR_OPT_RR, 85 "Return-Path", HDR_RETURN_PATH, HDR_OPT_DROP | HDR_OPT_SENDER, 86 "Return-Receipt-To", HDR_RETURN_RECEIPT_TO, HDR_OPT_SENDER, 87 "Sender", HDR_SENDER, HDR_OPT_SENDER, 88 "To", HDR_TO, HDR_OPT_XRECIP, 89 }; 90 91 #define HEADER_OPTS_SIZE (sizeof(header_opts) / sizeof(header_opts[0])) 92 93 static HTABLE *header_hash; /* quick lookup */ 94 static VSTRING *header_key; 95 96 /* header_opts_init - initialize */ 97 98 static void header_opts_init(void) 99 { 100 const HEADER_OPTS *hp; 101 const char *cp; 102 103 /* 104 * Build a hash table for quick lookup, and allocate memory for 105 * lower-casing the lookup key. 106 */ 107 header_key = vstring_alloc(10); 108 header_hash = htable_create(HEADER_OPTS_SIZE); 109 for (hp = header_opts; hp < header_opts + HEADER_OPTS_SIZE; hp++) { 110 VSTRING_RESET(header_key); 111 for (cp = hp->name; *cp; cp++) 112 VSTRING_ADDCH(header_key, TOLOWER(*cp)); 113 VSTRING_TERMINATE(header_key); 114 htable_enter(header_hash, vstring_str(header_key), (char *) hp); 115 } 116 } 117 118 /* header_opts_find - look up header options */ 119 120 const HEADER_OPTS *header_opts_find(const char *string) 121 { 122 const char *cp; 123 124 if (header_hash == 0) 125 header_opts_init(); 126 127 /* 128 * Look up the lower-cased version of the header name. 129 */ 130 VSTRING_RESET(header_key); 131 for (cp = string; *cp != ':'; cp++) { 132 if (*cp == 0) 133 msg_panic("header_opts_find: no colon in header: %.30s", string); 134 VSTRING_ADDCH(header_key, TOLOWER(*cp)); 135 } 136 vstring_truncate(header_key, 137 trimblanks(vstring_str(header_key), cp - string) 138 - vstring_str(header_key)); 139 VSTRING_TERMINATE(header_key); 140 return ((const HEADER_OPTS *) htable_find(header_hash, vstring_str(header_key))); 141 } 142