vita-toolchain

git clone https://git.neptards.moe/neptards/vita-toolchain.git
Log | Files | Refs | README | LICENSE

vita-pack-vpk.c (4713B)


      1 #include <stdio.h>
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 #include <sys/stat.h>
      6 #include <dirent.h>
      7 #include <getopt.h>
      8 #include <zip.h>
      9 
     10 #define DEFAULT_OUTPUT_FILE "output.vpk"
     11 #ifndef PATH_MAX
     12 #define PATH_MAX 4096
     13 #endif
     14 
     15 static void usage(const char *arg);
     16 
     17 static const struct option long_options[] = {
     18 	{"sfo", required_argument, NULL, 's'},
     19 	{"eboot", required_argument, NULL, 'b'},
     20 	{"add", required_argument, NULL, 'a'},
     21 	{"help", no_argument, NULL, 'h'},
     22 	{NULL, 0, NULL, 0}
     23 };
     24 
     25 static int add_file_zip(zip_t *zip, const char *src, const char *dst)
     26 {
     27 	struct stat s;
     28 	if (stat(src,&s)) {
     29 		return 0;
     30 	}
     31 	if (S_ISDIR(s.st_mode)) {
     32 		DIR *dir = opendir(src);
     33 		struct dirent *entry;
     34 		while((entry = readdir(dir))){
     35 			if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
     36 				continue;
     37 			char src_dir[PATH_MAX];
     38 			char dst_dir[PATH_MAX];
     39 			int src_len = snprintf(src_dir, sizeof(src_dir)-1, "%s/%s", src, entry->d_name);
     40 			int dst_len = snprintf(dst_dir, sizeof(dst_dir)-1, "%s/%s", dst, entry->d_name);
     41 			src_dir[src_len] = 0;
     42 			dst_dir[dst_len] = 0;
     43 			add_file_zip(zip, src_dir, dst_dir);
     44 		}
     45 		closedir(dir);
     46 	}else if(S_ISREG(s.st_mode)){
     47 		zip_file_add(zip, dst, zip_source_file(zip, src, 0, 0), 0);
     48 	} else { // symlink etc.
     49 		return 0;
     50 	}
     51 	return 1;
     52 }
     53 
     54 static struct {
     55 	char **src;
     56 	char **dst;
     57 	int num;
     58 } additional_list;
     59 
     60 static void additional_list_add(char *src, char *dst)
     61 {
     62 	additional_list.src = realloc(additional_list.src,
     63 		sizeof(*additional_list.src) * (additional_list.num + 1));
     64 	additional_list.dst = realloc(additional_list.dst,
     65 		sizeof(*additional_list.dst) * (additional_list.num + 1));
     66 
     67 	additional_list.src[additional_list.num] = src;
     68 	additional_list.dst[additional_list.num] = dst;
     69 
     70 	additional_list.num++;
     71 }
     72 
     73 static void additional_list_init()
     74 {
     75 	additional_list.src = NULL;
     76 	additional_list.dst = NULL;
     77 	additional_list.num = 0;
     78 }
     79 
     80 static void additional_list_free()
     81 {
     82 	int i;
     83 
     84 	for (i = 0; i < additional_list.num; i++) {
     85 		free(additional_list.src[i]);
     86 		free(additional_list.dst[i]);
     87 	}
     88 
     89 	free(additional_list.src);
     90 	free(additional_list.dst);
     91 }
     92 
     93 static void parse_add_subopt(char *optarg)
     94 {
     95 	char *src;
     96 	char *dst;
     97 	const char *equals;
     98 	size_t src_len;
     99 	size_t dst_len;
    100 	size_t len = strlen(optarg);
    101 
    102 	equals = strchr(optarg, '=');
    103 	if (!equals || (equals == optarg + len - 1))
    104 		return;
    105 
    106 	src_len = equals - optarg;
    107 	dst_len = len - (equals - optarg + 1);
    108 
    109 	src = malloc(sizeof(char) * (src_len + 1));
    110 	dst = malloc(sizeof(char) * (dst_len + 1));
    111 
    112 	strncpy(src, optarg, src_len);
    113 	src[src_len] = '\0';
    114 
    115 	strncpy(dst, optarg + src_len + 1, dst_len);
    116 	dst[dst_len] = '\0';
    117 
    118 	additional_list_add(src, dst);
    119 }
    120 
    121 int main(int argc, char *argv[])
    122 {
    123 	int i;
    124 	int err;
    125 	zip_t *zip;
    126 	int opt;
    127 	char *output = NULL;
    128 	char *sfo = NULL;
    129 	char *eboot = NULL;
    130 
    131 	if (argc < 2) {
    132 		usage(argv[0]);
    133 		return -1;
    134 	}
    135 
    136 	additional_list_init();
    137 
    138 	while ((opt = getopt_long(argc, argv, "hs:b:a:", long_options, NULL)) != -1) {
    139 		switch (opt) {
    140 		case 's':
    141 			sfo = strdup(optarg);
    142 			break;
    143 		case 'b':
    144 			eboot = strdup(optarg);
    145 			break;
    146 		case 'a':
    147 			parse_add_subopt(optarg);
    148 			break;
    149 		case 'h':
    150 			usage(argv[0]);
    151 			goto error_wrong_args;
    152 		}
    153 	}
    154 
    155 	if (!sfo) {
    156 		printf(".sfo file missing.\n");
    157 		goto error_wrong_args;
    158 	}
    159 
    160 	if (!eboot) {
    161 		printf(".bin file missing.\n");
    162 		goto error_wrong_args;
    163 	}
    164 
    165 	argc -= optind;
    166 	argv += optind;
    167 
    168 	if (argc > 0)
    169 		output = strdup(argv[0]);
    170 	else
    171 		output  = strdup(DEFAULT_OUTPUT_FILE);
    172 
    173 	zip = zip_open(output, ZIP_CREATE | ZIP_TRUNCATE, &err);
    174 	if (!zip) {
    175 		printf("Error creating: \'%s\': %s\n", output,
    176 			zip_strerror(zip));
    177 		goto error_create_zip;
    178 	}
    179 
    180 	if (!add_file_zip(zip, sfo, "sce_sys/param.sfo"))
    181 		goto error_add_zip;
    182 
    183 	if (!add_file_zip(zip, eboot, "eboot.bin"))
    184 		goto error_add_zip;
    185 
    186 	for (i = 0; i < additional_list.num; i++) {
    187 		if (!add_file_zip(zip, additional_list.src[i],
    188 				  additional_list.dst[i]))
    189 			goto error_add_zip;
    190 	}
    191 
    192 	err = zip_close(zip);
    193 	if (err == -1) {
    194 		printf("Error creating: \'%s\': %s\n", output,
    195 			zip_strerror(zip));
    196 		goto error_add_zip;
    197 	}
    198 
    199 	free(output);
    200 	free(sfo);
    201 	free(eboot);
    202 	additional_list_free();
    203 
    204 	return 0;
    205 
    206 error_add_zip:
    207 	zip_discard(zip);
    208 
    209 error_create_zip:
    210 	free(output);
    211 
    212 error_wrong_args:
    213 	if (sfo)
    214 		free(sfo);
    215 	if (eboot)
    216 		free(eboot);
    217 
    218 	additional_list_free();
    219 
    220 	return -1;
    221 }
    222 
    223 void usage(const char *arg)
    224 {
    225 	printf("Usage:\n\t%s [OPTIONS] output.vpk\n\n"
    226 		"  -s, --sfo=param.sfo     sets the param.sfo file\n"
    227 		"  -b, --eboot=eboot.bin   sets the eboot.bin file\n"
    228 		"  -a, --add src=dst       adds the file or directory src to the vpk as dst\n"
    229 		"  -h, --help              displays this help and exit\n"
    230 		, arg);
    231 }