agssim: catch potential OOB access in change_reg_usage
[rofl0r-agsutils.git] / agstract.c
blobce924d7407807c23007de8e8b2e23b70dafe3da5
1 #define _GNU_SOURCE
2 #include "Clib32.h"
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <sys/stat.h>
7 #include <errno.h>
8 #include "version.h"
9 #define ADS ":::AGStract " VERSION " by rofl0r:::"
11 __attribute__((noreturn))
12 void usage(char *argv0) {
13 dprintf(2, ADS "\nusage:\n%s agsgame.exe targetdir\n\n", argv0);
14 exit(1);
17 static void dump_exe(struct AgsFile *ags, const char *dir) {
18 if(ags->pack_off) {
19 char fnbuf[512];
20 snprintf(fnbuf, sizeof(fnbuf), "%s/agspack.exestub", dir);
21 AgsFile_extract(ags, 0, 0, ags->pack_off, fnbuf);
25 static FILE* open_packfile(const char* fn) {
26 return fopen(fn, "w");
29 #define EFPRINTF(F, FMT, ARGS...) \
30 do{if(fprintf(F, FMT, ## ARGS) < 0) {perror("fprintf"); return 1;}}while(0)
31 int main(int argc, char** argv) {
32 if(argc < 3) usage(argv[0]);
33 dprintf(1, ADS "\n");
34 struct AgsFile ags_b, *ags = &ags_b;
35 char *fn = argv[1];
36 char *dir = argv[2];
37 char fnbuf[512];
38 snprintf(fnbuf, sizeof(fnbuf), "%s/agspack.info", dir);
39 FILE *outf = open_packfile(fnbuf);
40 if(outf == 0 && errno == ENOENT) {
41 mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
42 outf = open_packfile(fnbuf);
44 if(outf == 0) {
45 perror("fopen");
46 dprintf(2, "did you forget to create %s?\n", dir);
47 perror(fnbuf);
48 return 1;
50 EFPRINTF(outf, "info=infofile created by %s\n"
51 "info=this file is needed to reconstruct the packfile with AGSpack\n", ADS);
52 AgsFile_init(ags, fn);
53 if(!AgsFile_open(ags)) {
54 dprintf(2, "error opening %s\n", fn);
55 return 1;
57 dump_exe(ags, dir);
58 int ec = 0;
59 size_t i, l = AgsFile_getFileCount(ags), ld =AgsFile_getDataFileCount(ags);
60 dprintf(1, "%s: version %d, containing %zu files.\n", fn, AgsFile_getVersion(ags), l);
61 EFPRINTF(outf, "agspackfile=%s\nagsversion=%d\nfilecount=%zu\n", fn, AgsFile_getVersion(ags), l);
62 EFPRINTF(outf, "datafilecount=%zu\n", ld);
63 for(i = 0; i < ld; i++) {
64 EFPRINTF(outf, "df%zu=%s\n", i, AgsFile_getDataFileName(ags, i));
66 for(i = 0; i < l; i++) {
67 char buf[16];
68 snprintf(buf, sizeof(buf), "%d", AgsFile_getFileNumber(ags, i));
69 EFPRINTF(outf, "fileno%zu=%s\n", i, buf);
71 for(i = 0; i < l; i++) {
72 char *currfn = AgsFile_getFileName(ags, i);
73 snprintf(fnbuf, sizeof(fnbuf), "%s/%s", dir, currfn);
74 dprintf(1, "%s -> %s\n", currfn, fnbuf);
75 EFPRINTF(outf, "%zu=%s\n", i, currfn);
76 if(!AgsFile_dump(ags, i, fnbuf)) ec++;
79 AgsFile_close(ags);
80 fclose(outf);
81 ec = !!ec;
82 return ec;