Beispiel #1
0
	virtual void PerformFriendAction(EFriendActionType::Type ActionType) override
	{
		if(SelectedFriend.IsValid())
		{
			if(SelectedFriend->ViewModel.IsValid())
			{
				SelectedFriend->ViewModel->PerformAction(ActionType);
			}
			else if(ActionType == EFriendActionType::SendFriendRequest)
			{
				FFriendsAndChatManager::Get()->RequestFriend(SelectedFriend->FriendName);
				CancelAction();
			}
			else if(ActionType == EFriendActionType::InviteToGame)
			{
				if(SelectedFriend->UserID.IsValid())
				{
					FFriendsAndChatManager::Get()->SendGameInvite(*SelectedFriend->UserID.Get());
				}
				else if(SelectedFriend->SelectedMessage.IsValid() && SelectedFriend->SelectedMessage->GetSenderID().IsValid())
				{
					FFriendsAndChatManager::Get()->SendGameInvite(*SelectedFriend->SelectedMessage->GetSenderID().Get());
				}
			}
			else if (ActionType == EFriendActionType::Whisper)
			{
				TSharedPtr<IFriendItem> FriendItem = FFriendsAndChatManager::Get()->FindUser(*SelectedFriend->UserID);
				if (FriendItem.IsValid())
				{
					FFriendsAndChatManager::Get()->SetChatFriend(FriendItem);					
				}				
				CancelAction();
			}
		}
	}
Beispiel #2
0
bool UpdateCheck()
{
	bool ret = 0;

	// we only check for an update if we have internet
	if(!networkInit)
		return 0;

	ShowAction("Checking for updates...");
	class twitCurl twitterObj;
	std::string tmp("392315277"); // @WiiTwiity userid
	if( twitterObj.userGet(tmp, 1) ){
		tmp.clear();
		twitterObj.getLastWebResponse(tmp);
	}else{
		CancelAction();
		return 0;
	}
	mxml_node_t *xml;
	mxml_node_t *item;

	xml = mxmlLoadString(NULL, tmp.c_str(), MXML_OPAQUE_CALLBACK);

	if(!xml){
		CancelAction();
		return 0;
	}

	item = mxmlFindElement(xml, xml, "text", NULL, NULL, MXML_DESCEND);
	if(item) // Tweet found!
	{
		const char * tweet = item->child->value.opaque;
		int verMajor, verMinor, verPoint;

		if(sscanf(tweet, "WiiTweet %d.%d.%d released! SHA-1: %s", &verMajor, &verMinor, &verPoint, updateHash) == 4)
		{
			int curMajor = APPVERSION[0] - '0';
			int curMinor = APPVERSION[2] - '0';
			int curPoint = APPVERSION[4] - '0';

			// check that the versioning is valid and is a newer version
			if((verMajor >= 0 && verMajor <= 9 &&
				verMinor >= 0 && verMinor <= 9 &&
				verPoint >= 0 && verPoint <= 9) &&
				(verMajor > curMajor ||
				(verMajor == curMajor && verMinor > curMinor) ||
				(verMajor == curMajor && verMinor == curMinor && verPoint > curPoint)))
			{
				snprintf(updateURL, 128, "http://wiitweet.googlecode.com/files/wiitweet%%20%d.%d.%d.zip", verMajor, verMinor, verPoint);
				ret = 1;
			}
		}
	}

	mxmlDelete(xml);
	CancelAction();
	return ret;
}
Beispiel #3
0
/****************************************************************************
* autoLoadMethod()
* Auto-determines and sets the load device
* Returns device set
****************************************************************************/
int autoLoadMethod()
{
	ShowAction ("Attempting to determine load device...");

	int device = DEVICE_AUTO;

	if(ChangeInterface(DEVICE_SD, SILENT))
		device = DEVICE_SD;
	else if(ChangeInterface(DEVICE_USB, SILENT))
		device = DEVICE_USB;
	else if(ChangeInterface(DEVICE_SD_SLOTA, SILENT))
		device = DEVICE_SD_SLOTA;
	else if(ChangeInterface(DEVICE_SD_SLOTB, SILENT))
		device = DEVICE_SD_SLOTB;
	else if(ChangeInterface(DEVICE_DVD, SILENT))
		device = DEVICE_DVD;
	else if(ChangeInterface(DEVICE_SMB, SILENT))
		device = DEVICE_SMB;
	else
		ErrorPrompt("Unable to locate a load device!");

	if(GCSettings.LoadMethod == DEVICE_AUTO)
		GCSettings.LoadMethod = device; // save device found for later use
	CancelAction();
	return device;
}
Beispiel #4
0
/****************************************************************************
* autoSaveMethod()
* Auto-determines and sets the save device
* Returns device set
****************************************************************************/
int autoSaveMethod(bool silent)
{
	if(!silent)
		ShowAction ("Attempting to determine save device...");

	int device = DEVICE_AUTO;

	if(ChangeInterface(DEVICE_SD, SILENT))
		device = DEVICE_SD;
	else if(ChangeInterface(DEVICE_USB, SILENT))
		device = DEVICE_USB;
	else if(ChangeInterface(DEVICE_SD_SLOTA, SILENT))
		device = DEVICE_SD_SLOTA;
	else if(ChangeInterface(DEVICE_SD_SLOTB, SILENT))
		device = DEVICE_SD_SLOTB;
	else if(ChangeInterface(DEVICE_SMB, SILENT))
		device = DEVICE_SMB;
	else if(!silent)
		ErrorPrompt("Unable to locate a save device!");

	if(GCSettings.SaveMethod == DEVICE_AUTO)
		GCSettings.SaveMethod = device; // save device found for later use

	CancelAction();
	return device;
}
Beispiel #5
0
static
void AcceptAction (Widget widget, XEvent *event,
		   String *params, Cardinal *num_params)
{
    (*promptfunction)(XawDialogGetValueString(promptDialog));
    CancelAction (widget, event, params, num_params);
}
Beispiel #6
0
bool SavePalettes(bool silent)
{
	char filepath[1024];
	int datasize;
	int offset = 0;

	if(prefpath[0] == 0)
		return false;

	sprintf(filepath, "%s/%s", prefpath, PAL_FILE_NAME);

	// Now create the XML palette file

	if (!silent)
		ShowAction("Saving palette...");

	AllocSaveBuffer();
	datasize = preparePalData(palettes, loadedPalettes);

	offset = SaveFile(filepath, datasize, silent);

	FreeSaveBuffer();

	CancelAction();

	if (offset > 0)
	{
		if (!silent)
			InfoPrompt("Palette saved");
		return true;
	}
	return false;
}
Beispiel #7
0
/****************************************************************************
 * Verify Memory Card file against buffer
 ***************************************************************************/
