hbmap: fix iterator truncation when size_t < 32bit
[rofl0r-agsutils.git] / agstract.c
blobea3ccae0cfaaf24c19de970dff807eff066ae3f3
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 #ifdef _WIN32
10 #include <direct.h>
11 #define MKDIR(D) mkdir(D)
12 #define PSEP '\\'
13 #else
14 #define MKDIR(D) mkdir(D, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)
15 #define PSEP '/'
16 #endif
18 #define ADS ":::AGStract " VERSION " by rofl0r:::"
20 static void usage(char *argv0) {
21 fprintf(stderr, ADS "\nusage:\n%s agsgame.exe targetdir\n\n", argv0);
22 exit(1);
25 static void dump_exe(struct AgsFile *ags, const char *dir) {
26 if(ags->pack_off) {
27 char fnbuf[512];
28 snprintf(fnbuf, sizeof(fnbuf), "%s%cagspack.exestub", dir, PSEP);
29 AgsFile_extract(ags, 0, 0, ags->pack_off, fnbuf);
33 static FILE* open_packfile(const char* fn) {
34 return fopen(fn, "w");
37 #define EFPRINTF(F, FMT, ...) \
38 do{if(fprintf(F, FMT, __VA_ARGS__) < 0) {perror("fprintf"); return 1;}}while(0)
39 int main(int argc, char** argv) {
40 if(argc < 3) usage(argv[0]);
41 fprintf(stdout, ADS "\n");
42 struct AgsFile *ags = calloc(1, sizeof(*ags));
43 char *fn = argv[1];
44 char *dir = argv[2];
45 char fnbuf[512];
46 char db[512];
47 snprintf(fnbuf, sizeof(fnbuf), "%s%cagspack.info", dir, PSEP);
48 FILE *outf = open_packfile(fnbuf);
49 if(outf == 0 && errno == ENOENT) {
50 MKDIR(dir);
51 outf = open_packfile(fnbuf);
53 if(outf == 0) {
54 perror("fopen");
55 fprintf(stderr, "did you forget to create %s?\n", dir);
56 perror(fnbuf);
57 return 1;
59 EFPRINTF(outf, "info=infofile created by %s\n"
60 "info=this file is needed to reconstruct the packfile with AGSpack\n", ADS);
61 AgsFile_init(ags, fn);
62 if(strchr(fn, PSEP)) {
63 strcpy(db, fn);
64 *strrchr(db, PSEP) = 0;
65 AgsFile_setSourceDir(ags, db);
67 if(!AgsFile_open(ags)) {
68 fprintf(stderr, "error opening %s\n", fn);
69 return 1;
71 dump_exe(ags, dir);
72 int ec = 0;
73 size_t i, l = AgsFile_getFileCount(ags), ld =AgsFile_getDataFileCount(ags);
74 fprintf(stdout, "%s: mfl version %d, containing %zu files.\n", fn, AgsFile_getVersion(ags), l);
75 EFPRINTF(outf, "agspackfile=%s\nmflversion=%d\nfilecount=%zu\n", fn, AgsFile_getVersion(ags), l);
76 EFPRINTF(outf, "datafilecount=%zu\n", ld);
77 for(i = 0; i < ld; i++) {
78 EFPRINTF(outf, "df%zu=%s\n", i, AgsFile_getDataFileName(ags, i));
80 for(i = 0; i < l; i++) {
81 char buf[16];
82 snprintf(buf, sizeof(buf), "%d", AgsFile_getFileNumber(ags, i));
83 EFPRINTF(outf, "fileno%zu=%s\n", i, buf);
85 for(i = 0; i < l; i++) {
86 char *currfn = AgsFile_getFileName(ags, i);
87 snprintf(fnbuf, sizeof(fnbuf), "%s%c%s", dir, PSEP, currfn);
88 fprintf(stdout, "%s -> %s\n", currfn, fnbuf);
89 EFPRINTF(outf, "%zu=%s\n", i, currfn);
90 if(!AgsFile_dump(ags, i, fnbuf)) ec++;
93 AgsFile_close(ags);
94 free(ags);
95 fclose(outf);
96 ec = !!ec;
97 return ec;