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 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <time.h>
24 #include <pwd.h>
25 #include <sys/types.h>
26 #include <signal.h>
27 #include <dlfcn.h>
28 
29 #include "def.h"
30 
31 #include "misc.h"
32 
33 #define IW_ERROR16(_buf) { \
34   cannaheader_t *he; \
35   he = (cannaheader_t *)(_buf); \
36   he->datalen = LSBMSB16(2); \
37   he->err.e16 = LSBMSB16(-1); \
38 }
39 
40 #define IW_ERROR8(_buf) { \
41   cannaheader_t *he; \
42   he = (cannaheader_t *)(_buf); \
43   he->datalen = LSBMSB16(1); \
44   he->err.e8 = -1; \
45 }
46 
47 typedef int (*imefunc_t)();
48 
49 static char *funcsymbols[] = {
50   "_finalize",
51   "_create_context",
52   "_duplicate_context",
53   "_close_context",
54   "_define_word",
55   "_delete_word",
56   "_begin_convert",
57   "_end_convert",
58   "_get_candidacy_list",
59   "_get_yomi",
60   "_subst_yomi",
61   "_store_yomi",
62   "_store_range",
63   "_get_lastyomi",
64   "_flush_yomi",
65   "_remove_yomi",
66   "_get_simplekanji",
67   "_resize_pause",
68   "_get_hinshi",
69   "_get_lex",
70   "_get_status",
71   "_set_locale",
72   "_auto_convert",
73   "_initialize",
74   "_init_rootclient",
75   "_end_client",
76   "_end_rootclient",
77   "_clear_client_data"
78 };
79 
80 /* �����ʥߥå����������ؿ����ֹ�Ȥ��б��դ� */
81 /*
82   _finalize 0
83   _create_context 1
84   _duplicate_context 2
85   _close_context 3
86   _define_word 4
87   _delete_word 5
88   _begin_convert 6
89   _end_convert 7
90   _get_candidacy_list 8
91   _get_yomi 9
92   _subst_yomi 10
93   _store_yomi 11
94   _store_range 12
95   _get_lastyomi 13
96   _flush_yomi 14
97   _remove_yomi 15
98   _get_simplekanji 16
99   _resize_pause 17
100   _get_hinshi 18
101   _get_lex 19
102   _get_status 20
103   _set_locale 21
104   _auto_convert 22
105   _initialize 23
106   _init_rootclient 24
107   _end_client 25
108   _end_rootclient 26
109   _clear_client_data 27
110   */
111 
112 #define F_initialize 23
113 #define F_init_rootclient 24
114 #define F_end_client 25
115 #define F_end_rootclient 26
116 #define F_clear_client_data 27
117 
118 #define F_COMMON_END 27
119 
120 #define VJE_clear_vjeid 28
121 #define VJE_restarted 29
122 #define VJE_connect_unix 30
123 #define VJE_close_connection 31
124 
125 static imefunc_t vjefunc[32];
126 static imefunc_t atokfunc[28];
127 static imefunc_t wnnfunc[28];
128 
129 static imefunc_t *imefunc[IME_END] = {vjefunc, vjefunc, atokfunc, wnnfunc};
130 static char ime_connected_flag[IME_END];
131 static void *ime_dl_handler[IME_END];
132 
133 char *ime_dl_name[] = {
134   "vje25.so", "vje30.so", "atok.so", "wnn6.so"
135 };
136 
137 extern char *protocol_name[], *e_protocol_name[];
138 extern client_t client[];
139 
140 /*
141  * ����ե�����졼�����ե�������ɤߡ��ɤ���� IME ����³���뤫�֤�
142  */
143 
iw_get_conf_file_path(char * home)144 static char *iw_get_conf_file_path(char *home)
145 {
146   char *path;
147 
148   if ((path = m_makepath(home, ".esecannarc")) == NULL) {
149     m_msg("out of memory!\n");
150     return NULL;
151   }
152 
153   if (access(path, R_OK)) {
154     free(path);
155     if ((path = strdup(ESECANNA_RC_PATH)) == NULL) {
156       m_msg("out of memory!\n");
157       return NULL;
158     }
159 
160     if (access(path, R_OK)) {
161       m_msg("No conffile found.\n");
162       return NULL;
163     }
164   }
165 
166   m_msg("Config file %s\n", path);
167 
168   return path;
169 }
170 
iw_read_conf_file(char * path)171 static int iw_read_conf_file(char *path)
172 {
173   FILE *fp;
174   char buf[1024];
175   char *ope, *val;
176   int ret = IME_NON;
177 
178   if ((fp = fopen(path, "r")) == NULL) {
179     m_msg("Cannot open Conffile %s.\n", path);
180     return IME_NON;
181   }
182 
183   while (fgets(buf, 1024, fp)) {
184     if (buf[0] != '#' && m_conf1_parse(buf, &ope, &val) == 0) {
185       if (m_conf_isequal(ope, "IME", val, "VJE25") == 2)
186 	ret = IME_VJE25;
187       if (m_conf_isequal(ope, "IME", val, "VJE30") == 2)
188 	ret = IME_VJE30;
189       if (m_conf_isequal(ope, "IME", val, "ATOK") == 2)
190 	ret = IME_ATOK;
191       if (m_conf_isequal(ope, "IME", val, "WNN6") == 2)
192 	ret = IME_WNN;
193       if (ret == IME_NON && m_conf_isequal(ope, "IME", val, "dummy"))
194 	m_msg("Unsupported IME: [%s]\n", val);
195 
196       if (ret != IME_NON)
197 	break;
198     }
199   }
200 
201   fclose(fp);
202 
203   return ret;
204 }
205 
206 /*
207  * �����ʥߥå��⥸�塼�����ɤ���
208  */
209 
iw_retrieve_vje_symbols(void * handler)210 static int iw_retrieve_vje_symbols(void *handler)
211 {
212   int i;
213   char buf[100];
214   int (*dl_start_func)();
215 
216   for (i = 0; i <= F_COMMON_END; i++) {
217     strcpy(buf, "vjewrapper");
218     strcat(buf, funcsymbols[i]);
219 
220     vjefunc[i] = dlsym(handler, buf);
221   }
222 
223   vjefunc[VJE_clear_vjeid] = dlsym(handler, "vjewrapper_clear_vjeid");
224   vjefunc[VJE_restarted] = dlsym(handler, "vjewrapper_restarted");
225   vjefunc[VJE_connect_unix] = dlsym(handler, "vje_socket_connect_unix");
226   vjefunc[VJE_close_connection] = dlsym(handler,"vje_socket_close_connection");
227 
228   dl_start_func = dlsym(handler, "vjewrapper_dl_started");
229 
230   return dl_start_func(client);
231 }
232 
iw_retrieve_atok_symbols(void * handler)233 static int iw_retrieve_atok_symbols(void *handler)
234 {
235   extern char debugmode;
236   int i;
237   char buf[100];
238   int (*dl_start_func)();
239 
240   for (i = 0; i <= F_COMMON_END; i++) {
241     strcpy(buf, "atokwrapper");
242     strcat(buf, funcsymbols[i]);
243 
244     atokfunc[i] = dlsym(handler, buf);
245   }
246 
247   dl_start_func = dlsym(handler, "atokwrapper_dl_started");
248 
249   return dl_start_func(client, debugmode);
250 }
251 
iw_retrieve_wnn_symbols(void * handler)252 static int iw_retrieve_wnn_symbols(void *handler)
253 {
254   int i;
255   char buf[100];
256   int (*dl_start_func)();
257 
258   for (i = 0; i <= F_COMMON_END; i++) {
259     strcpy(buf, "wnnwrapper");
260     strcat(buf, funcsymbols[i]);
261 
262     wnnfunc[i] = dlsym(handler, buf);
263   }
264 
265   dl_start_func = dlsym(handler, "wnnwrapper_dl_started");
266 
267   return dl_start_func(client);
268 }
269 
iw_load_library(int ime)270 static int iw_load_library(int ime)
271 {
272   char buf[1024];
273 
274   if (ime == IME_VJE25 && ime_dl_handler[IME_VJE30 - 1] != NULL) {
275     m_msg("vje30.so already loaded so vje25 not loaded.\n");
276     return -1;
277   }
278 
279   if (ime == IME_VJE30 && ime_dl_handler[IME_VJE25 - 1] != NULL) {
280     m_msg("vje25.so already loaded so vje30 not loaded.\n");
281     return -1;
282   }
283 
284   if (ime_dl_handler[ime - 1] == NULL) {
285     sprintf(buf, "%s/%s", ESECANNA_DL_PATH, ime_dl_name[ime - 1]);
286 
287     if ((ime_dl_handler[ime - 1] = dlopen(buf, RTLD_NOW)) == NULL) {
288       m_msg("unable to load module %s\n", ime_dl_name[ime - 1]);
289       m_msg(dlerror());
290 
291       return -1;
292     }
293 
294     m_msg("Module %s loaded.\n", ime_dl_name[ime - 1]);
295 
296     switch (ime) {
297       case IME_VJE25:
298       case IME_VJE30:
299 	return iw_retrieve_vje_symbols(ime_dl_handler[ime - 1]);
300       case IME_ATOK:
301 	return iw_retrieve_atok_symbols(ime_dl_handler[ime - 1]);
302       case IME_WNN:
303 	return iw_retrieve_wnn_symbols(ime_dl_handler[ime - 1]);
304     }
305   }
306 
307   return 0;
308 }
309 
310 /*
311  * �����ʥߥå��⥸�塼�������ɤ���
312  */
313 
iw_unload_library(int ime)314 static int iw_unload_library(int ime)
315 {
316   if (ime_dl_handler[ime - 1]) {
317     dlclose(ime_dl_handler[ime - 1]);
318 
319     ime_dl_handler[ime - 1] = NULL;
320 
321     m_msg("Module %s unloaded.\n", ime_dl_name[ime - 1]);
322   }
323 
324   return 0;
325 }
326 
327 /*
328  *  ���饤����Ȥν�λ��������
329  */
330 
imewrapper_end_client(int id)331 int imewrapper_end_client(int id)
332 {
333   int ime = client[id].ime;
334   imefunc_t *func;
335 
336   if (ime > 0 && ime_dl_handler[ime - 1]) {
337     func = imefunc[ime - 1];
338     (func[F_end_client])(id);
339   }
340 
341   return 0;
342 }
343 
344 /*
345  * ���� IME �ν�λ�������롣
346  */
347 
imewrapper_end_rootclient(int ime)348 int imewrapper_end_rootclient(int ime)
349 {
350   imefunc_t *func;
351 
352   if (ime > 0 && ime_dl_handler[ime - 1] != NULL) {
353     /* �����ʥߥå��⥸�塼�뤬���ɤ���Ƥ���Τʤ齪λ�������� */
354     func = imefunc[ime - 1];
355     (func[F_end_rootclient])();
356 
357     /* �⥸�塼��������� */
358     iw_unload_library(ime);
359 
360     /* ��³�ե饰���ꥢ */
361     ime_connected_flag[ime - 1] = FALSE;
362   }
363 
364   return 0;
365 }
366 
367 /*
368  * client[] �Υǡ������ꥢ����ؿ���Ƥ�
369  */
370 
imewrapper_clear_client_data(int id)371 int imewrapper_clear_client_data(int id)
372 {
373   int ime = client[id].ime;
374   imefunc_t *func;
375 
376   if (ime > 0 && ime_dl_handler[ime - 1]) {
377     func = imefunc[ime - 1];
378     (func[F_clear_client_data])(id);
379   }
380 
381   MYFREE(client[id].host);
382   MYFREE(client[id].homedir);
383 
384   client[id].ime = IME_NON;
385 
386   memset(&(client[id]), 0, sizeof(client_t));
387 
388   client[id].sockfd = -1;
389 
390   return 0;
391 }
392 
393 
394 
395 /*
396  * IME ���۾ェλ�����Ȥ��ν����ط��δؿ�s
397  */
398 
iw_vje_aborted(int ime)399 static int iw_vje_aborted(int ime)
400 {
401 #if 0
402   /* ���Ф餯���Ƶ�ư�� disable */
403   /* FIXME: ���δؿ��ϡ�vjewrapper.c �ˤ���٤� */
404 
405   (vjefunc[VJE_close_connection])();
406 
407   if (client[VJE_ROOT_CLIENT].restart_vjed && client[VJE_ROOT_CLIENT].restart
408       && access(client[VJE_ROOT_CLIENT].restart, R_OK | X_OK) == 0) {
409     /* vjed ��Ƶ�ư��������³���� */
410     m_msg("iw_vje_aborted(): vjed down. Restarting...\n");
411     m_system(client[VJE_ROOT_CLIENT].restart);
412     sleep(1);
413 
414     /* vjeid �����ƥ��ꥢ��BeginConvert �λ���
415        �Ƥ� vjeid ���������褦�ˤ��� */
416     (vjefunc[VJE_clear_vjeid])();
417 
418     if ((vjefunc[VJE_connect_unix])() == 0) {
419       /* �����餯�Ƶ�ư����Ƥ���Τ� vjeerror ���ꥢ���� */
420       (vjefunc[VJE_restarted])();
421 
422       if ((vjefunc[F_init_rootclient])() == 0) {
423 	return 0;
424       } else {
425 	(vjefunc[VJE_close_connection])();
426       }
427     }
428 
429     m_msg("failed.\n");
430   } else {
431     m_msg("vjed down.\n");
432   }
433 
434 #endif
435 
436   /* �Ƶ�ư�˼��Ԥ������ϡ�main.c �Ǥ��� IME ����³���Ƥ���
437    * ���Ƥ�(rootclient �ޤ�)���饤����Ȥν�λ�������뤿�ᡢ
438    * -ime ���֤���
439    */
440 
441   return -ime;
442 }
443 
iw_wnn_aborted(int ime)444 static int iw_wnn_aborted(int ime)
445 {
446   return -ime;
447 }
448 
iw_atok_aborted(int ime)449 static int iw_atok_aborted(int ime)
450 {
451   return -ime;
452 }
453 
imewrapper_ime_aborted(int ime)454 int imewrapper_ime_aborted(int ime)
455 {
456   switch (ime) {
457     case IME_VJE25:
458     case IME_VJE30:
459       return iw_vje_aborted(ime);
460     case IME_ATOK:
461       return iw_atok_aborted(ime);
462     case IME_WNN:
463       return iw_wnn_aborted(ime);
464   }
465 
466   return -1;
467 }
468 
469 /*
470  * ��������ʤ�λ�����뤿��δؿ�
471  */
472 
iw_send_term_signal()473 static int iw_send_term_signal()
474 {
475   raise(SIGTERM);
476 
477   return 0;
478 }
479 
480 /*
481  * VJE �ˤޤ���³���Ƥ��ʤ����˸ƤФ�롣��³������������롣���Ԥ����ʤ顢
482  * �⥸�塼��������롣
483  */
484 
iw_vje_connect(int ime)485 static int iw_vje_connect(int ime)
486 {
487   /* �⥸�塼������ */
488   if (iw_load_library(ime) == 0) {
489 
490     /* VJE ����³ */
491     if ((vjefunc[VJE_connect_unix])() == 0) {
492 
493       /* ����³�ξ���ͤ� restarted ��Ƥ�ǡ��ե饰���ꥢ���� */
494       (vjefunc[VJE_restarted])();
495 
496       /* ����� */
497       if ((vjefunc[F_init_rootclient])() == 0) {
498 	/* VJE ��³ & �������������*/
499 
500 	client[VJE_ROOT_CLIENT].ime = ime;
501 	ime_connected_flag[ime - 1] = TRUE;
502 
503 	return 0;
504       } else {
505 	/* ������ˤϼ��ԡ���³���ڤ� */
506 
507 	(vjefunc[F_end_rootclient])();
508       }
509     }
510     /* ��³�˼��ԡ��⥸�塼����� */
511 
512     iw_unload_library(ime);
513   }
514 
515   return -1;
516 }
517 
518 /*
519  * ATOK �ˤޤ���³���Ƥ��ʤ����˸ƤФ��
520  */
521 
iw_atok_connect(int ime)522 static int iw_atok_connect(int ime)
523 {
524   /* �⥸�塼������ */
525   if (iw_load_library(ime) == 0) {
526     /* ����� */
527     if ((atokfunc[F_init_rootclient])() == 0) {
528       /* ATOK ��³ & �������������*/
529 
530       client[ATOK_ROOT_CLIENT].ime = ime;
531       ime_connected_flag[ime - 1] = TRUE;
532 
533       return 0;
534     } else {
535       (atokfunc[F_end_rootclient])();
536     }
537 
538     iw_unload_library(ime);
539   }
540 
541   return -1;
542 }
543 
544 /*
545  * Wnn �ˤޤ���³���Ƥ��ʤ����˸ƤФ��
546  */
547 
iw_wnn_connect(int ime)548 static int iw_wnn_connect(int ime)
549 {
550   /* �⥸�塼������ */
551   if (iw_load_library(ime) == 0) {
552     /* ����� */
553     if ((wnnfunc[F_init_rootclient])() == 0) {
554       /* Wnn ��³ & �������������*/
555 
556       client[WNN_ROOT_CLIENT].ime = ime;
557       ime_connected_flag[ime - 1] = TRUE;
558 
559       return 0;
560     } else {
561       (wnnfunc[F_end_rootclient])();
562     }
563 
564     iw_unload_library(ime);
565   }
566 
567   return -1;
568 }
569 
570 /*
571  * IME �ˤޤ���³���Ƥ��ʤ����˸ƤФ��
572  */
573 
iw_ime_connect(int ime)574 static int iw_ime_connect(int ime)
575 {
576   switch (ime) {
577     case IME_VJE25:
578     case IME_VJE30:
579       return iw_vje_connect(ime);
580       break;
581     case IME_ATOK:
582       return iw_atok_connect(ime);
583       break;
584     case IME_WNN:
585       return iw_wnn_connect(ime);
586       break;
587   }
588 
589   return -1;
590 }
591 
592 /*
593  * ����ʥץ�ȥ���� wrap ����ؿ�s
594  */
595 
imewrapper_initialize(int id,buffer_t * cbuf)596 int imewrapper_initialize(int id, buffer_t *cbuf)
597 {
598   int ime = IME_NON, errflag, *ip = (int *)cbuf->buf;
599   short *sp = (short *)cbuf->buf;
600   short cx_num;
601   char *p, *major_p, *minor_p, *user = NULL, *home;
602   short major, minor;
603   struct passwd *pwd;
604   char *conffile = NULL;
605   imefunc_t *func;
606 
607   errflag = 0;
608 
609   major_p = &(cbuf->buf[0]); /* Initialize �˸¤�, cbuf->buf �˥إå�����
610 				����ʤ� */
611   home = NULL;
612   major = minor = -1;
613 
614   if ((p = strchr(major_p, '.')) == NULL)
615     errflag = 1;
616   else {
617     *p = 0;
618 
619     minor_p = p + 1;
620 
621     if ((p = strchr(minor_p, ':')) == NULL)
622       errflag = 2;
623     else {
624       *p = 0;
625       user = p + 1;
626 
627       if (user[0] == 0)
628 	errflag = 3;
629       else {
630 	if ((pwd = getpwnam(user)) == NULL)
631 	  errflag = 4;
632 	else {
633 	  if ((home = pwd->pw_dir) == NULL)
634 	    errflag = 5;
635 	  else {
636 	    if ((conffile = iw_get_conf_file_path(home)) == NULL)
637 	      errflag = 6;
638 
639 	    major = atoi(major_p);
640 	    minor = atoi(minor_p);
641 	  }
642 	}
643       }
644     }
645   }
646 
647   /* FIXME: major, minor �Ǿ��ˤ�äƤϥ��顼���֤��褦���� */
648 
649   if (errflag)
650     m_msg("Header invalid. Maybe server version mismatch?\n");
651 
652   if (errflag == 0) {
653     if ((ime = client[id].ime = iw_read_conf_file(conffile)) != 0) {
654       if (ime_connected_flag[ime - 1] == FALSE) {
655 	/* ��³�׵ᤵ�줿 IME �ˤޤ���³���Ƥ��ʤ���� */
656 
657 	iw_ime_connect(ime);
658       }
659     } else {
660       m_msg("IME not determined.\n");
661     }
662   }
663 
664   if (errflag == 0 && ime > 0 && ime_connected_flag[ime - 1] == TRUE) {
665     /* client[] �� user ̾��, �ۡ���ǥ��쥯�ȥ�Υѥ����ݴ� */
666     strncpy(client[id].user, user, 10);
667     client[id].user[9] = 0;
668     client[id].homedir = strdup(home);
669 
670     func = imefunc[ime - 1];
671 
672     cx_num = (func[F_initialize])(id, conffile);
673   } else {
674     cx_num = -1;
675   }
676 
677   if (cx_num == -1) {
678     m_msg("Initialize failed. #%d %s@%s refused.\n", id, user ? user : "",
679 	  client[id].host);
680 
681     /* �꥽�����ե�������ɤ߹����ʳ��Ǥμ��ԡ��ޤ��ϥ���ƥ����Ȥγ�����
682        ���ԡ����饤����ȤȤ���³���ڤäƤ��ޤ� */
683     client[id].need_terminate = TRUE; /* main.c �ǽ�λ�������Ƥ�餦 */
684     *ip = LSBMSB32(-1);
685   } else {  /* Success */
686     sp[0] = LSBMSB16(3);
687     sp[1] = LSBMSB16(cx_num);
688   }
689 
690   if (conffile)
691     free(conffile);
692 
693   return 1;
694 }
695 
696 #define CALLFUNC(_num) imefunc_t *func; func = imefunc[client[id].ime - 1]; \
697   return (func[_num])(id, cbuf); \
698 
699 
imewrapper_finalize(int id,buffer_t * cbuf)700 int imewrapper_finalize(int id, buffer_t *cbuf)
701 {
702   CALLFUNC(0);
703 }
704 
imewrapper_create_context(int id,buffer_t * cbuf)705 int imewrapper_create_context(int id, buffer_t *cbuf)
706 {
707   CALLFUNC(1);
708 }
709 
imewrapper_duplicate_context(int id,buffer_t * cbuf)710 int imewrapper_duplicate_context(int id, buffer_t *cbuf)
711 {
712   CALLFUNC(2);
713 }
714 
imewrapper_close_context(int id,buffer_t * cbuf)715 int imewrapper_close_context(int id, buffer_t *cbuf)
716 {
717   CALLFUNC(3);
718 }
719 
imewrapper_get_dictionary_list(int id,buffer_t * cbuf)720 int imewrapper_get_dictionary_list(int id, buffer_t *cbuf)
721 {
722   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
723 
724   header->datalen = LSBMSB16(2);
725   header->err.e16 = 0;
726 
727   return 1;
728 }
729 
imewrapper_get_directory_list(int id,buffer_t * cbuf)730 int imewrapper_get_directory_list(int id, buffer_t *cbuf)
731 {
732   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
733 
734   header->datalen = LSBMSB16(2);
735   header->err.e16 = 0;
736 
737   return 1;
738 }
739 
imewrapper_mount_dictionary(int id,buffer_t * cbuf)740 int imewrapper_mount_dictionary(int id, buffer_t *cbuf)
741 {
742   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
743 
744   header->datalen = LSBMSB16(1);
745   header->err.e8 = 0;
746 
747   return 1;
748 }
749 
imewrapper_unmount_dictionary(int id,buffer_t * cbuf)750 int imewrapper_unmount_dictionary(int id, buffer_t *cbuf)
751 {
752   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
753 
754   header->datalen = LSBMSB16(1);
755   header->err.e8 = 0;
756 
757   return 1;
758 }
759 
imewrapper_remount_dictionary(int id,buffer_t * cbuf)760 int imewrapper_remount_dictionary(int id, buffer_t *cbuf)
761 {
762   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
763 
764   header->datalen = LSBMSB16(1);
765   header->err.e8 = 0;
766 
767   return 1;
768 }
769 
imewrapper_get_mountdictionary_list(int id,buffer_t * cbuf)770 int imewrapper_get_mountdictionary_list(int id, buffer_t *cbuf)
771 {
772   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
773 
774   header->datalen = LSBMSB16(2);
775   header->err.e16 = 0;
776 
777   return 1;
778 }
779 
imewrapper_query_dictionary(int id,buffer_t * cbuf)780 int imewrapper_query_dictionary(int id, buffer_t *cbuf)
781 {
782   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
783 
784   header->datalen = LSBMSB16(1);
785   header->err.e8 = -1;
786 
787   return 1;
788 }
789 
imewrapper_define_word(int id,buffer_t * cbuf)790 int imewrapper_define_word(int id, buffer_t *cbuf)
791 {
792   CALLFUNC(4);
793 }
794 
imewrapper_delete_word(int id,buffer_t * cbuf)795 int imewrapper_delete_word(int id, buffer_t *cbuf)
796 {
797   CALLFUNC(5);
798 }
799 
imewrapper_begin_convert(int id,buffer_t * cbuf)800 int imewrapper_begin_convert(int id, buffer_t *cbuf)
801 {
802   CALLFUNC(6);
803 }
804 
imewrapper_end_convert(int id,buffer_t * cbuf)805 int imewrapper_end_convert(int id, buffer_t *cbuf)
806 {
807   CALLFUNC(7);
808 }
809 
imewrapper_get_candidacy_list(int id,buffer_t * cbuf)810 int imewrapper_get_candidacy_list(int id, buffer_t *cbuf)
811 {
812   CALLFUNC(8);
813 }
814 
imewrapper_get_yomi(int id,buffer_t * cbuf)815 int imewrapper_get_yomi(int id, buffer_t *cbuf)
816 {
817   CALLFUNC(9);
818 }
819 
imewrapper_subst_yomi(int id,buffer_t * cbuf)820 int imewrapper_subst_yomi(int id, buffer_t *cbuf)
821 {
822   CALLFUNC(10);
823 }
824 
imewrapper_store_yomi(int id,buffer_t * cbuf)825 int imewrapper_store_yomi(int id, buffer_t *cbuf)
826 {
827   CALLFUNC(11);
828 }
829 
imewrapper_store_range(int id,buffer_t * cbuf)830 int imewrapper_store_range(int id, buffer_t *cbuf)
831 {
832   CALLFUNC(12);
833 }
834 
imewrapper_get_lastyomi(int id,buffer_t * cbuf)835 int imewrapper_get_lastyomi(int id, buffer_t *cbuf)
836 {
837   CALLFUNC(13);
838 }
839 
imewrapper_flush_yomi(int id,buffer_t * cbuf)840 int imewrapper_flush_yomi(int id, buffer_t *cbuf)
841 {
842   CALLFUNC(14);
843 }
844 
imewrapper_remove_yomi(int id,buffer_t * cbuf)845 int imewrapper_remove_yomi(int id, buffer_t *cbuf)
846 {
847   CALLFUNC(15);
848 }
849 
imewrapper_get_simplekanji(int id,buffer_t * cbuf)850 int imewrapper_get_simplekanji(int id, buffer_t *cbuf)
851 {
852   CALLFUNC(16);
853 }
854 
imewrapper_resize_pause(int id,buffer_t * cbuf)855 int imewrapper_resize_pause(int id, buffer_t *cbuf)
856 {
857   CALLFUNC(17);
858 }
859 
imewrapper_get_hinshi(int id,buffer_t * cbuf)860 int imewrapper_get_hinshi(int id, buffer_t *cbuf)
861 {
862   CALLFUNC(18);
863 }
864 
imewrapper_get_lex(int id,buffer_t * cbuf)865 int imewrapper_get_lex(int id, buffer_t *cbuf)
866 {
867   CALLFUNC(19);
868 }
869 
imewrapper_get_status(int id,buffer_t * cbuf)870 int imewrapper_get_status(int id, buffer_t *cbuf)
871 {
872   CALLFUNC(20);
873 }
874 
imewrapper_set_locale(int id,buffer_t * cbuf)875 int imewrapper_set_locale(int id, buffer_t *cbuf)
876 {
877   CALLFUNC(21);
878 }
879 
imewrapper_auto_convert(int id,buffer_t * cbuf)880 int imewrapper_auto_convert(int id, buffer_t *cbuf)
881 {
882   CALLFUNC(22);
883 }
884 
imewrapper_query_extensions(int id,buffer_t * cbuf)885 int imewrapper_query_extensions(int id, buffer_t *cbuf)
886 {
887   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
888 
889   header->datalen = LSBMSB16(1);
890   header->err.e8 = 0;
891 
892   return 1;
893 }
894 
imewrapper_set_applicationname(int id,buffer_t * cbuf)895 int imewrapper_set_applicationname(int id, buffer_t *cbuf)
896 {
897   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
898 
899   header->datalen = LSBMSB16(1);
900   header->err.e8 = 0;
901 
902   return 1;
903 }
904 
905 
imewrapper_notice_groupname(int id,buffer_t * cbuf)906 int imewrapper_notice_groupname(int id, buffer_t *cbuf)
907 {
908   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
909 
910   header->datalen = LSBMSB16(1);
911   header->err.e8 = 0;
912 
913   return 1;
914 }
915 
imewrapper_through(int id,buffer_t * cbuf)916 int imewrapper_through(int id, buffer_t *cbuf)
917 {
918   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
919 
920   header->datalen = LSBMSB16(2);
921   header->err.e16 = 0;
922 
923   return 1;
924 }
925 
imewrapper_kill_server(int id,buffer_t * cbuf)926 int imewrapper_kill_server(int id, buffer_t *cbuf)
927 {
928   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
929   int err = 0;
930   char buf[128];
931   struct passwd *pw;
932   uid_t pid;
933 
934   if (gethostname(buf, 128))
935     buf[0] = 0;
936   pw = getpwnam(client[id].user);
937   pid = getuid();
938 
939   if (strcmp(client[id].host, "UNIX") && strcmp(client[id].host, buf) &&
940       strcmp(client[id].host, "localhost"))
941     err = -111; /* NOTUXSRV */
942   else if (pw->pw_uid != 0 && pw->pw_gid != 0 && pw->pw_uid != pid)
943     err = -112; /* NOTOWNSRV */
944 
945   header->datalen = LSBMSB16(1);
946   header->err.e8 = err;
947 
948   if (err == 0) {
949     signal(SIGALRM, (void(*)())iw_send_term_signal);
950     alarm(1);
951 
952     m_msg("KillServer from %s@%s accepted.\n",
953 	  client[id].user, client[id].host);
954   }
955 
956   return 1;
957 }
958 
imewrapper_get_serverinfo(int id,buffer_t * cbuf)959 int imewrapper_get_serverinfo(int id, buffer_t *cbuf)
960 {
961   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
962   int protocol_num, e_protocol_num, datalen, protocol_datalen, pnt;
963   int i;
964   uint ui;
965   short s;
966 
967   for (protocol_num = 0; protocol_name[protocol_num] != NULL; protocol_num++);
968   for (e_protocol_num = 0; e_protocol_name[e_protocol_num] != NULL;
969        e_protocol_num++);
970 
971   protocol_datalen = 0;
972   for (i = 0; i < protocol_num; i++)
973     protocol_datalen += strlen(protocol_name[i]) + 1;
974   for (i = 0; i < e_protocol_num; i++)
975     protocol_datalen += strlen(e_protocol_name[i]) + 1;
976   protocol_datalen++;
977 
978   datalen = 17 + protocol_datalen + (protocol_num + e_protocol_num) * 4;
979 
980   buffer_check(cbuf, datalen + 4);
981   header = (cannaheader_t *)cbuf->buf;
982 
983   header->type = 0x01;
984   header->extra = 0x01;
985   header->datalen = LSBMSB16(datalen);
986 
987   cbuf->buf[4] = 0;
988   cbuf->buf[5] = 3; /* Major Server Version */
989   cbuf->buf[6] = 5; /* Minor Server Version */
990 
991   ui = (uint)time(NULL); ui = LSBMSB32(ui);
992   memcpy(&(cbuf->buf[7]), &ui, 4);
993 
994   i = protocol_num + e_protocol_num;
995   s = LSBMSB16(i);
996   memcpy(&(cbuf->buf[11]), &s, 2);
997 
998   s = LSBMSB16(protocol_datalen);
999   memcpy(&(cbuf->buf[13]), &s, 2);
1000 
1001   pnt = 15;
1002   for (i = 0; i < protocol_num; i++) {
1003     strcpy(&(cbuf->buf[pnt]), protocol_name[i]);
1004     pnt += strlen(protocol_name[i]) + 1;
1005   }
1006 
1007   for (i = 0; i < e_protocol_num; i++) {
1008     strcpy(&(cbuf->buf[pnt]), e_protocol_name[i]);
1009     pnt += strlen(e_protocol_name[i]) + 1;
1010   }
1011 
1012   cbuf->buf[pnt++] = 0;
1013 
1014   memset(&(cbuf->buf[pnt]), 0, 4 * (protocol_num + e_protocol_num));
1015   pnt += 4 * (protocol_num + e_protocol_num);
1016 
1017   memset(&(cbuf->buf[pnt]), 0, 6);
1018   pnt += 6;
1019 
1020   return 1;
1021 }
1022 
imewrapper_get_access_control_list(int id,buffer_t * cbuf)1023 int imewrapper_get_access_control_list(int id, buffer_t *cbuf)
1024 {
1025   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
1026 
1027   header->datalen = LSBMSB16(2);
1028   header->err.e16 = LSBMSB16(-1);
1029 
1030   return 1;
1031 }
1032 
imewrapper_create_dictionary(int id,buffer_t * cbuf)1033 int imewrapper_create_dictionary(int id, buffer_t *cbuf)
1034 {
1035   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
1036 
1037   header->datalen = LSBMSB16(1);
1038   header->err.e8 = -1;
1039 
1040   return 1;
1041 }
1042 
imewrapper_delete_dictionary(int id,buffer_t * cbuf)1043 int imewrapper_delete_dictionary(int id, buffer_t *cbuf)
1044 {
1045   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
1046 
1047   header->datalen = LSBMSB16(1);
1048   header->err.e8 = -1;
1049 
1050   return 1;
1051 }
1052 
imewrapper_rename_dictionary(int id,buffer_t * cbuf)1053 int imewrapper_rename_dictionary(int id, buffer_t *cbuf)
1054 {
1055   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
1056 
1057   header->datalen = LSBMSB16(1);
1058   header->err.e8 = -1;
1059 
1060   return 1;
1061 }
1062 
imewrapper_get_wordtext_dictionary(int id,buffer_t * cbuf)1063 int imewrapper_get_wordtext_dictionary(int id, buffer_t *cbuf)
1064 {
1065   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
1066 
1067   header->datalen = LSBMSB16(2);
1068   header->err.e16 = LSBMSB16(-1);
1069 
1070   return 1;
1071 }
1072 
imewrapper_list_dictionary(int id,buffer_t * cbuf)1073 int imewrapper_list_dictionary(int id, buffer_t *cbuf)
1074 {
1075   cannaheader_t *header = (cannaheader_t *)cbuf->buf;
1076 
1077   header->datalen = LSBMSB16(1);
1078   header->err.e8 = -1;
1079 
1080   return 1;
1081 }
1082 
imewrapper_sync(int id,buffer_t * cbuf)1083 int imewrapper_sync(int id, buffer_t *cbuf)
1084 {
1085  cannaheader_t *header = (cannaheader_t *)cbuf->buf;
1086 
1087   header->datalen = LSBMSB16(1);
1088   header->err.e8 = 0;
1089 
1090   return 1;
1091 }
1092 
imewrapper_chmod_dictionary(int id,buffer_t * cbuf)1093 int imewrapper_chmod_dictionary(int id, buffer_t *cbuf)
1094 {
1095  cannaheader_t *header = (cannaheader_t *)cbuf->buf;
1096 
1097   header->datalen = LSBMSB16(1);
1098   header->err.e8 = -1;
1099 
1100   return 1;
1101 }
1102 
imewrapper_copy_dictionary(int id,buffer_t * cbuf)1103 int imewrapper_copy_dictionary(int id, buffer_t *cbuf)
1104 {
1105  cannaheader_t *header = (cannaheader_t *)cbuf->buf;
1106 
1107   header->datalen = LSBMSB16(1);
1108   header->err.e8 = -1;
1109 
1110   return 1;
1111 }
1112