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 <unistd.h>
22
23 #include "def.h"
24 #include "misc.h"
25 #include "imewrapper.h"
26 #include "cannaproto.h"
27
28 typedef int (*intfunc_t)();
29
30 intfunc_t wrapperfunc[] = {
31 imewrapper_initialize,
32 imewrapper_finalize,
33 imewrapper_create_context,
34 imewrapper_duplicate_context,
35 imewrapper_close_context,
36 imewrapper_get_dictionary_list,
37 imewrapper_get_directory_list,
38 imewrapper_mount_dictionary,
39 imewrapper_unmount_dictionary,
40 imewrapper_remount_dictionary,
41 imewrapper_get_mountdictionary_list,
42 imewrapper_query_dictionary,
43 imewrapper_define_word,
44 imewrapper_delete_word,
45 imewrapper_begin_convert,
46 imewrapper_end_convert,
47 imewrapper_get_candidacy_list,
48 imewrapper_get_yomi,
49 imewrapper_subst_yomi,
50 imewrapper_store_yomi,
51 imewrapper_store_range,
52 imewrapper_get_lastyomi,
53 imewrapper_flush_yomi,
54 imewrapper_remove_yomi,
55 imewrapper_get_simplekanji,
56 imewrapper_resize_pause,
57 imewrapper_get_hinshi,
58 imewrapper_get_lex,
59 imewrapper_get_status,
60 imewrapper_set_locale,
61 imewrapper_auto_convert,
62 imewrapper_query_extensions,
63 imewrapper_set_applicationname,
64 imewrapper_notice_groupname,
65 imewrapper_through,
66 imewrapper_kill_server
67 };
68
69 intfunc_t wrapperfunc_e[] = {
70 imewrapper_get_serverinfo,
71 imewrapper_get_access_control_list,
72 imewrapper_create_dictionary,
73 imewrapper_delete_dictionary,
74 imewrapper_rename_dictionary,
75 imewrapper_get_wordtext_dictionary,
76 imewrapper_list_dictionary,
77 imewrapper_sync,
78 imewrapper_chmod_dictionary,
79 imewrapper_copy_dictionary
80 };
81
82 static buffer_t packetbuf;
83
84 char *protocol_name[] = {
85 "Initialize",
86 "Finalize",
87 "CreateContext",
88 "DupricateContext",
89 "CloseContext",
90 "GetDictionaryList",
91 "GetDirectoryList",
92 "MountDictionary",
93 "UnmountDictionary",
94 "RemountDictionary",
95 "GetMountDictionaryList",
96 "QueryDictionary",
97 "DefineWord",
98 "DeleteWord",
99 "BeginConvert",
100 "EndConvert",
101 "GetCandidacyList",
102 "GetYomi",
103 "SubstYomi",
104 "StoreYomi",
105 "StoreRange",
106 "GetLastYomi",
107 "FlushYomi",
108 "RemoveYomi",
109 "GetSimpleKanji",
110 "ResizePause",
111 "GetHinshi",
112 "GetLex",
113 "GetStatus",
114 "SetLocale",
115 "AutoConvert",
116 "QueryExtensions",
117 "SetApplicationName",
118 "NoticeGroupName",
119 "Through",
120 "KillServer",
121 NULL
122 };
123
124 char *e_protocol_name[] = {
125 "GetServerInfo",
126 "GetAccessControlList",
127 "CreateDictionary",
128 "DeleteDictionary",
129 "RenameDictionary",
130 "GetWordTextDictionary",
131 "ListDictionary",
132 "Sync",
133 "ChmodDictionary",
134 "CopyDictionary",
135 NULL
136 };
137
138 extern client_t client[];
139
canna_proto_recv_request(int id)140 int canna_proto_recv_request(int id)
141 {
142 int datalen, extflag, type;
143 cannaheader_t *header;
144
145 buffer_check(&packetbuf, 24);
146
147 if (m_socket_read(client[id].sockfd, packetbuf.buf, 4) < 0) {
148 /* read ���顼�ϥ��饤����Ȥ�������������Ƚ�Ǥ��� */
149 return -1;
150 }
151
152 header = (cannaheader_t *)(packetbuf.buf);
153
154 if (header->type == 0x00) { /* Initialize */
155 if (m_socket_read(client[id].sockfd, (char *)(&datalen), 4) < 0)
156 return -1;
157 datalen = LSBMSB32(datalen);
158
159 buffer_check(&packetbuf, datalen);
160
161 if (m_socket_read(client[id].sockfd, packetbuf.buf, datalen) < 0)
162 return -1;
163
164 return 0x01;
165 } else {
166 datalen = LSBMSB16(header->datalen);
167 extflag = header->extra ? 0x1000 : 0x0000;
168 type = header->type;
169
170 if (datalen > 0) {
171 buffer_check(&packetbuf, datalen + 4);
172
173 if (m_socket_read(client[id].sockfd, &(packetbuf.buf[4]), datalen) < 0)
174 return -1;
175 }
176
177 return (type | extflag);
178 }
179 }
180
canna_proto_send_request(int id)181 int canna_proto_send_request(int id)
182 {
183 int datalen;
184 cannaheader_t *header;
185
186 header = (cannaheader_t *)(packetbuf.buf);
187
188 datalen = LSBMSB16(header->datalen) + 4;
189
190 if (m_socket_write(client[id].sockfd, packetbuf.buf, datalen) < 0)
191 return -1;
192
193 return 0;
194 }
195
canna_proto_main(int id)196 int canna_proto_main(int id)
197 {
198 int type, ret;
199 int (*callfunc)();
200 char *reqname;
201
202 if ((type = canna_proto_recv_request(id)) <= 0) {
203 client[id].need_terminate = TRUE; /* main.c �ǽ�λ�����Ƥ�餦 */
204 return 0;
205 }
206
207 if ((0x01 <= type && type <= 0x24) || (0x1001 <= type && type <= 0x100a)) {
208 if (type & 0x1000) {
209 reqname = e_protocol_name[(type & 0xff) - 1];
210 callfunc = wrapperfunc_e[(type & 0xff) - 1];
211 } else {
212 reqname = protocol_name[type - 1];
213 callfunc = wrapperfunc[type - 1];
214 }
215
216 m_msg_dbg("REQUEST %s called by %s@%s\n", reqname, client[id].user,
217 client[id].host);
218
219 ret = (*callfunc)(id, &packetbuf);
220
221 m_msg_dbg("Returned from request processing.\n");
222 } else {
223 /* �إå����ѡ�main.c �ǽ�λ�����Ƥ�餦���ꥯ�����Ȥϥ������֤� */
224 client[id].need_terminate = TRUE;
225 ret = 1;
226 }
227
228 /* ret..1 ���� ret..0 ̤���� ret..-1 IME ����� */
229
230 if (type == 0x01)
231 write(client[id].sockfd, packetbuf.buf, 4);
232 else
233 canna_proto_send_request(id);
234
235 if (ret == 0)
236 m_msg_dbg("Request %x is under construction.\n", type);
237 else if (ret == -1) {
238 m_msg("IME terminated.\n");
239
240 /* �Ƶ�ư�����롣���Ԥ������ϡ�-ime ���֤ꡢmain.c ��
241 * ���ƤΥ��饤����Ȥν�λ�����뤿�ᡢ-ime ���֤�
242 */
243
244 return imewrapper_ime_aborted(client[id].ime);
245 }
246
247 return 0;
248 }
249