Commit | Line | Data |
---|---|---|
9319b3c3 C |
1 | /* map.c - VT telnet profile mappings */ |
2 | ||
3 | #ifndef lint | |
4 | static char *rcsid = "$Header: /f/osi/vt/RCS/map.c,v 7.2 91/02/22 09:47:58 mrose Interim $"; | |
5 | #endif | |
6 | ||
7 | /* | |
8 | * $Header: /f/osi/vt/RCS/map.c,v 7.2 91/02/22 09:47:58 mrose Interim $ | |
9 | * | |
10 | * | |
11 | * $Log: map.c,v $ | |
12 | * Revision 7.2 91/02/22 09:47:58 mrose | |
13 | * Interim 6.8 | |
14 | * | |
15 | * Revision 7.1 90/07/09 14:51:50 mrose | |
16 | * sync | |
17 | * | |
18 | * Revision 7.0 89/11/23 22:31:31 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 | #define DO_LOCAL_ECHO | |
35 | #undef PEPYPARM | |
36 | #define PEPYPARM int * | |
37 | ||
38 | ||
39 | #include "vtpm.h" | |
40 | #include "sector1.h" | |
41 | ||
42 | #include <sys/ioctl.h> | |
43 | #ifdef BSD44 | |
44 | #include <sys/termios.h> | |
45 | #endif | |
46 | ||
47 | extern char erase_char; | |
48 | extern char erase_line; | |
49 | #ifdef BSD44 | |
50 | extern struct termios oterm; | |
51 | #else | |
52 | extern struct sgttyb ottyb; | |
53 | extern struct tchars otc; | |
54 | #endif | |
55 | extern char intr_char; | |
56 | extern char ni_image; | |
57 | extern char na_image; | |
58 | extern char nego_state; | |
59 | extern char kb_image; | |
60 | extern char di_image; | |
61 | extern char sync_image; | |
62 | extern char ga_image; | |
63 | extern int my_right; | |
64 | extern int cur_emode; | |
65 | extern char *myhostname; | |
66 | extern int pty; | |
67 | extern int transparent; | |
68 | extern int showoptions; | |
69 | extern int debug; | |
70 | extern int telnet_profile; | |
71 | ||
72 | TEXT_UPDATE *ndq_queue, *deq(); /*Incoming (From Net) NDQ's*/ | |
73 | ||
74 | map(ndq) /*Parse the given NDQ (could contain several updates). | |
75 | Pass individual updates to appropriate processing | |
76 | routine. | |
77 | */ | |
78 | PE ndq; | |
79 | { | |
80 | ||
81 | TEXT_UPDATE *ud; | |
82 | ||
83 | if(unbuild_NDQPDU_NDQpdu(ndq,1,NULLIP,NULLVP,(PEPYPARM)0) == NOTOK) | |
84 | { | |
85 | advise (LLOG_NOTICE,NULLCP, "NDQ parse failure (%s)", PY_pepy); | |
86 | return; | |
87 | } | |
88 | while(ud = deq(&ndq_queue) ) | |
89 | { | |
90 | if(ud->type_sw == DISPLAY_OBJ) | |
91 | { | |
92 | display_ud(&ud->updates.do_list); | |
93 | free((char *)ud->updates.do_list.do_name); | |
94 | } | |
95 | else if(ud->type_sw == CTRL_OBJ) | |
96 | { | |
97 | control_ud(&ud->updates.co_list); | |
98 | free((char *)ud->updates.co_list.co_name); | |
99 | } | |
100 | else | |
101 | advise(LLOG_NOTICE,NULLCP, "Invalid Update"); | |
102 | free((char *)ud); | |
103 | } | |
104 | pe_free(ndq); | |
105 | } | |
106 | ||
107 | \f | |
108 | display_ud(doptr) /*Handle Display Updates*/ | |
109 | DO_UPDATE *doptr; | |
110 | { | |
111 | ||
112 | int i; | |
113 | char *pt; | |
114 | #ifdef BSD44 | |
115 | struct termios term; | |
116 | #else | |
117 | struct sgttyb ttyb; | |
118 | #endif | |
119 | ||
120 | switch(doptr->do_type) { | |
121 | ||
122 | case DO_NEXT_X: | |
123 | if(putch('\r') == NOTOK) { | |
124 | if(debug) | |
125 | advise(LLOG_NOTICE,NULLCP, "DROPPED CHAR"); | |
126 | return; | |
127 | } | |
128 | ||
129 | if(my_right == INITIATOR) { | |
130 | if(putch('\n') == NOTOK) /*Current Telnet only gives | |
131 | CR to PTY*/ | |
132 | { | |
133 | advise(LLOG_NOTICE,NULLCP, "DROPPED CHAR"); | |
134 | return; | |
135 | } | |
136 | } | |
137 | break; | |
138 | ||
139 | case DO_NEXT_Y: | |
140 | if(debug) | |
141 | advise(LLOG_DEBUG,NULLCP, "Next Y Array"); | |
142 | break; | |
143 | ||
144 | case DO_PTR_REL: /*Ignore for TELNET since next update must | |
145 | be erase. */ | |
146 | break; | |
147 | ||
148 | case DO_PTR_ABS: /*Ignore for TELNET since must have been | |
149 | preceeded by erase line. */ | |
150 | break; | |
151 | ||
152 | case DO_TEXT: | |
153 | for(pt = doptr->do_cmd.text_ud.text_ptr, i = 0; | |
154 | i < doptr->do_cmd.text_ud.text_count; ++pt,++i) | |
155 | { | |
156 | if(putch(*pt) == NOTOK) | |
157 | { | |
158 | advise(LLOG_NOTICE,NULLCP, "DROPPED CHAR"); | |
159 | return; | |
160 | } | |
161 | } | |
162 | free(doptr->do_cmd.text_ud.text_ptr); | |
163 | break; | |
164 | ||
165 | case DO_RPT_TEXT: | |
166 | if(debug) | |
167 | advise(LLOG_DEBUG,NULLCP, "Repeat Text"); | |
168 | break; | |
169 | ||
170 | case DO_ATTR: | |
171 | if(debug) | |
172 | advise(LLOG_DEBUG,NULLCP, "Write Attribute"); | |
173 | attrib_hdlr(doptr); | |
174 | break; | |
175 | ||
176 | case DO_ERASE: | |
177 | if((doptr->do_cmd.erase.start_erase.ptr_type == 0) && | |
178 | (doptr->do_cmd.erase.end_erase.ptr_type == 0) ) | |
179 | { | |
180 | if(my_right == ACCEPTOR) | |
181 | { | |
182 | #ifdef BSD44 | |
183 | if (tcgetattr(pty, &term) == -1) | |
184 | perror("ioctl"); | |
185 | else | |
186 | (void)putch(erase_char=term.c_cc[VERASE]); /* XXX what if _POSIX_VDISABLE */ | |
187 | #else | |
188 | if (ioctl(pty,TIOCGETP,(char*)&ttyb) == -1) { | |
189 | perror("ioctl"); | |
190 | adios(NULLCP, "ioctl failed"); | |
191 | } | |
192 | (void)putch(ttyb.sg_erase); | |
193 | erase_char = ttyb.sg_erase; | |
194 | #endif | |
195 | } | |
196 | else (void)putch(erase_char); | |
197 | } | |
198 | else if((doptr->do_cmd.erase.start_erase.ptr_type == 3) && | |
199 | (doptr->do_cmd.erase.end_erase.ptr_type == 6)) | |
200 | { | |
201 | if(my_right == ACCEPTOR) | |
202 | { | |
203 | #ifdef BSD44 | |
204 | if (tcgetattr(pty, &term) == -1) | |
205 | perror("ioctl"); | |
206 | else | |
207 | (void)putch(erase_line=term.c_cc[VKILL]); /* XXX what if _POSIX_VDISABLE */ | |
208 | #else | |
209 | if (ioctl(pty,TIOCGETP,(char*)&ttyb) == -1) { | |
210 | perror("ioctl"); | |
211 | adios(NULLCP, "ioctl failed"); | |
212 | } | |
213 | (void)putch(ttyb.sg_kill); | |
214 | erase_line = ttyb.sg_kill; | |
215 | #endif | |
216 | } | |
217 | else (void)putch(erase_line); | |
218 | } | |
219 | break; | |
220 | ||
221 | case DO_PREV_X: | |
222 | if(debug) | |
223 | advise(LLOG_DEBUG,NULLCP, "Previous X-Array\n"); | |
224 | break; | |
225 | ||
226 | case DO_PREV_Y: | |
227 | if(debug) | |
228 | advise(LLOG_DEBUG,NULLCP, "Previous Y-Array\n"); | |
229 | break; | |
230 | } /*End Switch*/ | |
231 | } | |
232 | \f | |
233 | ||
234 | control_ud(coptr) /*Handle Control Object Updates*/ | |
235 | CO_UPDATE *coptr; | |
236 | { | |
237 | ||
238 | char active = 0; | |
239 | #ifdef BSD44 | |
240 | struct termios term; | |
241 | #else | |
242 | struct sgttyb sb; | |
243 | #endif | |
244 | ||
245 | if(!telnet_profile) | |
246 | { | |
247 | if((my_right == INITIATOR) && (!strcmp(coptr->co_name,"E"))) | |
248 | /*The Echo Control Object in Default Profile is WACA*/ | |
249 | def_echo(coptr); | |
250 | else | |
251 | advise(LLOG_NOTICE,NULLCP, "Received Invalid CO Update under Default Profile\n"); | |
252 | return; | |
253 | } | |
254 | if(coptr->co_type != 1) /*Only Booleans allowed in TELNET*/ | |
255 | { | |
256 | advise(LLOG_NOTICE,NULLCP, "Invalid CO Type\n"); | |
257 | return; | |
258 | } | |
259 | if(coptr->co_cmd.bool_update.mask_count == 0) active = 0xff; | |
260 | else active = *coptr->co_cmd.bool_update.mask; | |
261 | ||
262 | if(my_right == INITIATOR) | |
263 | { | |
264 | if(!strcmp(coptr->co_name,"DI") ) | |
265 | { | |
266 | if(active & AYT_OBJ) | |
267 | /*If This CO contains potential update to Are You There bit*/ | |
268 | { | |
269 | if( (di_image & AYT_OBJ) != | |
270 | (AYT_OBJ & *coptr->co_cmd.bool_update.value)) | |
271 | /*If this bit was toggled*/ | |
272 | { | |
273 | if(debug) | |
274 | advise(LLOG_DEBUG,NULLCP, "Toggled AYT in DI\n"); | |
275 | di_image ^= AYT_OBJ; /*Save the new value*/ | |
276 | } | |
277 | } | |
278 | if(active & AO_OBJ) | |
279 | /*If potential update to Abort Output bit*/ | |
280 | { | |
281 | if( (di_image & AO_OBJ) != | |
282 | (AO_OBJ & *coptr->co_cmd.bool_update.value)) | |
283 | /*Toggled AO bit*/ | |
284 | { | |
285 | if(debug) | |
286 | advise(LLOG_DEBUG,NULLCP, "Toggled AO in DI\n"); | |
287 | di_image ^= AO_OBJ; /*Record it*/ | |
288 | } | |
289 | } | |
290 | if(active & IP_OBJ) | |
291 | /*If potential update to Interrupt Process bit*/ | |
292 | { | |
293 | if( (di_image & IP_OBJ) != | |
294 | (IP_OBJ & *coptr->co_cmd.bool_update.value)) | |
295 | /*Toggled AO bit*/ | |
296 | { | |
297 | if(debug) | |
298 | advise(LLOG_DEBUG,NULLCP, "Toggled IP in DI/n"); | |
299 | di_image ^= IP_OBJ; | |
300 | } | |
301 | } | |
302 | if(active & DM_OBJ) | |
303 | { | |
304 | if( (di_image & DM_OBJ) != | |
305 | (DM_OBJ & *coptr->co_cmd.bool_update.value) ) | |
306 | ||
307 | /*Toggled DM Bit*/ | |
308 | { | |
309 | if(debug) | |
310 | advise(LLOG_DEBUG,NULLCP, "Toggled DM in DI\n"); | |
311 | di_image ^= DM_OBJ; | |
312 | } | |
313 | } | |
314 | if(active & BRK_OBJ) | |
315 | { | |
316 | if( (di_image & BRK_OBJ) != | |
317 | (BRK_OBJ & *coptr->co_cmd.bool_update.value) ) | |
318 | /*Toggled Break Bit*/ | |
319 | { | |
320 | if(debug) | |
321 | advise(LLOG_DEBUG,NULLCP, "Toggled BRK in DI\n"); | |
322 | di_image ^= BRK_OBJ; | |
323 | } | |
324 | } | |
325 | } | |
326 | else if( !strcmp(coptr->co_name,"NA") ) | |
327 | { | |
328 | if(active & ECHO_OBJ) | |
329 | /*Update to Echo Control Object*/ | |
330 | { | |
331 | if(ECHO_OBJ & *coptr->co_cmd.bool_update.value) | |
332 | /*Request from Server for Remote Echo*/ | |
333 | { | |
334 | na_image |= ECHO_OBJ; | |
335 | if(showoptions) | |
336 | (void)printf("Remote Echo Update Received\r\n"); | |
337 | if(ECHO_OBJ & nego_state) /*If now in Remote Echo*/ | |
338 | { | |
339 | if(ni_image & ECHO_OBJ) /*No request outstatnding*/ | |
340 | { | |
341 | if(showoptions) | |
342 | (void)printf("Server Request ignored--Now in Remote echo\r\n"); | |
343 | } | |
344 | else | |
345 | { | |
346 | if(showoptions) | |
347 | (void)printf("Request for Local Echo Denied by Server\r\n"); | |
348 | ni_image |= ECHO_OBJ; | |
349 | } | |
350 | } | |
351 | else /*Else Not in Remote Echo*/ | |
352 | { | |
353 | if(ni_image & ECHO_OBJ) /*I Requested Remote Echo*/ | |
354 | /*This must be confirmation*/ | |
355 | { | |
356 | if(showoptions) | |
357 | (void)printf("Server agreed to do Remote Echo\r\n"); | |
358 | } | |
359 | else /*Request to do Remote Echo*/ | |
360 | { | |
361 | if(showoptions) | |
362 | (void)printf("Server Requested Remote Echo\r\n"); | |
363 | ni_image |= ECHO_OBJ; | |
364 | vt_set_nego(ni_image,ECHO_OBJ);/*Respond "WILL"*/ | |
365 | } | |
366 | (void) tmode(1); | |
367 | nego_state |= ECHO_OBJ; | |
368 | cur_emode = ECHO_NOW; /*Want Server to Echo*/ | |
369 | } | |
370 | } | |
371 | else /*Request from server for Local Echo*/ | |
372 | { | |
373 | if(showoptions) | |
374 | (void)printf("NA--Local Echo\r\n"); | |
375 | cur_emode = NOT_ECHO_NOW; | |
376 | na_image &= ~ECHO_OBJ; | |
377 | if(nego_state & ECHO_OBJ) /*If now in Remote Echo*/ | |
378 | { | |
379 | if(ni_image & ECHO_OBJ) /*If no request pending*/ | |
380 | /*Must be request from sender*/ | |
381 | { | |
382 | if(showoptions) | |
383 | (void)printf("Server requested Local Echo -- O.K.\r\n"); | |
384 | ni_image &= ~ECHO_OBJ; | |
385 | vt_set_nego(ni_image,ECHO_OBJ);/*Respond "WILL"*/ | |
386 | } | |
387 | else | |
388 | { | |
389 | if(showoptions) | |
390 | (void)printf("User request for Local Echo Accepted\r\n"); | |
391 | } | |
392 | nego_state &= ~ECHO_OBJ; | |
393 | /* sb = ottyb; | |
394 | /* sb.sg_flags |= ECHO|CRMOD|CBREAK; | |
395 | /* ioctl(fileno(stdin),TIOCSETP,(char*)&sb); | |
396 | */ | |
397 | (void)tmode(2); | |
398 | } | |
399 | else /*Else now in Local Echo*/ | |
400 | { | |
401 | if(ni_image & ECHO_OBJ) /*If requeset pending*/ | |
402 | /*Must be negative response*/ | |
403 | { | |
404 | ni_image &= ~ECHO_OBJ; | |
405 | if(showoptions) | |
406 | (void)printf("Request for Remote Echo Denied by Server\r\n"); | |
407 | } | |
408 | else /*Else no request pending*/ | |
409 | { | |
410 | if(showoptions) | |
411 | (void)printf("Server Request Ignored--Now in Local Echo\r\n"); | |
412 | } | |
413 | } | |
414 | } | |
415 | } | |
416 | if(active & SUP_GA) | |
417 | /*Update to Suppress Go Ahead Control Object*/ | |
418 | { | |
419 | if(SUP_GA & *coptr->co_cmd.bool_update.value) | |
420 | { | |
421 | if(showoptions) | |
422 | (void)printf("Suppress Go Ahead\r\n"); | |
423 | na_image |= SUP_GA; | |
424 | if((ni_image & SUP_GA) == (nego_state & SUP_GA)) | |
425 | /*If no outstanding request from User*/ | |
426 | { | |
427 | if(!(nego_state & SUP_GA)) | |
428 | /*If not currently in Suppress Go Ahead*/ | |
429 | { | |
430 | ni_image |= SUP_GA; | |
431 | vt_set_nego(ni_image,SUP_GA);/*Reply "Will"*/ | |
432 | } | |
433 | } | |
434 | nego_state |= SUP_GA;/*Either here now or entering*/ | |
435 | } | |
436 | else | |
437 | { | |
438 | if(showoptions) | |
439 | (void)printf("Go Ahead\r\n"); | |
440 | na_image &= ~SUP_GA; | |
441 | if( (ni_image & SUP_GA) == (nego_state & SUP_GA) ) | |
442 | /*Must be request from Server*/ | |
443 | { | |
444 | ni_image |= SUP_GA; | |
445 | vt_set_nego(ni_image,SUP_GA);/*Reply "Won't"*/ | |
446 | } | |
447 | else /*Else response to my request to Suppress*/ | |
448 | { | |
449 | if(showoptions) | |
450 | (void)printf("Server refuses to Suppress Go Ahead\r\n"); | |
451 | ni_image &= ~SUP_GA; /*Give Up*/ | |
452 | /*May want to terminate Association here*/ | |
453 | } | |
454 | } | |
455 | } | |
456 | if(active & DISP_BIN) | |
457 | /*Update to WACA Binary Repertoire*/ | |
458 | { | |
459 | if(DISP_BIN & *coptr->co_cmd.bool_update.value) | |
460 | { | |
461 | if(showoptions) | |
462 | (void)printf("WACA requested Binary Repertoire on DI\r\n"); | |
463 | if((ni_image & DISP_BIN) == (nego_state & DISP_BIN)) | |
464 | /*No request outstanding from Initiator*/ | |
465 | { | |
466 | if(!(nego_state & DISP_BIN)) /*If not now binary*/ | |
467 | { | |
468 | ni_image |= DISP_BIN; | |
469 | vt_set_nego(ni_image,DISP_BIN); /*Send "Will"*/ | |
470 | } | |
471 | } | |
472 | nego_state |= DISP_BIN; | |
473 | ni_image |= DISP_BIN; | |
474 | } | |
475 | else | |
476 | { | |
477 | if(showoptions) | |
478 | (void)printf("WACA requested ASCII Repertoire on DI\r\n"); | |
479 | if((ni_image & DISP_BIN) == (nego_state & DISP_BIN)) | |
480 | { | |
481 | if(nego_state & DISP_BIN) /*If not now ASCII*/ | |
482 | { | |
483 | ni_image &= ~DISP_BIN; | |
484 | vt_set_nego(ni_image,DISP_BIN); | |
485 | } | |
486 | } | |
487 | nego_state &= ~DISP_BIN; | |
488 | ni_image &= ~DISP_BIN; | |
489 | } | |
490 | } | |
491 | if(active & KBD_BIN) | |
492 | /*Update to WACI Binary Repertoire*/ | |
493 | { | |
494 | if(KBD_BIN & *coptr->co_cmd.bool_update.value) | |
495 | { | |
496 | if(showoptions) | |
497 | (void)printf("WACA requested Binary Repertoire on KB\r\n"); | |
498 | if((ni_image & KBD_BIN) == (nego_state & KBD_BIN)) | |
499 | /*If no initiator request outstanding*/ | |
500 | { | |
501 | if(!(nego_state & KBD_BIN))/*If not now binary*/ | |
502 | { | |
503 | ni_image |= KBD_BIN; | |
504 | vt_set_nego(ni_image,KBD_BIN); /*Reply "Will"*/ | |
505 | switch_rep(2); | |
506 | /*Send Attribute update to use Binary Repertoire*/ | |
507 | } | |
508 | } | |
509 | else /*Else a response to Initiator Request*/ | |
510 | { | |
511 | if(ni_image & KBD_BIN) /*Positive response*/ | |
512 | switch_rep(2); | |
513 | } | |
514 | ni_image |= KBD_BIN; | |
515 | nego_state |= KBD_BIN; | |
516 | } | |
517 | else | |
518 | { | |
519 | if(showoptions) | |
520 | (void)printf("Acceptor requested ASCII Repertoire on KB\r\n"); | |
521 | if((ni_image & KBD_BIN) == (nego_state & KBD_BIN)) | |
522 | /*Request from Acceptor*/ | |
523 | { | |
524 | if(nego_state & KBD_BIN) /*If not now ASCII*/ | |
525 | { | |
526 | ni_image &= ~KBD_BIN; | |
527 | vt_set_nego(ni_image,KBD_BIN); /*Reply "Will"*/ | |
528 | switch_rep(1);/*Send Attr to ASCII*/ | |
529 | } | |
530 | } | |
531 | else /*Else response to Initiator Request*/ | |
532 | { | |
533 | if( !(ni_image & KBD_BIN))/*Positive response*/ | |
534 | switch_rep(1); | |
535 | } | |
536 | ni_image &= ~KBD_BIN; | |
537 | nego_state &= ~KBD_BIN; | |
538 | } | |
539 | } | |
540 | } | |
541 | } | |
542 | else /*Else Server (Display) side*/ | |
543 | { | |
544 | if(!strcmp(coptr->co_name,"KB") ) | |
545 | /*Server receives updates to the Keyboard*/ | |
546 | { | |
547 | if(active & AYT_OBJ) | |
548 | /*If This CO contains potential update to Are You There bit*/ | |
549 | { | |
550 | if( (kb_image & AYT_OBJ) != | |
551 | (AYT_OBJ & *coptr->co_cmd.bool_update.value)) | |
552 | /*If this bit was toggled*/ | |
553 | { | |
554 | if(debug) | |
555 | advise(LLOG_DEBUG,NULLCP, "Toggled AYT in KB"); | |
556 | kb_image ^= AYT_OBJ; /*Save the new value*/ | |
557 | if (vt_text("[associated with terminal service on ", strlen("[associated with terminal service on ")) != OK) | |
558 | advise(LLOG_NOTICE,NULLCP, "vt_text failed"); | |
559 | if (vt_text(myhostname,strlen(myhostname)) != OK) | |
560 | advise(LLOG_NOTICE,NULLCP, "vt_text failed"); | |
561 | if (vt_text("]\r\n",3) != OK) | |
562 | advise(LLOG_NOTICE,NULLCP, "vt_text failed"); | |
563 | vtsend(); | |
564 | } | |
565 | } | |
566 | if(active & AO_OBJ) | |
567 | /*If potential update to Abort Output bit*/ | |
568 | { | |
569 | if( (kb_image & AO_OBJ) != | |
570 | (AO_OBJ & *coptr->co_cmd.bool_update.value)) | |
571 | /*Toggled AO bit*/ | |
572 | { | |
573 | if(debug) | |
574 | advise(LLOG_DEBUG,NULLCP, "Toggled AO in KB"); | |
575 | kb_image ^= AO_OBJ; /*Record it*/ | |
576 | } | |
577 | } | |
578 | if(active & IP_OBJ) | |
579 | /*If potential update to Interrupt Process bit*/ | |
580 | { | |
581 | if( (kb_image & IP_OBJ) != | |
582 | (IP_OBJ & *coptr->co_cmd.bool_update.value)) | |
583 | /*Toggled IP bit*/ | |
584 | { | |
585 | if(debug) | |
586 | advise(LLOG_DEBUG,NULLCP, "Toggled IP in KB"); | |
587 | kb_image ^= IP_OBJ; | |
588 | kill_proc(); | |
589 | } | |
590 | } | |
591 | if(active & DM_OBJ) | |
592 | { | |
593 | if( (kb_image & DM_OBJ) != | |
594 | (DM_OBJ & *coptr->co_cmd.bool_update.value)) | |
595 | { | |
596 | /*Toggled DM BIt*/ | |
597 | if(debug) | |
598 | advise(LLOG_DEBUG,NULLCP, "Toggled DM in KB"); | |
599 | kb_image ^= DM_OBJ; | |
600 | } | |
601 | } | |
602 | if(active & BRK_OBJ) | |
603 | /*If potential update to Break Bit*/ | |
604 | { | |
605 | if( (kb_image & BRK_OBJ) != | |
606 | (BRK_OBJ & *coptr->co_cmd.bool_update.value)) | |
607 | /*Toggled BREAK bit*/ | |
608 | { | |
609 | if(debug) | |
610 | advise(LLOG_DEBUG,NULLCP, "Toggled BREAK in KB"); | |
611 | kb_image ^= BRK_OBJ; | |
612 | kill_proc(); | |
613 | } | |
614 | } | |
615 | } | |
616 | else if( !strcmp(coptr->co_name,"NI") ) | |
617 | { | |
618 | if(active & ECHO_OBJ) | |
619 | /*Update to Echo Control Object*/ | |
620 | { | |
621 | if(ECHO_OBJ & *coptr->co_cmd.bool_update.value) | |
622 | /*Request from User for Remote Echo*/ | |
623 | { | |
624 | ni_image |= ECHO_OBJ; | |
625 | if(showoptions) | |
626 | (void)printf("Remote Echo Update Received\n"); | |
627 | if(ECHO_OBJ & nego_state) /*If now in Remote Echo*/ | |
628 | { | |
629 | if(na_image & ECHO_OBJ) /*No request outstatnding*/ | |
630 | advise(LLOG_NOTICE,NULLCP, "User Request ignored--Now in Remote echo"); | |
631 | else /*Must be user's response to a request*/ | |
632 | { | |
633 | if(showoptions) | |
634 | (void)printf("Request for Local Echo Denied by User\n"); | |
635 | na_image |= ECHO_OBJ; | |
636 | } | |
637 | } | |
638 | else /*Else Not in Remote Echo*/ | |
639 | { | |
640 | if(na_image & ECHO_OBJ) /*I Requested Remote Echo*/ | |
641 | /*This must be confirmation*/ | |
642 | { | |
643 | if(showoptions) | |
644 | (void)printf("User agreed to do Remote Echo\n"); | |
645 | } | |
646 | else /*Request to do Remote Echo*/ | |
647 | { | |
648 | if(showoptions) | |
649 | (void)printf("User Requested Remote Echo--O.K.\n"); | |
650 | na_image |= ECHO_OBJ; | |
651 | vt_set_nego(na_image,ECHO_OBJ);/*Respond "WILL"*/ | |
652 | } | |
653 | #ifdef BSD44 | |
654 | realptyecho(1); | |
655 | #else | |
656 | if (ioctl(pty,TIOCGETP,(char*)&sb) == -1) { | |
657 | perror("ioctl"); | |
658 | adios(NULLCP, "ioctl failed"); | |
659 | } | |
660 | sb.sg_flags |= ECHO; /*Turn on Echo*/ | |
661 | if (ioctl(pty,TIOCSETP,(char*)&sb) == -1) { | |
662 | perror("ioctl"); | |
663 | adios(NULLCP, "ioctl failed"); | |
664 | } | |
665 | #endif | |
666 | nego_state |= ECHO_OBJ; | |
667 | cur_emode = NOT_ECHO_NOW; /*Don't Want user to Echo*/ | |
668 | } | |
669 | } | |
670 | else /*Request from user for Local Echo*/ | |
671 | { | |
672 | if(showoptions) | |
673 | (void)printf("NI--Local Echo\n"); | |
674 | cur_emode = NOT_ECHO_NOW; | |
675 | ni_image &= ~ECHO_OBJ; | |
676 | if(nego_state & ECHO_OBJ) /*If now in Remote Echo*/ | |
677 | { | |
678 | if(na_image & ECHO_OBJ) /*If no request pending*/ | |
679 | /*Must be request from user*/ | |
680 | { | |
681 | ||
682 | #ifdef DO_LOCAL_ECHO | |
683 | if(showoptions) | |
684 | (void)printf("User requested Local Echo -- O.K.\n"); | |
685 | ||
686 | na_image &= ~ECHO_OBJ; | |
687 | nego_state &= ~ECHO_OBJ; | |
688 | #ifdef BSD44 | |
689 | ptyecho(0); | |
690 | #else | |
691 | setmode(0,ECHO); | |
692 | #endif | |
693 | #else | |
694 | na_image |= ECHO_OBJ; | |
695 | if(showoptions) | |
696 | (void)printf("User requested Local Echo -- Denied\n"); | |
697 | #endif | |
698 | ||
699 | vt_set_nego(na_image,ECHO_OBJ); /*Respond "WILL"*/ | |
700 | } | |
701 | else | |
702 | { | |
703 | if(showoptions) | |
704 | (void)printf("Server request for Local Echo Accepted\n"); | |
705 | nego_state &= ~ECHO_OBJ; | |
706 | #ifdef BSD44 | |
707 | ptyecho(0); | |
708 | #else | |
709 | setmode(0,ECHO); | |
710 | #endif | |
711 | } | |
712 | } | |
713 | else /*Else now in Local Echo*/ | |
714 | { | |
715 | if(na_image & ECHO_OBJ) /*If requeset pending*/ | |
716 | /*Must be negative response*/ | |
717 | { | |
718 | na_image &= ~ECHO_OBJ; | |
719 | if(showoptions) | |
720 | (void)printf("Request for Remote Echo Denied by User\n"); | |
721 | } | |
722 | else /*Else no request pending*/ | |
723 | { | |
724 | if(showoptions) | |
725 | (void)printf("User Request Ignored--Now in Local Echo\n"); | |
726 | } | |
727 | } | |
728 | } | |
729 | } | |
730 | if(active & SUP_GA) | |
731 | /*Update to Suppress Go Ahead Control Object*/ | |
732 | { | |
733 | if(SUP_GA & *coptr->co_cmd.bool_update.value) | |
734 | { | |
735 | if(showoptions) | |
736 | (void)printf("Suppress Go Ahead\n"); | |
737 | ni_image |= SUP_GA; | |
738 | if((na_image & SUP_GA) == (nego_state &SUP_GA)) | |
739 | /*If no request from Acceptor outstanding*/ | |
740 | { | |
741 | if(!(nego_state & SUP_GA)) | |
742 | /*If not currently in Supress Go Ahead*/ | |
743 | { | |
744 | na_image |= SUP_GA; | |
745 | vt_set_nego(na_image,SUP_GA);/*Reply "Will"*/ | |
746 | } | |
747 | } | |
748 | nego_state |= SUP_GA; /*Entering or already there*/ | |
749 | } | |
750 | else | |
751 | { | |
752 | if(showoptions) | |
753 | (void)printf("Don't Suppress Go Ahead\n"); | |
754 | ni_image &= ~SUP_GA; | |
755 | if((na_image & SUP_GA) == (nego_state & SUP_GA)) | |
756 | /*Must be request from Initiator*/ | |
757 | { | |
758 | na_image |= SUP_GA; | |
759 | vt_set_nego(na_image,SUP_GA);/*Reply "Won't"*/ | |
760 | } | |
761 | else /*Else reply to my request*/ | |
762 | { | |
763 | if(showoptions) | |
764 | (void)printf("User refuses to Suppress Go Ahead\n"); | |
765 | na_image &= ~SUP_GA; /*Give up*/ | |
766 | } | |
767 | } | |
768 | } | |
769 | if(active & DISP_BIN) | |
770 | /*Update to WACI Binary Repertoire*/ | |
771 | { | |
772 | if(DISP_BIN & *coptr->co_cmd.bool_update.value) | |
773 | { | |
774 | if(showoptions) | |
775 | (void)printf("Initiator requested Binary Repertoire on DI\n"); | |
776 | if((na_image & DISP_BIN) == (nego_state & DISP_BIN)) | |
777 | /*No request outstanding from Acceptor*/ | |
778 | { | |
779 | if(!(nego_state & DISP_BIN)) /*If not now binary*/ | |
780 | { | |
781 | na_image |= DISP_BIN; | |
782 | vt_set_nego(na_image,DISP_BIN); /*Send "Will"*/ | |
783 | switch_rep(2); | |
784 | } | |
785 | } | |
786 | else /*Else a response to Acceptor request*/ | |
787 | { | |
788 | if(na_image & KBD_BIN) /*Positive Response*/ | |
789 | switch_rep(2); | |
790 | } | |
791 | nego_state |= DISP_BIN; | |
792 | na_image |= DISP_BIN; | |
793 | } | |
794 | else | |
795 | { | |
796 | if(showoptions) | |
797 | (void)printf("Initiator requested ASCII Repertoire on DI\n"); | |
798 | if((na_image & DISP_BIN) == (nego_state & DISP_BIN)) | |
799 | { | |
800 | if(nego_state & DISP_BIN) /*If not now ASCII*/ | |
801 | { | |
802 | na_image &= ~DISP_BIN; | |
803 | vt_set_nego(na_image,DISP_BIN); | |
804 | switch_rep(1); | |
805 | } | |
806 | } | |
807 | else | |
808 | { | |
809 | if(!(na_image & KBD_BIN)) /*Positive Response*/ | |
810 | switch_rep(1); | |
811 | } | |
812 | nego_state &= ~DISP_BIN; | |
813 | na_image &= ~DISP_BIN; | |
814 | } | |
815 | } | |
816 | if(active & KBD_BIN) | |
817 | /*Update to WACI Binary Repertoire*/ | |
818 | { | |
819 | if(KBD_BIN & *coptr->co_cmd.bool_update.value) | |
820 | { | |
821 | if(showoptions) | |
822 | (void)printf("Initiator requested Binary Repertoire on KB\n"); | |
823 | if((na_image & KBD_BIN) == (nego_state & KBD_BIN)) | |
824 | /*If no Acceptor request outstanding*/ | |
825 | { | |
826 | if(!(nego_state & KBD_BIN))/*If not now binary*/ | |
827 | { | |
828 | na_image |= KBD_BIN; | |
829 | vt_set_nego(na_image,KBD_BIN); /*Reply "Will"*/ | |
830 | } | |
831 | } | |
832 | na_image |= KBD_BIN; | |
833 | nego_state |= KBD_BIN; | |
834 | } | |
835 | else | |
836 | { | |
837 | if(showoptions) | |
838 | (void)printf("Initiator requested ASCII Repertoire on KB\n"); | |
839 | if((na_image & KBD_BIN) == (nego_state & KBD_BIN)) | |
840 | /*Request from Initator*/ | |
841 | { | |
842 | if(nego_state & KBD_BIN) /*If not now ASCII*/ | |
843 | { | |
844 | na_image &= ~KBD_BIN; | |
845 | vt_set_nego(na_image,KBD_BIN); /*Reply "Will"*/ | |
846 | } | |
847 | } | |
848 | na_image &= ~KBD_BIN; | |
849 | nego_state &= ~KBD_BIN; | |
850 | } | |
851 | } | |
852 | } | |
853 | } | |
854 | if( !strcmp(coptr->co_name,"SY") ) /*SYNCHRONIZE CO can be written | |
855 | by Initiator or Acceptor*/ | |
856 | { | |
857 | if(active & SYNC) | |
858 | /*Potential Update to Synch*/ | |
859 | { | |
860 | if( (SYNC & *coptr->co_cmd.bool_update.value) != | |
861 | (SYNC & sync_image) ) | |
862 | { | |
863 | advise(LLOG_NOTICE,NULLCP, "Toggled SYNC"); | |
864 | sync_image ^= SYNC; | |
865 | } | |
866 | } | |
867 | } | |
868 | if( !strcmp(coptr->co_name,"GA") ) | |
869 | { | |
870 | if(active & GO_AHEAD) | |
871 | /*Potential Update to Go Ahead*/ | |
872 | { | |
873 | if( (GO_AHEAD & *coptr->co_cmd.bool_update.value) != | |
874 | (GO_AHEAD & ga_image) ) | |
875 | { | |
876 | if(debug) | |
877 | advise(LLOG_DEBUG,NULLCP, "Toggled Go Ahead"); | |
878 | ga_image ^= GO_AHEAD; | |
879 | } | |
880 | } | |
881 | } | |
882 | ||
883 | } | |
884 | \f | |
885 | attrib_hdlr(doptr) /*Handle Write Attribute Display Object Update*/ | |
886 | DO_UPDATE *doptr; | |
887 | { | |
888 | ||
889 | ||
890 | if(doptr->do_cmd.wrt_attrib.attr_id == 0) | |
891 | /*If switching repertoires*/ | |
892 | { | |
893 | if(doptr->do_cmd.wrt_attrib.attr_ext == 2) | |
894 | /*If Modal extent*/ | |
895 | { | |
896 | if(doptr->do_cmd.wrt_attrib.attr_val == 1) | |
897 | { | |
898 | if(showoptions) | |
899 | if(my_right == INITIATOR) | |
900 | (void)printf("Switching to ASCII Repertoire\r\n"); | |
901 | transparent = 0; | |
902 | } | |
903 | else if(doptr->do_cmd.wrt_attrib.attr_val == 2) | |
904 | { | |
905 | if(showoptions) | |
906 | if(my_right == INITIATOR) | |
907 | (void)printf("Switching to Transparent profile.\r\n"); | |
908 | transparent = 1; | |
909 | } | |
910 | else (void)printf("Attribute for unavailable repertoire\n"); | |
911 | } | |
912 | else (void)printf("Attribute update with invalid extent (%d)\n", | |
913 | doptr->do_cmd.wrt_attrib.attr_ext); | |
914 | } | |
915 | else | |
916 | advise(LLOG_NOTICE,NULLCP, "Attribute Update with invalid I.D. (%d)\n", doptr->do_cmd.wrt_attrib.attr_id); | |
917 | } | |
918 | ||
919 | /* \f TTY */ | |
920 | ||
921 | #ifdef BSD44 | |
922 | extern struct termios oterm; | |
923 | ||
924 | int | |
925 | tmode(f) | |
926 | int f; | |
927 | { | |
928 | static int prevmode = 0; | |
929 | struct termios term; | |
930 | int onoff, old; | |
931 | ||
932 | if (prevmode == f) | |
933 | return (f); | |
934 | old = prevmode; | |
935 | prevmode = f; | |
936 | term = oterm; | |
937 | switch (f) { | |
938 | case 0: | |
939 | onoff = 0; | |
940 | break; | |
941 | case 1: | |
942 | case 2: | |
943 | onoff = 1; | |
944 | if (f == 1) | |
945 | { | |
946 | term.c_lflag &= ~ECHO; | |
947 | term.c_oflag &= ~OPOST; | |
948 | } | |
949 | else | |
950 | { | |
951 | term.c_lflag |= ECHO; | |
952 | term.c_oflag |= OPOST; | |
953 | } | |
954 | term.c_lflag &= ~(IEXTEN|ISIG|ICANON); | |
955 | break; | |
956 | default: | |
957 | return old; | |
958 | } | |
959 | if (tcsetattr(fileno(stdin), TCSAFLUSH, &term) == -1) | |
960 | perror("tcsetattr"); | |
961 | if (ioctl(fileno(stdin), FIONBIO, (char*)&onoff) == -1) { | |
962 | perror("ioctl"); | |
963 | } | |
964 | return (old); | |
965 | } | |
966 | ||
967 | #else | |
968 | ||
969 | extern struct tchars otc; | |
970 | extern struct ltchars oltc; | |
971 | extern struct sgttyb ottyb; | |
972 | ||
973 | /* struct tchars notc = { -1, 3, -1, -1, -1, -1 };*/ | |
974 | struct tchars notc = { | |
975 | -1, -1, -1, -1, -1, -1 }; | |
976 | struct ltchars noltc = { | |
977 | -1, -1, -1, -1, -1, -1 }; | |
978 | ||
979 | int | |
980 | tmode(f) | |
981 | register int f; | |
982 | { | |
983 | static int prevmode = 0; | |
984 | struct tchars *tc; | |
985 | struct ltchars *ltc; | |
986 | struct sgttyb sb; | |
987 | int onoff, old; | |
988 | ||
989 | if (prevmode == f) | |
990 | return (f); | |
991 | old = prevmode; | |
992 | prevmode = f; | |
993 | sb = ottyb; | |
994 | switch (f) { | |
995 | ||
996 | case 0: | |
997 | onoff = 0; | |
998 | tc = &otc; | |
999 | ltc = &oltc; | |
1000 | break; | |
1001 | ||
1002 | case 1: | |
1003 | case 2: | |
1004 | if (f == 1) | |
1005 | { | |
1006 | sb.sg_flags |= CBREAK; | |
1007 | sb.sg_flags &= ~(ECHO|CRMOD); | |
1008 | sb.sg_erase = sb.sg_kill = -1; | |
1009 | } | |
1010 | else | |
1011 | { | |
1012 | sb.sg_flags &= CBREAK; | |
1013 | sb.sg_flags |= ECHO|CRMOD; | |
1014 | } | |
1015 | tc = ¬c; | |
1016 | notc.t_stopc = otc.t_stopc; | |
1017 | notc.t_startc = otc.t_startc; | |
1018 | ltc = &noltc; | |
1019 | onoff = 1; | |
1020 | break; | |
1021 | ||
1022 | default: | |
1023 | return old; | |
1024 | } | |
1025 | if (ioctl(fileno(stdin), TIOCSLTC, (char *)ltc) == -1) { | |
1026 | perror("ioctl"); | |
1027 | adios(NULLCP, "ioctl failed"); | |
1028 | } | |
1029 | if (ioctl(fileno(stdin), TIOCSETC, (char *)tc) == -1) { | |
1030 | perror("ioctl"); | |
1031 | adios(NULLCP, "ioctl failed"); | |
1032 | } | |
1033 | if (ioctl(fileno(stdin), TIOCSETP, (char *)&sb) == -1) { | |
1034 | perror("ioctl"); | |
1035 | adios(NULLCP, "ioctl failed"); | |
1036 | } | |
1037 | if (ioctl(fileno(stdin), FIONBIO, (char*)&onoff) == -1) { | |
1038 | perror("ioctl"); | |
1039 | adios(NULLCP, "ioctl failed"); | |
1040 | } | |
1041 | if (ioctl(fileno(stdout), FIONBIO, (char*)&onoff) == -1) { | |
1042 | perror("ioctl"); | |
1043 | adios(NULLCP, "ioctl failed"); | |
1044 | } | |
1045 | return (old); | |
1046 | } | |
1047 | #endif | |
1048 | ||
1049 | kill_proc() /*Terminate current UNIX process using UNIX interrupt char*/ | |
1050 | { | |
1051 | #ifdef BSD44 | |
1052 | struct termios term; | |
1053 | ||
1054 | if (tcgetattr(pty, &term) == -1) | |
1055 | perror("tcgetattr"); | |
1056 | else if (term.c_cc[VINTR] != _POSIX_VDISABLE) | |
1057 | (void) putch(term.c_cc[VINTR]); | |
1058 | #else | |
1059 | if(ioctl(pty,TIOCGETC,(char *)&otc) == -1) | |
1060 | { | |
1061 | perror("ioctl"); | |
1062 | adios(NULLCP, "ioctl failed"); | |
1063 | } | |
1064 | (void) putch(otc.t_intrc); | |
1065 | #endif | |
1066 | } | |
1067 | ||
1068 | def_echo(coptr) /*Handle Default Profile Echo Ctrl Object*/ | |
1069 | CO_UPDATE *coptr; | |
1070 | { | |
1071 | ||
1072 | char active = 0; | |
1073 | ||
1074 | if(coptr->co_cmd.bool_update.mask_count == 0) active = 0xff; | |
1075 | else active = *coptr->co_cmd.bool_update.mask; | |
1076 | ||
1077 | if (active & ECHO_OBJ) { | |
1078 | if(*coptr->co_cmd.bool_update.value & ECHO_OBJ) | |
1079 | /*True means do local echo*/ | |
1080 | (void) tmode(2); | |
1081 | else | |
1082 | (void) tmode(1); | |
1083 | } | |
1084 | } | |
1085 | #ifdef BSD44 | |
1086 | static realptyecho(on) | |
1087 | { | |
1088 | struct termios term; | |
1089 | ||
1090 | if (tcgetattr(pty, &term) == -1) { | |
1091 | perror("tcgetattr"); | |
1092 | return; | |
1093 | } | |
1094 | if (on) | |
1095 | term.c_lflag |= ECHO; | |
1096 | else | |
1097 | term.c_lflag &= ECHO; | |
1098 | if (tcsetattr(pty, TCSAFLUSH, &term) == -1) { | |
1099 | perror("tcsetattr"); | |
1100 | return; | |
1101 | } | |
1102 | } | |
1103 | #endif |