1 /*
2  * $Id: jutil.c,v 1.3 2002/06/22 13:24:31 hiroo 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 1991, 1992 by Massachusetts Institute of Technology
14  * Copyright FreeWnn Project 2002
15  *
16  * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.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, or (at your option)
21  * 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 GNU Emacs; see the file COPYING.  If not, write to the
30  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31  *
32  * Commentary:
33  *
34  * Change log:
35  *      '99/04/19       TAOKA Satoshi - �IJ� �һ�<taoka@infonets.hiroshima-u.ac.jp>
36  *              srandom() ����������ȥ����ȡ�
37  *	2002/06/22	Hiroo Ono <hiroo@oikumene.gcd.org>
38  *		Use RAND() and SRAND definde in wnn_os.h for the pseudo random number generator.
39  *
40  * Code:
41  *
42  */
43 /*      Version 4.0
44  */
45 /* jisho utility routine for otasuke (user interface) process */
46 
47 #ifdef HAVE_CONFIG_H
48 #  include <config.h>
49 #endif
50 
51 #include <stdio.h>
52 #if STDC_HEADERS
53 #  include <stdlib.h>
54 #  include <time.h>
55 #endif /* STDC_HEADERS */
56 #include <X11/Xos.h>
57 
58 #include "jslib.h"
59 #include "commonhd.h"
60 #include "sdefine.h"
61 #include "xjutil.h"
62 #include "sxheader.h"
63 #include "config.h"
64 #include "xext.h"
65 #include "rk_spclval.h"
66 #include "rk_fundecl.h"
67 #include "wnn_os.h"
68 
69 int (*jutil_table[2][6]) () =
70 {
71   {
72   kworddel, kworduse, kwordcom, kwordhindo, kwordima, kworddel_op}
73   ,
74   {
75   kdicdel, kdicuse, kdiccom, NULL, NULL, NULL}
76 };
77 
78 int
sStrcpy_and_ck(c,w)79 sStrcpy_and_ck (c, w)
80      unsigned char *c;
81      w_char *w;
82 {
83   sStrcpy (c, w);
84   for (; *w; w++)
85     {
86       if (*w > 0xff)
87         return (1);
88     }
89   return (0);
90 }
91 
92 void
if_dead_disconnect(env,ret)93 if_dead_disconnect (env, ret)
94      register struct wnn_env *env;
95      int ret;
96 {
97   if (wnn_errorno == WNN_JSERVER_DEAD)
98     {
99       js_close (env->js_id);
100     }
101 }
102 
103 int
yes_or_no(string)104 yes_or_no (string)
105      char *string;
106 {
107   unsigned int c1;
108   init_yes_or_no (string, YesNoMessage);
109   for (;;)
110     {
111       c1 = keyin ();
112       if ((xjutil->sel_ret == 1) || (xjutil->sel_ret == -1 && (c1 == NEWLINE || c1 == CR || c1 == 'y' || c1 == 'Y')))
113         {
114           end_yes_or_no ();
115           xjutil->sel_ret = -1;
116           return (1);
117         }
118       else if ((xjutil->sel_ret == 0) || (xjutil->sel_ret == -1 && (c1 == 'n' || c1 == 'N')))
119         {
120           end_yes_or_no ();
121           xjutil->sel_ret = -1;
122           return (0);
123         }
124       else
125         {
126           ring_bell ();
127           xjutil->sel_ret = -1;
128         }
129     }
130 }
131 
132 static int
yes_or_no_or_newline(string)133 yes_or_no_or_newline (string)
134      char *string;
135 {
136   return (yes_or_no (string));
137 }
138 
139 void
paramchg()140 paramchg ()
141 {
142   int c, k;
143   int newval;
144   char *ch;
145   char st[80];
146   char message1[80];
147   char message2[80], *mes[1];
148   w_char kana_buf[1024];
149 
150   static char *ccc[] = { "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL",
151     "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL"
152   };
153   struct wnn_param para;
154   int *paraary;
155   char *cccmsg[(sizeof (ccc) / sizeof (char *))];
156   char buf[1024];
157   static int init = 0;
158 
159   if (get_env () == -1)
160     return;
161 
162   paraary = (int *) &para;
163   if (js_param_get (cur_env, &para) == -1)
164     {
165       if_dead_disconnect (cur_env, -1);
166       errorkeyin ();
167       return;
168     }
169   for (k = 0, ch = buf; k < (sizeof (ccc) / sizeof (char *)); k++)
170     {
171       cccmsg[k] = ch;
172       sprintf (ch, "%s[%d]", msg_get (cd, 10 + k, default_message[10 + k], xjutil->lang), paraary[k]);
173       ch += strlen (ch) + 1;
174     }
175   c = xw_select_one_element_call (cccmsg, (sizeof (ccc) / sizeof (char *)), init, msg_get (cd, 9, default_message[9], xjutil->lang));
176   if (c == -1 || c == -3)
177     {
178       return;
179     }
180   init = c;
181   if (c == 0)
182     {
183       sprintf (message1, "%s %d %s", msg_get (cd, 27, default_message[27], xjutil->lang), paraary[0], msg_get (cd, 28, default_message[28], xjutil->lang));
184       sprintf (message2, "%s", msg_get (cd, 29, default_message[29], xjutil->lang));
185     }
186   else
187     {
188       sprintf (message1, "%s %s %s %d %s",
189                msg_get (cd, 30, default_message[30], xjutil->lang),
190                msg_get (cd, 10 + c, default_message[10 + c], xjutil->lang), msg_get (cd, 31, default_message[31], xjutil->lang), paraary[c], msg_get (cd, 32, default_message[32], xjutil->lang));
191       sprintf (message2, "%s", msg_get (cd, 33, default_message[33], xjutil->lang));
192     }
193   mes[0] = message2;
194   init_jutil (message1, msg_get (cd, 8, default_message[8], xjutil->lang), 1, &mes, NULL);
195 Retry:
196   cur_text->max_pos = 127;
197   clr_line_all ();
198   throw_col (0);
199   kk_cursor_normal ();
200   kana_buf[0] = 0;
201   if (kana_in (UNDER_LINE_MODE, kana_buf, 1024) == -1)
202     {
203       kk_cursor_invisible ();
204       end_jutil ();
205       return;
206     }
207   kk_cursor_invisible ();
208   if (sStrcpy_and_ck (st, kana_buf) || sscanf (st, "%d", &newval) <= 0)
209     {
210       print_msg_getc ("%s", msg_get (cd, 34, default_message[34], xjutil->lang), NULL, NULL);
211       goto Retry;
212     }
213   else if (c == 0 && newval <= 0)
214     {
215       print_msg_getc ("%s", msg_get (cd, 35, default_message[35], xjutil->lang), NULL, NULL);
216       goto Retry;
217     }
218   paraary[c] = newval;
219   if (js_param_set (cur_env, &para) == -1)
220     {
221       if_dead_disconnect (cur_env, -1);
222       errorkeyin ();
223     }
224   end_jutil ();
225   return;
226 }
227 
228 int
update_dic_list(buf)229 update_dic_list (buf)
230      struct wnn_buf *buf;
231 {
232   if ((dic_list_size = js_dic_list (cur_env, &dicrb)) < -1)
233     {
234       if_dead_disconnect (cur_env, -1);
235       return (-1);
236     }
237   dicinfo = (WNN_DIC_INFO *) (dicrb.buf);
238   return (0);
239 }
240 
241 void
dic_nickname(dic_no,buf)242 dic_nickname (dic_no, buf)
243      int dic_no;
244      char *buf;
245 {
246   int j;
247 
248   if ((j = find_dic_by_no (dic_no)) == -1)
249     return;
250   if (*dicinfo[j].comment)
251     sStrcpy (buf, dicinfo[j].comment);
252   else
253     strcpy (buf, dicinfo[j].fname);
254 }
255 
256 int
find_dic_by_no(dic_no)257 find_dic_by_no (dic_no)
258      int dic_no;
259 {
260   int j;
261 
262   for (j = 0; j < dic_list_size; j++)
263     {
264       if (dicinfo[j].dic_no == dic_no)
265         return (j);
266     }
267   return (-1);
268 }
269 
270 static void
fill(c,x)271 fill (c, x)
272      char *c;
273      int x;
274 {
275   for (; *c; c++, x--);
276   for (; x; x--, c++)
277     {
278       *c = ' ';
279     }
280 }
281 
282 static int
make_info_out(buf,size,infobuf,cnt)283 make_info_out (buf, size, infobuf, cnt)
284      char buf[];
285      WNN_DIC_INFO infobuf[];
286      int cnt;
287      int size;
288 {
289   int max1 = 0;
290   int max0 = 0;
291   int i, k, j;
292 
293   for (k = 0; k < cnt; k++)
294     {
295       for (j = 0; j < size; j++)
296         {
297           buf[k * size + j] = 0;
298         }
299     }
300 
301   for (i = 0; i < 13; i++)
302     {
303       if (i == 12)
304         {
305           sprintf (buf + max0, "%3d/%-3d", 0, cnt - 1);
306         }
307       else
308         {
309           sprintf (buf + max0, "%s", msg_get (cd, 54 + i, default_message[54 + i], xjutil->lang));
310         }
311       max1 = MAX_VAL (max1, strlen (buf));
312       if (max1 >= size)
313         return (-1);
314       for (k = 1; k < cnt; k++)
315         {
316           switch (i)
317             {
318             case 0:
319               sprintf (buf + size * k + max0, "%3d ", infobuf[k - 1].dic_no);
320               break;
321             case 1:
322               {
323                 char *tmp;
324                 if ((0xff00 & infobuf[k - 1].type) == (BWNN_REV_DICT & 0xff00))
325                   tmp = bwnn_dic_types[0xff & infobuf[k - 1].type];
326                 else if ((0xff00 & infobuf[k - 1].type) == (CWNN_REV_DICT & 0xff00))
327                   tmp = cwnn_dic_types[0xff & infobuf[k - 1].type];
328                 else
329                   tmp = wnn_dic_types[infobuf[k - 1].type];
330                 sprintf (buf + size * k + max0, "%8s", tmp);
331               }
332               break;
333             case 2:
334               sStrcpy (buf + size * k + max0, infobuf[k - 1].comment);
335               break;
336             case 3:
337               strcpy (buf + size * k + max0, infobuf[k - 1].fname);
338               break;
339             case 4:
340               strcpy (buf + size * k + max0, infobuf[k - 1].hfname);
341               break;
342             case 5:
343               sprintf (buf + size * k + max0, "%6d", infobuf[k - 1].gosuu);
344               break;
345             case 6:
346               sprintf (buf + size * k + max0, "%4d", infobuf[k - 1].nice);
347               break;
348             case 7:
349               strcpy (buf + size * k + max0, (!infobuf[k - 1].rw) ? "Yes" : "No");
350               break;
351             case 8:
352               strcpy (buf + size * k + max0, (!infobuf[k - 1].hindo_rw) ? "Yes" : "No");
353               break;
354             case 9:
355               strcpy (buf + size * k + max0, ((infobuf[k - 1].enablef) ? msg_get (cd, 43, default_message[43], xjutil->lang) : msg_get (cd, 44, default_message[44], xjutil->lang)));
356               break;
357             case 10:
358               strcpy (buf + size * k + max0, infobuf[k - 1].passwd);
359               break;
360             case 11:
361               strcpy (buf + size * k + max0, infobuf[k - 1].hpasswd);
362               break;
363             case 12:
364               sprintf (buf + size * k + max0, "%3d/%-3d", k, cnt - 1);
365               break;
366             }
367           max1 = MAX_VAL (max1, strlen (buf + size * k));
368           if (max1 >= size)
369             return (-1);
370         }
371       max0 = max1 + 1;
372       for (k = 0; k < cnt; k++)
373         {
374           fill (buf + size * k, max0);
375         }
376     }
377   return (1);
378 }
379 
380 void
dicinfoout()381 dicinfoout ()
382 {
383   int k;
384   int cnt;
385   char buf[4096];
386   char *info[JISHOKOSUU];
387   char *comment;
388   int size;
389   char *table_t[3];
390   static int init = 0;
391 
392   if (get_env () == -1)
393     return;
394 
395   if (update_dic_list () == -1)
396     {
397       errorkeyin ();
398       return;
399     }
400   cnt = dic_list_size;
401   cnt += 1;                     /* for the comment line */
402   size = 4096 / cnt;
403   if (make_info_out (buf, size, dicinfo, cnt) == -1)
404     {
405       print_msg_getc ("%s", msg_get (cd, 40, default_message[40], xjutil->lang), NULL, NULL);
406     }
407   comment = buf;
408   for (k = 1; k < cnt; k++)
409     {
410       info[k - 1] = buf + k * size;
411     }
412   table_t[0] = msg_get (cd, 37, default_message[37], xjutil->lang);
413   table_t[1] = msg_get (cd, 38, default_message[38], xjutil->lang);
414   table_t[2] = msg_get (cd, 39, default_message[39], xjutil->lang);
415   if (init < 0 || init > (cnt - 1))
416     init = 0;
417   init = xw_select_one_element_keytable (info, cnt - 1, init, msg_get (cd, 36, default_message[36], xjutil->lang), 3, table_t, jutil_table[1], main_table[8], comment);
418   return;
419 }
420 
421 void
select_one_dict9()422 select_one_dict9 ()
423 {
424   int l;
425   char *c;
426   char buf[4096];
427   char *buf_ptr[JISHOKOSUU];
428   char baka[1024];
429   static int init = 0;
430 
431   if (get_env () == -1)
432     return;
433 
434   if (update_dic_list () == -1)
435     {
436       errorkeyin ();
437       return;
438     }
439   if (dic_list_size == 0)
440     {
441       print_msg_getc ("%s", msg_get (cd, 42, default_message[42], xjutil->lang), NULL, NULL);
442       return;
443     }
444 
445   for (c = buf, l = 0; l < dic_list_size; l++)
446     {
447       buf_ptr[l] = c;
448       dic_nickname (dicinfo[l].dic_no, baka);
449       sprintf (c, "%s(%s) %s %d/%d",
450                baka, dicinfo[l].hfname, (dicinfo[l].enablef ? msg_get (cd, 43, default_message[43], xjutil->lang) : msg_get (cd, 44, default_message[44], xjutil->lang)), (l + 1), dic_list_size);
451       c += strlen (c) + 1;
452     }
453   if (init < 0 || init > dic_list_size)
454     init = 0;
455   init = xw_select_one_element_call (buf_ptr, dic_list_size, init, msg_get (cd, 41, default_message[41], xjutil->lang));
456   return;
457 }
458 
459 void
fuzoku_set()460 fuzoku_set ()
461 {
462   int ret;
463   char *message1 = msg_get (cd, 45, default_message[45], xjutil->lang);
464   char *message2 = msg_get (cd, 46, default_message[46], xjutil->lang);
465   char *mes[1];
466   w_char kana_buf[1024];
467   register int fid, orgfid;
468 
469   if (get_env () == -1)
470     return;
471 
472   mes[0] = message2;
473   init_jutil (message1, msg_get (cd, 8, default_message[8], xjutil->lang), 1, &mes, NULL);
474   throw_col (0);
475   JWMline_clear (0);
476   kk_cursor_normal ();
477   Sstrcpy (kana_buf, fuzokugopath);
478   JWMflushw_buf (kana_buf, Strlen (kana_buf));
479 retry:
480   if ((ret = kana_in (UNDER_LINE_MODE, kana_buf, 1024)) == -1)
481     {
482       kk_cursor_invisible ();
483       end_jutil ();
484       return;
485     }
486   if (sStrcpy (fuzokugopath, kana_buf) == 0)
487     {
488       ring_bell ();
489       goto retry;
490     }
491   orgfid = js_fuzokugo_get (cur_env);
492   if (fuzokugopath[0] == C_LOCAL)
493     {
494       fid = js_file_send (cur_env, fuzokugopath + 1);
495     }
496   else
497     {
498       fid = js_file_read (cur_env, fuzokugopath);
499     }
500   if (fid == -1)
501     {
502       if_dead_disconnect (cur_env, -1);
503       errorkeyin ();
504       goto retry;
505     }
506   else if ((ret = js_fuzokugo_set (cur_env, fid)) < 0)
507     {
508       if_dead_disconnect (cur_env, -1);
509       errorkeyin ();
510       goto retry;
511     }
512   else if (fid != orgfid && orgfid != -1)
513     {
514       if_dead_disconnect (cur_env, -1);
515       errorkeyin ();
516       goto retry;
517     }
518   kk_cursor_invisible ();
519   end_jutil ();
520   return;
521 }
522 
523 static int
524 call_error_handler (error_handler, c)
525      int (*error_handler) ();
526      char *c;
527 {
528   register int x;
529   x = (*error_handler) (c);
530   return (x);
531 }
532 
533 static void
534 message_out (message_handler, format, s1, s2, s3)
535      int (*message_handler) ();
536      char *format;
537      char *s1, *s2, *s3;
538 {
539   if (message_handler)
540     {
541       (*message_handler) (format, s1, s2, s3);
542     }
543 }
544 
545 static int
get_pwd(pwd_dic,pwd)546 get_pwd (pwd_dic, pwd)
547      register char *pwd_dic, *pwd;
548 {
549   FILE *fp;
550 
551   if (pwd_dic && *pwd_dic)
552     {
553       if ((fp = fopen (pwd_dic, "r")) == NULL)
554         {
555           wnn_errorno = WNN_CANT_OPEN_PASSWD_FILE;
556           return (-1);
557         }
558       fgets (pwd, WNN_PASSWD_LEN, fp);
559       fclose (fp);
560     }
561   else
562     {
563       pwd[0] = 0;
564     }
565   return (0);
566 }
567 
568 static int
file_exist(env,n)569 file_exist (env, n)
570      struct wnn_env *env;
571      char *n;
572 {
573   extern int access ();
574 
575   if (n[0] == C_LOCAL)
576     {
577       wnn_errorno = 0;
578       return (access (n + 1, 4));
579     }
580   else
581     {
582       return (js_access (env, n, 4));
583     }
584 }
585 
586 static int
make_dir1(env,dirname,error_handler,message_handler)587 make_dir1 (env, dirname, error_handler, message_handler)
588      register struct wnn_env *env;
589      register char *dirname;
590      int (*error_handler) (), (*message_handler) ();
591 {
592   char gomi[128];
593   extern int mkdir (), chmod (), chown ();
594 
595   if (dirname[0] == C_LOCAL)
596     {
597       if (*(dirname + 1) == 0)
598         return (0);
599       if (access (dirname + 1, 0) == 0)
600         {                       /* check for existence */
601           return (0);           /* dir already exists */
602         }
603     }
604   else
605     {
606       if (*dirname == 0)
607         return (0);
608       if (js_access (env, dirname, 0) == 0)
609         {                       /* check for existence */
610           return (0);           /* dir already exists */
611         }
612     }
613   if ((int) error_handler != -1)
614     {
615       sprintf (gomi, "%s \"%s\" %s%s",
616                msg_get (cd, 110, default_message[110], xjutil->lang), dirname, msg_get (cd, 103, default_message[103], xjutil->lang), msg_get (cd, 104, default_message[104], xjutil->lang));
617       if (call_error_handler (error_handler, gomi) == 0)
618         {
619           wnn_errorno = WNN_MKDIR_FAIL;
620           return (-1);
621         }
622     }
623   if (dirname[0] == C_LOCAL)
624     {                           /* Create Directory */
625 #define MODE (0000000 | 0000777)
626 #if defined(BSD42) || defined(SX8870)
627       if (mkdir (dirname + 1, MODE) != 0)
628         {
629           wnn_errorno = WNN_MKDIR_FAIL;
630           return (-1);
631         }
632 #endif
633 #if defined(SYSVR2) && !defined(SX8870)
634       char buf[256];
635       strcpy (buf, "/bin/mkdir ");
636       strcat (buf, dirname + 1);
637       if (system (buf) != 0)
638         {
639           /*
640              wnn_errorno=WNN_MKDIR_FAIL;
641              return(-1);
642            */
643         }
644 #endif
645       chmod (dirname + 1, MODE);
646       chown (dirname + 1, getuid (), -1);
647     }
648   else
649     {
650       if (js_mkdir (env, dirname))
651         {
652           if_dead_disconnect (env, -1);
653           return (-1);
654         }
655     }
656   return (0);
657 }
658 
659 static int
make_dir_rec1(env,path,error_handler,message_handler)660 make_dir_rec1 (env, path, error_handler, message_handler)
661      struct wnn_env *env;
662      register char *path;
663      int (*error_handler) (), (*message_handler) ();
664 {
665   char gomi[128];
666   register char *c;
667   for (c = path; *c; c++)
668     {
669       if (*c == '/')
670         {
671           strncpy (gomi, path, c - path);
672           gomi[c - path] = 0;
673           if (make_dir1 (env, gomi, error_handler, message_handler) == -1)
674             {
675               return (-1);
676             }
677         }
678     }
679   return (0);
680 }
681 
682 static int
create_pwd_file(env,pwd_file,error_handler,message_handler)683 create_pwd_file (env, pwd_file, error_handler, message_handler)
684      register struct wnn_env *env;
685      char *pwd_file;
686      int (*error_handler) (), (*message_handler) ();
687 {
688   FILE *fp;
689   char gomi[256];
690 
691   if (pwd_file == NULL || *pwd_file == 0)
692     return (0);
693   if (access (pwd_file, F_OK) != -1)
694     return (0);
695   sprintf (gomi, "%s \"%s\" %s%s",
696            msg_get (cd, 108, default_message[108], xjutil->lang), pwd_file, msg_get (cd, 103, default_message[103], xjutil->lang), msg_get (cd, 104, default_message[104], xjutil->lang));
697   if (call_error_handler (error_handler, gomi) == 0)
698     {
699       wnn_errorno = WNN_NO_EXIST;
700       return (-1);
701     }
702   if ((fp = fopen (pwd_file, "w")) == NULL)
703     {
704       wnn_errorno = WNN_CANT_OPEN_PASSWD_FILE;
705       message_out (message_handler, wnn_perror_lang (xjutil->lang), NULL, NULL, NULL);
706       return (-1);
707     }
708   SRAND (time (0) + getuid ());
709   fprintf (fp, "%d\n", RAND ());
710   fclose (fp);
711 #define MODE_PWD (0000000 | 0000400)
712   chmod (pwd_file, MODE_PWD);
713   return (0);
714 }
715 
716 #define JISHO 1
717 #define HINDO 2
718 
719 static int
create_file(env,n,d,fid,pwd_dic,pwd_hindo,error_handler,message_handler)720 create_file (env, n, d, fid, pwd_dic, pwd_hindo, error_handler, message_handler)
721      register struct wnn_env *env;
722      char *n;
723      int d;
724      int fid;
725      char *pwd_dic, *pwd_hindo;
726      int (*error_handler) (), (*message_handler) ();
727 {
728   char pwd[WNN_PASSWD_LEN], hpwd[WNN_PASSWD_LEN];
729   int rev_dict_type;
730 
731   if (make_dir_rec1 (env, n, error_handler, message_handler) == -1)
732     {
733       wnn_errorno = WNN_MKDIR_FAIL;
734       return (-1);
735     }
736   if (d == HINDO)
737     {
738       if (create_pwd_file (env, pwd_hindo, error_handler, message_handler) == -1)
739         return (-1);
740       if (get_pwd (pwd_hindo, hpwd) == -1)
741         return (-1);
742       if (n[0] == C_LOCAL)
743         {
744           if (js_hindo_file_create_client (env, fid, n + 1, NULL, hpwd) == -1)
745             {
746               message_out (message_handler, wnn_perror_lang (xjutil->lang), NULL, NULL, NULL);
747               if_dead_disconnect (env, -1);
748             }
749           else
750             {
751               message_out (message_handler, "%s \"%s\" %s", msg_get (cd, 105, default_message[105], xjutil->lang), n, msg_get (cd, 109, default_message[109], xjutil->lang));
752               chown (n + 1, getuid (), -1);     /* H.T. */
753               return (0);
754             }
755         }
756       else
757         {
758           if (js_hindo_file_create (env, fid, n, NULL, hpwd) == -1)
759             {
760               message_out (message_handler, wnn_perror_lang (xjutil->lang));
761               if_dead_disconnect (env, -1);
762               return (-1);
763             }
764           else
765             {
766               message_out (message_handler, "%s \"%s\" %s", msg_get (cd, 105, default_message[105], xjutil->lang), n, msg_get (cd, 109, default_message[109], xjutil->lang));
767               return (0);
768             }
769         }
770     }
771   else
772     {
773       if (create_pwd_file (env, pwd_hindo, error_handler, message_handler) == -1)
774         return (-1);
775       if (get_pwd (pwd_hindo, hpwd) == -1)
776         return (-1);
777       if (create_pwd_file (env, pwd_dic, error_handler, message_handler) == -1)
778         return (-1);
779       if (get_pwd (pwd_dic, pwd) == -1)
780         return (-1);
781 
782 #ifdef  CHINESE
783       if (!strncmp (js_get_lang (env), LANG_CN, 5) || !strncmp (js_get_lang (env), LANG_TW, 5))
784         rev_dict_type = CWNN_REV_DICT;
785       else
786 #endif /* CHINESE */
787         rev_dict_type = WNN_REV_DICT;
788 
789       if (n[0] == C_LOCAL)
790         {
791           if (js_dic_file_create_client (env, n + 1, rev_dict_type, NULL, pwd, hpwd) == -1)
792             {
793               message_out (message_handler, wnn_perror_lang (xjutil->lang), NULL, NULL, NULL);
794               if_dead_disconnect (env, -1);
795               return (-1);
796             }
797           else
798             {
799               message_out (message_handler, "%s \"%s\" %s", msg_get (cd, 102, default_message[102], xjutil->lang), n, msg_get (cd, 109, default_message[109], xjutil->lang));
800               chown (n + 1, getuid (), -1);
801               return (0);
802             }
803         }
804       else
805         {
806           if (js_dic_file_create (env, n, rev_dict_type, NULL, pwd, hpwd) == -1)
807             {
808               message_out (message_handler, wnn_perror_lang (xjutil->lang), NULL, NULL, NULL);
809               if_dead_disconnect (env, -1);
810               return (-1);
811             }
812           else
813             {
814               message_out (message_handler, "%s \"%s\" %s", msg_get (cd, 102, default_message[102], xjutil->lang), n, msg_get (cd, 109, default_message[109], xjutil->lang));
815               return (0);
816             }
817         }
818     }
819   return (-1);
820 }
821 
822 static int
file_read(env,fname)823 file_read (env, fname)
824      struct wnn_env *env;
825      char *fname;
826 {
827   register int fid;
828   if (fname[0] == C_LOCAL)
829     {
830       fid = js_file_send (env, fname + 1);
831     }
832   else
833     {
834       fid = js_file_read (env, fname);
835     }
836   return (fid);
837 }
838 
839 static int
file_remove(server,fname,pwd)840 file_remove (server, fname, pwd)
841      register WNN_JSERVER_ID *server;
842      char *fname;
843      char *pwd;
844 {
845   if (fname[0] == C_LOCAL)
846     {
847       return (js_file_remove_client (server, fname + 1, pwd));
848     }
849   else
850     {
851       return (js_file_remove (server, fname, pwd));
852     }
853 }
854 
855 static int
file_discard(env,fid)856 file_discard (env, fid)
857      register struct wnn_env *env;
858      register int fid;
859 {
860   return (js_file_discard (env, fid));
861 }
862 
863 static int
dic_add_e(env,dic_name,hindo_name,rev,prio,rw,hrw,pwd_dic,pwd_hindo,error_handler,message_handler)864 dic_add_e (env, dic_name, hindo_name, rev, prio, rw, hrw, pwd_dic, pwd_hindo, error_handler, message_handler)
865      register struct wnn_env *env;
866      char *dic_name;
867      char *hindo_name;
868      int prio;
869      int rw, hrw, rev;
870      char *pwd_dic, *pwd_hindo;
871      int (*error_handler) (), (*message_handler) ();
872 {
873   char tmp[256];
874   char pwd[WNN_PASSWD_LEN], hpwd[WNN_PASSWD_LEN];
875   int fid, hfid = -1;
876   register int ret;
877 
878 
879   if (file_exist (env, dic_name) == -1)
880     {
881       if (wnn_errorno == WNN_JSERVER_DEAD)
882         {
883           js_close (env->js_id);
884           return (-1);
885         }
886       if ((int) error_handler == 0 || (rw == WNN_DIC_RDONLY))
887         {
888           message_out (message_handler, "%s \"%s\" %s", msg_get (cd, 102, default_message[102], xjutil->lang), dic_name, msg_get (cd, 103, default_message[103], xjutil->lang));
889           wnn_errorno = WNN_NO_EXIST;
890           return (-1);
891         }
892       sprintf (tmp, "%s \"%s\" %s%s",
893                msg_get (cd, 102, default_message[102], xjutil->lang), dic_name, msg_get (cd, 103, default_message[103], xjutil->lang), msg_get (cd, 104, default_message[104], xjutil->lang));
894       if ((int) error_handler == -1 || call_error_handler (error_handler, tmp))
895         {
896           if (create_file (env, dic_name, JISHO, -1,    /* -1 is dummy */
897                            pwd_dic, (hindo_name && *hindo_name) ? "" : pwd_hindo, error_handler, message_handler) == -1)
898             {
899               return (-1);
900             }
901         }
902       else
903         {
904           wnn_errorno = WNN_NO_EXIST;
905           return (-1);
906         }
907     }
908   if ((fid = file_read (env, dic_name)) == -1)
909     {
910       if_dead_disconnect (env, -1);
911       return (-1);
912     }
913   if (hindo_name && *hindo_name)
914     {
915       if (file_exist (env, hindo_name) == -1)
916         {
917           if (wnn_errorno == WNN_JSERVER_DEAD)
918             {
919               js_close (env->js_id);;
920               return (-1);
921             }
922           if ((int) error_handler == 0 || (hrw == WNN_DIC_RDONLY))
923             {
924               message_out (message_handler, "%s \"%s\" %s", msg_get (cd, 105, default_message[105], xjutil->lang), hindo_name, msg_get (cd, 103, default_message[103], xjutil->lang));
925               wnn_errorno = WNN_NO_EXIST;
926               return (-1);
927             }
928           sprintf (tmp, "%s \"%s\" %s%s",
929                    msg_get (cd, 105, default_message[105], xjutil->lang), hindo_name, msg_get (cd, 103, default_message[103], xjutil->lang), msg_get (cd, 104, default_message[104], xjutil->lang));
930           if ((int) error_handler == -1 || call_error_handler (error_handler, tmp))
931             {
932               if (create_file (env, hindo_name, HINDO, fid, "", pwd_hindo, error_handler, message_handler) == -1)
933                 return (-1);
934             }
935           else
936             {
937               wnn_errorno = WNN_NO_EXIST;
938               return (-1);
939             }
940         }
941       if ((hfid = file_read (env, hindo_name)) == -1)
942         {
943           if_dead_disconnect (env, -1);
944           return (-1);
945         }
946     }
947   if (get_pwd (pwd_dic, pwd) == -1)
948     return (-1);
949   if (get_pwd (pwd_hindo, hpwd) == -1)
950     return (-1);
951   if ((ret = js_dic_add (env, fid, hfid, rev, prio, rw, hrw, pwd, hpwd)) < 0)
952     {
953       if (wnn_errorno == WNN_JSERVER_DEAD)
954         {
955           js_close (env->js_id);
956           return (-1);
957         }
958       else if (wnn_errorno == WNN_HINDO_NO_MATCH)
959         {
960           if ((int) error_handler == 0)
961             {
962               return (-1);
963             }
964           sprintf (tmp, "%s \"%s\" %s", msg_get (cd, 106, default_message[106], xjutil->lang), hindo_name, msg_get (cd, 107, default_message[107], xjutil->lang));
965           if (!((int) error_handler == -1 || call_error_handler (error_handler, tmp)))
966             {
967               return (-1);
968             }
969           if (file_discard (env, hfid) == -1)
970             {
971               if_dead_disconnect (env, -1);
972               return (-1);
973             }
974           if (file_remove (env->js_id, hindo_name, hpwd) == -1)
975             {
976               if_dead_disconnect (env, -1);
977               return (-1);
978             }
979           if (create_file (env, hindo_name, HINDO, fid, NULL, pwd_hindo, -1, message_handler) == -1)
980             return (-1);
981           if ((hfid = file_read (env, hindo_name)) == -1)
982             {
983               if_dead_disconnect (env, -1);
984               return (-1);
985             }
986           if ((ret = js_dic_add (env, fid, hfid, rev, prio, rw, hrw, pwd, hpwd)) < 0)
987             {
988               if_dead_disconnect (env, -1);
989               return (-1);
990             }
991         }
992     }
993   return (ret);
994 }
995 
996 static void
getfname(file,path)997 getfname (file, path)
998      char *path, *file;
999 {
1000   char *c;
1001 
1002   c = path + strlen (path);
1003   for (; *c != '/' && c >= path; c--);
1004   strcpy (file, c + 1);
1005 }
1006 
1007 void
jishoadd()1008 jishoadd ()
1009 {
1010   int ret;
1011   char *message1 = msg_get (cd, 47, default_message[47], xjutil->lang);
1012   char *message2 = msg_get (cd, 48, default_message[48], xjutil->lang);
1013   char *message = msg_get (cd, 49, default_message[49], xjutil->lang);
1014   char *hmessage = msg_get (cd, 50, default_message[50], xjutil->lang);
1015   char *priomessage = msg_get (cd, 51, default_message[51], xjutil->lang);
1016   char *mes[1];
1017   char tmp[128];
1018   char hfname[128];
1019   int prio;
1020   int rdonly;
1021   int hrdonly;
1022   int id, l;
1023   w_char kana_buf[1024];
1024 
1025   if (get_env () == -1)
1026     return;
1027 
1028   mes[0] = message;
1029   init_jutil (message1, message2, 1, &mes, NULL);
1030   JWMline_clear (0);
1031   throw_col (0);
1032   kk_cursor_normal ();
1033   Sstrcpy (kana_buf, jishopath);
1034   JWMflushw_buf (kana_buf, Strlen (kana_buf));
1035   if ((ret = kana_in (UNDER_LINE_MODE, kana_buf, 1024)) == -1)
1036     {
1037       kk_cursor_invisible ();
1038       end_jutil ();
1039       return;
1040     }
1041   kk_cursor_invisible ();
1042   end_jutil ();
1043   if (sStrcpy (jishopath, kana_buf) == 0)
1044     {
1045       return;
1046     }
1047   Sstrcpy (kana_buf, hindopath);
1048   getfname (hfname, jishopath);
1049   if (strcmp (hfname + strlen (hfname) - 4, ".usr") == 0 ||
1050       strcmp (hfname + strlen (hfname) - 4, ".sys") == 0 || strcmp (hfname + strlen (hfname) - 4, ".dic") == 0 || strcmp (hfname + strlen (hfname) - 4, ".rev") == 0)
1051     {
1052       hfname[strlen (hfname) - 4] = 0;
1053       strcat (hfname, ".h");
1054     }
1055   else if (strcmp (hfname + strlen (hfname) - 5, ".usrR") == 0 || strcmp (hfname + strlen (hfname) - 5, ".sysR") == 0)
1056     {
1057       hfname[strlen (hfname) - 5] = 0;
1058       strcat (hfname, ".hR");
1059     }
1060   else
1061     {
1062       strcat (hfname, ".h");
1063     }
1064   Sstrcpy (kana_buf + Strlen (kana_buf), hfname);
1065   mes[0] = hmessage;
1066   init_jutil (message1, message2, 1, &mes, NULL);
1067   clr_line_all ();
1068   throw_col (0);
1069   kk_cursor_normal ();
1070   JWMflushw_buf (kana_buf, Strlen (kana_buf));
1071   if ((ret = kana_in (UNDER_LINE_MODE, kana_buf, 1024)) == -1)
1072     {
1073       kk_cursor_invisible ();
1074       end_jutil ();
1075       return;
1076     }
1077   kk_cursor_invisible ();
1078   end_jutil ();
1079   sStrcpy (hfname, kana_buf);
1080 Dicadd_Retry:
1081   sprintf (tmp, "%d", JISHO_PRIO_DEFAULT);
1082   Sstrcpy (kana_buf, tmp);
1083   mes[0] = priomessage;
1084   init_jutil (message1, message2, 1, &mes, NULL);
1085   clr_line_all ();
1086   throw_col (0);
1087   kk_cursor_normal ();
1088   JWMflushw_buf (kana_buf, Strlen (kana_buf));
1089   if ((ret = kana_in (UNDER_LINE_MODE, kana_buf, 1024)) == -1)
1090     {
1091       kk_cursor_invisible ();
1092       end_jutil ();
1093       return;
1094     }
1095   kk_cursor_invisible ();
1096   end_jutil ();
1097   if (sStrcpy_and_ck (tmp, kana_buf) || sscanf (tmp, "%d", &prio) <= 0)
1098     {
1099       print_msg_getc ("%s", msg_get (cd, 34, default_message[34], xjutil->lang), NULL, NULL);
1100       goto Dicadd_Retry;
1101     }
1102   if (yes_or_no_or_newline (msg_get (cd, 52, default_message[52], xjutil->lang)) == 1)
1103     {
1104       rdonly = 0;
1105     }
1106   else
1107     {
1108       rdonly = 1;
1109     }
1110   if (yes_or_no_or_newline (msg_get (cd, 53, default_message[53], xjutil->lang)) == 1)
1111     {
1112       hrdonly = 0;
1113     }
1114   else
1115     {
1116       hrdonly = 1;
1117     }
1118 
1119   if (((id = dic_add_e (cur_env, jishopath, hfname, 0, prio, rdonly, hrdonly, NULL, NULL, yes_or_no_or_newline, print_msg_getc)) == -1) && (wnn_errorno != -1))
1120     {
1121       errorkeyin ();
1122     }
1123   update_dic_list ();
1124   for (l = 0; l < dic_list_size; l++)
1125     {
1126       if (dicinfo[l].dic_no == id)
1127         {
1128           break;
1129         }
1130     }
1131   if (l != dic_list_size && cur_reverse_env->env && (dicinfo[l].type == WNN_REV_DICT || dicinfo[l].type == CWNN_REV_DICT))
1132     {
1133       if ((dic_add_e (cur_reverse_env->env, jishopath, hfname, 1, prio, rdonly, hrdonly, NULL, NULL, yes_or_no_or_newline, print_msg_getc) == -1) && (wnn_errorno != -1))
1134         {
1135           errorkeyin ();
1136         }
1137     }
1138   /*
1139      clr_line_all();
1140    */
1141   end_yes_or_no ();
1142 }
1143 
1144 int
dic_delete_e(env,dic_no)1145 dic_delete_e (env, dic_no)
1146      register struct wnn_env *env;
1147      register int dic_no;
1148 {
1149   WNN_DIC_INFO dic;
1150 
1151 
1152   if (js_dic_info (env, dic_no, &dic) < 0)
1153     {
1154       if_dead_disconnect (env, -1);
1155       return (-1);
1156     }
1157   if (js_dic_delete (env, dic_no) < 0)
1158     {
1159       if_dead_disconnect (env, -1);
1160       return (-1);
1161     }
1162   /*  dic Body        */
1163   if (file_discard (env, dic.body) < 0)
1164     {
1165       if_dead_disconnect (env, -1);
1166       return (-1);
1167     }
1168   /*  dic hindo       */
1169   if (dic.hindo != -1)
1170     {
1171       if (file_discard (env, dic.hindo) < 0)
1172         {
1173           if_dead_disconnect (env, -1);
1174           return (-1);
1175         }
1176     }
1177   return (0);
1178 }
1179