|
|
1.1 root 1: /* vtuser.c - VT user routines */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/vt/RCS/vtuser.c,v 7.2 90/07/09 14:52:10 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/vt/RCS/vtuser.c,v 7.2 90/07/09 14:52:10 mrose Exp $
9: *
10: *
11: * $Log: vtuser.c,v $
12: * Revision 7.2 90/07/09 14:52:10 mrose
13: * sync
14: *
15: * Revision 7.1 89/11/30 23:51:45 mrose
16: * pa2str
17: *
18: * Revision 7.0 89/11/23 22:32:00 mrose
19: * Release 6.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: #include "vtpm.h"
35: #include "sector1.h"
36: #include "sector5.h"
37: #include <sys/ioctl.h>
38:
39: #undef PTYBUG /*When testing Break and demon not started from rc.local,
40: this turns off resetting local echo so ioctl to pty
41: will not cause demon to hang up.
42: */
43:
44: #undef PEPYPARM
45: #define PEPYPARM int *
46:
47:
48: extern char peerhost[];
49: extern struct PSAPaddr ts_bound;
50: static char *myservice = "terminal";
51:
52: static char *mycontext = "iso vt";
53: static char *mypci = "iso vt pci";
54:
55: static char ascii_go_repertoire[] = {0x1a,0x28,0x42,0x00}; /*ESC 2/8 4/2*/
56: /*should be followed by 3 "voids" whatever that is*/
57: static char full_ascii_repertoire[] = {0x1a,0x28,0x42,/*VOID*/0x1a,0x21,0x40,0x00};
58: /*Approximation to GO & CO ASCII sets*/
59:
60: extern char *isodeversion;
61: extern char *my_displayobj;
62: extern int G_Func_Units; /*Functional Units for this Association*/
63: extern int vcwa; /*Collision Winner (TRUE if owned by this peer)*/
64: extern int vsmd, vtok;
65: extern int transparent;
66: extern char na_image;
67: extern char ni_image;
68: extern VT_PROFILE vtp_profile;
69: extern int telnet_profile;
70: extern int do_break;
71: extern int debug;
72:
73: int default_rep_flag = 0;
74:
75: /*************************************************************************/
76: /* VASS_REQ - create an ASQ PDU and generate a VASSreq event to */
77: /* send it. */
78: /* */
79: /* PARAMETERS - */
80: /* */
81: /* CLASS - class of VTP service (only BASIC supported) */
82: /* */
83: /* ACC_RI - access rights */
84: /* */
85: /* PROFILE - designator of the VT profile to request */
86: /*************************************************************************/
87: /* ARGSUSED */
88: vass_req(class, acc_ri, profile)
89: int class, acc_ri;
90: VT_PROFILE *profile;
91: {
92: PE a_req;
93: ASQ_MSG ud;
94: char my_version, my_fu;
95: OID p_oid;
96: int i;
97:
98: my_version = 0x01;
99: if(do_break) my_fu = destBreak;
100: else my_fu = 0x00;
101:
102: bzero ((char *) &ud, sizeof ud);
103: ud.class = class;
104: ud.valid_imp = 0;
105: ud.coll_winner = ACHOICE;
106: ud.valid_coll = 1;
107: ud.version.bitstring = my_version;
108: ud.version.bitcount = 1;
109: if( !strcmp(profile->profile_name,"telnet") )
110: {
111: ud.valid_prof = 1;
112: ud.asq_profile.oid_true = 1;
113: if((p_oid = ode2oid(profile->profile_name)) == NULLOID)
114: adios(NULLCP,"%s: unknown profile", profile->profile_name);
115: ud.asq_profile.prof_oid = p_oid;
116:
117: ud.asq_profile.num_sp_param = 0;
118: ud.asq_profile.num_cds_objects = 0;
119: ud.asq_profile.num_css_objects = 0;
120: ud.asq_profile.num_dev_objects = 0;
121: ud.asq_profile.del_ctrl.bitcount = 0;
122:
123: ud.asq_profile.num_cds_objects = 1;
124: ud.asq_profile.cds_offer_list[0].obj_name = "D";
125: for(i=0; i<ud.asq_profile.num_cds_objects; i++)
126: {
127: ud.asq_profile.cds_offer_list[i].valid_x_dim = 0;
128: ud.asq_profile.cds_offer_list[i].valid_y_dim= 0;
129: ud.asq_profile.cds_offer_list[i].valid_z_dim = 0;
130: ud.asq_profile.cds_offer_list[i].erasure.bitcount = 0;
131: ud.asq_profile.cds_offer_list[i].valid_emp_list = 0;
132: ud.asq_profile.cds_offer_list[i].valid_fore_color = 0;
133: ud.asq_profile.cds_offer_list[i].valid_back_color = 0;
134: ud.asq_profile.cds_offer_list[i].access_right.bitcount = 0;
135: ud.asq_profile.cds_offer_list[i].valid_rep_list = 0;
136: }
137: if(!vtp_profile.arg_val.tel_arg_list.full_ascii)
138: {
139: ud.asq_profile.cds_offer_list[0].valid_rep_list = 1;
140: ud.asq_profile.cds_offer_list[0].rep_offer.valid_cap = 1;
141: ud.asq_profile.cds_offer_list[0].rep_offer.capability.type = 0;
142: ud.asq_profile.cds_offer_list[0].rep_offer.capability.value = 1;
143: ud.asq_profile.cds_offer_list[0].rep_offer.num_reps = 1;
144: ud.asq_profile.cds_offer_list[0].rep_offer.repertoire[0].rep_type = 2;
145: ud.asq_profile.cds_offer_list[0].rep_offer.repertoire[0].valid_font_cap = 0;
146: ud.asq_profile.cds_offer_list[0].rep_offer.repertoire[0].num_fonts = 0;
147: ud.asq_profile.cds_offer_list[0].rep_offer.repertoire[0].rep_assign =
148: ascii_go_repertoire;
149: }
150:
151: ud.asq_profile.cds_offer_list[0].valid_x_dim = 1;
152: ud.asq_profile.cds_offer_list[0].x_dim.bound_type = 0;
153: ud.asq_profile.cds_offer_list[0].x_dim.addressing.bitcount = 0;
154: ud.asq_profile.cds_offer_list[0].x_dim.absolute.bitcount = 0;
155: ud.asq_profile.cds_offer_list[0].x_dim.window_type = 2;
156: ud.asq_profile.cds_offer_list[0].x_dim.window.type = 0;
157: ud.asq_profile.cds_offer_list[0].x_dim.window.value =
158: vtp_profile.arg_val.tel_arg_list.x_window;
159:
160: vtok = 1;
161: vsmd = 0;
162: }
163: else if( !strcmp(profile->profile_name,"default") )
164: {
165: ud.valid_prof = 0;
166: ud.asq_profile.oid_true = 0;
167: ud.asq_profile.num_sp_param = 0;
168: ud.asq_profile.num_cds_objects = 0;
169: ud.asq_profile.num_css_objects = 0;
170: ud.asq_profile.num_dev_objects = 0;
171: vtok = 1;
172: vsmd = 0;
173: }
174: else
175: adios(NULLCP, "%s: unsupported profile", profile->profile_name);
176:
177: ud.func_units.bitstring = my_fu;
178: ud.func_units.bitcount = 5;
179:
180: if(build_ASQPDU_ASQpdu(&a_req,1,NULL,NULLCP,(PEPYPARM)&ud) == NOTOK)
181: adios(NULLCP, "ASQ build failure (%s)", PY_pepy);
182:
183: (void)do_event(VASSreq, a_req);
184: }
185:
186:
187: /******************************************************************************/
188: /* VASS_RESP - create an ASR PDU and generate a VASSRSP event to send it.*/
189: /* */
190: /* PARAMETERS - */
191: /* */
192: /* RESULT - SUCCESS or FAILURE */
193: /******************************************************************************/
194:
195: vass_resp(result)
196: int result;
197: {
198: PE a_resp;
199: char my_version, my_fu;
200: ASR_MSG ud;
201: int i;
202:
203: my_version = 0x01;
204: if(G_Func_Units & destBreak) do_break = 1;
205: else do_break = 0;
206: my_fu = G_Func_Units & destBreak; /*VT-Break is only Functional Unit
207: we will accept*/
208: bzero ((char *) &ud, sizeof ud);
209: ud.valid_reason = 0;
210: ud.result = result;
211: ud.valid_imp = 0;
212: ud.valid_coll = 1;
213: if(vcwa == TRUE) ud.coll_winner = ACCEPTOR;
214: else ud.coll_winner = INITIATOR;
215: ud.version.bitstring = my_version;
216: ud.version.bitcount = 1;
217: if( !strcmp(vtp_profile.profile_name,"telnet") )
218: {
219: ud.valid_arg_list = 1;
220: ud.arg_list.num_css_objects = 0;
221: ud.arg_list.num_dev_objects = 0;
222: ud.arg_list.num_cds_objects = 1;
223:
224: ud.arg_list.cds_val[0].obj_name = "D";
225: for(i=0; i<ud.arg_list.num_cds_objects; i++)
226: {
227: ud.arg_list.cds_val[i].dimensions = 0;
228: ud.arg_list.cds_val[i].valid_x_dim = 0;
229: ud.arg_list.cds_val[i].valid_y_dim = 0;
230: ud.arg_list.cds_val[i].valid_z_dim = 0;
231: ud.arg_list.cds_val[i].valid_erasure= 0;
232: ud.arg_list.cds_val[i].valid_emp_list = 0;
233: ud.arg_list.cds_val[i].valid_fore_color = 0;
234: ud.arg_list.cds_val[i].valid_back_color = 0;
235: ud.arg_list.cds_val[i].valid_access_right = 0;
236: ud.arg_list.cds_val[i].valid_rep_list = 0;
237: ud.arg_list.cds_val[i].rep_value.repertoire[0].valid_font_cap = 0;
238: ud.arg_list.cds_val[i].rep_value.repertoire[0].num_fonts = 0;
239: }
240: if( !default_rep_flag)
241: {
242: ud.arg_list.cds_val[0].valid_rep_list = 1;
243: ud.arg_list.cds_val[0].rep_value.valid_cap = 1;
244: ud.arg_list.cds_val[0].rep_value.capability = 1;
245: ud.arg_list.cds_val[0].rep_value.num_reps = 1;
246: ud.arg_list.cds_val[0].rep_value.repertoire[0].rep_type = 2;
247: ud.arg_list.cds_val[0].rep_value.repertoire[0].rep_assign =
248: vtp_profile.arg_val.tel_arg_list.full_ascii ?
249: full_ascii_repertoire : ascii_go_repertoire;
250: }
251: ud.arg_list.num_sp_param = 0;
252: ud.arg_list.cds_val[0].valid_x_dim = 1;
253: ud.arg_list.cds_val[0].x_dim.bound_type = 0;
254: ud.arg_list.cds_val[0].x_dim.valid_addr = 0;
255: ud.arg_list.cds_val[0].x_dim.valid_abs = 0;
256: ud.arg_list.cds_val[0].x_dim.window_type = 2;
257: ud.arg_list.cds_val[0].x_dim.window =
258: vtp_profile.arg_val.tel_arg_list.x_window;
259:
260: }
261: else if( !strcmp(vtp_profile.profile_name,"default") )
262: {
263: ud.valid_arg_list = 0;
264: ud.arg_list.num_sp_param = 0;
265: ud.arg_list.num_cds_objects = 0;
266: ud.arg_list.num_css_objects = 0;
267: ud.arg_list.num_dev_objects = 0;
268: }
269: else
270: adios (NULLCP, "invalid profile stored");
271: ud.func_units.bitstring = my_fu;
272: ud.func_units.bitcount = 5;
273:
274: if(build_ASRPDU_ASRpdu((PE *)&a_resp,1,NULL,NULLCP,(PEPYPARM)&ud) == NOTOK)
275: advise(LLOG_NOTICE,NULLCP, "ASR build failure (%s) -- continuing",
276: PY_pepy);
277: return(do_event(VASSrsp, a_resp));
278: }
279:
280:
281: /*************************************************************************/
282: /* "pe" will be to store NDQ contents that could not be mapped to */
283: /* the cbuf because of lack of buffer space. There is only one, */
284: /* because a new NDQ can be combined with "pe" rather than creating */
285: /* a queue of PEs */
286: /*************************************************************************/
287:
288: PE pe_buf = NULLPE;
289:
290:
291: /************************************************************************/
292: /* VRELREQ - Generate a VRELREQ to VT State Machine */
293: /* */
294: /* PARAMETERS - none */
295: /************************************************************************/
296:
297: vrelreq()
298: {
299: PE r_req;
300:
301: r_req = NULLPE;
302: (void)do_event(VRELreq,r_req);
303: }
304:
305: /*************************************************************************/
306: /* VRELRSP - create an RLR PDU and send it and generate a VRELRSP-S */
307: /* */
308: /* PARAMETERS - */
309: /* */
310: /* RESULT - success or failure */
311: /* */
312: /*************************************************************************/
313:
314: vrelrsp(result)
315: int result;
316: {
317:
318: int offset = 0;
319: PE r_rsp, r_result, r_coll;
320:
321: if ((r_rsp = pe_alloc(PE_CLASS_CONT, PE_FORM_CONS, RLR_PDU)) == NULLPE)
322: adios (NULLCP, "RLR build failure (out of memory)");
323:
324: if ((r_result = num2prim(result,PE_CLASS_CONT,0)) == NULLPE)
325: adios (NULLCP, "RLR build failure (out of memory)");
326:
327: if (seq_add(r_rsp,r_result,offset) == NOTOK)
328: adios (NULLCP, "RLR build failure (%s)", pe_error(r_rsp -> pe_errno));
329:
330: if(result == COLL_DET)
331: {
332: if((r_coll = num2prim(0,PE_CLASS_CONT,2)) == NULLPE)
333: adios (NULLCP, "RLR build failure (out of memory)");
334: if (seq_add(r_rsp,r_coll,++offset) == NOTOK)
335: adios (NULLCP, "RLR build failure (%s)",
336: pe_error(r_rsp -> pe_errno));
337: }
338: if (seq2prim(r_rsp) == NULLPE)
339: adios(NULLCP, "RLR encode error, seq2prim: (%s)", PY_pepy);
340: (void)do_event(VRELrsp,r_rsp);
341:
342: pe_free(r_coll);
343: pe_free(r_result);
344: pe_free(r_rsp);
345:
346: }
347:
348:
349: vrelcnf()
350: {
351: if (debug)
352: advise(LLOG_DEBUG, NULLCP, "Release Confirmed");
353: }
354:
355:
356: vrelind()
357: {
358: if (AcFINISHser(sd,pf,aci) == NOTOK)
359: acs_adios (&aci->aci_abort, "A-RELEASE.INDICATION");
360:
361: vrelrsp(SUCCESS);
362: return(OK);
363: }
364:
365:
366:
367: PE p_ondq = NULLPE; /* the current "ndq" being prepared for sending*/
368: PE p_ovtsdi = NULLPE; /* the current "vtsdi" */
369: int sdi_count = 0; /* count of "vtsdi"s in current NDQ*/
370: PE p_oobjupdt = NULLPE; /* the current "object_update" */
371: int obj_count = 0; /* count of "object_update"s in current "vtsdi"*/
372: int updt_count = 0; /* count of updates in the current "object update"*/
373: int cur_emode = NOT_ECHO_NOW; /* echo mode (ECHO_NOW or NOT_ECHO_NOW)*/
374:
375: /*************************************************************************/
376: /* VT_TEXT - Add a text update to the PE that represents */
377: /* an NDQ of buffered updates awaiting delivery. */
378: /* */
379: /* When we do a control object update, the current buffer of */
380: /* display object updates is terminated and a new one will be */
381: /* started next time a display object update is queued. */
382: /* (this is so we can synchronize control updates with */
383: /* display updates.) */
384: /* */
385: /* Likewise, whenever we queue a display object update, we */
386: /* terminate the current sequence of control object updates. */
387: /* */
388: /* Whenever we change echo mode (ECHO_NOW or NOT_ECHO_NOW) */
389: /* we have to start a new "vtsdi". */
390: /* This requires that we terminate the current buffers of */
391: /* display object and control object updates. */
392: /* */
393: /* PARAMETERS - */
394: /* */
395: /* STR - the character string to be added to the NDQ PDU. */
396: /* LEN - Number of characters in the string. */
397: /*************************************************************************/
398:
399: vt_text(str, len)
400: char *str;
401: int len;
402: {
403: TEXT_UPDATE ud;
404:
405: if (debug > 6)
406: {
407: int i;
408:
409: (void)ll_log(vt_log, LLOG_DEBUG, NULLCP, ("vt_text sending"));
410: (void)ll_printf (vt_log, "<<");
411: for(i=0; i<len; i++)
412: (void)ll_printf (vt_log, "%02x ", *(str+i));
413: (void)ll_printf (vt_log, ">>\n");
414: (void)ll_sync (vt_log);
415: }
416:
417: bzero ((char *) &ud, sizeof ud);
418: ud.echo_sw = cur_emode;
419: ud.type_sw = 0; /*Display object*/
420: ud.updates.do_list.do_name = my_displayobj;
421: ud.updates.do_list.do_type = DO_TEXT; /*Text*/
422: ud.updates.do_list.do_cmd.text_ud.text_ptr = str;
423: ud.updates.do_list.do_cmd.text_ud.text_count = len;
424: send_queue(ud);
425:
426: return(OK);
427: }
428:
429:
430: send_queue(ud) /*Build NDQ with update supplied in ud structure*/
431: TEXT_UPDATE ud;
432: {
433:
434: PE vtsdip;
435:
436: if(p_ondq == NULLPE) /*Nothing waiting to be sent*/
437: {
438: if(build_NDQPDU_NDQpdu(&p_ondq,1,NULL,NULLCP,(PEPYPARM)&ud) == NOTOK)
439: adios(NULLCP,"NDQ build failure (%s)", PY_pepy);
440: p_ondq->pe_context = 1;
441: }
442: else
443: {
444: if(build_NDQPDU_VTsdi(&vtsdip,1,NULL,NULLCP,(int *)&ud) == NOTOK)
445: adios(NULLCP,"VTsdi build failure (%s)", PY_pepy);
446: vtsdip->pe_context = 1;
447: if(seq_add(p_ondq,vtsdip,-1) == NOTOK)
448: adios(NULLCP,"NDQ build failure (%s)",
449: pe_error(p_ondq->pe_errno));
450: }
451: }
452:
453:
454:
455: /* SETEMODE - set echo mode
456:
457: PARAMETERS -
458:
459: MODE - ECHO_NOW or NOT_ECHO_NOW
460: */
461:
462: setemode(mode)
463: int mode;
464: {
465: if (mode != ECHO_NOW && mode != NOT_ECHO_NOW)
466: return(NOTOK);
467: if (cur_emode != mode) {
468: p_ovtsdi = NULLPE;
469: sdi_count = 0;
470: p_oobjupdt = NULLPE;
471: obj_count = 0;
472: cur_emode = mode;
473: }
474: return(OK);
475: }
476:
477:
478: /* this data structure will buffer character output
479: that is ready to be read by the application or terminal.
480: */
481:
482: #define CBUFSIZE 10240
483:
484: struct char_buffer {
485: int max_len, queued;
486: unsigned char *head, *tail;
487: unsigned char buf[CBUFSIZE];
488: };
489:
490: struct char_buffer cbuf = { CBUFSIZE, 0 };
491:
492: /************************************************************************/
493: /* GETCH - get a character from the buffer waiting to */
494: /* be read by the application */
495: /* */
496: /* RETURNS - the character, NOTOK if no data, or an error code (<0)*/
497: /************************************************************************/
498:
499:
500: int
501: getch()
502: {
503: int c;
504:
505: if (data_pending() == FALSE) {
506: if (!connected)
507: return(E_EOF);
508: else
509: return(WOULDBLOCK);
510: }
511: c = *cbuf.head;
512: if (++cbuf.head >= cbuf.buf + CBUFSIZE)
513: cbuf.head = cbuf.buf;
514: cbuf.queued--;
515: if (debug > 1)
516: advise(LLOG_DEBUG, NULLCP, "normal return from getch, c is %c,queued is %d", c,cbuf.queued);
517: return(c);
518: }
519:
520: /* at some point we need to use the async. interface to the network
521: so that at any time when data becomes available, we trap to a vtpm
522: function to handle it. This function will examine the type of
523: network event and act accordingly. Each time the function is invoked
524: it should completely process the data received and free the PSAPdata
525: structure for use in processing the next network event.
526: If it is an expedited
527: data request, for instance, it is treated differently from a P-DATA.
528: If an NDQ is
529: received all the data should be read from the PSAPread structure and
530: mapped to the cbuf.
531: If the cbuf fills up in the process of doing this, the PE containing the
532: remaining updates should be put in a queue of pending PEs.
533: */
534:
535:
536: /* This macro does the same thing as PXFREE except it does not free
537: the PEs in the px_info array. We will use this instead of PXFREE
538: because we need to free the data PEs one at a time as they are
539: processed.
540: Any unprocessed (pending) PEs are maintained in a queue
541: by the VTPM. If some of the PEs received from a PDATArequest are in
542: this queue a call to PXFREE would free the
543: data and leave dangling references in the queue.
544:
545: Note that the vtuser may have at most one unprocessed or partially
546: processed PE. The VTPM can potentially have any number of unprocessed
547: PEs in its queue.
548: */
549:
550: #define PFIN(px) \
551: { \
552: register int PXI; \
553: \
554: if ((px) -> px_realinfo) \
555: pe_free ((px) -> px_realinfo), (px) -> px_realinfo = NULLPE; \
556: else { \
557: for (PXI = (px) -> px_ninfo - 1; PXI >= 0; PXI--) \
558: if ((px) -> px_info[PXI]) \
559: (px) -> px_info[PXI] = NULLPE; \
560: (px) -> px_ninfo = 0; \
561: } \
562: }
563:
564:
565: int
566: data_pending()
567: {
568: int result;
569: PE *peptr = NULLPEP;
570:
571: if (queued())
572: return(TRUE);
573:
574: /* something was already in the cbuf
575: */
576:
577: if (pe_buf != NULLPE) {
578:
579: /* there seems to be something to map
580: */
581:
582: map(pe_buf);
583: if (queued())
584: return(TRUE);
585: }
586: result = get_event(sd, peptr);
587:
588: /* if there was no network event
589: */
590: if (result == NOTOK)
591: return(FALSE);
592:
593: /* get_event may have resulted in data being read and mapped to the
594: cbuf
595: */
596:
597: if (queued())
598: return(TRUE);
599:
600: /* if there is no data left and get_event resulted in the association
601: being released
602: */
603: if (!connected) {
604: (void)putch(EOF);
605: return(TRUE);
606: }
607:
608: /* there's nothing to read right now, but we're still connected
609: */
610: return(FALSE);
611: }
612:
613:
614: int
615: queued()
616: {
617: return(cbuf.queued);
618: }
619:
620:
621: /*************************************************************************/
622: /* PUTCH - put a character on the buffer to be read by the */
623: /* application */
624: /* */
625: /* RETURNS - OK on success, NOTOK otherwise */
626: /*************************************************************************/
627: int
628: putch(c)
629: char c;
630: {
631: if (debug > 1) {
632: advise(LLOG_DEBUG, NULLCP, "in putch, queued is %d, c is %c", cbuf.queued, c);
633: advise(LLOG_DEBUG, NULLCP, "cbuf.buf is %d, cbuf.head is %d, cbuf.tail is %d", (int)cbuf.buf, (int)cbuf.head, (int)cbuf.tail);
634: advise(LLOG_DEBUG, NULLCP, "cbuf.max_len is %d", (int)cbuf.max_len);
635: }
636: if (cbuf.queued >= CBUFSIZE) {
637: if (debug > 1)
638: advise(LLOG_DEBUG, NULLCP, "***********************\nputch: queued exceeds CBUFSIZE ***************");
639: return(NOTOK);
640: }
641: if (cbuf.queued <= 0) {
642: cbuf.tail = cbuf.head = cbuf.buf;
643: cbuf.queued = 0;
644: if (debug)
645: advise(LLOG_DEBUG, NULLCP, "tail and head set to %d", (int)cbuf.buf);
646: }
647: *(cbuf.tail) = c;
648: if (++(cbuf.tail) > cbuf.buf + CBUFSIZE)
649: cbuf.tail = cbuf.buf;
650: cbuf.queued++;
651: return(OK);
652: }
653:
654:
655: /*************************************************************************/
656: /* VTSEND - send the updates that have been put into the PE */
657: /* called "p_ondq". */
658: /*************************************************************************/
659:
660: vtsend()
661: {
662: if(p_ondq == NULLPE) return;
663: vtdata(p_ondq);
664: pe_free(p_ondq);
665: p_ondq = NULLPE;
666: p_ovtsdi = NULLPE;
667: sdi_count = 0;
668: p_oobjupdt = NULLPE;
669: obj_count = 0;
670: updt_count = 0;
671: }
672:
673: /************************************************************************/
674: /* VTDATA - generate a VDATREQ event to send an NDQ */
675: /* */
676: /* PARAMETERS */
677: /* */
678: /* NDQ - a presentation element containing an NDQ. */
679: /************************************************************************/
680:
681: vtdata(ndq)
682: PE ndq;
683: {
684: if (ndq == NULLPE)
685: return;
686:
687: (void)do_event(VDATreq_n,ndq);
688: }
689:
690:
691: /************************************************************************/
692: /* MKDELIVER - create a DLQ. Requests for an acknowlegement are not */
693: /* allowed at this time. */
694: /************************************************************************/
695:
696: PE
697: mkdeliver(ack)
698: int ack;
699: {
700: PE p_dlq;
701:
702: if (ack != FALSE)
703: adios(NULLCP, "DLQ PDUs can only be sent without an ACK request");
704: if ((p_dlq = bool2prim(ack)) == NULLPE)
705: adios (NULLCP, "DLQ build failure (out of memory)");
706: p_dlq->pe_id = DLQ_PDU;
707: p_dlq->pe_class = PE_CLASS_CONT;
708: p_dlq->pe_context = 1;
709: return(p_dlq);
710: }
711:
712: /**************************************************************************/
713: /* VDELREQ - create a deliver request PE and generate a VDELreq */
714: /* event to send it. */
715: /**************************************************************************/
716:
717: vdelreq(ack)
718: int ack;
719: {
720: PE p_dlq;
721:
722: if (ack)
723: adios(NULLCP,
724: "ACK requests in deliver PDUs not supported at this time");
725: p_dlq = mkdeliver(FALSE);
726:
727: (void)do_event(VDELreq,p_dlq);
728: }
729:
730:
731: /**************************************************************************/
732: /* VDELIND - we queue up data to go to the terminal when the NDQ */
733: /* is received, so there's really nothing */
734: /* to do when we get a VDELIND */
735: /* */
736: /* PARAMETERS: */
737: /* ACK - TRUE or FALSE according to whether */
738: /* acknowledgement is requested or not. */
739: /**************************************************************************/
740:
741: vdelind(del_pe,ack)
742: PE del_pe;
743: int ack;
744: {
745: if (ack) {
746: if (debug)
747: advise(LLOG_DEBUG, NULLCP, "vdelind with ack requested not implemented!");
748: }
749: pe_free(del_pe);
750: }
751:
752: /************************************************************************/
753: /* VDATIND - On receiving a data indication we will go ahead and */
754: /* map the contents onto the character buffer to go to the terminal */
755: /* */
756: /* PARAMETERS - "type" can be SEQUENCED or NONSEQUENCED */
757: /* only SEQUENCED is implemented now */
758: /************************************************************************/
759:
760: vdatind(type, pe)
761: int type;
762: PE pe;
763: {
764: if (type != SEQUENCED)
765: adios(NULLCP, "unimplemented NDQ type %d", type);
766: map(pe);
767: }
768:
769: vhdatind(pe)
770: PE pe;
771: {
772:
773: advise(LLOG_NOTICE,NULLCP,"vhdatind(): HDQ's not supported\n");
774: pe_free(pe);
775: }
776:
777: vudatind(pe)
778: PE pe;
779: {
780:
781: TEXT_UPDATE ud;
782:
783: if(unbuild_UDQPDU_UDQpdu(pe,1,NULLIP,NULLVP,(PEPYPARM) &ud) == NOTOK)
784: {
785: advise(LLOG_NOTICE,NULLCP,"UDQ parse failure\n");
786: }
787: else
788: {
789: control_ud((CO_UPDATE *) &(ud.updates.co_list) );
790: free( (char *)ud.updates.co_list.co_name);
791: pe_free(pe);
792: }
793: }
794:
795: /*****************************************************************************/
796: /* Connect_request: */
797: /* */
798: /* Sends an ASQ, waits for a confirm. */
799: /* */
800: /* Returns the file descriptor that corresponds to the network socket */
801: /* for the association, or NOTOK if the association failed. */
802: /* */
803: /* The assumption is made that the acs_sd data element of the AcSAPstart*/
804: /* structure is same as the file descriptor for the network socket used */
805: /* by the association. */
806: /*****************************************************************************/
807:
808: con_req()
809: {
810: int uevent;
811:
812: if (debug)
813: advise(LLOG_DEBUG, NULLCP, "in con_req");
814:
815: vass_req(1,WACI_WACA,&vtp_profile);
816: if (acc->acc_result != ACS_ACCEPT) {
817: advise(LLOG_NOTICE,NULLCP, "association rejected: [%s]",
818: AcErrString (acc -> acc_result));
819: state = S1_01;
820: return NOTOK;
821: }
822:
823: if (debug) {
824: advise(LLOG_DEBUG, NULLCP, "got associate confirm event, sd is %d", acc->acc_sd);
825: advise(LLOG_DEBUG, NULLCP, "acc_ninfo is %d", acc->acc_ninfo);
826: advise(LLOG_DEBUG, NULLCP, "pe_id is %d", acc->acc_info[0]->pe_id);
827: advise(LLOG_DEBUG, NULLCP, "pe_class is %d", acc->acc_info[0]->pe_class);
828: advise(LLOG_DEBUG, NULLCP, "pe_form is %d", acc->acc_info[0]->pe_form);
829: }
830:
831: if (acc->acc_ninfo < 1)
832: adios(NULLCP, "no ASQ PDU sent with the associate confirm");
833:
834: sd = acc->acc_sd;
835: uevent = do_event(ASR,acc->acc_info[0]);
836:
837: if (debug)
838: advise(LLOG_DEBUG, NULLCP, "got user event %d", uevent);
839:
840: if(uevent == SUCCESS) return(sd);
841: else return(-1);
842: }
843:
844:
845:
846: read_asq(pe) /*Unwrap ASQ PDU. Use information it contains to fill in
847: some global values (profile_id,G_Func_Units,vcwa).
848: Return 0 if ASQ is improperly formatted or missing a
849: required field. For now, only the more obvious fields are
850: checked and only transparent and telnet profiles
851: are handled. Return PROFILE_NG if profile is not
852: supported. Return 1 if ASQ is valid.
853: */
854: PE pe;
855: {
856:
857: int i,n, D;
858: ASQ_MSG ud;
859:
860: bzero ((char *) &ud, sizeof ud);
861: if(unbuild_ASQPDU_ASQpdu(pe,1,NULLIP,NULLVP,(PEPYPARM)&ud) == NOTOK)
862: {
863: advise(LLOG_NOTICE,NULLCP, "ASQ parse failure (%s)", PY_pepy);
864: return(0);
865: }
866:
867:
868: if(!ud.class)
869: {
870: advise(LLOG_DEBUG, NULLCP, "ASQ without Class");
871: return(0);
872: }
873: if(ud.valid_coll)
874: {
875: if(ud.coll_winner == INITIATOR) vcwa = FALSE;
876: else vcwa = TRUE;
877: }
878: G_Func_Units = ud.func_units.bitstring & 0x1f;
879: if( (!ud.valid_prof) || (!ud.asq_profile.oid_true) ||
880: !oid_cmp(ud.asq_profile.prof_oid,ode2oid("default")) )
881: {
882: vtp_profile.profile_name = "default";
883: my_displayobj = "DISPLAY-OBJECT-1";
884: telnet_profile = 0;
885: return(1);
886: }
887: if( !oid_cmp(ud.asq_profile.prof_oid,ode2oid("telnet")) )
888: {
889: vtp_profile.profile_name = "telnet";
890: vtp_profile.arg_val.tel_arg_list.full_ascii = 0xff;
891: vtp_profile.arg_val.tel_arg_list.x_window = -1;
892:
893: D = -1;
894: for(n=0; n<ud.asq_profile.num_cds_objects; n++)
895: {
896: if( *ud.asq_profile.cds_offer_list[n].obj_name == 'D')
897: {
898: D = n;
899: break;
900: }
901: }
902: if(D < 0)
903: {
904: advise(LLOG_DEBUG, NULLCP, "ASQ with no D Display Object");
905: return(0);
906: }
907:
908: if( !ud.asq_profile.cds_offer_list[D].valid_rep_list )
909: {
910: vtp_profile.arg_val.tel_arg_list.full_ascii = 1;
911: default_rep_flag = 1;
912: }
913: else /*Repertoire specified*/
914: {
915: if(ud.asq_profile.cds_offer_list[D].rep_offer.num_reps
916: > MAXREPS)
917: {
918: advise(LLOG_DEBUG, NULLCP, "ASQ with too many repertoires");
919: return(0);
920: }
921: for(i=0; i< ud.asq_profile.cds_offer_list[D].rep_offer.num_reps;
922: i++)
923: {
924: if(ud.asq_profile.cds_offer_list[D].rep_offer.repertoire[i].rep_type != 2)
925: continue;
926: if(!strncmp(ud.asq_profile.cds_offer_list[D].rep_offer.repertoire[i].rep_assign,
927: ascii_go_repertoire,sizeof(ascii_go_repertoire)))
928: {
929: vtp_profile.arg_val.tel_arg_list.full_ascii = 0;
930: advise(LLOG_DEBUG, NULLCP, "Using ASCII GO Repertoire.");
931: break;
932: }
933: if(!strncmp(ud.asq_profile.cds_offer_list[D].rep_offer.repertoire[i].rep_assign,
934: full_ascii_repertoire,sizeof(full_ascii_repertoire)))
935: {
936: vtp_profile.arg_val.tel_arg_list.full_ascii = 1;
937: break;
938: }
939: }
940: if(vtp_profile.arg_val.tel_arg_list.full_ascii < 0) return(0);
941: }
942: transparent = 0;
943:
944: if(ud.asq_profile.cds_offer_list[D].valid_x_dim == 0)
945: {
946: advise(LLOG_DEBUG, NULLCP, "ASQ with no X-Window");
947: return(0);
948: }
949: if(ud.asq_profile.cds_offer_list[D].x_dim.window_type != 2)
950: /*If not integer type window field*/
951: {
952: advise(LLOG_DEBUG, NULLCP, "ASQ with invalid X-Window");
953: return(0);
954: }
955: if(ud.asq_profile.cds_offer_list[D].x_dim.window.type
956: == 0) /*If single value*/
957: {
958: vtp_profile.arg_val.tel_arg_list.x_window =
959: ud.asq_profile.cds_offer_list[D].x_dim.window.value;
960: }
961: else if(ud.asq_profile.cds_offer_list[D].x_dim.window.type == 1)
962: /*If range*/
963: {
964: if((ud.asq_profile.cds_offer_list[D].x_dim.window.min_val
965: <= 80) &&
966: (ud.asq_profile.cds_offer_list[D].x_dim.window.max_val
967: >= 80))
968: {
969: vtp_profile.arg_val.tel_arg_list.x_window = 80;
970: }
971: else
972: {
973: vtp_profile.arg_val.tel_arg_list.x_window =
974: ud.asq_profile.cds_offer_list[D].x_dim.window.min_val;
975: }
976:
977: }
978: if(vtp_profile.arg_val.tel_arg_list.x_window < 0)
979: {
980: advise(LLOG_DEBUG, NULLCP, "ASQ without x-window");
981: return(0);
982: }
983: if(vtp_profile.arg_val.tel_arg_list.full_ascii < 0)
984: {
985: advise(LLOG_DEBUG, NULLCP, "Using Default for ASCII repertoire (Full ASCII)");
986: vtp_profile.arg_val.tel_arg_list.full_ascii = 1;
987: }
988: }
989: else
990: {
991: advise(LLOG_DEBUG, NULLCP, "Unknown Profile Requested");
992: return(PROFILE_NG);
993: }
994:
995: return(1);
996: }
997:
998: vasscnf(pe) /*Handle ASR received from Acceptor*/
999: PE pe;
1000: {
1001:
1002: ASR_MSG udr;
1003: int rep, n;
1004: int window_flag = 0;
1005: int rep_flag = 0;
1006:
1007: bzero ((char *) &udr, sizeof udr);
1008: if(unbuild_ASRPDU_ASRpdu(pe,1,NULLIP,NULLVP,(PEPYPARM)&udr) == NOTOK)
1009: {
1010: advise (LLOG_NOTICE,NULLCP, "ASR parse failure (%s)", PY_pepy);
1011: return(NOTOK);
1012: }
1013: if(udr.result != SUCCESS)
1014: {
1015: advise(LLOG_NOTICE,NULLCP, "Association rejected by Peer VT");
1016: return(NOTOK);
1017: }
1018: if(udr.valid_coll) vcwa = udr.coll_winner;
1019: else
1020: advise(LLOG_DEBUG, NULLCP, "Received ASR with no collision winner");
1021: if(!strcmp(vtp_profile.profile_name,"transparent"))
1022: {
1023: if(!udr.arg_list.cds_val[0].valid_rep_list) /*No repertoires*/
1024: {
1025: if(strcmp(vtp_profile.arg_val.tr_arg_list.cur_rep,
1026: TRANSPARENT))
1027: /*If don't want default for this profile*/
1028: {
1029: advise(LLOG_DEBUG, NULLCP, "ASR with no repertoire");
1030: return(NOTOK);
1031: }
1032: }
1033: if(strcmp(vtp_profile.arg_val.tr_arg_list.cur_rep,
1034: udr.arg_list.cds_val[0].rep_value.repertoire[0].rep_assign))
1035: /*Only support 1 repertoire in transparent*/
1036: {
1037: advise(LLOG_DEBUG, NULLCP, "ASR--Invalid repertoire for transparent profile");
1038: return(NOTOK);
1039: }
1040: }
1041: else if(!strcmp(vtp_profile.profile_name,"telnet"))
1042: {
1043: if(udr.arg_list.num_sp_param < 1)
1044: {
1045: advise(LLOG_DEBUG, NULLCP, "ASR without enough Special Arguments");
1046: return(0);
1047: }
1048: for(n=0; n<udr.arg_list.num_sp_param; n++)
1049: {
1050: if(udr.arg_list.sp_val[n].param_num == 1)
1051: {
1052: if(udr.arg_list.sp_val[n].param_type == 1)
1053: /*If integer type*/
1054: {
1055: if(vtp_profile.arg_val.tel_arg_list.x_window !=
1056: udr.arg_list.sp_val[n].args.int_arg)
1057: {
1058: advise(LLOG_DEBUG, NULLCP, "ASR with invalid X-Window");
1059: return(NOTOK);
1060: }
1061: else ++window_flag;
1062: }
1063: }
1064: else if(udr.arg_list.sp_val[n].param_num == 2)
1065: /*ASCII Repertoire type*/
1066: {
1067: if(udr.arg_list.sp_val[n].param_type == 0)
1068: /*If Boolean*/
1069: {
1070: if(vtp_profile.arg_val.tel_arg_list.full_ascii)
1071: rep = 1;
1072: else rep = 0;
1073: if(udr.arg_list.sp_val[n].args.bool_arg != rep)
1074: {
1075: advise(LLOG_DEBUG, NULLCP, "ASR with invalid Repertoire");
1076: return(NOTOK);
1077: }
1078: ++rep_flag;
1079: }
1080: }
1081: } /*End for loop*/
1082: if(!window_flag)
1083: {
1084: advise(LLOG_DEBUG, NULLCP, "ASR without x-window");
1085: return(NOTOK);
1086: }
1087: if(!rep_flag)
1088: {
1089: advise(LLOG_DEBUG, NULLCP, "ASR with no repertoire");
1090: return(NOTOK);
1091: }
1092: }
1093: return(OK);
1094: }
1095:
1096:
1097: asq(data)
1098: PE data;
1099: {
1100: int srequirements;
1101: struct PSAPctxlist vclist;
1102: OID vt_asn;
1103: struct QOStype qos;
1104:
1105: qos.qos_reliability = HIGH_QUALITY;
1106: qos.qos_sversion = 2;
1107:
1108: if (debug)
1109: advise(LLOG_DEBUG, NULLCP, "in asq");
1110:
1111: acc = &accs;
1112: acr = &acrs;
1113: aci = &acis;
1114:
1115: /* I'm relying on "peerhost" being an external char * that
1116: has the name of the host we want to connect to
1117: */
1118: if ((aei = _str2aei (peerhost, myservice, "iso vt", 1)) == NULLAEI)
1119: adios (NULLCP, "unable to resolve service: %s", PY_pepy);
1120: if ((pa = aei2addr (aei)) == NULLPA)
1121: adios (NULLCP, "address translation failed");
1122:
1123: if ((ctx = ode2oid (mycontext)) == NULLOID)
1124: adios (NULLCP, "%s: unknown object descriptor", mycontext);
1125: if ((ctx = oid_cpy (ctx)) == NULLOID)
1126: adios (NULLCP, "out of memory");
1127: if ((pci = ode2oid (mypci)) == NULLOID)
1128: adios (NULLCP, "%s: unknown object descriptor", mypci);
1129: if ((pci = oid_cpy (pci)) == NULLOID)
1130: adios (NULLCP, "out of memory");
1131:
1132: if ((sf = addr2ref (PLocalHostName ())) == NULL) {
1133: sf = &sfs;
1134: (void) bzero ((char *) sf, sizeof *sf);
1135: }
1136:
1137: PLOG (vt_log, print_VT_PDUs, data, NULLCP, 0);
1138: aca = &aci->aci_abort;
1139: srequirements = SR_DUPLEX | SR_RESYNC | SR_TYPEDATA;
1140: srequirements &= ~SR_RLS_EXISTS;
1141:
1142: if((vt_asn = oid_cpy (pci)) == NULLOID)
1143: adios (NULLCP, "out of memory");
1144: vclist.pc_nctx = 1;
1145: vclist.pc_ctx[0].pc_id = 1;
1146: vclist.pc_ctx[0].pc_asn = vt_asn;
1147: vclist.pc_ctx[0].pc_atn = NULLOID;
1148: data -> pe_context = 1;
1149:
1150: if (AcAssocRequest (ctx, NULLAEI, aei, NULLPA, pa,
1151: &vclist, pci,
1152: 0, srequirements, SERIAL_MIN, 0, sf, &data, 1, &qos,
1153: acc, aci) == NOTOK)
1154: acs_adios (aca, "A-ASSOCIATE.REQUEST");
1155:
1156: if (acc -> acc_result != ACS_ACCEPT)
1157: return;
1158:
1159: sd = acc->acc_sd;
1160: ts_bound = acc -> acc_connect.pc_responding; /* struct copy */
1161: #ifdef DEBUG
1162: {
1163: register int i;
1164: register struct PSAPconnect *pc = &acc -> acc_connect;
1165: register struct PSAPctxlist *pl = &pc -> pc_ctxlist;
1166:
1167: advise (LLOG_DEBUG, NULLCP, "context: %s",
1168: oid2ode (acc -> acc_context));
1169:
1170: advise (LLOG_DEBUG, NULLCP,
1171: "responding AE title: %s, responding PSAP address: %s",
1172: sprintaei (&acc -> acc_respondtitle),
1173: paddr2str (&pc -> pc_responding, NULLNA));
1174:
1175: for (i = 0; i < pl -> pc_nctx; i++)
1176: advise (LLOG_DEBUG, NULLCP, "ctx %d: 0x%x 0x%x %d",
1177: pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
1178: pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
1179: advise (LLOG_DEBUG, NULLCP, "default %d", pc -> pc_defctxresult);
1180: advise (LLOG_DEBUG, NULLCP, "p/s requirements 0x%x/0x%x",
1181: pc -> pc_prequirements, pc -> pc_srequirements);
1182: }
1183: #endif
1184: }
1185:
1186: vt_disconnect()
1187: {
1188: if (AcRelRequest (sd, ACF_NORMAL, NULLPEP, 0, NOTOK, acr, aci)
1189: == NOTOK)
1190: acs_adios (aca, "A-RELEASE.REQUEST");
1191: if(acr->acr_affirmative) {
1192: connected = FALSE;
1193: (void) do_event (RLR, acr -> acr_info[0]);
1194: }
1195:
1196: ACRFREE (acr);
1197:
1198: }
1199:
1200:
1201:
1202: #define ASYNC 0
1203:
1204: #define RMASK \
1205: "\020\01HALFDUPLEX\02DUPLEX\03EXPEDITED\04MINORSYNC\05MAJORSYNC\06RESYNC\
1206: \07ACTIVITY\010NEGOTIATED\011CAPABILITY\012EXCEPTIONS\013TYPEDATA"
1207:
1208: #define PMASK \
1209: "\020\01MANAGEMENT\02RESTORATION"
1210:
1211: /* DATA */
1212:
1213: long time ();
1214: char *ctime ();
1215: int result;
1216:
1217: /*PE pe;*/
1218:
1219: /*************************************************************************/
1220: /* ASS_IND */
1221: /*************************************************************************/
1222:
1223: ass_ind (argc, argv)
1224: int argc;
1225: char **argv;
1226: {
1227: register struct PSAPctxlist *pl;
1228:
1229:
1230: aca = &aci->aci_abort;
1231: ps = &acs->acs_start;
1232: pl = &ps -> ps_ctxlist;
1233:
1234: if (AcInit (argc, argv, acs, aci) == NOTOK)
1235: acs_adios (aca, "initialization fails");
1236:
1237: advise (LLOG_NOTICE,NULLCP,
1238: "A-ASSOCIATE.INDICATION: <%d, %s, %s, %s, %d>",
1239: acs -> acs_sd, oid2ode (acs -> acs_context),
1240: sprintaei (&acs -> acs_callingtitle),
1241: sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo);
1242:
1243: advise (LLOG_NOTICE,NULLCP,
1244: "PSAP: <%d, %s, %s, %d, %s,",
1245: ps -> ps_sd,
1246: paddr2str (&ps -> ps_calling, NULLNA),
1247: paddr2str (&ps -> ps_called, NULLNA),
1248: pl -> pc_nctx, sprintb (ps -> ps_prequirements, PMASK));
1249: advise (LLOG_NOTICE,NULLCP,
1250: " %s, %d, %d>",
1251: sprintb (ps -> ps_srequirements, RMASK), ps -> ps_isn,
1252: ps -> ps_ssdusize);
1253:
1254: (void) strcpy (peerhost,
1255: na2str (ps -> ps_calling.pa_addr.sa_addr.ta_addrs));
1256:
1257: sd = acs->acs_sd;
1258:
1259: /* ACSFREE(acs);
1260: */
1261:
1262: PLOG (vt_log, print_VT_PDUs, acs -> acs_info[0], NULLCP, 1);
1263:
1264: return( do_event(ASQ,acs->acs_info[0]) );
1265: }
1266:
1267:
1268:
1269: /* ARGSUSED */
1270:
1271: vassind(pe)
1272: PE pe;
1273: {
1274: return(vass_resp(SUCCESS));
1275: }
1276:
1277:
1278: vbrkreq()
1279: {
1280: PE brk_pe;
1281: BRcnt brk;
1282:
1283: bzero ((char *) &brk, sizeof brk);
1284: brk.BKQcont.token_val = NOBKTOK;
1285: brk.BKQcont.ExplPtr.xval = 0;
1286: brk.BKQcont.ExplPtr.yval = 0;
1287: brk.BKQcont.ExplPtr.zval = NULLCOORD;
1288: if ((build_VT_BKQ__pdu(&brk_pe,1,NULL,NULLCP,(PEPYPARM)&brk)) == NOTOK)
1289: adios (NULLCP, "BKQ build failed (%s)", PY_pepy);
1290: brk_pe->pe_context = 1;
1291: flushbufs(); /* flush local buffers */
1292: (void)do_event(VBRKreq,brk_pe);
1293: }
1294:
1295: vbrkrsp()
1296: {
1297: PE brk_pe;
1298: BRcnt brk;
1299:
1300: bzero ((char *) &brk, sizeof brk);
1301: brk.BKRcont.token_val = NOBKTOK;
1302: brk.BKRcont.ExplPtr.xval = 0;
1303: brk.BKRcont.ExplPtr.yval = 0;
1304: brk.BKRcont.ExplPtr.zval = NULLCOORD;
1305: if ((build_VT_BKR__pdu(&brk_pe,1,NULL,NULLCP,(int *)&brk)) == NOTOK)
1306: adios (NULLCP, "BKR build failed (%s)", PY_pepy);
1307: brk_pe->pe_context = 1;
1308: (void)do_event(VBRKrsp,brk_pe);
1309: }
1310:
1311:
1312: /* ARGSUSED */
1313: vbrkind(brk_pe)
1314: PE brk_pe;
1315: {
1316: flushbufs();
1317: vtok = 1; /* got tokens from peer */
1318: advise(LLOG_DEBUG, NULLCP, "Received VT-BREAK");
1319: vt_clr_obj(); /*Initialize Control Objects*/
1320: vbrkrsp();
1321: if(telnet_profile)
1322: {
1323: #ifndef PTYBUG
1324: #ifdef BSD44
1325: ptyecho(0);
1326: #else
1327: setmode(0,ECHO); /*Return to Local Echo. This call is not
1328: the same for user (vtp) and server (vtpd) so for
1329: now, VT-BREAK can only be requested at user side.*/
1330: #endif
1331: vt_rem_echo(&na_image);
1332: #endif
1333: vt_sup_ga(&na_image);
1334: kill_proc();
1335: }
1336: /*Re-Negotiate Remote Echo and Suppress Go Ahead*/
1337: }
1338:
1339: /*ARGSUSED */
1340: vbrkcnf(brk_pe)
1341: PE brk_pe;
1342: {
1343: (void)printf("\r\n[break]\r\n");
1344: if(telnet_profile)
1345: {
1346: #ifndef PTYBUG
1347: vt_rem_echo(&ni_image);
1348: #endif
1349: vt_sup_ga(&ni_image);
1350: }
1351: }
1352:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.