#include #include #include #include #include #include #include #include #include #include #include int webclient(char* url, unsigned short jumps) { if (jumps > 5) { fprintf(stderr, "D'OH! Too many jumps, my legs hurts!\n"); return 1; } if (strstr(url, "://") != NULL) { url = strstr(url, "://") + strlen("://"); } char* parsedhost = url; char* parsedport = "80"; char* parsedurl = ""; char* parsedfile = "index.htm"; unsigned int i = 0; while (url[i] != '\0') { if (url[i] == ':') { url[i] = '\0'; parsedport = url + i + 1; } if (url[i] == '/') { url[i] = '\0'; parsedurl = url + i + 1; i++; while (url[i] != '\0') { if (url[i] == '/') { parsedfile = url + i + 1; } i++; } break; } i++; } if (strlen(parsedurl) < 1) { parsedurl = ""; } //printf("Host: %s\nPort: %s\nURL: %s\nFile: %s\n", parsedhost, parsedport, parsedurl, parsedfile); //DEBUG int s = socket(PF_INET, SOCK_STREAM, 0); if (s < 0) { fprintf(stderr, "D'OH! Broken socket, call electrician.\n"); return 1; } struct sockaddr_in sadr; bzero(&sadr, sizeof(sadr)); //radsi to vynulujem sadr.sin_family = AF_INET; //rodina struct hostent *host; if ((host = gethostbyname(parsedhost)) == NULL) { fprintf(stderr, "D'OH! Unknown host.\n"); return 1; } memcpy(&sadr.sin_addr, host->h_addr, host->h_length); //adresa sadr.sin_port = htons(atoi(parsedport)); if (connect(s, (struct sockaddr*) &sadr, sizeof(sadr)) < 0) { fprintf(stderr, "D'OH! Server is dead.\n"); return 1; } printf("Connected!\n"); printf("Negotiating...\n"); char* get = NULL; if (parsedurl == NULL) { parsedurl = ""; } //printf("Processing HTTP GET...\n"); get = malloc((strlen("GET /") + strlen(parsedurl) + strlen(" HTTP/1.0\r\nHost: ") + strlen(parsedhost) + strlen("\r\n\r\n")) * sizeof(char)); if (get == NULL) { fprintf(stderr, "D'OH! Malloc fail, buy more RAM!\n"); return 1; } get[0] = '\0'; strcat(get, "GET /"); strcat(get, parsedurl); strcat(get, " HTTP/1.0\r\nHost: "); strcat(get, parsedhost); strcat(get, "\r\n\r\n"); //printf("%s\n", get); if ((write(s, get, strlen(get))) <= 0) { fprintf(stderr, "D'OH! Can't write.\n"); if (parsedurl != NULL) { free(get); } return 1; } if (parsedurl != NULL) { free(get); } printf("Reading...\n"); char* header; unsigned int allocated = 1; unsigned int dumped = 0; header = malloc(allocated * sizeof(char)); if (header == NULL) { fprintf(stderr, "D'OH! Malloc fail, buy me more memory!\n"); return 1; } while (strstr(header, "\r\n\r\n") == NULL) { read(s, header + dumped, 1); dumped++; if (dumped >= allocated) { allocated *= 2; header = realloc(header, allocated); if (header == NULL) { fprintf(stderr, "D'OH! Realloc fail, buy me more memory!\n"); return 1; } } } //printf("Header:\n%s", header); unsigned int response = atoi(header + 9); printf("Response: %d\n", response); char* location = NULL; if (response >= 300 && response < 400) { location = strstr(header, "Location: ") + strlen("Location: "); i = 0; while (location[i] != '\r') { i++; } location[i] = '\0'; //printf("\nLocation: %s\n", location); } if (response == 200) { //printf("Socket -> %s...\n", parsedfile); printf("Downloading...\n"); FILE* fp = fopen(parsedfile, "w"); if (fp == NULL) { fprintf(stderr, "D'OH! I don't know where to write, buy me some paper!\n"); free(header); return 1; } char socketchar[1]; while (read(s, socketchar, 1) > 0) { fwrite(socketchar, sizeof(char), 1, fp); } fclose(fp); } if (response >= 300 && response < 400) { printf("Redirected...\n"); webclient(location, ++jumps); } free(header); shutdown(s, 2); close(s); return 0; } int main(int argc, char* argv[]) { if (argc > 2) { fprintf(stderr, "D'OH! Too many parameters.\n"); return 1; } if (argc == 1) { printf("USAGE: webclinet URL\n"); return 0; } return webclient(argv[1], 0); }