]> icculus.org git repositories - crow/jumpnbump.git/blob - modify/pack.c
Initial revision
[crow/jumpnbump.git] / modify / pack.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <string.h>
7 #include <getopt.h>
8 #include <unistd.h>
9
10 typedef struct {
11     char filename[12];
12     u_int32_t offset;
13     u_int32_t size;
14 } DirEntry;
15
16 int main(int argc, char **argv)
17 {
18     int fd;
19     DirEntry *datafile;
20     int num_entries, i;
21     int c;
22     char *outfile = NULL;
23     int offset = 0;
24
25     while ((c = getopt(argc, argv, "o:")) != EOF) {
26         switch (c) {
27             case 'o':
28                 if (optarg) {
29                     outfile = strdup(optarg);
30                 }
31                 break;
32         }
33     }
34     argc -= optind;
35     argv += optind;
36
37     if (outfile == NULL) {
38         printf("You must specify output filename with -o\n");
39         exit(1);
40     }
41     if (argc == 0) {
42         printf("You must specify some files to pack, duh\n");
43         exit(1);
44     }
45     num_entries = argc;
46
47     /* prepare to pack things - get sizes and calculate offsets */
48     printf("%u files to pack\n", num_entries);
49     datafile = calloc(num_entries, sizeof(DirEntry));
50
51     /* skip past the directory structure */
52     offset = 4 + (num_entries * 20);
53
54     for (i = 0; i < num_entries; i++) {
55         struct stat dummy;
56         if (stat(argv[i], &dummy)) {
57             fprintf(stderr, "%s is not accessible: ", argv[i]);
58             perror("");
59             exit(1);
60         }
61         if (strlen(argv[i]) > 12) {
62             fprintf(stderr, "filename %s is longer than 12 chars\n", argv[i]);
63             exit(1);
64         }
65         strncpy(datafile[i].filename, argv[i], 12);
66         datafile[i].size = dummy.st_size;
67         /* num_entries * (12 + 8) */
68         datafile[i].offset = offset;
69         offset += datafile[i].size;
70     }
71
72     /* here, we checked that all files are ok, and ready to roll the packfile */
73     fd = open(outfile, O_RDWR | O_CREAT, 0644);
74     if (fd == -1) {
75         perror("opening packfile");
76         exit(1);
77     }
78     printf("Opened %s\n", outfile);
79
80     /* write number of entries in this data file */
81     write(fd, &num_entries, 4);
82
83     /* write the directory structure */
84     for (i = 0; i < num_entries; i++) {
85         write(fd, &datafile[i], 20);
86     }
87
88     /* write in the actual files */
89     for (i = 0; i < num_entries; i++) {
90         int infd;
91         char *buf;
92
93         printf("adding %s ", argv[i]);
94
95         infd = open(argv[i], O_RDONLY);
96         if (infd == -1) {
97             perror("opening file");
98             exit(1);
99         }
100         buf = malloc(datafile[i].size + 16);
101         read(infd, buf, datafile[i].size);
102         close(infd);
103         write(fd, buf, datafile[i].size);
104         free(buf);
105         printf(" OK\n");
106     }
107     close(fd);
108     return 0;
109 }