📄 xstreams.c
字号:
/* * $XConsortium: Xstreams.c,v 1.26 91/07/23 12:15:13 rws Exp $ */#ifdef STREAMSCONN/* * Copyright 1991 USL, Inc. * Copyright 1991 Massachusetts Institute of Technology * Copyright 1988, 1989 AT&T, Inc. * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of * AT&T, USL, or MIT not be used in advertising or publicity * pertaining to distribution of the software without specific, * written prior permission. AT&T, USL, and MIT make no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. * * AT&T, USL, AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL AT&T, USL, OR MIT BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */#define _USHORT_H /* prevent conflicts between BSD sys/types.h and interlan/il_types.h */#define NEED_REPLIES#include <X11/Xlibint.h>#include <X11/Xos.h>#include "Xlibnet.h"#include <X11/Xauth.h>#include <X11/Xproto.h>#include <stdio.h>#include <tiuser.h> /* TLI user defs */#include <sys/param.h>#include <sys/utsname.h>#include <signal.h>#include <sys/stat.h>#include <errno.h>#include <sys/stropts.h>extern int errno;extern char *sys_errlist[];#ifdef SVR4#include <netdir.h>#include <netconfig.h>#ifndef __STDC__/* buggy SVR4 include file */char *setnetpath();struct netconfig *getnetconfigent();struct netconfig *getnetpath();int endnetpath();#endif#endif#include "Xstreams.h"#ifdef DEBUG#define PRMSG(x,a,b) fprintf(stderr, x,a,b); fflush(stderr)#else#define PRMSG(x,a,b)#endif#define LISTEN_QUE_SIZE 8 /* maximum # of connections for gen. listen */#define CLEAR 1/* * Ridiculously high value for maximum number of connects per stream. * Transport Provider will determine actual maximum to be used. */#define MAXCONNECTIONS 100 /* maximum # of connections for gen. listen */#define MAXLEN 80#define BUFFERSIZE 2048#define NOBUFFERNEEDED 512typedef struct { char *DataBuffer; int FirstBytePtr; int LastBytePtr; } InputBuffer;#ifdef SVR4InputBuffer _XsInputBuffer[MAXCONNECTIONS] = {NULL};#else#ifndef NOFILES_MAX#define NOFILES_MAX 128#endifInputBuffer _XsInputBuffer[NOFILES_MAX] = {NULL};#endif /* SVR4*/static char *ptmx = "/dev/ptmx";static char *dispno = "0";#ifdef attextern char *GetXWINHome ();#endifstatic char _dispno[MAX_DISP_DIGITS];extern int t_errno;static char ** addheader();static char ** addtliheader();static struct t_bind bind_ret, bind_req;static struct t_call call;static char ret_buf[MAXLEN], req_buf[MAXLEN], call_buf[MAXLEN];static int named = 0; /* not using named streams connection *//*** The following stubs functions should be kept to keep the** att libX11_s library (Shared library) happy. In the early versions** of XWIN, these functions were used.*/#ifdef USL_COMPATvoid CloseTcpStream () {}void WriteTcpStream () {}void ReadTcpStream () {}void CallTcpServer () {}void ConnectTcpClient () {}void SetupTcpStream () {}int CloseTliStream(){}int WriteTliStream(){}int ReadTliStream(){} int CloseLocalStream(){} int WriteLocalStream(){} #endif /* USL_COMPAT */#ifdef USL_SHARELIB#define fopen (*_libX_fopen)extern FILE *fopen();#define t_bind (*_libX_t_bind)extern int t_bind();#undef t_bind#define _iob (*_libX__iob)extern FILE _iob[];#endif /* USL_SHARELIB */extern int t_errno;#ifdef SYSV#define SIGNAL_T int#else#define SIGNAL_T void#endiftypedef SIGNAL_T (*PFV)();extern PFV signal();#define SUCCESS "1"extern char _XsTypeOfStream[];extern Xstream _XsStream[];static networkInfo Network;static int NameServer = -1;static int CallTheNameServer();static void checkNewEvent();static int OpenVirtualCircuit();static void LookForEvents();static int CheckListenQue();static void ClearCall(), RemoveCall();static int OpenLocalServer();static int OpenNamedServer();static int nameserver();/* Routines everybody shares */_XsErrorCall(){ fprintf(stderr, "ErrorCall: invalid or unsupported subroutine call\n"); return(-1);}/* * Following are some general queueing routines. The call list head contains * a pointer to the head of the queue and to the tail of the queue. Normally, * calls are added to the tail and removed from the head to ensure they are * processed in the order received, however, because of the possible interruption * of an acceptance with the resulting requeueing, it is necessary to have a * way to do a "priority queueing" which inserts at the head of the queue for * immediate processing *//* * Que: * * add calls to tail of queue */static voidQue(head, lc, flag)register struct listenQue *head;register struct listenCall *lc;char flag;{ if(flag == CLEAR) ClearCall(lc->CurrentCall); if (head->QueTail == (struct listenCall *) NULL) { lc->NextCall = (struct listenCall *) NULL; head->QueHead = head->QueTail = lc; } else { lc->NextCall = head->QueTail->NextCall; head->QueTail->NextCall = lc; head->QueTail = lc; }}/* * pQue: * * priority queuer, add calls to head of queue */static voidpQue(head, lc)register struct listenQue *head;register struct listenCall *lc;{ if (head->QueHead == (struct listenCall *) NULL) { lc->NextCall = (struct listenCall *) NULL; head->QueHead = head->QueTail = lc; } else { lc->NextCall = head->QueHead; head->QueHead = lc; }}/* * dequeue: * * remove a call from the head of queue */static struct listenCall *deQue(head)register struct listenQue *head;{ register struct listenCall *ret; if (head->QueHead == (struct listenCall *) NULL){ PRMSG("Fatal error. Queue is empty (shouldn't happen)\n",0,0); exit(1); } ret = head->QueHead; head->QueHead = ret->NextCall; if (head->QueHead == (struct listenCall *) NULL) head->QueTail = (struct listenCall *) NULL; return(ret);}/* Routines for handling local Named streams */#ifdef SVR4_XsSetupNamedStream(display, stype)char * display;char *stype;{ int munix, sunix; char * slave; char buf[MAX_AUTO_BUF_LEN]; int type = X_NAMED_STREAM; int fld[2], ret; struct stat sbuf; PRMSG("Calling SetupNamedStream()\n",0,0);/* if file not there create it, depends on SetupLocalStream to decide whether server already running , no checking is done here */ munix = atoi(display); sprintf(buf, "%s.%d", NAMED_LISTENER, munix); PRMSG("Calling SetupNamedStream()-(%s)\n",buf,0); if(stat(buf, &sbuf)!= 0) { if(errno ==ENOENT) { if(( munix = creat(buf, (mode_t) 0666) ) == -1) { PRMSG(" Can't create: %s\n", buf,0); return(-1); } close(munix); if(chmod(buf,(mode_t) 0666)<0) { PRMSG( "Cannot chmod %s", buf,0); perror(" "); return(-1); } } else { PRMSG("stat err=%d,-%s\n", errno, sys_errlist[errno]); return(-1); } } if(pipe(fld) != 0) { fprintf(stderr,"pipe failed, errno=%d:%s\n", errno, sys_errlist[errno]); return(-1); } if((ret=ioctl(fld[0], I_PUSH,"connld")) != 0) { fprintf(stderr,"ioctl error:%s\n", sys_errlist[errno]); return(-1); } if((fattach(fld[0], buf)) !=0) { fprintf(stderr,"fattach failed:%s\n", sys_errlist[errno]); return(-1); } _XsTypeOfStream[fld[1]] = type; NetworkInfo->_nnets++; return(fld[1]);}/* Enhanced Application Compatibility Support */int_XsSetupSpStream (display, stype)char *display;char *stype;{}int_XsConnectSpClient (connmaster) /* Add connection to new slave */ int connmaster; /* Master request connection */{}/* End Enhanced Application Compatibility Support */#endif /* SVR4 *//* Routines for handling local streams (streams-pipes) */_XsSetupLocalStream(display, stype)char * display;char *stype;{ int munix, sunix; char * slave; char buf[MAX_AUTO_BUF_LEN]; int type = X_LOCAL_STREAM; int nameserver(); PRMSG("Calling SetupLocalStream()\n",0,0); SetupNetworkInfo(); dispno = display; NetworkInfo->_nnets = NetworkInfo->_npeers = 0; NetworkInfo->_peer = NULL; NetworkInfo->_peerlen = NULL;#ifdef SVR4 NetworkInfo->_net[0] = (struct netconfig *) 0;#else NetworkInfo->_net[0] = (char *) 0;#endif NetworkInfo->_nnets++; munix = atoi(display);/* if(munix != 0){ fprintf(stderr, "Only display # 0 can be used on this server\n"); return(-1); }*/ sprintf(buf, "%s.%d", LOCAL_LISTENER, munix);/* if(open(buf, O_RDWR) >= 0){ fprintf(stderr, "Server is already running\n"); return(-1); }*/ if( (munix = open(ptmx, O_RDWR)) < 0 ){ fprintf(stderr,"Cannot open %s", ptmx); perror(" "); return(-1); } grantpt(munix); unlockpt(munix); if(unlink(buf) < 0 && errno != ENOENT){ fprintf(stderr, "Cannot unlink %s", buf); perror(" "); return(-1); } if(! (slave = (char *) ptsname(munix))) { close(munix); perror("Cannot get slave pt-name"); return(-1); } if( link(slave, buf) <0 ){ fprintf(stderr, "Cannot link %s to %s", slave, buf); perror(" "); return(-1); } if( chmod(buf, 0666) < 0){ close(munix); fprintf(stderr, "Cannot chmod %s", buf); perror(" "); return(-1); } sunix = open(buf, O_RDWR); if(sunix < 0){ fprintf(stderr, "Cannot open %s", buf); perror(" "); close(munix); return(-1); } _XsTypeOfStream[munix] = type; _XsTypeOfStream[sunix] = CLOSED_STREAM; return(munix);}_XsConnectLocalClient(ufd, MoreConnections)int ufd;char * MoreConnections;{ int fd; int read_in; unsigned char length; char buf[MAX_AUTO_BUF_LEN];#ifdef SVR4 struct strrecvfd str;#endif PRMSG("Calling ConnectLocalClient(%d)\n", ufd,0);/* MoreConnections is set to zero because if any more connections are underway * select() will return immediately. It is nicer if we can process all connections * that exist the way we handle TLI connections by setting MoreConnections. * May be I will end up doing it later. */ *MoreConnections = 0;#ifdef SVR4 if( _XsTypeOfStream[ufd] == X_NAMED_STREAM) { PRMSG("Calling ConnectLocalClient(%d) - thru named streams\n", ufd,0); if (ioctl(ufd, I_RECVFD, &str) < 0) { fprintf(stderr,"I_RECVFD failed\n"); return(-1); } _XsTypeOfStream[str.fd] = _XsTypeOfStream[ufd]; PRMSG("ConnectNamedClient(%d) return success\n", str.fd,0); return(str.fd); }/* Enhanced Application Compatibility Support *//* End Enhanced Application Compatibility Support */#endif /* SVR4 */ PRMSG("Calling ConnectLocalClient(%d) - thru psuedo tty\n", ufd,0); if( (read_in = read(ufd, &length, 1)) <= 0 ){ if( !read_in ) /* client closed fd */ perror("0 bytes read"); else perror("Error in reading the local connection msg length"); return(-1); } if( (read_in = read(ufd, buf, length)) <= 0 ){ if( !read_in ) /* client closed fd */ perror("0 bytes read"); else perror("Error in reading the local connection slave name"); return(-1); } buf[ length ] = '\0'; if( (fd = open(buf,O_RDWR)) < 0 ){ strcat(buf," open fail, clientfd");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -