#include <stdio.h>
#include <stdlib.h>

#define __USE_GNU
#include <string.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <ctype.h>

#include <errno.h>

#define WWW_PORT	80

//--------------------------------------------------------------------------
// Print an error message to stderr and terminate the program immediately
void
printerror(char *pcErrStr)
{
    fprintf(stderr, "ERROR: %s\n\n", pcErrStr);
    exit(1);
}

//--------------------------------------------------------------------------
// Input parameters are the name of the server to query and a pointer to a
// sockaddr_in structure to fill.  The function performs a lookup of the
// specified Internet name and stores the address along with the web port
// number (WWW_PORT) in the provided sockaddr_in structure
void
FillAddress(char *pcURL, struct sockaddr_in *psAddress)
{
    struct hostent      *psHostDetails;

    if ((psHostDetails = gethostbyname(pcURL)) == NULL) printerror("Can't determine address of website");

    memcpy(&(psAddress->sin_addr), psHostDetails->h_addr_list[0], 4);
    psAddress->sin_family = AF_INET;
    psAddress->sin_port = htons(WWW_PORT);

    printf("Server details:\n");
    printf("  Server:\t%s\n", pcURL);
    printf("  IP Address:\t%s\n", inet_ntoa(psAddress->sin_addr)); //Convert to human readable string
}

//--------------------------------------------------------------------------
int
main(int iArgC, char **ppcArgV)
{
    struct sockaddr_in  sAddress;
    char                *pcWWWServer, *pcPage, *pcPos;

    if (iArgC != 2) printerror("Command Line requires one parameter = website");

    // If the provided URL begins with "http://" then set pcWWWServer to point
    // to the next character otherwise set it to point to the entire provided URL
	//
	// strstr() - find a string in another string. return the first position
    if (pcWWWServer = strstr(ppcArgV[1], "http://")) 
        pcWWWServer+= 7;  //skip our pointer pcWWWServer forward 7 characters. Past the "http://"
    else 
        pcWWWServer = ppcArgV[1]; //It doesnt have http://, just grab the pointer to the string


	//Work out what the page part of the path is
    // If there is a "/" in the URL (after the http:// has been stripped) then 
    // replace it with a 0 so the string terminates as just the name.  Create 
    // a new string pointer (pcPage) to be a copy of the remaining string OR
    // just "/" if no page details have been provided
	//
	// strstr() - find a string in another string. return the first position
	// strdup() - duplicate a string, return a pointer to a new string that's a copy. New memory!
    if (pcPos = strstr(pcWWWServer, "/"))
    {
        pcPage = strdup(pcPos);
        pcPos[0] = 0; //We're splitting the original string by doing this. But entering a null
    } else
        pcPage = strdup("/");

    // Call FillAddress() to fill sAddress with the IP address details (and port
    // number 80) of the requested URL
	//
	//              INPUT      OUTPUT
    FillAddress(pcWWWServer, &sAddress);


    /* Download The Webpage */

    char bufferAllOfPage[1000000];
    bzero(bufferAllOfPage, sizeof(bufferAllOfPage));

    int sockfd;        
    char buffer[1024]; 
    int bytes_read;    

    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        printerror("Socket error");

    if( connect(sockfd, (struct sockaddr*)&sAddress, sizeof(sAddress)) != 0)
        printerror("Couldn't connect");

    sprintf(buffer, "GET %s HTTP/1.0\nHost: %s\n\n", pcPage, pcWWWServer);
    send(sockfd, buffer, strlen(buffer), 0);

    do
    {
        bzero(buffer, sizeof(buffer));
        bytes_read = recv(sockfd, buffer, sizeof(buffer), 0);
        if( bytes_read > 0)
        {
            strncat(bufferAllOfPage, buffer, bytes_read);
        }
    }
    while ( bytes_read > 0);

    close(sockfd);



    /* Now lets try and parse out the links and images */

    int i = 0;
    while(bufferAllOfPage[i])
    {
        bufferAllOfPage[i] = tolower(bufferAllOfPage[i]);
        i++;
    }

    printf("\nLooking for Links:\n");

    char *posStartLink;
    char *posEndLink;
    char *placeToStartLooking;

    placeToStartLooking = bufferAllOfPage;
    do
    {
        posStartLink = strstr(placeToStartLooking, " href=\"");
        if(posStartLink)
        {
            posStartLink += 7; 
            posEndLink  = strstr(posStartLink, "\""); 
        }

        if(posStartLink && posEndLink)
        {
            int linkLength;
            char linkBuf[1000];
            linkLength = posEndLink - posStartLink; 
            strncpy(linkBuf, posStartLink, linkLength);
            linkBuf[linkLength] = 0;

            printf("%s\n", linkBuf);

            placeToStartLooking = posEndLink;
        }
        else
            break;
    }
    while(posEndLink <= (bufferAllOfPage + strlen(bufferAllOfPage)) );



    return 0;
}