static int
VerifyMCFile (char *buf, int slot, char *filename, int datasize)
{
	card_file CardFile;
	int CardError;
	unsigned int blocks;
	unsigned int SectorSize;
	int bytesleft = 0;
	int bytesread = 0;

	verifybuffer = (u8 *)memalign(32, 262144);
	memset (verifybuffer, 0, 262144);

	// Get Sector Size
	CARD_GetSectorSize (slot, &SectorSize);

	memset (&CardFile, 0, sizeof (CardFile));
	CardError = CARD_Open (slot, filename, &CardFile);

	if(CardError)
	{
		ErrorPrompt("Unable to open file!");
	}
	else
	{
		blocks = CardFile.len;

		if (blocks < SectorSize)
			blocks = SectorSize;

		if (blocks % SectorSize)
			blocks += SectorSize;

		if (blocks > (unsigned int)datasize)
			blocks = datasize;

		bytesleft = blocks;
		bytesread = 0;
		while (bytesleft > 0)
		{
			CardError = CARD_Read (&CardFile, verifybuffer, SectorSize, bytesread);
			if (CardError || memcmp (buf + bytesread, verifybuffer, (unsigned int)bytesleft < SectorSize ? bytesleft : SectorSize) )
			{
				bytesread = 0;
				ErrorPrompt("File integrity could not be verified!");
				break;
			}

			bytesleft -= SectorSize;
			bytesread += SectorSize;
			ShowProgress ("Verifying...", bytesread, blocks);
		}
		CARD_Close (&CardFile);
		CancelAction();
	}
	free(verifybuffer);
	return bytesread;
}
Beispiel #8
0
void PNPActionServer::goalCallback(PNPAS::GoalHandle gh){
    boost::mutex::scoped_lock lock(state_mutex);

    current_gh = gh; 
    goal = *current_gh.getGoal();

    // Run action (wait until it finishes)
    //ROS_INFO_STREAM("### Received Goal: " << goal.id << " " << goal.name << " " << 
    //      goal.params << " " << goal.function);
    

    if (goal.function=="start") {
        ROS_DEBUG_STREAM("Starting action " << goal.robotname << " " << goal.name << " " << 
                        goal.params);
        current_gh.setAccepted();
        actionStart(goal.robotname, goal.name, goal.params);
        boost::thread t(
            boost::bind(&PNPActionServer::ActionExecutionThread, this, _1),
            current_gh);
    }
    else if (goal.function=="end") {
        ROS_DEBUG_STREAM("Terminating action " << goal.robotname << " " << goal.name << " " << 
                        goal.params);
        actionEnd(goal.robotname, goal.name, goal.params);
        CancelAction(goal.robotname,goal.name,goal.params);
        current_gh.setAccepted();
        for (int k=0; k<3; k++) { ros::spinOnce(); }
//        boost::this_thread::sleep(boost::posix_time::milliseconds(200));
        current_gh.setSucceeded();
    }
    else if (goal.function=="interrupt") {
        ROS_DEBUG_STREAM("Interrupting action " << goal.robotname << " " << goal.name << " " << 
                        goal.params);
        actionInterrupt(goal.robotname, goal.name, goal.params);
        CancelAction(goal.robotname,goal.name,goal.params);
        current_gh.setAccepted();
        for (int k=0; k<3; k++) { ros::spinOnce(); }
        //boost::this_thread::sleep(boost::posix_time::milliseconds(200));
        current_gh.setSucceeded();
    }

    // wait for actual delivery...
    for (int k=0; k<5; k++) { ros::spinOnce(); }
    // boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
}
Beispiel #9
0
static void
MakePrompt(Widget centerw, const char *prompt,
	   MakePromptFunc func, const char *def)
{
    static Arg dialogArgs[] = {
	{XtNlabel, 0},
	{XtNvalue, 0},
    };
    Arg valueArgs[1];
    Arg centerArgs[2];
    Position	source_x, source_y;
    Position	dest_x, dest_y;
    Dimension center_width, center_height;
    Dimension prompt_width, prompt_height;
    Widget  valueWidget;
    
    CancelAction ((Widget)NULL, (XEvent *) 0, (String *) 0, (Cardinal *) 0);
    promptShell = XtCreatePopupShell ("promptShell", transientShellWidgetClass,
				      toplevel, NULL, (Cardinal) 0);
    dialogArgs[0].value = (XtArgVal)prompt;
    dialogArgs[1].value = (XtArgVal)def;
    promptDialog = XtCreateManagedWidget( "promptDialog", dialogWidgetClass,
		    promptShell, dialogArgs, XtNumber (dialogArgs));
    XawDialogAddButton(promptDialog, "accept", NULL, (XtPointer) 0);
    XawDialogAddButton(promptDialog, "cancel", NULL, (XtPointer) 0);
    valueWidget = XtNameToWidget (promptDialog, "value");
    if (valueWidget) {
    	XtSetArg (valueArgs[0], (String)XtNresizable, TRUE);
    	XtSetValues (valueWidget, valueArgs, 1);
	/*
	 * as resizable isn't set until just above, the
	 * default value will be displayed incorrectly.
	 * rectify the situation by resetting the values
	 */
        XtSetValues (promptDialog, dialogArgs, XtNumber (dialogArgs));
    }
    XtSetKeyboardFocus (promptDialog, valueWidget);
    XtSetKeyboardFocus (toplevel, valueWidget);
    XtRealizeWidget (promptShell);
    /*
     * place the widget in the center of the "parent"
     */
    XtSetArg (centerArgs[0], XtNwidth, &center_width);
    XtSetArg (centerArgs[1], XtNheight, &center_height);
    XtGetValues (centerw, centerArgs, 2);
    XtSetArg (centerArgs[0], XtNwidth, &prompt_width);
    XtSetArg (centerArgs[1], XtNheight, &prompt_height);
    XtGetValues (promptShell, centerArgs, 2);
    source_x = (center_width - prompt_width) / 2;
    source_y = (center_height - prompt_height) / 3;
    XtTranslateCoords (centerw, source_x, source_y, &dest_x, &dest_y);
    XtSetArg (centerArgs[0], XtNx, dest_x);
    XtSetArg (centerArgs[1], XtNy, dest_y);
    XtSetValues (promptShell, centerArgs, 2);
    XtMapWidget(promptShell);
    promptfunction = func;
}
Beispiel #10
0
bool
ConnectShare (bool silent)
{
	if(!InitializeNetwork(silent))
		return false;

	if(networkShareInit)
		return true;

	int retry = 1;
	int chkS = (strlen(GCSettings.smbshare) > 0) ? 0:1;
	int chkI = (strlen(GCSettings.smbip) > 0) ? 0:1;

	// check that all parameters have been set
	if(chkS + chkI > 0)
	{
		if(!silent)
		{
			char msg[50];
			char msg2[100];
			if(chkS + chkI > 1) // more than one thing is wrong
				sprintf(msg, "Check settings.xml.");
			else if(chkS)
				sprintf(msg, "Share name is blank.");
			else if(chkI)
				sprintf(msg, "Share IP is blank.");

			sprintf(msg2, "Invalid network settings - %s", msg);
			ErrorPrompt(msg2);
		}
		return false;
	}

	while(retry)
	{
		if(!silent)
			ShowAction ("Connecting to network share...");
		
		if(smbInit(GCSettings.smbuser, GCSettings.smbpwd, GCSettings.smbshare, GCSettings.smbip))
			networkShareInit = true;

		if(networkShareInit || silent)
			break;

		retry = ErrorPromptRetry("Failed to connect to network share.");
	}

	if(!silent)
		CancelAction();

	return networkShareInit;
}
Beispiel #11
0
bool InitializeNetwork(bool silent)
{
#ifdef HW_RVL
	StopNetworkThread();

	if(networkInit && net_gethostip() > 0)
		return true;

	networkInit = false;
#else
	if(networkInit)
		return true;
#endif

	int retry = 1;

	while(retry)
	{
		ShowAction("Initializing network...");

#ifdef HW_RVL
		u64 start = gettime();
		StartNetworkThread();

		while (!LWP_ThreadIsSuspended(networkthread))
		{
			usleep(50 * 1000);

			if(diff_sec(start, gettime()) > 10) // wait for 10 seconds max for net init
				break;
		}
#else
		networkInit = !(if_config(wiiIP, NULL, NULL, true) < 0);
#endif

		CancelAction();

		if(networkInit || silent)
			break;

		retry = ErrorPromptRetry("Unable to initialize network!");
#ifdef HW_RVL  	
		if(networkInit && net_gethostip() > 0)
#else
		if(networkInit)
#endif
			return true;
	}
	return networkInit;
}
Beispiel #12
0
/****************************************************************************
 * ParseMCDirectory
 *
 * Parses a list of all files on the specified memory card
 ***************************************************************************/
