1 /*
2  * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
3  * This file is part of FreeWnn.
4  *
5  * Copyright Kyoto University Research Institute for Mathematical Sciences
6  *                 1987, 1988, 1989, 1990, 1991, 1992
7  * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
8  * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992
9  * Copyright FreeWnn Project 1999, 2000, 2002, 2003
10  *
11  * Maintainer:  FreeWnn Project   <freewnn@tomo.gr.jp>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27 
28 /*
29   (Updatable, Stable) dictionary read routine.
30 */
31 static char rcs_id[] = "$Id: readfile.c,v 1.9 2003/06/07 02:23:58 hiroo Exp $";
32 
33 #if defined(HAVE_CONFIG_H)
34 #include <config.h>
35 #endif
36 
37 #include <stdio.h>
38 #if STDC_HEADERS
39 #  include <stdlib.h>
40 #  include <string.h>
41 #else
42 #  if HAVE_MALLOC_H
43 #    include <malloc.h>
44 #  endif
45 #  if HAVE_STRINGS_H
46 #    include <strings.h>
47 #  endif
48 #endif /* STDC_HEADERS */
49 
50 #if defined(HAVE_SYS_TYPES_H)
51 #include <sys/types.h>
52 #endif
53 
54 #include "commonhd.h"
55 #include "de_header.h"
56 #include "jdata.h"
57 
58 #ifdef WRITE_CHECK
59 static int vfwrite (void*, int, int, FILE *);
60 #endif
61 static struct JT *readdict (FILE *);
62 static struct JT *copy_dict (struct JT *);
63 static int write_file_real (struct wnn_file *, FILE *, int);
64 static int writedict (struct JT *, FILE *);
65 static int write_hindo_of_dict (struct JT *, FILE *);
66 static struct JT * free_dict (struct JT *);
67 static struct HJT *readhindo (FILE *);
68 static int writehindo (struct HJT *, FILE *);
69 static struct HJT * free_hindo (struct HJT *);
70 static int alloc_dict (struct JT *);
71 static int check_and_change_pwd (char *, char *, char *);
72 
73 #define vfread(A, B, C, fp) ((fp)?fread((A),(B),(C),(fp)):fread_cur((A),(B),(C)))
74 #ifndef WRITE_CHECK
75 #define vfwrite(A, B, C, fp) {if(fp) {fwrite((A),(B),(C),(fp));}else\
76                                      {fwrite_cur((A),(B),(C));}}
77 #endif
78 #define vclose(fp) {if(fp) {fclose(fp);}else{fclose_cur();}}
79 
80 #ifdef WRITE_CHECK
81 static int
vfwrite(void * ptr,int size,int nitems,FILE * fp)82 vfwrite (void *ptr, int size, int nitems, FILE *fp)
83 {
84   if (fp)
85     {
86       if (fwrite (ptr, size, nitems, fp) != nitems)
87         return (-1);
88     }
89   else
90     {
91       fwrite_cur (ptr, size, nitems);
92     }
93   return (0);
94 }
95 #endif
96 
97 int
read_file(struct wnn_file * wf)98 read_file (struct wnn_file *wf)
99 {
100   FILE *fp;
101   struct wnn_file_head fh;
102   if (wf->localf == REMOTE)
103     {
104       if (fopen_read_cur (wf->name) == NULL)
105         {
106           wnn_errorno = WNN_FILE_READ_ERROR;
107           log_err ("read_file:could not open file %s.", wf->name);
108           return (-1);
109         }
110       fp = NULL;
111     }
112   else
113     {
114 #ifdef WRITE_CHECK
115       check_backup (wf->name);
116 #endif
117       if ((fp = fopen (wf->name, "r")) == NULL)
118         {
119           wnn_errorno = WNN_FILE_READ_ERROR;
120           log_err("read_file:could not open file %s.", wf->name);
121           return (-1);
122         }
123     }
124   if (input_file_header (fp, &fh) == -1)
125     {
126       wnn_errorno = WNN_NOT_A_FILE;
127       goto ERROR_RET;
128     }
129   bcopy ((char *) &(fh.file_uniq), (char *) &(wf->f_uniq), WNN_F_UNIQ_LEN);
130   bcopy ((char *) &(fh.file_uniq_org), (char *) &(wf->f_uniq_org), WNN_F_UNIQ_LEN);
131   strncpy (wf->passwd, fh.file_passwd, WNN_PASSWD_LEN);
132   wf->file_type = fh.file_type;
133   wf->ref_count = 0;
134 
135   switch (fh.file_type)
136     {
137     case WNN_FT_DICT_FILE:
138       wf->area = (char *) readdict (fp);
139       if (wf->area == NULL)
140         goto ERROR_RET;
141       break;
142     case WNN_FT_HINDO_FILE:
143       wf->area = (char *) readhindo (fp);
144       if (wf->area == NULL)
145         goto ERROR_RET;
146       break;
147     case WNN_FT_FUZOKUGO_FILE:
148       wf->area = (char *) fzk_read (fp);
149       if (wf->area == NULL)
150         goto ERROR_RET;
151       break;
152     }
153   vclose (fp);
154   return (0);
155 ERROR_RET:
156   vclose (fp);
157   return (-1);
158 }
159 
160 static struct JT *
readdict(FILE * fp)161 readdict (FILE *fp)
162 {
163   struct JT *jt1;
164   long x;
165 
166   jt1 = (struct JT *) malloc (sizeof (struct JT));
167   jt1->node = 0;
168   if (input_header_jt (fp, jt1) == -1)
169     {
170       wnn_errorno = WNN_NOT_A_FILE;
171       free (jt1);
172       return (NULL);
173     }
174   if (jt1->syurui == WNN_UD_DICT)
175     {
176       jt1->bufsize_serial = (jt1->maxserial + MAXSERIAL);
177       jt1->bufsize_kanji = (jt1->maxkanji + MAXKANJI);
178       jt1->bufsize_hontai = (jt1->maxhontai + MAXHONTAI);
179       jt1->bufsize_table = (jt1->maxtable + MAXTABLE);
180       jt1->bufsize_ri1[D_YOMI] = 0;
181       jt1->bufsize_ri1[D_KANJI] = 0;
182 #if     defined(CONVERT_by_STROKE) || defined(CONVERT_with_SiSheng)
183     }
184   else if ((jt1->syurui & 0xff) == WNN_REV_DICT)
185     {
186 #else
187     }
188   else if (jt1->syurui == WNN_REV_DICT)
189     {
190 #endif /* CONVERT_by_STROKE || CONVERT_with_SiSheng */
191       jt1->bufsize_serial = (jt1->maxserial + MAXSERIAL);
192       jt1->bufsize_kanji = (jt1->maxkanji + MAXKANJI);
193       jt1->bufsize_hontai = (jt1->maxhontai + MAXHONTAI);
194       jt1->bufsize_table = 0;
195       jt1->bufsize_ri1[D_YOMI] = (jt1->maxri1[D_YOMI] + MAXTABLE);
196       jt1->bufsize_ri1[D_KANJI] = (jt1->maxri1[D_KANJI] + MAXTABLE);
197     }
198   else if (jt1->syurui == WNN_STATIC_DICT)
199     {                           /* WNN_STATIC_DICT */
200       jt1->bufsize_serial = jt1->maxserial;
201       jt1->bufsize_kanji = jt1->maxkanji;
202       jt1->bufsize_hontai = jt1->maxhontai;
203       jt1->bufsize_table = 0;
204       jt1->bufsize_ri1[D_YOMI] = 0;
205       jt1->bufsize_ri1[D_KANJI] = 0;
206     }
207   else
208     {
209       wnn_errorno = WNN_NOT_A_DICT;
210       log_err ("not a correct dictionary.");
211       free (jt1);
212       return (NULL);
213     }
214   if (alloc_dict (jt1) == -1)
215     {
216       free (jt1);
217       return (NULL);
218     }
219   if (vfread (jt1->comment, 2, jt1->maxcomment, fp) != jt1->maxcomment)
220     {
221       wnn_errorno = WNN_NOT_A_DICT;
222       log_err ("not a correct dictionary.");
223       goto error;
224     }
225 
226   if (vfread (jt1->hinsi_list, 2, jt1->maxhinsi_list, fp) != jt1->maxhinsi_list)
227     {
228       wnn_errorno = WNN_NOT_A_DICT;
229       log_err ("not a correct dictionary.");
230       goto error;
231     }
232 
233   if (vfread (jt1->hindo, 1, jt1->maxserial, fp) != jt1->maxserial)
234     {
235       wnn_errorno = WNN_NOT_A_DICT;
236       log_err ("not a correct dictionary.");
237       goto error;
238     }
239   if (vfread (jt1->hinsi, 2, jt1->maxserial, fp) != jt1->maxserial)
240     {
241       wnn_errorno = WNN_NOT_A_DICT;
242       log_err ("not a correct dictionary.");
243       goto error;
244     }
245 #ifdef  CONVERT_with_SiSheng
246   if (jt1->syurui == CWNN_REV_DICT)
247     if (vfread (jt1->sisheng, 2, jt1->maxserial, fp) != jt1->maxserial)
248       {
249         wnn_errorno = WNN_NOT_A_DICT;
250         log_err ("not a correct dictionary.");
251         goto error;
252       }
253 #endif /* CONVERT_with_SiSheng */
254   if (vfread (jt1->kanji, 1, jt1->maxkanji, fp) != jt1->maxkanji)
255     {
256       wnn_errorno = WNN_NOT_A_DICT;
257       log_err ("not a correct dictionary.");
258       goto error;
259     }
260   if (vfread (jt1->table, sizeof (struct uind1), jt1->maxtable, fp) != jt1->maxtable)
261     {
262       wnn_errorno = WNN_NOT_A_DICT;
263       log_err ("not a correct dictionary.");
264       goto error;
265     }
266   if (vfread (jt1->ri1[D_YOMI], sizeof (struct rind1), jt1->maxri1[D_YOMI], fp) != jt1->maxri1[D_YOMI])
267     {
268       wnn_errorno = WNN_NOT_A_DICT;
269       log_err ("not a correct dictionary.");
270       goto error;
271     }
272   if (vfread (jt1->ri1[D_KANJI], sizeof (struct rind1), jt1->maxri1[D_KANJI], fp) != jt1->maxri1[D_KANJI])
273     {
274       wnn_errorno = WNN_NOT_A_DICT;
275       log_err ("not a correct dictionary.");
276       goto error;
277     }
278   if (vfread (jt1->hontai, 1, jt1->maxhontai, fp) != jt1->maxhontai)
279     {
280       wnn_errorno = WNN_NOT_A_DICT;
281       log_err ("not a correct dictionary.");
282       goto error;
283     }
284   if (vfread (jt1->ri2, sizeof (struct rind2), jt1->maxri2, fp) != jt1->maxri2)
285     {
286       wnn_errorno = WNN_NOT_A_DICT;
287       log_err ("not a correct dictionary.");
288       goto error;
289     }
290 
291   if (fp != NULL)
292     {
293       x = ftell (fp);
294       fseek (fp, 0, 2);
295       if (x != ftell (fp))
296         {
297           wnn_errorno = WNN_NOT_A_DICT;
298 	  log_err ("not a correct dictionary.");
299           goto error;
300         }
301     }
302 
303   make_hinsi_list (jt1);
304 
305   if (jt1->maxhontai == 0 && (jt1->syurui == WNN_UD_DICT || jt1->syurui == WNN_STATIC_DICT))
306     {
307       jt1->maxhontai = 4;
308     }
309   if (little_endian ())
310     {
311       revdic (jt1, 0);
312     }
313   jt1->dirty = 0;
314   jt1->hdirty = 0;
315 #ifdef  CONVERT_by_STROKE
316   if (jt1->syurui == BWNN_REV_DICT)
317     if ((jt1->max_bnode = create_b_index (jt1)) == -1)
318       {
319         goto error;
320       }
321 #endif /* CONVERT_by_STROKE */
322   return (jt1);
323 error:
324   jt1 = free_dict (jt1);
325   return (NULL);
326 }
327 
328 /*
329  * user_jisho_realloc: �桼��������˸����Ͽ���᤮�ư��դˤʤä���realloc����
330  *   return value: success:SUCCESS (non zero), failure:NULL
331  */
332 int
ud_realloc_hontai(struct JT * jt)333 ud_realloc_hontai (struct JT *jt)
334 {
335   size_t new_bufsize;
336   UCHAR *tp;
337 
338   log_debug ("hontai realloc occured.");
339   new_bufsize = jt->maxhontai + MAXHONTAI;
340   if ((tp = (UCHAR *) realloc (jt->hontai, new_bufsize)) == NULL)
341     {
342       wnn_errorno = WNN_MALLOC_ERR;
343       log_err ("could not make the jisho area bigger.");
344       return (NULL);
345     }
346   jt->bufsize_hontai = new_bufsize;
347   jt->hontai = tp;
348   return (SUCCESS);
349 }
350 
351 int
ud_realloc_kanji(struct JT * jt)352 ud_realloc_kanji (struct JT *jt)          /* Also for rd */
353 {
354   size_t new_bufsize;
355   UCHAR *tp;
356 
357   log_debug ("kanji realloc occured.");
358   new_bufsize = jt->maxkanji + MAXKANJI;
359   if ((tp = (UCHAR *) realloc (jt->kanji, new_bufsize)) == NULL)
360     {
361       wnn_errorno = WNN_MALLOC_ERR;
362       log_err ("could not make the jisho area bigger.");
363       return (NULL);
364     }
365   jt->bufsize_kanji = new_bufsize;
366   jt->kanji = tp;
367   return (SUCCESS);
368 }
369 
370 int
ud_realloc_serial(struct JT * jt)371 ud_realloc_serial (struct JT *jt)         /* Also for rd */
372 {
373   size_t new_bufsize;
374   UCHAR *tp_hindo;
375   unsigned short *tp_hinsi;
376 #ifdef  CONVERT_with_SiSheng
377   unsigned short *tp_sisheng;
378 #endif
379   struct rind2 *tp_ri2;
380 
381   log_debug ("serial realloc occured.");
382   new_bufsize = jt->maxserial + MAXSERIAL;
383 
384   tp_hindo = (UCHAR *) realloc (jt->hindo, new_bufsize * sizeof (*jt->hindo));
385   tp_hinsi = (unsigned short *) realloc (jt->hinsi, new_bufsize * sizeof (*jt->hinsi));
386 
387 #ifdef  CONVERT_with_SiSheng
388   tp_sisheng = (unsigned short *) realloc (jt->sisheng,
389 					   new_bufsize * sizeof (*jt->sisheng));
390 #endif /* CONVERT_with_SiSheng */
391 
392   if (tp_hindo == NULL || tp_hinsi == NULL
393 #ifdef  CONVERT_with_SiSheng
394      || tp_sisheng == NULL
395 #endif /* CONVERT_with_SiSheng */
396     )
397     {
398       free (tp_hindo);
399       free (tp_hinsi);
400 #ifdef  CONVERT_with_SiSheng
401       free (tp_sisheng);
402 #endif /* CONVERT_with_SiSheng */
403 
404       wnn_errorno = WNN_MALLOC_ERR;
405       log_err ("could notmake the jisho area bigger.");
406       return (NULL);
407     }
408   jt->bufsize_serial = new_bufsize;
409   jt->hindo = tp_hindo;
410   jt->hinsi = tp_hinsi;
411 #ifdef  CONVERT_with_SiSheng
412   jt->sisheng = tp_sisheng;
413 #endif /* CONVERT_with_SiSheng */
414 
415 
416 #if defined(CONVERT_by_STROKE) || defined(CONVERT_with_SiSheng)
417   if ((jt->syurui & 0xff) == WNN_REV_DICT)
418 #else
419   if (jt->syurui == WNN_REV_DICT)
420 #endif /* CONVERT_by_STROKE || CONVERT_with_SiSheng */
421     {
422       tp_ri2 = (struct rind2 *) realloc (jt->ri2,
423 					 new_bufsize * sizeof (struct rind2));
424       if (tp_ri2 == NULL)
425         {
426           wnn_errorno = WNN_MALLOC_ERR;
427           log_err ("could not make the jisho area bigger.");
428           return (NULL);
429         }
430       jt->ri2 = tp_ri2;
431     }
432 
433   return (SUCCESS);
434 }
435 
436 int
ud_realloc_table(struct JT * jt)437 ud_realloc_table (struct JT *jt)
438 {
439   size_t new_bufsize;
440   struct uind1 *tp;
441 
442   log_debug ("table realloc occured.");
443   new_bufsize = jt->maxtable + MAXTABLE;
444   tp = (struct uind1 *) realloc (jt->table, new_bufsize * sizeof (struct uind1));
445   if (tp == NULL)
446     {
447       wnn_errorno = WNN_MALLOC_ERR;
448       log_err ("could not make the jisho area bigger.");
449       return (NULL);
450     }
451   jt->bufsize_table = new_bufsize;
452   jt->table = tp;
453   return (SUCCESS);
454 }
455 
456 int
rd_realloc_ri1(struct JT * jt,int which)457 rd_realloc_ri1 (struct JT *jt, int which)
458 {
459   size_t new_bufsize;
460   struct rind1 *tp;
461 
462   log_debug ("ri1 reallocation occured.");
463   new_bufsize = jt->maxri1[which] + MAXTABLE;
464   tp = (struct rind1 *) realloc (jt->ri1[which],
465 				 new_bufsize * sizeof (struct rind1));
466   if (tp == NULL)
467     {
468       wnn_errorno = WNN_MALLOC_ERR;
469       log_err ("could not make the jisho area bigger.");
470       return (NULL);
471     }
472   jt->bufsize_ri1[which] = new_bufsize;
473   jt->ri1[which] = tp;
474   return (SUCCESS);
475 }
476 
477 
478 int
hindo_file_realloc(struct HJT * hjt)479 hindo_file_realloc (struct HJT *hjt)
480 {
481   size_t new_bufsize;
482   UCHAR *tp;
483 
484   log_debug ("hindo file reallocation occured.");
485   new_bufsize = hjt->maxserial + MAXSERIAL;
486   tp = (UCHAR *) realloc (hjt->hindo, new_bufsize * sizeof (*hjt->hindo));
487   if (tp == NULL)
488     {
489       wnn_errorno = WNN_MALLOC_ERR;
490       log_err ("could not make the hindo file area bigger.");
491       return (NULL);
492     }
493   hjt->bufsize_serial = new_bufsize;
494   hjt->hindo = tp;
495   return (SUCCESS);
496 }
497 
498 #ifdef CONVERT_by_STROKE
499 int
rd_realloc_bind(struct JT * jt)500 rd_realloc_bind (struct JT *jt)
501 {
502   size_t new_bufsize;
503   struct b_node *tp;
504 
505   log_debug ("jt->bind reallocation occured.");
506   new_bufsize = jt->bufsize_bnode + MAXBIND;
507   tp = (struct b_node *) realloc (jt->bind, new_bufsize * sizeof (struct b_node));
508   if (tp == NULL)
509     {
510       wnn_errorno = WNN_MALLOC_ERR;
511       log_err ("could not make the jisho area bigger.");
512       return (NULL);
513     }
514   jt->bufsize_bnode = new_bufsize;
515   jt->bind = tp;
516   return (SUCCESS);
517 }
518 #endif /* CONVERT_by_STROKE */
519 
520 static struct JT *
copy_dict(struct JT * jt1)521 copy_dict (struct JT *jt1)
522 {
523   struct JT *jt2;
524 
525   jt2 = (struct JT *) malloc (sizeof (struct JT));
526   *jt2 = *jt1;
527 
528   if (alloc_dict (jt2) == -1)
529     {
530       free (jt2);
531       return (NULL);
532     }
533   bcopy (jt1->hindo, jt2->hindo, jt1->maxserial);
534   bcopy (jt1->hinsi, jt2->hinsi, jt1->maxserial * 2);
535 #ifdef  CONVERT_with_SiSheng
536   if (jt1->syurui == CWNN_REV_DICT)     /* Chinese PinYin dic only  */
537     bcopy (jt1->sisheng, jt2->sisheng, jt1->maxserial * 2);
538 #endif /* CONVERT_with_SiSheng */
539   bcopy (jt1->kanji, jt2->kanji, jt1->maxkanji);
540   bcopy (jt1->table, jt2->table, jt1->maxtable * sizeof (struct uind1));
541   bcopy (jt1->hontai, jt2->hontai, jt1->maxhontai);
542   bcopy (jt1->comment, jt2->comment, jt1->maxcomment * sizeof (w_char));
543   bcopy (jt1->hinsi_list, jt2->hinsi_list, jt1->maxhinsi_list * sizeof (w_char));
544   bcopy (jt1->ri2, jt2->ri2, jt1->maxri2 * sizeof (struct rind2));
545   bcopy (jt1->ri1[D_YOMI], jt2->ri1[D_YOMI], jt1->maxri1[D_YOMI] * sizeof (struct rind1));
546   bcopy (jt1->ri1[D_KANJI], jt2->ri1[D_KANJI], jt1->maxri1[D_KANJI] * sizeof (struct rind1));
547   return (jt2);
548 }
549 
550 
551 int
must_write_file(struct wnn_file * wf,struct wnn_file_uniq * uniq)552 must_write_file (struct wnn_file *wf, struct wnn_file_uniq *uniq)
553 {
554   if (f_uniq_cmp (&(wf->f_uniq), uniq))
555     return (3);
556   /* The File to write is not read. */
557   switch (wf->file_type)
558     {
559     case WNN_FT_DICT_FILE:
560       {
561         struct JT *jt = (struct JT *) wf->area;
562         if (jt->dirty)
563           return 1;
564         if (jt->hdirty)
565           return 2;
566         return 0;
567       }
568     case WNN_FT_HINDO_FILE:
569       {
570         struct HJT *hjt = (struct HJT *) wf->area;
571         if (!(hjt->hdirty))
572           return (0);
573         else
574           return 1;
575       }
576     case WNN_FT_FUZOKUGO_FILE:
577       wnn_errorno = NOT_SUPPORTED_OPERATION;
578       return (-1);
579     }
580   return (-1);
581 }
582 
583 void
clear_dirty_bit(struct wnn_file * wf)584 clear_dirty_bit (struct wnn_file *wf)
585 {
586   switch (wf->file_type)
587     {
588     case WNN_FT_DICT_FILE:
589       {
590         struct JT *jt = (struct JT *) wf->area;
591         jt->dirty = 0;
592         jt->hdirty = 0;
593       }
594       break;
595     case WNN_FT_HINDO_FILE:
596       {
597         struct HJT *hjt = (struct HJT *) wf->area;
598         hjt->hdirty = 0;
599       }
600       break;
601     case WNN_FT_FUZOKUGO_FILE:
602       break;
603     }
604 }
605 
606 
607 int
rcv_file(struct wnn_file * wf,int mode)608 rcv_file (struct wnn_file *wf, int mode)
609 {
610   FILE *fp;
611   int x;
612 
613 /*    if(wf->localf == REMOTE){
614       }
615 */
616   if (fopen_write_cur (wf->name) == NULL)
617     {
618       log_err ("receive_file:No file %s.", wf->name);
619       wnn_errorno = WNN_FILE_WRITE_ERROR;
620       return (-1);
621     }
622   fp = NULL;
623   x = write_file_real (wf, fp, mode);
624   vclose (fp);
625   return (x);
626 }
627 
628 int
write_file(struct wnn_file * wf,char * n)629 write_file (struct wnn_file *wf, char *n)
630 {
631   FILE *fp;
632   int mode = 3;
633   struct wnn_file_head fh;
634 #ifdef WRITE_CHECK
635   char *tmp = NULL, *backup = NULL;
636 
637   check_backup (n);
638 #endif
639   if ((fp = fopen (n, "r")) != NULL)
640     {                           /* Old File Exist */
641       if (input_file_header (fp, &fh) == -1)
642         {
643           wnn_errorno = WNN_NOT_A_FILE;
644           fclose (fp);
645           return (-1);
646         }
647       mode = must_write_file (wf, &(fh.file_uniq));
648       fclose (fp);
649       if (mode == -1)
650         return -1;
651     }
652 
653   if (mode == 0)
654     {
655       return (0);               /* Need Not Write */
656     }
657   else if (mode == 1 || mode == 3)
658     {                           /* 3 when the file is not the one to be read. */
659 #ifdef WRITE_CHECK
660       backup = make_backup_file (n);
661       if ((tmp = make_tmp_file (n, 0, &fp)) == NULL)
662         {
663           delete_tmp_file (backup);
664 #else /* WRITE_CHECK */
665       if ((fp = fopen (n, "w+")) == NULL)
666         {
667 #endif /* WRITE_CHECK */
668           wnn_errorno = WNN_FILE_WRITE_ERROR;
669           return (-1);
670         }
671     }
672   else if (mode == 2)
673     {
674 #ifdef WRITE_CHECK
675       backup = make_backup_file (n);
676       if ((tmp = make_tmp_file (n, 1, &fp)) == NULL)
677         {
678           delete_tmp_file (backup);
679 #else /* WRITE_CHECK */
680       if ((fp = fopen (n, "r+")) == NULL)
681         {                       /* New File */
682 #endif /* WRITE_CHECK */
683           wnn_errorno = WNN_FILE_WRITE_ERROR;
684           return (-1);
685         }
686     }
687   if (write_file_real (wf, fp, mode) == -1)
688     {
689       fclose (fp);
690 #ifdef WRITE_CHECK
691       delete_tmp_file (tmp);
692       delete_tmp_file (backup);
693 #endif /* WRITE_CHECK */
694       return -1;
695     }
696   fclose (fp);
697 #ifdef WRITE_CHECK
698   move_tmp_to_org (tmp, n, 1);
699   delete_tmp_file (backup);
700 #endif /* WRITE_CHECK */
701   if ((mode == 1) || (mode == 2))
702     {
703       clear_dirty_bit (wf);
704     }
705   return (0);
706 }
707 
708 static int
709 write_file_real (struct wnn_file *wf,
710 		 FILE *fp,
711 		 int mode	/* 1 For All, 2 For only hindo */ )
712 {
713   struct wnn_file_head fh;
714 
715   if (fp)
716     rewind (fp);
717   bcopy ((char *) &wf->f_uniq, (char *) &(fh.file_uniq), WNN_F_UNIQ_LEN);
718   bcopy ((char *) &wf->f_uniq_org, (char *) &(fh.file_uniq_org), WNN_F_UNIQ_LEN);
719   bcopy (wf->passwd, fh.file_passwd, WNN_PASSWD_LEN);
720   fh.file_type = wf->file_type;
721 
722   if (output_file_header (fp, &fh) == -1)
723     {
724       wnn_errorno = WNN_FILE_WRITE_ERROR;
725       goto ERROR_RET;
726     }
727   switch (fh.file_type)
728     {
729     case WNN_FT_DICT_FILE:
730       {
731         struct JT *jt2;
732         struct JT *jt = (struct JT *) wf->area;
733         if (little_endian () && jt->dirty)
734           {
735             if ((jt2 = copy_dict ((struct JT *) wf->area)) == NULL)
736               goto ERROR_RET;
737             revdic (jt2, 1);
738             if (writedict (jt2, fp) == -1)
739               goto ERROR_RET;
740             jt2 = free_dict (jt2);
741           }
742         else
743           {
744 /*            if(writedict(wf->area, fp) == -1)goto ERROR_RET; */
745             if (mode == 2)
746               {
747                 if (write_hindo_of_dict (wf->area, fp) == -1)
748                   goto ERROR_RET;
749               }
750             else
751               {
752                 if (writedict (wf->area, fp) == -1)
753                   goto ERROR_RET;
754               }
755           }
756       }
757       break;
758     case WNN_FT_HINDO_FILE:
759       if (writehindo (wf->area, fp) == -1)
760         goto ERROR_RET;
761       break;
762     case WNN_FT_FUZOKUGO_FILE:
763       wnn_errorno = NOT_SUPPORTED_OPERATION;
764       goto ERROR_RET;
765     }
766   return (0);
767 ERROR_RET:
768   return (-1);
769 }
770 
771 static int
772 writedict (struct JT *jt1, FILE *fp)
773 {
774 
775   if (output_header_jt (fp, jt1) == -1)
776     return (-1);
777 #ifdef WRITE_CHECK
778   if ((vfwrite (jt1->comment, 2, jt1->maxcomment, fp) == -1) ||
779       (vfwrite (jt1->hinsi_list, 2, jt1->maxhinsi_list, fp) == -1) || (vfwrite (jt1->hindo, 1, jt1->maxserial, fp) == -1) || (vfwrite (jt1->hinsi, 2, jt1->maxserial, fp) == -1))
780     return (-1);
781 #ifdef  CONVERT_with_SiSheng
782   if (jt1->syurui == CWNN_REV_DICT)     /* for Chinese PinYin dic only */
783     if (vfwrite (jt1->sisheng, 2, jt1->maxserial, fp) == -1)
784       return (-1);
785 #endif /* CONVERT_with_SiSheng */
786   if ((vfwrite (jt1->kanji, 1, jt1->maxkanji, fp) == -1) ||
787       (vfwrite (jt1->table, sizeof (struct uind1), jt1->maxtable, fp) == -1) ||
788       (vfwrite (jt1->ri1[D_YOMI], sizeof (struct rind1),
789                 jt1->maxri1[D_YOMI], fp) == -1) ||
790       (vfwrite (jt1->ri1[D_KANJI], sizeof (struct rind1),
791                 jt1->maxri1[D_KANJI], fp) == -1) || (vfwrite (jt1->hontai, 1, jt1->maxhontai, fp) == -1) || (vfwrite (jt1->ri2, sizeof (struct rind2), jt1->maxri2, fp) == -1))
792     return (-1);
793 #else /* WRITE_CHECK */
794   vfwrite (jt1->comment, 2, jt1->maxcomment, fp);
795   vfwrite (jt1->hinsi_list, 2, jt1->maxhinsi_list, fp);
796   vfwrite (jt1->hindo, 1, jt1->maxserial, fp);
797   vfwrite (jt1->hinsi, 2, jt1->maxserial, fp);
798 #ifdef  CONVERT_with_SiSheng
799   if (jt1->syurui == CWNN_REV_DICT)     /* for Chinese PinYin dic only */
800     vfwrite (jt1->sisheng, 2, jt1->maxserial, fp);
801 #endif /* CONVERT_with_SiSheng */
802   vfwrite (jt1->kanji, 1, jt1->maxkanji, fp);
803   vfwrite (jt1->table, sizeof (struct uind1), jt1->maxtable, fp);
804   vfwrite (jt1->ri1[D_YOMI], sizeof (struct rind1), jt1->maxri1[D_YOMI], fp);
805   vfwrite (jt1->ri1[D_KANJI], sizeof (struct rind1), jt1->maxri1[D_KANJI], fp);
806   vfwrite (jt1->hontai, 1, jt1->maxhontai, fp);
807   vfwrite (jt1->ri2, sizeof (struct rind2), jt1->maxri2, fp);
808 #endif /* WRITE_CHECK */
809 
810   return (0);
811 }
812 
813 static int
814 write_hindo_of_dict (struct JT *jt1, FILE *fp)
815 {
816   if (output_header_jt (fp, jt1) == -1)
817     return (-1);
818 #ifdef WRITE_CHECK
819   if ((vfwrite (jt1->comment, 2, jt1->maxcomment, fp) == -1) || (vfwrite (jt1->hindo, 1, jt1->maxserial, fp) == -1))
820     return (-1);
821 #else /* WRITE_CHECK */
822   vfwrite (jt1->comment, 2, jt1->maxcomment, fp);
823   vfwrite (jt1->hindo, 1, jt1->maxserial, fp);
824 #endif /* WRITE_CHECK */
825   return (0);
826 }
827 
828 
829 
830 int
831 discardfile (struct wnn_file *wf)
832 {
833 #ifdef nodef
834   FILE *fp;
835   if (wf->localf == LOCAL)
836     {
837       if ((fp = fopen (wf->name, "r")) == NULL)
838         {
839           log_err ("discardfile:No file %s.", wf->name);
840           return (-1);
841         }
842       fclose (fp);
843     }
844 #endif
845   switch (wf->file_type)
846     {
847     case WNN_FT_DICT_FILE:
848       wf->area = free_dict (wf->area);
849       break;
850     case WNN_FT_HINDO_FILE:
851       wf->area = free_hindo (wf->area);
852       break;
853     case WNN_FT_FUZOKUGO_FILE:
854 /*
855         fzk_discard(wf->area);
856 */
857       break;
858     }
859   return (0);
860 }
861 
862 static struct JT *
863 free_dict (struct JT *jt)
864 {
865   if (jt)
866     {
867       free (jt->hindo);
868       free (jt->hinsi);
869 #ifdef  CONVERT_with_SiSheng
870       free (jt->sisheng);
871 #endif /* CONVERT_with_SiSheng */
872       free (jt->kanji);
873       free (jt->table);
874       free (jt->hontai);
875       free (jt->comment);
876       free (jt->hinsi_list);
877       free (jt->ri1[D_YOMI]);
878       free (jt->ri1[D_KANJI]);
879       free (jt->ri2);
880       free (jt->node);
881 #ifdef  CONVERT_by_STROKE
882       free (jt->bind);
883 #endif /* CONVERT_by_STROKE */
884       free (jt);
885     }
886   return (NULL);
887 }
888 
889 
890 
891 static struct HJT *
892 readhindo (FILE *fp)
893 {
894   struct HJT *hjt1;
895 
896   hjt1 = (struct HJT *) malloc (sizeof (struct HJT));
897   if (input_header_hjt (fp, hjt1) == -1)
898     {
899       wnn_errorno = WNN_NOT_A_FILE;
900       free (hjt1);
901       return (NULL);
902     }
903 
904   hjt1->bufsize_serial = (hjt1->maxserial + MAXSERIAL);
905 
906   hjt1->hindo = (UCHAR *) NULL;
907   hjt1->comment = (w_char *) NULL;
908   if ((hjt1->hindo = (UCHAR *) malloc (hjt1->bufsize_serial)) == NULL || (hjt1->comment = (w_char *) malloc (hjt1->maxcomment * sizeof (w_char))) == NULL)
909     {
910       wnn_errorno = WNN_MALLOC_ERR;
911       free (hjt1->hindo);
912       free (hjt1->comment);
913       free (hjt1);
914       log_err ("could not allocate hindo area.");
915       return (NULL);
916     }
917 
918   if (vfread (hjt1->comment, 2, hjt1->maxcomment, fp) != hjt1->maxcomment)
919     {
920       wnn_errorno = WNN_NOT_HINDO_FILE;
921       log_err ("not a correct hindo file.");
922       goto error;
923     }
924 
925   if (vfread (hjt1->hindo, 1, hjt1->maxserial, fp) != hjt1->maxserial)
926     {
927       wnn_errorno = WNN_NOT_HINDO_FILE;
928       log_err ("not a correct hindo file.");
929       goto error;
930     }
931   hjt1->hdirty = 0;
932   return (hjt1);
933 error:
934   hjt1 = free_hindo (hjt1);
935   return (NULL);
936 }
937 
938 
939 static int
940 writehindo (struct HJT *hjt1, FILE *fp)
941 {
942   if (output_header_hjt (fp, hjt1) == -1)
943     return (-1);
944 #ifdef WRITE_CHECK
945   if (vfwrite (hjt1->hindo, 1, hjt1->maxserial, fp) == -1)
946     return (-1);
947 #else
948   vfwrite (hjt1->hindo, 1, hjt1->maxserial, fp);
949 #endif
950   return (0);
951 }
952 
953 static struct HJT *
954 free_hindo (struct HJT *hjt)
955 {
956   if (hjt)
957     {
958       free (hjt->hindo);
959       free (hjt->comment);
960       free (hjt);
961     }
962   return (NULL);
963 }
964 
965 
966 int
967 create_hindo_file1 (struct wnn_file *wf,
968 		    char *fn,
969 		    w_char *comm,
970 		    char *passwd)
971 {
972 
973   return (create_hindo_file (&(wf->f_uniq_org), fn, comm, passwd, ((struct JT *) (wf->area))->maxserial));
974 }
975 
976 int
977 match_dic_and_hindo_p (struct wnn_file *wfp, struct wnn_file *whfp)
978 {
979   struct HJT *hjtp;
980   hjtp = (struct HJT *) (whfp->area);
981   if (bcmp ((char *) &wfp->f_uniq_org, (char *) (&(hjtp->dic_file_uniq)), WNN_F_UNIQ_LEN) == 0)
982     return (1);
983   return (0);
984 }
985 
986 static int
987 alloc_dict (struct JT *jt1)
988 {
989   jt1->hindo = (UCHAR *) NULL;
990   jt1->hinsi = (unsigned short *) NULL;
991 #ifdef  CONVERT_with_SiSheng
992   jt1->sisheng = (unsigned short *) NULL;
993 #endif /* CONVERT_with_SiSheng */
994   jt1->kanji = (UCHAR *) NULL;
995   jt1->table = (struct uind1 *) NULL;
996   jt1->hontai = (UCHAR *) NULL;
997   jt1->comment = (w_char *) NULL;
998   jt1->hinsi_list = (w_char *) NULL;
999   jt1->ri1[D_YOMI] = (struct rind1 *) NULL;
1000   jt1->ri1[D_KANJI] = (struct rind1 *) NULL;
1001   jt1->ri2 = (struct rind2 *) NULL;
1002   jt1->node = (struct wnn_hinsi_node *) NULL;
1003 #ifdef  CONVERT_by_STROKE
1004   jt1->bind = (struct b_node *) NULL;
1005 #endif /* CONVERT_by_STROKE */
1006   if (((jt1->hindo = (UCHAR *) malloc (jt1->bufsize_serial)) == NULL) || ((jt1->hinsi = (unsigned short *) (malloc (jt1->bufsize_serial * sizeof (short)))) == NULL) ||
1007 #ifdef  CONVERT_with_SiSheng
1008       ((jt1->sisheng = (unsigned short *) (malloc (jt1->bufsize_serial * sizeof (short)))) == NULL) ||
1009 #endif /* CONVERT_with_SiSheng */
1010       ((jt1->kanji = (UCHAR *) malloc (jt1->bufsize_kanji)) == NULL) ||
1011       ((jt1->table = (struct uind1 *) malloc (jt1->bufsize_table * sizeof (struct uind1))) == NULL) ||
1012       ((jt1->hontai = (UCHAR *) malloc (jt1->bufsize_hontai)) == NULL) ||
1013       ((jt1->comment = (w_char *) malloc (jt1->maxcomment * sizeof (w_char))) == NULL) ||
1014       ((jt1->hinsi_list = (w_char *) malloc (jt1->maxhinsi_list * sizeof (w_char))) == NULL) ||
1015       ((jt1->ri1[D_YOMI] = (struct rind1 *) malloc (jt1->bufsize_ri1[D_YOMI] * sizeof (struct rind1))) == NULL) ||
1016       ((jt1->ri1[D_KANJI] = (struct rind1 *) malloc (jt1->bufsize_ri1[D_KANJI] * sizeof (struct rind1))) == NULL) ||
1017       ((jt1->ri2 = (struct rind2 *) malloc (jt1->bufsize_serial * sizeof (struct rind2))) == NULL))
1018     {
1019       wnn_errorno = WNN_MALLOC_ERR;
1020       free (jt1->hindo);
1021       free (jt1->hinsi);
1022 #ifdef  CONVERT_with_SiSheng
1023       free (jt1->sisheng);
1024 #endif /* CONVERT_with_SiSheng */
1025       free (jt1->kanji);
1026       free (jt1->table);
1027       free (jt1->hontai);
1028       free (jt1->comment);
1029       free (jt1->hinsi_list);
1030       free (jt1->ri1[D_YOMI]);
1031       free (jt1->ri1[D_KANJI]);
1032       free (jt1->ri2);
1033       log_err ("could not allocate jisho area.");
1034       return (-1);
1035     }
1036   return (0);
1037 }
1038 
1039 int
1040 file_comment_set (struct wnn_file *wf, w_char *com)
1041 {
1042   struct JT *jt;
1043   struct HJT *hjt;
1044   size_t new_size;
1045   w_char *tp;
1046 
1047   switch (wf->file_type)
1048     {
1049     case WNN_FT_DICT_FILE:
1050       jt = (struct JT *) wf->area;
1051       new_size = Strlen (com) + 1;
1052       if ((tp = (w_char *) realloc (jt->comment, jt->maxcomment * sizeof (w_char))) == NULL)
1053 	{
1054 	  return (NULL);
1055 	}
1056       jt->maxcomment = new_size;
1057       jt->comment = tp;
1058       Strcpy (jt->comment, com);
1059       jt->dirty = 1;
1060       break;
1061     case WNN_FT_HINDO_FILE:
1062       hjt = (struct HJT *) wf->area;
1063       new_size = Strlen (com) + 1;
1064       if ((tp = (w_char *) realloc (hjt->comment, new_size * sizeof (w_char))) == NULL)
1065 	{
1066 	  return (NULL);
1067 	}
1068       hjt->maxcomment = new_size;
1069       hjt->comment = tp;
1070       Strcpy (hjt->comment, com);
1071       hjt->hdirty = 1;
1072       break;
1073     case WNN_FT_FUZOKUGO_FILE:
1074       wnn_errorno = NOT_SUPPORTED_OPERATION;
1075       return (NULL);
1076     }
1077   return (SUCCESS);
1078 }
1079 
1080 int
1081 file_password_set (struct wnn_file *wf,
1082 		   int which,
1083 		   char *old,
1084 		   char *new)
1085 {
1086   struct JT *jt;
1087   struct HJT *hjt;
1088 
1089   if (which == 0)
1090     which = 3;
1091   if (wf->file_type == WNN_FT_FUZOKUGO_FILE)
1092     {
1093       wnn_errorno = NOT_SUPPORTED_OPERATION;
1094       return (-1);
1095     }
1096   if (which & 0x01 || wf->file_type == WNN_FT_HINDO_FILE)
1097     {
1098       if (check_and_change_pwd (wf->passwd, old, new) == -1)
1099         return (-1);
1100       if (wf->file_type == WNN_FT_DICT_FILE)
1101         {
1102           jt = (struct JT *) wf->area;
1103           jt->dirty = 1;
1104         }
1105       else
1106         {
1107           hjt = (struct HJT *) wf->area;
1108           hjt->hdirty = 1;
1109         }
1110     }
1111   if (wf->file_type == WNN_FT_DICT_FILE && (which & 0x02))
1112     {
1113       jt = (struct JT *) wf->area;
1114       if (check_and_change_pwd (jt->hpasswd, old, new) == -1)
1115         return (-1);
1116       jt->dirty = 1;
1117     }
1118   return (0);
1119 }
1120 
1121 static int
1122 check_and_change_pwd (char *pwd, char *old, char *new)
1123 {
1124   if (!check_pwd (old, pwd))
1125     {
1126       wnn_errorno = WNN_INCORRECT_PASSWD;
1127       return (-1);
1128     }
1129   new_pwd (new, pwd);
1130   return (0);
1131 }
1132