//===================================================== file = httpresp.c =====
//=  A server program to respond to an HTTP GET from a Web browser            =
//=============================================================================
//=  Notes:                                                                   =
//=    1) This program conditionally compiles for Winsock and BSD sockets.    =
//=       Set the initial #define to WIN or BSD as appropriate.               =
//=    2) This program hardwires an HTML response message to return to        =
//=       the browser.                                                        =
//=---------------------------------------------------------------------------=
//=  Example execution:                                                       =
//=                                                                           =
//=   1) Determine the IP address on which httpresp will run                  =
//=      (e.g., 131.247.167.109).  On Windows NT/2000 use ipconfig to         =
//=      determine the IP address of the local machine.                       =
//=   2) Execute httpresp                                                     =
//=   3) Open a Web browser and surf to http://xxx.xxx.xxx.xxx where          =
//=      xxx.xxx.xxx.xxx is the IP address determined in step (1)             =
//=   4) Will see a response message (with red "Wow!") on the browser screen  =
//=---------------------------------------------------------------------------=
//=  Build: bcc32 httpresp.c, cl httpresp.c wsock32.lib,                      =
//=         gcc httpresp.c -lsocket -lnsl                                     =
//=---------------------------------------------------------------------------=
//=  Execute: httpresp                                                        =
//=---------------------------------------------------------------------------=
//=  History:  KJC (12/20/00) - Genesis (from server.c)                       =
//=============================================================================
#define  WIN                // WIN for Winsock and BSD for BSD sockets

//----- Include files ---------------------------------------------------------
#include <stdio.h>          // Needed for printf()
#include <stdlib.h>         // Needed for exit()
#include <string.h>         // Needed for strcpy() and strlen()
#ifdef WIN
  #include <windows.h>      // Needed for all Winsock stuff
#endif
#ifdef BSD
  #include <sys/types.h>    // Needed for system defined identifiers.
  #include <netinet/in.h>   // Needed for internet address structure.
  #include <sys/socket.h>   // Needed for socket(), bind(), etc...
  #include <arpa/inet.h>    // Needed for inet_ntoa()
  #include <fcntl.h>
  #include <netdb.h>
#endif

//----- Defines ---------------------------------------------------------------
#define  BUF_SIZE           10000     // Buffer size
#define  PORT_NUM              80     // This is the port number for a Web server

//===== Main program ==========================================================
void main(void)
{
#ifdef WIN
  WORD wVersionRequested = MAKEWORD(1,1);       // Stuff for WSA functions
  WSADATA wsaData;                              // Stuff for WSA functions
#endif

  unsigned int         server_s;             // Server socket descriptor
  struct sockaddr_in   server_addr;          // Server Internet address
  unsigned int         client_s;             // Client socket descriptor
  struct sockaddr_in   client_addr;          // Client Internet address
  struct in_addr       client_ip_addr;       // Client IP address
  int                  addr_len;             // Internet address length
  char                 out_buf[BUF_SIZE];    // Output buffer for HTML response
  char                 in_buf[BUF_SIZE];     // Input buffer for GET resquest
  unsigned int         retcode;              // Return code
  unsigned int         i;                    // Loop counter

#ifdef WIN
  // This stuff initializes winsock
  WSAStartup(wVersionRequested, &wsaData);
#endif

  // Create a socket
  server_s = socket(AF_INET, SOCK_STREAM, 0);

  // Fill-in my socket's address information and bind the socket
  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons(PORT_NUM);
  server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  bind(server_s, (struct sockaddr *)&server_addr, sizeof(server_addr));

  // Listen for connections and then accept
  listen(server_s, 1);
  addr_len = sizeof(client_addr);
  client_s = accept(server_s, (struct sockaddr *)&client_addr, &addr_len);

  // Receive from the Web browser
  //  - The return code from recv() is the number of bytes received
  retcode = recv(client_s, in_buf, BUF_SIZE, 0);
  for (i=0; i<retcode; i++)
    printf ("%c", in_buf[i]);

  // Copy the HTML response into the out buffer
  strcpy(out_buf, "<html><body><hr>This is a response <b>message</b> in HTML  \
                   format. <font color=red>Wow!</font><hr></body></html>");

  // Send HTML response to the client
  send(client_s, out_buf, strlen(out_buf), 0);

  // Close all open sockets
#ifdef WIN
  closesocket(server_s);
  closesocket(client_s);
#endif
#ifdef BSD
  close(server_s);
  close(client_s);
#endif

#ifdef WIN
  // This stuff cleans-up winsock
  WSACleanup();
#endif
}

