Solved

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

Posted on 1997-07-16
3
860 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

This article describes a technique for converting RTF (Rich Text Format) data to HTML and provides C++ source that does it all in just a few lines of code. Although RTF is coming to be considered a "legacy" format, it is still in common use... po…
With most software applications trying to cater to multiple user needs nowadays, the focus is to make them as configurable as possible. For e.g., when creating Silverlight applications which will connect to WCF services, the service end point usuall…
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…
In this video, viewers will be given step by step instructions on adjusting mouse, pointer and cursor visibility in Microsoft Windows 10. The video seeks to educate those who are struggling with the new Windows 10 Graphical User Interface. Change Cu…

691 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