static char rcsid[] = "@(#)$Id: okay_addr.c,v 1.20 2006/04/09 07:37:05 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.20 $   $State: Exp $
 *
 *  Reimplemented by: Kari Hurtta <hurtta+elm@posti.FMI.FI> 
 *                                (was hurtta+elm@ozone.FMI.FI)
 ******************************************************************************
 *  This code is reimplemented. Original code was following copyright:
 *
 *  The Elm Mail System 
 *
 *			Copyright (c) 1988-1992 USENET Community Trust
 *			Copyright (c) 1986,1987 Dave Taylor
 *****************************************************************************/

/** 

**/

#include "headers.h"

DEBUG_VAR(Debug,__FILE__,"addr");

/* returns:   1 if dequoted,
              0 if unmodified
	     -1 if overflow
	     -2 if syntax error
*/

static int strcpy_dequote P_((char * target, const char * source, int size));
static int strcpy_dequote(target,source,size)
     char * target; 
     CONST char * source; 
     int size;
{
    int r = 0;

    int q = 0;
    CONST char *s;
    char *t;
    int overflow     = 0;
    int syntax_error = 0;

#define ADD(x) { int X = (x); \
	if (t < target + size - 1) *t++=X; else overflow++; \
	}

    for (s = source, t = target; *s; s++) {
	if (q) {
	    if ('"' == *s) {
		q = !q;
	    } else if ('\\' == *s) {
		s++;
		if (!*s) {
		    syntax_error++;
		}
		ADD(*s);
	    } else {
		ADD(*s);
	    }
	} else {
	    if ('"' == *s) {
		r = 1;
		q = !q;
	    } else {
		if ('\\' == *s) {
		    syntax_error++;
		}
		ADD(*s);
	    }
	}
    }
    *t = '\0';

    if (syntax_error) {
	DPRINT(Debug,2,(&Debug,
			"strcpy_dequote: syntax error: source=%s\n",
			source));		   
	r = -2;
    } else if (overflow) {
	DPRINT(Debug,2,(&Debug,
			"strcpy_dequote: overflow: source=%s\n",
			source));
	
	r = -1;
    }

    return r;

}

