grabimage.c
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
struct in_addr addr;
char *path;
} webpic;
void line(int sock, char *buf);
webpic process_arg(char *arg);
void recieve(int sock, void *buf, int len);
void transmit(int sock, char *msg);
int main (int argc, char *argv[]) {
int sock, ilen;
webpic image;
struct sockaddr_in connto;
char message[1024], buffer[4096]={0}, *ptr;
void *img_data;
FILE *out;
if (argc < 2) { puts("Grab what image?"); return -1;}
image = process_arg(argv[1]);
connto.sin_family=AF_INET;
connto.sin_port=htons(80);
connto.sin_addr.s_addr=image.addr.s_addr;
memset(&(connto.sin_zero),0,8);
sprintf(message, "%s", inet_ntoa(image.addr));
printf("Connecting to %s...",message);
if ((sock=socket(PF_INET,SOCK_STREAM,0))==-1) perror("socket");
if (connect(sock,(struct sockaddr*)&connto,sizeof(struct sockaddr))==-1) {
perror("!connect");
return -3;
}
printf("success:\n\n");
sprintf(message,"GET /%s HTTP/1.0\r\n\r\n",image.path);
transmit(sock,message);
while (buffer[0]!='\r') {
line(sock,buffer);
if (strncasecmp(buffer,"Content-Length:",15)==0) {
sscanf(&buffer[16],"%d",&ilen);
}
printf(" %s\n", buffer);
}
img_data = malloc(ilen);
recieve(sock,img_data,ilen);
if ((ptr = strrchr(image.path,'/'))==NULL) ptr=image.path;
else ptr++;
out = fopen(ptr,"wb");
fwrite(img_data,ilen,1,out);
printf("Image copied to %s\n\n",ptr);
return 0;
}
void line(int sock, char *buf) {
char ch;
int i=0;
while(recv(sock,&ch,1,0)) {
if (ch=='\n') {
buf[i] = '\0';
return;
}
buf[i++]=ch;
}
}
void recieve(int sock, void *buf, int len) {
int done = 0, todo = len;
while (todo>0) {
if ((done=recv(sock,buf,todo,0))==-1) {
perror("recv");
exit (-5);
}
todo -= done;
buf += done;
}
}
void transmit(int sock, char *msg) {
int done, todo=strlen(msg);
while (todo>0) {
if ((done=send(sock,msg,todo,0))==-1) {
perror("send");
exit (-4);
}
todo-=done;
msg+=done;
}
}
webpic process_arg(char *arg) {
webpic data;
struct hostent *info;
struct in_addr *ptr;
data.path = strchr(arg,'/');
data.path[0] = 0;
data.path++;
if ((info=gethostbyname(arg))==NULL) {
printf("gethostbyname fail: %d\n",h_errno);
exit (-2);
}
ptr = (struct in_addr*)(info->h_addr);
data.addr.s_addr = ptr->s_addr;
return data;
}