Solved

inetd for Nt4.0 - stdin/stdout -> socket

Posted on 1997-07-16
3
840 Views
Last Modified: 2013-12-03
How can I write (a kind of) inetd for NT? I have to map stdin and stdout to the socket interface. In UNIX, I use fork, dup and exec to start the requested client. How can I map the stdio of my Thread/Child-Process to the socket created in the father process using wsock32 (or any other sock, if you have one).
0
Comment
Question by:thobe
3 Comments
 
LVL 3

Expert Comment

by:vinniew
ID: 1401046
This is all possible, I just haven't done it because of the terminal problems....

1.  You would start a command shell ( cmd.exe ).  
2.  You take the process handle and the context handles and use them in a command to redirect stdout/stdin.
3.  I think that the name of the command is StdoutHandle or something similar
4.  Use ReadFile/WriteFile on the handles that are now Stdout/Stdin
5.  You may want to do some light massaging on the lines to remove CR's
6.  Send/grab the info to the sockets.

post more specific questions if you need to .


0
 

Author Comment

by:thobe
ID: 1401047
Thanks for your answers, but what I need is: In UNIX, I have a
inet-deamon, which receives requests for services to start.
I have to write a C/C++ Windows-Programm, which waits at a
specific port an then starts some Windows-Programm, I have no
sources etc. It can also be a shell-script or Perl etc. In UNIX, you can easily fork your deamon, call close(stdin) and dup(s) on your socket s and call exec on the requested programm. Then, all
stdin/stdout will be written to the socket. When i try this under
NT with a socket, the dup() returns EBADF, a bad File descriptor.
Because I heared about inet-deamons on NT, it must be possible.
So, I am sorry, but the recent answer can not help me.
Thanks



0
 
LVL 3

Accepted Solution

by:
jaba earned 400 total points
ID: 1401048
Well , this is small programm working as telnet server under NT. It waiting for IT connet , when starting CMD.EXE and redirect its STDOUT and STDIN to pipes , pipes redirected to sockets. May be it will help you a lot as sample
#include <stdio.h>
#include <winsock.h>
#include <process.h>
#include <io.h>
#include <fcntl.h>

const char *SocketError(int nErrorCode)
{
      switch(nErrorCode){
            case WSABASEERR:         return "[0] No Error";
            case WSAEINTR:           return "[10004] Interrupted system call";
            case WSAEBADF:           return "[10009] Bad file number";
            case WSAEACCES:          return "[10013] Permission denied";
            case WSAEFAULT:          return "[10014] Bad address";
            case WSAEINVAL:          return "[10022] Invalid argument";
            case WSAEMFILE:          return "[10024] Too many open files";
            case WSAEWOULDBLOCK:     return "[10035] Operation would block";
            case WSAEINPROGRESS:     return "[10036] Operation now in progress";
            case WSAEALREADY:        return "[10037] Operation already in progress";
            case WSAENOTSOCK:        return "[10038] Socket operation on non-socket";
            case WSAEDESTADDRREQ:    return "[10039] Destination address required";
            case WSAEMSGSIZE:        return "[10040] Message too long";
            case WSAEPROTOTYPE:      return "[10041] Protocol wrong type for socket";
            case WSAENOPROTOOPT:     return "[10042] Bad protocol option";
            case WSAEPROTONOSUPPORT: return "[10043] Protocol not supported";
            case WSAESOCKTNOSUPPORT: return "[10044] Socket type not supported";
            case WSAEOPNOTSUPP:      return "[10045] Operation not supported on socket";
            case WSAEPFNOSUPPORT:    return "[10046] Protocol family not supported";
            case WSAEAFNOSUPPORT:    return "[10047] Address family not supported by protocol family";
            case WSAEADDRINUSE:      return "[10048] Address already in use";
            case WSAEADDRNOTAVAIL:   return "[10049] Can't assign requested address";
            case WSAENETDOWN:        return "[10050] Network is down";
            case WSAENETUNREACH:     return "[10051] Network is unreachable";
            case WSAENETRESET:       return "[10052] Net dropped connection or reset";
            case WSAECONNABORTED:    return "[10053] Software caused connection abort";
            case WSAECONNRESET:      return "[10054] Connection reset by peer";
            case WSAENOBUFS:         return "[10055] No buffer space available";
            case WSAEISCONN:         return "[10056] Socket is already connected";
            case WSAENOTCONN:        return "[10057] Socket is not connected";
            case WSAESHUTDOWN:       return "[10058] Can't send after socket shutdown";
            case WSAETOOMANYREFS:    return "[10059] Too many references, can't splice";
            case WSAETIMEDOUT:       return "[10060] Connection timed out";
            case WSAECONNREFUSED:    return "[10061] Connection refused";
            case WSAELOOP:           return "[10062] Too many levels of symbolic links";
            case WSAENAMETOOLONG:    return "[10063] File name too long";
            case WSAEHOSTDOWN:       return "[10064] Host is down";
            case WSAEHOSTUNREACH:    return "[10065] No Route to Host";
            case WSAENOTEMPTY:       return "[10066] Directory not empty";
            case WSAEPROCLIM:        return "[10067] Too many processes";
            case WSAEUSERS:          return "[10068] Too many users";
            case WSAEDQUOT:          return "[10069] Disc Quota Exceeded";
            case WSAESTALE:          return "[10070] Stale NFS file handle";
            case WSAEREMOTE:         return "[10071] Too many levels of remote in path";
            case WSASYSNOTREADY:     return "[10091] Network SubSystem is unavailable";
            case WSAVERNOTSUPPORTED: return "[10092] WINSOCK DLL Version out of range";
            case WSANOTINITIALISED:  return "[10093] Successful WSASTARTUP not yet performed";
            case WSAHOST_NOT_FOUND:  return "[11001] Host not found";
            case WSATRY_AGAIN:       return "[11002] Non-Authoritative Host not found";
            case WSANO_RECOVERY:     return "[11003] Non-Recoverable errors: FORMERR, REFUSED, NOTIMP";
            case WSANO_DATA:         return "[11004] Valid name, no data record of requested ";
            default:
                  static char sTmp[16];
                  wsprintf(sTmp, "[%d] Unknown Error", h_errno);
                  return sTmp;
   }
}

