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
15 #define COS_FILE_SIZE 7340000
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
)
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)
53 if (strcmp(de
->d_name
, "..") == 0)
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);
84 static void build_hdr(void)
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
);
100 fail("out of memory");
102 memset(hdr
, 0, hdr_size
);
105 wbe32(p
+ 0x00, 1); // magic
106 wbe32(p
+ 0x04, n_files
);
107 wbe64(p
+ 0x08, COS_FILE_SIZE
);
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);
118 static void write_pkg(const char *n
)
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
);
140 int main(int argc
, char *argv
[])
143 fail("usage: cospkg cos.pkg dir");