|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T a
Length: 12251 (0x2fdb)
Types: TextFile
Names: »ad_local.c«
└─⟦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«
/* 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;
}