Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
3
 * It is copyright by its individual contributors, as recorded in the
4
 * project's Git history.  See COPYING.txt at the top level for license
5
 * terms and a link to the Git history.
6
 */
7
/*
8
 * Written 1999 Jan 29 by Josh Cogliati
9
 * Modified for mvl by Bradley Bell, 2002, 2003
10
 * This program is licensed under the terms of the GPL, version 2 or later
11
 */
12
 
13
#include <stdio.h>
14
#include <stdlib.h>
15
#include <string.h>
16
#include <sys/types.h>
17
#include <sys/stat.h>
18
#include <fcntl.h>
19
 
20
#define SWAPINT(x)   (((x)<<24) | (((unsigned int)(x)) >> 24) | (((x) &0x0000ff00) << 8) | (((x) & 0x00ff0000) >> 8))
21
 
22
#define MAX_FILES 256
23
 
24
int
25
main(int argc, char *argv[])
26
{
27
        FILE *mvlfile, *writefile;
28
        int i, nfiles, len[MAX_FILES];
29
        char filename[MAX_FILES][13];
30
        char *buf;
31
        struct stat statbuf;
32
        int v = 0;
33
        int bigendian = 0;
34
 
35
        if (argc > 1 && !strcmp(argv[1], "v")) {
36
                v = 1;
37
                argc--;
38
                argv++;
39
        }
40
 
41
        if (argc < 2) {
42
                printf("Usage: mvlextract [v] mvlfile [filename]\n"
43
                       "extracts all the files in mvlfile into the current directory\n"
44
                           "Options:\n"
45
                           "  v    View files, don't extract\n");
46
                exit(0);
47
        }
48
        mvlfile = fopen(argv[1], "rb");
49
        stat(argv[1], &statbuf);
50
        printf("%i\n", (int)statbuf.st_size);
51
        buf = (char *)malloc(4);
52
        fread(buf, 4, 1, mvlfile);
53
        fread(&nfiles, 4, 1, mvlfile);
54
        printf("%d files\n", nfiles);
55
        if (nfiles > MAX_FILES) { // must be a bigendian mvl
56
                fprintf(stderr, "warning: nfiles>%d, trying reverse byte order...",
57
                                MAX_FILES);
58
                bigendian = 1;
59
        }
60
        if (bigendian)
61
                nfiles = SWAPINT(nfiles);
62
        printf("Extracting from: %s\n", argv[1]);
63
        free(buf);
64
        for (i = 0; i < nfiles; i++) {
65
                fread(filename[i], 13, 1, mvlfile);
66
                fread(&len[i], 4, 1, mvlfile);
67
                if (bigendian)
68
                        len[i] = SWAPINT(len[i]);
69
                if (argc == 2 || !strcmp(argv[2], filename[i]))
70
                        printf("Filename: %s \tLength: %i\n", filename[i], len[i]);
71
        }
72
 
73
        if (!v) {
74
                for (i = 0; i < nfiles; i++) {
75
                        if (argc > 2 && strcmp(argv[2], filename[i]))
76
                                fseek(mvlfile, len[i], SEEK_CUR);
77
                        else {
78
                                if (ftell(mvlfile) > statbuf.st_size) {
79
                                        printf("Error, end of file\n");
80
                                        exit(1);
81
                                }
82
                                buf = (char *)malloc(len[i]);
83
                                if (buf == NULL) {
84
                                        printf("Unable to allocate memory\n");
85
                                } else {
86
                                        fread(buf, len[i], 1, mvlfile);
87
                                        writefile = fopen(filename[i], "wb");
88
                                        fwrite(buf, len[i], 1, writefile);
89
                                        fclose(writefile);
90
                                        free(buf);
91
                                }
92
                        }
93
                }
94
        }
95
        fclose(mvlfile);
96
 
97
        return 0;
98
}