int
ParseMCDirectory (int slot)
{
	card_dir CardDir;
	int CardError;
	int entryNum = 0;

	// Try to mount the card
	CardError = MountMC(slot, NOTSILENT);

	if (CardError == 0)
	{
		CardError = CARD_FindFirst (slot, &CardDir, TRUE);
		while (CardError != CARD_ERROR_NOFILE)
		{
			BROWSERENTRY * newBrowserList = (BROWSERENTRY *)realloc(browserList, (entryNum+1) * sizeof(BROWSERENTRY));

			if(!newBrowserList) // failed to allocate required memory
			{
				ResetBrowser();
				ErrorPrompt("Out of memory: too many files!");
				entryNum = -1;
				break;
			}
			else
			{
				browserList = newBrowserList;
			}
			memset(&(browserList[entryNum]), 0, sizeof(BROWSERENTRY)); // clear the new entry

			strncpy(browserList[entryNum].filename, (char *)CardDir.filename, MAXJOLIET);
			StripExt(browserList[entryNum].displayname, browserList[entryNum].filename); // hide file extension
			browserList[entryNum].length = CardDir.filelen;

			entryNum++;

			CardError = CARD_FindNext (&CardDir);
		}
		CARD_Unmount(slot);
	}

	// Sort the file list
	qsort(browserList, entryNum, sizeof(BROWSERENTRY), FileSortCallback);

	CancelAction();

	browser.numEntries = entryNum;
	return entryNum;
}
Beispiel #13
0
/****************************************************************************
 * BrowserLoadFile
 *
 * Loads the selected ROM
 ***************************************************************************/