int addr_is_user(addr)
     char *addr;
{
    char **alternatives;
    char our_address[SLEN]; 
    char deqbuffer[SLEN];

    char *host_part;

    int D = strcpy_dequote(deqbuffer, addr, sizeof deqbuffer);

    if (D != 0) {
	DPRINT(Debug,25,(&Debug,
			 "addr_is_user(\"%s\"): Dequotation: %s\n",
			 addr,deqbuffer));
    }

    if (0 == strcmp(username, deqbuffer)) {
	DPRINT(Debug,25,(&Debug,
			 "addr_is_user(\"%s\")=TRUE: %s matches username\n",
			 D > 0 ? "(dequoted)" : "",
			 addr));
	return TRUE;
    }
	
          
    /* UUCP hostnames are case sensitive */
    elm_sfprintf(our_address, sizeof our_address,
		 FRM("%s!%s"), hostname, username);

    if (0 == strcmp(our_address, deqbuffer)) {
	DPRINT(Debug,25,(&Debug,				    
			 "addr_is_user(\"%s\")=TRUE: %s matches UUCP address\n",
			 D > 0 ? "(dequoted)" : "",
			 addr));
	return TRUE;
    }

    elm_sfprintf(our_address, sizeof our_address,
		 FRM("%s!%s"), hostfullname, username);

    if (0 == strcmp(our_address, deqbuffer)) {
	DPRINT(Debug,25,(&Debug,
			 "addr_is_user(\"%s\")=TRUE: %s matches UUCP address\n",
			 D > 0 ? "(dequoted)" : "",
			 addr));
	return TRUE;
    }
    
    /* Internet hostnames are case insensitive */
    host_part = qstrpbrk(addr,"@");
    if (host_part) {
	int LEN = host_part - addr +1;
	char * buffer = safe_malloc(LEN);
	char * buffer1 = safe_malloc(LEN);
	int D1;

	strncpy(buffer1,addr,host_part - addr);
	buffer1[host_part - addr] = '\0';

	
	D1 = strcpy_dequote(buffer,buffer1,LEN);

	DPRINT(Debug,25,(&Debug,
			 "addr_is_user(\"%s\"): user part=%s%s, host part=%s\n",
			 addr,buffer,
			 D1 > 0 ? " (dequoted)" : "",
			 host_part+1));
    
	if (0 == strcmp(buffer,username)) {
	    if (0 == istrcmp(hostname,host_part+1)) {
		DPRINT(Debug,25,(&Debug,
				 "addr_is_user(\"%s\")=TRUE: matches internet address\n",
				 addr));
		free(buffer);
		free(buffer1); buffer1 = NULL;
			       			
		return(TRUE);
	    }
      
	    if (0 == istrcmp(hostfullname,host_part+1)) {
		DPRINT(Debug,25,(&Debug,
				 "addr_is_user(\"%s\")=TRUE: matches internet address\n",
				 addr));		
		free(buffer);
		free(buffer1); buffer1 = NULL;
			
		return(TRUE);
	    }
	}

	alternatives = give_dt_path_as_elems(&alternative_addresses,
					     "alternatives");
	if (alternatives) {

	    int i;

	    for (i = 0; alternatives[i]; i++) {
		char * host_part2 = qstrpbrk(alternatives[i],"@");

		if (host_part2) {
		    int LEN = host_part2 - alternatives[i];
		    char * buffer2 = safe_malloc(LEN+1);

		    strncpy(buffer2,alternatives[i], LEN);
		    buffer2[LEN] = '\0';
		
		    DPRINT(Debug,27,(&Debug,
				     "addr_is_user: %s: user part=%s, host part=%s\n",
				     alternatives[i],buffer2,host_part2+1));
		
		    if ((0 == strcmp(buffer,buffer2) ||
			 0 == strcmp(buffer1,buffer2)
			 ) &&
			0 == istrcmp(host_part2+1,host_part+1)) {
			DPRINT(Debug,25,(&Debug,
					 "addr_is_user(\"%s\")=TRUE: matches alternative\n",
					 addr));		
			free(buffer2);
			free(buffer);		    
			free(buffer1); buffer1 = NULL;
			
			return(TRUE);		    
		    }
		    free(buffer2);
		}
	    }
	}
	free(buffer);
	free(buffer1); buffer1 = NULL;	
	
    }

    alternatives = give_dt_path_as_elems(&alternative_addresses,
					 "alternatives");    
    if (alternatives) {

	int i;
	
	for (i = 0; alternatives[i]; i++) {
	    
	    if (0 == strcmp(addr,alternatives[i])) {
		DPRINT(Debug,25,(&Debug,				   
				 "addr_is_user(\"%s\")=TRUE: matches alternative address\n",
				 addr));		
		return(TRUE);
	    }
	}
    }
    DPRINT(Debug,25,(&Debug,
		     "addr_is_user(\"%s\")=FALSE\n",addr));
    return FALSE;
}

int okay_address_l(address, return_address)
     CONST struct addr_item *address, *return_address;
{
    
    /** This routine checks to ensure that the address we just got
	from the "To:" or "Cc:" line isn't us AND isn't the person	
	who sent the message.  Returns true iff neither is the case **/
    
    CONST struct addr_item *ptr;
    
    for (ptr = return_address; ptr && ptr -> addr && ptr->fullname; ptr++) {
	if (0 == strcmp(ptr -> addr, address -> addr)) {
	    DPRINT(Debug,25,(&Debug,
			     "okay_address_l=FALSE:\n"));
	    DPRINT(Debug,25,(&Debug,
			     "     address{addr=%s,fullname=%S} same as return_address {addr=%s,fullname=%S}\n",
			     address -> addr, address -> fullname,
			     ptr -> addr, ptr -> fullname));
	    return(FALSE);
	}
    }

    if (addr_is_user(address -> addr)) {
	DPRINT(Debug,25,(&Debug,
		   "okay_address_l=FALSE:\n"));
	DPRINT(Debug,25,(&Debug,
			 "     address{addr=%s,fullname=%S} is user's address\n",
			 address -> addr, address -> fullname));	
	return(FALSE);
    }
    
    DPRINT(Debug,25,(&Debug,
		     "okay_address_l=TRUE:\n"));
    DPRINT(Debug,25,(&Debug,
		     "     address{addr=%s,fullname=%S} is not our address.\n",
		     address -> addr, address -> fullname)); 
    return(TRUE);
}


/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 *  buffer-file-coding-system: iso-8859-1
 * End:
 */


syntax highlighted by Code2HTML, v. 0.9.1