diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2a8f97a..24427a2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -157,6 +157,9 @@ add_dependencies(VitaShell usbdevice.skprx-self)
target_link_libraries(VitaShell
${CMAKE_CURRENT_BINARY_DIR}/modules/user/libVitaShellUser_stub_weak.a
+ curl
+ ssl
+ crypto
ftpvita
vita2d
vorbisfile
diff --git a/browser.c b/browser.c
index 6809ad7..57aa87a 100644
--- a/browser.c
+++ b/browser.c
@@ -470,10 +470,14 @@ int shortCuts() {
}
// QR
- if (current_pad[PAD_CIRCLE] && enabledQR()) {
- startQR();
- initMessageDialog(MESSAGE_DIALOG_QR_CODE, language_container[QR_SCANNING]);
- setDialogStep(DIALOG_STEP_QR);
+ if (current_pad[PAD_CIRCLE]/* && enabledQR()*/) {
+ initQR();
+ if (enabledQR())
+ {
+ startQR();
+ initMessageDialog(MESSAGE_DIALOG_QR_CODE, language_container[QR_SCANNING]);
+ setDialogStep(DIALOG_STEP_QR);
+ }
}
return 0;
diff --git a/file.h b/file.h
index a0a3447..d99e7d9 100644
--- a/file.h
+++ b/file.h
@@ -76,6 +76,7 @@ typedef struct {
uint64_t max;
void (* SetProgress)(uint64_t value, uint64_t max);
int (* cancelHandler)();
+ SceUID fp;
} FileProcessParam;
typedef struct FileListEntry {
diff --git a/init.c b/init.c
index e97d5d3..c9e9132 100644
--- a/init.c
+++ b/init.c
@@ -288,11 +288,6 @@ static void initNet() {
sceNetInit(¶m);
sceNetCtlInit();
- sceSslInit(300 * 1024);
- sceHttpInit(40 * 1024);
-
- sceHttpsDisableOption(SCE_HTTPS_FLAG_SERVER_VERIFY);
-
sceNetAdhocInit();
SceNetAdhocctlAdhocId adhocId;
@@ -305,8 +300,6 @@ static void initNet() {
static void finishNet() {
sceNetAdhocctlTerm();
sceNetAdhocTerm();
- sceSslTerm();
- sceHttpTerm();
sceNetCtlTerm();
sceNetTerm();
free(net_memory);
@@ -363,7 +356,6 @@ void initVitaShell() {
sceSysmoduleLoadModule(SCE_SYSMODULE_MUSIC_EXPORT);
sceSysmoduleLoadModule(SCE_SYSMODULE_PHOTO_EXPORT);
sceSysmoduleLoadModule(SCE_SYSMODULE_NET);
- sceSysmoduleLoadModule(SCE_SYSMODULE_HTTPS);
sceSysmoduleLoadModule(SCE_SYSMODULE_PSPNET_ADHOC);
sceSysmoduleLoadModule(SCE_SYSMODULE_SQLITE);
@@ -372,7 +364,6 @@ void initVitaShell() {
initVita2dLib();
initSceAppUtil();
initNet();
- initQR();
initSQLite();
// Init power tick thread
@@ -437,13 +428,11 @@ void finishVitaShell() {
finishNet();
finishSceAppUtil();
finishVita2dLib();
- finishQR();
vitaAudioShutdown();
// Unload modules
sceSysmoduleUnloadModule(SCE_SYSMODULE_SQLITE);
sceSysmoduleUnloadModule(SCE_SYSMODULE_PSPNET_ADHOC);
- sceSysmoduleUnloadModule(SCE_SYSMODULE_HTTPS);
sceSysmoduleUnloadModule(SCE_SYSMODULE_NET);
sceSysmoduleUnloadModule(SCE_SYSMODULE_PHOTO_EXPORT);
sceSysmoduleUnloadModule(SCE_SYSMODULE_MUSIC_EXPORT);
diff --git a/main.c b/main.c
index e6fd1e0..8689c3d 100644
--- a/main.c
+++ b/main.c
@@ -951,6 +951,7 @@ int dialogSteps() {
if (msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
setDialogStep(DIALOG_STEP_QR_WAITING);
stopQR();
+ finishQR();
SceUID thid = sceKernelCreateThread("qr_scan_thread", (SceKernelThreadEntry)qr_scan_thread, 0x10000100, 0x100000, 0, 0, NULL);
if (thid >= 0)
sceKernelStartThread(thid, 0, NULL);
@@ -988,6 +989,7 @@ int dialogSteps() {
case DIALOG_STEP_QR_DOWNLOADED_VPK:
{
if (msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
+
initMessageDialog(MESSAGE_DIALOG_PROGRESS_BAR, language_container[INSTALLING]);
setDialogStep(DIALOG_STEP_INSTALL_CONFIRMED_QR);
}
diff --git a/network_download.c b/network_download.c
index 87cc055..b265e38 100644
--- a/network_download.c
+++ b/network_download.c
@@ -16,6 +16,13 @@
along with this program. If not, see .
*/
+#include
+#include
+#include
+#include
+#include
+#include
+
#include "main.h"
#include "io_process.h"
#include "network_download.h"
@@ -28,198 +35,229 @@
#define VITASHELL_USER_AGENT "VitaShell/1.00 libhttp/1.1"
-int getDownloadFileSize(const char *src, uint64_t *size) {
- int res;
- int statusCode;
- int tmplId = -1, connId = -1, reqId = -1;
-
- res = sceHttpCreateTemplate(VITASHELL_USER_AGENT, SCE_HTTP_VERSION_1_1, SCE_TRUE);
- if (res < 0)
- goto ERROR_EXIT;
-
- tmplId = res;
-
- res = sceHttpCreateConnectionWithURL(tmplId, src, SCE_TRUE);
- if (res < 0)
- goto ERROR_EXIT;
-
- connId = res;
-
- res = sceHttpCreateRequestWithURL(connId, SCE_HTTP_METHOD_GET, src, 0);
- if (res < 0)
- goto ERROR_EXIT;
-
- reqId = res;
-
- res = sceHttpSendRequest(reqId, NULL, 0);
- if (res < 0)
- goto ERROR_EXIT;
-
- res = sceHttpGetStatusCode(reqId, &statusCode);
- if (res < 0)
- goto ERROR_EXIT;
+static char *parse_filename(const char *ptr, size_t len)
+{
+ char *copy;
+ char *p;
+ char *q;
+ char stop = '\0';
+
+ /* simple implementation of strndup() */
+ copy = malloc(len + 1);
+ if(!copy)
+ return NULL;
+ memcpy(copy, ptr, len);
+ copy[len] = '\0';
+
+ p = copy;
+ if(*p == '\'' || *p == '"') {
+ /* store the starting quote */
+ stop = *p;
+ p++;
+ }
+ else
+ stop = ';';
+
+ /* scan for the end letter and stop there */
+ q = strchr(p, stop);
+ if(q)
+ *q = '\0';
+
+ /* if the filename contains a path, only use filename portion */
+ q = strrchr(p, '/');
+ if(q) {
+ p = q + 1;
+ if(!*p) {
+ free(copy);
+ return NULL;
+ }
+ }
- if (statusCode == 200) {
- res = sceHttpGetResponseContentLength(reqId, size);
+ /* If the filename contains a backslash, only use filename portion. The idea
+ is that even systems that do not handle backslashes as path separators
+ probably want the path removed for convenience. */
+ q = strrchr(p, '\\');
+ if(q) {
+ p = q + 1;
+ if(!*p) {
+ free(copy);
+ return NULL;
+ }
}
-ERROR_EXIT:
- if (reqId >= 0)
- sceHttpDeleteRequest(reqId);
+ /* make sure the filename does not end in \r or \n */
+ q = strchr(p, '\r');
+ if(q)
+ *q = '\0';
- if (connId >= 0)
- sceHttpDeleteConnection(connId);
+ q = strchr(p, '\n');
+ if(q)
+ *q = '\0';
- if (tmplId >= 0)
- sceHttpDeleteTemplate(tmplId);
+ if(copy != p)
+ memmove(copy, p, strlen(p) + 1);
- return res;
+ return copy;
}
-int getFieldFromHeader(const char *src, const char *field, const char **data, unsigned int *valueLen) {
- int res;
- char *header;
- unsigned int headerSize;
- int tmplId = -1, connId = -1, reqId = -1;
-
- res = sceHttpCreateTemplate(VITASHELL_USER_AGENT, SCE_HTTP_VERSION_1_1, SCE_TRUE);
- if (res < 0)
- goto ERROR_EXIT;
-
- tmplId = res;
-
- res = sceHttpCreateConnectionWithURL(tmplId, src, SCE_TRUE);
- if (res < 0)
- goto ERROR_EXIT;
-
- connId = res;
-
- res = sceHttpCreateRequestWithURL(connId, SCE_HTTP_METHOD_GET, src, 0);
- if (res < 0)
- goto ERROR_EXIT;
-
- reqId = res;
-
- res = sceHttpSendRequest(reqId, NULL, 0);
- if (res < 0)
- goto ERROR_EXIT;
-
- res = sceHttpGetAllResponseHeaders(reqId, &header, &headerSize);
- if (res < 0)
- goto ERROR_EXIT;
-
- res = sceHttpParseResponseHeader(header, headerSize, field, data, valueLen);
- if (res < 0) {
- *data = "";
- *valueLen = 0;
- res = 0;
- }
-
-ERROR_EXIT:
- if (reqId >= 0)
- sceHttpDeleteRequest(reqId);
-
- if (connId >= 0)
- sceHttpDeleteConnection(connId);
- if (tmplId >= 0)
- sceHttpDeleteTemplate(tmplId);
+//static char* fname = NULL;
- return res;
-}
+size_t header_cb(char *buffer, size_t size, size_t nitems, void *userdata)
+{
+ const size_t cb = size * nitems;
+ const char *end = (char *)buffer + cb;
+ const char *str = buffer;
-int downloadFile(const char *src, const char *dst, FileProcessParam *param) {
- int res;
- int statusCode;
- int tmplId = -1, connId = -1, reqId = -1;
- SceUID fd = -1;
- int ret = 1;
+ if((cb > 20) && curl_strnequal(buffer, "Content-disposition:", 20)) {
+ const char *p = buffer + 20;
- res = sceHttpCreateTemplate(VITASHELL_USER_AGENT, SCE_HTTP_VERSION_1_1, SCE_TRUE);
- if (res < 0)
- goto ERROR_EXIT;
+ for(;;) {
+ char *filename;
+ size_t len;
- tmplId = res;
+ while((p < end) && *p && !isalpha((int)*p))
+ p++;
+ if(p > end - 9)
+ break;
- res = sceHttpCreateConnectionWithURL(tmplId, src, SCE_TRUE);
- if (res < 0)
- goto ERROR_EXIT;
+ if(memcmp(p, "filename=", 9)) {
+ // no match, find next parameter
+ while((p < end) && *p && (*p != ';'))
+ p++;
+ if((p < end) && *p)
+ continue;
+ else
+ break;
+ }
+ p += 9;
- connId = res;
+ len = cb - (size_t)(p - str);
- res = sceHttpCreateRequestWithURL(connId, SCE_HTTP_METHOD_GET, src, 0);
- if (res < 0)
- goto ERROR_EXIT;
+ filename = parse_filename(p, len);
- reqId = res;
+ if(filename) {
+ *(char**)userdata = strdup(filename);
+ free(filename);
+ }
+ break;
+ }
+ }
- res = sceHttpSendRequest(reqId, NULL, 0);
- if (res < 0)
- goto ERROR_EXIT;
+ return nitems * size;
+}
- res = sceHttpGetStatusCode(reqId, &statusCode);
- if (res < 0)
- goto ERROR_EXIT;
+int getDownloadFileInfo(const char* url, int64_t* size, char** fileName, long* response_code)
+{
+ CURL *curl;
+ CURLcode res;
+ static char* fname = NULL;
+
+ curl = curl_easy_init();
+
+ if (curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 0L);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+
+ if (fileName)
+ {
+ curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_cb);
+ curl_easy_setopt(curl, CURLOPT_HEADERDATA, &fname);
+ }
- if (statusCode == 200) {
- res = sceIoOpen(dst, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777);
- if (res < 0)
- goto ERROR_EXIT;
+ res = curl_easy_perform(curl);
+
+ // try to get size
+ curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, size);
+
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, response_code);
+
+ if (fileName)
+ {
+ // try to get filename
+ char *url = NULL;
+ curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
+
+ if (fname)
+ {
+ *fileName = strdup(fname);
+ free(fname);
+ fname = NULL;
+ }
+ else if (url)
+ {
+ *fileName = strdup(basename(url));
+ }
+ }
- fd = res;
+ curl_easy_cleanup(curl);
+ }
- uint8_t buf[4096];
+ return 0;
+}
- while (1) {
- int read = sceHttpReadData(reqId, buf, sizeof(buf));
-
- if (read < 0) {
- res = read;
- break;
- }
-
- if (read == 0)
- break;
-
- int written = sceIoWrite(fd, buf, read);
-
- if (written < 0) {
- res = written;
- break;
- }
+static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ FileProcessParam *param = (FileProcessParam*)stream;
+ size_t written = sceIoWrite(param->fp, ptr, size*nmemb);
- if (param) {
- if (param->value)
- (*param->value) += read;
+ if (param) {
+ if (param->value)
+ (*param->value) += written;
- if (param->SetProgress)
+ if (param->SetProgress)
param->SetProgress(param->value ? *param->value : 0, param->max);
- if (param->cancelHandler && param->cancelHandler()) {
- ret = 0;
- break;
- }
+ if (param->cancelHandler && param->cancelHandler()) {
+ return CURL_WRITEFUNC_ERROR;
}
- }
}
-ERROR_EXIT:
- if (fd >= 0)
- sceIoClose(fd);
-
- if (reqId >= 0)
- sceHttpDeleteRequest(reqId);
-
- if (connId >= 0)
- sceHttpDeleteConnection(connId);
+ return written;
+}
- if (tmplId >= 0)
- sceHttpDeleteTemplate(tmplId);
+int downloadFile(const char* url, const char* path, FileProcessParam *param)
+{
+ CURL *curl;
+ FILE *fp;
+ CURLcode res;
+
+ curl = curl_easy_init();
+ if (curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ curl_easy_setopt(curl, CURLOPT_NOBODY, 0L);
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 0L);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
+
+ param->fp = sceIoOpen(path, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777);
+
+ long response_code = 0;
+ if (param->fp >= 0)
+ {
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, param);
+ res = curl_easy_perform(curl);
+
+ sceIoClose(param->fp);
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
+ curl_easy_cleanup(curl);
+ }
+ if (response_code != 200) return -1;
+ }
- if (res < 0)
- return res;
+ return 0;
- return ret;
}
int downloadFileProcess(const char *url, const char *dest, int successStep) {
@@ -233,8 +271,16 @@ int downloadFileProcess(const char *url, const char *dest, int successStep) {
sceKernelDelayThread(DIALOG_WAIT); // Needed to see the percentage
// File size
- uint64_t size = 0;
- getDownloadFileSize(url, &size);
+ int64_t size = 0;
+ long code = 0;
+
+ getDownloadFileInfo(url, &size, NULL, &code);
+ if (size < 0 || code != 200)
+ {
+ closeWaitDialog();
+ setDialogStep(DIALOG_STEP_CANCELED);
+ errorDialog(code);
+ }
// Update thread
thid = createStartUpdateThread(size, 1);
@@ -249,7 +295,7 @@ int downloadFileProcess(const char *url, const char *dest, int successStep) {
param.cancelHandler = cancelHandler;
int res = downloadFile(url, dest, ¶m);
- if (res <= 0) {
+ if (res < 0) {
sceIoRemove(dest);
closeWaitDialog();
setDialogStep(DIALOG_STEP_CANCELED);
diff --git a/network_download.h b/network_download.h
index 09f2674..e37530b 100644
--- a/network_download.h
+++ b/network_download.h
@@ -25,8 +25,7 @@
#ifndef __NETWORK_DOWNLOAD_H__
#define __NETWORK_DOWNLOAD_H__
-int getDownloadFileSize(const char *src, uint64_t *size);
-int getFieldFromHeader(const char *src, const char *field, const char **data, unsigned int *valueLen);
+int getDownloadFileInfo(const char* url, int64_t* size, char** fileName, long* response_code);
int downloadFile(const char *src, const char *dst, FileProcessParam *param);
int downloadFileProcess(const char *url, const char *dest, int successStep);
diff --git a/network_update.c b/network_update.c
index e4f3fb8..dcb1c01 100644
--- a/network_update.c
+++ b/network_update.c
@@ -38,9 +38,18 @@ extern unsigned char _binary_resources_updater_param_bin_start;
extern unsigned char _binary_resources_updater_param_bin_size;
int network_update_thread(SceSize args, void *argp) {
- uint64_t size = 0;
- if (getDownloadFileSize(BASE_ADDRESS VERSION_URL, &size) >= 0 && size == sizeof(uint32_t)) {
- int res = downloadFile(BASE_ADDRESS VERSION_URL, VITASHELL_VERSION_FILE, NULL);
+ int64_t size = 0;
+ long code = 0;
+ if (getDownloadFileInfo(BASE_ADDRESS VERSION_URL, &size, NULL, &code) >= 0 && size == sizeof(uint32_t)) {
+ uint64_t value = 0;
+
+ FileProcessParam param;
+ param.value = &value;
+ param.max = size;
+ param.SetProgress = NULL;
+ param.cancelHandler = NULL;
+
+ int res = downloadFile(BASE_ADDRESS VERSION_URL, VITASHELL_VERSION_FILE, ¶m);
if (res <= 0)
goto EXIT;
diff --git a/qr.c b/qr.c
index f817bb5..2bb18a5 100644
--- a/qr.c
+++ b/qr.c
@@ -64,6 +64,8 @@ int qr_thread() {
qr = quirc_new();
quirc_resize(qr, CAM_WIDTH, CAM_HEIGHT);
qr_next = 1;
+ qr_scanned = 0;
+ memset(last_qr, 0, MAX_QR_LENGTH);
while (1) {
sceKernelDelayThread(10);
if (qr_next == 0 && qr_scanned == 0) {
@@ -74,7 +76,8 @@ int qr_thread() {
int i;
for (i = 0; i < w*h; i++) {
colourRGBA = qr_data[i];
- image[i] = ((colourRGBA & 0x000000FF) + ((colourRGBA & 0x0000FF00) >> 8) + ((colourRGBA & 0x00FF0000) >> 16)) / 3;
+ image[i] = MIN( MIN((colourRGBA & 0x000000FF), (colourRGBA & 0x0000FF00)), (colourRGBA & 0x00FF0000));
+// image[i] = ((colourRGBA & 0x000000FF) + ((colourRGBA & 0x0000FF00) >> 8) + ((colourRGBA & 0x00FF0000) >> 16)) / 3;
}
quirc_end(qr);
int num_codes = quirc_count(qr);
@@ -90,6 +93,7 @@ int qr_thread() {
memcpy(last_qr, data.payload, data.payload_len);
last_qr_len = data.payload_len;
qr_scanned = 1;
+ break;
}
} else {
memset(last_qr, 0, MAX_QR_LENGTH);
@@ -98,6 +102,7 @@ int qr_thread() {
sceKernelDelayThread(250000);
}
}
+ return 0;
}
int qr_scan_thread(SceSize args, void *argp) {
@@ -115,26 +120,24 @@ int qr_scan_thread(SceSize args, void *argp) {
}
initMessageDialog(SCE_MSG_DIALOG_BUTTON_TYPE_NONE, language_container[PLEASE_WAIT]);
-
+
// check for attached file
const char *headerData;
unsigned int headerLen;
unsigned int fileNameLength = 0;
int vpk = 0;
- char *fileName = "";
- uint64_t fileSize;
+ char *fileName = NULL;
+ int64_t fileSize;
+ long code = 0;
char sizeString[16];
int ret;
- ret = getDownloadFileSize(data, &fileSize);
- if (ret < 0)
- goto NETWORK_FAILURE;
- ret = getFieldFromHeader(data, "Content-Disposition", &headerData, &headerLen);
+ ret = getDownloadFileInfo(data, &fileSize, &fileName, &code);
+
if (ret < 0)
goto NETWORK_FAILURE;
- getSizeString(sizeString, fileSize);
sceMsgDialogClose();
// Wait for it to stop loading
@@ -142,66 +145,26 @@ int qr_scan_thread(SceSize args, void *argp) {
sceKernelDelayThread(10 * 1000);
}
- if (headerLen <= 0) {
- char *next;
- fileName = data;
- while ((next = strpbrk(fileName + 1, "\\/"))) fileName = next;
- if (fileName != last_qr) fileName++;
-
- char *ext = strrchr(fileName, '.');
- if (ext) {
- vpk = getFileType(fileName) == FILE_TYPE_VPK;
- } else {
- initMessageDialog(SCE_MSG_DIALOG_BUTTON_TYPE_YESNO, language_container[QR_OPEN_WEBSITE], data);
- setDialogStep(DIALOG_STEP_QR_OPEN_WEBSITE);
- return sceKernelExitDeleteThread(0);
- }
- } else {
- if (strstr(headerData, "inline") != NULL) {
- initMessageDialog(SCE_MSG_DIALOG_BUTTON_TYPE_YESNO, language_container[QR_OPEN_WEBSITE], data);
- setDialogStep(DIALOG_STEP_QR_OPEN_WEBSITE);
- return sceKernelExitDeleteThread(0);
- }
-
- char *p = strstr(headerData, "filename=");
- if (!p)
- goto EXIT;
-
- fileName = p+9;
-
- p = strchr(fileName, '\n');
- if (p)
- *p = '\0';
-
- // Trim at beginning
- while (*fileName < 0x20 ||
- *fileName == ' ' || *fileName == '\\' ||
- *fileName == '/' || *fileName == ':' ||
- *fileName == '*' || *fileName == '?' ||
- *fileName == '"' || *fileName == '<' ||
- *fileName == '>' || *fileName == '|') {
- fileName++;
- }
+ if (code != 200 || fileSize < 0)
+ {
+ free(fileName);
+ initMessageDialog(SCE_MSG_DIALOG_BUTTON_TYPE_YESNO, language_container[QR_OPEN_WEBSITE], data);
+ setDialogStep(DIALOG_STEP_QR_OPEN_WEBSITE);
+ return sceKernelExitDeleteThread(0);
+ }
- // Trim at end
- int i;
- for (i = strlen(fileName)-1; i >= 0; i--) {
- if (fileName[i] < 0x20 ||
- fileName[i] == ' ' || fileName[i] == '\\' ||
- fileName[i] == '/' || fileName[i] == ':' ||
- fileName[i] == '*' || fileName[i] == '?' ||
- fileName[i] == '"' || fileName[i] == '<' ||
- fileName[i] == '>' || fileName[i] == '|') {
- fileName[i] = 0;
- } else {
- break;
- }
- }
+ getSizeString(sizeString, fileSize);
- // VPK type
+ char *ext = strrchr(fileName, '.');
+ if (ext) {
vpk = getFileType(fileName) == FILE_TYPE_VPK;
+ } else {
+ free(fileName);
+ initMessageDialog(SCE_MSG_DIALOG_BUTTON_TYPE_YESNO, language_container[QR_OPEN_WEBSITE], data);
+ setDialogStep(DIALOG_STEP_QR_OPEN_WEBSITE);
+ return sceKernelExitDeleteThread(0);
}
-
+
if (vpk)
initMessageDialog(SCE_MSG_DIALOG_BUTTON_TYPE_YESNO, language_container[QR_CONFIRM_INSTALL], data, fileName, sizeString);
else
@@ -215,6 +178,7 @@ int qr_scan_thread(SceSize args, void *argp) {
// No
if (getDialogStep() == DIALOG_STEP_NONE) {
+ free(fileName);
goto EXIT;
}
@@ -222,8 +186,7 @@ int qr_scan_thread(SceSize args, void *argp) {
char download_path[MAX_URL_LENGTH];
char short_name[MAX_URL_LENGTH];
int count = 0;
-
- char *ext = strrchr(fileName, '.');
+
if (ext) {
int len = ext-fileName;
if (len > sizeof(short_name) - 1)
@@ -234,6 +197,7 @@ int qr_scan_thread(SceSize args, void *argp) {
strncpy(short_name, fileName, sizeof(short_name) - 1);
ext = "";
}
+
while (1) {
if (count == 0)
snprintf(download_path, sizeof(download_path) - 1, "ux0:download/%s", fileName);
@@ -246,14 +210,20 @@ int qr_scan_thread(SceSize args, void *argp) {
break;
count++;
}
+
+ free(fileName);
sceIoMkdir("ux0:download", 0006);
strcpy(last_download, download_path);
if (vpk)
+ {
return downloadFileProcess(data, download_path, DIALOG_STEP_QR_DOWNLOADED_VPK);
+ }
else
+ {
return downloadFileProcess(data, download_path, DIALOG_STEP_QR_DOWNLOADED);
+ }
EXIT:
return sceKernelExitDeleteThread(0);