1 /*
2  * $Id: do_socket.c,v 1.2 2001/06/14 18:16:14 ura Exp $
3  */
4 
5 /*
6  * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
7  * This file is part of FreeWnn.
8  *
9  * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
10  * Copyright 1991, 1992 by Massachusetts Institute of Technology
11  *
12  * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2, or (at your option)
17  * any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with GNU Emacs; see the file COPYING.  If not, write to the
26  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  *
28  * Commentary:
29  *
30  * Change log:
31  *
32  * Last modified date: 8,Feb.1999
33  *
34  * Code:
35  *
36  */
37 
38 #include <stdio.h>
39 #include <errno.h>
40 #include <X11/Xlib.h>
41 #ifdef  X11R4
42 #define NEED_EVENTS     1
43 #include <X11/Xlibos.h>
44 #else /* X11R4 */
45 #include "Xlibnet.h"
46 
47 #ifndef X11R5
48 /* followings were included in Xlibnet.h, but none in X11R6 */
49 #include <netinet/in.h>
50 #include <sys/ioctl.h>
51 #include <netdb.h>
52 /* end */
53 #endif /* !X11R5 */
54 
55 #endif /* X11R4 */
56 #include <X11/Xos.h>
57 #if defined(TCPCONN) || defined(UNIXCONN)
58 #include <sys/socket.h>
59 #endif /* defined(TCPCONN) || defined(UNIXCONN) */
60 #ifdef  TCPCONN
61 #define XIM_PORT_IN    0x9495
62 #endif /* TCPCONN */
63 
64 #ifdef  UNIXCONN
65 #include <sys/un.h>
66 #ifndef XIM_UNIX_PATH
67 #define XIM_UNIX_PATH   "/tmp/.X11-unix/XIM"
68 #endif /* XIM_UNIX_PATH */
69 #endif /* UNIXCONN */
70 
71 #include "sdefine.h"
72 #include "commonhd.h"
73 #include "xim.h"
74 #include "proto.h"
75 #include "ext.h"
76 
77 #if defined(XJPLIB) && defined(XJPLIB_DIRECT)
78 #define MAX_ACCEPT      5
79 #else
80 #define MAX_ACCEPT      3
81 #endif /* defined(XJPLIB) && defined(XJPLIB_DIRECT) */
82 
83 #define UNIX_ACPT       0
84 #define INET_ACPT       1
85 #define SERVER_ACPT     2
86 
87 char my_byteOrder;
88 
89 XIMCmblk accept_blk[MAX_ACCEPT];
90 XIMCmblk *cblk;
91 XIMCmblk *cur_cblk = NULL;
92 
93 int *all_socks;
94 int *ready_socks;
95 static int *dummy1_socks, *dummy2_socks;
96 static int sel_width;
97 
98 static int nofile;
99 int max_client;
100 int cur_sock = -1;
101 static int rest_length = 0;
102 
103 #ifndef SEND_BUF_SZ
104 #define SEND_BUF_SZ     8192
105 #endif
106 #ifndef RECV_BUF_SZ
107 #define RECV_BUF_SZ     8192
108 #endif
109 
110 static char send_buf[SEND_BUF_SZ];
111 static int sp = 0;
112 static char recv_buf[RECV_BUF_SZ];
113 static int rp = 0;
114 static int rc = 0;
115 
116 #define BINTSIZE        (sizeof(int)*8)
117 #define sock_set(array,pos)     (array[pos/BINTSIZE] |= (1<<(pos%BINTSIZE)))
118 #define sock_clr(array,pos)     (array[pos/BINTSIZE] &= ~(1<<(pos%BINTSIZE)))
119 #define sock_tst(array,pos)     (array[pos/BINTSIZE] & (1<<(pos%BINTSIZE)))
120 
121 #define _Read(fd, data, size)   read((fd), (data), (size))
122 #define _Write(fd, data, size)  write((fd), (data), (size))
123 
124 static void
_Error()125 _Error ()
126 {
127 #ifndef X11R5
128   XimError (cur_sock);
129 #endif
130   close_socket (cur_sock);
131 }
132 
133 static int
_Writen(num)134 _Writen (num)
135      register int num;
136 {
137   register int i, ret;
138 
139   if (cur_sock < 0)
140     return (-1);
141   for (i = 0; i < num;)
142     {
143       ret = _Write (cur_sock, &send_buf[i], num - i);
144       if (ret <= 0)
145         {
146           _Error ();
147           return (-1);
148         }
149       i += ret;
150     }
151   return (0);
152 }
153 
154 int
_Send_Flush()155 _Send_Flush ()
156 {
157   if (sp == 0)
158     {
159       return (0);
160     }
161   if (_Writen (sp) == -1)
162     {
163       sp = 0;
164       return (-1);
165     }
166   sp = 0;
167   return (0);
168 }
169 
170 #define my_bcopy(src, dst, size) {register int i; \
171         register unsigned char *ppp, *qqq;\
172         for(i=size,ppp=(unsigned char*)src,qqq=(unsigned char*)dst;i>0;i--) \
173         *qqq++=*ppp++; \
174 }
175 
176 int
_WriteToClient(p,num)177 _WriteToClient (p, num)
178      register char *p;
179      register int num;
180 {
181   if (num <= 0)
182     return (0);
183   for (;;)
184     {
185       if ((sp + num) > SEND_BUF_SZ)
186         {
187           my_bcopy (p, &send_buf[sp], SEND_BUF_SZ - sp);
188           if (_Writen (SEND_BUF_SZ) == -1)
189             {
190               sp = 0;
191               return (-1);
192             }
193           num -= (SEND_BUF_SZ - sp);
194           p += (SEND_BUF_SZ - sp);
195           sp = 0;
196         }
197       else
198         {
199           my_bcopy (p, &send_buf[sp], num);
200           sp += num;
201           return (0);
202         }
203     }
204 }
205 
206 int
_ReadFromClient(p,num)207 _ReadFromClient (p, num)
208      register char *p;
209      register int num;
210 {
211   register char *x = p;
212 
213   if (num <= 0)
214     return (0);
215   for (;;)
216     {
217       if (num > rc)
218         {
219           if (rc > 0)
220             {
221               my_bcopy (&recv_buf[rp], x, rc);
222               x += rc;
223               num -= rc;
224               rc = 0;
225             }
226           rc = _Read (cur_sock, recv_buf, RECV_BUF_SZ);
227           if (rc <= 0)
228             {
229               _Error ();
230               rp = 0;
231               rc = 0;
232               return (-1);
233             }
234           rp = 0;
235         }
236       else
237         {
238           my_bcopy (&recv_buf[rp], x, num);
239           rc -= num;
240           rp += num;
241           return (0);
242         }
243     }
244 }
245 
246 static int
init_net_area()247 init_net_area ()
248 {
249   register int sel_w;
250   register int sel_bwidth;
251   register char *p;
252 
253   nofile = OPEN_MAX;
254   sel_w = (nofile - 1) / BINTSIZE + 1;
255   sel_width = sel_w * sizeof (int);
256   sel_bwidth = sel_width * 8;
257   max_client = OPEN_MAX - MAX_ACCEPT;
258 
259   p = (char *) Malloc ((4 * sel_width) + (max_client * sizeof (XIMCmblk)));
260   if (!p)
261     {
262       malloc_error ("allocation of dates for socket");
263       return (-1);
264     }
265   all_socks = (int *) p;
266   p += sel_width;
267   ready_socks = (int *) p;
268   p += sel_width;
269   dummy1_socks = (int *) p;
270   p += sel_width;
271   dummy2_socks = (int *) p;
272   p += sel_width;
273   bzero (all_socks, sel_width);
274   bzero (ready_socks, sel_width);
275 
276   cblk = (XIMCmblk *) p;
277   bzero ((char *) cblk, max_client * sizeof (XIMCmblk));
278   bzero ((char *) accept_blk, MAX_ACCEPT * sizeof (XIMCmblk));
279 #ifdef  UNIXCONN
280   accept_blk[UNIX_ACPT].sd = -1;
281 #endif /* UNIXCONN */
282 #ifdef  TCPCONN
283   accept_blk[INET_ACPT].sd = -1;
284 #endif /* TCPCONN */
285   return (0);
286 }
287 
288 #ifdef  UNIXCONN
289 static int
init_net_un()290 init_net_un ()
291 {
292   int so;
293   struct sockaddr_un saddr_un;
294   extern int unlink (), socket (), bind (), shutdown (), listen ();
295 
296   unlink (XIM_UNIX_PATH);
297   saddr_un.sun_family = AF_UNIX;
298   strcpy (saddr_un.sun_path, XIM_UNIX_PATH);
299 
300   if ((so = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
301     {
302       return (-1);
303     }
304   if (bind (so, (struct sockaddr *) &saddr_un, strlen (saddr_un.sun_path) + 2) < 0)
305     {
306       shutdown (so, 2);
307       return (-1);
308     }
309   if (listen (so, 5) < 0)
310     {
311       shutdown (so, 2);
312       return (-1);
313     }
314   accept_blk[UNIX_ACPT].sd = so;
315   sock_set (all_socks, so);
316   return (0);
317 }
318 #endif /* UNIXCONN */
319 
320 #ifdef  TCPCONN
321 static short
init_net_in()322 init_net_in ()
323 {
324   int so;
325   struct servent *sp;
326   struct sockaddr_in saddr_in;
327   unsigned short port;
328 #ifndef SOLARIS
329   int on = 1;
330 #else /* SOLARIS */
331   int on = 0;
332 #endif /* SOLARIS */
333   int i, ok = 0;
334   extern int setsockopt ();
335 
336   if ((sp = getservbyname ("xim", "tcp")) == NULL)
337     {
338       port = XIM_PORT_IN;
339     }
340   else
341     {
342       port = ntohs (sp->s_port);
343     }
344   saddr_in.sin_family = AF_INET;
345   saddr_in.sin_port = htons (port);
346   saddr_in.sin_addr.s_addr = htonl (INADDR_ANY);
347 
348   for (i = 0; i < MAX_PORT_NUMBER; i++)
349     {
350       if ((so = socket (AF_INET, SOCK_STREAM, 0)) < 0)
351         {
352           return ((short) -1);
353         }
354       setsockopt (so, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (int));
355       if (bind (so, (struct sockaddr *) &saddr_in, sizeof (struct sockaddr_in)) == 0)
356         {
357           ok = 1;
358           break;
359         }
360       shutdown (so, 2);
361       saddr_in.sin_port = htons (++port);
362     }
363   if (ok == 0)
364     {
365       return ((short) -1);
366     }
367   if (listen (so, 5) < 0)
368     {
369       shutdown (so, 2);
370       return ((short) -1);
371     }
372   accept_blk[INET_ACPT].sd = so;
373   sock_set (all_socks, so);
374   return ((short) port);
375 }
376 #endif /* TCPCONN */
377 
378 short
init_net(fd,displayname)379 init_net (fd, displayname)
380      int fd;
381      char *displayname;
382 {
383   short port = -1;
384   int indian = 1;
385 
386   if (*(char *) &indian)
387     {
388       my_byteOrder = 'l';
389     }
390   else
391     {
392       my_byteOrder = 'B';
393     }
394   if (init_net_area () < 0)
395     return (port);
396 #ifdef  UNIXCONN
397   if (!strncmp (displayname, "unix:", 5) || !strncmp (displayname, ":", 1))
398     {
399       if (init_net_un () == (short) -1)
400         {
401           print_out ("Could not open UNIX domain socket.");
402         }
403     }
404 #endif /* UNIXCONN */
405 #ifdef  TCPCONN
406   if ((port = init_net_in ()) == (short) -1)
407     {
408       print_out ("Could not open INET domain socket.");
409       return (port);
410     }
411   accept_blk[SERVER_ACPT].sd = fd;
412   sock_set (all_socks, fd);
413 #endif /* TCPCONN */
414 #if defined(XJPLIB) && defined(XJPLIB_DIRECT)
415   XJp_init_net ();
416 #endif /* defined(XJPLIB) && defined(XJPLIB_DIRECT) */
417   return (port);
418 }
419 
420 void
close_net()421 close_net ()
422 {
423   int i;
424   int trueFlag = 1;
425 #ifdef  UNIXCONN
426   struct sockaddr_un addr_un;
427 #endif /* UNIXCONN */
428 #ifdef  TCPCONN
429   struct sockaddr_in addr_in;
430 #endif /* TCPCONN */
431 #if defined(UNIXCONN) || defined(TCPCONN)
432   int addrlen;
433   extern int accept (), close ();
434 #endif
435 
436 #ifdef  UNIXCONN
437   if (accept_blk[UNIX_ACPT].sd != -1)
438     {
439 #ifndef SOLARIS
440 #if defined(FIONBIO)
441       ioctl (accept_blk[UNIX_ACPT].sd, FIONBIO, &trueFlag);
442 #endif
443 #else /* !SOLARIS */
444       fcntl (accept_blk[UNIX_ACPT].sd, F_SETFL, F_UNLCK);
445 #endif /* !SOLARIS */
446       for (;;)
447         {
448           addrlen = sizeof (addr_un);
449           if (accept (accept_blk[UNIX_ACPT].sd, (struct sockaddr *) &addr_un, &addrlen) < 0)
450             break;
451         }
452       shutdown (accept_blk[UNIX_ACPT].sd, 2);
453       close (accept_blk[UNIX_ACPT].sd);
454     }
455 #endif /* UNIXCONN */
456 
457 #ifdef  TCPCONN
458   if (accept_blk[INET_ACPT].sd != -1)
459     {
460 #ifndef SOLARIS
461 #if defined(FIONBIO)
462       ioctl (accept_blk[INET_ACPT].sd, FIONBIO, &trueFlag);
463 #endif
464 #else /* !SOLARIS */
465       fcntl (accept_blk[INET_ACPT].sd, F_SETFL, F_UNLCK);
466 #endif /* !SOLARIS */
467       for (;;)
468         {
469           addrlen = sizeof (addr_in);
470           if (accept (accept_blk[INET_ACPT].sd, (struct sockaddr *) &addr_in, &addrlen) < 0)
471             break;
472         }
473       shutdown (accept_blk[INET_ACPT].sd, 2);
474       close (accept_blk[INET_ACPT].sd);
475     }
476 #endif /* TCPCONN */
477 #if defined(XJPLIB) && defined(XJPLIB_DIRECT)
478   XJp_close_net ();
479 #endif /* defined(XJPLIB) && defined(XJPLIB_DIRECT) */
480 
481   for (i = 0; i < max_client; i++)
482     {
483       if (cblk[i].use)
484         {
485           shutdown (cblk[i].sd, 2);
486           close (cblk[i].sd);
487         }
488     }
489 }
490 
491 #if defined(UNIXCONN) || defined(TCPCONN)
492 static int
get_screen_number(p)493 get_screen_number (p)
494      char *p;
495 {
496   register char *s;
497 
498   if (!(s = index (p, ':')))
499     return (-1);
500   if (!(s = index (s, '.')))
501     return (-1);
502   if (!*(++s))
503     return (-1);
504   return (atoi (s));
505 }
506 
507 #if defined(X11R5) || defined(BC_X11R5)
508 static void
new_cl_sock(b)509 new_cl_sock (b)
510      XIMCmblk *b;
511 {
512   char displaybuf[256];
513   ximConnClient client;
514   ximNormalReply reply;
515   int len;
516 
517   if (_ReadFromClient (&client, sz_ximConnClient) == -1)
518     return;
519   if (my_byteOrder != client.byteOrder)
520     {
521       b->byteOrder = True;
522     }
523   else
524     {
525       b->byteOrder = False;
526     }
527   if (need_byteswap () == True)
528     {
529       client.length = byteswap_s (client.length);
530     }
531   if (_ReadFromClient (displaybuf, client.length) == -1)
532     return;
533   displaybuf[client.length] = '\0';
534   if ((len = strlen (displaybuf)) > 0)
535     {
536       b->screen = get_screen_number (displaybuf);
537     }
538   else
539     {
540       b->screen = -1;
541     }
542   reply.state = 0;
543   if (need_byteswap () == True)
544     {
545       byteswap_NormalReply (&reply);
546     }
547   if (_WriteToClient (&reply, sz_ximNormalReply) == -1)
548     return;
549   if (_Send_Flush () == -1)
550     return;
551 }
552 #endif /* defined(X11R5) || defined(BC_X11R5) */
553 
554 #ifndef X11R5
555 static void
xim_new_cl_sock(b)556 xim_new_cl_sock (b)
557      XIMCmblk *b;
558 {
559 #ifdef BC_X11R5
560   extern int ximr5_client;
561   b->ximr5 = ximr5_client;
562   if (b->ximr5)
563     {
564       new_cl_sock (b);
565       return;
566     }
567   ximr5_client = 1;
568 #endif /* BC_X11R5 */
569   /* nothing to do, all are done in XimPreConnect() */
570 }
571 #endif /* !X11R5 */
572 
573 #endif /* defined(UNIXCONN) || defined(TCPCONN) */
574 
575 static int
new_client_acpt(fd)576 new_client_acpt (fd)
577      int fd;
578 {
579 #ifdef  UNIXCONN
580   struct sockaddr_un addr_un;
581 #endif /* UNIXCONN */
582 #ifdef  TCPCONN
583   struct sockaddr_in addr_in;
584 #endif /* TCPCONN */
585 #if defined(UNIXCONN) || defined(TCPCONN)
586   register int i;
587   int addrlen;
588 #endif
589 
590 #ifdef  UNIXCONN
591   if (accept_blk[UNIX_ACPT].sd != -1)
592     {
593       if (fd == accept_blk[UNIX_ACPT].sd)
594         {
595           for (i = 0; i < max_client; i++)
596             {
597               if (cblk[i].use == 0)
598                 {
599                   addrlen = sizeof (addr_un);
600                   if ((cblk[i].sd = accept (fd, (struct sockaddr *) &addr_un, &addrlen)) < 0)
601                     {
602                       return (-1);
603                     }
604                   cur_cblk = &cblk[i];
605                   cur_cblk->use = 1;
606 #if defined(XJPLIB) && defined(XJPLIB_DIRECT)
607                   cur_cblk->xjp = 0;
608 #endif /* defined(XJPLIB) && defined(XJPLIB_DIRECT) */
609                   cur_sock = cur_cblk->sd;
610                   sock_set (all_socks, cur_sock);
611 #ifdef X11R5
612                   new_cl_sock (cur_cblk);
613 #else
614                   xim_new_cl_sock (cur_cblk);
615 #endif /* X11R5 */
616                   return (0);
617                 }
618             }
619         }
620     }
621 #endif /* UNIXCONN */
622 #ifdef  TCPCONN
623   if (fd == accept_blk[INET_ACPT].sd)
624     {
625       for (i = 0; i < max_client; i++)
626         {
627           if (cblk[i].use == 0)
628             {
629               addrlen = sizeof (addr_in);
630               if ((cblk[i].sd = accept (fd, (struct sockaddr *) &addr_in, &addrlen)) < 0)
631                 {
632                   return (-1);
633                 }
634               cur_cblk = &cblk[i];
635               cur_cblk->use = 1;
636 #if defined(XJPLIB) && defined(XJPLIB_DIRECT)
637               cur_cblk->xjp = 0;
638 #endif /* defined(XJPLIB) && defined(XJPLIB_DIRECT) */
639               cur_sock = cur_cblk->sd;
640               sock_set (all_socks, cur_sock);
641 #ifdef X11R5
642               new_cl_sock (cur_cblk);
643 #else
644               xim_new_cl_sock (cur_cblk);
645 #endif /* X11R5 */
646               break;
647             }
648         }
649     }
650 #endif /* TCPCONN */
651   return (0);
652 }
653 
654 int
wait_for_socket()655 wait_for_socket ()
656 {
657   register int i;
658   int n, ret;
659   extern int errno;
660   extern int select ();
661 
662   /*
663    * If recv_buf has some data, return with as cur_sock get data
664    */
665   if (cur_sock != -1 && rc > 0)
666     {
667 #if defined(XJPLIB) && defined(XJPLIB_DIRECT)
668       if (cur_cblk && cur_cblk->xjp)
669         return (XJP_DIRECT_TYPE);
670 #endif /* defined(XJPLIB) && defined(XJPLIB_DIRECT) */
671 #ifdef X11R5
672       return (REQUEST_TYPE);
673 #else
674 #ifdef BC_X11R5
675       if (cur_cblk && cur_cblk->ximr5)
676         return REQUEST_TYPE;
677       else
678 #endif /* BC_X11R5 */
679         return REQUEST_TYPE_XIM;
680 #endif /* X11R5 */
681     }
682   if (!*ready_socks)
683     {
684       my_bcopy (all_socks, ready_socks, sel_width);
685       bzero (dummy1_socks, sel_width);
686       bzero (dummy2_socks, sel_width);
687 
688       if ((n = select (nofile, ready_socks, dummy1_socks, dummy2_socks, (struct timeval *) NULL)) == -1)
689         {
690           if (errno != EINTR)
691             do_end ();
692           else
693             {
694               bzero (ready_socks, sel_width);
695               return (0);
696             }
697         }
698     }
699 #ifdef  UNIXCONN
700   if (accept_blk[UNIX_ACPT].sd != -1)
701     {
702       if (sock_tst (ready_socks, accept_blk[UNIX_ACPT].sd))
703         {
704           sock_clr (ready_socks, accept_blk[UNIX_ACPT].sd);
705           cur_cblk = NULL;
706           cur_sock = -1;
707           new_client_acpt (accept_blk[UNIX_ACPT].sd);
708           return (0);
709         }
710     }
711 #endif /* UNIXCONN */
712 #ifdef  TCPCONN
713   if (accept_blk[INET_ACPT].sd != -1)
714     {
715       if (sock_tst (ready_socks, accept_blk[INET_ACPT].sd))
716         {
717           sock_clr (ready_socks, accept_blk[INET_ACPT].sd);
718           cur_cblk = NULL;
719           cur_sock = -1;
720           new_client_acpt (accept_blk[INET_ACPT].sd);
721           return (0);
722         }
723     }
724 #endif /* TCPCONN */
725   if (sock_tst (ready_socks, accept_blk[SERVER_ACPT].sd))
726     {
727       sock_clr (ready_socks, accept_blk[SERVER_ACPT].sd);
728       cur_cblk = NULL;
729       cur_sock = -1;
730       return (XEVENT_TYPE);
731     }
732   else
733     {
734       if (cur_sock != -1 && sock_tst (ready_socks, cur_sock))
735         {
736           sock_clr (ready_socks, cur_sock);
737 #if defined(XJPLIB) && defined(XJPLIB_DIRECT)
738           if (cur_cblk && cur_cblk->xjp)
739             return (XJP_DIRECT_TYPE);
740 #endif /* defined(XJPLIB) && defined(XJPLIB_DIRECT) */
741 #ifdef X11R5
742           return (REQUEST_TYPE);
743 #else
744 #ifdef BC_X11R5
745           if (cur_cblk && cur_cblk->ximr5)
746             return REQUEST_TYPE;
747           else
748 #endif /* BC_X11R5 */
749             return REQUEST_TYPE_XIM;
750 #endif /* X11R5 */
751         }
752       cur_cblk = NULL;
753       cur_sock = -1;
754       for (i = 0; i < max_client; i++)
755         {
756           if (cblk[i].use && sock_tst (ready_socks, cblk[i].sd))
757             {
758               sock_clr (ready_socks, cblk[i].sd);
759               cur_cblk = &cblk[i];
760               cur_sock = cur_cblk->sd;
761 #if defined(XJPLIB) && defined(XJPLIB_DIRECT)
762               if (cur_cblk && cur_cblk->xjp)
763                 return (XJP_DIRECT_TYPE);
764 #endif /* defined(XJPLIB) && defined(XJPLIB_DIRECT) */
765 #ifdef X11R5
766               return (REQUEST_TYPE);
767 #else
768 #ifdef BC_X11R5
769               if (cur_cblk && cur_cblk->ximr5)
770                 return REQUEST_TYPE;
771               else
772 #endif /* BC_X11R5 */
773                 return REQUEST_TYPE_XIM;
774 #endif /* X11R5 */
775             }
776         }
777 #if defined(XJPLIB) && defined(XJPLIB_DIRECT)
778       if (ret = XJp_wait_for_socket ())
779         return (0);
780 #endif /* defined(XJPLIB) && defined(XJPLIB_DIRECT) */
781       return (0);
782     }
783 }
784 
785 void
close_socket(fd)786 close_socket (fd)
787      int fd;
788 {
789   int i;
790   for (i = 0; i < max_client; i++)
791     {
792       if (fd == cblk[i].sd && cblk[i].use == 1)
793         {
794           cblk[i].use = 0;
795           shutdown (cblk[i].sd, 2);
796           sock_clr (all_socks, cblk[i].sd);
797           close (cblk[i].sd);
798 #if defined(XJPLIB) && defined(XJPLIB_DIRECT)
799           if (cblk[i].xjp)
800             XJp_destroy_for_sock (cblk[i].sd);
801           else
802 #endif /* defined(XJPLIB) && defined(XJPLIB_DIRECT) */
803             destroy_for_sock (cblk[i].sd);
804           if (cur_sock == fd)
805             cur_sock = -1;
806           return;
807         }
808     }
809 }
810 
811 int
get_cur_sock()812 get_cur_sock ()
813 {
814   return (cur_sock);
815 }
816 
817 int
get_rest_len()818 get_rest_len ()
819 {
820   return (rest_length);
821 }
822 
823 int
read_requestheader()824 read_requestheader ()
825 {
826   ximRequestHeader request_header;
827 
828   if (_ReadFromClient (&request_header, sz_ximRequestHeader) == -1)
829     {
830       return (-1);
831     }
832   else
833     {
834       if (need_byteswap () == True)
835         request_header.length = byteswap_s (request_header.length);
836       rest_length = request_header.length - sz_ximRequestHeader;
837       return (request_header.reqType);
838     }
839 }
840 
841 int
read_strings(p,p_len,r_len)842 read_strings (p, p_len, r_len)
843      char **p;
844      int *p_len, r_len;
845 {
846   register int len;
847   register char *ptr;
848   char tmp;
849 
850   if (r_len > 0)
851     {
852       if (*p_len <= r_len)
853         {
854           len = r_len + 1;
855           if (!(ptr = Malloc (len)))
856             {
857               malloc_error ("allocation of client data");
858               for (; r_len > 0; r_len--)
859                 {               /* read data in dummy */
860                   if (_ReadFromClient (&tmp, 1) == 1)
861                     return (-1);
862                 }
863               return (-2);
864             }
865           if (*p)
866             Free (*p);
867           *p = ptr;
868           *p_len = len;
869         }
870       if (_ReadFromClient (*p, r_len) == 1)
871         return (-1);
872       p[0][r_len] = '\0';
873     }
874   else
875     {
876       if (*p_len > 0)
877         **p = '\0';
878     }
879   return (0);
880 }
881 
882 /* *INDENT-OFF* */
883 Bool
need_byteswap()884 need_byteswap ()
885 /* *INDENT-ON* */
886 
887 {
888   if (!cur_cblk)
889     return (False);
890   return (cur_cblk->byteOrder);
891 }
892 
893 int
get_client_screen()894 get_client_screen ()
895 {
896   if (!cur_cblk)
897     return (-1);
898   return (cur_cblk->screen);
899 }
900