1 /*
2  *  jhlp.c,v 1.13 2002/08/26 09:27:21 aono Exp
3  *  Canna: $Id: jhlp.c,v 1.9.2.1 2004/04/26 21:48:37 aida_s Exp $
4  */
5 
6 /*
7  * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
8  * This file is part of FreeWnn.
9  *
10  * Copyright Kyoto University Research Institute for Mathematical Sciences
11  *                 1987, 1988, 1989, 1990, 1991, 1992
12  * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
13  * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992
14  * Copyright FreeWnn Project 1999, 2000, 2002
15  *
16  * Maintainer:  FreeWnn Project   <freewnn@tomo.gr.jp>
17  *
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 2 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
31  */
32 
33 #ifndef lint
34 static char *rcs_id = "jhlp.c,v 1.13 2002/08/26 09:27:21 aono Exp";
35 #endif /* lint */
36 
37 #ifdef HAVE_CONFIG_H
38 #  include <config.h>
39 #endif
40 
41 #include <stdio.h>
42 #include <setjmp.h>
43 #include <signal.h>
44 #if STDC_HEADERS
45 #  include <stdlib.h>
46 #  include <string.h>
47 #else
48 #  if HAVE_STRINGS_H
49 #    include <strings.h>
50 #  endif
51 #  if HAVE_MALLOC_H
52 #    include <malloc.h>
53 #  endif
54 #endif /* STDC_HEADERS */
55 #include <errno.h>
56 #include <sys/ioctl.h>
57 #ifdef HAVE_SYS_PARAM_H
58 #  include <sys/param.h>
59 #endif
60 #include <sys/stat.h>
61 #include <sys/time.h>
62 #include <sys/types.h>
63 #if HAVE_FCNTL_H
64 #  include <fcntl.h>
65 #endif
66 #include <pwd.h>
67 #ifdef HAVE_UNISTD_H
68 #  include <unistd.h>
69 #endif
70 #ifdef UX386
71 #include <sys/kdef.h>
72 #endif
73 
74 #include "commonhd.h"
75 #include "sdefine.h"
76 #include "sheader.h"
77 #include "wnn_config.h"
78 #include "wnn_os.h"
79 
80 
81 jmp_buf kk_env;
82 
83 
84 #ifdef HAVE_WAIT3
85 #       include <sys/wait.h>
86 #endif /* HAVE_WAIT3 */
87 
88 #ifdef USE_LIBSPT
89 # include <libspt.h>
90 #endif
91 
92 #if defined(HAVE_TERMIOS_H)
93 # include <termios.h>
94 # define USE_TERMIOS
95 #elif defined(HAVE_TERMIO_H)
96 # include <termio.h>
97 # define USE_TERMIO
98 #elif defined(HAVE_SYS_TERMIO_H)
99 # include <sys/termio.h>
100 # define USE_TERMIO
101 #elif defined(HAVE_SGTTY_H)
102 # include <sgtty.h>
103 # define USE_SGTTY
104 #else
105 # error "No termio header."
106 #endif
107 
108 #ifdef linux
109 /* # define USE_LINUX_TERM */
110 #endif
111 
112 #ifdef nec_ews_svr2
113 #include <sys/jtermio.h>
114 #endif /* nec_ews_svr2 */
115 
116 #if defined(uniosu)
117 #       include <sys/pty.h>
118 #endif /* defined(uniosu) */
119 
120 #ifdef SVR4
121 #include <sys/stropts.h>
122 #include <sys/euc.h>
123 #include <sys/eucioctl.h>
124 #endif /* SVR4 */
125 
126 #ifdef CANNA
127 #ifndef	LIBDIR
128 #define	LIBDIR		"/usr/local/lib/wnn"
129 #endif
130 #endif /* CANNA */
131 
132 
133 #define ERROR -1
134 
135 #ifdef TIOCSSIZE
136 struct ttysize pty_rowcol;
137 #endif /* TIOCSSIZE */
138 
139 int ttyfd;
140 
141 char *tname;                    /* terminal name */
142 char *cmdnm = "csh";            /* char *cmdnm = "csh"; */
143 
144 int child_id;
145 char *prog;
146 #ifdef USE_LIBSPT
147 spt_handle *spth = NULL;
148 int need_utmp_clear = 0;
149 #endif
150 
151 extern char *optarg;
152 extern int optind;
153 
154 extern char *ttyname ();
155 
156 static void save_signals ();
157 static void restore_signals ();
158 
159 static RETSIGTYPE terminate_handler ();
160 static void do_end (), open_pty (), open_ttyp (), do_main (), exec_cmd (), parse_options (), setsize (), get_rubout (), usage (), change_size (), default_usage ();
161 static void j_term_save (), j_term_restore (), j_term_p_init (int);
162 
163 /** �ᥤ�� */
164 int
main(argc,argv)165 main (argc, argv)
166      int argc;
167      char **argv;
168 {
169 
170   char *name;
171   char *p;
172   char nlspath[64];
173   FuncDataBase *f;
174   char *server_env;
175   char errprefix[1024] = "error";
176   int i;
177   extern char *get_server_env ();
178 
179   prog = argv[0];
180   flow_control = FLOW_CONTROL;
181   code_trans = default_code_trans;
182 
183   strcpy (username, getpwuid (getuid ())->pw_name);
184   if ((name = getenv (WNN_USERNAME_ENV)) != NULL)
185     {
186       strncpy(username, name, PATHNAMELEN-1);
187       username[PATHNAMELEN-1] = '\0';
188     }
189   for (i = 1; i < argc;)
190     {
191       if (!strcmp (argv[i++], "-L"))
192         {
193           if (i >= argc || argv[i][0] == '-')
194             default_usage ();
195           strncpy(lang_dir, argv[i++], LANGDIRLEN-1);
196           lang_dir[LANGDIRLEN-1] = '\0';
197           for (; i < argc; i++)
198             {
199               argv[i - 2] = argv[i];
200             }
201           argv[i - 2] = NULL;
202           argc -= 2;
203           break;
204         }
205     }
206 
207   if (*lang_dir == '\0')
208     {
209 #ifndef CANNA
210       if ((p = getenv ("LANG")) != NULL)
211         {
212           if (strlen (p) >= 4)
213             {
214               strncpy (lang_dir, p, 5);
215               lang_dir[5] = '\0';
216             }
217           else
218             {
219               strcpy (lang_dir, p);
220             }
221         }
222 #else /* CANNA */
223       strcpy (lang_dir, WNN_DEFAULT_LANG);
224 #endif /* CANNA */
225     }
226   for (f = function_db; *lang_dir && f && f->lang; f++)
227     {
228       if (!strcmp (f->lang, lang_dir))
229         {
230           lang_db = f;
231           break;
232         }
233     }
234   if (lang_db == NULL)
235     {
236       if (*lang_dir)
237         fprintf (stderr, "Lang \"%s\" is wrong, use default lang \"%s\".\n", lang_dir, WNN_DEFAULT_LANG);
238       strcpy (lang_dir, WNN_DEFAULT_LANG);
239       for (f = function_db; *lang_dir && f && f->lang; f++)
240         {
241           if (!strcmp (f->lang, lang_dir))
242             {
243               lang_db = f;
244               break;
245             }
246         }
247       if (lang_db == NULL)
248         {
249           fprintf (stderr, "Default lang \"%s\" is wrong.\n", lang_dir);
250           exit (1);
251         }
252     }
253   f_table = &(lang_db->f_table);
254   code_trans = lang_db->code_trans;
255   tty_c_flag = lang_db->tty_code;
256   pty_c_flag = lang_db->pty_code;
257   internal_code = lang_db->internal_code;
258   file_code = lang_db->file_code;
259 
260   parse_options (argc, argv);
261 
262   strcpy (nlspath, LIBDIR);
263   strcat (nlspath, "/%L/%N");
264   cd = msg_open ("uum.msg", nlspath, lang_dir);
265 
266   if (*def_servername == '\0')
267     {
268       if (!(server_env = get_server_env (lang_dir)))
269         {
270           server_env = WNN_DEF_SERVER_ENV;
271         }
272       if (name = getenv (server_env))
273         {
274           strncpy(def_servername, name, PATHNAMELEN-1);
275           def_servername[PATHNAMELEN-1] = '\0';
276           strcpy(def_reverse_servername, def_servername);
277         }
278     }
279 
280   if (!isatty (0))
281     {
282       fprintf (stderr, "Input must be a tty.\n");
283       exit (1);
284     }
285 
286   if ((p = getenv (WNN_COUNTDOWN_ENV)) == NULL)
287     {
288       if (setenv (WNN_COUNTDOWN_ENV, "0", 1) != 0)
289 	{
290 #if HAVE_SNPRINTF
291 	  snprintf (errprefix, sizeof (errprefix),
292 		    "error at %s (%d)", __FILE__, __LINE__);
293 #endif /* HAVE_SNPRINTF */
294 	  perror (errprefix);
295 	  exit (1);
296 	}
297     }
298   else if (atoi (p) <= 0)
299     {
300       puteustring (MSG_GET (4), stdout);
301       /*
302          puteustring("�������������ϵ������ޤ���\n",stdout);
303        */
304       exit (126);
305     }
306   else
307     {
308       sprintf (p, "%d", atoi (p) - 1);
309       if (setenv (WNN_COUNTDOWN_ENV, p, 1) != 0)
310 	{
311 #if HAVE_SNPRINTF
312 	  snprintf (errprefix, sizeof (errprefix),
313 		    "error at %s (%d)", __FILE__, __LINE__);
314 #endif /* HAVE_SNPRINTF */
315 	  perror (errprefix);
316 	  exit (1);
317 	}
318     }
319 
320   if ((tname = getenv ("TERM")) == NULL)
321     {
322       fprintf (stderr, "Sorry. Please set your terminal type.\r\n");
323       exit (1);
324     }
325 
326   if (optind)
327     {
328       optind--;
329       argc -= optind;
330       argv += optind;
331     }
332   if (argc > 1)
333     {
334       cmdnm = *++argv;
335     }
336   else
337     {
338       if ((name = getenv ("SHELL")) != NULL)
339         {
340           cmdnm = name;
341         }
342       argv[0] = cmdnm;
343       argv[1] = NULL;
344     }
345 
346   j_term_save ();
347   /* do_end() is allowed after here */
348   save_signals ();
349 
350 #ifdef TERMCAP
351   if (getTermData () == -1)
352     {
353       fprintf (stderr, "Sorry. Something is wrong with termcap, maybe.\r\n");
354       exit (21);
355     }
356 #endif /* TERMCAP */
357 #ifdef TERMINFO
358   if (openTermData () == -1)
359     {
360       fprintf (stderr, "Sorry. Something is wrong with terminfo, maybe.\r\n");
361       exit (21);
362     }
363   maxlength = columns;
364   crow = lines - conv_lines;
365 #endif /* TERMINFO */
366 #if defined(BSD43) || defined(DGUX)
367   setsize ();
368 #endif /* BSD43 */
369 
370 #ifdef TERMCAP
371   if (set_TERMCAP () == -1)
372     {
373       fprintf (stderr, "Sorry. Something is wrong with termcap, maybe.\r\n");
374       exit (21);
375     }
376 #endif /* TERMCAP */
377 
378   ttyfd = 0;
379   open_pty ();
380 #ifndef USE_LINUX_TERM
381   open_ttyp ();
382 #endif
383   exec_cmd (argv);
384 
385   get_rubout ();
386 
387   switch (init_uum ())
388     {                           /* initialize of kana-kanji henkan */
389     case -1:
390       terminate_handler ();
391       break;
392     case -2:
393       epilogue ();
394       do_end ();
395       break;
396     }
397 
398   fcntl (ttyfd, F_SETFL, O_NDELAY);
399 
400   if (j_term_init () == ERROR)
401     {
402       err ("term initialize fault.");
403     }
404 
405 #ifndef CANNA
406   if (!jl_isconnect (bun_data_))
407     {
408       if (!servername || *servername == 0)
409         {
410           printf ("%s\r\n", wnn_perror ());
411         }
412       else
413         {
414           printf ("jserver(at %s):%s\r\n", servername, wnn_perror ());
415         }
416       flush ();
417     }
418 #endif /* !CANNA */
419 
420   puteustring (MSG_GET (1),
421                /*
422                   "\r������(���ʴ����Ѵ��ե��ȥ���ɥץ��å�)\r\n",
423                 */
424                stdout);
425   initial_message_out ();       /* print message if exists. */
426 
427 #if defined(uniosu)
428   if (setjmp (kk_env))
429     {
430       disconnect_jserver ();
431       ioctl_off ();
432       connect_jserver (0);
433     }
434 #endif /* defined(uniosu) */
435 
436   do_main ();
437 }
438 
439 /*
440   each options handling functions
441  */
442 
443 static int
do_h_opt()444 do_h_opt ()
445 {
446   henkan_off_flag = 1;
447   defined_by_option |= OPT_WAKING_UP_MODE;
448   return 0;
449 }
450 
451 static int
do_H_opt()452 do_H_opt ()
453 {
454   henkan_off_flag = 0;
455   defined_by_option |= OPT_WAKING_UP_MODE;
456   return 0;
457 }
458 
459 #ifdef  JAPANESE
460 int
do_u_opt()461 do_u_opt ()
462 {
463   pty_c_flag = J_EUJIS;
464   return 0;
465 }
466 
467 int
do_j_opt()468 do_j_opt ()
469 {
470   pty_c_flag = J_JIS;
471   return 0;
472 }
473 
474 int
do_s_opt()475 do_s_opt ()
476 {
477   pty_c_flag = J_SJIS;
478   return 0;
479 }
480 
481 int
do_U_opt()482 do_U_opt ()
483 {
484   tty_c_flag = J_EUJIS;
485   return 0;
486 }
487 
488 int
do_J_opt()489 do_J_opt ()
490 {
491   tty_c_flag = J_JIS;
492   return 0;
493 }
494 
495 int
do_S_opt()496 do_S_opt ()
497 {
498   tty_c_flag = J_SJIS;
499   return 0;
500 }
501 #endif /* JAPANESE */
502 
503 #ifdef  CHINESE
504 int
do_b_opt()505 do_b_opt ()
506 {
507   pty_c_flag = C_BIG5;
508   return 0;
509 }
510 
511 int
do_t_opt()512 do_t_opt ()
513 {
514   pty_c_flag = C_ECNS11643;
515   return 0;
516 }
517 
518 int
do_B_opt()519 do_B_opt ()
520 {
521   tty_c_flag = C_BIG5;
522   return 0;
523 }
524 
525 int
do_T_opt()526 do_T_opt ()
527 {
528   tty_c_flag = C_ECNS11643;
529   return 0;
530 }
531 #endif /* CHINESE */
532 
533 #ifdef KOREAN
534 int
do_u_opt()535 do_u_opt ()
536 {
537   pty_c_flag = K_EUKSC;
538   return 0;
539 }
540 
541 int
do_U_opt()542 do_U_opt ()
543 {
544   tty_c_flag = K_EUKSC;
545   return 0;
546 }
547 #endif /* KOREAN */
548 
549 static int
do_P_opt()550 do_P_opt ()
551 {
552   sleep (20);
553   return 0;
554 }
555 
556 static int
do_x_opt()557 do_x_opt ()
558 {
559   flow_control = 0;
560   defined_by_option |= OPT_FLOW_CTRL;
561   return 0;
562 }
563 
564 static int
do_X_opt()565 do_X_opt ()
566 {
567   flow_control = 1;
568   defined_by_option |= OPT_FLOW_CTRL;
569   return 0;
570 }
571 
572 static int
do_k_opt()573 do_k_opt ()
574 {
575   strncpy(uumkey_name_in_uumrc, optarg, PATHNAMELEN-1);
576   uumkey_name_in_uumrc[PATHNAMELEN-1] = '\0';
577   if (*uumkey_name_in_uumrc == '\0')
578     {
579       return -1;
580     }
581   defined_by_option |= OPT_WNNKEY;
582   return 0;
583 }
584 
585 static int
do_c_opt()586 do_c_opt ()
587 {
588   strncpy(convkey_name_in_uumrc, optarg, PATHNAMELEN-1);
589   convkey_name_in_uumrc[PATHNAMELEN-1] = '\0';
590   if (*convkey_name_in_uumrc == '\0')
591     {
592       return -1;
593     }
594   defined_by_option |= OPT_CONVKEY;
595   return 0;
596 }
597 
598 static int
do_r_opt()599 do_r_opt ()
600 {
601   strncpy(rkfile_name_in_uumrc, optarg, PATHNAMELEN-1);
602   rkfile_name_in_uumrc[PATHNAMELEN-1] = '\0';
603   if (*rkfile_name_in_uumrc == '\0')
604     {
605       return -1;
606     }
607   defined_by_option |= OPT_RKFILE;
608   return 0;
609 }
610 
611 static int
do_l_opt()612 do_l_opt ()
613 {
614   conv_lines = atoi (optarg);
615   return 0;
616 }
617 
618 static int
do_D_opt()619 do_D_opt ()
620 {
621   strncpy(def_servername, optarg, PATHNAMELEN-1);
622   def_servername[PATHNAMELEN-1] = '\0';
623   strcpy(def_reverse_servername, def_servername);
624   if (*def_servername == '\0')
625     {
626       return -1;
627     }
628   return 0;
629 }
630 
631 static int
do_n_opt()632 do_n_opt ()
633 {
634   strncpy(username, optarg, PATHNAMELEN-1);
635   username[PATHNAMELEN-1] = '\0';
636   if (*username == '\0')
637     {
638       return -1;
639     }
640   return 0;
641 }
642 
643 static int
do_v_opt()644 do_v_opt ()
645 {
646   defined_by_option |= OPT_VERBOSE;
647   return 0;
648 }
649 
650 static int (*do_opt[]) () =
651 {
652   do_h_opt,                     /* 'h' : waking_up_in_henkan_mode */
653     do_H_opt,                   /* 'H' : waking_up_no_henkan_mode */
654     do_P_opt,                   /* 'P' : sleep 20 seconds (for debug) */
655     do_x_opt,                   /* 'x' : disable tty's flow control */
656     do_X_opt,                   /* 'X' : enable tty's flow control */
657     do_k_opt,                   /* 'k' : specify uumkey file */
658     do_c_opt,                   /* 'c' : specify convert_key file */
659     do_r_opt,                   /* 'r' : specify romkan mode file */
660     do_l_opt,                   /* 'l' : specify # of lines used for henkan */
661     do_D_opt,                   /* 'D' : specify hostname of jserver */
662     do_n_opt,                   /* 'n' : specify username for jserver */
663     do_v_opt,                   /* 'v' : verbose */
664 };
665 
666 static void
parse_options(argc,argv)667 parse_options (argc, argv)
668      int argc;
669      char **argv;
670 {
671   register int c;
672   register char *default_getoptstr = GETOPTSTR;
673   register char *default_ostr = OPTIONS;
674   char ostr[64];
675   register char *p;
676 
677   strcpy (ostr, default_getoptstr);
678   strcat (ostr, lang_db->getoptstr);
679   while ((c = getopt (argc, argv, ostr)) != EOF)
680     {
681       if (!(p = strchr (default_ostr, c)) || (*do_opt[p - default_ostr]) () < 0)
682         {
683           if (!(p = strchr (lang_db->ostr, c)) || (*lang_db->do_opt[p - lang_db->ostr]) () < 0)
684             {
685               strcpy (ostr, default_ostr);
686               strcat (ostr, lang_db->ostr);
687               usage (ostr);
688             }
689         }
690     }
691 }
692 
693 /** tty ���Ф��� ioctl �Υ��å� */
694 
695 #ifdef USE_SGTTY
696 #if defined(BSD43) || defined(DGUX) /* should be "defined(LPASS8)"? */
697 #  define SET_PASS8
698 #endif
699 struct sgttyb savetmio;
700 struct sgttyb ttyb_def =
701 { B9600, B9600, 0x7f, 0x15, EVENP | ODDP | ECHO | CRMOD };
702 int local_mode_def = LCRTBS | LCRTERA | LCRTKIL | LCTLECH | LPENDIN | LDECCTQ;
703 
704 /* added later */
705 struct tchars tcharsv;
706 struct ltchars ltcharsv;
707 struct sgttyb ttyb;
708 int local_mode;
709 #ifdef SET_PASS8
710 static int local_mode_sv;
711 #endif
712 
713 
714 static void
get_rubout()715 get_rubout ()
716 {
717 #ifdef nodef
718   if (savetmio.sg_erase == UNDEF_STTY)
719     {
720       rubout_code = RUBOUT;
721     }
722   else
723     {
724 #endif
725       rubout_code = savetmio.sg_erase;
726 #ifdef nodef
727     }
728 #endif
729 }
730 
731 int
j_term_init()732 j_term_init ()
733 {
734   struct sgttyb buf;
735 
736   buf = savetmio;
737   buf.sg_flags |= RAW;
738   buf.sg_flags &= ~ECHO;
739   ioctl (ttyfd, TIOCSETP, &buf);
740 #ifdef SET_PASS8
741   ioctl (ttyfd, TIOCLSET, &local_mode);
742 #endif
743 
744   return 0;
745 }
746 
747 static void
j_term_save()748 j_term_save ()
749 {
750   ioctl (ttyfd, TIOCGETC, &tcharsv);
751   ioctl (ttyfd, TIOCGLTC, &ltcharsv);
752   if (ioctl (ttyfd, TIOCGETP, &ttyb))
753     ttyb = ttyb_def;
754   savetmio = ttyb;
755 #ifdef SET_PASS8
756   if (ioctl (ttyfd, TIOCLGET, &local_mode_sv))
757     local_mode_sv = local_mode_def;
758   local_mode = local_mode_sv | LPASS8;  /* set PASS8 */
759 #else /* !SET_PASS8 */
760   if (ioctl (ttyfd, TIOCLGET, &local_mode))
761     local_mode = local_mode_def;
762 #endif /* !SET_PASS8 */
763 }
764 
765 static void
j_term_restore()766 j_term_restore ()
767 {
768   ioctl (ttyfd, TIOCSETP, &savetmio);
769 #ifdef SET_PASS8
770   ioctl (ttyfd, TIOCLSET, &local_mode_sv);
771 #endif /* SET_PASS8 */
772 }
773 
774 static void
j_term_p_init(ttypfd)775 j_term_p_init (ttypfd)
776   int ttypfd;
777 {
778   int word;
779   ioctl (ttypfd, TIOCSETC, &tcharsv);
780   ioctl (ttypfd, TIOCSLTC, &ltcharsv);
781   ioctl (ttypfd, TIOCSETP, &ttyb);
782   ioctl (ttypfd, TIOCLSET, &local_mode);
783   if (pty_c_flag == J_JIS)
784     {
785       word = LCTLECH;
786       ioctl (ttypfd, TIOCLBIC, &word);
787     }
788 }
789 #endif /* USE_SGTTY */
790 
791 #if defined(USE_TERMIO) || defined(USE_TERMIOS)
792 
793 #ifdef USE_TERMIOS
794 # define TERMIO termios
795 # define GET_TERMATTR(fd, tio) tcgetattr(fd, tio)
796 # define SET_TERMATTR(fd, tio) tcsetattr(fd, TCSADRAIN, tio)
797 # define UNDEF_STTY _POSIX_VDISABLE
798 # define SET_ATTR_ERROR "error in tcsetattr.\n"
799 #else
800 # define TERMIO termio
801 # define GET_TERMATTR(fd, tio) ioctl(fd, TCGETA, tio)
802 # ifdef TCSETAW
803 #  define SET_TERMATTR(fd, tio) ioctl(fd, TCSETAW, tio)
804 # else
805 #  define SET_TERMATTR(fd, tio) ioctl(fd, TCSETA, tio)
806 # endif
807 # define UNDEF_STTY 0xff
808 # define SET_ATTR_ERROR "error in ioctl TCSETA.\n"
809 #endif
810 #ifdef CERASE
811 # define WNN_CERASE CERASE
812 #elif defined(CDEL)
813 # define WNN_CERASE CDEL
814 #else
815 # define WNN_CERASE 0x7f
816 #endif
817 
818 struct TERMIO savetmio;
819 
820 static void
set_default_termio(terms)821 set_default_termio (terms)
822   struct TERMIO *terms;
823 {
824   bzero (terms, sizeof *terms);
825   terms->c_iflag = IGNBRK | ICRNL | IXON;
826   terms->c_oflag = OPOST;
827 #ifdef ONLCR
828   terms->c_oflag |= ONLCR;
829 #endif
830   terms->c_cflag = CS8 | CSTOPB | CREAD | CLOCAL;
831 #ifndef USE_TERMIOS
832   terms->c_cflag |= B9600;
833 #endif
834   terms->c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK;
835 #ifdef USE_TERMIOS
836   terms->c_cc[VINTR] = 0x3;
837   terms->c_cc[VQUIT] = 0x1c;
838   terms->c_cc[VERASE] = 0x8;
839   terms->c_cc[VKILL] = 0x15;
840   terms->c_cc[VEOF] = 0x4;
841   terms->c_cc[VEOL] = _POSIX_VDISABLE;
842 #ifdef VEOL2
843   terms->c_cc[VEOL2] = _POSIX_VDISABLE;
844 #endif
845   cfsetospeed (terms, B9600);
846   cfsetispeed (terms, B9600);
847 #else
848   terms->c_line = 0;
849   terms->c_cc[0] = 0x3;
850   terms->c_cc[1] = 0x1c;
851   terms->c_cc[2] = 0x8;
852   terms->c_cc[3] = 0x15;
853   terms->c_cc[4] = 0x4;
854   terms->c_cc[5] = 0;
855   terms->c_cc[6] = 0;
856   terms->c_cc[7] = 0;
857 #endif
858 }
859 
860 #if defined(uniosu)
861 struct jtermio savejtmio;
862 struct auxtermio auxterm = {
863   0,                            /* -tostop */
864   {0x1a, 0, 0, 0, 0, 0, 0, 0}   /* c_cc2 */
865 };
866 #endif /* defined(uniosu) */
867 
868 static void
get_rubout()869 get_rubout ()
870 {
871   if (savetmio.c_cc[VERASE] == UNDEF_STTY)
872     {
873       rubout_code = RUBOUT;
874     }
875   else
876     {
877       rubout_code = savetmio.c_cc[VERASE];
878     }
879 }
880 
881 int
j_term_init()882 j_term_init ()
883 {
884   struct TERMIO buf1;
885 #if defined(uniosu)
886   struct jtermio buf2;
887 #endif /* defined(uniosu) */
888 
889   buf1 = savetmio;
890 #ifdef USE_LINUX_TERM
891   buf1.c_lflag &= ~(ECHONL | ECHOK | ECHOE | ECHO | XCASE | ICANON | ISIG);
892   buf1.c_iflag = 0;
893   buf1.c_oflag &= ~OPOST;
894   buf1.c_cflag |= CS8;
895   buf1.c_cc[VMIN] = 1;          /* cf. ICANON */
896   buf1.c_cc[VTIME] = 0;
897 #else /* !USE_LINUX_TERM */
898   buf1.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON);
899 #ifdef IUCLC
900   buf1.c_iflag &= IUCLC;
901 #endif
902   if (flow_control)
903     {
904       buf1.c_iflag |= IXON;
905     }
906   buf1.c_lflag &= ~(ECHONL | ECHOK | ECHOE | ECHO | ICANON | ISIG);
907 #ifdef XCASE
908   buf1.c_lflag &= XCASE;
909 #endif
910   buf1.c_oflag = OPOST;
911 #ifdef USE_TERMIOS
912   buf1.c_cc[VMIN] = 1;          /* cf. ICANON */
913   buf1.c_cc[VTIME] = 0;
914   cfsetispeed(&buf1, cfgetispeed(&savetmio));
915   cfsetospeed(&buf1, cfgetospeed(&savetmio));
916 #else /* !USE_TERMIOS */
917   buf1.c_cc[VEOF] = 1;          /* cf. ICANON */
918   buf1.c_cc[VEOL] = 0;
919   /* not needed? cf.ISIG*/
920   buf1.c_cc[VINTR] = WNN_CERASE;
921   buf1.c_cc[VQUIT] = WNN_CERASE;
922   buf1.c_cc[VERASE] = WNN_CERASE;
923   buf1.c_cc[VKILL] = WNN_CERASE;
924 #endif /* !USE_TERMIOS */
925 #endif /* !USE_LINUX_TERM */
926   if (SET_TERMATTR (ttyfd, &buf1) < 0)
927     {
928       fprintf (stderr, SET_ATTR_ERROR);
929       exit (1);
930     }
931 
932 #if defined(uniosu)
933   buf2 = savejtmio;
934   buf2.j_flg = CONVTOEXT | WNN_EXIST;
935   buf2.j_level = jterm;
936   switch (jcode_set)
937     {
938     case 0:
939       buf2.j_ecode = JIS;
940       break;
941     case 1:
942       buf2.j_ecode = SJIS;
943       break;
944     case 2:
945       buf2.j_ecode = UJIS;
946       break;
947     default:
948       fprintf (stderr, "uum: kanji code set not supported in terminfo\n");
949       exit (1);
950     }
951   if (jis_kanji_in)
952     {
953       strcpy (buf2.j_jst, jis_kanji_in);
954       buf2.j_jstl = strlen (jis_kanji_in);
955     }
956   if (jis_kanji_out)
957     {
958       strcpy (buf2.j_jend, jis_kanji_out);
959       buf2.j_jendl = strlen (jis_kanji_out);
960     }
961   if (jgaiji_start_address)
962     {
963       *(short *) buf2.j_gcsa = jgaiji_start_address;
964     }
965   if (jgaiji_disp)
966     {
967       strcpy (buf2.j_gdsp, jgaiji_disp);
968       buf2.j_gdspl = strlen (jgaiji_disp);
969     }
970 
971   if (ioctl (ttyfd, JTERMSET, &buf2) < 0)
972     {
973       fprintf (stderr, "error in ioctl JTERMSET.\n");
974       exit (1);
975     }
976 #endif /* defined(uniosu) */
977 
978   return 0;
979 }
980 
981 static void
j_term_save()982 j_term_save ()
983 {
984   if (GET_TERMATTR (ttyfd, &savetmio) < 0)
985     {
986       set_default_termio (&savetmio);
987     }
988 #if defined(uniosu)
989   if (ioctl (ttyfd, JTERMGET, &savejtmio) < 0)
990     {
991       fprintf (stderr, "uum: error in ioctl JTERMGET in open_ttyp.\n");
992       exit (1);
993     }
994 #endif /* defined(uniosu) */
995 }
996 
997 static void
j_term_restore()998 j_term_restore ()
999 {
1000   if (SET_TERMATTR (ttyfd, &savetmio) < 0)
1001     {
1002       fprintf (stderr, SET_ATTR_ERROR);
1003       exit (1);
1004     }
1005 
1006 #if defined(uniosu)
1007   if (ioctl (ttyfd, JTERMSET, &savejtmio) < 0)
1008     {
1009       fprintf (stderr, "error in ioctl JTERMSET.\n");
1010       exit (1);
1011     }
1012 #endif /* defined(uniosu) */
1013 }
1014 
1015 static void
j_term_p_init(ttypfd)1016 j_term_p_init (ttypfd)
1017   int ttypfd;
1018 {
1019   struct TERMIO buf1;
1020 #if defined(uniosu)
1021   struct TERMIO buf2;
1022 #endif
1023   buf1 = savetmio;
1024 #ifdef DGUX                     /* copied from JLS5.4.2 */
1025   /* should clear on all platforms? */
1026   buf1.c_iflag &= ~ISTRIP;
1027 #endif /* DGUX */
1028 #ifdef nec_ews_svr2
1029   buf1.c_line = JAPANLD;
1030 #endif
1031 #ifdef USE_TERMIOS
1032   cfsetispeed(&buf1, cfgetispeed(&savetmio));
1033   cfsetospeed(&buf1, cfgetospeed(&savetmio));
1034 #endif
1035   if (SET_TERMATTR (ttypfd, &buf1) < 0)
1036     {
1037       fprintf (stderr, SET_ATTR_ERROR);
1038       exit (1);
1039     }
1040 #if defined(uniosu)
1041   buf2 = savejtmio;
1042   buf2.j_flg = CONVTOEXT | KANJIINPUT;  /* kanji input & output ok */
1043   buf2.j_level = jterm;
1044   switch (jcode_set)
1045     {
1046     case 0:
1047       buf2.j_ecode = JIS;
1048       break;
1049     case 1:
1050       buf2.j_ecode = SJIS;
1051       break;
1052     case 2:
1053       buf2.j_ecode = UJIS;
1054       break;
1055     default:
1056       fprintf (stderr, "uum: kanji code set not supported in terminfo.\n");
1057       exit (1);
1058     }
1059 
1060   if (jis_kanji_in)
1061     {
1062       strcpy (buf2.j_jst, jis_kanji_in);
1063       buf2.j_jstl = strlen (jis_kanji_in);
1064     }
1065   if (jis_kanji_out)
1066     {
1067       strcpy (buf2.j_jend, jis_kanji_out);
1068       buf2.j_jendl = strlen (jis_kanji_out);
1069     }
1070   if (jgaiji_start_address)
1071     {
1072       *(short *) buf2.j_gcsa = jgaiji_start_address;
1073     }
1074   if (jgaiji_disp)
1075     {
1076       strcpy (buf2.j_gdsp, jgaiji_disp);
1077       buf2.j_gdspl = strlen (jgaiji_disp);
1078     }
1079 
1080   if (ioctl (ttypfd, JTERMSET, &buf2) < 0)
1081     {
1082       fprintf (stderr, "error in ioctl JTERMSET.\n");
1083       exit (1);
1084     }
1085 
1086   if (ioctl (ttypfd, TIOCSETAUX, &auxterm) < 0)
1087     {
1088       fprintf (stderr, "error in ioctl TIOCSETAUX.\n");
1089       exit (1);
1090     }
1091 
1092 #endif /* defined(uniosu) */
1093 }
1094 #endif /* USE_TERMIO || USE_TERMIOS */
1095 
1096 /** signal SIGCHLD ���������ν������롣*/
1097 /* *INDENT-OFF* */
1098 RETSIGTYPE
chld_handler()1099 chld_handler ()
1100 /* *INDENT-ON* */
1101 {
1102 #ifdef HAVE_WAIT3
1103 #if !defined(_POSIX_VERSION) && defined(HAVE_UNION_WAIT) /* older way */
1104   union wait status;
1105 #else /* POSIX */
1106   int status;
1107 #endif
1108   int pid;
1109 
1110   if ((pid = wait3(&status, WNOHANG | WUNTRACED, NULL)) == child_id)
1111     {
1112       if (WIFSTOPPED (status))
1113         {
1114 #ifdef SIGCONT
1115           kill (pid, SIGCONT);
1116 #ifdef GETPGID
1117 	  KILLPG (GETPGID (pid), SIGCONT);
1118 #endif
1119 #endif
1120         }
1121       else
1122         {
1123           signal (SIGCHLD, SIG_IGN);
1124           printf (MSG_GET (3));
1125           /*
1126              printf("\r\n����������ޤ���\r\n");
1127            */
1128 #ifdef USE_LIBSPT
1129 	  if (spth)
1130 	    spt_utmp_set_exit (spth, *(int *)&status);
1131 #endif
1132           epilogue ();
1133           do_end ();
1134         }
1135     }
1136 #else /* ! HAVE_WAIT3 */
1137   if (wait (0) == child_id)
1138     {
1139       signal (SIGCHLD, SIG_IGN);
1140       printf (MSG_GET (3));
1141       /*
1142          printf("\r\n����������ޤ���\r\n");
1143        */
1144       epilogue ();
1145       do_end ();
1146     }
1147 #endif /* HAVE_WAIT3 */
1148 
1149   re_signal (SIGCHLD, chld_handler);
1150 
1151   /* not reached */
1152 #ifndef RETSIGTYPE_VOID
1153   return 0;
1154 #endif
1155 }
1156 
1157 /** signal SIGTERM ����������ν������롣*/
1158 static RETSIGTYPE
terminate_handler()1159 terminate_handler ()
1160 {
1161   signal (SIGCHLD, SIG_IGN);
1162   epilogue_no_close ();
1163   do_end ();
1164 
1165   /* not reached */
1166 #ifndef RETSIGTYPE_VOID
1167   return 0;
1168 #endif
1169 }
1170 
1171 #ifdef  SIGWINCH
1172 /* *INDENT-OFF* */
1173 RETSIGTYPE
resize_handler()1174 resize_handler ()
1175 /* *INDENT-ON* */
1176 {
1177   re_signal (SIGWINCH, resize_handler);
1178   change_size ();
1179 
1180   /* not reached */
1181 #ifndef RETSIGTYPE_VOID
1182   return 0;
1183 #endif
1184 }
1185 #endif /* SIGWINCH */
1186 
1187 /** �ᥤ��롼�� */
1188 
1189 wnn_fd_set sel_ptn;
1190 int ptyfd = -1;
1191 
1192 static void
do_main()1193 do_main ()
1194 {
1195 #ifndef CANNA
1196   unsigned char *buf;
1197   int ml;
1198 
1199   if ((buf = (unsigned char *) malloc (maxchg * 4)) == NULL)
1200     {
1201       printf (MSG_GET (2));
1202       printf (MSG_GET (3));
1203       /*
1204          printf("malloc �˼��Ԥ��ޤ���������������ޤ���\r\n");
1205        */
1206       epilogue ();
1207       do_end ();
1208     }
1209 #else /* CANNA */
1210   extern void canna_mainloop();
1211 #endif /* CANNA */
1212 
1213   WNN_FD_SET(ptyfd, &sel_ptn);
1214   WNN_FD_SET(ttyfd, &sel_ptn);
1215 
1216   if (henkan_off_flag == 0)
1217     {
1218       disp_mode ();
1219     }
1220 
1221 #ifndef CANNA
1222   for (;;)
1223     {
1224 
1225       ml = kk ();
1226 
1227       make_history (return_buf, ml);
1228       ml = (*code_trans[(internal_code << 2) | pty_c_flag]) (buf, return_buf, sizeof (w_char) * ml);
1229       if (ml > 0)
1230         write (ptyfd, buf, ml);
1231     }
1232 #else /* CANNA */
1233   canna_mainloop();
1234 #endif /* CANNA */
1235 }
1236 
1237 unsigned char keyin0 ();
1238 
1239 int
keyin2()1240 keyin2 ()
1241 {
1242   int total, ret;
1243   unsigned char in;
1244 
1245   in = keyin0 ();
1246   if (in == 0xff)
1247     return (-1);
1248   total = (int) (in & 0xff);
1249   if (henkan_off_flag == 0 || pty_c_flag != tty_c_flag)
1250     {
1251       ret = get_cswidth_by_char (in);
1252       for (; ret > 1; ret--)
1253         {
1254           total = ((total & 0xff) << 8) + (int) (keyin0 () & 0xff);
1255         }
1256     }
1257   return (total);
1258 }
1259 
1260 /** convert_key nomi okonau key-in function */
1261 int
conv_keyin(inkey)1262 conv_keyin (inkey)
1263      char *inkey;
1264 {
1265   return keyin1 (keyin2, inkey);
1266 }
1267 
1268 /** �������ϴؿ� 1 */
1269 int
keyin()1270 keyin ()
1271 {
1272   char inkey[16];
1273   return (conv_keyin (inkey));
1274 }
1275 
1276 /*
1277   through ��ɤ�
1278   char ��������γ�ʸ���� w_char �ˤ��� w_char ������˰ܤ���
1279   uum ���ꥸ�ʥ�� through �Ȥϰ�ä� void �ʤΤ���ա�
1280  */
1281 
1282 static void
throughlike(dest,src,n)1283 throughlike(dest, src, n)
1284 w_char *dest;
1285 unsigned char *src;
1286 int n;
1287 {
1288   while (n-- > 0) {
1289     *dest++ = (w_char)*src++;
1290   }
1291 }
1292 
1293 /** �������ϴؿ� 2 */
1294 unsigned char
keyin0()1295 keyin0 ()
1296 {
1297   static unsigned char buf[BUFSIZ];
1298   static unsigned char outbuf[BUFSIZ];
1299   static unsigned char *bufend = outbuf;
1300   static unsigned char *bufstart = outbuf;
1301   int n;
1302   wnn_fd_set rfds, mask;
1303   int i, j;
1304   unsigned char *p;
1305   extern int henkan_off_flag;
1306   struct timeval time_out;      /* If your OS's select was implemented as
1307                                    a pointer for int, you must modify the
1308                                    time_out variable to integer           */
1309   int sel_ret;
1310 
1311   if (bufstart < bufend)
1312     {
1313       return (*bufstart++);
1314     }
1315   for (;;)
1316     {
1317       if ((n = read (ttyfd, buf, BUFSIZ)) > 0)
1318         {
1319           if (henkan_off_flag == 1)
1320             {
1321               if (tty_c_flag == pty_c_flag)
1322                 {
1323                   i = through (outbuf, buf, n);
1324                 }
1325               else
1326                 {
1327                   i = (*code_trans[(tty_c_flag << 2) | file_code]) (outbuf, buf, n);
1328                 }
1329             }
1330           else
1331             {
1332               i = (*code_trans[(tty_c_flag << 2) | file_code]) (outbuf, buf, n);
1333             }
1334           if (i <= 0)
1335             continue;
1336           bufstart = outbuf;
1337           bufend = outbuf + i;
1338           return (*bufstart++);
1339         }
1340 
1341       time_out.tv_sec = 0;
1342       time_out.tv_usec = 200 * 1000;    /* 200 msec ���ԤĤΤ���! */
1343       for (rfds = sel_ptn;
1344 #ifdef USE_LINUX_TERM
1345            (sel_ret = select (20, &rfds, 0, 0, NULL)) < 0 && errno == EINTR;
1346 #else
1347            (sel_ret = select (20, &rfds, 0, 0, &time_out)) < 0 && errno == EINTR;
1348 #endif
1349            rfds = sel_ptn)
1350         ;
1351       if (sel_ret == 0)
1352         {
1353           if ((tty_c_flag == J_JIS) && ((i = flush_designate ((w_char *) outbuf)) > 0))
1354             {
1355               /* ί�ޤäƤ���ţӣä��Ǥ��Ф� */
1356               bufstart = outbuf;
1357               bufend = outbuf + i;
1358               return (*bufstart++);
1359             }
1360           return (0xff);
1361         }
1362 
1363       if (WNN_FD_ISSET(ptyfd, &rfds))
1364         {
1365           if ((n = read (ptyfd, buf, BUFSIZ)) <= 0)
1366             {
1367               epilogue ();
1368               do_end ();
1369             }
1370 #if defined(uniosu)
1371           if (*buf == PIOCPKT_IOCTL)
1372             {
1373               arrange_ioctl (1);
1374             }
1375           else if (*buf == 0)
1376 #endif /* defined(uniosu) */
1377             {                   /* sequence of data */
1378 #if defined(uniosu)
1379               i = (*code_trans[(pty_c_flag << 2) | tty_c_flag]) (outbuf, buf + 1, n - 1);
1380 #else /* defined(uniosu) */
1381               i = (*code_trans[(pty_c_flag << 2) | tty_c_flag]) (outbuf, buf, n);
1382 #endif /* defined(uniosu) */
1383               if (i <= 0)
1384                 continue;
1385               p = outbuf;
1386               push_cursor ();
1387               kk_restore_cursor ();
1388               while ((j = write (ttyfd, p, i)) < i)
1389                 {
1390                   if (j >= 0)
1391                     {
1392                       p += j;
1393                       i -= j;
1394                     }
1395 		  WNN_FD_SET(ttyfd, &mask);
1396                   select (32, 0, &mask, 0, 0);
1397                 }
1398               pop_cursor ();
1399             }
1400         }
1401       if (WNN_FD_ISSET(ttyfd, &rfds))
1402         {
1403           if ((n = read (ttyfd, buf, BUFSIZ)) > 0)
1404             {
1405               if (henkan_off_flag == 1)
1406                 {
1407                   if (tty_c_flag == pty_c_flag)
1408                     {
1409                       i = through (outbuf, buf, n);
1410                     }
1411                   else
1412                     {
1413                       i = (*code_trans[(tty_c_flag << 2) | file_code]) (outbuf, buf, n);
1414                     }
1415                 }
1416               else
1417                 {
1418                   i = (*code_trans[(tty_c_flag << 2) | file_code]) (outbuf, buf, n);
1419                 }
1420               if (i <= 0)
1421                 continue;
1422               bufstart = outbuf;
1423               bufend = outbuf + i;
1424               return (*bufstart++);
1425 #ifdef nodef
1426             }
1427           else
1428             {                   /* Consider it as EOF */
1429               epilogue ();
1430               do_end ();
1431 #endif /* It seems that select does not return EOF when  Non-brock
1432           What should I do? */
1433             }
1434         }
1435     }
1436 }
1437 
1438 
1439 #if defined(uniosu)
1440 /** pty ���� ioctl �������ä����ν��� */
1441 int
arrange_ioctl(jflg)1442 arrange_ioctl (jflg)
1443      int jflg;                  /* jtermio �� j_flg ���Ѵ��ե饰�����դλ� 0 ����λ� 1 */
1444 {
1445   struct jtermio jbuf1;
1446   struct TERMIO frombuf;
1447   struct TERMIO tobuf;
1448   int i;
1449 
1450   GET_TERMATTR (ptyfd, &frombuf);
1451   GET_TERMATTR (ttyfd, &frombuf);
1452 
1453   if ((i = (frombuf.c_iflag & IXON)) != (tobuf.c_iflag & IXON))
1454     {
1455       if (i == 0)
1456         {
1457           tobuf.c_iflag &= ~IXON;
1458         }
1459       else
1460         {
1461           tobuf.c_iflag |= IXON;
1462         }
1463     }
1464   if ((i = (frombuf.c_iflag & IXOFF)) != (tobuf.c_iflag & IXOFF))
1465     {
1466       if (i == 0)
1467         {
1468           tobuf.c_iflag &= ~IXOFF;
1469         }
1470       else
1471         {
1472           tobuf.c_iflag |= IXOFF;
1473         }
1474     }
1475   if ((i = (frombuf.c_oflag & OPOST)) != (tobuf.c_oflag & OPOST))
1476     {
1477       if (i == 0)
1478         {
1479           tobuf.c_oflag &= ~OPOST;
1480         }
1481       else
1482         {
1483           tobuf.c_oflag |= OPOST;
1484         }
1485     }
1486   tobuf.c_cflag = (tobuf.c_cflag & ~CBAUD) | (frombuf.c_cflag & CBAUD);
1487 
1488   SET_TERMATTR (ttyfd, &tobuf);		/* set again */
1489 
1490   ioctl (ptyfd, JTERMGET, &jbuf1);      /* about Japanease */
1491 
1492   if ((jflg) && ((jbuf1.j_flg & KANJIINPUT) == 0))
1493     {
1494       jbuf1.j_flg &= ~(KANJIINPUT | CONVTOINT); /* kanji henkan flg off */
1495       ioctl (ttyfd, JTERMSET, &jbuf1);
1496       kk_restore_cursor ();
1497       reset_cursor ();
1498       longjmp (kk_env, 1);
1499     }
1500   if ((!jflg) && ((jbuf1.j_flg & KANJIINPUT) != 0))
1501     {
1502       jbuf1.j_flg &= ~(KANJIINPUT | CONVTOINT); /* kanji henkan flg off */
1503       ioctl (ttyfd, JTERMSET, &jbuf1);
1504       return (1);
1505     }
1506   jbuf1.j_flg &= ~(KANJIINPUT | CONVTOINT);     /* kanji henkan flg off */
1507   ioctl (ttyfd, JTERMSET, &jbuf1);
1508   return (0);
1509 }
1510 #endif /* defined(uniosu) */
1511 
1512 /** �ҥץ�����������*/
1513 
1514 int ttypfd = -1;
1515 
1516 static void
exec_cmd(argv)1517 exec_cmd (argv)
1518      char **argv;
1519 {
1520   int i;
1521 #if defined(USE_LIBSPT) && !defined(USE_LINUX_TERM)
1522   int r;
1523   const char *ttynm;
1524 #elif !defined(HAVE_SETSID) || defined(USE_LINUX_TERM)
1525 #ifdef BSD42
1526   int pid;
1527 #endif
1528 #ifdef USE_LINUX_TERM
1529   struct winsize win;
1530   extern Term_RowWidth, crow;
1531 #endif
1532 #endif /* (!USE_LIBSPT && !HAVE_SETSID) || USE_LINUX_TERM */
1533 
1534   child_id = fork ();
1535   if (child_id < 0)
1536     err ("cannot fork.");
1537   if (!child_id)
1538     {
1539       /* --- start changing controlling tty --- */
1540 #if defined(USE_LIBSPT) && !defined(USE_LINUX_TERM)
1541 #if defined(SIGWINCH) && defined(TIOCSWINSZ)
1542       struct winsize win;
1543       if (ioctl (ttyfd, TIOCGWINSZ, &win) == 0)
1544 	ioctl (ttypfd, TIOCSWINSZ, &win);
1545 #endif /* SIGWINCH && TIOCSWINSZ */
1546       spt_detach_handle (spth);
1547       spth = NULL;
1548       if (spt_detach_ctty () || spt_set_ctty2 (ttypfd))
1549 	{
1550 	  err ("cannot change controlling tty.");
1551 	}
1552 
1553 #elif defined(HAVE_SETSID) && !defined(USE_LINUX_TERM) /* !USE_LIBSPT */
1554 
1555       int fd;
1556 #if defined(SIGWINCH) && defined(TIOCSWINSZ)
1557       struct winsize win;
1558       if (ioctl (ttyfd, TIOCGWINSZ, &win) == 0)
1559 	ioctl (ttypfd, TIOCSWINSZ, &win);
1560 #endif /* SIGWINCH && TIOCSWINSZ */
1561       setsid ();
1562 #ifdef TIOCSCTTY
1563       ioctl (ttypfd, TIOCSCTTY, 0);
1564 #else
1565       close (open (ttyname (ttypfd), O_WRONLY, 0));
1566 #endif
1567       if ((fd = open("/dev/tty", O_WRONLY)) < 0)
1568 	{
1569           err ("cannot change controlling tty.");
1570 	}
1571       close (fd);
1572       /* disable utmp logging for now */
1573 
1574 #else /* (!USE_LIBSPT && !HAVE_SETSID) || USE_LINUX_TERM */
1575 
1576 #if defined(SYSVR2) && !defined(USE_LINUX_TERM)
1577       setpgrp ();
1578       close (open (ttyname (ttypfd), O_WRONLY, 0));
1579 #endif /* SYSVR2 */
1580 
1581 #ifdef BSD42
1582 #ifdef TIOCNOTTY
1583       /* set notty */
1584       {
1585         int fd;
1586         if ((fd = open ("/dev/tty", O_WRONLY)) >= 0)
1587           {
1588             (void) ioctl (fd, TIOCNOTTY, 0);
1589             close (fd);
1590           }
1591       }
1592 #endif /* TIOCNOTTY */
1593 #ifdef TIOCSCTTY
1594       setsid ();
1595       ioctl (ttypfd, TIOCSCTTY, 0);
1596 #endif /* TIOCSCTTY */
1597       /* set tty process group */
1598       pid = getpid ();
1599       ioctl (ttypfd, TIOCSPGRP, &pid);
1600       setpgrp (0, 0);
1601       close (open (ttyname (ttypfd), O_WRONLY, 0));
1602       setpgrp (0, pid);
1603 #endif /* BSD42 */
1604 
1605 #ifdef USE_LINUX_TERM
1606       setsid ();
1607       open_ttyp ();
1608       close (ptyfd);
1609       ioctl (ttyfd, TIOCGWINSZ, &win);
1610       ioctl (ttypfd, TCSETA, &savetmio);
1611 #endif
1612 #endif /* (!USE_LIBSPT && !HAVE_SETSID) || USE_LINUX_TERM */
1613       /* --- finish changing controlling tty --- */
1614 
1615 #ifndef USE_LINUX_TERM
1616       setgid (getgid ());
1617       setuid (getuid ());
1618 #endif
1619 #ifdef HAVE_DUP2
1620       dup2 (ttypfd, 0);
1621       dup2 (ttypfd, 1);
1622       dup2 (ttypfd, 2);
1623 #else /* !HAVE_DUP2 */
1624       close (0);
1625       close (1);
1626       close (2);
1627       if (dup (ttypfd) != 0 || dup (ttypfd) != 1 || dup (ttypfd) != 2)
1628         {
1629           err ("redirection fault.");
1630         }
1631 #endif /* !HAVE_DUP2 */
1632       for (i = WNN_NFD - 1; i > 2; i--)
1633         {
1634           close (i);
1635         }
1636 
1637       restore_signals ();
1638 
1639 #ifdef SIGTSTP
1640       signal (SIGTSTP, SIG_IGN);
1641 #endif
1642 #ifdef SIGTTIN
1643       signal (SIGTTIN, SIG_IGN);
1644 #endif
1645 #ifdef SIGTTOU
1646       signal (SIGTTOU, SIG_IGN);
1647 #endif
1648 
1649 #ifdef USE_LINUX_TERM
1650       crow = win.ws_row = Term_RowWidth = win.ws_row - conv_lines;
1651       ioctl (ttyfd, TIOCSWINSZ, &win);
1652       setgid (getgid ());
1653       setuid (getuid ());
1654 #endif
1655       execvp (cmdnm, argv);
1656       err ("exec fault.");
1657     }
1658   /* parent */
1659 #ifdef USE_LIBSPT
1660   ttynm = ttyname (0);
1661   if (ttynm)
1662     {
1663       ttynm = strchr (ttynm + 1, '/');
1664       if (ttynm && ttynm[1])
1665 	{
1666 	  spt_utmp_set_host (spth, ttynm + 1);
1667 	}
1668     }
1669   spt_utmp_set_pid (spth, child_id);
1670   r = spt_login_utmp (spth);
1671   if (!r)
1672     {
1673       need_utmp_clear = 1;
1674     }
1675   else
1676     {
1677       spt_perror ("exec_cmd (login_utmp)", r);
1678     }
1679 #endif
1680 }
1681 
1682 #if !(HAVE_SETENV)
1683 /** �Ķ��ѿ��Υ��å� */
1684 /*
1685  * This function causes memory leak, but I leave it as it is. Anyway,
1686  * this function is called only a few times at the startup of uum.
1687  * The 3rd parameter is ignored. It is added for compatibility only.
1688  */
1689 int
setenv(var,value,overwrite)1690 setenv (var, value, overwrite)
1691      char *var;
1692      char *value;
1693      int  overwrite;
1694 {
1695   extern char **environ;
1696   char **newenv;
1697   int i, j;
1698 
1699   j = strlen (var);
1700   for (i = 0; environ[i] != NULL; i++)
1701     {
1702       if (strncmp (var, environ[i], j) == 0 && environ[i][j] == '=')
1703         {
1704           break;
1705         }
1706     }
1707   if (environ[i] == NULL)
1708     {
1709       if ((newenv = (char **) malloc ((sizeof (char *)) * (i + 2))) == NULL)
1710         {
1711 	  return (-1);
1712         }
1713       for (j = 0; j < i + 1; j++)
1714         {
1715           newenv[j] = environ[j];
1716         }
1717       newenv[i + 1] = NULL;
1718       environ = newenv;
1719     }
1720   if ((environ[i] = malloc (strlen (var) + strlen (value) + 2)) == NULL)
1721     {
1722       return (-1);
1723     }
1724   strcpy (environ[i], var);
1725   strcat (environ[i], "=");
1726   strcat (environ[i], value);
1727   return (0);
1728 }
1729 #endif /* !HAVE_SETENV */
1730 
1731 #ifdef SVR4
1732 static int
euc_set(eucioc,ttyfd)1733 euc_set (eucioc, ttyfd)
1734      eucioc_t *eucioc;
1735      int ttyfd;
1736 {
1737   struct strioctl sb;
1738 
1739   sb.ic_cmd = EUC_WSET;
1740   sb.ic_timout = 0;
1741   sb.ic_len = sizeof (struct eucioc);
1742   sb.ic_dp = (char *) eucioc;
1743   if (ioctl (ttyfd, I_STR, &sb) < 0)
1744     {
1745       return (1);
1746     }
1747   return (0);
1748 }
1749 
1750 static void
set_euc_term(ttyfd)1751 set_euc_term (ttyfd)
1752      int ttyfd;
1753 {
1754   eucioc_t eucioc;
1755 
1756   /* for Japanese EUC */
1757   eucioc.eucw[0] = 1;
1758   eucioc.eucw[1] = 2;
1759   eucioc.eucw[2] = 2;
1760   eucioc.eucw[3] = 3;
1761   eucioc.scrw[0] = 1;
1762   eucioc.scrw[1] = 2;
1763   eucioc.scrw[2] = 1;
1764   eucioc.scrw[3] = 2;
1765   if (euc_set (&eucioc, ttyfd) != 0)
1766     {
1767       fprintf (stderr, "eucwidth set failed\n");
1768       return;
1769     }
1770   return;
1771 }
1772 
1773 #endif /* SVR4 */
1774 
1775 #ifdef nec_ews_svr2
1776 static void
set_jterm(ttyfd,ttypfd)1777 set_jterm (ttyfd, ttypfd)
1778      int ttyfd, ttypfd;
1779 {
1780   struct jtermio buf;
1781 
1782   if (ioctl (ttyfd, TCJGETA, &buf) == -1)
1783     {
1784       fprintf (stderr, "error in ioctl TCJGETA.\n");
1785       exit (1);
1786     }
1787   buf.c_iflag = 0;
1788   buf.c_oflag = 0;
1789   if (ioctl (ttypfd, TCJSETA, &buf) < 0)
1790     {
1791       fprintf (stderr, "error in ioctl TCJSETA.\n");
1792       exit (1);
1793     }
1794 }
1795 #endif /* nec_ews_svr2 */
1796 
1797 #ifdef sony
1798 static void
set_sony_jterm(ttyfd,ttypfd)1799 set_sony_jterm(ttyfd, ttypfd)
1800 int ttyfd, ttypfd;
1801 {
1802 #ifdef TIOCKGET
1803   int tmode, jmode = 0;
1804   struct jtchars jtc;
1805 
1806   if (ioctl(ttyfd, TIOCKGET, &tmode) < 0) {
1807     fprintf(stderr, "error in ioctl TIOCKGET.\n");
1808     exit(1);
1809   }
1810   jmode = tmode;
1811   tmode &= ~(KM_SYSCODE | KM_TTYPE);
1812   switch (pty_c_flag) {
1813   case J_EUJIS:
1814     tmode |= KM_EUC | KM_SYSEUC;
1815     break;
1816   case J_JIS:
1817     tmode |= KM_ASCII;
1818     break;
1819   case J_SJIS:
1820     tmode |= KM_SJIS | KM_SYSSJIS;
1821     break;
1822   }
1823   if (ioctl(ttypfd, TIOCKSET, &tmode) < 0) {
1824     fprintf(stderr, "error in ioctl TIOCKSET.\n");
1825     exit(1);
1826   }
1827 #endif /* TIOCKGET */
1828 
1829 #ifdef TIOCKGETC
1830   if ((jmode & KM_TTYPE) == KM_JIS) {
1831     ioctl(ttyfd, TIOCKGETC, &jtc);
1832     jtc.t_ascii = 'B';
1833     jtc.t_kanji = 'B';
1834     if (ioctl(ttypfd, TIOCKSETC, &jtc) < 0) {
1835       fprintf(stderr, "error in ioctl TIOCKSETC.\n");
1836       exit(1);
1837     }
1838   }
1839 #endif
1840 }
1841 #endif /* sony */
1842 
1843 /** ttyp �Υ����ץ� */
1844 
1845 #ifndef USE_LIBSPT
1846 #define MAXPTYNO (0x10 * (('z' - 'p' + 1) + ('Z' - 'P' + 1)))
1847 int ptyno;
1848 char *ptynm = "/dev/pty";
1849 #ifdef sgi
1850 extern char *_getpty (int *, int, mode_t, int);
1851 char *ttypnm = "/dev/ttyqxxx";
1852 #else
1853 char *ttypnm = "/dev/tty";
1854 #endif /* sgi */
1855 
1856 #ifndef sgi
1857 static void ptyname ();
1858 #endif
1859 #endif /* !USE_LIBSPT */
1860 
1861 static void
open_ttyp()1862 open_ttyp ()
1863 {
1864   char nmbuf[20];
1865 
1866 #ifdef USE_LIBSPT
1867   if ((ttypfd = spt_open_slave(spth)) == ERROR)
1868     {
1869 #elif defined(sgi)
1870   if ((ttypfd = open (ttypnm, O_RDWR)) == ERROR)
1871     {
1872 #else
1873   ptyname (nmbuf, ttypnm, ptyno);
1874   if ((ttypfd = open (nmbuf, O_RDWR, 0)) == ERROR)
1875     {
1876 #endif
1877       err ("Can't open ttyp.");
1878     }
1879 #if !defined(USE_LINUX_TERM) && !defined(USE_LIBSPT)
1880   chown (nmbuf, getuid (), getgid ());
1881   chmod (nmbuf, 0622);
1882 #endif /* !USE_LINUX_TERM && !USE_LIBSPT */
1883 #if defined(USE_LIBSPT)
1884   spt_init_slavefd(spth, ttypfd);
1885 #elif defined(I_PUSH) && defined(SVR4)
1886   ioctl(ttypfd, I_PUSH, "ptem");
1887   ioctl(ttypfd, I_PUSH, "ldterm");
1888   ioctl(ttypfd, I_PUSH, "ttcompat");
1889 #endif
1890 
1891   /*
1892    * We save terminal settings in main() instead of here.
1893    * When USE_LINUX_TERM open_ttyp() is invoked from child!
1894    */
1895 #ifndef USE_LINUX_TERM
1896   j_term_p_init (ttypfd);
1897 #endif
1898 
1899 #ifdef TIOCSSIZE
1900     pty_rowcol.ts_lines = crow; /* instead of lines */
1901     pty_rowcol.ts_cols = maxlength; /* instead of columns */
1902     ioctl(ttypfd, TIOCSSIZE, &pty_rowcol);
1903 #endif /* TIOCSSIZE */
1904 
1905 #ifdef SVR4
1906   set_euc_term(ttypfd);
1907 #endif
1908 
1909 #if defined(nec_ews_svr2)
1910   set_jterm (ttyfd, ttypfd);
1911 #endif
1912 
1913 #ifdef sony
1914   set_sony_jterm(ttyfd, ttypfd);
1915 #endif
1916 
1917 }
1918 
1919 /** pty �Υ����ץ� */
1920 #if defined(USE_LIBSPT)
1921 static void
1922 open_pty ()
1923 {
1924   int r;
1925   r = spt_open_pty(&spth, &ptyfd, NULL, NULL);
1926   if (r != SPT_E_NONE && r != SPT_E_CHOWN_FAIL)
1927     err ("Can't get pty.");
1928   return;
1929 }
1930 #elif defined(sgi)
1931 static void
1932 open_pty ()
1933 {
1934   char nmbuf[20];
1935   char *tty_name_buff;
1936   tty_name_buff = _getpty (&ptyfd, O_RDWR | O_NDELAY, 0600, 0);
1937   if (tty_name_buff == 0)
1938     err ("Can't get pty.");
1939   strcpy (ttypnm, tty_name_buff);
1940   return;
1941 
1942 }
1943 #else
1944 static void
1945 open_pty ()
1946 {
1947   char nmbuf[20];
1948 
1949   for (ptyno = 0; ptyno < MAXPTYNO; ptyno++)
1950     {
1951       ptyname (nmbuf, ptynm, ptyno);
1952       if ((ptyfd = open (nmbuf, O_RDWR, 0)) != ERROR)
1953         {
1954 #if defined(uniosu)
1955           if (ioctl (ptyfd, PIOCPKT, 1) < 0)
1956             {                   /* packet mode on */
1957               fprintf (stderr, "error in ioctl PIOCPKT.\n");
1958               exit (1);
1959             }
1960 #endif
1961 	  return;
1962         }
1963     }
1964   err ("Can't get pty.");
1965 }
1966 #endif
1967 
1968 /** ���顼���衣���褦�ʤ顣 */
1969 void
1970 err (s)
1971      char *s;
1972 {
1973   puts (s);
1974   fclose (stdout);
1975   fclose (stderr);
1976   fclose (stdin);
1977   do_end ();
1978 }
1979 
1980 /** Ω��Ļ��������� �����ν��� */
1981 static void
1982 do_end ()
1983 {
1984 #ifdef USE_LIBSPT
1985   int r;
1986 #else
1987   char nmbuf[20];
1988 #endif
1989 
1990   static int do_end_flg = 0;
1991   if (do_end_flg == 1)
1992     return;
1993   do_end_flg = 1;
1994 
1995   signal (SIGCHLD, SIG_DFL);
1996   fcntl (ttyfd, F_SETFL, 0);
1997 
1998   j_term_restore ();
1999 
2000 #if !defined(USE_LIBSPT) && !defined(sgi)
2001   ptyname (nmbuf, ptynm, ptyno);
2002   if (chown (nmbuf, 0, 0) == ERROR)
2003     {
2004       perror (prog);
2005     }
2006   if (chmod (nmbuf, 0666) == ERROR)
2007     {
2008       perror (prog);
2009     }
2010 
2011   ptyname (nmbuf, ttypnm, ptyno);
2012   if (chown (nmbuf, 0, 0) == ERROR)
2013     {
2014       perror (prog);
2015     }
2016   if (chmod (nmbuf, 0666) == ERROR)
2017     {
2018       perror (prog);
2019     }
2020 
2021 #endif /* !USE_LIBSPT && !sgi */
2022   close (ttyfd);
2023 #ifdef USE_LIBSPT
2024   if (spth && need_utmp_clear && (r = spt_logout_utmp(spth)))
2025     spt_perror(NULL, r);
2026   if (spth && (r = spt_close_pty(spth)))
2027     spt_perror(NULL, r);
2028 #else
2029   close (ptyfd);
2030 #endif
2031 
2032   chdir ("/tmp");               /* to avoid making too many mon.out files */
2033 
2034   KILLPG (child_id, SIGHUP);
2035   exit (0);
2036 }
2037 
2038 #if defined(uniosu)
2039 /** ��̾�����Ѵ��� ioctl �ǥ��դ������� keyin ������ؿ� */
2040 int
2041 ioctl_off ()
2042 {
2043   static unsigned char buf[BUFSIZ];
2044   int n;
2045   wnn_fd_set rfds;
2046 
2047   kk_restore_cursor ();
2048   clr_line_all ();
2049   display_henkan_off_mode ();
2050 
2051   for (;;)
2052     {
2053       if ((n = read (ttyfd, buf, BUFSIZ)) > 0)
2054         {
2055           write (ptyfd, buf, n);
2056         }
2057       rfds = sel_ptn;
2058       select (20, &rfds, 0, 0, NULL);
2059       if (WNN_FD_ISSET(ptyfd, &rfds))
2060         {
2061           if ((n = read (ptyfd, buf, BUFSIZ)) <= 0)
2062             {
2063               epilogue ();
2064               do_end ();
2065             }
2066           if (*buf == 0)
2067             {                   /* sequence of data */
2068               write (ttyfd, buf + 1, n - 1);
2069             }
2070           else if (*buf == PIOCPKT_IOCTL)
2071             {
2072               if (arrange_ioctl (0) > 0)
2073                 {
2074                   return;
2075                 }
2076             }
2077         }
2078       if (WNN_FD_ISSET(ttyfd, &rfds))
2079         {
2080           if ((n = read (ttyfd, buf, BUFSIZ)) > 0)
2081             {
2082               write (ptyfd, buf, n);
2083             }
2084         }
2085     }
2086 }
2087 #endif /* defined(uniosu) */
2088 
2089 
2090 #if !defined(USE_LIBSPT) && !defined(sgi)
2091 static void
2092 ptyname (b, pty, no)
2093      char *b, *pty;
2094 {
2095 /*
2096  * Change pseudo-devices.
2097  * Because FreeBSD's master pseudo-devices are pty[p-sP-S][0-9a-v].
2098  * Patched by Hidekazu Kuroki(hidekazu@cs.titech.ac.jp)         1996/8/20
2099  */
2100 #if (defined(BSD) && (BSD >= 199306))   /* 4.4BSD-Lite by Taoka */
2101   sprintf (b, "%s%1c%1c", pty, "pqrsPQRS"[(no >> 5)], (((no & 0x1f) > 9) ? 'a' : '0') + (no & 0x1f));
2102 #else /* ! 4.4BSD-Lite */
2103   sprintf (b, "%s%1c%1x", pty, 'p' + (no >> 4), no & 0x0f);
2104   if (no < 0x10 * ('z' - 'p' + 1))
2105     {
2106       sprintf(b, "%s%1c%1x", pty, 'p' + (no >> 4), no & 0x0f);
2107     }
2108   else
2109     {
2110       no -= 0x10 * ('z' - 'p' + 1);
2111       sprintf(b, "%s%1c%1x", pty, 'P' + (no >> 4), no & 0x0f);
2112     }
2113 #endif /* ! 4.4BSD-Lite */
2114 }
2115 #endif /* !USE_LIBSPT && !sgi */
2116 
2117 static void
2118 default_usage ()
2119 {
2120   fprintf (stderr, "%s: Bad -L option\n", prog);
2121   exit (0);
2122 }
2123 
2124 static void
2125 usage (optstr)
2126      char *optstr;
2127 {
2128   printf ("usage: prog %s by lang \"%s\"\n", optstr, lang_dir);
2129   exit (0);
2130 }
2131 
2132 /*
2133   save/restore signal settings
2134  */
2135 
2136 intfnptr sigpipe, sighup, sigint, sigquit, sigterm, sigtstp, sigttin, sigttou, sigchld;
2137 #ifdef SIGWINCH
2138 intfnptr sigwinch;
2139 #endif /* SIGWINCH */
2140 
2141 static void
2142 save_signals ()
2143 {
2144   sigpipe = signal (SIGPIPE, SIG_IGN);
2145 #ifdef USE_LINUX_TERM			    /* XXX */
2146   sighup = signal (SIGHUP, SIG_IGN);
2147 #endif
2148   sighup = signal (SIGHUP, terminate_handler);
2149   sigint = signal (SIGINT, SIG_IGN);
2150   sigquit = signal (SIGQUIT, SIG_IGN);
2151   sigterm = signal (SIGTERM, terminate_handler);
2152   sigchld = signal (SIGCHLD, chld_handler);
2153 #ifdef SIGWINCH
2154   sigwinch = signal (SIGWINCH, resize_handler);
2155 #endif /* SIGWINCH */
2156 #ifdef SIGTSTP
2157   sigtstp = signal (SIGTSTP, SIG_IGN);
2158   sigttin = signal (SIGTTIN, SIG_IGN);
2159   sigttou = signal (SIGTTOU, SIG_IGN);
2160 #endif /* SIGTSTP */
2161 }
2162 
2163 static void
2164 restore_signals ()
2165 {
2166   signal (SIGPIPE, sigpipe);
2167   signal (SIGHUP, sighup);
2168   signal (SIGINT, sigint);
2169   signal (SIGQUIT, sigquit);
2170   signal (SIGTERM, sigterm);
2171   signal (SIGCHLD, sigchld);
2172 #ifdef SIGWINCH
2173   signal (SIGWINCH, sigwinch);
2174 #endif /* SIGWINCH */
2175 #ifdef SIGTSTP
2176   signal (SIGTSTP, sigtstp);
2177   signal (SIGTTIN, sigttin);
2178   signal (SIGTTOU, sigttou);
2179 #endif /* SIGTSTP */
2180 }
2181 
2182 /* should be "defined(SIGWINCH)"? */
2183 #if defined(BSD43) || defined(DGUX)
2184 static void
2185 setsize ()
2186 {
2187   register int i;
2188   struct winsize win;
2189   extern Term_LineWidth, Term_RowWidth, maxlength, crow;
2190 
2191   if (ioctl (ttyfd, TIOCGWINSZ, &win) < 0)
2192     {
2193       /* Default set at getTermData() */
2194       return;
2195     }
2196   else
2197     {
2198       if ((i = win.ws_row) != 0)
2199         {
2200           crow = Term_RowWidth = i - conv_lines;
2201         }
2202       if ((i = win.ws_col) != 0)
2203         {
2204           maxlength = Term_LineWidth = i;
2205         }
2206     }
2207 }
2208 #endif /* BSD43 */
2209 
2210 #ifdef  SIGWINCH
2211 static void
2212 change_size ()
2213 {
2214   register int i;
2215   struct winsize win;
2216   extern Term_LineWidth, Term_RowWidth, maxlength, crow;
2217 
2218   if (ioctl (ttyfd, TIOCGWINSZ, &win) < 0)
2219     {
2220       /* Default set at getTermData() */
2221       return;
2222     }
2223   else
2224     {
2225       throw_cur_raw (0, crow);
2226       clr_line ();
2227 
2228       if ((i = win.ws_row) != 0)
2229         {
2230           crow = Term_RowWidth = i - conv_lines;
2231 #ifdef TIOCSWINSZ
2232           win.ws_row = crow;
2233 #endif
2234         }
2235       if ((i = win.ws_col) != 0)
2236         {
2237           maxlength = Term_LineWidth = i;
2238         }
2239 #ifdef TIOCSWINSZ
2240       ioctl (ttypfd, TIOCSWINSZ, &win);
2241 #else /* !TIOCSWINSZ */
2242 #ifdef  TIOCSSIZE
2243       pty_rowcol.ts_lines = crow;       /* instead of lines */
2244       pty_rowcol.ts_cols = maxlength;   /* instead of columns */
2245       ioctl (ttypfd, TIOCSSIZE, &pty_rowcol);
2246 #endif /* TIOCSSIZE */
2247 #ifdef  sun                     /* When your machine needs SIGWINCH, add your machine */
2248       {
2249         int grp;
2250         ioctl (ptyfd, TIOCGPGRP, &grp);
2251 	KILLPG (grp, SIGWINCH);
2252       }
2253 #endif /* sun */
2254 #endif /* !TIOCSWINSZ */
2255 
2256 #ifndef CANNA
2257       set_scroll_region (0, crow - 1);
2258       if (henkan_off_flag)
2259         {
2260           kk_restore_cursor ();
2261           throw_cur_raw (0, 0);
2262           kk_save_cursor ();
2263           display_henkan_off_mode ();
2264           set_screen_vars_default ();
2265           t_print_l ();
2266           kk_restore_cursor ();
2267         }
2268       else
2269         {
2270           kk_restore_cursor ();
2271           throw_cur_raw (0, 0);
2272           kk_save_cursor ();
2273           disp_mode ();
2274           set_screen_vars_default ();
2275           t_print_l ();
2276         }
2277 #else /* CANNA */
2278       set_scroll_region(0, crow - 1);
2279       set_screen_vars_default();
2280       t_print_l();
2281 #endif /* CANNA */
2282     }
2283 }
2284 #endif /* SIGWINCH */
2285 /*
2286  * vim: set cinoptions={.5s,\:.5s,+.5s,t0,g0,^-2,e-2,n-2,p.5s,(0,=.5s:
2287  * vim: set formatoptions=mMcroql cindent shiftwidth=4:
2288  */
2289