|
|
1.1 root 1: /* $Header: CHlookup.c,v 2.0 85/11/21 07:22:32 jqj Exp $ */
2:
3: /* contains:
4: * CH_LookupAddr
5: * CH_GetFirstCH
6: * CH_GetOtherCH
7: * CH_NameDefault
8: */
9:
10: /* $Log: CHlookup.c,v $
11: * Revision 2.0 85/11/21 07:22:32 jqj
12: * 4.3BSD standard release
13: *
14: * Revision 1.3 85/11/21 07:14:19 jqj
15: * 4.3BSD standard release
16: *
17: * Revision 1.2 85/10/21 12:41:55 jqj
18: * Gould version: work around a Gould compiler bug. Default to /usr/new
19: * for consistency.
20: *
21: * Revision 1.1 85/10/18 09:14:53 jqj
22: * Initial revision
23: *
24: * Revision 1.1 85/03/26 06:27:00 jqj
25: * Initial revision
26: *
27: */
28: #include <stdio.h>
29: #include <sys/types.h>
30: #include <netns/ns.h>
31: #include <xnscourier/Clearinghouse2.h>
32: #include <xnscourier/CHEntries.h>
33: #include <xnscourier/except.h>
34: #define MAXPACKS 5
35: #define NLSIZE 50
36:
37: static Clearinghouse2_ObjectName *namelist[NLSIZE];
38: static int nlcount = 0;
39:
40: static Cardinal nullpasswd = 0;
41: static Clearinghouse2_Authenticator nullagent = {{0,{0,0}},{1,&nullpasswd}};
42:
43: static
44: GetData(conn)
45: CourierConnection *conn;
46: {
47: int count, i;
48: Unspecified buffer[MAXWORDS*MAXPACKS], *bp, *bufend;
49: Clearinghouse2_StreamOfObjectName obnames;
50:
51: bufend = buffer;
52: bp = buffer+((MAXWORDS-1)*MAXPACKS); /* end of available space */
53: while (count = BDTread(conn, (char*)bufend,
54: MAXWORDS*sizeof(Unspecified))
55: ) {
56: bufend += count/sizeof(Unspecified);
57: if (bufend > bp) {
58: fprintf(stderr,"BDT read too big to fit\n");
59: BDTabort(conn);
60: /* should clear out stuff here if we knew how much */
61: }
62: }
63: bp = buffer;
64: while (bp < bufend) {
65: bp += internalize_Clearinghouse2_StreamOfObjectName(&obnames,bp);
66: if (0 == (int) obnames.designator) {
67: for (i = 0; i < obnames.nextSegment_case.segment.length; i++)
68: if (nlcount < NLSIZE) namelist[nlcount++] =
69: &obnames.nextSegment_case.segment.sequence[i];
70: } else {
71: for (i = 0; i < obnames.lastSegment_case.length; i++)
72: if (nlcount < NLSIZE) namelist[nlcount++] =
73: &obnames.lastSegment_case.sequence[i];
74: return;
75: }
76: }
77: }
78:
79: static struct ns_addr*
80: itemtonsaddr(itemptr)
81: Clearinghouse2_Item *itemptr; /* i.e. a sequence of Unspecified */
82: {
83: static union {
84: struct ns_addr addr;
85: u_short shrt[6];
86: } result;
87: register int i;
88: register Unspecified *seq;
89:
90: if (itemptr->length < 7)
91: return(0);
92:
93: seq = itemptr->sequence +1;
94: /* itemptr->sequence[0] == number of addresses */
95: for (i = 0; i < 6; i++, seq++)
96: result.shrt[i] = ntohs(*seq);
97: return(&result.addr);
98: }
99:
100: /*
101: * path to look for the addresses file on
102: * (I wish I'd picked a shorter name, so we could rendezvous in /etc.
103: * But long file names in /etc are very unpopular!).
104: */
105: static char *chaddrpath[] = {
106: #ifdef CHADDRS
107: CHADDRS,
108: #endif
109: "/usr/new/lib/xnscourier/clearinghouse.addresses",
110: "/etc/clearinghouse.addresses",
111: "/usr/local/lib/xnscourier/clearinghouse.addresses",
112: 0 };
113:
114:
115: /*
116: * Set defaults for organization and domain, based on the file
117: * /usr/local/lib/xnscourier/clearinghouse.addresses
118: * (should get the local clearinghouse and set defaults based on
119: * ListDomainsServed
120: */
121: CH_NameDefault(defaultobjnamep)
122: Clearinghouse2_ObjectName *defaultobjnamep;
123: {
124: FILE *chfile;
125: int i, nmatch;
126: static char orgbuf[21], domainbuf[21];
127:
128: defaultobjnamep->object = "";
129: for (i=0; chaddrpath[i] != NULL; i++) {
130: chfile = fopen(chaddrpath[i],"r");
131: if (chfile != (FILE*)0) {
132: nmatch = fscanf(chfile,"%*[^ \t\n] \":%[^:]:%[^\"]",
133: domainbuf, orgbuf);
134: fclose(chfile);
135: if (nmatch == 2) {
136: defaultobjnamep->domain = domainbuf;
137: defaultobjnamep->organization = orgbuf;
138: return; /* done */
139: }
140: }
141: }
142: defaultobjnamep->organization = "";
143: defaultobjnamep->domain = "";
144: }
145:
146:
147: CourierConnection*
148: CH_GetFirstCH()
149: {
150: struct ns_addr *chaddr;
151: extern struct ns_addr *getXNSaddr();
152: char buf[BUFSIZ];
153: CourierConnection *result;
154: FILE *chfile;
155: int i;
156:
157: /* for now, use hard-coded CH */
158: /* eventually we'll do an expanding-ring or something */
159: result = (CourierConnection *) NULL;
160: for (i = 0; chaddrpath[i] != NULL; i++) {
161: if ((chfile = fopen(chaddrpath[i],"r")) != NULL) {
162: while (fgets(buf, BUFSIZ, chfile))
163: if ((chaddr = getXNSaddr(buf)) &&
164: (result = CourierOpen(chaddr))) {
165: fclose(chfile);
166: return(result);
167: }
168: fclose(chfile);
169: break; /* don't look for other files */
170: }
171: }
172: /* try expanding-ring here */
173: return(result);
174: }
175:
176: CourierConnection *
177: CH_GetOtherCH(conn,hint)
178: CourierConnection *conn;
179: Clearinghouse2_ObjectName hint;
180: {
181: struct ns_addr *ch2addr;
182: CourierConnection *ch2conn;
183: Clearinghouse2_RetrieveItemResults riresult;
184: Clearinghouse2_RetrieveMembersResults rmresult;
185: int i;
186:
187: Clearinghouse2_Property clearinghouseNames = 3;
188: Clearinghouse2_Property clearinghouseAddresses = 4;
189: Clearinghouse2_ObjectName hint1;
190:
191: DURING
192: /* get list of possible other clearinghouses */
193: rmresult = Clearinghouse2_RetrieveMembers(conn, GetData, hint,
194: clearinghouseNames, BulkData1_immediateSink,
195: nullagent);
196: HANDLER {
197: /* some race condition */
198: return(NULL);
199: } END_HANDLER;
200: /* throw away the distinguished name, which we don't need */
201: clear_Clearinghouse2_RetrieveMembersResults(&rmresult);
202: /* for each member of potentials list, probe it */
203: ch2conn = NULL;
204: for (i = 0; i < nlcount; i++) {
205: Clearinghouse2_ObjectName thisname;
206: thisname = *namelist[i];
207: /* get its address */
208: DURING
209: riresult = Clearinghouse2_RetrieveItem(conn, NULL,
210: thisname,
211: clearinghouseAddresses, nullagent);
212: HANDLER
213: continue; /* try next in namelist */
214: END_HANDLER;
215: ch2addr = itemtonsaddr(&riresult.value);
216: clear_Clearinghouse2_RetrieveItemResults(&riresult);
217: ch2conn = CourierOpen(ch2addr);
218: if (ch2conn == NULL) continue;
219: /* make sure the second CH is really there */
220: DURING
221: (void) Clearinghouse2_RetrieveAddresses(ch2conn, NULL);
222: HANDLER {
223: CourierClose(ch2conn);
224: ch2conn = NULL;
225: continue;
226: } END_HANDLER;
227: /* we got it! */
228: break;
229: }
230: for (i = 0; i < nlcount; i++) {
231: /* free namelist[i] components */
232: clear_Clearinghouse2_ObjectName(namelist[i]);
233: /* free the top level thing too */
234: Deallocate((Unspecified*) namelist[i]);
235: }
236: return(ch2conn);
237: }
238:
239: /*
240: * Given a Clearinghouse three part name (possibly containing wild cards)
241: * and the property number on which a NetworkAddress is expected to occur,
242: * returns the ns_addr structure associated with that name.
243: * Note that the ns_addr structure is statically allocated!
244: * Resets pattern to be the distinguished name of the object found.
245: */
246: struct ns_addr *
247: CH_LookupAddr(pattern,property)
248: Clearinghouse2_ObjectNamePattern pattern;
249: Clearinghouse2_Property property;
250: {
251: struct ns_addr* CH_LookupAddrDN();
252: return(CH_LookupAddrDN(pattern,property,0,0));
253: }
254:
255: /*
256: * Lookup a clearinghouse address, returning the address and the
257: * distinguished name of the object found.
258: */
259: struct ns_addr *
260: CH_LookupAddrDN(pattern,property,distnamep,distnamelen)
261: Clearinghouse2_ObjectNamePattern pattern;
262: Clearinghouse2_Property property;
263: char *distnamep;
264: int distnamelen;
265: {
266: struct ns_addr *chaddr, *resultaddr;
267: CourierConnection *conn, *ch2conn;
268: Clearinghouse2_ObjectName hint; /* from WrongServer errors */
269: Clearinghouse2_RetrieveItemResults riresult;
270:
271:
272: if ((long) property <= 0) /* default to addressList i.e. 4 */
273: property = CHEntries0_addressList;
274: if (pattern.object == NULL ||
275: pattern.domain == NULL ||
276: pattern.organization == NULL)
277: return(NULL); /* can't handle defaults */
278:
279: if ((conn = CH_GetFirstCH()) == NULL) {
280: fprintf(stderr,"Can't open connection to local Clearinghouse\n");
281: exit(1);
282: }
283: /* ask our primary clearinghouse for the address of this thing */
284: DURING {
285: riresult = Clearinghouse2_RetrieveItem(conn, NULL,
286: pattern, property, nullagent);
287: } HANDLER {
288: if (Exception.Code != Clearinghouse2_WrongServer) {
289: CourierClose(conn);
290: return(0); /* some random error */
291: }
292: hint = CourierErrArgs(Clearinghouse2_WrongServerArgs, hint);
293: ch2conn = CH_GetOtherCH(conn, hint);
294: CourierClose(conn);
295: if (ch2conn == NULL) return(0);
296: conn = ch2conn;
297: /* probe the second clearinghouse */
298: DURING
299: riresult = Clearinghouse2_RetrieveItem(conn, NULL,
300: pattern, property, nullagent);
301: HANDLER {
302: /* should be smarter if WrongServer here */
303: CourierClose(conn);
304: return(0);
305: } END_HANDLER;
306: /* we got it */
307: } END_HANDLER;
308: resultaddr = itemtonsaddr(&riresult.value);
309: if (distnamep != NULL &&
310: distnamelen >= (2+strlen(riresult.distinguishedObject.object)+
311: strlen(riresult.distinguishedObject.domain)+
312: strlen(riresult.distinguishedObject.organization)))
313: sprintf(distnamep,"%s:%s:%s",
314: riresult.distinguishedObject.object,
315: riresult.distinguishedObject.domain,
316: riresult.distinguishedObject.organization);
317: clear_Clearinghouse2_RetrieveItemResults(&riresult);
318: CourierClose(conn);
319: return(resultaddr);
320: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.