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
ckdlivopts(tcopy_hdr,svopts)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 */
getopts(s,optr)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 */
mergeopts(higher,lower)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