|
|
1.1 root 1: /* aetdase.c - DASE-based DSE */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/acsap/RCS/aetdase.c,v 7.1 90/07/09 14:30:48 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/acsap/RCS/aetdase.c,v 7.1 90/07/09 14:30:48 mrose Exp $
9: *
10: *
11: * $Log: aetdase.c,v $
12: * Revision 7.1 90/07/09 14:30:48 mrose
13: * sync
14: *
15: * Revision 7.0 90/07/07 16:11:32 mrose
16: * *** empty log message ***
17: *
18: */
19:
20: /*
21: * NOTICE
22: *
23: * Acquisition, use, and distribution of this module and related
24: * materials are subject to the restrictions of a license agreement.
25: * Consult the Preface in the User's Manual for the full terms of
26: * this agreement.
27: *
28: */
29:
30:
31: /* LINTLIBRARY */
32:
33: #include <ctype.h>
34: #include <setjmp.h>
35: #include <signal.h>
36: #include <stdio.h>
37: #include "DASE-types.h"
38: #include "psap.h"
39: #include "tsap.h"
40: #include "dgram.h"
41: #include "tailor.h"
42:
43:
44: /* DATA */
45:
46: static int stayopen = 0;
47:
48: static struct TSAPconnect tcs;
49: static PS ps = NULLPS;
50:
51:
52: static int armed = 0;
53: static int interrupted;
54: static jmp_buf intrenv;
55:
56: SFD intrser ();
57:
58:
59: struct element_DASE_1 *read_el ();
60:
61: /* LOOKUP */
62:
63: /* ARGSUSED */
64:
65: PE name2value_dase (name, qualifier, context, ontty, real_name)
66: char *name,
67: *qualifier,
68: *context;
69: int ontty;
70: PE *real_name;
71: {
72: int done,
73: err,
74: nfds,
75: vecp;
76: fd_set ifds;
77: char *vec[NVEC + 1];
78: PE pe = NULLPE,
79: result = NULLPE;
80: SFP istat;
81: register struct type_DASE_Query__REQ *parm = NULL;
82:
83: *real_name = NULLPE;
84:
85: if (ontty) {
86: istat = signal (SIGINT, intrser);
87: interrupted = 0;
88: }
89:
90: if (ps == NULLPS && dase_init () == NOTOK) {
91: if (ontty)
92: (void) signal (SIGINT, istat);
93:
94: return NULLPE;
95: }
96: err = 0;
97:
98: if ((vecp = sstr2arg (name, NVEC, vec, ",")) == NOTOK) {
99: PY_advise (NULLCP, "invalid name");
100: goto out;
101: }
102:
103: if ((parm = (struct type_DASE_Query__REQ *) calloc (1, sizeof *parm))
104: == NULL) {
105: no_mem: ;
106: PY_advise (NULLCP, "name2value_dase: out of memory");
107: goto out;
108: }
109: {
110: register char **vp;
111: register struct element_DASE_0 *dl,
112: **dp;
113:
114: dp = &parm -> name;
115: for (vp = vec; vecp > 0; vp++, vecp--) {
116: if ((dl = (struct element_DASE_0 *) calloc (1, sizeof *dl))
117: == NULL)
118: goto no_mem;
119: *dp = dl;
120: dp = &dl -> next;
121:
122: if ((dl -> IA5String = str2qb (*vp, strlen (*vp), 1)) == NULL)
123: goto no_mem;
124: }
125: }
126: parm -> interactive = ontty ? 1 : 0;
127: if ((parm -> envlist = read_el ()) == NULL
128: || (parm -> context = str2qb (context, strlen (context), 1))
129: == NULL)
130: goto out;
131:
132: if (encode_DASE_Query__REQ (&pe, 1, NULL, NULLCP, parm) == NOTOK)
133: goto out;
134:
135: if ((err = pe2ps (ps, pe)) == NOTOK) {
136: PY_advise (NULLCP, "unable to write query [%s]",
137: ps_error (ps -> ps_errno));
138: goto out;
139: }
140: PLOGP (addr_log,DASE_Message, pe, "message", 0);
141:
142: FD_ZERO (&ifds);
143:
144: nfds = tcs.tc_sd + 1;
145: FD_SET (tcs.tc_sd, &ifds);
146:
147: for (done = 0; !done; ) {
148: fd_set rfds;
149: struct type_DASE_Provider__RSP *rsp = NULL;
150: PE in;
151:
152: if (!interrupted) {
153: rfds = ifds; /* struct copy */
154:
155: (void) xselect (nfds, &rfds, NULLFD, NULLFD, NOTOK);
156: }
157:
158: if (interrupted) {
159: PY_advise (NULLCP, "interrupted");
160: break;
161: }
162:
163: if (!FD_ISSET (tcs.tc_sd, &rfds))
164: continue;
165:
166: if ((in = ps2pe (ps)) == NULLPE) {
167: PY_advise (NULLCP, "unable to read response [%s]",
168: ps_error (ps -> ps_errno));
169: err++;
170: break;
171: }
172:
173: if (decode_DASE_Provider__RSP (in, 1, NULLIP, NULLVP, &rsp) == NOTOK) {
174: you_lose: ;
175: pe_free (in);
176: if (rsp)
177: free_DASE_Provider__RSP (rsp);
178: err++;
179: break;
180: }
181: PLOGP (addr_log,DASE_Message, in, "message", 1);
182:
183: switch (rsp -> offset) {
184: case type_DASE_Provider__RSP_callback:
185: if (!ontty) {
186: PY_advise (NULLCP, "unexpected callback from nameservice");
187: goto you_lose;
188: }
189: if (dase_callback (rsp -> un.callback) == NOTOK)
190: goto you_lose;
191: break;
192:
193: case type_DASE_Provider__RSP_answer:
194: {
195: register char *pp,
196: *ep;
197: register struct qbuf *p,
198: *q;
199: register struct type_DASE_Query__RSP *ans
200: = rsp -> un.answer;
201:
202: if ((q = ans -> friendly) && ontty) {
203: printf ("[ using ");
204: print_qb (q);
205: printf (" ]\n");
206: (void) fflush (stdout);
207: }
208: *real_name = ans -> name, ans -> name = NULLPE;
209: result = ans -> value, ans -> value = NULLPE;
210: ep = (pp = PY_pepy) + BUFSIZ - 1;
211: if (q = ans -> diagnostic)
212: for (p = q -> qb_forw;
213: p != q && pp < ep;
214: pp += p -> qb_len, p = p -> qb_forw)
215: bcopy (p -> qb_data, pp, p -> qb_len);
216: *pp = NULL;
217:
218: done = 1;
219: }
220: break;
221:
222: default:
223: PY_advise (NULLCP, "unexpected response from nameservice: %d",
224: rsp -> offset);
225: goto you_lose;
226: }
227:
228: pe_free (in);
229: free_DASE_Provider__RSP (rsp);
230: }
231:
232: out: ;
233: if (result == NULLPE)
234: SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("%s", PY_pepy));
235: if (parm)
236: free_DASE_Query__REQ (parm);
237: if (pe)
238: pe_free (pe);
239: if (ps && (err || !stayopen)) {
240: struct TSAPdisconnect tds;
241:
242: (void) TDiscRequest (tcs.tc_sd, NULLCP, 0, &tds);
243: ps_free (ps);
244: ps = NULLPS;
245: }
246:
247: if (ontty)
248: (void) signal (SIGINT, istat);
249:
250: return result;
251: }
252:
253: /* */
254:
255: static int dase_init () {
256: int i,
257: nfds;
258: fd_set ifds;
259: register struct TSAPaddr *tz;
260: register struct TSAPconnect *tc = &tcs;
261: struct TSAPdisconnect tds;
262: register struct TSAPdisconnect *td = &tds;
263:
264: if ((tz = str2taddr (ns_address)) == NULL) {
265: PY_advise (NULLCP, "unable to parse nameservice address \"%s\"",
266: ns_address);
267: out: ;
268: SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("%s", PY_pepy));
269: return NOTOK;
270: }
271:
272: if ((i = TAsynConnRequest (NULLTA, tz, 0, NULLCP, 0, NULLQOS, tc, td, 1))
273: == NOTOK) {
274: you_lose: ;
275: PY_advise (NULLCP, td -> td_cc > 0
276: ? "unable to connect to nameservice: [%s] %*.*s"
277: : "unable to connect to nameservice: [%s]",
278: TErrString (td -> td_reason),
279: td -> td_cc, td -> td_cc, td -> td_data);
280: goto out;
281: }
282:
283: FD_ZERO (&ifds);
284:
285: nfds = tc -> tc_sd + 1;
286: FD_SET (tc -> tc_sd, &ifds);
287:
288: while (i == CONNECTING_1 || i == CONNECTING_2) {
289: fd_set mask,
290: *rmask,
291: *wmask;
292:
293: if (!interrupted) {
294: mask = ifds; /* struct copy */
295: if (i == CONNECTING_2)
296: rmask = &mask, wmask = NULLFD;
297: else
298: rmask = NULLFD, wmask = &mask;
299:
300: (void) xselect (nfds, rmask, wmask, NULLFD, NOTOK);
301: }
302:
303: if (interrupted) {
304: PY_advise (NULLCP, "interrupted");
305: goto oops;
306: }
307:
308: if ((rmask && !FD_ISSET (tc -> tc_sd, rmask))
309: || (wmask && !FD_ISSET (tc -> tc_sd, wmask)))
310: continue;
311:
312: if ((i = TAsynRetryRequest (tc -> tc_sd, tc, td)) == NOTOK)
313: goto you_lose;
314: }
315:
316: if ((ps = ps_alloc (dg_open)) == NULLPS
317: || dg_setup (ps, tc -> tc_sd, MAXDGRAM, ts_read, ts_write)
318: == NOTOK) {
319: if (ps == NULLPS)
320: PY_advise (NULLCP, "ps_alloc: out of memory");
321: else {
322: PY_advise (NULLCP, "dg_setup: %s", ps_error (ps -> ps_errno));
323: ps_free (ps);
324: ps = NULL;
325: }
326:
327: oops: ;
328: (void) TDiscRequest (tcs.tc_sd, NULLCP, 0, td);
329: goto out;
330: }
331:
332: return OK;
333: }
334:
335: /* */
336:
337: static int dase_callback (arg)
338: register struct type_DASE_Callback__REQ *arg;
339: {
340: register int i,
341: j;
342: int result;
343: register struct element_DASE_3 *choice;
344: struct type_DASE_Callback__RSP *rsp = NULL;
345: register struct type_DASE_Callback__RSP **rp = &rsp;
346: PE pe = NULLPE;
347:
348: i = 0;
349: for (choice = arg -> choices; choice; choice = choice -> next)
350: i++;
351:
352: if (i > 10) {
353: printf ("%d imprecise matches for '", i);
354: print_qb (arg -> string);
355: printf ("', select fron them [y/n] ? ");
356: if (yesno () != OK)
357: goto send_rsp;
358: }
359: else {
360: printf ("Please select from the following %d match%s for '",
361: i, i != 1 ? "es" : "");
362: print_qb (arg -> string);
363: printf ("':\n");
364: }
365:
366: j = 1;
367: for (choice = arg -> choices; choice; choice = choice -> next) {
368: register struct type_DASE_Callback__RSP *yes;
369:
370: printf (" ");
371: print_qb (choice -> Pair -> friendly);
372: printf (" [y/n] ? ");
373:
374: switch (yesno ()) {
375: case DONE:
376: goto send_rsp;
377:
378: case NOTOK:
379: default:
380: break;
381:
382: case OK:
383: if ((yes = (struct type_DASE_Callback__RSP *)
384: calloc (1, sizeof *yes)) == NULL) {
385: PY_advise (NULLCP, "dase_callback: out of memory");
386: result = NOTOK;
387: goto out;
388: }
389: *rp = yes, rp = &yes -> next;
390:
391: yes -> IA5String = choice -> Pair -> complete;
392: choice -> Pair -> complete = NULL;
393: break;
394: }
395:
396: if ((j++ % 10) == 0 && choice -> next) {
397: printf ("Continue (%d more) [y/n] ? ", i - j + 1);
398: if (yesno () != OK)
399: break;
400: }
401: }
402:
403: send_rsp: ;
404: if ((result = encode_DASE_Callback__RSP (&pe, 1, NULL, NULLCP, rsp))
405: == NOTOK)
406: goto out;
407: if ((result = pe2ps (ps, pe)) == NOTOK)
408: PY_advise (NULLCP, "unable to write callback [%s]",
409: ps_error (ps -> ps_errno));
410: else {
411: PLOGP (addr_log,DASE_Message, pe, "message", 0);
412:
413: result = OK;
414: }
415:
416: out: ;
417: if (rsp)
418: free_DASE_Callback__RSP (rsp);
419: if (pe)
420: pe_free (pe);
421:
422: return result;
423: }
424:
425: /* */
426:
427: static int yesno () {
428: int x,
429: y,
430: result;
431: char buffer[BUFSIZ];
432:
433: if (interrupted) {
434: interrupted = 0;
435: return DONE;
436: }
437:
438: switch (setjmp (intrenv)) {
439: case OK:
440: armed++;
441: break;
442:
443: case NOTOK:
444: default:
445: printf ("\n");
446: armed = 0;
447: return DONE;
448: }
449:
450: again: ;
451: x = y = getc (stdin);
452: while (y != '\n' && y != EOF)
453: y = getc (stdin);
454:
455: switch (x) {
456: case 'y':
457: case '\n':
458: result = OK;
459: break;
460:
461: case 'n':
462: result = NOTOK;
463: break;
464:
465: case EOF:
466: result = DONE;
467: clearerr (stdin);
468: break;
469:
470: default:
471: printf ("Please type 'y' or 'n': ");
472: goto again;
473: }
474:
475: armed = 0;
476:
477: return result;
478: }
479:
480:
481: static print_qb (q)
482: struct qbuf *q;
483: {
484: register struct qbuf *p;
485:
486: for (p = q -> qb_forw; p != q; p = p -> qb_forw)
487: printf ("%*.*s", p -> qb_len, p -> qb_len, p -> qb_data);
488: }
489:
490: /* */
491:
492: static struct element_DASE_1 *read_el () {
493: register int i;
494: register char *bp,
495: *cp;
496: char buffer[BUFSIZ],
497: ufnrc[BUFSIZ];
498: FILE *fp;
499: struct element_DASE_1 *top;
500: register struct element_DASE_1 **etail;
501: register struct element_DASE_2 **dtail;
502:
503: if (bp = getenv ("UFNRC"))
504: (void) strcpy (ufnrc, bp);
505: else {
506: if ((bp = getenv ("HOME")) == NULL)
507: bp = ".";
508:
509: (void) sprintf (ufnrc, "%s/.ufnrc", bp);
510: }
511:
512: if ((fp = fopen (ufnrc, "r")) == NULL) {
513: (void) strcpy (ufnrc, isodefile ("ufnrc", 0));
514:
515: if ((fp = fopen (ufnrc, "r")) == NULL) {
516: PY_advise (ufnrc, "unable to read");
517: return NULL;
518: }
519: }
520:
521: top = NULL, etail = &top, dtail = NULL;
522:
523: for (i = 0; fgets (bp = buffer, sizeof buffer, fp); i++) {
524: register struct element_DASE_2 *dl;
525:
526: if (*buffer == '#')
527: continue;
528: if (bp = index (buffer, '\n'))
529: *bp = NULL;
530:
531: bp = buffer;
532: if (*bp == NULL) {
533: dtail = NULL;
534: continue;
535: }
536:
537: if (!isspace (*bp)) {
538: register char *dp;
539: register struct element_DASE_1 *el;
540: register struct type_DASE_Environment *fl;
541:
542: if ((el = (struct element_DASE_1 *) calloc (1, sizeof *el))
543: == NULL) {
544: no_mem: ;
545: PY_advise (NULLCP, "real_el: out of memory");
546:
547: out: ;
548: for (; top; top = el) {
549: el = top -> next;
550:
551: free_DASE_Environment (top -> Environment);
552: free ((char *) top);
553: }
554: SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("%s", PY_pepy));
555: (void) fclose (fp);
556: return NULL;
557: }
558: *etail = el;
559: etail = &el -> next;
560:
561: if ((fl = (struct type_DASE_Environment *) calloc (1, sizeof *fl))
562: == NULL)
563: goto no_mem;
564: el -> Environment = fl;
565: dtail = &fl -> path;
566:
567: if ((cp = index (bp, ':')) == NULL) {
568: PY_advise (NULLCP, "%s: missing ':' at line %d", ufnrc, i);
569: goto out;
570: }
571: *cp++ = NULL;
572:
573: if (dp = index (bp, ',')) {
574: *dp++ = NULL;
575:
576: while (isspace (*dp))
577: dp++;
578: fl -> upper = *dp == '+' ? 32767 : atoi (dp);
579: }
580: else
581: fl -> upper = 0;
582:
583: fl -> lower = atoi (bp);
584: if (fl -> upper == 0)
585: fl -> upper = fl -> lower;
586:
587: bp = cp;
588: }
589: else
590: if (!dtail) {
591: PY_advise (NULLCP, "%s: unexpected blank at start of line %d",
592: ufnrc, i);
593: goto out;
594: }
595:
596: if ((dl = (struct element_DASE_2 *) calloc (1, sizeof *dl)) == NULL)
597: goto no_mem;
598: *dtail = dl;
599: dtail = &dl -> next;
600:
601: while (isspace (*bp))
602: bp++;
603: if ((dl -> IA5String = str2qb (bp, strlen (bp), 1)) == NULL)
604: goto no_mem;
605: }
606:
607: (void) fclose (fp);
608:
609: return top;
610: }
611:
612: /* */
613:
614: /* ARGSUSED */
615:
616: static SFD intrser (sig)
617: int sig;
618: {
619: #ifndef BSDSIGS
620: (void) signal (SIGINT, intrser);
621: #endif
622:
623: if (armed)
624: longjmp (intrenv, NOTOK);
625:
626: interrupted++;
627: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.