int BrowserLoadFile()
{
	int loaded = 0;
	int device;

	if(!FindDevice(browser.dir, &device))
		return 0;

	// check that this is a valid ROM
	if(!IsValidROM())
		goto done;

	// store the filename (w/o ext) - used for sram/freeze naming
	StripExt(Memory.ROMFilename, browserList[browser.selIndex].filename);
	snprintf(GCSettings.LastFileLoaded, MAXPATHLEN, "%s", browserList[browser.selIndex].filename);
	strncpy(Memory.ROMFilePath, browser.dir, PATH_MAX);

	SNESROMSize = 0;
	S9xDeleteCheats();
	Memory.LoadROM("ROM");

	if (SNESROMSize == 0)
	{
		ErrorPrompt("Error loading game!");
	}
	else if(bsxBiosLoadFailed) {
		ErrorPrompt("BS-X BIOS file not found!");
	}
	else
	{
		// load SRAM or snapshot
		if (GCSettings.AutoLoad == 1)
			LoadSRAMAuto(SILENT);
		else if (GCSettings.AutoLoad == 2)
			LoadSnapshotAuto(SILENT);

		ResetBrowser();
		loaded = 1;
	}
done:
	CancelAction();
	return loaded;
}
Beispiel #14
0
/****************************************************************************
 * BrowserLoadFile
 *
 * Loads the selected ROM
 ***************************************************************************/
int BrowserLoadFile()
{
	char path[MAXPATHLEN + 1];
	int loaded = 0;
	int device;

	if(!FindDevice(browser.dir, &device))
		return 0;

	// store the filename (w/o ext) - used for sram/freeze naming
	StripExt(ROMFilename, browserList[browser.selIndex].filename);
	strcpy(loadedFile, browserList[browser.selIndex].filename);
		
	snprintf(path, MAXPATHLEN, "%s%s", browser.dir, browserList[browser.selIndex].filename);
	EmuPrepareLaunch(path);	
	loaded = 1;
done:
	CancelAction();
	return loaded;
}
/****************************************************************************
 * BrowserLoadFile
 *
 * Loads the selected ROM
 ***************************************************************************/
int BrowserLoadFile()
{
	int loaded = 0;
	int device;

	if(!FindDevice(browser.dir, &device))
		return 0;

	GetFileSize(browser.selIndex);

	// check that this is a valid ROM
	if(!IsValidROM())
		goto done;

	// store the filename (w/o ext) - used for sram/freeze naming
	StripExt(Memory.ROMFilename, browserList[browser.selIndex].filename);
	strcpy(loadedFile, browserList[browser.selIndex].filename);

	SNESROMSize = 0;
	S9xDeleteCheats();
	Memory.LoadROM("ROM");

	if (SNESROMSize <= 0)
	{
		ErrorPrompt("Error loading game!");
	}
	else
	{
		// load SRAM or snapshot
		if (GCSettings.AutoLoad == 1)
			LoadSRAMAuto(SILENT);
		else if (GCSettings.AutoLoad == 2)
			LoadSnapshotAuto(SILENT);

		ResetBrowser();
		loaded = 1;
	}
done:
	CancelAction();
	return loaded;
}
Beispiel #16
0
void InitializeNetwork(bool silent)
{
	// stop if we're already initialized, or if auto-init has failed before
	// in which case, manual initialization is required
	if(networkInit || !autoNetworkInit)
		return;

	if(!silent)
		ShowAction ("Initializing network...");

	while(inNetworkInit) // a network init is already in progress!
		usleep(50);

	if(networkInit) // check again if the network was inited
		return;

	inNetworkInit = true;

	char ip[16];
	s32 initResult = if_config(ip, NULL, NULL, true);

	if(initResult == 0)
	{
		networkInit = true;
	}
	else
	{
		// do not automatically attempt a reconnection
		autoNetworkInit = false;

		if(!silent)
		{
			char msg[150];
			sprintf(msg, "Unable to initialize network (Error #: %i)", initResult);
			ErrorPrompt(msg);
		}
	}
	if(!silent)
		CancelAction();
	inNetworkInit = false;
}
Beispiel #17
0
/****************************************************************************
 * InitializeNetwork
 * Initializes the Wii/GameCube network interface
 ***************************************************************************/
bool InitializeNetwork(bool silent)
{

	StopNetworkThread();

	if(networkInit && net_gethostip() > 0)
		return true;

	networkInit = false;

	int retry = 1;

	while(retry)
	{
		ShowAction("Initializing network...");

		u64 start = gettime();
		StartNetworkThread();

		while (!LWP_ThreadIsSuspended(networkthread))
		{
			usleep(50 * 1000);

			if(diff_sec(start, gettime()) > 10) // wait for 10 seconds max for net init
				break;
		}

		CancelAction();

		if(networkInit || silent)
			break;

		retry = ErrorPromptRetry("Unable to initialize network!");
		
		if(networkInit && net_gethostip() > 0)

			return true;
	}
	return networkInit;
}
Beispiel #18
0
/****************************************************************************
 * MountDVD()
 *
 * Tests if a ISO9660 DVD is inserted and available, and mounts it
 ***************************************************************************/
