1 /*
2  * Copyright (c) 1991-1994  Sony Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL SONY CORPORATION BE LIABLE FOR ANY CLAIM,
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * Except as contained in this notice, the name of Sony Corporation
24  * shall not be used in advertising or otherwise to promote the sale, use
25  * or other dealings in this Software without prior written authorization
26  * from Sony Corporation.
27  *
28  */
29 
30 /*
31  * $SonyRCSfile: level1.c,v $
32  * $SonyRevision: 1.4 $
33  * $SonyDate: 1995/04/17 10:36:08 $
34  */
35 
36 #define SJ3LIB_INTERNAL
37 
38 #include "sj_sysvdef.h"
39 #include <stdio.h>
40 #include <netdb.h>
41 #include <pwd.h>
42 #include <unistd.h>
43 #include <sys/un.h>
44 #include <sys/types.h>
45 #include <sys/param.h>
46 #include <netinet/in.h>
47 #ifdef TLI
48 #include <fcntl.h>
49 #include <tiuser.h>
50 #include <stropts.h>
51 #include <netdir.h>
52 #include <netconfig.h>
53 #else
54 #include <sys/socket.h>
55 #endif
56 #include <signal.h>
57 
58 #include "Const.h"
59 #include "sj3cmd.h"
60 #include "sj3err.h"
61 #include "sj3lowlib.h"
62 #include "sj3lib.h"
63 
64 #ifdef SVR4
65 #define signal sigset
66 #endif
67 
68 #ifndef lint
69 static	char	rcsid_sony[] = "$SonyId: level1.c,v 1.4 1995/04/17 10:36:08 notanaka Exp $ SONY;";
70 #endif
71 
72 int	sj3_error_number;
73 char	*sj3_socket_name	= SocketName;
74 char	*sj3_port_name	= PortName;
75 #ifndef TLI
76 int	sj3_port_number	= PortNumber;
77 #endif
78 
79 #define BUFFER_SIZE BUFSIZ
80 static	char	*af_unix_str = "unix";
81 static	u_char	putbuf[BUFFER_SIZE];
82 static	u_char	getbuf[BUFFER_SIZE];
83 static	int	putpos = 0;
84 static	int	getlen = 0;
85 static	int	getpos = 0;
86 static	SJ3_CLIENT_ENV	*cliptr;
87 static	int	server_fd = -1;
88 
89 static        int     sj3_timeout = 0;
90 
91 static  int     INTLEN = sizeof(int);
92 static  int     CMDLEN = sizeof(int);
93 static  int     ReadErrorFlag = FALSE;
94 
95 #define	client_init(p)	{ \
96 		cliptr = (p); \
97 		if ((server_fd = cliptr -> fd) == -1) { \
98 			sj3_error_number = SJ3_NotOpened; \
99 			return ERROR; \
100 		} \
101 	}
102 
103 static int
put_flush()104 put_flush()
105 {
106 	int	i, j;
107 	u_char	*p;
108 
109 	for (i = putpos, p = putbuf ; i > 0 ; i -= j, p += j) {
110 #ifdef TLI
111 	  if ((j = write(server_fd, p, i)) <= 0) {
112 	    t_sndrel(server_fd);
113             close(server_fd);
114 #else
115 	  if ((j = write(server_fd, p, i)) <= 0) {
116 	    shutdown(server_fd, 2);
117 	    close(server_fd);
118 #endif
119 	    cliptr -> fd = server_fd = -1;
120 	    sj3_error_number = SJ3_ServerDown;
121 	    return(ERROR);
122 	  }
123 	}
124 	putpos = 0;
125 
126 	return 0;
127 }
128 static void
129 put_byte(int c)
130 {
131 	putbuf[putpos++] = c;
132 }
133 static void
134 put_word(int c)
135 {
136 	put_byte(c >> 8);
137 	put_byte(c & 0xff);
138 }
139 static void
140 put_int(int c)
141 {
142 	put_byte(c >> (8 * 3));
143 	put_byte(c >> (8 * 2));
144 	put_byte(c >> (8 * 1));
145 	put_byte(c);
146 }
147 static void
148 put_cmd(int cmd)
149 {
150         ReadErrorFlag = FALSE;
151 	putpos = getlen = 0;
152 	put_int(cmd);
153 }
154 
155 #define put_string put_ndata
156 
157 static u_char *
158 put_ndata(u_char *p, int n)
159 {
160 	while (n-- > 0) put_byte(p ? *p++ : 0);
161 	return p;
162 }
163 
164 static int
165 put_over(int buflen, int n,
166     u_char *(*func1)(), u_char *str1, int len1,
167     u_char *(*func2)(), u_char *str2, int len2,
168     u_char *(*func3)(), u_char *str3, int len3,
169     u_char *(*func4)(), u_char *str4, int len4)
170 {
171 #define ARGNUM 4
172   u_char *(*func[ARGNUM])();
173   u_char *data[ARGNUM];
174   int len[ARGNUM];
175   int i;
176 
177   func[0] = func1; data[0] = str1; len[0] = len1;
178   func[1] = func2; data[1] = str2; len[1] = len2;
179   func[2] = func3; data[2] = str3; len[2] = len3;
180   func[3] = func4; data[3] = str4; len[3] = len4;
181 
182   for(i = 0; i < n; i++) {
183     if (len[i] < buflen) {
184       (*func[i])(data[i], len[i]);
185       buflen -= len[i];
186     } else {
187       while (len[i] > 0) {
188         data[i] = (*func[i])(data[i], (len[i] < buflen) ? len[i] : buflen);
189 	if (put_flush() == ERROR) return ERROR;
190 	len[i] -= buflen;
191 	buflen = BUFFER_SIZE;
192       }
193     }
194   }
195   if ((buflen != BUFFER_SIZE) && (put_flush() == ERROR))
196     return ERROR;
197 
198   return  0;
199 }
200 
201 static int
202 get_buffer()
203 {
204         if (ReadErrorFlag) return ERROR;
205         getpos = getlen = 0;
206 
207         getlen = read(server_fd, getbuf, sizeof(getbuf));
208         if (getlen <=0) {
209 #ifdef TLI
210           t_close(server_fd);
211 #else
212 	  shutdown(server_fd, 2);
213 	  close(server_fd);
214 #endif
215 	  cliptr -> fd = server_fd = -1;
216 	  sj3_error_number = SJ3_ServerDown;
217 	  return ERROR;
218 	}
219         return getlen;
220 }
221 
222 static int
223 get_byte()
224 {
225         if ((getpos >= getlen) && (get_buffer() == ERROR)) {
226 	  ReadErrorFlag = TRUE;
227 	  return 0;
228 	}
229 	return(getbuf[getpos++] & 0xff);
230 }
231 static int
232 get_word()
233 {
234 	int	i;
235 
236 	i = get_byte();
237 	return ((i << 8) | get_byte());
238 }
239 static int
240 get_int()
241 {
242 	int    i0;
243 	int    i1;
244 	int    i2;
245 
246 	i0 = get_byte();
247 	i1 = get_byte();
248 	i2 = get_byte();
249 	return ((i0 << (8*3)) | (i1 << (8*2)) | (i2 << (8*1)) | get_byte());
250 }
251 static u_char *
252 get_string(u_char *p)
253 {
254 	int	c;
255 
256 	do {
257 		*p++ = c = get_byte();
258 	} while (c);
259 
260 	return p;
261 }
262 static int
263 get_nstring(u_char *p, int n)
264 {
265 	int	c;
266 
267 	c = get_byte();
268 	while (c) {
269 		if (n > 1) { *p++ = c; n--; }
270 		c = get_byte();
271 	}
272 	if (n > 0) *p++ = 0;
273 	return n;
274 }
275 static u_char *
276 get_ndata(u_char *p, int n)
277 {
278 	while (n-- > 0) *p++ = get_byte();
279 	return p;
280 }
281 static void
282 skip_string()
283 {
284 	while (get_byte()) ;
285 }
286 static void
287 skip_ndata(int n)
288 {
289 	while (n-- > 0) get_byte();
290 }
291 #ifndef TLI
292 static int
293 open_unix()
294 {
295 	int	fd;
296 	struct	sockaddr_un	sunix;
297 
298 	sunix.sun_family      = AF_UNIX;
299 	strlcpy(sunix.sun_path, sj3_socket_name, sizeof(sunix.sun_path));
300 
301 	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == ERROR) {
302 		sj3_error_number = SJ3_OpenSocket;
303 		return ERROR;
304 	}
305 
306 	if (connect(fd, (struct sockaddr *)&sunix, SUN_LEN(&sunix))
307 			== ERROR) {
308 		sj3_error_number = SJ3_ConnectSocket;
309 		return ERROR;
310 	}
311 
312 	return fd;
313 }
314 #endif
315 
316 int
317 sj3_set_timeout(int timeout)
318 {
319         sj3_timeout = timeout;
320 }
321 static void
322 connect_timeout()
323 {
324 }
325 
326 
327 static int
328 open_inet(char *host)
329 {
330 #ifdef TLI
331 	int val;
332         char *t_alloc();
333         struct t_call *callptr;
334         struct netconfig *nconf;
335         struct nd_hostserv hserv;
336         struct nd_addrlist *addrs;
337         void *handlep;
338 	char host_name[BUFSIZ], proto_name[BUFSIZ], *port_name, *tmp_addr;
339 #else
340 	struct	hostent	*hp;
341 	struct	servent	*sp;
342 	int	port;
343 	struct	sockaddr_in	sin;
344 #endif
345 	int	fd, ret;
346 
347 #ifdef TLI
348         if ((tmp_addr = strchr(host, '/')) != NULL) {
349 		strlcpy(proto_name, host, (unsigned int) (tmp_addr - host));
350                 tmp_addr++;
351         } else {
352 		strlcpy(proto_name, ProtoName, strlen(ProtoName));
353 		tmp_addr = host;
354 	}
355         if ((port_name = strchr(tmp_addr, ':')) != NULL) {
356 		strlcpy(host_name, tmp_addr, (unsigned int)(port_name - tmp_addr));
357                 port_name++;
358         } else {
359 		strlcpy(host_name, tmp_addr, sizeof(hostname));
360 		port_name = PortName;
361 	}
362         hserv.h_host = host_name;
363         hserv.h_serv = port_name;
364 
365 	if ((handlep = setnetpath()) == NULL) {
366                 sj3_error_number = SJ3_GetHostByName;
367                 return ERROR;
368 	}
369 	while ((nconf = getnetpath(handlep)) != NULL) {
370                 if (((nconf->nc_semantics == NC_TPI_COTS_ORD) ||
371 		    (nconf->nc_semantics == NC_TPI_COTS)) &&
372                     (strncmp(nconf->nc_proto, proto_name, strlen(proto_name)) == 0))
373                   break;
374 	}
375 	if (nconf == NULL) {
376                 sj3_error_number = SJ3_GetHostByName;
377                 return ERROR;
378 	}
379 	if (netdir_getbyname(nconf, &hserv, &addrs) != 0) {
380                 hserv.h_serv = PortNumber;
381 		if (netdir_getbyname(nconf, &hserv, &addrs) != 0) {
382                         sj3_error_number = SJ3_GetHostByName;
383                         return ERROR;
384 		}
385 	}
386 	if (( fd = t_open(nconf->nc_device, O_RDWR, (struct t_info *)0)) < 0) {
387                 sj3_error_number = SJ3_OpenSocket;
388                 return ERROR;
389 	}
390 	if (t_bind(fd, (struct t_bind *)0, (struct t_bind *) 0) < 0) {
391                 sj3_error_number = SJ3_OpenSocket;
392                 return ERROR;
393 	}
394 #else
395 	if (!(hp = gethostbyname(host))) {
396 		sj3_error_number = SJ3_GetHostByName;
397 		return ERROR;
398 	}
399 
400 	if (sp = getservbyname(sj3_port_name, "tcp"))
401 		port = ntohs(sp -> s_port);
402 	else
403 		port = sj3_port_number;
404 
405 	memset((char *)&sin, '\0',sizeof(sin));
406 	sin.sin_family      = AF_INET;
407 	sin.sin_port        = htons(port);
408 	memcpy(&sin.sin_addr, hp -> h_addr, hp -> h_length);
409 
410 	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == ERROR) {
411 		sj3_error_number = SJ3_OpenSocket;
412 		return ERROR;
413 	}
414 #endif
415 
416         if (sj3_timeout > 0) {
417                 signal(SIGALRM, (void (*)())connect_timeout);
418                 alarm(sj3_timeout);
419         }
420 #ifdef TLI
421 	if((callptr = (struct t_call *) t_alloc(fd, T_CALL, T_ALL)) == NULL) {
422 		sj3_error_number = SJ3_NotEnoughMemory;
423 		return ERROR;
424 	}
425         callptr->addr = *(addrs->n_addrs);
426         callptr->opt.len = 0;
427         callptr->opt.maxlen = 0;
428         callptr->opt.buf = (char *)NULL;
429         callptr->udata.len = 0;
430         callptr->udata.maxlen = 0;
431         callptr->udata.buf = (char *)NULL;
432 
433         ret = t_connect(fd, callptr, (struct t_call *) 0);
434 #else
435         ret = connect(fd, (struct sockaddr *)&sin, sizeof(sin));
436 #endif
437         if (sj3_timeout > 0) {
438                 alarm(0);
439                 signal(SIGALRM, SIG_IGN);
440         }
441         if (ret == ERROR) {
442 		sj3_error_number = SJ3_ConnectSocket;
443 		return ERROR;
444 	}
445 #ifdef TLI
446 	if (ioctl(fd, I_POP, (char *) 0) < 0) {
447                 sj3_error_number = SJ3_NotOpened;
448                 return ERROR;
449 	}
450 	if (ioctl(fd, I_PUSH, "tirdwr") < 0) {
451                 sj3_error_number = SJ3_NotOpened;
452                 return ERROR;
453 	}
454         val = 0;
455         (void) ioctl(fd, I_SETCLTIME, &val);
456         endnetpath(handlep);
457 #endif
458 
459 	return fd;
460 }
461 
462 
463 
464 int
465 sj3_make_connection(SJ3_CLIENT_ENV *client, char *serv, char *user, char *prog)
466 {
467 	char	host[MAXHOSTNAMELEN];
468 	int	tmp;
469         int     hostlen, userlen, proglen, datalen, buflen;
470         int     curlen;
471         char    *curdata;
472 
473 	client -> fd = -1;
474 
475 	if (!serv || *serv == '\0' || !strcmp(serv, af_unix_str)) {
476 #ifdef TLI
477                 serv = LocalHost;
478                 strlcpy(host, af_unix_str, sizeof(host));
479 	} else {
480                 gethostname(host, sizeof(host));
481 	}
482         if ((server_fd = open_inet(serv)) == ERROR) return ERROR;
483 
484 #else
485 		if ((server_fd = open_unix()) == ERROR) return ERROR;
486 		strlcpy(host, af_unix_str, sizeof(host));
487 	}
488 	else {
489 		if ((server_fd = open_inet(serv)) == ERROR) return ERROR;
490 		gethostname(host, sizeof(host));
491 	}
492 #endif
493 	client -> fd = server_fd;
494 	client_init(client);
495 
496         hostlen = strlen(host) + 1;
497         userlen = strlen(user) + 1;
498         proglen = strlen(prog) + 1;
499         datalen = hostlen + userlen + proglen;
500 
501 	put_cmd(SJ3_CONNECT);
502 	put_int(SJ3SERV_VERSION_NO);
503         if (datalen <= (buflen = BUFFER_SIZE - CMDLEN - INTLEN)) {
504 	  put_string(host, hostlen);
505 	  put_string(user, userlen);
506 	  put_string(prog, proglen);
507 	  if (put_flush() == ERROR) return ERROR;
508 	} else {
509 	  if (put_over(buflen, 3, put_string, host, hostlen, put_string, user,
510 		       userlen, put_string, prog, proglen, NULL, NULL, 0) == ERROR)
511 	    return ERROR;
512 	}
513 
514         if ((tmp = get_int()) == SJ3_DifferentVersion) {
515 		if (ReadErrorFlag) return ERROR;
516 		put_cmd(SJ3_CONNECT);
517 		put_int(1);
518 		if (datalen <= (buflen = BUFFER_SIZE - CMDLEN - INTLEN)) {
519 			put_string(host, hostlen);
520 			put_string(user, userlen);
521 			put_string(prog, proglen);
522 			if (put_flush() == ERROR) return ERROR;
523 		} else {
524 			if (put_over(buflen, 3, put_string, host, hostlen, put_string, user,
525 				     userlen, put_string, prog, proglen, NULL, NULL, 0) == ERROR)
526 			    return ERROR;
527 		}
528 		if (tmp = get_int()) {
529 			sj3_erase_connection(client);
530 			sj3_error_number = tmp;
531 			return ERROR;
532 		}
533 	} else if (tmp && (-2 < tmp)) {
534 		sj3_erase_connection(client);
535 		sj3_error_number = tmp;
536 		return ERROR;
537 	}
538         cliptr -> svr_version = ((tmp)? -tmp : 1);
539         cliptr -> cli_version = SJ3SERV_VERSION_NO;
540         cliptr -> default_char[0] = 0x81;
541         cliptr -> default_char[1] = 0x40;
542 	sj3_error_number = 0;
543 
544         if (ReadErrorFlag) return ERROR;
545 	put_cmd(SJ3_STDYSIZE);
546         if (put_flush() == ERROR) return ERROR;
547 
548 	if (tmp = get_int()) {
549 		sj3_erase_connection(client);
550 		sj3_error_number = tmp;
551 		return ERROR;
552 	}
553 
554 	cliptr -> stdy_size = get_int();
555 	cliptr -> fd        = server_fd;
556 
557         return ReadErrorFlag ? ERROR : 0;
558 }
559 int
sj3_erase_connection(SJ3_CLIENT_ENV * client)560 sj3_erase_connection(SJ3_CLIENT_ENV *client)
561 {
562 	client_init(client);
563 
564 	put_cmd(SJ3_DISCONNECT);
565         if (put_flush() == ERROR) return ERROR;
566 
567 	sj3_error_number = get_int();
568 #ifdef TLI
569         t_close(server_fd);
570 #else
571 	close(server_fd);
572 #endif
573 	cliptr -> fd = -1;
574         if (ReadErrorFlag) return ERROR;
575 	return sj3_error_number ? ERROR : 0;
576 }
577 
578 
579 
580 long
sj3_open_dictionary(SJ3_CLIENT_ENV * client,char * dictname,char * password)581 sj3_open_dictionary(SJ3_CLIENT_ENV *client, char *dictname, char *password)
582 {
583         int res;
584         int dictlen, passlen;
585         int datalen, buflen;
586 
587 	client_init(client);
588 
589         dictlen = strlen(dictname) + 1;
590         passlen = ((password) ? strlen(password) : 0) + 1;
591         datalen = dictlen + passlen;
592 
593 	put_cmd(SJ3_OPENDICT);
594         if (datalen < (buflen = BUFFER_SIZE - CMDLEN)) {
595 	  put_string(dictname, dictlen);
596 	  put_string(password, passlen);
597 	  if (put_flush() == ERROR) return ERROR;
598 	} else {
599 	  if (put_over(buflen, 2, put_string, dictname, dictlen, put_string,
600 		       password, passlen, NULL, NULL, 0, NULL, NULL, 0) == ERROR)
601 	    return ERROR;
602 	}
603 
604 	if (sj3_error_number = get_int()) return 0;
605         res = get_int();
606         return ReadErrorFlag ? ERROR : res;
607 }
608 int
sj3_close_dictionary(SJ3_CLIENT_ENV * client,long dicid)609 sj3_close_dictionary(SJ3_CLIENT_ENV *client, long dicid)
610 {
611 	client_init(client);
612 
613 	put_cmd(SJ3_CLOSEDICT);
614 	put_int(dicid);
615         if (put_flush() == ERROR) return ERROR;
616 
617 	if (sj3_error_number = get_int()) return ERROR;
618         return ReadErrorFlag ? ERROR : 0;
619 }
620 
621 
622 
623 int
sj3_open_study_file(SJ3_CLIENT_ENV * client,char * stdyname,char * password)624 sj3_open_study_file(SJ3_CLIENT_ENV *client, char *stdyname, char *password)
625 {
626         int stdylen, passlen;
627         int datalen, buflen;
628 
629 	client_init(client);
630 
631         stdylen = strlen(stdyname) + 1;
632         passlen = strlen(password) + 1;
633         datalen = stdylen + passlen;
634 
635 	put_cmd(SJ3_OPENSTDY);
636         if (datalen < (buflen = BUFFER_SIZE - CMDLEN)) {
637 	  put_string(stdyname, stdylen);
638 	  put_string(password, passlen);
639 	  if (put_flush() == ERROR) return ERROR;
640 	} else {
641 	  if (put_over(buflen, 2, put_string, stdyname, stdylen, put_string,
642 		       password, passlen, NULL, NULL, 0, NULL, NULL, 0) == ERROR)
643 	    return ERROR;
644 	}
645 
646 	if (sj3_error_number = get_int()) return ERROR;
647         return ReadErrorFlag ? ERROR : 0;
648 }
649 int
sj3_close_study_file(SJ3_CLIENT_ENV * client)650 sj3_close_study_file(SJ3_CLIENT_ENV *client)
651 {
652 	client_init(client);
653 
654 	put_cmd(SJ3_CLOSESTDY);
655         if (put_flush() == ERROR) return ERROR;
656 
657 	if (sj3_error_number = get_int()) return ERROR;
658         return ReadErrorFlag ? ERROR : 0;
659 }
660 
661 
662 
663 int
sj3_get_id_size(SJ3_CLIENT_ENV * client)664 sj3_get_id_size(SJ3_CLIENT_ENV *client)
665 {
666 	client_init(client);
667 
668 	put_cmd(SJ3_STDYSIZE);
669         if (put_flush() == ERROR) return ERROR;
670 
671 	if (sj3_error_number = get_int()) return ERROR;
672 	cliptr -> stdy_size = get_int();
673         return ReadErrorFlag ? ERROR : cliptr -> stdy_size;
674 }
675 
676 
677 
678 int
sj3_lock_server(SJ3_CLIENT_ENV * client)679 sj3_lock_server(SJ3_CLIENT_ENV *client)
680 {
681 	client_init(client);
682 
683 	put_cmd(SJ3_LOCK);
684         if (put_flush() == ERROR) return ERROR;
685 
686 	if (sj3_error_number = get_int()) return ERROR;
687         return ReadErrorFlag ? ERROR : 0;
688 }
689 int
sj3_unlock_server(SJ3_CLIENT_ENV * client)690 sj3_unlock_server(SJ3_CLIENT_ENV *client)
691 {
692 	client_init(client);
693 
694 	put_cmd(SJ3_UNLOCK);
695         if (put_flush() == ERROR) return ERROR;
696 
697 	if (sj3_error_number = get_int()) return ERROR;
698         return ReadErrorFlag ? ERROR : 0;
699 }
700 
701 
702 
703 int
sj3_ikkatu_henkan(SJ3_CLIENT_ENV * client,u_char * src,u_char * dst,int dstsiz,int mb_flag)704 sj3_ikkatu_henkan(SJ3_CLIENT_ENV *client, u_char *src, u_char *dst, int dstsiz, int mb_flag)
705 {
706 	int	c;
707 	u_char	*top;
708 	int	result;
709 	int	len;
710 	int	len1;
711 	int	stysiz;
712 
713         int     srclen;
714         int     buflen;
715 
716 	client_init(client);
717 
718         srclen = strlen(src) + 1;
719 
720 	if (mb_flag == MBCODE_SJIS)
721 	  put_cmd(SJ3_PH2KNJ);
722 	else
723 	  put_cmd(SJ3_PH2KNJ_EUC);
724         if (srclen < (buflen = BUFFER_SIZE - CMDLEN)) {
725 	  put_string(src, srclen);
726 	  if (put_flush() == ERROR) return ERROR;
727 	} else {
728 	  if (put_over(buflen, 1, put_string, src, srclen, NULL, NULL, 0,
729 			  NULL, NULL, 0, NULL, NULL, 0) == ERROR)
730 	    return ERROR;
731 	}
732 
733 	if (sj3_error_number = get_int()) return ERROR;
734 
735 	result = get_int();
736 
737 
738 	result = 0;
739 	stysiz = cliptr -> stdy_size;
740 	len1 =  1 + stysiz + 1 + 1;
741 	while (c = get_byte()) {
742 
743 		top = dst;
744 		if (dstsiz < len1) goto error1;
745 
746 		*dst++ = len = c;
747 		dst = get_ndata(dst, stysiz);
748 		dstsiz -= (stysiz + 1);
749 
750 		while (c = get_byte()) {
751 			if (dstsiz-- < 3) goto error2;
752 			*dst++ = c;
753 		}
754 		*dst++ = 0;
755 		dstsiz--;
756 		result += len;
757 	}
758 
759 	*dst = 0;
760         return ReadErrorFlag ? ERROR : result;
761 
762 
763 error1:
764 	do {
765 		skip_ndata(stysiz);
766 error2:
767 		while (get_byte()) ;
768 	} while (get_byte());
769 
770 	*top = 0;
771         return ReadErrorFlag ? ERROR : result;
772 }
773 
774 
775 
776 int
sj3_bunsetu_henkan(SJ3_CLIENT_ENV * client,u_char * yomi,int len,u_char * kanji,int mb_flag)777 sj3_bunsetu_henkan(SJ3_CLIENT_ENV *client, u_char *yomi, int len, u_char *kanji, int mb_flag)
778 {
779 	int	result;
780         int     buflen;
781 
782 	client_init(client);
783 
784 	if (mb_flag == MBCODE_SJIS)
785 	  put_cmd(SJ3_CL2KNJ);
786 	else
787 	  put_cmd(SJ3_CL2KNJ_EUC);
788 	put_int(len);
789         if ((len + 1) <= (buflen = BUFFER_SIZE - CMDLEN - INTLEN)) {
790 	  put_ndata(yomi, len);
791 	  put_byte(0);
792           if (put_flush() == ERROR) return ERROR;
793 	} else {
794 
795 	  if (put_over(buflen, 2, put_ndata, yomi, len, put_ndata, NULL, 1,
796 		       NULL, NULL, 0, NULL, NULL, 0) == ERROR)
797             return ERROR;
798 	}
799 
800 	if (sj3_error_number = get_int()) return ERROR;
801 
802 	result = get_int();
803 	get_string( get_ndata(kanji, cliptr -> stdy_size) );
804         return ReadErrorFlag ? ERROR : result;
805 }
806 int
sj3_bunsetu_jikouho(SJ3_CLIENT_ENV * client,u_char * kanji,int mode,int mb_flag)807 sj3_bunsetu_jikouho(SJ3_CLIENT_ENV *client, u_char *kanji, int mode, int mb_flag)
808 {
809 	int	result;
810 
811 	client_init(client);
812 
813 	if (mb_flag == MBCODE_SJIS)
814 	  put_cmd(SJ3_NEXTCL);
815 	else
816 	  put_cmd(SJ3_NEXTCL_EUC);
817 	put_int(mode);
818         if (put_flush() == ERROR) return ERROR;
819 
820 	if (sj3_error_number = get_int()) return ERROR;
821 
822 	result = get_int();
823 	get_string( get_ndata(kanji, cliptr -> stdy_size) );
824         return ReadErrorFlag ? ERROR : result;
825 }
826 int
sj3_bunsetu_maekouho(SJ3_CLIENT_ENV * client,u_char * kanji,int mode,int mb_flag)827 sj3_bunsetu_maekouho(SJ3_CLIENT_ENV *client, u_char *kanji, int mode, int mb_flag)
828 {
829 	int	result;
830 
831 	client_init(client);
832 
833 	if (mb_flag == MBCODE_SJIS)
834 	  put_cmd(SJ3_PREVCL);
835 	else
836 	  put_cmd(SJ3_PREVCL_EUC);
837 	put_int(mode);
838         if (put_flush() == ERROR) return ERROR;
839 
840 	if (sj3_error_number = get_int()) return ERROR;
841 
842 	result = get_int();
843 	get_string( get_ndata(kanji, cliptr -> stdy_size) );
844         return ReadErrorFlag ? ERROR : result;
845 }
846 
847 
848 
849 int
sj3_bunsetu_kouhosuu(SJ3_CLIENT_ENV * client,u_char * yomi,int len,int mb_flag)850 sj3_bunsetu_kouhosuu(SJ3_CLIENT_ENV *client, u_char *yomi, int len, int mb_flag)
851 {
852         int result;
853         int buflen;
854 
855 	client_init(client);
856 
857 	if (mb_flag == MBCODE_SJIS)
858 	  put_cmd(SJ3_CL2KNJ_CNT);
859 	else
860 	  put_cmd(SJ3_CL2KNJ_CNT_EUC);
861 	put_int(len);
862         if ((len + 1) <= (buflen = BUFFER_SIZE - CMDLEN - INTLEN)) {
863 	  put_ndata(yomi, len);
864 	  put_byte(0);
865           if (put_flush() == ERROR) return ERROR;
866 	} else {
867 
868           if (put_over(buflen, 2, put_ndata, yomi, len, put_ndata, NULL, 1,
869                        NULL, NULL, 0, NULL, NULL, 0) == ERROR)
870             return ERROR;
871 	}
872 
873 	if (sj3_error_number = get_int()) return ERROR;
874 
875 	result = get_int();
876         return ReadErrorFlag ? ERROR : result;
877 }
878 int
sj3_bunsetu_zenkouho(SJ3_CLIENT_ENV * client,u_char * yomi,int len,SJ3_DOUON * douon,int mb_flag)879 sj3_bunsetu_zenkouho(SJ3_CLIENT_ENV *client, u_char *yomi, int len, SJ3_DOUON *douon, int mb_flag)
880 {
881 	int	cnt = 0;
882         int buflen;
883 
884 	client_init(client);
885 
886 	if (mb_flag == MBCODE_SJIS)
887 	  put_cmd(SJ3_CL2KNJ_ALL);
888 	else
889 	  put_cmd(SJ3_CL2KNJ_ALL_EUC);
890 	put_int(len);
891         if ((len + 1) <= (buflen = BUFFER_SIZE - CMDLEN - INTLEN)) {
892 	  put_ndata(yomi, len);
893 	  put_byte(0);
894           if (put_flush() == ERROR) return ERROR;
895 	} else {
896 
897           if (put_over(buflen, 2, put_ndata, yomi, len, put_ndata, NULL, 1,
898                        NULL, NULL, 0, NULL, NULL, 0) == ERROR)
899             return ERROR;
900 	}
901 
902 	if (sj3_error_number = get_int()) return ERROR;
903 
904 	while (get_int()) {
905                 get_ndata((u_char *)&(douon -> dcid), cliptr -> stdy_size); /* XXX */
906 		get_string(douon -> ddata);
907 		douon -> dlen = strlen(douon -> ddata);
908 		douon++;
909 		cnt++;
910 	}
911 
912         return ReadErrorFlag ? ERROR : cnt;
913 }
914 
915 
916 
917 int
sj3_tango_gakusyuu(SJ3_CLIENT_ENV * client,SJ3_STUDYREC * stdy)918 sj3_tango_gakusyuu(SJ3_CLIENT_ENV *client, SJ3_STUDYREC *stdy)
919 {
920         int buflen;
921 
922 	client_init(client);
923 
924 	put_cmd(SJ3_STUDY);
925         if (cliptr -> stdy_size <= (buflen = BUFFER_SIZE - CMDLEN)) {
926 		put_ndata((u_char *)stdy, cliptr -> stdy_size); /* XXX */
927 		if (put_flush() == ERROR) return ERROR;
928 	} else {
929 		/* XXX */
930 		if (put_over(buflen, 1, put_ndata, (u_char *)stdy, cliptr -> stdy_size, NULL,
931 			NULL, 0, NULL, NULL, 0, NULL, NULL, 0) == ERROR)
932 			return ERROR;
933 	}
934 
935 
936 	if (sj3_error_number = get_int()) return ERROR;
937         return ReadErrorFlag ? ERROR : 0;
938 }
939 int
sj3_bunsetu_gakusyuu(SJ3_CLIENT_ENV * client,u_char * yomi1,u_char * yomi2,SJ3_STUDYREC * stdy,int mb_flag)940 sj3_bunsetu_gakusyuu(SJ3_CLIENT_ENV *client, u_char *yomi1, u_char *yomi2, SJ3_STUDYREC *stdy, int mb_flag)
941 {
942         int yomilen1, yomilen2;
943         int datalen, buflen;
944 
945 	client_init(client);
946 
947         yomilen1 = strlen(yomi1) + 1;
948         yomilen2 = strlen(yomi2) + 1;
949         datalen = yomilen1 + yomilen2 + cliptr -> stdy_size;
950 
951 	if (mb_flag == MBCODE_SJIS)
952 	  put_cmd(SJ3_CLSTUDY);
953 	else
954   	  put_cmd(SJ3_CLSTUDY_EUC);
955         if (datalen <= (buflen = BUFFER_SIZE - CMDLEN)) {
956 	  put_string(yomi1, yomilen1);
957 	  put_string(yomi2, yomilen2);
958 	  put_ndata((u_char *)stdy, cliptr -> stdy_size); /* XXX */
959           if (put_flush() == ERROR) return ERROR;
960 	} else {
961 	  if (put_over(buflen, 3, put_string, yomi1, yomilen1, put_string,
962 		  yomi2, yomilen2, put_ndata, (u_char *)stdy, cliptr->stdy_size, /* XXX */
963 		  NULL, NULL, 0) == ERROR)
964 		  return ERROR;
965 	}
966 
967 	if (sj3_error_number = get_int()) return ERROR;
968         return ReadErrorFlag ? ERROR : 0;
969 }
970 
971 
972 
973 int
sj3_tango_touroku(SJ3_CLIENT_ENV * client,long dicid,u_char * yomi,u_char * kanji,int code,int mb_flag)974 sj3_tango_touroku(SJ3_CLIENT_ENV *client, long dicid, u_char *yomi, u_char *kanji, int code, int mb_flag)
975 {
976         int yomilen, kanjilen;
977         int datalen, buflen;
978 
979 	client_init(client);
980 
981         yomilen = strlen(yomi) + 1;
982         kanjilen = strlen(kanji) + 1;
983         datalen = yomilen + kanjilen + INTLEN;
984 
985 	if (mb_flag == MBCODE_SJIS)
986 	  put_cmd(SJ3_ADDDICT);
987 	else
988 	  put_cmd(SJ3_ADDDICT_EUC);
989 	put_int(dicid);
990         if (datalen <= (buflen = BUFFER_SIZE - CMDLEN -INTLEN)) {
991 	  put_string(yomi, yomilen);
992 	  put_string(kanji, kanjilen);
993 	  put_int(code);
994           if (put_flush() == ERROR) return ERROR;
995 	} else {
996 	  if (put_over(buflen, 3, put_string, yomi, yomilen, put_string, kanji,
997 		  kanjilen, put_ndata, (u_char *)&code, INTLEN, NULL, NULL, 0) == ERROR) /* XXX */
998 		  return ERROR;
999 	}
1000 
1001 	if (sj3_error_number = get_int()) return ERROR;
1002         return ReadErrorFlag ? ERROR : 0;
1003 }
1004 int
sj3_tango_sakujo(SJ3_CLIENT_ENV * client,long dicid,u_char * yomi,u_char * kanji,int code,int mb_flag)1005 sj3_tango_sakujo(SJ3_CLIENT_ENV *client, long dicid, u_char *yomi, u_char *kanji, int code, int mb_flag)
1006 {
1007         int yomilen, kanjilen;
1008         int datalen, buflen;
1009 
1010 	client_init(client);
1011 
1012         yomilen = strlen(yomi) + 1;
1013         kanjilen = strlen(kanji) + 1;
1014         datalen = yomilen + kanjilen + INTLEN;
1015 
1016 	if (mb_flag == MBCODE_SJIS)
1017 	  put_cmd(SJ3_DELDICT);
1018 	else
1019 	  put_cmd(SJ3_DELDICT_EUC);
1020 	put_int(dicid);
1021         if (datalen <= (buflen = BUFFER_SIZE - CMDLEN -INTLEN)) {
1022 	  put_string(yomi, yomilen);
1023 	  put_string(kanji, kanjilen);
1024 	  put_int(code);
1025           if (put_flush() == ERROR) return ERROR;
1026 	} else {
1027 	  if (put_over(buflen, 3, put_string, yomi, yomilen, put_string, kanji,
1028 		  kanjilen, put_ndata, (u_char *)&code, INTLEN, NULL, NULL, 0) == ERROR)  /* XXX */
1029 		  return ERROR;
1030 	}
1031 
1032 	if (sj3_error_number = get_int()) return ERROR;
1033         return ReadErrorFlag ? ERROR : 0;
1034 }
1035 
1036 
1037 
1038 int
sj3_tango_syutoku(SJ3_CLIENT_ENV * client,int dicid,u_char * buf,int mb_flag)1039 sj3_tango_syutoku(SJ3_CLIENT_ENV *client, int dicid, u_char *buf, int mb_flag)
1040 {
1041 	u_char	*p;
1042 
1043 	client_init(client);
1044 
1045 	if (mb_flag == MBCODE_SJIS)
1046 	  put_cmd(SJ3_GETDICT);
1047 	else
1048 	  put_cmd(SJ3_GETDICT_EUC);
1049 	put_int(dicid);
1050         if (put_flush() == ERROR) return ERROR;
1051 
1052 	if (sj3_error_number = get_int()) return ERROR;
1053 
1054 	p = get_string(buf);
1055 	p = get_string(p);
1056 	*p = get_int();
1057         return ReadErrorFlag ? ERROR : 0;
1058 }
1059 int
sj3_tango_jikouho(SJ3_CLIENT_ENV * client,int dicid,u_char * buf,int mb_flag)1060 sj3_tango_jikouho(SJ3_CLIENT_ENV *client, int dicid, u_char *buf, int mb_flag)
1061 {
1062 	u_char	*p;
1063 
1064 	client_init(client);
1065 
1066 	if (mb_flag == MBCODE_SJIS)
1067 	  put_cmd(SJ3_NEXTDICT);
1068 	else
1069 	  put_cmd(SJ3_NEXTDICT_EUC);
1070 	put_int(dicid);
1071         if (put_flush() == ERROR) return ERROR;
1072 
1073 	if (sj3_error_number = get_int()) return ERROR;
1074 
1075 	p = get_string(buf);
1076 	p = get_string(p);
1077 	*p = get_int();
1078         return ReadErrorFlag ? ERROR : 0;
1079 }
1080 int
sj3_tango_maekouho(SJ3_CLIENT_ENV * client,int dicid,u_char * buf,int mb_flag)1081 sj3_tango_maekouho(SJ3_CLIENT_ENV *client, int dicid, u_char *buf, int mb_flag)
1082 {
1083 	u_char	*p;
1084 
1085 	client_init(client);
1086 
1087 	if (mb_flag == MBCODE_SJIS)
1088 	  put_cmd(SJ3_PREVDICT);
1089 	else
1090 	  put_cmd(SJ3_PREVDICT_EUC);
1091 	put_int(dicid);
1092         if (put_flush() == ERROR) return ERROR;
1093 
1094 	if (sj3_error_number = get_int()) return ERROR;
1095 
1096 	p = get_string(buf);
1097 	p = get_string(p);
1098 	*p = get_int();
1099         return ReadErrorFlag ? ERROR : 0;
1100 }
1101 
1102 
1103 
1104 int
sj3_make_dict_file(SJ3_CLIENT_ENV * client,char * path,int idxlen,int seglen,int segnum)1105 sj3_make_dict_file(SJ3_CLIENT_ENV *client, char *path, int idxlen, int seglen, int segnum)
1106 {
1107         int pathlen;
1108         int buflen, datalen;
1109 
1110 	client_init(client);
1111 
1112         pathlen = strlen(path) + 1;
1113         datalen = pathlen + INTLEN + INTLEN + INTLEN;
1114 
1115 	put_cmd(SJ3_MAKEDICT);
1116         if (datalen <= (buflen = BUFFER_SIZE - CMDLEN)) {
1117 	  put_string(path, pathlen);
1118 	  put_int(idxlen);
1119 	  put_int(seglen);
1120 	  put_int(segnum);
1121           if (put_flush() == ERROR) return ERROR;
1122 	} else {
1123           if (put_over(buflen, 4, put_string, path, pathlen, put_ndata,
1124 		  (u_char *)&idxlen, INTLEN, put_ndata, (u_char *)&seglen, INTLEN, /* XXX */
1125 		  put_ndata, (u_char *)&segnum, 0) == ERROR)
1126 		  return ERROR;
1127 	}
1128 
1129 	if (sj3_error_number = get_int()) return ERROR;
1130         return ReadErrorFlag ? ERROR : 0;
1131 }
1132 
1133 
1134 
1135 int
sj3_make_study_file(SJ3_CLIENT_ENV * client,char * path,int stynum,int clstep,int cllen)1136 sj3_make_study_file(SJ3_CLIENT_ENV *client, char *path, int stynum, int clstep, int cllen)
1137 {
1138         int pathlen;
1139         int buflen, datalen;
1140 
1141 	client_init(client);
1142 
1143         pathlen = strlen(path) + 1;
1144         datalen = pathlen + INTLEN + INTLEN + INTLEN;
1145 
1146 	put_cmd(SJ3_MAKESTDY);
1147         if (datalen <= (buflen = BUFFER_SIZE - CMDLEN)) {
1148 	  put_string(path, pathlen);
1149 	  put_int(stynum);
1150 	  put_int(clstep);
1151 	  put_int(cllen);
1152           if (put_flush() == ERROR) return ERROR;
1153 	} else {
1154           if (put_over(buflen, 4, put_string, path, pathlen, put_ndata,
1155 		  (u_char *)&stynum, INTLEN, put_ndata, (u_char *)&clstep, INTLEN, /* XXX */
1156 		  put_ndata, (u_char *)&cllen, 0) == ERROR)
1157             return ERROR;
1158 	}
1159 
1160 	if (sj3_error_number = get_int()) return ERROR;
1161         return ReadErrorFlag ? ERROR : 0;
1162 }
1163 
1164 
1165 
1166 int
sj3_make_directory(SJ3_CLIENT_ENV * client,char * path)1167 sj3_make_directory(SJ3_CLIENT_ENV *client, char *path)
1168 {
1169         int pathlen;
1170         int buflen;
1171 
1172 	client_init(client);
1173 
1174         pathlen = strlen(path) + 1;
1175 
1176 	put_cmd(SJ3_MAKEDIR);
1177         if (pathlen <= (buflen = BUFFER_SIZE - CMDLEN)) {
1178 	  put_string(path, pathlen);
1179           if (put_flush() == ERROR) return ERROR;
1180 	} else {
1181           if (put_over(buflen, 1, put_string, path, pathlen, NULL, NULL, 0,
1182 		       NULL, NULL, 0, NULL, NULL, 0) == ERROR)
1183             return ERROR;
1184 	}
1185 
1186 
1187 	if (sj3_error_number = get_int()) return ERROR;
1188         return ReadErrorFlag ? ERROR : 0;
1189 }
1190 
1191 
1192 
1193 int
sj3_access(SJ3_CLIENT_ENV * client,char * path,int mode)1194 sj3_access(SJ3_CLIENT_ENV *client, char *path, int mode)
1195 {
1196         int result;
1197         int pathlen;
1198         int buflen, datalen;
1199 
1200 	client_init(client);
1201 
1202         pathlen = strlen(path) + 1;
1203         datalen = pathlen + INTLEN;
1204 
1205 	put_cmd(SJ3_ACCESS);
1206         if (datalen <= (buflen = BUFFER_SIZE - CMDLEN)) {
1207 	  put_string(path, pathlen);
1208 	  put_int(mode);
1209           if (put_flush() == ERROR) return ERROR;
1210 	} else {
1211 		if (put_over(buflen, 2, put_string, path, pathlen, put_ndata,
1212 			(u_char *)&mode, INTLEN, NULL, NULL, 0, NULL, NULL, 0) == ERROR)
1213 			return ERROR;
1214 	}
1215 
1216 	sj3_error_number = 0;
1217 	result = get_int();
1218         return ReadErrorFlag ? ERROR : result;
1219 }
1220 
1221 
1222 
1223 int
sj3_who(SJ3_CLIENT_ENV * client,SJ3_WHO_STRUCT * ret,int num)1224 sj3_who(SJ3_CLIENT_ENV *client, SJ3_WHO_STRUCT *ret, int num)
1225 {
1226 	int	i, j;
1227 
1228 	client_init(client);
1229 
1230 	put_cmd(SJ3_WHO);
1231         if (put_flush() == ERROR) return ERROR;
1232 
1233 	if ((i = get_int()) < 0) {
1234 		sj3_error_number = SJ3_InternalError;
1235 		return -1;
1236 	}
1237 
1238 	sj3_error_number = 0;
1239 	for (j = 0 ; j < i ; j++) {
1240 		if (j < num) {
1241 			ret -> fd = get_int();
1242 			get_nstring(ret -> hostname, SJ3_NAME_LENGTH);
1243 			get_nstring(ret -> username, SJ3_NAME_LENGTH);
1244 			get_nstring(ret -> progname, SJ3_NAME_LENGTH);
1245 			ret++;
1246 		}
1247 		else {
1248 			get_int();
1249 			skip_string();
1250 			skip_string();
1251 			skip_string();
1252 		}
1253 	}
1254 
1255         return ReadErrorFlag ? ERROR : ((i < num) ? i : num);
1256 }
1257 
1258 
1259 
1260 int
sj3_quit(SJ3_CLIENT_ENV * client)1261 sj3_quit(SJ3_CLIENT_ENV *client)
1262 {
1263 	client_init(client);
1264 
1265 	put_cmd(SJ3_QUIT);
1266         if (put_flush() == ERROR) return ERROR;
1267 
1268 	if (sj3_error_number = get_int()) return ERROR;
1269         return ReadErrorFlag ? ERROR : 0;
1270 }
1271 int
sj3_kill(SJ3_CLIENT_ENV * client)1272 sj3_kill(SJ3_CLIENT_ENV *client)
1273 {
1274 	client_init(client);
1275 
1276 	put_cmd(SJ3_KILL);
1277         if (put_flush() == ERROR) return ERROR;
1278 
1279 	if (sj3_error_number = get_int()) return ERROR;
1280         return ReadErrorFlag ? ERROR : 0;
1281 }
1282 
1283 
1284 
1285 int
sj3_version(SJ3_CLIENT_ENV * client,char * dst,int dstsiz)1286 sj3_version(SJ3_CLIENT_ENV *client, char *dst, int dstsiz)
1287 {
1288 	int	c;
1289 
1290 	client_init(client);
1291 
1292 	put_cmd(SJ3_VERSION);
1293         if (put_flush() == ERROR) return ERROR;
1294 
1295 	sj3_error_number = get_int();
1296 	c = get_byte();
1297 	while (c) {
1298 		while (c) {
1299 			if (dstsiz > 2) { *dst++ = c; dstsiz--; }
1300 			c = get_byte();
1301 		}
1302 		if (dstsiz > 1) { *dst++ = 0; dstsiz--; }
1303 		c = get_byte();
1304 	}
1305 	if (dstsiz > 0) { *dst++ = 0; dstsiz--; }
1306         return ReadErrorFlag ? ERROR : 0;
1307 }
1308