enum PIPES { READ, WRITE }; /* Constants 0 and 1 for READ and WRITE */

const char *cmd = NULL;

void __cdecl CsockThreadProc(LPVOID pSock)
{
      SOCKET csock = (SOCKET) pSock;
      int hpipes_in[2], hpipes_out[2];
      if(_pipe(hpipes_in, 512, O_BINARY) == -1){
            printf("Could not open pipes\n");
            return;
      }
      if(_pipe(hpipes_out, 512, O_BINARY) == -1){
            printf("Could not open pipes\n");
            return;
      }
      int hStdIn = _dup(0);
      int hStdOut = _dup(1);
      int hStdErr = _dup(2);
      if(_dup2(hpipes_in[READ], 0) != 0){
            printf("dup2 on stdin failed\n");
            return;
      }
      if(_dup2(hpipes_out[WRITE], 1) != 0){
            printf("dup2 on stdin failed\n");
            return;
      }
      if(_dup2(hpipes_out[WRITE], 2) != 0){
            printf("dup2 on stdin failed\n");
            return;
      }
      close(hpipes_in[READ]); close(hpipes_out[WRITE]);
      HANDLE hProcess = (HANDLE) spawnlp(P_NOWAIT, cmd, cmd, NULL);
      _dup2(hStdIn, 0); _dup2(hStdOut, 1); _dup2(hStdErr, 2);
      close(hStdIn); close(hStdOut);
      if(hProcess == 0){
            printf("Can't start new process\n");
            close(hpipes_in[WRITE]); close(hpipes_out[READ]);
            closesocket(csock);
            return;
      }
      while(1){
            fd_set set; FD_ZERO(&set);
            FD_SET(csock, &set);
            timeval tm; tm.tv_sec = 0; tm.tv_usec = 0;
            if(select(0, &set, NULL, NULL, &tm) == SOCKET_ERROR){
                  printf("select: %s\n", SocketError(WSAGetLastError()));
                  break;
            }
            if(FD_ISSET(csock, &set)){
                  DWORD nRead;
                  if(ioctlsocket(csock, FIONREAD, &nRead) == SOCKET_ERROR){
                        printf("ioctl: %s\n", SocketError(WSAGetLastError()));
                        break;
                  }
                  if(nRead == 0){
                        // Socket is closed from other side
                        printf("Socket became closed from other side\n");
                        break;
                  }
                  char *b = new char[nRead];
                  int nBytes = recv(csock, b, nRead, 0);
                  if(nBytes == SOCKET_ERROR){
                        printf("recv: %s\n", SocketError(WSAGetLastError()));
                        delete b;
                        break;
                  }
                  if(nBytes != (int) nRead){
                        printf("error in recv: nRead=%d, nBytes=%d\n", nRead, nBytes);
                        delete b;
                        break;
                  }
                  nBytes = write(hpipes_in[WRITE], b, nRead);
                  delete b;
                  if(nBytes != (int) nRead){
                        printf("error %d in write: nRead=%d, nBytes=%d\n", GetLastError(), nRead, nBytes);
                        break;
                  }
            }
            int len = filelength(hpipes_out[READ]);
            if(len > 0){
                  char *b = new char[len];
                  int nRead = read(hpipes_out[READ], b, len);
                  if(nRead == -1){
                        printf("Error in read: %d\n", GetLastError());
                        delete b;
                        break;
                  }
                  if(nRead != len){
                        printf("nRead=%d, len=%d\n", nRead, len);
                  }
                  FD_ZERO(&set);
                  FD_SET(csock, &set);
                  tm; tm.tv_sec = 2; tm.tv_usec = 0;
                  if(select(0, NULL, &set, NULL, &tm) == SOCKET_ERROR){
                        delete b;
                        printf("select for write: %s\n", SocketError(WSAGetLastError()));
                        break;
                  }
                  if(!FD_ISSET(csock, &set)){
                        delete b;
                        printf("Timeout for write\n");
                        break;
                  }
                  if(send(csock, b, nRead, 0) == SOCKET_ERROR){
                        delete b;
                        printf("send: %s\n", SocketError(WSAGetLastError()));
                        break;
                  }
                  delete b;
            }
            // Sleep(500);
      }
      close(hpipes_in[WRITE]); close(hpipes_out[READ]);
      closesocket(csock);
}

