summaryrefslogtreecommitdiff
path: root/tbdiff
diff options
context:
space:
mode:
Diffstat (limited to 'tbdiff')
-rw-r--r--tbdiff/tbdiff-apply.c267
-rw-r--r--tbdiff/tbdiff-common.h87
-rw-r--r--tbdiff/tbdiff-create.c289
-rw-r--r--tbdiff/tbdiff-io.c202
-rw-r--r--tbdiff/tbdiff-io.h48
-rw-r--r--tbdiff/tbdiff-private.h4
-rw-r--r--tbdiff/tbdiff-stat.c6
-rw-r--r--tbdiff/tbdiff-stat.h18
-rw-r--r--tbdiff/tbdiff-xattrs.c11
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);