From 4d843e74117d3926fe03890f736cecd35c1e20a3 Mon Sep 17 00:00:00 2001 From: bucanero Date: Tue, 14 Dec 2021 22:10:31 -0300 Subject: [PATCH] Add https, progress bar --- Makefile | 2 +- include/saves.h | 5 +- source/dialog.c | 51 +++++----- source/http.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++ source/saves.c | 93 +++++++------------ source/settings.c | 5 +- source/zip_util.c | 29 +++++- 7 files changed, 319 insertions(+), 96 deletions(-) create mode 100644 source/http.c diff --git a/Makefile b/Makefile index d6e7c5c..5e75cdd 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ CONTENT_ID := IV0000-APOL00004_00-APOLLO0000000PS4 # Libraries linked into the ELF. LIBS := -lc -lkernel -lc++ -lSceAudioOut -lSceUserService -lSceVideoOut -lSceGnmDriver -lSceSysmodule -lSceFreeType \ - -lScePad -lSceSystemService -lSceSaveData -lSceCommonDialog -lSceMsgDialog \ + -lScePad -lSceSystemService -lSceSaveData -lSceCommonDialog -lSceMsgDialog -lSceNet -lSceSsl -lSceHttp \ -lSDL2 -lapollo -ldbglogger -lpolarssl -lz -lzip # Additional compile flags. diff --git a/include/saves.h b/include/saves.h index ea4f4e7..6e94e2c 100644 --- a/include/saves.h +++ b/include/saves.h @@ -127,6 +127,7 @@ enum cmd_code_enum #define SAVE_FLAG_TROPHY 128 #define SAVE_FLAG_ONLINE 256 #define SAVE_FLAG_PS4 512 +#define SAVE_FLAG_HDD 1024 enum save_type_enum { @@ -242,8 +243,8 @@ int extract_zip(const char* zip_file, const char* dest_path); int zip_directory(const char* basedir, const char* inputdir, const char* output_zipfile); int show_dialog(int dialog_type, const char * format, ...); -void init_progress_bar(const char* progress_bar_title, const char* msg); -void update_progress_bar(uint64_t* progress, const uint64_t total_size, const char* msg); +void init_progress_bar(const char* msg); +void update_progress_bar(uint64_t progress, const uint64_t total_size, const char* msg); void end_progress_bar(void); #define show_message(...) show_dialog(0, __VA_ARGS__) diff --git a/source/dialog.c b/source/dialog.c index 0642867..e28dd70 100644 --- a/source/dialog.c +++ b/source/dialog.c @@ -11,7 +11,6 @@ void drawDialogBackground(); -static float bar1_countparts; static inline void _orbisCommonDialogSetMagicNumber(uint32_t* magic, const OrbisCommonDialogBaseParam* param) { @@ -67,38 +66,42 @@ int show_dialog(int tdialog, const char * format, ...) return (result.buttonId == ORBIS_MSG_DIALOG_BUTTON_ID_YES); } -/* -void init_progress_bar(const char* progress_bar_title, const char* msg) +void init_progress_bar(const char* msg) { - bar1_countparts = 0.0f; + OrbisMsgDialogParam param; + OrbisMsgDialogProgressBarParam userBarParam; + OrbisMsgDialogResult result; - msgDialogOpen2(MSG_DIALOG_BKG_INVISIBLE | MSG_DIALOG_SINGLE_PROGRESSBAR | MSG_DIALOG_MUTE_ON, progress_bar_title, NULL, NULL, NULL); - msgDialogProgressBarSetMsg(MSG_PROGRESSBAR_INDEX0, msg); - msgDialogProgressBarReset(MSG_PROGRESSBAR_INDEX0); + sceMsgDialogInitialize(); + orbisMsgDialogParamInitialize(¶m); + param.mode = ORBIS_MSG_DIALOG_MODE_PROGRESS_BAR; + + memset(&userBarParam, 0, sizeof(userBarParam)); + userBarParam.msg = msg; + userBarParam.barType = ORBIS_MSG_DIALOG_PROGRESSBAR_TYPE_PERCENTAGE; + param.progBarParam = &userBarParam; + + if (sceMsgDialogOpen(¶m) < 0) + return; drawDialogBackground(); } void end_progress_bar(void) { - msgDialogAbort(); + sceMsgDialogClose(); + sceMsgDialogTerminate(); } -void update_progress_bar(uint64_t* progress, const uint64_t total_size, const char* msg) +void update_progress_bar(uint64_t progress, const uint64_t total_size, const char* msg) { - if(*progress > 0) { - bar1_countparts += (100.0f * ((double) *progress)) / ((double) total_size); - *progress = 0; - } - - if(bar1_countparts >= 1.0f) { - msgDialogProgressBarSetMsg(MSG_PROGRESSBAR_INDEX0, msg); - msgDialogProgressBarInc(MSG_PROGRESSBAR_INDEX0, (u32) bar1_countparts); - - bar1_countparts -= (float) ((u32) bar1_countparts); - } - - drawDialogBackground(); -} + float bar_value = (100.0f * ((double) progress)) / ((double) total_size); -*/ \ No newline at end of file + if (sceMsgDialogUpdateStatus() == ORBIS_COMMON_DIALOG_STATUS_RUNNING) + { + sceMsgDialogProgressBarSetMsg(0, msg); + sceMsgDialogProgressBarSetValue(0, (uint32_t) bar_value); + } + + drawDialogBackground(); +} diff --git a/source/http.c b/source/http.c new file mode 100644 index 0000000..f83e961 --- /dev/null +++ b/source/http.c @@ -0,0 +1,230 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "common.h" +#include "saves.h" + +#define HTTP_SUCCESS 1 +#define HTTP_FAILED 0 +#define HTTP_USER_AGENT "Mozilla/5.0 (PLAYSTATION 4; 1.00)" + +#define NET_POOLSIZE (4 * 1024) + + +static int libnetMemId = 0, libhttpCtxId = 0, libsslCtxId = 0; + +static int skipSslCallback(int libsslId, unsigned int verifyErr, void * const sslCert[], int certNum, void *userArg) +{ + LOG("sslCtx=%x (%X)", libsslId, verifyErr); + return HTTP_SUCCESS; +} + +int http_init() +{ + int ret; + + if(sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_INTERNAL_NET) < 0) + return HTTP_FAILED; + + if(sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_INTERNAL_HTTP) < 0) + return HTTP_FAILED; + + if(sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_INTERNAL_SSL) < 0) + return HTTP_FAILED; + + if (libnetMemId == 0 || libhttpCtxId == 0) + { + LOG("sceNet init"); + ret = sceNetInit(); + ret = sceNetPoolCreate("netPool", NET_POOLSIZE, 0); + if (ret < 0) { + LOG("sceNetPoolCreate() error: 0x%08X\n", ret); + return HTTP_FAILED; + } + libnetMemId = ret; + + LOG("sceSsl init"); + ret = sceSslInit(SSL_POOLSIZE); + if (ret < 0) { + LOG("sceSslInit() error: 0x%08X\n", ret); + return HTTP_FAILED; + } + libsslCtxId = ret; + + LOG("sceHttp init"); + ret = sceHttpInit(libnetMemId, libsslCtxId, LIBHTTP_POOLSIZE); + if (ret < 0) { + LOG("sceHttpInit() error: 0x%08X\n", ret); + return HTTP_FAILED; + } + libhttpCtxId = ret; + } + + return HTTP_SUCCESS; +} + +int http_download(const char* url, const char* filename, const char* local_dst, int show_progress) +{ + int ret, tpl = 0, conn = 0, req = 0; + int http_res = HTTP_FAILED; + int contentLengthType; + uint64_t contentLength; + int32_t statusCode; + char full_url[1024]; + + snprintf(full_url, sizeof(full_url), "%s%s", url, filename); + + tpl = sceHttpCreateTemplate(libhttpCtxId, HTTP_USER_AGENT, ORBIS_HTTP_VERSION_1_1, 1); + if (tpl < 0) { + LOG("sceHttpCreateConnectionWithURL() error: 0x%08X\n", tpl); + return HTTP_FAILED; + } + + ret = sceHttpsSetSslCallback(tpl, skipSslCallback, NULL); + if (ret < 0) { + LOG("sceHttpsSetSslCallback() error: 0x%08X\n", ret); + } + + conn = sceHttpCreateConnectionWithURL(tpl, full_url, 1); + if (conn < 0) { + LOG("sceHttpCreateConnectionWithURL() error: 0x%08X\n", conn); + goto close_http; + } + + req = sceHttpCreateRequestWithURL(conn, ORBIS_METHOD_GET, full_url, 0); + if (req < 0) { + LOG("sceHttpCreateRequestWithURL() error: 0x%08X\n", req); + goto close_http; + } + + LOG("Sending Request to '%s'\n", full_url); + ret = sceHttpSendRequest(req, NULL, 0); + if (ret < 0) { + LOG("sceHttpCreateRequestWithURL (%X)", ret); + goto close_http; + } + + ret = sceHttpGetStatusCode(req, &statusCode); + if (ret < 0) { + LOG("sceHttpGetStatusCode (%X)", ret); + goto close_http; + } + + ret = sceHttpGetResponseContentLength(req, &contentLengthType, &contentLength); + if (ret < 0) { + LOG("sceHttpGetContentLength() error: 0x%08X\n", ret); + //goto close_http; + } + else if (contentLengthType == ORBIS_HTTP_CONTENTLEN_EXIST) { + LOG("Content-Length = %lu\n", contentLength); + } + + if (statusCode != 200) + { + if (statusCode == 404) + LOG("404 Download Not Found"); + + else if (statusCode == 408) + LOG("Request Timed Out - Check your Connection"); + + goto close_http; + } + + uint8_t dl_buf[8 * 1024]; + uint64_t total_read = 0; + FILE* fd = fopen(local_dst, "wb"); + + if (!fd) { + LOG("fopen Error: File path '%s'", local_dst); + goto close_http; + } + + if (show_progress) + init_progress_bar("Downloading..."); + + while (1) { + int read = sceHttpReadData(req, dl_buf, sizeof(dl_buf)); + if (read < 0) + break; + + if (read == 0) + { + http_res = HTTP_SUCCESS; + break; + } + + ret = fwrite(dl_buf, 1, read, fd); + if (ret < 0 || ret != read) + break; + + total_read += read; + + if (show_progress) + update_progress_bar(total_read, contentLength, "Downloading..."); + + LOG("Downloaded %d/%d\n", total_read, contentLength); + } + + fclose(fd); + + if (show_progress) + end_progress_bar(); + +close_http: + if (req > 0) { + ret = sceHttpDeleteRequest(req); + if (ret < 0) { + LOG("sceHttpDeleteRequest() error: 0x%08X\n", ret); + } + } + + if (conn > 0) { + ret = sceHttpDeleteConnection(conn); + if (ret < 0) { + LOG("sceHttpDeleteConnection() error: 0x%08X\n", ret); + } + } + + if (tpl > 0) { + ret = sceHttpDeleteTemplate(tpl); + if (ret < 0) { + LOG("sceHttpDeleteTemplate() error: 0x%08X\n", ret); + } + } + + return (http_res); +} + +void http_end(void) +{ + sceHttpTerm(libhttpCtxId); + sceSslTerm(libsslCtxId); + sceNetPoolDestroy(libnetMemId); +} + +/* +void uri() { + int ret; + size_t mallocSize, outSize; + uchar8_t *data = "target string"; + char *out=NULL; + ret = sceHttpUriEscape(NULL, &mallocSize, 0, data); + if (ret < 0){ + printf("sceHttpUriEscape() returns %x.\n", ret); + goto error; + } + out = (uchar8_t*)malloc(mallocSize); + if (out == NULL){ + printf("can't allocate memory\n"); + goto error; + } + ret = sceHttpUriEscape(out, &outSize, mallocSize, data); +} +*/ diff --git a/source/saves.c b/source/saves.c index 5d19668..1bec983 100644 --- a/source/saves.c +++ b/source/saves.c @@ -1481,10 +1481,11 @@ list_t * ReadOnlineList(const char* urlPath) char url[256]; list_t *list = list_alloc(); - // PS3 save-games (Zip folder) - snprintf(url, sizeof(url), "%s" "PS3/", urlPath); - _ReadOnlineListEx(url, SAVE_FLAG_PS3, list); + // PS4 save-games (Zip folder) + snprintf(url, sizeof(url), "%s" "PS4/", urlPath); + _ReadOnlineListEx(url, SAVE_FLAG_PS4, list); +/* // PS2 save-games (Zip PSV) snprintf(url, sizeof(url), "%s" "PS2/", urlPath); _ReadOnlineListEx(url, SAVE_FLAG_PS2, list); @@ -1492,6 +1493,7 @@ list_t * ReadOnlineList(const char* urlPath) // PS1 save-games (Zip PSV) //snprintf(url, sizeof(url), "%s" "PS1/", urlPath); //_ReadOnlineListEx(url, SAVE_FLAG_PS1, list); +*/ if (!list_count(list)) { @@ -1501,27 +1503,25 @@ list_t * ReadOnlineList(const char* urlPath) return list; } -/* + list_t * ReadTrophyList(const char* userPath) { - DIR *d; - struct dirent *dir; save_entry_t *item; code_entry_t *cmd; list_t *list; char filePath[256]; - xmlDoc *doc = NULL; - xmlNode *root_element = NULL; - char *value, *buffer; - long bufferLen; + sqlite3 *db; + sqlite3_stmt *res; - if (dir_exists(userPath) != SUCCESS) + snprintf(filePath, sizeof(filePath), "%s" "trophy_local.db", userPath); + + if ((db = open_sqlite_db(filePath)) == NULL) return NULL; list = list_alloc(); - - item = _createSaveEntry(SAVE_FLAG_PS3, CHAR_ICON_COPY " Export Trophies"); - asprintf(&item->path, userPath); +/* + item = _createSaveEntry(SAVE_FLAG_PS4, CHAR_ICON_COPY " Export Trophies"); + item->path = strdup(userPath); item->codes = list_alloc(); cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_COPY " Backup Trophies to USB", CMD_CODE_NULL); cmd->options_count = 1; @@ -1532,58 +1532,29 @@ list_t * ReadTrophyList(const char* userPath) cmd->options = _createOptions(2, "Save .Zip to USB", CMD_ZIP_TROPHY_USB); list_append(item->codes, cmd); list_append(list, item); - - d = opendir(userPath); - - if (!d) - return list; - - while ((dir = readdir(d)) != NULL) +*/ + int rc = sqlite3_prepare_v2(db, "SELECT id, trophy_title_id, title FROM tbl_trophy_title", -1, &res, NULL); + if (rc != SQLITE_OK) { - if (dir->d_type != DT_DIR || strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) - continue; - - snprintf(filePath, sizeof(filePath), "%s%s/TROPCONF.SFM", userPath, dir->d_name); - if (file_exists(filePath) == SUCCESS) - { - LOG("Reading %s...", filePath); - - buffer = readFile(filePath, &bufferLen); - buffer[bufferLen]=0; - - //parse the file and get the DOM - doc = xmlReadMemory(buffer + 0x40, bufferLen - 0x40, NULL, NULL, XML_PARSE_NONET); - - if (!doc) - { - LOG("XML: could not parse file %s", filePath); - free(buffer); - continue; - } - - //Get the root element node - root_element = xmlDocGetRootElement(doc); - value = _get_xml_node_value(root_element->children, BAD_CAST "title-name"); - - item = _createSaveEntry(SAVE_FLAG_PS3 | SAVE_FLAG_TROPHY, value); - asprintf(&item->path, "%s%s/", userPath, dir->d_name); + LOG("Failed to fetch data: %s", sqlite3_errmsg(db)); + sqlite3_close(db); + return NULL; + } - value = _get_xml_node_value(root_element->children, BAD_CAST "npcommid"); - item->title_id = strdup(value); - item->type = FILE_TYPE_TRP; + while (sqlite3_step(res) == SQLITE_ROW) + { + item = _createSaveEntry(SAVE_FLAG_PS4 | SAVE_FLAG_TROPHY, (const char*) sqlite3_column_text(res, 2)); + item->blocks = sqlite3_column_int(res, 0); + item->path = strdup(filePath); + item->title_id = strdup((const char*) sqlite3_column_text(res, 1)); + item->type = FILE_TYPE_TRP; - //free the document - xmlFreeDoc(doc); - xmlCleanupParser(); - free(buffer); - - LOG("[%s] F(%d) name '%s'", item->title_id, item->flags, item->name); - list_append(list, item); - } + LOG("[%s] F(%d) name '%s'", item->title_id, item->flags, item->name); + list_append(list, item); } - closedir(d); + sqlite3_finalize(res); + sqlite3_close(db); return list; } -*/ \ No newline at end of file diff --git a/source/settings.c b/source/settings.c index 445dd20..d4dd606 100644 --- a/source/settings.c +++ b/source/settings.c @@ -197,9 +197,8 @@ void update_callback(int sel) if (show_dialog(1, "New version available! Download update?")) { -if(0) -// if (http_download(start, "", "/dev_hdd0/packages/apollo-ps3.pkg", 1)) - show_message("Update downloaded to /dev_hdd0/packages/"); + if (http_download(start, "", "/data/apollo-ps4.pkg", 1)) + show_message("Update downloaded to /data/apollo-ps4.pkg"); else show_message("Download error!"); } diff --git a/source/zip_util.c b/source/zip_util.c index 4b9c916..12fd25e 100644 --- a/source/zip_util.c +++ b/source/zip_util.c @@ -71,16 +71,37 @@ int zip_directory(const char* basedir, const char* inputdir, const char* output_ return (file_exists(output_filename) == SUCCESS); } -int on_extract_entry(const char *filename, void *arg) { +int on_extract_entry(const char *filename, void *arg) +{ + uint64_t* progress = (uint64_t*) arg; + LOG("Extracted: %s", filename); + update_progress_bar(++progress[0], progress[1], filename); return 0; } - int extract_zip(const char* zip_file, const char* dest_path) { - zip_extract(zip_file, dest_path, on_extract_entry, NULL); + int ret; + uint64_t progress[2]; + struct zip_t *archive = zip_open(zip_file, ZIP_DEFAULT_COMPRESSION_LEVEL, 'r'); + + if (!archive) + return 0; + + progress[0] = 0; + progress[1] = zip_entries_total(archive); + zip_close(archive); + + LOG("Extracting ZIP (%d) to <%s>...", progress[1], dest_path); + + init_progress_bar("Extracting files..."); + ret = zip_extract(zip_file, dest_path, on_extract_entry, progress); + end_progress_bar(); + + return (ret == SUCCESS); +} /* char path[256]; @@ -170,5 +191,3 @@ int extract_zip(const char* zip_file, const char* dest_path) end_progress_bar(); free(buffer); */ - return 1; -}