DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T a

⟦96c917cac⟧ TextFile

    Length: 12251 (0x2fdb)
    Types: TextFile
    Names: »ad_local.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« 
        └─⟦e5a54fb17⟧ 
            └─⟦this⟧ »pp-5.0/Lib/parse/ad_local.c« 

TextFile

/* ad_local.c: process a local address */

# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Lib/parse/RCS/ad_local.c,v 5.0 90/09/20 16:09:22 pp Exp Locker: pp $";
# endif

/*
 * $Header: /cs/research/pp/hubris/pp-beta/Lib/parse/RCS/ad_local.c,v 5.0 90/09/20 16:09:22 pp Exp Locker: pp $
 *
 * $Log:	ad_local.c,v $
 * Revision 5.0  90/09/20  16:09:22  pp
 * rcsforce : 5.0 public release
 * 
 */



#include "head.h"
#include "adr.h"
#include "alias.h"
#include "list_rchan.h"
#include <pwd.h>
#include "chan.h"
#include "ap.h"
#include "or.h"

extern void             x400_add (), rfc822_add();
extern CHAN             *ch_inbound;
extern ADDR             *adr_new();
extern  char		*loc_dom_mta;

static  int             do_user_check ();
static  int             do_alias_check ();
static  int             do_local_stuff();
static void             ad_copy ();

int			topParse = TRUE;

/* ---------------------  Begin  Routines  -------------------------------- */

int ad_local (name, ad, rp, ltablepref)
char    *name;
ADDR    *ad;
RP_Buf  *rp;
char	*ltablepref;
{
        ALIAS                   alias_struct,
                                *alp = &alias_struct;
        int                     retval;
        char                    temp[256];
        PP_TRACE (("ad_local (%s, ad=%s, %s)", name, ad -> ad_value,
		   ltablepref));

        switch (tb_getalias (name, alp, ltablepref)) {
        case NOTOK:
                /* -- routine or table error -- */
                PP_TRACE (("ad_local/tb_getalias failed on %s", name));
                return parselose (rp, RP_USER, "Alias error for %s", name);
        case OK:
                /* -- found, do alias check -- */
               if (rp_isbad(retval = do_alias_check (name, alp, ad,
						     rp, ltablepref))) {
                        sprintf(temp, "%s [Alias '%s' maps to '%s']",
                                ad->ad_parse_message, name, alp->alias_user);
			if (ad -> ad_parse_message)
				free(ad->ad_parse_message);
                        ad->ad_parse_message = strdup(temp);
                        strcpy(rp->rp_line, temp);
                        PP_LOG(LLOG_EXCEPTIONS,
                               ("Bad alias '%s' maps to '%s'",
                                name, alp->alias_user));
                }
                return retval;
        default:
                /* -- otherwise do the user checks -- */
                return do_user_check (name, ad, rp, ltablepref);
        }

        /*NOTREACHED*/
}




/* ---------------------  Static  Routines  ------------------------------- */




