Mercurial > freewnn
diff Wnn/jlib/js.c @ 0:bbc77ca4def5
initial import
author | Yoshiki Yazawa <yaz@cc.rim.or.jp> |
---|---|
date | Thu, 13 Dec 2007 04:30:14 +0900 |
parents | |
children | 790205f476c0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Wnn/jlib/js.c Thu Dec 13 04:30:14 2007 +0900 @@ -0,0 +1,3025 @@ +/* + * $Id: js.c,v 1.16 2005/04/10 15:26:37 aonoto Exp $ + */ + +/* + * 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 + * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992 + * Copyright FreeWnn Project 1999, 2000, 2001, 2002, 2003 + * + * Maintainer: FreeWnn Project <freewnn@tomo.gr.jp> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + Nihongo Henkan Library +*/ +/* + entry functions + + js_open_lang js_close + js_change_current_jserver + js_connect_lang js_disconnect + js_isconnect + + js_param_get js_param_set + + js_access js_mkdir + + js_get_lang js_set_lang + + +extern Variables + int wnn_errorno; +*/ + +#if defined(HAVE_CONFIG_H) +#include <config.h> +#endif + +#include <stdio.h> +#include <ctype.h> +#include <errno.h> +#include <signal.h> +#if STDC_HEADERS +# include <stdlib.h> +# include <string.h> +#else +# if HAVE_MALLOC_H +# include <malloc.h> +# endif +# if HAVE_STRINGS_H +# include <strings.h> +# endif +#endif /* STDC_HEADERS */ +#if HAVE_FCNTL_H +# include <fcntl.h> +#endif +#include <pwd.h> +#if HAVE_UNISTD_H +# include <unistd.h> +#endif +#include <sys/stat.h> +#include <sys/types.h> + +#include "jd_sock.h" +#include "commonhd.h" +#include "demcom.h" +#include "wnn_config.h" + +#include "wnnerror.h" +#include "jslib.h" +#include "jh.h" + +#include "msg.h" + +#define JS /* For include ../etc/bdic.c */ +#include "../etc/bdic.c" +#include "../etc/pwd.c" + +/* defined in wnn_os.h & should be modified in the future */ +/* #define bzero(adr,n) memset((adr),0,(n)) */ + +int wnn_errorno = 0; +struct msg_cat *wnn_msg_cat = NULL; + +/* j Lib. */ + +static int current_sd; /** ソケットfd **/ +static WNN_JSERVER_ID *current_js = NULL; + + +/* Packet Buffers */ +static unsigned char snd_buf[S_BUF_SIZ]; /** 送信 **/ +static int sbp = 0; /** 送信バッファーポインター **/ +static int rbc = -1; /** 受信バッファーポインター **/ + +#if defined(EAGAIN) +# if defined(EWOULDBLOCK) +# define ERRNO_CHECK(no) ((no) == EAGAIN || (no) == EWOULDBLOCK) +# else /* defined(EWOULDBLOCK) */ +# define ERRNO_CHECK(no) ((no) == EAGAIN) +# endif /* defined(EWOULDBLOCK) */ +#else /* defined(EAGAIN) */ +# if defined(EWOULDBLOCK) +# define ERRNO_CHECK(no) ((no) == EWOULDBLOCK) +# else /* defined(EWOULDBLOCK) */ +# define ERRNO_CHECK(no) (0) +# endif /* defined(EWOULDBLOCK) */ +#endif /* defined(EAGAIN) */ + +static void connect_timeout (); +static int _get_server_name (); +static int writen (); +static char *get_unixdomain_of_serv_defs (), *get_service_of_serv_defs (); +static int get_port_num_of_serv_defs (); +#if DEBUG +void xerror (); +#endif + +/********* V4 *****************/ +/*** + jserver_dead Macro +***/ + +static jmp_buf current_jserver_dead; + +#define handler_of_jserver_dead(err_val) \ +{ \ + if (current_js) { \ + if(current_js->js_dead){wnn_errorno=WNN_JSERVER_DEAD;return err_val;}\ + if(setjmp(current_jserver_dead)){ \ + wnn_errorno=WNN_JSERVER_DEAD; \ + return err_val; \ + } \ + wnn_errorno = 0; /* here initialize wnn_errorno; */ \ + } \ +} + +static void +set_current_js (server) + register WNN_JSERVER_ID *server; +{ + current_js = server; + current_sd = current_js->sd; +} + +/** デーモンが死んだ時のための後始末 **/ +static void +daemon_dead () +{ + current_js->js_dead = -1; + wnn_errorno = WNN_JSERVER_DEAD; + shutdown (current_sd, 2); +#ifdef HAVE_CLOSESOCKET + closesocket (current_sd); +#else + close (current_sd); +#endif +#if DEBUG + fprintf (stderr, "jslib:JSERVER %s is Dead\n", current_js->js_name); +#endif + if (current_js->js_dead_env_flg) + { + longjmp (current_js->js_dead_env, 666); + } + longjmp (current_jserver_dead, 666); +/* never reach */ +} + + +/** + ソケットをオープンしてcurrent_sdにソケットfdを返す + (cdというのはコミュニケーションデバイスの名残) +**/ +static int +cd_open_un (lang) + register char *lang; +{ +#ifdef AF_UNIX + int sd; + struct sockaddr_un saddr; /** ソケット **/ + char *sock_name = NULL; + saddr.sun_family = AF_UNIX; + + /* find socket name from table by lang */ + if (lang && *lang) + { + if ((sock_name = get_unixdomain_of_serv_defs (lang)) == NULL) + { + sock_name = sockname; + } + } + else + { + sock_name = sockname; /* Jserver */ + } + strcpy (saddr.sun_path, sock_name); + + if ((sd = socket (AF_UNIX, SOCK_STREAM, 0)) == ERROR) + { +#if DEBUG + xerror ("jslib:Can't create unix domain socket.\n"); +#endif + return -1; + } + +#if !defined(SUN_LEN) +# define SUN_LEN(su) (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) +#endif + if (connect (sd, (struct sockaddr *) &saddr, SUN_LEN (&saddr)) == ERROR) + { + +#if DEBUG + xerror ("jslib:Can't connect unix domain socket.\n"); +#endif + close (sd); + return -1; + } + return sd; +#else + return -1; +#endif +} + +static int +cd_open_in (server, lang, timeout) + register char *server; + register char *lang; + register int timeout; +{ + int sd; +#ifdef INET6 + struct addrinfo hints, *res, *res0; + int error; + char sport[6]; +#else + struct sockaddr_in saddr_in; /** ソケット **/ + register struct hostent *hp; +#endif + struct servent *sp = NULL; + int serverNO, port_num; + int ret; + char pserver[64]; + char sserver[64]; + char *serv_name = NULL; + + serverNO = _get_server_name (server, pserver); + + /* find service name from table by lang */ + if (lang && *lang) + { + if ((serv_name = get_service_of_serv_defs (lang)) == NULL) + { + strcpy (sserver, SERVERNAME); + } + else + { + strcpy (sserver, serv_name); + } + } + else + { +/* + serv_name = SERVERNAME; +*/ + strcpy (sserver, SERVERNAME); + } +/* + if ((sp = getservbyname(serv_name,"tcp")) != NULL) { +*/ + if ((sp = getservbyname (sserver, "tcp")) != NULL) + { + serverNO += ntohs (sp->s_port); + } + else + { + if ((port_num = get_port_num_of_serv_defs (lang)) == -1) + { + serverNO += WNN_PORT_IN; + } + else + { + serverNO += port_num; + } + } +#ifdef INET6 + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + sprintf(sport, "%d", serverNO); + error = getaddrinfo(pserver, sport, &hints, &res0); + if (error) + { +#if DEBUG + xerror (gai_strerror(error)); +#endif + return -1; + } + for (res = res0; res ; res = res->ai_next) { + if (res->ai_family == AF_INET || res->ai_family == AF_INET6){ + if ((sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) != ERROR){ +#else + if ((hp = gethostbyname (pserver)) == NULL) + { + return -1; + } + bzero ((char *) &saddr_in, sizeof (saddr_in)); + bcopy (hp->h_addr, (char *) &saddr_in.sin_addr, hp->h_length); + saddr_in.sin_family = AF_INET; + saddr_in.sin_port = htons (serverNO); + if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == ERROR) + { +#if DEBUG + xerror ("jslib:Can't create inet socket.\n"); +#endif + return -1; + } +#endif + + if (timeout != 0 && timeout > 0) + { + signal (SIGALRM, connect_timeout); + alarm (timeout); + } +#ifdef INET6 + ret = connect (sd, res->ai_addr, res->ai_addrlen); +#else + ret = connect (sd, (struct sockaddr *) &saddr_in, sizeof (saddr_in)); +#endif + if (timeout != 0 && timeout > 0) + { + alarm (0); + signal (SIGALRM, SIG_IGN); + } + if (ret == ERROR) + { +#if DEBUG +#ifdef INET6 + if (res->ai_family == AF_INET) + xerror ("jslib:Can't connect inet socket.\n"); + else if (res->ai_family == AF_INET6) + xerror ("jslib:Can't connect inet6 socket.\n"); +#else + xerror ("jslib:Can't connect inet socket.\n"); +#endif +#endif +#ifdef HAVE_CLOSESOCKET + closesocket (sd); +#else + close (sd); +#endif +#ifdef INET6 + sd = ERROR; + } else + break; + } else { +#if DEBUG + if (res->ai_family == AF_INET) + xerror ("jslib:Can't create inet socket.\n"); + else if (res->ai_family == AF_INET6) + xerror ("jslib:Can't create inet6 socket.\n"); +#endif + } + } + } + freeaddrinfo(res0); + if (sd == ERROR) { +#endif + return -1; + } + return sd; +} + +static void +connect_timeout () +{ +} + +/* get server name and return serverNo */ +static int +_get_server_name (server, pserver) + char *server; + char *pserver; +{ + register char *p; +#ifdef INET6 + int len; + + if (server[0] == '[') { + p = strchr(server++, ']'); + if (p) { + len = p-server<64-1?p-server:64-1; + strncpy(pserver, server, len); + pserver[len] = '\0'; + } else + pserver[0] = '\0'; + } else { +#endif + /* Workaround for pserver buffer overrun : Nov 11,1999 by T.Aono */ + /* assumes pserver[64]. variable length string is not supported. */ + strncpy(pserver, server, 64-1); + pserver[64-1] = '\0'; + p = pserver; +#ifdef INET6 + } +#endif + for (; *p && *p != ':'; p++); + if (!*p) + return (0); /* does not have a colon */ + *p = 0; + return (atoi (++p)); +} + +/* Packet SND/RCV subroutines */ +static void put4com (); + +/** パケットのヘッダーを送る **/ +static void +snd_head (cmd) + int cmd; /** cmd=コマンド **/ +{ + sbp = 0; + put4com (cmd); + rbc = -1; +} + +/** パケットのヘッダーを送る **/ +static int +snd_env_head (env, cmd) + register struct wnn_env *env; + int cmd; /** cmd=コマンド **/ +{ + snd_head (cmd); + put4com (env->env_id); + return 0; +} + +/** パケットのヘッダーを送る **/ +static int +snd_server_head (server, cmd) + register WNN_JSERVER_ID *server; + int cmd; /** cmd=コマンド **/ +{ + snd_head (cmd); + return 0; +} + +/** 送信バッファをフラッシュする **/ +static int +snd_flush () +{ + if (sbp == 0) + return (-1); + writen (sbp); + sbp = 0; + return (0); +} + +static int +writen (n) + int n; +{ + int cc, x; + for (cc = 0; cc < n;) + { + errno = 0; +#ifdef HAVE_SEND + x = send (current_sd, &snd_buf[cc], n - cc, 0); +#else + x = write (current_sd, &snd_buf[cc], n - cc); +#endif + if (x < 0) + { + if (ERRNO_CHECK (errno) || errno == EINTR) + { + continue; + } + else + { + daemon_dead (); + return -1; + } + } + cc += x; + } +#if DEBUG + fprintf (stderr, "jslib:writen=%d\n", x); +/* dmp(snd_buf,x); */ +#endif + return (0); +} + +/** サーバへ1バイト送る **/ +static void +put1com (c) + int c; +{ + snd_buf[sbp++] = c; + if (sbp >= S_BUF_SIZ) + { + writen (S_BUF_SIZ); + sbp = 0; + } +} + +/** サーバへ2バイト送る **/ +static void +put2com (c) + int c; +{ + put1com (c >> (8 * 1)); + put1com (c); +} + +/** サーバへ4バイト送る **/ +static void +put4com (c) + int c; +{ + put1com (c >> (8 * 3)); + put1com (c >> (8 * 2)); + put1com (c >> (8 * 1)); + put1com (c); +} + +/** サーバへ文字列を送る **/ +static void +putwscom (p) + register w_char *p; +{ + if (p == NULL) + { + put2com (0); + return; + } + while (*p) + put2com (*p++); + put2com (0); +} + +/** サーバへ文字列を送る **/ +static void +putscom (p) + register char *p; +{ + if (p == NULL) + { + put1com (0); + return; + } + while (*p) + put1com (*p++); + put1com (0); +} + +/** サーバから1バイト受ける **/ +static int +get1com () +{ + static int rbp; + static unsigned char rcv_buf[R_BUF_SIZ]; /** 受信 **/ + if (rbc <= 0) + { + while (1) + { + errno = 0; +#ifdef HAVE_RECV + rbc = recv (current_sd, rcv_buf, R_BUF_SIZ, 0); +#else + rbc = read (current_sd, rcv_buf, R_BUF_SIZ); +#endif + if (rbc <= 0) + { + if (ERRNO_CHECK (errno)) + { + continue; + } + else if (rbc == 0) + { + daemon_dead (); + return -1; + } + else + { /* cc == -1 */ + if (errno != EINTR) + { + daemon_dead (); + return -1; + } + continue; + } + } + rbp = 0; +#if DEBUG + fprintf (stderr, "jslib:read:rbc=%d\n", rbc); +/* dmp(rcv_buf,rbc); */ +#endif + break; + } + } + rbc--; + return rcv_buf[rbp++] & 0xFF; +} + +/** サーバから2バイト受ける **/ +static int +get2com () +{ + register int h; + h = get1com (); + return (h << 8) | get1com (); +} + +/** サーバから4バイト受ける **/ +static int +get4com () +{ + register int h1, h2, h3; + h1 = get1com () << 24; + h2 = get1com () << 16; + h3 = get1com () << 8; + return h1 | h2 | h3 | get1com (); +} + +/** サーバへ文字列を送る **/ +static void +getscom (p) + register char *p; +{ + while (*p++ = get1com ()) + ; +} + +/** サーバへ文字列を送る **/ +static void +getwscom (p) + w_char register *p; +{ + while (*p++ = get2com ()) + ; +} + +#ifdef nodef +/* Moved from ../etc/string.c */ +/** **/ +static int +Strlen (s) + register w_char *s; +{ + register int n; + + for (n = 0; *s++ != 0; n++); + return n; +} + +/** **/ +static w_char * +Strcpy (s1, s2) + register w_char *s1; + register w_char *s2; +{ + register w_char *d; + + for (d = s1; (*d++ = *s2++) != 0;); + return s1; +} +#endif + + +/* Debug Subroutines */ +#if DEBUG +void +xerror (s) + char *s; +{ + fprintf (stderr, "%s\n", s); +} + +void +dmp (p, c) + char *p; +{ + int i, j; + for (i = 0;; i += 16) + { + for (j = 0; j < 16; j++) + { + if (c <= 0) + { + fprintf (stderr, "\n"); + return; + } + fprintf (stderr, "%02x ", p[i + j] & 0xFF); + c--; + } + fprintf (stderr, "\n"); + } +} + +#endif + +/* get login name form /etc/passwd file */ +static char * +getlogname () +{ + struct passwd *getpwuid (); + return getpwuid (getuid ())->pw_name; +} + + + + +/* + * Lib. Functions + * raw lib. + */ + +/*** + js + ・global +***/ + +/** jserver と接続する。jserver_id を返す。 **/ +WNN_JSERVER_ID * +js_open_lang (server, lang, timeout) + register char *server, *lang; + register int timeout; +{ + char *new_js; + char host[WNN_HOSTLEN], user[WNN_ENVNAME_LEN]; + int x; + + if (wnn_msg_cat == NULL) + { + char nlspath[MAXPATHLEN]; + strcpy (nlspath, LIBDIR); + strcat (nlspath, "/%L/%N"); + wnn_msg_cat = msg_open ("libwnn.msg", nlspath, lang); + if (wnn_msg_cat == NULL) + { + fprintf (stderr, "libwnn: Cannot open message file for libwnn.a\n"); + } + } + sbp = 0; /* init sndBufPointer */ + if (!(new_js = (char *) malloc (sizeof (WNN_JSERVER_ID)))) + { + wnn_errorno = WNN_ALLOC_FAIL; + return NULL; + } + current_js = (WNN_JSERVER_ID *) new_js; + if (server == NULL) + { + current_js->js_name[0] = '\0'; + } + else + { + strncpy (current_js->js_name, server, sizeof (current_js->js_name) - 1); + current_js->js_name[sizeof (current_js->js_name) - 1] = '\0'; + } + current_js->js_dead = 0; + current_js->js_dead_env_flg = 0; +/* + if(user == NULL || 0==strcmp(user,"")) +*/ + strncpy (user, getlogname (), WNN_ENVNAME_LEN); + user[WNN_ENVNAME_LEN - 1] = '\0'; /* truncate by WNN_ENVNAME_LEN */ + if (server == NULL || 0 == strcmp (server, "") || 0 == strcmp (server, "unix")) + { + strcpy (host, "unix"); + if ((current_sd = cd_open_un (lang)) == -1) + { + wnn_errorno = WNN_SOCK_OPEN_FAIL; + free ((char *) current_js); + current_js = NULL; + return NULL; + } + } + else + { + gethostname (host, WNN_HOSTLEN); + host[WNN_HOSTLEN - 1] = '\0'; /* truncate by WNN_HOSTLEN */ + if ((current_sd = cd_open_in (server, lang, timeout)) == -1) + { + wnn_errorno = WNN_SOCK_OPEN_FAIL; + free ((char *) current_js); + current_js = NULL; + return NULL; + } + } + current_js->sd = current_sd; + handler_of_jserver_dead (NULL); + snd_head (JS_OPEN); + put4com (JLIB_VERSION); /* H.T. */ + putscom (host); + putscom (user); + snd_flush (); + if (get4com () == -1) + { + x = wnn_errorno = get4com (); + js_close (current_js); /* H.T. */ + current_js = NULL; + wnn_errorno = x; + return NULL; + } + return current_js; +} + + +/** ソケットをクローズする **/ +/** jserver との接続を close する。 **/ +int +js_close (server) + WNN_JSERVER_ID *server; +{ + register int x; + WNN_JSERVER_ID tmp_js_id; + if (server == 0) + return (-1); + tmp_js_id = *server; + free ((char *) server); + current_js = &tmp_js_id; + current_sd = current_js->sd; +/* handler of jserver dead */ + handler_of_jserver_dead (-1); + snd_head (JS_CLOSE); + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); +#ifdef HAVE_CLOSESOCKET + closesocket (current_sd); +#else + close (current_sd); +#endif + return x; +} + + +/* + jserver との間に connection を張り、同時に jserver の内部に環 + 境を作る。env_name に既に存在する環境を指定した時にはその環境を + 返し、NULL を指定した時には新しい環境を作って返す。 +*/ + +struct wnn_env * +js_connect_lang (server, env_name, lang) + register char *env_name; + WNN_JSERVER_ID *server; + char *lang; +{ + register int e_id; + register struct wnn_env *env; + void js_set_lang (); + + set_current_js (server); + if (!(env = (struct wnn_env *) malloc (sizeof (struct wnn_env)))) + { + wnn_errorno = WNN_ALLOC_FAIL; + return NULL; + } + handler_of_jserver_dead (NULL); + snd_head (JS_CONNECT); + putscom (env_name); + snd_flush (); + e_id = get4com (); + if (e_id == -1) + { + wnn_errorno = get4com (); + free (env); + return NULL; + } + env->env_id = e_id; + env->js_id = server; + strcpy (env->lang, lang); /* set language name */ + return env; +} + +#ifdef nodef +/* set language value to env */ +void +js_set_lang (env, lang) + struct wnn_env *env; + register char *lang; +{ + register char *p; + extern char *getenv (); + + /* if not specified language , use $LANG */ + if (lang == 0 || *lang == 0) + lang = getenv ("LANG"); + if (lang == 0 || *lang == 0) + lang = WNN_DEFAULT_LANG; + for (p = env->lang; *lang != '.' && *lang != '@' && *lang != 0; lang++, p++) + *p = *lang; + *p = 0; +} +#endif + +/* get language value from env */ +char * +js_get_lang (env) + struct wnn_env *env; +{ + return (env->lang); +} + +int +js_env_exist (server, env_name) + register char *env_name; + register WNN_JSERVER_ID *server; +{ + set_current_js (server); + handler_of_jserver_dead (-1); + snd_head (JS_ENV_EXIST); + putscom (env_name); + snd_flush (); + return (get4com ()); +} + +int +js_env_sticky (env) + register struct wnn_env *env; +{ + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_ENV_STICKY); + snd_flush (); + return (get4com ()); +} + +int +js_env_un_sticky (env) + register struct wnn_env *env; +{ + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_ENV_UN_STICKY); + snd_flush (); + return (get4com ()); +} + +/** + env で示される環境を無くす。 +**/ +int +js_disconnect (env) + register struct wnn_env *env; +{ + register int x; + struct wnn_env tmp_env; + if (env == 0) + return (-1); + tmp_env = *env; + /* 本来は、free しなきゃあかんのだけど、リソース管理が出来ないし、 + まあ、8バイトだから、ゴミが残るけどいいだろう。 + free((char *)env); + */ + set_current_js (env->js_id); + handler_of_jserver_dead (NULL); + snd_env_head (&tmp_env, JS_DISCONNECT); + snd_flush (); + x = get4com (); + if (x == -1) + { + wnn_errorno = get4com (); + } + return x; +} + +/** サーバとコネクトしているか **/ +int +js_isconnect (env) + register struct wnn_env *env; +{ + if (env && env->js_id) + return (env->js_id->js_dead); + return (-1); +} + +/** + env の 環境 との通信バッファを flush する。 +**/ +void +js_flush (env) + struct wnn_env *env; +{ +} + + + +/* Parameter set/get */ +/** 変換 parameter を設定する。 **/ +/** js_param_set **/ +int +js_param_set (env, para) + struct wnn_env *env; + register struct wnn_param *para; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_PARAM_SET); + put4com (para->n); /* N(大)文節解析のN */ + put4com (para->nsho); /* 大文節中の小文節の最大数 */ + put4com (para->p1); /* 幹語の頻度のパラメータ */ + put4com (para->p2); /* 小文節長のパラメータ */ + put4com (para->p3); /* 幹語長のパラメータ */ + put4com (para->p4); /* 今使ったよビットのパラメータ */ + put4com (para->p5); /* 辞書のパラメータ */ + put4com (para->p6); /* 小文節の評価値のパラメータ */ + put4com (para->p7); /* 大文節長のパラメータ */ + put4com (para->p8); /* 小文節数のパラメータ */ + + put4com (para->p9); /* 疑似品詞 数字の頻度 */ + put4com (para->p10); /* 疑似品詞 カナの頻度 *//* CWNN 英数の頻度 */ + put4com (para->p11); /* 疑似品詞 英数の頻度 *//* CWNN 記号の頻度 */ + put4com (para->p12); /* 疑似品詞 記号の頻度 *//* CWNN 開括弧の頻度 */ + put4com (para->p13); /* 疑似品詞 閉括弧の頻度 *//* CWNN 閉括弧の頻度 */ + put4com (para->p14); /* 疑似品詞 付属語の頻度 *//* BWNN No of koho */ + put4com (para->p15); /* 疑似品詞 開括弧の頻度 *//* CWNN Not used */ + + snd_flush (); + x = get4com (); + if (x == -1) + { + wnn_errorno = get4com (); + return -1; + } + return 0; +} + +/** js_param_get **/ +/** env で示される環境の変換 parameter を取り出す。 **/ +int +js_param_get (env, para) + struct wnn_env *env; + register struct wnn_param *para; +{ + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_PARAM_GET); + snd_flush (); + if (get4com () == -1) + { + wnn_errorno = get4com (); + return -1; + } + para->n = get4com (); /* N(大)文節解析のN */ + para->nsho = get4com (); /* 大文節中の小文節の最大数 */ + para->p1 = get4com (); /* 幹語の頻度のパラメータ */ + para->p2 = get4com (); /* 小文節長のパラメータ */ + para->p3 = get4com (); /* 幹語長のパラメータ */ + para->p4 = get4com (); /* 今使ったよビットのパラメータ */ + para->p5 = get4com (); /* 辞書のパラメータ */ + para->p6 = get4com (); /* 小文節の評価値のパラメータ */ + para->p7 = get4com (); /* 大文節長のパラメータ */ + para->p8 = get4com (); /* 小文節数のパラメータ */ + para->p9 = get4com (); /* 疑似品詞 数字の頻度 */ + para->p10 = get4com (); /* 疑似品詞 カナの頻度 */ + para->p11 = get4com (); /* 疑似品詞 英数の頻度 */ + para->p12 = get4com (); /* 疑似品詞 記号の頻度 */ + para->p13 = get4com (); /* 疑似品詞 閉括弧の頻度 */ + para->p14 = get4com (); /* 疑似品詞 付属語の頻度 */ + para->p15 = get4com (); /* 疑似品詞 開括弧の頻度 */ + + return 0; +} + +/* + global File Operation +*/ +/** js_mkdir **/ +int +js_mkdir (env, path) + struct wnn_env *env; + char *path; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_MKDIR); + putscom (path); + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); + return x; +} + +/** js_access **/ +int +js_access (env, path, amode) + struct wnn_env *env; + char *path; + int amode; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_ACCESS); + put4com (amode); + putscom (path); + snd_flush (); + x = get4com (); + return x; +} + +/** js_file_list_all **/ +static int rcv_file_list (); + +int +js_file_list_all (server, ret) + WNN_JSERVER_ID *server; + struct wnn_ret_buf *ret; +{ + set_current_js (server); + handler_of_jserver_dead (-1); + snd_server_head (server, JS_FILE_LIST_ALL); + snd_flush (); + return rcv_file_list (ret); +} + + +/** js_file_list **/ +int +js_file_list (env, ret) + struct wnn_env *env; + struct wnn_ret_buf *ret; +{ + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_FILE_LIST); + snd_flush (); + return rcv_file_list (ret); +} + +static void re_alloc (); + +static int +rcv_file_list (ret) + struct wnn_ret_buf *ret; +{ + register int i, count; + WNN_FILE_INFO_STRUCT *files; + count = get4com (); + re_alloc (ret, sizeof (WNN_FILE_INFO_STRUCT) * count); + files = (WNN_FILE_INFO_STRUCT *) ret->buf; + for (i = 0; i < count; i++) + { + files->fid = get4com (); + files->localf = get4com (); + files->ref_count = get4com (); + files->type = get4com (); + getscom (files->name); + files++; + } + return count; +} + +/** js_file_stat **/ +int +js_file_stat (env, path, s) + struct wnn_env *env; + char *path; + WNN_FILE_STAT *s; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_FILE_STAT); + putscom (path); + snd_flush (); + x = get4com (); + s->type = x; + return x; +} + + +/** js_file_info **/ +int +js_file_info (env, fid, file) + struct wnn_env *env; + int fid; + register WNN_FILE_INFO_STRUCT *file; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_FILE_INFO); + put4com (fid); + snd_flush (); + file->fid = fid; + x = get4com (); + if (x == -1) + { + wnn_errorno = get4com (); + return (-1); + } + getscom (file->name); + file->localf = get4com (); + file->ref_count = get4com (); + file->type = get4com (); + return 0; +} + +/** js_file_loaded **/ +int +js_file_loaded (server, path) + WNN_JSERVER_ID *server; + char *path; +{ + register int x; + set_current_js (server); + handler_of_jserver_dead (-1); + snd_server_head (server, JS_FILE_LOADED); + putscom (path); + snd_flush (); + x = get4com (); + return x; +} + +/** js_file_loaded_local **/ +static int check_local_file (); +static int file_loaded_local (); + +int +js_file_loaded_local (server, path) + WNN_JSERVER_ID *server; + char *path; +{ + int x; + set_current_js (server); + handler_of_jserver_dead (-1); + + if (check_local_file (path) == -1) + return (-1); + snd_server_head (server, JS_FILE_LOADED_LOCAL); + x = file_loaded_local (path); + if (x == -1) + { + return -1; + } + return x; +} + +static int +check_local_file (path) + char *path; +{ + register FILE *f; + register int x; + struct wnn_file_head fh; + +#ifdef WRITE_CHECK + check_backup (path); +#endif /* WRITE_CHECK */ + f = fopen (path, "r"); + if (f == NULL) + { + wnn_errorno = WNN_OPENF_ERR; + return -1; + } + x = input_file_header (f, &fh); + if (x == -1) + { + fclose (f); + wnn_errorno = WNN_NOT_A_FILE; + return -1; + } + if (check_inode (f, &fh) == -1) + { + change_file_uniq (&fh, path); +#ifdef WRITE_CHECK + fclose (f); + f = fopen (path, "r"); + if (f == NULL) + { + wnn_errorno = WNN_OPENF_ERR; + return (-1); + } +#endif /* WRITE_CHECK */ + if (check_inode (f, &fh) == -1) + { + fclose (f); + wnn_errorno = WNN_INODE_CHECK_ERROR; + return (-1); + } + } + fclose (f); + return 0; +} + + +static int +file_loaded_local (path) + char *path; +{ + register int x, i; + FILE *f; + struct wnn_file_head fh; + +#ifdef WRITE_CHECK + check_backup (path); +#endif /* WRITE_CHECK */ + f = fopen (path, "r"); + if (f == NULL) + { + wnn_errorno = WNN_OPENF_ERR; + return -1; + } + x = input_file_header (f, &fh); + if (x == -1) + { + fclose (f); + wnn_errorno = WNN_NOT_A_FILE; + return -1; + } + put4com (fh.file_uniq.time); + put4com (fh.file_uniq.dev); + put4com (fh.file_uniq.inode); + for (i = 0; i < WNN_HOSTLEN; i++) + { + put1com (fh.file_uniq.createhost[i]); + } + + snd_flush (); + x = get4com (); + fclose (f); + return x; +} + + +/** js_hindo_file_create **/ +int +js_hindo_file_create (env, fid, fn, comment, hpasswd) + struct wnn_env *env; + int fid; + char *fn; + w_char *comment; + char *hpasswd; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_HINDO_FILE_CREATE); + put4com (fid); + putscom (fn); + putwscom (comment); + putscom (hpasswd); + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); + return x; +} + +/** js_dic_file_create **/ +int +js_dic_file_create (env, fn, type, comment, passwd, hpasswd) + struct wnn_env *env; + char *fn; + w_char *comment; + char *passwd, *hpasswd; + int type; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_DIC_FILE_CREATE); + putscom (fn); + putwscom (comment); + putscom (passwd); + putscom (hpasswd); + put4com (type); + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); + return x; +} + + +/** js_file_discard **/ +int +js_file_discard (env, fid) + struct wnn_env *env; + int fid; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_FILE_DISCARD); + put4com (fid); + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); + return x; +} + +/** js_file_read **/ +int +js_file_read (env, fn) + struct wnn_env *env; + char *fn; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_FILE_READ); + putscom (fn); + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); + return x; +} + +/** js_file_write **/ +int +js_file_write (env, fid, fn) + struct wnn_env *env; + int fid; + char *fn; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_FILE_WRITE); + put4com (fid); + putscom (fn); + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); + return x; +} + +/** js_file_receive **/ +static int xget1com (); +static void xput1com (); + +int +js_file_receive (env, fid, fn) + struct wnn_env *env; + int fid; + char *fn; +{ + register int mode, x; + char file_name[1024]; + char buf[1024]; + FILE *f; + int n; + struct wnn_file_head fh; + int i; +#ifdef WRITE_CHECK + char *tmp, *backup = NULL, tmp_x; + int tmp_err = 0; +#endif /* WRITE_CHECK */ + + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_FILE_RECEIVE); + put4com (fid); + snd_flush (); + /**/ getscom (file_name); + if (fn == NULL || strcmp (fn, "") == 0) + { + gethostname (buf, 1024); + n = strlen (buf); + buf[n] = C_LOCAL; + buf[n + 1] = 0; + if (strncmp (buf, file_name, n + 1) == 0) + { + fn = file_name + n + 1; + } + } +#ifdef WRITE_CHECK + check_backup (fn); +#endif /* WRITE_CHECK */ + if ((f = fopen (fn, "r")) == NULL) + { /* New File */ + fh.file_uniq.time = fh.file_uniq.dev = fh.file_uniq.inode = 0; + } + else + { /* Old File Exists */ + if (input_file_header (f, &fh) == -1) + { + wnn_errorno = WNN_NOT_A_FILE; + fclose (f); + put4com (-1); + snd_flush (); + sleep (1); /* enssure handshake */ + return (-1); + } + fclose (f); + } + put4com (0); /* Ack */ + put4com (fh.file_uniq.time); + put4com (fh.file_uniq.dev); + put4com (fh.file_uniq.inode); + for (i = 0; i < WNN_HOSTLEN; i++) + { + put1com (fh.file_uniq.createhost[i]); + } + + snd_flush (); + + if ((mode = get4com ()) == -1) + { /* check stat */ + wnn_errorno = get4com (); + return -1; + } + else if (mode == 0) + { + return 0; /* need not saving */ + } + else if (mode == 1 || mode == 3) + { /* mode == 3 means the file is a new one. */ +#ifdef WRITE_CHECK + backup = make_backup_file (fn); + if ((tmp = make_tmp_file (fn, 0, &f)) == NULL) + { + delete_tmp_file (backup); +#else /* WRITE_CHECK */ + if ((f = fopen (fn, "w+")) == NULL) + { +#endif /* WRITE_CHECK */ + wnn_errorno = WNN_FILE_WRITE_ERROR; + put4com (-1); + snd_flush (); + sleep (1); /* enssure handshake */ + return (-1); + } + } + else if (mode == 2) + { +#ifdef WRITE_CHECK + backup = make_backup_file (fn); + if ((tmp = make_tmp_file (fn, 1, &f)) == NULL) + { + delete_tmp_file (backup); +#else /* WRITE_CHECK */ + if ((f = fopen (fn, "r+")) == NULL) + { /* New File */ +#endif /* WRITE_CHECK */ + wnn_errorno = WNN_FILE_WRITE_ERROR; + put4com (-1); + snd_flush (); + sleep (1); /* enssure handshake */ + return (-1); + } + } + put4com (0); + snd_flush (); /* ACK */ + for (;;) + { + if ((x = xget1com ()) == -1) + break; /* EOF */ +#ifdef WRITE_CHECK + tmp_x = (char) x; + if (fwrite (&tmp_x, sizeof (char), 1, f) == -1) + tmp_err = 1; +#else /* WRITE_CHECK */ + fputc (x, f); +#endif /* WRITE_CHECK */ + } + fclose (f); +#ifdef WRITE_CHECK + if (tmp_err == 0) + { + move_tmp_to_org (tmp, fn, 1); + } + else + { + delete_tmp_file (tmp); + } + delete_tmp_file (backup); +#endif /* WRITE_CHECK */ + + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); +#ifdef WRITE_CHECK + if (tmp_err) + { + wnn_errorno = WNN_FILE_WRITE_ERROR; + return (-1); + } +#endif /* WRITE_CHECK */ + + return x; +} + +static int +xget1com () +{ + register int x; + if ((x = get1com ()) != 0xFF) + return x; + if (get1com () == 0xFF) + return -1; /* EOF */ + return 0xFF; +} + +/** js_file_send **/ +int +js_file_send (env, fn) + struct wnn_env *env; + char *fn; +{ + register int x; + FILE *f; + int n; + char buf[1024], *b; + register int cc, i; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + + if (check_local_file (fn) == -1) + return (-1); + + snd_env_head (env, JS_FILE_SEND); + x = file_loaded_local (fn); + if (x != -1) + { /* file is already loaded */ + if (get4com () == -1) + { + wnn_errorno = get4com (); + return (-1); + } + return x; + } + + x = get4com (); + if (x == -1) + { + wnn_errorno = get4com (); + return -1; + } + + gethostname (buf, 1024); + n = strlen (buf); + buf[n] = C_LOCAL; + strcpy (buf + n + 1, fn); + putscom (buf); + +#ifdef WRITE_CHECK + check_backup (fn); +#endif /* WRITE_CHECK */ + if ((f = fopen (fn, "r")) == NULL) + { + xput1com (-1); /* EOF */ + return -1; + } + + /* send contents of file */ + for (;;) + { + cc = fread (buf, 1, 1024, f); + if (cc <= 0) + break; /* EOF */ + for (b = buf, i = 0; i < cc; i++) + { + xput1com ((int) *b++ & 0xff); + } + } + fclose (f); + xput1com (-1); /* EOF */ + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); + return x; +} + +static void +xput1com (d) + int d; +{ + if (d == -1) + { + put1com (0xFF); + put1com (0xFF); + return; /* EOF */ + } + put1com (d); + if (d == 0xFF) + { + put1com (0x00); + } +} + + +/*** Dic. Operation for Env. ***/ + +/** js_dic_add **/ +int +js_dic_add (env, fid, hfid, rev, jnice, rw, hrw, pw1, pw2) + struct wnn_env *env; + int fid, hfid, rev, jnice, rw, hrw; + char *pw1, *pw2; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_DIC_ADD); + put4com (fid); + put4com (hfid); + put4com (jnice); + put4com (rw); + put4com (hrw); + putscom (pw1); + putscom (pw2); + put4com (rev); /* rev is to add it as reverse dict */ + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); + return x; +} + +/** js_dic_delete **/ +int +js_dic_delete (env, dicno) + struct wnn_env *env; + int dicno; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_DIC_DELETE); + put4com (dicno); + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); + return x; +} + +/** js_dic_use **/ +int +js_dic_use (env, dic_no, flag) + struct wnn_env *env; + int dic_no, flag; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_DIC_USE); + put4com (dic_no); + put4com (flag); + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); + return x; +} + +/** js_fuzokugo_set **/ +int +js_fuzokugo_set (env, fid) + struct wnn_env *env; + int fid; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_FUZOKUGO_SET); + put4com (fid); + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); + return x; +} + +/** js_fuzokugo_get **/ +int +js_fuzokugo_get (env) + struct wnn_env *env; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_FUZOKUGO_GET); + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); + return x; +} + +/** js_dic_list_all **/ +static int rcv_dic_list (); +static void get_dic_info (); + +int +js_dic_list_all (server, ret) + WNN_JSERVER_ID *server; + struct wnn_ret_buf *ret; +{ + set_current_js (server); + handler_of_jserver_dead (-1); + snd_server_head (server, JS_DIC_LIST_ALL); + snd_flush (); + return rcv_dic_list (ret); +} + + +/** js_dic_list **/ +int +js_dic_list (env, ret) + struct wnn_env *env; + struct wnn_ret_buf *ret; +{ + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_DIC_LIST); + snd_flush (); + return rcv_dic_list (ret); +} + +static int +rcv_dic_list (ret) + struct wnn_ret_buf *ret; +{ + register int i, count; + register WNN_DIC_INFO *dic; + count = get4com (); + re_alloc (ret, sizeof (WNN_DIC_INFO) * (count + 1)); + + dic = (WNN_DIC_INFO *) ret->buf; + for (i = 0; i < count; i++) + { + get_dic_info (dic); + dic++; + } + dic->dic_no = -1; + return count; +} + +static void +get_dic_info (dic) + register WNN_DIC_INFO *dic; +{ + dic->dic_no = get4com (); /* dic_No */ + dic->body = get4com (); /* body fid */ + dic->hindo = get4com (); /* hindo fid */ + dic->rw = get4com (); /* r/w */ + dic->hindo_rw = get4com (); /* hindo r/w */ + dic->enablef = get4com (); /* enable/disable */ + dic->nice = get4com (); /* nice */ + dic->rev = get4com (); +/* added H.T */ + getwscom (dic->comment); + getscom (dic->fname); + getscom (dic->hfname); + getscom (dic->passwd); + getscom (dic->hpasswd); + dic->type = get4com (); + dic->gosuu = get4com (); + dic->localf = get4com (); + dic->hlocalf = get4com (); +} + +/*** Dic. Operation by dic_No. ***/ + +/** js_word_add **/ +int +js_word_add (env, dic_no, yomi, kanji, comment, hinshi, init_hindo) + struct wnn_env *env; + int dic_no; + w_char *yomi, *kanji, *comment; + int hinshi, init_hindo; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_WORD_ADD); + put4com (dic_no); + putwscom (yomi); + putwscom (kanji); + putwscom (comment); + put4com (hinshi); + put4com (init_hindo); + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); + return x; +} + +/** js_word_delete **/ +int +js_word_delete (env, dic_no, entry) + struct wnn_env *env; + int dic_no; + int entry; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_WORD_DELETE); + put4com (dic_no); + put4com (entry); + snd_flush (); + x = get4com (); + if (x == -1) + wnn_errorno = get4com (); + return x; +} + + +/** js_word_search **/ +static int rcv_word_data (); + +int +js_word_search (env, dic_no, yomi, ret) + struct wnn_env *env; + int dic_no; + w_char *yomi; + struct wnn_ret_buf *ret; +{ + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_WORD_SEARCH); + put4com (dic_no); + putwscom (yomi); + snd_flush (); + + return (rcv_word_data (ret, yomi)); +} + +/** js_word_search_by_env **/ +int +js_word_search_by_env (env, yomi, ret) + struct wnn_env *env; + w_char *yomi; + struct wnn_ret_buf *ret; +{ + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_WORD_SEARCH_BY_ENV); + putwscom (yomi); + snd_flush (); + + return (rcv_word_data (ret, yomi)); +} + +/** js_word_info **/ +int +js_word_info (env, dic_no, entry, ret) + struct wnn_env *env; + int dic_no, entry; + struct wnn_ret_buf *ret; +{ + register int x; + w_char yomi[LENGTHYOMI]; + + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_WORD_INFO); + put4com (dic_no); + put4com (entry); + snd_flush (); + x = get4com (); + if (x == -1) + { + wnn_errorno = get4com (); + return (-1); + } + getwscom (yomi); + rcv_word_data (ret, yomi); + return (0); +} + +int +js_word_comment_set (env, dic_no, entry, comment) + struct wnn_env *env; + int dic_no, entry; + w_char *comment; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_WORD_COMMENT_SET); + put4com (dic_no); + put4com (entry); + putwscom (comment); + snd_flush (); + x = get4com (); + if (x == -1) + { + wnn_errorno = get4com (); + return (-1); + } + return (0); +} + +/** rcv for word_search **/ +static int +rcv_word_data (ret, yomi) + struct wnn_ret_buf *ret; + w_char *yomi; /* Yomi is not sent from server + * (at least for the time being). + */ +{ + register int x, j_c, k_c; + w_char *k; + register struct wnn_jdata *jd; + register int cnt; + + j_c = get4com (); + k_c = get4com (); + re_alloc (ret, sizeof (struct wnn_jdata) * (j_c + 1) + sizeof (w_char) * (k_c + j_c * 3 + j_c * wnn_Strlen (yomi))); + jd = (struct wnn_jdata *) ret->buf; + for (cnt = 0;; cnt++) + { + jd->dic_no = x = get4com (); + if (x == -1) + break; + jd->serial = get4com (); + jd->hinshi = get4com (); + jd->hindo = get4com (); + jd->ima = get4com (); + jd->int_hindo = get4com (); + jd->int_ima = get4com (); + jd++; + } + jd++; + k = (w_char *) jd; + jd = (struct wnn_jdata *) ret->buf; + for (;;) + { + if (jd->dic_no == -1) + break; + + jd->yomi = k; /* Copy Yomi */ + wnn_Strcpy (k, yomi); + k += wnn_Strlen (k) + 1; + + jd->kanji = k; /* Get Kanji */ + getwscom (k); + k += wnn_Strlen (k) + 1; + + jd->com = k; /* Get Comment */ + getwscom (k); + k += wnn_Strlen (k) + 1; + jd++; + } + return cnt; +} + + +/** js_dic_info **/ +int +js_dic_info (env, dic_no, ret) + struct wnn_env *env; + int dic_no; + register WNN_DIC_INFO *ret; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_DIC_INFO); + put4com (dic_no); + snd_flush (); + x = get4com (); + if (x == -1) + { + return get4com (); + } + get_dic_info (ret); + return dic_no; +} + + +/** js_who **/ +int +js_who (server, ret) + WNN_JSERVER_ID *server; + struct wnn_ret_buf *ret; +{ + register int i, j, c; + WNN_JWHO *w; + set_current_js (server); + handler_of_jserver_dead (-1); + snd_server_head (server, JS_WHO); + snd_flush (); + + c = get4com (); + if (c == -1) + { + wnn_errorno = get4com (); + return -1; + } + + re_alloc (ret, sizeof (WNN_JWHO) * c); + w = (WNN_JWHO *) ret->buf; + for (i = 0; i < c; i++) + { + w->sd = get4com (); + getscom (w->user_name); + getscom (w->host_name); + for (j = 0; j < WNN_MAX_ENV_OF_A_CLIENT; j++) + { + (w->env)[j] = get4com (); + } + w++; + } + return (c); +} + +/** jserver 中の全ての環境に関する情報を得る。 + (ウラ技) +**/ +int +js_env_list (server, ret) + WNN_JSERVER_ID *server; + struct wnn_ret_buf *ret; +{ + register int i, j, c; + WNN_ENV_INFO *w; + set_current_js (server); + handler_of_jserver_dead (-1); + snd_server_head (server, JS_ENV_LIST); + snd_flush (); + + c = get4com (); + if (c == -1) + { + wnn_errorno = get4com (); + return -1; + } + + re_alloc (ret, sizeof (WNN_ENV_INFO) * c); + w = (WNN_ENV_INFO *) ret->buf; + for (i = 0; i < c; i++) + { + w->env_id = get4com (); + getscom (w->env_name); + w->ref_count = get4com (); + w->fzk_fid = get4com (); + w->jishomax = get4com (); + for (j = 0; j < WNN_MAX_JISHO_OF_AN_ENV; j++) + { + (w->jisho)[j] = get4com (); + } + for (j = 0; j < WNN_MAX_FILE_OF_AN_ENV; j++) + { + (w->file)[j] = get4com (); + } + w++; + } + return (c); +} + +/**** + +****/ +int +js_hindo_set (env, dic, entry, ima, hindo) + struct wnn_env *env; + int dic, entry, ima, hindo; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_HINDO_SET); + + put4com (dic); + put4com (entry); + put4com (ima); + put4com (hindo); + snd_flush (); + if ((x = get4com ()) == -1) + { + wnn_errorno = get4com (); + return -1; + } + return x; +} + + +/**** + Henkan +****/ + +static void +put_fzk_vec (hinsi, fzk, vec, vec1) + int hinsi; + w_char *fzk; + int vec; + int vec1; +{ + put4com (hinsi); + putwscom (fzk); + put4com (vec); + put4com (vec1); +} + +/** + kanren +**/ +static int rcv_dai (); +static void rcv_sho_x (); +static void rcv_sho_kanji (); + +int +js_kanren (env, yomi, hinsi, fzk, vec, vec1, vec2, rb) + struct wnn_env *env; + w_char *yomi; + int hinsi; + w_char *fzk; + int vec; + int vec1; + int vec2; + struct wnn_ret_buf *rb; +{ + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + + snd_env_head (env, JS_KANREN); + putwscom (yomi); + put_fzk_vec (hinsi, fzk, vec, vec1); + put4com (vec2); + snd_flush (); + return rcv_dai (rb); +} + +/* rcv dai */ +static int +rcv_dai (ret) + struct wnn_ret_buf *ret; +{ + int dai_cnt, sho_sum, kanji_sum, d_size, s_size, k_size, x; + register int i; + struct wnn_dai_bunsetsu *dai_list; + register struct wnn_dai_bunsetsu *dp; + struct wnn_sho_bunsetsu *sho_list; + register struct wnn_sho_bunsetsu *sp; + w_char *kanji, *kp; + + dai_cnt = get4com (); + if (dai_cnt == -1) + { /* error dayo */ + wnn_errorno = get4com (); + return -1; + } + sho_sum = get4com (); + kanji_sum = get4com (); + + d_size = sizeof (struct wnn_dai_bunsetsu) * dai_cnt; + s_size = sizeof (struct wnn_sho_bunsetsu) * sho_sum; + k_size = sizeof (w_char) * kanji_sum; + +/* re_alloc(ret, d_size+s_size+k_size); Seems This cause Bug?? H.T.*/ + re_alloc (ret, d_size + s_size + k_size); + + dai_list = (struct wnn_dai_bunsetsu *) ret->buf; + sho_list = (struct wnn_sho_bunsetsu *) ((char *) ret->buf + d_size); + kanji = (w_char *) ((char *) ret->buf + d_size + s_size); + + for (dp = dai_list, i = 0; i < dai_cnt; i++) + { + dp->end = get4com (); + dp->start = get4com (); + dp->sbncnt = get4com (); + dp->hyoka = get4com (); + dp++; + } + + for (dp = dai_list, sp = sho_list, i = 0; i < dai_cnt; i++) + { + dp->sbn = sp; + x = dp->sbncnt; + rcv_sho_x (sp, x); + sp += x; + dp++; + } + + for (dp = dai_list, kp = kanji, i = 0; i < dai_cnt; i++) + { + rcv_sho_kanji (dp->sbn, dp->sbncnt, &kp); + dp++; + } + return dai_cnt; +} + +/* rcv sho routines */ +static void +rcv_sho_x (sho_list, sho_cnt) + register struct wnn_sho_bunsetsu *sho_list; + int sho_cnt; +{ + register int i; + for (i = 0; i < sho_cnt; i++) + { + sho_list->end = get4com (); + sho_list->start = get4com (); + sho_list->jiriend = get4com (); + sho_list->dic_no = get4com (); + sho_list->entry = get4com (); + sho_list->hindo = get4com (); + sho_list->ima = get4com (); + sho_list->hinsi = get4com (); + sho_list->status = get4com (); + sho_list->status_bkwd = get4com (); + sho_list->kangovect = get4com (); + sho_list->hyoka = get4com (); + sho_list++; + } +} + +static void +rcv_sho_kanji (sho_list, sho_cnt, kanji) + struct wnn_sho_bunsetsu *sho_list; + int sho_cnt; + w_char **kanji; +{ + register w_char *k; + register int i, x; + k = *kanji; + for (i = 0; i < sho_cnt; i++) + { + sho_list->kanji = k; + getwscom (k); + x = wnn_Strlen (k); + k += x + 1; + + sho_list->yomi = k; + getwscom (k); + x = wnn_Strlen (k); + k += x + 1; + + sho_list->fuzoku = k; + getwscom (k); + x = wnn_Strlen (k); + k += x + 1; + sho_list++; + } + *kanji = k; +} + + +static int +rcv_sho (ret) + struct wnn_ret_buf *ret; +{ + register int sho_sum, kanji_sum, s_size, k_size; + struct wnn_sho_bunsetsu *sho_list; + w_char *kanji, *kp; + + sho_sum = get4com (); + if (sho_sum == -1) + { /* error dayo */ + wnn_errorno = get4com (); + return -1; + } + kanji_sum = get4com (); + + s_size = sizeof (struct wnn_sho_bunsetsu) * sho_sum; + k_size = sizeof (w_char) * kanji_sum; + + re_alloc (ret, s_size + k_size); + + sho_list = (struct wnn_sho_bunsetsu *) ((char *) ret->buf); + kanji = (w_char *) ((char *) ret->buf + s_size); + + rcv_sho_x (sho_list, sho_sum); + kp = kanji; + rcv_sho_kanji (sho_list, sho_sum, &kp); + return sho_sum; +} + +/** + kantan +**/ +int +js_kantan_dai (env, yomi, hinsi, fzk, vec, vec1, rb) + struct wnn_env *env; + w_char *yomi; + int hinsi; + w_char *fzk; + int vec; + int vec1; + struct wnn_ret_buf *rb; +{ + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + + snd_env_head (env, JS_KANTAN_DAI); + putwscom (yomi); + put_fzk_vec (hinsi, fzk, vec, vec1); + snd_flush (); + + return rcv_dai (rb); +} + +int +js_kantan_sho (env, yomi, hinsi, fzk, vec, vec1, rb) + struct wnn_env *env; + w_char *yomi; + int hinsi; + w_char *fzk; + int vec; + int vec1; + struct wnn_ret_buf *rb; +{ + int sbncnt; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + + snd_env_head (env, JS_KANTAN_SHO); + putwscom (yomi); + put_fzk_vec (hinsi, fzk, vec, vec1); + snd_flush (); + + sbncnt = rcv_sho (rb); + return sbncnt; +} + +/** + kanzen +**/ +int +js_kanzen_dai (env, yomi, hinsi, fzk, vec, vec1, rb) + struct wnn_env *env; + w_char *yomi; + int hinsi; + w_char *fzk; + int vec; + int vec1; + struct wnn_ret_buf *rb; +{ + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_KANZEN_DAI); + putwscom (yomi); + put_fzk_vec (hinsi, fzk, vec, vec1); + snd_flush (); + + return rcv_dai (rb); +} + + +int +js_kanzen_sho (env, yomi, hinsi, fzk, vec, vec1, rb) + struct wnn_env *env; + w_char *yomi; + int hinsi; + w_char *fzk; + int vec; + int vec1; + struct wnn_ret_buf *rb; +{ + int sbncnt; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_KANZEN_SHO); + putwscom (yomi); + put_fzk_vec (hinsi, fzk, vec, vec1); + snd_flush (); + + sbncnt = rcv_sho (rb); + return sbncnt; +} + +/** js_version **/ +int +js_version (server, serv, libv) + int *serv, *libv; + WNN_JSERVER_ID *server; +{ + set_current_js (server); + handler_of_jserver_dead (-1); + snd_server_head (server, JS_VERSION); + snd_flush (); + *libv = JLIB_VERSION; + return *serv = get4com (); +} + +static void +re_alloc (ret, size) + register struct wnn_ret_buf *ret; + int size; +{ + if (ret->size < size) + { + if (ret->buf) + free ((char *) ret->buf); + ret->buf = malloc (size); + ret->size = size; + } +} + + +int +js_kill (server) + WNN_JSERVER_ID *server; +{ + int x; + set_current_js (server); + handler_of_jserver_dead (-1); + snd_server_head (server, JS_KILL); + snd_flush (); + x = get4com (); + return (x); +} + + +int +js_file_remove (server, n, pwd) + WNN_JSERVER_ID *server; + char *n, *pwd; +{ + register int x; + set_current_js (server); + handler_of_jserver_dead (-1); + snd_server_head (server, JS_FILE_REMOVE); + putscom (n); + putscom (pwd); + snd_flush (); + if ((x = get4com ()) == -1) + { + wnn_errorno = get4com (); + return -1; + } + return (x); +} + +int +js_file_remove_client (server, n, pwd) + WNN_JSERVER_ID *server; + char *n, *pwd; +{ + struct wnn_file_head fh; + register FILE *fp; + set_current_js (server); + handler_of_jserver_dead (-1); + if (js_file_loaded_local (server, n) != -1) + { + wnn_errorno = WNN_FILE_IN_USE; + return (-1); + } +#ifdef WRITE_CHECK + check_backup (n); +#endif /* WRITE_CHECK */ + if ((fp = fopen (n, "r")) == NULL) + { + wnn_errorno = WNN_FILE_READ_ERROR; + return (-1); + } + if (input_file_header (fp, &fh) == -1) + { + fclose (fp); + wnn_errorno = WNN_NOT_A_FILE; + return (-1); + } + fclose (fp); + if (!check_pwd (pwd, fh.file_passwd)) + { + wnn_errorno = WNN_INCORRECT_PASSWD; + return (-1); + } + if (unlink (n) == -1) + { + wnn_errorno = WNN_UNLINK; + return (-1); + } + return (0); +} + +/** js_dic_file_create_client **/ +int +js_dic_file_create_client (env, fn, type, com, passwd, hpasswd) + struct wnn_env *env; + int type; + char *fn; + w_char *com; + char *passwd, *hpasswd; +{ + int x; + if (type != WNN_REV_DICT && type != CWNN_REV_DICT && type != BWNN_REV_DICT && type != WNN_UD_DICT) + { + wnn_errorno = WNN_NOT_A_UD; + return (-1); + } + x = create_null_dic (fn, com, passwd, hpasswd, type); + if (x == -1) + { + wnn_errorno = WNN_FILE_CREATE_ERROR; + return (-1); + } + return (0); +} + + +/** js_hindo_file_create_client **/ +int +js_hindo_file_create_client (env, fid, fn, com, hpasswd) + struct wnn_env *env; + int fid; + char *fn; + w_char *com; + char *hpasswd; +{ + register int x; + struct wnn_file_uniq funiq; + int serial; + register int i; + + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_HINDO_FILE_CREATE_CLIENT); + put4com (fid); + snd_flush (); + x = get4com (); + if (x == -1) + { + wnn_errorno = get4com (); + return (-1); + } + serial = get4com (); + funiq.time = get4com (); + funiq.dev = get4com (); + funiq.inode = get4com (); + for (i = 0; i < WNN_HOSTLEN; i++) + { + funiq.createhost[i] = get1com (); + } +/* getscom(funiq.createhost); */ + if (create_hindo_file (&funiq, fn, com, hpasswd, serial) == -1) + { + wnn_errorno = WNN_FILE_CREATE_ERROR; + return (-1); + } + return (0); +} + +int +js_file_comment_set (env, fid, comment) + struct wnn_env *env; + int fid; + w_char *comment; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_FILE_COMMENT_SET); + put4com (fid); + putwscom (comment); + snd_flush (); + x = get4com (); + if (x == -1) + { + wnn_errorno = get4com (); + return (-1); + } + return (0); +} + + +/* + * Hinsi Primitives + */ + +int +js_hinsi_name (server, no, rb) + WNN_JSERVER_ID *server; + int no; + struct wnn_ret_buf *rb; +{ + register int size; + + set_current_js (server); + handler_of_jserver_dead (-1); + snd_server_head (server, JS_HINSI_NAME); + put4com (no); + snd_flush (); + if ((size = get4com ()) == -1) + { + wnn_errorno = get4com (); + return (-1); + } + re_alloc (rb, sizeof (w_char) * (size + 1)); + getwscom ((w_char *) rb->buf); + return (0); +} + + +int +js_hinsi_number (server, name) + WNN_JSERVER_ID *server; + w_char *name; +{ + register int no; + + set_current_js (server); + handler_of_jserver_dead (-1); + snd_server_head (server, JS_HINSI_NUMBER); + putwscom (name); + snd_flush (); + if ((no = get4com ()) == -1) + { + wnn_errorno = get4com (); + return (-1); + } + return (no); +} + + +int +js_hinsi_list (env, dic_no, name, rb) + struct wnn_env *env; + int dic_no; + w_char *name; + struct wnn_ret_buf *rb; +{ + int size; + int count; + register w_char *s; + register w_char **r; + register int k; + + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_HINSI_LIST); + put4com (dic_no); + putwscom (name); + snd_flush (); + if ((count = get4com ()) == -1) + { + wnn_errorno = get4com (); + return (-1); + } + size = get4com (); + re_alloc (rb, sizeof (w_char) * (size + 1) + count * sizeof (w_char *)); + r = (w_char **) rb->buf; + s = (w_char *) ((w_char **) rb->buf + count); + for (k = 0; k < count; k++) + { + *r++ = s; + getwscom (s); + s += wnn_Strlen (s) + 1; + } + return (count); +} + + +int +js_hinsi_dicts (env, no, rb) + struct wnn_env *env; + int no; + struct wnn_ret_buf *rb; +{ + register int k, count; + int *p; + + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_HINSI_DICTS); + put4com (no); + snd_flush (); + if ((count = get4com ()) == -1) + { + wnn_errorno = get4com (); + return (-1); + } + re_alloc (rb, sizeof (int) * (count + 1)); + p = (int *) rb->buf; + + for (k = 0; k < count; k++) + { + *p++ = get4com (); + } + return (count); +} + + +char *wnn_dic_types[] = { "", "固定", "登録", "逆引", "正規" }; + +char *cwnn_dic_types[] = { "", "耕協", "鞠村", "憧咄", "屎号" }; +char *bwnn_dic_types[] = { "", "耕協", "鞠村", "永侏", "屎号" }; + +char *kwnn_dic_types[] = { "", "壱舛", "去系", "蝕遂", "舛鋭" }; + /* 由鑷 竒巵 羹齎 閨豫 */ + +/* New primitives 9/8 */ + +int +js_file_password_set (env, fid, which, old, new) + struct wnn_env *env; + int fid; + int which; /* 1 for dic, 2 for hindo 3(0) for both */ + char *old, *new; +{ + register int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_FILE_PASSWORD_SET); + put4com (fid); + put4com (which); + putscom (old); + putscom (new); + snd_flush (); + x = get4com (); + if (x == -1) + { + wnn_errorno = get4com (); + return (-1); + } + return (0); +} + +int +js_hinsi_table_set (env, dic_no, hinsi_table) + struct wnn_env *env; + int dic_no; + w_char *hinsi_table; +{ + int x; + if (env == 0) + return (-1); + set_current_js (env->js_id); + handler_of_jserver_dead (-1); + snd_env_head (env, JS_HINSI_TABLE_SET); + put4com (dic_no); + putwscom (hinsi_table); + snd_flush (); + x = get4com (); + if (x == -1) + { + wnn_errorno = get4com (); + return (-1); + } + return (0); +} + +#define SERVERDEFS_FILE "/serverdefs" + +#define MACHINE_NAME 1 +#define UNIXDOMAIN_NAME 2 +#define SERVICE_NAME 3 +#define SERVICE_PORT_NUM 4 + +static char * +get_serv_defs (lang, cnt) + char *lang; + int cnt; +{ + FILE *fp; + static char s[7][EXPAND_PATH_LENGTH]; + char serv_defs[EXPAND_PATH_LENGTH]; + char data[1024]; + int num; + + strcpy (serv_defs, LIBDIR); + strcat (serv_defs, SERVERDEFS_FILE); + if ((fp = fopen (serv_defs, "r")) == NULL) + { + return (NULL); + } + while (fgets (data, 1024, fp) != NULL) + { + num = sscanf (data, "%s %s %s %s %s %s %s", s[0], s[1], s[2], s[3], s[4], s[5], s[6]); + if ((num < 4) || s[0][0] == ';') + { + continue; + } + if (!strncmp (lang, s[0], strlen (s[0]))) + { + fclose (fp); + if (cnt == SERVICE_PORT_NUM && num < 5) + return (NULL); + if (strlen (s[cnt]) == strlen ("NULL") && !strcmp (s[cnt], "NULL")) + { + return (NULL); + } + else + { + return (s[cnt]); + } + } + } + fclose (fp); + return (NULL); +} + +char * +_wnn_get_machine_of_serv_defs (lang) + char *lang; +{ + return (get_serv_defs (lang, MACHINE_NAME)); +} + +static char * +get_unixdomain_of_serv_defs (lang) + char *lang; +{ + return (get_serv_defs (lang, UNIXDOMAIN_NAME)); +} + +static char * +get_service_of_serv_defs (lang) + char *lang; +{ + return (get_serv_defs (lang, SERVICE_NAME)); +} + +static int +get_port_num_of_serv_defs (lang) + char *lang; +{ + char *port_char; + + if ((port_char = get_serv_defs (lang, SERVICE_PORT_NUM)) == NULL) + { + return (-1); + } + else + { + return (atoi (port_char)); + } +}