blob: 9adbcac8664a8359d0e1db16f54099555cfc4197 [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include "hdhomerun_http.h"
#define HOST "google.com"
#define PAGE "/"
#define PORT 80
#define USERAGENT "SAGETV 1.0"
#define _MIN_(x,y) ((x)>(y)? (y):(x))
static char *get_ip(char *host, char* buf, int size)
{
struct hostent *hent;
char *ip = buf;
memset(ip, 0, size);
if((hent = gethostbyname(host)) == NULL)
{
herror("Can't get IP");
exit(1);
}
if(inet_ntop(AF_INET, (void *)hent->h_addr_list[0], ip, size) == NULL)
{
perror("Can't resolve host");
exit(1);
}
return ip;
}
static char *build_get_query(char *host, char *page)
{
char *query;
char *getpage = page;
char *tpl = "GET /%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n";
if(getpage[0] == '/'){
getpage = getpage + 1;
}
// -5 is to consider the %s %s %s in tpl and the ending \0
query = (char *)malloc(strlen(host)+strlen(getpage)+strlen(USERAGENT)+strlen(tpl)-5);
sprintf(query, tpl, getpage, host, USERAGENT);
return query;
}
int parse_http_page( char* host, char* page, parser_f parser, void* context )
{
struct sockaddr_in *remote;
int ret;
char buf[BUFSIZ+1];
int sock;
char *get;
char ip[32];
if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
perror("Can't create TCP socket");
return -1;
}
get_ip( host, ip, sizeof( ip ) );
remote = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in *));
remote->sin_family = AF_INET;
ret = inet_pton(AF_INET, ip, (void *)(&(remote->sin_addr.s_addr)));
if( ret < 0) {
perror("Can't set remote->sin_addr.s_addr");
return -1;
}else if(ret == 0) {
fprintf(stderr, "%s is not a valid IP address\n", ip);
return -1;
}
remote->sin_port = htons(PORT);
if(connect(sock, (struct sockaddr *)remote, sizeof(struct sockaddr)) < 0){
perror("Could not connect");
return -1;
}
get = build_get_query(host, page);
//send the query to the server
int sent = 0;
while(sent < strlen(get))
{
ret = send(sock, get+sent, strlen(get)-sent, 0);
if(ret == -1){
perror("Can't send query");
break;
}
sent += ret;
}
//recieve page
int remain = 0;
while( (ret = recv(sock, buf+remain, BUFSIZ-remain, 0)) > 0 ) {
int used_bytes = 0;
if ( parser != NULL && ret >= 0 ) {
*(buf+remain+ret) = 0x0;
used_bytes = parser( context, buf, ret+remain );
remain = ret+remain - used_bytes;
if ( remain > 0 )
memcpy( buf, buf+used_bytes, remain );
}
if ( used_bytes < 0 )
break;
}
free(get);
free(remote);
close(sock);
return 1;
}
#ifdef HTTP_GET_APP
static void usage()
{
fprintf(stderr, "USAGE: htmlget host [page]\n\
\thost: the website hostname. ex: coding.debuntu.org\n\
\tpage: the page to retrieve. ex: index.html, default: /\n");
}
static int noop_parser( void* context, char* buf, int bytes )
{
printf( "%s", buf );
return bytes;
}
int main(int argc, char **argv)
{
char *host;
char *page;
if(argc == 1){
usage();
exit(2);
}
host = argv[1];
if(argc > 2){
page = argv[2];
}else{
page = PAGE;
}
parse_http_page( host, page, noop_parser, NULL );
return 0;
}
#endif