Add COPYING file
[ps3tools.git] / cospkg.c
blob9f7c3a6fa150007b2bf9b1ef43b4925d7521c34b
1 // Copyright 2010 Sven Peter <svenpeter@gmail.com>
2 // Licensed under the terms of the GNU GPL, version 2
3 // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
5 #include "tools.h"
6 #include "types.h"
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <dirent.h>
12 #include <sys/stat.h>
13 #define MAX_FILES 255
15 #define COS_FILE_SIZE 7340000
18 struct pkg_file {
19 char name[0x20];
20 u8 *ptr;
21 u64 size;
22 u64 offset;
25 static u8 *hdr = NULL;
26 static u32 hdr_size = 0;
28 static u32 n_files = 0;
29 static struct pkg_file files[MAX_FILES];
31 static void get_files(const char *d)
33 DIR *dir;
34 struct dirent *de;
35 struct stat st;
36 char path[256];
37 u32 i;
38 u64 offset;
40 dir = opendir(d);
41 if (dir == NULL)
42 fail("opendir");
44 offset = 0;
45 i = 0;
46 while ((de = readdir(dir))) {
47 if (n_files == MAX_FILES)
48 fail("file overflow. increase MAX_FILES");
50 if (strcmp(de->d_name, ".") == 0)
51 continue;
53 if (strcmp(de->d_name, "..") == 0)
54 continue;
56 if (strlen(de->d_name) > 0x20)
57 fail("name too long: %s", de->d_name);
59 snprintf(path, sizeof path, "%s/%s", d, de->d_name);
61 memset(&files[i], 0, sizeof(*files));
62 strncpy(files[i].name, de->d_name, 0x19);
64 if (stat(path, &st) < 0)
65 fail("cannot stat %s", path);
67 if (!S_ISREG(st.st_mode))
68 fail("not a file: %s", de->d_name);
70 files[i].size = st.st_size;
72 files[i].ptr = mmap_file(path);
73 if (files[i].ptr == NULL)
74 fail("unable to mmap %s", path);
76 files[i].offset = offset;
77 offset = round_up(offset + files[i].size, 0x20);
79 i++;
80 n_files++;
84 static void build_hdr(void)
86 u8 *p;
87 u32 i;
88 u64 file_size;
90 file_size = files[n_files - 1].offset + files[n_files - 1].size;
91 hdr_size = 0x10 + n_files * 0x30;
93 if ((hdr_size + file_size) > COS_FILE_SIZE)
94 fail ("Too many files, size must be under %d but it is %d",
95 COS_FILE_SIZE, hdr_size + file_size);
97 hdr = malloc(hdr_size);
99 if (hdr == NULL)
100 fail("out of memory");
102 memset(hdr, 0, hdr_size);
103 p = hdr;
105 wbe32(p + 0x00, 1); // magic
106 wbe32(p + 0x04, n_files);
107 wbe64(p + 0x08, COS_FILE_SIZE);
108 p += 0x10;
110 for (i = 0; i < n_files; i++) {
111 wbe64(p + 0x00, files[i].offset + hdr_size);
112 wbe64(p + 0x08, files[i].size);
113 strncpy((char *)(p + 0x10), files[i].name, 0x20);
114 p += 0x30;
118 static void write_pkg(const char *n)
120 FILE *fp;
121 u32 i;
123 fp = fopen(n, "wb");
124 if (fp == NULL)
125 fail("fopen(%s) failed", n);
127 fwrite(hdr, hdr_size, 1, fp);
129 for (i = 0; i < n_files; i++) {
130 fseek(fp, files[i].offset + hdr_size, SEEK_SET);
131 fwrite(files[i].ptr, files[i].size, 1, fp);
134 fseek (fp, COS_FILE_SIZE-1, SEEK_SET);
135 fwrite("", 1, 1, fp);
137 fclose(fp);
140 int main(int argc, char *argv[])
142 if (argc != 3)
143 fail("usage: cospkg cos.pkg dir");
145 get_files(argv[2]);
146 build_hdr();
147 write_pkg(argv[1]);
149 return 0;