xref: /illumos-gate/usr/src/cmd/mail/ckdlivopts.c (revision d48be21240dfd051b689384ce2b23479d757f2d8)
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