bool MountDVD(bool silent)
{
	bool mounted = false;
	int retry = 1;

	if(unmountRequired[DEVICE_DVD])
	{
		unmountRequired[DEVICE_DVD] = false;
		ISO9660_Unmount("dvd:");
	}

	while(retry)
	{
		ShowAction("Loading DVD...");

		if(!dvd->isInserted())
		{
			if(silent)
				break;

			retry = ErrorPromptRetry("No disc inserted!");
		}
		else if(!ISO9660_Mount("dvd", dvd))
		{
			if(silent)
				break;
			
			retry = ErrorPromptRetry("Unrecognized DVD format.");
		}
		else
		{
			mounted = true;
			break;
		}
	}
	CancelAction();
	isMounted[DEVICE_DVD] = mounted;
	return mounted;
}
Beispiel #19
0
size_t SzExtractFile(int i, unsigned char *buffer)
{
	// prepare some variables
	SzBlockIndex = 0xFFFFFFFF;
	SzOffset = 0;

	// Unzip the file

	SzRes = SzExtract2(
		&SzArchiveStream.InStream,
		&SzDb,
		i,                      // index of file
		&SzBlockIndex,          // index of solid block
		&buffer,
		&SzBufferSize,
		&SzOffset,              // offset of stream for required file in *outBuffer
		&SzOutSizeProcessed,    // size of file in *outBuffer
		&SzAllocImp,
		&SzAllocTempImp);

	// close 7Zip archive and free memory
	SzClose();

	CancelAction();

	// check for errors
	if(SzRes != SZ_OK)
	{
		// display error message
		SzDisplayError(SzRes);
		return 0;
	}
	else
	{
		return SzOutSizeProcessed;
	}
}
Beispiel #20
0
/****************************************************************************
 * BrowserLoadFile
 *
 * Loads the selected ROM
 ***************************************************************************/
int BrowserLoadFile()
{
	int device;

	if(!FindDevice(browser.dir, &device))
		return 0;

	// store the filename (w/o ext) - used for sram/freeze naming
	StripExt(ROMFilename, browserList[browser.selIndex].filename);
	snprintf(GCSettings.LastFileLoaded, MAXPATHLEN, "%s", browserList[browser.selIndex].filename);

	loadingFile = true;
	ROMLoaded = LoadVBAROM();
	loadingFile = false;

	if (!ROMLoaded)
	{
		if(inSz)
		{
			browser.selIndex = 0;
			BrowserChangeFolder();
		}
		ErrorPrompt("Error loading game!");
	}
	else
	{
		if (GCSettings.AutoLoad == 1)
			LoadBatteryOrStateAuto(FILE_SRAM, SILENT);
		else if (GCSettings.AutoLoad == 2)
			LoadBatteryOrStateAuto(FILE_SNAPSHOT, SILENT);

		ResetBrowser();
	}
	CancelAction();
	return ROMLoaded;
}
Beispiel #21
0
/****************************************************************************
 * SaveFile
 * Write buffer to file
 ***************************************************************************/
size_t
SaveFile (char * buffer, char *filepath, size_t datasize, bool silent)
{
	size_t written = 0;
	size_t writesize, nextwrite;
	int retry = 1;
	int device;
		
	if(!FindDevice(filepath, &device))
		return 0;

	if(datasize == 0)
		return 0;

	// stop checking if devices were removed/inserted
	// since we're saving a file
	HaltDeviceThread();

	// halt parsing
	HaltParseThread();

	ShowAction("Saving...");

	while(!written && retry == 1)
	{
		if(!ChangeInterface(device, silent))
			break;

		file = fopen (filepath, "wb");

		if(!file)
		{
			if(silent)
				break;

			retry = ErrorPromptRetry("Error creating file!");
			continue;
		}

		while(written < datasize)
		{
			if(datasize - written > 4096) nextwrite=4096;
			else nextwrite = datasize-written;
			writesize = fwrite (buffer+written, 1, nextwrite, file);
			if(writesize != nextwrite) break; // write failure
			written += writesize;
		}
		fclose (file);

		if(written != datasize) written = 0;

		if(!written)
		{
			unmountRequired[device] = true;
			if(silent) break;
			retry = ErrorPromptRetry("Error saving file!");
		}
	}

	// go back to checking if devices were inserted/removed
	ResumeDeviceThread();

	CancelAction();
	return written;
}
Beispiel #22
0
/****************************************************************************
 * LoadFile
 ***************************************************************************/
size_t
LoadFile (char * rbuffer, char *filepath, size_t length, bool silent)
{
	char zipbuffer[2048];
	size_t size = 0, offset = 0, readsize = 0;
	int retry = 1;
	int device;

	if(!FindDevice(filepath, &device))
		return 0;

	// stop checking if devices were removed/inserted
	// since we're loading a file
	HaltDeviceThread();

	// halt parsing
	HaltParseThread();

	// open the file
	while(retry)
	{
		if(!ChangeInterface(device, silent))
			break;

		file = fopen (filepath, "rb");

		if(!file)
		{
			if(silent)
				break;

			retry = ErrorPromptRetry("Error opening file!");
			continue;
		}

		if(length > 0 && length <= 2048) // do a partial read (eg: to check file header)
		{
			size = fread (rbuffer, 1, length, file);
		}
		else // load whole file
		{
			readsize = fread (zipbuffer, 1, 32, file);

			if(!readsize)
			{
				unmountRequired[device] = true;
				retry = ErrorPromptRetry("Error reading file!");
				fclose (file);
				continue;
			}

			if (IsZipFile (zipbuffer))
			{
				size = UnZipBuffer ((unsigned char *)rbuffer); // unzip
			}
			else
			{
				fseeko(file,0,SEEK_END);
				size = ftello(file);
				fseeko(file,0,SEEK_SET);

				while(!feof(file))
				{
					// If the size requested is *less* than the filesize, only read that much - we don't want to overrun the buffer
					int toread = 4096;
					if (length > 0 && offset+toread > length) {
						toread = length - offset;
					}

					ShowProgress ("Loading...", offset, size);
					readsize = fread (rbuffer + offset, 1, 4096, file); // read in next chunk

					if(readsize <= 0)
						break; // reading finished (or failed)

					offset += readsize;
					if (length > 0 && offset >= length) {
						break;
					}
				}
				size = offset;
				CancelAction();
			}
		}
		retry = 0;
		fclose (file);
	}

	// go back to checking if devices were inserted/removed
	ResumeDeviceThread();
	CancelAction();
	return size;
}
Beispiel #23
0
/***************************************************************************
 * Browse subdirectories
 **************************************************************************/
