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