Commit b5b8f8556365b70a207fd5dd4924d041c378a394

Authored by Imanol-Mikel Barba Sabariego
1 parent 1e868e43

Made return codes a bit more sane, and used the return codes from libnbt

Showing 1 changed file with 111 additions and 70 deletions
mcpetbackup.c
1 1 #include <stdio.h>
2 2 #include <getopt.h>
3 3 #include <dirent.h>
  4 +#include <fcntl.h>
  5 +#include <errno.h>
  6 +#include <unistd.h>
  7 +#include <sys/stat.h>
  8 +#include <stdint.h>
4 9  
5 10 #include "nbt.h"
6 11 #include "chunk.h"
7 12  
8   -enum paramIndex
9   -{
  13 +enum paramIndex {
10 14 UNKNOWN = 0,
11 15 HELP,
12 16 REGION,
... ... @@ -36,13 +40,17 @@ static struct option longopts[] = {
36 40  
37 41 int savePetToFile(Tag* pet, const char* filename) {
38 42 void* petData;
39   - size_t petDataLength = composeTag(*pet, &petData);
  43 + ssize_t petDataLength = composeTag(*pet, &petData);
  44 + if(petDataLength < 0) {
  45 + fprintf(stderr,"Error while composing pet tag: code %d\n",(int)petDataLength);
  46 + return petDataLength;
  47 + }
40 48  
41 49 int fd = open(filename,O_CREAT|O_WRONLY,0644);
42 50 if(fd == -1) {
43 51 fprintf(stderr,"Unable to open file to save pet: %s\n",strerror(errno));
44 52 free(petData);
45   - return 1;
  53 + return -1;
46 54 }
47 55 ssize_t nWritten = 0;
48 56 size_t totalWritten = 0;
... ... @@ -55,7 +63,7 @@ int savePetToFile(Tag* pet, const char* filename) {
55 63 fprintf(stderr,"Unable to write pet data: %s\n",strerror(errno));
56 64 close(fd);
57 65 free(petData);
58   - return 2;
  66 + return -2;
59 67 }
60 68 totalWritten += nWritten;
61 69 }
... ... @@ -69,14 +77,14 @@ int loadPetFromFile(Tag* pet, const char* filename) {
69 77 int fd = open(filename,O_RDONLY);
70 78 if(fd == -1) {
71 79 fprintf(stderr,"Unable to open file to load pet: %s\n",strerror(errno));
72   - return 1;
  80 + return -1;
73 81 }
74 82  
75 83 struct stat sb;
76 84 if(stat(filename,&sb) == -1) {
77 85 fprintf(stderr,"Unable to stat() file to load pet: %s\n",strerror(errno));
78 86 close(fd);
79   - return 2;
  87 + return -2;
80 88 }
81 89 void* petData = calloc(sb.st_size,sizeof(uint8_t));
82 90  
... ... @@ -91,17 +99,22 @@ int loadPetFromFile(Tag* pet, const char* filename) {
91 99 fprintf(stderr,"Unable to write pet data: %s\n",strerror(errno));
92 100 close(fd);
93 101 free(petData);
94   - return 3;
  102 + return -3;
95 103 }
96 104 totalRead += nRead;
97 105 }
98 106 close(fd);
99 107  
100   - size_t pos = parseTag(petData,pet);
  108 + ssize_t pos = parseTag(petData,pet);
  109 + if(pos < 0) {
  110 + fprintf(stderr,"Error parsing pet data: code %d\n",(int)pos);
  111 + free(petData);
  112 + return pos;
  113 + }
101 114 if(pos != sb.st_size) {
102   - fprintf(stderr,"Error parsing pet data\n");
  115 + fprintf(stderr,"Didn't reach end of database while parsing\n");
103 116 free(petData);
104   - return 4;
  117 + return -4;
105 118 }
106 119  
107 120 free(petData);
... ... @@ -120,7 +133,7 @@ int getEntitiesTag(TagCompound* chunkRoot,Tag** entities) {
120 133 }
121 134 if(!found) {
122 135 fprintf(stderr,"Unable to locate Level tag\n");
123   - return 1;
  136 + return -1;
124 137 }
125 138 found = 0;
126 139  
... ... @@ -135,7 +148,7 @@ int getEntitiesTag(TagCompound* chunkRoot,Tag** entities) {
135 148 }
136 149 if(!found) {
137 150 fprintf(stderr,"Unable to locate Entities tag\n");
138   - return 2;
  151 + return -2;
139 152 }
140 153 *entities = t;
141 154 return 0;
... ... @@ -188,22 +201,35 @@ ssize_t insertPetIntoChunk(void** chunkData, Tag chunkRoot, Tag* entities, Tag p
188 201 Tag* newPet = &entitiesList->list[(entitiesList->size) - 1];
189 202  
190 203 void* rawPetData;
191   - size_t rawPetDataLength = composeTag(pet,&rawPetData);
192   - size_t parsePos = parseTag(rawPetData,newPet);
  204 + ssize_t rawPetDataLength = composeTag(pet,&rawPetData);
  205 + if(rawPetDataLength < 0) {
  206 + fprintf(stderr,"Error while composing pet tag: code %d\n",(int)rawPetDataLength);
  207 + return -2;
  208 + }
  209 + ssize_t parsePos = parseTag(rawPetData,newPet);
  210 + if(parsePos < 0) {
  211 + fprintf(stderr,"Error while parsing pet tag: code %d\n",(int)parsePos);
  212 + free(rawPetData);
  213 + return -3;
  214 + }
193 215 if(parsePos != rawPetDataLength) {
194 216 fprintf(stderr,"Error while duplicating pet. New pet data does not match original\n");
195 217 free(rawPetData);
196   - return -2;
  218 + return -4;
197 219 }
198 220 free(rawPetData);
199 221  
200 222 void* newChunkData;
201   - size_t chunkDataLength = composeTag(chunkRoot, &newChunkData);
  223 + ssize_t chunkDataLength = composeTag(chunkRoot, &newChunkData);
  224 + if(chunkDataLength < 0) {
  225 + fprintf(stderr,"Error while composing new chunk tag: code %d\n",(int)chunkDataLength);
  226 + return -5;
  227 + }
202 228 newptr = realloc(*chunkData,chunkDataLength);
203 229 if(newptr == NULL) {
204 230 fprintf(stderr,"Unable to realloc chunkData to fit new data\n");
205 231 free(newChunkData);
206   - return -4;
  232 + return -6;
207 233 }
208 234 *chunkData = newptr;
209 235 memcpy(*chunkData,newChunkData,chunkDataLength);
... ... @@ -250,7 +276,7 @@ int main(int argc, char** argv) {
250 276 fprintf(stderr,"No options specified\n\n");
251 277 fprintf(stderr,"Examples:\n");
252 278 printHelp();
253   - return 0;
  279 + return 3;
254 280 }
255 281  
256 282 while ((c = getopt_long(argc, argv, "r:s:l:n:o:c:h", longopts, &longIndex)) != -1)
... ... @@ -265,19 +291,19 @@ int main(int argc, char** argv) {
265 291 else {
266 292 fprintf(stderr,"Unrecognised argument: %s\n",optarg);
267 293 printHelp();
268   - return 1;
  294 + return 3;
269 295 }
270 296 }
271 297 if(optind != argc) {
272 298 fprintf(stderr,"Unrecognised argument: %s\n",argv[optind+1]);
273 299 printHelp();
274   - return 1;
  300 + return 3;
275 301 }
276 302  
277 303 if(regionFolder == NULL) {
278 304 fprintf(stderr,"Region path not specified (--regionpath PATH_TO_REGION_FOLDER)\n");
279 305 printHelp();
280   - return 2;
  306 + return 3;
281 307 } else if(!load && (petName == NULL && ownerUUID == NULL)) {
282 308 fprintf(stderr,"OwnerUUID and petName were unspecified (--owner UUID, --name PET_NAME)\n");
283 309 printHelp();
... ... @@ -289,7 +315,7 @@ int main(int argc, char** argv) {
289 315 } else if(save && coords == NULL) {
290 316 fprintf(stderr,"Coordinates were not specified\n");
291 317 printHelp();
292   - return 4;
  318 + return 3;
293 319 }
294 320  
295 321 if(!load) {
... ... @@ -298,7 +324,7 @@ int main(int argc, char** argv) {
298 324  
299 325 if((dirp = opendir(regionFolder)) == NULL) {
300 326 fprintf(stderr,"Unable to open region folder '%s'\n",regionFolder);
301   - return 1;
  327 + return 2;
302 328 }
303 329  
304 330 do {
... ... @@ -326,16 +352,22 @@ int main(int argc, char** argv) {
326 352 (chunk.z + 1) * BLOCKS_PER_CHUNK
327 353 );
328 354 ssize_t chunkLen = loadChunk(regionFolder, chunk, &chunkData);
329   - if(chunkLen < 0) {
330   - fprintf(stderr, "Unable to load chunk\n");
331   - return 5;
  355 + if(chunkLen == CHUNK_NOT_PRESENT) {
  356 + continue;
  357 + } else if(chunkLen < 0) {
  358 + fprintf(stderr, "Unable to load chunk: code %d\n",(int)chunkLen);
  359 + return 2;
332 360 } else if(chunkLen != 0) {
333 361 Tag t;
334   - unsigned int pos = parseTag(chunkData,&t);
  362 + ssize_t pos = parseTag(chunkData,&t);
  363 + if(pos < 0) {
  364 + fprintf(stderr, "Error parsing chunk root tag: code %d\n",(int)pos);
  365 + return 2;
  366 + }
335 367 if(pos != chunkLen) {
336 368 fprintf(stderr, "Didn't reach end of NBT file\n");
337 369 free(chunkData);
338   - return 5;
  370 + return 2;
339 371 }
340 372  
341 373 Tag* entities;
... ... @@ -343,7 +375,7 @@ int main(int argc, char** argv) {
343 375 fprintf(stderr, "Unable to find Entities tag\n");
344 376 free(chunkData);
345 377 destroyTag(&t);
346   - return 6;
  378 + return 2;
347 379 }
348 380 Tag* pet;
349 381 if(searchForPet(*entities,petName,ownerUUID,&pet) == 0) {
... ... @@ -354,7 +386,7 @@ int main(int argc, char** argv) {
354 386 fprintf(stderr, "Unable to save pet to file: %s\n",file);
355 387 free(chunkData);
356 388 closedir(dirp);
357   - return 8;
  389 + return 2;
358 390 }
359 391 }
360 392 destroyTag(&t);
... ... @@ -376,55 +408,64 @@ int main(int argc, char** argv) {
376 408 Coords location;
377 409 if(sscanf(coords,"%d,%d,%d",&location.x,&location.y,&location.z) != 3) {
378 410 fprintf(stderr, "Unable to parse coordinates, please specify coordinates correctly (--coords X,Y,Z)\n");
379   - return 5;
  411 + return 3;
380 412 }
381 413  
382 414 void *chunkData;
383 415 ChunkID chunk = translateCoordsToChunk(location.x, location.y, location.z);
384 416 ssize_t chunkLen = loadChunk(regionFolder, chunk, &chunkData);
385   - if(chunkLen <= 0) {
386   - fprintf(stderr, "Unable to load chunk\n");
387   - return 5;
388   - }
389   -
390   - Tag t;
391   - unsigned int pos = parseTag(chunkData,&t);
392   - if(pos != chunkLen) {
393   - fprintf(stderr, "Didn't reach end of NBT file\n");
394   - free(chunkData);
395   - return 5;
  417 + if(chunkLen == CHUNK_NOT_PRESENT) {
  418 + fprintf(stderr, "Tried to spawn pet in a chunk that has not been generated!\n");
  419 + return 2;
  420 + } else if(chunkLen < 0) {
  421 + fprintf(stderr, "Unable to load chunk: code %d\n",(int)chunkLen);
  422 + return 2;
396 423 }
  424 + if(chunkLen != 0) {
  425 + Tag t;
  426 + ssize_t pos = parseTag(chunkData,&t);
  427 + if(pos < 0) {
  428 + fprintf(stderr, "Error parsing chunk root tag: code %d\n",(int)pos);
  429 + return 2;
  430 + }
  431 + if(pos != chunkLen) {
  432 + fprintf(stderr, "Didn't reach end of NBT file\n");
  433 + free(chunkData);
  434 + return 2;
  435 + }
397 436  
398   - Tag* entities;
399   - if(getEntitiesTag((TagCompound*)t.payload,&entities)) {
400   - fprintf(stderr, "Unable to find Entities tag\n");
401   - free(chunkData);
402   - destroyTag(&t);
403   - return 6;
404   - }
405   - Tag pet;
406   - if(loadPetFromFile(&pet,file)) {
407   - fprintf(stderr, "Unable to load pet from file: %s\n",file);
408   - free(chunkData);
409   - destroyTag(&t);
410   - return 9;
411   - }
412   - chunkLen = insertPetIntoChunk(&chunkData,t,entities,pet,location.x,location.y,location.z);
413   - if(chunkLen <= 0) {
414   - fprintf(stderr, "Unable to insert pet into chunk\n");
415   - free(chunkData);
  437 + Tag* entities;
  438 + if(getEntitiesTag((TagCompound*)t.payload,&entities)) {
  439 + fprintf(stderr, "Unable to find Entities tag\n");
  440 + free(chunkData);
  441 + destroyTag(&t);
  442 + return 2;
  443 + }
  444 + Tag pet;
  445 + if(loadPetFromFile(&pet,file)) {
  446 + fprintf(stderr, "Unable to load pet from file: %s\n",file);
  447 + free(chunkData);
  448 + destroyTag(&t);
  449 + return 2;
  450 + }
  451 + chunkLen = insertPetIntoChunk(&chunkData,t,entities,pet,location.x,location.y,location.z);
  452 + if(chunkLen <= 0) {
  453 + fprintf(stderr, "Unable to insert pet into chunk\n");
  454 + free(chunkData);
  455 + destroyTag(&t);
  456 + return 2;
  457 + }
  458 + destroyTag(&pet);
  459 + int res = overwriteChunk(regionFolder, chunk, chunkData, chunkLen);
  460 + if(res) {
  461 + fprintf(stderr, "Unable to write new chunk: code %d\n",res);
  462 + free(chunkData);
  463 + destroyTag(&t);
  464 + return 2;
  465 + }
416 466 destroyTag(&t);
417   - return 10;
418   - }
419   - destroyTag(&pet);
420   - if(overwriteChunk(regionFolder, chunk, chunkData, chunkLen)) {
421   - fprintf(stderr, "Unable to write new chunk\n");
422 467 free(chunkData);
423   - destroyTag(&t);
424   - return 11;
425 468 }
426   - destroyTag(&t);
427   - free(chunkData);
428 469 }
429 470 return 0;
430 471 }
431 472 \ No newline at end of file
... ...