Mercurial > hg > dmlib
annotate src/dmpack.c @ 1033:c353e6bcb733
Change handling of filename field in PACKs.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 01 Mar 2015 16:39:46 +0200 |
parents | a76056297006 |
children | d674ddc0fc82 |
rev | line source |
---|---|
0 | 1 /* |
2 * DMLib | |
3 * -- PACK-file handling | |
4 * Programmed and designed by Matti 'ccr' Hamalainen | |
1013 | 5 * (C) Copyright 2011-2015 Tecnic Software productions (TNSP) |
0 | 6 */ |
7 #include "dmpack.h" | |
8 #include "dmfile.h" | |
9 | |
10 | |
721
bb14d7907eb2
Rename many pack & resource handling functions.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
11 DMPackEntry *dmPackEntryNew() |
0 | 12 { |
13 return (DMPackEntry *) dmMalloc0(sizeof(DMPackEntry)); | |
14 } | |
15 | |
16 | |
721
bb14d7907eb2
Rename many pack & resource handling functions.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
17 void dmPackEntryFree(DMPackEntry * node) |
0 | 18 { |
19 dmFree(node); | |
20 } | |
21 | |
22 | |
721
bb14d7907eb2
Rename many pack & resource handling functions.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
23 void dmPackEntryInsert(DMPackEntry ** packDir, DMPackEntry * node) |
0 | 24 { |
25 if (*packDir != NULL) | |
26 { | |
27 node->prev = (*packDir)->prev; | |
28 (*packDir)->prev->next = node; | |
29 (*packDir)->prev = node; | |
30 } | |
31 else | |
32 { | |
33 *packDir = node->prev = node; | |
34 } | |
35 | |
36 node->next = NULL; | |
37 } | |
38 | |
39 | |
721
bb14d7907eb2
Rename many pack & resource handling functions.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
40 void dmPackEntryDelete(DMPackEntry ** packDir, DMPackEntry * node) |
0 | 41 { |
42 if (node->prev) | |
43 node->prev->next = node->next; | |
44 | |
45 if (node->next) | |
46 node->next->prev = node->prev; | |
47 else | |
48 (*packDir)->prev = node->prev; | |
49 | |
50 node->prev = node->next = NULL; | |
51 } | |
52 | |
53 | |
721
bb14d7907eb2
Rename many pack & resource handling functions.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
54 DMPackEntry *dmPackFind(DMPackEntry *list, const char *filename) |
0 | 55 { |
56 DMPackEntry *node; | |
57 | |
58 for (node = list; node != NULL; node = node->next) | |
59 { | |
60 if (strcmp(node->filename, filename) == 0) | |
61 return node; | |
62 } | |
63 | |
64 return NULL; | |
65 } | |
66 | |
67 | |
68 /* | |
69 * OPEN a packfile | |
70 */ | |
721
bb14d7907eb2
Rename many pack & resource handling functions.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
71 int dmPackOpen(const char *filename, DMPackFile ** ppPack, BOOL readOnly) |
0 | 72 { |
73 unsigned int i; | |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
74 DMPackFile *pack = NULL; |
0 | 75 DMPackFileHeader hdr; |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
76 int ret = DMERR_OK; |
0 | 77 |
78 // Allocate packfile-structure | |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
79 if ((pack = dmMalloc0(sizeof(DMPackFile))) == NULL) |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
80 { |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
81 ret = DMERR_MALLOC; |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
82 goto out; |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
83 } |
0 | 84 |
85 // Open the file | |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
86 if ((pack->file = fopen(filename, readOnly ? "rb" : "r+b")) == NULL) |
0 | 87 { |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
88 ret = DMERR_FOPEN; |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
89 goto out; |
0 | 90 } |
91 | |
92 pack->filename = dm_strdup(filename); | |
93 | |
94 // Read PACK header | |
95 fseek(pack->file, 0L, SEEK_SET); | |
96 if (!dm_fread_str(pack->file, (Uint8 *) &hdr.ident, sizeof(hdr.ident)) || | |
97 !dm_fread_le16(pack->file, &hdr.version) || | |
98 !dm_fread_le32(pack->file, &hdr.dirEntries) || | |
99 !dm_fread_le32(pack->file, &hdr.dirOffset)) | |
100 { | |
1030 | 101 ret = DMERR_FREAD; |
102 goto out; | |
0 | 103 } |
104 | |
105 // Check information | |
106 if (memcmp(&hdr.ident, DPACK_IDENT, sizeof(hdr.ident)) != 0) | |
107 { | |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
108 ret = DMERR_NOTPACK; |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
109 goto out; |
0 | 110 } |
111 | |
112 if (hdr.version != DPACK_VERSION) | |
113 { | |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
114 ret = DMERR_VERSION; |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
115 goto out; |
0 | 116 } |
117 | |
118 // Read directory | |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
119 if (hdr.dirOffset < sizeof(hdr) || |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
120 fseek(pack->file, hdr.dirOffset, SEEK_SET) != 0) |
0 | 121 { |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
122 ret = DMERR_INVALID; |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
123 goto out; |
0 | 124 } |
125 | |
126 for (i = 0; i < hdr.dirEntries; i++) | |
127 { | |
128 // Allocate and read directory entry | |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
129 DMPackEntry *entry; |
0 | 130 |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
131 if ((entry = dmPackEntryNew()) == NULL) |
0 | 132 { |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
133 ret = DMERR_MALLOC; |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
134 goto out; |
0 | 135 } |
136 | |
1033
c353e6bcb733
Change handling of filename field in PACKs.
Matti Hamalainen <ccr@tnsp.org>
parents:
1030
diff
changeset
|
137 if (!dm_fread_str(pack->file, (Uint8 *) &entry->filename, DMRES_NAME_LEN) || |
0 | 138 !dm_fread_le32(pack->file, &entry->size) || |
139 !dm_fread_le32(pack->file, &entry->offset) || | |
140 !dm_fread_le32(pack->file, &entry->length) || | |
721
bb14d7907eb2
Rename many pack & resource handling functions.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
141 !dm_fread_le32(pack->file, &entry->flags)) |
0 | 142 { |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
143 ret = DMERR_FREAD; |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
144 goto out; |
0 | 145 } |
146 | |
1033
c353e6bcb733
Change handling of filename field in PACKs.
Matti Hamalainen <ccr@tnsp.org>
parents:
1030
diff
changeset
|
147 // Ensure that the filename ends in NUL |
c353e6bcb733
Change handling of filename field in PACKs.
Matti Hamalainen <ccr@tnsp.org>
parents:
1030
diff
changeset
|
148 entry->filename[DMRES_NAME_LEN] = 0; |
c353e6bcb733
Change handling of filename field in PACKs.
Matti Hamalainen <ccr@tnsp.org>
parents:
1030
diff
changeset
|
149 |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
150 // Validate |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
151 if (entry->size == 0 || entry->length == 0 || |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
152 entry->length > hdr.dirOffset || |
1033
c353e6bcb733
Change handling of filename field in PACKs.
Matti Hamalainen <ccr@tnsp.org>
parents:
1030
diff
changeset
|
153 entry->offset > hdr.dirOffset || |
c353e6bcb733
Change handling of filename field in PACKs.
Matti Hamalainen <ccr@tnsp.org>
parents:
1030
diff
changeset
|
154 strlen(entry->filename) == 0) |
1030 | 155 { |
156 ret = DMERR_INVALID; | |
157 goto out; | |
158 } | |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
159 |
0 | 160 // Insert into list |
721
bb14d7907eb2
Rename many pack & resource handling functions.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
161 dmPackEntryInsert(&pack->entries, entry); |
0 | 162 } |
163 | |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
164 out: |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
165 if (ret != DMERR_OK) |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
166 { |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
167 dmPackClose(pack); |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
168 pack = NULL; |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
169 } |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
170 |
0 | 171 *ppPack = pack; |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
172 |
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
173 return ret; |
0 | 174 } |
175 | |
176 | |
177 /* | |
178 * CLOSE the packfile | |
179 */ | |
721
bb14d7907eb2
Rename many pack & resource handling functions.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
180 int dmPackClose(DMPackFile * pack) |
0 | 181 { |
721
bb14d7907eb2
Rename many pack & resource handling functions.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
182 DMPackEntry *node; |
0 | 183 |
184 if (pack == NULL) | |
185 return DMERR_OK; | |
186 | |
187 // Write the directory | |
188 node = pack->entries; | |
189 while (node != NULL) | |
190 { | |
721
bb14d7907eb2
Rename many pack & resource handling functions.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
191 DMPackEntry *next = node->next; |
bb14d7907eb2
Rename many pack & resource handling functions.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
192 dmPackEntryFree(node); |
0 | 193 node = next; |
194 } | |
195 | |
196 // Close the file | |
197 if (pack->file != NULL) | |
198 fclose(pack->file); | |
199 | |
200 // Free structures | |
201 dmFree(pack->filename); | |
202 | |
203 // Free packfile | |
1012
7666ba24e0c6
Cleanups and improve error handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
812
diff
changeset
|
204 memset(pack, 0, sizeof(DMPackFile)); |
0 | 205 dmFree(pack); |
206 | |
207 return DMERR_OK; | |
208 } |