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 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 NAME 30 ckdlivopts - check delivery notification options 31 32 SYNOPSIS 33 int ckdlivopts(int tcopy_hdr, int *svopts) 34 35 DESCRIPTION 36 Check if delivery notification requested for message being 37 processed. Returns specified options as combined from H_DEFOPTS, 38 H_TROPTS, & H_TCOPY lines. 39 40 (Positive notification options) 41 001 ==> /delivery requested 42 002 ==> /nodelivery requested 43 (Negative notification options) 44 010 ==> /report requested 45 020 ==> /return requested 46 040 ==> /ignore requested 47 48 Combinations are expected, i.e. - 011 ==> /delivery/report 49 If not specified, the assumed defaults are /nodelivery/return (rc=022) 50 51 The options discovered in the header are stored into svopts. 52 */ 53 #include "mail.h" 54 55 static void getopts(); 56 static void mergeopts(); 57 58 struct dlvopts { 59 int deliv; 60 int nodeliv; 61 int rept; 62 int rtrn; 63 int ign; 64 }; 65 66 int ckdlivopts(tcopy_hdr, svopts) 67 int tcopy_hdr; 68 int *svopts; 69 { 70 static char pn[] = "ckdlivopts"; 71 struct hdrs *hp; 72 struct dlvopts toopts, tropts, defopts; 73 int rc; 74 75 /* already done this once. no need to repeat..... */ 76 if (svopts && *svopts != 0) { 77 Dout(pn, 0, "*svopts = o%o\n", *svopts); 78 return (*svopts); 79 } 80 memset((char *)&defopts, 0, sizeof(struct dlvopts)); 81 if ((hp = hdrlines[H_DEFOPTS].head) != (struct hdrs *)NULL) { 82 Dout(pn, 3, "H_DEFOPTS line = '%s'\n", hp->value); 83 getopts(hp->value, &defopts); 84 } 85 memset((char *)&tropts, 0, sizeof(struct dlvopts)); 86 if ((hp = hdrlines[H_TROPTS].head) != (struct hdrs *)NULL) { 87 Dout(pn, 3, "H_TROPTS line = '%s'\n", hp->value); 88 getopts(hp->value, &tropts); 89 } 90 memset((char *)&toopts, 0, sizeof(struct dlvopts)); 91 if ((hp = hdrlines[tcopy_hdr].head) != (struct hdrs *)NULL) { 92 Dout(pn, 3,"H_TCOPY line = '%s'\n", hp->value); 93 getopts(hp->value, &toopts); 94 } 95 /* Combine options from different header lines. Precedence is */ 96 /* toopts --> tropts --> defopts. Results left in defopts */ 97 mergeopts(&tropts,&defopts); 98 mergeopts(&toopts,&defopts); 99 100 if (defopts.deliv) rc = DELIVERY; 101 else rc = NODELIVERY; 102 103 if (defopts.rtrn) rc += RETURN; 104 else if (defopts.rept) rc += REPORT; 105 else if (defopts.ign) rc += IGNORE; 106 else rc += RETURN; 107 108 Dout(pn, 0,"returning = o%o\n", rc); 109 if (svopts) 110 *svopts = rc; 111 return (rc); 112 } 113 114 /* 115 * Pick transport options off of header line. 116 * If conflicting options found, use MOST demanding; i.e. - /delivery/return. 117 */ 118 static void getopts(s, optr) 119 register char *s; 120 register struct dlvopts *optr; 121 { 122 register char *op; 123 124 for (op = strchr (s, '/'); op++; op = strchr(op, '/')) { 125 if (casncmp(op, "delivery", 7) == 0) { 126 optr->deliv = 1; 127 optr->nodeliv = 0; 128 } else if (casncmp(op, "nodelivery", 10) == 0) { 129 if (optr->deliv == 0) { 130 optr->nodeliv = 1; 131 } 132 } else if (casncmp(op, "report", 6) == 0) { 133 optr->ign = 0; 134 if (optr->rtrn == 0) { 135 optr->rept = 1; 136 } 137 } else if (casncmp(op, "return", 6) == 0) { 138 optr->rtrn = 1; 139 optr->rept = optr->ign = 0; 140 } else if (casncmp(op, "ignore", 6) == 0) { 141 optr->rept = 0; 142 if (optr->rtrn == 0) { 143 optr->ign = 1; 144 } 145 } 146 } 147 } 148 149 /* 150 * Merge options between 2 sets. Higher set has precedence. 151 * Results left in lower set. 152 */ 153 static void mergeopts(higher, lower) 154 register struct dlvopts *higher, *lower; 155 { 156 if (higher->deliv == 1) { 157 lower->deliv = 1; 158 lower->nodeliv = 0; 159 } 160 if (higher->nodeliv == 1) { 161 lower->nodeliv = 1; 162 lower->deliv = 0; 163 } 164 if (higher->rept == 1) { 165 lower->rept = 1; 166 lower->rtrn = lower->ign = 0; 167 } 168 if (higher->rtrn == 1) { 169 lower->rtrn = 1; 170 lower->rept = lower->ign = 0; 171 } 172 if (higher->ign == 1) { 173 lower->ign = 1; 174 lower->rept = lower->rtrn = 0; 175 } 176 } 177