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