Commit 49636ad9c6e511591d340f6df068a3de8d51f7c8

Authored by Imanol-Mikel Barba Sabariego
1 parent 5ccd4c43

Added error codes

... ... @@ -35,57 +35,55 @@ int overwriteChunk(const char* regionFolder, ChunkID chunk, void* chunkData, siz
35 35 sprintf(regionFilename,"%s/r.%d.%d.mca",regionFolder,region.x,region.z);
36 36  
37 37 if(access(regionFilename,R_OK | W_OK) == -1) {
38   - fprintf(stderr,"Can't access file %s: %s\n",regionFilename,strerror(errno));
39   - return -1;
  38 + return ACCESS_ERROR;
40 39 }
41 40  
42 41 int fd = open(regionFilename,O_RDWR);
43 42 if(fd == -1) {
44   - fprintf(stderr,"Unable to open region file %s: %s\n",regionFilename,strerror(errno));
45   - return -2;
  43 + return OPEN_ERROR;
46 44 }
47 45 free(regionFilename);
48 46  
49 47 uint32_t chunkHeaderOffset;
50 48 if(pread(fd,&chunkHeaderOffset,sizeof(uint32_t),(relativeChunk.x + relativeChunk.z * CHUNK_OFFSET_LENGTH) * sizeof(uint32_t)) == -1) {
51 49 close(fd);
52   - fprintf(stderr,"Unable to read chunk header offset: %s\n",strerror(errno));
53   - return -3;
  50 + return READ_ERROR;
54 51 }
55 52 uint32_t totalChunkLength = (chunkHeaderOffset >> 24) * 4096;
56 53 chunkHeaderOffset = (__bswap_32(chunkHeaderOffset & 0x00FFFFFF) >> 8) * CHUNK_SECTOR_SIZE;
57 54 int pos = lseek(fd,chunkHeaderOffset,SEEK_SET);
58 55 if(pos == -1) {
59 56 close(fd);
60   - fprintf(stderr,"Unable to seek to header offset: %s\n",strerror(errno));
61   - return -4;
  57 + return SEEK_ERROR;
62 58 }
63 59  
64 60 ChunkHeader header;
65 61 if(pread(fd,&header,sizeof(ChunkHeader),pos) <= 0) {
66 62 close(fd);
67   - fprintf(stderr,"Unable to read chunk header: %s\n",strerror(errno));
68   - return -5;
  63 + return READ_ERROR;
69 64 }
70 65 header.length = __bswap_32(header.length);
71 66  
72 67 void* compressedChunk;
73 68 ssize_t compressedChunkLength = deflateGzip(chunkData,chunkLength,&compressedChunk,(header.compressionType == COMPRESSION_TYPE_ZLIB));
  69 + if(compressedChunkLength < 0) {
  70 + // Compression error
  71 + close(fd);
  72 + return compressedChunkLength;
  73 + }
74 74 if(compressedChunkLength > totalChunkLength) {
75 75 // Haven't determined if we can just allocate a new 4KiB sector for the chunk
76 76 // To avoid corrupting the region, let's just make the function fail and retry on another chunk that has
77 77 // free space at the end
78 78 close(fd);
79 79 free(compressedChunk);
80   - fprintf(stderr,"Not enough free space to overwrite the chunk.\n\nOriginal chunk size (with padding): %d\nNew chunk size:%d\n",totalChunkLength,(unsigned int)compressedChunkLength);
81   - return -6;
  80 + return INSUFFICIENT_SPACE_FOR_CHUNK;
82 81 }
83 82 header.length = __bswap_32((uint32_t)compressedChunkLength+1);
84 83 if(write(fd,&header,sizeof(ChunkHeader)) <= 0) {
85 84 close(fd);
86 85 free(compressedChunk);
87   - fprintf(stderr,"Unable to read chunk header: %s\n",strerror(errno));
88   - return -7;
  86 + return WRITE_ERROR;
89 87 }
90 88 ssize_t nWritten = 0;
91 89 size_t totalWritten = 0;
... ... @@ -95,16 +93,15 @@ int overwriteChunk(const char* regionFolder, ChunkID chunk, void* chunkData, siz
95 93 if(errno == EINTR) {
96 94 continue;
97 95 }
98   - fprintf(stderr,"Unable to write chunk: %s\n",strerror(errno));
99 96 close(fd);
100 97 free(compressedChunk);
101   - return -8;
  98 + return WRITE_ERROR;
102 99 }
103 100 totalWritten += nWritten;
104 101 }
105 102 close(fd);
106 103 free(compressedChunk);
107   - return 0;
  104 + return SUCCESS;
