Created
August 19, 2016 19:33
-
-
Save asutoshpalai/46a45cb7d7d3202877a361a33f3b0db3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <fcntl.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <stdbool.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <netdb.h> | |
#include <unistd.h> | |
#include <sys/types.h> | |
char *get(char *, int); | |
void open_file(char *dest); | |
int main() { | |
char *url = NULL; | |
int len; | |
getline(&url, &len, stdin); | |
char *tmp = strchr(url, '\n'); | |
if(tmp != NULL) | |
*tmp = '\0'; | |
char *dest = get(url, len); | |
if(dest != NULL) { | |
open_file(dest); | |
} | |
free(dest); | |
} | |
char *fetch(char *host, int port, char* loc); | |
char *get(char * url, int len) { | |
int port = 80; | |
char *host, *location; | |
char *proto_excluded = strstr(url, "//"); | |
if(proto_excluded != NULL) | |
proto_excluded += 2; | |
else | |
proto_excluded = url; | |
location = strchr(proto_excluded, '/'); | |
int host_length; | |
if(location == NULL) | |
host_length = strlen(proto_excluded); | |
else | |
host_length = location - proto_excluded; | |
host = malloc(sizeof(char) * (host_length + 1)); | |
strncpy(host, proto_excluded, host_length); | |
host[host_length] = '\0'; | |
char *ptr = strchr(host, ':'); | |
if(ptr != NULL) { | |
port = atoi(ptr + 1); | |
*ptr = '\0'; | |
host_length -= strlen(ptr + 1); | |
} | |
char *dest; | |
if(location == NULL) { | |
dest = fetch(host, port, "/"); | |
} | |
else { | |
dest = fetch(host, port, location); | |
} | |
free(host); | |
return dest; | |
} | |
void open_file(char *dest) { | |
pid_t child = fork(); | |
if(child < 0) { | |
perror("Error forking"); | |
} | |
else if(child == 0) { | |
int devNull = open("/dev/null", O_WRONLY); | |
dup2(devNull, STDOUT_FILENO); | |
dup2(devNull, STDERR_FILENO); | |
close(devNull); | |
execl("/usr/bin/xdg-open", "xdg-open", dest, (char *)0); | |
exit(0); | |
} | |
else { | |
wait(); | |
} | |
} | |
char *fetch(char *host, int port, char* loc){ | |
printf("host: %s, port : %d, loc: %s\n", host, port, loc); | |
char tmpname[] = "/tmp/text_file"; | |
char *fileName = malloc(sizeof(char) * sizeof(tmpname)); | |
strcpy(fileName, tmpname); | |
int sockfd = 0; | |
const int buffSize = 1024; | |
char recvBuff[buffSize], sendBuff[buffSize]; | |
struct sockaddr_in serveraddr; | |
struct hostent *server; | |
sockfd = socket(AF_INET, SOCK_STREAM, 0); | |
if(sockfd < 0) { | |
perror("Failed to create socket\n"); | |
return NULL; | |
} | |
server = gethostbyname(host); | |
if (server == NULL) { | |
fprintf(stderr,"ERROR, no such host as %s\n", host); | |
return NULL; | |
} | |
bzero((char *) &serveraddr, sizeof(serveraddr)); | |
serveraddr.sin_family = AF_INET; | |
bcopy((char *)server->h_addr, | |
(char *)&serveraddr.sin_addr.s_addr, server->h_length); | |
serveraddr.sin_port = htons(port); | |
if (connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0) { | |
perror("Failed to connect to server\n"); | |
return NULL; | |
} | |
sprintf(sendBuff, "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n", loc, host); | |
int n = write(sockfd, sendBuff, strlen(sendBuff)); | |
if(n <= 0) { | |
perror("Failed to write to socket\n"); | |
return NULL; | |
} | |
FILE *fp = fopen(fileName, "w+"); | |
bool header_ended = false; | |
char *ptr; | |
while((n = read(sockfd, recvBuff, buffSize)) > 0) { | |
if(header_ended == false && (ptr = strstr(recvBuff, "\r\n\r\n")) != NULL) { | |
ptr = ptr + 4; | |
fwrite(ptr, sizeof(char), n - (ptr - recvBuff) + 1, fp); | |
header_ended = true; | |
} | |
else if(header_ended == true) { | |
fwrite(recvBuff, sizeof(char), n, fp); | |
} | |
} | |
fclose(fp); | |
return fileName; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment