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 --- |