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