int
ParseDirectory(bool waitParse, bool filter)
{
	int retry = 1;
	bool mounted = false;
	parseFilter = filter;
	
	ResetBrowser(); // reset browser
	
	// add trailing slash
	if(browser.dir[strlen(browser.dir)-1] != '/')
		strcat(browser.dir, "/");

	// open the directory
	while(dir == NULL && retry == 1)
	{
		mounted = ChangeInterface(browser.dir, NOTSILENT);

		if(mounted)
			dir = opendir(browser.dir);
		else
			return -1;

		if(dir == NULL)
			retry = ErrorPromptRetry("Error opening directory!");
	}

	// if we can't open the dir, try higher levels
	if (dir == NULL)
	{
		char * devEnd = strrchr(browser.dir, '/');

		while(!IsDeviceRoot(browser.dir))
		{
			devEnd[0] = 0; // strip slash
			devEnd = strrchr(browser.dir, '/');

			if(devEnd == NULL)
				break;

			devEnd[1] = 0; // strip remaining file listing
			dir = opendir(browser.dir);
			if (dir)
				break;
		}
	}
	
	if(dir == NULL)
		return -1;

	if(IsDeviceRoot(browser.dir))
	{
		AddBrowserEntry();
		sprintf(browserList[0].filename, "..");
		sprintf(browserList[0].displayname, "Up One Level");
		browserList[0].length = 0;
		browserList[0].isdir = 1; // flag this as a dir
		browserList[0].icon = ICON_FOLDER;
		browser.numEntries++;
	}

	parseHalt = false;
	ParseDirEntries(); // index first 20 entries

	LWP_ResumeThread(parsethread); // index remaining entries

	if(waitParse) // wait for complete parsing
	{
		ShowAction("Loading...");

		while(!LWP_ThreadIsSuspended(parsethread))
			usleep(THREAD_SLEEP);

		CancelAction();
	}

	return browser.numEntries;
}
Beispiel #24
0
/****************************************************************************
 * 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)
{
	int res = 0;
	char http_host[1024];
	char http_path[1024];
	u16 http_port;

	http_res result;
	u32 http_status;
	u32 sizeread = 0, content_length = 0;

	int linecount;

	if(maxsize > MAX_SIZE)
		return 0;

	if (url == NULL || (hfile == NULL && buffer == NULL))
		return 0;
		
	if (!http_split_url(http_host, http_path, url))
		return 0;

	http_port = 80;
	http_status = 404;

	int s = tcp_connect(http_host, http_port);

	if (s < 0)
	{
		result = HTTPR_ERR_CONNECT;
		return 0;
	}

	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);
	r += sprintf(r, "Cache-Control: no-cache\r\n\r\n");

	res = tcp_write(s, (u8 *) request, strlen(request));

	char line[256];

	for (linecount = 0; linecount < 32; linecount++)
	{
		if (tcp_readln(s, line, 255) != 0)
		{
			http_status = 404;
			result = HTTPR_ERR_REQUEST;
			break;
		}

		if (strlen(line) < 1)
			break;

		sscanf(line, "HTTP/1.%*u %u", &http_status);
		sscanf(line, "Content-Length: %u", &content_length);
	}

	if (http_status != 200)
	{
		result = HTTPR_ERR_STATUS;
		net_close(s);
		return 0;
	}

	// length unknown - just read as much as we can
	if(content_length == 0)
	{
		content_length = maxsize;
	}
	else if (content_length > maxsize)
	{
		result = HTTPR_ERR_TOOBIG;
		net_close(s);
		return 0;
	}

	if (buffer != NULL)
	{
		if(!silent)
			ShowAction("Downloading...");

		sizeread = tcp_read(s, buffer, content_length);

		if(!silent)
			CancelAction();
	}
	else
	{
		// read into file
		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(s, fbuffer, readSize);
				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();
	}

	net_close(s);

	if (content_length < maxsize && sizeread != content_length)
	{
		result = HTTPR_ERR_RECEIVE;
		return 0;
	}

	result = HTTPR_OK;
	return sizeread;
}
Beispiel #25
0
size_t
UnZipBuffer (unsigned char *outbuffer)
{
	PKZIPHEADER pkzip;
	size_t zipoffset = 0;
	size_t zipchunk = 0;
	char out[ZIPCHUNK];
	z_stream zs;
	int res;
	size_t bufferoffset = 0;
	size_t have = 0;
	char readbuffer[ZIPCHUNK];
	size_t sizeread = 0;

	// Read Zip Header
	fseek(file, 0, SEEK_SET);
	sizeread = fread (readbuffer, 1, ZIPCHUNK, file);

	if(sizeread <= 0)
		return 0;

	/*** Copy PKZip header to local, used as info ***/
	memcpy (&pkzip, readbuffer, sizeof (PKZIPHEADER));

	pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize);

	ShowProgress ("Loading...", 0, pkzip.uncompressedSize);

	/*** Prepare the zip stream ***/
	memset (&zs, 0, sizeof (z_stream));
	zs.zalloc = Z_NULL;
	zs.zfree = Z_NULL;
	zs.opaque = Z_NULL;
	zs.avail_in = 0;
	zs.next_in = Z_NULL;
	res = inflateInit2 (&zs, -MAX_WBITS);

	if (res != Z_OK)
		goto done;

	/*** Set ZipChunk for first pass ***/
	zipoffset =
	(sizeof (PKZIPHEADER) + FLIP16 (pkzip.filenameLength) +
	FLIP16 (pkzip.extraDataLength));
	zipchunk = ZIPCHUNK - zipoffset;

	/*** Now do it! ***/
	do
	{
		zs.avail_in = zipchunk;
		zs.next_in = (Bytef *) & readbuffer[zipoffset];

		/*** Now inflate until input buffer is exhausted ***/
		do
		{
			zs.avail_out = ZIPCHUNK;
			zs.next_out = (Bytef *) & out;

			res = inflate (&zs, Z_NO_FLUSH);

			if (res == Z_MEM_ERROR)
			{
				goto done;
			}

			have = ZIPCHUNK - zs.avail_out;
			if (have)
			{
				/*** Copy to normal block buffer ***/
				memcpy (&outbuffer[bufferoffset], &out, have);
				bufferoffset += have;
			}
		}
		while (zs.avail_out == 0);

		// Readup the next 2k block
		zipoffset = 0;
		zipchunk = ZIPCHUNK;

		sizeread = fread (readbuffer, 1, ZIPCHUNK, file);
		if(sizeread <= 0)
			goto done; // read failure

		ShowProgress ("Loading...", bufferoffset, pkzip.uncompressedSize);
	}
	while (res != Z_STREAM_END);

