|
|
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.