108 105 }
109 106  
110 107 ssize_t loadChunk(const char* regionFolder, ChunkID chunk, void** chunkData) {
... ... @@ -117,53 +114,42 @@ ssize_t loadChunk(const char* regionFolder, ChunkID chunk, void** chunkData) {
117 114 sprintf(regionFilename,"%s/r.%d.%d.mca",regionFolder,region.x,region.z);
118 115  
119 116 if(access(regionFilename,R_OK) == -1) {
120   - fprintf(stderr,"Can't access file %s: %s\n",regionFilename,strerror(errno));
121   - return -1;
  117 + return ACCESS_ERROR;
122 118 }
123 119  
124 120 int fd = open(regionFilename,O_RDONLY);
125 121 if(fd == -1) {
126   - fprintf(stderr,"Unable to open region file %s: %s\n",regionFilename,strerror(errno));
127   - return -2;
  122 + return OPEN_ERROR;
128 123 }
129 124 free(regionFilename);
130 125  
131 126 uint32_t chunkHeaderOffset;
132 127 if(pread(fd,&chunkHeaderOffset,sizeof(uint32_t),(relativeChunk.x + relativeChunk.z * CHUNK_OFFSET_LENGTH) * sizeof(uint32_t)) == -1) {
133 128 close(fd);
134   - fprintf(stderr,"Unable to read chunk header offset: %s\n",strerror(errno));
135   - return -3;
  129 + return READ_ERROR;
136 130 }
137 131 chunkHeaderOffset = (__bswap_32(chunkHeaderOffset & 0x00FFFFFF) >> 8) * CHUNK_SECTOR_SIZE;
138 132 if(chunkHeaderOffset == 0) {
139 133 // Chunk not present. Hasn't been generated
140   - close(fd);
141   - return 0;
  134 + close(fd);
  135 + return CHUNK_NOT_PRESENT;
142 136 }
143 137  
144 138 if(lseek(fd,chunkHeaderOffset,SEEK_SET) == -1) {
145 139 close(fd);
146   - fprintf(stderr,"Unable to seek to header offset: %s\n",strerror(errno));
147   - return -4;
  140 + return SEEK_ERROR;
148 141 }
149 142  
150 143 ChunkHeader header;
151 144 if(read(fd,&header,sizeof(ChunkHeader)) <= 0) {
152 145 close(fd);
153   - fprintf(stderr,"Unable to read chunk header: %s\n",strerror(errno));
154   - return -5;
  146 + return READ_ERROR;
155 147 }
156 148 header.length = __bswap_32(header.length);
157 149 ssize_t chunkLength = header.length;
158   - if(header.compressionType != COMPRESSION_TYPE_ZLIB && header.compressionType != COMPRESSION_TYPE_GZIP) {
159   - fprintf(stderr, "Invalid compression method. Proably reading the wrong data for the header\n");
  150 + if((header.compressionType != COMPRESSION_TYPE_ZLIB && header.compressionType != COMPRESSION_TYPE_GZIP) || header.length == 0) {
160 151 close(fd);
161   - return -6;
162   - }
163   - if(header.length == 0) {
164   - fprintf(stderr, "Header length is 0. Probably reading the wrong data for the header\n");
165   - close(fd);
166   - return -7;
  152 + return INVALID_HEADER;
167 153 }
168 154  
169 155 void* compressedChunk = calloc(chunkLength,sizeof(char));
... ... @@ -175,10 +161,9 @@ ssize_t loadChunk(const char* regionFolder, ChunkID chunk, void** chunkData) {
175 161 if(errno == EINTR) {
176 162 continue;
177 163 }
178   - fprintf(stderr,"Unable to read chunk: %s\n",strerror(errno));
179 164 close(fd);
180 165 free(compressedChunk);
181   - return -8;
  166 + return READ_ERROR;
182 167 }
183 168 totalRead += nRead;
184 169 }
... ... @@ -186,11 +171,10 @@ ssize_t loadChunk(const char* regionFolder, ChunkID chunk, void** chunkData) {
186 171  
187 172 void *decompressedChunk;
188 173 chunkLength = inflateGzip(compressedChunk,chunkLength,&decompressedChunk,(header.compressionType == COMPRESSION_TYPE_ZLIB));
189   -
190   - if(chunkLength <= 0) {
191   - fprintf(stderr,"Error while decompressing chunk\n");
  174 + if(chunkLength < 0) {
  175 + // Error while decompressing chunk
192 176 free(compressedChunk);
193   - return -9;
  177 + return chunkLength;
194 178 }
195 179 free(compressedChunk);
196 180  
... ...
... ... @@ -12,6 +12,7 @@
12 12 #include <math.h>
13 13  
14 14 #include "compression.h"
  15 +#include "errors.h"
15 16  
16 17 #define BLOCKS_PER_CHUNK 16
17 18 #define CHUNKS_PER_REGION 32
... ...
compression.c
... ... @@ -21,9 +21,8 @@ ssize_t inflateGzip(void* compData, size_t compDataLen, void** unCompData, int h
21 21 }
22 22  
23 23 if(err != Z_OK) {
24   - fprintf(stderr, "Unable to initialize zlib zstream for decompression\n");
25 24 free(uncomp);
26   - return -1;
  25 + return ZLIB_STREAM_INIT_ERROR;
27 26 }
28 27  
29 28 do {
... ... @@ -32,10 +31,9 @@ ssize_t inflateGzip(void* compData, size_t compDataLen, void** unCompData, int h
32 31 // Increase size of output buffer
33 32 void* newptr = realloc(uncomp,uncompLength + increase);
34 33 if(newptr == NULL) {
35   - fprintf(stderr,"Unable to request memory realloc\n");
36 34 inflateEnd(&strm);
37 35 free(uncomp);
38   - return -2;
  36 + return MEMORY_ERROR;
39 37 }
40 38 uncomp = newptr;
41 39 uncompLength += increase;
... ... @@ -47,18 +45,16 @@ ssize_t inflateGzip(void* compData, size_t compDataLen, void** unCompData, int h
47 45 // Inflate another chunk.
48 46 err = inflate(&strm, Z_SYNC_FLUSH);
49 47 if(err != Z_OK && err != Z_STREAM_END) {
50   - fprintf(stderr, "Error while inflating buffer: %d - %s.\n", err,strm.msg);
51 48 inflateEnd(&strm);
52 49 free(uncomp);
53   - return -3;
  50 + return ZLIB_INFLATE_ERROR;
54 51 }
55 52 } while(err != Z_STREAM_END);
56 53 uncompLength = strm.total_out;
57 54  
58 55 if(inflateEnd(&strm) != Z_OK) {
59   - fprintf(stderr,"Error while deallocating libz zstream\n");
60 56 free(uncomp);
61   - return -4;
  57 + return ZLIB_STREAM_FREE_ERROR;
62 58 }
63 59  
64 60 *unCompData = uncomp;
... ... @@ -85,9 +81,8 @@ ssize_t deflateGzip(void* unCompData, size_t unCompDataLen, void** compData, int
85 81 }
86 82  
87 83 if(err != Z_OK) {
88   - fprintf(stderr, "Unable to initialize zlib zstream for compression\n");
89 84 free(comp);
90   - return -1;
  85 + return ZLIB_STREAM_INIT_ERROR;
91 86 }
92 87  
93 88 do {
... ... @@ -96,10 +91,9 @@ ssize_t deflateGzip(void* unCompData, size_t unCompDataLen, void** compData, int
96 91 // Increase size of output buffer
97 92 void* newptr = realloc(comp, compLength + increase);
98 93 if(newptr == NULL) {
99   - fprintf(stderr,"Unable to request memory realloc\n");
100 94 deflateEnd(&strm);
101 95 free(comp);
102   - return -2;
  96 + return MEMORY_ERROR;
103 97 }
104 98 comp = newptr;
105 99 compLength += increase;
... ... @@ -111,18 +105,16 @@ ssize_t deflateGzip(void* unCompData, size_t unCompDataLen, void** compData, int
111 105 // deflate another chunk
112 106 err = deflate(&strm, Z_FINISH);
113 107 if(err != Z_OK && err != Z_STREAM_END) {
114   - fprintf(stderr, "Error while deflating buffer: %d - %s\n",err,strm.msg);
115 108 deflateEnd(&strm);
116 109 free(comp);
117   - return -3;
  110 + return ZLIB_DEFLATE_ERROR;
118 111 }
119 112 } while(err != Z_STREAM_END);
120 113 compLength = strm.total_out;
121 114  
122 115 if(deflateEnd(&strm) != Z_OK) {
123   - fprintf(stderr,"Error while deallocating libz zstream\n");
124 116 free(comp);
125   - return -4;
  117 + return ZLIB_STREAM_FREE_ERROR;
126 118 }
127 119  
128 120 if(!headerless) {
... ...
compression.h
... ... @@ -5,6 +5,8 @@
5 5 #include <zlib.h>
6 6 #include <stdio.h>
7 7  
  8 +#include "errors.h"
  9 +
8 10 #define OS_FLAG_OFFSET 0x9
9 11  
10 12 ssize_t deflateGzip(void* unCompData, size_t unCompDataLen, void** compData, int headerless);
... ...
... ... @@ -8,18 +8,17 @@ void destroyTagList(TagList* l);
8 8 void destroyTagCompound(TagCompound* tc);
9 9 size_t getTypeSize(uint8_t type);
10 10 unsigned int parseList(void* addr, TagList* tl, uint8_t type);
11   -unsigned int parseCompound(void* addr, TagCompound* tc);
12   -unsigned int parsePayload(void* addr,Tag* t);
13   -unsigned int parseTag(void* addr, Tag* t);
14   -size_t composeCompound(TagCompound* tc, void** data);
15   -size_t composeList(uint8_t listType, TagList* tl, void** data);
16   -size_t composePayload(Tag t, void** data);
17   -size_t composeTag(Tag t, void** data);
  11 +ssize_t parseCompound(void* addr, TagCompound* tc);
  12 +ssize_t parsePayload(void* addr,Tag* t);
  13 +ssize_t parseTag(void* addr, Tag* t);
  14 +ssize_t composeCompound(TagCompound* tc, void** data);
  15 +ssize_t composeList(uint8_t listType, TagList* tl, void** data);
  16 +ssize_t composePayload(Tag t, void** data);
  17 +ssize_t composeTag(Tag t, void** data);
18 18  
19 19 ssize_t loadDB(const char* filename, void** data) {
20 20 if(access(filename,R_OK) == -1) {
21   - perror("Can't access file");
22   - return -1;
  21 + return ACCESS_ERROR;
23 22 }
24 23  
25 24 struct stat sb;
... ... @@ -27,8 +26,7 @@ ssize_t loadDB(const char* filename, void** data) {
27 26  
28 27 int fd = open(filename,O_RDONLY);
29 28 if(fd == -1) {
30   - perror("Can't open file");
31   - return -2;
  29 + return OPEN_ERROR;
32 30 }
33 31 fstat(fd, &sb);
34 32  
... ... @@ -44,8 +42,7 @@ ssize_t loadDB(const char* filename, void** data) {
44 42 if(errno == EINTR) {
45 43 continue;
46 44 }
47   - perror("Error reading file");
48   - return -7;
  45 + return READ_ERROR;
49 46 }
50 47 totalRead += nRead;
51 48 }
... ... @@ -144,7 +141,7 @@ unsigned int parseList(void* addr, TagList* tl, uint8_t type) {
144 141 return pos - addr;
145 142 }
146 143  
147   -unsigned int parseCompound(void* addr, TagCompound* tc) {
  144 +ssize_t parseCompound(void* addr, TagCompound* tc) {
148 145 void* pos = addr;
149 146 unsigned int numTags = 0;
150 147 Tag* list = calloc(REALLOC_SIZE,sizeof(Tag));
... ... @@ -152,8 +149,8 @@ unsigned int parseCompound(void* addr, TagCompound* tc) {
152 149 if(numTags && !(numTags % REALLOC_SIZE)) {
153 150 void* newptr = reallocarray(list, numTags + REALLOC_SIZE, sizeof(Tag));
154 151 if(!newptr) {
155   - fprintf(stderr,"Unable to request memory realloc\n");
156   - break;
  152 + free(list);
  153 + return MEMORY_ERROR;
157 154 }
158 155 list = newptr;
159 156 }
... ... @@ -162,7 +159,8 @@ unsigned int parseCompound(void* addr, TagCompound* tc) {
162 159  
163 160 void* newptr = reallocarray(list, numTags, sizeof(Tag));
164 161 if(!newptr) {
165   - fprintf(stderr,"Unable to request memory realloc\n");
  162 + free(list);
  163 + return MEMORY_ERROR;
166 164 }
167 165 list = newptr;
168 166  
... ... @@ -171,9 +169,10 @@ unsigned int parseCompound(void* addr, TagCompound* tc) {
171 169 return pos - addr;
172 170 }
173 171  
174   -unsigned int parsePayload(void* addr,Tag* t) {
  172 +ssize_t parsePayload(void* addr,Tag* t) {
175 173 void* pos = addr;
176 174 t->payloadLength = getTypeSize(t->type); // initially, then particularly for lists/compounds/strings
  175 + ssize_t compoundTagPos = 0;
177 176 TagCompound* tc;
178 177 TagList *tl;
179 178 uint16_t u16 = 0;
... ... @@ -218,7 +217,12 @@ unsigned int parsePayload(void* addr,Tag* t) {
218 217 tc = (TagCompound*)calloc(1,sizeof(TagCompound));
219 218 t->payloadLength = sizeof(sizeof(TagCompound));
220 219 t->payload = tc;
221   - pos += parseCompound(pos,tc);
  220 + compoundTagPos = parseCompound(pos,tc);
  221 + if(compoundTagPos < 0) {
  222 + // Memory error while parsing TAG_COMPOUND
  223 + return compoundTagPos;
  224 + }
  225 + pos += compoundTagPos;
222 226 break;
223 227 case TAG_LIST:
224 228 case TAG_BYTEARRAY:
... ... @@ -232,7 +236,7 @@ unsigned int parsePayload(void* addr,Tag* t) {
232 236 return pos - addr;
233 237 }
234 238  
235   -unsigned int parseTag(void* addr, Tag* t) {
  239 +ssize_t parseTag(void* addr, Tag* t) {
236 240 void* pos = addr;
237 241 t->type = *((uint8_t*)pos);
238 242 t->nameLength = 0;
... ... @@ -247,12 +251,16 @@ unsigned int parseTag(void* addr, Tag* t) {
247 251 }
248 252 pos += sizeof(uint16_t) + t->nameLength;
249 253 }
250   - pos += parsePayload(pos,t);
  254 + ssize_t payloadPos = parsePayload(pos,t);
  255 + if(payloadPos < 0) {
  256 + return payloadPos;
  257 + }
  258 + pos += payloadPos;
251 259  
252 260 return pos-addr;
253 261 }
254 262  
255   -size_t composeCompound(TagCompound* tc, void** data) {
  263 +ssize_t composeCompound(TagCompound* tc, void** data) {
256 264 size_t totalPayloadLength = 0;
257 265 void* totalPayload = calloc(1,sizeof(char));
258 266 unsigned int pos = 0;
... ... @@ -263,10 +271,9 @@ size_t composeCompound(TagCompound* tc, void** data) {
263 271 totalPayloadLength += childTagPayloadLength;
264 272 void* newptr = realloc(totalPayload,totalPayloadLength);
265 273 if(newptr == NULL) {
266   - fprintf(stderr, "Unable to realloc memory for child tag\n");
267 274 free(totalPayload);
268 275 free(childTagPayload);
269   - return 0;
  276 + return MEMORY_ERROR;
270 277 }
271 278 totalPayload = newptr;
272 279 memcpy(totalPayload+pos,childTagPayload,childTagPayloadLength);
... ... @@ -275,9 +282,8 @@ size_t composeCompound(TagCompound* tc, void** data) {
275 282 }
276 283 void* newptr = realloc(totalPayload,++totalPayloadLength);
277 284 if(newptr == NULL) {
278   - fprintf(stderr, "Unable to realloc memory for end tag\n");
279 285 free(totalPayload);
280   - return 0;
  286 + return MEMORY_ERROR;
281 287 }
282 288 totalPayload = newptr;
283 289 ((uint8_t*)totalPayload)[pos] = 0x00;
... ... @@ -285,7 +291,7 @@ size_t composeCompound(TagCompound* tc, void** data) {
285 291 return totalPayloadLength;
286 292 }
287 293  
288   -size_t composeList(uint8_t listType, TagList* tl, void** data) {
  294 +ssize_t composeList(uint8_t listType, TagList* tl, void** data) {
289 295 size_t totalPayloadLength = 0;
290 296 if(listType == TAG_LIST) {
291 297 totalPayloadLength += sizeof(uint8_t);
... ... @@ -306,10 +312,9 @@ size_t composeList(uint8_t listType, TagList* tl, void** data) {
306 312 totalPayloadLength += childTagPayloadLength;
307 313 void* newptr = realloc(totalPayload,totalPayloadLength);
308 314 if(newptr == NULL) {
309   - fprintf(stderr, "Unable to realloc memory for child tag\n");
310 315 free(totalPayload);
311 316 free(childTagPayload);
312   - return 0;
  317 + return MEMORY_ERROR;
313 318 }
314 319 totalPayload = newptr;
315 320 memcpy(totalPayload+pos,childTagPayload,childTagPayloadLength);
... ... @@ -321,7 +326,7 @@ size_t composeList(uint8_t listType, TagList* tl, void** data) {
321 326 return totalPayloadLength;
322 327 }
323 328  
324   -size_t composePayload(Tag t, void** data) {
  329 +ssize_t composePayload(Tag t, void** data) {
325 330 size_t payloadLength = getTypeSize(t.type); // initially, then particularly for lists/compounds/strings
326 331 void* payload;
327 332  
... ... @@ -371,7 +376,7 @@ size_t composePayload(Tag t, void** data) {
371 376 return payloadLength;
372 377 }
373 378  
374   -size_t composeTag(Tag t, void** data) {
  379 +ssize_t composeTag(Tag t, void** data) {
375 380 size_t headerSize = sizeof(uint8_t) + sizeof(uint16_t) + t.nameLength;
376 381 void* tagHeader = calloc(headerSize,sizeof(char));
377 382 ((uint8_t*)tagHeader)[0] = t.type;
... ... @@ -379,13 +384,16 @@ size_t composeTag(Tag t, void** data) {
379 384 memcpy(tagHeader+sizeof(uint8_t),&u16,sizeof(uint16_t));
380 385 memcpy(tagHeader+sizeof(uint8_t) + sizeof(uint16_t), t.name, t.nameLength);
381 386 void* tagPayload;
382   - size_t payloadSize = composePayload(t,&tagPayload);
  387 + ssize_t payloadSize = composePayload(t,&tagPayload);
  388 + if(payloadSize < 0) {
  389 + // Some error while composing payload
  390 + return payloadSize;
  391 + }
383 392 void* tagData = realloc(tagHeader,headerSize + payloadSize);
384 393 if(tagData == NULL) {
385   - fprintf(stderr, "Unable to realloc memory to merge header and payload\n");
386 394 free(tagHeader);
387 395 free(tagPayload);
388   - return 0;
  396 + return MEMORY_ERROR;
389 397 }
390 398 memcpy(tagData + headerSize,tagPayload, payloadSize);
391 399 free(tagPayload);
... ...
... ... @@ -13,6 +13,8 @@
13 13 #include <errno.h>
14 14 #include <zlib.h>
15 15  
  16 +#include "errors.h"
  17 +
16 18 #ifndef REALLOC_SIZE
17 19 #define REALLOC_SIZE 10
18 20 #endif
... ... @@ -59,7 +61,7 @@ enum TAG {
59 61  
60 62 ssize_t loadDB(const char* filename, void** data);
61 63 void destroyTag(Tag* t);
62   -unsigned int parseTag(void* addr, Tag* t);
63   -size_t composeTag(Tag t, void** data);
  64 +ssize_t parseTag(void* addr, Tag* t);
  65 +ssize_t composeTag(Tag t, void** data);
64 66  
65 67 #endif
66 68 \ No newline at end of file
... ...