static int do_user_check (name, ad, rp, ltablepref)
char    *name;
ADDR    *ad;
RP_Buf  *rp;
char	*ltablepref;
{
        LIST_RCHAN              *rlp, *ix, *ix2, *newchan, *end;
        char                    buf [BUFSIZ], *newadr, *oldadr;
	AP_ptr			tree, group, nameap, local, domain, route;
	int			next;
	extern LIST_RCHAN	*tb_getuser();

        PP_TRACE (("Lib/parse/do_user_check (%s)", name));

        if ((ad->ad_outchan = tb_getuser (name, ltablepref)) == NULLIST_RCHAN) {
		sprintf(buf,
			"Unknown local user '%s'", name);

		ad -> ad_parse_message = strdup(buf);
			
		return parselose (rp, ad -> ad_parse_stat = RP_USER,
				  "Unknown local user '%s'", name);
	}

	if (ad -> ad_type != AD_X400_TYPE
		&& ad->ad_r822adr != NULLCP) {
		oldadr = strdup(ad->ad_r822adr);
		if (ap_s2p(oldadr,
			   &tree,
			   &group,
			   &nameap,
			   &local,
			   &domain,
			   &route) != (char *) NOTOK) {
			if (local != NULLAP && local->ap_obvalue != NULLCP)
				free(local->ap_obvalue);
			if (local != NULLAP)
				local->ap_obvalue = strdup(name);
			if ((newadr = ap_p2s(group, nameap, local,
					     domain, route)) != NULLCP) {
				if (ad->ad_r822adr) free(ad->ad_r822adr);
				ad->ad_r822adr = newadr;
			}
			ap_sqdelete (tree, NULLAP);
			ap_free(tree);
		}
		free(oldadr);
		if (!ad -> ad_resp)
			return (ad->ad_parse_stat = RP_AOK);

		x400_add (ad);
	}
	else {
		OR_ptr	or = NULLOR, or2, or2next = NULLOR;
		OR_ptr orb = NULLOR;

		char	tbuf[BUFSIZ];

		if (ad -> ad_r400adr) {
			or = or_std2or (ad -> ad_r400adr);
			if (or2 = or_locate (or, OR_S)) {
				orb = or2 -> or_prev;
				or2next = or2 -> or_next;
				or2 -> or_next = NULLOR;
				or_free (or2);
				if (orb)
					orb -> or_next = NULLOR;
			}
			else
				for (orb = or; orb -> or_next;
				     orb = orb -> or_next)
					continue;
		}
		
		or2 = or_buildpn (name);
		if (orb) {
			orb -> or_next = or2;
			or2 -> or_prev = orb;
			if (or2next != NULLOR) {
				or2 -> or_next = or2next;
				or2next -> or_prev = or2;
			}
		}
		else {
			or = orb;
			if (or2next != NULLOR) {
				orb -> or_next = or2next;
				or2next -> or_prev = orb;
			}
		}
			

		or = or_default(or);
		or_or2std (or, tbuf, FALSE);
		if (ad -> ad_r400adr)
			free (ad -> ad_r400adr);
		ad -> ad_r400adr = strdup (tbuf);

		rfc822_add (ad);
	}
	
	next = TRUE;

	for (ix = ad->ad_outchan; ix != NULLIST_RCHAN; ix = (next == TRUE) ? ix -> li_next : ix) {

		/* -- this is the machine on which the local delivery is done -- */
		next = TRUE;

		/* have to compare this one against the real loc_dom_mta! */
		if (ix->li_mta != NULLCP &&
		    lexequ (ix -> li_mta, loc_dom_mta) != 0)
		{
			/* -- not this machine, update ix -- */
			newchan = NULLIST_RCHAN;
			if (tb_getchan (ix -> li_mta, &newchan) == NOTOK) {
				char	tmp[BUFSIZ];
				sprintf(tmp,"Domain '%s' not registered for channel '%s'",
					ix->li_mta, ix->li_chan->ch_name);
				ad->ad_parse_message = strdup(tmp);
				return ad -> ad_parse_stat =
					parselose (rp, RP_USER,
						   "Domain '%s' not registered for channel '%s'",
						   ix -> li_mta, ix -> li_chan->ch_name);
			} else {
				if (ix == ad->ad_outchan) {
					end = newchan;
					while (end -> li_next != NULLIST_RCHAN) end = end -> li_next;
					end -> li_next = ad -> ad_outchan -> li_next;
					ad -> ad_outchan = newchan;
					ix -> li_next = NULLIST_RCHAN;
					list_rchan_free(ix);
					ix = end;
				} else {
					ix2 = ad -> ad_outchan;
					while (ix2 != NULLIST_RCHAN
					       && ix2 -> li_next != ix)
						ix2 = ix2 -> li_next;
					if (ix2 != NULLIST_RCHAN) {
						end = newchan;
						while (end -> li_next != NULLIST_RCHAN) end = end -> li_next;
						end -> li_next = ix -> li_next;
						ix2 -> li_next = newchan;
						ix -> li_next = NULLIST_RCHAN;
						list_rchan_free(ix);
						ix = end;
					}
				}
			}
		} else if (ix -> li_chan == NULLCHAN) {
			/* invalid local channel */
			/* remove */
			LIST_RCHAN	*trash, *tmp;
			if (ix == ad->ad_outchan) {
				trash = ix;
				ix = ad->ad_outchan = ad->ad_outchan->li_next;
				next = FALSE;
				/* yuch */
			} else {
				for (tmp = ad->ad_outchan; tmp->li_next != ix; tmp = tmp->li_next);
				tmp -> li_next = ix->li_next;
				trash = ix;
				ix = tmp;
			}
			trash->li_next = NULLIST_RCHAN;
			list_rchan_free(trash);
		}
	}


	if (ad->ad_outchan == NULLIST_RCHAN) {
		/* no delivery channels */
		ad -> ad_parse_message = strdup("No valid outbound channels");
		return ad->ad_parse_stat =
			parselose(rp, RP_USER, "%s",
				  "No valid outbound channels");
	}
	/*
	  Go thru the list.  if li_mta (i.e mta) is not set,
	  insert official.
	  */
	for (rlp=ad->ad_outchan; rlp; rlp = rlp->li_next)
		if (rlp->li_mta == NULLCP)
			rlp->li_mta =strdup (loc_dom_mta);

	return (ad->ad_parse_stat = RP_AOK);

}

