1 /*
2  *  $Id: dispatch.c,v 1.11 2002/05/12 22:51:16 hiroo Exp $
3  */
4 
5 /*
6  * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
7  * This file is part of FreeWnn.
8  *
9  * Copyright Kyoto University Research Institute for Mathematical Sciences
10  *                 1987, 1988, 1989, 1990, 1991, 1992
11  * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
12  * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992
13  * Copyright FreeWnn Project 1999, 2000, 2001, 2002
14  *
15  * Maintainer:  FreeWnn Project   <freewnn@tomo.gr.jp>
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation; either version 2 of the License, or
20  * (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
30  */
31 
32 /*
33  *      Command Dispatch routine
34  */
35 
36 #if defined(HAVE_CONFIG_H)
37 #include <config.h>
38 #endif
39 
40 #include <stdio.h>
41 #if STDC_HEADERS
42 #  include <stdlib.h>
43 #  include <string.h>
44 #else
45 #  if HAVE_MALLOC_H
46 #    include <malloc.h>
47 #  endif
48 #  if HAVE_STRINGS_H
49 #    include <strings.h>
50 #  endif /* HAVE_STRINGS_H */
51 #endif /* STDC_HEADERS */
52 #include <sys/types.h>
53 
54 #include "commonhd.h"
55 #include "demcom.h"
56 #include "de_header.h"
57 
58 extern int cur_clp;
59 
60 void
do_command()61 do_command ()
62 {
63   register int command;
64 
65   wnn_errorno = 0;
66   command = get4_cur ();        /* get command */
67 
68 #if defined(__STDC__)
69 #define CASE(X) case (X): log_debug(#X "(%d): cur_clp = %d", command, cur_clp);
70 #else
71 #define CASE(X) case (X): log_debug("X(%d): cur_clp = %d", command, cur_clp);
72 #endif
73 
74   switch (command)
75     {
76       CASE (JS_VERSION) put4_cur (JSERVER_VERSION);
77       putc_purge ();
78       break;
79 
80       CASE (JS_OPEN) js_open ();
81       break;
82 
83       CASE (JS_CLOSE) js_close ();
84       break;
85 /* */
86       CASE (JS_CONNECT) js_connect ();
87       break;
88 
89       CASE (JS_DISCONNECT) js_disconnect ();
90       break;
91 
92       CASE (JS_ENV_EXIST) js_env_exist ();
93       break;
94 
95       CASE (JS_ENV_UN_STICKY) js_env_un_sticky ();
96       break;
97 
98       CASE (JS_ENV_STICKY) js_env_sticky ();
99       break;
100 /* */
101       CASE (JS_PARAM_SET) js_param_set ();
102       break;
103 
104       CASE (JS_PARAM_GET) js_param_get ();
105       break;
106 /* */
107       CASE (JS_MKDIR) js_mkdir ();
108       break;
109 
110       CASE (JS_ACCESS) js_access ();
111       break;
112 
113       CASE (JS_FILE_STAT) js_file_stat ();
114       break;
115 
116       CASE (JS_FILE_INFO) js_file_info ();
117       break;
118 
119       CASE (JS_FILE_LIST_ALL) js_file_list_all ();
120       break;
121 
122       CASE (JS_FILE_LIST) js_file_list ();
123       break;
124 
125       CASE (JS_FILE_LOADED) js_file_loaded ();
126       break;
127 
128       CASE (JS_FILE_LOADED_LOCAL) js_file_loaded_local ();
129       break;
130 
131       CASE (JS_FILE_READ) js_file_read ();
132       break;
133 
134       CASE (JS_FILE_WRITE) js_file_write ();
135       break;
136 
137       CASE (JS_FILE_SEND) js_file_send ();
138       break;
139 
140       CASE (JS_FILE_RECEIVE) js_file_receive ();
141       break;
142 
143       CASE (JS_HINDO_FILE_CREATE) js_hindo_file_create ();
144       break;
145 
146       CASE (JS_DIC_FILE_CREATE) js_dic_file_create ();
147       break;
148 
149       CASE (JS_FILE_REMOVE) js_file_remove ();
150       break;
151 
152       CASE (JS_FILE_DISCARD) js_file_discard ();
153       break;
154       CASE (JS_FILE_COMMENT_SET) js_file_comment_set ();
155       break;
156       CASE (JS_FILE_PASSWORD_SET) js_file_password_set ();
157       break;
158 
159 /* */
160       CASE (JS_DIC_ADD) js_dic_add ();
161       break;
162 
163       CASE (JS_DIC_DELETE) js_dic_delete ();
164       break;
165 
166       CASE (JS_DIC_USE) js_dic_use ();
167       break;
168 
169       CASE (JS_DIC_LIST) js_dic_list ();
170       break;
171 
172       CASE (JS_DIC_LIST_ALL) js_dic_list_all ();
173       break;
174 
175       CASE (JS_DIC_INFO) js_dic_info ();
176       break;
177 /* */
178       CASE (JS_FUZOKUGO_SET) js_fuzokugo_set ();
179       break;
180 
181       CASE (JS_FUZOKUGO_GET) js_fuzokugo_get ();
182       break;
183 /* */
184       CASE (JS_WORD_ADD) js_word_add ();
185       break;
186 
187       CASE (JS_WORD_DELETE) js_word_delete ();
188       break;
189 
190       CASE (JS_WORD_SEARCH) js_word_search ();
191       break;
192 
193       CASE (JS_WORD_SEARCH_BY_ENV) js_word_search_by_env ();
194       break;
195 
196       CASE (JS_WORD_INFO) js_word_info ();
197       break;
198       CASE (JS_WORD_COMMENT_SET) js_word_comment_set ();
199       break;
200 /* */
201       CASE (JS_KANREN) do_kanren ();
202       putc_purge ();
203       break;
204 
205       CASE (JS_KANTAN_DAI) do_kantan_dai ();
206       putc_purge ();
207       break;
208 
209       CASE (JS_KANTAN_SHO) do_kantan_sho ();
210       putc_purge ();
211       break;
212 
213       CASE (JS_KANZEN_DAI) do_kanzen_dai ();
214       putc_purge ();
215       break;
216 
217       CASE (JS_KANZEN_SHO) do_kanzen_sho ();
218       putc_purge ();
219       break;
220 
221       CASE (JS_HINDO_SET) js_hindo_set ();
222       break;
223 
224 /* */
225       CASE (JS_WHO) js_who ();
226       break;
227 
228       CASE (JS_ENV_LIST) js_env_list ();
229       break;
230       CASE (JS_KILL) js_kill ();
231       break;
232       CASE (JS_HINDO_FILE_CREATE_CLIENT) js_hindo_file_create_client ();
233       break;
234       CASE (JS_HINSI_LIST) js_hinsi_list ();
235       break;
236       CASE (JS_HINSI_NAME) js_hinsi_name ();
237       break;
238       CASE (JS_HINSI_NUMBER) js_hinsi_number ();
239       break;
240       CASE (JS_HINSI_DICTS) js_hinsi_dicts ();
241       break;
242       CASE (JS_HINSI_TABLE_SET) js_hinsi_table_set ();
243       break;
244     default:
245       error1 ("unknown command %x", command);
246     }
247 }
248 
249 /*
250         communication routine
251  */
252 
253 char *
get_file_name(buffer,buffer_size)254 get_file_name (buffer, buffer_size)
255      char *buffer;
256      size_t buffer_size;
257 {
258   buffer = gets_cur (buffer, buffer_size);
259 
260   if (!buffer || *buffer == '\0')
261     return NULL;
262 
263   return expand_file_name (buffer, buffer_size);
264 }
265 
266 char *
expand_file_name(buffer,buffer_size)267 expand_file_name (buffer, buffer_size)
268      char *buffer;
269      size_t buffer_size;
270 {
271   char *q;
272 
273 #ifdef WNN_ALLOW_UNSAFE_PATH
274   if (*buffer != '/')
275 #else
276     /* XXX: path under jserver_dir only */
277   if (*buffer != '/'
278       || strncmp(buffer, jserver_dir, strlen(jserver_dir)) != 0)
279 #endif
280     {
281       char *path;
282       size_t path_len;
283 
284       path_len = strlen (jserver_dir) + strlen (buffer) + 2;
285       if (path_len > buffer_size)
286         return NULL;
287 
288       path = malloc (path_len);
289       if (!path)
290         return NULL;
291 
292       strcpy (path, jserver_dir);
293 /*      strcat(path,c_c->user_name);   */
294 #ifndef WNN_ALLOW_UNSAFE_PATH
295       if (path[strlen(path)-1] != '/' && *buffer != '/')
296 #endif
297       strcat (path, "/");
298       strcat (path, buffer);
299       strcpy (buffer, path);
300 
301       free (path);
302     }
303 
304 #ifndef WNN_ALLOW_UNSAFE_PATH
305  {
306    char *p, *pp, *p0;
307    p = pp = p0 = malloc(strlen(buffer)+1);
308    for  (q = buffer; *q; p++, q++) {
309      if (*q == '/') {
310        while (*(q+1) == '/')
311 	 q++;
312        if (strncmp(q, "/..", 3) == 0 && (*(q+3) == '/' || (*(q+3) == '\0'))) {
313 	 q += 2;
314 	 p = pp-1;
315 	 continue;
316        }
317        pp = p;
318      }
319      *p = *q;
320    }
321    *p = '\0';
322    strcpy(buffer, p0);
323    free(p0);
324  }
325  if (strncmp(buffer, jserver_dir, strlen(jserver_dir)) != 0) {
326    /* unsafe path */
327    return NULL; /* XXX */
328  }
329 #endif
330   for (q = buffer; *q++;)
331     ;
332   q -= 2;
333 
334   for (;;)
335     {
336       if (*q != '/')
337         break;
338       *q-- = '\0';
339     }
340 /*
341 fprintf(stderr,"file_name=%s\n",p);
342 */
343 
344   return buffer;
345 }
346 
347 void
error_ret()348 error_ret ()
349 {
350   extern char *wnn_perror ();
351 
352   put4_cur (-1);
353   if (wnn_errorno == 0)
354     {
355       put4_cur (WNN_SOME_ERROR);
356     }
357   else
358     {
359       error1 ("Error %s(%d): cur_clp = %d\n", wnn_perror (), wnn_errorno, cur_clp);
360       put4_cur (wnn_errorno);
361     }
362   putc_purge ();
363 }
364