void main()
{
      WSADATA wsaData;
      int rc = WSAStartup(MAKEWORD(1, 1), &wsaData);
      if(rc != 0){
            printf("Could not initialize Windows sockets: %s\n", SocketError(rc));
            return;
      }

      servent *pse = getservbyname("inist_telnet", "tcp");
      if(pse == NULL || pse->s_port == 0) pse = getservbyname("telnet", "tcp");
      if(pse == NULL || pse->s_port == 0){
            printf("Can't detect port number for service telnet\n");
            return;
      }
      short nPort = pse->s_port;
      cmd = getenv("ComSpec");
      if(cmd == NULL){
            printf("Can't find ComSpec\n");
            return;
      }
      SOCKET lsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
      if(lsock == INVALID_SOCKET){
            printf("socket: %s\n", SocketError(WSAGetLastError()));
            return;
      }
      SOCKADDR_IN sockAddr;
      memset(&sockAddr,0,sizeof(sockAddr));
      sockAddr.sin_family = AF_INET;
      sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
      sockAddr.sin_port = nPort;
      if(bind(lsock, (SOCKADDR*) &sockAddr, sizeof sockAddr) == SOCKET_ERROR){
            printf("bind: %s\n", SocketError(WSAGetLastError()));
            closesocket(lsock);
            return;
      }
      if(listen(lsock, SOMAXCONN) == SOCKET_ERROR){
            printf("listen: %s\n", SocketError(WSAGetLastError()));
            closesocket(lsock);
            return;
      }

      while(1){
            SOCKET csock = accept(lsock, NULL, NULL);
            if(csock == INVALID_SOCKET){
                  printf("accept: %s\n", SocketError(WSAGetLastError()));
                  continue;
            }
            long hThread = _beginthread(CsockThreadProc, 0, (LPVOID) csock);
            if(hThread == -1){
                  printf("Can't start thread\n");
                  closesocket(csock);
            }
      }
      if(closesocket(lsock) == SOCKET_ERROR){
            printf("close: %s\n", SocketError(WSAGetLastError()));
      }
      WSACleanup();
}

0

Featured Post

Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial is about how to put some of your C++ program's functionality into a standard DLL, and how to make working with the EXE and the DLL simple and seamless.   We'll be using Microsoft Visual Studio 2008 and we will cut out the noise; that i…
This article describes how to add a user-defined command button to the Windows 7 Explorer toolbar.  In the previous article (http://www.experts-exchange.com/A_2172.html), we saw how to put the Delete button back there where it belongs.  "Delete" is …
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

820 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question