static int do_alias_check (name, alp, ad, rp, ltablepref)
char    *name;
ALIAS   *alp;
ADDR    *ad;
RP_Buf  *rp;
char	*ltablepref;
{
	ADDR	*new = NULLADDR;
	int	retval = RP_AOK;
	PP_TRACE (("Lib/parse/do_alias_check (%s)", name));

	if (inAliasList(alp->alias_user) == OK) {
		char    tmp[BUFSIZ];
		PP_LOG(LLOG_EXCEPTIONS,
		       ("Lib/parse/do_local circular aliases '%s'",
			alp->alias_user));
		(void) sprintf(tmp, "Circular alias '%s'", alp->alias_user);
		if (ad -> ad_parse_message)
			free (ad -> ad_parse_message);
		ad->ad_parse_message = strdup(tmp);
		return RP_PARSE;
	} else
		addToAliasList(alp->alias_user);

	switch (alp->alias_type) {
	    case ALIAS_SYNONYM: 
		new = adr_new (alp->alias_user,
			       ad->ad_type,
			       ad -> ad_extension);
		new->ad_resp = ad -> ad_resp;
		if (!rp_isbad(retval =ad_parse (new, rp, CH_USA_PREF)))
			ad_copy(ad, new, YES);
		break;

	    case ALIAS_PROPER:
		new = adr_new(alp->alias_user,
			      ad->ad_type,
			      ad->ad_extension);
		new->ad_resp = YES;
		if (!rp_isbad(retval = ad_parse (new, rp, CH_USA_PREF)))
			ad_copy(ad, new, ad->ad_resp);
		break;

	    case ALIAS_822_SYNONYM:
	    case ALIAS_X400_SYNONYM:
		new = adr_new (alp -> alias_user, 
			       (alp->alias_type == ALIAS_822_SYNONYM) ? AD_822_TYPE : AD_X400_TYPE,
			       ad -> ad_extension);
		new->ad_resp = ad->ad_resp;

		if (!rp_isbad (retval = ad_parse (new, rp, CH_USA_PREF)))
			ad_copy(ad, new, YES);
		break;

	    case ALIAS_822:
	    case ALIAS_X400:
		if (ad->ad_resp 
		    || rp_isbad(retval = do_user_check(name, ad, rp, ltablepref))) {
			new = adr_new(alp->alias_user,
				      (alp->alias_type == ALIAS_X400) ? AD_X400_TYPE : AD_822_TYPE,
				      ad -> ad_extension);
			new->ad_resp = YES;
			
			if (!rp_isbad (retval = ad_parse (new, rp, CH_USA_PREF)))
				ad_copy(ad, new, YES);
		}
		break;
	    default:
		break;
	}

	if (rp_isbad(retval)) {
		if (new != NULLADDR) {
			if (ad->ad_parse_message)
				free(ad->ad_parse_message);
			ad->ad_parse_message = strdup(new->ad_parse_message);
			ad->ad_parse_stat = new->ad_parse_stat;
		}
	}
	if (new)
		adr_free(new);
        return retval;
}


static int do_local_stuff (alp, ad, rp)
ALIAS   *alp;
ADDR    *ad;
RP_Buf  *rp;
{
        int     type;
        ADDR    *new;

        switch (alp->alias_type) {
        case ALIAS_822:
                type = AD_822_TYPE;
                break;
        case ALIAS_X400:
                type = AD_X400_TYPE;
                break;
        default:
                return (ad->ad_parse_stat = RP_USER);
        }

        new = adr_new (alp->alias_user, type, ad->ad_extension);

        if (rp_isbad (ad_parse (new, rp, CH_USA_PREF))) {
                adr_tfree (new);
                return (ad -> ad_parse_stat = rp -> rp_val);
        }

        ad_copy (ad, new);
        adr_tfree (new);
        return (ad->ad_parse_stat = RP_AOK);
}


static void ad_copy (ad, new, resp)
ADDR            *ad;
ADDR            *new;
int		resp;
{
        PP_DBG (("ad_copy()"));

        if (ad->ad_outchan != NULLIST_RCHAN)    
		list_rchan_free (ad->ad_outchan);
        ad->ad_outchan                          = new->ad_outchan;
        new->ad_outchan                         = NULLIST_RCHAN;

	if (resp == YES) {
		if (ad->ad_r822adr != NULLCP)           free (ad->ad_r822adr);
		if (ad->ad_r400adr != NULLCP)           free (ad->ad_r400adr);

		ad->ad_r822adr                          = new->ad_r822adr;
		ad->ad_r400adr                          = new->ad_r400adr;
		ad->ad_type                             = new->ad_type;

		new->ad_r822adr                         = NULLCP;
		new->ad_r400adr                         = NULLCP;
	}
}

/* \f

 */

typedef struct _aliasList {
        char                    *alias;
        struct _aliasList       *next;
} aliasList;

aliasList       *AliasList = NULL;

recFreeAliasList(list)
aliasList       *list;
{
        if (list->alias) free(list->alias);
        if (list->next) recFreeAliasList(list->next);
        free((char *) list);
}

freeAliasList()
{
        if (AliasList != NULL) {
                recFreeAliasList(AliasList);
                AliasList = NULL;
        }
}

static aliasList        *newAliasList(alias)
char    *alias;
{
        aliasList       *ret = (aliasList *) calloc(1, sizeof(*ret));
        ret->alias = strdup(alias);
        return ret;
}

addToAliasList(alias)
char    *alias;
{
        aliasList       *tmp = newAliasList(alias);
        if (AliasList == NULL)
                AliasList = tmp;
        else {
                tmp->next = AliasList;
                AliasList = tmp;
        }
}


int inAliasList(alias)
char    *alias;
{
        aliasList       *ix = AliasList;

        while (ix != NULL && strcmp(ix->alias, alias) != 0)
                ix = ix->next;

        if (ix != NULL)
                return OK;
        return NOTOK;
}