1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 /* 26 NAME 27 ckdlivopts - check delivery notification options 28 29 SYNOPSIS 30 int ckdlivopts(int tcopy_hdr, int *svopts) 31 32 DESCRIPTION 33 Check if delivery notification requested for message being 34 processed. Returns specified options as combined from H_DEFOPTS, 35 H_TROPTS, & H_TCOPY lines. 36 37 (Positive notification options) 38 001 ==> /delivery requested 39 002 ==> /nodelivery requested 40 (Negative notification options) 41 010 ==> /report requested 42 020 ==> /return requested 43 040 ==> /ignore requested 44 45 Combinations are expected, i.e. - 011 ==> /delivery/report 46 If not specified, the assumed defaults are /nodelivery/return (rc=022) 47 48 The options discovered in the header are stored into svopts. 49 */ 50 #include "mail.h" 51 52 static void getopts(); 53 static void mergeopts(); 54 55 struct dlvopts { 56 int deliv; 57 int nodeliv; 58 int rept; 59 int rtrn; 60 int ign; 61 }; 62 63 int ckdlivopts(tcopy_hdr, svopts) 64 int tcopy_hdr; 65 int *svopts; 66 { 67 static char pn[] = "ckdlivopts"; 68 struct hdrs *hp; 69 struct dlvopts toopts, tropts, defopts; 70 int rc; 71 72 /* already done this once. no need to repeat..... */ 73 if (svopts && *svopts != 0) { 74 Dout(pn, 0, "*svopts = o%o\n", *svopts); 75 return (*svopts); 76 } 77 memset((char *)&defopts, 0, sizeof(struct dlvopts)); 78 if ((hp = hdrlines[H_DEFOPTS].head) != (struct hdrs *)NULL) { 79 Dout(pn, 3, "H_DEFOPTS line = '%s'\n", hp->value); 80 getopts(hp->value, &defopts); 81 } 82 memset((char *)&tropts, 0, sizeof(struct dlvopts)); 83 if ((hp = hdrlines[H_TROPTS].head) != (struct hdrs *)NULL) { 84 Dout(pn, 3, "H_TROPTS line = '%s'\n", hp->value); 85 getopts(hp->value, &tropts); 86 } 87 memset((char *)&toopts, 0, sizeof(struct dlvopts)); 88 if ((hp = hdrlines[tcopy_hdr].head) != (struct hdrs *)NULL) { 89 Dout(pn, 3,"H_TCOPY line = '%s'\n", hp->value); 90 getopts(hp->value, &toopts); 91 } 92 /* Combine options from different header lines. Precedence is */ 93 /* toopts --> tropts --> defopts. Results left in defopts */ 94 mergeopts(&tropts,&defopts); 95 mergeopts(&toopts,&defopts); 96 97 if (defopts.deliv) rc = DELIVERY; 98 else rc = NODELIVERY; 99 100 if (defopts.rtrn) rc += RETURN; 101 else if (defopts.rept) rc += REPORT; 102 else if (defopts.ign) rc += IGNORE; 103 else rc += RETURN; 104 105 Dout(pn, 0,"returning = o%o\n", rc); 106 if (svopts) 107 *svopts = rc; 108 return (rc); 109 } 110 111 /* 112 * Pick transport options off of header line. 113 * If conflicting options found, use MOST demanding; i.e. - /delivery/return. 114 */ 115 static void getopts(s, optr) 116 register char *s; 117 register struct dlvopts *optr; 118 { 119 register char *op; 120 121 for (op = strchr (s, '/'); op++; op = strchr(op, '/')) { 122 if (casncmp(op, "delivery", 7) == 0) { 123 optr->deliv = 1; 124 optr->nodeliv = 0; 125 } else if (casncmp(op, "nodelivery", 10) == 0) { 126 if (optr->deliv == 0) { 127 optr->nodeliv = 1; 128 } 129 } else if (casncmp(op, "report", 6) == 0) { 130 optr->ign = 0; 131 if (optr->rtrn == 0) { 132 optr->rept = 1; 133 } 134 } else if (casncmp(op, "return", 6) == 0) { 135 optr->rtrn = 1; 136 optr->rept = optr->ign = 0; 137 } else if (casncmp(op, "ignore", 6) == 0) { 138 optr->rept = 0; 139 if (optr->rtrn == 0) { 140 optr->ign = 1; 141 } 142 } 143 } 144 } 145 146 /* 147 * Merge options between 2 sets. Higher set has precedence. 148 * Results left in lower set. 149 */ 150 static void mergeopts(higher, lower) 151 register struct dlvopts *higher, *lower; 152 { 153 if (higher->deliv == 1) { 154 lower->deliv = 1; 155 lower->nodeliv = 0; 156 } 157 if (higher->nodeliv == 1) { 158 lower->nodeliv = 1; 159 lower->deliv = 0; 160 } 161 if (higher->rept == 1) { 162 lower->rept = 1; 163 lower->rtrn = lower->ign = 0; 164 } 165 if (higher->rtrn == 1) { 166 lower->rtrn = 1; 167 lower->rept = lower->ign = 0; 168 } 169 if (higher->ign == 1) { 170 lower->ign = 1; 171 lower->rept = lower->rtrn = 0; 172 } 173 } 174