hbmap: fix iterator truncation when size_t < 32bit
[rofl0r-agsutils.git] / agspack.c
blob9915b0bbe9bfa4553209c762dfefbbac9c574e7d
1 #define _GNU_SOURCE
2 #include "Clib32.h"
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <ctype.h>
7 #include "version.h"
8 #ifdef _WIN32
9 #define PSEP '\\'
10 #else
11 #define PSEP '/'
12 #endif
13 #define ADS ":::AGSpack " VERSION " by rofl0r:::"
15 static int usage(char *argv0) {
16 fprintf(stderr, ADS
17 "\nusage:\n%s OPTIONS directory target-pack\n\n"
18 "OPTIONS:\n"
19 "-e: recreate original exe stub\n"
20 , argv0);
21 return 1;
24 int main(int argc, char** argv) {
25 int c, exe_opt = 0;
26 while((c = getopt(argc, argv, "e")) != -1) switch(c) {
27 default: return usage(argv[0]);
28 case 'e': exe_opt = 1; break;
30 if (!argv[optind] || !argv[optind+1])
31 return usage(argv[0]);
33 char *dir = argv[optind];
34 char *pack = argv[optind+1];
35 char fnbuf[512];
36 char line[1024];
37 FILE* fp;
38 snprintf(fnbuf, sizeof(fnbuf), "%s%c%s", dir, PSEP, "agspack.info");
39 if(!(fp = fopen(fnbuf, "r"))) {
40 fprintf(stderr, "couldnt open %s\n", fnbuf);
41 return 1;
43 if(exe_opt) {
44 snprintf(fnbuf, sizeof(fnbuf), "%s%c%s", dir, PSEP, "agspack.exestub");
45 if(access(fnbuf, R_OK) == -1) {
46 fprintf(stderr, "exestub requested, but couldnt read %s\n", fnbuf);
47 return 1;
50 size_t index = 0;
51 struct AgsFile *ags = calloc(1, sizeof(*ags));
52 AgsFile_init(ags, pack);
53 AgsFile_setSourceDir(ags, dir);
54 AgsFile_setDataFileCount(ags, 1); //TODO
55 if(!AgsFile_setDataFile(ags, 0, "AGSPACKv" VERSION)) {
56 fprintf(stderr, "error: packname exceeds 20 chars\n");
57 return 1;
59 if(exe_opt) AgsFile_setExeStub(ags, "agspack.exestub");
61 while(fgets(line, sizeof(line), fp)) {
62 size_t l = strlen(line);
63 if(l) {
64 line[l - 1] = 0;
65 if(--l && line[l-1] == '\r') line[l - 1] = 0;
67 char *p = strchr(line, '=');
68 if(!p) return 1;
69 *p = 0; p++;
70 if(0) ;
71 else if(strcmp(line, "agsversion") == 0 || strcmp(line, "mflversion") == 0)
72 AgsFile_setVersion(ags, atoi(p));
73 else if(strcmp(line, "filecount") == 0)
74 AgsFile_setFileCount(ags, atoi(p));
75 else if(isdigit(*line))
76 if(!AgsFile_setFile(ags, index++, p)) {
77 perror(p);
78 return 1;
81 fclose(fp);
82 size_t l = AgsFile_getFileCount(ags);
83 for(index = 0; index < l; index++) {
84 // TODO read from input file, but it seems to be all 0 for some games.
85 AgsFile_setFileNumber(ags, index, 0);
87 int ret = AgsFile_write(ags);
88 if(!ret) perror("write");
89 AgsFile_close(ags);
90 free(ags);
91 return !ret;