1/* 2 * Copyright 2004, ASUSTek Inc. 3 * All Rights Reserved. 4 * 5 * THIS SOFTWARE IS OFFERED "AS IS", AND ASUS GRANTS NO WARRANTIES OF ANY 6 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 7 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 8 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 9 * 10 * $Id: http_ex.c,v 1.2 2008/10/24 03:32:30 james26_jang Exp $ 11 */ 12 13#include <stdio.h> 14#include <stdlib.h> 15#include <limits.h> 16#include <ctype.h> 17#include <string.h> 18#include <signal.h> 19#include <time.h> 20#include <unistd.h> 21#include <errno.h> 22#include <sys/socket.h> 23#include <netinet/in.h> 24#include <arpa/inet.h> 25#include <sys/types.h> 26#include <sys/stat.h> 27#include <fcntl.h> // 2008.04 for open(). 28#include <unistd.h> // 2008.04 for open(). 29 30#include <shutils.h> 31 32#ifdef ASUS 33#define PATH_MAX 256 34#endif 35 36/*#define dprintf printf*/ 37 38static char * 39base64enc(const char *p, char *buf, int len) 40{ 41 char al[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 42 "0123456789+/"; 43 char *s = buf; 44 45 while(*p) { 46 if (s >= buf+len-4) 47 break; 48 *(s++) = al[(*p >> 2) & 0x3F]; 49 *(s++) = al[((*p << 4) & 0x30) | ((*(p+1) >> 4) & 0x0F)]; 50 *s = *(s+1) = '='; 51 *(s+2) = 0; 52 if (! *(++p)) break; 53 *(s++) = al[((*p << 2) & 0x3C) | ((*(p+1) >> 6) & 0x03)]; 54 if (! *(++p)) break; 55 *(s++) = al[*(p++) & 0x3F]; 56 } 57 58 return buf; 59} 60 61enum { 62 METHOD_GET, 63 METHOD_POST 64}; 65 66static int 67waitsock(int fd, int sec, int usec) 68{ 69 struct timeval tv; 70 fd_set fdvar; 71 int res; 72 73 FD_ZERO(&fdvar); 74 FD_SET(fd, &fdvar); 75 tv.tv_sec = sec; 76 tv.tv_usec = usec; 77 res = select(fd+1, &fdvar, NULL, NULL, &tv); 78 79 return res; 80} 81 82static int 83wget(int method, const char *server, char *buf, size_t count, off_t offset) 84{ 85 char url[PATH_MAX] = { 0 }, *s; 86 char *host = url, *path = "", auth[128] = { 0 }, line[1024]; 87 unsigned short port = 80; 88 int fd; 89 FILE *fp; 90 struct sockaddr_in sin; 91 struct stat fstatus; 92 93 int chunked = 0, len = 0; 94 95 if(server == NULL || !strcmp(server, "")){ 96 dprintf("wget: null server input\n"); 97 return (0); 98 } 99 100 strncpy(url, server, sizeof(url)); 101 102 /* Parse URL */ 103 if(!strncmp(url, "http://", 7)){ 104 port = 80; 105 host = url+7; 106 } 107 if((s = strchr(host, '/'))){ 108 *s++ = '\0'; 109 path = s; 110 } 111 if((s = strchr(host, '@'))){ 112 *s++ = '\0'; 113 base64enc(host, auth, sizeof(auth)); 114 host = s; 115 } 116 if((s = strchr(host, ':'))){ 117 *s++ = '\0'; 118 port = atoi(s); 119 } 120 121 /* Open socket */ 122 if(!inet_aton(host, &sin.sin_addr)) 123 return 0; 124 sin.sin_family = AF_INET; 125 sin.sin_port = htons(port); 126 127 dprintf("Connecting to %s:%u...\n", host, port); 128 if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0 129 || connect(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0 130//#ifdef REMOVE 131 || !(fp = fdopen(fd, "r+")) 132//#endif 133 ){ 134 perror(host); 135 if(fd >= 0) 136 close(fd); 137 return 0; 138 } 139 dprintf("connected!\n"); 140 141 /* Send HTTP request */ 142 sprintf(line, "%s /%s HTTP/1.1\r\n", method == METHOD_POST?"POST":"GET", path); 143 sprintf(line, "%sHost: %s\r\n", line, host); 144 sprintf(line, "%sUser-Agent: wget\r\n", line); 145 if(strlen(auth)) 146 sprintf(line, "%sAuthorization: Basic %s\r\n", line, auth); 147 if(offset) 148 sprintf(line, "%sRange: bytes=%ld-\r\n", line, offset); 149 150 if(method == METHOD_POST){ 151 sprintf(line, "%sContent-Type: application/x-www-form-urlencoded\r\n", line); 152 sprintf(line, "%sContent-Length: %d\r\n\r\n", line, (int)strlen(buf)); 153 sprintf(line, "%s%s", line, buf); 154 } 155 else 156 sprintf(line,"%sConnection: close\r\n\r\n", line); 157 158 /* Check HTTP response */ 159 dprintf("HTTP request sent, awaiting response..\n"); 160 write(fd, line, strlen(line)); 161 162 if(waitsock(fd, 2, 0) && read(fd, line, sizeof(line))) 163 { 164 dprintf("%s", line); 165 // get message anyway 166 /*close(fd); 167 return 1;//*/ 168//#ifdef REMOVE 169 for(s = line; *s && !isspace((int)*s); s++) ; 170 for(; isspace((int)*s); s++) ; 171 switch(atoi(s)){ 172 case 200: 173 if(offset) 174 goto done; 175 else 176 break; 177 case 206: 178 if(offset) 179 break; 180 else 181 goto done; 182 default: 183 goto done; 184 } 185//#endif 186 } 187 else 188 { 189 close(fd); 190 return 0; 191 } 192 193//#ifdef REMOVE 194 /* Parse headers */ 195 while(fgets(line, sizeof(line), fp)){ 196 dprintf("%s", line); 197 for(s = line; *s == '\r'; s++) ; 198 if(*s == '\n') 199 break; 200 if(!strncasecmp(s, "Content-Length:", 15)){ 201 for(s += 15; isblank(*s); s++) ; 202 chomp(s); 203 len = atoi(s); 204 } 205 else if (!strncasecmp(s, "Transfer-Encoding:", 18)) { 206 for(s += 18; isblank(*s); s++) ; 207 chomp(s); 208 if(!strncasecmp(s, "chunked", 7)) 209 chunked = 1; 210 } 211 } 212 213 if(chunked && fgets(line, sizeof(line), fp)) 214 len = strtol(line, NULL, 16); 215 216 len = (len > count) ? count : len; 217 len = fread(buf, 1, len, fp); 218 219done: 220 /* Close socket */ 221 fflush(fp); 222 fclose(fp); 223 return len; 224//#endif 225} 226 227int 228http_check(const char *server, char *buf, size_t count, off_t offset) 229{ 230// 2008.04 James. { 231 //return wget(METHOD_GET, server, buf, count, offset); 232 233 char *pid_file = "/var/run/httpd.pid"; 234 char pid_buf[10], proc_path[32]; 235 int fd, pid; 236 struct stat f_st; 237 238 if((fd = open(pid_file, O_RDONLY)) <= 0) 239 return 0; 240 memset(pid_buf, 0, sizeof(pid_buf)); 241 read(fd, pid_buf, sizeof(pid_buf)); 242 close(fd); 243 if((pid = atoi(pid_buf)) <= 0) 244 return 0; 245 246 memset(proc_path, 0, sizeof(proc_path)); 247 sprintf(proc_path, "/proc/%d", pid); 248 249 lstat(proc_path, &f_st); 250 if(!S_ISDIR(f_st.st_mode)) 251 return 0; 252 253 return 1; 254// 2008.04 James. } 255} 256