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