4b38031b7f
- Fix daemonizing part. It now returns the exit status correctly. - Fix *_{pre,post}cmd handling in the rc.d scripts. Plus, wnntouch is now invoked just before running the server process. - Use ${*_WNNMANDIR} in Makefile to use the common patchset in both FreeWnn-server and -lib. - Integrate libtool22 change and regenerate patch files.
2005 lines
46 KiB
C
2005 lines
46 KiB
C
Index: Wnn/jserver/de.c
|
|
===================================================================
|
|
RCS file: /home/cvs/private/hrs/freewnn/Wnn/jserver/de.c,v
|
|
retrieving revision 1.1.1.1
|
|
retrieving revision 1.7
|
|
diff -u -p -r1.1.1.1 -r1.7
|
|
--- Wnn/jserver/de.c 20 Dec 2008 07:13:30 -0000 1.1.1.1
|
|
+++ Wnn/jserver/de.c 2 Jan 2010 14:05:14 -0000 1.7
|
|
@@ -1,7 +1,7 @@
|
|
/*
|
|
* FreeWnn is a network-extensible Kana-to-Kanji conversion system.
|
|
* This file is part of FreeWnn.
|
|
- *
|
|
+ *
|
|
* Copyright Kyoto University Research Institute for Mathematical Sciences
|
|
* 1987, 1988, 1989, 1990, 1991, 1992
|
|
* Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
|
|
@@ -102,54 +102,35 @@ static char rcs_id[] = "$Id: de.c,v 1.36
|
|
#endif
|
|
|
|
#ifndef INET6
|
|
-# define OPTIONARGS "Df:s:h:N:p:vu4"
|
|
+# define OPTIONARGS "a:Df:s:h:N:p:vu4"
|
|
#else
|
|
-# define OPTIONARGS "Df:s:h:N:p:vu46"
|
|
+# define OPTIONARGS "a:Df:s:h:N:p:vu46"
|
|
#endif /* INET6 */
|
|
|
|
/* Accept Socket */
|
|
-#ifdef INET6
|
|
-#define MAX_ACCEPTS 3
|
|
-#else
|
|
-#define MAX_ACCEPTS 2
|
|
-#endif
|
|
-#define UNIX_ACPT 0
|
|
-#define INET_ACPT 1
|
|
-#ifdef INET6
|
|
-#define INET6_ACPT 2
|
|
-#endif
|
|
+#define MAX_ACCEPTS 256
|
|
|
|
-#define PROTO_ALL 0x1
|
|
#define PROTO_UN 0x2
|
|
#define PROTO_INET 0x4
|
|
-#ifdef INET6
|
|
#define PROTO_INET6 0x8
|
|
-#endif
|
|
-static int listen_proto = PROTO_ALL;
|
|
+#define PROTO_ALL (PROTO_UN|PROTO_INET|PROTO_INET6)
|
|
+static int listen_proto;
|
|
|
|
jmp_buf client_dead;
|
|
|
|
static int port;
|
|
-static int serverNO = 0;
|
|
+static int serverNO;
|
|
|
|
-struct cmblk
|
|
-{
|
|
- int sd; /** ソケットのfd **/
|
|
+struct cmblk {
|
|
+ int domain;
|
|
+ int sd; /* socket fd */
|
|
};
|
|
-#define COMS_BLOCK struct cmblk
|
|
|
|
-static COMS_BLOCK *cblk;
|
|
- /** クライアントごとのソケットを管理するテーブル **/
|
|
-
|
|
-static COMS_BLOCK accept_blk[MAX_ACCEPTS]; /*accept sock blocks */
|
|
-
|
|
-
|
|
-/* Communication Buffers */
|
|
-static char snd_buf[R_BUF_SIZ]; /** 送信バッファ **/
|
|
-static int sbp; /** 送信バッファポインタ **/
|
|
-
|
|
-static int rbc; /** 受信バッファcounter **/
|
|
-static char rcv_buf[S_BUF_SIZ]; /** 受信バッファ **/
|
|
+/** クライアントごとのソケットを管理するテーブル **/
|
|
+static struct cmblk *cblk;
|
|
+/*accept sock blocks */
|
|
+static struct cmblk accept_blk[MAX_ACCEPTS];
|
|
+static int bindex;
|
|
|
|
#if defined(EAGAIN)
|
|
# if defined(EWOULDBLOCK)
|
|
@@ -167,7 +148,6 @@ static char rcv_buf[S_BUF_SIZ];
|
|
|
|
/* Client Table */
|
|
int clientp; /** cblkの有効なデータの最後を差している **/
|
|
-
|
|
int cur_clp; /** 現在のクライアントの番号 **/
|
|
|
|
static fd_set *all_socks; /** ビットパターン
|
|
@@ -181,27 +161,24 @@ struct msg_cat *wnn_msg_cat;
|
|
struct msg_cat *js_msg_cat;
|
|
|
|
/* function prototypes */
|
|
-static void daemon_main (void);
|
|
-static void socket_disc_init (void);
|
|
-static void sel_all (void);
|
|
-static int get_client (void);
|
|
-static void new_client (void);
|
|
-static void daemon_init (void);
|
|
-static void daemon_fin_un (int);
|
|
-static void daemon_fin_in (int);
|
|
-static int rcv_1_client (int);
|
|
-static void snd_1_client (int, int);
|
|
-static void socket_init_un (void);
|
|
-static void socket_init_in (void);
|
|
-static int socket_accept_un (void);
|
|
-static int socket_accept_in (int);
|
|
-static void xerror (char*);
|
|
-static void get_options (int, char **);
|
|
-static void usage (void);
|
|
-static void print_version (void);
|
|
-#ifdef DEBUG
|
|
-static void dmp (char*, int);
|
|
-#endif
|
|
+static void daemon_main(void);
|
|
+static void socket_disc_init(void);
|
|
+static int sel_all(void);
|
|
+static int get_client(void);
|
|
+static void new_client(void);
|
|
+static void daemon_init(void);
|
|
+static void daemon_fin_un(int);
|
|
+static void daemon_fin_in(int);
|
|
+static int rcv_1_client(int);
|
|
+static void snd_1_client(int, int);
|
|
+static void socket_init_un(int *);
|
|
+static void socket_init_in(int *);
|
|
+static int socket_accept(int);
|
|
+static void xerror(char*);
|
|
+static void get_options(int, char **);
|
|
+static void usage(void);
|
|
+static void print_version(void);
|
|
+static void dmp(char*, int);
|
|
|
|
static char cmd_name[16];
|
|
|
|
@@ -214,154 +191,136 @@ int deny_severity;
|
|
|
|
/* No arguments are used. Only options. */
|
|
int
|
|
-main (int argc, char *argv[])
|
|
+main(int argc, char *argv[])
|
|
{
|
|
- int tmpttyfd;
|
|
- char *cswidth_name;
|
|
- extern char *get_cswidth_name ();
|
|
- extern void set_cswidth ();
|
|
-
|
|
- char nlspath[64];
|
|
-
|
|
- strcpy (cmd_name, WNN_DAEMON_NAME);
|
|
- strcpy (lang_dir, LANG_NAME);
|
|
- strcpy (nlspath, LIBDIR);
|
|
- strcat (nlspath, "/%L/%N");
|
|
- js_msg_cat = msg_open (MESSAGE_FILE, nlspath, lang_dir);
|
|
- wnn_msg_cat = msg_open ("libwnn.msg", nlspath, lang_dir);
|
|
- if (wnn_msg_cat == NULL)
|
|
- {
|
|
- log_err ("cannot open message file libwnn.msg.");
|
|
- }
|
|
- if (cswidth_name = get_cswidth_name (LANG_NAME))
|
|
- set_cswidth (create_cswidth (cswidth_name));
|
|
+ int tmpttyfd;
|
|
+ pid_t pid;
|
|
+ int fd;
|
|
+ char *cswidth_name;
|
|
+ extern char *get_cswidth_name ();
|
|
+ extern void set_cswidth ();
|
|
+
|
|
+ char nlspath[64];
|
|
+
|
|
+ strcpy(cmd_name, WNN_DAEMON_NAME);
|
|
+ strcpy(lang_dir, LANG_NAME);
|
|
+ strcpy(nlspath, LIBDIR);
|
|
+ strcat(nlspath, "/%L/%N");
|
|
+ js_msg_cat = msg_open (MESSAGE_FILE, nlspath, lang_dir);
|
|
+ wnn_msg_cat = msg_open ("libwnn.msg", nlspath, lang_dir);
|
|
|
|
- port = -1;
|
|
- /* option default */
|
|
- option_flag = (OPT_FORK & ~OPT_VERBOSE);
|
|
-
|
|
- setuid (geteuid ());
|
|
- get_options (argc, argv);
|
|
- print_version();
|
|
- log_debug("invoked as %s.", argv[0]);
|
|
- if (option_flag & OPT_FORK)
|
|
- {
|
|
- if (fork ())
|
|
- {
|
|
- signal (SIGCHLD, _exit);
|
|
- signal (SIGHUP, SIG_IGN);
|
|
- signal (SIGINT, SIG_IGN);
|
|
- signal (SIGQUIT, SIG_IGN);
|
|
-#ifdef SIGTSTP
|
|
- signal (SIGTSTP, SIG_IGN);
|
|
-#endif
|
|
- signal (SIGTERM, _exit);
|
|
- pause ();
|
|
+ if (wnn_msg_cat == NULL) {
|
|
+ log_err ("cannot open message file libwnn.msg.");
|
|
}
|
|
- }
|
|
+ if (cswidth_name = get_cswidth_name (LANG_NAME))
|
|
+ set_cswidth (create_cswidth (cswidth_name));
|
|
|
|
+ port = -1;
|
|
+ /* option default */
|
|
+ option_flag = (OPT_FORK & ~OPT_VERBOSE);
|
|
+
|
|
+ setuid(geteuid());
|
|
+ get_options (argc, argv);
|
|
+ print_version();
|
|
+ log_debug("invoked as %s.", argv[0]);
|
|
#if defined(HAVE_LIBWRAP)
|
|
- allow_severity = LOG_INFO;
|
|
- deny_severity = LOG_WARNING;
|
|
- /* hosts_access_verbose = 2; */
|
|
+ allow_severity = LOG_INFO;
|
|
+ deny_severity = LOG_WARNING;
|
|
+ /* hosts_access_verbose = 2; */
|
|
#endif /* HAVE_LIBWRAP */
|
|
|
|
- signal (SIGHUP, signal_hand);
|
|
- signal (SIGINT, signal_hand);
|
|
- signal (SIGQUIT, signal_hand);
|
|
- signal (SIGTERM, terminate_hand);
|
|
- if (option_flag & OPT_FORK)
|
|
- {
|
|
-#ifdef SIGTSTP
|
|
- signal (SIGTSTP, SIG_IGN);
|
|
+ signal(SIGHUP, signal_hand);
|
|
+ signal(SIGQUIT, signal_hand);
|
|
+ signal(SIGTERM, terminate_hand);
|
|
+ if (option_flag & OPT_FORK) {
|
|
+ /* when -D is not specified, accept SIGINT */
|
|
+ signal(SIGINT, signal_hand);
|
|
+#ifdef SIGTSTP
|
|
+ signal(SIGTSTP, SIG_IGN);
|
|
#endif /* SIGTSTP */
|
|
- }
|
|
- read_default ();
|
|
- daemon_init ();
|
|
-
|
|
- env_init ();
|
|
- if (file_init () == NULL)
|
|
- {
|
|
- exit (1);
|
|
- }
|
|
- dic_init ();
|
|
- if (NULL == get_kaiseki_area (LENGTHCONV + 1)) /* 変換可能文字数 */
|
|
- {
|
|
- log_err ("get_kaiseki_area failed.");
|
|
- exit (1);
|
|
- }
|
|
- init_work_areas ();
|
|
- init_jmt ();
|
|
-
|
|
- read_default_files ();
|
|
-
|
|
- if (option_flag & OPT_FORK)
|
|
- {
|
|
- /* End of initialization, kill parent */
|
|
- kill (getppid (), SIGTERM);
|
|
- fclose (stdin);
|
|
- fclose (stdout);
|
|
- if (!(option_flag & OPT_VERBOSE))
|
|
- {
|
|
-#if !(defined(BSD) && (BSD >= 199306)) /* !4.4BSD-Lite by Taoka */
|
|
- fclose (stderr);
|
|
-#else /* 4.4BSD-Lite */
|
|
- int fd = open ("/dev/null", O_WRONLY);
|
|
- if (fd < 0)
|
|
- {
|
|
- xerror ("Cannot open /dev/null");
|
|
- }
|
|
- dup2 (fd, 2);
|
|
- close (fd);
|
|
-#endif /* 4.4BSD-Lite */
|
|
}
|
|
-
|
|
+ read_default();
|
|
+ daemon_init();
|
|
+ env_init();
|
|
+ if (file_init() == 0)
|
|
+ exit (1);
|
|
+ dic_init();
|
|
+ if (0 == get_kaiseki_area (LENGTHCONV + 1)) {
|
|
+ /* 変換可能文字数 */
|
|
+ log_err ("get_kaiseki_area failed.");
|
|
+ exit (1);
|
|
+ }
|
|
+ init_work_areas();
|
|
+ init_jmt();
|
|
+ read_default_files();
|
|
+ if (option_flag & OPT_FORK) {
|
|
+ pid = fork();
|
|
+ if (pid == -1) {
|
|
+ log_err ("cannot fork.");
|
|
+ exit(1);
|
|
+ }
|
|
+ if (pid > 0)
|
|
+ _exit(0);
|
|
+ setsid();
|
|
+ pid = fork();
|
|
+ if (pid == -1) {
|
|
+ log_err ("cannot fork.");
|
|
+ exit(1);
|
|
+ }
|
|
+ if (pid > 0)
|
|
+ _exit(0);
|
|
+ chdir("/");
|
|
+ umask(0);
|
|
+ close(STDIN_FILENO);
|
|
+ close(STDOUT_FILENO);
|
|
+ if (!(option_flag & OPT_VERBOSE)) {
|
|
+ close(STDERR_FILENO);
|
|
+ fd = open("/dev/null", O_WRONLY);
|
|
+ if (fd < 0) {
|
|
+ xerror ("Cannot open /dev/null");
|
|
+ }
|
|
+ dup2(fd, STDERR_FILENO);
|
|
+ close(fd);
|
|
+ }
|
|
#ifdef SETPGRP_VOID
|
|
- setpgrp ();
|
|
+ setpgrp();
|
|
#else /* !SETPGRP_VOID */
|
|
# if !defined(TIOCNOTTY) && defined(SVR4)
|
|
# define TIOCNOTTY _IO('t', 113)
|
|
# endif /* !defined(TIOCNOTTY) && defined(SVR4) */
|
|
#ifndef HITACHI
|
|
- if ((tmpttyfd = open ("/dev/tty", O_RDWR)) >= 0)
|
|
- {
|
|
- ioctl (tmpttyfd, TIOCNOTTY, 0);
|
|
- close (tmpttyfd);
|
|
- }
|
|
+ if ((tmpttyfd = open("/dev/tty", O_RDWR)) >= 0) {
|
|
+ ioctl(tmpttyfd, TIOCNOTTY, 0);
|
|
+ close(tmpttyfd);
|
|
+ }
|
|
#endif /* HITACHI */
|
|
#endif /* SETPGRP_VOID */
|
|
- }
|
|
-
|
|
- daemon_main ();
|
|
-
|
|
- daemon_fin ();
|
|
- return (0); /* it is not reached. only for avoiding compiler warning. */
|
|
+ }
|
|
+ daemon_main();
|
|
+ daemon_fin();
|
|
+ return(0); /* NOTREACHED */
|
|
}
|
|
|
|
static void
|
|
daemon_main (void)
|
|
{
|
|
- for (;;)
|
|
- {
|
|
- c_c = NULL; /* Added for logging: server section */
|
|
- sel_all ();
|
|
- new_client ();
|
|
- for (;;)
|
|
- {
|
|
- if (get_client () == -1)
|
|
- break;
|
|
- c_c = &client[cur_clp];
|
|
- rbc = 0;
|
|
- sbp = 0;
|
|
+ for (;;) {
|
|
+ c_c = NULL; /* Added for logging: server section */
|
|
+ sel_all();
|
|
+ new_client();
|
|
+
|
|
+ for (;;) {
|
|
+ if (get_client () == -1)
|
|
+ break;
|
|
+ c_c = &client[cur_clp];
|
|
/* if(rcv_1_client(cur_clp) == 0){ del_client(); continue; } */
|
|
- if (setjmp (client_dead))
|
|
- {
|
|
- del_client ();
|
|
- continue;
|
|
- }
|
|
- do_command (c_c);
|
|
- }
|
|
- }
|
|
+ if (setjmp(client_dead)) {
|
|
+ del_client ();
|
|
+ continue;
|
|
+ }
|
|
+ do_command(c_c);
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
/*
|
|
@@ -370,39 +329,36 @@ daemon_main (void)
|
|
static void
|
|
socket_disc_init (void)
|
|
{
|
|
- if (WNN_NFD <= FD_SETSIZE)
|
|
- {
|
|
- nofile = WNN_NFD;
|
|
- }
|
|
- else
|
|
- {
|
|
- nofile = FD_SETSIZE;
|
|
- }
|
|
- all_socks = (fd_set *) malloc (sizeof (fd_set));
|
|
- FD_ZERO (all_socks);
|
|
- ready_socks = (fd_set *) malloc (sizeof (fd_set));
|
|
- dummy1_socks = (fd_set *) malloc (sizeof (fd_set));
|
|
- dummy2_socks = (fd_set *) malloc (sizeof (fd_set));
|
|
+ nofile = MIN(WNN_NFD, FD_SETSIZE);
|
|
+
|
|
+ all_socks = (fd_set *)malloc(sizeof(fd_set));
|
|
+ ready_socks = (fd_set *)malloc(sizeof(fd_set));
|
|
+ dummy1_socks = (fd_set *)malloc(sizeof(fd_set));
|
|
+ dummy2_socks = (fd_set *)malloc(sizeof(fd_set));
|
|
+ FD_ZERO(all_socks);
|
|
+ FD_ZERO(ready_socks);
|
|
+ FD_ZERO(dummy1_socks);
|
|
+ FD_ZERO(dummy2_socks);
|
|
}
|
|
|
|
/** 全てのソケットについて待つ **/
|
|
-static void
|
|
-sel_all (void)
|
|
+static int
|
|
+sel_all(void)
|
|
{
|
|
- memcpy (ready_socks, all_socks, sizeof (fd_set));
|
|
- bzero (dummy1_socks, sizeof (fd_set));
|
|
- bzero (dummy2_socks, sizeof (fd_set));
|
|
+ int ns = 0;
|
|
+ memcpy(ready_socks, all_socks, sizeof(fd_set));
|
|
+ FD_ZERO(dummy1_socks);
|
|
+ FD_ZERO(dummy2_socks);
|
|
|
|
top:
|
|
- errno = 0;
|
|
- if ((no_of_ready_socks = select (nofile, ready_socks, dummy1_socks, dummy2_socks, NULL)) == -1)
|
|
- {
|
|
- if (errno == EINTR)
|
|
- goto top;
|
|
- xerror ("select error");
|
|
- }
|
|
+ errno = 0;
|
|
+ if ((no_of_ready_socks = select(nofile, ready_socks, dummy1_socks, dummy2_socks, NULL)) == -1) {
|
|
+ if (errno == EINTR)
|
|
+ goto top;
|
|
+ xerror ("select error");
|
|
+ }
|
|
#ifdef DEBUG
|
|
- log_debug ("select OK, ready_socks[0]=%02X, n-r-s=%x\n", ready_socks[0], no_of_ready_socks);
|
|
+ log_debug ("select OK, ready_socks[0]=%02X, n-r-s=%x\n", ready_socks[0], no_of_ready_socks);
|
|
#endif
|
|
}
|
|
|
|
@@ -412,142 +368,136 @@ top:
|
|
static int
|
|
get_client (void)
|
|
{
|
|
- int i;
|
|
-
|
|
- if (no_of_ready_socks == 0)
|
|
- return -1; /* no client waits service */
|
|
-
|
|
- for (i = cur_clp;;)
|
|
- {
|
|
- if (no_of_ready_socks == 0)
|
|
- return -1;
|
|
- i++;
|
|
- if (i >= clientp)
|
|
- i = 0;
|
|
- if (FD_ISSET (cblk[i].sd, ready_socks))
|
|
- {
|
|
- FD_CLR (cblk[i].sd, ready_socks);
|
|
- no_of_ready_socks--;
|
|
- return cur_clp = i;
|
|
- }
|
|
- }
|
|
+ int i;
|
|
+
|
|
+ if (no_of_ready_socks == 0)
|
|
+ return -1; /* no client waits service */
|
|
+
|
|
+ for (i = cur_clp;;)
|
|
+ {
|
|
+ if (no_of_ready_socks == 0)
|
|
+ return -1;
|
|
+ i++;
|
|
+ if (i >= clientp)
|
|
+ i = 0;
|
|
+ if (FD_ISSET(cblk[i].sd, ready_socks)) {
|
|
+ FD_CLR(cblk[i].sd, ready_socks);
|
|
+ no_of_ready_socks--;
|
|
+ return (cur_clp = i);
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
/** 新しいクライアントが居るか否かを調べる
|
|
居た場合はcblkに登録する **/
|
|
static void
|
|
-new_client (void) /* NewClient */
|
|
+new_client(void)
|
|
{
|
|
- int sd;
|
|
- int full, i;
|
|
- FILE *f[3];
|
|
- char gomi[1024];
|
|
+ int sd = -1;
|
|
+ int full, i;
|
|
+ FILE *f[3];
|
|
+ char gomi[1024];
|
|
#ifdef HAVE_LIBWRAP
|
|
- int is_internet_socket;
|
|
- struct request_info tcpd_request;
|
|
+ int is_internet_socket;
|
|
+ struct request_info tcpd_request;
|
|
#endif /* HAVE_LIBWRAP */
|
|
-#ifdef AF_UNIX
|
|
- if ((serverNO == 0) &&
|
|
- (FD_ISSET (accept_blk[UNIX_ACPT].sd, ready_socks)))
|
|
- {
|
|
- FD_CLR (accept_blk[UNIX_ACPT].sd, ready_socks);
|
|
- no_of_ready_socks--;
|
|
- sd = socket_accept_un ();
|
|
+
|
|
+ log_debug("new client called");
|
|
+
|
|
+ for (i = 0; i < bindex && !FD_ISSET(accept_blk[i].sd, ready_socks); i++)
|
|
+ ;
|
|
+
|
|
+ if (i == bindex)
|
|
+ return;
|
|
+
|
|
+ FD_CLR(accept_blk[i].sd, ready_socks);
|
|
+ no_of_ready_socks--;
|
|
+ log_debug("new client: FDISSET(%d/%d) true, domain=%d",
|
|
+ i, bindex, accept_blk[i].domain);
|
|
+
|
|
+ switch (accept_blk[i].domain) {
|
|
+#ifdef AF_UNIX
|
|
+ case AF_UNIX:
|
|
+ sd = socket_accept(i);
|
|
#ifdef HAVE_LIBWRAP
|
|
- is_internet_socket = 0;
|
|
-#endif
|
|
- }
|
|
- else
|
|
+ is_internet_socket = 0;
|
|
+#endif /* HAVE_LIBWRAP */
|
|
+ break;
|
|
#endif
|
|
#ifdef INET6
|
|
- if (FD_ISSET (accept_blk[INET6_ACPT].sd, ready_socks))
|
|
- {
|
|
- FD_CLR (accept_blk[INET6_ACPT].sd, ready_socks);
|
|
- no_of_ready_socks--;
|
|
- sd = socket_accept_in (accept_blk[INET6_ACPT].sd);
|
|
-#ifdef HAVE_LIBWRAP
|
|
- is_internet_socket = 1;
|
|
-#endif
|
|
- }
|
|
- else
|
|
+ case AF_INET6:
|
|
#endif
|
|
- if (FD_ISSET (accept_blk[INET_ACPT].sd, ready_socks))
|
|
- {
|
|
- FD_CLR (accept_blk[INET_ACPT].sd, ready_socks);
|
|
- no_of_ready_socks--;
|
|
- sd = socket_accept_in (accept_blk[INET_ACPT].sd);
|
|
+ case AF_INET:
|
|
+ sd = socket_accept(i);
|
|
#ifdef HAVE_LIBWRAP
|
|
- is_internet_socket = 1;
|
|
-#endif
|
|
- }
|
|
- else
|
|
- {
|
|
- return;
|
|
- }
|
|
- log_debug ("new client: sd = %d", sd);
|
|
- /* reserve 2 fd */
|
|
- for (full = i = 0; i < 2; i++)
|
|
- {
|
|
- if (NULL == (f[i] = fopen ("/dev/null", "r")))
|
|
- {
|
|
- full = 1;
|
|
- }
|
|
- }
|
|
- for (i = 0; i < 2; i++)
|
|
- {
|
|
- if (NULL != f[i])
|
|
- fclose (f[i]);
|
|
- }
|
|
-
|
|
- if (full || sd >= nofile || clientp >= max_client)
|
|
- {
|
|
- log_err ("no more client.");
|
|
+ is_internet_socket = 1;
|
|
+#endif /* HAVE_LIBWRAP */
|
|
+ break;
|
|
+ default:
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ log_debug("new client: sd = %d (type=%d)",
|
|
+ sd, accept_blk[i].domain);
|
|
+
|
|
+ /* reserve 2 fd */
|
|
+ for (full = i = 0; i < 2; i++) {
|
|
+ if (NULL == (f[i] = fopen ("/dev/null", "r"))) {
|
|
+ full = 1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < 2; i++) {
|
|
+ if (NULL != f[i])
|
|
+ fclose (f[i]);
|
|
+ }
|
|
+
|
|
+ if (full || sd >= nofile || clientp >= max_client) {
|
|
+ log_err("no more client.");
|
|
#ifdef HAVE_RECV
|
|
- recv (sd, gomi, 1024, 0);
|
|
+ recv(sd, gomi, 1024, 0);
|
|
#else
|
|
- read (sd, gomi, 1024);
|
|
+ read(sd, gomi, 1024);
|
|
#endif
|
|
- shutdown (sd, 2);
|
|
+ shutdown(sd, 2);
|
|
#ifdef HAVE_CLOSESOCKET
|
|
- closesocket (sd);
|
|
+ closesocket(sd);
|
|
#else
|
|
- close (sd);
|
|
+ close(sd);
|
|
#endif
|
|
- return;
|
|
- }
|
|
-
|
|
+ return;
|
|
+ }
|
|
+
|
|
#ifdef HAVE_LIBWRAP
|
|
- if (is_internet_socket) {
|
|
- request_init (&tcpd_request,RQ_DAEMON, WNN_DAEMON_NAME,
|
|
- RQ_FILE, sd, NULL);
|
|
- fromhost (&tcpd_request);
|
|
- if (!hosts_access (&tcpd_request))
|
|
- {
|
|
- log_err ("reject client."); /* should be log_info? */
|
|
- /* should we log IP address / hostname? */
|
|
+ if (is_internet_socket) {
|
|
+ request_init (&tcpd_request,RQ_DAEMON, WNN_DAEMON_NAME,
|
|
+ RQ_FILE, sd, NULL);
|
|
+ fromhost (&tcpd_request);
|
|
+ if (!hosts_access (&tcpd_request)) {
|
|
+ log_err ("reject client."); /* should be log_info? */
|
|
+ /* should we log IP address / hostname? */
|
|
#ifdef HAVE_RECV
|
|
- recv (sd, gomi, 1024, 0);
|
|
+ recv(sd, gomi, 1024, 0);
|
|
#else
|
|
- read (sd, gomi, 1024);
|
|
+ read(sd, gomi, 1024);
|
|
#endif
|
|
- shutdown (sd, 2);
|
|
+ shutdown(sd, 2);
|
|
#ifdef HAVE_CLOSESOCKET
|
|
- closesocket (sd);
|
|
+ closesocket(sd);
|
|
#else
|
|
- close (sd);
|
|
+ close(sd);
|
|
#endif
|
|
- return;
|
|
- }
|
|
- }
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
#endif /* HAVE_LIBWRAP */
|
|
-
|
|
- cblk[clientp].sd = sd;
|
|
- FD_SET (sd, all_socks);
|
|
- for (i = 0; i < WNN_MAX_ENV_OF_A_CLIENT; i++)
|
|
- {
|
|
- (client[clientp].env)[i] = -1;
|
|
- }
|
|
- clientp++;
|
|
+
|
|
+ cblk[clientp].sd = sd;
|
|
+ FD_SET(sd, all_socks);
|
|
+ for (i = 0; i < WNN_MAX_ENV_OF_A_CLIENT; i++) {
|
|
+ (client[clientp].env)[i] = -1;
|
|
+ }
|
|
+ clientp++;
|
|
}
|
|
|
|
/** クライアントをcblkから削除する **/
|
|
@@ -555,746 +505,724 @@ new_client (void) /* NewCl
|
|
void
|
|
del_client (void)
|
|
{
|
|
- disconnect_all_env_of_client ();
|
|
- FD_CLR (cblk[cur_clp].sd, all_socks);
|
|
+ disconnect_all_env_of_client ();
|
|
+ FD_CLR(cblk[cur_clp].sd, all_socks);
|
|
#ifdef HAVE_CLOSESOCKET
|
|
- closesocket (cblk[cur_clp].sd);
|
|
+ closesocket(cblk[cur_clp].sd);
|
|
#else
|
|
- close (cblk[cur_clp].sd);
|
|
+ close(cblk[cur_clp].sd);
|
|
#endif
|
|
/* logging here because c_c (used in log_debug) will be broken after
|
|
following section */
|
|
- log_debug("Delete Client: cur_clp = %d\n", cur_clp);
|
|
- cblk[cur_clp] = cblk[clientp - 1];
|
|
- client[cur_clp] = client[clientp - 1];
|
|
- /* Clear host/user name with zero - needed for logging */
|
|
- client[clientp - 1].user_name[0] = '\0'; /* Should we use bzero()? */
|
|
- client[clientp - 1].host_name[0] = '\0';
|
|
- clientp--;
|
|
-}
|
|
+ log_debug("Delete Client: cur_clp = %d\n", cur_clp);
|
|
+ cblk[cur_clp] = cblk[clientp - 1];
|
|
+ client[cur_clp] = client[clientp - 1];
|
|
+ /* Clear host/user name with zero - needed for logging */
|
|
+
|
|
+ /* Should we use bzero()? */
|
|
+ client[clientp - 1].user_name[0] = '\0';
|
|
|
|
+ client[clientp - 1].host_name[0] = '\0';
|
|
+ clientp--;
|
|
+}
|
|
|
|
/** サーバをイニシャライズする **/
|
|
static void
|
|
-daemon_init (void) /* initialize Daemon */
|
|
+daemon_init(void) /* initialize Daemon */
|
|
{
|
|
- /*
|
|
- signal (SIGHUP, SIG_IGN);
|
|
- signal (SIGINT, SIG_IGN);
|
|
- signal (SIGQUIT, SIG_IGN);
|
|
- */
|
|
+ /*
|
|
+ signal (SIGHUP, SIG_IGN);
|
|
+ signal (SIGINT, SIG_IGN);
|
|
+ signal (SIGQUIT, SIG_IGN);
|
|
+ */
|
|
|
|
+ if ((cblk = (struct cmblk *)malloc(max_client * sizeof(struct cmblk))) == NULL) {
|
|
+ xerror ("daemon_init: ");
|
|
+ }
|
|
+
|
|
+ if ((client = (CLIENT *)malloc(max_client * sizeof (CLIENT))) == NULL) {
|
|
+ xerror ("daemon_init: ");
|
|
+ }
|
|
+
|
|
+ SDRAND(time(NULL));
|
|
+ clientp = 0; /* V3.0 */
|
|
+ cur_clp = 0; /* V3.0 */
|
|
+ socket_disc_init();
|
|
|
|
- if ((cblk = (COMS_BLOCK *) malloc (max_client * sizeof (COMS_BLOCK))) == NULL)
|
|
- {
|
|
- xerror ("daemon_init: ");
|
|
- }
|
|
- if ((client = (CLIENT *) malloc (max_client * sizeof (CLIENT))) == NULL)
|
|
- {
|
|
- xerror ("daemon_init: ");
|
|
- }
|
|
- SDRAND (time (NULL));
|
|
- clientp = 0; /* V3.0 */
|
|
- cur_clp = 0; /* V3.0 */
|
|
- socket_disc_init ();
|
|
-#ifdef INET6
|
|
- if (listen_proto&(PROTO_ALL|PROTO_INET|PROTO_INET6))
|
|
- socket_init_in ();
|
|
-#else
|
|
- if (listen_proto&(PROTO_ALL|PROTO_INET))
|
|
- socket_init_in ();
|
|
-#endif
|
|
#ifdef AF_UNIX
|
|
- if (listen_proto&(PROTO_ALL|PROTO_UN))
|
|
- socket_init_un ();
|
|
-#endif /* AF_UNIX */
|
|
+ if (listen_proto & PROTO_UN)
|
|
+ socket_init_un(&bindex);
|
|
+#endif
|
|
+ if (listen_proto & (PROTO_INET|PROTO_INET6))
|
|
+ socket_init_in(&bindex);
|
|
}
|
|
|
|
/** サーバを終わる **/
|
|
-#ifdef AF_UNIX
|
|
+#ifdef AF_UNIX
|
|
static void
|
|
-daemon_fin_un (int sock_d_un)
|
|
+daemon_fin_un(int sock_d_un)
|
|
{
|
|
- int trueFlag = 1;
|
|
- struct sockaddr_un addr_un;
|
|
- socklen_t addrlen;
|
|
+ int trueFlag = 1;
|
|
+ struct sockaddr_un addr_un;
|
|
+ socklen_t addrlen;
|
|
|
|
- if (serverNO == 0)
|
|
- {
|
|
#ifndef SOLARIS
|
|
#if defined(FIONBIO)
|
|
- ioctl (sock_d_un, FIONBIO, &trueFlag);
|
|
+ ioctl (sock_d_un, FIONBIO, &trueFlag);
|
|
#endif
|
|
#else /* !SOLARIS */
|
|
- fcntl (sock_d_un, F_SETFL, F_UNLCK);
|
|
+ fcntl (sock_d_un, F_SETFL, F_UNLCK);
|
|
#endif /* !SOLARIS */
|
|
- for (;;)
|
|
- {
|
|
- addrlen = sizeof (addr_un);
|
|
- if (accept (sock_d_un, (struct sockaddr *) &addr_un, &addrlen) < 0)
|
|
- break;
|
|
- /* EWOULDBLOCK EXPECTED, but we don't check */
|
|
+ for (;;) {
|
|
+ addrlen = sizeof (addr_un);
|
|
+ if (accept(sock_d_un,
|
|
+ (struct sockaddr *)&addr_un,
|
|
+ &addrlen) < 0)
|
|
+ break;
|
|
+ /* EWOULDBLOCK EXPECTED, but we don't check */
|
|
}
|
|
- shutdown (sock_d_un, 2);
|
|
- close (sock_d_un);
|
|
- }
|
|
+ shutdown (sock_d_un, 2);
|
|
+ close (sock_d_un);
|
|
}
|
|
#endif /* AF_UNIX */
|
|
|
|
static void
|
|
-daemon_fin_in (int sock_d_in)
|
|
+daemon_fin_in(int sock_d_in)
|
|
{
|
|
- int trueFlag = 1;
|
|
- struct sockaddr_in addr_in;
|
|
- socklen_t addrlen;
|
|
+ int trueFlag = 1;
|
|
+ struct sockaddr_in addr_in;
|
|
+ socklen_t addrlen;
|
|
#ifdef USE_SETSOCKOPT
|
|
- int on = ~0;
|
|
+ int on = ~0;
|
|
#endif
|
|
|
|
#ifndef SOLARIS
|
|
#ifdef USE_SETSOCKOPT
|
|
- setsockopt (sock_d_in, SOL_SOCKET, SO_NONBLOCK, &on, sizeof (int));
|
|
+ setsockopt(sock_d_in, SOL_SOCKET, SO_NONBLOCK, &on, sizeof(int));
|
|
#else
|
|
#if defined(FIONBIO)
|
|
- ioctl (sock_d_in, FIONBIO, &trueFlag);
|
|
+ ioctl(sock_d_in, FIONBIO, &trueFlag);
|
|
#endif
|
|
#endif /* USE_SETSOCKOPT */
|
|
#else /* !SOLARIS */
|
|
- fcntl (sock_d_in, F_SETFL, F_UNLCK);
|
|
+ fcntl(sock_d_in, F_SETFL, F_UNLCK);
|
|
#endif /* !SOLARIS */
|
|
- for (;;)
|
|
- {
|
|
- addrlen = sizeof (addr_in);
|
|
- if (accept (sock_d_in, (struct sockaddr *) &addr_in, &addrlen) < 0)
|
|
- break;
|
|
- /* EWOULDBLOCK EXPECTED, but we don't check */
|
|
- }
|
|
- shutdown (sock_d_in, 2);
|
|
+ for (;;) {
|
|
+ addrlen = sizeof(addr_in);
|
|
+ if (accept(sock_d_in,
|
|
+ (struct sockaddr *)&addr_in,
|
|
+ &addrlen) < 0)
|
|
+ break;
|
|
+ /* EWOULDBLOCK EXPECTED, but we don't check */
|
|
+ }
|
|
+ shutdown (sock_d_in, 2);
|
|
#ifdef HAVE_CLOSESOCKET
|
|
- closesocket (sock_d_in);
|
|
+ closesocket (sock_d_in);
|
|
#else
|
|
- close (sock_d_in);
|
|
+ close (sock_d_in);
|
|
#endif
|
|
}
|
|
|
|
void
|
|
daemon_fin (void)
|
|
{
|
|
- int fd;
|
|
-#ifdef AF_UNIX
|
|
- int sock_d_un = accept_blk[UNIX_ACPT].sd;
|
|
-#endif /* AF_UNIX */
|
|
- int sock_d_in = accept_blk[INET_ACPT].sd;
|
|
-#ifdef INET6
|
|
- int sock_d_in6 = accept_blk[INET6_ACPT].sd;
|
|
-#endif
|
|
+ int i;
|
|
+ int fd;
|
|
|
|
- /*
|
|
- accept all pending connection from new clients,
|
|
- avoiding kernel hangup.
|
|
- */
|
|
+ for (i = 0; i < bindex; i++) {
|
|
+ if (FD_ISSET(accept_blk[i].sd, all_socks)) {
|
|
+ switch (accept_blk[i].domain) {
|
|
#ifdef AF_UNIX
|
|
- daemon_fin_un (sock_d_un);
|
|
-#endif
|
|
- daemon_fin_in (sock_d_in);
|
|
+ case AF_UNIX:
|
|
+ if (listen_proto & PROTO_UN)
|
|
+ daemon_fin_un(accept_blk[i].sd);
|
|
+ break;
|
|
+#endif
|
|
+ case AF_INET:
|
|
+ if (listen_proto & PROTO_INET)
|
|
+ daemon_fin_in(accept_blk[i].sd);
|
|
+ break;
|
|
#ifdef INET6
|
|
- daemon_fin_in (sock_d_in6);
|
|
-#endif
|
|
+ case AF_INET6:
|
|
+ if (listen_proto & PROTO_INET6)
|
|
+ daemon_fin_in(accept_blk[i].sd);
|
|
+ break;
|
|
+#endif
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
|
|
- for (fd = nofile - 1; fd >= 0; fd--)
|
|
- {
|
|
- if ((fd != sock_d_in) &&
|
|
-#ifdef INET6
|
|
- (fd != sock_d_in6) &&
|
|
-#endif
|
|
-#ifdef AF_UNIX
|
|
- (fd != sock_d_un) &&
|
|
-#endif /* AF_UNIX */
|
|
- FD_ISSET (fd, all_socks))
|
|
- {
|
|
- shutdown (fd, 2);
|
|
+ for (fd = nofile - 1; fd >= 0; fd--) {
|
|
+ if (FD_ISSET(fd, all_socks)) {
|
|
+ shutdown (fd, 2);
|
|
#ifdef HAVE_CLOSESOCKET
|
|
- closesocket (fd);
|
|
+ closesocket (fd);
|
|
#else
|
|
- close (fd);
|
|
+ close (fd);
|
|
#endif
|
|
- }
|
|
- }
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
-/*------*/
|
|
+static unsigned char snd_buf[S_BUF_SIZ]; /** 送信バッファ **/
|
|
+static unsigned char *sp = snd_buf;
|
|
+
|
|
+static unsigned char rcv_buf[R_BUF_SIZ]; /** 受信バッファ **/
|
|
+static unsigned char *rbp = rcv_buf;
|
|
+static unsigned char *rp = rcv_buf;
|
|
|
|
-/** **/
|
|
char *
|
|
-gets_cur (char *buffer, size_t buffer_size)
|
|
+gets_cur(char *buffer, size_t buffer_size)
|
|
{
|
|
- char *b;
|
|
+ char *b;
|
|
|
|
- if (!buffer || !buffer_size)
|
|
- return NULL;
|
|
+ if (!buffer || !buffer_size)
|
|
+ return NULL;
|
|
|
|
- b = buffer;
|
|
+ b = buffer;
|
|
|
|
- while (--buffer_size && (*b = getc_cur ()) != '\0')
|
|
- b++;
|
|
+ while (--buffer_size && (*b = getc_cur()) != '\0')
|
|
+ b++;
|
|
|
|
- if (!buffer_size)
|
|
- {
|
|
- *b = '\0';
|
|
- while (getc_cur () != '\0')
|
|
- ;
|
|
- }
|
|
+ if (!buffer_size) {
|
|
+ *b = '\0';
|
|
+ while (getc_cur() != '\0')
|
|
+ ;
|
|
+ }
|
|
|
|
- return buffer;
|
|
+ return buffer;
|
|
}
|
|
|
|
/** **/
|
|
w_char *
|
|
-getws_cur (w_char *buffer, size_t buffer_size)
|
|
+getws_cur(w_char *buffer, size_t buffer_size)
|
|
{
|
|
- w_char *b;
|
|
+ w_char *b;
|
|
|
|
- if (!buffer || !buffer_size)
|
|
- return NULL;
|
|
+ if (!buffer || !buffer_size)
|
|
+ return NULL;
|
|
|
|
- b = buffer;
|
|
+ b = buffer;
|
|
|
|
- while (--buffer_size && (*b = get2_cur ()) != 0)
|
|
- b++;
|
|
+ while (--buffer_size && (*b = get2_cur ()) != 0)
|
|
+ b++;
|
|
|
|
- if (!buffer_size)
|
|
- {
|
|
- *b = 0;
|
|
- while (getc_cur () != 0)
|
|
- ;
|
|
- }
|
|
-
|
|
- return buffer;
|
|
+ if (!buffer_size) {
|
|
+ *b = 0;
|
|
+ while (getc_cur () != 0)
|
|
+ ;
|
|
+ }
|
|
+ return buffer;
|
|
}
|
|
|
|
/** カレント・クライアントから2バイト取る **/
|
|
int
|
|
get2_cur (void)
|
|
{
|
|
- int x;
|
|
- x = getc_cur ();
|
|
- return (x << 8) | getc_cur ();
|
|
+ int h;
|
|
+ h = getc_cur () << 8;
|
|
+ h |= getc_cur ();
|
|
+ return h;
|
|
}
|
|
|
|
/** カレント・クライアントから4バイト取る **/
|
|
int
|
|
get4_cur (void)
|
|
{
|
|
- int x1, x2, x3;
|
|
- x1 = getc_cur ();
|
|
- x2 = getc_cur ();
|
|
- x3 = getc_cur ();
|
|
- return (x1 << (8 * 3)) | (x2 << (8 * 2)) | (x3 << (8 * 1)) | getc_cur ();
|
|
+ int h;
|
|
+ h = getc_cur() << (8*3);
|
|
+ h |= getc_cur() << (8*2);
|
|
+ h |= getc_cur() << (8*1);
|
|
+ h |= getc_cur() << (8*0);
|
|
+ return h;
|
|
}
|
|
|
|
/** カレント・クライアントから1バイト取る **/
|
|
int
|
|
-getc_cur (void)
|
|
+getc_cur(void)
|
|
{
|
|
- static int rbp;
|
|
- if (rbc <= 0)
|
|
- {
|
|
- rbc = rcv_1_client (cur_clp);
|
|
- rbp = 0;
|
|
- }
|
|
- rbc--;
|
|
- return rcv_buf[rbp++] & 0xFF;
|
|
+#if DEBUG_IO
|
|
+ fprintf(stderr, "getc_cur: Enter\n");
|
|
+#endif
|
|
+ if (rp == rbp) {
|
|
+ rcv_1_client(cur_clp);
|
|
+ }
|
|
+#if DEBUG_IO
|
|
+ fprintf(stderr, "getc_cur: [%02x]\n", *rbp & 0xff);
|
|
+#endif
|
|
+ return *(rbp++) & 0xff;
|
|
}
|
|
|
|
/** クライアントから1パケット取る **/
|
|
static int
|
|
-rcv_1_client (int clp) /* clp=クライアント番号 */
|
|
+rcv_1_client(int clp) /* clp=クライアント番号 */
|
|
{
|
|
- int cc = 0;
|
|
- while (cc <= 0)
|
|
- {
|
|
- errno = 0;
|
|
+ int n = 0;
|
|
+
|
|
+ if (rbp == rp) {
|
|
+ rbp = rp = &rcv_buf[0];
|
|
+ }
|
|
+
|
|
+ while (rbp == rp) {
|
|
+ errno = 0;
|
|
#ifdef HAVE_RECV
|
|
- cc = recv (cblk[clp].sd, rcv_buf, S_BUF_SIZ, 0);
|
|
+ n = recv(cblk[clp].sd, rcv_buf, sizeof(rcv_buf), 0);
|
|
#else
|
|
- cc = read (cblk[clp].sd, rcv_buf, S_BUF_SIZ);
|
|
+ n = read(cblk[clp].sd, rcv_buf, sizeof(rcv_buf));
|
|
#endif
|
|
- if (cc <= 0)
|
|
- {
|
|
- if (ERRNO_CHECK (errno))
|
|
- {
|
|
- continue;
|
|
- }
|
|
- else if (cc == 0)
|
|
- { /* client dead */
|
|
- longjmp (client_dead, 666);
|
|
- }
|
|
- else
|
|
- { /* cc == -1 */
|
|
- if (errno != EINTR)
|
|
- longjmp (client_dead, 666);
|
|
- continue;
|
|
- }
|
|
- }
|
|
- }
|
|
-#ifdef DEBUG
|
|
- log_debug ("rcv: clp = %d, sd = %d, cc = %d", clp, cblk[clp].sd, cc);
|
|
- dmp (rcv_buf, cc);
|
|
+ if (n <= 0) {
|
|
+ if (ERRNO_CHECK (errno)) {
|
|
+ continue;
|
|
+ } else if (n == 0) {
|
|
+ /* client dead */
|
|
+ longjmp(client_dead, 666);
|
|
+ } else {
|
|
+ /* n == -1 */
|
|
+ if (errno != EINTR)
|
|
+ longjmp (client_dead, 666);
|
|
+ continue;
|
|
+ }
|
|
+ }
|
|
+ rp += n;
|
|
+ log_debug ("rcv: clp=%d, sd=%d, n=%d\n", clp, cblk[clp].sd, n);
|
|
+#if DEBUG_IO
|
|
+ dmp(rbp, rp - rbp);
|
|
#endif
|
|
- return cc;
|
|
+ }
|
|
+
|
|
+ return n;
|
|
}
|
|
|
|
/** クライアントへ1パケット送る **/
|
|
static void
|
|
-snd_1_client (int clp, /* clp: クライアント番号 */
|
|
- int n /* n : number of bytes to send */ )
|
|
+snd_1_client(int clp, int dummy)
|
|
{
|
|
- int cc, x;
|
|
-#ifdef DEBUG
|
|
- log_debug ("snd: clp = %d, sd = %d", clp, cblk[clp].sd);
|
|
- dmp (snd_buf, n);
|
|
+ unsigned char *bp = snd_buf;
|
|
+ int n;
|
|
+ size_t total = sp - bp;
|
|
+
|
|
+#if DEBUG_IO
|
|
+ fprintf(stderr, "snd: clp=%d, sd=%d\n", clp, cblk[clp].sd);
|
|
+ dmp(snd_buf, sp - bp);
|
|
#endif
|
|
- for (cc = 0; cc < n;)
|
|
- {
|
|
- errno = 0;
|
|
+
|
|
+ while (0 < sp - bp && sp <= snd_buf + sizeof(snd_buf)) {
|
|
+ errno =0;
|
|
#ifdef HAVE_SEND
|
|
- x = send (cblk[clp].sd, &snd_buf[cc], n - cc, 0);
|
|
+ n = send(cblk[clp].sd, bp, sp - bp, 0);
|
|
#else
|
|
- x = write (cblk[clp].sd, &snd_buf[cc], n - cc);
|
|
+ n = write(cblk[clp].sd, bp, sp - bp);
|
|
#endif
|
|
- if (x < 0)
|
|
- {
|
|
- if (ERRNO_CHECK (errno) || errno == EINTR)
|
|
- {
|
|
- errno = 0;
|
|
- continue;
|
|
- }
|
|
- else
|
|
- { /* client dead */
|
|
- longjmp (client_dead, 666);
|
|
- }
|
|
- }
|
|
- cc += x;
|
|
- }
|
|
+ if (n < 0) {
|
|
+ if (ERRNO_CHECK (errno) || errno == EINTR) {
|
|
+ continue;
|
|
+ } else {
|
|
+ /* client dead */
|
|
+ longjmp (client_dead, 666);
|
|
+ }
|
|
+ }
|
|
+ bp += n;
|
|
+ }
|
|
+ sp = snd_buf;
|
|
}
|
|
|
|
-/** **/
|
|
void
|
|
-puts_cur (char *p)
|
|
+puts_cur(char *p)
|
|
{
|
|
- int c;
|
|
- while (c = *p++)
|
|
- putc_cur (c);
|
|
- putc_cur (0);
|
|
+ int c;
|
|
+ while(c = *p++)
|
|
+ putc_cur(c);
|
|
+ putc_cur(0x00);
|
|
}
|
|
|
|
-/** **/
|
|
void
|
|
-puts_n_cur (char *p, int n)
|
|
+puts_n_cur(char *p, int n)
|
|
{
|
|
- int c;
|
|
- while ((c = *p++) && --n >= 0)
|
|
- putc_cur (c);
|
|
- putc_cur (0);
|
|
+ int c;
|
|
+ while ((c = *p++) && --n >= 0)
|
|
+ putc_cur(c);
|
|
+ putc_cur(0x00);
|
|
}
|
|
|
|
-/** **/
|
|
void
|
|
-putws_cur (w_char *p)
|
|
+putws_cur(w_char *p)
|
|
{
|
|
- int c;
|
|
- while (c = *p++)
|
|
- put2_cur (c);
|
|
- put2_cur (0);
|
|
+ int c;
|
|
+ while (c = *p++)
|
|
+ put2_cur(c);
|
|
+ put2_cur(0x0000);
|
|
}
|
|
|
|
-/** **/
|
|
void
|
|
-putnws_cur (w_char *p, int n)
|
|
+putnws_cur(w_char *p, int n)
|
|
{
|
|
- int c;
|
|
- for (; n > 0; n--)
|
|
- {
|
|
- if ((c = *p++) == 0)
|
|
- break;
|
|
- put2_cur (c);
|
|
- }
|
|
- put2_cur (0);
|
|
+ unsigned int c;
|
|
+ for (; n > 0; n--) {
|
|
+ if ((c = *p++) == 0)
|
|
+ break;
|
|
+ put2_cur(c);
|
|
+ }
|
|
+ put2_cur(0x0000);
|
|
}
|
|
|
|
-/** カレント・クライアントへ2バイト送る **/
|
|
void
|
|
-put2_cur (int c)
|
|
+put2_cur(int c)
|
|
{
|
|
- putc_cur (c >> (8 * 1));
|
|
- putc_cur (c);
|
|
+ putc_cur(c >> (8 * 1));
|
|
+ putc_cur(c);
|
|
}
|
|
|
|
-/** カレント・クライアントへ4バイト送る **/
|
|
void
|
|
-put4_cur (int c)
|
|
+put4_cur(int c)
|
|
{
|
|
- putc_cur (c >> (8 * 3));
|
|
- putc_cur (c >> (8 * 2));
|
|
- putc_cur (c >> (8 * 1));
|
|
- putc_cur (c);
|
|
+ putc_cur(c >> (8 * 3));
|
|
+ putc_cur(c >> (8 * 2));
|
|
+ putc_cur(c >> (8 * 1));
|
|
+ putc_cur(c);
|
|
}
|
|
|
|
-/** カレント・クライアントへ1バイト送る **/
|
|
void
|
|
-putc_cur (int c)
|
|
+putc_cur(int c)
|
|
{
|
|
- snd_buf[sbp++] = c;
|
|
- if (sbp >= R_BUF_SIZ)
|
|
- {
|
|
- snd_1_client (cur_clp, R_BUF_SIZ);
|
|
- sbp = 0;
|
|
- }
|
|
+#if DEBUG_IO
|
|
+ fprintf(stderr, "putc_cur: Enter\n");
|
|
+#endif
|
|
+ if (snd_buf + sizeof(snd_buf) <= sp)
|
|
+ putc_purge();
|
|
+
|
|
+#if DEBUG_IO
|
|
+ fprintf(stderr, "putc_cur: [%02x]\n", c & 0xff);
|
|
+#endif
|
|
+ *(sp++) = c & 0xff;
|
|
}
|
|
|
|
-/** カレント・クライアントの送信バッファをフラッシュする **/
|
|
+/* flush send buffer */
|
|
void
|
|
-putc_purge (void)
|
|
+putc_purge(void)
|
|
{
|
|
- if (sbp != 0)
|
|
- {
|
|
- snd_1_client (cur_clp, sbp);
|
|
- sbp = 0;
|
|
- }
|
|
+ if (snd_buf < sp) {
|
|
+ snd_1_client(cur_clp, 0);
|
|
+ }
|
|
}
|
|
|
|
-/*-----*/
|
|
-
|
|
-/** ソケットのイニシャライズ **/
|
|
+/* initialize sockets */
|
|
#ifdef AF_UNIX
|
|
+#if !defined(SUN_LEN)
|
|
+# define SUN_LEN(su) (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
|
|
+#endif
|
|
+
|
|
static void
|
|
-socket_init_un (void)
|
|
+socket_init_un(int *index)
|
|
{
|
|
- struct sockaddr_un saddr_un;
|
|
- int sock_d_un;
|
|
- if (serverNO == 0)
|
|
- {
|
|
- saddr_un.sun_family = AF_UNIX;
|
|
- unlink (sockname);
|
|
- strcpy (saddr_un.sun_path, sockname);
|
|
- if ((sock_d_un = socket (AF_UNIX, SOCK_STREAM, 0)) == ERROR)
|
|
- {
|
|
- xerror ("could not create unix domain socket");
|
|
- }
|
|
- if (bind (sock_d_un, (struct sockaddr *) &saddr_un, strlen (saddr_un.sun_path) + 2) == ERROR)
|
|
- {
|
|
- shutdown (sock_d_un, 2);
|
|
- xerror ("could not bind unix domain socket");
|
|
+ struct sockaddr_un saddr_un;
|
|
+ int sock_d_un;
|
|
+
|
|
+ saddr_un.sun_family = AF_UNIX;
|
|
+ strncpy(saddr_un.sun_path, sockname, sizeof(saddr_un.sun_path) - 1);
|
|
+ saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
|
|
+
|
|
+ unlink(saddr_un.sun_path);
|
|
+
|
|
+ if ((sock_d_un = socket(saddr_un.sun_family, SOCK_STREAM, 0)) == ERROR)
|
|
+ xerror("could not create unix domain socket");
|
|
+
|
|
+ if (bind(sock_d_un,
|
|
+ (struct sockaddr *)&saddr_un,
|
|
+ SUN_LEN(&saddr_un)) == ERROR) {
|
|
+ shutdown (sock_d_un, 2);
|
|
+ xerror("could not bind unix domain socket");
|
|
}
|
|
- if (listen (sock_d_un, 5) == ERROR)
|
|
- {
|
|
- shutdown (sock_d_un, 2);
|
|
- xerror ("could not listen unix domain socket");
|
|
+
|
|
+ if (listen(sock_d_un, 5) == ERROR) {
|
|
+ shutdown (sock_d_un, 2);
|
|
+ xerror("could not listen unix domain socket");
|
|
}
|
|
- chmod (sockname, 0777);
|
|
- signal (SIGPIPE, SIG_IGN);
|
|
-#ifdef DEBUG
|
|
- log_debug ("sock_d_un = %d", sock_d_un);
|
|
-#endif
|
|
- accept_blk[UNIX_ACPT].sd = sock_d_un;
|
|
- FD_SET (sock_d_un, all_socks);
|
|
- }
|
|
+
|
|
+ chmod(sockname, 0777);
|
|
+ signal(SIGPIPE, SIG_IGN);
|
|
+ log_debug("sock_d_un = %d (bindex=%d)", sock_d_un, *index);
|
|
+ accept_blk[(*index)].sd = sock_d_un;
|
|
+ accept_blk[(*index)].domain = saddr_un.sun_family;
|
|
+ (*index)++;
|
|
+ FD_SET (sock_d_un, all_socks);
|
|
}
|
|
#endif /* AF_UNIX */
|
|
|
|
/* Inet V3.0 */
|
|
static void
|
|
-socket_init_in (void)
|
|
+socket_init_in(int *index)
|
|
{
|
|
+ int i;
|
|
#ifndef SOLARIS
|
|
- int on = 1;
|
|
+ int on = 1;
|
|
#else /* SOLARIS */
|
|
- int on = 0;
|
|
+ int on = 0;
|
|
#endif /* SOLARIS */
|
|
- struct servent *sp;
|
|
+
|
|
+ struct servent *sp;
|
|
#if !defined(SO_DONTLINGER) && defined(SO_LINGER)
|
|
- struct linger linger;
|
|
+ struct linger linger;
|
|
#endif
|
|
-#ifdef INET6
|
|
- struct addrinfo hints, *res, *res0;
|
|
- int error;
|
|
- char sport[6];
|
|
-#else
|
|
- struct sockaddr_in saddr_in;
|
|
-#endif
|
|
- int sock_d_in;
|
|
-
|
|
- if (port < 0)
|
|
- {
|
|
- if ((sp = getservbyname (SERVERNAME, "tcp")) == NULL)
|
|
- {
|
|
- port = WNN_PORT_IN;
|
|
- }
|
|
- else
|
|
- {
|
|
- port = ntohs (sp->s_port);
|
|
- }
|
|
- }
|
|
+ struct addrinfo hints, *res, *res0;
|
|
+ struct sockaddr sa;
|
|
+ int error;
|
|
+ char hbuf[NI_MAXHOST];
|
|
+ char sbuf[NI_MAXSERV];
|
|
+ int sock_d_in;
|
|
+
|
|
+ memset(&sa, 0, sizeof(struct sockaddr));
|
|
+ if (port < 0) {
|
|
+ strncpy(sbuf, SERVERNAME, sizeof(sbuf) - 1);
|
|
+ sbuf[sizeof(sbuf) - 1] = '\0';
|
|
+ error = getnameinfo(&sa,
|
|
+ sa.sa_len,
|
|
+ NULL,
|
|
+ 0,
|
|
+ sbuf,
|
|
+ sizeof(sbuf),
|
|
+ NI_NUMERICSERV);
|
|
+ if (error)
|
|
+ sprintf(sbuf, "%d", WNN_PORT_IN);
|
|
+ } else {
|
|
+ sprintf(sbuf, "%d", port);
|
|
+ }
|
|
|
|
- port += serverNO;
|
|
+ port += serverNO;
|
|
|
|
-#if DEBUG
|
|
- log_debug ("port=%x", port);
|
|
-#endif
|
|
-#ifdef INET6
|
|
- memset(&hints, 0, sizeof(hints));
|
|
- if (listen_proto&PROTO_INET && !(listen_proto&PROTO_INET6))
|
|
- hints.ai_family = PF_INET;
|
|
- else if (listen_proto&PROTO_INET6 && !(listen_proto&PROTO_INET))
|
|
- hints.ai_family = PF_INET6;
|
|
- else
|
|
- hints.ai_family = PF_UNSPEC;
|
|
- hints.ai_socktype = SOCK_STREAM;
|
|
- hints.ai_flags = AI_PASSIVE;
|
|
- sprintf(sport, "%d", port);
|
|
- error = getaddrinfo(NULL, sport, &hints, &res0);
|
|
- if (error)
|
|
- {
|
|
- xerror (gai_strerror(error));
|
|
- }
|
|
- for (res = res0; res; res = res->ai_next) {
|
|
- if (res->ai_family == AF_INET || res->ai_family == AF_INET6){
|
|
- if ((sock_d_in = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) == ERROR)
|
|
-#else
|
|
- saddr_in.sin_family = AF_INET;
|
|
- saddr_in.sin_port = htons (port);
|
|
- saddr_in.sin_addr.s_addr = htonl (INADDR_ANY);
|
|
- if ((sock_d_in = socket (AF_INET, SOCK_STREAM, 0)) == ERROR)
|
|
-#endif
|
|
- {
|
|
+ memset(&hints, 0, sizeof(hints));
|
|
+ if (listen_proto & PROTO_INET
|
|
+ || listen_proto & PROTO_INET6)
|
|
+ hints.ai_family = PF_UNSPEC;
|
|
+ hints.ai_socktype = SOCK_STREAM;
|
|
+ hints.ai_flags = AI_PASSIVE;
|
|
+
|
|
+ for (i = 0; i < MAXLISTENADDR && listenaddr[i][0] != '\0'; i++) {
|
|
+ log_debug("getaddrinfo: try %s",listenaddr[i]);
|
|
+
|
|
+ if (error = getaddrinfo(listenaddr[i], sbuf, &hints, &res0))
|
|
+ xerror((char *)gai_strerror(error));
|
|
+
|
|
+ for (res = res0; res; res = res->ai_next) {
|
|
+ log_debug("socket: try %s : %s (type=%d)",
|
|
+ listenaddr[i], sbuf, res->ai_family);
|
|
+
|
|
+ switch (res->ai_family) {
|
|
+ case AF_INET:
|
|
+ if (!(listen_proto & PROTO_INET)) {
|
|
+ log_debug("socket: ignore %s\n", listenaddr[i]);
|
|
+ continue;
|
|
+ }
|
|
+ sock_d_in = socket(res->ai_family,
|
|
+ res->ai_socktype,
|
|
+ res->ai_protocol);
|
|
+ if (sock_d_in == -1)
|
|
+ xerror("could not create inet socket");
|
|
+ break;
|
|
#ifdef INET6
|
|
- if (res->ai_family == AF_INET6)
|
|
- xerror ("could not create inet6 socket");
|
|
- else if (res->ai_family == AF_INET)
|
|
+ case AF_INET6:
|
|
+ if (!(listen_proto & PROTO_INET6)) {
|
|
+ log_debug("socket: ignore %s\n", listenaddr[i]);
|
|
+ continue;
|
|
+ }
|
|
+ sock_d_in = socket(res->ai_family,
|
|
+ res->ai_socktype,
|
|
+ res->ai_protocol);
|
|
+ if (sock_d_in == -1)
|
|
+ xerror("could not create inet6 socket");
|
|
+#ifdef IPV6_V6ONLY
|
|
+ setsockopt(sock_d_in, IPPROTO_IPV6, IPV6_V6ONLY, NULL, 0);
|
|
#endif
|
|
- xerror ("could not create inet socket");
|
|
- }
|
|
- setsockopt (sock_d_in, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (int));
|
|
+#endif /* INET6 */
|
|
+ }
|
|
+ setsockopt (sock_d_in, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (int));
|
|
#ifdef SO_DONTLINGER
|
|
- setsockopt (sock_d_in, SOL_SOCKET, SO_DONTLINGER, (char *) 0, 0);
|
|
+ setsockopt (sock_d_in, SOL_SOCKET, SO_DONTLINGER, (char *) 0, 0);
|
|
#else
|
|
# ifdef SO_LINGER
|
|
- linger.l_onoff = 0;
|
|
- linger.l_linger = 0;
|
|
- setsockopt (sock_d_in, SOL_SOCKET, SO_LINGER, (char *) &linger, sizeof linger);
|
|
+ linger.l_onoff = 0;
|
|
+ linger.l_linger = 0;
|
|
+ setsockopt(sock_d_in, SOL_SOCKET, SO_LINGER, (char *) &linger, sizeof linger);
|
|
# endif /* SO_LINGER */
|
|
#endif /* SO_DONTLINGER */
|
|
|
|
-#ifdef INET6
|
|
- if (bind (sock_d_in, res->ai_addr, res->ai_addrlen) == ERROR)
|
|
-#else
|
|
- if (bind (sock_d_in, (struct sockaddr *) &saddr_in, sizeof (saddr_in)) == ERROR)
|
|
-#endif
|
|
- {
|
|
- shutdown (sock_d_in, 2);
|
|
-#ifdef INET6
|
|
- if (res->ai_family == AF_INET6)
|
|
- xerror ("can't bind inet6 socket");
|
|
- else if (res->ai_family == AF_INET)
|
|
-#endif
|
|
- xerror ("can't bind inet socket");
|
|
- }
|
|
- if (listen (sock_d_in, 5) == ERROR)
|
|
- {
|
|
- shutdown (sock_d_in, 2);
|
|
-#ifdef INET6
|
|
- if (res->ai_family == AF_INET6)
|
|
- xerror ("can't listen inet6 socket");
|
|
- else if (res->ai_family == AF_INET)
|
|
-#endif
|
|
- xerror ("can't listen inet socket");
|
|
- }
|
|
-#if DEBUG
|
|
- log_debug ("sock_d_in = %d", sock_d_in);
|
|
-#endif
|
|
- FD_SET (sock_d_in, all_socks);
|
|
-#ifdef INET6
|
|
- if (res->ai_family == AF_INET)
|
|
- accept_blk[INET_ACPT].sd = sock_d_in;
|
|
- else if (res->ai_family == AF_INET6)
|
|
- accept_blk[INET6_ACPT].sd = sock_d_in;
|
|
- }
|
|
- }
|
|
- freeaddrinfo(res0);
|
|
-#else
|
|
- accept_blk[INET_ACPT].sd = sock_d_in;
|
|
-#endif
|
|
+ if (bind(sock_d_in, res->ai_addr, res->ai_addrlen) == ERROR) {
|
|
+ shutdown (sock_d_in, 2);
|
|
+ xerror("could not bind inet/inet6 socket");
|
|
+ }
|
|
+
|
|
+ if (listen(sock_d_in, 5) == ERROR) {
|
|
+ shutdown (sock_d_in, 2);
|
|
+ xerror("could not listen inet/inet6 socket");
|
|
+ }
|
|
+
|
|
+ log_debug("sock_d_in = %d (bindex=%d)",
|
|
+ sock_d_in, *index);
|
|
+ FD_SET(sock_d_in, all_socks);
|
|
+ accept_blk[(*index)].sd = sock_d_in;
|
|
+ accept_blk[(*index)].domain = res->ai_family;
|
|
+ (*index)++;
|
|
+ }
|
|
+ }
|
|
+ freeaddrinfo(res0);
|
|
}
|
|
|
|
-
|
|
/** accept new client socket **/
|
|
-#ifdef AF_UNIX
|
|
static int
|
|
-socket_accept_un (void)
|
|
+socket_accept(int index)
|
|
{
|
|
- struct sockaddr_un addr;
|
|
- socklen_t addrlen;
|
|
-
|
|
- addrlen = sizeof (addr);
|
|
- return accept (accept_blk[UNIX_ACPT].sd, (struct sockaddr *) &addr, &addrlen);
|
|
-}
|
|
-#endif /* AF_UNIX */
|
|
-
|
|
-static int
|
|
-socket_accept_in (int fd)
|
|
-{
|
|
- struct sockaddr_in addr;
|
|
- socklen_t addrlen;
|
|
-
|
|
- addrlen = sizeof (addr);
|
|
- return accept (fd, (struct sockaddr *) &addr, &addrlen);
|
|
+ return accept(accept_blk[index].sd, NULL, NULL);
|
|
}
|
|
|
|
static void
|
|
-xerror (char *s)
|
|
+xerror(char *s)
|
|
{
|
|
- log_err ("%s (%s).", s, strerror(errno));
|
|
- exit (1);
|
|
+ log_err ("%s (%s).", s, strerror(errno));
|
|
+ exit (1);
|
|
}
|
|
|
|
-#if DEBUG
|
|
static void
|
|
-dmp (char *p, int n)
|
|
+dmp(char *p, int n)
|
|
{
|
|
- int i, j;
|
|
+ int i, j;
|
|
|
|
- for (i = 0; i < n; i += 16)
|
|
- {
|
|
- for (j = 0; j < 16; j++)
|
|
- {
|
|
- fprintf (stderr, "%02x ", p[i + j] & 0xFF);
|
|
- }
|
|
- fprintf (stderr, "n=%d\n", n);
|
|
- }
|
|
+ for (i = 0; i < n; i += 16) {
|
|
+ for (j = 0; j < 16; j++) {
|
|
+ fprintf (stderr, "%02x ", p[i + j] & 0xFF);
|
|
+ }
|
|
+ fprintf (stderr, "n=%d\n", n);
|
|
+ }
|
|
}
|
|
-#endif
|
|
|
|
static void
|
|
-get_options (int argc, char **argv)
|
|
+get_options(int argc, char **argv)
|
|
{
|
|
- int c;
|
|
- int digit_optind = 0;
|
|
-
|
|
- strcpy (jserverrcfile, LIBDIR); /* usr/local/lib/wnn */
|
|
- strcat (jserverrcfile, SERVER_INIT_FILE); /* ja_JP/jserverrc */
|
|
+ int c;
|
|
+ int digit_optind = 0;
|
|
+ int lindex = 0;
|
|
|
|
- while (1)
|
|
- {
|
|
- int this_option_optind = optind ? optind : 1;
|
|
- int option_index = 0;
|
|
- static struct option long_options[] =
|
|
- {
|
|
- {"baseport", 1, NULL, 'p'},
|
|
- {"inet", 0, NULL, '4'},
|
|
- {"inet6", 0, NULL, '6'},
|
|
- {"jserverrc", 1, NULL, 'f'},
|
|
- {"version", 0, NULL, 'v'},
|
|
- {0, 0, 0, 0}
|
|
- };
|
|
-
|
|
- c = getopt_long (argc, argv, OPTIONARGS,
|
|
- long_options, &option_index);
|
|
- if (c == -1)
|
|
- break;
|
|
+ strcpy (jserverrcfile, LIBDIR); /* usr/local/lib/wnn */
|
|
+ strcat (jserverrcfile, SERVER_INIT_FILE); /* ja_JP/jserverrc */
|
|
|
|
- switch (c)
|
|
+ while (1)
|
|
{
|
|
- case 'D': /* do not detach, not a daemon */
|
|
- option_flag &= ~OPT_FORK;
|
|
- break;
|
|
-
|
|
- case 'f': /* --jserverrc FILENAME */
|
|
- strcpy (jserverrcfile, optarg);
|
|
- break;
|
|
-
|
|
- case 's':
|
|
- /* should nuke noisy someday */
|
|
- noisy = 1; option_flag |= OPT_VERBOSE;
|
|
- if (strcmp ("-", optarg) != 0)
|
|
- {
|
|
- /** maybe FILE wnnerr = stderr; or wnnerr = open(optarg...) is better? or freopen is normal method? */
|
|
- /** take a look at daemon(3) */
|
|
- if (freopen (optarg, "a", stderr) == NULL)
|
|
- {
|
|
- /** fprintf to stderr? */
|
|
- printf ("Error in opening scriptfile %s.\n", optarg);
|
|
- exit (1);
|
|
- }
|
|
- }
|
|
- log_debug ("script started");
|
|
- break;
|
|
-
|
|
- case 'h':
|
|
- /* var hinsi_file_name polluted */
|
|
- hinsi_file_name = optarg;
|
|
- break;
|
|
-
|
|
- case 'N':
|
|
- serverNO = atoi (optarg);
|
|
- /* error handling needed */
|
|
- break;
|
|
-
|
|
- case 'p':
|
|
- port = atoi (optarg);
|
|
- /* error handling needed */
|
|
- break;
|
|
-
|
|
- case 'v':
|
|
- print_version();
|
|
- usage();
|
|
- break;
|
|
-
|
|
- case 'u':
|
|
- listen_proto &= ~PROTO_ALL;
|
|
- listen_proto |= PROTO_UN;
|
|
- break;
|
|
-
|
|
- case '4':
|
|
- listen_proto &= ~PROTO_ALL;
|
|
- listen_proto |= PROTO_INET;
|
|
- break;
|
|
+ int this_option_optind = optind ? optind : 1;
|
|
+ int option_index = 0;
|
|
+ static struct option long_options[] =
|
|
+ {
|
|
+ {"baseport", 1, NULL, 'p'},
|
|
+ {"inet", 0, NULL, '4'},
|
|
+ {"inet6", 0, NULL, '6'},
|
|
+ {"jserverrc", 1, NULL, 'f'},
|
|
+ {"listenaddr", 1, NULL, 'a'},
|
|
+ {"unix", 0, NULL, 'u'},
|
|
+ {"version", 0, NULL, 'v'},
|
|
+ {0, 0, 0, 0}
|
|
+ };
|
|
+
|
|
+ c = getopt_long (argc, argv, OPTIONARGS,
|
|
+ long_options, &option_index);
|
|
+ if (c == -1)
|
|
+ break;
|
|
+
|
|
+ switch (c)
|
|
+ {
|
|
+ case 'D': /* do not detach, not a daemon */
|
|
+ option_flag &= ~OPT_FORK;
|
|
+ break;
|
|
+
|
|
+ case 'f': /* --jserverrc FILENAME */
|
|
+ strncpy(jserverrcfile, optarg, sizeof(jserverrcfile) - 1);
|
|
+ jserverrcfile[sizeof(jserverrcfile) - 1] = '\0';
|
|
+ break;
|
|
+
|
|
+ case 'a': /* --listenaddr ADDR */
|
|
+ strncpy(listenaddr[lindex], optarg, NI_MAXHOST - 1);
|
|
+ listenaddr[lindex][NI_MAXHOST - 1] = '\0';
|
|
+ lindex++;
|
|
+ break;
|
|
+
|
|
+ case 's':
|
|
+ /* should nuke noisy someday */
|
|
+ noisy = 1; option_flag |= OPT_VERBOSE;
|
|
+ if (strcmp ("-", optarg) != 0)
|
|
+ {
|
|
+ /** maybe FILE wnnerr = stderr; or wnnerr = open(optarg...) is better? or freopen is normal method? */
|
|
+ /** take a look at daemon(3) */
|
|
+ if (freopen (optarg, "a", stderr) == NULL)
|
|
+ {
|
|
+ /** fprintf to stderr? */
|
|
+ printf ("Error in opening scriptfile %s.\n", optarg);
|
|
+ exit (1);
|
|
+ }
|
|
+ }
|
|
+ log_debug ("script started");
|
|
+ break;
|
|
+
|
|
+ case 'h':
|
|
+ /* var hinsi_file_name polluted */
|
|
+ hinsi_file_name = optarg;
|
|
+ break;
|
|
+
|
|
+ case 'N':
|
|
+ serverNO = atoi (optarg);
|
|
+ /* error handling needed */
|
|
+ break;
|
|
+
|
|
+ case 'p':
|
|
+ port = atoi (optarg);
|
|
+ /* error handling needed */
|
|
+ break;
|
|
+
|
|
+ case 'v':
|
|
+ print_version();
|
|
+ usage();
|
|
+ break;
|
|
+
|
|
+ case 'u':
|
|
+ listen_proto |= PROTO_UN;
|
|
+ break;
|
|
+
|
|
+ case '4':
|
|
+ listen_proto |= PROTO_INET;
|
|
+ break;
|
|
|
|
#ifdef INET6
|
|
- case '6':
|
|
- listen_proto &= ~PROTO_ALL;
|
|
- listen_proto |= PROTO_INET6;
|
|
- break;
|
|
+ case '6':
|
|
+ listen_proto |= PROTO_INET6;
|
|
+ break;
|
|
#endif /* INET6 */
|
|
-
|
|
- default:
|
|
- print_version();
|
|
- usage();
|
|
- break;
|
|
+ default:
|
|
+ print_version();
|
|
+ usage();
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (!listen_proto) {
|
|
+ listen_proto = PROTO_ALL;
|
|
}
|
|
- }
|
|
}
|
|
|
|
|
|
-/*
|
|
-*/
|
|
void
|
|
js_who (void)
|
|
{
|
|
- int i, j;
|
|
+ int i, j;
|
|
|
|
- put4_cur (clientp);
|
|
- for (i = 0; i < clientp; i++)
|
|
- {
|
|
- put4_cur (cblk[i].sd);
|
|
- puts_cur (client[i].user_name);
|
|
- puts_cur (client[i].host_name);
|
|
- for (j = 0; j < WNN_MAX_ENV_OF_A_CLIENT; j++)
|
|
- {
|
|
- put4_cur ((client[i].env)[j]);
|
|
- }
|
|
+ put4_cur (clientp);
|
|
+ for (i = 0; i < clientp; i++)
|
|
+ {
|
|
+ put4_cur (cblk[i].sd);
|
|
+ puts_cur (client[i].user_name);
|
|
+ puts_cur (client[i].host_name);
|
|
+ for (j = 0; j < WNN_MAX_ENV_OF_A_CLIENT; j++)
|
|
+ {
|
|
+ put4_cur ((client[i].env)[j]);
|
|
+ }
|
|
|
|
- }
|
|
- putc_purge ();
|
|
+ }
|
|
+ putc_purge();
|
|
}
|
|
|
|
void
|
|
@@ -1302,25 +1230,25 @@ js_kill (void)
|
|
{
|
|
if (clientp == 1)
|
|
{
|
|
- put4_cur (0);
|
|
- putc_purge ();
|
|
+ put4_cur(0x00000000);
|
|
+ putc_purge();
|
|
terminate_hand ();
|
|
}
|
|
else
|
|
{
|
|
put4_cur (clientp - 1);
|
|
- putc_purge ();
|
|
+ putc_purge();
|
|
}
|
|
}
|
|
|
|
void
|
|
usage (void)
|
|
{
|
|
- fprintf(stderr,
|
|
+ fprintf(stderr,
|
|
#ifdef INET6
|
|
- "usage: %s [-Du46][-f <init_file> -s <log_file(\"-\" for stderr)> -h <pos_file> -N <serverNO> -p <port_base>]\n",
|
|
+ "usage: %s [-Du46][-f <init_file> -a <listenaddr> -s <log_file(\"-\" for stderr)> -h <pos_file> -N <serverNO> -p <port_base>]\n",
|
|
#else
|
|
- "usage: %s [-Du4][-f <init_file> -s <log_file(\"-\" for stderr)> -h <pos_file> -N <serverNO> -p <port_base>]\n",
|
|
+ "usage: %s [-Du4][-f <init_file> -a <listenaddr> -s <log_file(\"-\" for stderr)> -h <pos_file> -N <serverNO> -p <port_base>]\n",
|
|
#endif
|
|
cmd_name);
|
|
fprintf(stderr,
|