int main(int argc, char *argv[]) { char buf[200]; APIRET rc; ULONG action,arg,argsz, nread; HFILE fd; /* open device */ rc = DosOpen((PSZ)"\\dev\\console$", &fd, &action, 0, FILE_NORMAL, FILE_OPEN, OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYNONE, (PEAOP2)NULL); if (rc) { fprintf(stderr, "!!! Cannot open console device, rc=%d\n", rc); fputs("Probably the XF86SUP device driver was not properly installed.\n", stderr); exit(1); } /* grab the console */ arg = 1; rc = DosDevIOCtl(fd, XFREE86_CONS, CONS_TIOCCONS, &arg, sizeof(arg),&argsz, NULL, 0, NULL); if (rc) { fprintf(stderr,"!!! Cannot grab console, status = %d\n",rc); fputs("Possibly another process currently owns the console\n", stderr); DosClose(fd); exit(2); } rc = DosDevIOCtl(fd, XFREE86_CONS, CONS_OWNER, NULL, 0, NULL, (PULONG)&buf, sizeof(buf),&argsz); if (rc) { fprintf(stderr,"!!! Cannot get console owner, status = %d\n",rc); fputs("Possibly another process currently owns the console\n", stderr); DosClose(fd); exit(2); } printf("Owner of console is: %s\n",buf); fd = _imphandle(fd); for(;;) { fd_set rfds,wfds,efds; int rc; /* read some chars */ memset(buf,0,200); FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); FD_SET(fd,&rfds); printf("%d %x %x %x\n",fd+1,(&rfds)[0],(&rfds)[1],(&rfds)[2]); rc = select(fd+1,&rfds,&wfds,&efds,NULL); printf("rc(select)=%d\n",rc); rc = DosRead(fd,(PVOID)buf,199,&nread); if (rc) { fprintf(stderr, "!!! Read from console returned status=%d\n", rc); break; } if (nread) { fputs(buf,stdout); if (nread < 199) { /* wait some time */ DosSleep(50); /* 50 msec */ } } } DosClose(fd); exit(0); return 0; }
static XtransConnInfo TRANS(Os2OpenClient)(Xtransport *thistrans, char *protocol, char *host, char *port) { APIRET rc; HFILE hfd,hServer; ULONG action,byteWritten,State; char pipename[256],clientname[256]; char server_string[256]; struct sockaddr *addr_name; unsigned char pipe_len; XtransConnInfo ciptr; static int unique_id=0; int i,namelen,try; PRMSG(2,"Os2OpenClient(%s,%s,%s)\n",protocol,host,port); /* test, whether the host is really local, i.e. either * "os2" or "local" */ if (strcmp(protocol,"os2") && strcmp(protocol,"local")) { PRMSG (1, "Os2OpenClient: Cannot connect to non-local host %s\n", host, 0, 0); return NULL; } /* make the pipename */ if (port && *port ) { if( *port == '/' ) { /* A full pathname */ (void) sprintf(pipename, "\\PIPE\\X\\%s,", port); } else { (void) sprintf(pipename, "%s%s", "\\PIPE\\X\\xf86.", port); } } else { (void) sprintf(pipename, "\\PIPE\\X\\xfree86"); } PRMSG(5, "Os2OpenClient: Creating pipe %s\n",pipename, 0,0 ); /* make a connection entry */ if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL ) { PRMSG(1,"Os2OpenClient: calloc(1,%d) failed\n", sizeof(struct _XtransConnInfo),0,0 ); return NULL; } /* open the pipe. Try ten times before giving up at 500ms intervals*/ try = 0; do { rc = DosOpen(pipename,&hServer, &action, 0, FILE_NORMAL, FILE_OPEN, OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYWRITE, (PEAOP2)NULL); if(rc == 0) break; if (try >=10) { PRMSG(1,"Os2OpenClient: Open server pipe %s failed, rc=%d\n", pipename,rc,0 ); PRMSG(1,"\tProbable causes: either the XServer is not running, or has not started properly,\n", 0,0,0 ); PRMSG(1,"\tor the DISPLAY variable is set incorrectly.\n", 0,0,0 ); xfree(ciptr); return NULL; } try ++; DosSleep(500); } while (rc != 0); /* OK, now we are talking to the server. Generate a unique pipe name and pass it to * the server. Make the pipe and wait for server to connect */ sprintf(clientname,"\\PIPE\\X\\%d.%d",getpid(),unique_id++); rc = DosCreateNPipe (clientname, &hfd, NP_NOINHERIT | NP_ACCESS_DUPLEX, 1 | NP_NOWAIT | NP_TYPE_BYTE | NP_READMODE_BYTE, 16384, 16384, 0); if (rc != 0){ PRMSG(1, "Os2OpenClient: Unable to create pipe %s\n", pipename,0,0 ); DosClose(hfd); pipe_len=0; DosWrite(hServer,&pipe_len,1,&byteWritten); DosClose(hServer); xfree(ciptr); return(NULL); } /* Connect to the pipe. */ rc = DosConnectNPipe (hfd); if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED) { PRMSG(1, "Os2OpenClient: Unable to connect to pipe %s\n", pipename,0,0 ); DosClose (hfd); DosClose(hServer); xfree(ciptr); return (NULL); } /* Now write name to server on hServer */ server_string[0]=(char) strlen(clientname)+1; strcpy(&server_string[1],clientname); rc = DosWrite(hServer,server_string,(ULONG)server_string[0]+1,&byteWritten); if(rc != 0){ /* Could not write to server pipe? */ PRMSG(1, "Os2OpenClient: Error writing to server pipe, handle=%d, rc=%d, w=%d\n", hServer,rc,byteWritten ); DosClose(hServer); DosClose(hfd); xfree(ciptr); return(NULL); } PRMSG (5, "Os2OpenCLient: Wrote pipename %s to server; len %d written %d \n", &server_string[1],server_string[0]+1,byteWritten); /* The server will respond by opening the pipe. Wait for that for 30 secs */ i=0; DosSleep(50); /* Give it time to catch up but minimize race condition*/ rc = DosConnectNPipe(hfd); while((rc == ERROR_PIPE_NOT_CONNECTED)&&(i++<60)) { DosSleep(500); rc = DosConnectNPipe(hfd); } if(rc != 0){ /* Server has not responded! */ PRMSG(1, "Os2OpenClient: Timeout on wait for server response, handle=%d, rc=%d\n",hServer,rc,0 ); PRMSG(1, "\tProbable cause: the XServer has exited or crashed while the connection was being established\n",0,0,0 ); PRMSG(1, "\tor the XServer is too busy to respond.\n",0,0,0 ); DosClose(hServer); DosClose(hfd); xfree(ciptr); return(NULL); } /* OK, the server has connected! Fill-in the info and return */ DosClose(hServer); /* Last check: make sure client is connected! */ rc = DosQueryNPHState(hfd,&State); if(rc != 0){ /* Client is not connected! */ PRMSG(1, "Os2OpenClient: Client pipe does not appear connected. rc=%d, h=%d\n",rc,hfd,0 ); PRMSG(1, "\tProbable cause: the XServer has just exited.\n",0,0,0 ); DosClose(hfd); xfree(ciptr); return(NULL); } namelen=sizeof(struct sockaddr); if ((ciptr->addr = (char *) xalloc (namelen)) == NULL) { PRMSG (1, "Os2OpenClient: Can't allocate space for the addr\n", 0, 0, 0); DosClose(hfd); xfree(ciptr); return(NULL); } ciptr->addrlen = namelen; ((struct sockaddr *)ciptr->addr)->sa_family = AF_UNIX; strcpy(((struct sockaddr *)ciptr->addr)->sa_data, "local"); if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL) { PRMSG (1, "Os2OpenCLient: Can't allocate space for the addr\n", 0, 0, 0); DosClose(hfd); xfree(ciptr->addr); xfree(ciptr); return(NULL); } ciptr->peeraddrlen = namelen; ((struct sockaddr *)ciptr->peeraddr)->sa_family = AF_UNIX; strcpy (((struct sockaddr *)ciptr->peeraddr)->sa_data,"local"); PRMSG (5, "Os2OpenCLient: Filled in struct: len %d %d name %s\n", ciptr->addrlen,ciptr->peeraddrlen,((struct sockaddr *)ciptr->peeraddr)->sa_data); ciptr->index=hfd; ciptr->family=AF_UNIX; if((ciptr->fd=_imphandle(hfd))<0){ PRMSG(1, "Os2OpenClient: Could not import the pipe handle into EMX\n",0,0,0 ); PRMSG(1, "\tProbable cause: EMX has run out of free file handles.\n",0,0,0 ); DosClose(hfd); xfree(ciptr->addr); xfree(ciptr->peeraddr); xfree(ciptr); return(NULL); } PRMSG(5, "Os2OpenClient: pipe handle %d EMX handle %d\n",ciptr->index,ciptr->fd,0 ); fcntl(ciptr->fd,F_SETFL,O_NDELAY); fcntl(ciptr->fd,F_SETFD,FD_CLOEXEC); return ciptr; } #endif /* TRANS_CLIENT */ #ifdef TRANS_SERVER static XtransConnInfo TRANS(Os2OpenServer)(Xtransport *thistrans, char *protocol, char *host, char *port) { APIRET rc; HFILE hfd; ULONG action; char pipename[256]; struct sockaddr *addr_name; XtransConnInfo ciptr; int namelen; #ifdef XSERV_t if (! init_server_pipes()) return(NULL); #endif PRMSG(2,"Os2OpenServer(%s,%s,%s)\n",protocol,host,port); if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL ) { PRMSG(1,"Os2OpenServer: xcalloc(1,%d) failed\n", sizeof(struct _XtransConnInfo),0,0 ); return NULL; } if (port && *port ) { if( *port == '/' ) { /* A full pathname */ (void) sprintf(pipename, "\\PIPE\\X\\%s", port); } else { (void) sprintf(pipename, "%s%s", "\\PIPE\\X\\xf86.", port); } } else { (void) sprintf(pipename, "\\PIPE\\X\\xfree86"); } PRMSG(5, "Os2OpenServer: Creating pipe %s\n",pipename, 0,0 ); rc = DosCreateNPipe (pipename, &hfd, NP_NOINHERIT | NP_ACCESS_INBOUND, 1 | NP_NOWAIT | NP_TYPE_BYTE | NP_READMODE_BYTE, 0, 8192, 0); if (rc != 0){ PRMSG(1, "Os2OpenServer: Unable to create pipe %s, rc=%d\n", pipename,rc,0 ); PRMSG(1, "\tProbable cause: there is already another XServer running on display :%s\n",port,0,0 ); DosClose(hfd); xfree(ciptr); return(NULL); } /* Connect to the pipe. */ rc = DosConnectNPipe (hfd); if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED) { PRMSG(1, "Os2OpenServer: Unable to connect to pipe %s\n", pipename,0,0 ); DosClose (hfd); xfree(ciptr); return (NULL); } /* Pipe is now connected and waiting for client connect */ /*** Put in info ***/ namelen=sizeof(struct sockaddr); if ((ciptr->addr = (char *) xalloc (namelen)) == NULL) { PRMSG (1, "Os2OpenServer: Can't allocate space for the addr\n", 0, 0, 0); DosClose(hfd); xfree(ciptr); return(NULL); } ciptr->addrlen = namelen; ((struct sockaddr *)ciptr->addr)->sa_family = AF_UNIX; strcpy (((struct sockaddr *)ciptr->addr)->sa_data, "local"); if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL) { PRMSG (1, "Os2OpenServer: Can't allocate space for the addr\n", 0, 0, 0); DosClose(hfd); xfree(ciptr->addr); xfree(ciptr); return(NULL); } ciptr->peeraddrlen = namelen; ((struct sockaddr *)ciptr->peeraddr)->sa_family = AF_UNIX; strcpy(((struct sockaddr *)ciptr->peeraddr)->sa_data,"local"); PRMSG (5, "Os2OpenServer: Filled in struct: len %d %d name %s\n", ciptr->addrlen,ciptr->peeraddrlen,((struct sockaddr *)ciptr->peeraddr)->sa_data); ciptr->index=hfd; /* Save this for later use in this unused member of struct */ ciptr->flags=1; /* Listener */ ciptr->family=AF_UNIX; if((ciptr->fd=_imphandle(hfd))<0){ DosClose(hfd); xfree(ciptr->addr); xfree(ciptr->peeraddr); xfree(ciptr); return(NULL); } PRMSG(5, "Os2OpenServer: Pipe handle %d EMX handle %d",ciptr->index,ciptr->fd,0 ); #ifdef XSERV_t /* Attach the pipe sem to the pipe. Use handle index as key */ rc = DosSetNPipeSem(ciptr->fd, (HSEM)hPipeSem, ciptr->fd); if (rc){ PRMSG(1, "Os2OpenCOTSServer: Could not attach sem %d to pipe %d, rc=%d\n", hPipeSem,ciptr->fd,rc); DosClose(ciptr->fd); xfree(ciptr->addr); xfree(ciptr->peeraddr); xfree(ciptr); return(NULL); } #endif fcntl(ciptr->fd,F_SETFL,O_NDELAY); fcntl(ciptr->fd,F_SETFD,FD_CLOEXEC); return(ciptr); }
int main(int argc, char **argv) { int c, end = 0, lines = 25; int x, y, h, n, v; FILE *in=NULL; char a; char buf[160]; HPIPE pipe; APIRET rc; char *target; /* Check command line */ if (argc!=2 && argc!=3) { printf("Usage: %s Mirror|Recall|Choice|Term-4|...|Term-7 [number of lines]\n" "Start this before angband.exe\n", argv[0]); exit(1); } if (argc==3) lines = atoi(argv[2]); if (lines <= 0) lines = 25; printf("Looking for Angband... press ^C to abort\n"); target=strdup(argv[1]); for (c=0; c<strlen(target); c++) target[c]=tolower(target[c]); strnfmt(buf, 160, "\\pipe\\angband\\%s", target); do { rc=DosCreateNPipe((PSZ)buf, /* Create pipe */ &pipe, NP_ACCESS_INBOUND, NP_WAIT|NP_TYPE_BYTE|NP_READMODE_BYTE|1, 1, /* No output buffer */ 1, /* No input buffer */ -1); if (rc) /* Pipe not created */ { printf("DosCreateNPipe: rc=%ld, pipe=%ld\n", (long)rc, (long)pipe); break; } do { rc=DosConnectNPipe(pipe); /* Wait for angband to connect */ if (!rc) break; _sleep2(500); /* Sleep for 0.5s */ } while (_read_kbd(0, 0, 0)==-1); /* Until key pressed */ if (rc) break; h=_imphandle(pipe); /* Register handle with io */ setmode(h, O_BINARY); /* Make it binary */ in=fdopen(h, "rb"); /* Register handle with stdio */ } while (0); /* We don't need no stinking exception handling <g> */ if (!in) { printf("Sorry, the pipe connection to Angband could not be established.\n"); exit(1); } printf("Connected.\n"); strnfmt(buf, 160, "mode co80,%d", lines); system(buf); /* Infinite loop */ while (!end) { /* Get command */ c = fgetc(in); switch (c) { case PIP_XTRA: if (!fread(&n, sizeof(x), 1, in) || !fread(&v, sizeof(y), 1, in)) abort(); /* This hack prevents another hack */ printf("Sorry, angband.exe and aclient.exe don't fit together.\n"); exit(1); break; case PIP_CURS: if (!fread(&x, sizeof(x), 1, in) || !fread(&y, sizeof(y), 1, in)) abort(); Term_curs_emx(x, y); break; case PIP_WIPE: if (!fread(&x, sizeof(x), 1, in) || !fread(&y, sizeof(y), 1, in) || !fread(&n, sizeof(n), 1, in)) abort(); Term_wipe_emx(x, y, n); break; case PIP_TEXT: if (!fread(&x, sizeof(x), 1, in) || !fread(&y, sizeof(y), 1, in) || !fread(&n, sizeof(n), 1, in) || !fread(&a, sizeof(a), 1, in) || (n > 160) || !fread(buf, n, 1, in)) abort(); Term_text_emx(x, y, n, a, buf); break; case PIP_INIT: Term_init_emx(NULL); break; case PIP_NUKE: case EOF: default: Term_nuke_emx(NULL); end=1; break; } } return 0; }
static XtransConnInfo TRANS(Os2Accept)(XtransConnInfo ciptr, int *status) { XtransConnInfo newciptr; HFILE hClient; unsigned char length; ULONG action; char clientname[256]; struct sockaddr *addr_name; int in,namelen; APIRET rc; PRMSG(2,"Os2Accept(%x->%d)\n", ciptr, ciptr->fd,0); if( (newciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo)))==NULL ) { PRMSG(1,"Os2Accept: xcalloc(1,%d) failed\n", sizeof(struct _XtransConnInfo),0,0 ); *status = TRANS_ACCEPT_BAD_MALLOC; return NULL; } /* Read in length of client pipe name. If fails, then reset server pipe */ if((in=read(ciptr->fd,&length,1))<=0){ PRMSG(2,"Os2Accept: Error reading incoming connection, in=%d, error=%d\n", in,errno,0 ); *status = TRANS_ACCEPT_MISC_ERROR; xfree(newciptr); rc = DosDisConnectNPipe(ciptr->fd); rc = DosConnectNPipe (ciptr->fd); if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED) { PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 ); } return NULL; } PRMSG(5, "Os2Accept: Bytes to read for name: %d\n",length,0,0 ); /* Check length for valid length ?? */ /* Now read in length bytes from pipe for client pipe name */ if((in=read(ciptr->fd,clientname,length))<=0){ PRMSG(2,"Os2Accept: Error reading incoming connection, in=%d, error=%d\n", in,errno,0 ); *status = TRANS_ACCEPT_MISC_ERROR; xfree(newciptr); rc = DosDisConnectNPipe(ciptr->fd); rc = DosConnectNPipe (ciptr->fd); if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED) { PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 ); } return NULL; } clientname[length]='\0'; PRMSG(5, "Os2Accept: Server name %s length %d\n",clientname,length,0 ); /* Now we have the client pipe name. Open it with DosOpen */ rc = DosOpen(clientname,&hClient, &action, 0, FILE_NORMAL, FILE_OPEN, OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE, (PEAOP2)NULL); PRMSG(5, "Os2Accept: Open pipe %s, handle = %d, rc=%d\n",clientname,hClient,rc ); if (rc) { PRMSG(1,"Os2Accept: Open pipe %s to client failed, rc=%d\n", clientname,rc,0 ); PRMSG(1, "\tProbable cause: the client has exited or timed-out.\n",0,0,0 ); xfree(newciptr); rc = DosDisConnectNPipe(ciptr->fd); rc = DosConnectNPipe (ciptr->fd); if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED) { PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 ); } return NULL; } rc = DosSetNPHState (hClient, NP_NOWAIT | NP_READMODE_BYTE); if (rc != 0) { PRMSG(1,"Os2Accept: Could not set pipe %s to non-blocking mode, rc=%d\n", hClient,rc,0 ); xfree(newciptr); rc = DosDisConnectNPipe(ciptr->fd); rc = DosConnectNPipe (ciptr->fd); if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED) { PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 ); } return NULL; } /* OK, we seem to be well connected to client. Now disconnect server pipe and put again in listen */ rc = DosDisConnectNPipe(ciptr->fd); rc = DosConnectNPipe (ciptr->fd); PRMSG(5, "Os2Accept: Reconnecting server pipe %d, rc = %d\n",ciptr->fd,rc,0 ); if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED) { PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 ); } /* Consider this non-fatal for present connection */ /* And finally fill-in info in newciptr */ namelen=sizeof(struct sockaddr); if ((newciptr->addr = (char *) xalloc (namelen)) == NULL) { PRMSG (1, "Os2Accept: Can't allocate space for the addr\n", 0, 0, 0); DosClose(hClient); xfree(newciptr); return(NULL); } newciptr->addrlen = namelen; ((struct sockaddr *)newciptr->addr)->sa_family = AF_UNIX; strcpy (((struct sockaddr *)newciptr->addr)->sa_data, "local"); if ((newciptr->peeraddr = (char *) xalloc (namelen)) == NULL) { PRMSG (1, "Os2Accept: Can't allocate space for the addr\n", 0, 0, 0); DosClose(hClient); xfree(ciptr->addr); xfree(newciptr); return(NULL); } newciptr->peeraddrlen = namelen; ((struct sockaddr *)newciptr->peeraddr)->sa_family = AF_UNIX; strcpy (((struct sockaddr *)newciptr->peeraddr)->sa_data, "local"); PRMSG (5, "Os2Accept: Filled in struct: len %d %d name %s\n", newciptr->addrlen,newciptr->peeraddrlen,newciptr->peeraddr); newciptr->index=hClient; newciptr->family=AF_UNIX; if((newciptr->fd=_imphandle(hClient))<0){ PRMSG(1,"Os2Accept: Could not import pipe %d into EMX, errno=%d\n", hClient,errno,0 ); PRMSG(1, "\tProbable cause: EMX has run out of file handles.\n",0,0,0 ); DosClose(hClient); xfree(newciptr->addr); xfree(newciptr->peeraddr); xfree(newciptr); return(NULL); } PRMSG(5, "Os2Accept: Pipe handle %d EMX handle %d",newciptr->index,newciptr->fd,0 ); #ifdef XSERV_t /* Attach the pipe sem to the pipe. Use handle index as key */ rc = DosSetNPipeSem(newciptr->fd, (HSEM)hPipeSem, newciptr->fd); if (rc){ PRMSG(1, "Os2OpenCOTSServer: Could not attach sem %d to pipe %d, rc=%d\n", hPipeSem,newciptr->fd,rc); DosClose(newciptr->fd); xfree(newciptr->addr); xfree(newciptr->peeraddr); xfree(newciptr); return(NULL); } #endif fcntl(ciptr->fd,F_SETFL,O_NDELAY); fcntl(ciptr->fd,F_SETFD,FD_CLOEXEC); *status=0; return newciptr; }