1/* 2 * Copyright 2004-2008, Fran��ois Revol, <revol@free.fr>. 3 * Distributed under the terms of the MIT License. 4 */ 5 6#include <OS.h> 7#include <KernelExport.h> 8#include <stdio.h> 9#include <stdlib.h> 10#include <string.h> 11#include <netinet/in.h> 12#include <arpa/inet.h> 13#include <malloc.h> 14#include <sys/socket.h> 15#include "http_cnx.h" 16#include "googlefs.h" 17#include "google_request.h" 18#include "lists2.h" 19#include "settings.h" 20#include "string_utils.h" 21 22#define DO_PUBLISH 23//#define FAKE_INPUT "/boot/home/devel/drivers/googlefs/log2.html" 24 25//#define TESTURL "http://www.google.com/search?as_q=google+api+&num=50&hl=en&ie=ISO-8859-1&btnG=Google+Search&as_epq=frequently+asked&as_oq=help&as_eq=plop&lr=lang_en&as_ft=i&as_filetype=&as_qdr=m3&as_nlo=&as_nhi=&as_occt=any&as_dt=i&as_sitesearch=" 26 27//#define BASEURL "http://www.google.com/search?as_q=" 28//#define Q "google+api+" 29//#define EXTRAURL "&num=50&hl=en&ie=ISO-8859-1&btnG=Google+Search&as_epq=frequently+asked&as_oq=help&as_eq=plop&lr=lang_en&as_ft=i&as_filetype=&as_qdr=m3&as_nlo=&as_nhi=&as_occt=any&as_dt=i&as_sitesearch=" 30 31#define TESTURL "http://www.google.com/search?hl=en&ie=UTF-8&num=50&q=beos" 32//#define BASEURL "http://www.google.com/search?hl=en&ie=UTF-8&num=50&q=" 33#define BASEURL "/search?hl=en&ie=UTF-8&oe=UTF-8" 34#define FMT_NUM "&num=%u" 35#define FMT_Q "&q=%s" 36 37/* parse_google_html.c */ 38extern int google_parse_results(const char *html, size_t htmlsize, struct google_result **results); 39 40// move that to ksocket inlined 41static int kinet_aton(const char *in, struct in_addr *addr) 42{ 43 int i; 44 unsigned long a; 45 uint32 inaddr = 0L; 46 const char *p = in; 47 for (i = 0; i < 4; i++) { 48 a = strtoul(p, (char **)&p, 10); 49 if (!p) 50 return -1; 51 inaddr = (inaddr >> 8) | ((a & 0x0ff) << 24); 52 *(uint32 *)addr = inaddr; 53 if (!*p) 54 return 0; 55 p++; 56 } 57 return 0; 58} 59 60 61status_t google_request_init(void) 62{ 63 status_t err; 64 err = http_init(); 65 return err; 66} 67 68status_t google_request_uninit(void) 69{ 70 status_t err; 71 err = http_uninit(); 72 return err; 73} 74 75status_t google_request_process(struct google_request *req) 76{ 77 struct sockaddr_in sin; 78 struct http_cnx *cnx = NULL; 79 struct google_result *res; 80 status_t err; 81 int count; 82 char *p = NULL; 83 char *url = NULL; 84 85 err = http_create(&cnx); 86 if (err) 87 return err; 88 err = ENOMEM; 89 req->cnx = cnx; 90#ifndef FAKE_INPUT 91 sin.sin_len = sizeof(struct sockaddr_in); 92 sin.sin_family = AF_INET; 93 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 94 if (kinet_aton(google_server, &sin.sin_addr) < 0) 95 goto err_cnx; 96 sin.sin_port = htons(google_server_port); 97 err = http_connect(cnx, &sin); 98 dprintf("google_request: http_connect: error 0x%08lx\n", err); 99 if (err) 100 goto err_cnx; 101 102 err = ENOMEM; 103 p = urlify_string(req->query_string); 104 if (!p) 105 goto err_con; 106 107 err = ENOMEM; 108 url = malloc(strlen(BASEURL)+strlen(FMT_NUM)+10+strlen(FMT_Q)+strlen(p)+2); 109 if (!url) 110 goto err_url; 111 strcpy(url, BASEURL); 112 sprintf(url+strlen(url), FMT_NUM, (unsigned int)max_results); 113 sprintf(url+strlen(url), FMT_Q, p); 114 115 dprintf("google_request: final URL: %s\n", url); 116 117 err = http_get(cnx, url); 118 dprintf("google_request: http_get: error 0x%08lx\n", err); 119 if (err < 0) 120 goto err_url2; 121 dprintf("google_request: http_get: HEADERS %ld:%s\n", cnx->headerslen, cnx->headers); 122 //dprintf("DATA: %d:%s\n", cnx->datalen, cnx->data); 123 124 dprintf("google_request: buffer @ %p, len %ld\n", cnx->data, cnx->datalen); 125 { 126 int fd; 127 // debug output 128 fd = open("/tmp/google.html", O_CREAT|O_TRUNC|O_RDWR, 0644); 129 write(fd, cnx->data, cnx->datalen); 130 close(fd); 131 } 132#else 133 { 134 int fd; 135 struct stat st; 136 // debug output 137 fd = open(FAKE_INPUT, O_RDONLY, 0644); 138 if (fd < 0) 139 return -1; 140 if (fstat(fd, &st) < 0) { 141 close(fd); 142 return -1; 143 } 144 cnx->datalen = st.st_size; 145 cnx->data = malloc(cnx->datalen); 146 if (!cnx->data) 147 return ENOMEM; 148 if (read(fd, cnx->data, cnx->datalen) < cnx->datalen) 149 return -1; 150 close(fd); 151 } 152#endif /* FAKE_INPUT */ 153 err = count = google_parse_results(req->cnx->data, req->cnx->datalen, &req->results); 154 if (err < 0) 155 goto err_get; 156#ifdef DO_PUBLISH 157 while ((res = SLL_DEQUEUE(req->results, next))) { 158 res->next = NULL; 159 googlefs_push_result_to_query(req, res); 160 } 161#endif 162 free(url); 163 free(p); 164 /* close now */ 165 http_close(cnx); 166 167 return B_OK; 168 169 170err_get: 171err_url2: 172 free(url); 173err_url: 174 free(p); 175err_con: 176 http_close(cnx); 177err_cnx: 178 http_delete(cnx); 179 req->cnx = NULL; 180 return err; 181} 182 183status_t google_request_process_async(struct google_request *req) 184{ 185 return ENOSYS; 186} 187 188status_t google_request_close(struct google_request *req) 189{ 190 if (!req) 191 return EINVAL; 192 if (!req->cnx) 193 return B_OK; 194 http_close(req->cnx); 195 http_delete(req->cnx); 196 req->cnx = NULL; 197 return B_OK; 198} 199 200status_t google_request_open(const char *query_string, struct fs_volume *volume, struct fs_node *query_node, struct google_request **req) 201{ 202 struct google_request *r; 203 if (!req) 204 return EINVAL; 205 r = malloc(sizeof(struct google_request)); 206 if (!r) 207 return ENOMEM; 208 memset(r, 0, sizeof(struct google_request)); 209 r->query_string = strdup(query_string); 210 r->volume = volume; 211 r->query_node = query_node; 212 *req = r; 213 return B_OK; 214} 215 216status_t google_request_free(struct google_request *req) 217{ 218 if (!req) 219 return EINVAL; 220 free(req->query_string); 221 free(req); 222 return B_OK; 223} 224