1 /* esecannaserver --- pseudo canna server that wraps another IME.
2 * Copyright (C) 1999-2000 Yasuhiro Take
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #define __USE_GNU
20 #define _GNU_SOURCE
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdarg.h>
26 #include <signal.h>
27 #include <unistd.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <sys/ioctl.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 #include <errno.h>
34 #include <time.h>
35
36 #define __misc_c__
37
38 #include "misc.h"
39
40 struct {
41 uchar zen[3];
42 uchar c;
43 } zen_han_table[] = {
44 {{0x81, 0x49, 0}, '!'},
45 {{0x81, 0x68, 0}, '"'},
46 {{0x81, 0x94, 0}, '#'},
47 {{0x81, 0x90, 0}, '$'},
48 {{0x81, 0x93, 0}, '%'},
49 {{0x81, 0x95, 0}, '&'},
50 {{0x81, 0x66, 0}, 0x27}, /* ' */
51 {{0x81, 0x69, 0}, '('},
52 {{0x81, 0x6a, 0}, ')'},
53 {{0x81, 0x96, 0}, '*'},
54 {{0x81, 0x7b, 0}, '+'},
55 {{0x81, 0x43, 0}, ','},
56 {{0x81, 0x7c, 0}, '-'},
57 {{0x81, 0x44, 0}, '.'},
58 {{0x81, 0x5e, 0}, '/'},
59 {{0x81, 0x46, 0}, ':'},
60 {{0x81, 0x47, 0}, ';'},
61 {{0x81, 0x83, 0}, '<'},
62 {{0x81, 0x81, 0}, '='},
63 {{0x81, 0x84, 0}, '!'},
64 {{0x81, 0x48, 0}, '?'},
65 {{0x81, 0x97, 0}, '@'},
66 {{0x81, 0x6b, 0}, '['},
67 {{0x81, 0x8f, 0}, '\\'},
68 {{0x81, 0x6e, 0}, ']'},
69 {{0x81, 0x4f, 0}, '^'},
70 {{0x81, 0x51, 0}, '_'},
71 {{0x81, 0x4d, 0}, '`'},
72 {{0x81, 0x6f, 0}, '{'},
73 {{0x81, 0x62, 0}, '|'},
74 {{0x81, 0x70, 0}, '}'},
75 {{0x81, 0x60, 0}, '~'},
76 {{0x81, 0x50, 0}, '~'},
77 {{0x81, 0x42, 0}, 0xa1}, /*��*/
78 {{0x81, 0x75, 0}, 0xa2}, /*��*/
79 {{0x81, 0x76, 0}, 0xa3}, /*��*/
80 {{0x81, 0x41, 0}, 0xa4}, /*��*/
81 {{0x81, 0x45, 0}, 0xa5}, /*��*/
82 {{0x81, 0x5b, 0}, 0xb0}, /*��*/
83 {{0x81, 0x4a, 0}, 0xde}, /*��*/
84 {{0x81, 0x4b, 0}, 0xdf}, /*��*/
85 {{ 0, 0, 0}, 0}
86 };
87
88 #define MOD_TEN 0x01 /* �� �������褿���,����(�� + ��= ��)���뤫 */
89 #define MOD_MARU 0x02 /* �� �������褿���,�������뤫 */
90 #define MOD_TM 0x03 /* �ϹԤ�, �� �� �� ξ�������դ��� */
91
92 /*
93 MOD_xxx �ϡ�ñ�ʤ�ե饰�Ȥ��Ƥ����Ϥʤ���
94 ʸ�����¤Ӥϡ��֤Ƥ�Ƥ�ʤ��ס֤Ƥ�Ƥ�ס֤ޤ뤢��פν硣
95 ���ʤ�����֥�������...�� �֥ϥХѥҥӥ�...�פΤ褦���¤֡�
96 ��äơ��㤨�� �֥��פ�, MOD_TEN �����С��֥��פˤʤ�Τ���
97 */
98
99
100 struct {
101 uchar han_start, han_end; /* 0xa1 - 0xdf */
102 uchar modifiers:4, /* MOD_xxx �� OR */
103 offset:4; /* ���Х��Ȥ��Ȥ˸���뤫 */
104 uchar zenkaku2_start; /* euc �Σ��Х����� */
105 } kana_table[] = {
106 {0xa6, 0xa6, 0, 0, 0xf2}, /* �� */
107 {0xa7, 0xab, 0, 2, 0xa1}, /* �� - �� */
108 {0xac, 0xae, 0, 2, 0xe3}, /* �� - �� */
109 {0xaf, 0xaf, 0, 0, 0xc3}, /* �� */
110 {0xb1, 0xb5, 0, 2, 0xa2}, /* �� - �� */
111 {0xb3, 0xb3, MOD_TEN, 0, 0xf3}, /* �� */
112 {0xb6, 0xba, MOD_TEN, 2, 0xab}, /* �� - �� �� - �� */
113 {0xbb, 0xbf, MOD_TEN, 2, 0xb5}, /* �� - �� �� �� �� */
114 {0xc0, 0xc1, MOD_TEN, 2, 0xbf}, /* �� - �� �� �� �� */
115 {0xc2, 0xc2, MOD_TEN, 0, 0xc4}, /* �� �� */
116 {0xc3, 0xc4, MOD_TEN, 2, 0xc6}, /* �� - �� �� - �� */
117 {0xc5, 0xc9, 0, 1, 0xca}, /* �� �� �� */
118 {0xca, 0xce, MOD_TM, 3, 0xcf}, /* �� �� �� �� - �� �� �� �� */
119 {0xcf, 0xd3, 0, 1, 0xde}, /* �� - �� */
120 {0xd4, 0xd6, 0, 2, 0xe4}, /* �� - �� */
121 {0xd7, 0xdb, 0, 1, 0xe9}, /* �� - �� */
122 {0xdc, 0xdc, 0, 0, 0xef}, /* �� */
123 {0xdd, 0xdd, 0, 0, 0xf3}, /* �� */
124 { 0, 0, 0, 0, 0}
125 };
126
127 /*
128 * Daemonize. from iMultiMouse...
129 */
130
131 static pid_t child;
132 static char *pid_file_path;
133
m_quit_parent()134 static void m_quit_parent()
135 {
136 FILE *fp;
137
138 if (pid_file_path != NULL && (fp = fopen(pid_file_path, "w")) != NULL) {
139 fprintf(fp, "%d\n", child);
140 fclose(fp);
141 }
142
143 exit(0);
144 }
145
m_daemonize(char * pid_path)146 int m_daemonize(char *pid_path)
147 {
148 pid_t parent;
149 int fd;
150
151 pid_file_path = pid_path;
152
153 parent = getpid();
154
155 close(fileno(stdin));
156 close(fileno(stdout));
157
158 if ((child = fork()) == -1) {
159 perror("");
160 return(EOF);
161 }
162
163 if (child)
164 m_quit_parent();
165
166 signal(SIGHUP, SIG_IGN);
167
168 setsid();
169
170 close(fileno(stderr));
171
172 if ((fd = open("/dev/null", 2)) >= 0) {
173 if (fd != 0)
174 dup2(fd, 0);
175 if (fd != 1)
176 dup2(fd, 1);
177 if (fd != 2)
178 dup2(fd, 2);
179 if (fd != 0 && fd != 1 && fd != 2)
180 close(fd);
181 }
182
183 chdir("/");
184
185 return(0);
186 }
187
188 /*
189 * m_message ... derived from Report* function, written by Morita Akio.
190 */
191
192 static FILE *logfp = NULL;
193 static ino_t loginode = 0;
194 static char *logfile;
195
m_message_log_open()196 static int m_message_log_open()
197 {
198 struct stat st;
199
200 if (logfile) {
201 if ((logfp = fopen(logfile, "a")) != NULL) {
202 if (fstat(fileno(logfp), &st) == 0) {
203 loginode = st.st_ino;
204
205 return 0;
206 }
207
208 loginode = 0;
209
210 fclose(logfp);
211 }
212
213 free(logfile);
214 logfile = NULL;
215 }
216
217 logfp = stderr;
218
219 m_msg_dbg("Logging to file failed.\n");
220
221 return -1;
222 }
223
m_message_log_close()224 static int m_message_log_close()
225 {
226 if (logfp != NULL && logfp != stderr) {
227 fclose(logfp);
228 logfp = stderr;
229 }
230
231 return 0;
232 }
233
m_message_log_check()234 static int m_message_log_check()
235 {
236 struct stat st;
237 static char recall_flag;
238
239 if (recall_flag)
240 return 0;
241
242 recall_flag = 1;
243
244 if (loginode) {
245 if (stat(logfile, &st) < 0 || st.st_ino != loginode) {
246 m_msg("Logfile rotated. Try to reopen...\n");
247
248 m_message_log_close();
249 if (m_message_log_open() == 0)
250 m_msg("Reopening logfile succeeded.\n");
251 else
252 m_msg("Reopening logfile failed.\n");
253 }
254 }
255
256 recall_flag = 0;
257
258 return 0;
259 }
260
m_message_init(char * logfilepath)261 int m_message_init(char *logfilepath)
262 {
263 if (logfilepath) {
264 logfile = strdup(logfilepath);
265
266 m_message_log_open();
267 } else
268 logfp = stderr;
269
270 return 0;
271 }
272
m_message_term()273 int m_message_term()
274 {
275 m_message_log_close();
276
277 return 0;
278 }
279
m_message_output(int level,const char * msg)280 int m_message_output(int level, const char *msg)
281 {
282 time_t tm;
283 char *timebuf, buf[26];
284
285 if (logfp && level == MSG_NOTICE) {
286 m_message_log_check();
287
288 tm = time(0);
289 timebuf = ctime(&tm);
290 memcpy(buf, &timebuf[4], 16);
291 buf[15] = 0;
292
293 fprintf(logfp, "%s: %s", buf, msg);
294 fflush(logfp);
295 } else {
296 fprintf(stderr, "%s", msg);
297 fflush(stderr);
298 }
299
300 return 0;
301 }
302
m_message_debug(const char * fmt,...)303 int m_message_debug(const char *fmt, ...)
304 {
305 #if HAVE_VASPRINTF
306 char *formated;
307 #else
308 char formated[1024]; /* FIXME:too ad-hoc!! */
309 #endif
310 va_list ap;
311
312 va_start(ap, fmt);
313 #if HAVE_VASPRINTF
314 vasprintf(&formated, fmt, ap);
315 #else
316 #if HAVE_VSNPRINTF
317 vsnprintf(formated, 1024, fmt, ap);
318 #else
319 vsprintf(formated, fmt, ap);
320 #endif
321 #endif
322 va_end(ap);
323
324 if (formated != NULL) {
325 m_message_output(MSG_DEBUG, formated);
326 #if HAVE_VASPRINTF
327 free((void *)formated);
328 #endif
329 return 0;
330 } else {
331 m_message_output(MSG_DEBUG, "out of memory!\n");
332 return -1;
333 }
334 }
335
m_message_notice(const char * fmt,...)336 int m_message_notice(const char *fmt, ...)
337 {
338 #if HAVE_VASPRINTF
339 char *formated;
340 #else
341 char formated[1024];
342 #endif
343 va_list ap;
344
345 va_start(ap, fmt);
346 #if HAVE_VASPRINTF
347 vasprintf(&formated, fmt, ap);
348 #else
349 #if HAVE_VSNPRINTF
350 vsnprintf(formated, 1024, fmt, ap);
351 #else
352 vsprintf(formated, fmt, ap);
353 #endif
354 #endif
355 va_end(ap);
356
357 if (formated != NULL) {
358 m_message_output(MSG_NOTICE, formated);
359 #if HAVE_VASPRINTF
360 free((void *)formated);
361 #endif
362 return 0;
363 } else {
364 m_message_output(MSG_NOTICE, "out of memory!\n");
365 return -1;
366 }
367 }
368
369 /*
370 * buffer_
371 */
372
buffer_free(buffer_t * b)373 int buffer_free(buffer_t *b)
374 {
375 if (b->buf && b->size)
376 free(b->buf);
377
378 b->buf = NULL;
379 b->size = 0;
380
381 return 0;
382 }
383
buffer_check(buffer_t * b,size_t required_size)384 int buffer_check(buffer_t *b, size_t required_size)
385 {
386 char *buf;
387 size_t size;
388
389 #ifdef DEBUG /* for Memory Allocate Stress Test */
390 size = required_size;
391 if (size > 0) {
392 if ((buf = malloc(size)) != NULL) {
393 memset(buf, 0, size);
394 if (b->size > 0) {
395 if (size > b->size) {
396 memcpy(buf, b->buf, b->size); /* Copy Buffer */
397 } else {
398 memcpy(buf, b->buf, size); /* Copy Buffer */
399 }
400 memset(b->buf, 0, b->size); /* Clear Old Buffer */
401 free(b->buf); /* Free Old Buffer */
402 }
403
404 /*
405 m_message_debug("Buffer Rellocate Request %d (%d -> %d reallcated)",
406 equired_size, b->size, size);
407 */
408
409 b->buf = buf;
410 b->size = size;
411
412 return 0;
413 } else {
414 return -1;
415 }
416 } else {
417 memset(b->buf, 0, b->size); /* Clear Old Buffer */
418 free(b->buf); /* Free Old Buffer */
419 b->size = 0;
420
421 /*
422 m_message_debug("Buffer Rellocate Request %d (%d -> %d reallcated)",
423 required_size, b->size, size);
424 */
425 return 0;
426 }
427 #else
428 if (required_size > b->size) {
429 size = ((required_size + 127) / 128) * 128;
430 if ((buf = realloc(b->buf, size)) != NULL) {
431 if (b->size == 0)
432 memset(buf, 0, size);
433
434 /*
435 m_message_debug("Buffer Rellocate Request %d (%d -> %d reallcated)",
436 required_size, b->size, size);
437 */
438
439 b->buf = buf;
440 b->size = size;
441
442 return 0;
443 } else {
444 return -1;
445 }
446 }
447 #endif
448 return 0;
449 }
450
buffer_clear(buffer_t * b)451 int buffer_clear(buffer_t *b)
452 {
453 if (b->buf)
454 memset(b->buf, 0, b->size);
455 return 0;
456 }
457
458 /* m_conf1_parse() : ����ե�����Τ����Ԥ���Ϥ���
459 * ʸˡ : OpeCode=String
460 * ������ : 0..Success -1..Error
461 * - line ... �ե�����ιԡ���¸����ʤ���
462 * - ope_r ... OpeCode ��ʸ������֤�
463 * - val_r ... String ��ʸ������֤�
464 */
465
m_conf1_parse(char * line,char ** ope_r,char ** val_r)466 int m_conf1_parse(char *line, char **ope_r, char **val_r)
467 {
468 char *p;
469
470 if ((p = strchr(line, '\n')) != NULL)
471 *p = '\0';
472 if ((p = strchr(line, '=')) != NULL) {
473 *p = '\0';
474 *val_r = p + 1;
475 *ope_r = line;
476
477 return 0;
478 }
479
480 return -1;
481 }
482
m_conf_string(char * ope,char * opestr,char * val,char ** val_r)483 int m_conf_string(char *ope, char *opestr, char *val, char **val_r)
484 {
485 if (strcmp(ope, opestr) == 0) {
486 if (*val_r)
487 free(*val_r);
488
489 if (val[0])
490 *val_r = strdup(val);
491 else
492 *val_r = NULL;
493
494 return 1;
495 }
496
497 return 0;
498 }
499
m_conf_multiple_choice(char * ope,char * opestr,char * val,char ** choice,int choice_n,int case_sensitive)500 int m_conf_multiple_choice(char *ope, char *opestr, char *val, char **choice,
501 int choice_n, int case_sensitive)
502 {
503 int i;
504 int (*compare)(const char *, const char *);
505
506 compare = (case_sensitive) ? strcmp : strcasecmp;
507
508 if (strcmp(ope, opestr) == 0) {
509 for (i = 0; i < choice_n; i++) {
510 if (compare(val, choice[i]) == 0)
511 return i + 1;
512 }
513 }
514
515 return 0;
516 }
517
m_conf_tof(char * ope,char * opestr,char * val,char * str1,char * str2,int case_sensitive)518 int m_conf_tof(char *ope, char *opestr, char *val, char *str1, char *str2,
519 int case_sensitive)
520 {
521 char *choice[2];
522
523 choice[0] = str1;
524 choice[1] = str2;
525
526 return m_conf_multiple_choice(ope, opestr, val, choice, 2, case_sensitive);
527 }
528
m_conf_isequal(char * ope,char * opestr,char * val,char * valstr)529 int m_conf_isequal(char *ope, char *opestr, char *val, char *valstr)
530 {
531 if (strcmp(ope, opestr) == 0) {
532 if (strcmp(val, valstr) == 0)
533 return 2;
534 else
535 return 1;
536 }
537
538 return 0;
539 }
540
541 /*
542 * m_memdup()
543 */
544
m_memdup(void * src,size_t n)545 void *m_memdup(void *src, size_t n)
546 {
547 char *dst;
548
549 dst = malloc(n);
550 memcpy(dst, src, n);
551
552 return (void *)dst;
553 }
554
555
556 /*
557 * m_makepath m_splitpath
558 */
559
m_makepath(char * dir,char * file)560 char *m_makepath(char *dir, char *file)
561 {
562 int dirlen, filelen;
563 char *path;
564
565 dirlen = strlen(dir);
566 filelen = strlen(file);
567
568 path = malloc(dirlen + 1 + filelen + 1);
569
570 if (path) {
571 strcpy(path, dir);
572
573 if (dirlen > 0 && dir[dirlen - 1] != '/')
574 strcat(path, "/");
575
576 strcat(path, file);
577 }
578
579 return path;
580 }
581
m_splitpath(char * path,char ** dir,char ** file)582 int m_splitpath(char *path, char **dir, char **file)
583 {
584 char *lastslash, *buf;
585
586 buf = strdup(path);
587 lastslash = strrchr(buf, '/');
588
589 if (dir != NULL) {
590 if (lastslash != NULL) {
591 *lastslash = '\0';
592
593 if ((*dir = strdup(buf)) == NULL) {
594 free(buf);
595 return -1;
596 }
597
598 lastslash++;
599 } else {
600 *dir = NULL;
601 lastslash = buf;
602 }
603 } else {
604 if (lastslash == NULL)
605 lastslash = buf;
606 }
607
608 if (file != NULL) {
609 if ((*file = strdup(lastslash)) == NULL) {
610 free(buf);
611 return -1;
612 }
613 }
614
615 free(buf);
616
617 return 0;
618 }
619
620 /*
621 * m_netaddr2ascii()
622 */
623
m_netaddr2ascii(uint netaddr,char * ascii)624 char *m_netaddr2ascii(uint netaddr, char *ascii)
625 {
626 #ifdef WORDS_BIGENDIAN
627 sprintf(ascii, "%d,%d,%d,%d",
628 (netaddr >> 24) & 0xff, (netaddr >> 16) & 0xff,
629 (netaddr >> 8) & 0xff, (netaddr) & 0xff);
630 #else
631 sprintf(ascii, "%d.%d.%d.%d",
632 (netaddr) & 0xff, (netaddr >> 8) & 0xff,
633 (netaddr >> 16) & 0xff, (netaddr >> 24) & 0xff);
634 #endif /* WORDS_BIGENDIAN */
635
636 return ascii;
637 }
638
639 /*
640 * analyze canna converting mode...
641 */
642
m_count_canna_mode(int mode)643 int m_count_canna_mode(int mode)
644 {
645 int ret = 0;
646
647 while (mode) {
648 mode = mode >> 4;
649 ret++;
650 }
651
652 return ret;
653 }
654
m_get_canna_mode(int mode,int n)655 int m_get_canna_mode(int mode, int n)
656 {
657 int ret;
658
659 ret = (mode >> (4 * n)) & 0x0f;
660
661 /* ret..1: HIRAGANA 2: HANKAKU 3: KATAKANA 4: ZENKAKU */
662
663 return ret;
664 }
665
m_count_valid_canna_mode(int mode)666 int m_count_valid_canna_mode(int mode)
667 {
668 int ret = 0;
669 int i, max, cmode;
670
671 max = m_count_canna_mode(mode);
672
673 for (i = 0; i < max; i++) {
674 cmode = m_get_canna_mode(mode, i);
675
676 if (cmode == 1 || cmode == 3)
677 ret++;
678 }
679
680 return ret;
681 }
682
683 /*
684 * convert coding system...
685 */
686
cannawc2euc(ushort * src,int srclen,char * dest,int destlen)687 int cannawc2euc(ushort *src, int srclen, char *dest, int destlen)
688 {
689 register int i, j;
690 register uchar *c;
691
692 for (i = 0, j = 0 ; i < srclen && j + 2 < destlen ; i++) {
693 c = (unsigned char *)(&src[i]);
694 switch ((c[0] | (c[1] << 8)) & 0x8080) {
695 case 0:
696 /* ASCII */
697 // dest[j++] = (char)(((unsigned)wc & 0x7f00) >> 8);
698 dest[j++] = c[1];
699 break;
700 case 0x8000:
701 /* Ⱦ�ѥ��� */
702 dest[j++] = (char)0x8e; /* SS2 */
703 // dest[j++] = (char)((((unsigned)wc & 0x7f00) >> 8) | 0x80);
704 dest[j++] = c[1] | 0x80;
705 break;
706 case 0x0080:
707 /* ���� */
708 dest[j++] = (char)0x8f;
709 // dest[j++] = (char)(((unsigned)wc & 0x7f) | 0x80);
710 // dest[j++] = (char)((((unsigned)wc & 0x7f00) >> 8) | 0x80);
711 dest[j++] = c[0] | 0x80;
712 dest[j++] = c[1] | 0x80;
713 break;
714 case 0x8080:
715 /* ���� */
716 // dest[j++] = (char)(((unsigned)wc & 0x7f) | 0x80);
717 // dest[j++] = (char)((((unsigned)wc & 0x7f00) >> 8) | 0x80);
718 dest[j++] = c[0] | 0x80;
719 dest[j++] = c[1] | 0x80;
720 break;
721 }
722 }
723 dest[j] = '\0';
724 return j;
725 }
726
euc2cannawc(char * src,int srclen,ushort * dest,int destlen)727 int euc2cannawc(char *src, int srclen, ushort *dest, int destlen)
728 {
729 register int i, j;
730 register unsigned ec;
731 uchar *c;
732
733 for (i = 0, j = 0 ; i < srclen && j + 1 < destlen ; i++) {
734 ec = (unsigned)(unsigned char)src[i];
735 c = (unsigned char *)(&dest[j++]);
736 if (ec & 0x80) {
737 switch (ec) {
738 case 0x8e: /* SS2 */
739 // dest[j++] = (ushort)((0x80 | ((unsigned)src[++i] & 0x7f)) << 8);
740 c[0] = 0;
741 c[1] = src[++i] | 0x80;
742 break;
743 case 0x8f: /* SS3 */
744 // dest[j++] = (ushort)(0x0080
745 // | ((unsigned)src[i + 1] & 0x7f)
746 // | (((unsigned)src[i + 2] & 0x7f) << 8));
747 c[0] = 0x80 | src[i + 1];
748 c[1] = src[i + 2] & 0x7f;
749
750 i += 2;
751 break;
752 default:
753 // dest[j++] = (ushort)(0x8080 | ((unsigned)src[i] & 0x7f)
754 // | (((unsigned)src[i + 1] & 0x7f) << 8));
755 c[0] = 0x80 | src[i];
756 c[1] = 0x80 | src[i + 1];
757
758 i++;
759 break;
760 }
761 }
762 else {
763 // dest[j++] = (ushort)(ec << 8);
764 c[0] = 0;
765 c[1] = ec;
766 }
767 }
768 dest[j] = 0;
769 return j;
770 }
771
cannawcstrlen(ushort * ws)772 int cannawcstrlen(ushort *ws)
773 {
774 int res = 0;
775 while (*ws++) {
776 res++;
777 }
778 return res;
779 }
780
cannawcstrdup(ushort * ws)781 ushort *cannawcstrdup(ushort *ws)
782 {
783 ushort *p;
784 int len;
785
786 len = cannawcstrlen(ws) * 2 + 2;
787
788 p = (ushort *)malloc(len);
789 memcpy(p, ws, len);
790
791 return (ushort *)p;
792 }
793
cannawcstrcat(ushort * p1,ushort * p2)794 ushort *cannawcstrcat(ushort *p1, ushort *p2)
795 {
796 uint l1, l2;
797
798 l1 = cannawcstrlen(p1);
799 l2 = cannawcstrlen(p2);
800
801 memcpy(&(p1[l1]), p2, l2);
802 p1[l1 + l2] = 0;
803
804 return p1;
805 }
806
807 /* src ��ˤ����Ĥ� key ������뤫������ */
808
cannawcnumstr(ushort * src,ushort * key)809 int cannawcnumstr(ushort *src, ushort *key)
810 {
811 int i, len1, len2, ret;
812
813 len1 = cannawcstrlen(src);
814 len2 = cannawcstrlen(key);
815 ret = 0;
816
817 for (i = 0; i <= len1 - len2;) {
818 if (memcmp(&(src[i]), key, len2 * 2) == 0) {
819 ret++;
820 i += len2;
821 } else {
822 i++;
823 }
824 }
825
826 return ret;
827 }
828
829
euc2sjis(uchar * euc,int euclen,uchar * sjis,int sjislen)830 int euc2sjis(uchar *euc, int euclen, uchar *sjis, int sjislen)
831 {
832 int euc_pnt = 0, sjis_pnt = 0;
833 uint hi, lo;
834
835 while (euc[euc_pnt] && euc_pnt < euclen && sjis_pnt < sjislen) {
836 if (euc[euc_pnt] & 0x80) {
837 if (euc[euc_pnt] == 0x8e) { /* Ⱦ�ѥ��� */
838 euc_pnt++;
839 sjis[sjis_pnt++] = euc[euc_pnt++];
840 } else { /* ����ʸ�� */
841 hi = euc[euc_pnt++] & 0x7f;
842 lo = euc[euc_pnt++] & 0x7f;
843
844 if ((hi & 1) == 0) {
845 lo += 0x5e;
846 hi--;
847 }
848
849 hi = ((hi - 0x21) >> 1) + 0x81;
850 lo += (0x40 - 0x21);
851
852 if (lo >= 0x7f)
853 lo++;
854 if (hi >= 0xa0)
855 hi += 0x40;
856
857 sjis[sjis_pnt++] = hi;
858 sjis[sjis_pnt++] = lo;
859 }
860 } else { /* ANK */
861 sjis[sjis_pnt++] = euc[euc_pnt++];
862 }
863 }
864
865 if (sjis_pnt < sjislen)
866 sjis[sjis_pnt] = '\0';
867 else
868 sjis[sjislen - 1] = '\0';
869
870 return sjis_pnt;
871 }
872
sjis2euc(uchar * sjis,int sjislen,uchar * euc,int euclen)873 int sjis2euc(uchar *sjis, int sjislen, uchar *euc, int euclen)
874 {
875 int euc_pnt = 0, sjis_pnt = 0;
876 int hi, lo;
877
878 while (sjis[sjis_pnt] && sjis_pnt < sjislen && euc_pnt < euclen) {
879 if (ISSJISKANJI1(sjis[sjis_pnt])) { /* ����ʸ�� */
880 hi = sjis[sjis_pnt++] & 0xff;
881 lo = sjis[sjis_pnt++] & 0xff;
882
883 if (hi >= 0xe0)
884 hi -= 0x40;
885 if (lo >= 0x80)
886 lo--;
887
888 lo -= (0x40 - 0x21);
889 hi = ((hi - 0x81) << 1) + 0x21;
890
891 if (lo >= 0x7f) {
892 lo -= 0x5e;
893 hi++;
894 }
895
896 euc[euc_pnt++] = hi | 0x80;
897 euc[euc_pnt++] = lo | 0x80;
898 } else if (ISSJISKANA(sjis[sjis_pnt])) { /* Ⱦ�ѥ��� */
899 euc[euc_pnt++] = 0x8e;
900 euc[euc_pnt++] = sjis[sjis_pnt++];
901 } else {
902 euc[euc_pnt++] = sjis[sjis_pnt++];
903 }
904 }
905
906 if (euc_pnt < euclen)
907 euc[euc_pnt] = '\0';
908 else
909 euc[euclen - 1] = '\0';
910
911 return euc_pnt;
912 }
913
914 /*
915 * signal setup...
916 */
917
m_setup_signal(signalhandler_t handler)918 int m_setup_signal(signalhandler_t handler)
919 {
920 signal(SIGINT, (void(*)())handler);
921 signal(SIGTERM, (void(*)())handler);
922 signal(SIGHUP, SIG_IGN);
923 signal(SIGQUIT, SIG_IGN);
924 signal(SIGPIPE, SIG_IGN);
925
926 return 0;
927 }
928
929 /*
930 * copy file...
931 */
932
m_copy_file_fp(FILE * from,FILE * to)933 int m_copy_file_fp(FILE *from, FILE *to)
934 {
935 char buf[1024];
936 int i;
937
938 do {
939 i = fread(buf, 1, 1024, from);
940 fwrite(buf, 1, i, to);
941 } while (i == 1024);
942
943 return 0;
944 }
945
m_copy_file(char * from,char * to)946 int m_copy_file(char *from, char *to)
947 {
948 FILE *fp1, *fp2;
949 char buf[1024];
950 int i;
951
952 if ((fp1 = fopen(from, "r")) != NULL) {
953 if ((fp2 = fopen(to, "w")) != NULL) {
954 do {
955 i = fread(buf, 1, 1024, fp1);
956 fwrite(buf, 1, i, fp2);
957 } while (i == 1024);
958
959 fclose(fp2);
960 fclose(fp1);
961
962 return 0;
963 }
964 fclose(fp1);
965 }
966
967 return -1;
968 }
969
970 /*
971 * system() ��Ʊ���δؿ�
972 */
973
974 static char m_system_opened_file[FOPEN_MAX];
975
m_system_clear()976 int m_system_clear()
977 {
978 memset(m_system_opened_file, 0, FOPEN_MAX);
979 return 0;
980 }
981
m_system_register_file(int fd)982 int m_system_register_file(int fd)
983 {
984 m_system_opened_file[fd] = 0xff;
985 return 0;
986 }
987
m_system(char * command)988 int m_system(char *command)
989 {
990 int i, status, pid;
991 char *argv[4];
992
993 if (command == NULL)
994 return -1;
995
996 pid = fork();
997
998 if (pid == -1)
999 return -1;
1000
1001 if (pid == 0) {
1002 for (i = 0; i < FOPEN_MAX; i++)
1003 if (m_system_opened_file[i])
1004 close(m_system_opened_file[i]);
1005
1006 argv[0] = "sh";
1007 argv[1] = "-c";
1008 argv[2] = command;
1009 argv[3] = NULL;
1010
1011 execv("/bin/sh", argv);
1012
1013 exit(127);
1014 }
1015
1016 for (;;) {
1017 if (waitpid(pid, &status, 0) == -1) {
1018 if (errno != EINTR)
1019 return -1;
1020 } else
1021 return status;
1022 }
1023 }
1024
1025 /*
1026 * read/write from/to socket functions...
1027 */
1028
m_socket_read(int fd,char * ptr,int totalsize)1029 int m_socket_read(int fd, char *ptr, int totalsize)
1030 {
1031 int size, ret;
1032
1033 size = 0;
1034 while (size < totalsize) {
1035 if ((ret = read(fd, &ptr[size], totalsize - size)) <= 0)
1036 return -1;
1037
1038 size += ret;
1039 }
1040
1041 return 0;
1042 }
1043
m_socket_write(int fd,char * ptr,int totalsize)1044 int m_socket_write(int fd, char *ptr, int totalsize)
1045 {
1046 int size, ret;
1047
1048 size = 0;
1049 while (size < totalsize) {
1050 if ((ret = write(fd, &ptr[size], totalsize - size)) < 0)
1051 return -1;
1052
1053 size += ret;
1054 }
1055
1056 return 0;
1057 }
1058
1059 /*
1060 * string modifier...
1061 */
1062
m_replace_string(uchar * eucbuf,char * pre,char * post)1063 int m_replace_string(uchar *eucbuf, char *pre, char *post)
1064 {
1065 char *p;
1066 int slen, prelen, postlen;
1067
1068 prelen = strlen(pre);
1069 postlen = strlen(post);
1070
1071 while ((p = strstr(eucbuf, pre)) != NULL) {
1072 slen = strlen(p);
1073
1074 memmove(p + postlen, p + prelen, slen - prelen + 1);
1075 memcpy(p, post, postlen);
1076 }
1077
1078 return strlen(eucbuf);
1079 }
1080
m_convert_zen2han(uchar * sjisbuf)1081 int m_convert_zen2han(uchar *sjisbuf)
1082 {
1083 int i = 0;
1084
1085 if (sjisbuf[0] == 0x82) { /* Alphabet */
1086 if (0x60 <= sjisbuf[1] && sjisbuf[1] < 0x60 + 26) /* A-Z */
1087 return 'A' + sjisbuf[1] - 0x60;
1088 if (0x81 <= sjisbuf[1] && sjisbuf[1] < 0x81 + 26) /* a-z */
1089 return 'a' + sjisbuf[1] - 0x81;
1090 }
1091 if (sjisbuf[0] == 0x82 && 0x4f <= sjisbuf[1] && sjisbuf[1] <= 0x58) /* 0-9 */
1092 return '0' + sjisbuf[1] - 0x4f;
1093
1094 if (sjisbuf[0] == 0x81) { /* ������ */
1095 while (zen_han_table[i].c) {
1096 if (zen_han_table[i].zen[1] == sjisbuf[1])
1097 return zen_han_table[i].c;
1098 i++;
1099 }
1100 }
1101
1102 return 0;
1103 }
1104
m_lookup_kana_table(uchar kana,int mod)1105 static int m_lookup_kana_table(uchar kana, int mod)
1106 {
1107 int i, j;
1108
1109 j = -1; i = 0;
1110 while (kana_table[i].han_start) {
1111 if (kana_table[i].han_start <= kana && kana <= kana_table[i].han_end) {
1112 j = i;
1113
1114 if (mod == 0 || (kana_table[i].modifiers & mod) != 0)
1115 break;
1116 }
1117 i++;
1118 }
1119
1120 return j;
1121 }
1122
m_convert_hankana2zenkana(uchar * euc,int len)1123 int m_convert_hankana2zenkana(uchar *euc, int len)
1124 {
1125 int i, j;
1126 uchar mod, c;
1127
1128 for (i = 0; i < len; i++) {
1129 mod = 0;
1130
1131 if (euc[i] == 0x8e) { /* non-ascii ��Ⱦ��ʸ���ʤ� */
1132 if (euc[i + 1] == 0xde) { /* ���� �� �ʤ� */
1133 euc[i] = 0xa1;
1134 euc[i + 1] = 0xab;
1135 i++;
1136 } else if (euc[i + 1] == 0xdf) { /* ���� �� �ʤ� */
1137 euc[i] = 0xa1;
1138 euc[i + 1] = 0xac;
1139 i++;
1140 } else { /* ���̤�Ⱦ�ѥ������ʤʤ� */
1141 if (i + 3 < len) {
1142 if (euc[i + 2] == 0x8e && euc[i + 3] == 0xde) /* ���� �� �ʤ� */
1143 mod = MOD_TEN;
1144 if (euc[i + 2] == 0x8e && euc[i + 3] == 0xdf) /* ���� �� �ʤ� */
1145 mod = MOD_MARU;
1146 }
1147
1148 if ((j = m_lookup_kana_table(euc[i + 1], mod)) != -1) {
1149 mod &= kana_table[j].modifiers; /* mod �ϡ֤Ƥ�Ƥ�ʤ��פ����
1150 ���ե��åȤ� */
1151 c = kana_table[j].zenkaku2_start;
1152 c += (euc[i + 1] - kana_table[j].han_start) * kana_table[j].offset;
1153 c += mod;
1154
1155 euc[i] = 0xa5; euc[i + 1] = c;
1156
1157 if (mod) {
1158 memmove(&(euc[i + 2]), &(euc[i + 4]), len - (i + 4) + 1);
1159 len -= 2;
1160 }
1161
1162 i++;
1163 }
1164 }
1165 }
1166 }
1167
1168 euc[len] = '\0';
1169
1170 return len;
1171 }
1172
m_convert_zenkana2zenhira(uchar * src,uchar * dst,int len)1173 int m_convert_zenkana2zenhira(uchar *src, uchar *dst, int len)
1174 {
1175 int i = 0;
1176 uchar euc[10];
1177
1178 while (i < len) {
1179 dst[i] = 0x82;
1180 dst[i + 1] = src[i + 1] + (0x9f - 0x40);
1181 if (src[i + 1] >= 0x80)
1182 dst[i + 1] -= 1;
1183
1184 i += 2;
1185 }
1186
1187 sjis2euc(dst, len, euc, 10);
1188
1189 return 0;
1190 }
1191
m_exist_hankata(uchar * euc)1192 int m_exist_hankata(uchar *euc)
1193 {
1194 uchar *p;
1195
1196 p = euc;
1197
1198 while (*p) {
1199 if (*p & 0x80) {
1200 if (*p == 0x8e)
1201 return 1;
1202 else
1203 p += 2;
1204 } else {
1205 p++;
1206 }
1207 }
1208
1209 return 0;
1210 }
1211
m_is_zenkata_string(uchar * euc)1212 int m_is_zenkata_string(uchar *euc)
1213 {
1214 uchar *p;
1215
1216 p = euc;
1217
1218 while (*p) {
1219 if (*p == 0xa5)
1220 p += 2;
1221 else
1222 return 0;
1223 }
1224
1225 return 1;
1226 }
1227
m_is_hiragana_string(uchar * euc)1228 int m_is_hiragana_string(uchar *euc)
1229 {
1230 uchar *p;
1231 int vu_flag = 0, hira_flag = 0;
1232
1233 p = euc;
1234
1235 while (*p) {
1236 if (*p == 0xa4) {
1237 hira_flag = 1;
1238 p += 2;
1239 } else if (*p == 0xa5 && *(p + 1) == 0xf4) { /* �� �� */
1240 vu_flag = 1;
1241 p += 2;
1242 } else
1243 return 0;
1244 }
1245
1246 if (vu_flag && hira_flag == 0)
1247 return 0; /* �� �����ξ��ϥ������ʤ�Ƚ�� */
1248
1249 return 1;
1250 }
1251
m_convert_zenhira2zenkata(uchar * euc_hira,int slen,uchar * euc_kata)1252 int m_convert_zenhira2zenkata(uchar *euc_hira, int slen, uchar *euc_kata)
1253 {
1254 int i, j;
1255
1256 for (i = j = 0; i < slen;) {
1257 if (euc_hira[i] == 0xa4) {
1258 if (i + 4 <= slen && euc_hira[i + 1] == 0xa6 &&
1259 euc_hira[i + 2] == 0xa1 && euc_hira[i + 3] == 0xab) {
1260 /* ���� �� */
1261 euc_kata[j] = 0xa5;
1262 euc_kata[j + 1] = 0xf4;
1263 j += 2;
1264 i += 4;
1265 } else {
1266 euc_kata[j] = 0xa5;
1267 euc_kata[j + 1] = euc_hira[i + 1];
1268 j += 2;
1269 i += 2;
1270 }
1271 } else if (euc_hira[i] & 0x80) {
1272 euc_kata[j++] = euc_hira[i++];
1273 euc_kata[j++] = euc_hira[i++];
1274 } else {
1275 euc_kata[j++] = euc_hira[i++];
1276 }
1277 }
1278
1279 euc_kata[j] = 0;
1280
1281 return j;
1282 }
1283
1284 /* reconvroma.c */
1285
1286 typedef struct {
1287 uchar roma[5];
1288 uchar hira[10];
1289 } romatbl_t;
1290
1291 static romatbl_t romatbl[] = {
1292 "a", "��",
1293 "i", "��",
1294 "u", "��",
1295 "e", "��",
1296 "o", "��",
1297 "ka", "��",
1298 "ki", "��",
1299 "ku", "��",
1300 "ke", "��",
1301 "ko", "��",
1302 "ga", "��",
1303 "gi", "��",
1304 "gu", "��",
1305 "ge", "��",
1306 "go", "��",
1307 "sa", "��",
1308 "si", "��",
1309 "su", "��",
1310 "se", "��",
1311 "so", "��",
1312 "za", "��",
1313 "zi", "��",
1314 "zu", "��",
1315 "ze", "��",
1316 "zo", "��",
1317 "ta", "��",
1318 "ti", "��",
1319 "tu", "��",
1320 "te", "��",
1321 "to", "��",
1322 "da", "��",
1323 "di", "��",
1324 "du", "��",
1325 "de", "��",
1326 "do", "��",
1327 "na", "��",
1328 "ni", "��",
1329 "nu", "��",
1330 "ne", "��",
1331 "no", "��",
1332 "nn", "��",
1333 "ha", "��",
1334 "hi", "��",
1335 "fu", "��",
1336 "he", "��",
1337 "ho", "��",
1338 "ba", "��",
1339 "bi", "��",
1340 "bu", "��",
1341 "be", "��",
1342 "bo", "��",
1343 "pa", "��",
1344 "pi", "��",
1345 "pu", "��",
1346 "pe", "��",
1347 "po", "��",
1348 "ma", "��",
1349 "mi", "��",
1350 "mu", "��",
1351 "me", "��",
1352 "mo", "��",
1353 "ya", "��",
1354 "yu", "��",
1355 "yo", "��",
1356 "ra", "��",
1357 "ri", "��",
1358 "ru", "��",
1359 "re", "��",
1360 "ro", "��",
1361 "wa", "��",
1362 "wi", "��",
1363 "we", "��",
1364 "wo", "��",
1365 "xa", "��",
1366 "xi", "��",
1367 "xu", "��",
1368 "xe", "��",
1369 "xo", "��",
1370 "xwa", "��",
1371 "xtu", "��",
1372 "xya", "��",
1373 "xyu", "��",
1374 "xyo", "��",
1375 };
1376
1377 static char *glyph =
1378 " ,.,./:;?! '` ^~_ -- /\\ | ' \"() []{}<> []{} +- = <> '\" \\$ %#&*@ ";
1379
1380 #define romatbl_num (sizeof(romatbl) / sizeof(romatbl_t))
1381
reconvroma_lookup(uchar * hira)1382 static int reconvroma_lookup(uchar *hira)
1383 {
1384 int i;
1385
1386 for (i = 0; i < romatbl_num; i++) {
1387 if (hira[1] == romatbl[i].hira[1])
1388 return i;
1389 }
1390
1391 return -1;
1392 }
1393
reconvroma_katakana2hiragana(uchar * src)1394 static uchar *reconvroma_katakana2hiragana(uchar *src)
1395 {
1396 int slen, i, j;
1397 uchar *p;
1398 static buffer_t zbuf;
1399
1400 slen = strlen(src);
1401 buffer_check(&zbuf, slen * 2);
1402 p = zbuf.buf;
1403
1404 if (p) {
1405 for (i = j = 0; i < slen;) {
1406 if (src[i] == 0xa5) { /* �������ʤξ�� */
1407 switch (src[i + 1]) {
1408 case 0xf4: /* �� */
1409 memcpy(&(p[j]), "����", 4);
1410 j += 4;
1411 break;
1412 case 0xf5:
1413 case 0xf6:
1414 memcpy(&(p[j]), "��", 2);
1415 j += 2;
1416 break;
1417 default:
1418 p[j++] = 0xa4;
1419 p[j++] = src[i + 1];
1420 }
1421
1422 i += 2;
1423 } else if (src[i] & 0x80) {
1424 p[j++] = src[i++];
1425 p[j++] = src[i++];
1426 } else {
1427 p[j++] = src[i++];
1428 }
1429 }
1430
1431 p[j] = 0;
1432 }
1433
1434 return p;
1435 }
1436
1437 /*
1438 * �Ҥ餬�ʡ��������ʡ�����ե��٥åȡ��������鹽��������ɤߤ�
1439 * �������Ѵ����롣
1440 * ����ե��٥åȤ˴ؤ��Ƥϡ�0x80 �� OR ���롣
1441 */
1442
m_reconvroma(uchar * src,uchar * dst)1443 int m_reconvroma(uchar *src, uchar *dst)
1444 {
1445 int src_pnt, i, srclen;
1446 uchar *p, buf[2];
1447
1448 p = reconvroma_katakana2hiragana(src); /* �������ʤ�Ҥ餬�ʤ��Ѵ� */
1449 srclen = strlen(p);
1450 dst[0] = '\0';
1451 src_pnt = 0;
1452
1453 while (p[src_pnt]) {
1454 switch (p[src_pnt]) {
1455 case 0xa4: /* �Ҥ餬�� */
1456 if (src_pnt + 4 <= srclen && p[src_pnt + 1] == 0xa6 &&
1457 p[src_pnt + 2] == 0xa1 && p[src_pnt + 3] == 0xab) {
1458 /* �֤����פΤФ��� */
1459 strcat(dst, "vu");
1460 src_pnt += 4;
1461 } else {
1462 if ((i = reconvroma_lookup(&(p[src_pnt]))) != -1) {
1463 strcat(dst, romatbl[i].roma);
1464 src_pnt += 2;
1465 } else {
1466 fprintf(stderr, "UNEXPECTED YOMI %d:%s\n", src_pnt, &(p[src_pnt]));
1467 free(p);
1468 return -1;
1469 }
1470 }
1471 break;
1472 case 0xa1: /* ���� */
1473 if (glyph[p[src_pnt + 1] - 0xa1] != ' ') {
1474 buf[0] = glyph[p[src_pnt + 1] - 0xa1];
1475 buf[1] = 0;
1476 strcat(dst, buf);
1477 src_pnt += 2;
1478 } else {
1479 fprintf(stderr, "UNEXPECTED GLYPH:%d:%s\n", src_pnt, &(p[src_pnt]));
1480 free(p);
1481 return -1;
1482 }
1483 break;
1484 case 0xa3: /* ����,����ե��٥å� */
1485 if (0xb0 <= p[src_pnt + 1] && p[src_pnt + 1] <= 0xb9) {
1486 buf[0] = '0' + (p[src_pnt + 1] - 0xb0);
1487 buf[1] = 0;
1488 strcat(dst, buf);
1489 src_pnt += 2;
1490 } else if (0xc1 <= p[src_pnt + 1] && p[src_pnt + 1] <= 0xda) {
1491 buf[0] = ('A' + (p[src_pnt + 1] - 0xc1)) | 0x80;
1492 buf[1] = 0;
1493 strcat(dst, buf);
1494 src_pnt += 2;
1495 } else if (0xe1 <= p[src_pnt + 1] && p[src_pnt + 1] <= 0xfa) {
1496 buf[0] = ('a' + (p[src_pnt + 1] - 0xe1)) | 0x80;
1497 buf[1] = 0;
1498 strcat(dst, buf);
1499 src_pnt += 2;
1500 } else {
1501 fprintf(stderr, "UNEXPECTED ALNUM:%d:%s\n", src_pnt, &(p[src_pnt]));
1502 free(p);
1503 return -1;
1504 }
1505 break;
1506 default:
1507 if ((p[src_pnt] & 0x80) == 0) {
1508 buf[0] = p[src_pnt] | 0x80;
1509 buf[1] = 0;
1510 strcat(dst, buf);
1511 src_pnt++;
1512 } else {
1513 fprintf(stderr, "UNEXPECTED:%d:%s\n", src_pnt, &(p[src_pnt]));
1514 free(p);
1515 return -1;
1516 }
1517 }
1518 }
1519
1520 return 0;
1521 }
1522
1523
1524