//===================================================== file = httpget1.c =====
//=  A client program to connect to a Web server and do one HTTP GET          =
//=   - Outputs the GET response                                              =
//=============================================================================
//=  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 the IP address of www.grad.csee.usf in the   =
//=       #define IP_ADDR and hardwires the GET request string into           =
//=       #define GET_STRING.                                                 =
//=---------------------------------------------------------------------------=
//=  Output from an execution (hardwired to get Christensen homepage):        =
//=                                                                           =
//=    HTTP/1.1 200 OK                                                        =
//=    Date: Wed, 20 Dec 2000 03:17:18 GMT                                    =
//=    Server: Apache/1.3.6 (Unix)                                            =
//=    Last-Modified: Sat, 16 Dec 2000 00:14:59 GMT                           =
//=    ETag: "25998c-340c-3a3ab403"                                           =
//=    Accept-Ranges: bytes                                                   =
//=    Content-Length: 13324                                                  =
//=    Connection: close                                                      =
//=    Content-Type: text/html                                                =
//=                                                                           =
//=    <html><head>                                                           =
//=    <title>Homepage for Kenneth J. Christensen</title>                     =
//=    </head><body background="back4.gif">                                   =
//=    <center>                                                               =
//=    <br>                                                                   =
//=    <table border=4>                                                       =
//=    --- SNIP SNIP ---                                                      =
//=    </ol>                                                                  =
//=    <hr size=4 width=100%>                                                 =
//=                                                                           =
//=    <address>                                                              =
//=    Last updated by <a href="http://www.csee.usf.edu/~christen">           =
//=    Ken Christensen</a> on DECEMBER 15, 2000                               =
//=    </address>                                                             =
//=                                                                           =
//=    </body></html>                                                         =
//=---------------------------------------------------------------------------=
//=  Build: bcc32 httpget1.c, cl httpget1.c wsock32.lib,                      =
//=         gcc httpget1.c -lsocket -lnsl                                     =
//=---------------------------------------------------------------------------=
//=  Execute: httpget1                                                       =
//=---------------------------------------------------------------------------=
//=  History:  KJC (01/04/01) - Genesis (from client.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            4096     // Buffer size
#define  PORT_NUM              80     // Web servers are at port 80
#define  IP_ADDR    "131.247.3.1" // IP address of www.csee.usf.edu
#define  GET_STRING "GET /~christen/index.html HTTP/1.0\n\n"  // GET string

//===== 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
  char                 out_buf[BUF_SIZE];    // Output buffer for GET request
  char                 in_buf[BUF_SIZE];     // Input buffer for response
  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 the Web server socket's address information
  server_addr.sin_family = AF_INET;                 // Address family to use
  server_addr.sin_port = htons(PORT_NUM);           // Port num to use
  server_addr.sin_addr.s_addr = inet_addr(IP_ADDR); // IP address to use

  // Do a connect (connect() blocks)
  retcode = connect(server_s, (struct sockaddr *)&server_addr,
                    sizeof(server_addr));
  if (retcode != 0)
  {
    printf("ERROR - connect() failed \n");
    exit(1);
  }

  // Send a GET to the Web server
  strcpy(out_buf, GET_STRING);
  send(server_s, out_buf, strlen(out_buf), 0);

  // Receive from the Web server
  //  - The return code from recv() is the number of bytes received
  retcode = recv(server_s, in_buf, BUF_SIZE, 0);
  while ((retcode > 0) || (retcode == -1))
  {
    if (retcode == -1)
    {
      printf("ERROR - recv() failed \n");
      exit(1);
    }
    for (i=0; i<retcode; i++)
      printf ("%c", in_buf[i]);
    retcode = recv(server_s, in_buf, BUF_SIZE, 0);
  }

  // Close all open sockets
#ifdef WIN
  closesocket(server_s);
#endif
#ifdef BSD
  close(server_s);
#endif

#ifdef WIN
  // This stuff cleans-up winsock
  WSACleanup();
#endif
}
