Deleted Added
full compact
parseaddr.c (42575) parseaddr.c (64562)
1/*
1/*
2 * Copyright (c) 1998 Sendmail, Inc. All rights reserved.
2 * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
3 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * By using this file, you agree to the terms and conditions set
8 * forth in the LICENSE file which can be found at the top level of
9 * the sendmail distribution.
10 *
11 */
12
13#ifndef lint
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
5 * Copyright (c) 1988, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
11 *
12 */
13
14#ifndef lint
14static char sccsid[] = "@(#)parseaddr.c 8.156 (Berkeley) 10/27/1998";
15#endif /* not lint */
15static char id[] = "@(#)$Id: parseaddr.c,v 8.234.4.1 2000/05/25 18:56:16 gshapiro Exp $";
16#endif /* ! lint */
16
17
17# include "sendmail.h"
18#include <sendmail.h>
18
19
20static void allocaddr __P((ADDRESS *, int, char *));
21static int callsubr __P((char**, int, ENVELOPE *));
22static char *map_lookup __P((STAB *, char *, char **, int *, ENVELOPE *));
23static ADDRESS *buildaddr __P((char **, ADDRESS *, int, ENVELOPE *));
24
19/*
20** PARSEADDR -- Parse an address
21**
22** Parses an address and breaks it up into three parts: a
23** net to transmit the message on, the host to transmit it
24** to, and a user on that host. These are loaded into an
25** ADDRESS header with the values squirreled away if necessary.
26** The "user" part may not be a real user; the process may

--- 20 unchanged lines hidden (view full) ---

47** `a' is non-NULL).
48** NULL on error.
49**
50** Side Effects:
51** none
52*/
53
54/* following delimiters are inherent to the internal algorithms */
25/*
26** PARSEADDR -- Parse an address
27**
28** Parses an address and breaks it up into three parts: a
29** net to transmit the message on, the host to transmit it
30** to, and a user on that host. These are loaded into an
31** ADDRESS header with the values squirreled away if necessary.
32** The "user" part may not be a real user; the process may

--- 20 unchanged lines hidden (view full) ---

53** `a' is non-NULL).
54** NULL on error.
55**
56** Side Effects:
57** none
58*/
59
60/* following delimiters are inherent to the internal algorithms */
55# define DELIMCHARS "()<>,;\r\n" /* default word delimiters */
61#define DELIMCHARS "()<>,;\r\n" /* default word delimiters */
56
57ADDRESS *
58parseaddr(addr, a, flags, delim, delimptr, e)
59 char *addr;
60 register ADDRESS *a;
61 int flags;
62 int delim;
63 char **delimptr;
64 register ENVELOPE *e;
65{
66 register char **pvp;
67 auto char *delimptrbuf;
62
63ADDRESS *
64parseaddr(addr, a, flags, delim, delimptr, e)
65 char *addr;
66 register ADDRESS *a;
67 int flags;
68 int delim;
69 char **delimptr;
70 register ENVELOPE *e;
71{
72 register char **pvp;
73 auto char *delimptrbuf;
68 bool queueup;
74 bool qup;
69 char pvpbuf[PSBUFSIZE];
75 char pvpbuf[PSBUFSIZE];
70 extern bool invalidaddr __P((char *, char *));
71 extern void allocaddr __P((ADDRESS *, int, char *));
72
73 /*
74 ** Initialize and prescan address.
75 */
76
77 e->e_to = addr;
78 if (tTd(20, 1))
76
77 /*
78 ** Initialize and prescan address.
79 */
80
81 e->e_to = addr;
82 if (tTd(20, 1))
79 printf("\n--parseaddr(%s)\n", addr);
83 dprintf("\n--parseaddr(%s)\n", addr);
80
81 if (delimptr == NULL)
82 delimptr = &delimptrbuf;
83
84 pvp = prescan(addr, delim, pvpbuf, sizeof pvpbuf, delimptr, NULL);
85 if (pvp == NULL)
86 {
87 if (tTd(20, 1))
84
85 if (delimptr == NULL)
86 delimptr = &delimptrbuf;
87
88 pvp = prescan(addr, delim, pvpbuf, sizeof pvpbuf, delimptr, NULL);
89 if (pvp == NULL)
90 {
91 if (tTd(20, 1))
88 printf("parseaddr-->NULL\n");
89 return (NULL);
92 dprintf("parseaddr-->NULL\n");
93 return NULL;
90 }
91
92 if (invalidaddr(addr, delim == '\0' ? NULL : *delimptr))
93 {
94 if (tTd(20, 1))
94 }
95
96 if (invalidaddr(addr, delim == '\0' ? NULL : *delimptr))
97 {
98 if (tTd(20, 1))
95 printf("parseaddr-->bad address\n");
99 dprintf("parseaddr-->bad address\n");
96 return NULL;
97 }
98
99 /*
100 ** Save addr if we are going to have to.
101 **
102 ** We have to do this early because there is a chance that
103 ** the map lookups in the rewriting rules could clobber

--- 11 unchanged lines hidden (view full) ---

115 **delimptr = savec;
116 }
117
118 /*
119 ** Apply rewriting rules.
120 ** Ruleset 0 does basic parsing. It must resolve.
121 */
122
100 return NULL;
101 }
102
103 /*
104 ** Save addr if we are going to have to.
105 **
106 ** We have to do this early because there is a chance that
107 ** the map lookups in the rewriting rules could clobber

--- 11 unchanged lines hidden (view full) ---

119 **delimptr = savec;
120 }
121
122 /*
123 ** Apply rewriting rules.
124 ** Ruleset 0 does basic parsing. It must resolve.
125 */
126
123 queueup = FALSE;
127 qup = FALSE;
124 if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)
128 if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)
125 queueup = TRUE;
129 qup = TRUE;
126 if (rewrite(pvp, 0, 0, e) == EX_TEMPFAIL)
130 if (rewrite(pvp, 0, 0, e) == EX_TEMPFAIL)
127 queueup = TRUE;
131 qup = TRUE;
128
129
130 /*
131 ** Build canonical address from pvp.
132 */
133
134 a = buildaddr(pvp, a, flags, e);
135
136 /*
137 ** Make local copies of the host & user and then
138 ** transport them out.
139 */
140
141 allocaddr(a, flags, addr);
132
133
134 /*
135 ** Build canonical address from pvp.
136 */
137
138 a = buildaddr(pvp, a, flags, e);
139
140 /*
141 ** Make local copies of the host & user and then
142 ** transport them out.
143 */
144
145 allocaddr(a, flags, addr);
142 if (bitset(QBADADDR, a->q_flags))
146 if (QS_IS_BADADDR(a->q_state))
143 return a;
144
145 /*
146 ** If there was a parsing failure, mark it for queueing.
147 */
148
147 return a;
148
149 /*
150 ** If there was a parsing failure, mark it for queueing.
151 */
152
149 if (queueup && OpMode != MD_INITALIAS)
153 if (qup && OpMode != MD_INITALIAS)
150 {
151 char *msg = "Transient parse error -- message queued for future delivery";
152
153 if (e->e_sendmode == SM_DEFER)
154 msg = "Deferring message until queue run";
155 if (tTd(20, 1))
154 {
155 char *msg = "Transient parse error -- message queued for future delivery";
156
157 if (e->e_sendmode == SM_DEFER)
158 msg = "Deferring message until queue run";
159 if (tTd(20, 1))
156 printf("parseaddr: queuing message\n");
160 dprintf("parseaddr: queuing message\n");
157 message(msg);
158 if (e->e_message == NULL && e->e_sendmode != SM_DEFER)
159 e->e_message = newstr(msg);
161 message(msg);
162 if (e->e_message == NULL && e->e_sendmode != SM_DEFER)
163 e->e_message = newstr(msg);
160 a->q_flags |= QQUEUEUP;
164 a->q_state = QS_QUEUEUP;
161 a->q_status = "4.4.3";
162 }
163
164 /*
165 ** Compute return value.
166 */
167
168 if (tTd(20, 1))
169 {
165 a->q_status = "4.4.3";
166 }
167
168 /*
169 ** Compute return value.
170 */
171
172 if (tTd(20, 1))
173 {
170 printf("parseaddr-->");
174 dprintf("parseaddr-->");
171 printaddr(a, FALSE);
172 }
173
175 printaddr(a, FALSE);
176 }
177
174 return (a);
178 return a;
175}
176 /*
177** INVALIDADDR -- check for address containing meta-characters
178**
179** Parameters:
180** addr -- the address to check.
181**
182** Returns:

--- 9 unchanged lines hidden (view full) ---

192 char savedelim = '\0';
193
194 if (delimptr != NULL)
195 {
196 savedelim = *delimptr;
197 if (savedelim != '\0')
198 *delimptr = '\0';
199 }
179}
180 /*
181** INVALIDADDR -- check for address containing meta-characters
182**
183** Parameters:
184** addr -- the address to check.
185**
186** Returns:

--- 9 unchanged lines hidden (view full) ---

196 char savedelim = '\0';
197
198 if (delimptr != NULL)
199 {
200 savedelim = *delimptr;
201 if (savedelim != '\0')
202 *delimptr = '\0';
203 }
200 if (strlen(addr) > TOBUFSIZE - 2)
204 if (strlen(addr) > MAXNAME - 1)
201 {
205 {
202 usrerr("553 Address too long (%d bytes max)", TOBUFSIZE - 2);
206 usrerr("553 5.1.1 Address too long (%d bytes max)",
207 MAXNAME - 1);
203 goto failure;
204 }
205 for (; *addr != '\0'; addr++)
206 {
207 if ((*addr & 0340) == 0200)
208 break;
209 }
210 if (*addr == '\0')
211 {
212 if (delimptr != NULL && savedelim != '\0')
213 *delimptr = savedelim;
214 return FALSE;
215 }
216 setstat(EX_USAGE);
208 goto failure;
209 }
210 for (; *addr != '\0'; addr++)
211 {
212 if ((*addr & 0340) == 0200)
213 break;
214 }
215 if (*addr == '\0')
216 {
217 if (delimptr != NULL && savedelim != '\0')
218 *delimptr = savedelim;
219 return FALSE;
220 }
221 setstat(EX_USAGE);
217 usrerr("553 Address contained invalid control characters");
222 usrerr("553 5.1.1 Address contained invalid control characters");
218failure:
219 if (delimptr != NULL && savedelim != '\0')
220 *delimptr = savedelim;
221 return TRUE;
222}
223 /*
224** ALLOCADDR -- do local allocations of address on demand.
225**

--- 7 unchanged lines hidden (view full) ---

233**
234** Returns:
235** none.
236**
237** Side Effects:
238** Copies portions of a into local buffers as requested.
239*/
240
223failure:
224 if (delimptr != NULL && savedelim != '\0')
225 *delimptr = savedelim;
226 return TRUE;
227}
228 /*
229** ALLOCADDR -- do local allocations of address on demand.
230**

--- 7 unchanged lines hidden (view full) ---

238**
239** Returns:
240** none.
241**
242** Side Effects:
243** Copies portions of a into local buffers as requested.
244*/
245
241void
246static void
242allocaddr(a, flags, paddr)
243 register ADDRESS *a;
244 int flags;
245 char *paddr;
246{
247 if (tTd(24, 4))
247allocaddr(a, flags, paddr)
248 register ADDRESS *a;
249 int flags;
250 char *paddr;
251{
252 if (tTd(24, 4))
248 printf("allocaddr(flags=%x, paddr=%s)\n", flags, paddr);
253 dprintf("allocaddr(flags=%x, paddr=%s)\n", flags, paddr);
249
250 a->q_paddr = paddr;
251
252 if (a->q_user == NULL)
254
255 a->q_paddr = paddr;
256
257 if (a->q_user == NULL)
253 a->q_user = "";
258 a->q_user = newstr("");
254 if (a->q_host == NULL)
259 if (a->q_host == NULL)
255 a->q_host = "";
260 a->q_host = newstr("");
256
257 if (bitset(RF_COPYPARSE, flags))
258 {
259 a->q_host = newstr(a->q_host);
260 if (a->q_user != a->q_paddr)
261 a->q_user = newstr(a->q_user);
262 }
263
264 if (a->q_paddr == NULL)
261
262 if (bitset(RF_COPYPARSE, flags))
263 {
264 a->q_host = newstr(a->q_host);
265 if (a->q_user != a->q_paddr)
266 a->q_user = newstr(a->q_user);
267 }
268
269 if (a->q_paddr == NULL)
265 a->q_paddr = a->q_user;
270 a->q_paddr = newstr(a->q_user);
266}
267 /*
268** PRESCAN -- Prescan name and make it canonical
269**
270** Scans a name and turns it into a set of tokens. This process
271}
272 /*
273** PRESCAN -- Prescan name and make it canonical
274**
275** Scans a name and turns it into a set of tokens. This process
271** deletes blanks and comments (in parentheses).
276** deletes blanks and comments (in parentheses) (if the token type
277** for left paren is SPC).
272**
273** This routine knows about quoted strings and angle brackets.
274**
275** There are certain subtleties to this routine. The one that
276** comes to mind now is that backslashes on the ends of names
277** are silently stripped off; this is intentional. The problem
278** is that some versions of sndmsg (like at LBL) set the kill
279** character to something other than @ when reading addresses;

--- 14 unchanged lines hidden (view full) ---

294** If NULL, use the default table.
295**
296** Returns:
297** A pointer to a vector of tokens.
298** NULL on error.
299*/
300
301/* states and character types */
278**
279** This routine knows about quoted strings and angle brackets.
280**
281** There are certain subtleties to this routine. The one that
282** comes to mind now is that backslashes on the ends of names
283** are silently stripped off; this is intentional. The problem
284** is that some versions of sndmsg (like at LBL) set the kill
285** character to something other than @ when reading addresses;

--- 14 unchanged lines hidden (view full) ---

300** If NULL, use the default table.
301**
302** Returns:
303** A pointer to a vector of tokens.
304** NULL on error.
305*/
306
307/* states and character types */
302# define OPR 0 /* operator */
303# define ATM 1 /* atom */
304# define QST 2 /* in quoted string */
305# define SPC 3 /* chewing up spaces */
306# define ONE 4 /* pick up one character */
307# define ILL 5 /* illegal character */
308#define OPR 0 /* operator */
309#define ATM 1 /* atom */
310#define QST 2 /* in quoted string */
311#define SPC 3 /* chewing up spaces */
312#define ONE 4 /* pick up one character */
313#define ILL 5 /* illegal character */
308
314
309# define NSTATES 6 /* number of states */
310# define TYPE 017 /* mask to select state type */
315#define NSTATES 6 /* number of states */
316#define TYPE 017 /* mask to select state type */
311
312/* meta bits for table */
317
318/* meta bits for table */
313# define M 020 /* meta character; don't pass through */
314# define B 040 /* cause a break */
315# define MB M|B /* meta-break */
319#define M 020 /* meta character; don't pass through */
320#define B 040 /* cause a break */
321#define MB M|B /* meta-break */
316
317static short StateTab[NSTATES][NSTATES] =
318{
319 /* oldst chtype> OPR ATM QST SPC ONE ILL */
320 /*OPR*/ { OPR|B, ATM|B, QST|B, SPC|MB, ONE|B, ILL|MB },
321 /*ATM*/ { OPR|B, ATM, QST|B, SPC|MB, ONE|B, ILL|MB },
322 /*QST*/ { QST, QST, OPR, QST, QST, QST },
323 /*SPC*/ { OPR, ATM, QST, SPC|M, ONE, ILL|MB },

--- 4 unchanged lines hidden (view full) ---

328/* token type table -- it gets modified with $o characters */
329static u_char TokTypeTab[256] =
330{
331 /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */
332 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,SPC,SPC,SPC,SPC,SPC,ATM,ATM,
333 /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */
334 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
335 /* sp ! " # $ % & ' ( ) * + , - . / */
322
323static short StateTab[NSTATES][NSTATES] =
324{
325 /* oldst chtype> OPR ATM QST SPC ONE ILL */
326 /*OPR*/ { OPR|B, ATM|B, QST|B, SPC|MB, ONE|B, ILL|MB },
327 /*ATM*/ { OPR|B, ATM, QST|B, SPC|MB, ONE|B, ILL|MB },
328 /*QST*/ { QST, QST, OPR, QST, QST, QST },
329 /*SPC*/ { OPR, ATM, QST, SPC|M, ONE, ILL|MB },

--- 4 unchanged lines hidden (view full) ---

334/* token type table -- it gets modified with $o characters */
335static u_char TokTypeTab[256] =
336{
337 /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */
338 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,SPC,SPC,SPC,SPC,SPC,ATM,ATM,
339 /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */
340 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
341 /* sp ! " # $ % & ' ( ) * + , - . / */
336 SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM, ATM,SPC,ATM,ATM,ATM,ATM,ATM,ATM,
342 SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM, SPC,SPC,ATM,ATM,ATM,ATM,ATM,ATM,
337 /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
338 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
339 /* @ A B C D E F G H I J K L M N O */
340 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
341 /* P Q R S T U V W X Y Z [ \ ] ^ _ */
342 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
343 /* ` a b c d e f g h i j k l m n o */
344 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,

--- 21 unchanged lines hidden (view full) ---

366/* token type table for MIME parsing */
367u_char MimeTokenTab[256] =
368{
369 /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */
370 ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,SPC,SPC,SPC,SPC,SPC,ILL,ILL,
371 /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */
372 ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
373 /* sp ! " # $ % & ' ( ) * + , - . / */
343 /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
344 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
345 /* @ A B C D E F G H I J K L M N O */
346 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
347 /* P Q R S T U V W X Y Z [ \ ] ^ _ */
348 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
349 /* ` a b c d e f g h i j k l m n o */
350 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,

--- 21 unchanged lines hidden (view full) ---

372/* token type table for MIME parsing */
373u_char MimeTokenTab[256] =
374{
375 /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */
376 ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,SPC,SPC,SPC,SPC,SPC,ILL,ILL,
377 /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */
378 ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
379 /* sp ! " # $ % & ' ( ) * + , - . / */
374 SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM, ATM,SPC,ATM,ATM,OPR,ATM,ATM,OPR,
380 SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM, SPC,SPC,ATM,ATM,OPR,ATM,ATM,OPR,
375 /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
376 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,OPR,OPR,OPR,OPR,OPR,OPR,
377 /* @ A B C D E F G H I J K L M N O */
378 OPR,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
379 /* P Q R S T U V W X Y Z [ \ ] ^ _ */
380 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,OPR,OPR,OPR,ATM,ATM,
381 /* ` a b c d e f g h i j k l m n o */
382 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,

--- 13 unchanged lines hidden (view full) ---

396 /* P Q R S T U V W X Y Z [ \ ] ^ _ */
397 ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
398 /* ` a b c d e f g h i j k l m n o */
399 ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
400 /* p q r s t u v w x y z { | } ~ del */
401 ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
402};
403
381 /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
382 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,OPR,OPR,OPR,OPR,OPR,OPR,
383 /* @ A B C D E F G H I J K L M N O */
384 OPR,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
385 /* P Q R S T U V W X Y Z [ \ ] ^ _ */
386 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,OPR,OPR,OPR,ATM,ATM,
387 /* ` a b c d e f g h i j k l m n o */
388 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,

--- 13 unchanged lines hidden (view full) ---

402 /* P Q R S T U V W X Y Z [ \ ] ^ _ */
403 ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
404 /* ` a b c d e f g h i j k l m n o */
405 ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
406 /* p q r s t u v w x y z { | } ~ del */
407 ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
408};
409
410/* token type table: don't strip comments */
411u_char TokTypeNoC[256] =
412{
413 /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */
414 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,SPC,SPC,SPC,SPC,SPC,ATM,ATM,
415 /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */
416 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
417 /* sp ! " # $ % & ' ( ) * + , - . / */
418 SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM, OPR,OPR,ATM,ATM,ATM,ATM,ATM,ATM,
419 /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
420 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
421 /* @ A B C D E F G H I J K L M N O */
422 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
423 /* P Q R S T U V W X Y Z [ \ ] ^ _ */
424 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
425 /* ` a b c d e f g h i j k l m n o */
426 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
427 /* p q r s t u v w x y z { | } ~ del */
428 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
404
429
405# define NOCHAR -1 /* signal nothing in lookahead token */
430 /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */
431 OPR,OPR,ONE,OPR,OPR,OPR,OPR,OPR, OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,
432 /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */
433 OPR,OPR,OPR,ONE,ONE,ONE,OPR,OPR, OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,
434 /* sp ! " # $ % & ' ( ) * + , - . / */
435 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
436 /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
437 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
438 /* @ A B C D E F G H I J K L M N O */
439 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
440 /* P Q R S T U V W X Y Z [ \ ] ^ _ */
441 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
442 /* ` a b c d e f g h i j k l m n o */
443 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
444 /* p q r s t u v w x y z { | } ~ del */
445 ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
446};
406
447
448
449#define NOCHAR -1 /* signal nothing in lookahead token */
450
407char **
408prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab)
409 char *addr;
410 int delim;
411 char pvpbuf[];
412 int pvpbsize;
413 char **delimptr;
414 u_char *toktab;

--- 5 unchanged lines hidden (view full) ---

420 bool bslashmode;
421 bool route_syntax;
422 int cmntcnt;
423 int anglecnt;
424 char *tok;
425 int state;
426 int newstate;
427 char *saveto = CurEnv->e_to;
451char **
452prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab)
453 char *addr;
454 int delim;
455 char pvpbuf[];
456 int pvpbsize;
457 char **delimptr;
458 u_char *toktab;

--- 5 unchanged lines hidden (view full) ---

464 bool bslashmode;
465 bool route_syntax;
466 int cmntcnt;
467 int anglecnt;
468 char *tok;
469 int state;
470 int newstate;
471 char *saveto = CurEnv->e_to;
428 static char *av[MAXATOM+1];
472 static char *av[MAXATOM + 1];
429 static char firsttime = TRUE;
430 extern int errno;
431
432 if (firsttime)
433 {
434 /* initialize the token type table */
435 char obuf[50];
436
437 firsttime = FALSE;
438 if (OperatorChars == NULL)
439 {
440 if (ConfigLevel < 7)
441 OperatorChars = macvalue('o', CurEnv);
442 if (OperatorChars == NULL)
443 OperatorChars = ".:@[]";
444 }
473 static char firsttime = TRUE;
474 extern int errno;
475
476 if (firsttime)
477 {
478 /* initialize the token type table */
479 char obuf[50];
480
481 firsttime = FALSE;
482 if (OperatorChars == NULL)
483 {
484 if (ConfigLevel < 7)
485 OperatorChars = macvalue('o', CurEnv);
486 if (OperatorChars == NULL)
487 OperatorChars = ".:@[]";
488 }
445 expand(OperatorChars, obuf, sizeof obuf - sizeof DELIMCHARS, CurEnv);
446 strcat(obuf, DELIMCHARS);
489 expand(OperatorChars, obuf, sizeof obuf - sizeof DELIMCHARS,
490 CurEnv);
491 (void) strlcat(obuf, DELIMCHARS, sizeof obuf);
447 for (p = obuf; *p != '\0'; p++)
448 {
449 if (TokTypeTab[*p & 0xff] == ATM)
450 TokTypeTab[*p & 0xff] = OPR;
492 for (p = obuf; *p != '\0'; p++)
493 {
494 if (TokTypeTab[*p & 0xff] == ATM)
495 TokTypeTab[*p & 0xff] = OPR;
496 if (TokTypeNoC[*p & 0xff] == ATM)
497 TokTypeNoC[*p & 0xff] = OPR;
451 }
452 }
453 if (toktab == NULL)
454 toktab = TokTypeTab;
455
456 /* make sure error messages don't have garbage on them */
457 errno = 0;
458

--- 4 unchanged lines hidden (view full) ---

463 anglecnt = 0;
464 avp = av;
465 state = ATM;
466 c = NOCHAR;
467 p = addr;
468 CurEnv->e_to = p;
469 if (tTd(22, 11))
470 {
498 }
499 }
500 if (toktab == NULL)
501 toktab = TokTypeTab;
502
503 /* make sure error messages don't have garbage on them */
504 errno = 0;
505

--- 4 unchanged lines hidden (view full) ---

510 anglecnt = 0;
511 avp = av;
512 state = ATM;
513 c = NOCHAR;
514 p = addr;
515 CurEnv->e_to = p;
516 if (tTd(22, 11))
517 {
471 printf("prescan: ");
518 dprintf("prescan: ");
472 xputs(p);
519 xputs(p);
473 (void) putchar('\n');
520 dprintf("\n");
474 }
475
476 do
477 {
478 /* read a token */
479 tok = q;
480 for (;;)
481 {
482 /* store away any old lookahead character */
483 if (c != NOCHAR && !bslashmode)
484 {
485 /* see if there is room */
486 if (q >= &pvpbuf[pvpbsize - 5])
487 {
521 }
522
523 do
524 {
525 /* read a token */
526 tok = q;
527 for (;;)
528 {
529 /* store away any old lookahead character */
530 if (c != NOCHAR && !bslashmode)
531 {
532 /* see if there is room */
533 if (q >= &pvpbuf[pvpbsize - 5])
534 {
488 usrerr("553 Address too long");
535 usrerr("553 5.1.1 Address too long");
489 if (strlen(addr) > (SIZE_T) MAXNAME)
490 addr[MAXNAME] = '\0';
491 returnnull:
492 if (delimptr != NULL)
493 *delimptr = p;
494 CurEnv->e_to = saveto;
536 if (strlen(addr) > (SIZE_T) MAXNAME)
537 addr[MAXNAME] = '\0';
538 returnnull:
539 if (delimptr != NULL)
540 *delimptr = p;
541 CurEnv->e_to = saveto;
495 return (NULL);
542 return NULL;
496 }
497
498 /* squirrel it away */
499 *q++ = c;
500 }
501
502 /* read a new input character */
503 c = *p++;

--- 30 unchanged lines hidden (view full) ---

534 {
535 usrerr("653 Unbalanced '<'");
536 c = '>';
537 p--;
538 }
539 }
540
541 if (tTd(22, 101))
543 }
544
545 /* squirrel it away */
546 *q++ = c;
547 }
548
549 /* read a new input character */
550 c = *p++;

--- 30 unchanged lines hidden (view full) ---

581 {
582 usrerr("653 Unbalanced '<'");
583 c = '>';
584 p--;
585 }
586 }
587
588 if (tTd(22, 101))
542 printf("c=%c, s=%d; ", c, state);
589 dprintf("c=%c, s=%d; ", c, state);
543
544 /* chew up special characters */
545 *q = '\0';
546 if (bslashmode)
547 {
548 bslashmode = FALSE;
549
550 /* kludge \! for naive users */

--- 10 unchanged lines hidden (view full) ---

561 }
562
563 if (c == '\\')
564 {
565 bslashmode = TRUE;
566 }
567 else if (state == QST)
568 {
590
591 /* chew up special characters */
592 *q = '\0';
593 if (bslashmode)
594 {
595 bslashmode = FALSE;
596
597 /* kludge \! for naive users */

--- 10 unchanged lines hidden (view full) ---

608 }
609
610 if (c == '\\')
611 {
612 bslashmode = TRUE;
613 }
614 else if (state == QST)
615 {
616 /* EMPTY */
569 /* do nothing, just avoid next clauses */
570 }
617 /* do nothing, just avoid next clauses */
618 }
571 else if (c == '(')
619 else if (c == '(' && toktab['('] == SPC)
572 {
573 cmntcnt++;
574 c = NOCHAR;
575 }
620 {
621 cmntcnt++;
622 c = NOCHAR;
623 }
576 else if (c == ')')
624 else if (c == ')' && toktab['('] == SPC)
577 {
578 if (cmntcnt <= 0)
579 {
580 usrerr("653 Unbalanced ')'");
581 c = NOCHAR;
582 }
583 else
584 cmntcnt--;
585 }
586 else if (cmntcnt > 0)
625 {
626 if (cmntcnt <= 0)
627 {
628 usrerr("653 Unbalanced ')'");
629 c = NOCHAR;
630 }
631 else
632 cmntcnt--;
633 }
634 else if (cmntcnt > 0)
635 {
587 c = NOCHAR;
636 c = NOCHAR;
637 }
588 else if (c == '<')
589 {
638 else if (c == '<')
639 {
590 char *q = p;
640 char *ptr = p;
591
592 anglecnt++;
641
642 anglecnt++;
593 while (isascii(*q) && isspace(*q))
594 q++;
595 if (*q == '@')
643 while (isascii(*ptr) && isspace(*ptr))
644 ptr++;
645 if (*ptr == '@')
596 route_syntax = TRUE;
597 }
598 else if (c == '>')
599 {
600 if (anglecnt <= 0)
601 {
602 usrerr("653 Unbalanced '>'");
603 c = NOCHAR;

--- 9 unchanged lines hidden (view full) ---

613 continue;
614
615 /* see if this is end of input */
616 if (c == delim && anglecnt <= 0 && state != QST)
617 break;
618
619 newstate = StateTab[state][toktab[c & 0xff]];
620 if (tTd(22, 101))
646 route_syntax = TRUE;
647 }
648 else if (c == '>')
649 {
650 if (anglecnt <= 0)
651 {
652 usrerr("653 Unbalanced '>'");
653 c = NOCHAR;

--- 9 unchanged lines hidden (view full) ---

663 continue;
664
665 /* see if this is end of input */
666 if (c == delim && anglecnt <= 0 && state != QST)
667 break;
668
669 newstate = StateTab[state][toktab[c & 0xff]];
670 if (tTd(22, 101))
621 printf("ns=%02o\n", newstate);
671 dprintf("ns=%02o\n", newstate);
622 state = newstate & TYPE;
623 if (state == ILL)
624 {
625 if (isascii(c) && isprint(c))
626 usrerr("653 Illegal character %c", c);
627 else
628 usrerr("653 Illegal character 0x%02x", c);
629 }

--- 4 unchanged lines hidden (view full) ---

634 }
635
636 /* new token */
637 if (tok != q)
638 {
639 *q++ = '\0';
640 if (tTd(22, 36))
641 {
672 state = newstate & TYPE;
673 if (state == ILL)
674 {
675 if (isascii(c) && isprint(c))
676 usrerr("653 Illegal character %c", c);
677 else
678 usrerr("653 Illegal character 0x%02x", c);
679 }

--- 4 unchanged lines hidden (view full) ---

684 }
685
686 /* new token */
687 if (tok != q)
688 {
689 *q++ = '\0';
690 if (tTd(22, 36))
691 {
642 printf("tok=");
692 dprintf("tok=");
643 xputs(tok);
693 xputs(tok);
644 (void) putchar('\n');
694 dprintf("\n");
645 }
646 if (avp >= &av[MAXATOM])
647 {
695 }
696 if (avp >= &av[MAXATOM])
697 {
648 usrerr("553 prescan: too many tokens");
698 usrerr("553 5.1.0 prescan: too many tokens");
649 goto returnnull;
650 }
651 if (q - tok > MAXNAME)
652 {
699 goto returnnull;
700 }
701 if (q - tok > MAXNAME)
702 {
653 usrerr("553 prescan: token too long");
703 usrerr("553 5.1.0 prescan: token too long");
654 goto returnnull;
655 }
656 *avp++ = tok;
657 }
658 } while (c != '\0' && (c != delim || anglecnt > 0));
659 *avp = NULL;
660 p--;
661 if (delimptr != NULL)
662 *delimptr = p;
663 if (tTd(22, 12))
664 {
704 goto returnnull;
705 }
706 *avp++ = tok;
707 }
708 } while (c != '\0' && (c != delim || anglecnt > 0));
709 *avp = NULL;
710 p--;
711 if (delimptr != NULL)
712 *delimptr = p;
713 if (tTd(22, 12))
714 {
665 printf("prescan==>");
715 dprintf("prescan==>");
666 printav(av);
667 }
668 CurEnv->e_to = saveto;
669 if (av[0] == NULL)
670 {
671 if (tTd(22, 1))
716 printav(av);
717 }
718 CurEnv->e_to = saveto;
719 if (av[0] == NULL)
720 {
721 if (tTd(22, 1))
672 printf("prescan: null leading token\n");
673 return (NULL);
722 dprintf("prescan: null leading token\n");
723 return NULL;
674 }
724 }
675 return (av);
725 return av;
676}
677 /*
678** REWRITE -- apply rewrite rules to token vector.
679**
680** This routine is an ordered production system. Each rewrite
681** rule has a LHS (called the pattern) and a RHS (called the
682** rewrite); 'rwr' points the the current rewrite rule.
683**

--- 23 unchanged lines hidden (view full) ---

707** attempt recovery.
708**
709** Side Effects:
710** pvp is modified.
711*/
712
713struct match
714{
726}
727 /*
728** REWRITE -- apply rewrite rules to token vector.
729**
730** This routine is an ordered production system. Each rewrite
731** rule has a LHS (called the pattern) and a RHS (called the
732** rewrite); 'rwr' points the the current rewrite rule.
733**

--- 23 unchanged lines hidden (view full) ---

757** attempt recovery.
758**
759** Side Effects:
760** pvp is modified.
761*/
762
763struct match
764{
715 char **first; /* first token matched */
716 char **last; /* last token matched */
717 char **pattern; /* pointer to pattern */
765 char **match_first; /* first token matched */
766 char **match_last; /* last token matched */
767 char **match_pattern; /* pointer to pattern */
718};
719
768};
769
720# define MAXMATCH 9 /* max params per rewrite */
770#define MAXMATCH 9 /* max params per rewrite */
721
722
723int
724rewrite(pvp, ruleset, reclevel, e)
725 char **pvp;
726 int ruleset;
727 int reclevel;
728 register ENVELOPE *e;
729{
730 register char *ap; /* address pointer */
731 register char *rp; /* rewrite pointer */
771
772
773int
774rewrite(pvp, ruleset, reclevel, e)
775 char **pvp;
776 int ruleset;
777 int reclevel;
778 register ENVELOPE *e;
779{
780 register char *ap; /* address pointer */
781 register char *rp; /* rewrite pointer */
782 register char *rulename; /* ruleset name */
783 register char *prefix;
732 register char **avp; /* address vector pointer */
733 register char **rvp; /* rewrite vector pointer */
734 register struct match *mlp; /* cur ptr into mlist */
735 register struct rewrite *rwr; /* pointer to current rewrite rule */
736 int ruleno; /* current rule number */
737 int rstat = EX_OK; /* return status */
738 int loopcount;
739 struct match mlist[MAXMATCH]; /* stores match on LHS */
784 register char **avp; /* address vector pointer */
785 register char **rvp; /* rewrite vector pointer */
786 register struct match *mlp; /* cur ptr into mlist */
787 register struct rewrite *rwr; /* pointer to current rewrite rule */
788 int ruleno; /* current rule number */
789 int rstat = EX_OK; /* return status */
790 int loopcount;
791 struct match mlist[MAXMATCH]; /* stores match on LHS */
740 char *npvp[MAXATOM+1]; /* temporary space for rebuild */
792 char *npvp[MAXATOM + 1]; /* temporary space for rebuild */
741 char buf[MAXLINE];
793 char buf[MAXLINE];
742 extern int callsubr __P((char**, int, ENVELOPE *));
743 extern int sm_strcasecmp __P((char *, char *));
794 char name[6];
744
795
745 if (OpMode == MD_TEST || tTd(21, 1))
796 if (ruleset < 0 || ruleset >= MAXRWSETS)
746 {
797 {
747 printf("rewrite: ruleset %3d input:", ruleset);
798 syserr("554 5.3.5 rewrite: illegal ruleset number %d", ruleset);
799 return EX_CONFIG;
800 }
801 rulename = RuleSetNames[ruleset];
802 if (rulename == NULL)
803 {
804 snprintf(name, sizeof name, "%d", ruleset);
805 rulename = name;
806 }
807 if (OpMode == MD_TEST)
808 prefix = "";
809 else
810 prefix = "rewrite: ruleset ";
811 if (OpMode == MD_TEST)
812 {
813 printf("%s%-16.16s input:", prefix, rulename);
748 printav(pvp);
749 }
814 printav(pvp);
815 }
750 if (ruleset < 0 || ruleset >= MAXRWSETS)
816 else if (tTd(21, 1))
751 {
817 {
752 syserr("554 rewrite: illegal ruleset number %d", ruleset);
753 return EX_CONFIG;
818 dprintf("%s%-16.16s input:", prefix, rulename);
819 printav(pvp);
754 }
755 if (reclevel++ > MaxRuleRecursion)
756 {
820 }
821 if (reclevel++ > MaxRuleRecursion)
822 {
757 syserr("rewrite: excessive recursion (max %d), ruleset %d",
758 MaxRuleRecursion, ruleset);
823 syserr("rewrite: excessive recursion (max %d), ruleset %s",
824 MaxRuleRecursion, rulename);
759 return EX_CONFIG;
760 }
761 if (pvp == NULL)
762 return EX_USAGE;
763
764 /*
765 ** Run through the list of rewrite rules, applying
766 ** any that match.
767 */
768
769 ruleno = 1;
770 loopcount = 0;
771 for (rwr = RewriteRules[ruleset]; rwr != NULL; )
772 {
825 return EX_CONFIG;
826 }
827 if (pvp == NULL)
828 return EX_USAGE;
829
830 /*
831 ** Run through the list of rewrite rules, applying
832 ** any that match.
833 */
834
835 ruleno = 1;
836 loopcount = 0;
837 for (rwr = RewriteRules[ruleset]; rwr != NULL; )
838 {
773 int stat;
839 int status;
774
775 /* if already canonical, quit now */
776 if (pvp[0] != NULL && (pvp[0][0] & 0377) == CANONNET)
777 break;
778
779 if (tTd(21, 12))
780 {
840
841 /* if already canonical, quit now */
842 if (pvp[0] != NULL && (pvp[0][0] & 0377) == CANONNET)
843 break;
844
845 if (tTd(21, 12))
846 {
781 printf("-----trying rule:");
847 if (tTd(21, 15))
848 dprintf("-----trying rule (line %d):",
849 rwr->r_line);
850 else
851 dprintf("-----trying rule:");
782 printav(rwr->r_lhs);
783 }
784
785 /* try to match on this rule */
786 mlp = mlist;
787 rvp = rwr->r_lhs;
788 avp = pvp;
789 if (++loopcount > 100)
790 {
852 printav(rwr->r_lhs);
853 }
854
855 /* try to match on this rule */
856 mlp = mlist;
857 rvp = rwr->r_lhs;
858 avp = pvp;
859 if (++loopcount > 100)
860 {
791 syserr("554 Infinite loop in ruleset %d, rule %d",
792 ruleset, ruleno);
861 syserr("554 5.3.5 Infinite loop in ruleset %s, rule %d",
862 rulename, ruleno);
793 if (tTd(21, 1))
794 {
863 if (tTd(21, 1))
864 {
795 printf("workspace: ");
865 dprintf("workspace: ");
796 printav(pvp);
797 }
798 break;
799 }
800
801 while ((ap = *avp) != NULL || *rvp != NULL)
802 {
803 rp = *rvp;
804 if (tTd(21, 35))
805 {
866 printav(pvp);
867 }
868 break;
869 }
870
871 while ((ap = *avp) != NULL || *rvp != NULL)
872 {
873 rp = *rvp;
874 if (tTd(21, 35))
875 {
806 printf("ADVANCE rp=");
876 dprintf("ADVANCE rp=");
807 xputs(rp);
877 xputs(rp);
808 printf(", ap=");
878 dprintf(", ap=");
809 xputs(ap);
879 xputs(ap);
810 printf("\n");
880 dprintf("\n");
811 }
812 if (rp == NULL)
813 {
814 /* end-of-pattern before end-of-address */
815 goto backup;
816 }
817 if (ap == NULL && (*rp & 0377) != MATCHZANY &&
818 (*rp & 0377) != MATCHZERO)
819 {
820 /* end-of-input with patterns left */
821 goto backup;
822 }
823
824 switch (*rp & 0377)
825 {
826 case MATCHCLASS:
827 /* match any phrase in a class */
881 }
882 if (rp == NULL)
883 {
884 /* end-of-pattern before end-of-address */
885 goto backup;
886 }
887 if (ap == NULL && (*rp & 0377) != MATCHZANY &&
888 (*rp & 0377) != MATCHZERO)
889 {
890 /* end-of-input with patterns left */
891 goto backup;
892 }
893
894 switch (*rp & 0377)
895 {
896 case MATCHCLASS:
897 /* match any phrase in a class */
828 mlp->pattern = rvp;
829 mlp->first = avp;
898 mlp->match_pattern = rvp;
899 mlp->match_first = avp;
830 extendclass:
831 ap = *avp;
832 if (ap == NULL)
833 goto backup;
900 extendclass:
901 ap = *avp;
902 if (ap == NULL)
903 goto backup;
834 mlp->last = avp++;
835 cataddr(mlp->first, mlp->last, buf, sizeof buf, '\0');
904 mlp->match_last = avp++;
905 cataddr(mlp->match_first, mlp->match_last,
906 buf, sizeof buf, '\0');
836 if (!wordinclass(buf, rp[1]))
837 {
838 if (tTd(21, 36))
839 {
907 if (!wordinclass(buf, rp[1]))
908 {
909 if (tTd(21, 36))
910 {
840 printf("EXTEND rp=");
911 dprintf("EXTEND rp=");
841 xputs(rp);
912 xputs(rp);
842 printf(", ap=");
913 dprintf(", ap=");
843 xputs(ap);
914 xputs(ap);
844 printf("\n");
915 dprintf("\n");
845 }
846 goto extendclass;
847 }
848 if (tTd(21, 36))
916 }
917 goto extendclass;
918 }
919 if (tTd(21, 36))
849 printf("CLMATCH\n");
920 dprintf("CLMATCH\n");
850 mlp++;
851 break;
852
853 case MATCHNCLASS:
854 /* match any token not in a class */
855 if (wordinclass(ap, rp[1]))
856 goto backup;
857
921 mlp++;
922 break;
923
924 case MATCHNCLASS:
925 /* match any token not in a class */
926 if (wordinclass(ap, rp[1]))
927 goto backup;
928
858 /* fall through */
929 /* FALLTHROUGH */
859
860 case MATCHONE:
861 case MATCHANY:
862 /* match exactly one token */
930
931 case MATCHONE:
932 case MATCHANY:
933 /* match exactly one token */
863 mlp->pattern = rvp;
864 mlp->first = avp;
865 mlp->last = avp++;
934 mlp->match_pattern = rvp;
935 mlp->match_first = avp;
936 mlp->match_last = avp++;
866 mlp++;
867 break;
868
869 case MATCHZANY:
870 /* match zero or more tokens */
937 mlp++;
938 break;
939
940 case MATCHZANY:
941 /* match zero or more tokens */
871 mlp->pattern = rvp;
872 mlp->first = avp;
873 mlp->last = avp - 1;
942 mlp->match_pattern = rvp;
943 mlp->match_first = avp;
944 mlp->match_last = avp - 1;
874 mlp++;
875 break;
876
877 case MATCHZERO:
878 /* match zero tokens */
879 break;
880
881 case MACRODEXPAND:
882 /*
883 ** Match against run-time macro.
884 ** This algorithm is broken for the
885 ** general case (no recursive macros,
886 ** improper tokenization) but should
887 ** work for the usual cases.
888 */
889
890 ap = macvalue(rp[1], e);
945 mlp++;
946 break;
947
948 case MATCHZERO:
949 /* match zero tokens */
950 break;
951
952 case MACRODEXPAND:
953 /*
954 ** Match against run-time macro.
955 ** This algorithm is broken for the
956 ** general case (no recursive macros,
957 ** improper tokenization) but should
958 ** work for the usual cases.
959 */
960
961 ap = macvalue(rp[1], e);
891 mlp->first = avp;
962 mlp->match_first = avp;
892 if (tTd(21, 2))
963 if (tTd(21, 2))
893 printf("rewrite: LHS $&%s => \"%s\"\n",
964 dprintf("rewrite: LHS $&%s => \"%s\"\n",
894 macname(rp[1]),
895 ap == NULL ? "(NULL)" : ap);
896
897 if (ap == NULL)
898 break;
899 while (*ap != '\0')
900 {
901 if (*avp == NULL ||
902 strncasecmp(ap, *avp, strlen(*avp)) != 0)
903 {
904 /* no match */
965 macname(rp[1]),
966 ap == NULL ? "(NULL)" : ap);
967
968 if (ap == NULL)
969 break;
970 while (*ap != '\0')
971 {
972 if (*avp == NULL ||
973 strncasecmp(ap, *avp, strlen(*avp)) != 0)
974 {
975 /* no match */
905 avp = mlp->first;
976 avp = mlp->match_first;
906 goto backup;
907 }
908 ap += strlen(*avp++);
909 }
910
911 /* match */
912 break;
913

--- 8 unchanged lines hidden (view full) ---

922 /* successful match on this token */
923 rvp++;
924 continue;
925
926 backup:
927 /* match failed -- back up */
928 while (--mlp >= mlist)
929 {
977 goto backup;
978 }
979 ap += strlen(*avp++);
980 }
981
982 /* match */
983 break;
984

--- 8 unchanged lines hidden (view full) ---

993 /* successful match on this token */
994 rvp++;
995 continue;
996
997 backup:
998 /* match failed -- back up */
999 while (--mlp >= mlist)
1000 {
930 rvp = mlp->pattern;
1001 rvp = mlp->match_pattern;
931 rp = *rvp;
1002 rp = *rvp;
932 avp = mlp->last + 1;
1003 avp = mlp->match_last + 1;
933 ap = *avp;
934
935 if (tTd(21, 36))
936 {
1004 ap = *avp;
1005
1006 if (tTd(21, 36))
1007 {
937 printf("BACKUP rp=");
1008 dprintf("BACKUP rp=");
938 xputs(rp);
1009 xputs(rp);
939 printf(", ap=");
1010 dprintf(", ap=");
940 xputs(ap);
1011 xputs(ap);
941 printf("\n");
1012 dprintf("\n");
942 }
943
944 if (ap == NULL)
945 {
946 /* run off the end -- back up again */
947 continue;
948 }
949 if ((*rp & 0377) == MATCHANY ||
950 (*rp & 0377) == MATCHZANY)
951 {
952 /* extend binding and continue */
1013 }
1014
1015 if (ap == NULL)
1016 {
1017 /* run off the end -- back up again */
1018 continue;
1019 }
1020 if ((*rp & 0377) == MATCHANY ||
1021 (*rp & 0377) == MATCHZANY)
1022 {
1023 /* extend binding and continue */
953 mlp->last = avp++;
1024 mlp->match_last = avp++;
954 rvp++;
955 mlp++;
956 break;
957 }
958 if ((*rp & 0377) == MATCHCLASS)
959 {
960 /* extend binding and try again */
1025 rvp++;
1026 mlp++;
1027 break;
1028 }
1029 if ((*rp & 0377) == MATCHCLASS)
1030 {
1031 /* extend binding and try again */
961 mlp->last = avp;
1032 mlp->match_last = avp;
962 goto extendclass;
963 }
964 }
965
966 if (mlp < mlist)
967 {
968 /* total failure to match */
969 break;
970 }
971 }
972
973 /*
974 ** See if we successfully matched
975 */
976
977 if (mlp < mlist || *rvp != NULL)
978 {
979 if (tTd(21, 10))
1033 goto extendclass;
1034 }
1035 }
1036
1037 if (mlp < mlist)
1038 {
1039 /* total failure to match */
1040 break;
1041 }
1042 }
1043
1044 /*
1045 ** See if we successfully matched
1046 */
1047
1048 if (mlp < mlist || *rvp != NULL)
1049 {
1050 if (tTd(21, 10))
980 printf("----- rule fails\n");
1051 dprintf("----- rule fails\n");
981 rwr = rwr->r_next;
982 ruleno++;
983 loopcount = 0;
984 continue;
985 }
986
987 rvp = rwr->r_rhs;
988 if (tTd(21, 12))
989 {
1052 rwr = rwr->r_next;
1053 ruleno++;
1054 loopcount = 0;
1055 continue;
1056 }
1057
1058 rvp = rwr->r_rhs;
1059 if (tTd(21, 12))
1060 {
990 printf("-----rule matches:");
1061 dprintf("-----rule matches:");
991 printav(rvp);
992 }
993
994 rp = *rvp;
1062 printav(rvp);
1063 }
1064
1065 rp = *rvp;
995 if ((*rp & 0377) == CANONUSER)
1066 if (rp != NULL)
996 {
1067 {
997 rvp++;
998 rwr = rwr->r_next;
999 ruleno++;
1000 loopcount = 0;
1068 if ((*rp & 0377) == CANONUSER)
1069 {
1070 rvp++;
1071 rwr = rwr->r_next;
1072 ruleno++;
1073 loopcount = 0;
1074 }
1075 else if ((*rp & 0377) == CANONHOST)
1076 {
1077 rvp++;
1078 rwr = NULL;
1079 }
1001 }
1080 }
1002 else if ((*rp & 0377) == CANONHOST)
1003 {
1004 rvp++;
1005 rwr = NULL;
1006 }
1007
1008 /* substitute */
1009 for (avp = npvp; *rvp != NULL; rvp++)
1010 {
1011 register struct match *m;
1012 register char **pp;
1013
1014 rp = *rvp;
1015 if ((*rp & 0377) == MATCHREPL)
1016 {
1017 /* substitute from LHS */
1018 m = &mlist[rp[1] - '1'];
1019 if (m < mlist || m >= mlp)
1020 {
1081
1082 /* substitute */
1083 for (avp = npvp; *rvp != NULL; rvp++)
1084 {
1085 register struct match *m;
1086 register char **pp;
1087
1088 rp = *rvp;
1089 if ((*rp & 0377) == MATCHREPL)
1090 {
1091 /* substitute from LHS */
1092 m = &mlist[rp[1] - '1'];
1093 if (m < mlist || m >= mlp)
1094 {
1021 syserr("554 rewrite: ruleset %d: replacement $%c out of bounds",
1022 ruleset, rp[1]);
1095 syserr("554 5.3.5 rewrite: ruleset %s: replacement $%c out of bounds",
1096 rulename, rp[1]);
1023 return EX_CONFIG;
1024 }
1025 if (tTd(21, 15))
1026 {
1097 return EX_CONFIG;
1098 }
1099 if (tTd(21, 15))
1100 {
1027 printf("$%c:", rp[1]);
1028 pp = m->first;
1029 while (pp <= m->last)
1101 dprintf("$%c:", rp[1]);
1102 pp = m->match_first;
1103 while (pp <= m->match_last)
1030 {
1104 {
1031 printf(" %lx=\"", (u_long) *pp);
1032 (void) fflush(stdout);
1033 printf("%s\"", *pp++);
1105 dprintf(" %lx=\"",
1106 (u_long) *pp);
1107 (void) dflush();
1108 dprintf("%s\"", *pp++);
1034 }
1109 }
1035 printf("\n");
1110 dprintf("\n");
1036 }
1111 }
1037 pp = m->first;
1038 while (pp <= m->last)
1112 pp = m->match_first;
1113 while (pp <= m->match_last)
1039 {
1040 if (avp >= &npvp[MAXATOM])
1041 {
1114 {
1115 if (avp >= &npvp[MAXATOM])
1116 {
1042 syserr("554 rewrite: expansion too long");
1117 syserr("554 5.3.0 rewrite: expansion too long");
1043 return EX_DATAERR;
1044 }
1045 *avp++ = *pp++;
1046 }
1047 }
1048 else
1049 {
1050 /* some sort of replacement */
1051 if (avp >= &npvp[MAXATOM])
1052 {
1053 toolong:
1118 return EX_DATAERR;
1119 }
1120 *avp++ = *pp++;
1121 }
1122 }
1123 else
1124 {
1125 /* some sort of replacement */
1126 if (avp >= &npvp[MAXATOM])
1127 {
1128 toolong:
1054 syserr("554 rewrite: expansion too long");
1129 syserr("554 5.3.0 rewrite: expansion too long");
1055 return EX_DATAERR;
1056 }
1057 if ((*rp & 0377) != MACRODEXPAND)
1058 {
1059 /* vanilla replacement */
1060 *avp++ = rp;
1061 }
1062 else
1063 {
1064 /* $&x replacement */
1065 char *mval = macvalue(rp[1], e);
1066 char **xpvp;
1067 int trsize = 0;
1068 static size_t pvpb1_size = 0;
1069 static char **pvpb1 = NULL;
1070 char pvpbuf[PSBUFSIZE];
1071
1072 if (tTd(21, 2))
1130 return EX_DATAERR;
1131 }
1132 if ((*rp & 0377) != MACRODEXPAND)
1133 {
1134 /* vanilla replacement */
1135 *avp++ = rp;
1136 }
1137 else
1138 {
1139 /* $&x replacement */
1140 char *mval = macvalue(rp[1], e);
1141 char **xpvp;
1142 int trsize = 0;
1143 static size_t pvpb1_size = 0;
1144 static char **pvpb1 = NULL;
1145 char pvpbuf[PSBUFSIZE];
1146
1147 if (tTd(21, 2))
1073 printf("rewrite: RHS $&%s => \"%s\"\n",
1148 dprintf("rewrite: RHS $&%s => \"%s\"\n",
1074 macname(rp[1]),
1075 mval == NULL ? "(NULL)" : mval);
1076 if (mval == NULL || *mval == '\0')
1077 continue;
1078
1079 /* save the remainder of the input */
1080 for (xpvp = pvp; *xpvp != NULL; xpvp++)
1081 trsize += sizeof *xpvp;
1149 macname(rp[1]),
1150 mval == NULL ? "(NULL)" : mval);
1151 if (mval == NULL || *mval == '\0')
1152 continue;
1153
1154 /* save the remainder of the input */
1155 for (xpvp = pvp; *xpvp != NULL; xpvp++)
1156 trsize += sizeof *xpvp;
1082 if (trsize > pvpb1_size)
1157 if ((size_t) trsize > pvpb1_size)
1083 {
1084 if (pvpb1 != NULL)
1085 free(pvpb1);
1086 pvpb1 = (char **)xalloc(trsize);
1087 pvpb1_size = trsize;
1088 }
1089
1158 {
1159 if (pvpb1 != NULL)
1160 free(pvpb1);
1161 pvpb1 = (char **)xalloc(trsize);
1162 pvpb1_size = trsize;
1163 }
1164
1090 bcopy((char *) pvp, (char *) pvpb1, trsize);
1165 memmove((char *) pvpb1,
1166 (char *) pvp,
1167 trsize);
1091
1092 /* scan the new replacement */
1093 xpvp = prescan(mval, '\0', pvpbuf,
1168
1169 /* scan the new replacement */
1170 xpvp = prescan(mval, '\0', pvpbuf,
1094 sizeof pvpbuf, NULL, NULL);
1171 sizeof pvpbuf, NULL,
1172 NULL);
1095 if (xpvp == NULL)
1096 {
1097 /* prescan pre-printed error */
1098 return EX_DATAERR;
1099 }
1100
1101 /* insert it into the output stream */
1102 while (*xpvp != NULL)
1103 {
1104 if (tTd(21, 19))
1173 if (xpvp == NULL)
1174 {
1175 /* prescan pre-printed error */
1176 return EX_DATAERR;
1177 }
1178
1179 /* insert it into the output stream */
1180 while (*xpvp != NULL)
1181 {
1182 if (tTd(21, 19))
1105 printf(" ... %s\n", *xpvp);
1183 dprintf(" ... %s\n",
1184 *xpvp);
1106 *avp++ = newstr(*xpvp);
1107 if (avp >= &npvp[MAXATOM])
1108 goto toolong;
1109 xpvp++;
1110 }
1111 if (tTd(21, 19))
1185 *avp++ = newstr(*xpvp);
1186 if (avp >= &npvp[MAXATOM])
1187 goto toolong;
1188 xpvp++;
1189 }
1190 if (tTd(21, 19))
1112 printf(" ... DONE\n");
1191 dprintf(" ... DONE\n");
1113
1114 /* restore the old trailing input */
1192
1193 /* restore the old trailing input */
1115 bcopy((char *) pvpb1, (char *) pvp, trsize);
1194 memmove((char *) pvp,
1195 (char *) pvpb1,
1196 trsize);
1116 }
1117 }
1118 }
1119 *avp++ = NULL;
1120
1121 /*
1122 ** Check for any hostname/keyword lookups.
1123 */

--- 5 unchanged lines hidden (view full) ---

1129 int trsize;
1130 char *replac;
1131 int endtoken;
1132 STAB *map;
1133 char *mapname;
1134 char **key_rvp;
1135 char **arg_rvp;
1136 char **default_rvp;
1197 }
1198 }
1199 }
1200 *avp++ = NULL;
1201
1202 /*
1203 ** Check for any hostname/keyword lookups.
1204 */

--- 5 unchanged lines hidden (view full) ---

1210 int trsize;
1211 char *replac;
1212 int endtoken;
1213 STAB *map;
1214 char *mapname;
1215 char **key_rvp;
1216 char **arg_rvp;
1217 char **default_rvp;
1137 char buf[MAXNAME + 1];
1218 char cbuf[MAXNAME + 1];
1138 char *pvpb1[MAXATOM + 1];
1139 char *argvect[10];
1140 char pvpbuf[PSBUFSIZE];
1141 char *nullpvp[1];
1219 char *pvpb1[MAXATOM + 1];
1220 char *argvect[10];
1221 char pvpbuf[PSBUFSIZE];
1222 char *nullpvp[1];
1142 extern char *map_lookup __P((STAB *, char *, char **, int *, ENVELOPE *));
1143
1144 if ((**rvp & 0377) != HOSTBEGIN &&
1145 (**rvp & 0377) != LOOKUPBEGIN)
1146 continue;
1147
1148 /*
1149 ** Got a hostname/keyword lookup.
1150 **

--- 8 unchanged lines hidden (view full) ---

1159 }
1160 else
1161 {
1162 endtoken = LOOKUPEND;
1163 mapname = *++rvp;
1164 }
1165 map = stab(mapname, ST_MAP, ST_FIND);
1166 if (map == NULL)
1223
1224 if ((**rvp & 0377) != HOSTBEGIN &&
1225 (**rvp & 0377) != LOOKUPBEGIN)
1226 continue;
1227
1228 /*
1229 ** Got a hostname/keyword lookup.
1230 **

--- 8 unchanged lines hidden (view full) ---

1239 }
1240 else
1241 {
1242 endtoken = LOOKUPEND;
1243 mapname = *++rvp;
1244 }
1245 map = stab(mapname, ST_MAP, ST_FIND);
1246 if (map == NULL)
1167 syserr("554 rewrite: map %s not found", mapname);
1247 syserr("554 5.3.0 rewrite: map %s not found", mapname);
1168
1169 /* extract the match part */
1170 key_rvp = ++rvp;
1171 default_rvp = NULL;
1172 arg_rvp = argvect;
1173 xpvp = NULL;
1174 replac = pvpbuf;
1175 while (*rvp != NULL && (**rvp & 0377) != endtoken)

--- 36 unchanged lines hidden (view full) ---

1212 &pvpbuf[sizeof pvpbuf] - replac,
1213 '\0');
1214 *++arg_rvp = replac;
1215 }
1216 *++arg_rvp = NULL;
1217
1218 /* save the remainder of the input string */
1219 trsize = (int) (avp - rvp + 1) * sizeof *rvp;
1248
1249 /* extract the match part */
1250 key_rvp = ++rvp;
1251 default_rvp = NULL;
1252 arg_rvp = argvect;
1253 xpvp = NULL;
1254 replac = pvpbuf;
1255 while (*rvp != NULL && (**rvp & 0377) != endtoken)

--- 36 unchanged lines hidden (view full) ---

1292 &pvpbuf[sizeof pvpbuf] - replac,
1293 '\0');
1294 *++arg_rvp = replac;
1295 }
1296 *++arg_rvp = NULL;
1297
1298 /* save the remainder of the input string */
1299 trsize = (int) (avp - rvp + 1) * sizeof *rvp;
1220 bcopy((char *) rvp, (char *) pvpb1, trsize);
1300 memmove((char *) pvpb1, (char *) rvp, trsize);
1221
1222 /* look it up */
1301
1302 /* look it up */
1223 cataddr(key_rvp, NULL, buf, sizeof buf, '\0');
1224 argvect[0] = buf;
1225 replac = map_lookup(map, buf, argvect, &rstat, e);
1303 cataddr(key_rvp, NULL, cbuf, sizeof cbuf,
1304 map == NULL ? '\0' : map->s_map.map_spacesub);
1305 argvect[0] = cbuf;
1306 replac = map_lookup(map, cbuf, argvect, &rstat, e);
1226
1227 /* if no replacement, use default */
1228 if (replac == NULL && default_rvp != NULL)
1229 {
1230 /* create the default */
1307
1308 /* if no replacement, use default */
1309 if (replac == NULL && default_rvp != NULL)
1310 {
1311 /* create the default */
1231 cataddr(default_rvp, NULL, buf, sizeof buf, '\0');
1232 replac = buf;
1312 cataddr(default_rvp, NULL, cbuf, sizeof cbuf, '\0');
1313 replac = cbuf;
1233 }
1234
1235 if (replac == NULL)
1236 {
1237 xpvp = key_rvp;
1238 }
1239 else if (*replac == '\0')
1240 {

--- 27 unchanged lines hidden (view full) ---

1268 if (avp >= &npvp[MAXATOM])
1269 goto toolong;
1270 }
1271
1272 /*
1273 ** Check for subroutine calls.
1274 */
1275
1314 }
1315
1316 if (replac == NULL)
1317 {
1318 xpvp = key_rvp;
1319 }
1320 else if (*replac == '\0')
1321 {

--- 27 unchanged lines hidden (view full) ---

1349 if (avp >= &npvp[MAXATOM])
1350 goto toolong;
1351 }
1352
1353 /*
1354 ** Check for subroutine calls.
1355 */
1356
1276 stat = callsubr(npvp, reclevel, e);
1277 if (rstat == EX_OK || stat == EX_TEMPFAIL)
1278 rstat = stat;
1357 status = callsubr(npvp, reclevel, e);
1358 if (rstat == EX_OK || status == EX_TEMPFAIL)
1359 rstat = status;
1279
1280 /* copy vector back into original space. */
1281 for (avp = npvp; *avp++ != NULL;)
1282 continue;
1360
1361 /* copy vector back into original space. */
1362 for (avp = npvp; *avp++ != NULL;)
1363 continue;
1283 bcopy((char *) npvp, (char *) pvp,
1364 memmove((char *) pvp, (char *) npvp,
1284 (int) (avp - npvp) * sizeof *avp);
1365 (int) (avp - npvp) * sizeof *avp);
1285
1366
1286 if (tTd(21, 4))
1287 {
1367 if (tTd(21, 4))
1368 {
1288 printf("rewritten as:");
1369 dprintf("rewritten as:");
1289 printav(pvp);
1290 }
1291 }
1292
1370 printav(pvp);
1371 }
1372 }
1373
1293 if (OpMode == MD_TEST || tTd(21, 1))
1374 if (OpMode == MD_TEST)
1294 {
1375 {
1295 printf("rewrite: ruleset %3d returns:", ruleset);
1376 printf("%s%-16.16s returns:", prefix, rulename);
1296 printav(pvp);
1297 }
1377 printav(pvp);
1378 }
1298
1379 else if (tTd(21, 1))
1380 {
1381 dprintf("%s%-16.16s returns:", prefix, rulename);
1382 printav(pvp);
1383 }
1299 return rstat;
1300}
1301 /*
1302** CALLSUBR -- call subroutines in rewrite vector
1303**
1304** Parameters:
1305** pvp -- pointer to token vector.
1306** reclevel -- the current recursion level.
1307** e -- the current envelope.
1308**
1309** Returns:
1310** The status from the subroutine call.
1311**
1312** Side Effects:
1313** pvp is modified.
1314*/
1315
1384 return rstat;
1385}
1386 /*
1387** CALLSUBR -- call subroutines in rewrite vector
1388**
1389** Parameters:
1390** pvp -- pointer to token vector.
1391** reclevel -- the current recursion level.
1392** e -- the current envelope.
1393**
1394** Returns:
1395** The status from the subroutine call.
1396**
1397** Side Effects:
1398** pvp is modified.
1399*/
1400
1316int
1401static int
1317callsubr(pvp, reclevel, e)
1318 char **pvp;
1319 int reclevel;
1320 ENVELOPE *e;
1321{
1402callsubr(pvp, reclevel, e)
1403 char **pvp;
1404 int reclevel;
1405 ENVELOPE *e;
1406{
1322 char **avp;
1323 char **rvp;
1407 char **avp;
1408 char **rvp;
1324 register int i;
1325 int subr;
1409 register int i;
1410 int subr;
1326 int stat;
1411 int status;
1327 int rstat = EX_OK;
1328 char *tpvp[MAXATOM + 1];
1329
1330 for (avp = pvp; *avp != NULL; avp++)
1331 {
1332 if ((**avp & 0377) == CALLSUBR && avp[1] != NULL)
1333 {
1334 stripquotes(avp[1]);
1335 subr = strtorwset(avp[1], NULL, ST_FIND);
1336 if (subr < 0)
1337 {
1338 syserr("Unknown ruleset %s", avp[1]);
1339 return EX_CONFIG;
1340 }
1341
1342 if (tTd(21, 3))
1412 int rstat = EX_OK;
1413 char *tpvp[MAXATOM + 1];
1414
1415 for (avp = pvp; *avp != NULL; avp++)
1416 {
1417 if ((**avp & 0377) == CALLSUBR && avp[1] != NULL)
1418 {
1419 stripquotes(avp[1]);
1420 subr = strtorwset(avp[1], NULL, ST_FIND);
1421 if (subr < 0)
1422 {
1423 syserr("Unknown ruleset %s", avp[1]);
1424 return EX_CONFIG;
1425 }
1426
1427 if (tTd(21, 3))
1343 printf("-----callsubr %s (%d)\n", avp[1], subr);
1344
1428 dprintf("-----callsubr %s (%d)\n",
1429 avp[1], subr);
1430
1345 /*
1346 ** Take care of possible inner calls first.
1347 ** use a full size temporary buffer to avoid
1348 ** overflows in rewrite, but strip off the
1349 ** subroutine call.
1350 */
1351
1352 for (i = 2; avp[i] != NULL; i++)
1353 tpvp[i - 2] = avp[i];
1354 tpvp[i - 2] = NULL;
1355
1431 /*
1432 ** Take care of possible inner calls first.
1433 ** use a full size temporary buffer to avoid
1434 ** overflows in rewrite, but strip off the
1435 ** subroutine call.
1436 */
1437
1438 for (i = 2; avp[i] != NULL; i++)
1439 tpvp[i - 2] = avp[i];
1440 tpvp[i - 2] = NULL;
1441
1356 stat = callsubr(tpvp, reclevel, e);
1357 if (rstat == EX_OK || stat == EX_TEMPFAIL)
1358 rstat = stat;
1442 status = callsubr(tpvp, reclevel, e);
1443 if (rstat == EX_OK || status == EX_TEMPFAIL)
1444 rstat = status;
1359
1360 /*
1361 ** Now we need to call the ruleset specified for
1362 ** the subroutine. we can do this with the
1363 ** temporary buffer that we set up earlier,
1364 ** since it has all the data we want to rewrite.
1365 */
1366
1445
1446 /*
1447 ** Now we need to call the ruleset specified for
1448 ** the subroutine. we can do this with the
1449 ** temporary buffer that we set up earlier,
1450 ** since it has all the data we want to rewrite.
1451 */
1452
1367 stat = rewrite(tpvp, subr, reclevel, e);
1368 if (rstat == EX_OK || stat == EX_TEMPFAIL)
1369 rstat = stat;
1453 status = rewrite(tpvp, subr, reclevel, e);
1454 if (rstat == EX_OK || status == EX_TEMPFAIL)
1455 rstat = status;
1370
1371 /*
1372 ** Find length of tpvp and current offset into
1373 ** pvp, if the total is greater than MAXATOM,
1374 ** then it would overflow the buffer if we copied
1375 ** it back in to pvp, in which case we throw a
1376 ** fit.
1377 */
1378
1379 for (rvp = tpvp; *rvp != NULL; rvp++)
1380 continue;
1381 if (((rvp - tpvp) + (avp - pvp)) > MAXATOM)
1382 {
1456
1457 /*
1458 ** Find length of tpvp and current offset into
1459 ** pvp, if the total is greater than MAXATOM,
1460 ** then it would overflow the buffer if we copied
1461 ** it back in to pvp, in which case we throw a
1462 ** fit.
1463 */
1464
1465 for (rvp = tpvp; *rvp != NULL; rvp++)
1466 continue;
1467 if (((rvp - tpvp) + (avp - pvp)) > MAXATOM)
1468 {
1383 syserr("554 callsubr: expansion too long");
1469 syserr("554 5.3.0 callsubr: expansion too long");
1384 return EX_DATAERR;
1385 }
1386
1387 /*
1388 ** Now we can copy the rewritten code over
1389 ** the initial subroutine call in the buffer.
1390 */
1391

--- 23 unchanged lines hidden (view full) ---

1415** status from the lookup.
1416** e -- the current envelope.
1417**
1418** Returns:
1419** The result of the lookup.
1420** NULL -- if there was no data for the given key.
1421*/
1422
1470 return EX_DATAERR;
1471 }
1472
1473 /*
1474 ** Now we can copy the rewritten code over
1475 ** the initial subroutine call in the buffer.
1476 */
1477

--- 23 unchanged lines hidden (view full) ---

1501** status from the lookup.
1502** e -- the current envelope.
1503**
1504** Returns:
1505** The result of the lookup.
1506** NULL -- if there was no data for the given key.
1507*/
1508
1423char *
1424map_lookup(map, key, argvect, pstat, e)
1425 STAB *map;
1509static char *
1510map_lookup(smap, key, argvect, pstat, e)
1511 STAB *smap;
1426 char key[];
1427 char **argvect;
1428 int *pstat;
1429 ENVELOPE *e;
1430{
1512 char key[];
1513 char **argvect;
1514 int *pstat;
1515 ENVELOPE *e;
1516{
1431 auto int stat = EX_OK;
1517 auto int status = EX_OK;
1518 MAP *map;
1432 char *replac;
1433
1519 char *replac;
1520
1434 if (e->e_sendmode == SM_DEFER)
1521 if (smap == NULL)
1522 return NULL;
1523
1524 map = &smap->s_map;
1525 DYNOPENMAP(map);
1526
1527 if (e->e_sendmode == SM_DEFER &&
1528 bitset(MF_DEFER, map->map_mflags))
1435 {
1436 /* don't do any map lookups */
1437 if (tTd(60, 1))
1529 {
1530 /* don't do any map lookups */
1531 if (tTd(60, 1))
1438 printf("map_lookup(%s, %s) => DEFERRED\n",
1439 map->s_name, key);
1532 dprintf("map_lookup(%s, %s) => DEFERRED\n",
1533 smap->s_name, key);
1440 *pstat = EX_TEMPFAIL;
1441 return NULL;
1442 }
1534 *pstat = EX_TEMPFAIL;
1535 return NULL;
1536 }
1443 if (map == NULL || !bitset(MF_OPEN, map->s_map.map_mflags))
1444 return NULL;
1445
1537
1446 if (!bitset(MF_KEEPQUOTES, map->s_map.map_mflags))
1538 if (!bitset(MF_KEEPQUOTES, map->map_mflags))
1447 stripquotes(key);
1448
1539 stripquotes(key);
1540
1449 /* XXX should try to auto-open the map here */
1450
1451 if (tTd(60, 1))
1452 {
1541 if (tTd(60, 1))
1542 {
1453 printf("map_lookup(%s, %s", map->s_name, key);
1543 dprintf("map_lookup(%s, %s", smap->s_name, key);
1454 if (tTd(60, 5))
1455 {
1456 int i;
1457
1458 for (i = 0; argvect[i] != NULL; i++)
1544 if (tTd(60, 5))
1545 {
1546 int i;
1547
1548 for (i = 0; argvect[i] != NULL; i++)
1459 printf(", %%%d=%s", i, argvect[i]);
1549 dprintf(", %%%d=%s", i, argvect[i]);
1460 }
1550 }
1461 printf(") => ");
1551 dprintf(") => ");
1462 }
1552 }
1463 replac = (*map->s_map.map_class->map_lookup)(&map->s_map,
1464 key, argvect, &stat);
1553 replac = (*map->map_class->map_lookup)(map, key, argvect, &status);
1465 if (tTd(60, 1))
1554 if (tTd(60, 1))
1466 printf("%s (%d)\n",
1555 dprintf("%s (%d)\n",
1467 replac != NULL ? replac : "NOT FOUND",
1556 replac != NULL ? replac : "NOT FOUND",
1468 stat);
1557 status);
1469
1558
1470 /* should recover if stat == EX_TEMPFAIL */
1471 if (stat == EX_TEMPFAIL && !bitset(MF_NODEFER, map->s_map.map_mflags))
1559 /* should recover if status == EX_TEMPFAIL */
1560 if (status == EX_TEMPFAIL && !bitset(MF_NODEFER, map->map_mflags))
1472 {
1473 *pstat = EX_TEMPFAIL;
1474 if (tTd(60, 1))
1561 {
1562 *pstat = EX_TEMPFAIL;
1563 if (tTd(60, 1))
1475 printf("map_lookup(%s, %s) tempfail: errno=%d\n",
1476 map->s_name, key, errno);
1564 dprintf("map_lookup(%s, %s) tempfail: errno=%d\n",
1565 smap->s_name, key, errno);
1477 if (e->e_message == NULL)
1478 {
1479 char mbuf[320];
1480
1481 snprintf(mbuf, sizeof mbuf,
1482 "%.80s map: lookup (%s): deferred",
1566 if (e->e_message == NULL)
1567 {
1568 char mbuf[320];
1569
1570 snprintf(mbuf, sizeof mbuf,
1571 "%.80s map: lookup (%s): deferred",
1483 map->s_name,
1572 smap->s_name,
1484 shortenstring(key, MAXSHORTSTR));
1485 e->e_message = newstr(mbuf);
1486 }
1487 }
1573 shortenstring(key, MAXSHORTSTR));
1574 e->e_message = newstr(mbuf);
1575 }
1576 }
1488 if (stat == EX_TEMPFAIL && map->s_map.map_tapp != NULL)
1577 if (status == EX_TEMPFAIL && map->map_tapp != NULL)
1489 {
1578 {
1490 size_t i = strlen(key) + strlen(map->s_map.map_tapp) + 1;
1579 size_t i = strlen(key) + strlen(map->map_tapp) + 1;
1491 static char *rwbuf = NULL;
1492 static size_t rwbuflen = 0;
1493
1494 if (i > rwbuflen)
1495 {
1496 if (rwbuf != NULL)
1497 free(rwbuf);
1498 rwbuflen = i;
1499 rwbuf = (char *) xalloc(rwbuflen);
1500 }
1580 static char *rwbuf = NULL;
1581 static size_t rwbuflen = 0;
1582
1583 if (i > rwbuflen)
1584 {
1585 if (rwbuf != NULL)
1586 free(rwbuf);
1587 rwbuflen = i;
1588 rwbuf = (char *) xalloc(rwbuflen);
1589 }
1501 snprintf(rwbuf, rwbuflen, "%s%s", key, map->s_map.map_tapp);
1590 snprintf(rwbuf, rwbuflen, "%s%s", key, map->map_tapp);
1502 if (tTd(60, 4))
1591 if (tTd(60, 4))
1503 printf("map_lookup tempfail: returning \"%s\"\n",
1592 dprintf("map_lookup tempfail: returning \"%s\"\n",
1504 rwbuf);
1505 return rwbuf;
1506 }
1507 return replac;
1508}
1509 /*
1593 rwbuf);
1594 return rwbuf;
1595 }
1596 return replac;
1597}
1598 /*
1599** INITERRMAILERS -- initialize error and discard mailers
1600**
1601** Parameters:
1602** none.
1603**
1604** Returns:
1605** none.
1606**
1607** Side Effects:
1608** initializes error and discard mailers.
1609*/
1610
1611static MAILER discardmailer;
1612static MAILER errormailer;
1613static char *discardargv[] = { "DISCARD", NULL };
1614static char *errorargv[] = { "ERROR", NULL };
1615
1616void
1617initerrmailers()
1618{
1619 if (discardmailer.m_name == NULL)
1620 {
1621 /* initialize the discard mailer */
1622 discardmailer.m_name = "*discard*";
1623 discardmailer.m_mailer = "DISCARD";
1624 discardmailer.m_argv = discardargv;
1625 }
1626 if (errormailer.m_name == NULL)
1627 {
1628 /* initialize the bogus mailer */
1629 errormailer.m_name = "*error*";
1630 errormailer.m_mailer = "ERROR";
1631 errormailer.m_argv = errorargv;
1632 }
1633}
1634 /*
1510** BUILDADDR -- build address from token vector.
1511**
1512** Parameters:
1513** tv -- token vector.
1514** a -- pointer to address descriptor to fill.
1515** If NULL, one will be allocated.
1516** flags -- info regarding whether this is a sender or
1517** a recipient.
1518** e -- the current envelope.
1519**
1520** Returns:
1521** NULL if there was an error.
1522** 'a' otherwise.
1523**
1524** Side Effects:
1525** fills in 'a'
1526*/
1527
1635** BUILDADDR -- build address from token vector.
1636**
1637** Parameters:
1638** tv -- token vector.
1639** a -- pointer to address descriptor to fill.
1640** If NULL, one will be allocated.
1641** flags -- info regarding whether this is a sender or
1642** a recipient.
1643** e -- the current envelope.
1644**
1645** Returns:
1646** NULL if there was an error.
1647** 'a' otherwise.
1648**
1649** Side Effects:
1650** fills in 'a'
1651*/
1652
1528struct errcodes
1653static struct errcodes
1529{
1530 char *ec_name; /* name of error code */
1531 int ec_code; /* numeric code */
1532} ErrorCodes[] =
1533{
1534 { "usage", EX_USAGE },
1535 { "nouser", EX_NOUSER },
1536 { "nohost", EX_NOHOST },
1537 { "unavailable", EX_UNAVAILABLE },
1538 { "software", EX_SOFTWARE },
1539 { "tempfail", EX_TEMPFAIL },
1540 { "protocol", EX_PROTOCOL },
1541#ifdef EX_CONFIG
1542 { "config", EX_CONFIG },
1654{
1655 char *ec_name; /* name of error code */
1656 int ec_code; /* numeric code */
1657} ErrorCodes[] =
1658{
1659 { "usage", EX_USAGE },
1660 { "nouser", EX_NOUSER },
1661 { "nohost", EX_NOHOST },
1662 { "unavailable", EX_UNAVAILABLE },
1663 { "software", EX_SOFTWARE },
1664 { "tempfail", EX_TEMPFAIL },
1665 { "protocol", EX_PROTOCOL },
1666#ifdef EX_CONFIG
1667 { "config", EX_CONFIG },
1543#endif
1668#endif /* EX_CONFIG */
1544 { NULL, EX_UNAVAILABLE }
1545};
1546
1669 { NULL, EX_UNAVAILABLE }
1670};
1671
1547ADDRESS *
1672
1673static ADDRESS *
1548buildaddr(tv, a, flags, e)
1549 register char **tv;
1550 register ADDRESS *a;
1551 int flags;
1552 register ENVELOPE *e;
1553{
1554 struct mailer **mp;
1555 register struct mailer *m;
1556 register char *p;
1557 char *mname;
1558 char **hostp;
1559 char hbuf[MAXNAME + 1];
1674buildaddr(tv, a, flags, e)
1675 register char **tv;
1676 register ADDRESS *a;
1677 int flags;
1678 register ENVELOPE *e;
1679{
1680 struct mailer **mp;
1681 register struct mailer *m;
1682 register char *p;
1683 char *mname;
1684 char **hostp;
1685 char hbuf[MAXNAME + 1];
1560 static MAILER discardmailer;
1561 static MAILER errormailer;
1562 static char *discardargv[] = { "DISCARD", NULL };
1563 static char *errorargv[] = { "ERROR", NULL };
1564 static char ubuf[MAXNAME + 2];
1565
1566 if (tTd(24, 5))
1567 {
1686 static char ubuf[MAXNAME + 2];
1687
1688 if (tTd(24, 5))
1689 {
1568 printf("buildaddr, flags=%x, tv=", flags);
1690 dprintf("buildaddr, flags=%x, tv=", flags);
1569 printav(tv);
1570 }
1571
1572 if (a == NULL)
1573 a = (ADDRESS *) xalloc(sizeof *a);
1691 printav(tv);
1692 }
1693
1694 if (a == NULL)
1695 a = (ADDRESS *) xalloc(sizeof *a);
1574 bzero((char *) a, sizeof *a);
1696 memset((char *) a, '\0', sizeof *a);
1697 hbuf[0] = '\0';
1575
1576 /* set up default error return flags */
1577 a->q_flags |= DefaultNotify;
1578
1698
1699 /* set up default error return flags */
1700 a->q_flags |= DefaultNotify;
1701
1579 if (discardmailer.m_name == NULL)
1580 {
1581 /* initialize the discard mailer */
1582 discardmailer.m_name = "*discard*";
1583 discardmailer.m_mailer = "DISCARD";
1584 discardmailer.m_argv = discardargv;
1585 }
1586
1587 /* figure out what net/mailer to use */
1588 if (*tv == NULL || (**tv & 0377) != CANONNET)
1589 {
1702 /* figure out what net/mailer to use */
1703 if (*tv == NULL || (**tv & 0377) != CANONNET)
1704 {
1590 syserr("554 buildaddr: no mailer in parsed address");
1705 syserr("554 5.3.5 buildaddr: no mailer in parsed address");
1591badaddr:
1706badaddr:
1592 a->q_flags |= QBADADDR;
1593 a->q_mailer = &errormailer;
1594 if (errormailer.m_name == NULL)
1707 if (ExitStat == EX_TEMPFAIL)
1708 a->q_state = QS_QUEUEUP;
1709 else
1595 {
1710 {
1596 /* initialize the bogus mailer */
1597 errormailer.m_name = "*error*";
1598 errormailer.m_mailer = "ERROR";
1599 errormailer.m_argv = errorargv;
1711 a->q_state = QS_BADADDR;
1712 a->q_mailer = &errormailer;
1600 }
1601 return a;
1602 }
1603 mname = *++tv;
1604
1605 /* extract host and user portions */
1606 if (*++tv != NULL && (**tv & 0377) == CANONHOST)
1607 hostp = ++tv;
1608 else
1609 hostp = NULL;
1610 while (*tv != NULL && (**tv & 0377) != CANONUSER)
1611 tv++;
1612 if (*tv == NULL)
1613 {
1713 }
1714 return a;
1715 }
1716 mname = *++tv;
1717
1718 /* extract host and user portions */
1719 if (*++tv != NULL && (**tv & 0377) == CANONHOST)
1720 hostp = ++tv;
1721 else
1722 hostp = NULL;
1723 while (*tv != NULL && (**tv & 0377) != CANONUSER)
1724 tv++;
1725 if (*tv == NULL)
1726 {
1614 syserr("554 buildaddr: no user");
1727 syserr("554 5.3.5 buildaddr: no user");
1615 goto badaddr;
1616 }
1617 if (tv == hostp)
1618 hostp = NULL;
1619 else if (hostp != NULL)
1620 cataddr(hostp, tv - 1, hbuf, sizeof hbuf, '\0');
1621 cataddr(++tv, NULL, ubuf, sizeof ubuf, ' ');
1622
1623 /* save away the host name */
1624 if (strcasecmp(mname, "error") == 0)
1625 {
1728 goto badaddr;
1729 }
1730 if (tv == hostp)
1731 hostp = NULL;
1732 else if (hostp != NULL)
1733 cataddr(hostp, tv - 1, hbuf, sizeof hbuf, '\0');
1734 cataddr(++tv, NULL, ubuf, sizeof ubuf, ' ');
1735
1736 /* save away the host name */
1737 if (strcasecmp(mname, "error") == 0)
1738 {
1739 /* Set up triplet for use by -bv */
1740 a->q_mailer = &errormailer;
1741 a->q_user = newstr(ubuf);
1742
1626 if (hostp != NULL)
1627 {
1628 register struct errcodes *ep;
1629
1743 if (hostp != NULL)
1744 {
1745 register struct errcodes *ep;
1746
1747 a->q_host = newstr(hbuf);
1630 if (strchr(hbuf, '.') != NULL)
1631 {
1748 if (strchr(hbuf, '.') != NULL)
1749 {
1632 extern int dsntoexitstat __P((char *));
1633
1634 a->q_status = newstr(hbuf);
1635 setstat(dsntoexitstat(hbuf));
1636 }
1637 else if (isascii(hbuf[0]) && isdigit(hbuf[0]))
1638 {
1639 setstat(atoi(hbuf));
1640 }
1641 else
1642 {
1643 for (ep = ErrorCodes; ep->ec_name != NULL; ep++)
1644 if (strcasecmp(ep->ec_name, hbuf) == 0)
1645 break;
1646 setstat(ep->ec_code);
1647 }
1648 }
1649 else
1750 a->q_status = newstr(hbuf);
1751 setstat(dsntoexitstat(hbuf));
1752 }
1753 else if (isascii(hbuf[0]) && isdigit(hbuf[0]))
1754 {
1755 setstat(atoi(hbuf));
1756 }
1757 else
1758 {
1759 for (ep = ErrorCodes; ep->ec_name != NULL; ep++)
1760 if (strcasecmp(ep->ec_name, hbuf) == 0)
1761 break;
1762 setstat(ep->ec_code);
1763 }
1764 }
1765 else
1766 {
1767 a->q_host = NULL;
1650 setstat(EX_UNAVAILABLE);
1768 setstat(EX_UNAVAILABLE);
1769 }
1651 stripquotes(ubuf);
1770 stripquotes(ubuf);
1652 if (isascii(ubuf[0]) && isdigit(ubuf[0]) &&
1653 isascii(ubuf[1]) && isdigit(ubuf[1]) &&
1654 isascii(ubuf[2]) && isdigit(ubuf[2]) &&
1655 ubuf[3] == ' ')
1771 if (ISSMTPCODE(ubuf) && ubuf[3] == ' ')
1656 {
1772 {
1657 char fmt[10];
1773 char fmt[16];
1774 int off;
1658
1775
1659 strncpy(fmt, ubuf, 3);
1660 strcpy(&fmt[3], " %s");
1661 usrerr(fmt, ubuf + 4);
1662
1663 /*
1664 ** If this is a 4xx code and we aren't running
1665 ** SMTP on our input, bounce this message;
1666 ** otherwise it disappears without a trace.
1667 */
1668
1669 if (fmt[0] == '4' && OpMode != MD_SMTP &&
1670 OpMode != MD_DAEMON)
1776 if ((off = isenhsc(ubuf + 4, ' ')) > 0)
1671 {
1777 {
1672 e->e_flags |= EF_FATALERRS;
1778 ubuf[off + 4] = '\0';
1779 off += 5;
1673 }
1780 }
1781 else
1782 {
1783 off = 4;
1784 ubuf[3] = '\0';
1785 }
1786 (void) snprintf(fmt, sizeof fmt, "%s %%s", ubuf);
1787 if (off > 4)
1788 usrerr(fmt, ubuf + off);
1789 else if (isenhsc(hbuf, '\0') > 0)
1790 usrerrenh(hbuf, fmt, ubuf + off);
1791 else
1792 usrerr(fmt, ubuf + off);
1793 /* XXX ubuf[off - 1] = ' '; */
1674 }
1675 else
1676 {
1794 }
1795 else
1796 {
1677 usrerr("553 %s", ubuf);
1797 usrerr("553 5.3.0 %s", ubuf);
1678 }
1679 goto badaddr;
1680 }
1681
1682 for (mp = Mailer; (m = *mp++) != NULL; )
1683 {
1684 if (strcasecmp(m->m_name, mname) == 0)
1685 break;
1686 }
1687 if (m == NULL)
1688 {
1798 }
1799 goto badaddr;
1800 }
1801
1802 for (mp = Mailer; (m = *mp++) != NULL; )
1803 {
1804 if (strcasecmp(m->m_name, mname) == 0)
1805 break;
1806 }
1807 if (m == NULL)
1808 {
1689 syserr("554 buildaddr: unknown mailer %s", mname);
1809 syserr("554 5.3.5 buildaddr: unknown mailer %s", mname);
1690 goto badaddr;
1691 }
1692 a->q_mailer = m;
1693
1694 /* figure out what host (if any) */
1695 if (hostp == NULL)
1696 {
1697 if (!bitnset(M_LOCALMAILER, m->m_flags))
1698 {
1810 goto badaddr;
1811 }
1812 a->q_mailer = m;
1813
1814 /* figure out what host (if any) */
1815 if (hostp == NULL)
1816 {
1817 if (!bitnset(M_LOCALMAILER, m->m_flags))
1818 {
1699 syserr("554 buildaddr: no host");
1819 syserr("554 5.3.5 buildaddr: no host");
1700 goto badaddr;
1701 }
1702 a->q_host = NULL;
1703 }
1704 else
1705 a->q_host = newstr(hbuf);
1706
1707 /* figure out the user */

--- 22 unchanged lines hidden (view full) ---

1730 a->q_mailer = m = InclMailer;
1731 a->q_user = newstr(&ubuf[9]);
1732 return a;
1733 }
1734 }
1735
1736 /* rewrite according recipient mailer rewriting rules */
1737 define('h', a->q_host, e);
1820 goto badaddr;
1821 }
1822 a->q_host = NULL;
1823 }
1824 else
1825 a->q_host = newstr(hbuf);
1826
1827 /* figure out the user */

--- 22 unchanged lines hidden (view full) ---

1850 a->q_mailer = m = InclMailer;
1851 a->q_user = newstr(&ubuf[9]);
1852 return a;
1853 }
1854 }
1855
1856 /* rewrite according recipient mailer rewriting rules */
1857 define('h', a->q_host, e);
1858
1859#if _FFR_ADDR_TYPE
1860 /*
1861 ** Note, change the 9 to a 10 before removing #if FFR check
1862 ** in a future version.
1863 */
1864
1865 if (ConfigLevel >= 9 ||
1866 !bitset(RF_SENDERADDR|RF_HEADERADDR, flags))
1867#else /* _FFR_ADDR_TYPE */
1738 if (!bitset(RF_SENDERADDR|RF_HEADERADDR, flags))
1868 if (!bitset(RF_SENDERADDR|RF_HEADERADDR, flags))
1869#endif /* _FFR_ADDR_TYPE */
1739 {
1740 /* sender addresses done later */
1741 (void) rewrite(tv, 2, 0, e);
1742 if (m->m_re_rwset > 0)
1743 (void) rewrite(tv, m->m_re_rwset, 0, e);
1744 }
1745 (void) rewrite(tv, 4, 0, e);
1746
1747 /* save the result for the command line/RCPT argument */
1748 cataddr(tv, NULL, ubuf, sizeof ubuf, '\0');
1870 {
1871 /* sender addresses done later */
1872 (void) rewrite(tv, 2, 0, e);
1873 if (m->m_re_rwset > 0)
1874 (void) rewrite(tv, m->m_re_rwset, 0, e);
1875 }
1876 (void) rewrite(tv, 4, 0, e);
1877
1878 /* save the result for the command line/RCPT argument */
1879 cataddr(tv, NULL, ubuf, sizeof ubuf, '\0');
1749 a->q_user = ubuf;
1880 a->q_user = newstr(ubuf);
1750
1751 /*
1752 ** Do mapping to lower case as requested by mailer
1753 */
1754
1755 if (a->q_host != NULL && !bitnset(M_HST_UPPER, m->m_flags))
1756 makelower(a->q_host);
1757 if (!bitnset(M_USR_UPPER, m->m_flags))
1758 makelower(a->q_user);
1759
1760 if (tTd(24, 6))
1761 {
1881
1882 /*
1883 ** Do mapping to lower case as requested by mailer
1884 */
1885
1886 if (a->q_host != NULL && !bitnset(M_HST_UPPER, m->m_flags))
1887 makelower(a->q_host);
1888 if (!bitnset(M_USR_UPPER, m->m_flags))
1889 makelower(a->q_user);
1890
1891 if (tTd(24, 6))
1892 {
1762 printf("buildaddr => ");
1893 dprintf("buildaddr => ");
1763 printaddr(a, FALSE);
1764 }
1765 return a;
1766}
1767 /*
1768** CATADDR -- concatenate pieces of addresses (putting in <LWSP> subs)
1769**
1770** Parameters:

--- 20 unchanged lines hidden (view full) ---

1791 register int sz;
1792 int spacesub;
1793{
1794 bool oatomtok = FALSE;
1795 bool natomtok = FALSE;
1796 register int i;
1797 register char *p;
1798
1894 printaddr(a, FALSE);
1895 }
1896 return a;
1897}
1898 /*
1899** CATADDR -- concatenate pieces of addresses (putting in <LWSP> subs)
1900**
1901** Parameters:

--- 20 unchanged lines hidden (view full) ---

1922 register int sz;
1923 int spacesub;
1924{
1925 bool oatomtok = FALSE;
1926 bool natomtok = FALSE;
1927 register int i;
1928 register char *p;
1929
1930 if (sz <= 0)
1931 return;
1932
1799 if (spacesub == '\0')
1800 spacesub = SpaceSub;
1801
1802 if (pvp == NULL)
1803 {
1933 if (spacesub == '\0')
1934 spacesub = SpaceSub;
1935
1936 if (pvp == NULL)
1937 {
1804 (void) strcpy(buf, "");
1938 *buf = '\0';
1805 return;
1806 }
1807 p = buf;
1808 sz -= 2;
1939 return;
1940 }
1941 p = buf;
1942 sz -= 2;
1809 while (*pvp != NULL && (i = strlen(*pvp)) < sz)
1943 while (*pvp != NULL && (i = strlen(*pvp)) < sz - 1)
1810 {
1811 natomtok = (TokTypeTab[**pvp & 0xff] == ATM);
1812 if (oatomtok && natomtok)
1944 {
1945 natomtok = (TokTypeTab[**pvp & 0xff] == ATM);
1946 if (oatomtok && natomtok)
1947 {
1813 *p++ = spacesub;
1948 *p++ = spacesub;
1814 (void) strcpy(p, *pvp);
1949 --sz;
1950 }
1951 (void) strlcpy(p, *pvp, sz);
1815 oatomtok = natomtok;
1816 p += i;
1952 oatomtok = natomtok;
1953 p += i;
1817 sz -= i + 1;
1954 sz -= i;
1818 if (pvp++ == evp)
1819 break;
1820 }
1821 *p = '\0';
1822}
1823 /*
1824** SAMEADDR -- Determine if two addresses are the same
1825**

--- 15 unchanged lines hidden (view full) ---

1841sameaddr(a, b)
1842 register ADDRESS *a;
1843 register ADDRESS *b;
1844{
1845 register ADDRESS *ca, *cb;
1846
1847 /* if they don't have the same mailer, forget it */
1848 if (a->q_mailer != b->q_mailer)
1955 if (pvp++ == evp)
1956 break;
1957 }
1958 *p = '\0';
1959}
1960 /*
1961** SAMEADDR -- Determine if two addresses are the same
1962**

--- 15 unchanged lines hidden (view full) ---

1978sameaddr(a, b)
1979 register ADDRESS *a;
1980 register ADDRESS *b;
1981{
1982 register ADDRESS *ca, *cb;
1983
1984 /* if they don't have the same mailer, forget it */
1985 if (a->q_mailer != b->q_mailer)
1849 return (FALSE);
1986 return FALSE;
1850
1851 /* if the user isn't the same, we can drop out */
1852 if (strcmp(a->q_user, b->q_user) != 0)
1987
1988 /* if the user isn't the same, we can drop out */
1989 if (strcmp(a->q_user, b->q_user) != 0)
1853 return (FALSE);
1990 return FALSE;
1854
1855 /* if we have good uids for both but they differ, these are different */
1856 if (a->q_mailer == ProgMailer)
1857 {
1858 ca = getctladdr(a);
1859 cb = getctladdr(b);
1860 if (ca != NULL && cb != NULL &&
1861 bitset(QGOODUID, ca->q_flags & cb->q_flags) &&
1862 ca->q_uid != cb->q_uid)
1991
1992 /* if we have good uids for both but they differ, these are different */
1993 if (a->q_mailer == ProgMailer)
1994 {
1995 ca = getctladdr(a);
1996 cb = getctladdr(b);
1997 if (ca != NULL && cb != NULL &&
1998 bitset(QGOODUID, ca->q_flags & cb->q_flags) &&
1999 ca->q_uid != cb->q_uid)
1863 return (FALSE);
2000 return FALSE;
1864 }
1865
1866 /* otherwise compare hosts (but be careful for NULL ptrs) */
1867 if (a->q_host == b->q_host)
1868 {
1869 /* probably both null pointers */
2001 }
2002
2003 /* otherwise compare hosts (but be careful for NULL ptrs) */
2004 if (a->q_host == b->q_host)
2005 {
2006 /* probably both null pointers */
1870 return (TRUE);
2007 return TRUE;
1871 }
1872 if (a->q_host == NULL || b->q_host == NULL)
1873 {
1874 /* only one is a null pointer */
2008 }
2009 if (a->q_host == NULL || b->q_host == NULL)
2010 {
2011 /* only one is a null pointer */
1875 return (FALSE);
2012 return FALSE;
1876 }
1877 if (strcmp(a->q_host, b->q_host) != 0)
2013 }
2014 if (strcmp(a->q_host, b->q_host) != 0)
1878 return (FALSE);
2015 return FALSE;
1879
2016
1880 return (TRUE);
2017 return TRUE;
1881}
1882 /*
1883** PRINTADDR -- print address (for debugging)
1884**
1885** Parameters:
1886** a -- the address to print
1887** follow -- follow the q_next chain.
1888**

--- 5 unchanged lines hidden (view full) ---

1894*/
1895
1896struct qflags
1897{
1898 char *qf_name;
1899 u_long qf_bit;
1900};
1901
2018}
2019 /*
2020** PRINTADDR -- print address (for debugging)
2021**
2022** Parameters:
2023** a -- the address to print
2024** follow -- follow the q_next chain.
2025**

--- 5 unchanged lines hidden (view full) ---

2031*/
2032
2033struct qflags
2034{
2035 char *qf_name;
2036 u_long qf_bit;
2037};
2038
1902struct qflags AddressFlags[] =
2039static struct qflags AddressFlags[] =
1903{
2040{
1904 { "QDONTSEND", QDONTSEND },
1905 { "QBADADDR", QBADADDR },
1906 { "QGOODUID", QGOODUID },
1907 { "QPRIMARY", QPRIMARY },
2041 { "QGOODUID", QGOODUID },
2042 { "QPRIMARY", QPRIMARY },
1908 { "QQUEUEUP", QQUEUEUP },
1909 { "QSENT", QSENT },
1910 { "QNOTREMOTE", QNOTREMOTE },
1911 { "QSELFREF", QSELFREF },
2043 { "QNOTREMOTE", QNOTREMOTE },
2044 { "QSELFREF", QSELFREF },
1912 { "QVERIFIED", QVERIFIED },
1913 { "QBOGUSSHELL", QBOGUSSHELL },
1914 { "QUNSAFEADDR", QUNSAFEADDR },
1915 { "QPINGONSUCCESS", QPINGONSUCCESS },
1916 { "QPINGONFAILURE", QPINGONFAILURE },
1917 { "QPINGONDELAY", QPINGONDELAY },
1918 { "QHASNOTIFY", QHASNOTIFY },
1919 { "QRELAYED", QRELAYED },
1920 { "QEXPANDED", QEXPANDED },

--- 36 unchanged lines hidden (view full) ---

1957
1958 printf("%s:\n\tmailer %d (%s), host `%s'\n",
1959 a->q_paddr == NULL ? "<null>" : a->q_paddr,
1960 m->m_mno, m->m_name,
1961 a->q_host == NULL ? "<null>" : a->q_host);
1962 printf("\tuser `%s', ruser `%s'\n",
1963 a->q_user,
1964 a->q_ruser == NULL ? "<null>" : a->q_ruser);
2045 { "QBOGUSSHELL", QBOGUSSHELL },
2046 { "QUNSAFEADDR", QUNSAFEADDR },
2047 { "QPINGONSUCCESS", QPINGONSUCCESS },
2048 { "QPINGONFAILURE", QPINGONFAILURE },
2049 { "QPINGONDELAY", QPINGONDELAY },
2050 { "QHASNOTIFY", QHASNOTIFY },
2051 { "QRELAYED", QRELAYED },
2052 { "QEXPANDED", QEXPANDED },

--- 36 unchanged lines hidden (view full) ---

2089
2090 printf("%s:\n\tmailer %d (%s), host `%s'\n",
2091 a->q_paddr == NULL ? "<null>" : a->q_paddr,
2092 m->m_mno, m->m_name,
2093 a->q_host == NULL ? "<null>" : a->q_host);
2094 printf("\tuser `%s', ruser `%s'\n",
2095 a->q_user,
2096 a->q_ruser == NULL ? "<null>" : a->q_ruser);
1965 printf("\tnext=%lx, alias %lx, uid %d, gid %d\n",
2097 printf("\tstate=");
2098 switch (a->q_state)
2099 {
2100 case QS_OK:
2101 printf("OK");
2102 break;
2103
2104 case QS_DONTSEND:
2105 printf("DONTSEND");
2106 break;
2107
2108 case QS_BADADDR:
2109 printf("BADADDR");
2110 break;
2111
2112 case QS_QUEUEUP:
2113 printf("QUEUEUP");
2114 break;
2115
2116 case QS_SENT:
2117 printf("SENT");
2118 break;
2119
2120 case QS_VERIFIED:
2121 printf("VERIFIED");
2122 break;
2123
2124 case QS_EXPANDED:
2125 printf("EXPANDED");
2126 break;
2127
2128 case QS_SENDER:
2129 printf("SENDER");
2130 break;
2131
2132 case QS_CLONED:
2133 printf("CLONED");
2134 break;
2135
2136 case QS_DISCARDED:
2137 printf("DISCARDED");
2138 break;
2139
2140 case QS_REPLACED:
2141 printf("REPLACED");
2142 break;
2143
2144 case QS_REMOVED:
2145 printf("REMOVED");
2146 break;
2147
2148 case QS_DUPLICATE:
2149 printf("DUPLICATE");
2150 break;
2151
2152 case QS_INCLUDED:
2153 printf("INCLUDED");
2154 break;
2155
2156 default:
2157 printf("%d", a->q_state);
2158 break;
2159 }
2160 printf(", next=%lx, alias %lx, uid %d, gid %d\n",
1966 (u_long) a->q_next, (u_long) a->q_alias,
1967 (int) a->q_uid, (int) a->q_gid);
1968 printf("\tflags=%lx<", a->q_flags);
1969 firstone = TRUE;
1970 for (qfp = AddressFlags; qfp->qf_name != NULL; qfp++)
1971 {
1972 if (!bitset(qfp->qf_bit, a->q_flags))
1973 continue;

--- 9 unchanged lines hidden (view full) ---

1983 a->q_fullname == NULL ? "(none)" : a->q_fullname);
1984 printf("\torcpt=\"%s\", statmta=%s, status=%s\n",
1985 a->q_orcpt == NULL ? "(none)" : a->q_orcpt,
1986 a->q_statmta == NULL ? "(none)" : a->q_statmta,
1987 a->q_status == NULL ? "(none)" : a->q_status);
1988 printf("\trstatus=\"%s\"\n",
1989 a->q_rstatus == NULL ? "(none)" : a->q_rstatus);
1990 printf("\tspecificity=%d, statdate=%s\n",
2161 (u_long) a->q_next, (u_long) a->q_alias,
2162 (int) a->q_uid, (int) a->q_gid);
2163 printf("\tflags=%lx<", a->q_flags);
2164 firstone = TRUE;
2165 for (qfp = AddressFlags; qfp->qf_name != NULL; qfp++)
2166 {
2167 if (!bitset(qfp->qf_bit, a->q_flags))
2168 continue;

--- 9 unchanged lines hidden (view full) ---

2178 a->q_fullname == NULL ? "(none)" : a->q_fullname);
2179 printf("\torcpt=\"%s\", statmta=%s, status=%s\n",
2180 a->q_orcpt == NULL ? "(none)" : a->q_orcpt,
2181 a->q_statmta == NULL ? "(none)" : a->q_statmta,
2182 a->q_status == NULL ? "(none)" : a->q_status);
2183 printf("\trstatus=\"%s\"\n",
2184 a->q_rstatus == NULL ? "(none)" : a->q_rstatus);
2185 printf("\tspecificity=%d, statdate=%s\n",
1991 a->q_specificity, ctime(&a->q_statdate));
2186 a->q_specificity,
2187 a->q_statdate == 0 ? "(none)" : ctime(&a->q_statdate));
1992
1993 if (!follow)
1994 return;
1995 a = a->q_next;
1996 }
1997}
1998 /*
1999** EMPTYADDR -- return TRUE if this address is empty (``<>'')

--- 47 unchanged lines hidden (view full) ---

2047{
2048 register char **pvp;
2049 char *fancy;
2050 char *oldg = macvalue('g', e);
2051 int rwset;
2052 static char buf[MAXNAME + 1];
2053 char lbuf[MAXNAME + 1];
2054 char pvpbuf[PSBUFSIZE];
2188
2189 if (!follow)
2190 return;
2191 a = a->q_next;
2192 }
2193}
2194 /*
2195** EMPTYADDR -- return TRUE if this address is empty (``<>'')

--- 47 unchanged lines hidden (view full) ---

2243{
2244 register char **pvp;
2245 char *fancy;
2246 char *oldg = macvalue('g', e);
2247 int rwset;
2248 static char buf[MAXNAME + 1];
2249 char lbuf[MAXNAME + 1];
2250 char pvpbuf[PSBUFSIZE];
2055 extern char *crackaddr __P((char *));
2251#if _FFR_ADDR_TYPE
2252 char addrtype[4];
2253#endif /* _FFR_ADDR_TYPE */
2056
2057 if (tTd(12, 1))
2254
2255 if (tTd(12, 1))
2058 printf("remotename(%s)\n", name);
2256 dprintf("remotename(%s)\n", name);
2059
2060 /* don't do anything if we are tagging it as special */
2061 if (bitset(RF_SENDERADDR, flags))
2257
2258 /* don't do anything if we are tagging it as special */
2259 if (bitset(RF_SENDERADDR, flags))
2260 {
2062 rwset = bitset(RF_HEADERADDR, flags) ? m->m_sh_rwset
2063 : m->m_se_rwset;
2261 rwset = bitset(RF_HEADERADDR, flags) ? m->m_sh_rwset
2262 : m->m_se_rwset;
2263#if _FFR_ADDR_TYPE
2264 addrtype[2] = 's';
2265#endif /* _FFR_ADDR_TYPE */
2266 }
2064 else
2267 else
2268 {
2065 rwset = bitset(RF_HEADERADDR, flags) ? m->m_rh_rwset
2066 : m->m_re_rwset;
2269 rwset = bitset(RF_HEADERADDR, flags) ? m->m_rh_rwset
2270 : m->m_re_rwset;
2271#if _FFR_ADDR_TYPE
2272 addrtype[2] = 'r';
2273#endif /* _FFR_ADDR_TYPE */
2274 }
2067 if (rwset < 0)
2275 if (rwset < 0)
2068 return (name);
2276 return name;
2277#if _FFR_ADDR_TYPE
2278 addrtype[1] = ' ';
2279 addrtype[3] = '\0';
2280 addrtype[0] = bitset(RF_HEADERADDR, flags) ? 'h' : 'e';
2281 define(macid("{addr_type}", NULL), addrtype, e);
2282#endif /* _FFR_ADDR_TYPE */
2069
2070 /*
2071 ** Do a heuristic crack of this name to extract any comment info.
2072 ** This will leave the name as a comment and a $g macro.
2073 */
2074
2075 if (bitset(RF_CANONICAL, flags) || bitnset(M_NOCOMMENT, m->m_flags))
2076 fancy = "\201g";

--- 5 unchanged lines hidden (view full) ---

2082 ** Normally this will be RFC 822 style, i.e., "user@domain".
2083 ** If this only resolves to "user", and the "C" flag is
2084 ** specified in the sending mailer, then the sender's
2085 ** domain will be appended.
2086 */
2087
2088 pvp = prescan(name, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL);
2089 if (pvp == NULL)
2283
2284 /*
2285 ** Do a heuristic crack of this name to extract any comment info.
2286 ** This will leave the name as a comment and a $g macro.
2287 */
2288
2289 if (bitset(RF_CANONICAL, flags) || bitnset(M_NOCOMMENT, m->m_flags))
2290 fancy = "\201g";

--- 5 unchanged lines hidden (view full) ---

2296 ** Normally this will be RFC 822 style, i.e., "user@domain".
2297 ** If this only resolves to "user", and the "C" flag is
2298 ** specified in the sending mailer, then the sender's
2299 ** domain will be appended.
2300 */
2301
2302 pvp = prescan(name, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL);
2303 if (pvp == NULL)
2090 return (name);
2304 return name;
2091 if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)
2092 *pstat = EX_TEMPFAIL;
2093 if (bitset(RF_ADDDOMAIN, flags) && e->e_fromdomain != NULL)
2094 {
2095 /* append from domain to this address */
2096 register char **pxp = pvp;
2305 if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)
2306 *pstat = EX_TEMPFAIL;
2307 if (bitset(RF_ADDDOMAIN, flags) && e->e_fromdomain != NULL)
2308 {
2309 /* append from domain to this address */
2310 register char **pxp = pvp;
2311 int l = MAXATOM; /* size of buffer for pvp */
2097
2098 /* see if there is an "@domain" in the current name */
2099 while (*pxp != NULL && strcmp(*pxp, "@") != 0)
2312
2313 /* see if there is an "@domain" in the current name */
2314 while (*pxp != NULL && strcmp(*pxp, "@") != 0)
2315 {
2100 pxp++;
2316 pxp++;
2317 --l;
2318 }
2101 if (*pxp == NULL)
2102 {
2103 /* no.... append the "@domain" from the sender */
2104 register char **qxq = e->e_fromdomain;
2105
2106 while ((*pxp++ = *qxq++) != NULL)
2319 if (*pxp == NULL)
2320 {
2321 /* no.... append the "@domain" from the sender */
2322 register char **qxq = e->e_fromdomain;
2323
2324 while ((*pxp++ = *qxq++) != NULL)
2107 continue;
2325 {
2326 if (--l <= 0)
2327 {
2328 *--pxp = NULL;
2329 usrerr("553 5.1.0 remotename: too many tokens");
2330 *pstat = EX_UNAVAILABLE;
2331 break;
2332 }
2333 }
2108 if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)
2109 *pstat = EX_TEMPFAIL;
2110 }
2111 }
2112
2113 /*
2114 ** Do more specific rewriting.
2115 ** Rewrite using ruleset 1 or 2 depending on whether this is

--- 38 unchanged lines hidden (view full) ---

2154 if (bitset(RF_CANONICAL, flags) && lbuf[0] == '@')
2155 expand("<\201g>", buf, sizeof buf, e);
2156 else
2157 expand(fancy, buf, sizeof buf, e);
2158
2159 define('g', oldg, e);
2160
2161 if (tTd(12, 1))
2334 if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)
2335 *pstat = EX_TEMPFAIL;
2336 }
2337 }
2338
2339 /*
2340 ** Do more specific rewriting.
2341 ** Rewrite using ruleset 1 or 2 depending on whether this is

--- 38 unchanged lines hidden (view full) ---

2380 if (bitset(RF_CANONICAL, flags) && lbuf[0] == '@')
2381 expand("<\201g>", buf, sizeof buf, e);
2382 else
2383 expand(fancy, buf, sizeof buf, e);
2384
2385 define('g', oldg, e);
2386
2387 if (tTd(12, 1))
2162 printf("remotename => `%s'\n", buf);
2163 return (buf);
2388 dprintf("remotename => `%s'\n", buf);
2389 return buf;
2164}
2165 /*
2166** MAPLOCALUSER -- run local username through ruleset 5 for final redirection
2167**
2168** Parameters:
2169** a -- the address to map (but just the user name part).
2170** sendq -- the sendq in which to install any replacement
2171** addresses.

--- 17 unchanged lines hidden (view full) ---

2189{
2190 register char **pvp;
2191 register ADDRESS *a1 = NULL;
2192 auto char *delimptr;
2193 char pvpbuf[PSBUFSIZE];
2194
2195 if (tTd(29, 1))
2196 {
2390}
2391 /*
2392** MAPLOCALUSER -- run local username through ruleset 5 for final redirection
2393**
2394** Parameters:
2395** a -- the address to map (but just the user name part).
2396** sendq -- the sendq in which to install any replacement
2397** addresses.

--- 17 unchanged lines hidden (view full) ---

2415{
2416 register char **pvp;
2417 register ADDRESS *a1 = NULL;
2418 auto char *delimptr;
2419 char pvpbuf[PSBUFSIZE];
2420
2421 if (tTd(29, 1))
2422 {
2197 printf("maplocaluser: ");
2423 dprintf("maplocaluser: ");
2198 printaddr(a, FALSE);
2199 }
2200 pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, &delimptr, NULL);
2201 if (pvp == NULL)
2202 {
2203 if (tTd(29, 9))
2424 printaddr(a, FALSE);
2425 }
2426 pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, &delimptr, NULL);
2427 if (pvp == NULL)
2428 {
2429 if (tTd(29, 9))
2204 printf("maplocaluser: cannot prescan %s\n", a->q_user);
2430 dprintf("maplocaluser: cannot prescan %s\n",
2431 a->q_user);
2205 return;
2206 }
2207
2208 define('h', a->q_host, e);
2209 define('u', a->q_user, e);
2210 define('z', a->q_home, e);
2432 return;
2433 }
2434
2435 define('h', a->q_host, e);
2436 define('u', a->q_user, e);
2437 define('z', a->q_home, e);
2211
2438
2439#if _FFR_ADDR_TYPE
2440 define(macid("{addr_type}", NULL), "e r", e);
2441#endif /* _FFR_ADDR_TYPE */
2212 if (rewrite(pvp, 5, 0, e) == EX_TEMPFAIL)
2213 {
2214 if (tTd(29, 9))
2442 if (rewrite(pvp, 5, 0, e) == EX_TEMPFAIL)
2443 {
2444 if (tTd(29, 9))
2215 printf("maplocaluser: rewrite tempfail\n");
2216 a->q_flags |= QQUEUEUP;
2445 dprintf("maplocaluser: rewrite tempfail\n");
2446 a->q_state = QS_QUEUEUP;
2217 a->q_status = "4.4.3";
2218 return;
2219 }
2220 if (pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET)
2221 {
2222 if (tTd(29, 9))
2447 a->q_status = "4.4.3";
2448 return;
2449 }
2450 if (pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET)
2451 {
2452 if (tTd(29, 9))
2223 printf("maplocaluser: doesn't resolve\n");
2453 dprintf("maplocaluser: doesn't resolve\n");
2224 return;
2225 }
2226
2227 /* if non-null, mailer destination specified -- has it changed? */
2228 a1 = buildaddr(pvp, NULL, 0, e);
2229 if (a1 == NULL || sameaddr(a, a1))
2230 {
2231 if (tTd(29, 9))
2454 return;
2455 }
2456
2457 /* if non-null, mailer destination specified -- has it changed? */
2458 a1 = buildaddr(pvp, NULL, 0, e);
2459 if (a1 == NULL || sameaddr(a, a1))
2460 {
2461 if (tTd(29, 9))
2232 printf("maplocaluser: address unchanged\n");
2462 dprintf("maplocaluser: address unchanged\n");
2233 if (a1 != NULL)
2234 free(a1);
2235 return;
2236 }
2237
2238 /* make new address take on flags and print attributes of old */
2239 a1->q_flags &= ~Q_COPYFLAGS;
2240 a1->q_flags |= a->q_flags & Q_COPYFLAGS;
2463 if (a1 != NULL)
2464 free(a1);
2465 return;
2466 }
2467
2468 /* make new address take on flags and print attributes of old */
2469 a1->q_flags &= ~Q_COPYFLAGS;
2470 a1->q_flags |= a->q_flags & Q_COPYFLAGS;
2241 a1->q_paddr = a->q_paddr;
2471 a1->q_paddr = newstr(a->q_paddr);
2472 a1->q_orcpt = a->q_orcpt;
2242
2243 /* mark old address as dead; insert new address */
2473
2474 /* mark old address as dead; insert new address */
2244 a->q_flags |= QDONTSEND;
2475 a->q_state = QS_REPLACED;
2245 if (tTd(29, 5))
2246 {
2476 if (tTd(29, 5))
2477 {
2247 printf("maplocaluser: QDONTSEND ");
2478 dprintf("maplocaluser: QS_REPLACED ");
2248 printaddr(a, FALSE);
2249 }
2250 a1->q_alias = a;
2479 printaddr(a, FALSE);
2480 }
2481 a1->q_alias = a;
2251 allocaddr(a1, RF_COPYALL, a->q_paddr);
2482 allocaddr(a1, RF_COPYALL, newstr(a->q_paddr));
2252 (void) recipient(a1, sendq, aliaslevel, e);
2253}
2254 /*
2255** DEQUOTE_INIT -- initialize dequote map
2256**
2257** This is a no-op.
2258**
2259** Parameters:

--- 6 unchanged lines hidden (view full) ---

2266
2267bool
2268dequote_init(map, args)
2269 MAP *map;
2270 char *args;
2271{
2272 register char *p = args;
2273
2483 (void) recipient(a1, sendq, aliaslevel, e);
2484}
2485 /*
2486** DEQUOTE_INIT -- initialize dequote map
2487**
2488** This is a no-op.
2489**
2490** Parameters:

--- 6 unchanged lines hidden (view full) ---

2497
2498bool
2499dequote_init(map, args)
2500 MAP *map;
2501 char *args;
2502{
2503 register char *p = args;
2504
2505 /* there is no check whether there is really an argument */
2274 map->map_mflags |= MF_KEEPQUOTES;
2275 for (;;)
2276 {
2277 while (isascii(*p) && isspace(*p))
2278 p++;
2279 if (*p != '-')
2280 break;
2281 switch (*++p)
2282 {
2283 case 'a':
2284 map->map_app = ++p;
2285 break;
2286
2506 map->map_mflags |= MF_KEEPQUOTES;
2507 for (;;)
2508 {
2509 while (isascii(*p) && isspace(*p))
2510 p++;
2511 if (*p != '-')
2512 break;
2513 switch (*++p)
2514 {
2515 case 'a':
2516 map->map_app = ++p;
2517 break;
2518
2519 case 'D':
2520 map->map_mflags |= MF_DEFER;
2521 break;
2522
2523 case 'S':
2287 case 's':
2524 case 's':
2288 map->map_coldelim = *++p;
2525 map->map_spacesub = *++p;
2289 break;
2290 }
2291 while (*p != '\0' && !(isascii(*p) && isspace(*p)))
2292 p++;
2293 if (*p != '\0')
2294 *p = '\0';
2295 }
2296 if (map->map_app != NULL)

--- 28 unchanged lines hidden (view full) ---

2325 register char *q;
2326 register char c;
2327 int anglecnt = 0;
2328 int cmntcnt = 0;
2329 int quotecnt = 0;
2330 int spacecnt = 0;
2331 bool quotemode = FALSE;
2332 bool bslashmode = FALSE;
2526 break;
2527 }
2528 while (*p != '\0' && !(isascii(*p) && isspace(*p)))
2529 p++;
2530 if (*p != '\0')
2531 *p = '\0';
2532 }
2533 if (map->map_app != NULL)

--- 28 unchanged lines hidden (view full) ---

2562 register char *q;
2563 register char c;
2564 int anglecnt = 0;
2565 int cmntcnt = 0;
2566 int quotecnt = 0;
2567 int spacecnt = 0;
2568 bool quotemode = FALSE;
2569 bool bslashmode = FALSE;
2333 char spacesub = map->map_coldelim;
2570 char spacesub = map->map_spacesub;
2334
2335 for (p = q = name; (c = *p++) != '\0'; )
2336 {
2337 if (bslashmode)
2338 {
2339 bslashmode = FALSE;
2340 *q++ = c;
2341 continue;

--- 13 unchanged lines hidden (view full) ---

2355 break;
2356
2357 case ')':
2358 if (cmntcnt-- <= 0)
2359 return NULL;
2360 break;
2361
2362 case ' ':
2571
2572 for (p = q = name; (c = *p++) != '\0'; )
2573 {
2574 if (bslashmode)
2575 {
2576 bslashmode = FALSE;
2577 *q++ = c;
2578 continue;

--- 13 unchanged lines hidden (view full) ---

2592 break;
2593
2594 case ')':
2595 if (cmntcnt-- <= 0)
2596 return NULL;
2597 break;
2598
2599 case ' ':
2600 case '\t':
2363 spacecnt++;
2364 break;
2365 }
2366
2367 if (cmntcnt > 0)
2368 {
2369 *q++ = c;
2370 continue;

--- 27 unchanged lines hidden (view full) ---

2398 /*
2399** RSCHECK -- check string(s) for validity using rewriting sets
2400**
2401** Parameters:
2402** rwset -- the rewriting set to use.
2403** p1 -- the first string to check.
2404** p2 -- the second string to check -- may be null.
2405** e -- the current envelope.
2601 spacecnt++;
2602 break;
2603 }
2604
2605 if (cmntcnt > 0)
2606 {
2607 *q++ = c;
2608 continue;

--- 27 unchanged lines hidden (view full) ---

2636 /*
2637** RSCHECK -- check string(s) for validity using rewriting sets
2638**
2639** Parameters:
2640** rwset -- the rewriting set to use.
2641** p1 -- the first string to check.
2642** p2 -- the second string to check -- may be null.
2643** e -- the current envelope.
2644** rmcomm -- remove comments?
2645** cnt -- count rejections (statistics)?
2646** logl -- logging level
2406**
2407** Returns:
2408** EX_OK -- if the rwset doesn't resolve to $#error
2409** else -- the failure status (message printed)
2410*/
2411
2412int
2647**
2648** Returns:
2649** EX_OK -- if the rwset doesn't resolve to $#error
2650** else -- the failure status (message printed)
2651*/
2652
2653int
2413rscheck(rwset, p1, p2, e)
2654rscheck(rwset, p1, p2, e, rmcomm, cnt, logl)
2414 char *rwset;
2415 char *p1;
2416 char *p2;
2417 ENVELOPE *e;
2655 char *rwset;
2656 char *p1;
2657 char *p2;
2658 ENVELOPE *e;
2659 bool rmcomm, cnt;
2660 int logl;
2418{
2419 char *buf;
2420 int bufsize;
2421 int saveexitstat;
2422 int rstat = EX_OK;
2423 char **pvp;
2424 int rsno;
2425 bool discard = FALSE;
2426 auto ADDRESS a1;
2427 bool saveQuickAbort = QuickAbort;
2428 bool saveSuprErrs = SuprErrs;
2429 char buf0[MAXLINE];
2430 char pvpbuf[PSBUFSIZE];
2431 extern char MsgBuf[];
2432
2433 if (tTd(48, 2))
2661{
2662 char *buf;
2663 int bufsize;
2664 int saveexitstat;
2665 int rstat = EX_OK;
2666 char **pvp;
2667 int rsno;
2668 bool discard = FALSE;
2669 auto ADDRESS a1;
2670 bool saveQuickAbort = QuickAbort;
2671 bool saveSuprErrs = SuprErrs;
2672 char buf0[MAXLINE];
2673 char pvpbuf[PSBUFSIZE];
2674 extern char MsgBuf[];
2675
2676 if (tTd(48, 2))
2434 printf("rscheck(%s, %s, %s)\n", rwset, p1,
2677 dprintf("rscheck(%s, %s, %s)\n", rwset, p1,
2435 p2 == NULL ? "(NULL)" : p2);
2436
2437 rsno = strtorwset(rwset, NULL, ST_FIND);
2438 if (rsno < 0)
2439 return EX_OK;
2440
2441 if (p2 != NULL)
2442 {

--- 16 unchanged lines hidden (view full) ---

2459 {
2460 buf = buf0;
2461 bufsize = sizeof buf0;
2462 }
2463 (void) snprintf(buf, bufsize, "%s", p1);
2464 }
2465 SuprErrs = TRUE;
2466 QuickAbort = FALSE;
2678 p2 == NULL ? "(NULL)" : p2);
2679
2680 rsno = strtorwset(rwset, NULL, ST_FIND);
2681 if (rsno < 0)
2682 return EX_OK;
2683
2684 if (p2 != NULL)
2685 {

--- 16 unchanged lines hidden (view full) ---

2702 {
2703 buf = buf0;
2704 bufsize = sizeof buf0;
2705 }
2706 (void) snprintf(buf, bufsize, "%s", p1);
2707 }
2708 SuprErrs = TRUE;
2709 QuickAbort = FALSE;
2467 pvp = prescan(buf, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL);
2710 pvp = prescan(buf, '\0', pvpbuf, sizeof pvpbuf, NULL,
2711 rmcomm ? NULL : TokTypeNoC);
2468 SuprErrs = saveSuprErrs;
2469 if (pvp == NULL)
2470 {
2471 if (tTd(48, 2))
2712 SuprErrs = saveSuprErrs;
2713 if (pvp == NULL)
2714 {
2715 if (tTd(48, 2))
2472 printf("rscheck: cannot prescan input\n");
2716 dprintf("rscheck: cannot prescan input\n");
2473/*
2474 syserr("rscheck: cannot prescan input: \"%s\"",
2475 shortenstring(buf, MAXSHORTSTR));
2476 rstat = EX_DATAERR;
2477*/
2478 goto finis;
2479 }
2480 (void) rewrite(pvp, rsno, 0, e);
2481 if (pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET ||
2482 pvp[1] == NULL || (strcmp(pvp[1], "error") != 0 &&
2483 strcmp(pvp[1], "discard") != 0))
2484 {
2485 goto finis;
2486 }
2487
2488 if (strcmp(pvp[1], "discard") == 0)
2489 {
2490 if (tTd(48, 2))
2717/*
2718 syserr("rscheck: cannot prescan input: \"%s\"",
2719 shortenstring(buf, MAXSHORTSTR));
2720 rstat = EX_DATAERR;
2721*/
2722 goto finis;
2723 }
2724 (void) rewrite(pvp, rsno, 0, e);
2725 if (pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET ||
2726 pvp[1] == NULL || (strcmp(pvp[1], "error") != 0 &&
2727 strcmp(pvp[1], "discard") != 0))
2728 {
2729 goto finis;
2730 }
2731
2732 if (strcmp(pvp[1], "discard") == 0)
2733 {
2734 if (tTd(48, 2))
2491 printf("rscheck: discard mailer selected\n");
2735 dprintf("rscheck: discard mailer selected\n");
2492 e->e_flags |= EF_DISCARD;
2493 discard = TRUE;
2494 }
2736 e->e_flags |= EF_DISCARD;
2737 discard = TRUE;
2738 }
2495 else
2739 else
2496 {
2497 int savelogusrerrs = LogUsrErrs;
2498 static bool logged = FALSE;
2499
2500 /* got an error -- process it */
2501 saveexitstat = ExitStat;
2502 LogUsrErrs = FALSE;
2503 (void) buildaddr(pvp, &a1, 0, e);
2504 LogUsrErrs = savelogusrerrs;
2505 rstat = ExitStat;
2506 ExitStat = saveexitstat;
2507 if (!logged)
2508 {
2740 {
2741 int savelogusrerrs = LogUsrErrs;
2742 static bool logged = FALSE;
2743
2744 /* got an error -- process it */
2745 saveexitstat = ExitStat;
2746 LogUsrErrs = FALSE;
2747 (void) buildaddr(pvp, &a1, 0, e);
2748 LogUsrErrs = savelogusrerrs;
2749 rstat = ExitStat;
2750 ExitStat = saveexitstat;
2751 if (!logged)
2752 {
2509 markstats(e, &a1, TRUE);
2753 if (cnt)
2754 markstats(e, &a1, TRUE);
2510 logged = TRUE;
2511 }
2512 }
2755 logged = TRUE;
2756 }
2757 }
2513
2514 if (LogLevel >= 4)
2758
2759 if (LogLevel >= logl)
2515 {
2516 char *relay;
2517 char *p;
2518 char lbuf[MAXLINE];
2519
2520 p = lbuf;
2521 if (p2 != NULL)
2522 {

--- 33 unchanged lines hidden ---
2760 {
2761 char *relay;
2762 char *p;
2763 char lbuf[MAXLINE];
2764
2765 p = lbuf;
2766 if (p2 != NULL)
2767 {

--- 33 unchanged lines hidden ---