/***************************************************************************
Name:          getpage.c
Autor:         www.c-worker.ch
Beschreibung:  Zeigt die Antwort des Webservers auf eine bestimmte URL an
               oder lädt wahlweise die Site in eine Datei herunter.
Return Code:   0 = ok,  >0 oder <0 = Fehler

----------------------------------------------------------------------------
Aus RFC 1945, HTTP/1.0:
Full-Response  = Status-Line
                 *( General-Header
                  | Response-Header
                  | Entity-Header )
                 CRLF   (ich gehe in diesem Code davon aus es handelt sich um \x0D\x0A\x0D\x0A)
                 [ Entity-Body ]

****************************************************************************/

#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>

void perr_exit(char* msg, int ret_code)
{
  printf("%s, Error: ",msg);
  printf("%d\n",ret_code);
  exit(ret_code);
}

void usage(char* prgname)
{
  printf("\nUsage:\t");
  printf("%s <URL> [<File>]\n",prgname);
  printf("\tURL:  Website URL\n");
  printf("\tFile: Optional File to store the Website\n");
  exit(0);
}

int main(int argc, char** argv)
{
  char* url;
  char* site;
  char* host;
  char  buf[1024];
  char  send_buf[256];
  char  recv_buf[256];
  long  rc;
  FILE* target_file;
  char  uses_file=0;
  char* write_ptr;
  SOCKET s;
  SOCKADDR_IN addr;
  WSADATA wsa;
  HOSTENT* hent;

  if(WSAStartup(MAKEWORD(2,0),&wsa))
    perr_exit("WSAStartup failed",WSAGetLastError());

  addr.sin_family=AF_INET;
  addr.sin_port=htons(80);

  if(argc<2)
  {
    printf("\nURL: ");
    scanf("%s",buf);
    url=buf;
  }
  else
  {
    if(strcmp(argv[1],"/?")==0 ||
    strcmp(argv[1],"/help")==0 ||
    strcmp(argv[1],"/h")==0 ||
    strcmp(argv[1],"--help")==0 ||
    strcmp(argv[1],"-h")==0)
      usage(argv[0]);

    url=argv[1];
  }
  if(argc>2)
  {
    if(!(target_file=fopen(argv[2],"w")))
    {
      printf("Cannot open File ");
      perr_exit(argv[2],GetLastError());
    }
    uses_file=1;
  }

  if(strncmp("http://",url,7)==0)
    host=url+7;
  else
    host=url;

  if((site=strchr(host,'/'))!=0)
    *site++='\0';
  else
    site=host+strlen(host); /* \0 */

  printf("Host: %s\n",host);
  printf("Site: %s\n",site);
  printf("Connecting....\n");

  if((addr.sin_addr.s_addr=inet_addr(host))==INADDR_NONE)
  {
    if(!(hent=gethostbyname(host)))
      perr_exit("Cannot resolve Host",WSAGetLastError());

    strncpy((char*)&addr.sin_addr.s_addr,hent->h_addr,4);

    if(addr.sin_addr.s_addr==INADDR_NONE)
      perr_exit("Cannot resolve Host",WSAGetLastError());
  }

  if((s=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET)
    perr_exit("Cannot create Socket",WSAGetLastError());

  if( connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)))
    perr_exit("Cannot connect",WSAGetLastError());

  printf("Connected to %s...\n",host);

  sprintf(send_buf,"GET /%s HTTP/1.0\nUser-Agent: Visit www.c-worker.ch!\n\n",site);

  if((send(s,send_buf,strlen(send_buf),0))<strlen(send_buf))
    perr_exit("Cannot send Data",WSAGetLastError());

  if(uses_file)
    printf("Downloading Page to File %s...",argv[2]);                                  
  else
    printf("----Result----\n");

  while((rc=recv(s,recv_buf,255,0))>0)
  {
    recv_buf[rc]='\0';
    if(uses_file)
    {
      if(uses_file==1)
      {
        /* web server info nicht in Datei speichern */
        if((write_ptr=strstr(recv_buf,"\x0D\x0A\x0D\x0A"))>0)
        {
          uses_file=2;
          write_ptr+=4;
        }
      }
      else
        write_ptr=recv_buf;
      if(uses_file==2)
      {
        if( fwrite(write_ptr,1, rc-(write_ptr-recv_buf), target_file)<rc-(write_ptr-recv_buf))
          fclose(target_file);
      }
    }
    else /* uses_file */
      printf("%s",recv_buf);
  }

  printf("\nDONE!");
  if(uses_file)
    fclose(target_file);
  closesocket(s);
  return 0;
}
