summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Brewer <ben.brewer@codethink.co.uk>2014-06-02 15:51:02 +0100
committerBen Brewer <ben.brewer@codethink.co.uk>2014-06-02 15:52:15 +0100
commit20d5fb340c6ad1e7b16c6dc17e3f6c364a5a5515 (patch)
tree3b8966f7eaa6855c0718b52437a374b710a51eca
parent485e76fea076b2a5f0efeab3ac7f98037f4e00c0 (diff)
parentfb454c327097dda283c35a911fef141382aa383f (diff)
downloadtbdiff-20d5fb340c6ad1e7b16c6dc17e3f6c364a5a5515.tar.gz
Merge branch 'baserock/benbrewer/overhaul-v2'
Reviewed-by: Richard Maw Reviewed-by: Lars Wirzenius
-rw-r--r--.gitignore28
-rw-r--r--TODO14
-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
11 files changed, 519 insertions, 455 deletions
diff --git a/.gitignore b/.gitignore
index a2f5be1..6bb8de7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,31 @@ tbdiff-deploy/tbdiff-deploy
*.o
*.log
*.d
+*.la
+*.lo
+*.pc
+.deps
+.libs
+INSTALL
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache
+compile
+config.guess
+config.h
+config.h.in
+config.h.in~
+config.status
+config.sub
+configure
+depcomp
+install-sh
+libtool
+ltmain.sh
+m4/
+missing
+sockbind
+stamp-h1
+symtime
+test-driver
diff --git a/TODO b/TODO
index a7c6da0..d2102d3 100644
--- a/TODO
+++ b/TODO
@@ -12,32 +12,18 @@ There has been a problem while testing on a real system directory tree, during d
----------------------------------------------
Right now the stream parsing and the filesystem operations are both made in one go. This operations should be made separately so that output the stream and dry runs can be performed. We should have a defined struct per command for easier understanding of what goes into the wire.
-+ Abstract endianness
--------------------
-At the moment the endianness of the file is the same than the one used in the image creation host. We need to state the endianness of the file and perform the transformations in those platforms that need it.
-
+ Abstract the stream object
--------------------------
Right now FILE* is used as the stream object. However abstracting the stream object is desirable.
-+ Write atuotools or waf scripts to build and release
----------------------------------------------------
-A simple Makefile is not the best way to maintain a package. Waf or autotools scripts should be put in place.
-
General
=======
- + Use sizeof(var) or (type) instead of fixed byte lengths on fread/fwrite
- + Fix endian issues in case we run the generator on a different
- endianness to the deployer.
+ Separate reading/writing stream data from actual file system operation
+ Create a manifest of deleted/created/modified files
+ Improve commandline for the deploy command
- + Rename the project to trebuchet-differ (tbdiff)
- + Create autotools scripts
+ Improve function namespaces to ease understanding
- + Add copyright headers to all source files
Features
========
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);