#include #include #include #include #include #include #include #include int connect_to_server(const char* hostname, unsigned short port) { int fd; struct sockaddr_in in; struct hostent *hp; if((hp = gethostbyname(hostname)) == NULL) { perror("gethostbyname"); exit(1); } memset(&in, 0, sizeof(in)); in.sin_family = AF_INET; in.sin_port = htons(port); memcpy(&in.sin_addr, hp->h_addr, hp->h_length); if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); exit(1); } if(connect(fd, (struct sockaddr *)&in, sizeof(in)) < 0) { perror("connect"); exit(1); } return fd; } int parse_url(const char* url, char* host, unsigned short* port, char* filename) { *port = 0; if(strncmp(url, "http://", 7) != 0) return 0; url += 7; if(!*url) return 0; while(*url && *url != '/' && *url != ':') *host++ = *url++; *host = '\0'; if(*url == ':') { url++; *port = atoi(url); while(*url && *url != '/') url++; } while(*url) *filename++ = *url++; *filename = '\0'; return 1; } char* truncate_newline(char* s) { int len = strlen(s); if(len < 2) { if(len == 0) return s; if(s[0] == '\n' || s[0] == '\r') s[0] = '\0'; return s; } if(s[len - 1] == '\n') s[--len] = '\0'; if(s[len - 1] == '\r') s[--len] = '\0'; return s; } int main(int argc, char** argv) { int fd; FILE* fp; char hostname[BUFSIZ]; char filename[BUFSIZ]; char buff[BUFSIZ]; int n; struct servent* sp; unsigned short port; char* url; int doc = 0; if(argc == 3 && !strcmp(argv[1], "-d")) { doc = 1; url = argv[2]; } else if(argc == 2) { url = argv[1]; } else { fprintf(stderr, "Usage: httpget [-d] URL\n"); return 1; } if(strlen(url) >= BUFSIZ) { fprintf(stderr, "URL is too long.\n"); return 1; } if(parse_url(url, hostname, &port, filename) == 0) { fprintf(stderr, "Invalid URL:%s\n", url); return 1; } if(port == 0) { sp = getservbyname("http", "tcp"); if(sp == NULL) { /* fprintf(stderr, "WARNING http/tcp: unknown service\n"); */ port = 80; } else port = sp->s_port; } fd = connect_to_server(hostname, port); if((fp = fdopen(fd, "r")) == NULL) { perror("fdopen"); return 1; } write(fd, "GET ", 4); write(fd, filename, strlen(filename)); write(fd, " HTTP/1.0\r\n\r\n", 13); if(doc) { do { if(fgets(buff, BUFSIZ, fp) == NULL) { fprintf(stderr, "No documentation.\n"); fclose(fp); close(fd); return 1; } truncate_newline(buff); } while(buff[0] != '\0'); } while((n = fread(buff, 1, BUFSIZ, fp)) > 0) fwrite(buff, 1, n, stdout); fclose(fp); close(fd); return 0; }