|
|
1.1 root 1: /* isoc.c - "minimal" ISODE client for testing */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/support/RCS/isoc.c,v 7.1 89/12/07 21:19:51 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/support/RCS/isoc.c,v 7.1 89/12/07 21:19:51 mrose Exp $
9: *
10: *
11: * $Log: isoc.c,v $
12: * Revision 7.1 89/12/07 21:19:51 mrose
13: * stuff
14: *
15: * Revision 7.0 89/11/23 22:27:15 mrose
16: * Release 6.0
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: #include <stdio.h>
32: #include <varargs.h>
33: #include "rosap.h"
34: #include "rtsap.h"
35: #include "acsap.h"
36: #include "psap2.h"
37: #include "ssap.h"
38: #include "tsap.h"
39: #ifdef TCP
40: #include "internet.h"
41: #ifdef BSD42
42: #include <sys/ioctl.h>
43: #endif
44: #ifdef SVR3
45: #include <fcntl.h>
46: #endif
47: #endif
48: #include "isoservent.h"
49: #include "tailor.h"
50: #include <sys/stat.h>
51:
52: #undef TIMER
53: #undef TMS
54: #ifdef BSD42
55: #define TIMER
56: #endif
57: #ifdef SYS5
58: #define TIMER
59: #ifndef HPUX
60: #include <sys/times.h>
61: #define TMS
62: #endif
63: #endif
64:
65: #if !defined (TCP) || defined (FIONBIO) || defined (SVR3)
66: #define ASYNC
67: #endif
68:
69: /* DATA */
70:
71: #define ISN(req) \
72: (req & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY)) \
73: ? (long) ((getpid () % (SERIAL_MAX - SERIAL_MIN + 1)) + SERIAL_MIN) \
74: : SERIAL_NONE
75:
76: static enum { echo, sink, XXX } mode = XXX;
77:
78: static int testing_queued_writes = 0;
79:
80: static char *isacs = NULL;
81: static int isrts = 0;
82:
83: static int status = 0;
84:
85: static char *myname = "isoc";
86:
87:
88: void adios (), advise ();
89: void ts_adios (), ts_advise ();
90: void ss_adios (), ss_advise ();
91: void ps_adios (), ps_advise ();
92: void acs_adios (), acs_advise ();
93: void rts_adios (), rts_advise ();
94: void ros_adios (), ros_advise ();
95:
96:
97: long lseek ();
98:
99: /* MAIN */
100:
101: #define chkacs() if (isacs) \
102: adios (NULLCP, "no association control for %s", \
103: argv[2])
104:
105: /* ARGSUSED */
106:
107: main (argc, argv, envp)
108: int argc;
109: char **argv,
110: **envp;
111: {
112: register struct isoservent *is;
113:
114: if (myname = rindex (argv[0], '/'))
115: myname++;
116: if (myname == NULL || *myname == NULL)
117: myname = argv[0];
118:
119: isodetailor (myname, 1);
120:
121: if (argc != 4)
122: adios (NULLCP, "usage: %s host provider entity", myname);
123:
124: #ifdef TCP
125: if (strcmp (argv[2], "raw") == 0) {
126: raw_main (argv[3], argv[1]);
127: exit (0);
128: }
129: #endif
130:
131: if (index (argv[3], '/')) {
132: mode = strcmp (isacs = argv[3], "isode/sink") ? echo : sink;
133: }
134: else {
135: if ((is = getisoserventbyname (argv[3], argv[2])) == NULL)
136: adios (NULLCP, "%s/%s: unknown provider/entity pair",
137: argv[2], argv[3]);
138:
139: mode = strcmp (is -> is_entity, "sink") ? echo : sink;
140: }
141:
142: if (strcmp (argv[2], "tsap") == 0) {
143: chkacs ();
144: ts_main (is, argv[1]);
145: }
146: else
147: if (strcmp (argv[2], "ssap") == 0) {
148: chkacs ();
149: ss_main (is, argv[1]);
150: }
151: else
152: if (strcmp (argv[2], "psap") == 0)
153: ps_main (is, argv[1]);
154: else
155: if (strcmp (argv[2], "rtsap") == 0) {
156: isrts = 1;
157: rts_main (is, argv[1]);
158: }
159: else
160: if (strcmp (argv[2], "rosap") == 0)
161: ros_main (is, argv[1]);
162: else
163: adios (NULLCP, "unknown provider: \"%s\"", argv[2]);
164:
165: exit (status); /* NOTREACHED */
166: }
167:
168: /* RAW */
169:
170: #ifdef TCP
171: static int raw_main (service, addr)
172: char *service,
173: *addr;
174: {
175: int sd,
176: cc,
177: i,
178: j;
179: char *cp,
180: *dp;
181: register struct hostent *hp;
182: register struct servent *sp;
183: struct sockaddr_in in_socket;
184: register struct sockaddr_in *isock = &in_socket;
185: struct stat st;
186:
187: if (strcmp (service, "sink"))
188: adios (NULLCP, "only sink on raw tcp is supported");
189: if ((sp = getservbyname (service, "tcp")) == NULL)
190: adios (NULLCP, "%s/%s: unknown service", "tcp", service);
191: if ((hp = gethostbystring (addr)) == NULL)
192: adios (NULLCP, "%s: unknown host", addr);
193:
194: bzero ((char *) isock, sizeof *isock);
195: isock -> sin_family = hp -> h_addrtype;
196: isock -> sin_port = sp -> s_port;
197: inaddr_copy (hp, isock);
198:
199: if ((sd = start_tcp_client ((struct sockaddr_in *) 0, 0)) == NOTOK)
200: adios ("socket", "unable to start");
201: fprintf (stderr, "%s... ", hp -> h_name);
202: (void) fflush (stderr);
203: if (join_tcp_server (sd, isock) == NOTOK) {
204: fprintf (stderr, "failed\n");
205: adios ("socket", "unable to connect");
206: }
207: fprintf (stderr, "connected\n");
208:
209: if (fstat (fileno (stdin), &st) == NOTOK
210: || (st.st_mode & S_IFMT) != S_IFREG
211: || (cc = st.st_size) == 0)
212: adios (NULLCP, "standard input not a regular file");
213: (void) lseek (fileno (stdin), 0L, 0);
214:
215: if ((cp = malloc ((unsigned) cc)) == NULL)
216: adios (NULLCP, "no memory");
217: for (dp = cp, j = cc; j > 0; dp += i, j -= i)
218: switch (i = read (fileno (stdin), dp, j)) {
219: case NOTOK:
220: adios ("on stdin", "read failed");
221:
222: case OK:
223: adios (NULLCP, "premature end-of-file");
224:
225: default:
226: break;
227: }
228:
229: #ifdef TIMER
230: timer (0);
231: #endif
232: if (write_tcp_socket (sd, cp, cc) != cc)
233: adios ("writing", "error");
234: (void) close_tcp_socket (sd);
235: #ifdef TIMER
236: timer (cc);
237: #endif
238: }
239: #endif
240:
241: /* TSAP */
242:
243: static int ts_main (is, addr)
244: struct isoservent *is;
245: char *addr;
246: {
247: int sd,
248: cc,
249: i,
250: j,
251: expedited,
252: expd;
253: char *cp,
254: *dp,
255: buffer[BUFSIZ];
256: struct TSAPaddr *ta;
257: struct TSAPconnect tcs;
258: register struct TSAPconnect *tc = &tcs;
259: struct TSAPdisconnect tds;
260: register struct TSAPdisconnect *td = &tds;
261: struct stat st;
262:
263: if ((ta = is2taddr (addr, NULLCP, is)) == NULL)
264: adios (NULLCP, "address translation failed");
265:
266: fprintf (stderr, "%s... ", addr);
267: (void) fflush (stderr);
268: #ifndef ASYNC
269: if (TConnRequest (NULLTA, ta, 1, NULLCP, 0, NULLQOS, tc, td) == NOTOK) {
270: fprintf (stderr, "failed\n");
271: ts_adios (td, "T-CONNECT.REQUEST");
272: }
273: sd = tc -> tc_sd;
274: #else
275: if ((i = TAsynConnRequest (NULLTA, ta, 1, NULLCP, 0, NULLQOS, tc, td, 1))
276: == NOTOK) {
277: fprintf (stderr, "failed\n");
278: ts_adios (td, "T-(ASYN-)CONNECT.REQUEST");
279: }
280: sd = tc -> tc_sd, cc = 0;
281: while (i == CONNECTING_1 || i == CONNECTING_2) {
282: int nfds;
283: fd_set mask,
284: *rmask,
285: *wmask;
286:
287: nfds = 0;
288: FD_ZERO (&mask);
289: if (TSelectMask (sd, &mask, &nfds, td) == NOTOK) {
290: fprintf (stderr, "failed\n");
291: ts_adios (td, "T-(ASYN-)CONNECT.REQUEST(TSelectMask)");
292: }
293: rmask = (i == CONNECTING_2) ? &mask : NULLFD;
294: wmask = (i == CONNECTING_2) ? NULLFD : &mask;
295:
296: fprintf (stderr, ".");
297: (void) fflush (stderr);
298: if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
299: fprintf (stderr, "failed\n");
300: adios ("failed", "select");
301: }
302:
303: if ((rmask && FD_ISSET (sd, rmask) == 0)
304: || (wmask && FD_ISSET (sd, wmask) == 0))
305: continue;
306:
307: if ((i = TAsynRetryRequest (sd, tc, td)) == NOTOK) {
308: fprintf (stderr, "failed\n");
309: ts_adios (td, "T-ASYN-RETRY.REQUEST");
310: }
311: }
312: #endif
313: fprintf (stderr, "connected\n");
314:
315:
316: if (getenv ("TEST_QUEUED_WRITES")) {
317: if (TSetQueuesOK (tc -> tc_sd, 1, td) == NOTOK)
318: ts_adios (td, "T-SET-QUEUES-OK");
319:
320: tsap_log -> ll_events |= LLOG_EXCEPTIONS;
321: tsap_log -> ll_file = "-";
322: (void) ll_close (tsap_log);
323:
324: testing_queued_writes = 1;
325: }
326:
327: expd = tc -> tc_expedited;
328: #ifdef DEBUG
329: {
330: advise (NULLCP, "responding TSAP address: %s",
331: taddr2str (&tc -> tc_responding));
332:
333: if (tc -> tc_cc > 0)
334: advise (NULLCP, "greetings: %d octets", tc -> tc_cc);
335: }
336: #endif
337:
338: if (fstat (fileno (stdin), &st) != NOTOK
339: && (st.st_mode & S_IFMT) == S_IFREG
340: && (cc = st.st_size) != 0) {
341: (void) lseek (fileno (stdin), 0L, 0);
342:
343: if ((cp = malloc ((unsigned) cc)) == NULL)
344: adios (NULLCP, "no memory");
345: for (dp = cp, j = cc; j > 0; dp += i, j -= i)
346: switch (i = read (fileno (stdin), dp, j)) {
347: case NOTOK:
348: adios ("on stdin", "read failed");
349:
350: case OK:
351: adios (NULLCP, "premature end-of-file");
352:
353: default:
354: break;
355: }
356: for (i = 10; i > 0; i--) {
357: #ifdef TIMER
358: timer (0);
359: #endif
360: ts_datarequest (sd, cp, cc, 0);
361: #ifdef TIMER
362: timer (cc);
363: #endif
364: }
365: free (cp);
366: }
367: else
368: for (expedited = 0;
369: fgets (buffer, sizeof buffer, stdin);
370: expedited = !expedited) {
371: if ((cc = strlen (buffer) + 1) > TX_SIZE && expedited)
372: expedited = 0;
373:
374: ts_datarequest (sd, buffer, cc, expd ? expedited : 0);
375: }
376:
377: if (TDiscRequest (sd, NULLCP, 0, td) == NOTOK)
378: ts_adios (td, "T-DISCONNECT.REQUEST");
379: }
380:
381: /* */
382:
383: static int ts_datarequest (sd, data, cc, expedited)
384: int sd;
385: char *data;
386: int cc,
387: expedited;
388: {
389: struct TSAPdata txs;
390: register struct TSAPdata *tx = &txs;
391: struct TSAPdisconnect tds;
392: register struct TSAPdisconnect *td = &tds;
393:
394: if ((expedited ? TExpdRequest (sd, data, cc, td)
395: : TDataRequest (sd, data, cc, td)) == NOTOK)
396: if (expedited)
397: ts_adios (td, "T-EXPEDITED-DATA.REQUEST");
398: else
399: ts_adios (td, "T-DATA.REQUEST");
400:
401: if (mode == echo) {
402: if (testing_queued_writes) {
403: int vecp;
404: char *vec[4];
405: fd_set rfds;
406:
407: FD_ZERO (&rfds);
408: FD_SET (sd, &rfds);
409: if (TNetAccept (&vecp, vec, sd + 1, &rfds, NULLFD, NULLFD, NOTOK,
410: td) == NOTOK)
411: ts_adios (td, "T-NET-ACCEPT");
412: }
413:
414: if (TReadRequest (sd, tx, NOTOK, td) == NOTOK)
415: ts_adios (td, "T-READ.REQUEST");
416: if (cc != tx -> tx_cc) {
417: advise (NULLCP, "length mismatch, orig=%d echo=%d",
418: cc, tx -> tx_cc);
419: status++;
420: }
421: else
422: if (qcmp (data, &tx -> tx_qbuf, cc))
423: status++;
424: TXFREE (tx)
425: }
426: }
427:
428: /* */
429:
430: static void ts_adios (td, event)
431: register struct TSAPdisconnect *td;
432: char *event;
433: {
434: ts_advise (td, event);
435:
436: _exit (1);
437: }
438:
439:
440: static void ts_advise (td, event)
441: register struct TSAPdisconnect *td;
442: char *event;
443: {
444: char data[BUFSIZ];
445:
446: if (td -> td_cc > 0) {
447: (void) sprintf (data, "[%s] %*.*s",
448: TErrString (td -> td_reason),
449: td -> td_cc, td -> td_cc, td -> td_data);
450: }
451: else
452: (void) sprintf (data, "[%s]", TErrString (td -> td_reason));
453:
454: advise (NULLCP, "%s: %s", event, data);
455: }
456:
457: /* SSAP */
458:
459: static int requirements = SR_HALFDUPLEX | SR_DUPLEX | SR_EXPEDITED
460: | SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY
461: | SR_NEGOTIATED | SR_CAPABILITY | SR_EXCEPTIONS | SR_TYPEDATA;
462:
463: static int owned = 0;
464: static int avail = 0;
465:
466: static long ssn;
467:
468: static int nmodes;
469: static int datamodes[4];
470:
471: static char userdata[1024];
472:
473: /* */
474:
475: static int ss_main (is, addr)
476: struct isoservent *is;
477: char *addr;
478: {
479: int sd,
480: cc,
481: i,
482: j,
483: k,
484: l,
485: tokens;
486: char *cp,
487: *dp,
488: buffer[BUFSIZ];
489: struct SSAPactid ids;
490: register struct SSAPactid *id = &ids;
491: register struct SSAPaddr *sz;
492: struct SSAPref sfs;
493: register struct SSAPref *sf;
494: struct SSAPconnect scs;
495: register struct SSAPconnect *sc = &scs;
496: struct SSAPrelease srs;
497: register struct SSAPrelease *sr = &srs;
498: struct SSAPindication sis;
499: register struct SSAPindication *si = &sis;
500: register struct SSAPabort *sa = &si -> si_abort;
501: struct stat st;
502:
503: bzero (userdata, sizeof userdata);
504:
505: if ((sz = is2saddr (addr, NULLCP, is)) == NULL)
506: adios (NULLCP, "address translation failed");
507: if ((sf = addr2ref (SLocalHostName ())) == NULL) {
508: sf = &sfs;
509: (void) bzero ((char *) sf, sizeof *sf);
510: }
511:
512: tokens = 0;
513: #define dotoken(requires,shift,bit,type) \
514: { \
515: if (requirements & requires) \
516: tokens |= ST_CALL_VALUE << shift; \
517: }
518: dotokens ();
519: #undef dotoken
520:
521: fprintf (stderr, "%s... ", addr);
522: (void) fflush (stderr);
523: #ifndef ASYNC
524: if (SConnRequest (sf, NULLSA, sz, requirements, tokens, ISN (requirements),
525: userdata, sizeof userdata /*SS_SIZE*/, NULLQOS, sc, si) == NOTOK) {
526: fprintf (stderr, "failed\n");
527: ss_adios (sa, "S-CONNECT.REQUEST");
528: }
529: sd = sc -> sc_sd;
530: #else
531: if ((i = SAsynConnRequest (sf, NULLSA, sz, requirements, tokens,
532: ISN (requirements), userdata, sizeof userdata /*SS_SIZE*/, NULLQOS,
533: sc, si, 1))
534: == NOTOK) {
535: fprintf (stderr, "failed\n");
536: ss_adios (sa, "S-(ASYN-)CONNECT.REQUEST");
537: }
538: sd = sc -> sc_sd, cc = 0;
539: while (i == CONNECTING_1 || i == CONNECTING_2) {
540: int nfds;
541: fd_set mask,
542: *rmask,
543: *wmask;
544:
545: nfds = 0;
546: FD_ZERO (&mask);
547: if (SSelectMask (sd, &mask, &nfds, si) == NOTOK) {
548: fprintf (stderr, "failed\n");
549: ss_adios (sa, "S-(ASYN-)CONNECT.REQUEST(SSelectMask)");
550: }
551: rmask = (i == CONNECTING_2) ? &mask : NULLFD;
552: wmask = (i == CONNECTING_2) ? NULLFD : &mask;
553:
554: fprintf (stderr, ".");
555: if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
556: fprintf (stderr, "failed\n");
557: adios ("failed", "select");
558: }
559:
560: if ((rmask && FD_ISSET (sd, rmask) == 0)
561: || (wmask && FD_ISSET (sd, wmask) == 0))
562: continue;
563:
564: if ((i = SAsynRetryRequest (sd, sc, si)) == NOTOK) {
565: fprintf (stderr, "failed\n");
566: ss_adios (sa, "S-ASYN-RETRY.REQUEST");
567: }
568: }
569: #endif
570:
571: if (sc -> sc_result != SC_ACCEPT) {
572: fprintf (stderr, "failed\n");
573: if (sc -> sc_cc > 0)
574: adios (NULLCP, "connection rejected: [%s] %*.*s",
575: SErrString (sc -> sc_result),
576: sc -> sc_cc, sc -> sc_cc, sc -> sc_data);
577: else
578: adios (NULLCP, "connection rejected: [%s]",
579: SErrString (sc -> sc_result));
580: }
581: fprintf (stderr, "connected\n");
582:
583: #ifdef DEBUG
584: {
585: advise (NULLCP, "responding SSAP address: %s",
586: saddr2str (&sc -> sc_responding));
587:
588: if (sc -> sc_cc > 0)
589: advise (NULLCP, "greetings: %d octets", sc -> sc_cc);
590: }
591: #endif
592: requirements = sc -> sc_requirements;
593: nmodes = 0;
594: datamodes[nmodes++] = SX_NORMAL;
595: if (requirements & SR_EXPEDITED)
596: datamodes[nmodes++] = SX_EXPEDITED;
597: if ((requirements & SR_CAPABILITY) && (requirements & SR_ACTIVITY))
598: datamodes[nmodes++] = SX_CAPDIND;
599: if (requirements & SR_TYPEDATA)
600: datamodes[nmodes++] = SX_TYPED;
601:
602: #define dotoken(requires,shift,bit,type) \
603: { \
604: if (requirements & requires) \
605: switch (sc -> sc_settings & (ST_MASK << shift)) { \
606: case ST_CALL_VALUE: \
607: adios (NULLCP, "%s token: choice", type); \
608: \
609: case ST_INIT_VALUE: \
610: owned |= bit, avail |= bit; \
611: break; \
612: \
613: case ST_RESP_VALUE: \
614: avail |= bit; \
615: break; \
616: \
617: default: \
618: adios (NULLCP, "%s token: reserved", type); \
619: } \
620: }
621: dotokens ();
622: #undef dotoken
623:
624: if (requirements & SR_ACTIVITY) {
625: (void) strcpy (id -> sd_data, mode == echo ? "echo" : "sink");
626: id -> sd_len = strlen (id -> sd_data);
627: if (SActStartRequest (sd, id, userdata, SV_SIZE, si) == NOTOK)
628: ss_adios (sa, "S-ACTIVITY-START.REQUEST");
629: }
630:
631: if (fstat (fileno (stdin), &st) != NOTOK
632: && (st.st_mode & S_IFMT) == S_IFREG
633: && (cc = st.st_size) != 0) {
634: (void) lseek (fileno (stdin), 0L, 0);
635:
636: if ((cp = malloc ((unsigned) cc)) == NULL)
637: adios (NULLCP, "no memory");
638: for (dp = cp, j = cc; j > 0; dp += i, j -= i)
639: switch (i = read (fileno (stdin), dp, j)) {
640: case NOTOK:
641: adios ("on stdin", "read failed");
642:
643: case OK:
644: adios (NULLCP, "premature end-of-file");
645:
646: default:
647: break;
648: }
649: for (i = 10; i > 0; i--) {
650: #ifdef TIMER
651: timer (0);
652: #endif
653: ss_datarequest (sd, cp, cc, SX_NORMAL, 0);
654: #ifdef TIMER
655: timer (cc);
656: #endif
657: }
658: free (cp);
659: }
660: else {
661: for (j = l = 0; fgets (buffer, sizeof buffer, stdin); ) {
662: k = j >= nmodes ? SX_EXPEDITED : datamodes[j++ % nmodes];
663: if ((cc = strlen (buffer) + 1) > SX_EXSIZE && k == SX_EXPEDITED) {
664: if ((k = datamodes[j++ % nmodes]) == SX_EXPEDITED)
665: k = datamodes[j++ % nmodes];
666: }
667:
668: switch (k) {
669: case SX_CAPDIND:
670: if (!(requirements & SR_RESYNC) || l++ & 0x01) {
671: ss_waitfor (sd, ST_ACT_TOKEN);
672: if (l & 0x03) {
673: if (SActIntrRequest (sd, SP_SEQUENCE, si)
674: == NOTOK)
675: ss_adios (sa, "S-ACTIVITY-INTERRUPT.REQUEST");
676: }
677: else {
678: if (SActDiscRequest (sd, SP_SEQUENCE, si)
679: == NOTOK)
680: ss_adios (sa, "S-ACTIVITY-DISCARD.REQUEST");
681: }
682: ss_waitfor (sd, -1);
683: goto push_data;
684: }
685: if (!(requirements & SR_RESYNC))
686: break;
687: tokens = 0;
688: #define dotoken(requires,shift,bit,type) \
689: { \
690: if (requirements & requires) \
691: tokens |= ST_CALL_VALUE << shift; \
692: }
693: dotokens ();
694: #undef dotoken
695: if (SReSyncRequest (sd, SYNC_SET, ssn - 1, tokens,
696: userdata, SN_SIZE, si) == NOTOK)
697: ss_adios (sa, "S-RESYNCHRONIZE.REQUEST");
698: ss_waitfor (sd, -1);
699: break;
700:
701: case SX_EXPEDITED:
702: if (j >= nmodes)
703: j = j % nmodes;/* fall... */
704: if (!(requirements & SR_EXPEDITED))
705: k = SX_NORMAL; /* fall... */
706: default:
707: push_data: ;
708: ss_datarequest (sd, buffer, cc, k, 1);
709: if (k == SX_CAPDIND
710: && SActResumeRequest (sd, id, id,
711: (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1))
712: + SERIAL_MIN, sf, userdata, SV_SIZE, si)
713: == NOTOK)
714: ss_adios (sa, "S-ACTIVITY-RESUME.REQUEST");
715: break;
716: }
717: }
718:
719: if (requirements & SR_EXCEPTIONS) {
720: if (owned & ST_DAT_TOKEN)
721: if (SGTokenRequest (sd, ST_DAT_TOKEN, si) == NOTOK)
722: ss_adios (sa, "S-TOKEN-GIVE.REQUEST");
723: else
724: owned &= ~ST_DAT_TOKEN;
725: if (SUReportRequest (sd, SP_NOREASON, userdata, SP_SIZE, si)
726: == NOTOK)
727: ss_adios (sa, "S-U-EXCEPTION-REPORT.REQUEST");
728: ss_waitfor (sd, -1);
729: }
730: }
731:
732: if ((requirements & SR_MAJORSYNC) && !(requirements & SR_ACTIVITY)) {
733: if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si) == NOTOK)
734: switch (sa -> sa_reason) {
735: case SC_OPERATION:
736: ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
737: | ST_MAJ_TOKEN);
738: if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si)
739: == OK)
740: break; /* else fall */
741:
742: default:
743: ss_adios (sa, "S-MAJOR-SYNC.REQUEST");
744: }
745:
746: ss_waitfor (sd, -1);
747: }
748:
749: if (requirements & SR_ACTIVITY) {
750: if (SActEndRequest (sd, &ssn, userdata, SV_SIZE, si) == NOTOK)
751: switch (sa -> sa_reason) {
752: case SC_OPERATION:
753: ss_waitfor (sd, avail);
754: if (SActEndRequest (sd, &ssn, userdata, SV_SIZE, si) == OK)
755: break; /* else fall */
756:
757: default:
758: ss_adios (sa, "S-ACTIVITY-END.REQUEST");
759: }
760:
761: ss_waitfor (sd, -1);
762:
763: if (SGControlRequest (sd, si) == NOTOK)
764: switch (sa -> sa_reason) {
765: case SC_OPERATION:
766: ss_waitfor (sd, avail);
767: if (SGControlRequest (sd, si) == OK)
768: break; /* else fall */
769:
770: default:
771: ss_adios (sa, "S-CONTROL-GIVE.REQUEST");
772: }
773:
774: owned = 0;
775:
776: ss_waitfor (sd, -1);
777: }
778:
779: if (SRelRequest (sd, userdata, SF_SIZE, NOTOK, sr, si) == NOTOK)
780: switch (sa -> sa_reason) {
781: case SC_OPERATION:
782: case SC_WAITING:
783: ss_waitfor (sd, avail);
784: if (SRelRequest (sd, userdata, SF_SIZE, NOTOK, sr, si) == OK)
785: break; /* else fall */
786:
787: default:
788: ss_adios (sa, "S-RELEASE.REQUEST");
789: }
790:
791: if (!sr -> sr_affirmative) {
792: (void) SUAbortRequest (sd, NULLCP, 0, si);
793:
794: if (sr -> sr_cc > 0)
795: adios (NULLCP, "release rejected by peer: %*.*s",
796: sr -> sr_cc, sr -> sr_cc, sr -> sr_data);
797: else
798: adios (NULLCP, "release rejected by peer");
799: }
800: SRFREE (sr);
801: }
802:
803: /* */
804:
805: static int ss_datarequest (sd, data, cc, dm, sync)
806: int sd;
807: char *data;
808: int cc,
809: dm,
810: sync;
811: {
812: int result;
813: struct SSAPdata sxs;
814: register struct SSAPdata *sx = &sxs;
815: struct SSAPindication sis;
816: register struct SSAPindication *si = &sis;
817: register struct SSAPabort *sa = &si -> si_abort;
818:
819: switch (dm) {
820: default:
821: if (SDataRequest (sd, data, cc, si) == NOTOK)
822: switch (sa -> sa_reason) {
823: case SC_OPERATION:
824: ss_waitfor (sd, ST_DAT_TOKEN);
825: if (SDataRequest (sd, data, cc, si) == OK)
826: break;/* else fall */
827:
828: default:
829: ss_adios (sa, "S-DATA.REQUEST");
830: }
831: break;
832:
833: case SX_EXPEDITED:
834: if (SExpdRequest (sd, data, cc, si) == NOTOK)
835: ss_adios (sa, "S-EXPEDITED-DATA.REQUEST");
836: break;
837:
838: case SX_CAPDIND:
839: if (SCapdRequest (sd, data, cc, si) == NOTOK)
840: switch (sa -> sa_reason) {
841: case SC_OPERATION:
842: ss_waitfor (sd, avail & ~ST_RLS_TOKEN);
843: if (SCapdRequest (sd, data, cc, si) == OK)
844: break;/* else fall */
845:
846: default:
847: ss_adios (sa, "S-CAPABILITY-DATA.REQUEST");
848: }
849: break;
850:
851: case SX_TYPED:
852: if (STypedRequest (sd, data, cc, si) == NOTOK)
853: ss_adios (sa, "S-TYPED-DATA.REQUEST");
854: break;
855: }
856:
857: if (mode == echo || dm == SX_CAPDIND)
858: for (;;) {
859: switch (result = SReadRequest (sd, sx, NOTOK, si)) {
860: case NOTOK:
861: ss_adios (sa, "S-READ.REQUEST");
862:
863: case OK:
864: if ((dm != SX_CAPDIND ? dm : SX_CAPDCNF)
865: != sx -> sx_type) {
866: advise (NULLCP,
867: "data indication type mismatch, orig=%d echo=%d",
868: dm, sx -> sx_type);
869: status++;
870: }
871: if (cc != sx -> sx_cc) {
872: advise (NULLCP, "length mismatch, orig=%d echo=%d",
873: cc, sx -> sx_cc);
874: status++;
875: }
876: else
877: if (qcmp (data, &sx -> sx_qbuf, cc))
878: status++;
879: SXFREE (sx)
880: break;
881:
882: case DONE:
883: ss_event (sd, si);
884: continue;
885:
886: default:
887: adios (NULLCP, "unknown return from SReadRequest=%d",
888: result);
889: }
890: break;
891: }
892:
893: if (sync &&
894: (requirements & SR_MINORSYNC) && !(requirements & SR_ACTIVITY)) {
895: if (SMinSyncRequest (sd, SYNC_CONFIRM, &ssn, userdata, SN_SIZE, si)
896: == NOTOK)
897: switch (sa -> sa_reason) {
898: case SC_OPERATION:
899: ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN);
900: if (SMinSyncRequest (sd, SYNC_CONFIRM, &ssn, userdata,
901: SN_SIZE, si) == OK)
902: break; /* else fall */
903:
904: default:
905: ss_adios (sa, "S-MINOR-SYNC.REQUEST");
906: }
907:
908: ss_waitfor (sd, -1);
909: }
910: else
911: if (sync
912: && (requirements & SR_ACTIVITY)
913: && (requirements & SR_MAJORSYNC)
914: && dm == SX_NORMAL) {
915: if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si) == NOTOK)
916: switch (sa -> sa_reason) {
917: case SC_OPERATION:
918: ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
919: | ST_MAJ_TOKEN);
920: if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si)
921: == OK)
922: break;/* else fall */
923:
924: default:
925: ss_adios (sa, "S-MAJOR-SYNC.REQUEST");
926: }
927:
928: ss_waitfor (sd, -1);
929: }
930: }
931:
932: /* */
933:
934: static int ss_waitfor (sd, want)
935: int sd,
936: want;
937: {
938: int result,
939: tokens;
940: char buffer[BUFSIZ];
941: struct SSAPdata sxs;
942: register struct SSAPdata *sx = &sxs;
943: struct SSAPindication sis;
944: register struct SSAPindication *si = &sis;
945: register struct SSAPabort *sa = &si -> si_abort;
946:
947: for (;;) {
948: if (want == -1) {
949: want = avail;
950: goto read_it;
951: }
952:
953: tokens = 0;
954: #define dotoken(requires,shift,bit,type) \
955: { \
956: if ((want & bit) && !(owned & bit)) \
957: tokens |= bit; \
958: }
959: dotokens ();
960: #undef dotoken
961: if (tokens == 0)
962: return;
963:
964: if (SPTokenRequest (sd, tokens, userdata, ST_SIZE, si) == NOTOK)
965: ss_adios (sa, "S-TOKEN-PLEASE.REQUEST");
966:
967: read_it: ;
968: switch (result = SReadRequest (sd, sx, NOTOK, si)) {
969: case NOTOK:
970: ss_adios (sa, "S-READ.REQUEST");
971:
972: case OK:
973: (void) strcpy (buffer, "protocol screw-up");
974: if (SUAbortRequest (sd, buffer, strlen (buffer) + 1, si) == NOTOK)
975: ss_adios (sa, "S-U-ABORT.REQUEST");
976: adios (NULLCP, "%s, data indication type=0x%x",
977: buffer, sx -> sx_type);
978:
979: case DONE:
980: ss_event (sd, si);
981: break;
982:
983: default:
984: adios (NULLCP, "unknown return from SReadRequest=%d",
985: result);
986: }
987: }
988: }
989:
990: /* */
991:
992: static ss_event (sd, si)
993: int sd;
994: register struct SSAPindication *si;
995: {
996: register struct SSAPabort *sa = &si -> si_abort;
997: register struct SSAPactivity *sv = &si -> si_activity;
998: register struct SSAPfinish *sf = &si -> si_finish;
999: register struct SSAPreport *sp = &si -> si_report;
1000: register struct SSAPsync *sn = &si -> si_sync;
1001: register struct SSAPtoken *st = &si -> si_token;
1002:
1003: switch (si -> si_type) {
1004: case SI_TOKEN:
1005: switch (st -> st_type) {
1006: case ST_GIVE:
1007: case ST_CONTROL:
1008: owned = st -> st_owned;
1009: break;
1010:
1011: case ST_PLEASE:
1012: if (SGTokenRequest (sd,
1013: (int) st -> st_tokens, si)
1014: == NOTOK)
1015: ss_adios (sa, "S-TOKEN-GIVE.REQUEST");
1016: else
1017: owned &= ~st -> st_tokens;
1018: break;
1019:
1020: default:
1021: adios (NULLCP,
1022: "unknown token indication type=0x%x, %d bytes",
1023: st -> st_type, st -> st_cc);
1024: }
1025: STFREE (st);
1026: break;
1027:
1028: case SI_SYNC:
1029: switch (sn -> sn_type) {
1030: case SN_MAJORIND:
1031: adios (NULLCP, "majorsync indication %d, %d bytes",
1032: sn -> sn_ssn, sn -> sn_cc);
1033: break;
1034:
1035: case SN_MAJORCNF:
1036: break;
1037:
1038: case SN_MINORIND:
1039: adios (NULLCP, "minorsync indication %d%s, %d bytes",
1040: sn -> sn_ssn, sn -> sn_options == SYNC_CONFIRM
1041: ? " (wants confirmation)" : NULLCP, sn -> sn_cc);
1042: break;
1043:
1044: case SN_MINORCNF:
1045: break;
1046:
1047: case SN_RESETIND:
1048: #define dotoken(requires,shift,bit,type) \
1049: { \
1050: if (requirements & requires) \
1051: switch (sn -> sn_settings & (ST_MASK << shift)) { \
1052: case ST_CALL_VALUE << shift: \
1053: sn -> sn_settings &= ~(ST_MASK << shift); \
1054: sn -> sn_settings |= ST_RESP_VALUE << shift; \
1055: case ST_RESP_VALUE << shift: \
1056: owned &= ~bit; \
1057: break; \
1058: \
1059: case ST_INIT_VALUE << shift: \
1060: owned |= bit; \
1061: break; \
1062: \
1063: default: \
1064: adios (NULLCP, "%s token: reserved", type); \
1065: break; \
1066: } \
1067: }
1068: dotokens ();
1069: #undef dotoken
1070: if (SReSyncResponse (sd, sn -> sn_ssn, sn -> sn_settings,
1071: userdata, SN_SIZE, si) == NOTOK)
1072: ss_adios (sa, "S-RESYNCHRONIZE.RESPONSE");
1073: break;
1074:
1075: case SN_RESETCNF:
1076: break;
1077:
1078: default:
1079: adios (NULLCP,
1080: "unknown sync indication=0x%x, ssn=%d, %d bytes",
1081: sn -> sn_type, sn -> sn_ssn, sn -> sn_cc);
1082: }
1083: SNFREE (sn);
1084: break;
1085:
1086: case SI_ACTIVITY:
1087: switch (sv -> sv_type) {
1088: case SV_START:
1089: adios (NULLCP,
1090: "activity start indication: %*.*s, %d bytes",
1091: sv -> sv_id.sd_len, sv -> sv_id.sd_len,
1092: sv -> sv_id.sd_data, sv -> sv_cc);
1093:
1094: case SV_RESUME:
1095: adios (NULLCP,
1096: "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d, %d bytes",
1097: sv -> sv_id.sd_len, sv -> sv_id.sd_len,
1098: sv -> sv_id.sd_data, sv -> sv_oid.sd_len,
1099: sv -> sv_oid.sd_len, sv -> sv_oid.sd_data,
1100: sprintref (&sv -> sv_connect), sv -> sv_ssn,
1101: sv -> sv_cc);
1102:
1103: case SV_INTRIND:
1104: adios (NULLCP,
1105: "activity interrupt indication %d, %d bytes",
1106: sv -> sv_reason, sv -> sv_cc);
1107:
1108: case SV_INTRCNF:
1109: break;
1110:
1111: case SV_DISCIND:
1112: adios (NULLCP,
1113: "activity discard indication %d, %d bytes",
1114: sv -> sv_reason, sv -> sv_cc);
1115:
1116: case SV_DISCCNF:
1117: break;
1118:
1119: case SV_ENDIND:
1120: adios (NULLCP, "activity end indication %d, %d bytes",
1121: sv -> sv_ssn, sv -> sv_cc);
1122:
1123: case SV_ENDCNF:
1124: break;
1125:
1126: default:
1127: adios (NULLCP,
1128: "unknown activity indication=0x%x, %d bytes",
1129: sv -> sv_type, sv -> sv_cc);
1130: }
1131: SVFREE (sv);
1132: break;
1133:
1134: case SI_REPORT:
1135: if (requirements & SR_DAT_EXISTS) {
1136: if (SGTokenRequest (sd, ST_DAT_TOKEN, si) == NOTOK)
1137: ss_adios (sa, "S-TOKEN-GIVE.REQUEST (to clear exception)");
1138: else
1139: owned &= ~ST_DAT_TOKEN;
1140: }
1141: else
1142: if (SUAbortRequest (sd, NULLCP, 0, si) == NOTOK)
1143: ss_adios (sa, "S-U-ABORT.REQUEST");
1144: else
1145: adios (NULLCP, "aborted");
1146: SPFREE (sp);
1147: break;
1148:
1149: case SI_FINISH:
1150: if (SRelResponse (sd, SC_REJECTED, NULLCP, 0, si) == NOTOK)
1151: ss_adios (sa, "S-RELEASE.RESPONSE");
1152: SFFREE (sf);
1153: break;
1154:
1155: default:
1156: adios (NULLCP, "unknown indication type=0x%x",
1157: si -> si_type);
1158: }
1159: }
1160:
1161: /* */
1162:
1163: static void ss_adios (sa, event)
1164: register struct SSAPabort *sa;
1165: char *event;
1166: {
1167: ss_advise (sa, event);
1168:
1169: _exit (1);
1170: }
1171:
1172:
1173: static void ss_advise (sa, event)
1174: register struct SSAPabort *sa;
1175: char *event;
1176: {
1177: char buffer[BUFSIZ];
1178:
1179: if (sa -> sa_cc > 0)
1180: (void) sprintf (buffer, "[%s] %*.*s",
1181: SErrString (sa -> sa_reason),
1182: sa -> sa_cc, sa -> sa_cc, sa -> sa_data);
1183: else
1184: (void) sprintf (buffer, "[%s]", SErrString (sa -> sa_reason));
1185:
1186: advise (NULLCP, "%s: %s%s", event, buffer,
1187: sa -> sa_peer ? " (peer initiated)" : "");
1188:
1189: SAFREE (sa);
1190: }
1191:
1192: /* PSAP */
1193:
1194: static int prequirements = 0;
1195: #define srequirements requirements
1196:
1197: static int nctxs;
1198: static int datactxs[NPCTX];
1199:
1200: /* */
1201:
1202: static int ps_main (is, addr)
1203: struct isoservent *is;
1204: char *addr;
1205: {
1206: int sd,
1207: cc,
1208: i,
1209: j,
1210: k,
1211: l,
1212: m,
1213: tokens;
1214: char *cp,
1215: *dp,
1216: buffer[BUFSIZ];
1217: register struct PSAPaddr *pz;
1218: struct SSAPactid ids;
1219: register struct SSAPactid *id = &ids;
1220: struct SSAPref sfs;
1221: register struct SSAPref *sf;
1222: struct PSAPconnect pcs;
1223: register struct PSAPconnect *pc = &pcs;
1224: struct PSAPctxlist pls;
1225: register struct PSAPctxlist *pl = &pls;
1226: struct PSAPrelease prs;
1227: register struct PSAPrelease *pr = &prs;
1228: struct PSAPindication pis;
1229: register struct PSAPindication *pi = &pis;
1230: register struct PSAPabort *pa = &pi -> pi_abort;
1231: struct AcSAPconnect accs;
1232: register struct AcSAPconnect *acc = &accs;
1233: struct AcSAPrelease acrs;
1234: register struct AcSAPrelease *acr = &acrs;
1235: struct AcSAPindication acis;
1236: register struct AcSAPindication *aci = &acis;
1237: register struct AcSAPabort *aca = &aci -> aci_abort;
1238: register PE pe;
1239: PE udata[NPDATA];
1240: AEI aei;
1241: OID oid,
1242: ode;
1243: struct stat st;
1244:
1245: if (isacs) {
1246: if ((aei = str2aei (addr, isacs)) == NULLAEI)
1247: adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs);
1248: if ((pz = aei2addr (aei)) == NULLPA)
1249: adios (NULLCP, "address translation failed");
1250:
1251: cp = mode == echo ? "isode echo pci" : "isode sink pci";
1252: if ((ode = ode2oid (cp)) == NULLOID)
1253: adios (NULLCP, "%s: unknown object descriptor", cp);
1254: ode = oid_cpy (ode);
1255: }
1256: else
1257: if ((pz = is2paddr (addr, NULLCP, is)) == NULL)
1258: adios (NULLCP, "address translation failed");
1259: if ((sf = addr2ref (PLocalHostName ())) == NULL) {
1260: sf = &sfs;
1261: (void) bzero ((char *) sf, sizeof *sf);
1262: }
1263:
1264: tokens = 0;
1265: #define dotoken(requires,shift,bit,type) \
1266: { \
1267: if (srequirements & requires) \
1268: tokens |= ST_CALL_VALUE << shift; \
1269: }
1270: dotokens ();
1271: #undef dotoken
1272:
1273: for (i = (pl -> pc_nctx = NPCTX - (isacs ? 1 : 0)) - 1; i >= 0; i--) {
1274: pl -> pc_ctx[i].pc_id = i * 2 + 1;
1275: if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID)
1276: adios (NULLCP, "iso asn.1 abstract syntax: unknown");
1277: pl -> pc_ctx[i].pc_asn = oid_cpy (oid);
1278: pl -> pc_ctx[i].pc_atn = NULLOID;
1279: }
1280:
1281: for (i = 0; i < NPDATA; i++) {
1282: if ((pe = int2prim (i)) == NULLPE)
1283: adios (NULLCP, "unable to allocate hello");
1284: pe -> pe_context = (i % pl -> pc_nctx) * 2 + 1;
1285: udata[i] = pe;
1286: }
1287:
1288: fprintf (stderr, "%s... ", addr);
1289: (void) fflush (stderr);
1290: if (isacs) {
1291: #ifndef ASYNC
1292: if (AcAssocRequest (ode, NULLAEI, aei, NULLPA, pz, pl, ode,
1293: prequirements, srequirements, ISN (srequirements), tokens, sf,
1294: udata, NACDATA, NULLQOS, acc, aci)
1295: == NOTOK) {
1296: fprintf (stderr, "failed\n");
1297: acs_adios (aca, "A-ASSOCIATE.REQUEST");
1298: }
1299: sd = acc -> acc_sd;
1300: #else
1301: if ((i = AcAsynAssocRequest (ode, NULLAEI, aei, NULLPA, pz, pl, ode,
1302: prequirements, srequirements, ISN (srequirements), tokens, sf,
1303: udata, NACDATA, NULLQOS, acc, aci, 1)) == NOTOK) {
1304: fprintf (stderr, "failed\n");
1305: acs_adios (aca, "A-(ASYN-)ASSOCIATE.REQUEST");
1306: }
1307: sd = acc -> acc_sd, cc = 0;
1308: while (i == CONNECTING_1 || i == CONNECTING_2) {
1309: int nfds;
1310: fd_set mask,
1311: *rmask,
1312: *wmask;
1313:
1314: nfds = 0;
1315: FD_ZERO (&mask);
1316: if (PSelectMask (sd, &mask, &nfds, pi) == NOTOK) {
1317: fprintf (stderr, "failed\n");
1318: acs_adios (aca, "A-(ASYN-)ASSOCIATE.REQUEST(PSelectMask)");
1319: }
1320: rmask = (i == CONNECTING_2) ? &mask : NULLFD;
1321: wmask = (i == CONNECTING_2) ? NULLFD : &mask;
1322:
1323: fprintf (stderr, ".");
1324: if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
1325: fprintf (stderr, "failed\n");
1326: adios ("failed", "select");
1327: }
1328:
1329: if ((rmask && FD_ISSET (sd, rmask) == 0)
1330: || (wmask && FD_ISSET (sd, wmask) == 0))
1331: continue;
1332:
1333: if ((i = AcAsynRetryRequest (sd, acc, aci)) == NOTOK) {
1334: fprintf (stderr, "failed\n");
1335: acs_adios (aca, "A-ASYN-RETRY.REQUEST");
1336: }
1337: }
1338: #endif
1339:
1340: if (acc -> acc_result != ACS_ACCEPT) {
1341: fprintf (stderr, "failed\n");
1342: adios (NULLCP, "connection rejected: [%s], %d elements",
1343: AcErrString (acc -> acc_result), acc -> acc_ninfo);
1344: }
1345: }
1346: else {
1347: #ifndef ASYNC
1348: if (PConnRequest (NULLPA, pz, pl, NULLOID, prequirements,
1349: srequirements, srequirements
1350: & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY)
1351: ? (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1)) + SERIAL_MIN
1352: : SERIAL_NONE, tokens, sf, udata, NPDATA, NULLQOS, pc, pi) == NOTOK) {
1353: fprintf (stderr, "failed\n");
1354: ps_adios (pa, "P-CONNECT.REQUEST");
1355: }
1356: sd = pc -> pc_sd;
1357: #else
1358: if ((i = PAsynConnRequest (NULLPA, pz, pl, NULLOID, prequirements,
1359: srequirements, ISN (srequirements), tokens, sf, udata, NPDATA,
1360: NULLQOS, pc, pi, 1)) == NOTOK) {
1361: fprintf (stderr, "failed\n");
1362: ps_adios (pa, "P-CONNECT.REQUEST");
1363: }
1364: sd = pc -> pc_sd, cc = 0;
1365: while (i == CONNECTING_1 || i == CONNECTING_2) {
1366: int nfds;
1367: fd_set mask,
1368: *rmask,
1369: *wmask;
1370:
1371: nfds = 0;
1372: FD_ZERO (&mask);
1373: if (PSelectMask (sd, &mask, &nfds, pi) == NOTOK) {
1374: fprintf (stderr, "failed\n");
1375: ps_adios (pa, "P-CONNECT.REQUEST(PSelectMask)");
1376: }
1377: rmask = (i == CONNECTING_2) ? &mask : NULLFD;
1378: wmask = (i == CONNECTING_2) ? NULLFD : &mask;
1379:
1380: fprintf (stderr, ".");
1381: if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
1382: fprintf (stderr, "failed\n");
1383: adios ("failed", "select");
1384: }
1385:
1386: if ((rmask && FD_ISSET (sd, rmask) == 0)
1387: || (wmask && FD_ISSET (sd, wmask) == 0))
1388: continue;
1389:
1390: if ((i = PAsynRetryRequest (sd, pc, pi)) == NOTOK) {
1391: fprintf (stderr, "failed\n");
1392: ps_adios (pa, "P-ASYN-RETRY.REQUEST");
1393: }
1394: }
1395: #endif
1396:
1397: if (pc -> pc_result != PC_ACCEPT) {
1398: fprintf (stderr, "failed\n");
1399: adios (NULLCP, "connection rejected: [%s], %d elements",
1400: PErrString (pc -> pc_result), pc -> pc_ninfo);
1401: }
1402: }
1403: fprintf (stderr, "connected\n");
1404:
1405: if (isacs) {
1406: pc = &acc -> acc_connect;
1407:
1408: #ifdef DEBUG
1409: {
1410: advise (NULLCP, "context: %s", oid2ode (acc -> acc_context));
1411:
1412: advise (NULLCP,
1413: "responding AE title: %s, responding PSAP address: %s",
1414: sprintaei (&acc -> acc_respondtitle),
1415: paddr2str (&pc -> pc_responding, NULLNA));
1416:
1417: advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo);
1418:
1419: pl = &pc -> pc_ctxlist;
1420: for (i = 0; i < pl -> pc_nctx; i++)
1421: advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
1422: pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
1423: pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
1424: advise (NULLCP, "default %d", pc -> pc_defctxresult);
1425: advise (NULLCP, "p/s requirements 0x%x/0x%x",
1426: pc -> pc_prequirements, pc -> pc_srequirements);
1427: }
1428: #endif
1429:
1430: pl = &pc -> pc_ctxlist;
1431:
1432: if (mode == echo) {
1433: if (acc -> acc_ninfo != NACDATA)
1434: adios (NULLCP, "expecting %d hellos, got %d elements",
1435: NACDATA, acc -> acc_ninfo);
1436: for (i = 0; i < NACDATA; i++) {
1437: if ((pe = acc -> acc_info[i]) == NULLPE)
1438: adios (NULLCP, "hello %d: NULL", i);
1439: if ((j = prim2num (pe)) == NOTOK
1440: && pe -> pe_errno != PE_ERR_NONE)
1441: adios (NULLCP, "hello %d: %s", i,
1442: pe_error (pe -> pe_errno));
1443: if (j != i)
1444: adios (NULLCP, "hello %d: value %d", i, j);
1445: if (pe -> pe_context != udata[i] -> pe_context)
1446: adios (NULLCP, "hello %d: context of %d instead of %d",
1447: i, pe -> pe_context, udata[i] -> pe_context);
1448: }
1449: }
1450:
1451: goto do_release;
1452: }
1453: else {
1454: #ifdef DEBUG
1455: {
1456: advise (NULLCP, "responding PSAP address: %s",
1457: paddr2str (&pc -> pc_responding, NULLNA));
1458:
1459: advise (NULLCP, "greetings: %d elements", pc -> pc_ninfo);
1460:
1461: pl = &pc -> pc_ctxlist;
1462: for (i = 0; i < pl -> pc_nctx; i++)
1463: advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
1464: pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
1465: pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
1466: advise (NULLCP, "default %d", pc -> pc_defctxresult);
1467: advise (NULLCP, "p/s requirements 0x%x/0x%x",
1468: pc -> pc_prequirements, pc -> pc_srequirements);
1469: }
1470: #endif
1471:
1472: if (mode == echo) {
1473: if (pc -> pc_ninfo != NPDATA)
1474: adios (NULLCP, "expecting %d hellos, got %d elements",
1475: NPDATA, pc -> pc_ninfo);
1476: for (i = 0; i < NPDATA; i++) {
1477: if ((pe = pc -> pc_info[i]) == NULLPE)
1478: adios (NULLCP, "hello %d: NULL", i);
1479: if ((j = prim2num (pe)) == NOTOK
1480: && pe -> pe_errno != PE_ERR_NONE)
1481: adios (NULLCP, "hello %d: %s", i,
1482: pe_error (pe -> pe_errno));
1483: if (j != i)
1484: adios (NULLCP, "hello %d: value %d", i, j);
1485: if (pe -> pe_context != udata[i] -> pe_context)
1486: adios (NULLCP, "hello %d: context of %d instead of %d",
1487: i, pe -> pe_context, udata[i] -> pe_context);
1488: }
1489: }
1490: }
1491:
1492: nctxs = 0;
1493: pl = &pc -> pc_ctxlist;
1494: for (i = 0; i < pl -> pc_nctx; i++)
1495: if (pl -> pc_ctx[i].pc_result == PC_ACCEPT)
1496: datactxs[nctxs++] = pl -> pc_ctx[i].pc_id;
1497:
1498: srequirements = pc -> pc_srequirements;
1499: nmodes = 0;
1500: datamodes[nmodes++] = SX_NORMAL;
1501: if (srequirements & SR_EXPEDITED)
1502: datamodes[nmodes++] = SX_EXPEDITED;
1503: if ((srequirements & SR_CAPABILITY) && (srequirements & SR_ACTIVITY))
1504: datamodes[nmodes++] = SX_CAPDIND;
1505: if (srequirements & SR_TYPEDATA)
1506: datamodes[nmodes++] = SX_TYPED;
1507:
1508: #define dotoken(requires,shift,bit,type) \
1509: { \
1510: if (srequirements & requires) \
1511: switch (pc -> pc_settings & (ST_MASK << shift)) { \
1512: case ST_CALL_VALUE: \
1513: adios (NULLCP, "%s token: choice", type); \
1514: \
1515: case ST_INIT_VALUE: \
1516: owned |= bit, avail |= bit; \
1517: break; \
1518: \
1519: case ST_RESP_VALUE: \
1520: avail |= bit; \
1521: break; \
1522: \
1523: default: \
1524: adios (NULLCP, "%s token: reserved", type); \
1525: } \
1526: }
1527: dotokens ();
1528: #undef dotoken
1529:
1530: if (isacs)
1531: ACCFREE (acc)
1532: else
1533: PCFREE (pc);
1534:
1535: if (srequirements & SR_ACTIVITY) {
1536: (void) strcpy (id -> sd_data, mode == echo ? "echo" : "sink");
1537: id -> sd_len = strlen (id -> sd_data);
1538: if (PActStartRequest (sd, id, udata, NPDATA, pi) == NOTOK)
1539: ps_adios (pa, "P-ACTIVITY-START.REQUEST");
1540: }
1541:
1542: if (fstat (fileno (stdin), &st) != NOTOK
1543: && (st.st_mode & S_IFMT) == S_IFREG
1544: && (cc = st.st_size) != 0) {
1545: (void) lseek (fileno (stdin), 0L, 0);
1546:
1547: if ((cp = malloc ((unsigned) cc)) == NULL)
1548: adios (NULLCP, "no memory");
1549: for (dp = cp, j = cc; j > 0; dp += i, j -= i)
1550: switch (i = read (fileno (stdin), dp, j)) {
1551: case NOTOK:
1552: adios ("on stdin", "read failed");
1553:
1554: case OK:
1555: adios (NULLCP, "premature end-of-file");
1556:
1557: default:
1558: break;
1559: }
1560: if ((pe = oct2prim (cp, cc)) == NULLPE)
1561: adios (NULLCP, "unable to allocate PSDU");
1562: free (cp);
1563: if (nctxs)
1564: pe -> pe_context = datactxs[0];
1565: for (i = 10; i > 0; i--) {
1566: #ifdef TIMER
1567: timer (0);
1568: #endif
1569: ps_datarequest (sd, pe, SX_NORMAL, 0);
1570: #ifdef TIMER
1571: timer (cc);
1572: #endif
1573: }
1574: pe_free (pe);
1575: }
1576: else {
1577: for (j = l = m = 0; fgets (buffer, sizeof buffer, stdin); ) {
1578: k = j >= nmodes ? SX_EXPEDITED : datamodes[j++ % nmodes];
1579: if ((cc = strlen (buffer) + 1) > SX_EXSIZE - 7
1580: && k == SX_EXPEDITED) {
1581: if ((k = datamodes[j++ % nmodes]) == SX_EXPEDITED)
1582: k = datamodes[j++ % nmodes];
1583: }
1584:
1585: switch (k) {
1586: case SX_CAPDIND:
1587: if (!(requirements & SR_RESYNC) || l++ & 0x01) {
1588: ps_waitfor (sd, ST_ACT_TOKEN);
1589: if (l & 0x03) {
1590: if (PActIntrRequest (sd, SP_SEQUENCE, pi)
1591: == NOTOK)
1592: ps_adios (pa, "P-ACTIVITY-INTERRUPT.REQUEST");
1593: }
1594: else {
1595: if (PActDiscRequest (sd, SP_SEQUENCE, pi)
1596: == NOTOK)
1597: ps_adios (pa, "P-ACTIVITY-DISCARD.REQUEST");
1598: }
1599: ps_waitfor (sd, -1);
1600: goto push_data;
1601: }
1602: tokens = 0;
1603: #define dotoken(requires,shift,bit,type) \
1604: { \
1605: if (requirements & requires) \
1606: tokens |= ST_CALL_VALUE << shift; \
1607: }
1608: dotokens ();
1609: #undef dotoken
1610: if (PReSyncRequest (sd, SYNC_SET, ssn - 1, tokens,
1611: udata, NPDATA, pi) == NOTOK)
1612: ps_adios (pa, "P-RESYNCHRONIZE.REQUEST");
1613: ps_waitfor (sd, -1);
1614: break;
1615:
1616: case SX_EXPEDITED:
1617: if (j >= nmodes)
1618: j = j % nmodes;
1619: if (!(srequirements & SR_EXPEDITED))
1620: k = SX_NORMAL; /* fall... */
1621: default:
1622: push_data: ;
1623: if ((pe = oct2prim (buffer, cc)) == NULLPE)
1624: adios (NULLCP, "unable to allocate PSDU");
1625: if (nctxs && k != SX_EXPEDITED)
1626: pe -> pe_context = datactxs[m++ % nctxs];
1627: ps_datarequest (sd, pe, k, 1);
1628: pe_free (pe);
1629: if (k == SX_CAPDIND
1630: && PActResumeRequest (sd, id, id,
1631: (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1))
1632: + SERIAL_MIN, sf, udata, NPDATA, pi)
1633: == NOTOK)
1634: ps_adios (pa, "P-ACTIVITY-RESUME.REQUEST");
1635: break;
1636: }
1637: }
1638:
1639: if (requirements & SR_EXCEPTIONS) {
1640: if (owned & ST_DAT_TOKEN)
1641: if (PGTokenRequest (sd, ST_DAT_TOKEN, pi) == NOTOK)
1642: ps_adios (pa, "P-TOKEN-GIVE.REQUEST");
1643: else
1644: owned &= ~ST_DAT_TOKEN;
1645: if (PUReportRequest (sd, SP_NOREASON, udata, NPDATA, pi) == NOTOK)
1646: ps_adios (pa, "P-U-EXCEPTION-REPORT.REQUEST");
1647: ps_waitfor (sd, -1);
1648: }
1649: }
1650:
1651: if ((requirements & SR_MAJORSYNC) && !(requirements & SR_ACTIVITY)) {
1652: if (PMajSyncRequest (sd, &ssn, udata, NPDATA, pi) == NOTOK)
1653: switch (pa -> pa_reason) {
1654: case PC_OPERATION:
1655: ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
1656: | ST_MAJ_TOKEN);
1657: if (PMajSyncRequest (sd, &ssn, udata, NPDATA, pi) == OK)
1658: break; /* else fall */
1659:
1660: default:
1661: ps_adios (pa, "P-MAJOR-SYNC.REQUEST");
1662: }
1663:
1664: ps_waitfor (sd, -1);
1665: }
1666:
1667: if (requirements & SR_ACTIVITY) {
1668: if (PActEndRequest (sd, &ssn, udata, NPDATA, pi) == NOTOK)
1669: switch (pa -> pa_reason) {
1670: case PC_OPERATION:
1671: ps_waitfor (sd, avail);
1672: if (PActEndRequest (sd, &ssn, udata, NPDATA, pi) == OK)
1673: break; /* else fall */
1674:
1675: default:
1676: ps_adios (pa, "P-ACTIVITY-END.REQUEST");
1677: }
1678:
1679: ps_waitfor (sd, -1);
1680:
1681: if (PGControlRequest (sd, pi) == NOTOK)
1682: switch (pa -> pa_reason) {
1683: case PC_OPERATION:
1684: ps_waitfor (sd, avail);
1685: if (PGControlRequest (sd, pi) == OK)
1686: break; /* else fall */
1687:
1688: default:
1689: ps_adios (pa, "P-CONTROL-GIVE.REQUEST");
1690: }
1691:
1692: owned = 0;
1693:
1694: ps_waitfor (sd, -1);
1695: }
1696:
1697: do_release: ;
1698: if (isacs) {
1699: if (AcRelRequest (sd, ACF_NORMAL, udata, NACDATA, NOTOK, acr, aci)
1700: == NOTOK)
1701: switch (aca -> aca_reason) {
1702: case ACS_OPERATION:
1703: ps_waitfor (sd, avail);
1704: if (AcRelRequest (sd, ACF_NORMAL, udata, NACDATA, NOTOK,
1705: acr, aci) == OK)
1706: break; /* else fall */
1707:
1708: default:
1709: acs_adios (aca, "A-RELEASE.REQUEST");
1710: }
1711:
1712: if (!acr -> acr_affirmative) {
1713: (void) AcUAbortRequest (sd, NULLPEP, 0, aci);
1714: adios (NULLCP, "release rejected by peer: %d, %d elements",
1715: acr -> acr_reason, acr -> acr_ninfo);
1716: }
1717:
1718: #ifdef DEBUG
1719: advise (NULLCP, "A-RELEASE.CONFIRMATION: %d, %d elements",
1720: acr -> acr_reason, acr -> acr_ninfo);
1721: #endif
1722: ACRFREE (acr);
1723: }
1724: else {
1725: if (PRelRequest (sd, udata, NPDATA, NOTOK, pr, pi) == NOTOK)
1726: switch (pa -> pa_reason) {
1727: case PC_OPERATION:
1728: case PC_WAITING:
1729: ps_waitfor (sd, avail);
1730: if (PRelRequest (sd, udata, NPDATA, NOTOK, pr, pi) == OK)
1731: break; /* else fall */
1732:
1733: default:
1734: ps_adios (pa, "P-RELEASE.REQUEST");
1735: }
1736:
1737: if (!pr -> pr_affirmative) {
1738: (void) PUAbortRequest (sd, NULLPEP, 0, pi);
1739: adios (NULLCP, "release rejected by peer: %d elements",
1740: pr -> pr_ninfo);
1741: }
1742: PRFREE (pr);
1743: }
1744:
1745: for (i = 0; i < NPDATA; i++)
1746: pe_free (udata[i]);
1747: }
1748:
1749: /* */
1750:
1751: static int ps_datarequest (sd, pe, dm, sync)
1752: int sd;
1753: PE pe;
1754: int dm,
1755: sync;
1756: {
1757: int result;
1758: struct PSAPdata pxs;
1759: register struct PSAPdata *px = &pxs;
1760: struct PSAPindication pis;
1761: register struct PSAPindication *pi = &pis;
1762: register struct PSAPabort *pa = &pi -> pi_abort;
1763:
1764: switch (dm) {
1765: default:
1766: if (PDataRequest (sd, &pe, 1, pi) == NOTOK)
1767: switch (pa -> pa_reason) {
1768: case PC_OPERATION:
1769: ps_waitfor (sd, ST_DAT_TOKEN);
1770: if (PDataRequest (sd, &pe, 1, pi) == OK)
1771: break;/* else fall */
1772:
1773: default:
1774: ps_adios (pa, "P-DATA.REQUEST");
1775: }
1776: break;
1777:
1778: case SX_EXPEDITED:
1779: if (PExpdRequest (sd, &pe, 1, pi) == NOTOK)
1780: ps_adios (pa, "P-EXPEDITED-DATA.REQUEST");
1781: break;
1782:
1783: case SX_CAPDIND:
1784: if (PCapdRequest (sd, &pe, 1, pi) == NOTOK)
1785: switch (pa -> pa_reason) {
1786: case PC_OPERATION:
1787: ps_waitfor (sd, avail & ~ST_RLS_TOKEN);
1788: if (PCapdRequest (sd, &pe, 1, pi) == OK)
1789: break;/* else fall */
1790:
1791: default:
1792: ps_adios (pa, "P-CAPABILITY-DATA.REQUEST");
1793: }
1794: break;
1795:
1796: case SX_TYPED:
1797: if (PTypedRequest (sd, &pe, 1, pi) == NOTOK)
1798: ps_adios (pa, "P-TYPED-DATA.REQUEST");
1799: break;
1800: }
1801:
1802: if (mode == echo || dm == SX_CAPDIND)
1803: for (;;) {
1804: switch (result = PReadRequest (sd, px, NOTOK, pi)) {
1805: case NOTOK:
1806: ps_adios (pa, "P-READ.REQUEST");
1807:
1808: case OK:
1809: if ((dm != SX_CAPDIND ? dm : SX_CAPDCNF)
1810: != px -> px_type) {
1811: advise (NULLCP,
1812: "data indication type mismatch, orig=%d echo=%d",
1813: dm, px -> px_type);
1814: status++;
1815: }
1816: if (px -> px_ninfo != 1) {
1817: advise (NULLCP, "length mismatch, orig=%d echo=%d",
1818: 1, px -> px_ninfo);
1819: status++;
1820: }
1821: if (pe -> pe_context != (*px -> px_info) -> pe_context) {
1822: advise (NULLCP, "context mismatch, orig=%d echo=%d",
1823: pe -> pe_context,
1824: (*px -> px_info) -> pe_context);
1825: status++;
1826: }
1827: if (pe_cmp (pe, *px -> px_info)) {
1828: advise (NULLCP, "data mismatch");
1829: status++;
1830: }
1831: PXFREE (px)
1832: break;
1833:
1834: case DONE:
1835: ps_event (sd, pi);
1836: continue;
1837:
1838: default:
1839: adios (NULLCP, "unknown return from PReadRequest=%d",
1840: result);
1841: }
1842: break;
1843: }
1844:
1845: if (sync &&
1846: (srequirements & SR_MINORSYNC) && !(srequirements & SR_ACTIVITY)) {
1847: if (PMinSyncRequest (sd, SYNC_CONFIRM, &ssn, NULLPEP, 0, pi) == NOTOK)
1848: switch (pa -> pa_reason) {
1849: case PC_OPERATION:
1850: ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN);
1851: if (PMinSyncRequest (sd, SYNC_CONFIRM, &ssn, NULLPEP, 0,
1852: pi) == OK)
1853: break; /* else fall */
1854:
1855: default:
1856: ps_adios (pa, "P-MINOR-SYNC.REQUEST");
1857: }
1858:
1859: ps_waitfor (sd, -1);
1860: }
1861: else
1862: if (sync
1863: && (srequirements & SR_ACTIVITY)
1864: && (srequirements & SR_MAJORSYNC)
1865: && dm == SX_NORMAL) {
1866: if (PMajSyncRequest (sd, &ssn, NULLPEP, 0, pi) == NOTOK)
1867: switch (pa -> pa_reason) {
1868: case PC_OPERATION:
1869: ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
1870: | ST_MAJ_TOKEN);
1871: if (PMajSyncRequest (sd, &ssn, NULLPEP, 0, pi) == OK)
1872: break;/* else fall */
1873:
1874: default:
1875: ps_adios (pa, "P-MAJOR-SYNC.REQUEST");
1876: }
1877:
1878: ps_waitfor (sd, -1);
1879: }
1880: }
1881:
1882: /* */
1883:
1884: static int ps_waitfor (sd, want)
1885: int sd,
1886: want;
1887: {
1888: int result,
1889: tokens;
1890: struct PSAPdata pxs;
1891: register struct PSAPdata *px = &pxs;
1892: struct PSAPindication pis;
1893: register struct PSAPindication *pi = &pis;
1894: register struct PSAPabort *pa = &pi -> pi_abort;
1895:
1896: for (;;) {
1897: if (want == -1) {
1898: want = avail;
1899: goto read_it;
1900: }
1901:
1902: tokens = 0;
1903: #define dotoken(requires,shift,bit,type) \
1904: { \
1905: if ((want & bit) && !(owned & bit)) \
1906: tokens |= bit; \
1907: }
1908: dotokens ();
1909: #undef dotoken
1910: if (tokens == 0)
1911: return;
1912:
1913: if (PPTokenRequest (sd, tokens, NULLPEP, 0, pi) == NOTOK)
1914: ps_adios (pa, "P-TOKEN-PLEASE.REQUEST");
1915:
1916: read_it: ;
1917: switch (result = PReadRequest (sd, px, NOTOK, pi)) {
1918: case NOTOK:
1919: ps_adios (pa, "P-READ.REQUEST");
1920:
1921: case OK:
1922: ps_abort (sd, "protocol screw-up");
1923:
1924: case DONE:
1925: ps_event (sd, pi);
1926: break;
1927:
1928: default:
1929: adios (NULLCP, "unknown return from PReadRequest=%d",
1930: result);
1931: }
1932: }
1933: }
1934:
1935: /* */
1936:
1937: static ps_event (sd, pi)
1938: int sd;
1939: register struct PSAPindication *pi;
1940: {
1941: register struct PSAPabort *pa = &pi -> pi_abort;
1942: register struct PSAPactivity *pv = &pi -> pi_activity;
1943: register struct PSAPfinish *pf = &pi -> pi_finish;
1944: register struct PSAPreport *pp = &pi -> pi_report;
1945: register struct PSAPsync *pn = &pi -> pi_sync;
1946: register struct PSAPtoken *pt = &pi -> pi_token;
1947: struct AcSAPindication acis;
1948: register struct AcSAPindication *aci = &acis;
1949: register struct AcSAPabort *aca = &aci -> aci_abort;
1950: register struct AcSAPfinish *acf = &aci -> aci_finish;
1951:
1952: switch (pi -> pi_type) {
1953: case PI_TOKEN:
1954: switch (pt -> pt_type) {
1955: case ST_GIVE:
1956: case ST_CONTROL:
1957: owned = pt -> pt_owned;
1958: break;
1959:
1960: case ST_PLEASE:
1961: if (PGTokenRequest (sd,
1962: (int) pt -> pt_tokens, pi)
1963: == NOTOK)
1964: ps_adios (pa, "P-TOKEN-GIVE.REQUEST");
1965: else
1966: owned &= ~pt -> pt_tokens;
1967: break;
1968:
1969: default:
1970: adios (NULLCP,
1971: "unknown token indication type=0x%x",
1972: pt -> pt_type);
1973: }
1974: PTFREE (pt);
1975: break;
1976:
1977: case PI_SYNC:
1978: switch (pn -> pn_type) {
1979: case SN_MAJORIND:
1980: adios (NULLCP, "majorsync indication %d",
1981: pn -> pn_ssn);
1982: break;
1983:
1984: case SN_MAJORCNF:
1985: break;
1986:
1987: case SN_MINORIND:
1988: adios (NULLCP, "minorsync indication %d%s",
1989: pn -> pn_ssn, pn -> pn_options == SYNC_CONFIRM
1990: ? " (wants confirmation)" : NULLCP);
1991: break;
1992:
1993: case SN_MINORCNF:
1994: break;
1995:
1996: case SN_RESETIND:
1997: #define dotoken(requires,shift,bit,type) \
1998: { \
1999: if (srequirements & requires) \
2000: switch (pn -> pn_settings & (ST_MASK << shift)) { \
2001: case ST_CALL_VALUE << shift: \
2002: pn -> pn_settings &= ~(ST_MASK << shift); \
2003: pn -> pn_settings |= ST_RESP_VALUE << shift; \
2004: case ST_RESP_VALUE << shift: \
2005: owned &= ~bit; \
2006: break; \
2007: \
2008: case ST_INIT_VALUE << shift: \
2009: owned |= bit; \
2010: break; \
2011: \
2012: default: \
2013: adios (NULLCP, "%s token: reserved", type); \
2014: break; \
2015: } \
2016: }
2017: dotokens ();
2018: #undef dotoken
2019: if (PReSyncResponse (sd, pn -> pn_ssn, pn -> pn_settings,
2020: NULLPEP, 0, pi) == NOTOK)
2021: ps_adios (pa, "P-RESYNCHRONIZE.RESPONSE");
2022: break;
2023:
2024: case SN_RESETCNF:
2025: break;
2026:
2027: default:
2028: adios (NULLCP, "unknown sync indication=0x%x, ssn=%d",
2029: pn -> pn_type, pn -> pn_ssn);
2030: }
2031: PNFREE (pn);
2032: break;
2033:
2034: case PI_ACTIVITY:
2035: switch (pv -> pv_type) {
2036: case SV_START:
2037: adios (NULLCP, "activity start indication: %*.*s",
2038: pv -> pv_id.sd_len, pv -> pv_id.sd_len,
2039: pv -> pv_id.sd_data);
2040:
2041: case SV_RESUME:
2042: adios (NULLCP,
2043: "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d",
2044: pv -> pv_id.sd_len, pv -> pv_id.sd_len,
2045: pv -> pv_id.sd_data, pv -> pv_oid.sd_len,
2046: pv -> pv_oid.sd_len, pv -> pv_oid.sd_data,
2047: sprintref (&pv -> pv_connect), pv -> pv_ssn);
2048:
2049: case SV_INTRIND:
2050: adios (NULLCP, "activity interrupt indication %d",
2051: pv -> pv_reason);
2052:
2053: case SV_INTRCNF:
2054: break;
2055:
2056: case SV_DISCIND:
2057: adios (NULLCP, "activity discard indication %d",
2058: pv -> pv_reason);
2059:
2060: case SV_DISCCNF:
2061: break;
2062:
2063: case SV_ENDIND:
2064: adios (NULLCP, "activity end indication %d",
2065: pv -> pv_ssn);
2066:
2067: case SV_ENDCNF:
2068: break;
2069:
2070: default:
2071: adios (NULLCP, "unknown activity indication=0x%x",
2072: pv -> pv_type);
2073: }
2074: PVFREE (pv);
2075: break;
2076:
2077: case PI_REPORT:
2078: advise (NULLCP, "%s report %d",
2079: pp -> pp_peer ? "user" : "provider", pp -> pp_reason);
2080: if (srequirements & SR_DAT_EXISTS) {
2081: if (PGTokenRequest (sd, ST_DAT_TOKEN, pi) == NOTOK)
2082: ps_adios (pa, "P-TOKEN-GIVE.REQUEST (to clear exception)");
2083: else
2084: owned &= ~ST_DAT_TOKEN;
2085: }
2086: else
2087: ps_abort (sd, "aborted");
2088: PPFREE (pp);
2089: break;
2090:
2091: case PI_FINISH:
2092: if (isacs) {
2093: if (AcFINISHser (sd, pf, aci) == NOTOK)
2094: acs_adios (aca, "AcFINISHser");
2095: #ifdef DEBUG
2096: advise (NULLCP, "A-RELEASE.INDICATION %d, %d elements",
2097: acf -> acf_reason, acf -> acf_ninfo);
2098: if (AcRelResponse (sd, ACS_USER_NOREASON, ACR_NOTFINISHED,
2099: NULLPEP, 0, aci) == NOTOK)
2100: acs_adios (aca, "A-RELEASE.RESPONSE");
2101: #endif
2102:
2103: ACFFREE (acf);
2104: }
2105: else {
2106: if (PRelResponse (sd, PC_REJECTED, NULLPEP, 0, pi) == NOTOK)
2107: ps_adios (pa, "P-RELEASE.RESPONSE");
2108:
2109: PFFREE (pf);
2110: }
2111: break;
2112:
2113: default:
2114: adios (NULLCP, "unknown indication type=0x%x", pi -> pi_type);
2115: }
2116: }
2117:
2118: /* */
2119:
2120: static ps_abort (sd, reason)
2121: int sd;
2122: char *reason;
2123: {
2124: struct PSAPindication pis;
2125: register struct PSAPindication *pi = &pis;
2126: register struct PSAPabort *pa = &pi -> pi_abort;
2127: struct AcSAPindication acis;
2128: register struct AcSAPindication *aci = &acis;
2129: register struct AcSAPabort *aca = &aci -> aci_abort;
2130:
2131: if (isacs) {
2132: if (AcUAbortRequest (sd, NULLPEP, 0, aci) == NOTOK)
2133: acs_adios (aca, "A-U-ABORT.REQUEST");
2134: }
2135: else {
2136: if (PUAbortRequest (sd, NULLPEP, 0, pi) == NOTOK)
2137: ps_adios (pa, "P-U-ABORT.REQUEST");
2138: }
2139:
2140: adios (NULLCP, "%s", reason);
2141: }
2142:
2143: /* */
2144:
2145: static void ps_adios (pa, event)
2146: register struct PSAPabort *pa;
2147: char *event;
2148: {
2149: ps_advise (pa, event);
2150:
2151: _exit (1);
2152: }
2153:
2154:
2155: static void ps_advise (pa, event)
2156: register struct PSAPabort *pa;
2157: char *event;
2158: {
2159: char buffer[BUFSIZ];
2160:
2161: if (pa -> pa_cc > 0)
2162: (void) sprintf (buffer, "[%s] %*.*s",
2163: PErrString (pa -> pa_reason),
2164: pa -> pa_cc, pa -> pa_cc, pa -> pa_data);
2165: else
2166: (void) sprintf (buffer, "[%s]", PErrString (pa -> pa_reason));
2167:
2168: advise (NULLCP, "%s: %s%s", event, buffer,
2169: pa -> pa_peer ? " (peer initiated)" : "");
2170: }
2171:
2172: /* AcSAP */
2173:
2174: static void acs_adios (aca, event)
2175: register struct AcSAPabort *aca;
2176: char *event;
2177: {
2178: acs_advise (aca, event);
2179:
2180: _exit (1);
2181: }
2182:
2183:
2184: static void acs_advise (aca, event)
2185: register struct AcSAPabort *aca;
2186: char *event;
2187: {
2188: char buffer[BUFSIZ];
2189:
2190: if (aca -> aca_cc > 0)
2191: (void) sprintf (buffer, "[%s] %*.*s",
2192: AcErrString (aca -> aca_reason),
2193: aca -> aca_cc, aca -> aca_cc, aca -> aca_data);
2194: else
2195: (void) sprintf (buffer, "[%s]", AcErrString (aca -> aca_reason));
2196:
2197: advise (NULLCP, "%s: %s (source %d)", event, buffer,
2198: aca -> aca_source);
2199: }
2200:
2201: /* RtSAP */
2202:
2203: static int turn = 0;
2204:
2205: /* */
2206:
2207: static int rts_main (is, addr)
2208: struct isoservent *is;
2209: char *addr;
2210: {
2211: int sd,
2212: cc,
2213: i,
2214: j,
2215: ros;
2216: char *cp,
2217: *dp,
2218: buffer[BUFSIZ];
2219: register struct PSAPaddr *pa;
2220: struct PSAPctxlist pls;
2221: register struct PSAPctxlist *pl = &pls;
2222: struct AcSAPrelease acrs;
2223: register struct AcSAPrelease *acr = &acrs;
2224: struct RtSAPaddr rtzs;
2225: register struct RtSAPaddr *rtz = &rtzs;
2226: struct RtSAPconnect rtcs;
2227: register struct RtSAPconnect *rtc = &rtcs;
2228: struct RtSAPindication rtis;
2229: register struct RtSAPindication *rti = &rtis;
2230: register struct RtSAPabort *rta = &rti -> rti_abort;
2231: #ifdef DEBUG
2232: struct AcSAPconnect *acc= &rtc -> rtc_connect;
2233: struct PSAPconnect *pc = &acc -> acc_connect;
2234: #endif
2235: register PE pe;
2236: AEI aei;
2237: OID oid,
2238: ode;
2239: struct stat st;
2240:
2241: if ((pe = int2prim (i = getpid ())) == NULLPE)
2242: adios (NULLCP, "unable to allocate hello");
2243:
2244: turn = mode == sink;
2245:
2246: if (isacs) {
2247: if (ros = strncmp (isacs, "isode/ros_", strlen ("isode/ros_")) == 0)
2248: mode = strcmp (isacs, "isode/ros_sink") ? echo : sink;
2249: else
2250: mode = strcmp (isacs, "isode/rtse sink") ? echo : sink;
2251: turn = mode == sink;
2252:
2253: if ((aei = str2aei (addr, isacs)) == NULLAEI)
2254: adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs);
2255: if ((pa = aei2addr (aei)) == NULLPA)
2256: adios (NULLCP, "address translation failed");
2257:
2258: cp = mode == echo ? "isode echo pci" : "isode sink pci";
2259: if ((ode = ode2oid (cp)) == NULLOID)
2260: adios (NULLCP, "%s: unknown object descriptor", cp);
2261: ode = oid_cpy (ode);
2262:
2263: for (j = (pl -> pc_nctx = NPCTX - 2) - 1; j >= 0; j--) {
2264: pl -> pc_ctx[j].pc_id = j * 2 + 1;
2265: if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID)
2266: adios (NULLCP, "iso asn.1 abstract syntax: unknown");
2267: pl -> pc_ctx[j].pc_asn = oid_cpy (oid);
2268: pl -> pc_ctx[j].pc_atn = NULLOID;
2269: }
2270:
2271: fprintf (stderr, "%s... ", addr);
2272: (void) fflush (stderr);
2273: if (RtOpenRequest (RTS_TWA, turn ? RTS_INITIATOR : RTS_RESPONDER,
2274: ode, NULLAEI, aei, NULLPA, pa, pl, ode, pe,
2275: NULLQOS, rtc, rti) == NOTOK) {
2276: fprintf (stderr, "failed\n");
2277: rts_adios (rta, "RT-OPEN.REQUEST");
2278: }
2279: }
2280: else {
2281: register struct SSAPaddr *sa;
2282:
2283: if (ros = strncmp (is -> is_entity, "ros_", strlen ("ros_")) == 0) {
2284: mode = strcmp (is -> is_entity, "ros_sink") ? echo : sink;
2285: turn = mode == sink;
2286: }
2287:
2288: rtz -> rta_port = is -> is_port; /* yikes! */
2289: if ((is = getisoserventbyname ("rts", "ssap")) == NULL)
2290: adios (NULLCP, "ssap/rts: unknown entity");
2291: if ((sa = is2saddr (addr, NULLCP, is)) == NULLSA)
2292: adios (NULLCP, "address translation failed");
2293: rtz -> rta_addr = *sa; /* struct copy */
2294:
2295: fprintf (stderr, "%s... ", addr);
2296: (void) fflush (stderr);
2297: if (RtBeginRequest (rtz, RTS_TWA, turn ? RTS_INITIATOR : RTS_RESPONDER,
2298: pe, rtc, rti) == NOTOK) {
2299: fprintf (stderr, "failed\n");
2300: rts_adios (rta, "RT-BEGIN.REQUEST");
2301: }
2302: }
2303:
2304: pe_free (pe);
2305:
2306: if (rtc -> rtc_result != RTS_ACCEPT) {
2307: fprintf (stderr, "failed\n");
2308: adios (NULLCP, "association rejected: [%s]",
2309: RtErrString (rtc -> rtc_result));
2310: }
2311: fprintf (stderr, "connected\n");
2312:
2313: #ifdef DEBUG
2314: advise (NULLCP, "sent greetings of %d", i);
2315: #endif
2316:
2317: sd = rtc -> rtc_sd;
2318: if (rtc -> rtc_data) {
2319: if ((i = prim2num (rtc -> rtc_data)) == NOTOK
2320: && rtc -> rtc_data -> pe_errno != PE_ERR_NONE)
2321: adios (NULLCP, "error decoding hello: %s (%d)",
2322: pe_error (rtc -> rtc_data -> pe_errno), i);
2323: #ifdef DEBUG
2324: advise (NULLCP, "received greetings of %d", i);
2325: #endif
2326: }
2327:
2328: #ifdef DEBUG
2329: if (isacs) {
2330: advise (NULLCP, "context: %s", oid2ode (acc -> acc_context));
2331:
2332: advise (NULLCP,
2333: "responding AE title: %s, responding PSAP address: %s",
2334: sprintaei (&acc -> acc_respondtitle),
2335: paddr2str (&pc -> pc_responding, NULLNA));
2336:
2337: advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo);
2338:
2339: pl = &pc -> pc_ctxlist;
2340: for (i = 0; i < pl -> pc_nctx; i++)
2341: advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
2342: pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
2343: pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
2344: advise (NULLCP, "default %d", pc -> pc_defctxresult);
2345: advise (NULLCP, "p/s requirements 0x%x/0x%x",
2346: pc -> pc_prequirements, pc -> pc_srequirements);
2347: }
2348: #endif
2349:
2350: RTCFREE (rtc);
2351:
2352: if (ros) {
2353: struct RoSAPindication rois;
2354: register struct RoSAPpreject *rop = &rois.roi_preject;
2355:
2356: if (RoSetService (sd, RoRtService, &rois) == NOTOK)
2357: ros_adios (rop, "set RO/PT fails");
2358:
2359: do_ros (sd);
2360: return;
2361: }
2362:
2363: if (fstat (fileno (stdin), &st) != NOTOK
2364: && (st.st_mode & S_IFMT) == S_IFREG
2365: && (cc = st.st_size) != 0) {
2366: (void) lseek (fileno (stdin), 0L, 0);
2367:
2368: if ((cp = malloc ((unsigned) cc)) == NULL)
2369: adios (NULLCP, "no memory");
2370: for (dp = cp, j = cc; j > 0; dp += i, j -= i)
2371: switch (i = read (fileno (stdin), dp, j)) {
2372: case NOTOK:
2373: adios ("on stdin", "read failed");
2374:
2375: case OK:
2376: adios (NULLCP, "premature end-of-file");
2377:
2378: default:
2379: break;
2380: }
2381: if ((pe = oct2prim (cp, cc)) == NULLPE)
2382: adios (NULLCP, "unable to allocate APDU");
2383: free (cp);
2384: for (i = 10; i > 0; i--) {
2385: #ifdef TIMER
2386: timer (0);
2387: #endif
2388: rts_transferequest (sd, pe);
2389: #ifdef TIMER
2390: timer (cc);
2391: #endif
2392: }
2393: pe_free (pe);
2394: }
2395: else
2396: while (fgets (buffer, sizeof buffer, stdin)) {
2397: if ((pe = oct2prim (buffer, strlen (buffer) + 1)) == NULLPE)
2398: adios (NULLCP, "unable to allocate APDU");
2399: rts_transferequest (sd, pe);
2400: pe_free (pe);
2401: }
2402:
2403: if (isacs) {
2404: if ((pe = int2prim (i = getpid ())) == NULLPE)
2405: adios (NULLCP, "unable to allocate hello");
2406:
2407: if (RtCloseRequest (sd, ACF_NORMAL, pe, acr, rti) == NOTOK)
2408: switch (rta -> rta_reason) {
2409: case RTS_OPERATION:
2410: case RTS_WAITING:
2411: rts_waitfor (sd);
2412: if (RtCloseRequest (sd, ACF_NORMAL, pe, acr, rti)
2413: == OK)
2414: break; /* else fall */
2415:
2416: default:
2417: rts_adios (rta, "RT-CLOSE.REQUEST");
2418: }
2419:
2420: if (!acr -> acr_affirmative) {
2421: (void) RtUAbortRequest (sd, NULLPE, rti);
2422: adios (NULLCP, "release rejected by peer: %d, %d elements",
2423: acr -> acr_reason, acr -> acr_ninfo);
2424: }
2425:
2426: if (mode == echo) {
2427: if (acr -> acr_ninfo != 1)
2428: advise (NULLCP, "got %d elements returned on close",
2429: acr -> acr_ninfo);
2430: if (pe_cmp (pe, acr -> acr_info[0])) {
2431: advise (NULLCP, "data mismatch");
2432: status++;
2433: }
2434: }
2435:
2436: ACRFREE (acr);
2437:
2438: pe_free (pe);
2439: }
2440: else
2441: if (RtEndRequest (sd, rti) == NOTOK)
2442: switch (rta -> rta_reason) {
2443: case RTS_OPERATION:
2444: case RTS_WAITING:
2445: rts_waitfor (sd);
2446: if (RtEndRequest (sd, rti) == OK)
2447: break; /* else fall */
2448:
2449: default:
2450: rts_adios (rta, "RT-END.REQUEST");
2451: }
2452: }
2453:
2454: /* */
2455:
2456: static int rts_transferequest (sd, pe)
2457: int sd;
2458: register PE pe;
2459: {
2460: int result;
2461: struct RtSAPindication rtis;
2462: register struct RtSAPindication *rti = &rtis;
2463: register struct RtSAPabort *rta = &rti -> rti_abort;
2464: register struct RtSAPtransfer *rtt = &rti -> rti_transfer;
2465:
2466: if (RtTransferRequest (sd, pe, NOTOK, rti) == NOTOK)
2467: switch (rta -> rta_reason) {
2468: case RTS_OPERATION:
2469: rts_waitfor (sd);
2470: if (RtTransferRequest (sd, pe, NOTOK, rti) == OK)
2471: break; /* else fall */
2472:
2473: default:
2474: if (RTS_FATAL (rta -> rta_reason))
2475: rts_adios (rta, "RT-TRANSFER.REQUEST");
2476: rts_advise (rta, "RT-TRANSFER.REQUEST");
2477: return;
2478: }
2479:
2480: if (mode == echo)
2481: for (;;)
2482: switch (result = RtWaitRequest (sd, NOTOK, rti)) {
2483: case NOTOK:
2484: rts_adios (rta, "RT-WAIT.REQUEST");
2485:
2486: case OK:
2487: if (pe_cmp (pe, rtt -> rtt_data)) {
2488: advise (NULLCP, "data mismatch");
2489: status++;
2490: }
2491: RTTFREE (rtt);
2492: return;
2493:
2494: case DONE:
2495: rts_event (sd, rti);
2496: break;
2497:
2498: default:
2499: adios (NULLCP, "unknown return from RtWaitRequest=%d",
2500: result);
2501: }
2502: }
2503:
2504: /* */
2505:
2506: static int rts_waitfor (sd)
2507: int sd;
2508: {
2509: int result;
2510: struct RtSAPindication rtis;
2511: register struct RtSAPindication *rti = &rtis;
2512: register struct RtSAPabort *rta = &rti -> rti_abort;
2513: static int priority = 1;
2514:
2515: if (turn)
2516: return;
2517:
2518: if (RtPTurnRequest (sd, priority++, rti) == NOTOK)
2519: rts_adios (rta, "RT-TURN-PLEASE.REQUEST");
2520:
2521: while (!turn)
2522: switch (result = RtWaitRequest (sd, NOTOK, rti)) {
2523: case NOTOK:
2524: rts_adios (rta, "RT-WAIT.REQUEST");
2525:
2526: case OK:
2527: adios (NULLCP, "protocol screw-up");
2528:
2529: case DONE:
2530: rts_event (sd, rti);
2531: break;
2532:
2533: default:
2534: adios (NULLCP, "unknown return from RtWaitRequest=%d",
2535: result);
2536: }
2537: }
2538:
2539: /* */
2540:
2541: static int rts_event (sd, rti)
2542: int sd;
2543: register struct RtSAPindication *rti;
2544: {
2545: register struct RtSAPabort *rta = &rti -> rti_abort;
2546: register struct RtSAPturn *rtu = &rti -> rti_turn;
2547:
2548: switch (rti -> rti_type) {
2549: case RTI_TURN:
2550: if (rtu -> rtu_please) {
2551: if (RtGTurnRequest (sd, rti) == NOTOK)
2552: rts_adios (rta, "RT-TURN-GIVE.REQUEST");
2553: turn = 0;
2554: }
2555: else
2556: turn = 1;
2557: break;
2558:
2559: case RTI_CLOSE:
2560: adios (NULLCP, "got RT-END.INDICATION");
2561:
2562: case RTI_FINISH:
2563: adios (NULLCP, "got RT-CLOSE.INDICATION");
2564:
2565: default:
2566: adios (NULLCP, "unknown indication type=0x%x",
2567: rti -> rti_type);
2568: }
2569: }
2570:
2571: /* */
2572:
2573: static void rts_adios (rta, event)
2574: register struct RtSAPabort *rta;
2575: char *event;
2576: {
2577: rts_advise (rta, event);
2578:
2579: _exit (1);
2580: }
2581:
2582:
2583: static void rts_advise (rta, event)
2584: register struct RtSAPabort *rta;
2585: char *event;
2586: {
2587: char buffer[BUFSIZ];
2588:
2589: if (rta -> rta_cc > 0)
2590: (void) sprintf (buffer, "[%s] %*.*s", RtErrString (rta -> rta_reason),
2591: rta -> rta_cc, rta -> rta_cc, rta -> rta_data);
2592: else
2593: (void) sprintf (buffer, "[%s]", RtErrString (rta -> rta_reason));
2594:
2595: advise (NULLCP, "%s: %s", event, buffer);
2596: }
2597:
2598: /* RoSAP */
2599:
2600: static int ros_main (is, addr)
2601: struct isoservent *is;
2602: char *addr;
2603: {
2604: int sd,
2605: i;
2606: char *cp;
2607: struct SSAPref sfs;
2608: register struct SSAPref *sf;
2609: register struct PSAPaddr *pa;
2610: struct AcSAPconnect accs;
2611: register struct AcSAPconnect *acc = &accs;
2612: struct AcSAPindication acis;
2613: register struct AcSAPindication *aci = &acis;
2614: register struct AcSAPabort *aca = &aci -> aci_abort;
2615: struct RoSAPaddr roas;
2616: register struct RoSAPaddr *roa = &roas;
2617: struct RoSAPconnect rocs;
2618: register struct RoSAPconnect *roc = &rocs;
2619: struct RoSAPindication rois;
2620: register struct RoSAPindication *roi = &rois;
2621: register struct RoSAPpreject *rop = &roi -> roi_preject;
2622: #ifdef DEBUG
2623: struct PSAPconnect *pc = &acc -> acc_connect;
2624: #endif
2625: struct PSAPctxlist pls;
2626: register struct PSAPctxlist *pl = &pls;
2627: AEI aei;
2628: OID oid,
2629: ode;
2630: register PE pe;
2631:
2632: if (isacs) {
2633: if ((aei = str2aei (addr, isacs)) == NULLAEI)
2634: adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs);
2635: if ((pa = aei2addr (aei)) == NULLPA)
2636: adios (NULLCP, "address translation failed");
2637:
2638: cp = mode == echo ? "isode echo pci" : "isode sink pci";
2639: if ((ode = ode2oid (cp)) == NULLOID)
2640: adios (NULLCP, "%s: unknown object descriptor", cp);
2641: ode = oid_cpy (ode);
2642:
2643: if ((sf = addr2ref (PLocalHostName ())) == NULL) {
2644: sf = &sfs;
2645: (void) bzero ((char *) sf, sizeof *sf);
2646: }
2647: pl -> pc_nctx = 1;
2648: pl -> pc_ctx[0].pc_id = 1;
2649: if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID)
2650: adios (NULLCP, "iso asn.1 abstract syntax: unknown");
2651: pl -> pc_ctx[0].pc_asn = oid_cpy (oid);
2652: pl -> pc_ctx[0].pc_atn = NULLOID;
2653:
2654: fprintf (stderr, "%s... ", addr);
2655: (void) fflush (stderr);
2656: if (AcAssocRequest (ode, NULLAEI, aei, NULLPA, pa, pl, ode,
2657: 0, ROS_MYREQUIRE, SERIAL_NONE, 0, sf, NULLPEP, 0, NULLQOS,
2658: acc, aci)
2659: == NOTOK)
2660: acs_adios (aca, "A-ASSOCIATE.REQUEST");
2661:
2662: if (acc -> acc_result != ACS_ACCEPT) {
2663: fprintf (stderr, "failed\n");
2664: adios (NULLCP, "association rejected: [%s]",
2665: AcErrString (acc -> acc_result));
2666: }
2667: fprintf (stderr, "connected\n");
2668:
2669: sd = acc -> acc_sd;
2670:
2671: #ifdef DEBUG
2672: pa = &pc -> pc_responding;
2673: {
2674: advise (NULLCP, "context: %s", oid2ode (acc -> acc_context));
2675:
2676: advise (NULLCP,
2677: "responding AE title: %s, responding PSAP address: %s",
2678: sprintaei (&acc -> acc_respondtitle),
2679: paddr2str (&pc -> pc_responding, NULLNA));
2680:
2681: advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo);
2682:
2683: pl = &pc -> pc_ctxlist;
2684: for (i = 0; i < pl -> pc_nctx; i++)
2685: advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
2686: pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
2687: pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
2688: advise (NULLCP, "default %d", pc -> pc_defctxresult);
2689: advise (NULLCP, "p/s requirements 0x%x/0x%x",
2690: pc -> pc_prequirements, pc -> pc_srequirements);
2691: }
2692: #endif
2693:
2694: ACCFREE (acc);
2695:
2696: if (RoSetService (sd, RoPService, roi) == NOTOK)
2697: ros_adios (rop, "set RO/PT fails");
2698: }
2699: else {
2700: register struct SSAPaddr *sa;
2701:
2702: roa -> roa_port = is -> is_port; /* yikes! */
2703: if ((is = getisoserventbyname ("ros", "ssap")) == NULL)
2704: adios (NULLCP, "ssap/ros: unknown entity");
2705: if ((sa = is2saddr (addr, NULLCP, is)) == NULLSA)
2706: adios (NULLCP, "address translation failed");
2707: roa -> roa_addr = *sa; /* struct copy */
2708:
2709: if ((pe = int2prim (i = getpid ())) == NULLPE)
2710: adios (NULLCP, "unable to allocate hello");
2711:
2712: fprintf (stderr, "%s... ", addr);
2713: (void) fflush (stderr);
2714: if (RoBeginRequest (roa, pe, roc, roi) == NOTOK) {
2715: fprintf (stderr, "failed\n");
2716: ros_adios (rop, "RO-BEGIN.REQUEST");
2717: }
2718:
2719: pe_free (pe);
2720:
2721: if (roc -> roc_result != ROS_ACCEPT) {
2722: fprintf (stderr, "failed\n");
2723: adios (NULLCP, "association rejected: [%s]",
2724: RoErrString (roc -> roc_result));
2725: }
2726: fprintf (stderr, "connected\n");
2727:
2728: #ifdef DEBUG
2729: advise (NULLCP, "sent greetings of %d", i);
2730: #endif
2731:
2732: sd = roc -> roc_sd;
2733: if (roc -> roc_data) {
2734: if ((i = prim2num (roc -> roc_data)) == NOTOK
2735: && roc -> roc_data -> pe_errno != PE_ERR_NONE)
2736: adios (NULLCP, "error decoding hello: %s (%d)",
2737: pe_error (roc -> roc_data -> pe_errno), i);
2738: #ifdef DEBUG
2739: advise (NULLCP, "received greetings of %d", i);
2740: #endif
2741: }
2742: ROCFREE (roc);
2743: }
2744:
2745: do_ros (sd);
2746: }
2747:
2748: /* */
2749:
2750: static int do_ros (sd)
2751: int sd;
2752: {
2753: int cc,
2754: i,
2755: j;
2756: char *cp,
2757: *dp,
2758: buffer[BUFSIZ];
2759: struct RoSAPindication rois;
2760: register struct RoSAPindication *roi = &rois;
2761: register struct RoSAPpreject *rop = &roi -> roi_preject;
2762: struct AcSAPrelease acrs;
2763: register struct AcSAPrelease *acr = &acrs;
2764: register PE pe;
2765: struct stat st;
2766:
2767: if (fstat (fileno (stdin), &st) != NOTOK
2768: && (st.st_mode & S_IFMT) == S_IFREG
2769: && (cc = st.st_size) != 0) {
2770: (void) lseek (fileno (stdin), 0L, 0);
2771:
2772: if ((cp = malloc ((unsigned) cc)) == NULL)
2773: adios (NULLCP, "no memory");
2774: for (dp = cp, j = cc; j > 0; dp += i, j -= i)
2775: switch (i = read (fileno (stdin), dp, j)) {
2776: case NOTOK:
2777: adios ("on stdin", "read failed");
2778:
2779: case OK:
2780: adios (NULLCP, "premature end-of-file");
2781:
2782: default:
2783: break;
2784: }
2785: if ((pe = oct2prim (cp, cc)) == NULLPE)
2786: adios (NULLCP, "unable to allocate invocation argument");
2787: free (cp);
2788: for (i = 10; i > 0; i--) {
2789: #ifdef TIMER
2790: timer (0);
2791: #endif
2792: ros_invokerequest (sd, pe);
2793: #ifdef TIMER
2794: timer (cc);
2795: #endif
2796: }
2797: pe_free (pe);
2798: }
2799: else
2800: while (fgets (buffer, sizeof buffer, stdin)) {
2801: if ((pe = oct2prim (buffer, strlen (buffer) + 1)) == NULLPE)
2802: adios (NULLCP, "unable to allocate invocation argument");
2803: ros_invokerequest (sd, pe);
2804: pe_free (pe);
2805: }
2806:
2807: if (isrts) {
2808: struct RtSAPindication rtis;
2809: register struct RtSAPindication *rti = &rtis;
2810: register struct RtSAPabort *rta = &rti -> rti_abort;
2811:
2812: if (isacs) {
2813: if (RtCloseRequest (sd, ACF_NORMAL, NULLPE, acr, rti) == NOTOK)
2814: switch (rta -> rta_reason) {
2815: case RTS_OPERATION:
2816: case RTS_WAITING:
2817: rts_waitfor (sd);
2818: if (RtCloseRequest (sd, ACF_NORMAL, NULLPE, acr, rti)
2819: == OK)
2820: break; /* else fall */
2821:
2822: default:
2823: rts_adios (rta, "RT-CLOSE.REQUEST");
2824: }
2825:
2826: if (!acr -> acr_affirmative) {
2827: (void) RtUAbortRequest (sd, NULLPE, rti);
2828: adios (NULLCP, "release rejected by peer: %d, %d elements",
2829: acr -> acr_reason, acr -> acr_ninfo);
2830: }
2831: }
2832: else
2833: if (RtEndRequest (sd, rti) == NOTOK)
2834: switch (rta -> rta_reason) {
2835: case RTS_OPERATION:
2836: case RTS_WAITING:
2837: rts_waitfor (sd);
2838: if (RtEndRequest (sd, rti) == OK)
2839: break; /* else fall */
2840:
2841: default:
2842: rts_adios (rta, "RT-END.REQUEST");
2843: }
2844: }
2845: else
2846: if (isacs) {
2847: struct AcSAPindication acis;
2848: register struct AcSAPindication *aci = &acis;
2849: register struct AcSAPabort *aca = &aci -> aci_abort;
2850:
2851: if (AcRelRequest (sd, ACF_NORMAL, NULLPEP, 0, NOTOK, acr, aci)
2852: == NOTOK)
2853: acs_adios (aca, "A-RELEASE.REQUEST");
2854:
2855: if (!acr -> acr_affirmative) {
2856: (void) AcUAbortRequest (sd, NULLPEP, 0, aci);
2857: adios (NULLCP, "release rejected by peer: %d, %d elements",
2858: acr -> acr_reason, acr -> acr_ninfo);
2859: }
2860: ACRFREE (acr);
2861: }
2862: else
2863: if (RoEndRequest (sd, ROS_NOPRIO, roi) == NOTOK)
2864: ros_adios (rop, "RO-END.REQUEST");
2865: }
2866:
2867: /* */
2868:
2869: static int ros_invokerequest (sd, pe)
2870: int sd;
2871: PE pe;
2872: {
2873: int result;
2874: struct RoSAPindication rois;
2875: register struct RoSAPindication *roi = &rois;
2876: register struct RoSAPpreject *rop = &roi -> roi_preject;
2877: static int id = 0;
2878: static int op = 0;
2879:
2880: switch (result = RoInvokeRequest (sd, op++, ROS_SYNC, pe, ++id, NULLIP,
2881: ROS_NOPRIO, roi)) {
2882: case NOTOK:
2883: if (ROS_FATAL (rop -> rop_reason))
2884: ros_adios (rop, "RO-INVOKE.REQUEST");
2885: ros_advise (rop, "RO-INVOKE.REQUEST");
2886: break;
2887:
2888: case OK:
2889: switch (roi -> roi_type) {
2890: case ROI_INVOKE:
2891: adios (NULLCP, "got RO-INVOKE.INDICATION");
2892:
2893: case ROI_RESULT:
2894: {
2895: register struct RoSAPresult *ror = &roi -> roi_result;
2896:
2897: if (ror -> ror_id != id) {
2898: advise (NULLCP, "id mismatch (wanted %d, got %d)",
2899: id, ror -> ror_id);
2900: status++;
2901: if (RoURejectRequest (sd, &ror -> ror_id,
2902: ROS_RRP_UNRECOG, ROS_NOPRIO, roi) == NOTOK)
2903: ros_adios (rop, "RO-REJECT-U.REQUEST");
2904: }
2905: else
2906: if (mode == echo
2907: && pe_cmp (pe, ror -> ror_result)) {
2908: advise (NULLCP, "data mismatch");
2909: status++;
2910: }
2911:
2912: RORFREE (ror);
2913: }
2914: break;
2915:
2916: case ROI_ERROR:
2917: {
2918: register struct RoSAPerror *roe = &roi -> roi_error;
2919:
2920: if (roe -> roe_id != id) {
2921: advise (NULLCP, "id mismatch (wanted %d, got %d)",
2922: id, roe -> roe_id);
2923: status++;
2924: if (RoURejectRequest (sd, &roe -> roe_id,
2925: ROS_REP_UNRECOG, ROS_NOPRIO, roi) == NOTOK)
2926: ros_adios (rop, "RO-REJECT-U.REQUEST");
2927: }
2928: else
2929: if (mode == echo
2930: && pe_cmp (pe, roe -> roe_param)) {
2931: advise (NULLCP, "data mismatch");
2932: status++;
2933: }
2934:
2935: ROEFREE (roe);
2936: }
2937: break;
2938:
2939: case ROI_UREJECT:
2940: {
2941: register struct RoSAPureject *rou = &roi -> roi_ureject;
2942:
2943: if (rou -> rou_noid)
2944: advise (NULLCP, "RO-REJECT-U.INDICATION: %s",
2945: RoErrString (rou -> rou_reason));
2946: else
2947: advise (NULLCP, "RO-REJECT-U.INDICATION: %s (id=%d)",
2948: RoErrString (rou -> rou_reason),
2949: rou -> rou_id);
2950: if (!rou -> rou_noid && rou -> rou_id != id) {
2951: advise (NULLCP, "id mismatch (wanted %d, got %d)",
2952: id, rou -> rou_id);
2953: status++;
2954: }
2955: }
2956: break;
2957:
2958: default:
2959: adios (NULLCP, "unknown indication type=%d",
2960: roi -> roi_type);
2961: }
2962: if (isrts)
2963: turn = 0;
2964: break;
2965:
2966: case DONE:
2967: adios (NULLCP, "got RO-END.INDICATION");
2968:
2969: default:
2970: adios (NULLCP, "unknown return from RoInvokeRequest=%d", result);
2971: }
2972: }
2973:
2974:
2975: /* */
2976:
2977: static void ros_adios (rop, event)
2978: register struct RoSAPpreject *rop;
2979: char *event;
2980: {
2981: ros_advise (rop, event);
2982:
2983: _exit (1);
2984: }
2985:
2986:
2987: static void ros_advise (rop, event)
2988: register struct RoSAPpreject *rop;
2989: char *event;
2990: {
2991: char buffer[BUFSIZ];
2992:
2993: if (rop -> rop_cc > 0)
2994: (void) sprintf (buffer, "[%s] %*.*s", RoErrString (rop -> rop_reason),
2995: rop -> rop_cc, rop -> rop_cc, rop -> rop_data);
2996: else
2997: (void) sprintf (buffer, "[%s]", RoErrString (rop -> rop_reason));
2998:
2999: advise (NULLCP, "%s: %s", event, buffer);
3000: }
3001:
3002: /* TIMER */
3003:
3004: #ifdef TIMER
3005:
3006: #ifndef NBBY
3007: #define NBBY 8
3008: #endif
3009:
3010:
3011: #ifndef TMS
3012: static timer (cc)
3013: int cc;
3014: {
3015: int bytes;
3016: long ms;
3017: float bs;
3018: struct timeval stop,
3019: td;
3020: static struct timeval start;
3021:
3022: if (cc == 0) {
3023: (void) gettimeofday (&start, (struct timezone *) 0);
3024: return;
3025: }
3026: else
3027: (void) gettimeofday (&stop, (struct timezone *) 0);
3028:
3029: tvsub (&td, &stop, &start);
3030: ms = (td.tv_sec * 1000) + (td.tv_usec / 1000);
3031: bytes = mode == echo ? cc * 2 : cc;
3032: bs = (((float) bytes * NBBY * 1000) / (float) (ms ? ms : 1)) / NBBY;
3033:
3034: advise (NULLCP, "%d bytes %s in %d.%02d seconds (%.2f Kbytes/s)",
3035: cc, mode == echo ? "echoed" : "sunk",
3036: td.tv_sec, td.tv_usec / 10000, bs / 1024);
3037: }
3038:
3039:
3040: static tvsub (tdiff, t1, t0)
3041: register struct timeval *tdiff,
3042: *t1,
3043: *t0;
3044: {
3045:
3046: tdiff -> tv_sec = t1 -> tv_sec - t0 -> tv_sec;
3047: tdiff -> tv_usec = t1 -> tv_usec - t0 -> tv_usec;
3048: if (tdiff -> tv_usec < 0)
3049: tdiff -> tv_sec--, tdiff -> tv_usec += 1000000;
3050: }
3051: #else
3052: long times ();
3053:
3054:
3055: static timer (cc)
3056: int cc;
3057: {
3058: int bytes;
3059: long ms;
3060: float bs;
3061: long stop,
3062: td,
3063: secs,
3064: msecs;
3065: struct tms tm;
3066: static long start;
3067:
3068: if (cc == 0) {
3069: start = times (&tm);
3070: return;
3071: }
3072: else
3073: stop = times (&tm);
3074:
3075: td = stop - start;
3076: secs = td / 60, msecs = (td % 60) * 1000 / 60;
3077: ms = (secs * 1000) + msecs;
3078: bytes = mode == echo ? cc * 2 : cc;
3079: bs = (((float) bytes * NBBY * 1000) / (float) (ms ? ms : 1)) / NBBY;
3080:
3081: advise (NULLCP, "%d bytes %s in %d.%02d seconds (%.2f KBytes/s)",
3082: cc, mode == echo ? "echoed" : "sunk",
3083: secs, msecs / 10, bs / 1024);
3084: }
3085: #endif
3086: #endif
3087:
3088: /* QBUF */
3089:
3090: static int qcmp (b, qb, l)
3091: register char *b;
3092: register struct qbuf *qb;
3093: register int l;
3094: {
3095: register struct qbuf *qp;
3096:
3097: for (qp = qb -> qb_forw; qp != qb; qp = qp -> qb_forw) {
3098: if ((l -= qp -> qb_len) < 0) {
3099: advise (NULLCP, "length mismatch(1)");
3100: return NOTOK;
3101: }
3102:
3103: if (bcmp (b, qp -> qb_data, qp -> qb_len)) {
3104: advise (NULLCP, "data mismatch");
3105: return NOTOK;
3106: }
3107:
3108: b += qp -> qb_len;
3109: }
3110:
3111: if (l != 0) {
3112: advise (NULLCP, "length mismatch(2)");
3113: return NOTOK;
3114: }
3115:
3116: return OK;
3117: }
3118:
3119: /* ERRORS */
3120:
3121: #ifndef lint
3122: void _advise ();
3123:
3124:
3125: void adios (va_alist)
3126: va_dcl
3127: {
3128: va_list ap;
3129:
3130: va_start (ap);
3131:
3132: _advise (ap);
3133:
3134: va_end (ap);
3135:
3136: _exit (1);
3137: }
3138: #else
3139: /* VARARGS */
3140:
3141: void adios (what, fmt)
3142: char *what,
3143: *fmt;
3144: {
3145: adios (what, fmt);
3146: }
3147: #endif
3148:
3149:
3150: #ifndef lint
3151: void advise (va_alist)
3152: va_dcl
3153: {
3154: va_list ap;
3155:
3156: va_start (ap);
3157:
3158: _advise (ap);
3159:
3160: va_end (ap);
3161: }
3162:
3163:
3164: static void _advise (ap)
3165: va_list ap;
3166: {
3167: char buffer[BUFSIZ];
3168:
3169: asprintf (buffer, ap);
3170:
3171: (void) fflush (stdout);
3172:
3173: fprintf (stderr, "%s: ", myname);
3174: (void) fputs (buffer, stderr);
3175: (void) fputc ('\n', stderr);
3176:
3177: (void) fflush (stderr);
3178: }
3179: #else
3180: /* VARARGS */
3181:
3182: void advise (what, fmt)
3183: char *what,
3184: *fmt;
3185: {
3186: advise (what, fmt);
3187: }
3188: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.