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