bool getCoverFromServer(char* url, char* imgPath, int v, int max){ struct block file; char* pch; sprintf(self.debugMsg, TX.getting, url); Paint_Progress_Generic(v, max,self.debugMsg); file = downloadfile(url); if(file.data != NULL && file.size >= 4000){ char* msg = CFMalloc(20*sizeof(char)); strncpy(msg, (char*)file.data,20); pch = strtok(msg, " "); if(strcmp(pch,"<!DOCTYPE")==0) //test for a bad file { CFFree(msg); CFFree(file.data); return false; } CFFree(msg); unlink(imgPath); saveFile(imgPath, file); CFFree(file.data); sprintf(self.debugMsg, TX.done ); Paint_Progress_Generic(v, max,self.debugMsg); return true; } return false; }
/** * This function reads all the data from a connection into a buffer which it returns. * It will return an empty buffer if something doesn't go as planned * * @param s32 connection The connection identifier to suck the response out of * @return block A 'block' struct (see http.h) in which the buffer is located */ struct block read_message(s32 connection) { //Create a block of memory to put in the response struct block buffer; buffer.data = CFMalloc(HTTP_BUFFER_SIZE); buffer.size = HTTP_BUFFER_SIZE; if(buffer.data == NULL) { return emptyblock; } //The offset variable always points to the first byte of memory that is free in the buffer u32 offset = 0; while(1) { //Fill the buffer with a new batch of bytes from the connection, //starting from where we left of in the buffer till the end of the buffer s32 bytes_read = net_read(connection, buffer.data + offset, buffer.size - offset); //Anything below 0 is an error in the connection if(bytes_read < 0) { printf(TX.errorConnect, bytes_read); return emptyblock; } //No more bytes were read into the buffer, //we assume this means the HTTP response is done if(bytes_read == 0) { break; } offset += bytes_read; //Check if we have enough buffer left over, //if not expand it with an additional HTTP_BUFFER_GROWTH worth of bytes if(offset >= buffer.size) { buffer.size += HTTP_BUFFER_GROWTH; buffer.data = CFRealloc(buffer.data, buffer.size); if(buffer.data == NULL) { return emptyblock; } } } //At the end of above loop offset should be precisely the amount of bytes that were read from the connection buffer.size = offset; //Shrink the size of the buffer so the data fits exactly in it CFRealloc(buffer.data, buffer.size); return buffer; }
CFThreadNotify* CFThreadNotifyNew(CFThreadNotifyCb cb, void* userData, CFFdevents* evts) { CFThreadNotify* ntf; if (!(ntf = CFMalloc(sizeof(CFThreadNotify)))) { LCF_ERR_OUT(ERR_OUT, "out of memory\n"); } ntf->evts = evts; ntf->userData = userData; ntf->cb = cb; if (pipe2(ntf->pipeFd, O_NONBLOCK|O_CLOEXEC)) { LCF_ERR_OUT(ERR_FREE_NTF, "pipe2() failed\n"); } if (!(ntf->rdEvt = CFFdeventNew(ntf->pipeFd[0], "ThreadNotifyRdEvt", ThreadNotifyReadable, ntf, NULL, NULL, NULL, NULL))) { LCF_ERR_OUT(ERR_CLOSE_PIPE, "CFFdeventNew() failed\n"); } if (CFFdeventsAdd(evts, ntf->rdEvt)) { LCF_ERR_OUT(ERR_DESTY_RD_EVT, "CFFdeventsAdd() failed\n"); } return ntf; ERR_DEL_RD_EVT: CFFdeventsDel(evts, ntf->rdEvt); ERR_DESTY_RD_EVT: CFFdeventFree(ntf->rdEvt); ERR_CLOSE_PIPE: close(ntf->pipeFd[0]); close(ntf->pipeFd[1]); ERR_FREE_NTF: CFFree(ntf); ERR_OUT: return NULL; }
bool downloadTitles(){ //WindowPrompt(TX.error, "Error initializing network\nTitles.txt can't be downloaded.", &okButton, 0); char titlesPath[100]; struct block file; //snprintf(titlesPath, sizeof(titlesPath), "%s/titles.txt", USBLOADER_PATH); snprintf(titlesPath, sizeof(titlesPath), "%s/titles.txt", dynPath.dir_usb_loader); //file = downloadfile("http://www.wiiboxart.com/titles.txt"); file = downloadfile("http://wiitdb.com/titles.txt"); if(file.data != NULL){ char* pch; char* msg = CFMalloc(20*sizeof(char)); strncpy(msg, (char*)file.data,20); pch = strtok(msg, " "); if(strcmp(pch,"<!DOCTYPE")==0) //test for a bad file { CFFree(msg); CFFree(file.data); return false; } CFFree(msg); unlink(titlesPath); if(saveFile(titlesPath, file)) { CFFree(file.data); return true; } else{ CFFree(file.data); return false; } } return false; }
bool Load_Dol(void **buffer, int* dollen, char * filepath) { int ret; FILE* file; void* dol_buffer; char fullpath[200]; char gameidbuffer6[7]; memset(gameidbuffer6, 0, 7); memcpy(gameidbuffer6, (char*)0x80000000, 6); snprintf(fullpath, 200, "%s/%s.dol", filepath, gameidbuffer6); SDCard_Init(); USBDevice_Init(); file = fopen(fullpath, "rb"); if(file == NULL) { #ifdef DEBTXT_ALTDOL DebTxt(".dol is missing"); #endif fclose(file); SDCard_deInit(); USBDevice_deInit(); return false; } ClearAllocatedMemory(); int filesize; fseek(file, 0, SEEK_END); filesize = ftell(file); fseek(file, 0, SEEK_SET); #ifdef LOUDTEST dol_buffer = (void *) MEM2_START_ADDRESS; //safest #else dol_buffer = CFMalloc(filesize); #endif if (dol_buffer == NULL) { #ifdef DEBTXT_ALTDOL char dbg[80]; DebTxt("Out of memory"); sprintf(dbg,"%s %d", gameidbuffer6, filesize); DebTxt(dbg); #endif fclose(file); SDCard_deInit(); USBDevice_deInit(); return false; } ret = fread( dol_buffer, 1, filesize, file); if(ret != filesize) { #ifdef DEBTXT_ALTDOL DebTxt("Error reading dol header"); #endif #ifndef LOUDTEST CFFree(dol_buffer); #endif fclose(file); SDCard_deInit(); USBDevice_deInit(); return false; } fclose(file); #ifdef DEBTXT_ALTDOL DebTxt("dol header in buffer"); #endif SDCard_deInit(); USBDevice_deInit(); *buffer = dol_buffer; *dollen = filesize; return true; }
/** * Downloads the contents of a URL to memory * This method is not threadsafe (because networking is not threadsafe on the Wii) */ struct block downloadfile(const char *url) { //Check if the url starts with "http://", if not it is not considered a valid url if(strncmp(url, "http://", strlen("http://")) != 0) { sprintf(emptyblock.error,TX.URLnoBegin, url); //doen't start with http:// return emptyblock; } //Locate the path part of the url by searching for '/' past "http://" char *path = strchr(url + strlen("http://"), '/'); //At the very least the url has to end with '/', ending with just a domain is invalid if(path == NULL) { sprintf(emptyblock.error,TX.URLnoPath, url); //no path part in URL return emptyblock; } //Extract the domain part out of the url int domainlength = path - url - strlen("http://"); if(domainlength == 0) { sprintf(emptyblock.error,TX.URLnoDomain, url); //couldn't find a domain in url return emptyblock; } char domain[domainlength + 1]; strncpy(domain, url + strlen("http://"), domainlength); domain[domainlength] = '\0'; //Parsing of the URL is done, start making an actual connection u32 ipaddress = getipbyname(domain); //slower but doesn't leak memory if(ipaddress == 0) { sprintf(emptyblock.error,TX.errorDomain, domain); //couldn't resolve domain return emptyblock; } s32 connection = server_connect(ipaddress, 80); if(connection < 0) { sprintf(emptyblock.error,TX.errEstablishConn); //couldn't establish connection return emptyblock; } //Form a nice request header to send to the webserver char* headerformat = "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: WiiEarthh 1.0\r\n\r\n";; char header[strlen(headerformat) + strlen(domain) + strlen(path)]; sprintf(header, headerformat, path, domain); //Do the request and get the response send_message(connection, header); struct block response = read_message(connection); net_close(connection); //Search for the 4-character sequence \r\n\r\n in the response which signals the start of the http payload (file) unsigned char *filestart = NULL; u32 filesize = 0; int i; for(i = 3; i < response.size; i++) { if(response.data[i] == '\n' && response.data[i-1] == '\r' && response.data[i-2] == '\n' && response.data[i-3] == '\r') { filestart = response.data + i + 1; filesize = response.size - i - 1; break; } } if(filestart == NULL) { sprintf(emptyblock.error,TX.HTTPnoFile); return emptyblock; } //Copy the file part of the response into a new memoryblock to return struct block file; file.data = CFMalloc(filesize); file.size = filesize; if(file.data == NULL) { sprintf(emptyblock.error,TX.noMemCopy ); //couldn't copy the file to the block CFFree(response.data); return emptyblock; } memcpy(file.data, filestart, filesize); //Dispose of the original response CFFree(response.data); return file; }