1#include <stdio.h> 2#include <unistd.h> 3#include <stdlib.h> 4#include <string.h> 5#include <ctype.h> 6#include <limits.h> 7#include <sys/socket.h> 8#include <netinet/in.h> 9#include <netinet/ip.h> 10#include <netinet/ip_icmp.h> 11#include <arpa/inet.h> 12#include <netdb.h> 13#include "shutils.h" 14 15int waitsock(int fd, int sec, int usec){ 16 struct timeval tv; 17 fd_set fdvar; 18 int res; 19 20 FD_ZERO(&fdvar); 21 FD_SET(fd, &fdvar); 22 tv.tv_sec = sec; 23 tv.tv_usec = usec; 24 res = select(fd+1, &fdvar, NULL, NULL, &tv); 25 26 return res; 27} 28 29char *base64enc(const char *p, char *buf, int len){ 30 char al[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 31 char *s = buf; 32 33 while(*p){ 34 if(s >= buf+len-4) 35 break; 36 37 *(s++) = al[(*p>>2)&0x3F]; 38 *(s++) = al[((*p<<4)&0x30)|((*(p+1)>>4)&0x0F)]; 39 *s = *(s+1) = '='; 40 *(s+2) = 0; 41 if(!*(++p)) 42 break; 43 *(s++) = al[((*p<<2)&0x3C)|((*(p+1)>>6)&0x03)]; 44 if(!*(++p)) 45 break; 46 *(s++) = al[*(p++)&0x3F]; 47 } 48 49 return buf; 50} 51 52int wgetToFile(const char *const server, const char *const filename){ 53 char url[PATH_MAX], *s; 54 char *host = url, *path = "", auth[128], line[PATH_MAX]; 55 unsigned short port = 80; 56 int fd, len = 0; 57 FILE *np, *fp; 58 struct sockaddr_in sin; 59 struct hostent *hostaddr; 60 unsigned long ul_hostip; 61 int i; 62 63 memset(url, 0, PATH_MAX); 64 strncpy(url, server, PATH_MAX); 65 66 // Parse URL 67 if(!strncmp(url, "http://", 7)){ 68 port = 80; 69 host = url+7; 70 } 71 if((s = strchr(host, '/'))){ 72 *s++ = '\0'; 73 path = s; 74 } 75 if((s = strchr(host, '@'))){ 76 *s++ = '\0'; 77 base64enc(host, auth, sizeof(auth)); 78 host = s; 79 } 80 if((s = strchr(host, ':'))){ 81 *s++ = '\0'; 82 port = atoi(s); 83 } 84 printf("host: %s!\n", host); 85 // Open socket 86 if((ul_hostip = inet_addr(host)) != INADDR_NONE){ 87 //printf("1.\n"); 88 sin.sin_addr.s_addr = ul_hostip; 89 } 90 else if((hostaddr = gethostbyname(host)) != NULL){ 91 //printf("2.\n"); 92 memcpy(&sin.sin_addr, hostaddr->h_addr, sizeof(sin.sin_addr)); 93 } 94 else{ 95 printf("Failed to get host, %s!\n", host); 96 return -1; 97 } 98 99 sin.sin_family = AF_INET; 100 sin.sin_port = htons(port); 101 102 printf("\nConnecting to %s:%u...\n", host, port); 103 if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0 104 || connect(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0 105 || !(np = fdopen(fd, "r")) 106 ){ 107 perror(host); 108 if(fd >= 0) 109 close(fd); 110 return -1; 111 } 112 printf("connected!\n\n"); 113 114 // Send HTTP request 115 memset(line, 0, PATH_MAX); 116 sprintf(line, "GET /%s HTTP/1.0\r\n", path); 117 sprintf(line, "%sUser-Agent: wget\r\n", line); 118 sprintf(line, "%sHost: %s\r\n", line, host); 119 sprintf(line, "%sAccept: */*\r\n", line); 120 if(strlen(auth) > 0) 121 sprintf(line, "%sAuthorization: Basic %s\r\n", line, auth); 122 sprintf(line, "%sConnection: close\r\n\r\n", line); 123 //sprintf(line, "%sConnection: Keep-Alive\r\n\r\n", line); 124 125 // Check HTTP response 126 printf("wrote the request:\n"); 127 printf("******************************\n"); 128 printf("%s", line); 129 printf("******************************\n");//*/ 130 write(fd, line, strlen(line)); 131 132 //printf("Got header:\n"); 133 //printf("******************************\n"); 134 if(waitsock(fd, 2, 0) && fgets(line, sizeof(line), np)){ 135 //printf("%s", line); 136 for(s = line; *s && !isspace((int)*s); s++) 137 ; 138 139 for(; isspace((int)*s); s++) 140 ; 141 142 switch(atoi(s)){ 143 case 200: 144 break; 145 case 206: 146 printf("Failed to get the page!\n"); 147 goto done; 148 default: 149 printf("Exceptionable error!\n"); 150 goto done; 151 } 152 } 153 else{ 154 printf("Failed to get the page!\n"); 155 close(fd); 156 return -1; 157 } 158 159 while(fgets(line, sizeof(line), np)) 160 if(strlen(line) == 2) 161 break; 162 //printf("******************************\n\n"); 163 if(line == NULL || strlen(line) <= 0){ 164 printf("Failed to get the page!\n"); 165 goto done; 166 } 167 168 printf("Got content:\n"); 169 //printf("******************************\n"); 170 if((fp = fopen(filename, "w+")) != NULL){ 171 //printf("Wrote the file, %s...\n", filename); 172 i = 0; 173 while(fgets(line, sizeof(line), np)){ 174 //printf("%s", line); 175 //printf("wrote %d rows: ", ++i); 176 fputs(line, fp); 177 //printf("ok!\n"); 178 } 179 //printf("Finished!\n");//*/ 180 fclose(fp); 181 } 182 //printf("******************************\n\n"); 183 printf("Ok!\n"); 184 185done: 186 // Close socket 187 fflush(np); 188 fclose(np); 189 return len; 190} 191 192int main(int argc, char *argv[]){ 193 if(argc != 3){ 194 fprintf(stderr, "usage: wget [url] [outpur file]\n"); 195 return -1; 196 } 197 198 wgetToFile(argv[1], argv[2]); 199 200 return 0; 201} 202