|
|
1.1 root 1: /* ro2ss.c - ROPM: SSAP interface */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2ss.c,v 7.1 90/07/01 21:05:48 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/rosap/RCS/ro2ss.c,v 7.1 90/07/01 21:05:48 mrose Exp $
9: *
10: * Based on an TCP-based implementation by George Michaelson of University
11: * College London.
12: *
13: *
14: * $Log: ro2ss.c,v $
15: * Revision 7.1 90/07/01 21:05:48 mrose
16: * pepsy
17: *
18: * Revision 6.0 89/03/18 23:42:14 mrose
19: * Release 5.0
20: *
21: */
22:
23: /*
24: * NOTICE
25: *
26: * Acquisition, use, and distribution of this module and related
27: * materials are subject to the restrictions of a license agreement.
28: * Consult the Preface in the User's Manual for the full terms of
29: * this agreement.
30: *
31: */
32:
33:
34: /* LINTLIBRARY */
35:
36: #include <stdio.h>
37: #include "ROS-types.h"
38: #include "../acsap/OACS-types.h"
39: #include "ropkt.h"
40: #include "tailor.h"
41:
42: /* DATA */
43:
44: #define doSSabort ss2rosabort
45:
46:
47: int ssDATAser (), ssTOKENser (), ssSYNCser (), ssACTIVITYser (),
48: ssREPORTser (), ssFINISHser (), ssABORTser ();
49:
50: /* bind underlying service */
51:
52: int RoSService (acb, roi)
53: register struct assocblk *acb;
54: struct RoSAPindication *roi;
55: {
56: if (acb -> acb_flags & (ACB_ACS | ACB_RTS))
57: return rosaplose (roi, ROS_OPERATION, NULLCP,
58: "not an association descriptor for ROS on session");
59:
60: acb -> acb_putosdu = ro2sswrite;
61: acb -> acb_rowaitrequest = ro2sswait;
62: acb -> acb_getosdu = qbuf2pe;
63: acb -> acb_ready = ro2ssready;
64: acb -> acb_rosetindications = ro2ssasync;
65: acb -> acb_roselectmask = ro2ssmask;
66: acb -> acb_ropktlose = ro2sslose;
67:
68: return OK;
69: }
70:
71: /* define vectors for INDICATION events */
72:
73: #define e(i) (indication ? (i) : NULLIFP)
74:
75:
76: /* ARGSUSED */
77:
78: int ro2ssasync (acb, indication, roi)
79: register struct assocblk *acb;
80: IFP indication;
81: struct RoSAPindication *roi;
82: {
83: struct SSAPindication sis;
84: register struct SSAPabort *sa = &sis.si_abort;
85:
86: if (SSetIndications (acb -> acb_fd, e (ssDATAser), e (ssTOKENser),
87: e (ssSYNCser), e (ssACTIVITYser), e (ssREPORTser),
88: e (ssFINISHser), e (ssABORTser), &sis) == NOTOK)
89: switch (sa -> sa_reason) {
90: case SC_WAITING:
91: return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);
92:
93: default:
94: (void) ss2roslose (acb, roi, "SSetIndications", sa);
95: freeacblk (acb);
96: return NOTOK;
97: }
98:
99: if (acb -> acb_rosindication = indication)
100: acb -> acb_flags |= ACB_ASYN;
101: else
102: acb -> acb_flags &= ~ACB_ASYN;
103:
104: return OK;
105: }
106:
107: #undef e
108:
109: /* map association descriptors for select() */
110:
111: /* ARGSUSED */
112:
113: int ro2ssmask (acb, mask, nfds, roi)
114: register struct assocblk *acb;
115: fd_set *mask;
116: int *nfds;
117: struct RoSAPindication *roi;
118: {
119: struct SSAPindication sis;
120: register struct SSAPabort *sa = &sis.si_abort;
121:
122: if (SSelectMask (acb -> acb_fd, mask, nfds, &sis) == NOTOK)
123: switch (sa -> sa_reason) {
124: case SC_WAITING:
125: return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);
126:
127: default:
128: (void) ss2roslose (acb, roi, "SSelectMask", sa);
129: freeacblk (acb);
130: return NOTOK;
131: }
132:
133: return OK;
134: }
135:
136: /* protocol-level abort */
137:
138: int ro2sslose (acb, result)
139: register struct assocblk *acb;
140: int result;
141: {
142: int len;
143: char *base;
144: PE pe;
145: struct SSAPindication sis;
146:
147: base = NULL, len = 0;
148: /* begin AbortInformation PSDU (pseudo) */
149: if (pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SET)) {
150: if (set_add (pe, num2prim (result, PE_CLASS_CONT, 0)) != NOTOK)
151: (void) pe2ssdu (pe, &base, &len);
152:
153: PLOGP (rosap_log,OACS_AbortInformation, pe, "AbortInformation",
154: 0);
155:
156: pe_free (pe);
157: }
158: /* end AbortInformation PSDU */
159:
160: (void) SUAbortRequest (acb -> acb_fd, base, len, &sis);
161: acb -> acb_fd = NOTOK;
162:
163: if (base)
164: free (base);
165: }
166:
167: /* SSAP interface */
168:
169: int ro2sswait (acb, invokeID, secs, roi)
170: register struct assocblk *acb;
171: int *invokeID,
172: secs;
173: register struct RoSAPindication *roi;
174: {
175: int result;
176: struct SSAPdata sxs;
177: register struct SSAPdata *sx = &sxs;
178: struct SSAPindication sis;
179: register struct SSAPindication *si = &sis;
180:
181: if (acb -> acb_apdu) {
182: result = acb2osdu (acb, NULLIP, acb -> acb_apdu, roi);
183: acb -> acb_apdu = NULLPE;
184:
185: return result;
186: }
187:
188: for (;;) {
189: switch (result = SReadRequest (acb -> acb_fd, sx, secs, si)) {
190: case NOTOK:
191: return doSSabort (acb, &si -> si_abort, roi);
192:
193: case OK:
194: if ((result = doSSdata (acb, invokeID, sx, roi)) != OK)
195: return (result != DONE ? result : OK);
196: continue;
197:
198: case DONE:
199: switch (si -> si_type) {
200: case SI_TOKEN:
201: if (doSStokens (acb, &si -> si_token, roi) == NOTOK)
202: return NOTOK;
203: continue;
204:
205: case SI_SYNC:
206: if (doSSsync (acb, &si -> si_sync, roi) == NOTOK)
207: return NOTOK;
208: continue;
209:
210: case SI_ACTIVITY:
211: if (doSSactivity (acb, &si -> si_activity, roi) == NOTOK)
212: return NOTOK;
213: continue;
214:
215: case SI_REPORT:
216: if (doSSreport (acb, &si -> si_report, roi) == NOTOK)
217: return NOTOK;
218: continue;
219:
220: case SI_FINISH:
221: if (doSSfinish (acb, &si -> si_finish, roi) == NOTOK)
222: return NOTOK;
223: return DONE;
224:
225: default:
226: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
227: "unknown indication (0x%x) from session",
228: si -> si_type);
229: break;
230: }
231: break;
232:
233: default:
234: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
235: "unexpected return from SReadRequest=%d", result);
236: break;
237: }
238: break;
239: }
240:
241: freeacblk (acb);
242:
243: return NOTOK;
244: }
245:
246: /* */
247:
248: /* ARGSUSED */
249:
250: int ro2ssready (acb, priority, roi)
251: register struct assocblk *acb;
252: int priority;
253: struct RoSAPindication *roi;
254: {
255: int result;
256: PE pe;
257: struct SSAPdata sxs;
258: register struct SSAPdata *sx = &sxs;
259: struct SSAPindication sis;
260: struct SSAPindication *si = &sis;
261: struct SSAPabort *sa = &si -> si_abort;
262:
263: if (acb -> acb_apdu || (acb -> acb_flags & ACB_CLOSING))
264: return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);
265:
266: if (!(acb -> acb_requirements & SR_HALFDUPLEX)
267: || (acb -> acb_flags & ACB_TURN))
268: return OK;
269:
270: if (!(acb -> acb_flags & ACB_PLEASE)) {
271: if (SPTokenRequest (acb -> acb_fd, ST_DAT_TOKEN, NULLCP, 0, si)
272: == NOTOK) {
273: (void) ss2roslose (acb, roi, "SPTokenRequest", sa);
274: goto out;
275: }
276:
277: acb -> acb_flags |= ACB_PLEASE;
278: }
279:
280: for (;;) {
281: switch (result = SReadRequest (acb -> acb_fd, sx, NOTOK, si)) {
282: case NOTOK:
283: return doSSabort (acb, &si -> si_abort, roi);
284:
285: case OK:
286: if (sx -> sx_type != SX_NORMAL) {
287: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
288: "unexpected data indication (0x%x)",
289: sx -> sx_type);
290: goto bad_sx;
291: }
292: if (pe = qbuf2pe (&sx -> sx_qbuf, sx -> sx_cc, &result)) {
293: acb -> acb_apdu = pe;
294: return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);
295: }
296: if (result != PS_ERR_NMEM) {
297: (void) rosapreject (acb, roi, ROS_GP_STRUCT, NULLCP, "%s",
298: ps_error (result));
299: continue;
300: }
301:
302: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, "%s",
303: ps_error (result));
304: bad_sx: ;
305: SXFREE (sx);
306: goto out;
307:
308: case DONE:
309: switch (si -> si_type) {
310: case SI_TOKEN:
311: if (doSStokens (acb, &si -> si_token, roi) == NOTOK)
312: return NOTOK;
313: return OK;
314:
315: case SI_SYNC:
316: if (doSSsync (acb, &si -> si_sync, roi) == NOTOK)
317: return NOTOK;
318: continue;
319:
320: case SI_ACTIVITY:
321: if (doSSactivity (acb, &si -> si_activity, roi) == NOTOK)
322: return NOTOK;
323: continue;
324:
325: case SI_REPORT:
326: if (doSSreport (acb, &si -> si_report, roi) == NOTOK)
327: return NOTOK;
328: continue;
329:
330: case SI_FINISH:
331: if (doSSfinish (acb, &si -> si_finish, roi) == NOTOK)
332: return NOTOK;
333: return DONE;
334:
335: default:
336: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
337: "unknown indication (0x%x) from session",
338: si -> si_type);
339: break;
340: }
341: break;
342:
343: default:
344: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
345: "unexpected return from SReadRequest=%d", result);
346: break;
347: }
348: break;
349: }
350:
351: out: ;
352: freeacblk (acb);
353:
354: return NOTOK;
355: }
356:
357: /* */
358:
359: /* ARGSUSED */
360:
361: int ro2sswrite (acb, pe, fe, priority, roi)
362: register struct assocblk *acb;
363: register PE pe;
364: PE fe;
365: int priority;
366: struct RoSAPindication *roi;
367: {
368: int result;
369: register struct udvec *vv;
370: struct udvec *uv;
371: struct SSAPindication sis;
372: register struct SSAPindication *si = &sis;
373: register struct SSAPabort *sa = &si -> si_abort;
374:
375: PLOGP (rosap_log,ROS_OPDU, pe, "OPDU", 0);
376:
377: uv = NULL;
378: if ((result = pe2uvec (pe, &uv)) == NOTOK)
379: (void) rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory");
380: else
381: if ((result = SWriteRequest (acb -> acb_fd, 0, uv, si)) == NOTOK)
382: (void) ss2roslose (acb, roi, "SWriteRequest", sa);
383: else
384: result = OK;
385:
386: if (fe)
387: (void) pe_extract (pe, fe);
388: pe_free (pe);
389:
390: if (uv) {
391: for (vv = uv; vv -> uv_base; vv++)
392: if (!vv -> uv_inline)
393: free ((char *) vv -> uv_base);
394: free ((char *) uv);
395: }
396:
397: if (result == NOTOK)
398: freeacblk (acb);
399:
400: return result;
401: }
402:
403: /* */
404:
405: static int doSSdata (acb, invokeID, sx, roi)
406: register struct assocblk *acb;
407: int *invokeID;
408: register struct SSAPdata *sx;
409: struct RoSAPindication *roi;
410: {
411: int result;
412: register PE pe;
413:
414: if (sx -> sx_type != SX_NORMAL) {
415: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
416: "unexpected data indication (0x%x)", sx -> sx_type);
417: goto out;
418: }
419:
420: if (pe = (*acb -> acb_getosdu) (&sx -> sx_qbuf, sx -> sx_cc, &result))
421: return acb2osdu (acb, invokeID, pe, roi);
422:
423: if (result != PS_ERR_NMEM)
424: return rosapreject (acb, roi, ROS_GP_STRUCT, NULLCP, "%s",
425: ps_error (result));
426:
427: (void) ropktlose (acb, roi, ROS_CONGEST, NULLCP, "%s",
428: ps_error (result));
429:
430: out: ;
431: SXFREE (sx);
432:
433: freeacblk (acb);
434: return NOTOK;
435: }
436:
437: /* */
438:
439: static int doSStokens (acb, st, roi)
440: register struct assocblk *acb;
441: register struct SSAPtoken *st;
442: struct RoSAPindication *roi;
443: {
444: int result;
445: struct SSAPindication sis;
446: struct SSAPindication *si = &sis;
447: struct SSAPabort *sa = &si -> si_abort;
448:
449: switch (st -> st_type) {
450: case ST_CONTROL:
451: break;
452:
453: case ST_PLEASE:
454: if (!(acb -> acb_requirements & SR_HALFDUPLEX))
455: break;
456: if (!(acb -> acb_flags & ACB_TURN))
457: break; /* error - do not have turn */
458:
459: result = SGTokenRequest (acb -> acb_fd, ST_DAT_TOKEN, si);
460:
461: if (result == NOTOK) {
462: (void) ss2roslose (acb, roi, "SGTokenRequest", sa);
463: goto out;
464: }
465: acb -> acb_flags &= ~ACB_TURN;
466: STFREE (st);
467: return result;
468:
469: case ST_GIVE:
470: if (!(acb -> acb_requirements & SR_HALFDUPLEX))
471: break;
472: if (acb -> acb_flags & ACB_TURN)
473: break; /* error - have turn already */
474:
475: if (st -> st_tokens & ST_DAT_TOKEN) {
476: acb -> acb_flags |= ACB_TURN;
477: acb -> acb_flags &= ~ACB_PLEASE;
478: }
479: return result;
480:
481: default:
482: break;
483: }
484:
485: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
486: "unexpected token indication (0x%x)", st -> st_type);
487:
488: out: ;
489: STFREE (st);
490:
491: freeacblk (acb);
492: return NOTOK;
493: }
494:
495: /* */
496:
497: static int doSSsync (acb, sn, roi)
498: register struct assocblk *acb;
499: register struct SSAPsync *sn;
500: struct RoSAPindication *roi;
501: {
502: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
503: "unexpected sync indication (0x%x)", sn -> sn_type);
504:
505: SNFREE (sn);
506:
507: freeacblk (acb);
508: return NOTOK;
509: }
510:
511: /* */
512:
513: static int doSSactivity (acb, sv, roi)
514: register struct assocblk *acb;
515: register struct SSAPactivity *sv;
516: struct RoSAPindication *roi;
517: {
518: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
519: "unexpected activity indication (0x%x)", sv -> sv_type);
520:
521: SVFREE (sv);
522:
523: freeacblk (acb);
524: return NOTOK;
525: }
526:
527: /* */
528:
529: static int doSSreport (acb, sp, roi)
530: register struct assocblk *acb;
531: register struct SSAPreport *sp;
532: struct RoSAPindication *roi;
533: {
534: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
535: "unexpected exception report indication (0x%x)", sp -> sp_peer);
536:
537: SPFREE (sp);
538:
539: freeacblk (acb);
540: return NOTOK;
541: }
542:
543: /* */
544:
545: static int doSSfinish (acb, sf, roi)
546: register struct assocblk *acb;
547: struct SSAPfinish *sf;
548: struct RoSAPindication *roi;
549: {
550: SFFREE (sf);
551:
552: if (acb -> acb_flags & ACB_INIT) {
553: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
554: "association management botched");
555: freeacblk (acb);
556: return NOTOK;
557: }
558:
559: acb -> acb_flags |= ACB_FINN;
560: roi -> roi_type = ROI_END;
561: {
562: register struct RoSAPend *roe = &roi -> roi_end;
563:
564: bzero ((char *) roe, sizeof *roe);
565: }
566:
567: return DONE;
568: }
569:
570: /* */
571:
572: int ss2rosabort (acb, sa, roi)
573: register struct assocblk *acb;
574: register struct SSAPabort *sa;
575: struct RoSAPindication *roi;
576: {
577: int result;
578: register PE pe;
579: struct type_OACS_AbortInformation *pabort
580: = (struct type_OACS_AbortInformation *) 0;
581: int acsap_abort = -1;
582:
583: if (!sa -> sa_peer) {
584: if (sa -> sa_reason == SC_TIMER)
585: return rosaplose (roi, ROS_TIMER, NULLCP, NULLCP);
586:
587: (void) ss2roslose (acb, roi, NULLCP, sa);
588: goto out;
589: }
590:
591: if (sa -> sa_cc == 0) {
592: (void) rosaplose (roi, ROS_ABORTED, NULLCP, NULLCP);
593: goto out;
594: }
595:
596: if ((pe = ssdu2pe (sa -> sa_info, sa -> sa_cc, NULLCP, &result))
597: == NULLPE) {
598: (void) rosaplose (roi, ROS_PROTOCOL, NULLCP, NULLCP);
599: goto out;
600: }
601: result = parse_OACS_AbortInformation (pe, 1, NULLIP, NULLVP, NULLCP);
602:
603: #ifdef DEBUG
604: if (result != NOTOK && (rosap_log -> ll_events & LLOG_PDUS))
605: pvpdu (rosap_log, print_OACS_AbortInformation_P, pe,
606: "AbortInformation", 1);
607: #endif
608:
609: pe_free (pe);
610: if (result == NOTOK) {
611: (void) rosaplose (roi, ROS_PROTOCOL, "%s", PY_pepy);
612: goto out;
613: }
614: acsap_abort = pabort->member_OACS_6->parm;
615: switch (acsap_abort) {
616: case ABORT_LSP:
617: case ABORT_TMP:
618: result = ROS_REMOTE;
619: break;
620:
621: default:
622: result = ROS_PROTOCOL;
623: break;
624: }
625: (void) rosaplose (roi, result, NULLCP, NULLCP);
626:
627: out: ;
628: SAFREE (sa);
629: acb -> acb_fd = NOTOK;
630: freeacblk (acb);
631: if (pabort)
632: free_OACS_AbortInformation(pabort);
633:
634: return NOTOK;
635: }
636:
637: /* */
638:
639: static int ssDATAser (sd, sx)
640: int sd;
641: register struct SSAPdata *sx;
642: {
643: IFP handler;
644: register struct assocblk *acb;
645: struct RoSAPindication rois;
646: register struct RoSAPindication *roi = &rois;
647:
648: if ((acb = findacblk (sd)) == NULL)
649: return;
650: handler = acb -> acb_rosindication;
651:
652: if (doSSdata (acb, NULLIP, sx, roi) != OK)
653: (*handler) (sd, roi);
654: }
655:
656: /* */
657:
658: static int ssTOKENser (sd, st)
659: int sd;
660: register struct SSAPtoken *st;
661: {
662: IFP handler;
663: register struct assocblk *acb;
664: struct RoSAPindication rois;
665: register struct RoSAPindication *roi = &rois;
666:
667: if ((acb = findacblk (sd)) == NULL)
668: return;
669: handler = acb -> acb_rosindication;
670:
671: if (doSStokens (acb, st, roi) != OK)
672: (*handler) (sd, roi);
673: }
674:
675: /* */
676:
677: static int ssSYNCser (sd, sn)
678: int sd;
679: register struct SSAPsync *sn;
680: {
681: IFP handler;
682: register struct assocblk *acb;
683: struct RoSAPindication rois;
684: register struct RoSAPindication *roi = &rois;
685:
686: if ((acb = findacblk (sd)) == NULL)
687: return;
688: handler = acb -> acb_rosindication;
689:
690: if (doSSsync (acb, sn, roi) != OK)
691: (*handler) (sd, roi);
692: }
693:
694: /* */
695:
696: static int ssACTIVITYser (sd, sv)
697: int sd;
698: register struct SSAPactivity *sv;
699: {
700: IFP handler;
701: register struct assocblk *acb;
702: struct RoSAPindication rois;
703: register struct RoSAPindication *roi = &rois;
704:
705: if ((acb = findacblk (sd)) == NULL)
706: return;
707: handler = acb -> acb_rosindication;
708:
709: if (doSSactivity (acb, sv, roi) != OK)
710: (*handler) (sd, roi);
711: }
712:
713: /* */
714:
715: static int ssREPORTser (sd, sp)
716: int sd;
717: register struct SSAPreport *sp;
718: {
719: IFP handler;
720: register struct assocblk *acb;
721: struct RoSAPindication rois;
722: register struct RoSAPindication *roi = &rois;
723:
724: if ((acb = findacblk (sd)) == NULL)
725: return;
726: handler = acb -> acb_rosindication;
727:
728: if (doSSreport (acb, sp, roi) != OK)
729: (*handler) (sd, roi);
730: }
731:
732: /* */
733:
734: static int ssFINISHser (sd, sf)
735: int sd;
736: struct SSAPfinish *sf;
737: {
738: IFP handler;
739: register struct assocblk *acb;
740: struct RoSAPindication rois;
741: register struct RoSAPindication *roi = &rois;
742:
743: if ((acb = findacblk (sd)) == NULL)
744: return;
745: handler = acb -> acb_rosindication;
746:
747: (void) doSSfinish (acb, sf, roi);
748:
749: (*handler) (sd, roi);
750: }
751:
752: /* */
753:
754: static int ssABORTser (sd, sa)
755: int sd;
756: register struct SSAPabort *sa;
757: {
758: IFP handler;
759: register struct assocblk *acb;
760: struct RoSAPindication rois;
761: register struct RoSAPindication *roi = &rois;
762:
763: if ((acb = findacblk (sd)) == NULL)
764: return;
765: handler = acb -> acb_rosindication;
766:
767: (void) doSSabort (acb, sa, roi);
768:
769: (*handler) (sd, roi);
770: }
771:
772: /* */
773:
774: int ss2roslose (acb, roi, event, sa)
775: register struct assocblk *acb;
776: register struct RoSAPindication *roi;
777: char *event;
778: register struct SSAPabort *sa;
779: {
780: int reason;
781: char *cp,
782: buffer[BUFSIZ];
783:
784: if (event)
785: SLOG (rosap_log, LLOG_EXCEPTIONS, NULLCP,
786: (sa -> sa_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event,
787: SErrString (sa -> sa_reason), sa -> sa_cc, sa -> sa_cc,
788: sa -> sa_data));
789:
790: cp = "";
791: switch (sa -> sa_reason) {
792: case SC_SSAPID:
793: case SC_SSUSER:
794: case SC_ADDRESS:
795: reason = ROS_ADDRESS;
796: break;
797:
798: case SC_REFUSED:
799: reason = ROS_REFUSED;
800: break;
801:
802: case SC_CONGEST:
803: reason = ROS_CONGEST;
804: break;
805:
806: default:
807: (void) sprintf (cp = buffer, " (%s at session)",
808: SErrString (sa -> sa_reason));
809: case SC_TRANSPORT:
810: case SC_ABORT:
811: reason = ROS_SESSION;
812: break;
813: }
814:
815: if (sa -> sa_cc > 0)
816: return ropktlose (acb, roi, reason, NULLCP, "%*.*s%s",
817: sa -> sa_cc, sa -> sa_cc, sa -> sa_data, cp);
818: else
819: return ropktlose (acb, roi, reason, NULLCP, "%s", *cp ? cp + 1 : cp);
820: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.