#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>

#define BUF_LEN 4096
#define BLOCK_SIZE 4096

int main (int argc, char *argv[]) {

    int sfd, fd, bytes;
    char buf[BUF_LEN];
    struct addrinfo *res;

    if (argc != 3) {
	fprintf (stderr, "Usage: %s remote_file local_file\nremote_file must be an absolute path.\n", argv[0]);
	exit (1);
    }
    //open the file to be saved (local file)
    fd = open (argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0777);
    if (fd == -1) {
	perror ("open()");
	exit (1);
    }
    
    sfd = socket (AF_INET, SOCK_STREAM, 0);
    if (sfd == -1) {
	perror ("socket()");
	exit (1);
    }
    //get the address information of the server
    if (getaddrinfo ("localhost", "4096", NULL, &res) != 0) {
	fprintf (stderr, "getaddrinfo() failed.\n");
	exit (1);
    }
    //connect to the server
    if (connect (sfd, res->ai_addr, res->ai_addrlen) != 0) {
	perror ("connect()");
	exit (1);
    }
    //send filename to server
    if (write (sfd, argv[1], strlen (argv[1])) < strlen (argv[1])) {
	perror ("write()");
	exit (1);
    }
    //now read from server
    while (1) {
	
	bytes = read (sfd, buf, BLOCK_SIZE);
	if (bytes == -1) {
	    perror ("read()");
	    exit (1);
	}
	// write data read to the local file.
	if (write (fd, buf, bytes) < bytes) {
	    perror ("write()");
	    exit (1);
	}
	if (bytes < BLOCK_SIZE) // no more to read
	    break;
	else
	    continue; //ha ha
    }
    return 0;
}

