Esempio n. 1
0
static Result action_install_cdn_get_src_size(void* data, u32 handle, u64* size) {
    u32 downloadSize = 0;
    Result res = httpcGetDownloadSizeState((httpcContext*) handle, NULL, &downloadSize);

    *size = downloadSize;
    return res;
}
Esempio n. 2
0
const char* HttpService::get(char *url) {
	u32 statuscode = 0;
	u32 contentsize = 0;
	u8 *buf;
	httpcContext context;
	Result ret = 0;
	ret = httpcOpenContext(&context, url, 1);
	ret = httpcBeginRequest(&context);
	if(ret!=0)return NULL;

	ret = httpcGetResponseStatusCode(&context, &statuscode, 0);
	if(ret!=0)return NULL;
	if(statuscode!=200)return NULL;

	ret=httpcGetDownloadSizeState(&context, NULL, &contentsize);
	if(ret!=0)return NULL;

	buf = (u8*)malloc(contentsize + 1);
	if(buf==NULL)return NULL;
	memset(buf, 0, contentsize + 1);

	ret = httpcDownloadData(&context, buf, contentsize, NULL);
	if(ret!=0)
	{
		free(buf);
		return NULL;
	}
	httpcCloseContext(&context);
	return (const char*)buf;
}
Esempio n. 3
0
/***
Download and return the data of the context.
@function :downloadData
@treturn[1] string data
@treturn[2] nil in case of error
@treturn[2] integer error code
*/
static int httpc_downloadData(lua_State *L) {
	httpcContext *context = lua_touserdata(L, 1);
	u32 status = 0;
	Result ret = httpcGetResponseStatusCode(context, &status, 0);
	if (ret != 0) {
		lua_pushnil(L);
		lua_pushinteger(L, ret);
		return 2;
	}
	
	u32 size = 0;
	httpcGetDownloadSizeState(context, NULL, &size);
	u8 *buff = (u8*)malloc(size);
	
	ret = httpcDownloadData(context, buff, size, NULL);
	if (ret != 0) {
		free(buff);
		lua_pushnil(L);
		lua_pushinteger(L, ret);
		return 2;
	}
	
	lua_pushstring(L, (char*)buff);
	free(buff);
	//lua_pushinteger(L, size); // only for test purposes.
	return 1;
}
Esempio n. 4
0
static int lua_downstring(lua_State *L){
	int argc = lua_gettop(L);
	#ifndef SKIP_ERROR_HANDLING
		if (argc != 1) return luaL_error(L, "wrong number of arguments");
	#endif
	const char* url = luaL_checkstring(L,1);
	httpcContext context;
	Result ret = httpcOpenContext(&context, (char*)url , 0);
	#ifndef SKIP_ERROR_HANDLING
		if(ret==0){
	#endif
		httpcBeginRequest(&context);
		/*httpcReqStatus loading;
		httpcGetRequestState(&context, &loading);
		while (loading == 0x5){
			httpcGetRequestState(&context, &loading);
		}*/
		u32 statuscode=0;
		u32 contentsize=0;
		httpcGetResponseStatusCode(&context, &statuscode, 0);
		char text[128];
		sprintf(text,"%i",statuscode);
		if (statuscode != 200) luaL_error(L, text);
		httpcGetDownloadSizeState(&context, NULL, &contentsize);
		unsigned char *buffer = (unsigned char*)malloc(contentsize+1);
		httpcDownloadData(&context, buffer, contentsize, NULL);
		buffer[contentsize] = 0;
		lua_pushlstring(L,(const char*)buffer,contentsize);
		free(buffer);
	#ifndef SKIP_ERROR_HANDLING
		}else luaL_error(L, "error opening url");
	#endif
	httpcCloseContext(&context);
	return 1;
}
Esempio n. 5
0
Result http_download(httpcContext *context, u8** out_buf, u32* out_size)
{
	Result ret=0;
	u32 statuscode=0;
	u32 contentsize=0;
	u8 *buf;

	ret = httpcBeginRequest(context);
	if(ret!=0)return ret;

	ret = httpcGetResponseStatusCode(context, &statuscode, 0);
	if(ret!=0)return ret;

	if(statuscode!=200)return -2;

	ret=httpcGetDownloadSizeState(context, NULL, &contentsize);
	if(ret!=0)return ret;

	buf = (u8*)malloc(contentsize);
	if(buf==NULL)return -1;
	memset(buf, 0, contentsize);

	ret = httpcDownloadData(context, buf, contentsize, NULL);
	if(ret!=0)
	{
		free(buf);
		return ret;
	}

	if(out_size)*out_size = contentsize;
	if(out_buf)*out_buf = buf;
	else free(buf);

	return 0;
}
Esempio n. 6
0
/***
Return the amount of data to download.
@function :getDownloadSize
@treturn number size in (bytes)
*/
static int httpc_getDownloadSize(lua_State *L) {
	httpcContext *context = lua_touserdata(L, 1);
	u32 contentSize = 0;
	
	httpcGetDownloadSizeState(context, NULL, &contentSize);
	
	lua_pushinteger(L, contentSize);
	return 1;
}
Esempio n. 7
0
Result DownloadFile_Internal(const char *url, void *out, bool bProgress,
							 void (*write)(void* out, unsigned char* buffer, u32 readSize))
{
    httpcContext context;
    u32 fileSize = 0;
    u32 procSize = 0;
    Result ret = 0;
    Result dlret = HTTPC_RESULTCODE_DOWNLOADPENDING;
    u32 status;
    u32 bufSize = 0x100000;
    u32 readSize = 0;
    httpcOpenContext(&context, HTTPC_METHOD_GET, (char*)url, 1);

    ret = httpcBeginRequest(&context);
    if (ret != 0) goto _out;

    ret = httpcGetResponseStatusCode(&context, &status, 0);
    if (ret != 0) goto _out;

    if (status != 200)
    {
        ret = status;
        goto _out;
    }

    ret = httpcGetDownloadSizeState(&context, NULL, &fileSize);
    if (ret != 0) goto _out;

    {
        unsigned char *buffer = (unsigned char *)linearAlloc(bufSize);
        if (buffer == NULL)
        {
            printf("Error allocating download buffer\n");
            ret = -1;
            goto _out;
        }

        while (dlret == (s32)HTTPC_RESULTCODE_DOWNLOADPENDING)
        {
            memset(buffer, 0, bufSize);

            dlret = httpcDownloadData(&context, buffer, bufSize, &readSize);
            write(out, buffer, readSize);

            procSize += readSize;
            if (bProgress)
            {
            	PrintProgress(fileSize, procSize);
            }
        }
        linearFree(buffer);
    }
_out:
    httpcCloseContext(&context);

    return ret;
}
Esempio n. 8
0
Result http_download(httpcContext *context)
{
	ret=0;
	//u8* framebuf_top;
	u32 statuscode=0;
	//u32 size=0;
	u32 contentsize=0;
	u8 *buf;

	ret = httpcBeginRequest(context);
	if(ret!=0)return ret;

	ret = httpcGetResponseStatusCode(context, &statuscode, 0);
	if(ret!=0)return ret;

	//printf("http status code: %i\n", statuscode);

	if(statuscode!=200){
		printf("status code not 200, it was %i", statuscode);
		gfxFlushBuffers();
		return -2;
	}

	ret=httpcGetDownloadSizeState(context, NULL, &contentsize);
	if(ret!=0)return ret;
	unsigned char *buffer = (unsigned char*)malloc(contentsize+1);

	consoleSelect(&topScreen);

	printf("HTTP status code: %i\n", statuscode);
	printf("%i bytes\n", contentsize);
	gfxFlushBuffers();

	buf = (u8*)malloc(contentsize);
	if(buf==NULL)return -1;
	memset(buf, 0, contentsize);


	ret = httpcDownloadData(context, buffer, contentsize, NULL);
	if(ret!=0)
	{
		free(buf);
		return ret;
	}

	consoleSelect(&bottomScreen);
	printf("%s", buffer);

	free(buf);

	return 0;
}
Esempio n. 9
0
Result httpcDownloadData(httpcContext *context, u8* buffer, u32 size, u32 *downloadedsize)
{
	Result ret=0;
	u32 contentsize=0;
	u32 pos=0, sz=0;

	if(downloadedsize)*downloadedsize = 0;

	ret=httpcGetDownloadSizeState(context, NULL, &contentsize);
	if(ret!=0)return ret;

	while(pos < size)
	{
		sz = size - pos;

		ret=httpcReceiveData(context, &buffer[pos], sz);

		if(ret==HTTPC_RESULTCODE_DOWNLOADPENDING)
		{
			ret=httpcGetDownloadSizeState(context, &pos, NULL);
			if(ret!=0)return ret;
		}
		else if(ret!=0)
		{
			return ret;
		}
		else
		{
			pos+= sz;
		}

		if(downloadedsize)*downloadedsize = pos;
	}

	return 0;
}
Esempio n. 10
0
static int lua_download(lua_State *L){
	int argc = lua_gettop(L);
	#ifndef SKIP_ERROR_HANDLING
		if (argc != 2) return luaL_error(L, "wrong number of arguments");
	#endif
	const char* url = luaL_checkstring(L,1);
	const char* file = luaL_checkstring(L,2);
	httpcContext context;
	Result ret = httpcOpenContext(&context, (char*)url , 0);
	#ifndef SKIP_ERROR_HANDLING
		if(ret==0){
	#endif
		httpcBeginRequest(&context);
		/*httpcReqStatus loading;
		httpcGetRequestState(&context, &loading);
		while (loading == 0x5){
			httpcGetRequestState(&context, &loading);
		}*/
		u32 statuscode=0;
		u32 contentsize=0;
		httpcGetResponseStatusCode(&context, &statuscode, 0);
		#ifndef SKIP_ERROR_HANDLING
			if (statuscode != 200) luaL_error(L, "download request error");
		#endif
		httpcGetDownloadSizeState(&context, NULL, &contentsize);
		u8* buf = (u8*)malloc(contentsize);
		memset(buf, 0, contentsize);
		httpcDownloadData(&context, buf, contentsize, NULL);
		Handle fileHandle;
		u32 bytesWritten;
		FS_Archive sdmcArchive=(FS_Archive){ARCHIVE_SDMC, (FS_Path){PATH_EMPTY, 1, (u8*)""}};
		FS_Path filePath=fsMakePath(PATH_ASCII, file);
		FSUSER_OpenFileDirectly( &fileHandle, sdmcArchive, filePath, FS_OPEN_CREATE|FS_OPEN_WRITE, 0x00000000);
		FSFILE_Write(fileHandle, &bytesWritten, 0, buf, contentsize,0x10001);
		FSFILE_Close(fileHandle);
		svcCloseHandle(fileHandle);
		free(buf);
	#ifndef SKIP_ERROR_HANDLING
		}else luaL_error(L, "error opening url");
	#endif
	httpcCloseContext(&context);
	return 0;
}
Esempio n. 11
0
Result download_file(httpcContext *context, void** buffer, size_t* size, char* user_agent)
{
    Result ret;

    ret = httpcAddRequestHeaderField(context, "User-Agent", user_agent);
    if(R_FAILED(ret)) return ret;

    ret = httpcBeginRequest(context);
    if(R_FAILED(ret)) return ret;

    u32 status_code = 0;
    ret = httpcGetResponseStatusCode(context, &status_code);
    if(R_FAILED(ret)) return ret;

    if(status_code != 200) return -1;

    u32 sz = 0;
    ret = httpcGetDownloadSizeState(context, NULL, &sz);
    if(R_FAILED(ret)) return ret;

    void* buf = malloc(sz);
    if(!buf) return -2;

    memset(buf, 0, sz);

    ret = httpcDownloadData(context, buf, sz, NULL);
    if(R_FAILED(ret))
    {
        free(buf);
        return ret;
    }

    if(size) *size = sz;
    if(buffer) *buffer = buf;
    else free(buf);

    return 0;
}
Esempio n. 12
0
Result downloadPage(Handle httpcHandle, char* url, const short* filename)
{
    Result ret;
    httpcContext context;
    u32 statuscode, size;    

    ret = httpcOpenContext(httpcHandle, &context, url);

    if(!ret)
    {
        ret = httpcBeginRequest(&context);
        if(ret) goto exit;
        ret = httpcGetResponseStatusCode(&context, &statuscode);
        if(ret || statuscode != 200) goto exit;
        ret = httpcGetDownloadSizeState(&context, 0, &size);
        if(ret) goto exit;
        ret = downloadPageToSDCard(&context, filename, size);

exit:   httpcCloseContext(httpcHandle, &context);
    }

    return ret;
}
Esempio n. 13
0
int httpGet(const char* url, u8** buf, u32* size) {
	httpcContext context;
	CHECK(httpcOpenContext(&context, HTTPC_METHOD_GET, (char*)url, 0), "Could not open HTTP context");
	// Add User Agent field (required by Github API calls)
	CHECK(httpcAddRequestHeaderField(&context, (char*)"User-Agent", (char*)"ARN-UPDATER"), "Could not set User Agent");

	CHECK(httpcBeginRequest(&context), "Could not begin request");

	// Add root CA required for Github and AWS URLs
	CHECK(httpcAddTrustedRootCA(&context, digicert_cer, digicert_cer_len), "Could not add Digicert root CA");
	CHECK(httpcAddTrustedRootCA(&context, cybertrust_cer, cybertrust_cer_len), "Could not add Cybertrust root CA");

	u32 statuscode = 0;
	CHECK(httpcGetResponseStatusCode(&context, &statuscode, 0), "Could not get status code");
	if (statuscode != 200) {
		// Handle 3xx codes
		if (statuscode >= 300 && statuscode < 400) {
			char newUrl[1024];
			CHECK(httpcGetResponseHeader(&context, (char*)"Location", newUrl, 1024), "Could not get Location header for 3xx reply");
			CHECK(httpcCloseContext(&context), "Could not close HTTP context");
			return httpGet(newUrl, buf, size);
		}
		throw formatErrMessage("Non-200 status code", statuscode);
	}

	CHECK(httpcGetDownloadSizeState(&context, NULL, size), "Could not get file size");

	*buf = (u8*)std::malloc(*size);
	if (*buf == NULL) throw formatErrMessage("Could not allocate enough memory", *size);
	std::memset(*buf, 0, *size);

	CHECK(httpcDownloadData(&context, *buf, *size, NULL), "Could not download data");

	CHECK(httpcCloseContext(&context), "Could not close HTTP context");

	return 1;
}
Esempio n. 14
0
Result inline downloadPageToSDCard(httpcContext* context, const short* filename, u32 size)
{
    Result ret = 0;
    u32 pos = 0, sz = 0;

    IFile_Open(FILE_LOC, filename, FILE_W);
    *((int *)FILE_LOC + 1) = 0;
    svcSleepThread(0x400000LL);

    while(pos < size)
    {
        sz = size - pos;

        sz = sz > BUF_LEN ? BUF_LEN : sz;

        ret = httpcReceiveData(context, BUF_LOC, sz);

        if(ret == HTTPC_RESULTCODE_DOWNLOADPENDING)
        {
            ret = httpcGetDownloadSizeState(context, &pos, 0);
            if(ret)
                return ret;
            goto filewrite;
        }
        else if(ret)
            return ret;
        else
        {
            pos += sz;
filewrite:  IFile_Write(FILE_LOC, WRITTEN_LOC, BUF_LOC, sz);
            svcSleepThread(0x400000LL);
        }

    }

    return 0;
}
Esempio n. 15
0
File: main.c Progetto: ThibG/ctrulib
Result http_download(httpcContext *context)//This error handling needs updated with proper text printing once ctrulib itself supports that.
{
	Result ret=0;
	u8* framebuf_top, *framebuf_bottom;
	u32 statuscode=0;
	u32 size=0, contentsize=0;
	u8 *buf;

	framebuf_bottom = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL);
	memset(framebuf_bottom, 0x40, 240*320*3);
	gfxFlushBuffers();
	gfxSwapBuffers();

	framebuf_bottom = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL);
	memset(framebuf_bottom, 0x40, 240*320*3);
	gfxFlushBuffers();
	gfxSwapBuffers();
	gspWaitForVBlank();

	ret = httpcBeginRequest(context);
	if(ret!=0)return ret;

	ret = httpcGetResponseStatusCode(context, &statuscode, 0);
	if(ret!=0)return ret;

	if(statuscode!=200)return -2;

	ret=httpcGetDownloadSizeState(context, NULL, &contentsize);
	if(ret!=0)return ret;

	buf = (u8*)malloc(contentsize);
	if(buf==NULL)return -1;
	memset(buf, 0, contentsize);

	framebuf_bottom = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL);
	memset(framebuf_bottom, 0xc0, 240*320*3);
	gfxFlushBuffers();
	gfxSwapBuffers();

	framebuf_bottom = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL);
	memset(framebuf_bottom, 0xc0, 240*320*3);
	gfxFlushBuffers();
	gfxSwapBuffers();
	gspWaitForVBlank();

	framebuf_top = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);
	framebuf_bottom = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL);

	ret = httpcDownloadData(context, buf, contentsize, NULL);
	if(ret!=0)
	{
		free(buf);
		return ret;
	}

	size = contentsize;
	if(size>(240*400*3))size = 240*400*3;

	memset(framebuf_bottom, 0xff, 240*320*3);
	memcpy(framebuf_top, buf, size);

	gfxFlushBuffers();
	gfxSwapBuffers();

	framebuf_top = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);
	framebuf_bottom = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL);

	memset(framebuf_bottom, 0xff, 240*320*3);
	memcpy(framebuf_top, buf, size);

	gfxFlushBuffers();
	gfxSwapBuffers();
	gspWaitForVBlank();

	free(buf);

	return 0;
}
Esempio n. 16
0
Result http_downloadsave(httpcContext *context, char *filename)//This error handling needs updated with proper text printing once ctrulib itself supports that.
{
    ret = 0;
    //u8* framebuf_top;
    u32 statuscode=0;
    //u32 size=0;
    u32 contentsize=0;
    u8 *buf;

    ret = httpcBeginRequest(context);
    if(ret!=0)return ret;

    ret = httpcGetResponseStatusCode(context, &statuscode, 0);
    if(ret!=0)return ret;

    //printf("http status code: %i\n", statuscode);

    if(statuscode!=200){
        printf("status code not 200, it was %i\n", statuscode);
        gfxFlushBuffers();
        return -2;
    }

    ret=httpcGetDownloadSizeState(context, NULL, &contentsize);
    if(ret!=0)return ret;
    unsigned char *buffer = (unsigned char*)malloc(contentsize+1);

    consoleSelect(&topScreen);

    printf("HTTP status code: %i\n", statuscode);
    printf("%i bytes\n", contentsize);
    gfxFlushBuffers();

    buf = (u8*)malloc(contentsize);
    if(buf==NULL)return -1;
    memset(buf, 0, contentsize);


    ret = httpcDownloadData(context, buffer, contentsize, NULL);
    if(ret!=0)
    {
        free(buf);
        return ret;
    }

    /*size = contentsize;
    if(size>(240*400*3*2))size = 240*400*3*2;
    framebuf_top = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);
    memcpy(framebuf_top, buf, size);
    gfxFlushBuffers();
    gfxSwapBuffers();
    framebuf_top = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);
    memcpy(framebuf_top, buf, size);
    gfxFlushBuffers();
    gfxSwapBuffers();
    gspWaitForVBlank();*/

		printf("Got file\n");

		//char filename[32];
		FILE *dlfile;

		char *fnameformat;

		//snprintf(filename, sizeof(char) * 32, "koopadl%i.txt", ++dlCounter);
		printf("Saving to %s\n", filename);

    dlfile = fopen(filename, "w");
    fwrite(buffer, 1, contentsize, dlfile);
    fclose(dlfile);

    consoleSelect(&topScreen);
		printf("Saved to %s\n", filename);

    //printf("%s", buffer);

    free(buf);

    return 0;
}
Esempio n. 17
0
static int lua_sendmail(lua_State *L){ //BETA func
	int argc = lua_gettop(L);
	#ifndef SKIP_ERROR_HANDLING
		if (argc != 3) return luaL_error(L, "wrong number of arguments");
	#endif
	char* to = (char*)luaL_checkstring(L,1);
	char* subj = (char*)luaL_checkstring(L,2);
	char* mex = (char*)luaL_checkstring(L,3);
	int req_size = 70;
	int nss = SpaceCounter(subj);
	int nsm = SpaceCounter(mex);
	req_size = req_size + nss * 2 + nsm * 2 + strlen(subj) + strlen(mex) + strlen(to);
	char* url = (char*)malloc(req_size);
	strcpy(url,"http://rinnegatamante.netsons.org/tmp_mail_lpp_beta.php?t=");
	strcat(url,to);
	strcat(url,"&s=");
	char* subj_p = subj;
	char* url_p = &url[strlen(url)];
	while (*subj_p){
		if (subj_p[0] == 0x20){
			url_p[0] = '%';
			url_p++;
			url_p[0] = '2';
			url_p++;
			url_p[0] = '0';
		}else url_p[0] = subj_p[0];
		url_p++;
		subj_p++;
	}
	strcat(url,"&b=");
	char* mex_p = mex;
	url_p = &url[strlen(url)];
	while (*mex_p){
		if (mex_p[0] == 0x20){
			url_p[0] = '%';
			url_p++;
			url_p[0] = '2';
			url_p++;
			url_p[0] = '0';
		}else url_p[0] = mex_p[0];
		url_p++;
		mex_p++;
	}
	url_p[0] = 0;
	httpcContext context;
	Result ret = httpcOpenContext(&context, (char*)url , 0);
	#ifndef SKIP_ERROR_HANDLING
		if(ret==0){
	#endif
		httpcBeginRequest(&context);
		HTTPC_RequestStatus loading;
		httpcGetRequestState(&context, &loading);
		while (loading == HTTPC_STATUS_REQUEST_IN_PROGRESS){
			httpcGetRequestState(&context, &loading);
		}
		u32 statuscode=0;
		u32 contentsize=0;
		httpcGetResponseStatusCode(&context, &statuscode, 0);
		if (statuscode != 200) luaL_error(L, "request error");
		httpcGetDownloadSizeState(&context, NULL, &contentsize);
		u8 response;
		httpcDownloadData(&context, &response, contentsize, NULL);
		lua_pushboolean(L,response);
		free(url);
	#ifndef SKIP_ERROR_HANDLING
		}else luaL_error(L, "error opening url");
	#endif
	httpcCloseContext(&context);
	return 1;
}
Esempio n. 18
0
Result InitializeClockOffset() {
	/* Compares the system clock with current UTC time from timeapi.com */
	/* ESSENTIAL for correct OTP generation, unless system clock is UTC */
	/* Returns difference, in seconds. */
	/* Add the result of this function to the 3DS time to get UTC. */
	
	if (IsValidTimeOffset(g_SystemClockUtcOffset)) return true;
	
	Result ret = 0;
	unsigned long statusCode = 0;
	unsigned long contentSize = 0;
	unsigned char *buffer = NULL;

	httpcContext context; // NOTE: Uninitialized memory
	httpcInit(0);
	
	char * url = "http://old-labs.muffinti.me/atoolyoucanputonthewall.php";
	/* put this line into a blank PHP file:

	<?php date_default_timezone_set("UTC"); echo time(); exit; ?>

	*/

	/* URL returning current time in UTC */
	
	if (ret) {
		ret = httpcOpenContext(&context, HTTPC_METHOD_GET, url, 1);
	}

	if (ret) {
		ret = httpcBeginRequest(&context);
	}
	
	if (ret) {
		ret = httpcGetResponseStatusCode(&context, &statusCode);
		if (ret && statusCode != 200) {
			printf("WARNING: HTTP status code returned was %d\n", statusCode);
		}
	}
	if (ret) {
		ret = httpcGetDownloadSizeState(&context, NULL, &contentSize);
	}
	if (ret) {
		if(contentSize+1 < contentSize) {
			ret =  R_TINYTOT_OVERFLOW; // overflow -- do not allow
		}
	}
	if (ret) {
		buffer = (unsigned char*)malloc(contentSize+1);
		if(buffer == NULL) {
			ret = R_TINYTOT_OUTOFMEMORY;
		}
	}
	if (ret) {
		memset(buffer, 0, contentSize+1); // zero that last byte also
		ret = httpcDownloadData(&context, buffer, contentSize, NULL);
	}
	if (ret) {
		time_t utcTime = (time_t)atol(buffer);
		time_t systemTime = time(NULL);
		signed long timeDifference = systemTime - utcTime; /* time(NULL) + timeDifference = UTC */
		g_SystemClockUtcOffset = timeDifference;
	}
	if (NULL != buffer) {
		free(buffer);
	}
	return ret;
}
Result http_download_payload(char *url, u32 *payloadsize)
{
	Result ret=0;
	u32 statuscode=0;
	u32 contentsize=0;
	httpcContext context;

	ret = httpcOpenContext(&context, url, 1);
	if(ret!=0)return ret;

	ret = httpcAddRequestHeaderField(&context, "User-Agent", "hblauncher_loader/"VERSION);
	if(ret!=0)
	{
		httpcCloseContext(&context);
		return ret;
	}

	ret = httpcBeginRequest(&context);
	if(ret!=0)
	{
		httpcCloseContext(&context);
		return ret;
	}

	ret = httpcGetResponseStatusCode(&context, &statuscode, 0);
	if(ret!=0)
	{
		httpcCloseContext(&context);
		return ret;
	}

	if(statuscode!=200)
	{
		printf("Error: server returned HTTP statuscode %u.\n", (unsigned int)statuscode);
		httpcCloseContext(&context);
		return -2;
	}

	ret=httpcGetDownloadSizeState(&context, NULL, &contentsize);
	if(ret!=0)
	{
		httpcCloseContext(&context);
		return ret;
	}

	if(contentsize==0 || contentsize>PAYLOAD_TEXTMAXSIZE)
	{
		printf("Invalid HTTP content-size: 0x%08x.\n", (unsigned int)contentsize);
		ret = -3;
		httpcCloseContext(&context);
		return ret;
	}

	ret = httpcDownloadData(&context, filebuffer, contentsize, NULL);
	if(ret!=0)
	{
		httpcCloseContext(&context);
		return ret;
	}

	httpcCloseContext(&context);

	*payloadsize = contentsize;

	return 0;
}