diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | create.c | 5 | ||||
-rw-r--r-- | deploy.c | 5 | ||||
-rw-r--r-- | error.h | 31 | ||||
-rw-r--r-- | otap.h | 6 | ||||
-rw-r--r-- | otap_apply.c | 181 | ||||
-rw-r--r-- | otap_create.c | 225 |
7 files changed, 270 insertions, 185 deletions
@@ -1,2 +1,4 @@ otap_create otap_deploy +*.o +*.log @@ -41,10 +41,11 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - if(!otap_create(fp, tstat[0], tstat[1])) { + int err; + if((err = otap_create(fp, tstat[0], tstat[1])) != 0) { fclose(fp); remove("patch.otap"); - fprintf(stderr, "Error: Failed to create otap.\n"); + fprintf(stderr, "Error: Failed to create otap (err=%d).\n", err); return EXIT_FAILURE; } @@ -34,9 +34,10 @@ int main(int argc, char** argv) { return EXIT_FAILURE; }*/ - if(!otap_apply(patch)) { + int err; + if((err = otap_apply(patch)) != 0) { fclose(patch); - fprintf(stderr, "Error: Error applying patch stream.\n"); + fprintf(stderr, "Error: Error applying patch stream (err=%d).\n", err); return EXIT_FAILURE; } @@ -0,0 +1,31 @@ +#ifndef __otap_error_h__ +#define __otap_error_h__ + +typedef enum { + otap_error_success = 0, + otap_error_failure = -1, + otap_error_out_of_memory = -2, + otap_error_null_pointer = -3, + otap_error_invalid_parameter = -4, + otap_error_unable_to_read_stream = -5, + otap_error_unable_to_write_stream = -6, + otap_error_unable_to_create_dir = -7, + otap_error_unable_to_change_dir = -8, + otap_error_unable_to_open_file_for_reading = -9, + otap_error_unable_to_open_file_for_writing = -10, + otap_error_file_already_exists = -11, + otap_error_unable_to_remove_file = -12, + otap_error_unable_to_seek_through_stream = -13, + otap_error_feature_not_implemented = -14, + otap_error_file_does_not_exist = -15, + otap_error_unable_to_detect_stream_position = -16, + otap_error_unable_to_stat_file = -17, +} otap_error_e; + +#ifdef NDEBUG +#define otap_error(e) return e +#else +#define otap_error(e) { if(e != 0) fprintf(stderr, "OTAP error '%s' in function '%s' at line %d of file '%s'.\n", #e, __FUNCTION__, __LINE__, __FILE__); return e; } +#endif + +#endif @@ -1,8 +1,8 @@ #ifndef __otap_h__ #define __otap_h__ -#include <stdbool.h> #include <stdio.h> +#include <stdint.h> #include "stat.h" @@ -39,7 +39,7 @@ extern const char* otap_ident; -extern bool otap_apply(FILE* stream); -extern bool otap_create(FILE* stream, otap_stat_t* a, otap_stat_t* b); +extern int otap_apply(FILE* stream); +extern int otap_create(FILE* stream, otap_stat_t* a, otap_stat_t* b); #endif diff --git a/otap_apply.c b/otap_apply.c index cbcf296..ada0519 100644 --- a/otap_apply.c +++ b/otap_apply.c @@ -1,5 +1,8 @@ #include "otap.h" +//#define NDEBUG +#include "error.h" + #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -16,112 +19,118 @@ -static bool _otap_apply_identify(FILE* stream) { +static int _otap_apply_identify(FILE* stream) { uint8_t cmd; if(fread(&cmd, 1, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); if(cmd != otap_cmd_identify) - return false; + otap_error(otap_error_invalid_parameter); uint16_t nlen; if(fread(&nlen, 2, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); if(strlen(otap_ident) != nlen) - return false; + otap_error(otap_error_invalid_parameter); char nstr[nlen]; if(fread(nstr, 1, nlen, stream) != nlen) - return false; - return (strncmp(nstr, otap_ident, nlen) == 0); + otap_error(otap_error_unable_to_read_stream); + if(strncmp(nstr, otap_ident, nlen) != 0) + otap_error(otap_error_invalid_parameter); + return 0; } -static bool _otap_apply_cmd_dir_create(FILE* stream) { +static int _otap_apply_cmd_dir_create(FILE* stream) { uint16_t dlen; if(fread(&dlen, 2, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); char dname[dlen + 1]; if(fread(dname, 1, dlen, stream) != dlen) - return false; + otap_error(otap_error_unable_to_read_stream); dname[dlen] = '\0'; printf("cmd_dir_create %s\n", dname); if(strchr(dname, '/') != NULL) - return false; + otap_error(otap_error_invalid_parameter); // TODO - Apply metadata. uint32_t mtime; if(fread(&mtime, 4, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); - return (mkdir(dname, (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) == 0); + if(mkdir(dname, (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) != 0) + otap_error(otap_error_unable_to_create_dir); + return 0; } -static bool _otap_apply_cmd_dir_enter(FILE* stream, uintptr_t* depth) { +static int _otap_apply_cmd_dir_enter(FILE* stream, uintptr_t* depth) { uint16_t dlen; if(fread(&dlen, 2, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); char dname[dlen + 1]; if(fread(dname, 1, dlen, stream) != dlen) - return false; + otap_error(otap_error_unable_to_read_stream); dname[dlen] = '\0'; printf("cmd_dir_enter %s\n", dname); if((strchr(dname, '/') != NULL) || (strcmp(dname, "..") == 0)) - return false; + otap_error(otap_error_unable_to_change_dir); if(depth != NULL) (*depth)++; - return (chdir(dname) == 0); + if(chdir(dname) != 0) + otap_error(otap_error_unable_to_change_dir); + return 0; } -static bool _otap_apply_cmd_dir_leave(FILE* stream, uintptr_t* depth) { +static int _otap_apply_cmd_dir_leave(FILE* stream, uintptr_t* depth) { uint8_t count; if(fread(&count, 1, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); uintptr_t rcount = count + 1; printf("cmd_dir_leave %"PRIuPTR"\n", rcount); if((depth != NULL) && (*depth < rcount)) - return false; + otap_error(otap_error_invalid_parameter); uintptr_t i; for(i = 0; i < rcount; i++) { if(chdir("..") != 0) - return false; + otap_error(otap_error_unable_to_change_dir); } if(depth != NULL) *depth -= rcount; - return true; + return 0; } -static bool _otap_apply_cmd_file_create(FILE* stream) { +static int _otap_apply_cmd_file_create(FILE* stream) { uint16_t flen; if(fread(&flen, 2, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); char fname[flen + 1]; if(fread(fname, 1, flen, stream) != flen) - return false; + otap_error(otap_error_unable_to_read_stream); fname[flen] = '\0'; if((strchr(fname, '/') != NULL) || (strcmp(fname, "..") == 0)) - return false; + otap_error(otap_error_invalid_parameter); uint32_t mtime; if(fread(&mtime, 4, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); uint32_t fsize; if(fread(&fsize, 4, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); printf("cmd_file_create %s:%"PRIuPTR"\n", fname, fsize); FILE* fp = fopen(fname, "rb"); if(fp != NULL) { fclose(fp); - return false; + otap_error(otap_error_file_already_exists); } fp = fopen(fname, "wb"); if(fp == NULL) - return false; + otap_error(otap_error_unable_to_open_file_for_writing); uintptr_t block = 256; uint8_t fbuff[block]; @@ -129,9 +138,9 @@ static bool _otap_apply_cmd_file_create(FILE* stream) { if(fsize < block) block = fsize; if(fread(fbuff, 1, block, stream) != block) - return false; + otap_error(otap_error_unable_to_read_stream); if(fwrite(fbuff, 1, block, fp) != block) - return false; + otap_error(otap_error_unable_to_write_stream); } fclose(fp); @@ -139,43 +148,43 @@ static bool _otap_apply_cmd_file_create(FILE* stream) { struct utimbuf timebuff = { time(NULL), mtime }; utime(fname, &timebuff); // Don't care if it succeeds right now. - return true; + return 0; } -static bool _otap_apply_cmd_file_delta(FILE* stream) { +static int _otap_apply_cmd_file_delta(FILE* stream) { uint16_t flen; if(fread(&flen, 2, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); char fname[flen + 1]; if(fread(fname, 1, flen, stream) != flen) - return false; + otap_error(otap_error_unable_to_read_stream); fname[flen] = '\0'; printf("cmd_file_delta %s\n", fname); if((strchr(fname, '/') != NULL) || (strcmp(fname, "..") == 0)) - return false; + otap_error(otap_error_invalid_parameter); uint32_t mtime; if(fread(&mtime, 4, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); FILE* op = fopen(fname, "rb"); if(op == NULL) - return false; + otap_error(otap_error_unable_to_open_file_for_reading); if(remove(fname) != 0) { fclose(op); - return false; + otap_error(otap_error_unable_to_remove_file); } FILE* np = fopen(fname, "wb"); if(np == NULL) { fclose(op); - return false; + otap_error(otap_error_unable_to_open_file_for_writing); } uint32_t dstart, dend; if(fread(&dstart, 4, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); if(fread(&dend, 4, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); uintptr_t block; uint8_t fbuff[256]; @@ -183,34 +192,34 @@ static bool _otap_apply_cmd_file_delta(FILE* stream) { if(dstart < block) block = dstart; if(fread(fbuff, 1, block, op) != block) - return false; + otap_error(otap_error_unable_to_read_stream); if(fwrite(fbuff, 1, block, np) != block) - return false; + otap_error(otap_error_unable_to_write_stream); } uint32_t fsize; if(fread(&fsize, 4, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); for(block = 256; fsize != 0; fsize -= block) { if(fsize < block) block = fsize; if(fread(fbuff, 1, block, stream) != block) - return false; + otap_error(otap_error_unable_to_read_stream); if(fwrite(fbuff, 1, block, np) != block) - return false; + otap_error(otap_error_unable_to_write_stream); } if(fseek(op, dend, SEEK_SET) != 0) { fclose(np); fclose(op); - return false; + otap_error(otap_error_unable_to_seek_through_stream); } for(block = 256; block != 0;) { block = fread(fbuff, 1, block, op); if(fwrite(fbuff, 1, block, np) != block) - return false; + otap_error(otap_error_unable_to_write_stream); } fclose(np); @@ -220,107 +229,113 @@ static bool _otap_apply_cmd_file_delta(FILE* stream) { struct utimbuf timebuff = { time(NULL), mtime }; utime(fname, &timebuff); // Don't care if it succeeds right now. - return true; + return 0; } -static bool __otap_apply_cmd_entity_delete(const char* name) { +static int __otap_apply_cmd_entity_delete(const char* name) { DIR* dp = opendir(name); if(dp == NULL) { FILE* fp = fopen(name, "rb"); if(fp != NULL) { fclose(fp); - return (remove(name) == 0); + if(remove(name) != 0) + otap_error(otap_error_unable_to_remove_file); + return 0; } - return false; + otap_error(otap_error_file_does_not_exist); } if(chdir(name) != 0) { closedir(dp); - return false; + otap_error(otap_error_unable_to_change_dir); } struct dirent* entry; while((entry = readdir(dp)) != NULL) { if((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) continue; - if(!__otap_apply_cmd_entity_delete(entry->d_name)) { + int err; + if((err = __otap_apply_cmd_entity_delete(entry->d_name)) != 0) { closedir(dp); chdir(".."); - return false; + return err; } } closedir(dp); chdir(".."); - return (remove(name) == 0); + if(remove(name) != 0) + otap_error(otap_error_unable_to_remove_file); + return 0; } -static bool _otap_apply_cmd_entity_delete(FILE* stream) { +static int _otap_apply_cmd_entity_delete(FILE* stream) { uint16_t elen; if(fread(&elen, 2, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); char ename[elen + 1]; if(fread(ename, 1, elen, stream) != elen) - return false; + otap_error(otap_error_unable_to_read_stream); ename[elen] = '\0'; printf("cmd_entity_delete %s\n", ename); if((strchr(ename, '/') != NULL) || (strcmp(ename, "..") == 0)) - return false; + otap_error(otap_error_invalid_parameter); return __otap_apply_cmd_entity_delete(ename); } -bool otap_apply(FILE* stream) { +int otap_apply(FILE* stream) { if(stream == NULL) - return false; + otap_error(otap_error_null_pointer); - if(!_otap_apply_identify(stream)) - return false; + int err; + if((err = _otap_apply_identify(stream)) != 0) + return err; uintptr_t depth = 0; bool flush = false; while(!flush) { uint8_t cmd; if(fread(&cmd, 1, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_read_stream); switch(cmd) { case otap_cmd_dir_create: - if(!_otap_apply_cmd_dir_create(stream)) - return false; + if((err = _otap_apply_cmd_dir_create(stream)) != 0) + return err; break; case otap_cmd_dir_enter: - if(!_otap_apply_cmd_dir_enter(stream, &depth)) - return false; + if((err = _otap_apply_cmd_dir_enter(stream, &depth)) != 0) + return err; break; case otap_cmd_dir_leave: - if(!_otap_apply_cmd_dir_leave(stream, &depth)) - return false; + if((err = _otap_apply_cmd_dir_leave(stream, &depth)) != 0) + return err; break; case otap_cmd_file_create: - if(!_otap_apply_cmd_file_create(stream)) - return false; + if((err = _otap_apply_cmd_file_create(stream)) != 0) + return err; break; case otap_cmd_file_delta: - if(!_otap_apply_cmd_file_delta(stream)) - return false; + if((err = _otap_apply_cmd_file_delta(stream)) != 0) + return err; break; case otap_cmd_entity_move: case otap_cmd_entity_copy: - return false; // TODO - Implement. + otap_error(otap_error_feature_not_implemented); // TODO - Implement. case otap_cmd_entity_delete: - if(!_otap_apply_cmd_entity_delete(stream)) - return false; + if((err = _otap_apply_cmd_entity_delete(stream)) != 0) + return err; break; case otap_cmd_update: flush = true; break; default: fprintf(stderr, "Error: Invalid command 0x%02"PRIx8".\n", cmd); - return false; + otap_error(otap_error_invalid_parameter); } } - return true; + return 0; } diff --git a/otap_create.c b/otap_create.c index de8084b..09e4202 100644 --- a/otap_create.c +++ b/otap_create.c @@ -1,4 +1,5 @@ #include "otap.h" +#include "error.h" #include <stdlib.h> #include <stdio.h> @@ -12,45 +13,58 @@ -static bool _otap_create_fwrite_cmd(FILE* stream, uint8_t cmd) { - return (fwrite(&cmd, 1, 1, stream) == 1); +static int _otap_create_fwrite_cmd(FILE* stream, uint8_t cmd) { + if(fwrite(&cmd, 1, 1, stream) != 1) + otap_error(otap_error_unable_to_write_stream); + return 0; } -static bool _otap_create_fwrite_string(FILE* stream, const char* string) { +static int _otap_create_fwrite_string(FILE* stream, const char* string) { uint16_t slen = strlen(string); - if(fwrite(&slen, 2, 1, stream) != 1) - return false; - return (fwrite(string, 1, slen, stream) == slen); + if((fwrite(&slen, 2, 1, stream) != 1) + || (fwrite(string, 1, slen, stream) != slen)) + otap_error(otap_error_unable_to_write_stream); + return 0; } -static bool _otap_create_fwrite_mtime(FILE* stream, uint32_t mtime) { - return (fwrite(&mtime, 4, 1, stream) == 1); +static int _otap_create_fwrite_mtime(FILE* stream, uint32_t mtime) { + if(fwrite(&mtime, 4, 1, stream) != 1) + otap_error(otap_error_unable_to_write_stream); + return 0; } -static bool _otap_create_cmd_ident(FILE* stream) { - return (_otap_create_fwrite_cmd(stream, otap_cmd_identify) - && _otap_create_fwrite_string(stream, otap_ident)); +static int _otap_create_cmd_ident(FILE* stream) { + int err; + + if((err = _otap_create_fwrite_cmd(stream, otap_cmd_identify)) != 0) + return err; + if((err = _otap_create_fwrite_string(stream, otap_ident)) != 0) + return err; + return 0; } -static bool _otap_create_cmd_update(FILE* stream) { +static int _otap_create_cmd_update(FILE* stream) { return _otap_create_fwrite_cmd(stream, otap_cmd_update); } -static bool _otap_create_cmd_file_create(FILE* stream, otap_stat_t* f) { - if(!_otap_create_fwrite_cmd(stream, otap_cmd_file_create) - || !_otap_create_fwrite_string(stream, f->name) - || !_otap_create_fwrite_mtime(stream, f->mtime)) - return false; +static int _otap_create_cmd_file_create(FILE* stream, otap_stat_t* f) { + int err; + if((err = _otap_create_fwrite_cmd(stream, otap_cmd_file_create)) != 0) + return err; + if((err = _otap_create_fwrite_string(stream, f->name)) != 0) + return err; + if((err = _otap_create_fwrite_mtime(stream, f->mtime)) != 0) + return err; uint32_t size = f->size; if(fwrite(&size, 4, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_write_stream); FILE* fp = otap_stat_fopen(f, "rb"); if(fp == NULL) - return false; + otap_error(otap_error_unable_to_open_file_for_reading); uint8_t buff[256]; uintptr_t b = 256; @@ -58,21 +72,21 @@ static bool _otap_create_cmd_file_create(FILE* stream, otap_stat_t* f) { b = fread(buff, 1, b, fp); if(fwrite(buff, 1, b, stream) != b) { fclose(fp); - return false; + otap_error(otap_error_unable_to_write_stream); } } fclose(fp); - return true; + return 0; } -static bool _otap_create_cmd_file_delta(FILE* stream, otap_stat_t* a, otap_stat_t* b) { +static int _otap_create_cmd_file_delta(FILE* stream, otap_stat_t* a, otap_stat_t* b) { FILE* fpa = otap_stat_fopen(a, "rb"); if(fpa == NULL) - return false; + otap_error(otap_error_unable_to_open_file_for_reading); FILE* fpb = otap_stat_fopen(b, "rb"); if(fpb == NULL) { fclose(fpa); - return false; + otap_error(otap_error_unable_to_open_file_for_reading); } // Calculate start. @@ -100,7 +114,7 @@ static bool _otap_create_cmd_file_delta(FILE* stream, otap_stat_t* a, otap_stat_ if((fseek(fpa, 0, SEEK_END) != 0) || (fseek(fpb, 0, SEEK_END) != 0)) { fclose(fpa); fclose(fpb); - return false; + otap_error(otap_error_unable_to_seek_through_stream); } // Find length. @@ -109,7 +123,7 @@ static bool _otap_create_cmd_file_delta(FILE* stream, otap_stat_t* a, otap_stat_ if((flena < 0) || (flenb < 0)) { fclose(fpa); fclose(fpb); - return false; + otap_error(otap_error_unable_to_detect_stream_position); } // Find end. @@ -123,13 +137,13 @@ static bool _otap_create_cmd_file_delta(FILE* stream, otap_stat_t* a, otap_stat_ if((fseek(fpa, flena - (o + blks[0]), SEEK_SET) != 0) || (fseek(fpb, flenb - (o + blks[1]), SEEK_SET) != 0)) { fclose(fpa); fclose(fpb); - return false; + otap_error(otap_error_unable_to_seek_through_stream); } if((fread(buff[0], 1, blks[0], fpa) != blks[0]) || (fread(buff[1], 1, blks[1], fpb) != blks[1])) { fclose(fpa); fclose(fpb); - return false; + otap_error(otap_error_unable_to_read_stream); } uintptr_t i, ja, jb; @@ -155,173 +169,194 @@ static bool _otap_create_cmd_file_delta(FILE* stream, otap_stat_t* a, otap_stat_ if((end == start) && (size == 0)) { fclose(fpb); - return true; + return 0; } - if(!_otap_create_fwrite_cmd(stream, otap_cmd_file_delta) - || !_otap_create_fwrite_string(stream, b->name) - || !_otap_create_fwrite_mtime(stream, b->mtime) - || (fwrite(&start, 4, 1, stream) != 1) + int err; + if(((err = _otap_create_fwrite_cmd(stream, otap_cmd_file_delta)) != 0) + || ((err = _otap_create_fwrite_string(stream, b->name)) != 0) + || ((err = _otap_create_fwrite_mtime(stream, b->mtime)) != 0)) { + fclose(fpb); + return err; + } + if((fwrite(&start, 4, 1, stream) != 1) || (fwrite(&end, 4, 1, stream) != 1) - || (fwrite(&size, 4, 1, stream) != 1) - || (fseek(fpb, start, SEEK_SET) != 0)) { + || (fwrite(&size, 4, 1, stream) != 1)) { + fclose(fpb); + otap_error(otap_error_unable_to_write_stream); + } + if(fseek(fpb, start, SEEK_SET) != 0) { fclose(fpb); - return false; + otap_error(otap_error_unable_to_seek_through_stream); } for(o = 0; o < size; o += 256) { uintptr_t csize = ((size - o) > 256 ? 256 : (size - o)); - if((fread(buff[0], 1, csize, fpb) != csize) - || (fwrite(buff[0], 1, csize, stream) != csize)) { + if(fread(buff[0], 1, csize, fpb) != csize) { fclose(fpb); - return false; + otap_error(otap_error_unable_to_read_stream); + } + if(fwrite(buff[0], 1, csize, stream) != csize) { + fclose(fpb); + otap_error(otap_error_unable_to_write_stream); } } fclose(fpb); - return true; + return 0; } -static bool _otap_create_cmd_dir_create(FILE* stream, otap_stat_t* d) { - return (_otap_create_fwrite_cmd(stream, otap_cmd_dir_create) - && _otap_create_fwrite_string(stream, d->name) - && _otap_create_fwrite_mtime(stream, d->mtime)); +static int _otap_create_cmd_dir_create(FILE* stream, otap_stat_t* d) { + int err; + if(((err = _otap_create_fwrite_cmd(stream, otap_cmd_dir_create)) != 0) + || ((err = _otap_create_fwrite_string(stream, d->name)) != 0)) + return err; + return _otap_create_fwrite_mtime(stream, d->mtime); } -static bool _otap_create_cmd_dir_enter(FILE* stream, const char* name) { - return (_otap_create_fwrite_cmd(stream, otap_cmd_dir_enter) - && _otap_create_fwrite_string(stream, name)); +static int _otap_create_cmd_dir_enter(FILE* stream, const char* name) { + int err; + if((err = _otap_create_fwrite_cmd(stream, otap_cmd_dir_enter)) != 0) + return err; + return _otap_create_fwrite_string(stream, name); } -static bool _otap_create_cmd_dir_leave(FILE* stream, uintptr_t count) { +static int _otap_create_cmd_dir_leave(FILE* stream, uintptr_t count) { if(count == 0) - return true; - if(!_otap_create_fwrite_cmd(stream, otap_cmd_dir_leave)) - return false; + return 0; + int err; + if((err = _otap_create_fwrite_cmd(stream, otap_cmd_dir_leave)) != 0) + return err; uint8_t token; if(count > 256) { token = 255; for(; count > 256; count -= 256) { if(fwrite(&token, 1, 1, stream) != 1) - return false; + otap_error(otap_error_unable_to_write_stream); } } token = (count - 1); - return (fwrite(&token, 1, 1, stream) == 1); + if(fwrite(&token, 1, 1, stream) != 1) + otap_error(otap_error_unable_to_write_stream); + return 0; } -static bool _otap_create_cmd_entity_delete(FILE* stream, const char* name) { - return (_otap_create_fwrite_cmd(stream, otap_cmd_entity_delete) - && _otap_create_fwrite_string(stream, name)); +static int _otap_create_cmd_entity_delete(FILE* stream, const char* name) { + int err; + if((err = _otap_create_fwrite_cmd(stream, otap_cmd_entity_delete)) != 0) + return err; + return _otap_create_fwrite_string(stream, name); } -static bool _otap_create_dir(FILE* stream, otap_stat_t* d) { - if((!_otap_create_cmd_dir_create(stream, d)) - || (!_otap_create_cmd_dir_enter(stream, d->name))) - return false; +static int _otap_create_dir(FILE* stream, otap_stat_t* d) { + int err; + if(((err =_otap_create_cmd_dir_create(stream, d)) != 0) + || ((err = _otap_create_cmd_dir_enter(stream, d->name)) != 0)) + return err; uintptr_t i; for(i = 0; i < d->size; i++) { otap_stat_t* f = otap_stat_entry(d, i); if(f == NULL) - return false; - bool ret = false; + otap_error(otap_error_unable_to_stat_file); switch(f->type) { case otap_stat_type_file: - ret = _otap_create_cmd_file_create(stream, f); + err = _otap_create_cmd_file_create(stream, f); break; case otap_stat_type_dir: - ret = _otap_create_dir(stream, f); + err = _otap_create_dir(stream, f); break; default: + otap_stat_free(f); + otap_error(otap_error_feature_not_implemented); break; } otap_stat_free(f); - if(!ret) - return false; + if(err != 0) + return err; } return _otap_create_cmd_dir_leave(stream, 1); } -static bool _otap_create(FILE* stream, otap_stat_t* a, otap_stat_t* b, bool top) { +static int _otap_create(FILE* stream, otap_stat_t* a, otap_stat_t* b, bool top) { if((a == NULL) && (b == NULL)) - return false; + otap_error(otap_error_null_pointer); + int err; if(((b == NULL) || ((a != NULL) && (a->type != b->type))) - && !_otap_create_cmd_entity_delete(stream, a->name)) - return false; + && ((err = _otap_create_cmd_entity_delete(stream, a->name)) != 0)) + return err; if((a == NULL) || ((b != NULL) && (a->type != b->type))) { switch(b->type) { case otap_stat_type_file: - if(_otap_create_cmd_file_create(stream, b)) - return true; - break; + return _otap_create_cmd_file_create(stream, b); case otap_stat_type_dir: - if(_otap_create_dir(stream, b)) - return true; - break; + return _otap_create_dir(stream, b); default: break; } - return false; + otap_error(otap_error_feature_not_implemented); } if(a->type == otap_stat_type_file) return _otap_create_cmd_file_delta(stream, a, b); if(a->type != otap_stat_type_dir) - return false; // TODO - Handle other types of files (incl. symlink); + otap_error(otap_error_feature_not_implemented); // TODO - Handle other types of files (incl. symlink); - if(!top && !_otap_create_cmd_dir_enter(stream, b->name)) - return false; + if(!top && ((err = _otap_create_cmd_dir_enter(stream, b->name)) != 0)) + return err; // Handle changes/additions. uintptr_t i; for(i = 0; i < b->size; i++) { otap_stat_t* _b = otap_stat_entry(b, i); if(_b == NULL) - return false; + otap_error(otap_error_unable_to_stat_file); otap_stat_t* _a = otap_stat_entry_find(a, _b->name); - bool ret = _otap_create(stream, _a, _b, false); + err = _otap_create(stream, _a, _b, false); otap_stat_free(_a); otap_stat_free(_b); - if(!ret) - return false; + if(err != 0) + return err; } // Handle deletions. for(i = 0; i < a->size; i++) { otap_stat_t* _a = otap_stat_entry(a, i); if(_a == NULL) - return false; + otap_error(otap_error_unable_to_stat_file); otap_stat_t* _b = otap_stat_entry_find(b, _a->name); - bool ret = ((_b != NULL) || _otap_create_cmd_entity_delete(stream, _a->name)); + err = (_b != NULL ? 0 : _otap_create_cmd_entity_delete(stream, _a->name)); otap_stat_free(_b); otap_stat_free(_a); - if(!ret) - return false; + if(err != 0) + return err; } - return (top || _otap_create_cmd_dir_leave(stream, 1)); + if(!top && ((err = _otap_create_cmd_dir_leave(stream, 1)) != 0)) + return err; + return 0; } -bool otap_create(FILE* stream, otap_stat_t* a, otap_stat_t* b) { +int otap_create(FILE* stream, otap_stat_t* a, otap_stat_t* b) { if((stream == NULL) || (a == NULL) || (b == NULL)) - return false; + otap_error(otap_error_null_pointer); - if(!_otap_create_cmd_ident(stream)) - return false; + int err; + if((err = _otap_create_cmd_ident(stream)) != 0) + return err; - if(!_otap_create(stream, a, b, true)) - return false; + if((err = _otap_create(stream, a, b, true)) != 0) + return err; return _otap_create_cmd_update(stream); } |