Path: blob/main/japanese/FreeWnn-server/files/patch-Wnn-jserver-de.c
16461 views
Index: Wnn/jserver/de.c1===================================================================2RCS file: /home/cvs/private/hrs/freewnn/Wnn/jserver/de.c,v3retrieving revision 1.1.1.14retrieving revision 1.85diff -u -p -r1.1.1.1 -r1.86--- Wnn/jserver/de.c 20 Dec 2008 07:13:30 -0000 1.1.1.17+++ Wnn/jserver/de.c 9 Sep 2014 16:18:01 -0000 1.88@@ -1,7 +1,7 @@9/*10* FreeWnn is a network-extensible Kana-to-Kanji conversion system.11* This file is part of FreeWnn.12- *13+ *14* Copyright Kyoto University Research Institute for Mathematical Sciences15* 1987, 1988, 1989, 1990, 1991, 199216* Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 199917@@ -102,54 +102,35 @@ static char rcs_id[] = "$Id: de.c,v 1.3618#endif1920#ifndef INET621-# define OPTIONARGS "Df:s:h:N:p:vu4"22+# define OPTIONARGS "a:Df:s:h:N:p:vu4"23#else24-# define OPTIONARGS "Df:s:h:N:p:vu46"25+# define OPTIONARGS "a:Df:s:h:N:p:vu46"26#endif /* INET6 */2728/* Accept Socket */29-#ifdef INET630-#define MAX_ACCEPTS 331-#else32-#define MAX_ACCEPTS 233-#endif34-#define UNIX_ACPT 035-#define INET_ACPT 136-#ifdef INET637-#define INET6_ACPT 238-#endif39+#define MAX_ACCEPTS 2564041-#define PROTO_ALL 0x142#define PROTO_UN 0x243#define PROTO_INET 0x444-#ifdef INET645#define PROTO_INET6 0x846-#endif47-static int listen_proto = PROTO_ALL;48+#define PROTO_ALL (PROTO_UN|PROTO_INET|PROTO_INET6)49+static int listen_proto;5051jmp_buf client_dead;5253static int port;54-static int serverNO = 0;55+static int serverNO;5657-struct cmblk58-{59- int sd; /** �����åȤ�fd **/60+struct cmblk {61+ int domain;62+ int sd; /* socket fd */63};64-#define COMS_BLOCK struct cmblk6566-static COMS_BLOCK *cblk;67- /** ���饤����Ȥ��ȤΥ����åȤ��������ơ��֥� **/68-69-static COMS_BLOCK accept_blk[MAX_ACCEPTS]; /*accept sock blocks */70-71-72-/* Communication Buffers */73-static char snd_buf[R_BUF_SIZ]; /** �����Хåե� **/74-static int sbp; /** �����Хåե��ݥ��� **/75-76-static int rbc; /** �����Хåե�counter **/77-static char rcv_buf[S_BUF_SIZ]; /** �����Хåե� **/78+/** ���饤����Ȥ��ȤΥ����åȤ��������ơ��֥� **/79+static struct cmblk *cblk;80+/*accept sock blocks */81+static struct cmblk accept_blk[MAX_ACCEPTS];82+static int bindex;8384#if defined(EAGAIN)85# if defined(EWOULDBLOCK)86@@ -167,7 +148,6 @@ static char rcv_buf[S_BUF_SIZ];8788/* Client Table */89int clientp; /** cblk��ͭ���ʥǡ����κǸ���Ƥ��� **/90-91int cur_clp; /** ���ߤΥ��饤����Ȥ��ֹ� **/9293static fd_set *all_socks; /** �ӥåȥѥ�����94@@ -181,27 +161,24 @@ struct msg_cat *wnn_msg_cat;95struct msg_cat *js_msg_cat;9697/* function prototypes */98-static void daemon_main (void);99-static void socket_disc_init (void);100-static void sel_all (void);101-static int get_client (void);102-static void new_client (void);103-static void daemon_init (void);104-static void daemon_fin_un (int);105-static void daemon_fin_in (int);106-static int rcv_1_client (int);107-static void snd_1_client (int, int);108-static void socket_init_un (void);109-static void socket_init_in (void);110-static int socket_accept_un (void);111-static int socket_accept_in (int);112-static void xerror (char*);113-static void get_options (int, char **);114-static void usage (void);115-static void print_version (void);116-#ifdef DEBUG117-static void dmp (char*, int);118-#endif119+static void daemon_main(void);120+static void socket_disc_init(void);121+static int sel_all(void);122+static int get_client(void);123+static void new_client(void);124+static void daemon_init(void);125+static void daemon_fin_un(int);126+static void daemon_fin_in(int);127+static int rcv_1_client(int);128+static void snd_1_client(int, int);129+static void socket_init_un(int *);130+static void socket_init_in(int *);131+static int socket_accept(int);132+static void xerror(char*);133+static void get_options(int, char **);134+static void usage(void);135+static void print_version(void);136+static void dmp(char*, int);137138static char cmd_name[16];139140@@ -214,154 +191,136 @@ int deny_severity;141142/* No arguments are used. Only options. */143int144-main (int argc, char *argv[])145+main(int argc, char *argv[])146{147- int tmpttyfd;148- char *cswidth_name;149- extern char *get_cswidth_name ();150- extern void set_cswidth ();151-152- char nlspath[64];153-154- strcpy (cmd_name, WNN_DAEMON_NAME);155- strcpy (lang_dir, LANG_NAME);156- strcpy (nlspath, LIBDIR);157- strcat (nlspath, "/%L/%N");158- js_msg_cat = msg_open (MESSAGE_FILE, nlspath, lang_dir);159- wnn_msg_cat = msg_open ("libwnn.msg", nlspath, lang_dir);160- if (wnn_msg_cat == NULL)161- {162- log_err ("cannot open message file libwnn.msg.");163- }164- if (cswidth_name = get_cswidth_name (LANG_NAME))165- set_cswidth (create_cswidth (cswidth_name));166+ int tmpttyfd;167+ pid_t pid;168+ int fd;169+ char *cswidth_name;170+ extern char *get_cswidth_name ();171+ extern void set_cswidth ();172+173+ char nlspath[64];174+175+ strcpy(cmd_name, WNN_DAEMON_NAME);176+ strcpy(lang_dir, LANG_NAME);177+ strcpy(nlspath, LIBDIR);178+ strcat(nlspath, "/%L/%N");179+ js_msg_cat = msg_open (MESSAGE_FILE, nlspath, lang_dir);180+ wnn_msg_cat = msg_open ("libwnn.msg", nlspath, lang_dir);181182- port = -1;183- /* option default */184- option_flag = (OPT_FORK & ~OPT_VERBOSE);185-186- setuid (geteuid ());187- get_options (argc, argv);188- print_version();189- log_debug("invoked as %s.", argv[0]);190- if (option_flag & OPT_FORK)191- {192- if (fork ())193- {194- signal (SIGCHLD, _exit);195- signal (SIGHUP, SIG_IGN);196- signal (SIGINT, SIG_IGN);197- signal (SIGQUIT, SIG_IGN);198-#ifdef SIGTSTP199- signal (SIGTSTP, SIG_IGN);200-#endif201- signal (SIGTERM, _exit);202- pause ();203+ if (wnn_msg_cat == NULL) {204+ log_err ("cannot open message file libwnn.msg.");205}206- }207+ if (cswidth_name = get_cswidth_name (LANG_NAME))208+ set_cswidth (create_cswidth (cswidth_name));209210+ port = -1;211+ /* option default */212+ option_flag = (OPT_FORK & ~OPT_VERBOSE);213+214+ setuid(geteuid());215+ get_options (argc, argv);216+ print_version();217+ log_debug("invoked as %s.", argv[0]);218#if defined(HAVE_LIBWRAP)219- allow_severity = LOG_INFO;220- deny_severity = LOG_WARNING;221- /* hosts_access_verbose = 2; */222+ allow_severity = LOG_INFO;223+ deny_severity = LOG_WARNING;224+ /* hosts_access_verbose = 2; */225#endif /* HAVE_LIBWRAP */226227- signal (SIGHUP, signal_hand);228- signal (SIGINT, signal_hand);229- signal (SIGQUIT, signal_hand);230- signal (SIGTERM, terminate_hand);231- if (option_flag & OPT_FORK)232- {233-#ifdef SIGTSTP234- signal (SIGTSTP, SIG_IGN);235+ signal(SIGHUP, signal_hand);236+ signal(SIGQUIT, signal_hand);237+ signal(SIGTERM, terminate_hand);238+ if (option_flag & OPT_FORK) {239+ /* when -D is not specified, accept SIGINT */240+ signal(SIGINT, signal_hand);241+#ifdef SIGTSTP242+ signal(SIGTSTP, SIG_IGN);243#endif /* SIGTSTP */244- }245- read_default ();246- daemon_init ();247-248- env_init ();249- if (file_init () == NULL)250- {251- exit (1);252- }253- dic_init ();254- if (NULL == get_kaiseki_area (LENGTHCONV + 1)) /* �Ѵ���ǽʸ���� */255- {256- log_err ("get_kaiseki_area failed.");257- exit (1);258- }259- init_work_areas ();260- init_jmt ();261-262- read_default_files ();263-264- if (option_flag & OPT_FORK)265- {266- /* End of initialization, kill parent */267- kill (getppid (), SIGTERM);268- fclose (stdin);269- fclose (stdout);270- if (!(option_flag & OPT_VERBOSE))271- {272-#if !(defined(BSD) && (BSD >= 199306)) /* !4.4BSD-Lite by Taoka */273- fclose (stderr);274-#else /* 4.4BSD-Lite */275- int fd = open ("/dev/null", O_WRONLY);276- if (fd < 0)277- {278- xerror ("Cannot open /dev/null");279- }280- dup2 (fd, 2);281- close (fd);282-#endif /* 4.4BSD-Lite */283}284-285+ read_default();286+ daemon_init();287+ env_init();288+ if (file_init() == 0)289+ exit (1);290+ dic_init();291+ if (0 == get_kaiseki_area (LENGTHCONV + 1)) {292+ /* �Ѵ���ǽʸ���� */293+ log_err ("get_kaiseki_area failed.");294+ exit (1);295+ }296+ init_work_areas();297+ init_jmt();298+ read_default_files();299+ if (option_flag & OPT_FORK) {300+ pid = fork();301+ if (pid == -1) {302+ log_err ("cannot fork.");303+ exit(1);304+ }305+ if (pid > 0)306+ _exit(0);307+ setsid();308+ pid = fork();309+ if (pid == -1) {310+ log_err ("cannot fork.");311+ exit(1);312+ }313+ if (pid > 0)314+ _exit(0);315+ chdir("/");316+ umask(0);317+ close(STDIN_FILENO);318+ close(STDOUT_FILENO);319+ if (!(option_flag & OPT_VERBOSE)) {320+ close(STDERR_FILENO);321+ fd = open("/dev/null", O_WRONLY);322+ if (fd < 0) {323+ xerror ("Cannot open /dev/null");324+ }325+ dup2(fd, STDERR_FILENO);326+ close(fd);327+ }328#ifdef SETPGRP_VOID329- setpgrp ();330+ setpgrp();331#else /* !SETPGRP_VOID */332# if !defined(TIOCNOTTY) && defined(SVR4)333# define TIOCNOTTY _IO('t', 113)334# endif /* !defined(TIOCNOTTY) && defined(SVR4) */335#ifndef HITACHI336- if ((tmpttyfd = open ("/dev/tty", O_RDWR)) >= 0)337- {338- ioctl (tmpttyfd, TIOCNOTTY, 0);339- close (tmpttyfd);340- }341+ if ((tmpttyfd = open("/dev/tty", O_RDWR)) >= 0) {342+ ioctl(tmpttyfd, TIOCNOTTY, 0);343+ close(tmpttyfd);344+ }345#endif /* HITACHI */346#endif /* SETPGRP_VOID */347- }348-349- daemon_main ();350-351- daemon_fin ();352- return (0); /* it is not reached. only for avoiding compiler warning. */353+ }354+ daemon_main();355+ daemon_fin();356+ return(0); /* NOTREACHED */357}358359static void360daemon_main (void)361{362- for (;;)363- {364- c_c = NULL; /* Added for logging: server section */365- sel_all ();366- new_client ();367- for (;;)368- {369- if (get_client () == -1)370- break;371- c_c = &client[cur_clp];372- rbc = 0;373- sbp = 0;374+ for (;;) {375+ c_c = NULL; /* Added for logging: server section */376+ sel_all();377+ new_client();378+379+ for (;;) {380+ if (get_client () == -1)381+ break;382+ c_c = &client[cur_clp];383/* if(rcv_1_client(cur_clp) == 0){ del_client(); continue; } */384- if (setjmp (client_dead))385- {386- del_client ();387- continue;388- }389- do_command (c_c);390- }391- }392+ if (setjmp(client_dead)) {393+ del_client ();394+ continue;395+ }396+ do_command(c_c);397+ }398+ }399}400401/*402@@ -370,39 +329,36 @@ daemon_main (void)403static void404socket_disc_init (void)405{406- if (WNN_NFD <= FD_SETSIZE)407- {408- nofile = WNN_NFD;409- }410- else411- {412- nofile = FD_SETSIZE;413- }414- all_socks = (fd_set *) malloc (sizeof (fd_set));415- FD_ZERO (all_socks);416- ready_socks = (fd_set *) malloc (sizeof (fd_set));417- dummy1_socks = (fd_set *) malloc (sizeof (fd_set));418- dummy2_socks = (fd_set *) malloc (sizeof (fd_set));419+ nofile = MIN(WNN_NFD, FD_SETSIZE);420+421+ all_socks = (fd_set *)malloc(sizeof(fd_set));422+ ready_socks = (fd_set *)malloc(sizeof(fd_set));423+ dummy1_socks = (fd_set *)malloc(sizeof(fd_set));424+ dummy2_socks = (fd_set *)malloc(sizeof(fd_set));425+ FD_ZERO(all_socks);426+ FD_ZERO(ready_socks);427+ FD_ZERO(dummy1_socks);428+ FD_ZERO(dummy2_socks);429}430431/** ���ƤΥ����åȤˤĤ����Ԥ� **/432-static void433-sel_all (void)434+static int435+sel_all(void)436{437- memcpy (ready_socks, all_socks, sizeof (fd_set));438- bzero (dummy1_socks, sizeof (fd_set));439- bzero (dummy2_socks, sizeof (fd_set));440+ int ns = 0;441+ memcpy(ready_socks, all_socks, sizeof(fd_set));442+ FD_ZERO(dummy1_socks);443+ FD_ZERO(dummy2_socks);444445top:446- errno = 0;447- if ((no_of_ready_socks = select (nofile, ready_socks, dummy1_socks, dummy2_socks, NULL)) == -1)448- {449- if (errno == EINTR)450- goto top;451- xerror ("select error");452- }453+ errno = 0;454+ if ((no_of_ready_socks = select(nofile, ready_socks, dummy1_socks, dummy2_socks, NULL)) == -1) {455+ if (errno == EINTR)456+ goto top;457+ xerror ("select error");458+ }459#ifdef DEBUG460- log_debug ("select OK, ready_socks[0]=%02X, n-r-s=%x\n", ready_socks[0], no_of_ready_socks);461+ log_debug ("select OK, ready_socks[0]=%02X, n-r-s=%x\n", ready_socks[0], no_of_ready_socks);462#endif463}464465@@ -412,142 +368,136 @@ top:466static int467get_client (void)468{469- int i;470-471- if (no_of_ready_socks == 0)472- return -1; /* no client waits service */473-474- for (i = cur_clp;;)475- {476- if (no_of_ready_socks == 0)477- return -1;478- i++;479- if (i >= clientp)480- i = 0;481- if (FD_ISSET (cblk[i].sd, ready_socks))482- {483- FD_CLR (cblk[i].sd, ready_socks);484- no_of_ready_socks--;485- return cur_clp = i;486- }487- }488+ int i;489+490+ if (no_of_ready_socks == 0)491+ return -1; /* no client waits service */492+493+ for (i = cur_clp;;)494+ {495+ if (no_of_ready_socks == 0)496+ return -1;497+ i++;498+ if (i >= clientp)499+ i = 0;500+ if (FD_ISSET(cblk[i].sd, ready_socks)) {501+ FD_CLR(cblk[i].sd, ready_socks);502+ no_of_ready_socks--;503+ return (cur_clp = i);504+ }505+ }506}507508/** ���������饤����Ȥ���뤫�ݤ���Ĵ�٤�509�錄����cblk����Ͽ���� **/510static void511-new_client (void) /* NewClient */512+new_client(void)513{514- int sd;515- int full, i;516- FILE *f[3];517- char gomi[1024];518+ int sd = -1;519+ int full, i;520+ FILE *f[3];521+ char gomi[1024];522#ifdef HAVE_LIBWRAP523- int is_internet_socket;524- struct request_info tcpd_request;525+ int is_internet_socket;526+ struct request_info tcpd_request;527#endif /* HAVE_LIBWRAP */528-#ifdef AF_UNIX529- if ((serverNO == 0) &&530- (FD_ISSET (accept_blk[UNIX_ACPT].sd, ready_socks)))531- {532- FD_CLR (accept_blk[UNIX_ACPT].sd, ready_socks);533- no_of_ready_socks--;534- sd = socket_accept_un ();535+536+ log_debug("new client called");537+538+ for (i = 0; i < bindex && !FD_ISSET(accept_blk[i].sd, ready_socks); i++)539+ ;540+541+ if (i == bindex)542+ return;543+544+ FD_CLR(accept_blk[i].sd, ready_socks);545+ no_of_ready_socks--;546+ log_debug("new client: FDISSET(%d/%d) true, domain=%d",547+ i, bindex, accept_blk[i].domain);548+549+ switch (accept_blk[i].domain) {550+#ifdef AF_UNIX551+ case AF_UNIX:552+ sd = socket_accept(i);553#ifdef HAVE_LIBWRAP554- is_internet_socket = 0;555-#endif556- }557- else558+ is_internet_socket = 0;559+#endif /* HAVE_LIBWRAP */560+ break;561#endif562#ifdef INET6563- if (FD_ISSET (accept_blk[INET6_ACPT].sd, ready_socks))564- {565- FD_CLR (accept_blk[INET6_ACPT].sd, ready_socks);566- no_of_ready_socks--;567- sd = socket_accept_in (accept_blk[INET6_ACPT].sd);568-#ifdef HAVE_LIBWRAP569- is_internet_socket = 1;570-#endif571- }572- else573+ case AF_INET6:574#endif575- if (FD_ISSET (accept_blk[INET_ACPT].sd, ready_socks))576- {577- FD_CLR (accept_blk[INET_ACPT].sd, ready_socks);578- no_of_ready_socks--;579- sd = socket_accept_in (accept_blk[INET_ACPT].sd);580+ case AF_INET:581+ sd = socket_accept(i);582#ifdef HAVE_LIBWRAP583- is_internet_socket = 1;584-#endif585- }586- else587- {588- return;589- }590- log_debug ("new client: sd = %d", sd);591- /* reserve 2 fd */592- for (full = i = 0; i < 2; i++)593- {594- if (NULL == (f[i] = fopen ("/dev/null", "r")))595- {596- full = 1;597- }598- }599- for (i = 0; i < 2; i++)600- {601- if (NULL != f[i])602- fclose (f[i]);603- }604-605- if (full || sd >= nofile || clientp >= max_client)606- {607- log_err ("no more client.");608+ is_internet_socket = 1;609+#endif /* HAVE_LIBWRAP */610+ break;611+ default:612+ return;613+ }614+615+ log_debug("new client: sd = %d (type=%d)",616+ sd, accept_blk[i].domain);617+618+ /* reserve 2 fd */619+ for (full = i = 0; i < 2; i++) {620+ if (NULL == (f[i] = fopen ("/dev/null", "r"))) {621+ full = 1;622+ }623+ }624+625+ for (i = 0; i < 2; i++) {626+ if (NULL != f[i])627+ fclose (f[i]);628+ }629+630+ if (full || sd >= nofile || clientp >= max_client) {631+ log_err("no more client.");632#ifdef HAVE_RECV633- recv (sd, gomi, 1024, 0);634+ recv(sd, gomi, 1024, 0);635#else636- read (sd, gomi, 1024);637+ read(sd, gomi, 1024);638#endif639- shutdown (sd, 2);640+ shutdown(sd, 2);641#ifdef HAVE_CLOSESOCKET642- closesocket (sd);643+ closesocket(sd);644#else645- close (sd);646+ close(sd);647#endif648- return;649- }650-651+ return;652+ }653+654#ifdef HAVE_LIBWRAP655- if (is_internet_socket) {656- request_init (&tcpd_request,RQ_DAEMON, WNN_DAEMON_NAME,657- RQ_FILE, sd, NULL);658- fromhost (&tcpd_request);659- if (!hosts_access (&tcpd_request))660- {661- log_err ("reject client."); /* should be log_info? */662- /* should we log IP address / hostname? */663+ if (is_internet_socket) {664+ request_init (&tcpd_request,RQ_DAEMON, WNN_DAEMON_NAME,665+ RQ_FILE, sd, NULL);666+ fromhost (&tcpd_request);667+ if (!hosts_access (&tcpd_request)) {668+ log_err ("reject client."); /* should be log_info? */669+ /* should we log IP address / hostname? */670#ifdef HAVE_RECV671- recv (sd, gomi, 1024, 0);672+ recv(sd, gomi, 1024, 0);673#else674- read (sd, gomi, 1024);675+ read(sd, gomi, 1024);676#endif677- shutdown (sd, 2);678+ shutdown(sd, 2);679#ifdef HAVE_CLOSESOCKET680- closesocket (sd);681+ closesocket(sd);682#else683- close (sd);684+ close(sd);685#endif686- return;687- }688- }689+ return;690+ }691+ }692#endif /* HAVE_LIBWRAP */693-694- cblk[clientp].sd = sd;695- FD_SET (sd, all_socks);696- for (i = 0; i < WNN_MAX_ENV_OF_A_CLIENT; i++)697- {698- (client[clientp].env)[i] = -1;699- }700- clientp++;701+702+ cblk[clientp].sd = sd;703+ FD_SET(sd, all_socks);704+ for (i = 0; i < WNN_MAX_ENV_OF_A_CLIENT; i++) {705+ (client[clientp].env)[i] = -1;706+ }707+ clientp++;708}709710/** ���饤����Ȥ�cblk���������� **/711@@ -555,746 +505,726 @@ new_client (void) /* NewCl712void713del_client (void)714{715- disconnect_all_env_of_client ();716- FD_CLR (cblk[cur_clp].sd, all_socks);717+ disconnect_all_env_of_client ();718+ FD_CLR(cblk[cur_clp].sd, all_socks);719#ifdef HAVE_CLOSESOCKET720- closesocket (cblk[cur_clp].sd);721+ closesocket(cblk[cur_clp].sd);722#else723- close (cblk[cur_clp].sd);724+ close(cblk[cur_clp].sd);725#endif726/* logging here because c_c (used in log_debug) will be broken after727following section */728- log_debug("Delete Client: cur_clp = %d\n", cur_clp);729- cblk[cur_clp] = cblk[clientp - 1];730- client[cur_clp] = client[clientp - 1];731- /* Clear host/user name with zero - needed for logging */732- client[clientp - 1].user_name[0] = '\0'; /* Should we use bzero()? */733- client[clientp - 1].host_name[0] = '\0';734- clientp--;735-}736+ log_debug("Delete Client: cur_clp = %d\n", cur_clp);737+ cblk[cur_clp] = cblk[clientp - 1];738+ client[cur_clp] = client[clientp - 1];739+ /* Clear host/user name with zero - needed for logging */740+741+ /* Should we use bzero()? */742+ client[clientp - 1].user_name[0] = '\0';743744+ client[clientp - 1].host_name[0] = '\0';745+ clientp--;746+}747748/** �����Ф˥���饤������ **/749static void750-daemon_init (void) /* initialize Daemon */751+daemon_init(void) /* initialize Daemon */752{753- /*754- signal (SIGHUP, SIG_IGN);755- signal (SIGINT, SIG_IGN);756- signal (SIGQUIT, SIG_IGN);757- */758+ /*759+ signal (SIGHUP, SIG_IGN);760+ signal (SIGINT, SIG_IGN);761+ signal (SIGQUIT, SIG_IGN);762+ */763764+ if ((cblk = (struct cmblk *)malloc(max_client * sizeof(struct cmblk))) == NULL) {765+ xerror ("daemon_init: ");766+ }767+768+ if ((client = (CLIENT *)malloc(max_client * sizeof (CLIENT))) == NULL) {769+ xerror ("daemon_init: ");770+ }771+772+ SDRAND(time(NULL));773+ clientp = 0; /* V3.0 */774+ cur_clp = 0; /* V3.0 */775+ socket_disc_init();776777- if ((cblk = (COMS_BLOCK *) malloc (max_client * sizeof (COMS_BLOCK))) == NULL)778- {779- xerror ("daemon_init: ");780- }781- if ((client = (CLIENT *) malloc (max_client * sizeof (CLIENT))) == NULL)782- {783- xerror ("daemon_init: ");784- }785- SDRAND (time (NULL));786- clientp = 0; /* V3.0 */787- cur_clp = 0; /* V3.0 */788- socket_disc_init ();789-#ifdef INET6790- if (listen_proto&(PROTO_ALL|PROTO_INET|PROTO_INET6))791- socket_init_in ();792-#else793- if (listen_proto&(PROTO_ALL|PROTO_INET))794- socket_init_in ();795-#endif796#ifdef AF_UNIX797- if (listen_proto&(PROTO_ALL|PROTO_UN))798- socket_init_un ();799-#endif /* AF_UNIX */800+ if (listen_proto & PROTO_UN)801+ socket_init_un(&bindex);802+#endif803+ if (listen_proto & (PROTO_INET|PROTO_INET6))804+ socket_init_in(&bindex);805}806807/** �����Ф�� **/808-#ifdef AF_UNIX809+#ifdef AF_UNIX810static void811-daemon_fin_un (int sock_d_un)812+daemon_fin_un(int sock_d_un)813{814- int trueFlag = 1;815- struct sockaddr_un addr_un;816- socklen_t addrlen;817+ int trueFlag = 1;818+ struct sockaddr_un addr_un;819+ socklen_t addrlen;820821- if (serverNO == 0)822- {823#ifndef SOLARIS824#if defined(FIONBIO)825- ioctl (sock_d_un, FIONBIO, &trueFlag);826+ ioctl (sock_d_un, FIONBIO, &trueFlag);827#endif828#else /* !SOLARIS */829- fcntl (sock_d_un, F_SETFL, F_UNLCK);830+ fcntl (sock_d_un, F_SETFL, F_UNLCK);831#endif /* !SOLARIS */832- for (;;)833- {834- addrlen = sizeof (addr_un);835- if (accept (sock_d_un, (struct sockaddr *) &addr_un, &addrlen) < 0)836- break;837- /* EWOULDBLOCK EXPECTED, but we don't check */838+ for (;;) {839+ addrlen = sizeof (addr_un);840+ if (accept(sock_d_un,841+ (struct sockaddr *)&addr_un,842+ &addrlen) < 0)843+ break;844+ /* EWOULDBLOCK EXPECTED, but we don't check */845}846- shutdown (sock_d_un, 2);847- close (sock_d_un);848- }849+ shutdown (sock_d_un, 2);850+ close (sock_d_un);851}852#endif /* AF_UNIX */853854static void855-daemon_fin_in (int sock_d_in)856+daemon_fin_in(int sock_d_in)857{858- int trueFlag = 1;859- struct sockaddr_in addr_in;860- socklen_t addrlen;861+ int trueFlag = 1;862+ struct sockaddr_in addr_in;863+ socklen_t addrlen;864#ifdef USE_SETSOCKOPT865- int on = ~0;866+ int on = ~0;867#endif868869#ifndef SOLARIS870#ifdef USE_SETSOCKOPT871- setsockopt (sock_d_in, SOL_SOCKET, SO_NONBLOCK, &on, sizeof (int));872+ setsockopt(sock_d_in, SOL_SOCKET, SO_NONBLOCK, &on, sizeof(int));873#else874#if defined(FIONBIO)875- ioctl (sock_d_in, FIONBIO, &trueFlag);876+ ioctl(sock_d_in, FIONBIO, &trueFlag);877#endif878#endif /* USE_SETSOCKOPT */879#else /* !SOLARIS */880- fcntl (sock_d_in, F_SETFL, F_UNLCK);881+ fcntl(sock_d_in, F_SETFL, F_UNLCK);882#endif /* !SOLARIS */883- for (;;)884- {885- addrlen = sizeof (addr_in);886- if (accept (sock_d_in, (struct sockaddr *) &addr_in, &addrlen) < 0)887- break;888- /* EWOULDBLOCK EXPECTED, but we don't check */889- }890- shutdown (sock_d_in, 2);891+ for (;;) {892+ addrlen = sizeof(addr_in);893+ if (accept(sock_d_in,894+ (struct sockaddr *)&addr_in,895+ &addrlen) < 0)896+ break;897+ /* EWOULDBLOCK EXPECTED, but we don't check */898+ }899+ shutdown (sock_d_in, 2);900#ifdef HAVE_CLOSESOCKET901- closesocket (sock_d_in);902+ closesocket (sock_d_in);903#else904- close (sock_d_in);905+ close (sock_d_in);906#endif907}908909void910daemon_fin (void)911{912- int fd;913-#ifdef AF_UNIX914- int sock_d_un = accept_blk[UNIX_ACPT].sd;915-#endif /* AF_UNIX */916- int sock_d_in = accept_blk[INET_ACPT].sd;917-#ifdef INET6918- int sock_d_in6 = accept_blk[INET6_ACPT].sd;919-#endif920+ int i;921+ int fd;922923- /*924- accept all pending connection from new clients,925- avoiding kernel hangup.926- */927+ for (i = 0; i < bindex; i++) {928+ if (FD_ISSET(accept_blk[i].sd, all_socks)) {929+ switch (accept_blk[i].domain) {930#ifdef AF_UNIX931- daemon_fin_un (sock_d_un);932-#endif933- daemon_fin_in (sock_d_in);934+ case AF_UNIX:935+ if (listen_proto & PROTO_UN)936+ daemon_fin_un(accept_blk[i].sd);937+ break;938+#endif939+ case AF_INET:940+ if (listen_proto & PROTO_INET)941+ daemon_fin_in(accept_blk[i].sd);942+ break;943#ifdef INET6944- daemon_fin_in (sock_d_in6);945-#endif946+ case AF_INET6:947+ if (listen_proto & PROTO_INET6)948+ daemon_fin_in(accept_blk[i].sd);949+ break;950+#endif951+ default:952+ break;953+ }954+ }955+ }956957- for (fd = nofile - 1; fd >= 0; fd--)958- {959- if ((fd != sock_d_in) &&960-#ifdef INET6961- (fd != sock_d_in6) &&962-#endif963-#ifdef AF_UNIX964- (fd != sock_d_un) &&965-#endif /* AF_UNIX */966- FD_ISSET (fd, all_socks))967- {968- shutdown (fd, 2);969+ for (fd = nofile - 1; fd >= 0; fd--) {970+ if (FD_ISSET(fd, all_socks)) {971+ shutdown (fd, 2);972#ifdef HAVE_CLOSESOCKET973- closesocket (fd);974+ closesocket (fd);975#else976- close (fd);977+ close (fd);978#endif979- }980- }981+ }982+ }983}984985-/*------*/986+static unsigned char snd_buf[S_BUF_SIZ]; /** �����Хåե� **/987+static unsigned char *sp = snd_buf;988+989+static unsigned char rcv_buf[R_BUF_SIZ]; /** �����Хåե� **/990+static unsigned char *rbp = rcv_buf;991+static unsigned char *rp = rcv_buf;992993-/** **/994char *995-gets_cur (char *buffer, size_t buffer_size)996+gets_cur(char *buffer, size_t buffer_size)997{998- char *b;999+ char *b;10001001- if (!buffer || !buffer_size)1002- return NULL;1003+ if (!buffer || !buffer_size)1004+ return NULL;10051006- b = buffer;1007+ b = buffer;10081009- while (--buffer_size && (*b = getc_cur ()) != '\0')1010- b++;1011+ while (--buffer_size && (*b = getc_cur()) != '\0')1012+ b++;10131014- if (!buffer_size)1015- {1016- *b = '\0';1017- while (getc_cur () != '\0')1018- ;1019- }1020+ if (!buffer_size) {1021+ *b = '\0';1022+ while (getc_cur() != '\0')1023+ ;1024+ }10251026- return buffer;1027+ return buffer;1028}10291030/** **/1031w_char *1032-getws_cur (w_char *buffer, size_t buffer_size)1033+getws_cur(w_char *buffer, size_t buffer_size)1034{1035- w_char *b;1036+ w_char *b;10371038- if (!buffer || !buffer_size)1039- return NULL;1040+ if (!buffer || !buffer_size)1041+ return NULL;10421043- b = buffer;1044+ b = buffer;10451046- while (--buffer_size && (*b = get2_cur ()) != 0)1047- b++;1048+ while (--buffer_size && (*b = get2_cur ()) != 0)1049+ b++;10501051- if (!buffer_size)1052- {1053- *b = 0;1054- while (getc_cur () != 0)1055- ;1056- }1057-1058- return buffer;1059+ if (!buffer_size) {1060+ *b = 0;1061+ while (getc_cur () != 0)1062+ ;1063+ }1064+ return buffer;1065}10661067/** �����ȡ����饤����Ȥ���2�Х��ȼ�� **/1068int1069get2_cur (void)1070{1071- int x;1072- x = getc_cur ();1073- return (x << 8) | getc_cur ();1074+ int h;1075+ h = getc_cur () << 8;1076+ h |= getc_cur ();1077+ return h;1078}10791080/** �����ȡ����饤����Ȥ���4�Х��ȼ�� **/1081int1082get4_cur (void)1083{1084- int x1, x2, x3;1085- x1 = getc_cur ();1086- x2 = getc_cur ();1087- x3 = getc_cur ();1088- return (x1 << (8 * 3)) | (x2 << (8 * 2)) | (x3 << (8 * 1)) | getc_cur ();1089+ int h;1090+ h = getc_cur() << (8*3);1091+ h |= getc_cur() << (8*2);1092+ h |= getc_cur() << (8*1);1093+ h |= getc_cur() << (8*0);1094+ return h;1095}10961097/** �����ȡ����饤����Ȥ���1�Х��ȼ�� **/1098int1099-getc_cur (void)1100+getc_cur(void)1101{1102- static int rbp;1103- if (rbc <= 0)1104- {1105- rbc = rcv_1_client (cur_clp);1106- rbp = 0;1107- }1108- rbc--;1109- return rcv_buf[rbp++] & 0xFF;1110+#if DEBUG_IO1111+ fprintf(stderr, "getc_cur: Enter\n");1112+#endif1113+ if (rp == rbp) {1114+ rcv_1_client(cur_clp);1115+ }1116+#if DEBUG_IO1117+ fprintf(stderr, "getc_cur: [%02x]\n", *rbp & 0xff);1118+#endif1119+ return *(rbp++) & 0xff;1120}11211122/** ���饤����Ȥ���1�ѥ��åȼ�� **/1123static int1124-rcv_1_client (int clp) /* clp=���饤������ֹ� */1125+rcv_1_client(int clp) /* clp=���饤������ֹ� */1126{1127- int cc = 0;1128- while (cc <= 0)1129- {1130- errno = 0;1131+ int n = 0;1132+1133+ if (rbp == rp) {1134+ rbp = rp = &rcv_buf[0];1135+ }1136+1137+ while (rbp == rp) {1138+ errno = 0;1139#ifdef HAVE_RECV1140- cc = recv (cblk[clp].sd, rcv_buf, S_BUF_SIZ, 0);1141+ n = recv(cblk[clp].sd, rcv_buf, sizeof(rcv_buf), 0);1142#else1143- cc = read (cblk[clp].sd, rcv_buf, S_BUF_SIZ);1144+ n = read(cblk[clp].sd, rcv_buf, sizeof(rcv_buf));1145#endif1146- if (cc <= 0)1147- {1148- if (ERRNO_CHECK (errno))1149- {1150- continue;1151- }1152- else if (cc == 0)1153- { /* client dead */1154- longjmp (client_dead, 666);1155- }1156- else1157- { /* cc == -1 */1158- if (errno != EINTR)1159- longjmp (client_dead, 666);1160- continue;1161- }1162- }1163- }1164-#ifdef DEBUG1165- log_debug ("rcv: clp = %d, sd = %d, cc = %d", clp, cblk[clp].sd, cc);1166- dmp (rcv_buf, cc);1167+ if (n <= 0) {1168+ if (ERRNO_CHECK (errno)) {1169+ continue;1170+ } else if (n == 0) {1171+ /* client dead */1172+ longjmp(client_dead, 666);1173+ } else {1174+ /* n == -1 */1175+ if (errno != EINTR)1176+ longjmp (client_dead, 666);1177+ continue;1178+ }1179+ }1180+ rp += n;1181+ log_debug ("rcv: clp=%d, sd=%d, n=%d\n", clp, cblk[clp].sd, n);1182+#if DEBUG_IO1183+ dmp(rbp, rp - rbp);1184#endif1185- return cc;1186+ }1187+1188+ return n;1189}11901191/** ���饤����Ȥ�1�ѥ��å����� **/1192static void1193-snd_1_client (int clp, /* clp: ���饤������ֹ� */1194- int n /* n : number of bytes to send */ )1195+snd_1_client(int clp, int dummy)1196{1197- int cc, x;1198-#ifdef DEBUG1199- log_debug ("snd: clp = %d, sd = %d", clp, cblk[clp].sd);1200- dmp (snd_buf, n);1201+ unsigned char *bp = snd_buf;1202+ int n;1203+ size_t total = sp - bp;1204+1205+#if DEBUG_IO1206+ fprintf(stderr, "snd: clp=%d, sd=%d\n", clp, cblk[clp].sd);1207+ dmp(snd_buf, sp - bp);1208#endif1209- for (cc = 0; cc < n;)1210- {1211- errno = 0;1212+1213+ while (0 < sp - bp && sp <= snd_buf + sizeof(snd_buf)) {1214+ errno =0;1215#ifdef HAVE_SEND1216- x = send (cblk[clp].sd, &snd_buf[cc], n - cc, 0);1217+ n = send(cblk[clp].sd, bp, sp - bp, 0);1218#else1219- x = write (cblk[clp].sd, &snd_buf[cc], n - cc);1220+ n = write(cblk[clp].sd, bp, sp - bp);1221#endif1222- if (x < 0)1223- {1224- if (ERRNO_CHECK (errno) || errno == EINTR)1225- {1226- errno = 0;1227- continue;1228- }1229- else1230- { /* client dead */1231- longjmp (client_dead, 666);1232- }1233- }1234- cc += x;1235- }1236+ if (n < 0) {1237+ if (ERRNO_CHECK (errno) || errno == EINTR) {1238+ continue;1239+ } else {1240+ /* client dead */1241+ longjmp (client_dead, 666);1242+ }1243+ }1244+ bp += n;1245+ }1246+ sp = snd_buf;1247}12481249-/** **/1250void1251-puts_cur (char *p)1252+puts_cur(char *p)1253{1254- int c;1255- while (c = *p++)1256- putc_cur (c);1257- putc_cur (0);1258+ int c;1259+ while(c = *p++)1260+ putc_cur(c);1261+ putc_cur(0x00);1262}12631264-/** **/1265void1266-puts_n_cur (char *p, int n)1267+puts_n_cur(char *p, int n)1268{1269- int c;1270- while ((c = *p++) && --n >= 0)1271- putc_cur (c);1272- putc_cur (0);1273+ int c;1274+ while ((c = *p++) && --n >= 0)1275+ putc_cur(c);1276+ putc_cur(0x00);1277}12781279-/** **/1280void1281-putws_cur (w_char *p)1282+putws_cur(w_char *p)1283{1284- int c;1285- while (c = *p++)1286- put2_cur (c);1287- put2_cur (0);1288+ int c;1289+ while (c = *p++)1290+ put2_cur(c);1291+ put2_cur(0x0000);1292}12931294-/** **/1295void1296-putnws_cur (w_char *p, int n)1297+putnws_cur(w_char *p, int n)1298{1299- int c;1300- for (; n > 0; n--)1301- {1302- if ((c = *p++) == 0)1303- break;1304- put2_cur (c);1305- }1306- put2_cur (0);1307+ unsigned int c;1308+ for (; n > 0; n--) {1309+ if ((c = *p++) == 0)1310+ break;1311+ put2_cur(c);1312+ }1313+ put2_cur(0x0000);1314}13151316-/** �����ȡ����饤����Ȥ�2�Х������� **/1317void1318-put2_cur (int c)1319+put2_cur(int c)1320{1321- putc_cur (c >> (8 * 1));1322- putc_cur (c);1323+ putc_cur(c >> (8 * 1));1324+ putc_cur(c);1325}13261327-/** �����ȡ����饤����Ȥ�4�Х������� **/1328void1329-put4_cur (int c)1330+put4_cur(int c)1331{1332- putc_cur (c >> (8 * 3));1333- putc_cur (c >> (8 * 2));1334- putc_cur (c >> (8 * 1));1335- putc_cur (c);1336+ putc_cur(c >> (8 * 3));1337+ putc_cur(c >> (8 * 2));1338+ putc_cur(c >> (8 * 1));1339+ putc_cur(c);1340}13411342-/** �����ȡ����饤����Ȥ�1�Х������� **/1343void1344-putc_cur (int c)1345+putc_cur(int c)1346{1347- snd_buf[sbp++] = c;1348- if (sbp >= R_BUF_SIZ)1349- {1350- snd_1_client (cur_clp, R_BUF_SIZ);1351- sbp = 0;1352- }1353+#if DEBUG_IO1354+ fprintf(stderr, "putc_cur: Enter\n");1355+#endif1356+ if (snd_buf + sizeof(snd_buf) <= sp)1357+ putc_purge();1358+1359+#if DEBUG_IO1360+ fprintf(stderr, "putc_cur: [%02x]\n", c & 0xff);1361+#endif1362+ *(sp++) = c & 0xff;1363}13641365-/** �����ȡ����饤����Ȥ������Хåե���ե�å��夹�� **/1366+/* flush send buffer */1367void1368-putc_purge (void)1369+putc_purge(void)1370{1371- if (sbp != 0)1372- {1373- snd_1_client (cur_clp, sbp);1374- sbp = 0;1375- }1376+ if (snd_buf < sp) {1377+ snd_1_client(cur_clp, 0);1378+ }1379}13801381-/*-----*/1382-1383-/** �����åȤΥ��˥���饤�� **/1384+/* initialize sockets */1385#ifdef AF_UNIX1386+#if !defined(SUN_LEN)1387+# define SUN_LEN(su) (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))1388+#endif1389+1390static void1391-socket_init_un (void)1392+socket_init_un(int *index)1393{1394- struct sockaddr_un saddr_un;1395- int sock_d_un;1396- if (serverNO == 0)1397- {1398- saddr_un.sun_family = AF_UNIX;1399- unlink (sockname);1400- strcpy (saddr_un.sun_path, sockname);1401- if ((sock_d_un = socket (AF_UNIX, SOCK_STREAM, 0)) == ERROR)1402- {1403- xerror ("could not create unix domain socket");1404- }1405- if (bind (sock_d_un, (struct sockaddr *) &saddr_un, strlen (saddr_un.sun_path) + 2) == ERROR)1406- {1407- shutdown (sock_d_un, 2);1408- xerror ("could not bind unix domain socket");1409+ struct sockaddr_un saddr_un;1410+ int sock_d_un;1411+1412+ saddr_un.sun_family = AF_UNIX;1413+ strncpy(saddr_un.sun_path, sockname, sizeof(saddr_un.sun_path) - 1);1414+ saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';1415+1416+ unlink(saddr_un.sun_path);1417+1418+ if ((sock_d_un = socket(saddr_un.sun_family, SOCK_STREAM, 0)) == ERROR)1419+ xerror("could not create unix domain socket");1420+1421+ if (bind(sock_d_un,1422+ (struct sockaddr *)&saddr_un,1423+ SUN_LEN(&saddr_un)) == ERROR) {1424+ shutdown (sock_d_un, 2);1425+ xerror("could not bind unix domain socket");1426}1427- if (listen (sock_d_un, 5) == ERROR)1428- {1429- shutdown (sock_d_un, 2);1430- xerror ("could not listen unix domain socket");1431+1432+ if (listen(sock_d_un, 5) == ERROR) {1433+ shutdown (sock_d_un, 2);1434+ xerror("could not listen unix domain socket");1435}1436- chmod (sockname, 0777);1437- signal (SIGPIPE, SIG_IGN);1438-#ifdef DEBUG1439- log_debug ("sock_d_un = %d", sock_d_un);1440-#endif1441- accept_blk[UNIX_ACPT].sd = sock_d_un;1442- FD_SET (sock_d_un, all_socks);1443- }1444+1445+ chmod(sockname, 0777);1446+ signal(SIGPIPE, SIG_IGN);1447+ log_debug("sock_d_un = %d (bindex=%d)", sock_d_un, *index);1448+ accept_blk[(*index)].sd = sock_d_un;1449+ accept_blk[(*index)].domain = saddr_un.sun_family;1450+ (*index)++;1451+ FD_SET (sock_d_un, all_socks);1452}1453#endif /* AF_UNIX */14541455/* Inet V3.0 */1456static void1457-socket_init_in (void)1458+socket_init_in(int *index)1459{1460+ int i;1461#ifndef SOLARIS1462- int on = 1;1463+ int on = 1;1464#else /* SOLARIS */1465- int on = 0;1466+ int on = 0;1467#endif /* SOLARIS */1468- struct servent *sp;1469+1470+ struct servent *sp;1471#if !defined(SO_DONTLINGER) && defined(SO_LINGER)1472- struct linger linger;1473+ struct linger linger;1474#endif1475-#ifdef INET61476- struct addrinfo hints, *res, *res0;1477- int error;1478- char sport[6];1479-#else1480- struct sockaddr_in saddr_in;1481-#endif1482- int sock_d_in;1483-1484- if (port < 0)1485- {1486- if ((sp = getservbyname (SERVERNAME, "tcp")) == NULL)1487- {1488- port = WNN_PORT_IN;1489- }1490- else1491- {1492- port = ntohs (sp->s_port);1493- }1494- }1495+ struct addrinfo hints, *res, *res0;1496+ struct sockaddr sa;1497+ int error;1498+ char hbuf[NI_MAXHOST];1499+ char sbuf[NI_MAXSERV];1500+ int sock_d_in;1501+1502+ memset(&sa, 0, sizeof(struct sockaddr));1503+ if (port < 0) {1504+ strncpy(sbuf, SERVERNAME, sizeof(sbuf) - 1);1505+ sbuf[sizeof(sbuf) - 1] = '\0';1506+ error = getnameinfo(&sa,1507+ sa.sa_len,1508+ NULL,1509+ 0,1510+ sbuf,1511+ sizeof(sbuf),1512+ NI_NUMERICSERV);1513+ if (error)1514+ sprintf(sbuf, "%d", WNN_PORT_IN);1515+ } else {1516+ sprintf(sbuf, "%d", port);1517+ }15181519- port += serverNO;1520+ port += serverNO;15211522-#if DEBUG1523- log_debug ("port=%x", port);1524-#endif1525-#ifdef INET61526- memset(&hints, 0, sizeof(hints));1527- if (listen_proto&PROTO_INET && !(listen_proto&PROTO_INET6))1528- hints.ai_family = PF_INET;1529- else if (listen_proto&PROTO_INET6 && !(listen_proto&PROTO_INET))1530- hints.ai_family = PF_INET6;1531- else1532- hints.ai_family = PF_UNSPEC;1533- hints.ai_socktype = SOCK_STREAM;1534- hints.ai_flags = AI_PASSIVE;1535- sprintf(sport, "%d", port);1536- error = getaddrinfo(NULL, sport, &hints, &res0);1537- if (error)1538- {1539- xerror (gai_strerror(error));1540- }1541- for (res = res0; res; res = res->ai_next) {1542- if (res->ai_family == AF_INET || res->ai_family == AF_INET6){1543- if ((sock_d_in = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) == ERROR)1544-#else1545- saddr_in.sin_family = AF_INET;1546- saddr_in.sin_port = htons (port);1547- saddr_in.sin_addr.s_addr = htonl (INADDR_ANY);1548- if ((sock_d_in = socket (AF_INET, SOCK_STREAM, 0)) == ERROR)1549-#endif1550- {1551+ memset(&hints, 0, sizeof(hints));1552+ if (listen_proto & PROTO_INET1553+ || listen_proto & PROTO_INET6)1554+ hints.ai_family = PF_UNSPEC;1555+ hints.ai_socktype = SOCK_STREAM;1556+ hints.ai_flags = AI_PASSIVE;1557+1558+ for (i = 0; i < MAXLISTENADDR && listenaddr[i][0] != '\0'; i++) {1559+ log_debug("getaddrinfo: try %s",listenaddr[i]);1560+1561+ if (error = getaddrinfo(listenaddr[i], sbuf, &hints, &res0))1562+ xerror((char *)gai_strerror(error));1563+1564+ for (res = res0; res; res = res->ai_next) {1565+ log_debug("socket: try %s : %s (type=%d)",1566+ listenaddr[i], sbuf, res->ai_family);1567+1568+ switch (res->ai_family) {1569+ case AF_INET:1570+ if (!(listen_proto & PROTO_INET)) {1571+ log_debug("socket: ignore %s\n", listenaddr[i]);1572+ continue;1573+ }1574+ sock_d_in = socket(res->ai_family,1575+ res->ai_socktype,1576+ res->ai_protocol);1577+ if (sock_d_in == -1)1578+ xerror("could not create inet socket");1579+ break;1580#ifdef INET61581- if (res->ai_family == AF_INET6)1582- xerror ("could not create inet6 socket");1583- else if (res->ai_family == AF_INET)1584+ case AF_INET6:1585+ if (!(listen_proto & PROTO_INET6)) {1586+ log_debug("socket: ignore %s\n", listenaddr[i]);1587+ continue;1588+ }1589+ sock_d_in = socket(res->ai_family,1590+ res->ai_socktype,1591+ res->ai_protocol);1592+ if (sock_d_in == -1)1593+ xerror("could not create inet6 socket");1594+#ifdef IPV6_V6ONLY1595+ setsockopt(sock_d_in, IPPROTO_IPV6, IPV6_V6ONLY, NULL, 0);1596#endif1597- xerror ("could not create inet socket");1598- }1599- setsockopt (sock_d_in, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (int));1600+#endif /* INET6 */1601+ default:1602+ continue;1603+ }1604+ setsockopt (sock_d_in, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (int));1605#ifdef SO_DONTLINGER1606- setsockopt (sock_d_in, SOL_SOCKET, SO_DONTLINGER, (char *) 0, 0);1607+ setsockopt (sock_d_in, SOL_SOCKET, SO_DONTLINGER, (char *) 0, 0);1608#else1609# ifdef SO_LINGER1610- linger.l_onoff = 0;1611- linger.l_linger = 0;1612- setsockopt (sock_d_in, SOL_SOCKET, SO_LINGER, (char *) &linger, sizeof linger);1613+ linger.l_onoff = 0;1614+ linger.l_linger = 0;1615+ setsockopt(sock_d_in, SOL_SOCKET, SO_LINGER, (char *) &linger, sizeof linger);1616# endif /* SO_LINGER */1617#endif /* SO_DONTLINGER */16181619-#ifdef INET61620- if (bind (sock_d_in, res->ai_addr, res->ai_addrlen) == ERROR)1621-#else1622- if (bind (sock_d_in, (struct sockaddr *) &saddr_in, sizeof (saddr_in)) == ERROR)1623-#endif1624- {1625- shutdown (sock_d_in, 2);1626-#ifdef INET61627- if (res->ai_family == AF_INET6)1628- xerror ("can't bind inet6 socket");1629- else if (res->ai_family == AF_INET)1630-#endif1631- xerror ("can't bind inet socket");1632- }1633- if (listen (sock_d_in, 5) == ERROR)1634- {1635- shutdown (sock_d_in, 2);1636-#ifdef INET61637- if (res->ai_family == AF_INET6)1638- xerror ("can't listen inet6 socket");1639- else if (res->ai_family == AF_INET)1640-#endif1641- xerror ("can't listen inet socket");1642- }1643-#if DEBUG1644- log_debug ("sock_d_in = %d", sock_d_in);1645-#endif1646- FD_SET (sock_d_in, all_socks);1647-#ifdef INET61648- if (res->ai_family == AF_INET)1649- accept_blk[INET_ACPT].sd = sock_d_in;1650- else if (res->ai_family == AF_INET6)1651- accept_blk[INET6_ACPT].sd = sock_d_in;1652- }1653- }1654- freeaddrinfo(res0);1655-#else1656- accept_blk[INET_ACPT].sd = sock_d_in;1657-#endif1658+ if (bind(sock_d_in, res->ai_addr, res->ai_addrlen) == ERROR) {1659+ shutdown (sock_d_in, 2);1660+ xerror("could not bind inet/inet6 socket");1661+ }1662+1663+ if (listen(sock_d_in, 5) == ERROR) {1664+ shutdown (sock_d_in, 2);1665+ xerror("could not listen inet/inet6 socket");1666+ }1667+1668+ log_debug("sock_d_in = %d (bindex=%d)",1669+ sock_d_in, *index);1670+ FD_SET(sock_d_in, all_socks);1671+ accept_blk[(*index)].sd = sock_d_in;1672+ accept_blk[(*index)].domain = res->ai_family;1673+ (*index)++;1674+ }1675+ }1676+ freeaddrinfo(res0);1677}16781679-1680/** accept new client socket **/1681-#ifdef AF_UNIX1682static int1683-socket_accept_un (void)1684+socket_accept(int index)1685{1686- struct sockaddr_un addr;1687- socklen_t addrlen;1688-1689- addrlen = sizeof (addr);1690- return accept (accept_blk[UNIX_ACPT].sd, (struct sockaddr *) &addr, &addrlen);1691-}1692-#endif /* AF_UNIX */1693-1694-static int1695-socket_accept_in (int fd)1696-{1697- struct sockaddr_in addr;1698- socklen_t addrlen;1699-1700- addrlen = sizeof (addr);1701- return accept (fd, (struct sockaddr *) &addr, &addrlen);1702+ return accept(accept_blk[index].sd, NULL, NULL);1703}17041705static void1706-xerror (char *s)1707+xerror(char *s)1708{1709- log_err ("%s (%s).", s, strerror(errno));1710- exit (1);1711+ log_err ("%s (%s).", s, strerror(errno));1712+ exit (1);1713}17141715-#if DEBUG1716static void1717-dmp (char *p, int n)1718+dmp(char *p, int n)1719{1720- int i, j;1721+ int i, j;17221723- for (i = 0; i < n; i += 16)1724- {1725- for (j = 0; j < 16; j++)1726- {1727- fprintf (stderr, "%02x ", p[i + j] & 0xFF);1728- }1729- fprintf (stderr, "n=%d\n", n);1730- }1731+ for (i = 0; i < n; i += 16) {1732+ for (j = 0; j < 16; j++) {1733+ fprintf (stderr, "%02x ", p[i + j] & 0xFF);1734+ }1735+ fprintf (stderr, "n=%d\n", n);1736+ }1737}1738-#endif17391740static void1741-get_options (int argc, char **argv)1742+get_options(int argc, char **argv)1743{1744- int c;1745- int digit_optind = 0;1746-1747- strcpy (jserverrcfile, LIBDIR); /* usr/local/lib/wnn */1748- strcat (jserverrcfile, SERVER_INIT_FILE); /* ja_JP/jserverrc */1749+ int c;1750+ int digit_optind = 0;1751+ int lindex = 0;17521753- while (1)1754- {1755- int this_option_optind = optind ? optind : 1;1756- int option_index = 0;1757- static struct option long_options[] =1758- {1759- {"baseport", 1, NULL, 'p'},1760- {"inet", 0, NULL, '4'},1761- {"inet6", 0, NULL, '6'},1762- {"jserverrc", 1, NULL, 'f'},1763- {"version", 0, NULL, 'v'},1764- {0, 0, 0, 0}1765- };1766-1767- c = getopt_long (argc, argv, OPTIONARGS,1768- long_options, &option_index);1769- if (c == -1)1770- break;1771+ strcpy (jserverrcfile, LIBDIR); /* usr/local/lib/wnn */1772+ strcat (jserverrcfile, SERVER_INIT_FILE); /* ja_JP/jserverrc */17731774- switch (c)1775+ while (1)1776{1777- case 'D': /* do not detach, not a daemon */1778- option_flag &= ~OPT_FORK;1779- break;1780-1781- case 'f': /* --jserverrc FILENAME */1782- strcpy (jserverrcfile, optarg);1783- break;1784-1785- case 's':1786- /* should nuke noisy someday */1787- noisy = 1; option_flag |= OPT_VERBOSE;1788- if (strcmp ("-", optarg) != 0)1789- {1790- /** maybe FILE wnnerr = stderr; or wnnerr = open(optarg...) is better? or freopen is normal method? */1791- /** take a look at daemon(3) */1792- if (freopen (optarg, "a", stderr) == NULL)1793- {1794- /** fprintf to stderr? */1795- printf ("Error in opening scriptfile %s.\n", optarg);1796- exit (1);1797- }1798- }1799- log_debug ("script started");1800- break;1801-1802- case 'h':1803- /* var hinsi_file_name polluted */1804- hinsi_file_name = optarg;1805- break;1806-1807- case 'N':1808- serverNO = atoi (optarg);1809- /* error handling needed */1810- break;1811-1812- case 'p':1813- port = atoi (optarg);1814- /* error handling needed */1815- break;1816-1817- case 'v':1818- print_version();1819- usage();1820- break;1821-1822- case 'u':1823- listen_proto &= ~PROTO_ALL;1824- listen_proto |= PROTO_UN;1825- break;1826-1827- case '4':1828- listen_proto &= ~PROTO_ALL;1829- listen_proto |= PROTO_INET;1830- break;1831+ int this_option_optind = optind ? optind : 1;1832+ int option_index = 0;1833+ static struct option long_options[] =1834+ {1835+ {"baseport", 1, NULL, 'p'},1836+ {"inet", 0, NULL, '4'},1837+ {"inet6", 0, NULL, '6'},1838+ {"jserverrc", 1, NULL, 'f'},1839+ {"listenaddr", 1, NULL, 'a'},1840+ {"unix", 0, NULL, 'u'},1841+ {"version", 0, NULL, 'v'},1842+ {0, 0, 0, 0}1843+ };1844+1845+ c = getopt_long (argc, argv, OPTIONARGS,1846+ long_options, &option_index);1847+ if (c == -1)1848+ break;1849+1850+ switch (c)1851+ {1852+ case 'D': /* do not detach, not a daemon */1853+ option_flag &= ~OPT_FORK;1854+ break;1855+1856+ case 'f': /* --jserverrc FILENAME */1857+ strncpy(jserverrcfile, optarg, sizeof(jserverrcfile) - 1);1858+ jserverrcfile[sizeof(jserverrcfile) - 1] = '\0';1859+ break;1860+1861+ case 'a': /* --listenaddr ADDR */1862+ strncpy(listenaddr[lindex], optarg, NI_MAXHOST - 1);1863+ listenaddr[lindex][NI_MAXHOST - 1] = '\0';1864+ lindex++;1865+ break;1866+1867+ case 's':1868+ /* should nuke noisy someday */1869+ noisy = 1; option_flag |= OPT_VERBOSE;1870+ if (strcmp ("-", optarg) != 0)1871+ {1872+ /** maybe FILE wnnerr = stderr; or wnnerr = open(optarg...) is better? or freopen is normal method? */1873+ /** take a look at daemon(3) */1874+ if (freopen (optarg, "a", stderr) == NULL)1875+ {1876+ /** fprintf to stderr? */1877+ printf ("Error in opening scriptfile %s.\n", optarg);1878+ exit (1);1879+ }1880+ }1881+ log_debug ("script started");1882+ break;1883+1884+ case 'h':1885+ /* var hinsi_file_name polluted */1886+ hinsi_file_name = optarg;1887+ break;1888+1889+ case 'N':1890+ serverNO = atoi (optarg);1891+ /* error handling needed */1892+ break;1893+1894+ case 'p':1895+ port = atoi (optarg);1896+ /* error handling needed */1897+ break;1898+1899+ case 'v':1900+ print_version();1901+ usage();1902+ break;1903+1904+ case 'u':1905+ listen_proto |= PROTO_UN;1906+ break;1907+1908+ case '4':1909+ listen_proto |= PROTO_INET;1910+ break;19111912#ifdef INET61913- case '6':1914- listen_proto &= ~PROTO_ALL;1915- listen_proto |= PROTO_INET6;1916- break;1917+ case '6':1918+ listen_proto |= PROTO_INET6;1919+ break;1920#endif /* INET6 */1921-1922- default:1923- print_version();1924- usage();1925- break;1926+ default:1927+ print_version();1928+ usage();1929+ break;1930+ }1931+ }1932+ if (!listen_proto) {1933+ listen_proto = PROTO_ALL;1934}1935- }1936}193719381939-/*1940-*/1941void1942js_who (void)1943{1944- int i, j;1945+ int i, j;19461947- put4_cur (clientp);1948- for (i = 0; i < clientp; i++)1949- {1950- put4_cur (cblk[i].sd);1951- puts_cur (client[i].user_name);1952- puts_cur (client[i].host_name);1953- for (j = 0; j < WNN_MAX_ENV_OF_A_CLIENT; j++)1954- {1955- put4_cur ((client[i].env)[j]);1956- }1957+ put4_cur (clientp);1958+ for (i = 0; i < clientp; i++)1959+ {1960+ put4_cur (cblk[i].sd);1961+ puts_cur (client[i].user_name);1962+ puts_cur (client[i].host_name);1963+ for (j = 0; j < WNN_MAX_ENV_OF_A_CLIENT; j++)1964+ {1965+ put4_cur ((client[i].env)[j]);1966+ }19671968- }1969- putc_purge ();1970+ }1971+ putc_purge();1972}19731974void1975@@ -1302,25 +1232,25 @@ js_kill (void)1976{1977if (clientp == 1)1978{1979- put4_cur (0);1980- putc_purge ();1981+ put4_cur(0x00000000);1982+ putc_purge();1983terminate_hand ();1984}1985else1986{1987put4_cur (clientp - 1);1988- putc_purge ();1989+ putc_purge();1990}1991}19921993void1994usage (void)1995{1996- fprintf(stderr,1997+ fprintf(stderr,1998#ifdef INET61999- "usage: %s [-Du46][-f <init_file> -s <log_file(\"-\" for stderr)> -h <pos_file> -N <serverNO> -p <port_base>]\n",2000+ "usage: %s [-Du46][-f <init_file> -a <listenaddr> -s <log_file(\"-\" for stderr)> -h <pos_file> -N <serverNO> -p <port_base>]\n",2001#else2002- "usage: %s [-Du4][-f <init_file> -s <log_file(\"-\" for stderr)> -h <pos_file> -N <serverNO> -p <port_base>]\n",2003+ "usage: %s [-Du4][-f <init_file> -a <listenaddr> -s <log_file(\"-\" for stderr)> -h <pos_file> -N <serverNO> -p <port_base>]\n",2004#endif2005cmd_name);2006fprintf(stderr,200720082009