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