|
|
BSD 4.3
/* $Header: /var/lib/cvsd/repos/CSRG/43BSD/contrib/xns/morexnslib/ch/CHlookup.c,v 1.1.1.1 2018/04/24 16:12:54 root Exp $ */
/* contains:
* CH_LookupAddr
* CH_GetFirstCH
* CH_GetOtherCH
* CH_NameDefault
*/
/* $Log: CHlookup.c,v $
/* Revision 1.1.1.1 2018/04/24 16:12:54 root
/* BSD 4.3
/*
* Revision 2.0 85/11/21 07:22:32 jqj
* 4.3BSD standard release
*
* Revision 1.3 85/11/21 07:14:19 jqj
* 4.3BSD standard release
*
* Revision 1.2 85/10/21 12:41:55 jqj
* Gould version: work around a Gould compiler bug. Default to /usr/new
* for consistency.
*
* Revision 1.1 85/10/18 09:14:53 jqj
* Initial revision
*
* Revision 1.1 85/03/26 06:27:00 jqj
* Initial revision
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <netns/ns.h>
#include <xnscourier/Clearinghouse2.h>
#include <xnscourier/CHEntries.h>
#include <xnscourier/except.h>
#define MAXPACKS 5
#define NLSIZE 50
static Clearinghouse2_ObjectName *namelist[NLSIZE];
static int nlcount = 0;
static Cardinal nullpasswd = 0;
static Clearinghouse2_Authenticator nullagent = {{0,{0,0}},{1,&nullpasswd}};
static
GetData(conn)
CourierConnection *conn;
{
int count, i;
Unspecified buffer[MAXWORDS*MAXPACKS], *bp, *bufend;
Clearinghouse2_StreamOfObjectName obnames;
bufend = buffer;
bp = buffer+((MAXWORDS-1)*MAXPACKS); /* end of available space */
while (count = BDTread(conn, (char*)bufend,
MAXWORDS*sizeof(Unspecified))
) {
bufend += count/sizeof(Unspecified);
if (bufend > bp) {
fprintf(stderr,"BDT read too big to fit\n");
BDTabort(conn);
/* should clear out stuff here if we knew how much */
}
}
bp = buffer;
while (bp < bufend) {
bp += internalize_Clearinghouse2_StreamOfObjectName(&obnames,bp);
if (0 == (int) obnames.designator) {
for (i = 0; i < obnames.nextSegment_case.segment.length; i++)
if (nlcount < NLSIZE) namelist[nlcount++] =
&obnames.nextSegment_case.segment.sequence[i];
} else {
for (i = 0; i < obnames.lastSegment_case.length; i++)
if (nlcount < NLSIZE) namelist[nlcount++] =
&obnames.lastSegment_case.sequence[i];
return;
}
}
}
static struct ns_addr*
itemtonsaddr(itemptr)
Clearinghouse2_Item *itemptr; /* i.e. a sequence of Unspecified */
{
static union {
struct ns_addr addr;
u_short shrt[6];
} result;
register int i;
register Unspecified *seq;
if (itemptr->length < 7)
return(0);
seq = itemptr->sequence +1;
/* itemptr->sequence[0] == number of addresses */
for (i = 0; i < 6; i++, seq++)
result.shrt[i] = ntohs(*seq);
return(&result.addr);
}
/*
* path to look for the addresses file on
* (I wish I'd picked a shorter name, so we could rendezvous in /etc.
* But long file names in /etc are very unpopular!).
*/
static char *chaddrpath[] = {
#ifdef CHADDRS
CHADDRS,
#endif
"/usr/new/lib/xnscourier/clearinghouse.addresses",
"/etc/clearinghouse.addresses",
"/usr/local/lib/xnscourier/clearinghouse.addresses",
0 };
/*
* Set defaults for organization and domain, based on the file
* /usr/local/lib/xnscourier/clearinghouse.addresses
* (should get the local clearinghouse and set defaults based on
* ListDomainsServed
*/
CH_NameDefault(defaultobjnamep)
Clearinghouse2_ObjectName *defaultobjnamep;
{
FILE *chfile;
int i, nmatch;
static char orgbuf[21], domainbuf[21];
defaultobjnamep->object = "";
for (i=0; chaddrpath[i] != NULL; i++) {
chfile = fopen(chaddrpath[i],"r");
if (chfile != (FILE*)0) {
nmatch = fscanf(chfile,"%*[^ \t\n] \":%[^:]:%[^\"]",
domainbuf, orgbuf);
fclose(chfile);
if (nmatch == 2) {
defaultobjnamep->domain = domainbuf;
defaultobjnamep->organization = orgbuf;
return; /* done */
}
}
}
defaultobjnamep->organization = "";
defaultobjnamep->domain = "";
}
CourierConnection*
CH_GetFirstCH()
{
struct ns_addr *chaddr;
extern struct ns_addr *getXNSaddr();
char buf[BUFSIZ];
CourierConnection *result;
FILE *chfile;
int i;
/* for now, use hard-coded CH */
/* eventually we'll do an expanding-ring or something */
result = (CourierConnection *) NULL;
for (i = 0; chaddrpath[i] != NULL; i++) {
if ((chfile = fopen(chaddrpath[i],"r")) != NULL) {
while (fgets(buf, BUFSIZ, chfile))
if ((chaddr = getXNSaddr(buf)) &&
(result = CourierOpen(chaddr))) {
fclose(chfile);
return(result);
}
fclose(chfile);
break; /* don't look for other files */
}
}
/* try expanding-ring here */
return(result);
}
CourierConnection *
CH_GetOtherCH(conn,hint)
CourierConnection *conn;
Clearinghouse2_ObjectName hint;
{
struct ns_addr *ch2addr;
CourierConnection *ch2conn;
Clearinghouse2_RetrieveItemResults riresult;
Clearinghouse2_RetrieveMembersResults rmresult;
int i;
Clearinghouse2_Property clearinghouseNames = 3;
Clearinghouse2_Property clearinghouseAddresses = 4;
Clearinghouse2_ObjectName hint1;
DURING
/* get list of possible other clearinghouses */
rmresult = Clearinghouse2_RetrieveMembers(conn, GetData, hint,
clearinghouseNames, BulkData1_immediateSink,
nullagent);
HANDLER {
/* some race condition */
return(NULL);
} END_HANDLER;
/* throw away the distinguished name, which we don't need */
clear_Clearinghouse2_RetrieveMembersResults(&rmresult);
/* for each member of potentials list, probe it */
ch2conn = NULL;
for (i = 0; i < nlcount; i++) {
Clearinghouse2_ObjectName thisname;
thisname = *namelist[i];
/* get its address */
DURING
riresult = Clearinghouse2_RetrieveItem(conn, NULL,
thisname,
clearinghouseAddresses, nullagent);
HANDLER
continue; /* try next in namelist */
END_HANDLER;
ch2addr = itemtonsaddr(&riresult.value);
clear_Clearinghouse2_RetrieveItemResults(&riresult);
ch2conn = CourierOpen(ch2addr);
if (ch2conn == NULL) continue;
/* make sure the second CH is really there */
DURING
(void) Clearinghouse2_RetrieveAddresses(ch2conn, NULL);
HANDLER {
CourierClose(ch2conn);
ch2conn = NULL;
continue;
} END_HANDLER;
/* we got it! */
break;
}
for (i = 0; i < nlcount; i++) {
/* free namelist[i] components */
clear_Clearinghouse2_ObjectName(namelist[i]);
/* free the top level thing too */
Deallocate((Unspecified*) namelist[i]);
}
return(ch2conn);
}
/*
* Given a Clearinghouse three part name (possibly containing wild cards)
* and the property number on which a NetworkAddress is expected to occur,
* returns the ns_addr structure associated with that name.
* Note that the ns_addr structure is statically allocated!
* Resets pattern to be the distinguished name of the object found.
*/
struct ns_addr *
CH_LookupAddr(pattern,property)
Clearinghouse2_ObjectNamePattern pattern;
Clearinghouse2_Property property;
{
struct ns_addr* CH_LookupAddrDN();
return(CH_LookupAddrDN(pattern,property,0,0));
}
/*
* Lookup a clearinghouse address, returning the address and the
* distinguished name of the object found.
*/
struct ns_addr *
CH_LookupAddrDN(pattern,property,distnamep,distnamelen)
Clearinghouse2_ObjectNamePattern pattern;
Clearinghouse2_Property property;
char *distnamep;
int distnamelen;
{
struct ns_addr *chaddr, *resultaddr;
CourierConnection *conn, *ch2conn;
Clearinghouse2_ObjectName hint; /* from WrongServer errors */
Clearinghouse2_RetrieveItemResults riresult;
if ((long) property <= 0) /* default to addressList i.e. 4 */
property = CHEntries0_addressList;
if (pattern.object == NULL ||
pattern.domain == NULL ||
pattern.organization == NULL)
return(NULL); /* can't handle defaults */
if ((conn = CH_GetFirstCH()) == NULL) {
fprintf(stderr,"Can't open connection to local Clearinghouse\n");
exit(1);
}
/* ask our primary clearinghouse for the address of this thing */
DURING {
riresult = Clearinghouse2_RetrieveItem(conn, NULL,
pattern, property, nullagent);
} HANDLER {
if (Exception.Code != Clearinghouse2_WrongServer) {
CourierClose(conn);
return(0); /* some random error */
}
hint = CourierErrArgs(Clearinghouse2_WrongServerArgs, hint);
ch2conn = CH_GetOtherCH(conn, hint);
CourierClose(conn);
if (ch2conn == NULL) return(0);
conn = ch2conn;
/* probe the second clearinghouse */
DURING
riresult = Clearinghouse2_RetrieveItem(conn, NULL,
pattern, property, nullagent);
HANDLER {
/* should be smarter if WrongServer here */
CourierClose(conn);
return(0);
} END_HANDLER;
/* we got it */
} END_HANDLER;
resultaddr = itemtonsaddr(&riresult.value);
if (distnamep != NULL &&
distnamelen >= (2+strlen(riresult.distinguishedObject.object)+
strlen(riresult.distinguishedObject.domain)+
strlen(riresult.distinguishedObject.organization)))
sprintf(distnamep,"%s:%s:%s",
riresult.distinguishedObject.object,
riresult.distinguishedObject.domain,
riresult.distinguishedObject.organization);
clear_Clearinghouse2_RetrieveItemResults(&riresult);
CourierClose(conn);
return(resultaddr);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.