1 static char rcsid[] = "@(#)$Id: okay_addr.c,v 1.5 1996/03/14 17:27:42 wfp5p Exp $";
2 
3 /*******************************************************************************
4  *  The Elm Mail System  -  $Revision: 1.5 $   $State: Exp $
5  *
6  *                      Copyright (c) 1988-1995 USENET Community Trust
7  *			Copyright (c) 1986,1987 Dave Taylor
8  *******************************************************************************
9  * Bug reports, patches, comments, suggestions should be sent to:
10  *
11  *      Bill Pemberton, Elm Coordinator
12  *      flash@virginia.edu
13  *
14  *******************************************************************************
15  * $Log: okay_addr.c,v $
16  * Revision 1.5  1996/03/14  17:27:42  wfp5p
17  * Alpha 9
18  *
19  * Revision 1.4  1995/09/29  17:41:23  wfp5p
20  * Alpha 8 (Chip's big changes)
21  *
22  * Revision 1.3  1995/09/11  15:18:56  wfp5p
23  * Alpha 7
24  *
25  * Revision 1.2  1995/06/22  14:48:37  wfp5p
26  * Performance enhancements from Paul Close
27  *
28  * Revision 1.1.1.1  1995/04/19  20:38:32  wfp5p
29  * Initial import of elm 2.4 PL0 as base for elm 2.5.
30  *
31  ******************************************************************************/
32 
33 #include "elm_defs.h"
34 
35 #define before_okay(c)	\
36 	((c) == 0 || (c) == '<' || (c) == '!' || (c) == ':' || (c) == '%' || \
37 	 (c) == ' ' || (c) == ',')
38 #define after_okay(c)	\
39 	((c) == 0 || (c) == '>' || (c) == ':' || (c) == '%' || (c) == '@' || \
40 	 (c) == ' ' || (c) == ',' || (c) == '\r' || (c) == '\n')
41 
42 int
okay_address(address,return_address)43 okay_address(address, return_address)
44 char *address, *return_address;
45 {
46 	/** This routine checks to ensure that the address we just got
47 	    from the "To:" or "Cc:" line isn't us AND isn't the person
48 	    who sent the message.  Returns true iff neither is the case **/
49 
50 	static int first_time = TRUE;
51 	static int host_equal_hostfull;
52 	static int userlen, hostlen, hostfulllen;
53 
54 	struct addr_rec  *alternatives;
55 
56 	char *usrp;
57 
58 	if (first_time) {
59 	  /* username and hostname don't change, so do this only once */
60 	  host_equal_hostfull = (istrcmp(host_name, host_fullname) == 0);
61 	  userlen = strlen(user_name);
62 	  hostlen = strlen(host_name);
63 	  hostfulllen = strlen(host_fullname);
64 	  first_time = FALSE;
65 	}
66 
67 	/* check for return_address */
68 
69 	if (return_address && in_list(address, return_address))
70 	  return(FALSE);
71 
72 	/* check for username, optionally combined with hostname(s) */
73 
74 	if ((usrp = strstr(address, user_name)) != NULL) {
75 	  char pre, post;
76 	  pre = (usrp == address)? 0: usrp[-1];
77 	  post = usrp[userlen];
78 	  if (before_okay(pre) && after_okay(post)) {
79 	    /* we have a valid username */
80 	    /* look for user@host or user%host */
81 	    if (post == '@' || post == '%') {
82 	      char *maybehost = usrp+userlen+1;
83 	      if (strincmp(maybehost, host_name, hostlen) == 0 &&
84 		  after_okay(maybehost[hostlen])) {
85 		/* got user@host */
86 		return FALSE;
87 	      }
88 	      if (! host_equal_hostfull &&
89 		  strincmp(maybehost, host_fullname, hostfulllen) == 0 &&
90 		  after_okay(maybehost[hostfulllen])) {
91 		/* got user@fullhost */
92 		return FALSE;
93 	      }
94 	    }
95 	    /* look for host!user */
96 	    else if (pre == '!') {
97 	      char *maybehost = usrp-hostlen-1;
98 	      if ((maybehost == address ||
99 		   (maybehost > address && before_okay(maybehost[-1]))) &&
100 	          strincmp(maybehost, host_name, hostlen) == 0) {
101 		/* got host!user */
102 		return FALSE;
103 	      }
104 	      maybehost = usrp-hostfulllen-1;
105 	      if (! host_equal_hostfull &&
106 		  (maybehost == address ||
107 		   (maybehost > address && before_okay(maybehost[-1]))) &&
108 	          strincmp(maybehost, host_fullname, hostfulllen) == 0) {
109 		/* got fullhost!user */
110 		return FALSE;
111 	      }
112 	    }
113 	    else {
114 	      /* not preceded by ! or followed by [@%] -- just username */
115 	      return FALSE;
116 	    }
117 	  }
118 	}
119 
120 	/* didn't find valid username, look for alternates */
121 
122 	alternatives = alternative_addresses;
123 
124 	while (alternatives != NULL) {
125 	  if (in_list(address, alternatives->address))
126 	    return(FALSE);
127 	  alternatives = alternatives->next;
128 	}
129 
130 	return(TRUE);
131 }
132