Ticket Change Details
Not logged in
Overview

Artifact ID: 1052b0c4dc927bd3cb5403ed3c7636242366ddb5
Ticket: 2384764107f0d084867503e16461f18b80f72e24
Make the http command working on Windows.
User & Date: anonymous 2009-09-17 14:08:24
Changes

  1. comment changed to:
    This would make it possible to use Fossil with Inetd like servers on Windows, for example [http://www.xmailserver.org/wininetd.html].
    
    The following patch against Fossil version [0eb08b860c] implements this functionality:
    
    <verbatim>
    diff -Naur fossil-src/src/cgi.c fossil-src-mod/src/cgi.c
    --- fossil-src/src/cgi.c	2009-09-13 09:37:48 +0000
    +++ fossil-src-mod/src/cgi.c	2009-09-17 11:25:47 +0000
    @@ -29,10 +29,11 @@
     */
     #include "config.h"
     #ifdef __MINGW32__
    -#  include <windows.h>           /* for Sleep once server works again */
    -#  include <winsock2.h>          /* socket operations */
    -#  define sleep Sleep            /* windows does not have sleep, but Sleep */
    -#  include <ws2tcpip.h>          
    +#  include <windows.h>           /* Windows specific declarations */
    +#  include <winsock2.h>          /* Windows socket operations */
    +#  include <ws2tcpip.h>          /* for socklen_t */
    +#  include <fcntl.h>
    +#  include <io.h>
     #else
     #  include <sys/socket.h>
     #  include <netinet/in.h>
    @@ -1076,6 +1077,95 @@
       return zResult;
     }
     
    +#ifdef __MINGW32__
    +/*
    +** Data structure related to all variables for the windows socket environment.
    +*/
    +typedef struct WinSocketData {
    +  int     fWSAInit;       /* True, if Windows sockets initialized */
    +  SOCKET  hSocket;        /* Handle to the socket */
    +} WinSocketData;
    +
    +static WinSocketData wsd;
    +
    +/*
    +** Exit handler routine. Make sure any remaining output gets flushed to the
    +** output stream. If the standard handles are redirected to a socket then
    +** make shure the socket gets closed properly and clean up the windows socket
    +** environment.
    +*/
    +static void cgi_handle_http_request_exit(void)
    +{
    +  fflush(g.httpOut);
    +
    +  if( wsd.hSocket != INVALID_SOCKET ){
    +    shutdown(wsd.hSocket, SD_BOTH);
    +    closesocket(wsd.hSocket);
    +  }
    +  if (wsd.fWSAInit) {
    +    WSACleanup();
    +  }
    +  return;
    +}
    +
    +/*
    +** This routine initalizes the environment on windows for the
    +** cgi_handle_http_request routine. It sets the standard input and ouput
    +** handles to binary mode, initalizes the windows socket environment and tries
    +** to get the socket handle from the standard handles. It also establishs a
    +** exit routine to clean up on program exit.
    +*/
    +void cgi_handle_http_request_init(void)
    +{
    +  WSADATA wd;
    +  SOCKET hSock;
    +  int socket_type;
    +  int socket_type_len = sizeof(socket_type);
    +
    +  /*
    +  ** Initialize the windows socket data structure.
    +  */
    +  wsd.fWSAInit = 0;
    +  wsd.hSocket = INVALID_SOCKET;
    +
    +  /*
    +  ** Register the exit function.
    +  */
    +  atexit(cgi_handle_http_request_exit);
    +
    +  /*
    +  ** Set the mode of the http input and output streams to binary.
    +  */
    +  _setmode(_fileno(g.httpIn),  _O_BINARY);
    +  _setmode(_fileno(g.httpOut), _O_BINARY);
    +
    +  /*
    +  ** Initialize the windows socket API. This is required if we need to
    +  ** call any other Windows Socket function.
    +  */
    +  if( WSAStartup(MAKEWORD(2,2), &wd) == 0 ) wsd.fWSAInit = 1;
    +
    +  /*
    +  ** Windows Socket handles must be handled differently than file handles.
    +  ** There is no function to detect if a file handle is a socket or not, so
    +  ** lets call a socket function with the handle from stdin, and if there is
    +  ** no error, assume it is a socket!
    +  */
    +  if( wsd.fWSAInit ){
    +    hSock = (SOCKET)_get_osfhandle(_fileno(stdin));
    +    if( getsockopt (hSock, SOL_SOCKET, SO_TYPE,
    +                    (char *)&socket_type, &socket_type_len) == 0 ){
    +      wsd.hSocket = hSock;
    +    }
    +  }
    +  return;
    +}
    +
    +#  define CGI_SOCKET wsd.hSocket
    +#else
    +#  define CGI_SOCKET fileno(g.httpIn)
    +#endif /* __MINGW32__ */
    +
     /*
     ** This routine handles a single HTTP request which is coming in on
     ** standard input and which replies on standard output.
    @@ -1092,6 +1182,9 @@
       size_t size = sizeof(struct sockaddr_in);
       char zLine[2000];     /* A single line of input. */
     
    +#ifdef __MINGW32__
    +  cgi_handle_http_request_init();
    +#endif
       g.fullHttpReply = 1;
       if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
         malformed_request();
    @@ -1116,7 +1209,7 @@
       cgi_setenv("PATH_INFO", zToken);
       cgi_setenv("QUERY_STRING", &zToken[i]);
       if( zIpAddr==0 &&
    -        getpeername(fileno(g.httpIn), (struct sockaddr*)&remoteName, 
    +        getpeername(CGI_SOCKET, (struct sockaddr*)&remoteName, 
                                     (socklen_t*)&size)>=0
       ){
         zIpAddr = inet_ntoa(remoteName.sin_addr);
    </verbatim>
    
    --tsbg
    
  2. foundin changed to: "0eb08b860c"
  3. private_contact changed to: "76518fb407f147a1d053c00b5b993281a339c0e3"
  4. severity changed to: "Important"
  5. status changed to: "Open"
  6. title changed to: "Make the http command working on Windows."
  7. type changed to: "Feature_Request"