done:
	inflateEnd (&zs);
	CancelAction();

	if (res == Z_STREAM_END)
		return pkzip.uncompressedSize;
	else
		return 0;
}
Beispiel #26
0
int SzParse(char * filepath)
{
	if(!filepath)
		return 0;
	
	int device;
	
	if(!FindDevice(browser.dir, &device) || !GetFileSize(browser.selIndex))
		return 0;

	int nbfiles = 0;

	// save the length/offset of this file
	unsigned int filelen = browserList[browser.selIndex].length;

	// setup archive stream
	SzArchiveStream.offset = 0;
	SzArchiveStream.len = filelen;
	SzArchiveStream.pos = 0;

	// open file
	file = fopen (filepath, "rb");
	if(!file)
		return 0;

	// set szMethod to current chosen load device
	szMethod = device;

	// set handler functions for reading data from SD/USB/SMB/DVD
	SzArchiveStream.InStream.Read = SzFileReadImp;
	SzArchiveStream.InStream.Seek = SzFileSeekImp;

	// set default 7Zip SDK handlers for allocation and freeing memory
	SzAllocImp.Alloc = SzAlloc;
	SzAllocImp.Free = SzFree;
	SzAllocTempImp.Alloc = SzAllocTemp;
	SzAllocTempImp.Free = SzFreeTemp;

	// prepare CRC and 7Zip database structures
	InitCrcTable();
	SzArDbExInit(&SzDb);

	// open the archive
	SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp,
			&SzAllocTempImp);

	if (SzRes != SZ_OK)
	{
		SzDisplayError(SzRes);
		// free memory used by the 7z SDK
		SzClose();
	}
	else // archive opened successfully
	{
		if(SzDb.Database.NumFiles > 0)
		{
			// Parses the 7z into a full file listing

			HaltParseThread(); // halt parsing
			ResetBrowser(); // reset browser

			// add '..' folder in case the user wants exit the 7z
			AddBrowserEntry();

			sprintf(browserList[0].displayname, "Up One Level");
			browserList[0].isdir = 1;
			browserList[0].length = filelen;
			browserList[0].icon = ICON_FOLDER;

			// get contents and parse them into file list structure
			unsigned int SzI, SzJ;
			SzJ = 1;
			for (SzI = 0; SzI < SzDb.Database.NumFiles; SzI++)
			{
				SzF = SzDb.Database.Files + SzI;

				// skip directories
				if (SzF->IsDirectory)
					continue;

				if(!AddBrowserEntry())
				{
					ResetBrowser();
					ErrorPrompt("Out of memory: too many files!");
					SzClose();
					SzJ = 0;
					break;
				}

				// parse information about this file to the file list structure
				snprintf(browserList[SzJ].filename, MAXJOLIET, "%s", SzF->Name);
				StripExt(browserList[SzJ].displayname, browserList[SzJ].filename);
				browserList[SzJ].length = SzF->Size; // filesize
				browserList[SzJ].isdir = 0; // only files will be displayed (-> no flags)
				browserList[SzJ].filenum = SzI; // the extraction function identifies the file with this number
				SzJ++;
			}
			nbfiles = SzJ;
		}
		else
		{
			SzClose();
		}
	}

	CancelAction();

	// close file
	fclose(file);
	return nbfiles;
}
Beispiel #27
0
/****************************************************************************
 * LoadMCFile
 * Load savebuffer from Memory Card file
 ***************************************************************************/
int
LoadMCFile (char *buf, int slot, char *filename, bool silent)
{
	card_file CardFile;
	int CardError;
	unsigned int blocks;
	unsigned int SectorSize;
	int bytesleft = 0;
	int bytesread = 0;

	// Try to mount the card
	CardError = MountMC(slot, NOTSILENT);

	if (CardError == 0)
	{
		// Get Sector Size
		CARD_GetSectorSize (slot, &SectorSize);

		memset (&CardFile, 0, sizeof (CardFile));
		CardError = CARD_Open (slot, filename, &CardFile);

		if(CardError)
		{
			if(!silent)
				ErrorPrompt("Unable to open file!");
		}
		else
		{
			blocks = CardFile.len;

			if (blocks < SectorSize)
				blocks = SectorSize;

			if (blocks % SectorSize)
				blocks += SectorSize;

			bytesleft = blocks;
			bytesread = 0;
			while (bytesleft > 0)
			{
				CardError = CARD_Read (&CardFile, buf + bytesread, SectorSize, bytesread);

				if(CardError)
				{
					ErrorPrompt("Error loading file!");
					bytesread = 0;
					break;
				}

				bytesleft -= SectorSize;
				bytesread += SectorSize;
				ShowProgress ("Loading...", bytesread, blocks);
			}
			CARD_Close (&CardFile);
			CancelAction();
		}
		CARD_Unmount(slot);
	}

	// discard save icon and comments
	memmove(buf, buf+sizeof(saveicon)+64, bytesread);
	bytesread -= (sizeof(saveicon)+64);

	free(SysArea);
	return bytesread;
}
Beispiel #28
0
/****************************************************************************
 * SaveMCFile
 * Write savebuffer to Memory Card file
 ***************************************************************************/
