Skip to content

Commit

Permalink
add zip support
Browse files Browse the repository at this point in the history
download and unpack .zip links (for homebrew)
fix #12
  • Loading branch information
bucanero committed Feb 24, 2024
1 parent b4c208d commit 1c88e1e
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 28 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ find_package(CURL REQUIRED)
option(PKGI_ENABLE_DEBUG "enables debug logging over udp multicast" OFF)

if(PKGI_ENABLE_DEBUG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPKGI_ENABLE_LOGGING")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPKGI_ENABLE_LOGGING=1")
endif()

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11")
Expand Down Expand Up @@ -62,6 +62,7 @@ add_executable(${PROJECT_NAME}
source/loadpng.c
source/libfont.c
source/ttf_fonts.c
source/zip_util.c
source/pkgi.c
source/pkgi_aes.c
source/pkgi_db.c
Expand All @@ -81,6 +82,7 @@ target_link_libraries(${PROJECT_NAME}
pspnet
pspnet_apctl
mini18n
zip
bz2
z
)
Expand Down
2 changes: 1 addition & 1 deletion include/font-8x16.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// https://github.com/idispatch/raster-fonts
unsigned char console_font_8x16[] = {
static const unsigned char console_font_8x16[] = {

/*
* code=0, hex=0x00, ascii="^@"
Expand Down
12 changes: 6 additions & 6 deletions include/pkgi.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "pkgi_dialog.h"

#define PKGI_UPDATE_URL "https://api.github.com/repos/bucanero/pkgi-psp/releases/latest"
#define PKGI_VERSION "1.0.0"
#define PKGI_VERSION "1.1.0"

#define PKGI_BUTTON_SELECT 0x000001
#define PKGI_BUTTON_START 0x000008
Expand All @@ -17,10 +17,10 @@
#define PKGI_BUTTON_LT 0x000100 // L1
#define PKGI_BUTTON_RT 0x000200 // R1

#define PKGI_BUTTON_X 0x004000 // cross
#define PKGI_BUTTON_O 0x002000 // circle
#define PKGI_BUTTON_T 0x001000 // triangle
#define PKGI_BUTTON_S 0x008000 // square
#define PKGI_BUTTON_X 0x004000 // cross
#define PKGI_BUTTON_O 0x002000 // circle
#define PKGI_BUTTON_T 0x001000 // triangle
#define PKGI_BUTTON_S 0x008000 // square

#define PKGI_UNUSED(x) (void)(x)

Expand Down Expand Up @@ -73,7 +73,7 @@ int pkgi_is_incomplete(const char* titleid);
int pkgi_is_installed(const char* titleid);
int pkgi_install(int iso_mode, int remove_pkg);

uint32_t pkgi_time_msec();
uint32_t pkgi_time_msec(void);

typedef void pkgi_thread_entry(void);
void pkgi_start_thread(const char* name, pkgi_thread_entry* start);
Expand Down
1 change: 1 addition & 0 deletions include/pkgi_download.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ void progress_screen_refresh(void);
void update_install_progress(const char *filename, int64_t progress);
int install_psp_pkg(const char *file);
int convert_psp_pkg_iso(const char* pkg_arg, int cso);
int extract_zip(const char* zip_file);
2 changes: 1 addition & 1 deletion source/loadpng.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ static rawImage_t *imgLoadPngFromBuffer(const void *buffer)
if(png_sig_cmp((png_byte *)buffer, 0, PNG_SIGSIZE) != 0)
return NULL;

uint64_t buffer_address=(uint64_t)buffer+PNG_SIGSIZE;
uint64_t buffer_address=(uint32_t)buffer+PNG_SIGSIZE;

return imgLoadPngGeneric((void *)&buffer_address, imgReadPngFromBuffer);
}
Expand Down
1 change: 1 addition & 0 deletions source/pkgi.c
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,7 @@ int main(int argc, char* argv[])

pkgi_load_config(&config, (char*) &refresh_url, sizeof(refresh_url[0]));
pkgi_load_language(config.language);
pkgi_is_psp_go(config.storage);
pkgi_dialog_init();

font_height = pkgi_text_height("M");
Expand Down
15 changes: 13 additions & 2 deletions source/pkgi_download.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,11 +312,17 @@ static int create_rap(const char* contentid, const uint8_t* rap)
return 1;
}

static int is_zip(const char* filename)
{
const char* extension = pkgi_strrchr(filename, '.');
return extension && (pkgi_stricmp(extension, ".zip") == 0);
}

int pkgi_download(const DbItem* item)
{
int result = 0;

pkgi_snprintf(root, sizeof(root), "%s.pkg", item->content);
pkgi_snprintf(root, sizeof(root), "%s.%s", item->content, is_zip(item->url) ? "zip" : "pkg");
LOG("package installation file: %s", root);

pkgi_snprintf(resume_file, sizeof(resume_file), "%s%s/%s.resume", pkgi_get_storage_device(), pkgi_get_temp_folder(), item->content);
Expand Down Expand Up @@ -385,7 +391,12 @@ int pkgi_install(int iso_mode, int remove_pkg)
download_offset = 0;
total_size = download_size;

result = iso_mode ? convert_psp_pkg_iso(item_path, (iso_mode == 2)) : install_psp_pkg(item_path);
// check if it's a zip file
if (is_zip(item_path))
result = extract_zip(item_path);
else
result = iso_mode ? convert_psp_pkg_iso(item_path, (iso_mode == 2)) : install_psp_pkg(item_path);

if (result && remove_pkg)
{
pkgi_rm(item_path);
Expand Down
23 changes: 6 additions & 17 deletions source/pkgi_psp.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ typedef struct

char * strcasestr(const char *haystack, const char *needle);

static char disp_list[0x10000] __attribute__((aligned(64)));
static SceLwMutexWorkarea g_dialog_lock;

static int g_ok_button;
Expand Down Expand Up @@ -399,12 +400,8 @@ void pkgi_dialog_input_text(const char* title, const char* text)
if (sceUtilityOskInitStart(&params) < 0)
return;

void* list = aligned_alloc(16, 0x100000);
if (!list)
return;

do {
sceGuStart(GU_DIRECT, list);
sceGuStart(GU_DIRECT, disp_list);
sceGuClearColor(0xFF68260D);
sceGuClearDepth(0);
sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
Expand All @@ -427,8 +424,6 @@ void pkgi_dialog_input_text(const char* title, const char* text)
sceGuSwapBuffers();
} while (done != PSP_UTILITY_DIALOG_FINISHED);

free(list);

if (data.result == PSP_UTILITY_OSK_RESULT_CANCELLED)
return;

Expand Down Expand Up @@ -487,13 +482,9 @@ static int Net_DisplayNetDialog(void)
return 0;
}

void* list = aligned_alloc(16, 0x100000);
if (!list)
return 0;

while(!done)
{
sceGuStart(GU_DIRECT, list);
sceGuStart(GU_DIRECT, disp_list);
sceGuClearColor(0xFF68260D);
sceGuClearDepth(0);
sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
Expand Down Expand Up @@ -530,8 +521,6 @@ static int Net_DisplayNetDialog(void)
sceDisplayWaitVblankStart();
sceGuSwapBuffers();
}
free(list);

done = PSP_NET_APCTL_STATE_DISCONNECTED;
if ((ret = sceNetApctlGetState(&done)) < 0) {
LOG("sceNetApctlGetState() failed: 0x%08x", ret);
Expand Down Expand Up @@ -905,17 +894,17 @@ int pkgi_is_installed(const char* titleid)
return (pkgi_dir_exists(path));
}

uint32_t pkgi_time_msec()
uint32_t pkgi_time_msec(void)
{
struct timeval tv;

gettimeofday(&tv,NULL);
return (((uint32_t)tv.tv_sec)*1000)+(tv.tv_usec/1000);
}

void pkgi_thread_exit()
void pkgi_thread_exit(void)
{
sceKernelExitThread(0);
sceKernelExitDeleteThread(0);
}

void pkgi_start_thread(const char* name, pkgi_thread_entry* start)
Expand Down
112 changes: 112 additions & 0 deletions source/zip_util.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#include <zip.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <dirent.h>

#include "pkgi.h"
#include "pkgi_download.h"

#define UNZIP_BUF_SIZE 0x20000

static inline uint64_t min64(uint64_t a, uint64_t b)
{
return a < b ? a : b;
}

int extract_zip(const char* zip_file)
{
char path[256];
uint8_t* buffer;
int64_t zsize = pkgi_get_size(zip_file);
struct zip* archive = zip_open(zip_file, ZIP_RDONLY | ZIP_CHECKCONS, NULL);
int files = zip_get_num_files(archive);

if (files <= 0) {
LOG("Empty ZIP file.");
zip_close(archive);
return 0;
}

buffer = malloc(UNZIP_BUF_SIZE);
if (!buffer)
return 0;

LOG("Extracting %s to <%s>...", zip_file, dest_path);

for (int i = 0; i < files; i++) {
const char* filename = zip_get_name(archive, i, 0);

update_install_progress(filename, (zsize * i)/files);
LOG("Unzip [%d/%d] '%s'...", i+1, files, filename);

if (!filename)
continue;

if (filename[0] == '/')
filename++;

if (strncasecmp(filename, "PSP/GAME/", 9) == 0)
filename += 9;

snprintf(path, sizeof(path)-1, "%s/PSP/GAME/%s", pkgi_get_storage_device(), filename);
char* slash = strrchr(path, '/');
*slash = 0;
pkgi_mkdirs(path);
*slash = '/';

if (filename[strlen(filename) - 1] == '/')
continue;

struct zip_stat st;
if (zip_stat_index(archive, i, 0, &st)) {
LOG("Unable to access file %s in zip.", filename);
continue;
}
struct zip_file* zfd = zip_fopen_index(archive, i, 0);
if (!zfd) {
LOG("Unable to open file %s in zip.", filename);
continue;
}

FILE* tfd = fopen(path, "wb");
if(!tfd) {
free(buffer);
zip_fclose(zfd);
zip_close(archive);
LOG("Error opening temporary file '%s'.", path);
return 0;
}

uint64_t pos = 0, count;
while (pos < st.size) {
count = min64(UNZIP_BUF_SIZE, st.size - pos);
if (zip_fread(zfd, buffer, count) != count) {
free(buffer);
fclose(tfd);
zip_fclose(zfd);
zip_close(archive);
LOG("Error reading from zip.");
return 0;
}

fwrite(buffer, count, 1, tfd);
pos += count;
}

zip_fclose(zfd);
fclose(tfd);

update_install_progress(NULL, zsize * (i+1)/files);
}

if (archive) {
zip_close(archive);
}

update_install_progress(NULL, zsize);
free(buffer);

return files;
}

0 comments on commit 1c88e1e

Please sign in to comment.