/*
* $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));
}
}
syntax highlighted by Code2HTML, v. 0.9.1