int
SaveMCFile (char *buf, int slot, char *filename, int datasize, bool silent)
{
	card_file CardFile;
	card_stat CardStatus;
	int CardError;
	unsigned int blocks;
	unsigned int SectorSize;
	int byteswritten = 0;
	int bytesleft = 0;

	if(datasize <= 0)
		return 0;

	// add save icon and comments
	memmove(buf+sizeof(saveicon)+64, buf, datasize);
	memcpy(buf, saveicon, sizeof(saveicon));
	memcpy(buf+sizeof(saveicon), savecomments, 64);
	datasize += (sizeof(saveicon)+64);

	// Try to mount the card
	CardError = MountMC(slot, NOTSILENT);

	if (CardError == 0)
	{
		// Get Sector Size
		CARD_GetSectorSize (slot, &SectorSize);

		// Calculate number of blocks required
		blocks = (datasize / SectorSize) * SectorSize;
		if (datasize % SectorSize)
			blocks += SectorSize;

		// Delete existing file (if present)
		memset(&CardStatus, 0, sizeof(card_stat));
		CardError = CARD_Open (slot, filename, &CardFile);

		if(CardError == 0)
		{
			CARD_Close (&CardFile);
			CardError = CARD_Delete(slot, filename);
			if (CardError)
			{
				ErrorPrompt("Unable to delete existing file!");
				goto done;
			}
		}

		// Create new file
		memset(&CardStatus, 0, sizeof(card_stat));
		CardError = CARD_Create (slot, filename, blocks, &CardFile);
		if (CardError)
		{
			if (CardError == CARD_ERROR_INSSPACE)
				ErrorPrompt("Insufficient space to create file!");
			else
				ErrorPrompt("Unable to create card file!");
			goto done;
		}

		// Now, have an open file handle, ready to send out the data
		CARD_GetStatus (slot, CardFile.filenum, &CardStatus);
		CardStatus.icon_addr = 0x0;
		CardStatus.icon_fmt = 2;
		CardStatus.icon_speed = 1;
		CardStatus.comment_addr = 2048;
		CARD_SetStatus (slot, CardFile.filenum, &CardStatus);

		bytesleft = blocks;

		while (bytesleft > 0)
		{
			CardError =
				CARD_Write (&CardFile, buf + byteswritten, SectorSize, byteswritten);

			if(CardError)
			{
				ErrorPrompt("Error writing file!");
				byteswritten = 0;
				break;
			}

			bytesleft -= SectorSize;
			byteswritten += SectorSize;

			ShowProgress ("Saving...", byteswritten, blocks);
		}
		CARD_Close (&CardFile);
		CancelAction();

		if (byteswritten > 0 && GCSettings.VerifySaves)
		{
			// Verify the written file
			if (!VerifyMCFile (buf, slot, filename, byteswritten) )
				byteswritten = 0;
		}
done:
		CARD_Unmount (slot);
	}

	free(SysArea);
	return byteswritten;
}
Beispiel #29
0
bool
SavePrefs (bool silent)
{
	char filepath[MAXPATHLEN];
	int datasize;
	int offset = 0;
	int device = 0;
	
	if(prefpath[0] != 0)
	{
		sprintf(filepath, "%s/%s", prefpath, PREF_FILE_NAME);
		FindDevice(filepath, &device);
	}
	else if(appPath[0] != 0)
	{
		sprintf(filepath, "%s/%s", appPath, PREF_FILE_NAME);
		strcpy(prefpath, appPath);
		FindDevice(filepath, &device);
	}
	else
	{
		device = autoSaveMethod(silent);
		
		if(device == 0)
			return false;
		
		sprintf(filepath, "%s%s", pathPrefix[device], APPFOLDER);
						
		DIR *dir = opendir(filepath);
		if (!dir)
		{
			if(mkdir(filepath, 0777) != 0)
				return false;
			sprintf(filepath, "%s%s/roms", pathPrefix[device], APPFOLDER);
			if(mkdir(filepath, 0777) != 0)
				return false;
			sprintf(filepath, "%s%s/saves", pathPrefix[device], APPFOLDER);
			if(mkdir(filepath, 0777) != 0)
				return false;
		}
		else
		{
			closedir(dir);
		}
		sprintf(filepath, "%s%s/%s", pathPrefix[device], APPFOLDER, PREF_FILE_NAME);
		sprintf(prefpath, "%s%s", pathPrefix[device], APPFOLDER);
	}
	
	if(device == 0)
		return false;

	if (!silent)
		ShowAction ("Saving preferences...");

	FixInvalidSettings();

	AllocSaveBuffer ();
	datasize = preparePrefsData ();

	offset = SaveFile(filepath, datasize, silent);

	FreeSaveBuffer ();

	CancelAction();

	if (offset > 0)
	{
		if (!silent)
			InfoPrompt("Preferences saved");
		return true;
	}
	return false;
}
Beispiel #30
0
/****************************************************************************
 * 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;
}