diff options
Diffstat (limited to 'tbdiff')
-rw-r--r-- | tbdiff/tbdiff-apply.c | 267 | ||||
-rw-r--r-- | tbdiff/tbdiff-common.h | 87 | ||||
-rw-r--r-- | tbdiff/tbdiff-create.c | 289 | ||||
-rw-r--r-- | tbdiff/tbdiff-io.c | 202 | ||||
-rw-r--r-- | tbdiff/tbdiff-io.h | 48 | ||||
-rw-r--r-- | tbdiff/tbdiff-private.h | 4 | ||||
-rw-r--r-- | tbdiff/tbdiff-stat.c | 6 | ||||
-rw-r--r-- | tbdiff/tbdiff-stat.h | 18 | ||||
-rw-r--r-- | tbdiff/tbdiff-xattrs.c | 11 |
9 files changed, 491 insertions, 441 deletions
diff --git a/tbdiff/tbdiff-apply.c b/tbdiff/tbdiff-apply.c index e281d73..666d876 100644 --- a/tbdiff/tbdiff-apply.c +++ b/tbdiff/tbdiff-apply.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Codethink Ltd. + * Copyright (C) 2011-2014 Codethink Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as @@ -29,7 +29,13 @@ #include <unistd.h> #include <utime.h> +#include "config.h" + +#if HAVE_ATTR_XATTR_H #include <attr/xattr.h> +#else +#include <sys/xattr.h> +#endif #include <tbdiff/tbdiff-common.h> #include <tbdiff/tbdiff-io.h> @@ -37,10 +43,10 @@ #include <tbdiff/tbdiff-xattrs.h> char* -tbd_apply_fread_string(FILE *stream) +tbd_apply_read_string(FILE *stream) { uint16_t dlen; - if(tbd_read_uint16_t(&dlen, stream) != 1) + if(tbd_read_uint16(&dlen, stream) != 1) return NULL; char dname[dlen + 1]; if(fread(dname, 1, dlen, stream) != dlen) @@ -60,7 +66,8 @@ tbd_apply_fread_string(FILE *stream) * - or realloc doesn't free old memory (though this will be a memory leak) * - or your allocator does nothing when asked to free non-allocated memory */ -int tbd_apply_fread_block(FILE *stream, void **data, size_t *size) +int +tbd_apply_read_block(FILE *stream, void **data, size_t *size) { { size_t _size; @@ -86,13 +93,13 @@ int tbd_apply_fread_block(FILE *stream, void **data, size_t *size) static int tbd_apply_identify(FILE *stream) { - uint8_t cmd; - if(fread(&cmd, 1, 1, stream) != 1) + tbd_cmd_t cmd; + if(fread(&cmd, sizeof(tbd_cmd_t), 1, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); if(cmd != TBD_CMD_IDENTIFY) return TBD_ERROR(TBD_ERROR_INVALID_PARAMETER); uint16_t nlen; - if(tbd_read_uint16_t(&nlen, stream) != 1) + if(tbd_read_uint16(&nlen, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); if(strlen(TB_DIFF_PROTOCOL_ID) != nlen) return TBD_ERROR(TBD_ERROR_INVALID_PARAMETER); @@ -108,40 +115,41 @@ static int tbd_apply_cmd_dir_create(FILE *stream) { uint16_t dlen; - if(tbd_read_uint16_t(&dlen, stream) != 1) + if(tbd_read_uint16(&dlen, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); char dname[dlen + 1]; if(fread(dname, 1, dlen, stream) != dlen) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); dname[dlen] = '\0'; - fprintf(stderr, "cmd_dir_create %s\n", dname); + TBD_DEBUGF("cmd_dir_create %s\n", dname); if(strchr(dname, '/') != NULL) return TBD_ERROR(TBD_ERROR_INVALID_PARAMETER); time_t mtime; - if(tbd_read_time_t(&mtime, stream) != 1) + if(tbd_read_time(&mtime, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); uid_t uid; - if(tbd_read_uid_t(&uid, stream) != 1) + if(tbd_read_uid(&uid, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); gid_t gid; - if(tbd_read_gid_t(&gid, stream) != 1) + if(tbd_read_gid(&gid, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); mode_t mode; - if(tbd_read_mode_t(&mode, stream) != 1) + if(tbd_read_mode(&mode, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); if(mkdir(dname, (mode_t)mode) != 0) return TBD_ERROR(TBD_ERROR_UNABLE_TO_CREATE_DIR); - // Apply metadata. + /* Apply metadata. */ struct utimbuf timebuff = { time(NULL), mtime }; - utime(dname, &timebuff); // Don't care if it succeeds right now. + utime(dname, &timebuff); /* Don't care if it succeeds right now. */ - chown(dname, (uid_t)uid, (gid_t)gid); + if (chown(dname, (uid_t)uid, (gid_t)gid) < 0) + TBD_WARN("Failed to change ownership of directory"); chmod (dname, mode); return 0; @@ -152,13 +160,13 @@ tbd_apply_cmd_dir_enter(FILE *stream, uintptr_t *depth) { uint16_t dlen; - if(tbd_read_uint16_t(&dlen, stream) != 1) + if(tbd_read_uint16(&dlen, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); char dname[dlen + 1]; if(fread(dname, 1, dlen, stream) != dlen) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); dname[dlen] = '\0'; - fprintf(stderr, "cmd_dir_enter %s\n", dname); + TBD_DEBUGF("cmd_dir_enter %s\n", dname); if((strchr(dname, '/') != NULL) || (strcmp(dname, "..") == 0)) return TBD_ERROR(TBD_ERROR_UNABLE_TO_CHANGE_DIR); if(depth != NULL) @@ -176,12 +184,12 @@ tbd_apply_cmd_dir_leave(FILE *stream, int err = TBD_ERROR_SUCCESS; struct utimbuf time; - if (tbd_read_time_t(&(time.modtime), stream) != 1) { + if (tbd_read_time(&(time.modtime), stream) != 1) { return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); } time.actime = time.modtime;/* not sure what the best atime to use is */ - fprintf(stderr, "cmd_dir_leave\n"); + TBD_DEBUG("cmd_dir_leave\n"); /* test for leaving shallowest depth */ if ((depth != NULL) && (*depth < 1)) { @@ -207,7 +215,7 @@ static int tbd_apply_cmd_file_create(FILE *stream) { uint16_t flen; - if(tbd_read_uint16_t(&flen, stream) != 1) + if(tbd_read_uint16(&flen, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); char fname[flen + 1]; if(fread(fname, 1, flen, stream) != flen) @@ -222,14 +230,14 @@ tbd_apply_cmd_file_create(FILE *stream) gid_t gid; uint32_t fsize; - if(tbd_read_time_t(&mtime, stream) != 1 || - tbd_read_uint32_t(&mode, stream) != 1 || - tbd_read_uid_t(&uid, stream) != 1 || - tbd_read_gid_t(&gid, stream) != 1 || - tbd_read_uint32_t(&fsize, stream) != 1) + if(tbd_read_time (&mtime, stream) != 1 || + tbd_read_uint32(&mode , stream) != 1 || + tbd_read_uid (&uid , stream) != 1 || + tbd_read_gid (&gid , stream) != 1 || + tbd_read_uint32(&fsize, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); - fprintf(stderr, "cmd_file_create %s:%"PRId32"\n", fname, fsize); + TBD_DEBUGF("cmd_file_create %s:%"PRId32"\n", fname, fsize); FILE *fp = fopen(fname, "rb"); if(fp != NULL) { @@ -246,20 +254,25 @@ tbd_apply_cmd_file_create(FILE *stream) for(; fsize != 0; fsize -= block) { if(fsize < block) block = fsize; - if(fread(fbuff, 1, block, stream) != block) + if(fread(fbuff, 1, block, stream) != block) { + fclose(fp); return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); - if(fwrite(fbuff, 1, block, fp) != block) + } + if(fwrite(fbuff, 1, block, fp) != block) { + fclose(fp); return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); + } } fclose(fp); - // Apply metadata. + /* Apply metadata. */ struct utimbuf timebuff = { time(NULL), mtime }; - // Don't care if it succeeds right now. + /* Don't care if it succeeds right now. */ utime(fname, &timebuff); /* Chown ALWAYS have to be done before chmod */ - chown(fname, (uid_t)uid, (gid_t)gid); + if (chown(fname, (uid_t)uid, (gid_t)gid) < 0) + TBD_WARN("Failed to change ownership of file"); chmod(fname, mode); return 0; @@ -274,25 +287,27 @@ tbd_apply_cmd_file_delta(FILE *stream) gid_t gid; mode_t mode; uint16_t flen; - if(tbd_read_uint16_t(&flen, stream) != 1) + int error; + + if(tbd_read_uint16(&flen, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); char fname[flen + 1]; if(fread(fname, 1, flen, stream) != flen) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); fname[flen] = '\0'; - fprintf(stderr, "cmd_file_delta %s\n", fname); + TBD_DEBUGF("cmd_file_delta %s\n", fname); if((strchr(fname, '/') != NULL) || (strcmp(fname, "..") == 0)) return TBD_ERROR(TBD_ERROR_INVALID_PARAMETER); /* Reading metadata */ - if(tbd_read_uint16_t(&mdata_mask, stream) != 1 || - tbd_read_time_t(&mtime, stream) != 1 || - tbd_read_uid_t(&uid, stream) != 1 || - tbd_read_gid_t(&gid, stream) != 1 || - tbd_read_uint32_t(&mode, stream) != 1) + if(tbd_read_uint16(&mdata_mask, stream) != 1 || + tbd_read_time (&mtime , stream) != 1 || + tbd_read_uid (&uid , stream) != 1 || + tbd_read_gid (&gid , stream) != 1 || + tbd_read_uint32(&mode , stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); FILE *op = fopen(fname, "rb"); @@ -309,51 +324,66 @@ tbd_apply_cmd_file_delta(FILE *stream) } uint32_t dstart, dend; - if(tbd_read_uint32_t(&dstart, stream) != 1) - return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); - if(tbd_read_uint32_t(&dend, stream) != 1) - return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); + if(tbd_read_uint32(&dstart, stream) != 1) { + error = TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); + goto tbd_apply_cmd_file_delta_error; + } + if(tbd_read_uint32(&dend, stream) != 1) { + error = TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); + goto tbd_apply_cmd_file_delta_error; + } uintptr_t block; uint8_t fbuff[256]; for(block = 256; dstart != 0; dstart -= block) { if(dstart < block) block = dstart; - if(fread(fbuff, 1, block, op) != block) - return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); - if(fwrite(fbuff, 1, block, np) != block) - return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); + if(fread(fbuff, 1, block, op) != block) { + error = TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); + goto tbd_apply_cmd_file_delta_error; + } + if(fwrite(fbuff, 1, block, np) != block) { + error = TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); + goto tbd_apply_cmd_file_delta_error; + } } uint32_t fsize; - if(tbd_read_uint32_t(&fsize, stream) != 1) - return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); + if(tbd_read_uint32(&fsize, stream) != 1) { + error = TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); + goto tbd_apply_cmd_file_delta_error; + } for(block = 256; fsize != 0; fsize -= block) { if(fsize < block) block = fsize; - if(fread(fbuff, 1, block, stream) != block) - return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); - if(fwrite(fbuff, 1, block, np) != block) - return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); + if(fread(fbuff, 1, block, stream) != block) { + error = TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); + goto tbd_apply_cmd_file_delta_error; + } + if(fwrite(fbuff, 1, block, np) != block) { + error = TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); + goto tbd_apply_cmd_file_delta_error; + } } if(fseek(op, dend, SEEK_SET) != 0) { - fclose(np); - fclose(op); - return TBD_ERROR(TBD_ERROR_UNABLE_TO_SEEK_THROUGH_STREAM); + error = TBD_ERROR(TBD_ERROR_UNABLE_TO_SEEK_THROUGH_STREAM); + goto tbd_apply_cmd_file_delta_error; } for(block = 256; block != 0;) { block = fread(fbuff, 1, block, op); - if(fwrite(fbuff, 1, block, np) != block) - return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); + if(fwrite(fbuff, 1, block, np) != block) { + error = TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); + goto tbd_apply_cmd_file_delta_error; + } } fclose(np); fclose(op); - // Apply metadata. + /* Apply metadata. */ /* file was removed so old permissions were lost * all permissions need to be reapplied, all were sent in this protocol * if only changed sent will have to save mdata from file before it is @@ -378,10 +408,19 @@ tbd_apply_cmd_file_delta(FILE *stream) } return 0; + +tbd_apply_cmd_file_delta_error: + fclose(np); + fclose(op); + + return error; } -static int tbd_apply_cmd_entity_delete_for_name(const char*); -static int tbd_apply_cmd_dir_delete(const char *name) +static int +tbd_apply_cmd_entity_delete_for_name(const char*); + +static int +tbd_apply_cmd_dir_delete(const char *name) { int err = TBD_ERROR_SUCCESS; DIR *dp; @@ -396,7 +435,7 @@ static int tbd_apply_cmd_dir_delete(const char *name) } while ((entry = readdir(dp)) != NULL) { - if ((strcmp(entry->d_name, ".") == 0) || + if ((strcmp(entry->d_name, "." ) == 0) || (strcmp(entry->d_name, "..") == 0)) { continue; } @@ -441,14 +480,14 @@ static int tbd_apply_cmd_entity_delete(FILE *stream) { uint16_t elen; - if(tbd_read_uint16_t(&elen, stream) != 1) + if(tbd_read_uint16(&elen, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); char ename[elen + 1]; if(fread(ename, 1, elen, stream) != elen) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); ename[elen] = '\0'; - fprintf(stderr, "cmd_entity_delete %s\n", ename); + TBD_DEBUGF("cmd_entity_delete %s\n", ename); if((strchr(ename, '/') != NULL) || (strcmp(ename, "..") == 0)) return TBD_ERROR(TBD_ERROR_INVALID_PARAMETER); @@ -463,13 +502,13 @@ tbd_apply_cmd_symlink_create(FILE *stream) uid_t uid; gid_t gid; - if(tbd_read_time_t(&mtime, stream) != 1 || - tbd_read_uid_t(&uid, stream) != 1 || - tbd_read_gid_t(&gid, stream) != 1) + if(tbd_read_time(&mtime, stream) != 1 || + tbd_read_uid(&uid , stream) != 1 || + tbd_read_gid(&gid , stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); /* Reading link file name */ - if(tbd_read_uint16_t(&len, stream) != 1) + if(tbd_read_uint16(&len, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); char linkname[len + 1]; @@ -478,7 +517,7 @@ tbd_apply_cmd_symlink_create(FILE *stream) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); /* Reading target path */ - if(tbd_read_uint16_t(&len, stream) != 1) + if(tbd_read_uint16(&len, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); char linkpath[len+1]; linkpath[len] = '\0'; @@ -486,7 +525,7 @@ tbd_apply_cmd_symlink_create(FILE *stream) if(fread(linkpath, sizeof(char), len, stream) != len) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); - fprintf(stderr, "cmd_symlink_create %s -> %s\n", linkname, linkpath); + TBD_DEBUGF("cmd_symlink_create %s -> %s\n", linkname, linkpath); if(symlink(linkpath, linkname)) return TBD_ERROR(TBD_ERROR_UNABLE_TO_CREATE_SYMLINK); @@ -496,8 +535,9 @@ tbd_apply_cmd_symlink_create(FILE *stream) tv[1].tv_sec = (long) mtime; tv[1].tv_usec = 0; - lutimes(linkname, tv); // Don't care if it succeeds right now. - lchown(linkname, (uid_t)uid, (uid_t)gid); + lutimes(linkname, tv); /* Don't care if it succeeds right now. */ + if (lchown(linkname, (uid_t)uid, (uid_t)gid) < 0) + TBD_WARN("Failed to change ownership of symlink"); return TBD_ERROR_SUCCESS; } @@ -505,7 +545,7 @@ tbd_apply_cmd_symlink_create(FILE *stream) static int tbd_apply_cmd_special_create(FILE *stream) { - char *name = tbd_apply_fread_string(stream); + char *name = tbd_apply_read_string(stream); time_t mtime; mode_t mode; uid_t uid; @@ -513,16 +553,16 @@ tbd_apply_cmd_special_create(FILE *stream) uint32_t dev; if(name == NULL || - tbd_read_time_t(&mtime, stream) != 1 || - tbd_read_mode_t(&mode, stream) != 1 || - tbd_read_uid_t(&uid, stream) != 1 || - tbd_read_gid_t(&gid, stream) != 1 || - tbd_read_uint32_t(&dev, stream) != 1) { + tbd_read_time (&mtime, stream) != 1 || + tbd_read_mode (&mode , stream) != 1 || + tbd_read_uid (&uid , stream) != 1 || + tbd_read_gid (&gid , stream) != 1 || + tbd_read_uint32(&dev , stream) != 1) { free(name); return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); } - fprintf(stderr, "cmd_special_create %s\n", name); + TBD_DEBUGF("cmd_special_create %s\n", name); if(mknod(name, mode, (dev_t)dev) != 0) { free(name); @@ -530,9 +570,10 @@ tbd_apply_cmd_special_create(FILE *stream) } struct utimbuf timebuff = { time(NULL), mtime }; - utime(name, &timebuff); // Don't care if it succeeds right now. + utime(name, &timebuff); /* Don't care if it succeeds right now. */ - chown(name, (uid_t)uid, (gid_t)gid); + if (chown(name, (uid_t)uid, (gid_t)gid) < 0) + TBD_WARN("Failed to change ownership of node"); chmod(name, mode); free(name); @@ -548,25 +589,27 @@ tbd_apply_cmd_dir_delta(FILE *stream) gid_t gid; mode_t mode; - if(tbd_read_uint16_t(&metadata_mask, stream) != 1 || - tbd_read_time_t(&mtime, stream) != 1 || - tbd_read_uid_t(&uid, stream) != 1 || - tbd_read_gid_t(&gid, stream) != 1 || - tbd_read_uint32_t(&mode, stream) != 1) + if(tbd_read_uint16(&metadata_mask, stream) != 1 || + tbd_read_time (&mtime , stream) != 1 || + tbd_read_uid (&uid , stream) != 1 || + tbd_read_gid (&gid , stream) != 1 || + tbd_read_uint32(&mode , stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); - char *dname = tbd_apply_fread_string(stream); + char *dname = tbd_apply_read_string(stream); if(dname == NULL) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); - fprintf(stderr, "cmd_dir_delta %s\n", dname); + TBD_DEBUGF("cmd_dir_delta %s\n", dname); if(metadata_mask & TBD_METADATA_MTIME) { struct utimbuf timebuff = { time(NULL), mtime }; - utime(dname, &timebuff); // Don't care if it succeeds right now. + utime(dname, &timebuff); /* Don't care if it succeeds right now. */ + } + if(metadata_mask & TBD_METADATA_UID || metadata_mask & TBD_METADATA_GID) { + if (chown(dname, (uid_t)uid, (gid_t)gid) < 0) + TBD_WARN("Failed to change ownership during file modification"); } - if(metadata_mask & TBD_METADATA_UID || metadata_mask & TBD_METADATA_GID) - chown(dname, (uid_t)uid, (gid_t)gid); if(metadata_mask | TBD_METADATA_MODE) chmod(dname, mode); @@ -583,25 +626,28 @@ tbd_apply_cmd_file_mdata_update(FILE *stream) gid_t gid; mode_t mode; - if(tbd_read_uint16_t(&metadata_mask, stream) != 1 || - tbd_read_time_t(&mtime, stream) != 1 || - tbd_read_uid_t(&uid, stream) != 1 || - tbd_read_gid_t(&gid, stream) != 1 || - tbd_read_uint32_t(&mode, stream) != 1) + if(tbd_read_uint16(&metadata_mask, stream) != 1 || + tbd_read_time (&mtime , stream) != 1 || + tbd_read_uid (&uid , stream) != 1 || + tbd_read_gid (&gid , stream) != 1 || + tbd_read_uint32(&mode , stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); - char *dname = tbd_apply_fread_string(stream); + char *dname = tbd_apply_read_string(stream); if(dname == NULL) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); - fprintf(stderr, "cmd_metadata_update %s\n", dname); + TBD_DEBUGF("cmd_metadata_update %s\n", dname); if(metadata_mask & TBD_METADATA_MTIME) { struct utimbuf timebuff = { time(NULL), mtime }; - utime(dname, &timebuff); // Don't care if it succeeds right now. + utime(dname, &timebuff); /* Don't care if it succeeds right now. */ + } + if(metadata_mask & TBD_METADATA_UID || metadata_mask & TBD_METADATA_GID) { + if (chown(dname, (uid_t)uid, (gid_t)gid) < 0) + TBD_WARN("Failed to change ownership" + " during file attribute modification"); } - if(metadata_mask & TBD_METADATA_UID || metadata_mask & TBD_METADATA_GID) - chown(dname, (uid_t)uid, (gid_t)gid); if(metadata_mask | TBD_METADATA_MODE) chmod(dname, mode); @@ -609,7 +655,8 @@ tbd_apply_cmd_file_mdata_update(FILE *stream) return TBD_ERROR_SUCCESS; } -static int tbd_apply_cmd_xattrs_update(FILE *stream) +static int +tbd_apply_cmd_xattrs_update(FILE *stream) { int err = TBD_ERROR_SUCCESS; char *fname; @@ -617,7 +664,7 @@ static int tbd_apply_cmd_xattrs_update(FILE *stream) void *data = NULL; size_t dsize = 0; /* read the name of the file to operate on */ - if ((fname = tbd_apply_fread_string(stream)) == NULL) { + if ((fname = tbd_apply_read_string(stream)) == NULL) { return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); } @@ -627,21 +674,21 @@ static int tbd_apply_cmd_xattrs_update(FILE *stream) } /* read how many attributes to process */ - if (tbd_read_uint32_t(&count, stream) != 1) { + if (tbd_read_uint32(&count, stream) != 1) { err = TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); goto cleanup; } /* operate on each attribute */ while (count > 0) { - char *aname = tbd_apply_fread_string(stream); + char *aname = tbd_apply_read_string(stream); if (aname == NULL) { err=TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); goto cleanup; } /* read a block of data, reallocating if needed */ - if ((err = tbd_apply_fread_block(stream, &data, &dsize)) + if ((err = tbd_apply_read_block(stream, &data, &dsize)) != TBD_ERROR_SUCCESS) { free(aname); goto cleanup; @@ -674,8 +721,8 @@ tbd_apply(FILE *stream) uintptr_t depth = 0; bool flush = false; while(!flush) { - uint8_t cmd; - if(fread(&cmd, 1, 1, stream) != 1) + tbd_cmd_t cmd; + if(fread(&cmd, sizeof(tbd_cmd_t), 1, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_STREAM); switch(cmd) { case TBD_CMD_DIR_CREATE: @@ -722,7 +769,7 @@ tbd_apply(FILE *stream) break; case TBD_CMD_ENTITY_MOVE: case TBD_CMD_ENTITY_COPY: - return TBD_ERROR(TBD_ERROR_FEATURE_NOT_IMPLEMENTED); // TODO - Implement. + return TBD_ERROR(TBD_ERROR_FEATURE_NOT_IMPLEMENTED); /* TODO - Implement. */ case TBD_CMD_ENTITY_DELETE: if((err = tbd_apply_cmd_entity_delete(stream)) != 0) return err; @@ -731,7 +778,7 @@ tbd_apply(FILE *stream) flush = true; break; default: - fprintf(stderr, "Error: Invalid command 0x%02"PRIx8".\n", cmd); + TBD_DEBUGF("Invalid command 0x%02"PRIx8".\n", cmd); return TBD_ERROR(TBD_ERROR_INVALID_PARAMETER); } } diff --git a/tbdiff/tbdiff-common.h b/tbdiff/tbdiff-common.h index d4ac2c8..cbb5c0d 100644 --- a/tbdiff/tbdiff-common.h +++ b/tbdiff/tbdiff-common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Codethink Ltd. + * Copyright (C) 2011-2014 Codethink Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as @@ -24,6 +24,7 @@ #include <stdio.h> #include <stdint.h> +#include <stdarg.h> #include <tbdiff/tbdiff-stat.h> @@ -45,6 +46,8 @@ typedef enum { TBD_CMD_XATTRS_UPDATE = 0x60, } tbd_cmd_e; +typedef uint8_t tbd_cmd_t; + typedef enum { TBD_METADATA_NONE = 0x0, TBD_METADATA_MTIME = 0x1, @@ -55,49 +58,75 @@ typedef enum { } tbd_metadata_type_e; typedef enum { - TBD_ERROR_SUCCESS = 0, - TBD_ERROR_FAILURE = -1, - TBD_ERROR_OUT_OF_MEMORY = -2, - TBD_ERROR_NULL_POINTER = -3, - TBD_ERROR_INVALID_PARAMETER = -4, - TBD_ERROR_UNABLE_TO_READ_STREAM = -5, - TBD_ERROR_UNABLE_TO_WRITE_STREAM = -6, - TBD_ERROR_UNABLE_TO_CREATE_DIR = -7, - TBD_ERROR_UNABLE_TO_CHANGE_DIR = -8, - TBD_ERROR_UNABLE_TO_OPEN_FILE_FOR_READING = -9, - TBD_ERROR_UNABLE_TO_OPEN_FILE_FOR_WRITING = -10, - TBD_ERROR_FILE_ALREADY_EXISTS = -11, - TBD_ERROR_UNABLE_TO_REMOVE_FILE = -12, - TBD_ERROR_UNABLE_TO_SEEK_THROUGH_STREAM = -13, - TBD_ERROR_FEATURE_NOT_IMPLEMENTED = -14, - TBD_ERROR_FILE_DOES_NOT_EXIST = -15, + TBD_ERROR_SUCCESS = 0, + TBD_ERROR_FAILURE = -1, + TBD_ERROR_OUT_OF_MEMORY = -2, + TBD_ERROR_NULL_POINTER = -3, + TBD_ERROR_INVALID_PARAMETER = -4, + TBD_ERROR_UNABLE_TO_READ_STREAM = -5, + TBD_ERROR_UNABLE_TO_WRITE_STREAM = -6, + TBD_ERROR_UNABLE_TO_CREATE_DIR = -7, + TBD_ERROR_UNABLE_TO_CHANGE_DIR = -8, + TBD_ERROR_UNABLE_TO_OPEN_FILE_FOR_READING = -9, + TBD_ERROR_UNABLE_TO_OPEN_FILE_FOR_WRITING = -10, + TBD_ERROR_FILE_ALREADY_EXISTS = -11, + TBD_ERROR_UNABLE_TO_REMOVE_FILE = -12, + TBD_ERROR_UNABLE_TO_SEEK_THROUGH_STREAM = -13, + TBD_ERROR_FEATURE_NOT_IMPLEMENTED = -14, + TBD_ERROR_FILE_DOES_NOT_EXIST = -15, TBD_ERROR_UNABLE_TO_DETECT_STREAM_POSITION = -16, - TBD_ERROR_UNABLE_TO_STAT_FILE = -17, - TBD_ERROR_UNABLE_TO_READ_SYMLINK = -18, - TBD_ERROR_UNABLE_TO_CREATE_SYMLINK = -19, - TBD_ERROR_UNABLE_TO_READ_SPECIAL_FILE = -20, - TBD_ERROR_UNABLE_TO_CREATE_SPECIAL_FILE = -21, - TBD_ERROR_UNABLE_TO_CREATE_SOCKET_FILE = -22, - TBD_ERROR_XATTRS_NOT_SUPPORTED = -23, - TBD_ERROR_XATTRS_MISSING_ATTR = -24, + TBD_ERROR_UNABLE_TO_STAT_FILE = -17, + TBD_ERROR_UNABLE_TO_READ_SYMLINK = -18, + TBD_ERROR_UNABLE_TO_CREATE_SYMLINK = -19, + TBD_ERROR_UNABLE_TO_READ_SPECIAL_FILE = -20, + TBD_ERROR_UNABLE_TO_CREATE_SPECIAL_FILE = -21, + TBD_ERROR_UNABLE_TO_CREATE_SOCKET_FILE = -22, + TBD_ERROR_XATTRS_NOT_SUPPORTED = -23, + TBD_ERROR_XATTRS_MISSING_ATTR = -24, } tbd_error_e; #ifdef NDEBUG +#define TBD_DEBUG(d) +#define TBD_WARN(w) #define TBD_ERROR(e) (e) +#define TBD_DEBUGF(d, ...) +#define TBD_WARNF(w, ...) #else +#define TBD_DEBUG(d) \ + tbd_log("debug", "%s", __func__, __LINE__, __FILE__, d) +#define TBD_WARN(w) \ + tbd_log("warning", "%s", __func__, __LINE__, __FILE__, w) +#define TBD_DEBUGF(d, ...) \ + tbd_log("debug", d, __func__, __LINE__, __FILE__, __VA_ARGS__) +#define TBD_WARNF(w, ...) \ + tbd_log("warning", w, __func__, __LINE__, __FILE__, __VA_ARGS__) +static inline +tbd_log(char const *t, char const *s, char const *func, int line, + char const *file, ...) +{ + va_list args; + va_start(args, file); + + fprintf(stderr, "TBDiff %s '", t); + vfprintf(stderr, s, args); + fprintf(stderr, "' in function '%s' at line %d of file '%s'.\n", + func, line, file); + + va_end(args); +} + #define TBD_ERROR(e) tbd_error(e, #e, __func__, __LINE__, __FILE__) static inline tbd_error_e tbd_error(tbd_error_e e, char const *s, char const *func, int line, char const* file) { if (e != TBD_ERROR_SUCCESS) - fprintf(stderr, "TBDiff error '%s' in function '%s' at line %d " - "of file '%s'.\n", s, func, line, file); + tbd_log("error", "%s", func, line, file, s); return e; } #endif -extern int tbd_apply (FILE *stream); -extern int tbd_create(FILE *stream, tbd_stat_t *a, tbd_stat_t *b); +extern int tbd_apply (FILE *stream); +extern int tbd_create(FILE *stream, tbd_stat_t *a, tbd_stat_t *b); #endif /* !__TBDIFF_COMMON_H__ */ diff --git a/tbdiff/tbdiff-create.c b/tbdiff/tbdiff-create.c index ec5a8ce..edfb985 100644 --- a/tbdiff/tbdiff-create.c +++ b/tbdiff/tbdiff-create.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Codethink Ltd. + * Copyright (C) 2011-2014 Codethink Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as @@ -33,27 +33,29 @@ #define PATH_BUFFER_LENGTH 4096 static int -tbd_create_fwrite_cmd(FILE *stream, - uint8_t cmd) +tbd_create_write_cmd(FILE *stream, + tbd_cmd_t cmd) { - if(fwrite(&cmd, 1, 1, stream) != 1) + if(fwrite(&cmd, sizeof(tbd_cmd_t), 1, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); return 0; } static int -tbd_create_fwrite_string(FILE *stream, - const char *string) +tbd_create_write_string(FILE *stream, + const char *string) { uint16_t slen = strlen(string); - if((tbd_write_uint16_t(slen, stream) != 1) + if((tbd_write_uint16(slen, stream) != 1) || (fwrite(string, 1, slen, stream) != slen)) return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); return 0; } static int -tbd_create_fwrite_block(FILE *stream, void const *data, size_t size) +tbd_create_write_block(FILE *stream, + void const *data, + size_t size) { if (fwrite(&size, 1, sizeof(size), stream) != sizeof(size)) { return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); @@ -66,55 +68,55 @@ tbd_create_fwrite_block(FILE *stream, void const *data, size_t size) } static int -tbd_create_fwrite_mdata_mask(FILE *stream, - uint16_t mask) +tbd_create_write_mdata_mask(FILE *stream, + uint16_t mask) { - if(tbd_write_uint16_t(mask, stream) != 1) + if(tbd_write_uint16(mask, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); return 0; } static int -tbd_create_fwrite_mtime(FILE *stream, - time_t mtime) +tbd_create_write_mtime(FILE *stream, + time_t mtime) { - if(tbd_write_time_t(mtime, stream) != 1) + if(tbd_write_time(mtime, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); return 0; } static int -tbd_create_fwrite_mode(FILE *stream, - mode_t mode) +tbd_create_write_mode(FILE *stream, + mode_t mode) { - if(tbd_write_mode_t(mode, stream) != 1) + if(tbd_write_mode(mode, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); return 0; } static int -tbd_create_fwrite_gid(FILE *stream, - gid_t gid) +tbd_create_write_gid(FILE *stream, + gid_t gid) { - if(tbd_write_gid_t(gid, stream) != 1) + if(tbd_write_gid(gid, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); return 0; } static int -tbd_create_fwrite_uid(FILE *stream, - uid_t uid) +tbd_create_write_uid(FILE *stream, + uid_t uid) { - if(tbd_write_uid_t(uid, stream) != 1) + if(tbd_write_uid(uid, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); return 0; } static int -tbd_create_fwrite_dev(FILE *stream, - uint32_t dev) +tbd_create_write_dev(FILE *stream, + uint32_t dev) { - if(tbd_write_uint32_t(dev, stream) != 1) + if(tbd_write_uint32(dev, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); return 0; } @@ -124,9 +126,9 @@ tbd_create_cmd_ident(FILE *stream) { int err; - if((err = tbd_create_fwrite_cmd(stream, TBD_CMD_IDENTIFY)) != 0) + if((err = tbd_create_write_cmd(stream, TBD_CMD_IDENTIFY)) != 0) return err; - if((err = tbd_create_fwrite_string(stream, TB_DIFF_PROTOCOL_ID)) != 0) + if((err = tbd_create_write_string(stream, TB_DIFF_PROTOCOL_ID)) != 0) return err; return 0; } @@ -134,33 +136,33 @@ tbd_create_cmd_ident(FILE *stream) static int tbd_create_cmd_update(FILE *stream) { - return tbd_create_fwrite_cmd(stream, TBD_CMD_UPDATE); + return tbd_create_write_cmd(stream, TBD_CMD_UPDATE); } /* callback function to pass to tbx_xattrs_pairs * this will write the attribute name, then the data representing that block */ static int -_write_pair(char const *name, void const *data, size_t size, void *ud) +tbd_create_cmd_write_xattr_pair(char const *name, + void const *data, + size_t size, + void *stream) { - FILE *stream = ud; int err; - if ((err = tbd_create_fwrite_string(stream, name)) != - TBD_ERROR_SUCCESS) { + if ((err = tbd_create_write_string(stream, name)) != + TBD_ERROR_SUCCESS) return err; - } - if ((err = tbd_create_fwrite_block(stream, data, size)) != - TBD_ERROR_SUCCESS) { + if ((err = tbd_create_write_block(stream, data, size)) != + TBD_ERROR_SUCCESS) return err; - } return TBD_ERROR_SUCCESS; } static int -tbd_create_cmd_fwrite_xattrs(FILE *stream, tbd_stat_t *f) +tbd_create_cmd_write_xattrs(FILE *stream, tbd_stat_t *f) { int err = TBD_ERROR_SUCCESS; tbd_xattrs_names_t names; @@ -186,25 +188,28 @@ tbd_create_cmd_fwrite_xattrs(FILE *stream, tbd_stat_t *f) goto cleanup_names; } - if ((err = tbd_create_fwrite_cmd(stream, + if ((err = tbd_create_write_cmd(stream, TBD_CMD_XATTRS_UPDATE) ) != TBD_ERROR_SUCCESS) { goto cleanup_names; } - if ((err = tbd_create_fwrite_string(stream, f->name))!= + if ((err = tbd_create_write_string(stream, f->name))!= TBD_ERROR_SUCCESS) { goto cleanup_names; } - if (tbd_write_uint32_t(count, stream) != 1) { + if (tbd_write_uint32(count, stream) != 1) { err = TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); goto cleanup_names; } } /* write the name:data pairs */ - err = tbd_xattrs_pairs(&names, path, _write_pair, stream); + err = tbd_xattrs_pairs(&names, + path, + tbd_create_cmd_write_xattr_pair, + stream); cleanup_names: tbd_xattrs_names_free(&names); @@ -218,16 +223,16 @@ tbd_create_cmd_file_create(FILE *stream, tbd_stat_t *f) { int err; - if((err = tbd_create_fwrite_cmd(stream, TBD_CMD_FILE_CREATE)) != 0 || - (err = tbd_create_fwrite_string(stream, f->name)) != 0 || - (err = tbd_create_fwrite_mtime (stream, f->mtime)) != 0 || - (err = tbd_create_fwrite_mode (stream, f->mode)) != 0 || - (err = tbd_create_fwrite_uid (stream, f->uid)) != 0 || - (err = tbd_create_fwrite_gid (stream, f->gid)) != 0) + if((err = tbd_create_write_cmd(stream, TBD_CMD_FILE_CREATE)) != 0 || + (err = tbd_create_write_string(stream, f->name)) != 0 || + (err = tbd_create_write_mtime (stream, f->mtime)) != 0 || + (err = tbd_create_write_mode (stream, f->mode)) != 0 || + (err = tbd_create_write_uid (stream, f->uid)) != 0 || + (err = tbd_create_write_gid (stream, f->gid)) != 0) return err; uint32_t size = f->size; - if(tbd_write_uint32_t(size, stream) != 1) + if(tbd_write_uint32(size, stream) != 1) return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); FILE *fp = tbd_stat_fopen(f, "rb"); @@ -245,7 +250,7 @@ tbd_create_cmd_file_create(FILE *stream, } fclose(fp); - return tbd_create_cmd_fwrite_xattrs(stream, f); + return tbd_create_cmd_write_xattrs(stream, f); } static uint16_t @@ -268,7 +273,7 @@ tbd_metadata_mask(tbd_stat_t *a, } static int -tbd_create_cmd_file_metadata_update(FILE *stream, +tbd_create_cmd_file_metadata_update(FILE *stream, tbd_stat_t *a, tbd_stat_t *b) { @@ -278,15 +283,15 @@ tbd_create_cmd_file_metadata_update(FILE *stream, if(metadata_mask == TBD_METADATA_NONE) return 0; /* TODO: Optimize protocol by only sending useful metadata */ - if((err = tbd_create_fwrite_cmd(stream, TBD_CMD_FILE_METADATA_UPDATE)) != 0 || - (err = tbd_create_fwrite_mdata_mask (stream, metadata_mask)) != 0 || - (err = tbd_create_fwrite_mtime (stream, b->mtime)) != 0 || - (err = tbd_create_fwrite_uid (stream, b->uid)) != 0 || - (err = tbd_create_fwrite_gid (stream, b->gid)) != 0 || - (err = tbd_create_fwrite_mode (stream, b->mode)) != 0) + if((err = tbd_create_write_cmd(stream, TBD_CMD_FILE_METADATA_UPDATE)) != 0 || + (err = tbd_create_write_mdata_mask(stream, metadata_mask)) != 0 || + (err = tbd_create_write_mtime (stream, b->mtime)) != 0 || + (err = tbd_create_write_uid (stream, b->uid)) != 0 || + (err = tbd_create_write_gid (stream, b->gid)) != 0 || + (err = tbd_create_write_mode (stream, b->mode)) != 0) return err; - return tbd_create_fwrite_string(stream, b->name); + return tbd_create_write_string(stream, b->name); } static int @@ -303,7 +308,7 @@ tbd_create_cmd_file_delta(FILE *stream, return TBD_ERROR(TBD_ERROR_UNABLE_TO_OPEN_FILE_FOR_READING); } - // Calculate start. + /* Calculate start. */ uintptr_t blks[2] = { 256, 256 }; uint8_t buff[2][256]; @@ -332,7 +337,7 @@ tbd_create_cmd_file_delta(FILE *stream, return TBD_ERROR(TBD_ERROR_UNABLE_TO_SEEK_THROUGH_STREAM); } - // Find length. + /* Find length. */ long flena = ftell(fpa); long flenb = ftell(fpb); @@ -342,7 +347,7 @@ tbd_create_cmd_file_delta(FILE *stream, return TBD_ERROR(TBD_ERROR_UNABLE_TO_DETECT_STREAM_POSITION); } - // Find end. + /* Find end. */ blks[0] = 256; blks[1] = 256; for(o = 0; true; o += blks[1]) { @@ -377,7 +382,7 @@ tbd_create_cmd_file_delta(FILE *stream, } fclose(fpa); - // Ensure that the start and end don't overlap for the new file. + /* Ensure that the start and end don't overlap for the new file. */ if((flenb - o) < start) o = (flenb - start); @@ -385,32 +390,32 @@ tbd_create_cmd_file_delta(FILE *stream, if(end < start) end = start; - uint32_t size = flenb - ((flena - end) + start); //(flenb - (o + start)); + uint32_t size = flenb - ((flena - end) + start); /* (flenb - (o + start)); */ /* Data is identical, only alter metadata */ if((end == start) && (size == 0)) { tbd_create_cmd_file_metadata_update(stream, a, b); fclose(fpb); - return tbd_create_cmd_fwrite_xattrs(stream, b); + return tbd_create_cmd_write_xattrs(stream, b); } uint16_t metadata_mask = tbd_metadata_mask(a, b); /* TODO: Optimize protocol by only sending useful metadata */ int err; - if(((err = tbd_create_fwrite_cmd(stream, TBD_CMD_FILE_DELTA)) != 0) || - ((err = tbd_create_fwrite_string(stream, b->name)) != 0) || - ((err = tbd_create_fwrite_mdata_mask(stream, metadata_mask)) != 0) || - ((err = tbd_create_fwrite_mtime (stream, b->mtime)) != 0) || - ((err = tbd_create_fwrite_uid (stream, b->uid)) != 0) || - ((err = tbd_create_fwrite_gid (stream, b->gid)) != 0) || - ((err = tbd_create_fwrite_mode (stream, b->mode)) != 0)) { + if(((err = tbd_create_write_cmd(stream, TBD_CMD_FILE_DELTA)) != 0) || + ((err = tbd_create_write_string(stream, b->name)) != 0) || + ((err = tbd_create_write_mdata_mask(stream, metadata_mask)) != 0) || + ((err = tbd_create_write_mtime (stream, b->mtime)) != 0) || + ((err = tbd_create_write_uid (stream, b->uid)) != 0) || + ((err = tbd_create_write_gid (stream, b->gid)) != 0) || + ((err = tbd_create_write_mode (stream, b->mode)) != 0)) { fclose(fpb); return err; } - if((tbd_write_uint32_t(start, stream) != 1) || - (tbd_write_uint32_t(end, stream) != 1) || - (tbd_write_uint32_t(size, stream) != 1)) { + if((tbd_write_uint32(start, stream) != 1) || + (tbd_write_uint32(end, stream) != 1) || + (tbd_write_uint32(size, stream) != 1)) { fclose(fpb); return TBD_ERROR(TBD_ERROR_UNABLE_TO_WRITE_STREAM); } @@ -432,23 +437,23 @@ tbd_create_cmd_file_delta(FILE *stream, } fclose(fpb); - return tbd_create_cmd_fwrite_xattrs(stream, b); + return tbd_create_cmd_write_xattrs(stream, b); } static int -tbd_create_cmd_dir_create(FILE *stream, - tbd_stat_t *d) +tbd_create_cmd_dir_create(FILE *stream, + tbd_stat_t *d) { int err; - if((err = tbd_create_fwrite_cmd(stream, TBD_CMD_DIR_CREATE)) != 0 || - (err = tbd_create_fwrite_string(stream, d->name)) != 0 || - (err = tbd_create_fwrite_mtime(stream, d->mtime)) != 0 || - (err = tbd_create_fwrite_uid(stream, d->uid)) != 0 || - (err = tbd_create_fwrite_gid(stream, d->gid)) != 0) + if((err = tbd_create_write_cmd(stream, TBD_CMD_DIR_CREATE)) != 0 || + (err = tbd_create_write_string(stream, d->name)) != 0 || + (err = tbd_create_write_mtime(stream, d->mtime)) != 0 || + (err = tbd_create_write_uid(stream, d->uid)) != 0 || + (err = tbd_create_write_gid(stream, d->gid)) != 0) return err; - return tbd_create_fwrite_mode(stream, d->mode); + return tbd_create_write_mode(stream, d->mode); } static int @@ -456,22 +461,22 @@ tbd_create_cmd_dir_enter(FILE *stream, const char *name) { int err; - if((err = tbd_create_fwrite_cmd(stream, TBD_CMD_DIR_ENTER)) != 0) + if((err = tbd_create_write_cmd(stream, TBD_CMD_DIR_ENTER)) != 0) return err; - return tbd_create_fwrite_string(stream, name); + return tbd_create_write_string(stream, name); } static int -tbd_create_cmd_dir_leave(FILE *stream, - tbd_stat_t *dir) +tbd_create_cmd_dir_leave(FILE *stream, + tbd_stat_t *dir) { int err; - if ((err = tbd_create_fwrite_cmd(stream, TBD_CMD_DIR_LEAVE)) != + if ((err = tbd_create_write_cmd(stream, TBD_CMD_DIR_LEAVE)) != TBD_ERROR_SUCCESS) { return err; } - return tbd_create_fwrite_mtime(stream, dir->mtime); + return tbd_create_write_mtime(stream, dir->mtime); } static int @@ -479,9 +484,9 @@ tbd_create_cmd_entity_delete(FILE *stream, const char *name) { int err; - if((err = tbd_create_fwrite_cmd(stream, TBD_CMD_ENTITY_DELETE)) != 0) + if((err = tbd_create_write_cmd(stream, TBD_CMD_ENTITY_DELETE)) != 0) return err; - return tbd_create_fwrite_string(stream, name); + return tbd_create_write_string(stream, name); } static int @@ -495,20 +500,20 @@ tbd_create_cmd_dir_delta(FILE *stream, if(metadata_mask == TBD_METADATA_NONE) return 0; - if((err = tbd_create_fwrite_cmd(stream, TBD_CMD_DIR_DELTA)) != 0 || - (err = tbd_create_fwrite_mdata_mask (stream, metadata_mask)) != 0 || - (err = tbd_create_fwrite_mtime (stream, b->mtime)) != 0 || - (err = tbd_create_fwrite_uid (stream, b->uid)) != 0 || - (err = tbd_create_fwrite_gid (stream, b->gid)) != 0 || - (err = tbd_create_fwrite_mode (stream, b->mode)) != 0) + if((err = tbd_create_write_cmd(stream, TBD_CMD_DIR_DELTA)) != 0 || + (err = tbd_create_write_mdata_mask (stream, metadata_mask)) != 0 || + (err = tbd_create_write_mtime (stream, b->mtime)) != 0 || + (err = tbd_create_write_uid (stream, b->uid)) != 0 || + (err = tbd_create_write_gid (stream, b->gid)) != 0 || + (err = tbd_create_write_mode (stream, b->mode)) != 0) return err; - return tbd_create_fwrite_string(stream, b->name); + return tbd_create_write_string(stream, b->name); } static int -tbd_create_cmd_symlink_create(FILE *stream, - tbd_stat_t *symlink) +tbd_create_cmd_symlink_create(FILE *stream, + tbd_stat_t *symlink) { int err; char path[PATH_BUFFER_LENGTH]; @@ -520,20 +525,20 @@ tbd_create_cmd_symlink_create(FILE *stream, return TBD_ERROR(TBD_ERROR_UNABLE_TO_READ_SYMLINK); path[len] = '\0'; - if((err = tbd_create_fwrite_cmd(stream, TBD_CMD_SYMLINK_CREATE)) != 0 || - (err = tbd_create_fwrite_mtime (stream, symlink->mtime)) != 0 || - (err = tbd_create_fwrite_uid (stream, symlink->uid)) != 0 || - (err = tbd_create_fwrite_gid (stream, symlink->gid)) != 0 || - (err = tbd_create_fwrite_string(stream, symlink->name)) != 0) + if((err = tbd_create_write_cmd(stream, TBD_CMD_SYMLINK_CREATE)) != 0 || + (err = tbd_create_write_mtime (stream, symlink->mtime)) != 0 || + (err = tbd_create_write_uid (stream, symlink->uid)) != 0 || + (err = tbd_create_write_gid (stream, symlink->gid)) != 0 || + (err = tbd_create_write_string(stream, symlink->name)) != 0) return err; - return tbd_create_fwrite_string(stream, path); + return tbd_create_write_string(stream, path); } static int -tbd_create_cmd_symlink_delta(FILE *stream, - tbd_stat_t *a, - tbd_stat_t *b) +tbd_create_cmd_symlink_delta(FILE *stream, + tbd_stat_t *a, + tbd_stat_t *b) { int err; char path_a[PATH_BUFFER_LENGTH]; @@ -569,25 +574,25 @@ tbd_create_cmd_symlink_delta(FILE *stream, } static int -tbd_create_cmd_special_create(FILE *stream, - tbd_stat_t *nod) +tbd_create_cmd_special_create(FILE *stream, + tbd_stat_t *nod) { int err; - if((err = tbd_create_fwrite_cmd(stream, TBD_CMD_SPECIAL_CREATE)) != 0 || - (err = tbd_create_fwrite_string(stream, nod->name)) != 0 || - (err = tbd_create_fwrite_mtime (stream, nod->mtime)) != 0 || - (err = tbd_create_fwrite_mode (stream, nod->mode)) != 0 || - (err = tbd_create_fwrite_uid (stream, nod->uid)) != 0 || - (err = tbd_create_fwrite_gid (stream, nod->gid)) != 0) + if((err = tbd_create_write_cmd(stream, TBD_CMD_SPECIAL_CREATE)) != 0 || + (err = tbd_create_write_string(stream, nod->name)) != 0 || + (err = tbd_create_write_mtime (stream, nod->mtime)) != 0 || + (err = tbd_create_write_mode (stream, nod->mode)) != 0 || + (err = tbd_create_write_uid (stream, nod->uid)) != 0 || + (err = tbd_create_write_gid (stream, nod->gid)) != 0) return err; - return tbd_create_fwrite_dev(stream, nod->rdev); + return tbd_create_write_dev(stream, nod->rdev); } static int -tbd_create_cmd_special_delta(FILE *stream, - tbd_stat_t *a, - tbd_stat_t *b) +tbd_create_cmd_special_delta(FILE *stream, + tbd_stat_t *a, + tbd_stat_t *b) { uint16_t metadata_mask = tbd_metadata_mask(a, b); if(a->rdev != b->rdev) @@ -670,17 +675,17 @@ tbd_create_dir(FILE *stream, } static int -tbd_create_impl(FILE *stream, - tbd_stat_t *a, - tbd_stat_t *b, - bool top) +tbd_create_impl(FILE *stream, + tbd_stat_t *a, + tbd_stat_t *b, + bool top) { if((a == NULL) && (b == NULL)) return TBD_ERROR(TBD_ERROR_NULL_POINTER); int err; if(((b == NULL) || ((a != NULL) && (a->type != b->type)))) { - fprintf(stderr, "file delete %s\n", a->name); + TBD_DEBUGF("file delete %s\n", a->name); if((err = tbd_create_cmd_entity_delete(stream, a->name)) != 0) return err; } @@ -688,21 +693,21 @@ tbd_create_impl(FILE *stream, if((a == NULL) || ((b != NULL) && (a->type != b->type))) { switch(b->type) { case TBD_STAT_TYPE_FILE: - fprintf(stderr, "file new %s\n", b->name); + TBD_DEBUGF("file new %s\n", b->name); return tbd_create_cmd_file_create(stream, b); case TBD_STAT_TYPE_DIR: - fprintf(stderr, "dir new %s\n", b->name); + TBD_DEBUGF("dir new %s\n", b->name); return tbd_create_dir(stream, b); case TBD_STAT_TYPE_SYMLINK: - fprintf(stderr, "symlink new %s\n", b->name); + TBD_DEBUGF("symlink new %s\n", b->name); return tbd_create_cmd_symlink_create(stream, b); case TBD_STAT_TYPE_CHRDEV: case TBD_STAT_TYPE_BLKDEV: case TBD_STAT_TYPE_FIFO: - fprintf(stderr, "special new %s\n", b->name); + TBD_DEBUGF("special new %s\n", b->name); return tbd_create_cmd_special_create(stream, b); case TBD_STAT_TYPE_SOCKET: - fprintf(stderr, "socket new %s\n", b->name); + TBD_DEBUGF("socket new %s\n", b->name); return tbd_create_cmd_socket_create(stream, b); default: return TBD_ERROR(TBD_ERROR_FEATURE_NOT_IMPLEMENTED); @@ -711,22 +716,22 @@ tbd_create_impl(FILE *stream, switch(b->type) { case TBD_STAT_TYPE_FILE: - fprintf(stderr, "file delta %s\n", a->name); + TBD_DEBUGF("file delta %s\n", a->name); return tbd_create_cmd_file_delta(stream, a, b); case TBD_STAT_TYPE_SYMLINK: - fprintf(stderr, "symlink delta %s\n", a->name); + TBD_DEBUGF("symlink delta %s\n", a->name); return tbd_create_cmd_symlink_delta(stream, a, b); case TBD_STAT_TYPE_CHRDEV: case TBD_STAT_TYPE_BLKDEV: case TBD_STAT_TYPE_FIFO: - fprintf(stderr, "special delta %s\n", a->name); + TBD_DEBUGF("special delta %s\n", a->name); return tbd_create_cmd_special_delta(stream, a, b); case TBD_STAT_TYPE_SOCKET: - fprintf(stderr, "socket delta %s\n", a->name); + TBD_DEBUGF("socket delta %s\n", a->name); return tbd_create_cmd_socket_delta(stream, a, b); case TBD_STAT_TYPE_DIR: if(!top) { - fprintf(stderr, "dir delta %s\n", a->name); + TBD_DEBUGF("dir delta %s\n", a->name); if ((err = tbd_create_cmd_dir_delta(stream, a, b)) != TBD_ERROR_SUCCESS) { return err; @@ -740,7 +745,7 @@ tbd_create_impl(FILE *stream, if(!top && ((err = tbd_create_cmd_dir_enter(stream, b->name)) != 0)) return err; - // Handle changes/additions. + /* Handle changes/additions. */ uintptr_t i; for(i = 0; i < b->size; i++) { tbd_stat_t *_b = tbd_stat_entry(b, i); @@ -754,10 +759,10 @@ tbd_create_impl(FILE *stream, return err; } - // Handle deletions. + /* Handle deletions. */ for(i = 0; i < a->size; i++) { err = 0; - + tbd_stat_t *_a = tbd_stat_entry(a, i); if(_a == NULL) return TBD_ERROR(TBD_ERROR_UNABLE_TO_STAT_FILE); @@ -781,9 +786,9 @@ tbd_create_impl(FILE *stream, } int -tbd_create(FILE *stream, - tbd_stat_t *a, - tbd_stat_t *b) +tbd_create(FILE *stream, + tbd_stat_t *a, + tbd_stat_t *b) { int err; if((stream == NULL) || (a == NULL) || (b == NULL)) diff --git a/tbdiff/tbdiff-io.c b/tbdiff/tbdiff-io.c index 698273b..c33364b 100644 --- a/tbdiff/tbdiff-io.c +++ b/tbdiff/tbdiff-io.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Codethink Ltd. + * Copyright (C) 2011-2014 Codethink Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as @@ -21,146 +21,120 @@ #include <tbdiff/tbdiff-stat.h> -#if __BYTE_ORDER == __BIG_ENDIAN -//inverts the indices of an array of bytes. -static void byteswap (char* value, int size) { - char tmp; - int i; - for (i = 0; i < size/2; i++) { - tmp = value[i]; - value[i] = value[size-i-1]; - value[size-i-1] = tmp; - } -} +#if __STDC_VERSION__ >= 199901L +#define RESTRICT restrict +#elif defined(__GNUC__) +#define RESTRICT __restrict__ +#else +#define RESTRICT #endif -size_t tbd_write_uint16_t (uint16_t value, FILE* stream) { #if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)&value, sizeof(value)); -#endif - return fwrite(&value, sizeof(value), 1, stream); +static inline void byteswap(char *RESTRICT a, char *RESTRICT b) +{ + char swap = *a; + *a = *b; + *b = swap; } -size_t tbd_write_uint32_t (uint32_t value, FILE* stream) { -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)&value, sizeof(value)); -#endif - return fwrite(&value, sizeof(value), 1, stream); +/*inverts the indices of an array of bytes. */ +static inline void endianswap(void* value, size_t size) +{ + + char* cvalue = value; + int i, j; + for (i = 0, j = (size - 1); i < (size / 2); i++, j--) + byteswap(&cvalue[i], &cvalue[j]); } -size_t tbd_write_uint64_t (uint64_t value, FILE* stream) { -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)&value, sizeof(value)); +#define ENDIANSWAP(v) endianswap(v, sizeof(*v)) +#else +#define ENDIANSWAP(v) #endif - return fwrite(&value, sizeof(value), 1, stream); + +size_t tbd_write_uint16(uint16_t value, FILE *stream) { + ENDIANSWAP(&value); + return fwrite(&value, sizeof(value), 1, stream); } -size_t tbd_write_time_t (time_t value, FILE* stream) { - uint64_t realv = value; -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)&realv, sizeof(realv)); -#endif - return fwrite(&realv, sizeof(realv), 1, stream); +size_t tbd_write_uint32(uint32_t value, FILE *stream) { + ENDIANSWAP(&value); + return fwrite(&value, sizeof(value), 1, stream); } -size_t tbd_write_mode_t (mode_t value, FILE* stream) { -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)&value, sizeof(value)); -#endif - return fwrite(&value, sizeof(value), 1, stream); +size_t tbd_write_uint64(uint64_t value, FILE *stream) { + ENDIANSWAP(&value); + return fwrite(&value, sizeof(value), 1, stream); } -size_t tbd_write_uid_t (uid_t value, FILE* stream) { -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)&value, sizeof(value)); -#endif - return fwrite(&value, sizeof(value), 1, stream); +size_t tbd_write_time(time_t value, FILE *stream) { + uint64_t realv = value; + ENDIANSWAP(&realv); + return fwrite(&realv, sizeof(realv), 1, stream); } -size_t tbd_write_gid_t (gid_t value, FILE* stream) { -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)&value, sizeof(value)); -#endif - return fwrite(&value, sizeof(value), 1, stream); +size_t tbd_write_mode(mode_t value, FILE *stream) { + ENDIANSWAP(&value); + return fwrite(&value, sizeof(value), 1, stream); } -size_t tbd_write_size_t (size_t value, FILE* stream) { -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)&value, sizeof(value)); -#endif - return fwrite(&value, sizeof(value), 1, stream); +size_t tbd_write_uid(uid_t value, FILE *stream) { + ENDIANSWAP(&value); + return fwrite(&value, sizeof(value), 1, stream); } -size_t tbd_read_uint16_t (uint16_t *value, FILE* stream) { - assert(value != NULL); - size_t rval = fread(value, sizeof(*value), 1, stream); -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)value, sizeof(*value)); -#endif - return rval; +size_t tbd_write_gid(gid_t value, FILE *stream) { + ENDIANSWAP(&value); + return fwrite(&value, sizeof(value), 1, stream); } -size_t tbd_read_uint32_t (uint32_t *value, FILE* stream) { - assert(value != NULL); - size_t rval = fread(value, sizeof(*value), 1, stream); -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)value, sizeof(*value)); -#endif - return rval; +size_t tbd_read_uint16(uint16_t *value, FILE *stream) { + assert(value != NULL); + size_t rval = fread(value, sizeof(*value), 1, stream); + ENDIANSWAP(value); + return rval; } -size_t tbd_read_uint64_t (uint64_t *value, FILE* stream) { - assert(value != NULL); - size_t rval = fread(value, sizeof(*value), 1, stream); -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)value, sizeof(*value)); -#endif - return rval; +size_t tbd_read_uint32(uint32_t *value, FILE *stream) { + assert(value != NULL); + size_t rval = fread(value, sizeof(*value), 1, stream); + ENDIANSWAP(value); + return rval; } -size_t tbd_read_time_t (time_t *value, FILE* stream) { - assert(value != NULL); - uint64_t realv; - size_t rval = fread(&realv, sizeof(realv), 1, stream); -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)&realv, sizeof(realv)); -#endif - *value = realv; - return rval; - } +size_t tbd_read_uint64(uint64_t *value, FILE *stream) { + assert(value != NULL); + size_t rval = fread(value, sizeof(*value), 1, stream); + ENDIANSWAP(value); + return rval; +} -size_t tbd_read_mode_t (mode_t *value, FILE* stream) { - assert(value != NULL); - size_t rval = fread(value, sizeof(*value), 1, stream); -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)value, sizeof(*value)); -#endif - return rval; - } +size_t tbd_read_time(time_t *value, FILE *stream) { + assert(value != NULL); + uint64_t realv; + size_t rval = fread(&realv, sizeof(realv), 1, stream); + ENDIANSWAP(&realv); + *value = realv; + return rval; +} -size_t tbd_read_uid_t (uid_t *value, FILE* stream) { - assert(value != NULL); - size_t rval = fread(value, sizeof(*value), 1, stream); -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)value, sizeof(*value)); -#endif - return rval; - } +size_t tbd_read_mode(mode_t *value, FILE *stream) { + assert(value != NULL); + size_t rval = fread(value, sizeof(*value), 1, stream); + ENDIANSWAP(value); + return rval; +} -size_t tbd_read_gid_t (gid_t *value, FILE* stream) { - assert(value != NULL); - size_t rval = fread(value, sizeof(*value), 1, stream); -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)value, sizeof(*value)); -#endif - return rval; - } +size_t tbd_read_uid(uid_t *value, FILE *stream) { + assert(value != NULL); + size_t rval = fread(value, sizeof(*value), 1, stream); + ENDIANSWAP(value); + return rval; +} -size_t tbd_read_size_t (size_t *value, FILE* stream) { - assert(value != NULL); - size_t rval = fread(value, sizeof(*value), 1, stream); -#if __BYTE_ORDER == __BIG_ENDIAN - byteswap((char*)value, sizeof(*value)); -#endif - return rval; - } +size_t tbd_read_gid(gid_t *value, FILE *stream) { + assert(value != NULL); + size_t rval = fread(value, sizeof(*value), 1, stream); + ENDIANSWAP(value); + return rval; +} diff --git a/tbdiff/tbdiff-io.h b/tbdiff/tbdiff-io.h index 73e7711..585f670 100644 --- a/tbdiff/tbdiff-io.h +++ b/tbdiff/tbdiff-io.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Codethink Ltd. + * Copyright (C) 2011-2014 Codethink Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as @@ -28,36 +28,20 @@ #include <tbdiff/tbdiff-stat.h> -size_t tbd_write_uint16_t (uint16_t value, FILE* stream); - -size_t tbd_write_uint32_t (uint32_t value, FILE* stream); - -size_t tbd_write_uint64_t (uint64_t value, FILE* stream); - -size_t tbd_write_time_t (time_t value, FILE* stream); - -size_t tbd_write_mode_t (mode_t value, FILE* stream); - -size_t tbd_write_uid_t (uid_t value, FILE* stream); - -size_t tbd_write_gid_t (gid_t value, FILE* stream); - -size_t tbd_write_size_t (size_t value, FILE* stream); - -size_t tbd_read_uint16_t (uint16_t *value, FILE* stream); - -size_t tbd_read_uint32_t (uint32_t *value, FILE* stream); - -size_t tbd_read_uint64_t (uint64_t *value, FILE* stream); - -size_t tbd_read_time_t (time_t *value, FILE* stream); - -size_t tbd_read_mode_t (mode_t *value, FILE* stream); - -size_t tbd_read_uid_t (uid_t *value, FILE* stream); - -size_t tbd_read_gid_t (gid_t *value, FILE* stream); - -size_t tbd_read_size_t (size_t *value, FILE* stream); +extern size_t tbd_write_uint16(uint16_t value, FILE* stream); +extern size_t tbd_write_uint32(uint32_t value, FILE* stream); +extern size_t tbd_write_uint64(uint64_t value, FILE* stream); +extern size_t tbd_write_time(time_t value, FILE* stream); +extern size_t tbd_write_mode(mode_t value, FILE* stream); +extern size_t tbd_write_uid(uid_t value, FILE* stream); +extern size_t tbd_write_gid(gid_t value, FILE* stream); + +extern size_t tbd_read_uint16(uint16_t *value, FILE* stream); +extern size_t tbd_read_uint32(uint32_t *value, FILE* stream); +extern size_t tbd_read_uint64(uint64_t *value, FILE* stream); +extern size_t tbd_read_time(time_t *value, FILE* stream); +extern size_t tbd_read_mode(mode_t *value, FILE* stream); +extern size_t tbd_read_uid(uid_t *value, FILE* stream); +extern size_t tbd_read_gid(gid_t *value, FILE* stream); #endif /* !__TBDIFF_IO_H__ */ diff --git a/tbdiff/tbdiff-private.h b/tbdiff/tbdiff-private.h index 8287670..296dbcb 100644 --- a/tbdiff/tbdiff-private.h +++ b/tbdiff/tbdiff-private.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Codethink Ltd. + * Copyright (C) 2011-2014 Codethink Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as @@ -22,6 +22,6 @@ #ifndef __TBDIFF_PRIVATE_H__ #define __TBDIFF_PRIVATE_H__ -#define TB_DIFF_PROTOCOL_ID "Codethink:TBDIFFv0" +static const char* TB_DIFF_PROTOCOL_ID = "Codethink:TBDIFFv0"; #endif /* !__TBDIFF_PRIVATE_H__ */ diff --git a/tbdiff/tbdiff-stat.c b/tbdiff/tbdiff-stat.c index fd8964e..66e2caf 100644 --- a/tbdiff/tbdiff-stat.c +++ b/tbdiff/tbdiff-stat.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Codethink Ltd. + * Copyright (C) 2011-2014 Codethink Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as @@ -144,8 +144,10 @@ tbd_stat_entry(tbd_stat_t *file, uint32_t entry) closedir (dp); char *spath = tbd_stat_subpath(file, name); - if(spath == NULL) + if(spath == NULL) { + free(name); return NULL; + } tbd_stat_t *ret = tbd_stat_from_path(name, (const char*)spath); diff --git a/tbdiff/tbdiff-stat.h b/tbdiff/tbdiff-stat.h index d23cc80..22da466 100644 --- a/tbdiff/tbdiff-stat.h +++ b/tbdiff/tbdiff-stat.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Codethink Ltd. + * Copyright (C) 2011-2014 Codethink Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as @@ -37,17 +37,19 @@ typedef enum { TBD_STAT_TYPE_SOCKET = 's' } tbd_stat_type_e; -typedef struct { - void* parent; +typedef struct tbd_stat_s tbd_stat_t; + +struct tbd_stat_s { + tbd_stat_t* parent; char* name; tbd_stat_type_e type; time_t mtime; - uint32_t size; // Count for directory. - uid_t uid; - gid_t gid; - mode_t mode; + uint32_t size; /* Count for directory. */ + uid_t uid; + gid_t gid; + mode_t mode; uint32_t rdev; -} tbd_stat_t; +}; extern tbd_stat_t* tbd_stat(const char *path); extern void tbd_stat_free(tbd_stat_t *file); diff --git a/tbdiff/tbdiff-xattrs.c b/tbdiff/tbdiff-xattrs.c index 95d263f..c020ee5 100644 --- a/tbdiff/tbdiff-xattrs.c +++ b/tbdiff/tbdiff-xattrs.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Codethink Ltd. + * Copyright (C) 2011-2014 Codethink Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as @@ -18,7 +18,14 @@ #include <string.h> #include <stdlib.h> +#include "config.h" + +#if HAVE_ATTR_XATTR_H #include <attr/xattr.h> +#else +#include <sys/xattr.h> +#endif + #include <errno.h> #include <tbdiff/tbdiff-common.h> @@ -117,7 +124,7 @@ static int name_remove(char const *name, void *ud) { char const *path = ud; if (lremovexattr(path, name) < 0) { switch (errno) { - case ENOATTR: + case ENODATA: return TBD_ERROR(TBD_ERROR_XATTRS_MISSING_ATTR); case ENOTSUP: return TBD_ERROR(TBD_ERROR_XATTRS_NOT_SUPPORTED); |