Mercurial > freewnn
annotate Wnn/jserver/de.c @ 27:6bfa7ea3b75b
- resolved conflict between pointer and int
- more warning suppression
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Sat, 06 Mar 2010 18:29:27 +0900 |
parents | 466fe6732d8d |
children |
rev | line source |
---|---|
0 | 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, 2001, 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 Jserver (Nihongo Daemon) | |
30 */ | |
31 | |
32 #if defined(HAVE_CONFIG_H) | |
33 # include <config.h> | |
34 #endif | |
35 #include "getopt.h" | |
36 | |
37 #include <stdio.h> | |
38 #include <ctype.h> | |
39 #include <errno.h> | |
40 #include <signal.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 | |
51 #endif /* STDC_HEADERS */ | |
52 #include <sys/ioctl.h> | |
53 #include <sys/stat.h> | |
54 #if TIME_WITH_SYS_TIME | |
55 # include <sys/time.h> | |
56 # include <time.h> | |
57 #else | |
58 # if HAVE_SYS_TIME_H | |
59 # include <sys/time.h> | |
60 # else | |
61 # include <time.h> | |
62 # endif /* HAVE_SYS_TIME_H */ | |
63 #endif /* TIME_WITH_SYS_TIME */ | |
64 #if HAVE_UNISTD_H | |
65 # include <sys/types.h> | |
66 # include <unistd.h> | |
67 #endif | |
68 #ifdef HAVE_FCNTL_H | |
69 # include <fcntl.h> | |
70 #endif | |
71 #if HAVE_SYS_PARAM_H | |
72 # include <sys/param.h> | |
73 #endif | |
74 | |
75 #include "getopt.h" | |
76 | |
77 #include "commonhd.h" | |
78 #include "wnn_config.h" | |
79 #include "jd_sock.h" | |
80 #include "demcom.h" | |
81 #include "wnn_os.h" | |
82 #define GLOBAL_VALUE_DEFINE 1 | |
83 #include "de_header.h" | |
84 #undef GLOBAL_VALUE_DEFINE | |
85 #include "msg.h" | |
86 | |
87 #ifdef SOLARIS | |
88 #ifdef SO_DONTLINGER | |
89 #undef SO_DONTLINGER | |
90 #endif | |
91 #endif /* SOLARIS */ | |
92 | |
93 #if defined(HAVE_SETSOCKOPT) && defined(SOL_SOCKET) && defined(SO_NONBLOCK) | |
94 #define USE_SETSOCKOPT 1 | |
95 #else | |
96 #undef USE_SETSOCKOPT | |
97 #endif | |
98 | |
99 #ifndef min | |
100 #define min(x,y) ( (x)<(y) ? (x) : (y) ) | |
101 #endif | |
102 | |
103 #ifndef INET6 | |
104 # define OPTIONARGS "Df:s:h:N:p:vu4" | |
105 #else | |
106 # define OPTIONARGS "Df:s:h:N:p:vu46" | |
107 #endif /* INET6 */ | |
108 | |
109 /* Accept Socket */ | |
110 #ifdef INET6 | |
111 #define MAX_ACCEPTS 3 | |
112 #else | |
113 #define MAX_ACCEPTS 2 | |
114 #endif | |
115 #define UNIX_ACPT 0 | |
116 #define INET_ACPT 1 | |
117 #ifdef INET6 | |
118 #define INET6_ACPT 2 | |
119 #endif | |
120 | |
121 #define PROTO_ALL 0x1 | |
122 #define PROTO_UN 0x2 | |
123 #define PROTO_INET 0x4 | |
124 #ifdef INET6 | |
125 #define PROTO_INET6 0x8 | |
126 #endif | |
127 static int listen_proto = PROTO_ALL; | |
128 | |
129 jmp_buf client_dead; | |
130 | |
131 static int port; | |
132 static int serverNO = 0; | |
133 | |
134 struct cmblk | |
135 { | |
136 int sd; /** ¥½¥±¥Ã¥È¤Îfd **/ | |
137 }; | |
138 #define COMS_BLOCK struct cmblk | |
139 | |
140 static COMS_BLOCK *cblk; | |
141 /** ¥¯¥é¥¤¥¢¥ó¥È¤´¤È¤Î¥½¥±¥Ã¥È¤ò´ÉÍý¤¹¤ë¥Æ¡¼¥Ö¥ë **/ | |
142 | |
143 static COMS_BLOCK accept_blk[MAX_ACCEPTS]; /*accept sock blocks */ | |
144 | |
145 | |
146 /* Communication Buffers */ | |
147 static char snd_buf[R_BUF_SIZ]; /** Á÷¿®¥Ð¥Ã¥Õ¥¡ **/ | |
148 static int sbp; /** Á÷¿®¥Ð¥Ã¥Õ¥¡¥Ý¥¤¥ó¥¿ **/ | |
149 | |
150 static int rbc; /** ¼õ¿®¥Ð¥Ã¥Õ¥¡counter **/ | |
151 static char rcv_buf[S_BUF_SIZ]; /** ¼õ¿®¥Ð¥Ã¥Õ¥¡ **/ | |
152 | |
153 #if defined(EAGAIN) | |
154 # if defined(EWOULDBLOCK) | |
155 # define ERRNO_CHECK(no) ((no) == EAGAIN || (no) == EWOULDBLOCK) | |
156 # else /* defined(EWOULDBLOCK) */ | |
157 # define ERRNO_CHECK(no) ((no) == EAGAIN) | |
158 # endif /* defined(EWOULDBLOCK) */ | |
159 #else /* defined(EAGAIN) */ | |
160 # if defined(EWOULDBLOCK) | |
161 # define ERRNO_CHECK(no) ((no) == EWOULDBLOCK) | |
162 # else /* defined(EWOULDBLOCK) */ | |
163 # define ERRNO_CHECK(no) (0) | |
164 # endif /* defined(EWOULDBLOCK) */ | |
165 #endif /* defined(EAGAIN) */ | |
166 | |
167 /* Client Table */ | |
168 int clientp; /** cblk¤Î͸ú¤Ê¥Ç¡¼¥¿¤ÎºÇ¸å¤òº¹¤·¤Æ¤¤¤ë **/ | |
169 | |
170 int cur_clp; /** ¸½ºß¤Î¥¯¥é¥¤¥¢¥ó¥È¤ÎÈÖ¹æ **/ | |
171 | |
172 static fd_set *all_socks; /** ¥Ó¥Ã¥È¥Ñ¥¿¡¼¥ó | |
173 which jserver to select ¤òÊÝ»ý **/ | |
174 static fd_set *ready_socks; /** ¥Ç¡¼¥¿¤Î¤¤Æ¤¤¤ë¥½¥±¥Ã¥È¤Î | |
175 ¥Ó¥Ã¥È¥Ñ¥¿¡¼¥ó¤òÊÝ»ý **/ | |
176 static fd_set *dummy1_socks, *dummy2_socks; | |
177 static int no_of_ready_socks; | |
178 static int nofile; /** No. of files **/ | |
179 struct msg_cat *wnn_msg_cat; | |
180 struct msg_cat *js_msg_cat; | |
181 | |
182 /* function prototypes */ | |
183 static void daemon_main (void); | |
184 static void socket_disc_init (void); | |
185 static void sel_all (void); | |
186 static int get_client (void); | |
187 static void new_client (void); | |
188 static void daemon_init (void); | |
189 static void daemon_fin_un (int); | |
190 static void daemon_fin_in (int); | |
191 static int rcv_1_client (int); | |
192 static void snd_1_client (int, int); | |
193 static void socket_init_un (void); | |
194 static void socket_init_in (void); | |
195 static int socket_accept_un (void); | |
196 static int socket_accept_in (int); | |
197 static void xerror (char*); | |
198 static void get_options (int, char **); | |
199 static void usage (void); | |
200 static void print_version (void); | |
201 #ifdef DEBUG | |
202 static void dmp (char*, int); | |
203 #endif | |
204 | |
205 static char cmd_name[16]; | |
206 | |
207 #if defined(HAVE_LIBWRAP) | |
208 int allow_severity; | |
209 int deny_severity; | |
210 # include <syslog.h> | |
211 # include <tcpd.h> | |
212 #endif /* HAVE_LIBWRAP */ | |
213 | |
214 /* No arguments are used. Only options. */ | |
215 int | |
216 main (int argc, char *argv[]) | |
217 { | |
218 char *cswidth_name; | |
219 extern char *get_cswidth_name (); | |
220 extern void set_cswidth (); | |
221 | |
222 char nlspath[64]; | |
223 | |
224 strcpy (cmd_name, WNN_DAEMON_NAME); | |
225 strcpy (lang_dir, LANG_NAME); | |
226 strcpy (nlspath, LIBDIR); | |
227 strcat (nlspath, "/%L/%N"); | |
228 js_msg_cat = msg_open (MESSAGE_FILE, nlspath, lang_dir); | |
229 wnn_msg_cat = msg_open ("libwnn.msg", nlspath, lang_dir); | |
230 if (wnn_msg_cat == NULL) | |
231 { | |
232 log_err ("cannot open message file libwnn.msg."); | |
233 } | |
3 | 234 if ((cswidth_name = get_cswidth_name (LANG_NAME)) != NULL) |
0 | 235 set_cswidth (create_cswidth (cswidth_name)); |
236 | |
237 port = -1; | |
238 /* option default */ | |
239 option_flag = (OPT_FORK & ~OPT_VERBOSE); | |
240 | |
241 setuid (geteuid ()); | |
242 get_options (argc, argv); | |
243 print_version(); | |
244 log_debug("invoked as %s.", argv[0]); | |
245 if (option_flag & OPT_FORK) | |
246 { | |
247 if (fork ()) | |
248 { | |
249 signal (SIGCHLD, _exit); | |
250 signal (SIGHUP, SIG_IGN); | |
251 signal (SIGINT, SIG_IGN); | |
252 signal (SIGQUIT, SIG_IGN); | |
253 #ifdef SIGTSTP | |
254 signal (SIGTSTP, SIG_IGN); | |
255 #endif | |
256 signal (SIGTERM, _exit); | |
257 pause (); | |
258 } | |
259 } | |
260 | |
261 #if defined(HAVE_LIBWRAP) | |
262 allow_severity = LOG_INFO; | |
263 deny_severity = LOG_WARNING; | |
264 /* hosts_access_verbose = 2; */ | |
265 #endif /* HAVE_LIBWRAP */ | |
266 | |
267 signal (SIGHUP, signal_hand); | |
268 signal (SIGINT, signal_hand); | |
269 signal (SIGQUIT, signal_hand); | |
270 signal (SIGTERM, terminate_hand); | |
271 if (option_flag & OPT_FORK) | |
272 { | |
273 #ifdef SIGTSTP | |
274 signal (SIGTSTP, SIG_IGN); | |
275 #endif /* SIGTSTP */ | |
276 } | |
277 read_default (); | |
278 daemon_init (); | |
279 | |
280 env_init (); | |
1 | 281 if (!file_init ()) |
0 | 282 { |
283 exit (1); | |
284 } | |
285 dic_init (); | |
1 | 286 if (!get_kaiseki_area (LENGTHCONV + 1)) /* ÊÑ´¹²Äǽʸ»ú¿ô */ |
0 | 287 { |
288 log_err ("get_kaiseki_area failed."); | |
289 exit (1); | |
290 } | |
291 init_work_areas (); | |
292 init_jmt (); | |
293 | |
294 read_default_files (); | |
295 | |
296 if (option_flag & OPT_FORK) | |
297 { | |
298 /* End of initialization, kill parent */ | |
299 kill (getppid (), SIGTERM); | |
300 fclose (stdin); | |
301 fclose (stdout); | |
302 if (!(option_flag & OPT_VERBOSE)) | |
303 { | |
304 #if !(defined(BSD) && (BSD >= 199306)) /* !4.4BSD-Lite by Taoka */ | |
305 fclose (stderr); | |
306 #else /* 4.4BSD-Lite */ | |
307 int fd = open ("/dev/null", O_WRONLY); | |
308 if (fd < 0) | |
309 { | |
310 xerror ("Cannot open /dev/null"); | |
311 } | |
312 dup2 (fd, 2); | |
313 close (fd); | |
314 #endif /* 4.4BSD-Lite */ | |
315 } | |
316 | |
317 #ifdef SETPGRP_VOID | |
318 setpgrp (); | |
319 #else /* !SETPGRP_VOID */ | |
320 # if !defined(TIOCNOTTY) && defined(SVR4) | |
321 # define TIOCNOTTY _IO('t', 113) | |
322 # endif /* !defined(TIOCNOTTY) && defined(SVR4) */ | |
323 #ifndef HITACHI | |
27
6bfa7ea3b75b
- resolved conflict between pointer and int
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
25
diff
changeset
|
324 int tmpttyfd; |
6bfa7ea3b75b
- resolved conflict between pointer and int
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
25
diff
changeset
|
325 if ((tmpttyfd = open ("/dev/tty", O_RDWR)) >= 0) |
0 | 326 { |
327 ioctl (tmpttyfd, TIOCNOTTY, 0); | |
328 close (tmpttyfd); | |
329 } | |
330 #endif /* HITACHI */ | |
331 #endif /* SETPGRP_VOID */ | |
332 } | |
333 | |
334 daemon_main (); | |
335 | |
336 daemon_fin (); | |
337 return (0); /* it is not reached. only for avoiding compiler warning. */ | |
338 } | |
339 | |
340 static void | |
341 daemon_main (void) | |
342 { | |
343 for (;;) | |
344 { | |
345 c_c = NULL; /* Added for logging: server section */ | |
346 sel_all (); | |
347 new_client (); | |
348 for (;;) | |
349 { | |
350 if (get_client () == -1) | |
351 break; | |
352 c_c = &client[cur_clp]; | |
353 rbc = 0; | |
354 sbp = 0; | |
355 /* if(rcv_1_client(cur_clp) == 0){ del_client(); continue; } */ | |
356 if (setjmp (client_dead)) | |
357 { | |
358 del_client (); | |
359 continue; | |
360 } | |
361 do_command (c_c); | |
362 } | |
363 } | |
364 } | |
365 | |
366 /* | |
367 allocs area for selecting socketts | |
368 */ | |
369 static void | |
370 socket_disc_init (void) | |
371 { | |
372 if (WNN_NFD <= FD_SETSIZE) | |
373 { | |
374 nofile = WNN_NFD; | |
375 } | |
376 else | |
377 { | |
378 nofile = FD_SETSIZE; | |
379 } | |
380 all_socks = (fd_set *) malloc (sizeof (fd_set)); | |
381 FD_ZERO (all_socks); | |
382 ready_socks = (fd_set *) malloc (sizeof (fd_set)); | |
383 dummy1_socks = (fd_set *) malloc (sizeof (fd_set)); | |
384 dummy2_socks = (fd_set *) malloc (sizeof (fd_set)); | |
385 } | |
386 | |
387 /** Á´¤Æ¤Î¥½¥±¥Ã¥È¤Ë¤Ä¤¤¤ÆÂÔ¤Ä **/ | |
388 static void | |
389 sel_all (void) | |
390 { | |
391 memcpy (ready_socks, all_socks, sizeof (fd_set)); | |
392 bzero (dummy1_socks, sizeof (fd_set)); | |
393 bzero (dummy2_socks, sizeof (fd_set)); | |
394 | |
395 top: | |
396 errno = 0; | |
397 if ((no_of_ready_socks = select (nofile, ready_socks, dummy1_socks, dummy2_socks, NULL)) == -1) | |
398 { | |
399 if (errno == EINTR) | |
400 goto top; | |
401 xerror ("select error"); | |
402 } | |
403 #ifdef DEBUG | |
404 log_debug ("select OK, ready_socks[0]=%02X, n-r-s=%x\n", ready_socks[0], no_of_ready_socks); | |
405 #endif | |
406 } | |
407 | |
408 /** ready_socks¤«¤éº£¤ä¤ë°ì¿Í¤ò¼è¤ê½Ð¤·¤ÆÊÖ¤¹(cur_clp¤Ë¤â¥»¥Ã¥È¤¹¤ë) | |
409 ï¤âµï¤Ê¤¤»þ¤Ï-1 | |
410 ¥¹¥±¥¸¥å¡¼¥ê¥ó¥°¤Ï¥é¥¦¥ó¥É¥í¥Ó¥ó **/ | |
411 static int | |
412 get_client (void) | |
413 { | |
414 int i; | |
415 | |
416 if (no_of_ready_socks == 0) | |
417 return -1; /* no client waits service */ | |
418 | |
419 for (i = cur_clp;;) | |
420 { | |
421 if (no_of_ready_socks == 0) | |
422 return -1; | |
423 i++; | |
424 if (i >= clientp) | |
425 i = 0; | |
426 if (FD_ISSET (cblk[i].sd, ready_socks)) | |
427 { | |
428 FD_CLR (cblk[i].sd, ready_socks); | |
429 no_of_ready_socks--; | |
430 return cur_clp = i; | |
431 } | |
432 } | |
433 } | |
434 | |
435 /** ¿·¤·¤¤¥¯¥é¥¤¥¢¥ó¥È¤¬µï¤ë¤«Èݤ«¤òÄ´¤Ù¤ë | |
436 µï¤¿¾ì¹ç¤Ïcblk¤ËÅÐÏ¿¤¹¤ë **/ | |
437 static void | |
438 new_client (void) /* NewClient */ | |
439 { | |
440 int sd; | |
441 int full, i; | |
442 FILE *f[3]; | |
443 char gomi[1024]; | |
444 #ifdef HAVE_LIBWRAP | |
445 int is_internet_socket; | |
446 struct request_info tcpd_request; | |
447 #endif /* HAVE_LIBWRAP */ | |
448 #ifdef AF_UNIX | |
449 if ((serverNO == 0) && | |
450 (FD_ISSET (accept_blk[UNIX_ACPT].sd, ready_socks))) | |
451 { | |
452 FD_CLR (accept_blk[UNIX_ACPT].sd, ready_socks); | |
453 no_of_ready_socks--; | |
454 sd = socket_accept_un (); | |
455 #ifdef HAVE_LIBWRAP | |
456 is_internet_socket = 0; | |
457 #endif | |
458 } | |
459 else | |
460 #endif | |
461 #ifdef INET6 | |
462 if (FD_ISSET (accept_blk[INET6_ACPT].sd, ready_socks)) | |
463 { | |
464 FD_CLR (accept_blk[INET6_ACPT].sd, ready_socks); | |
465 no_of_ready_socks--; | |
466 sd = socket_accept_in (accept_blk[INET6_ACPT].sd); | |
467 #ifdef HAVE_LIBWRAP | |
468 is_internet_socket = 1; | |
469 #endif | |
470 } | |
471 else | |
472 #endif | |
473 if (FD_ISSET (accept_blk[INET_ACPT].sd, ready_socks)) | |
474 { | |
475 FD_CLR (accept_blk[INET_ACPT].sd, ready_socks); | |
476 no_of_ready_socks--; | |
477 sd = socket_accept_in (accept_blk[INET_ACPT].sd); | |
478 #ifdef HAVE_LIBWRAP | |
479 is_internet_socket = 1; | |
480 #endif | |
481 } | |
482 else | |
483 { | |
484 return; | |
485 } | |
486 log_debug ("new client: sd = %d", sd); | |
487 /* reserve 2 fd */ | |
488 for (full = i = 0; i < 2; i++) | |
489 { | |
490 if (NULL == (f[i] = fopen ("/dev/null", "r"))) | |
491 { | |
492 full = 1; | |
493 } | |
494 } | |
495 for (i = 0; i < 2; i++) | |
496 { | |
497 if (NULL != f[i]) | |
498 fclose (f[i]); | |
499 } | |
500 | |
501 if (full || sd >= nofile || clientp >= max_client) | |
502 { | |
503 log_err ("no more client."); | |
504 #ifdef HAVE_RECV | |
505 recv (sd, gomi, 1024, 0); | |
506 #else | |
507 read (sd, gomi, 1024); | |
508 #endif | |
509 shutdown (sd, 2); | |
510 #ifdef HAVE_CLOSESOCKET | |
511 closesocket (sd); | |
512 #else | |
513 close (sd); | |
514 #endif | |
515 return; | |
516 } | |
517 | |
518 #ifdef HAVE_LIBWRAP | |
519 if (is_internet_socket) { | |
520 request_init (&tcpd_request,RQ_DAEMON, WNN_DAEMON_NAME, | |
521 RQ_FILE, sd, NULL); | |
522 fromhost (&tcpd_request); | |
523 if (!hosts_access (&tcpd_request)) | |
524 { | |
525 log_err ("reject client."); /* should be log_info? */ | |
526 /* should we log IP address / hostname? */ | |
527 #ifdef HAVE_RECV | |
528 recv (sd, gomi, 1024, 0); | |
529 #else | |
530 read (sd, gomi, 1024); | |
531 #endif | |
532 shutdown (sd, 2); | |
533 #ifdef HAVE_CLOSESOCKET | |
534 closesocket (sd); | |
535 #else | |
536 close (sd); | |
537 #endif | |
538 return; | |
539 } | |
540 } | |
541 #endif /* HAVE_LIBWRAP */ | |
542 | |
543 cblk[clientp].sd = sd; | |
544 FD_SET (sd, all_socks); | |
545 for (i = 0; i < WNN_MAX_ENV_OF_A_CLIENT; i++) | |
546 { | |
547 (client[clientp].env)[i] = -1; | |
548 } | |
549 clientp++; | |
550 } | |
551 | |
552 /** ¥¯¥é¥¤¥¢¥ó¥È¤òcblk¤«¤éºï½ü¤¹¤ë **/ | |
553 /* delete Client (please call from JS_CLOSE) */ | |
554 void | |
555 del_client (void) | |
556 { | |
557 disconnect_all_env_of_client (); | |
558 FD_CLR (cblk[cur_clp].sd, all_socks); | |
559 #ifdef HAVE_CLOSESOCKET | |
560 closesocket (cblk[cur_clp].sd); | |
561 #else | |
562 close (cblk[cur_clp].sd); | |
563 #endif | |
564 /* logging here because c_c (used in log_debug) will be broken after | |
565 following section */ | |
566 log_debug("Delete Client: cur_clp = %d\n", cur_clp); | |
567 cblk[cur_clp] = cblk[clientp - 1]; | |
568 client[cur_clp] = client[clientp - 1]; | |
569 /* Clear host/user name with zero - needed for logging */ | |
570 client[clientp - 1].user_name[0] = '\0'; /* Should we use bzero()? */ | |
571 client[clientp - 1].host_name[0] = '\0'; | |
572 clientp--; | |
573 } | |
574 | |
575 | |
576 /** ¥µ¡¼¥Ð¤ò¥¤¥Ë¥·¥ã¥é¥¤¥º¤¹¤ë **/ | |
577 static void | |
578 daemon_init (void) /* initialize Daemon */ | |
579 { | |
580 /* | |
581 signal (SIGHUP, SIG_IGN); | |
582 signal (SIGINT, SIG_IGN); | |
583 signal (SIGQUIT, SIG_IGN); | |
584 */ | |
585 | |
586 | |
587 if ((cblk = (COMS_BLOCK *) malloc (max_client * sizeof (COMS_BLOCK))) == NULL) | |
588 { | |
589 xerror ("daemon_init: "); | |
590 } | |
591 if ((client = (CLIENT *) malloc (max_client * sizeof (CLIENT))) == NULL) | |
592 { | |
593 xerror ("daemon_init: "); | |
594 } | |
595 SDRAND (time (NULL)); | |
596 clientp = 0; /* V3.0 */ | |
597 cur_clp = 0; /* V3.0 */ | |
598 socket_disc_init (); | |
599 #ifdef INET6 | |
600 if (listen_proto&(PROTO_ALL|PROTO_INET|PROTO_INET6)) | |
601 socket_init_in (); | |
602 #else | |
603 if (listen_proto&(PROTO_ALL|PROTO_INET)) | |
604 socket_init_in (); | |
605 #endif | |
606 #ifdef AF_UNIX | |
607 if (listen_proto&(PROTO_ALL|PROTO_UN)) | |
608 socket_init_un (); | |
609 #endif /* AF_UNIX */ | |
610 } | |
611 | |
612 /** ¥µ¡¼¥Ð¤ò½ª¤ï¤ë **/ | |
613 #ifdef AF_UNIX | |
614 static void | |
615 daemon_fin_un (int sock_d_un) | |
616 { | |
617 int trueFlag = 1; | |
618 struct sockaddr_un addr_un; | |
619 socklen_t addrlen; | |
620 | |
621 if (serverNO == 0) | |
622 { | |
623 #ifndef SOLARIS | |
624 #if defined(FIONBIO) | |
625 ioctl (sock_d_un, FIONBIO, &trueFlag); | |
626 #endif | |
627 #else /* !SOLARIS */ | |
628 fcntl (sock_d_un, F_SETFL, F_UNLCK); | |
629 #endif /* !SOLARIS */ | |
630 for (;;) | |
631 { | |
632 addrlen = sizeof (addr_un); | |
633 if (accept (sock_d_un, (struct sockaddr *) &addr_un, &addrlen) < 0) | |
634 break; | |
635 /* EWOULDBLOCK EXPECTED, but we don't check */ | |
636 } | |
637 shutdown (sock_d_un, 2); | |
638 close (sock_d_un); | |
639 } | |
640 } | |
641 #endif /* AF_UNIX */ | |
642 | |
643 static void | |
644 daemon_fin_in (int sock_d_in) | |
645 { | |
646 int trueFlag = 1; | |
647 struct sockaddr_in addr_in; | |
648 socklen_t addrlen; | |
649 #ifdef USE_SETSOCKOPT | |
650 int on = ~0; | |
651 #endif | |
652 | |
653 #ifndef SOLARIS | |
654 #ifdef USE_SETSOCKOPT | |
655 setsockopt (sock_d_in, SOL_SOCKET, SO_NONBLOCK, &on, sizeof (int)); | |
656 #else | |
657 #if defined(FIONBIO) | |
658 ioctl (sock_d_in, FIONBIO, &trueFlag); | |
659 #endif | |
660 #endif /* USE_SETSOCKOPT */ | |
661 #else /* !SOLARIS */ | |
662 fcntl (sock_d_in, F_SETFL, F_UNLCK); | |
663 #endif /* !SOLARIS */ | |
664 for (;;) | |
665 { | |
666 addrlen = sizeof (addr_in); | |
667 if (accept (sock_d_in, (struct sockaddr *) &addr_in, &addrlen) < 0) | |
668 break; | |
669 /* EWOULDBLOCK EXPECTED, but we don't check */ | |
670 } | |
671 shutdown (sock_d_in, 2); | |
672 #ifdef HAVE_CLOSESOCKET | |
673 closesocket (sock_d_in); | |
674 #else | |
675 close (sock_d_in); | |
676 #endif | |
677 } | |
678 | |
679 void | |
680 daemon_fin (void) | |
681 { | |
682 int fd; | |
683 #ifdef AF_UNIX | |
684 int sock_d_un = accept_blk[UNIX_ACPT].sd; | |
685 #endif /* AF_UNIX */ | |
686 int sock_d_in = accept_blk[INET_ACPT].sd; | |
687 #ifdef INET6 | |
688 int sock_d_in6 = accept_blk[INET6_ACPT].sd; | |
689 #endif | |
690 | |
691 /* | |
692 accept all pending connection from new clients, | |
693 avoiding kernel hangup. | |
694 */ | |
695 #ifdef AF_UNIX | |
696 daemon_fin_un (sock_d_un); | |
697 #endif | |
698 daemon_fin_in (sock_d_in); | |
699 #ifdef INET6 | |
700 daemon_fin_in (sock_d_in6); | |
701 #endif | |
702 | |
703 for (fd = nofile - 1; fd >= 0; fd--) | |
704 { | |
705 if ((fd != sock_d_in) && | |
706 #ifdef INET6 | |
707 (fd != sock_d_in6) && | |
708 #endif | |
709 #ifdef AF_UNIX | |
710 (fd != sock_d_un) && | |
711 #endif /* AF_UNIX */ | |
712 FD_ISSET (fd, all_socks)) | |
713 { | |
714 shutdown (fd, 2); | |
715 #ifdef HAVE_CLOSESOCKET | |
716 closesocket (fd); | |
717 #else | |
718 close (fd); | |
719 #endif | |
720 } | |
721 } | |
722 } | |
723 | |
724 /*------*/ | |
725 | |
726 /** **/ | |
727 char * | |
728 gets_cur (char *buffer, size_t buffer_size) | |
729 { | |
730 char *b; | |
731 | |
732 if (!buffer || !buffer_size) | |
733 return NULL; | |
734 | |
735 b = buffer; | |
736 | |
737 while (--buffer_size && (*b = getc_cur ()) != '\0') | |
738 b++; | |
739 | |
740 if (!buffer_size) | |
741 { | |
742 *b = '\0'; | |
743 while (getc_cur () != '\0') | |
744 ; | |
745 } | |
746 | |
747 return buffer; | |
748 } | |
749 | |
750 /** **/ | |
751 w_char * | |
752 getws_cur (w_char *buffer, size_t buffer_size) | |
753 { | |
754 w_char *b; | |
755 | |
756 if (!buffer || !buffer_size) | |
757 return NULL; | |
758 | |
759 b = buffer; | |
760 | |
761 while (--buffer_size && (*b = get2_cur ()) != 0) | |
762 b++; | |
763 | |
764 if (!buffer_size) | |
765 { | |
766 *b = 0; | |
767 while (getc_cur () != 0) | |
768 ; | |
769 } | |
770 | |
771 return buffer; | |
772 } | |
773 | |
774 /** ¥«¥ì¥ó¥È¡¦¥¯¥é¥¤¥¢¥ó¥È¤«¤é2¥Ð¥¤¥È¼è¤ë **/ | |
775 int | |
776 get2_cur (void) | |
777 { | |
778 int x; | |
779 x = getc_cur (); | |
780 return (x << 8) | getc_cur (); | |
781 } | |
782 | |
783 /** ¥«¥ì¥ó¥È¡¦¥¯¥é¥¤¥¢¥ó¥È¤«¤é4¥Ð¥¤¥È¼è¤ë **/ | |
784 int | |
785 get4_cur (void) | |
786 { | |
787 int x1, x2, x3; | |
788 x1 = getc_cur (); | |
789 x2 = getc_cur (); | |
790 x3 = getc_cur (); | |
791 return (x1 << (8 * 3)) | (x2 << (8 * 2)) | (x3 << (8 * 1)) | getc_cur (); | |
792 } | |
793 | |
794 /** ¥«¥ì¥ó¥È¡¦¥¯¥é¥¤¥¢¥ó¥È¤«¤é1¥Ð¥¤¥È¼è¤ë **/ | |
795 int | |
796 getc_cur (void) | |
797 { | |
798 static int rbp; | |
799 if (rbc <= 0) | |
800 { | |
801 rbc = rcv_1_client (cur_clp); | |
802 rbp = 0; | |
803 } | |
804 rbc--; | |
805 return rcv_buf[rbp++] & 0xFF; | |
806 } | |
807 | |
808 /** ¥¯¥é¥¤¥¢¥ó¥È¤«¤é1¥Ñ¥±¥Ã¥È¼è¤ë **/ | |
809 static int | |
810 rcv_1_client (int clp) /* clp=¥¯¥é¥¤¥¢¥ó¥ÈÈÖ¹æ */ | |
811 { | |
812 int cc = 0; | |
813 while (cc <= 0) | |
814 { | |
815 errno = 0; | |
816 #ifdef HAVE_RECV | |
817 cc = recv (cblk[clp].sd, rcv_buf, S_BUF_SIZ, 0); | |
818 #else | |
819 cc = read (cblk[clp].sd, rcv_buf, S_BUF_SIZ); | |
820 #endif | |
821 if (cc <= 0) | |
822 { | |
823 if (ERRNO_CHECK (errno)) | |
824 { | |
825 continue; | |
826 } | |
827 else if (cc == 0) | |
828 { /* client dead */ | |
829 longjmp (client_dead, 666); | |
830 } | |
831 else | |
832 { /* cc == -1 */ | |
833 if (errno != EINTR) | |
834 longjmp (client_dead, 666); | |
835 continue; | |
836 } | |
837 } | |
838 } | |
839 #ifdef DEBUG | |
840 log_debug ("rcv: clp = %d, sd = %d, cc = %d", clp, cblk[clp].sd, cc); | |
841 dmp (rcv_buf, cc); | |
842 #endif | |
843 return cc; | |
844 } | |
845 | |
846 /** ¥¯¥é¥¤¥¢¥ó¥È¤Ø1¥Ñ¥±¥Ã¥ÈÁ÷¤ë **/ | |
847 static void | |
848 snd_1_client (int clp, /* clp: ¥¯¥é¥¤¥¢¥ó¥ÈÈÖ¹æ */ | |
849 int n /* n : number of bytes to send */ ) | |
850 { | |
851 int cc, x; | |
852 #ifdef DEBUG | |
853 log_debug ("snd: clp = %d, sd = %d", clp, cblk[clp].sd); | |
854 dmp (snd_buf, n); | |
855 #endif | |
856 for (cc = 0; cc < n;) | |
857 { | |
858 errno = 0; | |
859 #ifdef HAVE_SEND | |
860 x = send (cblk[clp].sd, &snd_buf[cc], n - cc, 0); | |
861 #else | |
862 x = write (cblk[clp].sd, &snd_buf[cc], n - cc); | |
863 #endif | |
864 if (x < 0) | |
865 { | |
866 if (ERRNO_CHECK (errno) || errno == EINTR) | |
867 { | |
868 errno = 0; | |
869 continue; | |
870 } | |
871 else | |
872 { /* client dead */ | |
873 longjmp (client_dead, 666); | |
874 } | |
875 } | |
876 cc += x; | |
877 } | |
878 } | |
879 | |
880 /** **/ | |
881 void | |
882 puts_cur (char *p) | |
883 { | |
884 int c; | |
3 | 885 while ((c = *p++) != '\0') |
0 | 886 putc_cur (c); |
887 putc_cur (0); | |
888 } | |
889 | |
890 /** **/ | |
891 void | |
892 puts_n_cur (char *p, int n) | |
893 { | |
894 int c; | |
895 while ((c = *p++) && --n >= 0) | |
896 putc_cur (c); | |
897 putc_cur (0); | |
898 } | |
899 | |
900 /** **/ | |
901 void | |
902 putws_cur (w_char *p) | |
903 { | |
904 int c; | |
3 | 905 while ((c = *p++) != '\0') |
0 | 906 put2_cur (c); |
907 put2_cur (0); | |
908 } | |
909 | |
910 /** **/ | |
911 void | |
912 putnws_cur (w_char *p, int n) | |
913 { | |
914 int c; | |
915 for (; n > 0; n--) | |
916 { | |
917 if ((c = *p++) == 0) | |
918 break; | |
919 put2_cur (c); | |
920 } | |
921 put2_cur (0); | |
922 } | |
923 | |
924 /** ¥«¥ì¥ó¥È¡¦¥¯¥é¥¤¥¢¥ó¥È¤Ø2¥Ð¥¤¥ÈÁ÷¤ë **/ | |
925 void | |
926 put2_cur (int c) | |
927 { | |
928 putc_cur (c >> (8 * 1)); | |
929 putc_cur (c); | |
930 } | |
931 | |
932 /** ¥«¥ì¥ó¥È¡¦¥¯¥é¥¤¥¢¥ó¥È¤Ø4¥Ð¥¤¥ÈÁ÷¤ë **/ | |
933 void | |
934 put4_cur (int c) | |
935 { | |
936 putc_cur (c >> (8 * 3)); | |
937 putc_cur (c >> (8 * 2)); | |
938 putc_cur (c >> (8 * 1)); | |
939 putc_cur (c); | |
940 } | |
941 | |
942 /** ¥«¥ì¥ó¥È¡¦¥¯¥é¥¤¥¢¥ó¥È¤Ø1¥Ð¥¤¥ÈÁ÷¤ë **/ | |
943 void | |
944 putc_cur (int c) | |
945 { | |
946 snd_buf[sbp++] = c; | |
947 if (sbp >= R_BUF_SIZ) | |
948 { | |
949 snd_1_client (cur_clp, R_BUF_SIZ); | |
950 sbp = 0; | |
951 } | |
952 } | |
953 | |
954 /** ¥«¥ì¥ó¥È¡¦¥¯¥é¥¤¥¢¥ó¥È¤ÎÁ÷¿®¥Ð¥Ã¥Õ¥¡¤ò¥Õ¥é¥Ã¥·¥å¤¹¤ë **/ | |
955 void | |
956 putc_purge (void) | |
957 { | |
958 if (sbp != 0) | |
959 { | |
960 snd_1_client (cur_clp, sbp); | |
961 sbp = 0; | |
962 } | |
963 } | |
964 | |
965 /*-----*/ | |
966 | |
967 /** ¥½¥±¥Ã¥È¤Î¥¤¥Ë¥·¥ã¥é¥¤¥º **/ | |
968 #ifdef AF_UNIX | |
969 static void | |
970 socket_init_un (void) | |
971 { | |
972 struct sockaddr_un saddr_un; | |
973 int sock_d_un; | |
974 if (serverNO == 0) | |
975 { | |
976 saddr_un.sun_family = AF_UNIX; | |
977 unlink (sockname); | |
978 strcpy (saddr_un.sun_path, sockname); | |
979 if ((sock_d_un = socket (AF_UNIX, SOCK_STREAM, 0)) == ERROR) | |
980 { | |
981 xerror ("could not create unix domain socket"); | |
982 } | |
983 if (bind (sock_d_un, (struct sockaddr *) &saddr_un, strlen (saddr_un.sun_path) + 2) == ERROR) | |
984 { | |
985 shutdown (sock_d_un, 2); | |
986 xerror ("could not bind unix domain socket"); | |
987 } | |
988 if (listen (sock_d_un, 5) == ERROR) | |
989 { | |
990 shutdown (sock_d_un, 2); | |
991 xerror ("could not listen unix domain socket"); | |
992 } | |
993 chmod (sockname, 0777); | |
994 signal (SIGPIPE, SIG_IGN); | |
995 #ifdef DEBUG | |
996 log_debug ("sock_d_un = %d", sock_d_un); | |
997 #endif | |
998 accept_blk[UNIX_ACPT].sd = sock_d_un; | |
999 FD_SET (sock_d_un, all_socks); | |
1000 } | |
1001 } | |
1002 #endif /* AF_UNIX */ | |
1003 | |
1004 /* Inet V3.0 */ | |
1005 static void | |
1006 socket_init_in (void) | |
1007 { | |
1008 #ifndef SOLARIS | |
1009 int on = 1; | |
1010 #else /* SOLARIS */ | |
1011 int on = 0; | |
1012 #endif /* SOLARIS */ | |
1013 struct servent *sp; | |
1014 #if !defined(SO_DONTLINGER) && defined(SO_LINGER) | |
1015 struct linger linger; | |
1016 #endif | |
1017 #ifdef INET6 | |
1018 struct addrinfo hints, *res, *res0; | |
1019 int error; | |
1020 char sport[6]; | |
1021 #else | |
1022 struct sockaddr_in saddr_in; | |
1023 #endif | |
1024 int sock_d_in; | |
1025 | |
1026 if (port < 0) | |
1027 { | |
1028 if ((sp = getservbyname (SERVERNAME, "tcp")) == NULL) | |
1029 { | |
1030 port = WNN_PORT_IN; | |
1031 } | |
1032 else | |
1033 { | |
1034 port = ntohs (sp->s_port); | |
1035 } | |
1036 } | |
1037 | |
1038 port += serverNO; | |
1039 | |
1040 #if DEBUG | |
1041 log_debug ("port=%x", port); | |
1042 #endif | |
1043 #ifdef INET6 | |
1044 memset(&hints, 0, sizeof(hints)); | |
1045 if (listen_proto&PROTO_INET && !(listen_proto&PROTO_INET6)) | |
1046 hints.ai_family = PF_INET; | |
1047 else if (listen_proto&PROTO_INET6 && !(listen_proto&PROTO_INET)) | |
1048 hints.ai_family = PF_INET6; | |
1049 else | |
1050 hints.ai_family = PF_UNSPEC; | |
1051 hints.ai_socktype = SOCK_STREAM; | |
1052 hints.ai_flags = AI_PASSIVE; | |
1053 sprintf(sport, "%d", port); | |
1054 error = getaddrinfo(NULL, sport, &hints, &res0); | |
1055 if (error) | |
1056 { | |
1057 xerror (gai_strerror(error)); | |
1058 } | |
1059 for (res = res0; res; res = res->ai_next) { | |
1060 if (res->ai_family == AF_INET || res->ai_family == AF_INET6){ | |
1061 if ((sock_d_in = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) == ERROR) | |
1062 #else | |
1063 saddr_in.sin_family = AF_INET; | |
1064 saddr_in.sin_port = htons (port); | |
1065 saddr_in.sin_addr.s_addr = htonl (INADDR_ANY); | |
1066 if ((sock_d_in = socket (AF_INET, SOCK_STREAM, 0)) == ERROR) | |
1067 #endif | |
1068 { | |
1069 #ifdef INET6 | |
1070 if (res->ai_family == AF_INET6) | |
1071 xerror ("could not create inet6 socket"); | |
1072 else if (res->ai_family == AF_INET) | |
1073 #endif | |
1074 xerror ("could not create inet socket"); | |
1075 } | |
1076 setsockopt (sock_d_in, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (int)); | |
1077 #ifdef SO_DONTLINGER | |
25
466fe6732d8d
- fixed more NULL pointer related errata
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
3
diff
changeset
|
1078 setsockopt (sock_d_in, SOL_SOCKET, SO_DONTLINGER, NULL, 0); |
0 | 1079 #else |
1080 # ifdef SO_LINGER | |
1081 linger.l_onoff = 0; | |
1082 linger.l_linger = 0; | |
1083 setsockopt (sock_d_in, SOL_SOCKET, SO_LINGER, (char *) &linger, sizeof linger); | |
1084 # endif /* SO_LINGER */ | |
1085 #endif /* SO_DONTLINGER */ | |
1086 | |
1087 #ifdef INET6 | |
1088 if (bind (sock_d_in, res->ai_addr, res->ai_addrlen) == ERROR) | |
1089 #else | |
1090 if (bind (sock_d_in, (struct sockaddr *) &saddr_in, sizeof (saddr_in)) == ERROR) | |
1091 #endif | |
1092 { | |
1093 shutdown (sock_d_in, 2); | |
1094 #ifdef INET6 | |
1095 if (res->ai_family == AF_INET6) | |
1096 xerror ("can't bind inet6 socket"); | |
1097 else if (res->ai_family == AF_INET) | |
1098 #endif | |
1099 xerror ("can't bind inet socket"); | |
1100 } | |
1101 if (listen (sock_d_in, 5) == ERROR) | |
1102 { | |
1103 shutdown (sock_d_in, 2); | |
1104 #ifdef INET6 | |
1105 if (res->ai_family == AF_INET6) | |
1106 xerror ("can't listen inet6 socket"); | |
1107 else if (res->ai_family == AF_INET) | |
1108 #endif | |
1109 xerror ("can't listen inet socket"); | |
1110 } | |
1111 #if DEBUG | |
1112 log_debug ("sock_d_in = %d", sock_d_in); | |
1113 #endif | |
1114 FD_SET (sock_d_in, all_socks); | |
1115 #ifdef INET6 | |
1116 if (res->ai_family == AF_INET) | |
1117 accept_blk[INET_ACPT].sd = sock_d_in; | |
1118 else if (res->ai_family == AF_INET6) | |
1119 accept_blk[INET6_ACPT].sd = sock_d_in; | |
1120 } | |
1121 } | |
1122 freeaddrinfo(res0); | |
1123 #else | |
1124 accept_blk[INET_ACPT].sd = sock_d_in; | |
1125 #endif | |
1126 } | |
1127 | |
1128 | |
1129 /** accept new client socket **/ | |
1130 #ifdef AF_UNIX | |
1131 static int | |
1132 socket_accept_un (void) | |
1133 { | |
1134 struct sockaddr_un addr; | |
1135 socklen_t addrlen; | |
1136 | |
1137 addrlen = sizeof (addr); | |
1138 return accept (accept_blk[UNIX_ACPT].sd, (struct sockaddr *) &addr, &addrlen); | |
1139 } | |
1140 #endif /* AF_UNIX */ | |
1141 | |
1142 static int | |
1143 socket_accept_in (int fd) | |
1144 { | |
1145 struct sockaddr_in addr; | |
1146 socklen_t addrlen; | |
1147 | |
1148 addrlen = sizeof (addr); | |
1149 return accept (fd, (struct sockaddr *) &addr, &addrlen); | |
1150 } | |
1151 | |
1152 static void | |
1153 xerror (char *s) | |
1154 { | |
1155 log_err ("%s (%s).", s, strerror(errno)); | |
1156 exit (1); | |
1157 } | |
1158 | |
1159 #if DEBUG | |
1160 static void | |
1161 dmp (char *p, int n) | |
1162 { | |
1163 int i, j; | |
1164 | |
1165 for (i = 0; i < n; i += 16) | |
1166 { | |
1167 for (j = 0; j < 16; j++) | |
1168 { | |
1169 fprintf (stderr, "%02x ", p[i + j] & 0xFF); | |
1170 } | |
1171 fprintf (stderr, "n=%d\n", n); | |
1172 } | |
1173 } | |
1174 #endif | |
1175 | |
1176 static void | |
1177 get_options (int argc, char **argv) | |
1178 { | |
1179 int c; | |
1180 | |
1181 strcpy (jserverrcfile, LIBDIR); /* usr/local/lib/wnn */ | |
1182 strcat (jserverrcfile, SERVER_INIT_FILE); /* ja_JP/jserverrc */ | |
1183 | |
1184 while (1) | |
1185 { | |
1186 int option_index = 0; | |
1187 static struct option long_options[] = | |
1188 { | |
1189 {"baseport", 1, NULL, 'p'}, | |
1190 {"inet", 0, NULL, '4'}, | |
1191 {"inet6", 0, NULL, '6'}, | |
1192 {"jserverrc", 1, NULL, 'f'}, | |
1193 {"version", 0, NULL, 'v'}, | |
1194 {0, 0, 0, 0} | |
1195 }; | |
1196 | |
1197 c = getopt_long (argc, argv, OPTIONARGS, | |
1198 long_options, &option_index); | |
1199 if (c == -1) | |
1200 break; | |
1201 | |
1202 switch (c) | |
1203 { | |
1204 case 'D': /* do not detach, not a daemon */ | |
1205 option_flag &= ~OPT_FORK; | |
1206 break; | |
1207 | |
1208 case 'f': /* --jserverrc FILENAME */ | |
1209 strcpy (jserverrcfile, optarg); | |
1210 break; | |
1211 | |
1212 case 's': | |
1213 /* should nuke noisy someday */ | |
1214 noisy = 1; option_flag |= OPT_VERBOSE; | |
1215 if (strcmp ("-", optarg) != 0) | |
1216 { | |
1217 /** maybe FILE wnnerr = stderr; or wnnerr = open(optarg...) is better? or freopen is normal method? */ | |
1218 /** take a look at daemon(3) */ | |
1219 if (freopen (optarg, "a", stderr) == NULL) | |
1220 { | |
1221 /** fprintf to stderr? */ | |
1222 printf ("Error in opening scriptfile %s.\n", optarg); | |
1223 exit (1); | |
1224 } | |
1225 } | |
1226 log_debug ("script started"); | |
1227 break; | |
1228 | |
1229 case 'h': | |
1230 /* var hinsi_file_name polluted */ | |
1231 hinsi_file_name = optarg; | |
1232 break; | |
1233 | |
1234 case 'N': | |
1235 serverNO = atoi (optarg); | |
1236 /* error handling needed */ | |
1237 break; | |
1238 | |
1239 case 'p': | |
1240 port = atoi (optarg); | |
1241 /* error handling needed */ | |
1242 break; | |
1243 | |
1244 case 'v': | |
1245 print_version(); | |
1246 usage(); | |
1247 break; | |
1248 | |
1249 case 'u': | |
1250 listen_proto &= ~PROTO_ALL; | |
1251 listen_proto |= PROTO_UN; | |
1252 break; | |
1253 | |
1254 case '4': | |
1255 listen_proto &= ~PROTO_ALL; | |
1256 listen_proto |= PROTO_INET; | |
1257 break; | |
1258 | |
1259 #ifdef INET6 | |
1260 case '6': | |
1261 listen_proto &= ~PROTO_ALL; | |
1262 listen_proto |= PROTO_INET6; | |
1263 break; | |
1264 #endif /* INET6 */ | |
1265 | |
1266 default: | |
1267 print_version(); | |
1268 usage(); | |
1269 break; | |
1270 } | |
1271 } | |
1272 } | |
1273 | |
1274 | |
1275 /* | |
1276 */ | |
1277 void | |
1278 js_who (void) | |
1279 { | |
1280 int i, j; | |
1281 | |
1282 put4_cur (clientp); | |
1283 for (i = 0; i < clientp; i++) | |
1284 { | |
1285 put4_cur (cblk[i].sd); | |
1286 puts_cur (client[i].user_name); | |
1287 puts_cur (client[i].host_name); | |
1288 for (j = 0; j < WNN_MAX_ENV_OF_A_CLIENT; j++) | |
1289 { | |
1290 put4_cur ((client[i].env)[j]); | |
1291 } | |
1292 | |
1293 } | |
1294 putc_purge (); | |
1295 } | |
1296 | |
1297 void | |
1298 js_kill (void) | |
1299 { | |
1300 if (clientp == 1) | |
1301 { | |
1302 put4_cur (0); | |
1303 putc_purge (); | |
1304 terminate_hand (); | |
1305 } | |
1306 else | |
1307 { | |
1308 put4_cur (clientp - 1); | |
1309 putc_purge (); | |
1310 } | |
1311 } | |
1312 | |
1313 void | |
1314 usage (void) | |
1315 { | |
1316 fprintf(stderr, | |
1317 #ifdef INET6 | |
1318 "usage: %s [-Du46][-f <init_file> -s <log_file(\"-\" for stderr)> -h <pos_file> -N <serverNO> -p <port_base>]\n", | |
1319 #else | |
1320 "usage: %s [-Du4][-f <init_file> -s <log_file(\"-\" for stderr)> -h <pos_file> -N <serverNO> -p <port_base>]\n", | |
1321 #endif | |
1322 cmd_name); | |
1323 fprintf(stderr, | |
1324 " %s -v\n", | |
1325 cmd_name); | |
1326 exit (1); | |
1327 } | |
1328 | |
1329 void | |
1330 print_version (void) | |
1331 { | |
1332 #if defined(CHINESE) | |
1333 printf ("%s (%s) Chinese Multi Client Server\n", cmd_name, SER_VERSION); | |
1334 #elif defined(KOREAN) | |
1335 printf ("%s (%s) Korean Multi Client Server\n", cmd_name, SER_VERSION); | |
1336 #else | |
1337 printf ("%s (%s) Nihongo Multi Client Server\n", cmd_name, SER_VERSION); | |
1338 #endif /* CHINESE */ | |
1339 } |