void curl_slist_free_all(struct curl_slist * clist){ if(clist->data){ mem2_free(clist->data, MEM2_OTHER); clist->data = NULL; } if(clist){ mem2_free(clist, MEM2_OTHER); clist = NULL; } }
CURLcode curl_easy_perform(CURL *curl){ if(http_response == NULL){ http_response = (u8 *) mem2_malloc(MAXTWITCURL, MEM2_OTHER); } curl->URLsplit(); curl->buildHttpRequest(); curl_request = mem2_strdup(curl->req.c_str(), MEM2_OTHER); if(!curl_request){ return 1; // No memory } int ret = (http_request(curl->url.c_str(), NULL, http_response, MAXTWITCURL, 1, curl->accept_encoding)); if(curl->callback) curl->callback((char *)http_response, ret, 1, curl->userdata); mem2_free(curl_request, MEM2_OTHER); curl_request = NULL; curl->postdata.clear(); curl->req.clear(); curl->headers.clear(); return !ret; //0 means ok to twitcurl }
int parseUsers(std::string &xmlstr, struct t_user ** dest){ mxml_node_t *xml; mxml_node_t *unit; struct t_user * users = (struct t_user *)mem2_calloc(MAXUNITS, sizeof(struct t_user), MEM2_OTHER); if(!users){ return 0; } size_t pos = 0; while(1){ pos = xmlstr.find("&amp;", pos); if(pos == std::string::npos) break; xmlstr.replace(pos, 9, "&"); } xml = mxmlLoadString(NULL, xmlstr.c_str(), MXML_OPAQUE_CALLBACK); if(!xml){ mem2_free(users, MEM2_OTHER); return 0; } int t=0; for(unit = mxmlFindElement(xml, xml, "user", NULL, NULL, MXML_DESCEND); unit; unit = mxmlFindElement(unit, xml, "user", NULL, NULL, MXML_DESCEND)){ parseUser(unit, &users[t++]); } mxmlDelete(xml); if(t < MAXUNITS){ //Free unused memory users = (struct t_user *)mem2_realloc(users, t*sizeof(struct t_user), MEM2_OTHER); } *dest = users; return t; }
int parseSearch(std::string &xmlstr, struct t_tweet ** dest){ mxml_node_t *xml; mxml_node_t *unit; struct t_tweet * tweets = (struct t_tweet *)mem2_calloc(MAXUNITS, sizeof(struct t_tweet), MEM2_OTHER); if(!tweets){ return 0; } size_t pos = 0; while(1){ pos = xmlstr.find("&amp;", pos); if(pos == std::string::npos) break; xmlstr.replace(pos, 9, "&"); } xml = mxmlLoadString(NULL, xmlstr.c_str(), MXML_OPAQUE_CALLBACK); if(!xml){ mem2_free(tweets, MEM2_OTHER); return 0; } int t=0; for(unit = mxmlFindElement(xml, xml, "entry", NULL, NULL, MXML_DESCEND); unit && t < MAXUNITS; unit = mxmlFindElement(unit, xml, "entry", NULL, NULL, MXML_DESCEND)){ parseSearchEntry(unit, &tweets[t++]); } mxmlDelete(xml); if(t < MAXUNITS){ //Free unused memory tweets = (struct t_tweet *)mem2_realloc(tweets, t*sizeof(struct t_tweet), MEM2_OTHER); } *dest = tweets; return t; }
void ARLs::Clear(){ it = elements.begin(); while(it != elements.end()){ if((*it).text){ mem2_free((*it).text, MEM2_OTHER); } ++it; } elements.clear(); }
struct t_arl * ARLs::Build(char ep, u64 arg1, u64 arg2, u64 arg3, const char * str){ struct t_arl temp; memset(&temp, 0, sizeof(struct t_arl)); if(elements.size() && (selected_index + 1 != elements.size())){ it = elements.begin(); advance(it, selected_index+1); while((++it) != elements.end()){ if((*it).text) mem2_free((*it).text, MEM2_OTHER); } it = elements.begin(); advance(it, selected_index+1); elements.erase(it, elements.end()); }else if(elements.size() == maxelements){ elements.erase(elements.begin()); selected_index--; } temp.endpoint = ep; temp.user_id = arg1; temp.arg_id = arg2; temp.arg_id_2 = arg3; if(str) temp.text = mem2_strdup(str, MEM2_OTHER); if(elements.size() == maxelements){ it = elements.begin(); if((*it).text) mem2_free((*it).text, MEM2_OTHER); elements.erase(it); } elements.push_back(temp); selected_index = elements.size()-1; return GetSelected(); }
struct curl_slist * curl_slist_append(struct curl_slist * clist, const char * str){ struct curl_slist * temp; temp = (curl_slist *)mem2_malloc(sizeof(curl_slist), MEM2_OTHER); if(temp == NULL){ return NULL; } temp->data = (char *)mem2_malloc(strlen(str)+1, MEM2_OTHER); if(temp->data == NULL){ mem2_free(temp, MEM2_OTHER); return NULL; } strcpy(temp->data, str); return temp; }
int httpInflate(void * output, const void * input, unsigned int length, unsigned int type){ z_stream * stream = (z_stream *)mem2_malloc(sizeof(z_stream), MEM2_OTHER); memset(stream, 0, sizeof(z_stream)); stream->zalloc = mem2_zalloc; stream->zfree = mem2_zfree; stream->opaque = Z_NULL; stream->avail_in = length; stream->next_in = (Bytef *)input; stream->avail_out = MAXTWITCURL; stream->next_out = (Bytef *)output; int ret; if(type == 1){ //deflate ret = inflateInit(stream); if(ret != Z_OK) return ret; }else if(type == 2){ //gzip ret = inflateInit2(stream, 16+MAX_WBITS); if(ret != Z_OK) return ret; }else{ return -10; } ret = inflate(stream, Z_NO_FLUSH); if(ret != Z_STREAM_END){ inflateEnd(stream); return ret; } ret = inflateEnd(stream); if(ret != Z_OK) return ret; int size = (MAXTWITCURL - stream->avail_out); mem2_free(stream, MEM2_OTHER); return size; }
/**************************************************************************** * http_request * Retrieves the specified URL, and stores it in the specified file or buffer ***************************************************************************/ int http_request(const char *url, FILE *hfile, u8 *buffer, u32 maxsize, bool silent, bool accept_encoding) { int res = 0; int chunked = 0; char http_host[64]; char http_path[256]; char content_encoding[16] = ""; u16 http_port; #ifdef DEBUGHEADERS int debugging = 0; #endif http_res result; u32 sizeread = 0; content_length = 0; int linecount; if(maxsize > MAX_SIZE){ #ifdef DEBUGERRORS InfoPrompt("maxsize > MAX_SIZE"); #endif return 0; } if (url == NULL || (hfile == NULL && buffer == NULL)){ #ifdef DEBUGERRORS InfoPrompt("!url || (!hfile && !buffer)"); #endif return 0; } if(!silent) ShowAction("Sending data..."); split_res = http_split_url(http_host, http_path, url); // 2 : https ; 1 : http ; 0 : invalid url if (split_res == 2){ http_port = 443; writeFunc = ssl_write; readFunc = ssl_read; }else if( split_res == 1 ){ http_port = 80; writeFunc = net_write; readFunc = net_read; }else{ #ifdef DEBUGERRORS InfoPrompt("Invalid url"); #endif return 0; } http_status = 404; int s = tcp_connect(http_host, http_port); if (s < 0) { result = HTTPR_ERR_CONNECT; #ifdef DEBUGERRORS InfoPrompt("Socket!"); #endif return 0; } int ssl_context = 0; if(split_res == 2){ ssl_context = ssl_setup(http_host, s); #ifdef DEBUGERRORS if(ssl_context < 0){ InfoPrompt("ssl_context() failed"); } #endif if(ssl_context < 0){ net_close(s); return 0; } scktctx = &ssl_context; } else{ scktctx = &s; } if(curl_request){ //Request made by through the CURL class res = tcp_write(*scktctx, (u8 *) curl_request, strlen(curl_request)); }else{ char request[1024]; char *r = request; r += sprintf(r, "GET %s HTTP/1.1\r\n", http_path); r += sprintf(r, "Host: %s\r\n", http_host); if(accept_encoding && hfile){ r += sprintf(r, "Accept-Encoding: gzip, deflate\r\n"); } r += sprintf(r, "Cache-Control: no-cache\r\n\r\n"); res = tcp_write(*scktctx, (u8 *) request, strlen(request)); } if(!silent) CancelAction(); #ifdef DEBUGHEADERS InfoPrompt(http_path); #endif char line[1024]; //Twitter sends a long header for (linecount = 0; linecount < 45; linecount++) { if (tcp_readln(*scktctx, line, 1024) != 0) { #ifdef DEBUGERRORS InfoPrompt("tcp_readln != 0"); #endif http_status = 404; result = HTTPR_ERR_REQUEST; break; } if (!line[0]) break; #ifdef DEBUGHEADERS if(sscanf(line, "HTTP/1.%*u %u", &http_status)){ if(http_status != 200) debugging = 1; } if(sscanf(line, "Content-Length: %u", &content_length) || sscanf(line, "Content-Encoding: %s", content_encoding)){ if(!debugging){ InfoPrompt(line); } } if(!strncmp(line, "Transfer-Encoding: chunked", 25)){ InfoPrompt("Transfer-Encoding: chunked"); chunked = 1; } #else sscanf(line, "HTTP/1.%*u %u", &http_status); sscanf(line, "Content-Length: %u", &content_length); sscanf(line, "Content-Encoding: %s", content_encoding); if(!strncmp(line, "Transfer-Encoding: chunked", 25)) chunked = 1; #endif u32 api_ratelimit=0; if(sscanf(line, "X-RateLimit-Remaining: %u", &api_ratelimit) && api_ratelimit <= 10 && api_ratelimit % 5 == 0){ WindowPrompt("You are on fire!", "You are about to reach Twitter's requests limit. WiiTweet will not work correctly then.", "I'll take a break", 0); } if(get_timeoffset){ if(!strncasecmp(line, "Date:", 5)){ //Case insensitiveness just in case... const char format[] = "%a, %d %b %Y %H:%M:%S %Z"; const char *pointline = line; pointline += 6; struct tm tm; memset(&tm, 0, sizeof(tm)); strptime(pointline, format, &tm); timeoffset = mktime(&tm) - time(NULL); get_timeoffset = 0; } } #ifdef DEBUGHEADERS if(debugging){ InfoPrompt(line); } #endif } if (http_status != 200) { result = HTTPR_ERR_STATUS; #ifdef DEBUGERRORS if(ssl_context){ if(ssl_shutdown(ssl_context)){ InfoPrompt("ssl_shutdown() 1"); } } net_close(s); #else if(ssl_context){ssl_shutdown(ssl_context);} net_close(s); #endif #ifdef DEBUGERRORS char status[64]; sprintf(status, "HTTP Status = %d", http_status); InfoPrompt(status); #endif return 0; }//Try to read anyways? ssl gets rude if it is not convinced there is no data //length unknown - just read as much as we can if(content_length == 0) { content_length = maxsize; } else if (content_length > maxsize) //ssl_shutdown() would fail in this case (?), but it is not likely for our purposes... { result = HTTPR_ERR_TOOBIG; #ifdef DEBUGERRORS if(ssl_context){ if(ssl_shutdown(ssl_context)){ InfoPrompt("ssl_shutdown() 2"); } } net_close(s); #else if(ssl_context){ssl_shutdown(ssl_context);} net_close(s); #endif #ifdef DEBUGERRORS InfoPrompt("content_length > maxsize"); #endif return 0; } unsigned int inflatetype = 0; if(!strncasecmp(content_encoding, "gzip", 4)){ inflatetype = 2; }else if(!strncasecmp(content_encoding, "deflate", 7)){ inflatetype = 1; }else if(content_encoding[0] != '\0'){//Unsupported encoding. This should never happen. #ifdef DEBUGERRORS if(ssl_context){ if(ssl_shutdown(ssl_context)){ InfoPrompt("ssl_shutdown() 3"); } } net_close(s); #else if(ssl_context){ssl_shutdown(ssl_context);} net_close(s); #endif #ifdef DEBUGERRORS InfoPrompt("Unsupported encoding"); #endif return 0; } if (buffer != NULL) { if(!silent) ShowAction("Downloading..."); if(inflatetype){ //Compressed content u8 * inflate_me = (u8 *) mem2_malloc(content_length, MEM2_OTHER); if(!inflate_me){ #ifdef DEBUGERRORS if(ssl_context){ if(ssl_shutdown(ssl_context)){ InfoPrompt("ssl_shutdown() 4"); } } net_close(s); #else if(ssl_context){ssl_shutdown(ssl_context);} net_close(s); #endif #ifdef DEBUGERRORS InfoPrompt("!inflate_me"); #endif return 0; } #ifdef DEBUGHEADERS int tcpread = tcp_read(*scktctx, inflate_me, content_length, chunked); char atoi[64]; sprintf(atoi, "%d", tcpread); WindowPrompt("tcp_read()", atoi, "ok", 0); #else int tcpread = tcp_read(*scktctx, inflate_me, content_length, chunked); #endif /* static int s = 0; char path[256]; sprintf(path, "sd:/catcha%d", s++); SaveFile ((char *)inflate_me, path, tcpread, 1); */ sizeread = httpInflate(buffer, inflate_me, tcpread, inflatetype); if(sizeread < 0){ mem2_free(inflate_me, MEM2_OTHER); #ifdef DEBUGERRORS if(ssl_context){ if(ssl_shutdown(ssl_context)){ InfoPrompt("ssl_shutdown() 5"); } } net_close(s); #else if(ssl_context){ssl_shutdown(ssl_context);} net_close(s); #endif #ifdef DEBUGERRORS InfoPrompt("sizeread < 0"); #endif return 0; } mem2_free(inflate_me, MEM2_OTHER); }else{ //Uncomprpessed content sizeread = tcp_read(*scktctx, buffer, content_length, chunked); } if(!silent) CancelAction(); } else // write into file { /* Uncompressed data. This may fail if the content is chunked and longer than 32KB+2B but chunked is not used in such scenarios */ u32 bufSize = (1024 * 32); u32 bytesLeft = content_length; u32 readSize; if(!silent) ShowProgress("Downloading...", 0, content_length); u8 * fbuffer = (u8 *) malloc(bufSize); if(fbuffer) { while (bytesLeft > 0) { if (bytesLeft < bufSize) readSize = bytesLeft; else readSize = bufSize; res = tcp_read(*scktctx, fbuffer, readSize, chunked); if (!res) break; sizeread += res; bytesLeft -= res; res = fwrite(fbuffer, 1, res, hfile); if (!res) break; if(!silent) ShowProgress("Downloading...", (content_length - bytesLeft), content_length); } free(fbuffer); } if(!silent) CancelAction(); } #ifdef DEBUGERRORS if(ssl_context){ if(ssl_shutdown(ssl_context)){ InfoPrompt("ssl_shutdown() 6"); } } net_close(s); #else if(ssl_context){ssl_shutdown(ssl_context);} net_close(s); #endif if (content_length < maxsize && sizeread != content_length && !inflatetype) { #ifdef DEBUGERRORS InfoPrompt("ERR_RECEIVE"); #endif result = HTTPR_ERR_RECEIVE; return 0; } if (http_status != 200){ #ifdef DEBUGERRORS InfoPrompt("http_status != 200"); #endif return 0; } if(result) //Avoid ugly compiler warning :p result = HTTPR_OK; return sizeread; }
void mem2_zfree(voidpf opaque, voidpf address){ mem2_free(address, MEM2_OTHER); }
CURL::~CURL(){ if(http_response){ mem2_free(http_response, MEM2_OTHER); http_response = NULL; } }
// overloaded delete operator void ARLs::operator delete(void *p) { mem2_free(p, MEM2_OTHER); }