1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-06-14 23:44:58 +02:00

Improve type safety of interfaces and drivers.

The function pointer casting used when creating drivers made changing interfaces difficult and led to slightly divergent driver implementations.  Unit testing caught production-level errors but there were a lot of small issues and the process was harder than it should have been.

Use void pointers instead so that no casts are required.  Introduce the THIS_VOID and THIS() macros to make dealing with void pointers a little safer.

Since we don't want to expose void pointers in header files, driver functions have been removed from the headers and the various driver objects return their interface type.  This cuts down on accessor methods and the vast majority of those functions were not being used.  Move functions that are still required to .intern.h.

Remove the special "C" crypto functions that were used in libc and instead use the standard interface.
This commit is contained in:
David Steele
2019-05-02 17:52:24 -04:00
parent 28359eea83
commit 8c712d89eb
104 changed files with 2701 additions and 4219 deletions

View File

@ -55,6 +55,14 @@
<p>Don't append <code>strerror()</code> to error message when <code>errno</code> is 0.</p>
</release-item>
<release-item>
<release-item-contributor-list>
<release-item-reviewer id="cynthia.shang"/>
</release-item-contributor-list>
<p>Improve type safety of interfaces and drivers.</p>
</release-item>
<release-item>
<p>Various <code>Buffer</code> improvements.</p>
</release-item>

View File

@ -18,6 +18,10 @@ new(class, mode, type, key, keySize, digest = NULL)
CODE:
RETVAL = NULL;
CHECK(type != NULL);
CHECK(key != NULL);
CHECK(keySize != 0);
// Not much point to this but it keeps the var from being unused
if (strcmp(class, PACKAGE_NAME_LIBC "::Cipher::Block") != 0)
croak("unexpected class name '%s'", class);
@ -25,10 +29,9 @@ CODE:
MEM_CONTEXT_XS_NEW_BEGIN("cipherBlockXs")
{
RETVAL = memNew(sizeof(CipherBlockXs));
RETVAL->memContext = MEM_COMTEXT_XS();
RETVAL->pxPayload = cipherBlockNewC(mode, type, key, keySize, digest);
RETVAL->pxPayload = cipherBlockNew(mode, cipherType(STR(type)), BUF(key, keySize), digest == NULL ? NULL : STR(digest));
}
MEM_CONTEXT_XS_NEW_END();
OUTPUT:
@ -47,10 +50,27 @@ CODE:
STRLEN tSize;
const unsigned char *sourcePtr = (const unsigned char *)SvPV(source, tSize);
RETVAL = NEWSV(0, cipherBlockProcessSizeC(self->pxPayload, tSize));
RETVAL = NEWSV(0, ioBufferSize());
SvPOK_only(RETVAL);
SvCUR_set(RETVAL, cipherBlockProcessC(self->pxPayload, sourcePtr, tSize, (unsigned char *)SvPV_nolen(RETVAL)));
if (tSize > 0)
{
size_t outBufferUsed = 0;
do
{
SvGROW(RETVAL, outBufferUsed + ioBufferSize());
Buffer *outBuffer = bufNewUseC((unsigned char *)SvPV_nolen(RETVAL) + outBufferUsed, ioBufferSize());
ioFilterProcessInOut(self->pxPayload, BUF(sourcePtr, tSize), outBuffer);
outBufferUsed += bufUsed(outBuffer);
}
while (ioFilterInputSame(self->pxPayload));
SvCUR_set(RETVAL, outBufferUsed);
}
else
SvCUR_set(RETVAL, 0);
}
MEM_CONTEXT_XS_END();
OUTPUT:
@ -65,10 +85,22 @@ CODE:
MEM_CONTEXT_XS_BEGIN(self->memContext)
{
RETVAL = NEWSV(0, cipherBlockProcessSizeC(self->pxPayload, 0));
RETVAL = NEWSV(0, ioBufferSize());
SvPOK_only(RETVAL);
SvCUR_set(RETVAL, cipherBlockFlushC(self->pxPayload, (unsigned char *)SvPV_nolen(RETVAL)));
size_t outBufferUsed = 0;
do
{
SvGROW(RETVAL, outBufferUsed + ioBufferSize());
Buffer *outBuffer = bufNewUseC((unsigned char *)SvPV_nolen(RETVAL) + outBufferUsed, ioBufferSize());
ioFilterProcessInOut(self->pxPayload, NULL, outBuffer);
outBufferUsed += bufUsed(outBuffer);
}
while (!ioFilterDone(self->pxPayload));
SvCUR_set(RETVAL, outBufferUsed);
}
MEM_CONTEXT_XS_END();
OUTPUT:

View File

@ -1,7 +1,9 @@
/***********************************************************************************************************************************
Block Cipher XS Header
***********************************************************************************************************************************/
#include "common/assert.h"
#include "common/crypto/cipherBlock.h"
#include "common/io/io.h"
#include "common/memContext.h"
// Encrypt/decrypt modes
@ -11,5 +13,5 @@ Block Cipher XS Header
typedef struct CipherBlockXs
{
MemContext *memContext;
CipherBlock *pxPayload;
IoFilter *pxPayload;
} CipherBlockXs, *pgBackRest__LibC__Cipher__Block;

View File

@ -36,9 +36,10 @@ CODE:
MEM_CONTEXT_XS_TEMP_BEGIN()
{
STRLEN messageSize;
const unsigned char *messagePtr = (const unsigned char *)SvPV(message, messageSize);
const void *messagePtr = SvPV(message, messageSize);
cryptoHashProcessC(self->pxPayload, messagePtr, messageSize);
if (messageSize > 0)
ioFilterProcessIn(self->pxPayload, BUF(messagePtr, messageSize));
}
MEM_CONTEXT_XS_TEMP_END();
@ -51,7 +52,7 @@ CODE:
MEM_CONTEXT_XS_TEMP_BEGIN()
{
String *hash = bufHex(cryptoHash(self->pxPayload));
const String *hash = varStr(ioFilterResult(self->pxPayload));
RETVAL = newSV(strSize(hash));
SvPOK_only(RETVAL);
@ -82,9 +83,9 @@ CODE:
MEM_CONTEXT_XS_TEMP_BEGIN()
{
STRLEN messageSize;
const unsigned char *messagePtr = (const unsigned char *)SvPV(message, messageSize);
const void *messagePtr = SvPV(message, messageSize);
String *hash = bufHex(cryptoHashOneC(strNew(type), messagePtr, messageSize));
String *hash = bufHex(cryptoHashOne(strNew(type), BUF(messagePtr, messageSize)));
RETVAL = newSV(strSize(hash));
SvPOK_only(RETVAL);

View File

@ -2,10 +2,11 @@
Cryptographic Hashes XS Header
***********************************************************************************************************************************/
#include "common/crypto/hash.h"
#include "common/io/filter/filter.intern.h"
#include "common/memContext.h"
typedef struct CryptoHashXs
{
MemContext *memContext;
CryptoHash *pxPayload;
IoFilter *pxPayload;
} CryptoHashXs, *pgBackRest__LibC__Crypto__Hash;

View File

@ -13,6 +13,8 @@ storageDriverPosixPathRemove(path, errorOnMissing, recurse)
CODE:
MEM_CONTEXT_XS_TEMP_BEGIN()
{
storageDriverPosixPathRemove(storageDriverPosixNew(strNew("/"), 0640, 750, true, NULL), strNew(path), errorOnMissing, recurse);
storagePathRemoveP(
storageDriverPosixNew(strNew("/"), 0640, 750, true, NULL), strNew(path), .errorOnMissing = errorOnMissing,
.recurse = recurse);
}
MEM_CONTEXT_XS_TEMP_END();

View File

@ -232,19 +232,19 @@ command/remote/remote.o: command/remote/remote.c build.auto.h common/assert.h co
common/compress/gzip/common.o: common/compress/gzip/common.c build.auto.h common/assert.h common/compress/gzip/common.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/convert.h
$(CC) $(CFLAGS) $(CMAKE) -c common/compress/gzip/common.c -o common/compress/gzip/common.o
common/compress/gzip/compress.o: common/compress/gzip/compress.c build.auto.h common/assert.h common/compress/gzip/common.h common/compress/gzip/compress.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
common/compress/gzip/compress.o: common/compress/gzip/compress.c build.auto.h common/assert.h common/compress/gzip/common.h common/compress/gzip/compress.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
$(CC) $(CFLAGS) $(CMAKE) -c common/compress/gzip/compress.c -o common/compress/gzip/compress.o
common/compress/gzip/decompress.o: common/compress/gzip/decompress.c build.auto.h common/assert.h common/compress/gzip/common.h common/compress/gzip/decompress.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
common/compress/gzip/decompress.o: common/compress/gzip/decompress.c build.auto.h common/assert.h common/compress/gzip/common.h common/compress/gzip/decompress.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
$(CC) $(CFLAGS) $(CMAKE) -c common/compress/gzip/decompress.c -o common/compress/gzip/decompress.o
common/crypto/cipherBlock.o: common/crypto/cipherBlock.c build.auto.h common/assert.h common/crypto/cipherBlock.h common/crypto/common.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
common/crypto/cipherBlock.o: common/crypto/cipherBlock.c build.auto.h common/assert.h common/crypto/cipherBlock.h common/crypto/common.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
$(CC) $(CFLAGS) $(CMAKE) -c common/crypto/cipherBlock.c -o common/crypto/cipherBlock.o
common/crypto/common.o: common/crypto/common.c build.auto.h common/assert.h common/crypto/common.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/stackTrace.h common/type/convert.h
$(CC) $(CFLAGS) $(CMAKE) -c common/crypto/common.c -o common/crypto/common.o
common/crypto/hash.o: common/crypto/hash.c build.auto.h common/assert.h common/crypto/common.h common/crypto/hash.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
common/crypto/hash.o: common/crypto/hash.c build.auto.h common/assert.h common/crypto/common.h common/crypto/hash.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
$(CC) $(CFLAGS) $(CMAKE) -c common/crypto/hash.c -o common/crypto/hash.o
common/debug.o: common/debug.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/stackTrace.h common/type/convert.h
@ -259,7 +259,7 @@ common/encode/base64.o: common/encode/base64.c build.auto.h common/assert.h comm
common/error.o: common/error.c build.auto.h common/error.auto.c common/error.auto.h common/error.h common/logLevel.h common/stackTrace.h
$(CC) $(CFLAGS) $(CMAKE) -c common/error.c -o common/error.o
common/exec.o: common/exec.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/exec.h common/io/filter/filter.h common/io/filter/group.h common/io/handleRead.h common/io/handleWrite.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h
common/exec.o: common/exec.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/exec.h common/io/filter/filter.h common/io/filter/group.h common/io/handleRead.h common/io/handleWrite.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h common/wait.h
$(CC) $(CFLAGS) $(CMAKE) -c common/exec.c -o common/exec.o
common/exit.o: common/exit.c build.auto.h command/command.h common/assert.h common/debug.h common/error.auto.h common/error.h common/exit.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h perl/exec.h protocol/client.h protocol/command.h protocol/helper.h
@ -271,13 +271,13 @@ common/fork.o: common/fork.c build.auto.h common/assert.h common/debug.h common/
common/ini.o: common/ini.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/write.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
$(CC) $(CFLAGS) $(CMAKE) -c common/ini.c -o common/ini.o
common/io/bufferRead.o: common/io/bufferRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/bufferRead.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
common/io/bufferRead.o: common/io/bufferRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/bufferRead.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
$(CC) $(CFLAGS) $(CMAKE) -c common/io/bufferRead.c -o common/io/bufferRead.o
common/io/bufferWrite.o: common/io/bufferWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/bufferWrite.h common/io/filter/filter.h common/io/filter/group.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
common/io/bufferWrite.o: common/io/bufferWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/bufferWrite.h common/io/filter/filter.h common/io/filter/group.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
$(CC) $(CFLAGS) $(CMAKE) -c common/io/bufferWrite.c -o common/io/bufferWrite.o
common/io/filter/buffer.o: common/io/filter/buffer.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/buffer.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
common/io/filter/buffer.o: common/io/filter/buffer.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/buffer.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
$(CC) $(CFLAGS) $(CMAKE) -c common/io/filter/buffer.c -o common/io/filter/buffer.o
common/io/filter/filter.o: common/io/filter/filter.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
@ -286,16 +286,16 @@ common/io/filter/filter.o: common/io/filter/filter.c build.auto.h common/assert.
common/io/filter/group.o: common/io/filter/group.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/buffer.h common/io/filter/filter.h common/io/filter/filter.intern.h common/io/filter/group.h common/io/io.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/list.h common/type/string.h common/type/variant.h common/type/variantList.h
$(CC) $(CFLAGS) $(CMAKE) -c common/io/filter/group.c -o common/io/filter/group.o
common/io/filter/size.o: common/io/filter/size.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/io/filter/size.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
common/io/filter/size.o: common/io/filter/size.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/io/filter/size.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
$(CC) $(CFLAGS) $(CMAKE) -c common/io/filter/size.c -o common/io/filter/size.o
common/io/handleRead.o: common/io/handleRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/handleRead.h common/io/read.h common/io/read.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
common/io/handleRead.o: common/io/handleRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/handleRead.h common/io/read.h common/io/read.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
$(CC) $(CFLAGS) $(CMAKE) -c common/io/handleRead.c -o common/io/handleRead.o
common/io/handleWrite.o: common/io/handleWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/handleWrite.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
common/io/handleWrite.o: common/io/handleWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/handleWrite.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
$(CC) $(CFLAGS) $(CMAKE) -c common/io/handleWrite.c -o common/io/handleWrite.o
common/io/http/client.o: common/io/http/client.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/common.h common/io/http/header.h common/io/http/query.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/tls/client.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h
common/io/http/client.o: common/io/http/client.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/common.h common/io/http/header.h common/io/http/query.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/tls/client.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h
$(CC) $(CFLAGS) $(CMAKE) -c common/io/http/client.c -o common/io/http/client.o
common/io/http/common.o: common/io/http/common.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/http/common.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h
@ -313,13 +313,13 @@ common/io/io.o: common/io/io.c build.auto.h common/assert.h common/debug.h commo
common/io/read.o: common/io/read.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/read.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
$(CC) $(CFLAGS) $(CMAKE) -c common/io/read.c -o common/io/read.o
common/io/tls/client.o: common/io/tls/client.c build.auto.h common/assert.h common/crypto/common.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/tls/client.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h common/wait.h
common/io/tls/client.o: common/io/tls/client.c build.auto.h common/assert.h common/crypto/common.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/tls/client.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h common/wait.h
$(CC) $(CFLAGS) $(CMAKE) -c common/io/tls/client.c -o common/io/tls/client.o
common/io/write.o: common/io/write.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
$(CC) $(CFLAGS) $(CMAKE) -c common/io/write.c -o common/io/write.o
common/lock.o: common/lock.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/handleWrite.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h storage/storage.intern.h version.h
common/lock.o: common/lock.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/handleWrite.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/helper.h storage/info.h storage/storage.h storage/storage.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c common/lock.c -o common/lock.o
common/log.o: common/log.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/stackTrace.h common/time.h common/type/convert.h
@ -388,7 +388,7 @@ config/parse.o: config/parse.c build.auto.h common/assert.h common/debug.h commo
config/protocol.o: config/protocol.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/protocol.h protocol/client.h protocol/command.h protocol/server.h
$(CC) $(CFLAGS) $(CMAKE) -c config/protocol.c -o config/protocol.o
info/info.o: info/info.c build.auto.h common/assert.h common/crypto/cipherBlock.h common/crypto/common.h common/crypto/hash.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/json.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h info/info.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
info/info.o: info/info.c build.auto.h common/assert.h common/crypto/cipherBlock.h common/crypto/common.h common/crypto/hash.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/filter.intern.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/json.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h info/info.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c info/info.c -o info/info.o
info/infoArchive.o: info/infoArchive.c build.auto.h common/assert.h common/crypto/common.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h info/info.h info/infoArchive.h info/infoPg.h postgres/interface.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
@ -409,7 +409,7 @@ main.o: main.c build.auto.h command/archive/get/get.h command/archive/push/push.
perl/config.o: perl/config.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/json.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h
$(CC) $(CFLAGS) $(CMAKE) -c perl/config.c -o perl/config.o
perl/exec.o: perl/exec.c ../libc/LibC.h build.auto.h common/assert.h common/crypto/cipherBlock.h common/crypto/common.h common/crypto/hash.h common/debug.h common/encode.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h config/parse.h perl/config.h perl/embed.auto.c perl/exec.h perl/libc.auto.c postgres/pageChecksum.h storage/driver/posix/fileRead.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h version.h ../libc/xs/common/encode.xsh ../libc/xs/crypto/cipherBlock.xsh ../libc/xs/crypto/hash.xsh
perl/exec.o: perl/exec.c ../libc/LibC.h build.auto.h common/assert.h common/crypto/cipherBlock.h common/crypto/common.h common/crypto/hash.h common/debug.h common/encode.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h config/parse.h perl/config.h perl/embed.auto.c perl/exec.h perl/libc.auto.c postgres/pageChecksum.h storage/driver/posix/storage.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h ../libc/xs/common/encode.xsh ../libc/xs/crypto/cipherBlock.xsh ../libc/xs/crypto/hash.xsh
$(CC) $(CFLAGS) $(CMAKE) -c perl/exec.c -o perl/exec.o
postgres/interface.o: postgres/interface.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h postgres/interface.h postgres/interface/version.h postgres/version.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
@ -469,50 +469,50 @@ protocol/parallelJob.o: protocol/parallelJob.c build.auto.h common/assert.h comm
protocol/server.o: protocol/server.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/json.h common/type/keyValue.h common/type/list.h common/type/string.h common/type/variant.h common/type/variantList.h protocol/client.h protocol/command.h protocol/server.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c protocol/server.c -o protocol/server.o
storage/driver/cifs/storage.o: storage/driver/cifs/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/cifs/storage.h storage/driver/posix/fileRead.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
storage/driver/cifs/storage.o: storage/driver/cifs/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/cifs/storage.h storage/driver/posix/storage.h storage/driver/posix/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/cifs/storage.c -o storage/driver/cifs/storage.o
storage/driver/posix/common.o: storage/driver/posix/common.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h storage/driver/posix/common.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/posix/common.c -o storage/driver/posix/common.o
storage/driver/posix/fileRead.o: storage/driver/posix/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h storage/driver/posix/common.h storage/driver/posix/fileRead.h storage/driver/posix/storage.h storage/fileRead.h storage/fileRead.intern.h
storage/driver/posix/fileRead.o: storage/driver/posix/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/posix/common.h storage/driver/posix/fileRead.h storage/driver/posix/storage.h storage/driver/posix/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/posix/fileRead.c -o storage/driver/posix/fileRead.o
storage/driver/posix/fileWrite.o: storage/driver/posix/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h storage/driver/posix/common.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/fileWrite.h storage/fileWrite.intern.h version.h
storage/driver/posix/fileWrite.o: storage/driver/posix/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/posix/common.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/driver/posix/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/posix/fileWrite.c -o storage/driver/posix/fileWrite.o
storage/driver/posix/storage.o: storage/driver/posix/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/posix/common.h storage/driver/posix/fileRead.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
storage/driver/posix/storage.o: storage/driver/posix/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/posix/common.h storage/driver/posix/fileRead.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/driver/posix/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/posix/storage.c -o storage/driver/posix/storage.o
storage/driver/remote/fileRead.o: storage/driver/remote/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/read.intern.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/client.h protocol/command.h protocol/server.h storage/driver/remote/fileRead.h storage/driver/remote/protocol.h storage/driver/remote/storage.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
storage/driver/remote/fileRead.o: storage/driver/remote/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/client.h protocol/command.h protocol/server.h storage/driver/remote/fileRead.h storage/driver/remote/protocol.h storage/driver/remote/storage.h storage/driver/remote/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/remote/fileRead.c -o storage/driver/remote/fileRead.o
storage/driver/remote/fileWrite.o: storage/driver/remote/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/client.h protocol/command.h protocol/server.h storage/driver/remote/fileWrite.h storage/driver/remote/protocol.h storage/driver/remote/storage.h storage/fileRead.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
storage/driver/remote/fileWrite.o: storage/driver/remote/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/client.h protocol/command.h protocol/server.h storage/driver/remote/fileWrite.h storage/driver/remote/protocol.h storage/driver/remote/storage.h storage/driver/remote/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/remote/fileWrite.c -o storage/driver/remote/fileWrite.o
storage/driver/remote/protocol.o: storage/driver/remote/protocol.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/server.h storage/driver/remote/protocol.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h storage/storage.intern.h
storage/driver/remote/protocol.o: storage/driver/remote/protocol.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/server.h storage/driver/remote/protocol.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/helper.h storage/info.h storage/storage.h storage/storage.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/remote/protocol.c -o storage/driver/remote/protocol.o
storage/driver/remote/storage.o: storage/driver/remote/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/client.h protocol/command.h protocol/helper.h protocol/server.h storage/driver/remote/fileRead.h storage/driver/remote/fileWrite.h storage/driver/remote/protocol.h storage/driver/remote/storage.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
storage/driver/remote/storage.o: storage/driver/remote/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/client.h protocol/command.h protocol/server.h storage/driver/remote/fileRead.h storage/driver/remote/fileWrite.h storage/driver/remote/protocol.h storage/driver/remote/storage.h storage/driver/remote/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/remote/storage.c -o storage/driver/remote/storage.o
storage/driver/s3/fileRead.o: storage/driver/s3/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/read.intern.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/s3/fileRead.h storage/driver/s3/storage.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
storage/driver/s3/fileRead.o: storage/driver/s3/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/s3/fileRead.h storage/driver/s3/storage.h storage/driver/s3/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/s3/fileRead.c -o storage/driver/s3/fileRead.o
storage/driver/s3/fileWrite.o: storage/driver/s3/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/type/xml.h storage/driver/s3/fileWrite.h storage/driver/s3/storage.h storage/fileRead.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
storage/driver/s3/fileWrite.o: storage/driver/s3/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/type/xml.h storage/driver/s3/fileWrite.h storage/driver/s3/storage.h storage/driver/s3/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/s3/fileWrite.c -o storage/driver/s3/fileWrite.o
storage/driver/s3/storage.o: storage/driver/s3/storage.c build.auto.h common/assert.h common/crypto/hash.h common/debug.h common/encode.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/common.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/type/xml.h storage/driver/s3/fileRead.h storage/driver/s3/fileWrite.h storage/driver/s3/storage.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
storage/driver/s3/storage.o: storage/driver/s3/storage.c build.auto.h common/assert.h common/crypto/hash.h common/debug.h common/encode.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/common.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/type/xml.h storage/driver/s3/fileRead.h storage/driver/s3/fileWrite.h storage/driver/s3/storage.h storage/driver/s3/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/s3/storage.c -o storage/driver/s3/storage.o
storage/fileRead.o: storage/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h storage/fileRead.h storage/fileRead.intern.h
storage/fileRead.o: storage/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h storage/fileRead.h storage/fileRead.intern.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/fileRead.c -o storage/fileRead.o
storage/fileWrite.o: storage/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h storage/fileWrite.h storage/fileWrite.intern.h version.h
storage/fileWrite.o: storage/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h storage/fileWrite.h storage/fileWrite.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/fileWrite.c -o storage/fileWrite.o
storage/helper.o: storage/helper.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h protocol/client.h protocol/command.h protocol/helper.h storage/driver/cifs/storage.h storage/driver/posix/fileRead.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/driver/remote/storage.h storage/driver/s3/storage.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h storage/storage.intern.h
storage/helper.o: storage/helper.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h protocol/client.h protocol/command.h protocol/helper.h storage/driver/cifs/storage.h storage/driver/posix/storage.h storage/driver/remote/storage.h storage/driver/s3/storage.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/helper.h storage/info.h storage/storage.h storage/storage.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/helper.c -o storage/helper.o
storage/storage.o: storage/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
storage/storage.o: storage/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
$(CC) $(CFLAGS) $(CMAKE) -c storage/storage.c -o storage/storage.o

View File

@ -153,14 +153,12 @@ archiveGetFile(
if (cipherType != cipherTypeNone)
{
ioFilterGroupAdd(
filterGroup,
cipherBlockFilter(
cipherBlockNew(cipherModeDecrypt, cipherType, BUFSTR(archiveGetCheckResult.cipherPass), NULL)));
filterGroup, cipherBlockNew(cipherModeDecrypt, cipherType, BUFSTR(archiveGetCheckResult.cipherPass), NULL));
}
// If file is compressed then add the decompression filter
if (strEndsWithZ(archiveGetCheckResult.archiveFileActual, "." GZIP_EXT))
ioFilterGroupAdd(filterGroup, gzipDecompressFilter(gzipDecompressNew(false)));
ioFilterGroupAdd(filterGroup, gzipDecompressNew(false));
ioWriteFilterGroupSet(storageFileWriteIo(destination), filterGroup);

View File

@ -74,7 +74,7 @@ archivePushFile(
{
// Generate a sha1 checksum for the wal segment. ??? Probably need a function in storage for this.
IoRead *read = storageFileReadIo(storageNewReadNP(storageLocal(), walSource));
IoFilterGroup *filterGroup = ioFilterGroupAdd(ioFilterGroupNew(), cryptoHashFilter(cryptoHashNew(HASH_TYPE_SHA1_STR)));
IoFilterGroup *filterGroup = ioFilterGroupAdd(ioFilterGroupNew(), cryptoHashNew(HASH_TYPE_SHA1_STR));
ioReadFilterGroupSet(read, filterGroup);
Buffer *buffer = bufNew(ioBufferSize());
@ -126,15 +126,12 @@ archivePushFile(
if (isSegment && compress)
{
strCat(archiveDestination, "." GZIP_EXT);
ioFilterGroupAdd(filterGroup, gzipCompressFilter(gzipCompressNew(compressLevel, false)));
ioFilterGroupAdd(filterGroup, gzipCompressNew(compressLevel, false));
}
// If there is a cipher then add the encrypt filter
if (cipherType != cipherTypeNone)
{
ioFilterGroupAdd(
filterGroup, cipherBlockFilter(cipherBlockNew(cipherModeEncrypt, cipherType, BUFSTR(cipherPass), NULL)));
}
ioFilterGroupAdd(filterGroup, cipherBlockNew(cipherModeEncrypt, cipherType, BUFSTR(cipherPass), NULL));
ioReadFilterGroupSet(storageFileReadIo(source), filterGroup);

View File

@ -25,9 +25,9 @@ cmdLocal(int handleRead, int handleWrite)
MEM_CONTEXT_TEMP_BEGIN()
{
String *name = strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u", cfgOptionUInt(cfgOptProcess));
IoRead *read = ioHandleReadIo(ioHandleReadNew(name, handleRead, (TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * 1000)));
IoRead *read = ioHandleReadNew(name, handleRead, (TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * 1000));
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(name, handleWrite));
IoWrite *write = ioHandleWriteNew(name, handleWrite);
ioWriteOpen(write);
ProtocolServer *server = protocolServerNew(name, PROTOCOL_SERVICE_LOCAL_STR, read, write);

View File

@ -26,9 +26,9 @@ cmdRemote(int handleRead, int handleWrite)
MEM_CONTEXT_TEMP_BEGIN()
{
String *name = strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u", cfgOptionUInt(cfgOptProcess));
IoRead *read = ioHandleReadIo(ioHandleReadNew(name, handleRead, (TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * 1000)));
IoRead *read = ioHandleReadNew(name, handleRead, (TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * 1000));
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(name, handleWrite));
IoWrite *write = ioHandleWriteNew(name, handleWrite);
ioWriteOpen(write);
ProtocolServer *server = protocolServerNew(name, PROTOCOL_SERVICE_REMOTE_STR, read, write);

View File

@ -12,6 +12,7 @@ Gzip Compress
#include "common/io/filter/filter.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
/***********************************************************************************************************************************
Filter type constant
@ -22,67 +23,45 @@ Filter type constant
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct GzipCompress
typedef struct GzipCompress
{
MemContext *memContext; // Context to store data
z_stream *stream; // Compression stream state
IoFilter *filter; // Filter interface
bool inputSame; // Is the same input required on the next process call?
bool flush; // Is input complete and flushing in progress?
bool done; // Is compression done?
};
} GzipCompress;
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
static String *
gzipCompressToLog(const GzipCompress *this)
{
return strNewFmt(
"{inputSame: %s, done: %s, flushing: %s, availIn: %u}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done),
cvtBoolToConstZ(this->done), this->stream->avail_in);
}
#define FUNCTION_LOG_GZIP_COMPRESS_TYPE \
GzipCompress *
#define FUNCTION_LOG_GZIP_COMPRESS_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, gzipCompressToLog, buffer, bufferSize)
/***********************************************************************************************************************************
Compression constants
***********************************************************************************************************************************/
#define MEM_LEVEL 9
/***********************************************************************************************************************************
New object
***********************************************************************************************************************************/
GzipCompress *
gzipCompressNew(int level, bool raw)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(INT, level);
FUNCTION_LOG_PARAM(BOOL, raw);
FUNCTION_LOG_END();
ASSERT(level >= -1 && level <= 9);
GzipCompress *this = NULL;
MEM_CONTEXT_NEW_BEGIN("GzipCompress")
{
// Allocate state and set context
this = memNew(sizeof(GzipCompress));
this->memContext = MEM_CONTEXT_NEW();
// Create gzip stream
this->stream = memNew(sizeof(z_stream));
gzipError(deflateInit2(this->stream, level, Z_DEFLATED, gzipWindowBits(raw), MEM_LEVEL, Z_DEFAULT_STRATEGY));
// Set free callback to ensure gzip context is freed
memContextCallback(this->memContext, (MemContextCallback)gzipCompressFree, this);
// Create filter interface
this->filter = ioFilterNewP(
GZIP_COMPRESS_FILTER_TYPE_STR, this, .done = (IoFilterInterfaceDone)gzipCompressDone,
.inOut = (IoFilterInterfaceProcessInOut)gzipCompressProcess,
.inputSame = (IoFilterInterfaceInputSame)gzipCompressInputSame);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(GZIP_COMPRESS, this);
}
/***********************************************************************************************************************************
Compress data
***********************************************************************************************************************************/
void
gzipCompressProcess(GzipCompress *this, const Buffer *uncompressed, Buffer *compressed)
static void
gzipCompressProcess(THIS_VOID, const Buffer *uncompressed, Buffer *compressed)
{
THIS(GzipCompress);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(GZIP_COMPRESS, this);
FUNCTION_LOG_PARAM(BUFFER, uncompressed);
@ -136,9 +115,11 @@ gzipCompressProcess(GzipCompress *this, const Buffer *uncompressed, Buffer *comp
/***********************************************************************************************************************************
Is compress done?
***********************************************************************************************************************************/
bool
gzipCompressDone(const GzipCompress *this)
static bool
gzipCompressDone(const THIS_VOID)
{
THIS(const GzipCompress);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(GZIP_COMPRESS, this);
FUNCTION_TEST_END();
@ -148,27 +129,14 @@ gzipCompressDone(const GzipCompress *this)
FUNCTION_TEST_RETURN(this->done);
}
/***********************************************************************************************************************************
Get filter interface
***********************************************************************************************************************************/
IoFilter *
gzipCompressFilter(const GzipCompress *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(GZIP_COMPRESS, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->filter);
}
/***********************************************************************************************************************************
Is the same input required on the next process call?
***********************************************************************************************************************************/
bool
gzipCompressInputSame(const GzipCompress *this)
static bool
gzipCompressInputSame(const THIS_VOID)
{
THIS(const GzipCompress);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(GZIP_COMPRESS, this);
FUNCTION_TEST_END();
@ -178,21 +146,10 @@ gzipCompressInputSame(const GzipCompress *this)
FUNCTION_TEST_RETURN(this->inputSame);
}
/***********************************************************************************************************************************
Render as string for logging
***********************************************************************************************************************************/
String *
gzipCompressToLog(const GzipCompress *this)
{
return strNewFmt(
"{inputSame: %s, done: %s, flushing: %s, availIn: %u}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done),
cvtBoolToConstZ(this->done), this->stream->avail_in);
}
/***********************************************************************************************************************************
Free memory
***********************************************************************************************************************************/
void
static void
gzipCompressFree(GzipCompress *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
@ -210,3 +167,40 @@ gzipCompressFree(GzipCompress *this)
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
New object
***********************************************************************************************************************************/
IoFilter *
gzipCompressNew(int level, bool raw)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(INT, level);
FUNCTION_LOG_PARAM(BOOL, raw);
FUNCTION_LOG_END();
ASSERT(level >= -1 && level <= 9);
IoFilter *this = NULL;
MEM_CONTEXT_NEW_BEGIN("GzipCompress")
{
GzipCompress *driver = memNew(sizeof(GzipCompress));
driver->memContext = MEM_CONTEXT_NEW();
// Create gzip stream
driver->stream = memNew(sizeof(z_stream));
gzipError(deflateInit2(driver->stream, level, Z_DEFLATED, gzipWindowBits(raw), MEM_LEVEL, Z_DEFAULT_STRATEGY));
// Set free callback to ensure gzip context is freed
memContextCallback(driver->memContext, (MemContextCallback)gzipCompressFree, driver);
// Create filter interface
this = ioFilterNewP(
GZIP_COMPRESS_FILTER_TYPE_STR, driver, .done = gzipCompressDone, .inOut = gzipCompressProcess,
.inputSame = gzipCompressInputSame);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
}

View File

@ -6,44 +6,11 @@ Compress IO using the gzip format.
#ifndef COMMON_COMPRESS_GZIP_COMPRESS_H
#define COMMON_COMPRESS_GZIP_COMPRESS_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct GzipCompress GzipCompress;
#include "common/io/filter/filter.h"
#include "common/type/buffer.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
GzipCompress *gzipCompressNew(int level, bool raw);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void gzipCompressProcess(GzipCompress *this, const Buffer *uncompressed, Buffer *compressed);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
bool gzipCompressDone(const GzipCompress *this);
IoFilter *gzipCompressFilter(const GzipCompress *this);
bool gzipCompressInputSame(const GzipCompress *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void gzipCompressFree(GzipCompress *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
String *gzipCompressToLog(const GzipCompress *this);
#define FUNCTION_LOG_GZIP_COMPRESS_TYPE \
GzipCompress *
#define FUNCTION_LOG_GZIP_COMPRESS_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, gzipCompressToLog, buffer, bufferSize)
IoFilter *gzipCompressNew(int level, bool raw);
#endif

View File

@ -12,6 +12,7 @@ Gzip Decompress
#include "common/io/filter/filter.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
/***********************************************************************************************************************************
Filter type constant
@ -22,59 +23,40 @@ Filter type constant
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct GzipDecompress
typedef struct GzipDecompress
{
MemContext *memContext; // Context to store data
z_stream *stream; // Decompression stream state
IoFilter *filter; // Filter interface
int result; // Result of last operation
bool inputSame; // Is the same input required on the next process call?
bool done; // Is decompression done?
};
} GzipDecompress;
/***********************************************************************************************************************************
New object
Macros for function logging
***********************************************************************************************************************************/
String *
gzipDecompressToLog(const GzipDecompress *this)
{
return strNewFmt(
"{inputSame: %s, done: %s, availIn: %u}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done),
this->stream->avail_in);
}
#define FUNCTION_LOG_GZIP_DECOMPRESS_TYPE \
GzipDecompress *
gzipDecompressNew(bool raw)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(BOOL, raw);
FUNCTION_LOG_END();
GzipDecompress *this = NULL;
MEM_CONTEXT_NEW_BEGIN("GzipDecompress")
{
// Allocate state and set context
this = memNew(sizeof(GzipDecompress));
this->memContext = MEM_CONTEXT_NEW();
// Create gzip stream
this->stream = memNew(sizeof(z_stream));
gzipError(this->result = inflateInit2(this->stream, gzipWindowBits(raw)));
// Set free callback to ensure gzip context is freed
memContextCallback(this->memContext, (MemContextCallback)gzipDecompressFree, this);
// Create filter interface
this->filter = ioFilterNewP(
GZIP_DECOMPRESS_FILTER_TYPE_STR, this, .done = (IoFilterInterfaceDone)gzipDecompressDone,
.inOut = (IoFilterInterfaceProcessInOut)gzipDecompressProcess,
.inputSame = (IoFilterInterfaceInputSame)gzipDecompressInputSame);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(GZIP_DECOMPRESS, this);
}
#define FUNCTION_LOG_GZIP_DECOMPRESS_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, gzipDecompressToLog, buffer, bufferSize)
/***********************************************************************************************************************************
Decompress data
***********************************************************************************************************************************/
void
gzipDecompressProcess(GzipDecompress *this, const Buffer *compressed, Buffer *uncompressed)
gzipDecompressProcess(THIS_VOID, const Buffer *compressed, Buffer *uncompressed)
{
THIS(GzipDecompress);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(GZIP_DECOMPRESS, this);
FUNCTION_LOG_PARAM(BUFFER, compressed);
@ -113,8 +95,10 @@ gzipDecompressProcess(GzipDecompress *this, const Buffer *compressed, Buffer *un
Is decompress done?
***********************************************************************************************************************************/
bool
gzipDecompressDone(const GzipDecompress *this)
gzipDecompressDone(const THIS_VOID)
{
THIS(const GzipDecompress);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(GZIP_DECOMPRESS, this);
FUNCTION_TEST_END();
@ -124,27 +108,14 @@ gzipDecompressDone(const GzipDecompress *this)
FUNCTION_TEST_RETURN(this->done);
}
/***********************************************************************************************************************************
Get filter interface
***********************************************************************************************************************************/
IoFilter *
gzipDecompressFilter(const GzipDecompress *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(GZIP_DECOMPRESS, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->filter);
}
/***********************************************************************************************************************************
Is the same input required on the next process call?
***********************************************************************************************************************************/
bool
gzipDecompressInputSame(const GzipDecompress *this)
gzipDecompressInputSame(const THIS_VOID)
{
THIS(const GzipDecompress);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(GZIP_DECOMPRESS, this);
FUNCTION_TEST_END();
@ -154,21 +125,10 @@ gzipDecompressInputSame(const GzipDecompress *this)
FUNCTION_TEST_RETURN(this->inputSame);
}
/***********************************************************************************************************************************
Render as string for logging
***********************************************************************************************************************************/
String *
gzipDecompressToLog(const GzipDecompress *this)
{
return strNewFmt(
"{inputSame: %s, done: %s, availIn: %u}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done),
this->stream->avail_in);
}
/***********************************************************************************************************************************
Free memory
***********************************************************************************************************************************/
void
static void
gzipDecompressFree(GzipDecompress *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
@ -185,3 +145,38 @@ gzipDecompressFree(GzipDecompress *this)
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
New object
***********************************************************************************************************************************/
IoFilter *
gzipDecompressNew(bool raw)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(BOOL, raw);
FUNCTION_LOG_END();
IoFilter *this = NULL;
MEM_CONTEXT_NEW_BEGIN("GzipDecompress")
{
// Allocate state and set context
GzipDecompress *driver = memNew(sizeof(GzipDecompress));
driver->memContext = MEM_CONTEXT_NEW();
// Create gzip stream
driver->stream = memNew(sizeof(z_stream));
gzipError(driver->result = inflateInit2(driver->stream, gzipWindowBits(raw)));
// Set free callback to ensure gzip context is freed
memContextCallback(driver->memContext, (MemContextCallback)gzipDecompressFree, driver);
// Create filter interface
this = ioFilterNewP(
GZIP_DECOMPRESS_FILTER_TYPE_STR, driver, .done = gzipDecompressDone, .inOut = gzipDecompressProcess,
.inputSame = gzipDecompressInputSame);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
}

View File

@ -6,44 +6,11 @@ Decompress IO from the gzip format.
#ifndef COMMON_COMPRESS_GZIP_DECOMPRESS_H
#define COMMON_COMPRESS_GZIP_DECOMPRESS_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct GzipDecompress GzipDecompress;
#include "common/io/filter/filter.h"
#include "common/type/string.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
GzipDecompress *gzipDecompressNew(bool raw);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void gzipDecompressProcess(GzipDecompress *this, const Buffer *compressed, Buffer *uncompressed);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
bool gzipDecompressDone(const GzipDecompress *this);
IoFilter *gzipDecompressFilter(const GzipDecompress *this);
bool gzipDecompressInputSame(const GzipDecompress *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void gzipDecompressFree(GzipDecompress *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
String *gzipDecompressToLog(const GzipDecompress *this);
#define FUNCTION_LOG_GZIP_DECOMPRESS_TYPE \
GzipDecompress *
#define FUNCTION_LOG_GZIP_DECOMPRESS_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, gzipDecompressToLog, buffer, bufferSize)
IoFilter *gzipDecompressNew(bool raw);
#endif

View File

@ -14,6 +14,7 @@ Block Cipher
#include "common/io/filter/filter.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
/***********************************************************************************************************************************
Filter type constant
@ -35,7 +36,7 @@ Header constants and sizes
/***********************************************************************************************************************************
Track state during block encrypt/decrypt
***********************************************************************************************************************************/
struct CipherBlock
typedef struct CipherBlock
{
MemContext *memContext; // Context to store data
CipherMode mode; // Mode encrypt/decrypt
@ -49,106 +50,55 @@ struct CipherBlock
const EVP_MD *digest; // Message digest object
EVP_CIPHER_CTX *cipherContext; // Encrypt/decrypt context
IoFilter *filter; // Filter interface
Buffer *buffer; // Internal buffer in case destination buffer isn't large enough
bool inputSame; // Is the same input required on next process call?
bool done; // Is processing done?
};
} CipherBlock;
/***********************************************************************************************************************************
New block encrypt/decrypt object
Macros for function logging
***********************************************************************************************************************************/
CipherBlock *
cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, const String *digestName)
String *
cipherBlockToLog(const CipherBlock *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(ENUM, mode);
FUNCTION_LOG_PARAM(ENUM, cipherType);
FUNCTION_LOG_PARAM(BUFFER, pass);
FUNCTION_LOG_PARAM(STRING, digestName);
FUNCTION_LOG_END();
ASSERT(cipherType == cipherTypeAes256Cbc);
ASSERT(pass != NULL);
ASSERT(bufSize(pass) > 0);
FUNCTION_LOG_RETURN(
CIPHER_BLOCK, cipherBlockNewC(mode, CIPHER_TYPE_AES_256_CBC, bufPtr(pass), bufSize(pass), strPtr(digestName)));
return strNewFmt(
"{inputSame: %s, done: %s}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done));
}
#define FUNCTION_LOG_CIPHER_BLOCK_TYPE \
CipherBlock *
cipherBlockNewC(CipherMode mode, const char *cipherName, const unsigned char *pass, size_t passSize, const char *digestName)
#define FUNCTION_LOG_CIPHER_BLOCK_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, cipherBlockToLog, buffer, bufferSize)
/***********************************************************************************************************************************
Free object
***********************************************************************************************************************************/
static void
cipherBlockFree(CipherBlock *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(ENUM, mode);
FUNCTION_LOG_PARAM(STRINGZ, cipherName);
FUNCTION_LOG_PARAM_P(UCHARDATA, pass);
FUNCTION_LOG_PARAM(SIZE, passSize);
FUNCTION_LOG_PARAM(STRINGZ, digestName);
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
FUNCTION_LOG_END();
ASSERT(cipherName != NULL);
ASSERT(pass != NULL);
ASSERT(passSize > 0);
// Init crypto subsystem
cryptoInit();
// Lookup cipher by name. This means the ciphers passed in must exactly match a name expected by OpenSSL. This is a good
// thing since the name required by the openssl command-line tool will match what is used by pgBackRest.
const EVP_CIPHER *cipher = EVP_get_cipherbyname(cipherName);
if (!cipher)
THROW_FMT(AssertError, "unable to load cipher '%s'", cipherName);
// Lookup digest. If not defined it will be set to sha1.
const EVP_MD *digest = NULL;
if (digestName)
digest = EVP_get_digestbyname(digestName);
else
digest = EVP_sha1();
if (!digest)
THROW_FMT(AssertError, "unable to load digest '%s'", digestName);
// Allocate memory to hold process state
CipherBlock *this = NULL;
MEM_CONTEXT_NEW_BEGIN("cipherBlock")
if (this != NULL)
{
// Allocate state and set context
this = memNew(sizeof(CipherBlock));
this->memContext = MEM_CONTEXT_NEW();
// Free cipher context
if (this->cipherContext)
EVP_CIPHER_CTX_cleanup(this->cipherContext);
// Set mode, encrypt or decrypt
this->mode = mode;
// Set cipher and digest
this->cipher = cipher;
this->digest = digest;
// Store the passphrase
this->passSize = passSize;
this->pass = memNewRaw(this->passSize);
memcpy(this->pass, pass, this->passSize);
// Create filter interface
this->filter = ioFilterNewP(
CIPHER_BLOCK_FILTER_TYPE_STR, this, .done = (IoFilterInterfaceDone)cipherBlockDone,
.inOut = (IoFilterInterfaceProcessInOut)cipherBlockProcess,
.inputSame = (IoFilterInterfaceInputSame)cipherBlockInputSame);
// Free mem context
memContextCallbackClear(this->memContext);
memContextFree(this->memContext);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(CIPHER_BLOCK, this);
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Determine how large the destination buffer should be
***********************************************************************************************************************************/
size_t
cipherBlockProcessSizeC(CipherBlock *this, size_t sourceSize)
static size_t
cipherBlockProcessSize(CipherBlock *this, size_t sourceSize)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
@ -170,8 +120,8 @@ cipherBlockProcessSizeC(CipherBlock *this, size_t sourceSize)
/***********************************************************************************************************************************
Encrypt/decrypt data
***********************************************************************************************************************************/
size_t
cipherBlockProcessC(CipherBlock *this, const unsigned char *source, size_t sourceSize, unsigned char *destination)
static size_t
cipherBlockProcessBlock(CipherBlock *this, const unsigned char *source, size_t sourceSize, unsigned char *destination)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
@ -285,12 +235,12 @@ cipherBlockProcessC(CipherBlock *this, const unsigned char *source, size_t sourc
/***********************************************************************************************************************************
Flush the remaining data
***********************************************************************************************************************************/
size_t
cipherBlockFlushC(CipherBlock *this, unsigned char *destination)
static size_t
cipherBlockFlush(CipherBlock *this, Buffer *destination)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
FUNCTION_LOG_PARAM_P(UCHARDATA, destination);
FUNCTION_LOG_PARAM(BUFFER, destination);
FUNCTION_LOG_END();
ASSERT(this != NULL);
@ -304,7 +254,7 @@ cipherBlockFlushC(CipherBlock *this, unsigned char *destination)
THROW(CryptoError, "cipher header missing");
// Only flush remaining data if some data was processed
if (!EVP_CipherFinal(this->cipherContext, destination, (int *)&destinationSize))
if (!EVP_CipherFinal(this->cipherContext, bufRemainsPtr(destination), (int *)&destinationSize))
THROW(CryptoError, "unable to flush");
// Return actual destination size
@ -314,9 +264,11 @@ cipherBlockFlushC(CipherBlock *this, unsigned char *destination)
/***********************************************************************************************************************************
Process function used by C filter
***********************************************************************************************************************************/
void
cipherBlockProcess(CipherBlock *this, const Buffer *source, Buffer *destination)
static void
cipherBlockProcess(THIS_VOID, const Buffer *source, Buffer *destination)
{
THIS(CipherBlock);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
FUNCTION_LOG_PARAM(BUFFER, source);
@ -355,7 +307,7 @@ cipherBlockProcess(CipherBlock *this, const Buffer *source, Buffer *destination)
// Determine how much space is required in the output buffer
Buffer *outputActual = destination;
size_t destinationSize = cipherBlockProcessSizeC(this, source == NULL ? 0 : bufUsed(source));
size_t destinationSize = cipherBlockProcessSize(this, source == NULL ? 0 : bufUsed(source));
if (destinationSize > bufRemains(destination))
{
@ -384,15 +336,15 @@ cipherBlockProcess(CipherBlock *this, const Buffer *source, Buffer *destination)
// file but we need to call process to generate the header.
if (!this->saltDone)
{
destinationSizeActual = cipherBlockProcessC(this, NULL, 0, bufRemainsPtr(outputActual));
destinationSizeActual = cipherBlockProcessBlock(this, NULL, 0, bufRemainsPtr(outputActual));
bufUsedInc(outputActual, destinationSizeActual);
}
destinationSizeActual = cipherBlockFlushC(this, bufRemainsPtr(outputActual));
destinationSizeActual = cipherBlockFlush(this, outputActual);
this->done = true;
}
else
destinationSizeActual = cipherBlockProcessC(this, bufPtr(source), bufUsed(source), bufRemainsPtr(outputActual));
destinationSizeActual = cipherBlockProcessBlock(this, bufPtr(source), bufUsed(source), bufRemainsPtr(outputActual));
bufUsedInc(outputActual, destinationSizeActual);
@ -407,9 +359,11 @@ cipherBlockProcess(CipherBlock *this, const Buffer *source, Buffer *destination)
/***********************************************************************************************************************************
Is cipher done?
***********************************************************************************************************************************/
bool
cipherBlockDone(const CipherBlock *this)
static bool
cipherBlockDone(const THIS_VOID)
{
THIS(const CipherBlock);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(CIPHER_BLOCK, this);
FUNCTION_TEST_END();
@ -419,27 +373,14 @@ cipherBlockDone(const CipherBlock *this)
FUNCTION_TEST_RETURN(this->done && !this->inputSame);
}
/***********************************************************************************************************************************
Get filter interface
***********************************************************************************************************************************/
IoFilter *
cipherBlockFilter(const CipherBlock *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(CIPHER_BLOCK, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->filter);
}
/***********************************************************************************************************************************
Should the same input be provided again?
***********************************************************************************************************************************/
bool
cipherBlockInputSame(const CipherBlock *this)
static bool
cipherBlockInputSame(const THIS_VOID)
{
THIS(const CipherBlock);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(CIPHER_BLOCK, this);
FUNCTION_TEST_END();
@ -450,35 +391,68 @@ cipherBlockInputSame(const CipherBlock *this)
}
/***********************************************************************************************************************************
Render as string for logging
New block encrypt/decrypt object
***********************************************************************************************************************************/
String *
cipherBlockToLog(const CipherBlock *this)
{
return strNewFmt(
"{inputSame: %s, done: %s}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done));
}
/***********************************************************************************************************************************
Free memory
***********************************************************************************************************************************/
void
cipherBlockFree(CipherBlock *this)
IoFilter *
cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, const String *digestName)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
FUNCTION_LOG_PARAM(ENUM, mode);
FUNCTION_LOG_PARAM(ENUM, cipherType);
FUNCTION_LOG_PARAM(BUFFER, pass);
FUNCTION_LOG_PARAM(STRING, digestName);
FUNCTION_LOG_END();
if (this != NULL)
ASSERT(pass != NULL);
ASSERT(bufSize(pass) > 0);
// Init crypto subsystem
cryptoInit();
// Lookup cipher by name. This means the ciphers passed in must exactly match a name expected by OpenSSL. This is a good
// thing since the name required by the openssl command-line tool will match what is used by pgBackRest.
const EVP_CIPHER *cipher = EVP_get_cipherbyname(strPtr(cipherTypeName(cipherType)));
if (!cipher)
THROW_FMT(AssertError, "unable to load cipher '%s'", strPtr(cipherTypeName(cipherType)));
// Lookup digest. If not defined it will be set to sha1.
const EVP_MD *digest = NULL;
if (digestName)
digest = EVP_get_digestbyname(strPtr(digestName));
else
digest = EVP_sha1();
if (!digest)
THROW_FMT(AssertError, "unable to load digest '%s'", strPtr(digestName));
// Allocate memory to hold process state
IoFilter *this = NULL;
MEM_CONTEXT_NEW_BEGIN("CipherBlock")
{
// Free cipher context
if (this->cipherContext)
EVP_CIPHER_CTX_cleanup(this->cipherContext);
CipherBlock *driver = memNew(sizeof(CipherBlock));
driver->memContext = MEM_CONTEXT_NEW();
// Free mem context
memContextCallbackClear(this->memContext);
memContextFree(this->memContext);
}
// Set mode, encrypt or decrypt
driver->mode = mode;
FUNCTION_LOG_RETURN_VOID();
// Set cipher and digest
driver->cipher = cipher;
driver->digest = digest;
// Store the passphrase
driver->passSize = bufUsed(pass);
driver->pass = memNewRaw(driver->passSize);
memcpy(driver->pass, bufPtr(pass), driver->passSize);
// Create filter interface
this = ioFilterNewP(
CIPHER_BLOCK_FILTER_TYPE_STR, driver, .done = cipherBlockDone, .inOut = cipherBlockProcess,
.inputSame = cipherBlockInputSame);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
}

View File

@ -4,54 +4,12 @@ Block Cipher Header
#ifndef COMMON_CRYPTO_CIPHERBLOCK_H
#define COMMON_CRYPTO_CIPHERBLOCK_H
/***********************************************************************************************************************************
CipherBlock object
***********************************************************************************************************************************/
typedef struct CipherBlock CipherBlock;
#include "common/io/filter/filter.h"
#include "common/type/buffer.h"
#include "common/crypto/common.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
CipherBlock *cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, const String *digestName);
// Deprecated constructor with C-style call signatures now needed only for the Perl interface
CipherBlock *cipherBlockNewC(
CipherMode mode, const char *cipherName, const unsigned char *pass, size_t passSize, const char *digestName);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void cipherBlockProcess(CipherBlock *this, const Buffer *source, Buffer *destination);
// Deprecated functions with C-style call signatures now needed only for the Perl interface
size_t cipherBlockProcessSizeC(CipherBlock *this, size_t sourceSize);
size_t cipherBlockProcessC(CipherBlock *this, const unsigned char *source, size_t sourceSize, unsigned char *destination);
size_t cipherBlockFlushC(CipherBlock *this, unsigned char *destination);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
bool cipherBlockDone(const CipherBlock *this);
IoFilter *cipherBlockFilter(const CipherBlock *this);
bool cipherBlockInputSame(const CipherBlock *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void cipherBlockFree(CipherBlock *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
String *cipherBlockToLog(const CipherBlock *this);
#define FUNCTION_LOG_CIPHER_BLOCK_TYPE \
CipherBlock *
#define FUNCTION_LOG_CIPHER_BLOCK_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, cipherBlockToLog, buffer, bufferSize)
IoFilter *cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, const String *digestName);
#endif

View File

@ -14,6 +14,7 @@ Cryptographic Hash
#include "common/io/filter/filter.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
#include "common/crypto/common.h"
/***********************************************************************************************************************************
@ -31,125 +32,49 @@ STRING_EXTERN(HASH_TYPE_SHA256_STR, HASH_TYPE_SH
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct CryptoHash
typedef struct CryptoHash
{
MemContext *memContext; // Context to store data
const EVP_MD *hashType; // Hash type (sha1, md5, etc.)
EVP_MD_CTX *hashContext; // Message hash context
Buffer *hash; // Hash in binary form
IoFilter *filter; // Filter interface
};
} CryptoHash;
/***********************************************************************************************************************************
New object
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_CRYPTO_HASH_TYPE \
CryptoHash *
cryptoHashNew(const String *type)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, type);
FUNCTION_LOG_END();
ASSERT(type != NULL);
// Init crypto subsystem
cryptoInit();
// Allocate memory to hold process state
CryptoHash *this = NULL;
MEM_CONTEXT_NEW_BEGIN("CryptoHash")
{
// Allocate state and set context
this = memNew(sizeof(CryptoHash));
this->memContext = MEM_CONTEXT_NEW();
// Lookup digest
if ((this->hashType = EVP_get_digestbyname(strPtr(type))) == NULL)
THROW_FMT(AssertError, "unable to load hash '%s'", strPtr(type));
// Create context
cryptoError((this->hashContext = EVP_MD_CTX_create()) == NULL, "unable to create hash context");
// Set free callback to ensure hash context is freed
memContextCallback(this->memContext, (MemContextCallback)cryptoHashFree, this);
// Initialize context
cryptoError(!EVP_DigestInit_ex(this->hashContext, this->hashType, NULL), "unable to initialize hash context");
// Create filter interface
this->filter = ioFilterNewP(
CRYPTO_HASH_FILTER_TYPE_STR, this, .in = (IoFilterInterfaceProcessIn)cryptoHashProcess,
.result = (IoFilterInterfaceResult)cryptoHashResult);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(CRYPTO_HASH, this);
}
#define FUNCTION_LOG_CRYPTO_HASH_FORMAT(value, buffer, bufferSize) \
objToLog(value, "CryptoHash", buffer, bufferSize)
/***********************************************************************************************************************************
Add message data to the hash
Add message data to the hash from a Buffer
***********************************************************************************************************************************/
void
cryptoHashProcessC(CryptoHash *this, const unsigned char *message, size_t messageSize)
static void
cryptoHashProcess(THIS_VOID, const Buffer *message)
{
THIS(CryptoHash);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CRYPTO_HASH, this);
FUNCTION_LOG_PARAM_P(UCHARDATA, message);
FUNCTION_LOG_PARAM(SIZE, messageSize);
FUNCTION_LOG_PARAM(BUFFER, message);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(this->hashContext != NULL);
ASSERT(this->hash == NULL);
ASSERT(message != NULL);
cryptoError(!EVP_DigestUpdate(this->hashContext, message, messageSize), "unable to process message hash");
cryptoError(!EVP_DigestUpdate(this->hashContext, bufPtr(message), bufUsed(message)), "unable to process message hash");
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Add message data to the hash from a Buffer
***********************************************************************************************************************************/
void
cryptoHashProcess(CryptoHash *this, const Buffer *message)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(CRYPTO_HASH, this);
FUNCTION_TEST_PARAM(BUFFER, message);
FUNCTION_TEST_END();
ASSERT(this != NULL);
ASSERT(message != NULL);
cryptoHashProcessC(this, bufPtr(message), bufUsed(message));
FUNCTION_TEST_RETURN_VOID();
}
/***********************************************************************************************************************************
Add message data to the hash from a String
***********************************************************************************************************************************/
void
cryptoHashProcessStr(CryptoHash *this, const String *message)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(CRYPTO_HASH, this);
FUNCTION_TEST_PARAM(STRING, message);
FUNCTION_TEST_END();
ASSERT(this != NULL);
ASSERT(message != NULL);
cryptoHashProcessC(this, (const unsigned char *)strPtr(message), strSize(message));
FUNCTION_TEST_RETURN_VOID();
}
/***********************************************************************************************************************************
Get binary representation of the hash
***********************************************************************************************************************************/
const Buffer *
static const Buffer *
cryptoHash(CryptoHash *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
@ -166,10 +91,6 @@ cryptoHash(CryptoHash *this)
bufUsedSet(this->hash, bufSize(this->hash));
cryptoError(!EVP_DigestFinal_ex(this->hashContext, bufPtr(this->hash), NULL), "unable to finalize message hash");
// Free the context
EVP_MD_CTX_destroy(this->hashContext);
this->hashContext = NULL;
}
MEM_CONTEXT_END();
}
@ -177,74 +98,91 @@ cryptoHash(CryptoHash *this)
FUNCTION_LOG_RETURN(BUFFER, this->hash);
}
/***********************************************************************************************************************************
Get filter interface
***********************************************************************************************************************************/
IoFilter *
cryptoHashFilter(CryptoHash *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CRYPTO_HASH, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
FUNCTION_LOG_RETURN(IO_FILTER, this->filter);
}
/***********************************************************************************************************************************
Get string representation of the hash as a filter result
***********************************************************************************************************************************/
const Variant *
cryptoHashResult(CryptoHash *this)
static Variant *
cryptoHashResult(THIS_VOID)
{
THIS(CryptoHash);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CRYPTO_HASH, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
Variant *result = NULL;
MEM_CONTEXT_BEGIN(this->memContext)
{
result = varNewStr(bufHex(cryptoHash(this)));
}
MEM_CONTEXT_END();
FUNCTION_LOG_RETURN(VARIANT, result);
FUNCTION_LOG_RETURN(VARIANT, varNewStr(bufHex(cryptoHash(this))));
}
/***********************************************************************************************************************************
Free memory
***********************************************************************************************************************************/
void
cryptoHashFree(CryptoHash *this)
static void
cryptoHashFreeCallback(CryptoHash *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CRYPTO_HASH, this);
FUNCTION_LOG_END();
if (this != NULL)
{
EVP_MD_CTX_destroy(this->hashContext);
memContextCallbackClear(this->memContext);
memContextFree(this->memContext);
FUNCTION_LOG_RETURN_VOID();
}
FUNCTION_LOG_RETURN_VOID();
/***********************************************************************************************************************************
New object
***********************************************************************************************************************************/
IoFilter *
cryptoHashNew(const String *type)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, type);
FUNCTION_LOG_END();
ASSERT(type != NULL);
// Init crypto subsystem
cryptoInit();
// Allocate memory to hold process state
IoFilter *this = NULL;
MEM_CONTEXT_NEW_BEGIN("CryptoHash")
{
CryptoHash *driver = memNew(sizeof(CryptoHash));
driver->memContext = MEM_CONTEXT_NEW();
// Lookup digest
if ((driver->hashType = EVP_get_digestbyname(strPtr(type))) == NULL)
THROW_FMT(AssertError, "unable to load hash '%s'", strPtr(type));
// Create context
cryptoError((driver->hashContext = EVP_MD_CTX_create()) == NULL, "unable to create hash context");
// Set free callback to ensure hash context is freed
memContextCallback(driver->memContext, (MemContextCallback)cryptoHashFreeCallback, driver);
// Initialize context
cryptoError(!EVP_DigestInit_ex(driver->hashContext, driver->hashType, NULL), "unable to initialize hash context");
// Create filter interface
this = ioFilterNewP(CRYPTO_HASH_FILTER_TYPE_STR, driver, .in = cryptoHashProcess, .result = cryptoHashResult);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
}
/***********************************************************************************************************************************
Get hash for one C buffer
***********************************************************************************************************************************/
Buffer *
cryptoHashOneC(const String *type, const unsigned char *message, size_t messageSize)
cryptoHashOne(const String *type, const Buffer *message)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, type);
FUNCTION_LOG_PARAM_P(UCHARDATA, message);
FUNCTION_LOG_PARAM(BUFFER, message);
FUNCTION_LOG_END();
ASSERT(type != NULL);
@ -254,11 +192,15 @@ cryptoHashOneC(const String *type, const unsigned char *message, size_t messageS
MEM_CONTEXT_TEMP_BEGIN()
{
CryptoHash *hash = cryptoHashNew(type);
cryptoHashProcessC(hash, message, messageSize);
IoFilter *hash = cryptoHashNew(type);
if (bufUsed(message) > 0)
ioFilterProcessIn(hash, message);
const Buffer *buffer = cryptoHash((CryptoHash *)ioFilterDriver(hash));
memContextSwitch(MEM_CONTEXT_OLD());
result = bufDup(cryptoHash(hash));
result = bufDup(buffer);
memContextSwitch(MEM_CONTEXT_TEMP());
}
MEM_CONTEXT_TEMP_END();
@ -266,40 +208,6 @@ cryptoHashOneC(const String *type, const unsigned char *message, size_t messageS
FUNCTION_LOG_RETURN(BUFFER, result);
}
/***********************************************************************************************************************************
Get hash for one Buffer
***********************************************************************************************************************************/
Buffer *
cryptoHashOne(const String *type, const Buffer *message)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, type);
FUNCTION_TEST_PARAM(BUFFER, message);
FUNCTION_TEST_END();
ASSERT(type != NULL);
ASSERT(message != NULL);
FUNCTION_TEST_RETURN(cryptoHashOneC(type, bufPtr(message), bufUsed(message)));
}
/***********************************************************************************************************************************
Get hash for one String
***********************************************************************************************************************************/
Buffer *
cryptoHashOneStr(const String *type, const String *message)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, type);
FUNCTION_TEST_PARAM(STRING, message);
FUNCTION_TEST_END();
ASSERT(type != NULL);
ASSERT(message != NULL);
FUNCTION_TEST_RETURN(cryptoHashOneC(type, (const unsigned char *)strPtr(message), strSize(message)));
}
/***********************************************************************************************************************************
Get hmac for one message/key
***********************************************************************************************************************************/

View File

@ -6,11 +6,6 @@ Generate a hash (sha1, md5, etc.) from a string, Buffer, or using an IoFilter.
#ifndef COMMON_CRYPTO_HASH_H
#define COMMON_CRYPTO_HASH_H
/***********************************************************************************************************************************
Hash object
***********************************************************************************************************************************/
typedef struct CryptoHash CryptoHash;
#include "common/io/filter/filter.h"
#include "common/type/string.h"
@ -45,42 +40,12 @@ Hash type sizes
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
CryptoHash *cryptoHashNew(const String *type);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void cryptoHashProcess(CryptoHash *this, const Buffer *message);
void cryptoHashProcessC(CryptoHash *this, const unsigned char *message, size_t messageSize);
void cryptoHashProcessStr(CryptoHash *this, const String *message);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
const Buffer *cryptoHash(CryptoHash *this);
IoFilter *cryptoHashFilter(CryptoHash *this);
const Variant *cryptoHashResult(CryptoHash *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void cryptoHashFree(CryptoHash *this);
IoFilter *cryptoHashNew(const String *type);
/***********************************************************************************************************************************
Helper functions
***********************************************************************************************************************************/
Buffer *cryptoHashOne(const String *type, const Buffer *message);
Buffer *cryptoHashOneC(const String *type, const unsigned char *message, size_t messageSize);
Buffer *cryptoHashOneStr(const String *type, const String *message);
Buffer *cryptoHmacOne(const String *type, const Buffer *key, const Buffer *message);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_CRYPTO_HASH_TYPE \
CryptoHash *
#define FUNCTION_LOG_CRYPTO_HASH_FORMAT(value, buffer, bufferSize) \
objToLog(value, "CryptoHash", buffer, bufferSize)
#endif

View File

@ -18,6 +18,7 @@ Execute Process
#include "common/io/io.h"
#include "common/io/read.intern.h"
#include "common/io/write.intern.h"
#include "common/object.h"
#include "common/wait.h"
/***********************************************************************************************************************************
@ -37,7 +38,7 @@ struct Exec
int handleWrite; // Write handle
int handleError; // Error handle
IoHandleRead *ioReadHandle; // Handle read driver
IoRead *ioReadHandle; // Handle read driver
IoWrite *ioWriteHandle; // Handle write interface
IoRead *ioReadExec; // Wrapper for handle read interface
@ -110,6 +111,155 @@ execNew(const String *command, const StringList *param, const String *name, Time
FUNCTION_LOG_RETURN(EXEC, this);
}
/***********************************************************************************************************************************
Check if the process is still running
This should be called when anything unexpected happens while reading or writing, including errors and eof. If this function returns
then the original error should be rethrown.
***********************************************************************************************************************************/
static void
execCheck(Exec *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(EXEC, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
int processStatus;
int processResult;
THROW_ON_SYS_ERROR(
(processResult = waitpid(this->processId, &processStatus, WNOHANG)) == -1, ExecuteError, "unable to wait on child process");
if (processResult != 0)
{
// Clear the process id so we don't try to wait for this process on free
this->processId = 0;
// If the process exited normally
if (WIFEXITED(processStatus))
{
// Get data from stderr to help diagnose the problem
IoRead *ioReadError = ioHandleReadNew(strNewFmt("%s error", strPtr(this->name)), this->handleError, 0);
ioReadOpen(ioReadError);
String *errorStr = strTrim(strNewBuf(ioReadBuf(ioReadError)));
// Throw the error with as much information as is available
THROWP_FMT(
errorTypeFromCode(WEXITSTATUS(processStatus)), "%s terminated unexpectedly [%d]%s%s", strPtr(this->name),
WEXITSTATUS(processStatus), strSize(errorStr) > 0 ? ": " : "", strSize(errorStr) > 0 ? strPtr(errorStr) : "");
}
// If the process did not exit normally then it must have been a signal
THROW_FMT(ExecuteError, "%s terminated unexpectedly on signal %d", strPtr(this->name), WTERMSIG(processStatus));
}
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Read from the process
***********************************************************************************************************************************/
static size_t
execRead(THIS_VOID, Buffer *buffer, bool block)
{
THIS(Exec);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(EXEC, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_PARAM(BOOL, block);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(buffer != NULL);
size_t result = 0;
TRY_BEGIN()
{
result = ioReadInterface(this->ioReadHandle)->read(ioReadDriver(this->ioReadHandle), buffer, block);
}
CATCH_ANY()
{
execCheck(this);
RETHROW();
}
TRY_END();
FUNCTION_LOG_RETURN(SIZE, result);
}
/***********************************************************************************************************************************
Write to the process
***********************************************************************************************************************************/
static void
execWrite(THIS_VOID, const Buffer *buffer)
{
THIS(Exec);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(EXEC, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(buffer != NULL);
TRY_BEGIN()
{
ioWrite(this->ioWriteHandle, buffer);
ioWriteFlush(this->ioWriteHandle);
}
CATCH_ANY()
{
execCheck(this);
RETHROW();
}
TRY_END();
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Is the process eof?
***********************************************************************************************************************************/
static bool
execEof(THIS_VOID)
{
THIS(Exec);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(EXEC, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
// Check if the process is still running on eof
if (ioReadInterface(this->ioReadHandle)->eof(ioReadDriver(this->ioReadHandle)))
execCheck(this);
FUNCTION_LOG_RETURN(BOOL, false);
}
/***********************************************************************************************************************************
Get the read handle
***********************************************************************************************************************************/
static int
execHandleRead(const THIS_VOID)
{
THIS(const Exec);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(EXEC, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->handleRead);
}
/***********************************************************************************************************************************
Execute command
***********************************************************************************************************************************/
@ -171,15 +321,13 @@ execOpen(Exec *this)
// Assign handles to io interfaces
this->ioReadHandle = ioHandleReadNew(strNewFmt("%s read", strPtr(this->name)), this->handleRead, this->timeout);
this->ioWriteHandle = ioHandleWriteIo(ioHandleWriteNew(strNewFmt("%s write", strPtr(this->name)), this->handleWrite));
this->ioWriteHandle = ioHandleWriteNew(strNewFmt("%s write", strPtr(this->name)), this->handleWrite);
ioWriteOpen(this->ioWriteHandle);
// Create wrapper interfaces that check process state
this->ioReadExec = ioReadNewP(
this, .block = true, .read = (IoReadInterfaceRead)execRead, .eof = (IoReadInterfaceEof)execEof,
.handle = (IoReadInterfaceHandle)execHandleRead);
this->ioReadExec = ioReadNewP(this, .block = true, .read = execRead, .eof = execEof, .handle = execHandleRead);
ioReadOpen(this->ioReadExec);
this->ioWriteExec = ioWriteNewP(this, .write = (IoWriteInterfaceWrite)execWrite);
this->ioWriteExec = ioWriteNewP(this, .write = execWrite);
ioWriteOpen(this->ioWriteExec);
// Set a callback so the handles will get freed
@ -188,132 +336,6 @@ execOpen(Exec *this)
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Check if the process is still running
This should be called when anything unexpected happens while reading or writing, including errors and eof. If this function returns
then the original error should be rethrown.
***********************************************************************************************************************************/
static void
execCheck(Exec *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(EXEC, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
int processStatus;
int processResult;
THROW_ON_SYS_ERROR(
(processResult = waitpid(this->processId, &processStatus, WNOHANG)) == -1, ExecuteError, "unable to wait on child process");
if (processResult != 0)
{
// Clear the process id so we don't try to wait for this process on free
this->processId = 0;
// If the process exited normally
if (WIFEXITED(processStatus))
{
// Get data from stderr to help diagnose the problem
IoRead *ioReadError = ioHandleReadIo(ioHandleReadNew(strNewFmt("%s error", strPtr(this->name)), this->handleError, 0));
ioReadOpen(ioReadError);
String *errorStr = strTrim(strNewBuf(ioReadBuf(ioReadError)));
// Throw the error with as much information as is available
THROWP_FMT(
errorTypeFromCode(WEXITSTATUS(processStatus)), "%s terminated unexpectedly [%d]%s%s", strPtr(this->name),
WEXITSTATUS(processStatus), strSize(errorStr) > 0 ? ": " : "", strSize(errorStr) > 0 ? strPtr(errorStr) : "");
}
// If the process did not exit normally then it must have been a signal
THROW_FMT(ExecuteError, "%s terminated unexpectedly on signal %d", strPtr(this->name), WTERMSIG(processStatus));
}
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Read from the process
***********************************************************************************************************************************/
size_t
execRead(Exec *this, Buffer *buffer, bool block)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(EXEC, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_PARAM(BOOL, block);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(buffer != NULL);
size_t result = 0;
TRY_BEGIN()
{
result = ioHandleRead(this->ioReadHandle, buffer, block);
}
CATCH_ANY()
{
execCheck(this);
RETHROW();
}
TRY_END();
FUNCTION_LOG_RETURN(SIZE, result);
}
/***********************************************************************************************************************************
Write to the process
***********************************************************************************************************************************/
void
execWrite(Exec *this, Buffer *buffer)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(EXEC, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(buffer != NULL);
TRY_BEGIN()
{
ioWrite(this->ioWriteHandle, buffer);
ioWriteFlush(this->ioWriteHandle);
}
CATCH_ANY()
{
execCheck(this);
RETHROW();
}
TRY_END();
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Is the process eof?
***********************************************************************************************************************************/
bool
execEof(Exec *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(EXEC, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
// Check that the process is still running on eof
if (ioHandleReadEof(this->ioReadHandle))
execCheck(this);
FUNCTION_LOG_RETURN(BOOL, false);
}
/***********************************************************************************************************************************
Get read interface
***********************************************************************************************************************************/
@ -359,21 +381,6 @@ execMemContext(const Exec *this)
FUNCTION_TEST_RETURN(this->memContext);
}
/***********************************************************************************************************************************
Get the read handle
***********************************************************************************************************************************/
int
execHandleRead(Exec *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(EXEC, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->handleRead);
}
/***********************************************************************************************************************************
Free the object
***********************************************************************************************************************************/

View File

@ -17,7 +17,6 @@ typedef struct Exec Exec;
#include "common/io/read.h"
#include "common/io/write.h"
#include "common/time.h"
#include "common/type/stringList.h"
/***********************************************************************************************************************************
Constructor
@ -28,17 +27,12 @@ Exec *execNew(const String *command, const StringList *param, const String *name
Functions
***********************************************************************************************************************************/
void execOpen(Exec *this);
size_t execRead(Exec *this, Buffer *buffer, bool block);
void execWrite(Exec *this, Buffer *buffer);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
bool execEof(Exec *this);
IoRead *execIoRead(const Exec *this);
IoWrite *execIoWrite(const Exec *this);
MemContext *execMemContext(const Exec *this);
int execHandleRead(Exec *this);
/***********************************************************************************************************************************
Destructor

View File

@ -8,52 +8,36 @@ Buffer IO Read
#include "common/io/read.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct IoBufferRead
typedef struct IoBufferRead
{
MemContext *memContext; // Object memory context
IoRead *io; // IoRead interface
const Buffer *read; // Buffer to read data from
size_t readPos; // Current position in the read buffer
bool eof; // Has the end of the buffer been reached?
};
} IoBufferRead;
/***********************************************************************************************************************************
New object
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_IO_BUFFER_READ_TYPE \
IoBufferRead *
ioBufferReadNew(const Buffer *buffer)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END();
ASSERT(buffer != NULL);
IoBufferRead *this = NULL;
MEM_CONTEXT_NEW_BEGIN("IoBufferRead")
{
this = memNew(sizeof(IoBufferRead));
this->memContext = memContextCurrent();
this->io = ioReadNewP(this, .eof = (IoReadInterfaceEof)ioBufferReadEof, .read = (IoReadInterfaceRead)ioBufferRead);
this->read = buffer;
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_BUFFER_READ, this);
}
#define FUNCTION_LOG_IO_BUFFER_READ_FORMAT(value, buffer, bufferSize) \
objToLog(value, "IoBufferRead", buffer, bufferSize)
/***********************************************************************************************************************************
Read data from the buffer
***********************************************************************************************************************************/
size_t
ioBufferRead(IoBufferRead *this, Buffer *buffer, bool block)
static size_t
ioBufferRead(THIS_VOID, Buffer *buffer, bool block)
{
THIS(IoBufferRead);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_BUFFER_READ, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
@ -83,31 +67,14 @@ ioBufferRead(IoBufferRead *this, Buffer *buffer, bool block)
FUNCTION_LOG_RETURN(SIZE, actualBytes);
}
/***********************************************************************************************************************************
Move the object to a new context
***********************************************************************************************************************************/
IoBufferRead *
ioBufferReadMove(IoBufferRead *this, MemContext *parentNew)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_BUFFER_READ, this);
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
FUNCTION_TEST_END();
ASSERT(parentNew != NULL);
if (this != NULL)
memContextMove(this->memContext, parentNew);
FUNCTION_TEST_RETURN(this);
}
/***********************************************************************************************************************************
Have all bytes been read from the buffer?
***********************************************************************************************************************************/
bool
ioBufferReadEof(const IoBufferRead *this)
static bool
ioBufferReadEof(THIS_VOID)
{
THIS(IoBufferRead);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_BUFFER_READ, this);
FUNCTION_LOG_END();
@ -118,32 +85,28 @@ ioBufferReadEof(const IoBufferRead *this)
}
/***********************************************************************************************************************************
Get io interface
New object
***********************************************************************************************************************************/
IoRead *
ioBufferReadIo(const IoBufferRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_BUFFER_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->io);
}
/***********************************************************************************************************************************
Free the object
***********************************************************************************************************************************/
void
ioBufferReadFree(IoBufferRead *this)
ioBufferReadNew(const Buffer *buffer)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_BUFFER_READ, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END();
if (this != NULL)
memContextFree(this->memContext);
ASSERT(buffer != NULL);
FUNCTION_LOG_RETURN_VOID();
IoRead *this = NULL;
MEM_CONTEXT_NEW_BEGIN("IoBufferRead")
{
IoBufferRead *driver = memNew(sizeof(IoBufferRead));
driver->memContext = memContextCurrent();
driver->read = buffer;
this = ioReadNewP(driver, .eof = ioBufferReadEof, .read = ioBufferRead);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_READ, this);
}

View File

@ -6,41 +6,11 @@ Read from a Buffer object using the IoRead interface.
#ifndef COMMON_IO_BUFFERREAD_H
#define COMMON_IO_BUFFERREAD_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct IoBufferRead IoBufferRead;
#include "common/io/read.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
IoBufferRead *ioBufferReadNew(const Buffer *buffer);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
size_t ioBufferRead(IoBufferRead *this, Buffer *buffer, bool block);
IoBufferRead *ioBufferReadMove(IoBufferRead *this, MemContext *parentNew);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
bool ioBufferReadEof(const IoBufferRead *this);
IoRead *ioBufferReadIo(const IoBufferRead *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void ioBufferReadFree(IoBufferRead *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_IO_BUFFER_READ_TYPE \
IoBufferRead *
#define FUNCTION_LOG_IO_BUFFER_READ_FORMAT(value, buffer, bufferSize) \
objToLog(value, "IoBufferRead", buffer, bufferSize)
IoRead *ioBufferReadNew(const Buffer *buffer);
#endif

View File

@ -8,49 +8,33 @@ Buffer IO Write
#include "common/io/write.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct IoBufferWrite
typedef struct IoBufferWrite
{
MemContext *memContext; // Object memory context
IoWrite *io; // IoWrite interface
Buffer *write; // Buffer to write into
};
} IoBufferWrite;
/***********************************************************************************************************************************
New object
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_IO_BUFFER_WRITE_TYPE \
IoBufferWrite *
ioBufferWriteNew(Buffer *buffer)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END();
ASSERT(buffer != NULL);
IoBufferWrite *this = NULL;
MEM_CONTEXT_NEW_BEGIN("IoBufferWrite")
{
this = memNew(sizeof(IoBufferWrite));
this->memContext = memContextCurrent();
this->io = ioWriteNewP(this, .write = (IoWriteInterfaceWrite)ioBufferWrite);
this->write = buffer;
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_BUFFER_WRITE, this);
}
#define FUNCTION_LOG_IO_BUFFER_WRITE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "IoBufferWrite", buffer, bufferSize)
/***********************************************************************************************************************************
Write to the buffer
***********************************************************************************************************************************/
void
ioBufferWrite(IoBufferWrite *this, Buffer *buffer)
static void
ioBufferWrite(THIS_VOID, const Buffer *buffer)
{
THIS(IoBufferWrite);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_BUFFER_WRITE, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
@ -65,51 +49,28 @@ ioBufferWrite(IoBufferWrite *this, Buffer *buffer)
}
/***********************************************************************************************************************************
Move the object to a new context
***********************************************************************************************************************************/
IoBufferWrite *
ioBufferWriteMove(IoBufferWrite *this, MemContext *parentNew)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_BUFFER_WRITE, this);
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
FUNCTION_TEST_END();
ASSERT(parentNew != NULL);
if (this != NULL)
memContextMove(this->memContext, parentNew);
FUNCTION_TEST_RETURN(this);
}
/***********************************************************************************************************************************
Get io interface
New object
***********************************************************************************************************************************/
IoWrite *
ioBufferWriteIo(const IoBufferWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_BUFFER_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->io);
}
/***********************************************************************************************************************************
Free the object
***********************************************************************************************************************************/
void
ioBufferWriteFree(IoBufferWrite *this)
ioBufferWriteNew(Buffer *buffer)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_BUFFER_WRITE, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END();
if (this != NULL)
memContextFree(this->memContext);
ASSERT(buffer != NULL);
FUNCTION_LOG_RETURN_VOID();
IoWrite *this = NULL;
MEM_CONTEXT_NEW_BEGIN("IoBufferWrite")
{
IoBufferWrite *driver = memNew(sizeof(IoBufferWrite));
driver->memContext = memContextCurrent();
driver->write = buffer;
this = ioWriteNewP(driver, .write = ioBufferWrite);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_WRITE, this);
}

View File

@ -6,40 +6,11 @@ Write to a Buffer object using the IoWrite interface.
#ifndef COMMON_IO_BUFFERWRITE_H
#define COMMON_IO_BUFFERWRITE_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct IoBufferWrite IoBufferWrite;
#include "common/io/write.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
IoBufferWrite *ioBufferWriteNew(Buffer *buffer);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void ioBufferWrite(IoBufferWrite *this, Buffer *buffer);
IoBufferWrite *ioBufferWriteMove(IoBufferWrite *this, MemContext *parentNew);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
IoWrite *ioBufferWriteIo(const IoBufferWrite *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void ioBufferWriteFree(IoBufferWrite *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_IO_BUFFER_WRITE_TYPE \
IoBufferWrite *
#define FUNCTION_LOG_IO_BUFFER_WRITE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "IoBufferWrite", buffer, bufferSize)
IoWrite *ioBufferWriteNew(Buffer *buffer);
#endif

View File

@ -10,6 +10,7 @@ IO Buffer Filter
#include "common/io/filter/filter.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
/***********************************************************************************************************************************
Filter type constant
@ -20,46 +21,36 @@ Filter type constant
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct IoBuffer
typedef struct IoBuffer
{
MemContext *memContext; // Mem context of filter
IoFilter *filter; // Filter interface
size_t inputPos; // Position in input buffer
bool inputSame; // Is the same input required again?
};
} IoBuffer;
/***********************************************************************************************************************************
New object
Macros for function logging
***********************************************************************************************************************************/
String *
ioBufferToLog(const IoBuffer *this)
{
return strNewFmt("{inputSame: %s, inputPos: %zu}", cvtBoolToConstZ(this->inputSame), this->inputPos);
}
#define FUNCTION_LOG_IO_BUFFER_TYPE \
IoBuffer *
ioBufferNew(void)
{
FUNCTION_LOG_VOID(logLevelTrace);
IoBuffer *this = NULL;
MEM_CONTEXT_NEW_BEGIN("IoBuffer")
{
this = memNew(sizeof(IoBuffer));
this->memContext = memContextCurrent();
// Create filter interface
this->filter = ioFilterNewP(
BUFFER_FILTER_TYPE_STR, this, .inOut = (IoFilterInterfaceProcessInOut)ioBufferProcess,
.inputSame = (IoFilterInterfaceInputSame)ioBufferInputSame);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_BUFFER, this);
}
#define FUNCTION_LOG_IO_BUFFER_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, ioBufferToLog, buffer, bufferSize)
/***********************************************************************************************************************************
Move data from the input buffer to the output buffer
***********************************************************************************************************************************/
void
ioBufferProcess(IoBuffer *this, const Buffer *input, Buffer *output)
static void
ioBufferProcess(THIS_VOID, const Buffer *input, Buffer *output)
{
THIS(IoBuffer)
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_BUFFER, this);
FUNCTION_LOG_PARAM(BUFFER, input);
@ -101,9 +92,11 @@ Is the same input required again?
If the remaining space in the output buffer is smaller than the used space in the input buffer then the same input must be provided
again.
***********************************************************************************************************************************/
bool
ioBufferInputSame(const IoBuffer *this)
static bool
ioBufferInputSame(const THIS_VOID)
{
THIS(const IoBuffer)
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_BUFFER, this);
FUNCTION_TEST_END();
@ -114,41 +107,23 @@ ioBufferInputSame(const IoBuffer *this)
}
/***********************************************************************************************************************************
Get filter interface
New object
***********************************************************************************************************************************/
IoFilter *
ioBufferFilter(const IoBuffer *this)
ioBufferNew(void)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_BUFFER, this);
FUNCTION_TEST_END();
FUNCTION_LOG_VOID(logLevelTrace);
ASSERT(this != NULL);
IoFilter *this = NULL;
FUNCTION_TEST_RETURN(this->filter);
}
/***********************************************************************************************************************************
Render as string for logging
***********************************************************************************************************************************/
String *
ioBufferToLog(const IoBuffer *this)
MEM_CONTEXT_NEW_BEGIN("IoBuffer")
{
return strNewFmt("{inputSame: %s, inputPos: %zu}", cvtBoolToConstZ(this->inputSame), this->inputPos);
IoBuffer *driver = memNew(sizeof(IoBuffer));
driver->memContext = memContextCurrent();
this = ioFilterNewP(BUFFER_FILTER_TYPE_STR, driver, .inOut = ioBufferProcess, .inputSame = ioBufferInputSame);
}
MEM_CONTEXT_NEW_END();
/***********************************************************************************************************************************
Free the filter group
***********************************************************************************************************************************/
void
ioBufferFree(IoBuffer *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_BUFFER, this);
FUNCTION_LOG_END();
if (this != NULL)
memContextFree(this->memContext);
FUNCTION_LOG_RETURN_VOID();
FUNCTION_LOG_RETURN(IO_FILTER, this);
}

View File

@ -7,43 +7,12 @@ in a FilterGroup if the last filter is not already an InOut filter, so there is
#ifndef COMMON_IO_FILTER_BUFFER_H
#define COMMON_IO_FILTER_BUFFER_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct IoBuffer IoBuffer;
#include "common/io/filter/filter.h"
#include "common/type/buffer.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
IoBuffer *ioBufferNew(void);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void ioBufferProcess(IoBuffer *this, const Buffer *input, Buffer *output);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
IoFilter *ioBufferFilter(const IoBuffer *this);
bool ioBufferInputSame(const IoBuffer *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void ioBufferFree(IoBuffer *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
String *ioBufferToLog(const IoBuffer *this);
#define FUNCTION_LOG_IO_BUFFER_TYPE \
IoBuffer *
#define FUNCTION_LOG_IO_BUFFER_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, ioBufferToLog, buffer, bufferSize)
IoFilter *ioBufferNew(void);
#endif

View File

@ -132,6 +132,21 @@ ioFilterDone(const IoFilter *this)
FUNCTION_TEST_RETURN(this->interface.done != NULL ? this->interface.done(this->driver) : !ioFilterInputSame(this));
}
/***********************************************************************************************************************************
Driver for the filter
***********************************************************************************************************************************/
void *
ioFilterDriver(IoFilter *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_FILTER, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->driver);
}
/***********************************************************************************************************************************
Does the filter need the same input again?
@ -149,6 +164,21 @@ ioFilterInputSame(const IoFilter *this)
FUNCTION_TEST_RETURN(this->interface.inputSame != NULL ? this->interface.inputSame(this->driver) : false);
}
/***********************************************************************************************************************************
Interface for the filter
***********************************************************************************************************************************/
const IoFilterInterface *
ioFilterInterface(const IoFilter *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_FILTER, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(&this->interface);
}
/***********************************************************************************************************************************
Does filter produce output?
@ -169,7 +199,7 @@ ioFilterOutput(const IoFilter *this)
/***********************************************************************************************************************************
Get filter result
***********************************************************************************************************************************/
const Variant *
Variant *
ioFilterResult(const IoFilter *this)
{
FUNCTION_TEST_BEGIN();
@ -197,3 +227,19 @@ ioFilterType(const IoFilter *this)
FUNCTION_TEST_RETURN(this->type);
}
/***********************************************************************************************************************************
Free object
***********************************************************************************************************************************/
void
ioFilterFree(IoFilter *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_FILTER, this);
FUNCTION_TEST_END();
if (this != NULL)
memContextFree(this->memContext);
FUNCTION_TEST_RETURN_VOID();
}

View File

@ -22,9 +22,14 @@ typedef struct IoFilter IoFilter;
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
const Variant *ioFilterResult(const IoFilter *this);
Variant *ioFilterResult(const IoFilter *this);
const String *ioFilterType(const IoFilter *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void ioFilterFree(IoFilter *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/

View File

@ -23,35 +23,29 @@ Each filter has a type that allows it to be identified in the filter list.
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
typedef bool (*IoFilterInterfaceDone)(const void *driver);
typedef void (*IoFilterInterfaceProcessIn)(void *driver, const Buffer *);
typedef void (*IoFilterInterfaceProcessInOut)(void *driver, const Buffer *, Buffer *);
typedef bool (*IoFilterInterfaceInputSame)(const void *driver);
typedef Variant *(*IoFilterInterfaceResult)(const void *driver);
typedef struct IoFilterInterface
{
// Indicates that filter processing is done. This is used for filters that have additional data to be flushed even after all
// input has been processed. Compression and encryption filters will usually need to implement done. If done is not
// implemented then it will always return true if all input has been consumed, i.e. if inputSame returns false.
IoFilterInterfaceDone done;
bool (*done)(const void *driver);
// Processing function for filters that do not produce output. Note that result must be implemented in this case (or else what
// would be the point.
IoFilterInterfaceProcessIn in;
void (*in)(void *driver, const Buffer *);
// Processing function for filters that produce output. InOut filters will typically implement inputSame and may also implement
// done.
IoFilterInterfaceProcessInOut inOut;
void (*inOut)(void *driver, const Buffer *, Buffer *);
// InOut filters must be prepared for an output buffer that is too small to accept all the processed output. In this case the
// filter must implement inputSame and set it to true when there is more output to be produced for a given input. On the next
// call to inOut the same input will be passed along with a fresh output buffer with space for more processed output.
IoFilterInterfaceInputSame inputSame;
bool (*inputSame)(const void *driver);
// If the filter produces a result then this function must be implemented to return the result. A result can be anything that
// is not processed output, e.g. a count of total bytes or a cryptographic hash.
IoFilterInterfaceResult result;
Variant *(*result)(void *driver);
} IoFilterInterface;
#define ioFilterNewP(type, driver, ...) \
@ -70,7 +64,9 @@ IoFilter *ioFilterMove(IoFilter *this, MemContext *parentNew);
Getters
***********************************************************************************************************************************/
bool ioFilterDone(const IoFilter *this);
void *ioFilterDriver(IoFilter *this);
bool ioFilterInputSame(const IoFilter *this);
const IoFilterInterface *ioFilterInterface(const IoFilter *this);
bool ioFilterOutput(const IoFilter *this);
/***********************************************************************************************************************************

View File

@ -134,7 +134,7 @@ ioFilterGroupOpen(IoFilterGroup *this)
// If the last filter is not an output filter then add a filter to buffer/copy data. Input filters won't copy to an output
// buffer so we need some way to get the data to the output buffer.
if (lstSize(this->filterList) == 0 || !ioFilterOutput((ioFilterGroupGet(this, lstSize(this->filterList) - 1))->filter))
ioFilterGroupAdd(this, ioBufferFilter(ioBufferNew()));
ioFilterGroupAdd(this, ioBufferNew());
// Create filter input/output buffers. Input filters do not get an output buffer since they don't produce output.
Buffer *lastOutputBuffer = NULL;

View File

@ -10,6 +10,7 @@ IO Size Filter
#include "common/io/filter/size.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
/***********************************************************************************************************************************
Filter type constant
@ -20,45 +21,35 @@ Filter type constant
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct IoSize
typedef struct IoSize
{
MemContext *memContext; // Mem context of filter
IoFilter *filter; // Filter interface
uint64_t size; // Total size of al input
};
} IoSize;
/***********************************************************************************************************************************
New object
Macros for function logging
***********************************************************************************************************************************/
String *
ioSizeToLog(const IoSize *this)
{
return strNewFmt("{size: %" PRIu64 "}", this->size);
}
#define FUNCTION_LOG_IO_SIZE_TYPE \
IoSize *
ioSizeNew(void)
{
FUNCTION_LOG_VOID(logLevelTrace);
IoSize *this = NULL;
MEM_CONTEXT_NEW_BEGIN("IoSize")
{
this = memNew(sizeof(IoSize));
this->memContext = memContextCurrent();
// Create filter interface
this->filter = ioFilterNewP(
SIZE_FILTER_TYPE_STR, this, .in = (IoFilterInterfaceProcessIn)ioSizeProcess,
.result = (IoFilterInterfaceResult)ioSizeResult);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_SIZE, this);
}
#define FUNCTION_LOG_IO_SIZE_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, ioSizeToLog, buffer, bufferSize)
/***********************************************************************************************************************************
Count bytes in the input
***********************************************************************************************************************************/
void
ioSizeProcess(IoSize *this, const Buffer *input)
static void
ioSizeProcess(THIS_VOID, const Buffer *input)
{
THIS(IoSize);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_SIZE, this);
FUNCTION_LOG_PARAM(BUFFER, input);
@ -72,65 +63,41 @@ ioSizeProcess(IoSize *this, const Buffer *input)
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Get filter interface
***********************************************************************************************************************************/
IoFilter *
ioSizeFilter(const IoSize *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_SIZE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->filter);
}
/***********************************************************************************************************************************
Render as string for logging
***********************************************************************************************************************************/
String *
ioSizeToLog(const IoSize *this)
{
return strNewFmt("{size: %" PRIu64 "}", this->size);
}
/***********************************************************************************************************************************
Return filter result
***********************************************************************************************************************************/
const Variant *
ioSizeResult(IoSize *this)
static Variant *
ioSizeResult(THIS_VOID)
{
THIS(IoSize);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_SIZE, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
Variant *result = NULL;
MEM_CONTEXT_BEGIN(this->memContext)
{
result = varNewUInt64(this->size);
}
MEM_CONTEXT_END();
FUNCTION_LOG_RETURN(VARIANT, result);
FUNCTION_LOG_RETURN(VARIANT, varNewUInt64(this->size));
}
/***********************************************************************************************************************************
Free the filter group
New object
***********************************************************************************************************************************/
void
ioSizeFree(IoSize *this)
IoFilter *
ioSizeNew(void)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_SIZE, this);
FUNCTION_LOG_END();
FUNCTION_LOG_VOID(logLevelTrace);
if (this != NULL)
memContextFree(this->memContext);
IoFilter *this = NULL;
FUNCTION_LOG_RETURN_VOID();
MEM_CONTEXT_NEW_BEGIN("IoSize")
{
IoSize *driver = memNew(sizeof(IoSize));
driver->memContext = memContextCurrent();
this = ioFilterNewP(SIZE_FILTER_TYPE_STR, driver, .in = ioSizeProcess, .result = ioSizeResult);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
}

View File

@ -7,43 +7,11 @@ in a FilterGroup with IoWrite.
#ifndef COMMON_IO_FILTER_SIZE_H
#define COMMON_IO_FILTER_SIZE_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct IoSize IoSize;
#include "common/io/filter/filter.h"
#include "common/type/buffer.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
IoSize *ioSizeNew(void);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void ioSizeProcess(IoSize *this, const Buffer *input);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
IoFilter *ioSizeFilter(const IoSize *this);
const Variant *ioSizeResult(IoSize *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void ioSizeFree(IoSize *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
String *ioSizeToLog(const IoSize *this);
#define FUNCTION_LOG_IO_SIZE_TYPE \
IoSize *
#define FUNCTION_LOG_IO_SIZE_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, ioSizeToLog, buffer, bufferSize)
IoFilter *ioSizeNew(void);
#endif

View File

@ -11,56 +11,36 @@ Handle IO Read
#include "common/io/read.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct IoHandleRead
typedef struct IoHandleRead
{
MemContext *memContext; // Object memory context
IoRead *io; // IoRead interface
const String *name; // Handle name for error messages
int handle; // Handle to read data from
TimeMSec timeout; // Timeout for read operation
bool eof; // Has the end of the stream been reached?
};
} IoHandleRead;
/***********************************************************************************************************************************
New object
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_IO_HANDLE_READ_TYPE \
IoHandleRead *
ioHandleReadNew(const String *name, int handle, TimeMSec timeout)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(INT, handle);
FUNCTION_LOG_END();
ASSERT(handle != -1);
IoHandleRead *this = NULL;
MEM_CONTEXT_NEW_BEGIN("IoHandleRead")
{
this = memNew(sizeof(IoHandleRead));
this->memContext = memContextCurrent();
this->io = ioReadNewP(
this, .block = true, .eof = (IoReadInterfaceEof)ioHandleReadEof, .handle = (IoReadInterfaceHandle)ioHandleReadHandle,
.read = (IoReadInterfaceRead)ioHandleRead);
this->name = strDup(name);
this->handle = handle;
this->timeout = timeout;
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_HANDLE_READ, this);
}
#define FUNCTION_LOG_IO_HANDLE_READ_FORMAT(value, buffer, bufferSize) \
objToLog(value, "IoHandleRead", buffer, bufferSize)
/***********************************************************************************************************************************
Read data from the handle
***********************************************************************************************************************************/
size_t
ioHandleRead(IoHandleRead *this, Buffer *buffer, bool block)
static size_t
ioHandleRead(THIS_VOID, Buffer *buffer, bool block)
{
THIS(IoHandleRead);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_HANDLE_READ, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
@ -116,31 +96,14 @@ ioHandleRead(IoHandleRead *this, Buffer *buffer, bool block)
FUNCTION_LOG_RETURN(SIZE, (size_t)actualBytes);
}
/***********************************************************************************************************************************
Move the object to a new context
***********************************************************************************************************************************/
IoHandleRead *
ioHandleReadMove(IoHandleRead *this, MemContext *parentNew)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_HANDLE_READ, this);
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
FUNCTION_TEST_END();
ASSERT(parentNew != NULL);
if (this != NULL)
memContextMove(this->memContext, parentNew);
FUNCTION_TEST_RETURN(this);
}
/***********************************************************************************************************************************
Have all bytes been read from the buffer?
***********************************************************************************************************************************/
bool
ioHandleReadEof(const IoHandleRead *this)
static bool
ioHandleReadEof(THIS_VOID)
{
THIS(IoHandleRead);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_HANDLE_READ, this);
FUNCTION_LOG_END();
@ -153,9 +116,11 @@ ioHandleReadEof(const IoHandleRead *this)
/***********************************************************************************************************************************
Get handle (file descriptor)
***********************************************************************************************************************************/
int
ioHandleReadHandle(const IoHandleRead *this)
static int
ioHandleReadHandle(const THIS_VOID)
{
THIS(const IoHandleRead);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_HANDLE_READ, this);
FUNCTION_TEST_END();
@ -166,32 +131,30 @@ ioHandleReadHandle(const IoHandleRead *this)
}
/***********************************************************************************************************************************
Get io interface
New object
***********************************************************************************************************************************/
IoRead *
ioHandleReadIo(const IoHandleRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_HANDLE_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->io);
}
/***********************************************************************************************************************************
Free the object
***********************************************************************************************************************************/
void
ioHandleReadFree(IoHandleRead *this)
ioHandleReadNew(const String *name, int handle, TimeMSec timeout)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_HANDLE_READ, this);
FUNCTION_LOG_PARAM(INT, handle);
FUNCTION_LOG_END();
if (this != NULL)
memContextFree(this->memContext);
ASSERT(handle != -1);
FUNCTION_LOG_RETURN_VOID();
IoRead *this = NULL;
MEM_CONTEXT_NEW_BEGIN("IoHandleRead")
{
IoHandleRead *driver = memNew(sizeof(IoHandleRead));
driver->memContext = memContextCurrent();
driver->name = strDup(name);
driver->handle = handle;
driver->timeout = timeout;
this = ioReadNewP(driver, .block = true, .eof = ioHandleReadEof, .handle = ioHandleReadHandle, .read = ioHandleRead);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_READ, this);
}

View File

@ -6,43 +6,12 @@ Read from a handle using the IoRead interface.
#ifndef COMMON_IO_HANDLEREAD_H
#define COMMON_IO_HANDLEREAD_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct IoHandleRead IoHandleRead;
#include "common/io/read.h"
#include "common/time.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
IoHandleRead *ioHandleReadNew(const String *name, int handle, TimeMSec timeout);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
size_t ioHandleRead(IoHandleRead *this, Buffer *buffer, bool block);
IoHandleRead *ioHandleReadMove(IoHandleRead *this, MemContext *parentNew);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
bool ioHandleReadEof(const IoHandleRead *this);
int ioHandleReadHandle(const IoHandleRead *this);
IoRead *ioHandleReadIo(const IoHandleRead *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void ioHandleReadFree(IoHandleRead *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_IO_HANDLE_READ_TYPE \
IoHandleRead *
#define FUNCTION_LOG_IO_HANDLE_READ_FORMAT(value, buffer, bufferSize) \
objToLog(value, "IoHandleRead", buffer, bufferSize)
IoRead *ioHandleReadNew(const String *name, int handle, TimeMSec timeout);
#endif

View File

@ -10,50 +10,34 @@ Handle IO Write
#include "common/io/write.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct IoHandleWrite
typedef struct IoHandleWrite
{
MemContext *memContext; // Object memory context
IoWrite *io; // IoWrite interface
const String *name; // Handle name for error messages
int handle; // Handle to write to
};
} IoHandleWrite;
/***********************************************************************************************************************************
New object
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_IO_HANDLE_WRITE_TYPE \
IoHandleWrite *
ioHandleWriteNew(const String *name, int handle)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(INT, handle);
FUNCTION_LOG_END();
IoHandleWrite *this = NULL;
MEM_CONTEXT_NEW_BEGIN("IoHandleWrite")
{
this = memNew(sizeof(IoHandleWrite));
this->memContext = memContextCurrent();
this->io = ioWriteNewP(
this, .handle = (IoWriteInterfaceHandle)ioHandleWriteHandle, .write = (IoWriteInterfaceWrite)ioHandleWrite);
this->name = strDup(name);
this->handle = handle;
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_HANDLE_WRITE, this);
}
#define FUNCTION_LOG_IO_HANDLE_WRITE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "IoHandleWrite", buffer, bufferSize)
/***********************************************************************************************************************************
Write to the handle
***********************************************************************************************************************************/
void
ioHandleWrite(IoHandleWrite *this, Buffer *buffer)
static void
ioHandleWrite(THIS_VOID, const Buffer *buffer)
{
THIS(IoHandleWrite);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_HANDLE_WRITE, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
@ -68,31 +52,14 @@ ioHandleWrite(IoHandleWrite *this, Buffer *buffer)
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Move the object to a new context
***********************************************************************************************************************************/
IoHandleWrite *
ioHandleWriteMove(IoHandleWrite *this, MemContext *parentNew)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_HANDLE_WRITE, this);
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
FUNCTION_TEST_END();
ASSERT(parentNew != NULL);
if (this != NULL)
memContextMove(this->memContext, parentNew);
FUNCTION_TEST_RETURN(this);
}
/***********************************************************************************************************************************
Get handle (file descriptor)
***********************************************************************************************************************************/
int
ioHandleWriteHandle(const IoHandleWrite *this)
static int
ioHandleWriteHandle(const THIS_VOID)
{
THIS(const IoHandleWrite);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_HANDLE_WRITE, this);
FUNCTION_TEST_END();
@ -103,34 +70,29 @@ ioHandleWriteHandle(const IoHandleWrite *this)
}
/***********************************************************************************************************************************
Get io interface
New object
***********************************************************************************************************************************/
IoWrite *
ioHandleWriteIo(const IoHandleWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_HANDLE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->io);
}
/***********************************************************************************************************************************
Free the object
***********************************************************************************************************************************/
void
ioHandleWriteFree(IoHandleWrite *this)
ioHandleWriteNew(const String *name, int handle)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_HANDLE_WRITE, this);
FUNCTION_LOG_PARAM(INT, handle);
FUNCTION_LOG_END();
if (this != NULL)
memContextFree(this->memContext);
IoWrite *this = NULL;
FUNCTION_LOG_RETURN_VOID();
MEM_CONTEXT_NEW_BEGIN("IoHandleWrite")
{
IoHandleWrite *driver = memNew(sizeof(IoHandleWrite));
driver->memContext = memContextCurrent();
driver->name = strDup(name);
driver->handle = handle;
this = ioWriteNewP(driver, .handle = ioHandleWriteHandle, .write = ioHandleWrite);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(IO_WRITE, this);
}
/***********************************************************************************************************************************

View File

@ -6,46 +6,16 @@ Write to a handle using the IoWrite interface.
#ifndef COMMON_IO_HANDLEWRITE_H
#define COMMON_IO_HANDLEWRITE_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct IoHandleWrite IoHandleWrite;
#include "common/io/write.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
IoHandleWrite *ioHandleWriteNew(const String *name, int handle);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void ioHandleWrite(IoHandleWrite *this, Buffer *buffer);
IoHandleWrite *ioHandleWriteMove(IoHandleWrite *this, MemContext *parentNew);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
int ioHandleWriteHandle(const IoHandleWrite *this);
IoWrite *ioHandleWriteIo(const IoHandleWrite *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void ioHandleWriteFree(IoHandleWrite *this);
IoWrite *ioHandleWriteNew(const String *name, int handle);
/***********************************************************************************************************************************
Helper functions
***********************************************************************************************************************************/
void ioHandleWriteOneStr(int handle, const String *string);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_IO_HANDLE_WRITE_TYPE \
IoHandleWrite *
#define FUNCTION_LOG_IO_HANDLE_WRITE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "IoHandleWrite", buffer, bufferSize)
#endif

View File

@ -10,6 +10,7 @@ Http Client
#include "common/io/read.intern.h"
#include "common/io/tls/client.h"
#include "common/log.h"
#include "common/object.h"
#include "common/wait.h"
/***********************************************************************************************************************************
@ -64,8 +65,10 @@ struct HttpClient
Read content
***********************************************************************************************************************************/
static size_t
httpClientRead(HttpClient *this, Buffer *buffer, bool block)
httpClientRead(THIS_VOID, Buffer *buffer, bool block)
{
THIS(HttpClient);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(HTTP_CLIENT, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
@ -145,8 +148,10 @@ httpClientRead(HttpClient *this, Buffer *buffer, bool block)
Has all content been read?
***********************************************************************************************************************************/
static bool
httpClientEof(const HttpClient *this)
httpClientEof(THIS_VOID)
{
THIS(HttpClient);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(HTTP_CLIENT, this);
FUNCTION_LOG_END();
@ -388,8 +393,7 @@ httpClientRequest(
{
MEM_CONTEXT_BEGIN(this->memContext)
{
this->ioRead = ioReadNewP(
this, .eof = (IoReadInterfaceEof)httpClientEof, .read = (IoReadInterfaceRead)httpClientRead);
this->ioRead = ioReadNewP(this, .eof = httpClientEof, .read = httpClientRead);
ioReadOpen(this->ioRead);
}
MEM_CONTEXT_END();

View File

@ -322,6 +322,21 @@ ioReadBlock(const IoRead *this)
FUNCTION_TEST_RETURN(this->interface.block);
}
/***********************************************************************************************************************************
Driver for the read object
***********************************************************************************************************************************/
void *
ioReadDriver(IoRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->driver);
}
/***********************************************************************************************************************************
Is IO at EOF?
@ -393,6 +408,21 @@ ioReadHandle(const IoRead *this)
FUNCTION_LOG_RETURN(INT, this->interface.handle == NULL ? -1 : this->interface.handle(this->driver));
}
/***********************************************************************************************************************************
Interface for the read object
***********************************************************************************************************************************/
const IoReadInterface *
ioReadInterface(const IoRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(&this->interface);
}
/***********************************************************************************************************************************
Free the object
***********************************************************************************************************************************/

View File

@ -4,25 +4,23 @@ IO Read Interface Internal
#ifndef COMMON_IO_READ_INTERN_H
#define COMMON_IO_READ_INTERN_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
#include "common/io/read.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
typedef bool (*IoReadInterfaceEof)(void *driver);
typedef void (*IoReadInterfaceClose)(void *driver);
typedef bool (*IoReadInterfaceOpen)(void *driver);
typedef int (*IoReadInterfaceHandle)(void *driver);
typedef size_t (*IoReadInterfaceRead)(void *driver, Buffer *buffer, bool block);
typedef struct IoReadInterface
{
bool block; // Do reads block when buffer is larger than available bytes?
IoReadInterfaceEof eof;
IoReadInterfaceClose close;
IoReadInterfaceHandle handle;
IoReadInterfaceOpen open;
IoReadInterfaceRead read;
bool (*eof)(void *driver);
void (*close)(void *driver);
bool (*open)(void *driver);
int (*handle)(const void *driver);
size_t (*read)(void *driver, Buffer *buffer, bool block);
} IoReadInterface;
#define ioReadNewP(driver, ...) \
@ -30,6 +28,12 @@ typedef struct IoReadInterface
IoRead *ioReadNew(void *driver, IoReadInterface interface);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
void *ioReadDriver(IoRead *this);
const IoReadInterface *ioReadInterface(const IoRead *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/

View File

@ -24,6 +24,7 @@ TLS Client
#include "common/io/read.intern.h"
#include "common/io/write.intern.h"
#include "common/memContext.h"
#include "common/object.h"
#include "common/time.h"
#include "common/type/keyValue.h"
#include "common/wait.h"
@ -258,6 +259,147 @@ tlsClientHostVerify(const String *host, X509 *certificate)
FUNCTION_LOG_RETURN(BOOL, result);
}
/***********************************************************************************************************************************
Read from the TLS session
***********************************************************************************************************************************/
size_t
tlsClientRead(THIS_VOID, Buffer *buffer, bool block)
{
THIS(TlsClient);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_PARAM(BOOL, block);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(this->session != NULL);
ASSERT(buffer != NULL);
ASSERT(!bufFull(buffer));
ssize_t actualBytes = 0;
// If blocking read keep reading until buffer is full
do
{
// If no tls data pending then check the socket
if (!SSL_pending(this->session))
{
// Initialize the file descriptor set used for select
fd_set selectSet;
FD_ZERO(&selectSet);
// We know the socket is not negative because it passed error handling, so it is safe to cast to unsigned
FD_SET((unsigned int)this->socket, &selectSet);
// Initialize timeout struct used for select. Recreate this structure each time since Linux (at least) will modify it.
struct timeval timeoutSelect;
timeoutSelect.tv_sec = (time_t)(this->timeout / MSEC_PER_SEC);
timeoutSelect.tv_usec = (time_t)(this->timeout % MSEC_PER_SEC * 1000);
// Determine if there is data to be read
int result = select(this->socket + 1, &selectSet, NULL, NULL, &timeoutSelect);
THROW_ON_SYS_ERROR_FMT(result == -1, AssertError, "unable to select from '%s:%u'", strPtr(this->host), this->port);
// If no data read after time allotted then error
if (!result)
{
THROW_FMT(
FileReadError, "unable to read data from '%s:%u' after %" PRIu64 "ms",
strPtr(this->host), this->port, this->timeout);
}
}
// Read and handle errors
size_t expectedBytes = bufRemains(buffer);
actualBytes = SSL_read(this->session, bufRemainsPtr(buffer), (int)expectedBytes);
cryptoError(actualBytes < 0, "unable to read from TLS");
// Update amount of buffer used
bufUsedInc(buffer, (size_t)actualBytes);
// If zero bytes were returned then the connection was closed
if (actualBytes == 0)
{
tlsClientClose(this);
break;
}
}
while (block && bufRemains(buffer) > 0);
FUNCTION_LOG_RETURN(SIZE, (size_t)actualBytes);
}
/***********************************************************************************************************************************
Write to the tls session
***********************************************************************************************************************************/
void
tlsClientWrite(THIS_VOID, const Buffer *buffer)
{
THIS(TlsClient);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(this->session != NULL);
ASSERT(buffer != NULL);
cryptoError(SSL_write(this->session, bufPtr(buffer), (int)bufUsed(buffer)) != (int)bufUsed(buffer), "unable to write");
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Close the connection
***********************************************************************************************************************************/
void
tlsClientClose(TlsClient *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
// Close the socket
if (this->socket != -1)
{
close(this->socket);
this->socket = -1;
}
// Free the TLS session
if (this->session != NULL)
{
SSL_free(this->session);
this->session = NULL;
}
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Has session been closed by the server?
***********************************************************************************************************************************/
bool
tlsClientEof(THIS_VOID)
{
THIS(TlsClient);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
FUNCTION_LOG_RETURN(BOOL, this->session == NULL);
}
/***********************************************************************************************************************************
Open connection if this is a new client or if the connection was closed by the server
***********************************************************************************************************************************/
@ -414,10 +556,9 @@ tlsClientOpen(TlsClient *this)
MEM_CONTEXT_BEGIN(this->memContext)
{
// Create read and write interfaces
this->write = ioWriteNewP(this, .write = (IoWriteInterfaceWrite)tlsClientWrite);
this->write = ioWriteNewP(this, .write = tlsClientWrite);
ioWriteOpen(this->write);
this->read = ioReadNewP(
this, .block = true, .eof = (IoReadInterfaceEof)tlsClientEof, .read = (IoReadInterfaceRead)tlsClientRead);
this->read = ioReadNewP(this, .block = true, .eof = tlsClientEof, .read = tlsClientRead);
ioReadOpen(this->read);
}
MEM_CONTEXT_END();
@ -426,141 +567,6 @@ tlsClientOpen(TlsClient *this)
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Read from the TLS session
***********************************************************************************************************************************/
size_t
tlsClientRead(TlsClient *this, Buffer *buffer, bool block)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_PARAM(BOOL, block);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(this->session != NULL);
ASSERT(buffer != NULL);
ASSERT(!bufFull(buffer));
ssize_t actualBytes = 0;
// If blocking read keep reading until buffer is full
do
{
// If no tls data pending then check the socket
if (!SSL_pending(this->session))
{
// Initialize the file descriptor set used for select
fd_set selectSet;
FD_ZERO(&selectSet);
// We know the socket is not negative because it passed error handling, so it is safe to cast to unsigned
FD_SET((unsigned int)this->socket, &selectSet);
// Initialize timeout struct used for select. Recreate this structure each time since Linux (at least) will modify it.
struct timeval timeoutSelect;
timeoutSelect.tv_sec = (time_t)(this->timeout / MSEC_PER_SEC);
timeoutSelect.tv_usec = (time_t)(this->timeout % MSEC_PER_SEC * 1000);
// Determine if there is data to be read
int result = select(this->socket + 1, &selectSet, NULL, NULL, &timeoutSelect);
THROW_ON_SYS_ERROR_FMT(result == -1, AssertError, "unable to select from '%s:%u'", strPtr(this->host), this->port);
// If no data read after time allotted then error
if (!result)
{
THROW_FMT(
FileReadError, "unable to read data from '%s:%u' after %" PRIu64 "ms",
strPtr(this->host), this->port, this->timeout);
}
}
// Read and handle errors
size_t expectedBytes = bufRemains(buffer);
actualBytes = SSL_read(this->session, bufRemainsPtr(buffer), (int)expectedBytes);
cryptoError(actualBytes < 0, "unable to read from TLS");
// Update amount of buffer used
bufUsedInc(buffer, (size_t)actualBytes);
// If zero bytes were returned then the connection was closed
if (actualBytes == 0)
{
tlsClientClose(this);
break;
}
}
while (block && bufRemains(buffer) > 0);
FUNCTION_LOG_RETURN(SIZE, (size_t)actualBytes);
}
/***********************************************************************************************************************************
Write to the tls session
***********************************************************************************************************************************/
void
tlsClientWrite(TlsClient *this, const Buffer *buffer)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(this->session != NULL);
ASSERT(buffer != NULL);
cryptoError(SSL_write(this->session, bufPtr(buffer), (int)bufUsed(buffer)) != (int)bufUsed(buffer), "unable to write");
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Close the connection
***********************************************************************************************************************************/
void
tlsClientClose(TlsClient *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
// Close the socket
if (this->socket != -1)
{
close(this->socket);
this->socket = -1;
}
// Free the TLS session
if (this->session != NULL)
{
SSL_free(this->session);
this->session = NULL;
}
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Has session been closed by the server?
***********************************************************************************************************************************/
bool
tlsClientEof(const TlsClient *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
FUNCTION_LOG_RETURN(BOOL, this->session == NULL);
}
/***********************************************************************************************************************************
Get read interface
***********************************************************************************************************************************/

View File

@ -36,14 +36,11 @@ TlsClient *tlsClientNew(
Functions
***********************************************************************************************************************************/
void tlsClientOpen(TlsClient *this);
size_t tlsClientRead(TlsClient *this, Buffer *buffer, bool block);
void tlsClientWrite(TlsClient *this, const Buffer *buffer);
void tlsClientClose(TlsClient *this);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
bool tlsClientEof(const TlsClient *this);
IoRead *tlsClientIoRead(const TlsClient *this);
IoWrite *tlsClientIoWrite(const TlsClient *this);

View File

@ -246,6 +246,21 @@ ioWriteClose(IoWrite *this)
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Interface for the write object
***********************************************************************************************************************************/
void *
ioWriteDriver(IoWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->driver);
}
/***********************************************************************************************************************************
Get/set filters
@ -304,6 +319,21 @@ ioWriteHandle(const IoWrite *this)
FUNCTION_LOG_RETURN(INT, this->interface.handle == NULL ? -1 : this->interface.handle(this->driver));
}
/***********************************************************************************************************************************
Interface for the write object
***********************************************************************************************************************************/
const IoWriteInterface *
ioWriteInterface(const IoWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(&this->interface);
}
/***********************************************************************************************************************************
Free the object
***********************************************************************************************************************************/

View File

@ -3,7 +3,7 @@ IO Write Interface
Objects that write to some IO destination (file, socket, etc.) are implemented using this interface. All objects are required to
implement IoWriteProcess and can optionally implement IoWriteOpen or IoWriteClose. IoWriteOpen and IoWriteClose can be used to
allocate/open or deallocate/free resources. An example of an IoWrite object is IoBufferRead.
allocate/open or deallocate/free resources. An example of an IoWrite object is IoBufferWrite.
***********************************************************************************************************************************/
#ifndef COMMON_IO_WRITE_H
#define COMMON_IO_WRITE_H

View File

@ -9,17 +9,12 @@ IO Write Interface Internal
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
typedef void (*IoWriteInterfaceClose)(void *driver);
typedef int (*IoWriteInterfaceHandle)(void *driver);
typedef void (*IoWriteInterfaceOpen)(void *driver);
typedef void (*IoWriteInterfaceWrite)(void *driver, const Buffer *buffer);
typedef struct IoWriteInterface
{
IoWriteInterfaceClose close;
IoWriteInterfaceHandle handle;
IoWriteInterfaceOpen open;
IoWriteInterfaceWrite write;
void (*close)(void *driver);
int (*handle)(const void *driver);
void (*open)(void *driver);
void (*write)(void *driver, const Buffer *buffer);
} IoWriteInterface;
#define ioWriteNewP(driver, ...) \
@ -27,6 +22,12 @@ typedef struct IoWriteInterface
IoWrite *ioWriteNew(void *driver, IoWriteInterface interface);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
void *ioWriteDriver(IoWrite *this);
const IoWriteInterface *ioWriteInterface(const IoWrite *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/

20
src/common/object.h Normal file
View File

@ -0,0 +1,20 @@
/***********************************************************************************************************************************
Object Macros
***********************************************************************************************************************************/
#ifndef COMMON_OBJECT_H
#define COMMON_OBJECT_H
/***********************************************************************************************************************************
Used in function parameter lists to discourage use of the untyped thisVoid parameter, e.g.:
size_t bufferRead(THIS_VOID, Buffer *buffer)
***********************************************************************************************************************************/
#define THIS_VOID void *thisVoid
/***********************************************************************************************************************************
Create a local "this" variable of the correct type from a void parameter.
***********************************************************************************************************************************/
#define THIS(type) \
type *this = thisVoid;
#endif

View File

@ -10,6 +10,7 @@ Info Handler
#include "common/crypto/cipherBlock.h"
#include "common/crypto/hash.h"
#include "common/debug.h"
#include "common/io/filter/filter.intern.h"
#include "common/ini.h"
#include "common/log.h"
#include "common/memContext.h"
@ -56,11 +57,11 @@ infoHash(const Ini *ini)
MEM_CONTEXT_TEMP_BEGIN()
{
CryptoHash *hash = cryptoHashNew(HASH_TYPE_SHA1_STR);
IoFilter *hash = cryptoHashNew(HASH_TYPE_SHA1_STR);
StringList *sectionList = strLstSort(iniSectionList(ini), sortOrderAsc);
// Initial JSON opening bracket
cryptoHashProcessC(hash, (const unsigned char *)"{", 1);
ioFilterProcessIn(hash, BUFSTRDEF("{"));
// Loop through sections and create hash for checking checksum
for (unsigned int sectionIdx = 0; sectionIdx < strLstSize(sectionList); sectionIdx++)
@ -69,12 +70,12 @@ infoHash(const Ini *ini)
// Add a comma before additional sections
if (sectionIdx != 0)
cryptoHashProcessC(hash, (const unsigned char *)",", 1);
ioFilterProcessIn(hash, BUFSTRDEF(","));
// Create the section header
cryptoHashProcessC(hash, (const unsigned char *)"\"", 1);
cryptoHashProcessStr(hash, section);
cryptoHashProcessC(hash, (const unsigned char *)"\":{", 3);
ioFilterProcessIn(hash, BUFSTRDEF("\""));
ioFilterProcessIn(hash, BUFSTR(section));
ioFilterProcessIn(hash, BUFSTRDEF("\":{"));
StringList *keyList = strLstSort(iniSectionKeyList(ini, section), sortOrderAsc);
unsigned int keyListSize = strLstSize(keyList);
@ -88,25 +89,27 @@ infoHash(const Ini *ini)
if ((strEq(section, INFO_SECTION_BACKREST_STR) && !strEq(key, INFO_KEY_CHECKSUM_STR)) ||
!strEq(section, INFO_SECTION_BACKREST_STR))
{
cryptoHashProcessC(hash, (const unsigned char *)"\"", 1);
cryptoHashProcessStr(hash, key);
cryptoHashProcessC(hash, (const unsigned char *)"\":", 2);
cryptoHashProcessStr(hash, iniGet(ini, section, strLstGet(keyList, keyIdx)));
ioFilterProcessIn(hash, BUFSTRDEF("\""));
ioFilterProcessIn(hash, BUFSTR(key));
ioFilterProcessIn(hash, BUFSTRDEF("\":"));
ioFilterProcessIn(hash, BUFSTR(iniGet(ini, section, strLstGet(keyList, keyIdx))));
if ((keyListSize > 1) && (keyIdx < keyListSize - 1))
cryptoHashProcessC(hash, (const unsigned char *)",", 1);
ioFilterProcessIn(hash, BUFSTRDEF(","));
}
}
// Close the key/value list
cryptoHashProcessC(hash, (const unsigned char *)"}", 1);
ioFilterProcessIn(hash, BUFSTRDEF("}"));
}
// JSON closing bracket
cryptoHashProcessC(hash, (const unsigned char *)"}", 1);
ioFilterProcessIn(hash, BUFSTRDEF("}"));
Variant *resultVar = ioFilterResult(hash);
memContextSwitch(MEM_CONTEXT_OLD());
result = bufHex(cryptoHash(hash));
result = strDup(varStr(resultVar));
memContextSwitch(MEM_CONTEXT_TEMP());
}
MEM_CONTEXT_TEMP_END();
@ -145,9 +148,7 @@ infoLoad(Info *this, const Storage *storage, const String *fileName, bool copyFi
{
ioReadFilterGroupSet(
storageFileReadIo(infoRead),
ioFilterGroupAdd(
ioFilterGroupNew(), cipherBlockFilter(cipherBlockNew(cipherModeDecrypt, cipherType, BUFSTR(cipherPass),
NULL))));
ioFilterGroupAdd(ioFilterGroupNew(), cipherBlockNew(cipherModeDecrypt, cipherType, BUFSTR(cipherPass), NULL)));
}
// Load and parse the info file
@ -333,9 +334,7 @@ infoSave(
{
ioWriteFilterGroupSet(
infoWrite,
ioFilterGroupAdd(
ioFilterGroupNew(), cipherBlockFilter(cipherBlockNew(cipherModeEncrypt, cipherType, BUFSTR(cipherPass),
NULL))));
ioFilterGroupAdd(ioFilterGroupNew(), cipherBlockNew(cipherModeEncrypt, cipherType, BUFSTR(cipherPass), NULL)));
}
iniSave(ini, infoWrite);

View File

@ -289,7 +289,9 @@ XS_EUPXS(XS_pgBackRest__LibC_storageDriverPosixPathRemove)
;
MEM_CONTEXT_XS_TEMP_BEGIN()
{
storageDriverPosixPathRemove(storageDriverPosixNew(strNew("/"), 0640, 750, true, NULL), strNew(path), errorOnMissing, recurse);
storagePathRemoveP(
storageDriverPosixNew(strNew("/"), 0640, 750, true, NULL), strNew(path), .errorOnMissing = errorOnMissing,
.recurse = recurse);
}
MEM_CONTEXT_XS_TEMP_END();
}
@ -482,9 +484,10 @@ XS_EUPXS(XS_pgBackRest__LibC__Crypto__Hash_process)
MEM_CONTEXT_XS_TEMP_BEGIN()
{
STRLEN messageSize;
const unsigned char *messagePtr = (const unsigned char *)SvPV(message, messageSize);
const void *messagePtr = SvPV(message, messageSize);
cryptoHashProcessC(self->pxPayload, messagePtr, messageSize);
if (messageSize > 0)
ioFilterProcessIn(self->pxPayload, BUF(messagePtr, messageSize));
}
MEM_CONTEXT_XS_TEMP_END();
}
@ -515,7 +518,7 @@ XS_EUPXS(XS_pgBackRest__LibC__Crypto__Hash_result)
MEM_CONTEXT_XS_TEMP_BEGIN()
{
String *hash = bufHex(cryptoHash(self->pxPayload));
const String *hash = varStr(ioFilterResult(self->pxPayload));
RETVAL = newSV(strSize(hash));
SvPOK_only(RETVAL);
@ -571,9 +574,9 @@ XS_EUPXS(XS_pgBackRest__LibC_cryptoHashOne)
MEM_CONTEXT_XS_TEMP_BEGIN()
{
STRLEN messageSize;
const unsigned char *messagePtr = (const unsigned char *)SvPV(message, messageSize);
const void *messagePtr = SvPV(message, messageSize);
String *hash = bufHex(cryptoHashOneC(strNew(type), messagePtr, messageSize));
String *hash = bufHex(cryptoHashOne(strNew(type), BUF(messagePtr, messageSize)));
RETVAL = newSV(strSize(hash));
SvPOK_only(RETVAL);
@ -619,6 +622,10 @@ XS_EUPXS(XS_pgBackRest__LibC__Cipher__Block_new)
}
RETVAL = NULL;
CHECK(type != NULL);
CHECK(key != NULL);
CHECK(keySize != 0);
// Not much point to this but it keeps the var from being unused
if (strcmp(class, PACKAGE_NAME_LIBC "::Cipher::Block") != 0)
croak("unexpected class name '%s'", class);
@ -626,10 +633,9 @@ XS_EUPXS(XS_pgBackRest__LibC__Cipher__Block_new)
MEM_CONTEXT_XS_NEW_BEGIN("cipherBlockXs")
{
RETVAL = memNew(sizeof(CipherBlockXs));
RETVAL->memContext = MEM_COMTEXT_XS();
RETVAL->pxPayload = cipherBlockNewC(mode, type, key, keySize, digest);
RETVAL->pxPayload = cipherBlockNew(mode, cipherType(STR(type)), BUF(key, keySize), digest == NULL ? NULL : STR(digest));
}
MEM_CONTEXT_XS_NEW_END();
{
@ -671,10 +677,27 @@ XS_EUPXS(XS_pgBackRest__LibC__Cipher__Block_process)
STRLEN tSize;
const unsigned char *sourcePtr = (const unsigned char *)SvPV(source, tSize);
RETVAL = NEWSV(0, cipherBlockProcessSizeC(self->pxPayload, tSize));
RETVAL = NEWSV(0, ioBufferSize());
SvPOK_only(RETVAL);
SvCUR_set(RETVAL, cipherBlockProcessC(self->pxPayload, sourcePtr, tSize, (unsigned char *)SvPV_nolen(RETVAL)));
if (tSize > 0)
{
size_t outBufferUsed = 0;
do
{
SvGROW(RETVAL, outBufferUsed + ioBufferSize());
Buffer *outBuffer = bufNewUseC((unsigned char *)SvPV_nolen(RETVAL) + outBufferUsed, ioBufferSize());
ioFilterProcessInOut(self->pxPayload, BUF(sourcePtr, tSize), outBuffer);
outBufferUsed += bufUsed(outBuffer);
}
while (ioFilterInputSame(self->pxPayload));
SvCUR_set(RETVAL, outBufferUsed);
}
else
SvCUR_set(RETVAL, 0);
}
MEM_CONTEXT_XS_END();
RETVAL = sv_2mortal(RETVAL);
@ -707,10 +730,22 @@ XS_EUPXS(XS_pgBackRest__LibC__Cipher__Block_flush)
MEM_CONTEXT_XS_BEGIN(self->memContext)
{
RETVAL = NEWSV(0, cipherBlockProcessSizeC(self->pxPayload, 0));
RETVAL = NEWSV(0, ioBufferSize());
SvPOK_only(RETVAL);
SvCUR_set(RETVAL, cipherBlockFlushC(self->pxPayload, (unsigned char *)SvPV_nolen(RETVAL)));
size_t outBufferUsed = 0;
do
{
SvGROW(RETVAL, outBufferUsed + ioBufferSize());
Buffer *outBuffer = bufNewUseC((unsigned char *)SvPV_nolen(RETVAL) + outBufferUsed, ioBufferSize());
ioFilterProcessInOut(self->pxPayload, NULL, outBuffer);
outBufferUsed += bufUsed(outBuffer);
}
while (!ioFilterDone(self->pxPayload));
SvCUR_set(RETVAL, outBufferUsed);
}
MEM_CONTEXT_XS_END();
RETVAL = sv_2mortal(RETVAL);

View File

@ -8,28 +8,17 @@ CIFS Storage Driver
#include "common/memContext.h"
#include "common/regExp.h"
#include "storage/driver/cifs/storage.h"
#include "storage/driver/posix/storage.h"
#include "storage/driver/posix/storage.intern.h"
/***********************************************************************************************************************************
Driver type constant string
***********************************************************************************************************************************/
STRING_EXTERN(STORAGE_DRIVER_CIFS_TYPE_STR, STORAGE_DRIVER_CIFS_TYPE);
/***********************************************************************************************************************************
Object type
This type *must* stay in sync with StorageDriverPosix since it is cast to StorageDriverPosix.
***********************************************************************************************************************************/
struct StorageDriverCifs
{
MemContext *memContext; // Object memory context
Storage *interface; // Driver interface
};
/***********************************************************************************************************************************
New object
***********************************************************************************************************************************/
StorageDriverCifs *
Storage *
storageDriverCifsNew(
const String *path, mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction)
{
@ -41,114 +30,8 @@ storageDriverCifsNew(
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
FUNCTION_LOG_END();
ASSERT(path != NULL);
ASSERT(modeFile != 0);
ASSERT(modePath != 0);
// Create the object
StorageDriverCifs *this = NULL;
MEM_CONTEXT_NEW_BEGIN("StorageDriverCifs")
{
this = memNew(sizeof(StorageDriverCifs));
this->memContext = MEM_CONTEXT_NEW();
this->interface = storageNewP(
STORAGE_DRIVER_CIFS_TYPE_STR, path, modeFile, modePath, write, pathExpressionFunction, this,
.exists = (StorageInterfaceExists)storageDriverPosixExists, .info = (StorageInterfaceInfo)storageDriverPosixInfo,
.list = (StorageInterfaceList)storageDriverPosixList, .move = (StorageInterfaceMove)storageDriverPosixMove,
.newRead = (StorageInterfaceNewRead)storageDriverPosixNewRead,
.newWrite = (StorageInterfaceNewWrite)storageDriverCifsNewWrite,
.pathCreate = (StorageInterfacePathCreate)storageDriverPosixPathCreate,
.pathRemove = (StorageInterfacePathRemove)storageDriverPosixPathRemove,
.pathSync = (StorageInterfacePathSync)storageDriverCifsPathSync,
.remove = (StorageInterfaceRemove)storageDriverPosixRemove);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_DRIVER_CIFS, this);
}
/***********************************************************************************************************************************
New file write object
***********************************************************************************************************************************/
StorageFileWrite *
storageDriverCifsNewWrite(
StorageDriverCifs *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_CIFS, this);
FUNCTION_LOG_PARAM(STRING, file);
FUNCTION_LOG_PARAM(MODE, modeFile);
FUNCTION_LOG_PARAM(MODE, modePath);
FUNCTION_LOG_PARAM(STRING, user);
FUNCTION_LOG_PARAM(STRING, group);
FUNCTION_LOG_PARAM(INT64, timeModified);
FUNCTION_LOG_PARAM(BOOL, createPath);
FUNCTION_LOG_PARAM(BOOL, syncFile);
FUNCTION_LOG_PARAM(BOOL, syncPath);
FUNCTION_LOG_PARAM(BOOL, atomic);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(file != NULL);
FUNCTION_LOG_RETURN(
STORAGE_FILE_WRITE,
storageDriverPosixFileWriteInterface(
storageDriverPosixFileWriteNew(
(StorageDriverPosix *)this, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, false,
atomic)));
}
/***********************************************************************************************************************************
Sync a path
CIFS does not support explicit syncs.
***********************************************************************************************************************************/
void
storageDriverCifsPathSync(StorageDriverCifs *this, const String *path, bool ignoreMissing)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_CIFS, this);
FUNCTION_LOG_PARAM(STRING, path);
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(path != NULL);
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
Storage *
storageDriverCifsInterface(const StorageDriverCifs *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_LOG_PARAM(STORAGE_DRIVER_CIFS, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface);
}
/***********************************************************************************************************************************
Free the file
***********************************************************************************************************************************/
void
storageDriverCifsFree(StorageDriverCifs *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_CIFS, this);
FUNCTION_LOG_END();
if (this != NULL)
memContextFree(this->memContext);
FUNCTION_LOG_RETURN_VOID();
STORAGE,
storageDriverPosixNewInternal(
STORAGE_DRIVER_CIFS_TYPE_STR, path, modeFile, modePath, write, pathExpressionFunction, false));
}

View File

@ -4,18 +4,6 @@ CIFS Storage Driver
#ifndef STORAGE_DRIVER_CIFS_STORAGE_H
#define STORAGE_DRIVER_CIFS_STORAGE_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct StorageDriverCifs StorageDriverCifs;
#include <sys/types.h>
#include "common/type/buffer.h"
#include "common/type/stringList.h"
#include "storage/driver/posix/fileRead.h"
#include "storage/driver/posix/fileWrite.h"
#include "storage/info.h"
#include "storage/storage.intern.h"
/***********************************************************************************************************************************
@ -27,33 +15,7 @@ Driver type constant
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
StorageDriverCifs *storageDriverCifsNew(
Storage *storageDriverCifsNew(
const String *path, mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
StorageFileWrite *storageDriverCifsNewWrite(
StorageDriverCifs *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
void storageDriverCifsPathSync(StorageDriverCifs *this, const String *path, bool ignoreMissing);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
Storage *storageDriverCifsInterface(const StorageDriverCifs *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void storageDriverCifsFree(StorageDriverCifs *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_CIFS_TYPE \
StorageDriverCifs *
#define FUNCTION_LOG_STORAGE_DRIVER_CIFS_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageDriverCifs", buffer, bufferSize)
#endif

View File

@ -10,77 +10,90 @@ Posix Storage File Read Driver
#include "common/io/read.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
#include "storage/driver/posix/common.h"
#include "storage/driver/posix/fileRead.h"
#include "storage/driver/posix/storage.intern.h"
#include "storage/fileRead.intern.h"
/***********************************************************************************************************************************
Object type
Object types
***********************************************************************************************************************************/
struct StorageDriverPosixFileRead
typedef struct StorageFileReadDriverPosix
{
MemContext *memContext;
StorageDriverPosix *storage;
StorageFileRead *interface;
IoRead *io;
String *name;
bool ignoreMissing;
MemContext *memContext; // Object mem context
StorageFileReadInterface interface; // Driver interface
StorageDriverPosix *storage; // Storage that created this object
int handle;
bool eof;
};
} StorageFileReadDriverPosix;
/***********************************************************************************************************************************
Create a new file
Macros for function logging
***********************************************************************************************************************************/
StorageDriverPosixFileRead *
storageDriverPosixFileReadNew(StorageDriverPosix *storage, const String *name, bool ignoreMissing)
#define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_POSIX_TYPE \
StorageFileReadDriverPosix *
#define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_POSIX_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageFileReadDriverPosix", buffer, bufferSize)
/***********************************************************************************************************************************
Close the file
***********************************************************************************************************************************/
static void
storageFileReadDriverPosixClose(THIS_VOID)
{
THIS(StorageFileReadDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, name);
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
FUNCTION_LOG_END();
ASSERT(name != NULL);
ASSERT(this != NULL);
StorageDriverPosixFileRead *this = NULL;
// Create the file object
MEM_CONTEXT_NEW_BEGIN("StorageDriverPosixFileRead")
// Close if the file has not already been closed
if (this->handle != -1)
{
this = memNew(sizeof(StorageDriverPosixFileRead));
this->memContext = MEM_CONTEXT_NEW();
this->storage = storage;
this->name = strDup(name);
this->ignoreMissing = ignoreMissing;
// Close the file
storageDriverPosixFileClose(this->handle, this->interface.name, true);
this->handle = -1;
this->interface = storageFileReadNewP(
STORAGE_DRIVER_POSIX_TYPE_STR, this,
.ignoreMissing = (StorageFileReadInterfaceIgnoreMissing)storageDriverPosixFileReadIgnoreMissing,
.io = (StorageFileReadInterfaceIo)storageDriverPosixFileReadIo,
.name = (StorageFileReadInterfaceName)storageDriverPosixFileReadName);
this->io = ioReadNewP(
this, .eof = (IoReadInterfaceEof)storageDriverPosixFileReadEof,
.close = (IoReadInterfaceClose)storageDriverPosixFileReadClose,
.handle = (IoReadInterfaceHandle)storageDriverPosixFileReadHandle,
.open = (IoReadInterfaceOpen)storageDriverPosixFileReadOpen, .read = (IoReadInterfaceRead)storageDriverPosixFileRead);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_DRIVER_POSIX_FILE_READ, this);
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Free the object
***********************************************************************************************************************************/
static void
storageFileReadDriverPosixFree(StorageFileReadDriverPosix *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
FUNCTION_LOG_END();
if (this != NULL)
{
storageFileReadDriverPosixClose(this);
memContextCallbackClear(this->memContext);
memContextFree(this->memContext);
}
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Open the file
***********************************************************************************************************************************/
bool
storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this)
static bool
storageFileReadDriverPosixOpen(THIS_VOID)
{
THIS(StorageFileReadDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
@ -89,12 +102,12 @@ storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this)
bool result = false;
// Open the file and handle errors
this->handle = storageDriverPosixFileOpen(this->name, O_RDONLY, 0, this->ignoreMissing, true, "read");
this->handle = storageDriverPosixFileOpen(this->interface.name, O_RDONLY, 0, this->interface.ignoreMissing, true, "read");
// On success set free callback to ensure file handle is freed
if (this->handle != -1)
{
memContextCallback(this->memContext, (MemContextCallback)storageDriverPosixFileReadFree, this);
memContextCallback(this->memContext, (MemContextCallback)storageFileReadDriverPosixFree, this);
result = true;
}
@ -104,11 +117,13 @@ storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this)
/***********************************************************************************************************************************
Read from a file
***********************************************************************************************************************************/
size_t
storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, bool block)
static size_t
storageFileReadDriverPosix(THIS_VOID, Buffer *buffer, bool block)
{
THIS(StorageFileReadDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_PARAM(BOOL, block);
FUNCTION_LOG_END();
@ -127,7 +142,7 @@ storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, boo
// Error occurred during read
if (actualBytes == -1)
THROW_SYS_ERROR_FMT(FileReadError, "unable to read '%s'", strPtr(this->name));
THROW_SYS_ERROR_FMT(FileReadError, "unable to read '%s'", strPtr(this->interface.name));
// Update amount of buffer used
bufUsedInc(buffer, (size_t)actualBytes);
@ -141,38 +156,16 @@ storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, boo
FUNCTION_LOG_RETURN(SIZE, (size_t)actualBytes);
}
/***********************************************************************************************************************************
Close the file
***********************************************************************************************************************************/
void
storageDriverPosixFileReadClose(StorageDriverPosixFileRead *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
// Close if the file has not already been closed
if (this->handle != -1)
{
// Close the file
storageDriverPosixFileClose(this->handle, this->name, true);
this->handle = -1;
}
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Has file reached EOF?
***********************************************************************************************************************************/
bool
storageDriverPosixFileReadEof(const StorageDriverPosixFileRead *this)
static bool
storageFileReadDriverPosixEof(THIS_VOID)
{
THIS(StorageFileReadDriverPosix);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
FUNCTION_TEST_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
@ -183,11 +176,13 @@ storageDriverPosixFileReadEof(const StorageDriverPosixFileRead *this)
/***********************************************************************************************************************************
Get handle (file descriptor)
***********************************************************************************************************************************/
int
storageDriverPosixFileReadHandle(const StorageDriverPosixFileRead *this)
static int
storageFileReadDriverPosixHandle(const THIS_VOID)
{
THIS(const StorageFileReadDriverPosix);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
FUNCTION_TEST_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
@ -196,82 +191,46 @@ storageDriverPosixFileReadHandle(const StorageDriverPosixFileRead *this)
}
/***********************************************************************************************************************************
Should a missing file be ignored?
***********************************************************************************************************************************/
bool
storageDriverPosixFileReadIgnoreMissing(const StorageDriverPosixFileRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->ignoreMissing);
}
/***********************************************************************************************************************************
Get the interface
New object
***********************************************************************************************************************************/
StorageFileRead *
storageDriverPosixFileReadInterface(const StorageDriverPosixFileRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface);
}
/***********************************************************************************************************************************
Get the I/O interface
***********************************************************************************************************************************/
IoRead *
storageDriverPosixFileReadIo(const StorageDriverPosixFileRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->io);
}
/***********************************************************************************************************************************
File name
***********************************************************************************************************************************/
const String *
storageDriverPosixFileReadName(const StorageDriverPosixFileRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->name);
}
/***********************************************************************************************************************************
Free the file
***********************************************************************************************************************************/
void
storageDriverPosixFileReadFree(StorageDriverPosixFileRead *this)
storageFileReadDriverPosixNew(StorageDriverPosix *storage, const String *name, bool ignoreMissing)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
FUNCTION_LOG_PARAM(STRING, name);
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
FUNCTION_LOG_END();
if (this != NULL)
ASSERT(name != NULL);
StorageFileRead *this = NULL;
MEM_CONTEXT_NEW_BEGIN("StorageFileReadDriverPosix")
{
storageDriverPosixFileReadClose(this);
StorageFileReadDriverPosix *driver = memNew(sizeof(StorageFileReadDriverPosix));
driver->memContext = MEM_CONTEXT_NEW();
memContextCallbackClear(this->memContext);
memContextFree(this->memContext);
}
driver->interface = (StorageFileReadInterface)
{
.type = STORAGE_DRIVER_POSIX_TYPE_STR,
.name = strDup(name),
.ignoreMissing = ignoreMissing,
FUNCTION_LOG_RETURN_VOID();
.ioInterface = (IoReadInterface)
{
.eof = storageFileReadDriverPosixEof,
.handle = storageFileReadDriverPosixHandle,
.open = storageFileReadDriverPosixOpen,
.read = storageFileReadDriverPosix,
},
};
driver->storage = storage;
driver->handle = -1;
this = storageFileReadNew(driver, &driver->interface);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, this);
}

View File

@ -4,49 +4,12 @@ Posix Storage File Read Driver
#ifndef STORAGE_DRIVER_POSIX_FILEREAD_H
#define STORAGE_DRIVER_POSIX_FILEREAD_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct StorageDriverPosixFileRead StorageDriverPosixFileRead;
#include "common/type/buffer.h"
#include "common/type/string.h"
#include "storage/driver/posix/storage.h"
#include "storage/fileRead.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
StorageDriverPosixFileRead *storageDriverPosixFileReadNew(StorageDriverPosix *storage, const String *name, bool ignoreMissing);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
bool storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this);
size_t storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, bool block);
void storageDriverPosixFileReadClose(StorageDriverPosixFileRead *this);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
bool storageDriverPosixFileReadEof(const StorageDriverPosixFileRead *this);
int storageDriverPosixFileReadHandle(const StorageDriverPosixFileRead *this);
bool storageDriverPosixFileReadIgnoreMissing(const StorageDriverPosixFileRead *this);
StorageFileRead *storageDriverPosixFileReadInterface(const StorageDriverPosixFileRead *this);
IoRead *storageDriverPosixFileReadIo(const StorageDriverPosixFileRead *this);
const String *storageDriverPosixFileReadName(const StorageDriverPosixFileRead *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void storageDriverPosixFileReadFree(StorageDriverPosixFileRead *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_POSIX_FILE_READ_TYPE \
StorageDriverPosixFileRead *
#define FUNCTION_LOG_STORAGE_DRIVER_POSIX_FILE_READ_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageDriverPosixFileRead", buffer, bufferSize)
StorageFileRead *storageFileReadDriverPosixNew(StorageDriverPosix *storage, const String *name, bool ignoreMissing);
#endif

View File

@ -14,36 +14,33 @@ Posix Storage File Write Driver
#include "common/io/write.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
#include "storage/driver/posix/common.h"
#include "storage/driver/posix/fileWrite.h"
#include "storage/driver/posix/storage.intern.h"
#include "storage/fileWrite.intern.h"
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct StorageDriverPosixFileWrite
typedef struct StorageFileWriteDriverPosix
{
MemContext *memContext;
StorageDriverPosix *storage;
StorageFileWrite *interface;
IoWrite *io;
String *nameTmp;
String *path;
String *name;
mode_t modeFile;
mode_t modePath;
const String *user;
const String *group;
time_t timeModified;
bool createPath;
bool syncFile;
bool syncPath;
bool atomic;
MemContext *memContext; // Object mem context
StorageFileWriteInterface interface; // Driver interface
StorageDriverPosix *storage; // Storage that created this object
const String *nameTmp;
const String *path;
int handle;
};
} StorageFileWriteDriverPosix;
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_POSIX_TYPE \
StorageFileWriteDriverPosix *
#define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_POSIX_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageFileWriteDriverPosix", buffer, bufferSize)
/***********************************************************************************************************************************
File open constants
@ -54,10 +51,195 @@ Since open is called more than once use constants to make sure these parameters
#define FILE_OPEN_PURPOSE "write"
/***********************************************************************************************************************************
Create a new file
Close the file
***********************************************************************************************************************************/
StorageDriverPosixFileWrite *
storageDriverPosixFileWriteNew(
static void
storageFileWriteDriverPosixClose(THIS_VOID)
{
THIS(StorageFileWriteDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_POSIX, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
// Close if the file has not already been closed
if (this->handle != -1)
{
// Sync the file
if (this->interface.syncFile)
storageDriverPosixFileSync(this->handle, this->nameTmp, true, false);
// Close the file
storageDriverPosixFileClose(this->handle, this->nameTmp, true);
// Update modified time
if (this->interface.timeModified != 0)
{
THROW_ON_SYS_ERROR_FMT(
utime(
strPtr(this->nameTmp),
&((struct utimbuf){.actime = this->interface.timeModified, .modtime = this->interface.timeModified})) == -1,
FileInfoError, "unable to set time for '%s'", strPtr(this->nameTmp));
}
// Rename from temp file
if (this->interface.atomic)
{
if (rename(strPtr(this->nameTmp), strPtr(this->interface.name)) == -1)
{
THROW_SYS_ERROR_FMT(
FileMoveError, "unable to move '%s' to '%s'", strPtr(this->nameTmp), strPtr(this->interface.name));
}
}
// Sync the path
if (this->interface.syncPath)
storageDriverPosixPathSync(this->storage, this->path, false);
// This marks the file as closed
this->handle = -1;
}
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Free object
***********************************************************************************************************************************/
static void
storageFileWriteDriverPosixFree(StorageFileWriteDriverPosix *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_POSIX, this);
FUNCTION_LOG_END();
if (this != NULL)
{
memContextCallbackClear(this->memContext);
// Close the temp file. *Close() must be called explicitly in order for the file to be sycn'ed, renamed, etc. If *Free()
// is called first the assumption is that some kind of error occurred and we should only close the handle to free
// resources.
if (this->handle != -1)
storageDriverPosixFileClose(this->handle, this->interface.name, true);
memContextFree(this->memContext);
}
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Open the file
***********************************************************************************************************************************/
static void
storageFileWriteDriverPosixOpen(THIS_VOID)
{
THIS(StorageFileWriteDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_POSIX, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(this->handle == -1);
// Open the file and handle errors
this->handle = storageDriverPosixFileOpen(
this->nameTmp, FILE_OPEN_FLAGS, this->interface.modeFile, this->interface.createPath, true, FILE_OPEN_PURPOSE);
// If path is missing
if (this->handle == -1)
{
// Create the path
storageDriverPosixPathCreate(this->storage, this->path, false, false, this->interface.modePath);
// Try the open again
this->handle = storageDriverPosixFileOpen(
this->nameTmp, FILE_OPEN_FLAGS, this->interface.modeFile, false, true, FILE_OPEN_PURPOSE);
}
// Set free callback to ensure file handle is freed
memContextCallback(this->memContext, (MemContextCallback)storageFileWriteDriverPosixFree, this);
// Update user/group owner
if (this->interface.user != NULL || this->interface.group != NULL)
{
struct passwd *userData = NULL;
struct group *groupData = NULL;
if (this->interface.user != NULL)
{
THROW_ON_SYS_ERROR_FMT(
(userData = getpwnam(strPtr(this->interface.user))) == NULL, UserMissingError, "unable to find user '%s'",
strPtr(this->interface.user));
}
if (this->interface.group != NULL)
{
THROW_ON_SYS_ERROR_FMT(
(groupData = getgrnam(strPtr(this->interface.group))) == NULL, GroupMissingError, "unable to find group '%s'",
strPtr(this->interface.group));
}
THROW_ON_SYS_ERROR_FMT(
chown(
strPtr(this->nameTmp), userData != NULL ? userData->pw_uid : (uid_t)-1,
groupData != NULL ? groupData->gr_gid : (gid_t)-1) == -1,
FileOwnerError, "unable to set ownership for '%s'", strPtr(this->nameTmp));
}
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Write to the file
***********************************************************************************************************************************/
static void
storageFileWriteDriverPosix(THIS_VOID, const Buffer *buffer)
{
THIS(StorageFileWriteDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(buffer != NULL);
ASSERT(this->handle != -1);
// Write the data
if (write(this->handle, bufPtr(buffer), bufUsed(buffer)) != (ssize_t)bufUsed(buffer))
THROW_SYS_ERROR_FMT(FileWriteError, "unable to write '%s'", strPtr(this->nameTmp));
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Get handle (file descriptor)
***********************************************************************************************************************************/
static int
storageFileWriteDriverPosixHandle(const THIS_VOID)
{
THIS(const StorageFileWriteDriverPosix);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE_DRIVER_POSIX, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->handle);
}
/***********************************************************************************************************************************
New object
***********************************************************************************************************************************/
StorageFileWrite *
storageFileWriteDriverPosixNew(
StorageDriverPosix *storage, const String *name, mode_t modeFile, mode_t modePath, const String *user, const String *group,
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
{
@ -80,357 +262,44 @@ storageDriverPosixFileWriteNew(
ASSERT(modeFile != 0);
ASSERT(modePath != 0);
StorageDriverPosixFileWrite *this = NULL;
StorageFileWrite *this = NULL;
// Create the file
MEM_CONTEXT_NEW_BEGIN("StorageDriverPosixFileWrite")
MEM_CONTEXT_NEW_BEGIN("StorageFileWriteDriverPosix")
{
this = memNew(sizeof(StorageDriverPosixFileWrite));
this->memContext = MEM_CONTEXT_NEW();
this->storage = storage;
StorageFileWriteDriverPosix *driver = memNew(sizeof(StorageFileWriteDriverPosix));
driver->memContext = MEM_CONTEXT_NEW();
this->interface = storageFileWriteNewP(
STORAGE_DRIVER_POSIX_TYPE_STR, this, .atomic = (StorageFileWriteInterfaceAtomic)storageDriverPosixFileWriteAtomic,
.createPath = (StorageFileWriteInterfaceCreatePath)storageDriverPosixFileWriteCreatePath,
.io = (StorageFileWriteInterfaceIo)storageDriverPosixFileWriteIo,
.modeFile = (StorageFileWriteInterfaceModeFile)storageDriverPosixFileWriteModeFile,
.modePath = (StorageFileWriteInterfaceModePath)storageDriverPosixFileWriteModePath,
.name = (StorageFileWriteInterfaceName)storageDriverPosixFileWriteName,
.syncFile = (StorageFileWriteInterfaceSyncFile)storageDriverPosixFileWriteSyncFile,
.syncPath = (StorageFileWriteInterfaceSyncPath)storageDriverPosixFileWriteSyncPath);
driver->interface = (StorageFileWriteInterface)
{
.type = STORAGE_DRIVER_POSIX_TYPE_STR,
.name = strDup(name),
.atomic = atomic,
.createPath = createPath,
.group = strDup(group),
.modeFile = modeFile,
.modePath = modePath,
.syncFile = syncFile,
.syncPath = syncPath,
.user = strDup(user),
.timeModified = timeModified,
this->io = ioWriteNewP(
this, .close = (IoWriteInterfaceClose)storageDriverPosixFileWriteClose,
.handle = (IoWriteInterfaceHandle)storageDriverPosixFileWriteHandle,
.open = (IoWriteInterfaceOpen)storageDriverPosixFileWriteOpen,
.write = (IoWriteInterfaceWrite)storageDriverPosixFileWrite);
.ioInterface = (IoWriteInterface)
{
.close = storageFileWriteDriverPosixClose,
.handle = storageFileWriteDriverPosixHandle,
.open = storageFileWriteDriverPosixOpen,
.write = storageFileWriteDriverPosix,
},
};
this->path = strPath(name);
this->name = strDup(name);
this->nameTmp = atomic ? strNewFmt("%s." STORAGE_FILE_TEMP_EXT, strPtr(name)) : this->name;
this->modeFile = modeFile;
this->modePath = modePath;
this->user = strDup(user);
this->group = strDup(group);
this->timeModified = timeModified;
this->createPath = createPath;
this->syncFile = syncFile;
this->syncPath = syncPath;
this->atomic = atomic;
driver->storage = storage;
driver->nameTmp = atomic ? strNewFmt("%s." STORAGE_FILE_TEMP_EXT, strPtr(name)) : driver->interface.name;
driver->path = strPath(name);
driver->handle = -1;
this->handle = -1;
this = storageFileWriteNew(driver, &driver->interface);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
}
/***********************************************************************************************************************************
Open the file
***********************************************************************************************************************************/
void
storageDriverPosixFileWriteOpen(StorageDriverPosixFileWrite *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(this->handle == -1);
// Open the file and handle errors
this->handle = storageDriverPosixFileOpen(
this->nameTmp, FILE_OPEN_FLAGS, this->modeFile, this->createPath, true, FILE_OPEN_PURPOSE);
// If path is missing
if (this->handle == -1)
{
// Create the path
storageDriverPosixPathCreate(this->storage, this->path, false, false, this->modePath);
// Try the open again
this->handle = storageDriverPosixFileOpen(
this->nameTmp, FILE_OPEN_FLAGS, this->modeFile, false, true, FILE_OPEN_PURPOSE);
}
// On success set free callback to ensure file handle is freed
else
memContextCallback(this->memContext, (MemContextCallback)storageDriverPosixFileWriteFree, this);
// Update user/group owner
if (this->user != NULL || this->group != NULL)
{
struct passwd *userData = NULL;
struct group *groupData = NULL;
if (this->user != NULL)
{
THROW_ON_SYS_ERROR_FMT(
(userData = getpwnam(strPtr(this->user))) == NULL, UserMissingError, "unable to find user '%s'",
strPtr(this->user));
}
if (this->group != NULL)
{
THROW_ON_SYS_ERROR_FMT(
(groupData = getgrnam(strPtr(this->group))) == NULL, GroupMissingError, "unable to find group '%s'",
strPtr(this->group));
}
THROW_ON_SYS_ERROR_FMT(
chown(
strPtr(this->nameTmp), userData != NULL ? userData->pw_uid : (uid_t)-1,
groupData != NULL ? groupData->gr_gid : (gid_t)-1) == -1,
FileOwnerError, "unable to set ownership for '%s'", strPtr(this->nameTmp));
}
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Write to a file
***********************************************************************************************************************************/
void
storageDriverPosixFileWrite(StorageDriverPosixFileWrite *this, const Buffer *buffer)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(buffer != NULL);
ASSERT(this->handle != -1);
// Write the data
if (write(this->handle, bufPtr(buffer), bufUsed(buffer)) != (ssize_t)bufUsed(buffer))
THROW_SYS_ERROR_FMT(FileWriteError, "unable to write '%s'", strPtr(this->nameTmp));
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Close the file
***********************************************************************************************************************************/
void
storageDriverPosixFileWriteClose(StorageDriverPosixFileWrite *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
// Close if the file has not already been closed
if (this->handle != -1)
{
// Sync the file
if (this->syncFile)
storageDriverPosixFileSync(this->handle, this->nameTmp, true, false);
// Close the file
storageDriverPosixFileClose(this->handle, this->nameTmp, true);
// Update modified time
if (this->timeModified != 0)
{
THROW_ON_SYS_ERROR_FMT(
utime(
strPtr(this->nameTmp), &((struct utimbuf){.actime = this->timeModified, .modtime = this->timeModified})) == -1,
FileInfoError, "unable to set time for '%s'", strPtr(this->nameTmp));
}
// Rename from temp file
if (this->atomic)
{
if (rename(strPtr(this->nameTmp), strPtr(this->name)) == -1)
THROW_SYS_ERROR_FMT(FileMoveError, "unable to move '%s' to '%s'", strPtr(this->nameTmp), strPtr(this->name));
}
// Sync the path
if (this->syncPath)
storageDriverPosixPathSync(this->storage, this->path, false);
// This marks the file as closed
this->handle = -1;
}
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Will the file be written atomically?
For the posix driver this means writing to a temp file first and then renaming once it is closed and synced.
***********************************************************************************************************************************/
bool
storageDriverPosixFileWriteAtomic(const StorageDriverPosixFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->atomic);
}
/***********************************************************************************************************************************
Will the path be created for the file if it does not exist?
***********************************************************************************************************************************/
bool
storageDriverPosixFileWriteCreatePath(const StorageDriverPosixFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->createPath);
}
/***********************************************************************************************************************************
Get handle (file descriptor)
***********************************************************************************************************************************/
int
storageDriverPosixFileWriteHandle(const StorageDriverPosixFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->handle);
}
/***********************************************************************************************************************************
Get interface
***********************************************************************************************************************************/
StorageFileWrite *
storageDriverPosixFileWriteInterface(const StorageDriverPosixFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface);
}
/***********************************************************************************************************************************
Get I/O interface
***********************************************************************************************************************************/
IoWrite *
storageDriverPosixFileWriteIo(const StorageDriverPosixFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->io);
}
/***********************************************************************************************************************************
Mode for the file to be created
***********************************************************************************************************************************/
mode_t
storageDriverPosixFileWriteModeFile(const StorageDriverPosixFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->modeFile);
}
/***********************************************************************************************************************************
Mode for any paths that are created while writing the file
***********************************************************************************************************************************/
mode_t
storageDriverPosixFileWriteModePath(const StorageDriverPosixFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->modePath);
}
/***********************************************************************************************************************************
File name
***********************************************************************************************************************************/
const String *
storageDriverPosixFileWriteName(const StorageDriverPosixFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->name);
}
/***********************************************************************************************************************************
Will the file be synced after it is closed?
***********************************************************************************************************************************/
bool
storageDriverPosixFileWriteSyncFile(const StorageDriverPosixFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->syncFile);
}
/***********************************************************************************************************************************
Will the directory be synced to disk after the write is completed?
***********************************************************************************************************************************/
bool
storageDriverPosixFileWriteSyncPath(const StorageDriverPosixFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->syncPath);
}
/***********************************************************************************************************************************
Free the file
***********************************************************************************************************************************/
void
storageDriverPosixFileWriteFree(StorageDriverPosixFileWrite *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
FUNCTION_LOG_END();
if (this != NULL)
{
memContextCallbackClear(this->memContext);
// Close the temp file. *Close() must be called explicitly in order for the file to be sycn'ed, renamed, etc. If *Free()
// is called first the assumption is that some kind of error occurred and we should only close the handle to free
// resources.
if (this->handle != -1)
storageDriverPosixFileClose(this->handle, this->name, true);
memContextFree(this->memContext);
}
FUNCTION_LOG_RETURN_VOID();
FUNCTION_LOG_RETURN(STORAGE_FILE_WRITE, this);
}

View File

@ -4,57 +4,15 @@ Posix Storage File Write Driver
#ifndef STORAGE_DRIVER_POSIX_FILEWRITE_H
#define STORAGE_DRIVER_POSIX_FILEWRITE_H
#include <sys/types.h>
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct StorageDriverPosixFileWrite StorageDriverPosixFileWrite;
#include "common/type/buffer.h"
#include "storage/fileWrite.intern.h"
#include "storage/driver/posix/storage.h"
#include "storage/fileWrite.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
StorageDriverPosixFileWrite *storageDriverPosixFileWriteNew(
StorageFileWrite *storageFileWriteDriverPosixNew(
StorageDriverPosix *storage, const String *name, mode_t modeFile, mode_t modePath, const String *user, const String *group,
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void storageDriverPosixFileWriteOpen(StorageDriverPosixFileWrite *this);
void storageDriverPosixFileWrite(StorageDriverPosixFileWrite *this, const Buffer *buffer);
void storageDriverPosixFileWriteClose(StorageDriverPosixFileWrite *this);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
bool storageDriverPosixFileWriteAtomic(const StorageDriverPosixFileWrite *this);
bool storageDriverPosixFileWriteCreatePath(const StorageDriverPosixFileWrite *this);
mode_t storageDriverPosixFileWriteModeFile(const StorageDriverPosixFileWrite *this);
int storageDriverPosixFileWriteHandle(const StorageDriverPosixFileWrite *this);
StorageFileWrite* storageDriverPosixFileWriteInterface(const StorageDriverPosixFileWrite *this);
IoWrite *storageDriverPosixFileWriteIo(const StorageDriverPosixFileWrite *this);
mode_t storageDriverPosixFileWriteModePath(const StorageDriverPosixFileWrite *this);
const String *storageDriverPosixFileWriteName(const StorageDriverPosixFileWrite *this);
const StorageDriverPosix *storageDriverPosixFileWriteStorage(const StorageDriverPosixFileWrite *this);
bool storageDriverPosixFileWriteSyncFile(const StorageDriverPosixFileWrite *this);
bool storageDriverPosixFileWriteSyncPath(const StorageDriverPosixFileWrite *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void storageDriverPosixFileWriteFree(StorageDriverPosixFileWrite *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_POSIX_FILE_WRITE_TYPE \
StorageDriverPosixFileWrite *
#define FUNCTION_LOG_STORAGE_DRIVER_POSIX_FILE_WRITE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageDriverPosixFileWrite", buffer, bufferSize)
#endif

View File

@ -7,6 +7,7 @@ Posix Storage Driver
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <limits.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
@ -17,16 +18,11 @@ Posix Storage Driver
#include "common/log.h"
#include "common/memContext.h"
#include "common/regExp.h"
#include "storage/driver/posix/storage.h"
#include "storage/driver/posix/fileRead.h"
#include "storage/driver/posix/fileWrite.h"
#include "storage/driver/posix/storage.intern.h"
#include "storage/driver/posix/common.h"
/***********************************************************************************************************************************
Define PATH_MAX if it is not defined
***********************************************************************************************************************************/
#ifndef PATH_MAX
#define PATH_MAX (4 * 1024)
#endif
/***********************************************************************************************************************************
Driver type constant string
***********************************************************************************************************************************/
@ -38,58 +34,17 @@ Object type
struct StorageDriverPosix
{
MemContext *memContext; // Object memory context
Storage *interface; // Driver interface
bool syncPath; // Will paths be synced?
};
/***********************************************************************************************************************************
New object
***********************************************************************************************************************************/
StorageDriverPosix *
storageDriverPosixNew(
const String *path, mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STRING, path);
FUNCTION_LOG_PARAM(MODE, modeFile);
FUNCTION_LOG_PARAM(MODE, modePath);
FUNCTION_LOG_PARAM(BOOL, write);
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
FUNCTION_LOG_END();
ASSERT(path != NULL);
ASSERT(modeFile != 0);
ASSERT(modePath != 0);
// Create the object
StorageDriverPosix *this = NULL;
MEM_CONTEXT_NEW_BEGIN("StorageDriverPosix")
{
this = memNew(sizeof(StorageDriverPosix));
this->memContext = MEM_CONTEXT_NEW();
this->interface = storageNewP(
STORAGE_DRIVER_POSIX_TYPE_STR, path, modeFile, modePath, write, pathExpressionFunction, this,
.exists = (StorageInterfaceExists)storageDriverPosixExists, .info = (StorageInterfaceInfo)storageDriverPosixInfo,
.infoList = (StorageInterfaceInfoList)storageDriverPosixInfoList, .list = (StorageInterfaceList)storageDriverPosixList,
.move = (StorageInterfaceMove)storageDriverPosixMove, .newRead = (StorageInterfaceNewRead)storageDriverPosixNewRead,
.newWrite = (StorageInterfaceNewWrite)storageDriverPosixNewWrite,
.pathCreate = (StorageInterfacePathCreate)storageDriverPosixPathCreate,
.pathRemove = (StorageInterfacePathRemove)storageDriverPosixPathRemove,
.pathSync = (StorageInterfacePathSync)storageDriverPosixPathSync,
.remove = (StorageInterfaceRemove)storageDriverPosixRemove);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_DRIVER_POSIX, this);
}
/***********************************************************************************************************************************
Does a file exist? This function is only for files, not paths.
***********************************************************************************************************************************/
bool
storageDriverPosixExists(StorageDriverPosix *this, const String *path)
static bool
storageDriverPosixExists(THIS_VOID, const String *path)
{
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -119,9 +74,11 @@ storageDriverPosixExists(StorageDriverPosix *this, const String *path)
/***********************************************************************************************************************************
File/path info
***********************************************************************************************************************************/
StorageInfo
storageDriverPosixInfo(StorageDriverPosix *this, const String *file, bool ignoreMissing, bool followLink)
static StorageInfo
storageDriverPosixInfo(THIS_VOID, const String *file, bool ignoreMissing, bool followLink)
{
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, file);
@ -227,10 +184,12 @@ storageDriverPosixInfoListEntry(
FUNCTION_TEST_RETURN_VOID();
}
bool
static bool
storageDriverPosixInfoList(
StorageDriverPosix *this, const String *path, bool errorOnMissing, StorageInfoListCallback callback, void *callbackData)
THIS_VOID, const String *path, bool errorOnMissing, StorageInfoListCallback callback, void *callbackData)
{
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -292,9 +251,11 @@ storageDriverPosixInfoList(
/***********************************************************************************************************************************
Get a list of files from a directory
***********************************************************************************************************************************/
StringList *
storageDriverPosixList(StorageDriverPosix *this, const String *path, bool errorOnMissing, const String *expression)
static StringList *
storageDriverPosixList(THIS_VOID, const String *path, bool errorOnMissing, const String *expression)
{
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -362,13 +323,15 @@ storageDriverPosixList(StorageDriverPosix *this, const String *path, bool errorO
/***********************************************************************************************************************************
Move a path/file
***********************************************************************************************************************************/
bool
storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *source, StorageDriverPosixFileWrite *destination)
static bool
storageDriverPosixMove(THIS_VOID, StorageFileRead *source, StorageFileWrite *destination)
{
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, source);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, destination);
FUNCTION_LOG_PARAM(STORAGE_FILE_READ, source);
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE, destination);
FUNCTION_LOG_END();
ASSERT(this != NULL);
@ -379,8 +342,8 @@ storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *sou
MEM_CONTEXT_TEMP_BEGIN()
{
const String *sourceFile = storageDriverPosixFileReadName(source);
const String *destinationFile = storageDriverPosixFileWriteName(destination);
const String *sourceFile = storageFileReadName(source);
const String *destinationFile = storageFileWriteName(destination);
const String *destinationPath = strPath(destinationFile);
// Attempt to move the file
@ -392,13 +355,13 @@ storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *sou
if (!storageDriverPosixExists(this, sourceFile))
THROW_SYS_ERROR_FMT(FileMissingError, "unable to move missing file '%s'", strPtr(sourceFile));
if (!storageDriverPosixFileWriteCreatePath(destination))
if (!storageFileWriteCreatePath(destination))
{
THROW_SYS_ERROR_FMT(
PathMissingError, "unable to move '%s' to missing path '%s'", strPtr(sourceFile), strPtr(destinationPath));
}
storageDriverPosixPathCreate(this, destinationPath, false, false, storageDriverPosixFileWriteModePath(destination));
storageDriverPosixPathCreate(this, destinationPath, false, false, storageFileWriteModePath(destination));
result = storageDriverPosixMove(this, source, destination);
}
// Else the destination is on a different device so a copy will be needed
@ -413,7 +376,7 @@ storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *sou
else
{
// Sync source path if the destination path was synced and the paths are not equal
if (storageDriverPosixFileWriteSyncPath(destination))
if (storageFileWriteSyncPath(destination))
{
String *sourcePath = strPath(sourceFile);
@ -430,9 +393,11 @@ storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *sou
/***********************************************************************************************************************************
New file read object
***********************************************************************************************************************************/
StorageFileRead *
storageDriverPosixNewRead(StorageDriverPosix *this, const String *file, bool ignoreMissing)
static StorageFileRead *
storageDriverPosixNewRead(THIS_VOID, const String *file, bool ignoreMissing)
{
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, file);
@ -442,18 +407,19 @@ storageDriverPosixNewRead(StorageDriverPosix *this, const String *file, bool ign
ASSERT(this != NULL);
ASSERT(file != NULL);
FUNCTION_LOG_RETURN(
STORAGE_FILE_READ, storageDriverPosixFileReadInterface(storageDriverPosixFileReadNew(this, file, ignoreMissing)));
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, storageFileReadDriverPosixNew(this, file, ignoreMissing));
}
/***********************************************************************************************************************************
New file write object
***********************************************************************************************************************************/
StorageFileWrite *
static StorageFileWrite *
storageDriverPosixNewWrite(
StorageDriverPosix *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
THIS_VOID, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
{
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, file);
@ -473,17 +439,19 @@ storageDriverPosixNewWrite(
FUNCTION_LOG_RETURN(
STORAGE_FILE_WRITE,
storageDriverPosixFileWriteInterface(
storageDriverPosixFileWriteNew(
this, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, syncPath, atomic)));
storageFileWriteDriverPosixNew(
this, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, this->syncPath ? syncPath : false,
atomic));
}
/***********************************************************************************************************************************
Create a path
***********************************************************************************************************************************/
void
storageDriverPosixPathCreate(StorageDriverPosix *this, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
storageDriverPosixPathCreate(THIS_VOID, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
{
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -515,9 +483,11 @@ storageDriverPosixPathCreate(StorageDriverPosix *this, const String *path, bool
/***********************************************************************************************************************************
Remove a path
***********************************************************************************************************************************/
void
storageDriverPosixPathRemove(StorageDriverPosix *this, const String *path, bool errorOnMissing, bool recurse)
static void
storageDriverPosixPathRemove(THIS_VOID, const String *path, bool errorOnMissing, bool recurse)
{
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -574,8 +544,10 @@ storageDriverPosixPathRemove(StorageDriverPosix *this, const String *path, bool
Sync a path
***********************************************************************************************************************************/
void
storageDriverPosixPathSync(StorageDriverPosix *this, const String *path, bool ignoreMissing)
storageDriverPosixPathSync(THIS_VOID, const String *path, bool ignoreMissing)
{
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -585,6 +557,8 @@ storageDriverPosixPathSync(StorageDriverPosix *this, const String *path, bool ig
ASSERT(this != NULL);
ASSERT(path != NULL);
if (this->syncPath)
{
// Open directory and handle errors
int handle = storageDriverPosixFileOpen(path, O_RDONLY, 0, ignoreMissing, false, "sync");
@ -597,6 +571,7 @@ storageDriverPosixPathSync(StorageDriverPosix *this, const String *path, bool ig
// Close the directory
storageDriverPosixFileClose(handle, path, false);
}
}
FUNCTION_LOG_RETURN_VOID();
}
@ -604,9 +579,11 @@ storageDriverPosixPathSync(StorageDriverPosix *this, const String *path, bool ig
/***********************************************************************************************************************************
Remove a file
***********************************************************************************************************************************/
void
storageDriverPosixRemove(StorageDriverPosix *this, const String *file, bool errorOnMissing)
static void
storageDriverPosixRemove(THIS_VOID, const String *file, bool errorOnMissing)
{
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, file);
@ -627,32 +604,63 @@ storageDriverPosixRemove(StorageDriverPosix *this, const String *file, bool erro
}
/***********************************************************************************************************************************
Getters
New object
***********************************************************************************************************************************/
Storage *
storageDriverPosixInterface(const StorageDriverPosix *this)
storageDriverPosixNewInternal(
const String *type, const String *path, mode_t modeFile, mode_t modePath, bool write,
StoragePathExpressionCallback pathExpressionFunction, bool syncPath)
{
FUNCTION_TEST_BEGIN();
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface);
}
/***********************************************************************************************************************************
Free the file
***********************************************************************************************************************************/
void
storageDriverPosixFree(StorageDriverPosix *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STRING, type);
FUNCTION_LOG_PARAM(STRING, path);
FUNCTION_LOG_PARAM(MODE, modeFile);
FUNCTION_LOG_PARAM(MODE, modePath);
FUNCTION_LOG_PARAM(BOOL, write);
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
FUNCTION_LOG_PARAM(BOOL, syncPath);
FUNCTION_LOG_END();
if (this != NULL)
memContextFree(this->memContext);
ASSERT(type != NULL);
ASSERT(path != NULL);
ASSERT(modeFile != 0);
ASSERT(modePath != 0);
FUNCTION_LOG_RETURN_VOID();
// Create the object
Storage *this = NULL;
MEM_CONTEXT_NEW_BEGIN("StorageDriverPosix")
{
StorageDriverPosix *driver = memNew(sizeof(StorageDriverPosix));
driver->memContext = MEM_CONTEXT_NEW();
driver->syncPath = syncPath;
this = storageNewP(
type, path, modeFile, modePath, write, pathExpressionFunction, driver, .exists = storageDriverPosixExists,
.info = storageDriverPosixInfo, .infoList = storageDriverPosixInfoList, .list = storageDriverPosixList,
.move = storageDriverPosixMove, .newRead = storageDriverPosixNewRead, .newWrite = storageDriverPosixNewWrite,
.pathCreate = storageDriverPosixPathCreate, .pathRemove = storageDriverPosixPathRemove,
.pathSync = storageDriverPosixPathSync, .remove = storageDriverPosixRemove);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE, this);
}
Storage *
storageDriverPosixNew(
const String *path, mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STRING, path);
FUNCTION_LOG_PARAM(MODE, modeFile);
FUNCTION_LOG_PARAM(MODE, modePath);
FUNCTION_LOG_PARAM(BOOL, write);
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
FUNCTION_LOG_END();
FUNCTION_LOG_RETURN(
STORAGE,
storageDriverPosixNewInternal(
STORAGE_DRIVER_POSIX_TYPE_STR, path, modeFile, modePath, write, pathExpressionFunction, true));
}

View File

@ -9,13 +9,6 @@ Object type
***********************************************************************************************************************************/
typedef struct StorageDriverPosix StorageDriverPosix;
#include <sys/types.h>
#include "common/type/buffer.h"
#include "common/type/stringList.h"
#include "storage/driver/posix/fileRead.h"
#include "storage/driver/posix/fileWrite.h"
#include "storage/info.h"
#include "storage/storage.intern.h"
/***********************************************************************************************************************************
@ -27,44 +20,7 @@ Driver type constant
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
StorageDriverPosix *storageDriverPosixNew(
Storage *storageDriverPosixNew(
const String *path, mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
bool storageDriverPosixExists(StorageDriverPosix *this, const String *path);
StorageInfo storageDriverPosixInfo(StorageDriverPosix *this, const String *file, bool ignoreMissing, bool followLink);
bool storageDriverPosixInfoList(
StorageDriverPosix *this, const String *path, bool errorOnMissing, StorageInfoListCallback callback, void *callbackData);
StringList *storageDriverPosixList(StorageDriverPosix *this, const String *path, bool errorOnMissing, const String *expression);
bool storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *source, StorageDriverPosixFileWrite *destination);
StorageFileRead *storageDriverPosixNewRead(StorageDriverPosix *this, const String *file, bool ignoreMissing);
StorageFileWrite *storageDriverPosixNewWrite(
StorageDriverPosix *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
void storageDriverPosixPathCreate(
StorageDriverPosix *this, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode);
void storageDriverPosixPathRemove(StorageDriverPosix *this, const String *path, bool errorOnMissing, bool recurse);
void storageDriverPosixPathSync(StorageDriverPosix *this, const String *path, bool ignoreMissing);
void storageDriverPosixRemove(StorageDriverPosix *this, const String *file, bool errorOnMissing);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
Storage *storageDriverPosixInterface(const StorageDriverPosix *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void storageDriverPosixFree(StorageDriverPosix *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_POSIX_TYPE \
StorageDriverPosix *
#define FUNCTION_LOG_STORAGE_DRIVER_POSIX_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageDriverPosix", buffer, bufferSize)
#endif

View File

@ -0,0 +1,31 @@
/***********************************************************************************************************************************
Posix Storage Driver Internal
***********************************************************************************************************************************/
#ifndef STORAGE_DRIVER_POSIX_STORAGE_INTERN_H
#define STORAGE_DRIVER_POSIX_STORAGE_INTERN_H
#include "common/object.h"
#include "storage/driver/posix/storage.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
Storage *storageDriverPosixNewInternal(
const String *type, const String *path, mode_t modeFile, mode_t modePath, bool write,
StoragePathExpressionCallback pathExpressionFunction, bool pathSync);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void storageDriverPosixPathCreate(THIS_VOID, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode);
void storageDriverPosixPathSync(THIS_VOID, const String *path, bool ignoreMissing);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_POSIX_TYPE \
StorageDriverPosix *
#define FUNCTION_LOG_STORAGE_DRIVER_POSIX_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageDriverPosix *", buffer, bufferSize)
#endif

View File

@ -10,6 +10,7 @@ Remote Storage File Read Driver
#include "common/io/read.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
#include "common/type/convert.h"
#include "storage/driver/remote/fileRead.h"
#include "storage/driver/remote/protocol.h"
@ -18,73 +19,35 @@ Remote Storage File Read Driver
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct StorageDriverRemoteFileRead
typedef struct StorageFileReadDriverRemote
{
MemContext *memContext;
StorageDriverRemote *storage;
StorageFileRead *interface;
IoRead *io;
String *name;
bool ignoreMissing;
MemContext *memContext; // Object mem context
StorageFileReadInterface interface; // Driver interface
StorageDriverRemote *storage; // Storage that created this object
ProtocolClient *client; // Protocol client for requests
size_t remaining; // Bytes remaining to be read
size_t remaining; // Bytes remaining to be read in block
bool eof; // Has the file reached eof?
};
} StorageFileReadDriverRemote;
/***********************************************************************************************************************************
Create a new file
Macros for function logging
***********************************************************************************************************************************/
StorageDriverRemoteFileRead *
storageDriverRemoteFileReadNew(StorageDriverRemote *storage, ProtocolClient *client, const String *name, bool ignoreMissing)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, storage);
FUNCTION_LOG_PARAM(PROTOCOL_CLIENT, client);
FUNCTION_LOG_PARAM(STRING, name);
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
FUNCTION_LOG_END();
ASSERT(storage != NULL);
ASSERT(client != NULL);
ASSERT(name != NULL);
StorageDriverRemoteFileRead *this = NULL;
// Create the file object
MEM_CONTEXT_NEW_BEGIN("StorageDriverRemoteFileRead")
{
this = memNew(sizeof(StorageDriverRemoteFileRead));
this->memContext = MEM_CONTEXT_NEW();
this->storage = storage;
this->name = strDup(name);
this->ignoreMissing = ignoreMissing;
this->client = client;
this->interface = storageFileReadNewP(
strNew(STORAGE_DRIVER_REMOTE_TYPE), this,
.ignoreMissing = (StorageFileReadInterfaceIgnoreMissing)storageDriverRemoteFileReadIgnoreMissing,
.io = (StorageFileReadInterfaceIo)storageDriverRemoteFileReadIo,
.name = (StorageFileReadInterfaceName)storageDriverRemoteFileReadName);
this->io = ioReadNewP(
this, .eof = (IoReadInterfaceEof)storageDriverRemoteFileReadEof,
.open = (IoReadInterfaceOpen)storageDriverRemoteFileReadOpen, .read = (IoReadInterfaceRead)storageDriverRemoteFileRead);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_DRIVER_REMOTE_FILE_READ, this);
}
#define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_REMOTE_TYPE \
StorageFileReadDriverRemote *
#define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_REMOTE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageFileReadDriverRemote", buffer, bufferSize)
/***********************************************************************************************************************************
Open the file
***********************************************************************************************************************************/
bool
storageDriverRemoteFileReadOpen(StorageDriverRemoteFileRead *this)
static bool
storageFileReadDriverRemoteOpen(THIS_VOID)
{
THIS(StorageFileReadDriverRemote);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this);
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_REMOTE, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
@ -94,8 +57,8 @@ storageDriverRemoteFileReadOpen(StorageDriverRemoteFileRead *this)
MEM_CONTEXT_TEMP_BEGIN()
{
ProtocolCommand *command = protocolCommandNew(PROTOCOL_COMMAND_STORAGE_OPEN_READ_STR);
protocolCommandParamAdd(command, VARSTR(this->name));
protocolCommandParamAdd(command, VARBOOL(this->ignoreMissing));
protocolCommandParamAdd(command, VARSTR(this->interface.name));
protocolCommandParamAdd(command, VARBOOL(this->interface.ignoreMissing));
result = varBool(protocolClientExecute(this->client, command, true));
}
@ -107,11 +70,13 @@ storageDriverRemoteFileReadOpen(StorageDriverRemoteFileRead *this)
/***********************************************************************************************************************************
Read from a file
***********************************************************************************************************************************/
size_t
storageDriverRemoteFileRead(StorageDriverRemoteFileRead *this, Buffer *buffer, bool block)
static size_t
storageFileReadDriverRemote(THIS_VOID, Buffer *buffer, bool block)
{
THIS(StorageFileReadDriverRemote);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this);
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_PARAM(BOOL, block);
FUNCTION_LOG_END();
@ -164,11 +129,13 @@ storageDriverRemoteFileRead(StorageDriverRemoteFileRead *this, Buffer *buffer, b
/***********************************************************************************************************************************
Has file reached EOF?
***********************************************************************************************************************************/
bool
storageDriverRemoteFileReadEof(const StorageDriverRemoteFileRead *this)
static bool
storageFileReadDriverRemoteEof(THIS_VOID)
{
THIS(StorageFileReadDriverRemote);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this);
FUNCTION_TEST_PARAM(STORAGE_FILE_READ_DRIVER_REMOTE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
@ -177,61 +144,49 @@ storageDriverRemoteFileReadEof(const StorageDriverRemoteFileRead *this)
}
/***********************************************************************************************************************************
Should a missing file be ignored?
***********************************************************************************************************************************/
bool
storageDriverRemoteFileReadIgnoreMissing(const StorageDriverRemoteFileRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->ignoreMissing);
}
/***********************************************************************************************************************************
Get the interface
New object
***********************************************************************************************************************************/
StorageFileRead *
storageDriverRemoteFileReadInterface(const StorageDriverRemoteFileRead *this)
storageFileReadDriverRemoteNew(StorageDriverRemote *storage, ProtocolClient *client, const String *name, bool ignoreMissing)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this);
FUNCTION_TEST_END();
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, storage);
FUNCTION_LOG_PARAM(PROTOCOL_CLIENT, client);
FUNCTION_LOG_PARAM(STRING, name);
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(storage != NULL);
ASSERT(client != NULL);
ASSERT(name != NULL);
FUNCTION_TEST_RETURN(this->interface);
}
StorageFileRead *this = NULL;
/***********************************************************************************************************************************
Get the I/O interface
***********************************************************************************************************************************/
IoRead *
storageDriverRemoteFileReadIo(const StorageDriverRemoteFileRead *this)
MEM_CONTEXT_NEW_BEGIN("StorageFileReadDriverRemote")
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this);
FUNCTION_TEST_END();
StorageFileReadDriverRemote *driver = memNew(sizeof(StorageFileReadDriverRemote));
driver->memContext = MEM_CONTEXT_NEW();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->io);
}
/***********************************************************************************************************************************
File name
***********************************************************************************************************************************/
const String *
storageDriverRemoteFileReadName(const StorageDriverRemoteFileRead *this)
driver->interface = (StorageFileReadInterface)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this);
FUNCTION_TEST_END();
.type = STORAGE_DRIVER_REMOTE_TYPE_STR,
.name = strDup(name),
.ignoreMissing = ignoreMissing,
ASSERT(this != NULL);
.ioInterface = (IoReadInterface)
{
.eof = storageFileReadDriverRemoteEof,
.open = storageFileReadDriverRemoteOpen,
.read = storageFileReadDriverRemote,
},
};
FUNCTION_TEST_RETURN(this->name);
driver->storage = storage;
driver->client = client;
this = storageFileReadNew(driver, &driver->interface);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, this);
}

View File

@ -4,49 +4,14 @@ Remote Storage File Read Driver
#ifndef STORAGE_DRIVER_REMOTE_FILEREAD_H
#define STORAGE_DRIVER_REMOTE_FILEREAD_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct StorageDriverRemoteFileRead StorageDriverRemoteFileRead;
#include "common/type/buffer.h"
#include "common/type/string.h"
#include "protocol/client.h"
#include "storage/driver/remote/storage.h"
#include "storage/driver/remote/storage.intern.h"
#include "storage/fileRead.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
StorageDriverRemoteFileRead *storageDriverRemoteFileReadNew(
StorageFileRead *storageFileReadDriverRemoteNew(
StorageDriverRemote *storage, ProtocolClient *client, const String *name, bool ignoreMissing);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
bool storageDriverRemoteFileReadOpen(StorageDriverRemoteFileRead *this);
size_t storageDriverRemoteFileRead(StorageDriverRemoteFileRead *this, Buffer *buffer, bool block);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
bool storageDriverRemoteFileReadEof(const StorageDriverRemoteFileRead *this);
bool storageDriverRemoteFileReadIgnoreMissing(const StorageDriverRemoteFileRead *this);
StorageFileRead *storageDriverRemoteFileReadInterface(const StorageDriverRemoteFileRead *this);
IoRead *storageDriverRemoteFileReadIo(const StorageDriverRemoteFileRead *this);
const String *storageDriverRemoteFileReadName(const StorageDriverRemoteFileRead *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void storageDriverRemoteFileReadFree(StorageDriverRemoteFileRead *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_REMOTE_FILE_READ_TYPE \
StorageDriverRemoteFileRead *
#define FUNCTION_LOG_STORAGE_DRIVER_REMOTE_FILE_READ_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageDriverRemoteFileRead", buffer, bufferSize)
#endif

View File

@ -7,6 +7,7 @@ Remote Storage File Write Driver
#include "common/io/write.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
#include "storage/driver/remote/fileWrite.h"
#include "storage/driver/remote/protocol.h"
#include "storage/fileWrite.intern.h"
@ -14,157 +15,32 @@ Remote Storage File Write Driver
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct StorageDriverRemoteFileWrite
typedef struct StorageFileWriteDriverRemote
{
MemContext *memContext;
StorageDriverRemote *storage;
ProtocolClient *client;
StorageFileWrite *interface;
IoWrite *io;
String *name;
mode_t modeFile;
mode_t modePath;
const String *user;
const String *group;
time_t timeModified;
bool createPath;
bool syncFile;
bool syncPath;
bool atomic;
};
MemContext *memContext; // Object mem context
StorageFileWriteInterface interface; // Driver interface
StorageDriverRemote *storage; // Storage that created this object
ProtocolClient *client; // Protocol client to make requests with
} StorageFileWriteDriverRemote;
/***********************************************************************************************************************************
Create a new file
Macros for function logging
***********************************************************************************************************************************/
StorageDriverRemoteFileWrite *
storageDriverRemoteFileWriteNew(
StorageDriverRemote *storage, ProtocolClient *client, const String *name, mode_t modeFile, mode_t modePath, const String *user,
const String *group, time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, storage);
FUNCTION_LOG_PARAM(STRING, name);
FUNCTION_LOG_PARAM(MODE, modeFile);
FUNCTION_LOG_PARAM(MODE, modePath);
FUNCTION_LOG_PARAM(STRING, user);
FUNCTION_LOG_PARAM(STRING, group);
FUNCTION_LOG_PARAM(INT64, timeModified);
FUNCTION_LOG_PARAM(BOOL, createPath);
FUNCTION_LOG_PARAM(BOOL, syncFile);
FUNCTION_LOG_PARAM(BOOL, syncPath);
FUNCTION_LOG_PARAM(BOOL, atomic);
FUNCTION_LOG_END();
ASSERT(storage != NULL);
ASSERT(name != NULL);
ASSERT(modeFile != 0);
ASSERT(modePath != 0);
StorageDriverRemoteFileWrite *this = NULL;
// Create the file
MEM_CONTEXT_NEW_BEGIN("StorageDriverRemoteFileWrite")
{
this = memNew(sizeof(StorageDriverRemoteFileWrite));
this->memContext = MEM_CONTEXT_NEW();
this->storage = storage;
this->client = client;
this->interface = storageFileWriteNewP(
STORAGE_DRIVER_REMOTE_TYPE_STR, this, .atomic = (StorageFileWriteInterfaceAtomic)storageDriverRemoteFileWriteAtomic,
.createPath = (StorageFileWriteInterfaceCreatePath)storageDriverRemoteFileWriteCreatePath,
.io = (StorageFileWriteInterfaceIo)storageDriverRemoteFileWriteIo,
.modeFile = (StorageFileWriteInterfaceModeFile)storageDriverRemoteFileWriteModeFile,
.modePath = (StorageFileWriteInterfaceModePath)storageDriverRemoteFileWriteModePath,
.name = (StorageFileWriteInterfaceName)storageDriverRemoteFileWriteName,
.syncFile = (StorageFileWriteInterfaceSyncFile)storageDriverRemoteFileWriteSyncFile,
.syncPath = (StorageFileWriteInterfaceSyncPath)storageDriverRemoteFileWriteSyncPath);
this->io = ioWriteNewP(
this, .close = (IoWriteInterfaceClose)storageDriverRemoteFileWriteClose,
.open = (IoWriteInterfaceOpen)storageDriverRemoteFileWriteOpen,
.write = (IoWriteInterfaceWrite)storageDriverRemoteFileWrite);
this->name = strDup(name);
this->modeFile = modeFile;
this->modePath = modePath;
this->user = strDup(user);
this->group = strDup(group);
this->timeModified = timeModified;
this->createPath = createPath;
this->syncFile = syncFile;
this->syncPath = syncPath;
this->atomic = atomic;
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
}
/***********************************************************************************************************************************
Open the file
***********************************************************************************************************************************/
void
storageDriverRemoteFileWriteOpen(StorageDriverRemoteFileWrite *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
MEM_CONTEXT_TEMP_BEGIN()
{
ProtocolCommand *command = protocolCommandNew(PROTOCOL_COMMAND_STORAGE_OPEN_WRITE_STR);
protocolCommandParamAdd(command, VARSTR(this->name));
protocolCommandParamAdd(command, VARUINT(this->modeFile));
protocolCommandParamAdd(command, VARUINT(this->modePath));
protocolCommandParamAdd(command, VARSTR(this->user));
protocolCommandParamAdd(command, VARSTR(this->group));
protocolCommandParamAdd(command, VARINT64(this->timeModified));
protocolCommandParamAdd(command, VARBOOL(this->createPath));
protocolCommandParamAdd(command, VARBOOL(this->syncFile));
protocolCommandParamAdd(command, VARBOOL(this->syncPath));
protocolCommandParamAdd(command, VARBOOL(this->atomic));
protocolClientExecute(this->client, command, false);
}
MEM_CONTEXT_TEMP_END();
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Write to the file
***********************************************************************************************************************************/
void
storageDriverRemoteFileWrite(StorageDriverRemoteFileWrite *this, const Buffer *buffer)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(buffer != NULL);
ioWriteStrLine(protocolClientIoWrite(this->client), strNewFmt(PROTOCOL_BLOCK_HEADER "%zu", bufUsed(buffer)));
ioWrite(protocolClientIoWrite(this->client), buffer);
ioWriteFlush(protocolClientIoWrite(this->client));
FUNCTION_LOG_RETURN_VOID();
}
#define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_REMOTE_TYPE \
StorageFileWriteDriverRemote *
#define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_REMOTE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageFileWriteDriverRemote", buffer, bufferSize)
/***********************************************************************************************************************************
Close the file
***********************************************************************************************************************************/
void
storageDriverRemoteFileWriteClose(StorageDriverRemoteFileWrite *this)
static void
storageFileWriteDriverRemoteClose(THIS_VOID)
{
THIS(StorageFileWriteDriverRemote);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_REMOTE, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
@ -182,149 +58,14 @@ storageDriverRemoteFileWriteClose(StorageDriverRemoteFileWrite *this)
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Will the file be written atomically?
***********************************************************************************************************************************/
bool
storageDriverRemoteFileWriteAtomic(const StorageDriverRemoteFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->atomic);
}
/***********************************************************************************************************************************
Will the path be created for the file if it does not exist?
***********************************************************************************************************************************/
bool
storageDriverRemoteFileWriteCreatePath(const StorageDriverRemoteFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->createPath);
}
/***********************************************************************************************************************************
Get interface
***********************************************************************************************************************************/
StorageFileWrite *
storageDriverRemoteFileWriteInterface(const StorageDriverRemoteFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface);
}
/***********************************************************************************************************************************
Get I/O interface
***********************************************************************************************************************************/
IoWrite *
storageDriverRemoteFileWriteIo(const StorageDriverRemoteFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->io);
}
/***********************************************************************************************************************************
Mode for the file to be created
***********************************************************************************************************************************/
mode_t
storageDriverRemoteFileWriteModeFile(const StorageDriverRemoteFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->modeFile);
}
/***********************************************************************************************************************************
Mode for any paths that are created while writing the file
***********************************************************************************************************************************/
mode_t
storageDriverRemoteFileWriteModePath(const StorageDriverRemoteFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->modePath);
}
/***********************************************************************************************************************************
File name
***********************************************************************************************************************************/
const String *
storageDriverRemoteFileWriteName(const StorageDriverRemoteFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->name);
}
/***********************************************************************************************************************************
Will the file be synced after it is closed?
***********************************************************************************************************************************/
bool
storageDriverRemoteFileWriteSyncFile(const StorageDriverRemoteFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->syncFile);
}
/***********************************************************************************************************************************
Will the directory be synced to disk after the write is completed?
***********************************************************************************************************************************/
bool
storageDriverRemoteFileWriteSyncPath(const StorageDriverRemoteFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->syncPath);
}
/***********************************************************************************************************************************
Free the file
***********************************************************************************************************************************/
void
storageDriverRemoteFileWriteFree(StorageDriverRemoteFileWrite *this)
static void
storageFileWriteDriverRemoteFree(StorageFileWriteDriverRemote *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_REMOTE, this);
FUNCTION_LOG_END();
if (this != NULL)
@ -346,3 +87,131 @@ storageDriverRemoteFileWriteFree(StorageDriverRemoteFileWrite *this)
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Open the file
***********************************************************************************************************************************/
static void
storageFileWriteDriverRemoteOpen(THIS_VOID)
{
THIS(StorageFileWriteDriverRemote);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_REMOTE, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
MEM_CONTEXT_TEMP_BEGIN()
{
ProtocolCommand *command = protocolCommandNew(PROTOCOL_COMMAND_STORAGE_OPEN_WRITE_STR);
protocolCommandParamAdd(command, VARSTR(this->interface.name));
protocolCommandParamAdd(command, VARUINT(this->interface.modeFile));
protocolCommandParamAdd(command, VARUINT(this->interface.modePath));
protocolCommandParamAdd(command, VARSTR(this->interface.user));
protocolCommandParamAdd(command, VARSTR(this->interface.group));
protocolCommandParamAdd(command, VARINT64(this->interface.timeModified));
protocolCommandParamAdd(command, VARBOOL(this->interface.createPath));
protocolCommandParamAdd(command, VARBOOL(this->interface.syncFile));
protocolCommandParamAdd(command, VARBOOL(this->interface.syncPath));
protocolCommandParamAdd(command, VARBOOL(this->interface.atomic));
protocolClientExecute(this->client, command, false);
// Set free callback to ensure remote file is freed
memContextCallback(this->memContext, (MemContextCallback)storageFileWriteDriverRemoteFree, this);
}
MEM_CONTEXT_TEMP_END();
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Write to the file
***********************************************************************************************************************************/
static void
storageFileWriteDriverRemote(THIS_VOID, const Buffer *buffer)
{
THIS(StorageFileWriteDriverRemote);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(buffer != NULL);
ioWriteStrLine(protocolClientIoWrite(this->client), strNewFmt(PROTOCOL_BLOCK_HEADER "%zu", bufUsed(buffer)));
ioWrite(protocolClientIoWrite(this->client), buffer);
ioWriteFlush(protocolClientIoWrite(this->client));
FUNCTION_LOG_RETURN_VOID();
}
/***********************************************************************************************************************************
Create a new file
***********************************************************************************************************************************/
StorageFileWrite *
storageFileWriteDriverRemoteNew(
StorageDriverRemote *storage, ProtocolClient *client, const String *name, mode_t modeFile, mode_t modePath, const String *user,
const String *group, time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, storage);
FUNCTION_LOG_PARAM(STRING, name);
FUNCTION_LOG_PARAM(MODE, modeFile);
FUNCTION_LOG_PARAM(MODE, modePath);
FUNCTION_LOG_PARAM(STRING, user);
FUNCTION_LOG_PARAM(STRING, group);
FUNCTION_LOG_PARAM(INT64, timeModified);
FUNCTION_LOG_PARAM(BOOL, createPath);
FUNCTION_LOG_PARAM(BOOL, syncFile);
FUNCTION_LOG_PARAM(BOOL, syncPath);
FUNCTION_LOG_PARAM(BOOL, atomic);
FUNCTION_LOG_END();
ASSERT(storage != NULL);
ASSERT(client != NULL);
ASSERT(name != NULL);
ASSERT(modeFile != 0);
ASSERT(modePath != 0);
StorageFileWrite *this = NULL;
MEM_CONTEXT_NEW_BEGIN("StorageFileWriteDriverRemote")
{
StorageFileWriteDriverRemote *driver = memNew(sizeof(StorageFileWriteDriverRemote));
driver->memContext = MEM_CONTEXT_NEW();
driver->interface = (StorageFileWriteInterface)
{
.type = STORAGE_DRIVER_REMOTE_TYPE_STR,
.name = strDup(name),
.atomic = atomic,
.createPath = createPath,
.group = strDup(group),
.modeFile = modeFile,
.modePath = modePath,
.syncFile = syncFile,
.syncPath = syncPath,
.user = strDup(user),
.timeModified = timeModified,
.ioInterface = (IoWriteInterface)
{
.close = storageFileWriteDriverRemoteClose,
.open = storageFileWriteDriverRemoteOpen,
.write = storageFileWriteDriverRemote,
},
};
driver->storage = storage;
driver->client = client;
this = storageFileWriteNew(driver, &driver->interface);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_FILE_WRITE, this);
}

View File

@ -4,57 +4,15 @@ Remote Storage File Write Driver
#ifndef STORAGE_DRIVER_REMOTE_FILEWRITE_H
#define STORAGE_DRIVER_REMOTE_FILEWRITE_H
#include <sys/types.h>
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct StorageDriverRemoteFileWrite StorageDriverRemoteFileWrite;
#include "common/type/buffer.h"
#include "protocol/client.h"
#include "storage/driver/remote/storage.h"
#include "storage/driver/remote/storage.intern.h"
#include "storage/fileWrite.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
StorageDriverRemoteFileWrite *storageDriverRemoteFileWriteNew(
StorageFileWrite *storageFileWriteDriverRemoteNew(
StorageDriverRemote *storage, ProtocolClient *client, const String *name, mode_t modeFile, mode_t modePath, const String *user,
const String *group, time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void storageDriverRemoteFileWriteOpen(StorageDriverRemoteFileWrite *this);
void storageDriverRemoteFileWrite(StorageDriverRemoteFileWrite *this, const Buffer *buffer);
void storageDriverRemoteFileWriteClose(StorageDriverRemoteFileWrite *this);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
bool storageDriverRemoteFileWriteAtomic(const StorageDriverRemoteFileWrite *this);
bool storageDriverRemoteFileWriteCreatePath(const StorageDriverRemoteFileWrite *this);
mode_t storageDriverRemoteFileWriteModeFile(const StorageDriverRemoteFileWrite *this);
StorageFileWrite* storageDriverRemoteFileWriteInterface(const StorageDriverRemoteFileWrite *this);
IoWrite *storageDriverRemoteFileWriteIo(const StorageDriverRemoteFileWrite *this);
mode_t storageDriverRemoteFileWriteModePath(const StorageDriverRemoteFileWrite *this);
const String *storageDriverRemoteFileWriteName(const StorageDriverRemoteFileWrite *this);
const StorageDriverRemote *storageDriverRemoteFileWriteStorage(const StorageDriverRemoteFileWrite *this);
bool storageDriverRemoteFileWriteSyncFile(const StorageDriverRemoteFileWrite *this);
bool storageDriverRemoteFileWriteSyncPath(const StorageDriverRemoteFileWrite *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void storageDriverRemoteFileWriteFree(StorageDriverRemoteFileWrite *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_REMOTE_FILE_WRITE_TYPE \
StorageDriverRemoteFileWrite *
#define FUNCTION_LOG_STORAGE_DRIVER_REMOTE_FILE_WRITE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageDriverRemoteFileWrite", buffer, bufferSize)
#endif

View File

@ -6,12 +6,11 @@ Remote Storage Driver
#include "common/debug.h"
#include "common/log.h"
#include "common/memContext.h"
#include "protocol/client.h"
#include "protocol/helper.h"
#include "common/object.h"
#include "storage/driver/remote/fileRead.h"
#include "storage/driver/remote/fileWrite.h"
#include "storage/driver/remote/protocol.h"
#include "storage/driver/remote/storage.h"
#include "storage/driver/remote/storage.intern.h"
/***********************************************************************************************************************************
Driver type constant string
@ -24,61 +23,17 @@ Object type
struct StorageDriverRemote
{
MemContext *memContext;
Storage *interface; // Driver interface
ProtocolClient *client; // Protocol client
};
/***********************************************************************************************************************************
New object
***********************************************************************************************************************************/
StorageDriverRemote *
storageDriverRemoteNew(
mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction, ProtocolClient *client)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(MODE, modeFile);
FUNCTION_LOG_PARAM(MODE, modePath);
FUNCTION_LOG_PARAM(BOOL, write);
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
FUNCTION_LOG_PARAM(PROTOCOL_CLIENT, client);
FUNCTION_LOG_END();
ASSERT(modeFile != 0);
ASSERT(modePath != 0);
ASSERT(client != NULL);
// Create the object
StorageDriverRemote *this = NULL;
MEM_CONTEXT_NEW_BEGIN("StorageDriverRemote")
{
this = memNew(sizeof(StorageDriverRemote));
this->memContext = MEM_CONTEXT_NEW();
this->client = client;
// Create the storage interface
this->interface = storageNewP(
STORAGE_DRIVER_REMOTE_TYPE_STR, NULL, modeFile, modePath, write, pathExpressionFunction, this,
.exists = (StorageInterfaceExists)storageDriverRemoteExists, .info = (StorageInterfaceInfo)storageDriverRemoteInfo,
.list = (StorageInterfaceList)storageDriverRemoteList, .newRead = (StorageInterfaceNewRead)storageDriverRemoteNewRead,
.newWrite = (StorageInterfaceNewWrite)storageDriverRemoteNewWrite,
.pathCreate = (StorageInterfacePathCreate)storageDriverRemotePathCreate,
.pathRemove = (StorageInterfacePathRemove)storageDriverRemotePathRemove,
.pathSync = (StorageInterfacePathSync)storageDriverRemotePathSync,
.remove = (StorageInterfaceRemove)storageDriverRemoteRemove);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_DRIVER_REMOTE, this);
}
/***********************************************************************************************************************************
Does a file exist? This function is only for files, not paths.
***********************************************************************************************************************************/
bool
storageDriverRemoteExists(StorageDriverRemote *this, const String *path)
static bool
storageDriverRemoteExists(THIS_VOID, const String *path)
{
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -104,9 +59,11 @@ storageDriverRemoteExists(StorageDriverRemote *this, const String *path)
/***********************************************************************************************************************************
File/path info
***********************************************************************************************************************************/
StorageInfo
storageDriverRemoteInfo(StorageDriverRemote *this, const String *file, bool ignoreMissing, bool followLink)
static StorageInfo
storageDriverRemoteInfo(THIS_VOID, const String *file, bool ignoreMissing, bool followLink)
{
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, file);
@ -125,9 +82,11 @@ storageDriverRemoteInfo(StorageDriverRemote *this, const String *file, bool igno
/***********************************************************************************************************************************
Get a list of files from a directory
***********************************************************************************************************************************/
StringList *
storageDriverRemoteList(StorageDriverRemote *this, const String *path, bool errorOnMissing, const String *expression)
static StringList *
storageDriverRemoteList(THIS_VOID, const String *path, bool errorOnMissing, const String *expression)
{
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -157,9 +116,11 @@ storageDriverRemoteList(StorageDriverRemote *this, const String *path, bool erro
/***********************************************************************************************************************************
New file read object
***********************************************************************************************************************************/
StorageFileRead *
storageDriverRemoteNewRead(StorageDriverRemote *this, const String *file, bool ignoreMissing)
static StorageFileRead *
storageDriverRemoteNewRead(THIS_VOID, const String *file, bool ignoreMissing)
{
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, file);
@ -168,19 +129,19 @@ storageDriverRemoteNewRead(StorageDriverRemote *this, const String *file, bool i
ASSERT(this != NULL);
FUNCTION_LOG_RETURN(
STORAGE_FILE_READ,
storageDriverRemoteFileReadInterface(storageDriverRemoteFileReadNew(this, this->client, file, ignoreMissing)));
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, storageFileReadDriverRemoteNew(this, this->client, file, ignoreMissing));
}
/***********************************************************************************************************************************
New file write object
***********************************************************************************************************************************/
StorageFileWrite *
static StorageFileWrite *
storageDriverRemoteNewWrite(
StorageDriverRemote *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
THIS_VOID, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
{
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, file);
@ -200,17 +161,18 @@ storageDriverRemoteNewWrite(
FUNCTION_LOG_RETURN(
STORAGE_FILE_WRITE,
storageDriverRemoteFileWriteInterface(
storageDriverRemoteFileWriteNew(
this, this->client, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, syncPath, atomic)));
storageFileWriteDriverRemoteNew(
this, this->client, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, syncPath, atomic));
}
/***********************************************************************************************************************************
Create a path. There are no physical paths on S3 so just return success.
***********************************************************************************************************************************/
void
storageDriverRemotePathCreate(StorageDriverRemote *this, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
static void
storageDriverRemotePathCreate(THIS_VOID, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
{
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -230,9 +192,11 @@ storageDriverRemotePathCreate(StorageDriverRemote *this, const String *path, boo
/***********************************************************************************************************************************
Remove a path
***********************************************************************************************************************************/
void
storageDriverRemotePathRemove(StorageDriverRemote *this, const String *path, bool errorOnMissing, bool recurse)
static void
storageDriverRemotePathRemove(THIS_VOID, const String *path, bool errorOnMissing, bool recurse)
{
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -251,9 +215,11 @@ storageDriverRemotePathRemove(StorageDriverRemote *this, const String *path, boo
/***********************************************************************************************************************************
Sync a path. There's no need for this on S3 so just return success.
***********************************************************************************************************************************/
void
storageDriverRemotePathSync(StorageDriverRemote *this, const String *path, bool ignoreMissing)
static void
storageDriverRemotePathSync(THIS_VOID, const String *path, bool ignoreMissing)
{
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -271,9 +237,11 @@ storageDriverRemotePathSync(StorageDriverRemote *this, const String *path, bool
/***********************************************************************************************************************************
Remove a file
***********************************************************************************************************************************/
void
storageDriverRemoteRemove(StorageDriverRemote *this, const String *file, bool errorOnMissing)
static void
storageDriverRemoteRemove(THIS_VOID, const String *file, bool errorOnMissing)
{
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, file);
@ -289,16 +257,40 @@ storageDriverRemoteRemove(StorageDriverRemote *this, const String *file, bool er
}
/***********************************************************************************************************************************
Get storage interface
New object
***********************************************************************************************************************************/
Storage *
storageDriverRemoteInterface(const StorageDriverRemote *this)
storageDriverRemoteNew(
mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction, ProtocolClient *client)
{
FUNCTION_TEST_BEGIN();
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_TEST_END();
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(MODE, modeFile);
FUNCTION_LOG_PARAM(MODE, modePath);
FUNCTION_LOG_PARAM(BOOL, write);
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
FUNCTION_LOG_PARAM(PROTOCOL_CLIENT, client);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(modeFile != 0);
ASSERT(modePath != 0);
ASSERT(client != NULL);
FUNCTION_TEST_RETURN(this->interface);
Storage *this = NULL;
MEM_CONTEXT_NEW_BEGIN("StorageDriverRemote")
{
StorageDriverRemote *driver = memNew(sizeof(StorageDriverRemote));
driver->memContext = MEM_CONTEXT_NEW();
driver->client = client;
this = storageNewP(
STORAGE_DRIVER_REMOTE_TYPE_STR, NULL, modeFile, modePath, write, pathExpressionFunction, driver,
.exists = storageDriverRemoteExists, .info = storageDriverRemoteInfo, .list = storageDriverRemoteList,
.newRead = storageDriverRemoteNewRead, .newWrite = storageDriverRemoteNewWrite,
.pathCreate = storageDriverRemotePathCreate, .pathRemove = storageDriverRemotePathRemove,
.pathSync = storageDriverRemotePathSync, .remove = storageDriverRemoteRemove);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE, this);
}

View File

@ -4,13 +4,7 @@ Remote Storage Driver
#ifndef STORAGE_DRIVER_REMOTE_STORAGE_H
#define STORAGE_DRIVER_REMOTE_STORAGE_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct StorageDriverRemote StorageDriverRemote;
#include "common/io/http/client.h"
#include "common/type/string.h"
#include "protocol/client.h"
#include "storage/storage.intern.h"
/***********************************************************************************************************************************
@ -22,41 +16,7 @@ Driver type constant
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
StorageDriverRemote *storageDriverRemoteNew(
Storage *storageDriverRemoteNew(
mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction, ProtocolClient *client);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
bool storageDriverRemoteExists(StorageDriverRemote *this, const String *path);
StorageInfo storageDriverRemoteInfo(StorageDriverRemote *this, const String *file, bool ignoreMissing, bool followLink);
StringList *storageDriverRemoteList(StorageDriverRemote *this, const String *path, bool errorOnMissing, const String *expression);
StorageFileRead *storageDriverRemoteNewRead(StorageDriverRemote *this, const String *file, bool ignoreMissing);
StorageFileWrite *storageDriverRemoteNewWrite(
StorageDriverRemote *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
void storageDriverRemotePathCreate(
StorageDriverRemote *this, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode);
void storageDriverRemotePathRemove(StorageDriverRemote *this, const String *path, bool errorOnMissing, bool recurse);
void storageDriverRemotePathSync(StorageDriverRemote *this, const String *path, bool ignoreMissing);
void storageDriverRemoteRemove(StorageDriverRemote *this, const String *file, bool errorOnMissing);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
Storage *storageDriverRemoteInterface(const StorageDriverRemote *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void storageDriverRemoteFree(StorageDriverRemote *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_REMOTE_TYPE \
StorageDriverRemote *
#define FUNCTION_LOG_STORAGE_DRIVER_REMOTE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageDriverRemote", buffer, bufferSize)
#endif

View File

@ -0,0 +1,22 @@
/***********************************************************************************************************************************
Remote Storage Driver Internal
***********************************************************************************************************************************/
#ifndef STORAGE_DRIVER_REMOTE_STORAGE_INTERN_H
#define STORAGE_DRIVER_REMOTE_STORAGE_INTERN_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct StorageDriverRemote StorageDriverRemote;
#include "storage/driver/remote/storage.h"
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_REMOTE_TYPE \
StorageDriverRemote *
#define FUNCTION_LOG_STORAGE_DRIVER_REMOTE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageDriverRemote", buffer, bufferSize)
#endif

View File

@ -11,73 +11,40 @@ S3 Storage File Read Driver
#include "common/io/read.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
#include "storage/driver/s3/fileRead.h"
#include "storage/fileRead.intern.h"
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct StorageDriverS3FileRead
typedef struct StorageFileReadDriverS3
{
MemContext *memContext;
StorageDriverS3 *storage;
StorageFileRead *interface;
IoRead *io;
String *name;
bool ignoreMissing;
MemContext *memContext; // Object mem context
StorageFileReadInterface interface; // Driver interface
StorageDriverS3 *storage; // Storage that created this object
HttpClient *httpClient; // Http client for requests
};
} StorageFileReadDriverS3;
/***********************************************************************************************************************************
Create a new file
Macros for function logging
***********************************************************************************************************************************/
StorageDriverS3FileRead *
storageDriverS3FileReadNew(StorageDriverS3 *storage, const String *name, bool ignoreMissing)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, storage);
FUNCTION_LOG_PARAM(STRING, name);
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
FUNCTION_LOG_END();
ASSERT(storage != NULL);
ASSERT(name != NULL);
StorageDriverS3FileRead *this = NULL;
// Create the file object
MEM_CONTEXT_NEW_BEGIN("StorageDriverS3FileRead")
{
this = memNew(sizeof(StorageDriverS3FileRead));
this->memContext = MEM_CONTEXT_NEW();
this->storage = storage;
this->name = strDup(name);
this->ignoreMissing = ignoreMissing;
this->interface = storageFileReadNewP(
strNew(STORAGE_DRIVER_S3_TYPE), this,
.ignoreMissing = (StorageFileReadInterfaceIgnoreMissing)storageDriverS3FileReadIgnoreMissing,
.io = (StorageFileReadInterfaceIo)storageDriverS3FileReadIo,
.name = (StorageFileReadInterfaceName)storageDriverS3FileReadName);
this->io = ioReadNewP(
this, .eof = (IoReadInterfaceEof)storageDriverS3FileReadEof,
.open = (IoReadInterfaceOpen)storageDriverS3FileReadOpen, .read = (IoReadInterfaceRead)storageDriverS3FileRead);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_DRIVER_S3_FILE_READ, this);
}
#define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_S3_TYPE \
StorageFileReadDriverS3 *
#define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_S3_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageFileReadDriverS3", buffer, bufferSize)
/***********************************************************************************************************************************
Open the file
***********************************************************************************************************************************/
bool
storageDriverS3FileReadOpen(StorageDriverS3FileRead *this)
static bool
storageFileReadDriverS3Open(THIS_VOID)
{
THIS(StorageFileReadDriverS3);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_S3, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
@ -86,7 +53,7 @@ storageDriverS3FileReadOpen(StorageDriverS3FileRead *this)
bool result = false;
// Request the file
storageDriverS3Request(this->storage, HTTP_VERB_GET_STR, this->name, NULL, NULL, false, true);
storageDriverS3Request(this->storage, HTTP_VERB_GET_STR, this->interface.name, NULL, NULL, false, true);
// On success
this->httpClient = storageDriverS3HttpClient(this->storage);
@ -95,8 +62,8 @@ storageDriverS3FileReadOpen(StorageDriverS3FileRead *this)
result = true;
// Else error unless ignore missing
else if (!this->ignoreMissing)
THROW_FMT(FileMissingError, "unable to open '%s': No such file or directory", strPtr(this->name));
else if (!this->interface.ignoreMissing)
THROW_FMT(FileMissingError, "unable to open '%s': No such file or directory", strPtr(this->interface.name));
FUNCTION_LOG_RETURN(BOOL, result);
}
@ -104,11 +71,13 @@ storageDriverS3FileReadOpen(StorageDriverS3FileRead *this)
/***********************************************************************************************************************************
Read from a file
***********************************************************************************************************************************/
size_t
storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer, bool block)
static size_t
storageFileReadDriverS3(THIS_VOID, Buffer *buffer, bool block)
{
THIS(StorageFileReadDriverS3);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_S3, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_PARAM(BOOL, block);
FUNCTION_LOG_END();
@ -122,11 +91,13 @@ storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer, bool bloc
/***********************************************************************************************************************************
Has file reached EOF?
***********************************************************************************************************************************/
bool
storageDriverS3FileReadEof(const StorageDriverS3FileRead *this)
static bool
storageFileReadDriverS3Eof(THIS_VOID)
{
THIS(StorageFileReadDriverS3);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
FUNCTION_TEST_PARAM(STORAGE_FILE_READ_DRIVER_S3, this);
FUNCTION_TEST_END();
ASSERT(this != NULL && this->httpClient != NULL);
@ -135,61 +106,46 @@ storageDriverS3FileReadEof(const StorageDriverS3FileRead *this)
}
/***********************************************************************************************************************************
Should a missing file be ignored?
***********************************************************************************************************************************/
bool
storageDriverS3FileReadIgnoreMissing(const StorageDriverS3FileRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->ignoreMissing);
}
/***********************************************************************************************************************************
Get the interface
Create a new file
***********************************************************************************************************************************/
StorageFileRead *
storageDriverS3FileReadInterface(const StorageDriverS3FileRead *this)
storageFileReadDriverS3New(StorageDriverS3 *storage, const String *name, bool ignoreMissing)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
FUNCTION_TEST_END();
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, storage);
FUNCTION_LOG_PARAM(STRING, name);
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(storage != NULL);
ASSERT(name != NULL);
FUNCTION_TEST_RETURN(this->interface);
}
StorageFileRead *this = NULL;
/***********************************************************************************************************************************
Get the I/O interface
***********************************************************************************************************************************/
IoRead *
storageDriverS3FileReadIo(const StorageDriverS3FileRead *this)
MEM_CONTEXT_NEW_BEGIN("StorageFileReadDriverS3")
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
FUNCTION_TEST_END();
StorageFileReadDriverS3 *driver = memNew(sizeof(StorageFileReadDriverS3));
driver->memContext = MEM_CONTEXT_NEW();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->io);
}
/***********************************************************************************************************************************
File name
***********************************************************************************************************************************/
const String *
storageDriverS3FileReadName(const StorageDriverS3FileRead *this)
driver->interface = (StorageFileReadInterface)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
FUNCTION_TEST_END();
.type = STORAGE_DRIVER_S3_TYPE_STR,
.name = strDup(name),
.ignoreMissing = ignoreMissing,
ASSERT(this != NULL);
.ioInterface = (IoReadInterface)
{
.eof = storageFileReadDriverS3Eof,
.open = storageFileReadDriverS3Open,
.read = storageFileReadDriverS3,
},
};
FUNCTION_TEST_RETURN(this->name);
driver->storage = storage;
this = storageFileReadNew(driver, &driver->interface);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, this);
}

View File

@ -4,47 +4,12 @@ S3 Storage File Read Driver
#ifndef STORAGE_DRIVER_S3_FILEREAD_H
#define STORAGE_DRIVER_S3_FILEREAD_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct StorageDriverS3FileRead StorageDriverS3FileRead;
#include "common/type/buffer.h"
#include "common/type/string.h"
#include "storage/driver/s3/storage.h"
#include "storage/driver/s3/storage.intern.h"
#include "storage/fileRead.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
StorageDriverS3FileRead *storageDriverS3FileReadNew(StorageDriverS3 *storage, const String *name, bool ignoreMissing);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
bool storageDriverS3FileReadOpen(StorageDriverS3FileRead *this);
size_t storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer, bool block);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
bool storageDriverS3FileReadEof(const StorageDriverS3FileRead *this);
bool storageDriverS3FileReadIgnoreMissing(const StorageDriverS3FileRead *this);
StorageFileRead *storageDriverS3FileReadInterface(const StorageDriverS3FileRead *this);
IoRead *storageDriverS3FileReadIo(const StorageDriverS3FileRead *this);
const String *storageDriverS3FileReadName(const StorageDriverS3FileRead *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void storageDriverS3FileReadFree(StorageDriverS3FileRead *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_S3_FILE_READ_TYPE \
StorageDriverS3FileRead *
#define FUNCTION_LOG_STORAGE_DRIVER_S3_FILE_READ_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageDriverS3FileRead", buffer, bufferSize)
StorageFileRead *storageFileReadDriverS3New(StorageDriverS3 *storage, const String *name, bool ignoreMissing);
#endif

View File

@ -7,6 +7,7 @@ S3 Storage File Write Driver
#include "common/io/write.intern.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
#include "common/type/xml.h"
#include "storage/driver/s3/fileWrite.h"
#include "storage/fileWrite.intern.h"
@ -30,76 +31,36 @@ STRING_STATIC(S3_XML_TAG_PART_NUMBER_STR, "PartNumber"
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct StorageDriverS3FileWrite
typedef struct StorageFileWriteDriverS3
{
MemContext *memContext;
StorageDriverS3 *storage;
StorageFileWrite *interface;
IoWrite *io;
MemContext *memContext; // Object mem context
StorageFileWriteInterface interface; // Driver interface
StorageDriverS3 *storage; // Storage that created this object
const String *path;
const String *name;
size_t partSize;
Buffer *partBuffer;
const String *uploadId;
StringList *uploadPartList;
};
} StorageFileWriteDriverS3;
/***********************************************************************************************************************************
Create a new file
Macros for function logging
***********************************************************************************************************************************/
StorageDriverS3FileWrite *
storageDriverS3FileWriteNew(StorageDriverS3 *storage, const String *name, size_t partSize)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, storage);
FUNCTION_LOG_PARAM(STRING, name);
FUNCTION_LOG_END();
ASSERT(storage != NULL);
ASSERT(name != NULL);
StorageDriverS3FileWrite *this = NULL;
// Create the file
MEM_CONTEXT_NEW_BEGIN("StorageDriverS3FileWrite")
{
this = memNew(sizeof(StorageDriverS3FileWrite));
this->memContext = MEM_CONTEXT_NEW();
this->storage = storage;
this->interface = storageFileWriteNewP(
STORAGE_DRIVER_S3_TYPE_STR, this, .atomic = (StorageFileWriteInterfaceAtomic)storageDriverS3FileWriteAtomic,
.createPath = (StorageFileWriteInterfaceCreatePath)storageDriverS3FileWriteCreatePath,
.io = (StorageFileWriteInterfaceIo)storageDriverS3FileWriteIo,
.modeFile = (StorageFileWriteInterfaceModeFile)storageDriverS3FileWriteModeFile,
.modePath = (StorageFileWriteInterfaceModePath)storageDriverS3FileWriteModePath,
.name = (StorageFileWriteInterfaceName)storageDriverS3FileWriteName,
.syncFile = (StorageFileWriteInterfaceSyncFile)storageDriverS3FileWriteSyncFile,
.syncPath = (StorageFileWriteInterfaceSyncPath)storageDriverS3FileWriteSyncPath);
this->io = ioWriteNewP(
this, .close = (IoWriteInterfaceClose)storageDriverS3FileWriteClose,
.open = (IoWriteInterfaceOpen)storageDriverS3FileWriteOpen,
.write = (IoWriteInterfaceWrite)storageDriverS3FileWrite);
this->path = strPath(name);
this->name = strDup(name);
this->partSize = partSize;
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_DRIVER_S3_FILE_WRITE, this);
}
#define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_S3_TYPE \
StorageFileWriteDriverS3 *
#define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_S3_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageFileWriteDriverS3", buffer, bufferSize)
/***********************************************************************************************************************************
Open the file
***********************************************************************************************************************************/
void
storageDriverS3FileWriteOpen(StorageDriverS3FileWrite *this)
static void
storageFileWriteDriverS3Open(THIS_VOID)
{
THIS(StorageFileWriteDriverS3);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_S3, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
@ -119,10 +80,10 @@ storageDriverS3FileWriteOpen(StorageDriverS3FileWrite *this)
Flush bytes to upload part
***********************************************************************************************************************************/
static void
storageDriverS3FileWritePart(StorageDriverS3FileWrite *this)
storageFileWriteDriverS3Part(StorageFileWriteDriverS3 *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_S3, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
@ -138,7 +99,7 @@ storageDriverS3FileWritePart(StorageDriverS3FileWrite *this)
XmlNode *xmlRoot = xmlDocumentRoot(
xmlDocumentNewBuf(
storageDriverS3Request(
this->storage, HTTP_VERB_POST_STR, this->name,
this->storage, HTTP_VERB_POST_STR, this->interface.name,
httpQueryAdd(httpQueryNew(), S3_QUERY_UPLOADS_STR, EMPTY_STR), NULL, true, false).response));
// Store the upload id
@ -159,7 +120,7 @@ storageDriverS3FileWritePart(StorageDriverS3FileWrite *this)
this->uploadPartList,
httpHeaderGet(
storageDriverS3Request(
this->storage, HTTP_VERB_PUT_STR, this->name, query, this->partBuffer, true, false).responseHeader,
this->storage, HTTP_VERB_PUT_STR, this->interface.name, query, this->partBuffer, true, false).responseHeader,
HTTP_HEADER_ETAG_STR));
ASSERT(strLstGet(this->uploadPartList, strLstSize(this->uploadPartList) - 1) != NULL);
@ -172,11 +133,13 @@ storageDriverS3FileWritePart(StorageDriverS3FileWrite *this)
/***********************************************************************************************************************************
Write to internal buffer
***********************************************************************************************************************************/
void
storageDriverS3FileWrite(StorageDriverS3FileWrite *this, const Buffer *buffer)
static void
storageFileWriteDriverS3(THIS_VOID, const Buffer *buffer)
{
THIS(StorageFileWriteDriverS3);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END();
@ -197,7 +160,7 @@ storageDriverS3FileWrite(StorageDriverS3FileWrite *this, const Buffer *buffer)
// If the part buffer is full then write it
if (bufRemains(this->partBuffer) == 0)
{
storageDriverS3FileWritePart(this);
storageFileWriteDriverS3Part(this);
bufUsedZero(this->partBuffer);
}
}
@ -209,11 +172,13 @@ storageDriverS3FileWrite(StorageDriverS3FileWrite *this, const Buffer *buffer)
/***********************************************************************************************************************************
Close the file
***********************************************************************************************************************************/
void
storageDriverS3FileWriteClose(StorageDriverS3FileWrite *this)
static void
storageFileWriteDriverS3Close(THIS_VOID)
{
THIS(StorageFileWriteDriverS3);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_S3, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
@ -228,7 +193,7 @@ storageDriverS3FileWriteClose(StorageDriverS3FileWrite *this)
{
// If there is anything left in the part buffer then write it
if (bufUsed(this->partBuffer) > 0)
storageDriverS3FileWritePart(this);
storageFileWriteDriverS3Part(this);
// Generate the xml part list
XmlDocument *partList = xmlDocumentNew(S3_XML_TAG_COMPLETE_MULTIPART_UPLOAD_STR);
@ -242,12 +207,15 @@ storageDriverS3FileWriteClose(StorageDriverS3FileWrite *this)
// Finalize the multi-part upload
storageDriverS3Request(
this->storage, HTTP_VERB_POST_STR, this->name,
this->storage, HTTP_VERB_POST_STR, this->interface.name,
httpQueryAdd(httpQueryNew(), S3_QUERY_UPLOAD_ID_STR, this->uploadId), xmlDocumentBuf(partList), false, false);
}
// Else upload all the data in a single put
else
storageDriverS3Request(this->storage, HTTP_VERB_PUT_STR, this->name, NULL, this->partBuffer, false, false);
{
storageDriverS3Request(
this->storage, HTTP_VERB_PUT_STR, this->interface.name, NULL, this->partBuffer, false, false);
}
bufFree(this->partBuffer);
this->partBuffer = NULL;
@ -259,158 +227,49 @@ storageDriverS3FileWriteClose(StorageDriverS3FileWrite *this)
}
/***********************************************************************************************************************************
S3 operations are always atomic, so return true
***********************************************************************************************************************************/
bool
storageDriverS3FileWriteAtomic(const StorageDriverS3FileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
(void)this;
FUNCTION_TEST_RETURN(true);
}
/***********************************************************************************************************************************
S3 paths are always implicitly created
***********************************************************************************************************************************/
bool
storageDriverS3FileWriteCreatePath(const StorageDriverS3FileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
(void)this;
FUNCTION_TEST_RETURN(true);
}
/***********************************************************************************************************************************
Get interface
New object
***********************************************************************************************************************************/
StorageFileWrite *
storageDriverS3FileWriteInterface(const StorageDriverS3FileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface);
}
/***********************************************************************************************************************************
Get I/O interface
***********************************************************************************************************************************/
IoWrite *
storageDriverS3FileWriteIo(const StorageDriverS3FileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->io);
}
/***********************************************************************************************************************************
S3 does not support Posix-style mode
***********************************************************************************************************************************/
mode_t
storageDriverS3FileWriteModeFile(const StorageDriverS3FileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
(void)this;
FUNCTION_TEST_RETURN(0);
}
/***********************************************************************************************************************************
S3 does not support Posix-style mode
***********************************************************************************************************************************/
mode_t
storageDriverS3FileWriteModePath(const StorageDriverS3FileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
(void)this;
FUNCTION_TEST_RETURN(0);
}
/***********************************************************************************************************************************
File name
***********************************************************************************************************************************/
const String *
storageDriverS3FileWriteName(const StorageDriverS3FileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->name);
}
/***********************************************************************************************************************************
S3 operations are always atomic, so return true
***********************************************************************************************************************************/
bool
storageDriverS3FileWriteSyncFile(const StorageDriverS3FileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
(void)this;
FUNCTION_TEST_RETURN(true);
}
/***********************************************************************************************************************************
S3 operations are always atomic, so return true
***********************************************************************************************************************************/
bool
storageDriverS3FileWriteSyncPath(const StorageDriverS3FileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
(void)this;
FUNCTION_TEST_RETURN(true);
}
/***********************************************************************************************************************************
Free the file
***********************************************************************************************************************************/
void
storageDriverS3FileWriteFree(StorageDriverS3FileWrite *this)
storageFileWriteDriverS3New(StorageDriverS3 *storage, const String *name, size_t partSize)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, storage);
FUNCTION_LOG_PARAM(STRING, name);
FUNCTION_LOG_END();
if (this != NULL)
memContextFree(this->memContext);
ASSERT(storage != NULL);
ASSERT(name != NULL);
FUNCTION_LOG_RETURN_VOID();
StorageFileWrite *this = NULL;
MEM_CONTEXT_NEW_BEGIN("StorageFileWriteDriverS3")
{
StorageFileWriteDriverS3 *driver = memNew(sizeof(StorageFileWriteDriverS3));
driver->memContext = MEM_CONTEXT_NEW();
driver->interface = (StorageFileWriteInterface)
{
.type = STORAGE_DRIVER_S3_TYPE_STR,
.name = strDup(name),
.atomic = true,
.createPath = true,
.syncFile = true,
.syncPath = true,
.ioInterface = (IoWriteInterface)
{
.close = storageFileWriteDriverS3Close,
.open = storageFileWriteDriverS3Open,
.write = storageFileWriteDriverS3,
},
};
driver->storage = storage;
driver->partSize = partSize;
this = storageFileWriteNew(driver, &driver->interface);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_FILE_WRITE, this);
}

View File

@ -4,54 +4,12 @@ S3 Storage File Write Driver
#ifndef STORAGE_DRIVER_S3_FILEWRITE_H
#define STORAGE_DRIVER_S3_FILEWRITE_H
#include <sys/types.h>
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct StorageDriverS3FileWrite StorageDriverS3FileWrite;
#include "common/type/buffer.h"
#include "storage/driver/s3/storage.h"
#include "storage/fileWrite.h"
#include "storage/driver/s3/storage.intern.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
StorageDriverS3FileWrite *storageDriverS3FileWriteNew(StorageDriverS3 *storage, const String *name, size_t partSize);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void storageDriverS3FileWriteOpen(StorageDriverS3FileWrite *this);
void storageDriverS3FileWrite(StorageDriverS3FileWrite *this, const Buffer *buffer);
void storageDriverS3FileWriteClose(StorageDriverS3FileWrite *this);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
bool storageDriverS3FileWriteAtomic(const StorageDriverS3FileWrite *this);
bool storageDriverS3FileWriteCreatePath(const StorageDriverS3FileWrite *this);
mode_t storageDriverS3FileWriteModeFile(const StorageDriverS3FileWrite *this);
StorageFileWrite* storageDriverS3FileWriteInterface(const StorageDriverS3FileWrite *this);
IoWrite *storageDriverS3FileWriteIo(const StorageDriverS3FileWrite *this);
mode_t storageDriverS3FileWriteModePath(const StorageDriverS3FileWrite *this);
const String *storageDriverS3FileWriteName(const StorageDriverS3FileWrite *this);
const StorageDriverS3 *storageDriverS3FileWriteStorage(const StorageDriverS3FileWrite *this);
bool storageDriverS3FileWriteSyncFile(const StorageDriverS3FileWrite *this);
bool storageDriverS3FileWriteSyncPath(const StorageDriverS3FileWrite *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void storageDriverS3FileWriteFree(StorageDriverS3FileWrite *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_S3_FILE_WRITE_TYPE \
StorageDriverS3FileWrite *
#define FUNCTION_LOG_STORAGE_DRIVER_S3_FILE_WRITE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageDriverS3FileWrite", buffer, bufferSize)
StorageFileWrite *storageFileWriteDriverS3New(StorageDriverS3 *storage, const String *name, size_t partSize);
#endif

View File

@ -12,11 +12,12 @@ S3 Storage Driver
#include "common/io/http/common.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/object.h"
#include "common/regExp.h"
#include "common/type/xml.h"
#include "storage/driver/s3/fileRead.h"
#include "storage/driver/s3/fileWrite.h"
#include "storage/driver/s3/storage.h"
#include "storage/driver/s3/storage.intern.h"
/***********************************************************************************************************************************
Driver type constant string
@ -72,7 +73,6 @@ Object type
struct StorageDriverS3
{
MemContext *memContext;
Storage *interface; // Driver interface
HttpClient *httpClient; // Http client to service requests
const StringList *headerRedactList; // List of headers to redact from logging
@ -182,7 +182,7 @@ storageDriverS3Auth(
// Generate string to sign
const String *stringToSign = strNewFmt(
AWS4_HMAC_SHA256 "\n%s\n%s/%s/" S3 "/" AWS4_REQUEST "\n%s", strPtr(dateTime), strPtr(date), strPtr(this->region),
strPtr(bufHex(cryptoHashOneStr(HASH_TYPE_SHA256_STR, canonicalRequest))));
strPtr(bufHex(cryptoHashOne(HASH_TYPE_SHA256_STR, BUFSTR(canonicalRequest)))));
// Generate signing key. This key only needs to be regenerated every seven days but we'll do it once a day to keep the
// logic simple. It's a relatively expensive operation so we'd rather not do it for every request.
@ -216,81 +216,6 @@ storageDriverS3Auth(
FUNCTION_TEST_RETURN_VOID();
}
/***********************************************************************************************************************************
New object
***********************************************************************************************************************************/
StorageDriverS3 *
storageDriverS3New(
const String *path, bool write, StoragePathExpressionCallback pathExpressionFunction, const String *bucket,
const String *endPoint, const String *region, const String *accessKey, const String *secretAccessKey,
const String *securityToken, size_t partSize, const String *host, unsigned int port, TimeMSec timeout, bool verifyPeer,
const String *caFile, const String *caPath)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STRING, path);
FUNCTION_LOG_PARAM(BOOL, write);
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
FUNCTION_LOG_PARAM(STRING, bucket);
FUNCTION_LOG_PARAM(STRING, endPoint);
FUNCTION_LOG_PARAM(STRING, region);
FUNCTION_TEST_PARAM(STRING, accessKey);
FUNCTION_TEST_PARAM(STRING, secretAccessKey);
FUNCTION_TEST_PARAM(STRING, securityToken);
FUNCTION_TEST_PARAM(SIZE, partSize);
FUNCTION_LOG_PARAM(STRING, host);
FUNCTION_LOG_PARAM(UINT, port);
FUNCTION_LOG_PARAM(TIME_MSEC, timeout);
FUNCTION_LOG_PARAM(BOOL, verifyPeer);
FUNCTION_LOG_PARAM(STRING, caFile);
FUNCTION_LOG_PARAM(STRING, caPath);
FUNCTION_LOG_END();
ASSERT(path != NULL);
ASSERT(bucket != NULL);
ASSERT(endPoint != NULL);
ASSERT(region != NULL);
ASSERT(accessKey != NULL);
ASSERT(secretAccessKey != NULL);
// Create the object
StorageDriverS3 *this = NULL;
MEM_CONTEXT_NEW_BEGIN("StorageDriverS3")
{
this = memNew(sizeof(StorageDriverS3));
this->memContext = MEM_CONTEXT_NEW();
this->bucket = strDup(bucket);
this->region = strDup(region);
this->accessKey = strDup(accessKey);
this->secretAccessKey = strDup(secretAccessKey);
this->securityToken = strDup(securityToken);
this->partSize = partSize;
this->host = host == NULL ? strNewFmt("%s.%s", strPtr(bucket), strPtr(endPoint)) : strDup(host);
this->port = port;
// Force the signing key to be generated on the first run
this->signingKeyDate = YYYYMMDD_STR;
// Create the storage interface
this->interface = storageNewP(
STORAGE_DRIVER_S3_TYPE_STR, path, 0, 0, write, pathExpressionFunction, this,
.exists = (StorageInterfaceExists)storageDriverS3Exists, .info = (StorageInterfaceInfo)storageDriverS3Info,
.list = (StorageInterfaceList)storageDriverS3List, .newRead = (StorageInterfaceNewRead)storageDriverS3NewRead,
.newWrite = (StorageInterfaceNewWrite)storageDriverS3NewWrite,
.pathCreate = (StorageInterfacePathCreate)storageDriverS3PathCreate,
.pathRemove = (StorageInterfacePathRemove)storageDriverS3PathRemove,
.pathSync = (StorageInterfacePathSync)storageDriverS3PathSync, .remove = (StorageInterfaceRemove)storageDriverS3Remove);
// Create the http client used to service requests
this->httpClient = httpClientNew(this->host, this->port, timeout, verifyPeer, caFile, caPath);
this->headerRedactList = strLstAdd(strLstNew(), S3_HEADER_AUTHORIZATION_STR);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_DRIVER_S3, this);
}
/***********************************************************************************************************************************
Process S3 request
***********************************************************************************************************************************/
@ -410,9 +335,11 @@ storageDriverS3Request(
/***********************************************************************************************************************************
Does a file exist? This function is only for files, not paths.
***********************************************************************************************************************************/
bool
storageDriverS3Exists(StorageDriverS3 *this, const String *path)
static bool
storageDriverS3Exists(THIS_VOID, const String *path)
{
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -459,9 +386,11 @@ storageDriverS3Exists(StorageDriverS3 *this, const String *path)
/***********************************************************************************************************************************
File/path info
***********************************************************************************************************************************/
StorageInfo
storageDriverS3Info(StorageDriverS3 *this, const String *file, bool ignoreMissing, bool followLink)
static StorageInfo
storageDriverS3Info(THIS_VOID, const String *file, bool ignoreMissing, bool followLink)
{
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, file);
@ -481,9 +410,11 @@ storageDriverS3Info(StorageDriverS3 *this, const String *file, bool ignoreMissin
/***********************************************************************************************************************************
Get a list of files from a directory
***********************************************************************************************************************************/
StringList *
storageDriverS3List(StorageDriverS3 *this, const String *path, bool errorOnMissing, const String *expression)
static StringList *
storageDriverS3List(THIS_VOID, const String *path, bool errorOnMissing, const String *expression)
{
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -608,9 +539,11 @@ storageDriverS3List(StorageDriverS3 *this, const String *path, bool errorOnMissi
/***********************************************************************************************************************************
New file read object
***********************************************************************************************************************************/
StorageFileRead *
storageDriverS3NewRead(StorageDriverS3 *this, const String *file, bool ignoreMissing)
static StorageFileRead *
storageDriverS3NewRead(THIS_VOID, const String *file, bool ignoreMissing)
{
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, file);
@ -620,18 +553,19 @@ storageDriverS3NewRead(StorageDriverS3 *this, const String *file, bool ignoreMis
ASSERT(this != NULL);
ASSERT(file != NULL);
FUNCTION_LOG_RETURN(
STORAGE_FILE_READ, storageDriverS3FileReadInterface(storageDriverS3FileReadNew(this, file, ignoreMissing)));
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, storageFileReadDriverS3New(this, file, ignoreMissing));
}
/***********************************************************************************************************************************
New file write object
***********************************************************************************************************************************/
StorageFileWrite *
static StorageFileWrite *
storageDriverS3NewWrite(
StorageDriverS3 *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
THIS_VOID, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
{
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, file);
@ -653,8 +587,7 @@ storageDriverS3NewWrite(
ASSERT(group == NULL);
ASSERT(timeModified == 0);
FUNCTION_LOG_RETURN(
STORAGE_FILE_WRITE, storageDriverS3FileWriteInterface(storageDriverS3FileWriteNew(this, file, this->partSize)));
FUNCTION_LOG_RETURN(STORAGE_FILE_WRITE, storageFileWriteDriverS3New(this, file, this->partSize));
}
/***********************************************************************************************************************************
@ -662,9 +595,11 @@ Create a path
There are no physical paths on S3 so just return success.
***********************************************************************************************************************************/
void
storageDriverS3PathCreate(StorageDriverS3 *this, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
static void
storageDriverS3PathCreate(THIS_VOID, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
{
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -683,9 +618,11 @@ storageDriverS3PathCreate(StorageDriverS3 *this, const String *path, bool errorO
/***********************************************************************************************************************************
Remove a path
***********************************************************************************************************************************/
void
storageDriverS3PathRemove(StorageDriverS3 *this, const String *path, bool errorOnMissing, bool recurse)
static void
storageDriverS3PathRemove(THIS_VOID, const String *path, bool errorOnMissing, bool recurse)
{
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -706,9 +643,11 @@ Sync a path
There's no need for this on S3 so just return success.
***********************************************************************************************************************************/
void
storageDriverS3PathSync(StorageDriverS3 *this, const String *path, bool ignoreMissing)
static void
storageDriverS3PathSync(THIS_VOID, const String *path, bool ignoreMissing)
{
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, path);
@ -724,9 +663,11 @@ storageDriverS3PathSync(StorageDriverS3 *this, const String *path, bool ignoreMi
/***********************************************************************************************************************************
Remove a file
***********************************************************************************************************************************/
void
storageDriverS3Remove(StorageDriverS3 *this, const String *file, bool errorOnMissing)
static void
storageDriverS3Remove(THIS_VOID, const String *file, bool errorOnMissing)
{
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, file);
@ -757,16 +698,71 @@ storageDriverS3HttpClient(const StorageDriverS3 *this)
}
/***********************************************************************************************************************************
Get storage interface
New object
***********************************************************************************************************************************/
Storage *
storageDriverS3Interface(const StorageDriverS3 *this)
storageDriverS3New(
const String *path, bool write, StoragePathExpressionCallback pathExpressionFunction, const String *bucket,
const String *endPoint, const String *region, const String *accessKey, const String *secretAccessKey,
const String *securityToken, size_t partSize, const String *host, unsigned int port, TimeMSec timeout, bool verifyPeer,
const String *caFile, const String *caPath)
{
FUNCTION_TEST_BEGIN();
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_TEST_END();
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STRING, path);
FUNCTION_LOG_PARAM(BOOL, write);
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
FUNCTION_LOG_PARAM(STRING, bucket);
FUNCTION_LOG_PARAM(STRING, endPoint);
FUNCTION_LOG_PARAM(STRING, region);
FUNCTION_TEST_PARAM(STRING, accessKey);
FUNCTION_TEST_PARAM(STRING, secretAccessKey);
FUNCTION_TEST_PARAM(STRING, securityToken);
FUNCTION_TEST_PARAM(SIZE, partSize);
FUNCTION_LOG_PARAM(STRING, host);
FUNCTION_LOG_PARAM(UINT, port);
FUNCTION_LOG_PARAM(TIME_MSEC, timeout);
FUNCTION_LOG_PARAM(BOOL, verifyPeer);
FUNCTION_LOG_PARAM(STRING, caFile);
FUNCTION_LOG_PARAM(STRING, caPath);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(path != NULL);
ASSERT(bucket != NULL);
ASSERT(endPoint != NULL);
ASSERT(region != NULL);
ASSERT(accessKey != NULL);
ASSERT(secretAccessKey != NULL);
FUNCTION_TEST_RETURN(this->interface);
Storage *this = NULL;
MEM_CONTEXT_NEW_BEGIN("StorageDriverS3")
{
StorageDriverS3 *driver = memNew(sizeof(StorageDriverS3));
driver->memContext = MEM_CONTEXT_NEW();
driver->bucket = strDup(bucket);
driver->region = strDup(region);
driver->accessKey = strDup(accessKey);
driver->secretAccessKey = strDup(secretAccessKey);
driver->securityToken = strDup(securityToken);
driver->partSize = partSize;
driver->host = host == NULL ? strNewFmt("%s.%s", strPtr(bucket), strPtr(endPoint)) : strDup(host);
driver->port = port;
// Force the signing key to be generated on the first run
driver->signingKeyDate = YYYYMMDD_STR;
// Create the http client used to service requests
driver->httpClient = httpClientNew(driver->host, driver->port, timeout, verifyPeer, caFile, caPath);
driver->headerRedactList = strLstAdd(strLstNew(), S3_HEADER_AUTHORIZATION_STR);
this = storageNewP(
STORAGE_DRIVER_S3_TYPE_STR, path, 0, 0, write, pathExpressionFunction, driver,
.exists = storageDriverS3Exists, .info = storageDriverS3Info, .list = storageDriverS3List,
.newRead = storageDriverS3NewRead, .newWrite = storageDriverS3NewWrite, .pathCreate = storageDriverS3PathCreate,
.pathRemove = storageDriverS3PathRemove, .pathSync = storageDriverS3PathSync, .remove = storageDriverS3Remove);
}
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE, this);
}

View File

@ -4,13 +4,6 @@ S3 Storage Driver
#ifndef STORAGE_DRIVER_S3_STORAGE_H
#define STORAGE_DRIVER_S3_STORAGE_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct StorageDriverS3 StorageDriverS3;
#include "common/io/http/client.h"
#include "common/type/string.h"
#include "storage/storage.intern.h"
/***********************************************************************************************************************************
@ -24,66 +17,15 @@ Defaults
***********************************************************************************************************************************/
#define STORAGE_DRIVER_S3_PORT_DEFAULT 443
#define STORAGE_DRIVER_S3_TIMEOUT_DEFAULT 60000
#define STORAGE_DRIVER_S3_PARTSIZE_MIN ((size_t)5 * 1024 * 1024)
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
StorageDriverS3 *storageDriverS3New(
Storage *storageDriverS3New(
const String *path, bool write, StoragePathExpressionCallback pathExpressionFunction, const String *bucket,
const String *endPoint, const String *region, const String *accessKey, const String *secretAccessKey,
const String *securityToken, size_t partSize, const String *host, unsigned int port, TimeMSec timeout, bool verifyPeer,
const String *caFile, const String *caPath);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
bool storageDriverS3Exists(StorageDriverS3 *this, const String *path);
StorageInfo storageDriverS3Info(StorageDriverS3 *this, const String *file, bool ignoreMissing, bool followLink);
StringList *storageDriverS3List(StorageDriverS3 *this, const String *path, bool errorOnMissing, const String *expression);
StorageFileRead *storageDriverS3NewRead(StorageDriverS3 *this, const String *file, bool ignoreMissing);
StorageFileWrite *storageDriverS3NewWrite(
StorageDriverS3 *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
void storageDriverS3PathCreate(StorageDriverS3 *this, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode);
void storageDriverS3PathRemove(StorageDriverS3 *this, const String *path, bool errorOnMissing, bool recurse);
void storageDriverS3PathSync(StorageDriverS3 *this, const String *path, bool ignoreMissing);
void storageDriverS3Remove(StorageDriverS3 *this, const String *file, bool errorOnMissing);
/***********************************************************************************************************************************
Perform an S3 Request
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_S3_REQUEST_RESULT_TYPE \
StorageDriverS3RequestResult
#define FUNCTION_LOG_STORAGE_DRIVER_S3_REQUEST_RESULT_FORMAT(value, buffer, bufferSize) \
objToLog(&value, "StorageDriverS3RequestResult", buffer, bufferSize)
typedef struct StorageDriverS3RequestResult
{
HttpHeader *responseHeader;
Buffer *response;
} StorageDriverS3RequestResult;
StorageDriverS3RequestResult storageDriverS3Request(
StorageDriverS3 *this, const String *verb, const String *uri, const HttpQuery *query, const Buffer *body, bool returnContent,
bool allowMissing);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
HttpClient *storageDriverS3HttpClient(const StorageDriverS3 *this);
Storage *storageDriverS3Interface(const StorageDriverS3 *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void storageDriverS3Free(StorageDriverS3 *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_S3_TYPE \
StorageDriverS3 *
#define FUNCTION_LOG_STORAGE_DRIVER_S3_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageDriverS3", buffer, bufferSize)
#endif

View File

@ -0,0 +1,46 @@
/***********************************************************************************************************************************
S3 Storage Driver Internal
***********************************************************************************************************************************/
#ifndef STORAGE_DRIVER_S3_STORAGE_INTERN_H
#define STORAGE_DRIVER_S3_STORAGE_INTERN_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct StorageDriverS3 StorageDriverS3;
#include "common/io/http/client.h"
#include "storage/driver/s3/storage.h"
/***********************************************************************************************************************************
Perform an S3 Request
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_S3_REQUEST_RESULT_TYPE \
StorageDriverS3RequestResult
#define FUNCTION_LOG_STORAGE_DRIVER_S3_REQUEST_RESULT_FORMAT(value, buffer, bufferSize) \
objToLog(&value, "StorageDriverS3RequestResult", buffer, bufferSize)
typedef struct StorageDriverS3RequestResult
{
HttpHeader *responseHeader;
Buffer *response;
} StorageDriverS3RequestResult;
StorageDriverS3RequestResult storageDriverS3Request(
StorageDriverS3 *this, const String *verb, const String *uri, const HttpQuery *query, const Buffer *body, bool returnContent,
bool allowMissing);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
HttpClient *storageDriverS3HttpClient(const StorageDriverS3 *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_DRIVER_S3_TYPE \
StorageDriverS3 *
#define FUNCTION_LOG_STORAGE_DRIVER_S3_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageDriverS3", buffer, bufferSize)
#endif

View File

@ -13,37 +13,42 @@ Object type
***********************************************************************************************************************************/
struct StorageFileRead
{
MemContext *memContext;
const String *type;
MemContext *memContext; // Object mem context
void *driver;
StorageFileReadInterface interface;
const StorageFileReadInterface *interface;
IoRead *io;
};
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_FILE_READ_INTERFACE_TYPE \
StorageFileReadInterface
#define FUNCTION_LOG_STORAGE_FILE_READ_INTERFACE_FORMAT(value, buffer, bufferSize) \
objToLog(&value, "StorageFileReadInterface", buffer, bufferSize)
/***********************************************************************************************************************************
Create a new storage file
***********************************************************************************************************************************/
StorageFileRead *
storageFileReadNew(const String *type, void *driver, StorageFileReadInterface interface)
storageFileReadNew(void *driver, const StorageFileReadInterface *interface)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, type);
FUNCTION_LOG_PARAM_P(VOID, driver);
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_INTERFACE, interface);
FUNCTION_LOG_PARAM_P(STORAGE_FILE_READ_INTERFACE, interface);
FUNCTION_LOG_END();
ASSERT(type != NULL);
ASSERT(driver != NULL);
ASSERT(interface.ignoreMissing != NULL);
ASSERT(interface.io != NULL);
ASSERT(interface.name != NULL);
ASSERT(interface != NULL);
StorageFileRead *this = NULL;
this = memNew(sizeof(StorageFileRead));
this->memContext = memContextCurrent();
this->type = type;
this->interface = interface;
this->driver = driver;
this->interface = interface;
this->io = ioReadNew(driver, interface->ioInterface);
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, this);
}
@ -94,7 +99,7 @@ storageFileReadIgnoreMissing(const StorageFileRead *this)
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface.ignoreMissing(this->driver));
FUNCTION_TEST_RETURN(this->interface->ignoreMissing);
}
/***********************************************************************************************************************************
@ -109,7 +114,7 @@ storageFileReadIo(const StorageFileRead *this)
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface.io(this->driver));
FUNCTION_TEST_RETURN(this->io);
}
/***********************************************************************************************************************************
@ -124,7 +129,7 @@ storageFileReadName(const StorageFileRead *this)
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface.name(this->driver));
FUNCTION_TEST_RETURN(this->interface->name);
}
/***********************************************************************************************************************************
@ -139,7 +144,7 @@ storageFileReadType(const StorageFileRead *this)
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->type);
FUNCTION_TEST_RETURN(this->interface->type);
}
/***********************************************************************************************************************************
@ -149,8 +154,8 @@ String *
storageFileReadToLog(const StorageFileRead *this)
{
return strNewFmt(
"{type: %s, name: %s, ignoreMissing: %s}", strPtr(this->type), strPtr(strToLog(storageFileReadName(this))),
cvtBoolToConstZ(storageFileReadIgnoreMissing(this)));
"{type: %s, name: %s, ignoreMissing: %s}", strPtr(this->interface->type), strPtr(strToLog(this->interface->name)),
cvtBoolToConstZ(this->interface->ignoreMissing));
}
/***********************************************************************************************************************************

View File

@ -19,7 +19,6 @@ StorageFileRead *storageFileReadMove(StorageFileRead *this, MemContext *parentNe
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
void *storageFileReadDriver(const StorageFileRead *this);
IoRead *storageFileReadIo(const StorageFileRead *this);
bool storageFileReadIgnoreMissing(const StorageFileRead *this);
const String *storageFileReadName(const StorageFileRead *this);

View File

@ -4,33 +4,25 @@ Storage File Read Interface Internal
#ifndef STORAGE_FILEREAD_INTERN_H
#define STORAGE_FILEREAD_INTERN_H
#include "common/io/read.intern.h"
#include "storage/fileRead.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
typedef bool (*StorageFileReadInterfaceIgnoreMissing)(const void *driver);
typedef IoRead *(*StorageFileReadInterfaceIo)(const void *driver);
typedef const String *(*StorageFileReadInterfaceName)(const void *driver);
typedef struct StorageFileReadInterface
{
StorageFileReadInterfaceIgnoreMissing ignoreMissing;
StorageFileReadInterfaceIo io;
StorageFileReadInterfaceName name;
const String * type;
const String * name;
bool ignoreMissing;
IoReadInterface ioInterface;
} StorageFileReadInterface;
#define storageFileReadNewP(type, driver, ...) \
storageFileReadNew(type, driver, (StorageFileReadInterface){__VA_ARGS__})
StorageFileRead *storageFileReadNew(const String *type, void *driver, StorageFileReadInterface interface);
StorageFileRead *storageFileReadNew(void *driver, const StorageFileReadInterface *interface);
/***********************************************************************************************************************************
Macros for function logging
Constructor
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_FILE_READ_INTERFACE_TYPE \
StorageFileReadInterface
#define FUNCTION_LOG_STORAGE_FILE_READ_INTERFACE_FORMAT(value, buffer, bufferSize) \
objToLog(&value, "StorageFileReadInterface", buffer, bufferSize)
void *storageFileReadDriver(const StorageFileRead *this);
#endif

View File

@ -13,12 +13,20 @@ Object type
***********************************************************************************************************************************/
struct StorageFileWrite
{
MemContext *memContext;
const String *type;
MemContext *memContext; // Object mem context
void *driver;
StorageFileWriteInterface interface;
const StorageFileWriteInterface *interface;
IoWrite *io;
};
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_FILE_WRITE_INTERFACE_TYPE \
StorageFileWriteInterface
#define FUNCTION_LOG_STORAGE_FILE_WRITE_INTERFACE_FORMAT(value, buffer, bufferSize) \
objToLog(&value, "StorageFileWriteInterface", buffer, bufferSize)
/***********************************************************************************************************************************
Create a new storage file
@ -26,32 +34,24 @@ This object expects its context to be created in advance. This is so the callin
required multiple functions and contexts to make it safe.
***********************************************************************************************************************************/
StorageFileWrite *
storageFileWriteNew(const String *type, void *driver, StorageFileWriteInterface interface)
storageFileWriteNew(void *driver, const StorageFileWriteInterface *interface)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, type);
FUNCTION_LOG_PARAM_P(VOID, driver);
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_INTERFACE, interface);
FUNCTION_LOG_PARAM_P(STORAGE_FILE_WRITE_INTERFACE, interface);
FUNCTION_LOG_END();
ASSERT(type != NULL);
ASSERT(driver != NULL);
ASSERT(interface.atomic != NULL);
ASSERT(interface.createPath != NULL);
ASSERT(interface.io != NULL);
ASSERT(interface.modeFile != NULL);
ASSERT(interface.modePath != NULL);
ASSERT(interface.name != NULL);
ASSERT(interface.syncFile != NULL);
ASSERT(interface.syncPath != NULL);
ASSERT(interface != NULL);
StorageFileWrite *this = memNew(sizeof(StorageFileWrite));
this->memContext = memContextCurrent();
this->type = type;
this->driver = driver;
this->interface = interface;
this->io = ioWriteNew(driver, interface->ioInterface);
FUNCTION_LOG_RETURN(STORAGE_FILE_WRITE, this);
}
@ -88,7 +88,7 @@ storageFileWriteAtomic(const StorageFileWrite *this)
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface.atomic(this->driver));
FUNCTION_TEST_RETURN(this->interface->atomic);
}
/***********************************************************************************************************************************
@ -103,7 +103,7 @@ storageFileWriteCreatePath(const StorageFileWrite *this)
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface.createPath(this->driver));
FUNCTION_TEST_RETURN(this->interface->createPath);
}
/***********************************************************************************************************************************
@ -133,7 +133,7 @@ storageFileWriteIo(const StorageFileWrite *this)
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface.io(this->driver));
FUNCTION_TEST_RETURN(this->io);
}
/***********************************************************************************************************************************
@ -148,7 +148,7 @@ storageFileWriteModeFile(const StorageFileWrite *this)
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface.modeFile(this->driver));
FUNCTION_TEST_RETURN(this->interface->modeFile);
}
/***********************************************************************************************************************************
@ -163,7 +163,7 @@ storageFileWriteModePath(const StorageFileWrite *this)
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface.modePath(this->driver));
FUNCTION_TEST_RETURN(this->interface->modePath);
}
/***********************************************************************************************************************************
@ -178,7 +178,7 @@ storageFileWriteName(const StorageFileWrite *this)
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface.name(this->driver));
FUNCTION_TEST_RETURN(this->interface->name);
}
/***********************************************************************************************************************************
@ -193,7 +193,7 @@ storageFileWriteSyncFile(const StorageFileWrite *this)
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface.syncFile(this->driver));
FUNCTION_TEST_RETURN(this->interface->syncFile);
}
/***********************************************************************************************************************************
@ -208,7 +208,7 @@ storageFileWriteSyncPath(const StorageFileWrite *this)
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface.syncPath(this->driver));
FUNCTION_TEST_RETURN(this->interface->syncPath);
}
/***********************************************************************************************************************************
@ -223,7 +223,7 @@ storageFileWriteType(const StorageFileWrite *this)
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->type);
FUNCTION_TEST_RETURN(this->interface->type);
}
/***********************************************************************************************************************************
@ -234,7 +234,7 @@ storageFileWriteToLog(const StorageFileWrite *this)
{
return strNewFmt(
"{type: %s, name: %s, modeFile: %04o, modePath: %04o, createPath: %s, syncFile: %s, syncPath: %s, atomic: %s}",
strPtr(this->type), strPtr(strToLog(storageFileWriteName(this))), storageFileWriteModeFile(this),
strPtr(storageFileWriteType(this)), strPtr(strToLog(storageFileWriteName(this))), storageFileWriteModeFile(this),
storageFileWriteModePath(this), cvtBoolToConstZ(storageFileWriteCreatePath(this)),
cvtBoolToConstZ(storageFileWriteSyncFile(this)), cvtBoolToConstZ(storageFileWriteSyncPath(this)),
cvtBoolToConstZ(storageFileWriteAtomic(this)));

View File

@ -4,10 +4,8 @@ Storage File Write Interface
#ifndef STORAGE_FILEWRITE_H
#define STORAGE_FILEWRITE_H
#include <sys/types.h>
/***********************************************************************************************************************************
Object type
Object types
***********************************************************************************************************************************/
typedef struct StorageFileWrite StorageFileWrite;
@ -25,7 +23,6 @@ Getters
***********************************************************************************************************************************/
bool storageFileWriteAtomic(const StorageFileWrite *this);
bool storageFileWriteCreatePath(const StorageFileWrite *this);
void *storageFileWriteFileDriver(const StorageFileWrite *this);
IoWrite *storageFileWriteIo(const StorageFileWrite *this);
mode_t storageFileWriteModeFile(const StorageFileWrite *this);
mode_t storageFileWriteModePath(const StorageFileWrite *this);

View File

@ -4,6 +4,7 @@ Storage File Write Internal
#ifndef STORAGE_FILEWRITE_INTERN_H
#define STORAGE_FILEWRITE_INTERN_H
#include "common/io/write.intern.h"
#include "storage/fileWrite.h"
#include "version.h"
@ -15,38 +16,29 @@ Temporary file extension
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
typedef bool (*StorageFileWriteInterfaceAtomic)(const void *data);
typedef bool (*StorageFileWriteInterfaceCreatePath)(const void *data);
typedef IoWrite *(*StorageFileWriteInterfaceIo)(const void *data);
typedef mode_t (*StorageFileWriteInterfaceModeFile)(const void *data);
typedef mode_t (*StorageFileWriteInterfaceModePath)(const void *data);
typedef const String *(*StorageFileWriteInterfaceName)(const void *data);
typedef bool (*StorageFileWriteInterfaceSyncFile)(const void *data);
typedef bool (*StorageFileWriteInterfaceSyncPath)(const void *data);
typedef struct StorageFileWriteInterface
{
StorageFileWriteInterfaceAtomic atomic;
StorageFileWriteInterfaceCreatePath createPath;
StorageFileWriteInterfaceIo io;
StorageFileWriteInterfaceModeFile modeFile;
StorageFileWriteInterfaceModePath modePath;
StorageFileWriteInterfaceName name;
StorageFileWriteInterfaceSyncFile syncFile;
StorageFileWriteInterfaceSyncPath syncPath;
const String *type;
const String *name;
bool atomic;
bool createPath;
const String *group; // Group that owns the file
mode_t modeFile;
mode_t modePath;
bool syncFile;
bool syncPath;
time_t timeModified; // Time file was last modified
const String *user; // User that owns the file
IoWriteInterface ioInterface;
} StorageFileWriteInterface;
#define storageFileWriteNewP(type, driver, ...) \
storageFileWriteNew(type, driver, (StorageFileWriteInterface){__VA_ARGS__})
StorageFileWrite *storageFileWriteNew(const String *type, void *driver, StorageFileWriteInterface interface);
StorageFileWrite *storageFileWriteNew(void *driver, const StorageFileWriteInterface *interface);
/***********************************************************************************************************************************
Macros for function logging
Functions
***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_FILE_WRITE_INTERFACE_TYPE \
StorageFileWriteInterface
#define FUNCTION_LOG_STORAGE_FILE_WRITE_INTERFACE_FORMAT(value, buffer, bufferSize) \
objToLog(&value, "StorageFileWriteInterface", buffer, bufferSize)
void *storageFileWriteFileDriver(const StorageFileWrite *this);
#endif

View File

@ -105,9 +105,8 @@ storageLocal(void)
MEM_CONTEXT_BEGIN(storageHelper.memContext)
{
storageHelper.storageLocal = storageDriverPosixInterface(
storageDriverPosixNew(
FSLASH_STR, STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL));
storageHelper.storageLocal = storageDriverPosixNew(
FSLASH_STR, STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL);
}
MEM_CONTEXT_END();
}
@ -131,9 +130,8 @@ storageLocalWrite(void)
MEM_CONTEXT_BEGIN(storageHelper.memContext)
{
storageHelper.storageLocalWrite = storageDriverPosixInterface(
storageDriverPosixNew(
FSLASH_STR, STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
storageHelper.storageLocalWrite = storageDriverPosixNew(
FSLASH_STR, STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
}
MEM_CONTEXT_END();
}
@ -155,9 +153,8 @@ storagePg(void)
MEM_CONTEXT_BEGIN(storageHelper.memContext)
{
storageHelper.storagePg = storageDriverPosixInterface(
storageDriverPosixNew(
cfgOptionStr(cfgOptPgPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL));
storageHelper.storagePg = storageDriverPosixNew(
cfgOptionStr(cfgOptPgPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL);
}
MEM_CONTEXT_END();
}
@ -179,9 +176,8 @@ storagePgWrite(void)
MEM_CONTEXT_BEGIN(storageHelper.memContext)
{
storageHelper.storagePgWrite = storageDriverPosixInterface(
storageDriverPosixNew(
cfgOptionStr(cfgOptPgPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
storageHelper.storagePgWrite = storageDriverPosixNew(
cfgOptionStr(cfgOptPgPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
}
MEM_CONTEXT_END();
}
@ -280,26 +276,21 @@ storageRepoGet(const String *type, bool write)
// Use remote storage
if (!repoIsLocal())
{
result = storageDriverRemoteInterface(
storageDriverRemoteNew(
result = storageDriverRemoteNew(
STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, write, storageRepoPathExpression,
protocolRemoteGet(protocolStorageTypeRepo)));
protocolRemoteGet(protocolStorageTypeRepo));
}
// Use the CIFS driver
else if (strEqZ(type, STORAGE_TYPE_CIFS))
{
result = storageDriverCifsInterface(
storageDriverCifsNew(
cfgOptionStr(cfgOptRepoPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, write,
storageRepoPathExpression));
result = storageDriverCifsNew(
cfgOptionStr(cfgOptRepoPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, write, storageRepoPathExpression);
}
// Use the Posix driver
else if (strEqZ(type, STORAGE_TYPE_POSIX))
{
result = storageDriverPosixInterface(
storageDriverPosixNew(
cfgOptionStr(cfgOptRepoPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, write,
storageRepoPathExpression));
result = storageDriverPosixNew(
cfgOptionStr(cfgOptRepoPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, write, storageRepoPathExpression);
}
// Use the S3 driver
else if (strEqZ(type, STORAGE_TYPE_S3))
@ -311,14 +302,13 @@ storageRepoGet(const String *type, bool write)
const String *endPoint = cfgOptionHostPort(cfgOptRepoS3Endpoint, &port);
const String *host = cfgOptionHostPort(cfgOptRepoS3Host, &port);
result = storageDriverS3Interface(
storageDriverS3New(
cfgOptionStr(cfgOptRepoPath), write, storageRepoPathExpression, cfgOptionStr(cfgOptRepoS3Bucket),
endPoint, cfgOptionStr(cfgOptRepoS3Region), cfgOptionStr(cfgOptRepoS3Key), cfgOptionStr(cfgOptRepoS3KeySecret),
cfgOptionTest(cfgOptRepoS3Token) ? cfgOptionStr(cfgOptRepoS3Token) : NULL, (size_t)5 * 1024 * 1024, host, port,
result = storageDriverS3New(
cfgOptionStr(cfgOptRepoPath), write, storageRepoPathExpression, cfgOptionStr(cfgOptRepoS3Bucket), endPoint,
cfgOptionStr(cfgOptRepoS3Region), cfgOptionStr(cfgOptRepoS3Key), cfgOptionStr(cfgOptRepoS3KeySecret),
cfgOptionTest(cfgOptRepoS3Token) ? cfgOptionStr(cfgOptRepoS3Token) : NULL, STORAGE_DRIVER_S3_PARTSIZE_MIN, host, port,
STORAGE_DRIVER_S3_TIMEOUT_DEFAULT, cfgOptionBool(cfgOptRepoS3VerifySsl),
cfgOptionTest(cfgOptRepoS3CaFile) ? cfgOptionStr(cfgOptRepoS3CaFile) : NULL,
cfgOptionTest(cfgOptRepoS3CaPath) ? cfgOptionStr(cfgOptRepoS3CaPath) : NULL));
cfgOptionTest(cfgOptRepoS3CaPath) ? cfgOptionStr(cfgOptRepoS3CaPath) : NULL);
}
else
THROW_FMT(AssertError, "invalid storage type '%s'", strPtr(type));
@ -425,10 +415,9 @@ storageSpool(void)
MEM_CONTEXT_BEGIN(storageHelper.memContext)
{
storageHelper.storageSpool = storageDriverPosixInterface(
storageDriverPosixNew(
storageHelper.storageSpool = storageDriverPosixNew(
cfgOptionStr(cfgOptSpoolPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false,
storageSpoolPathExpression));
storageSpoolPathExpression);
}
MEM_CONTEXT_END();
}
@ -451,10 +440,9 @@ storageSpoolWrite(void)
MEM_CONTEXT_BEGIN(storageHelper.memContext)
{
storageHelper.storageSpoolWrite = storageDriverPosixInterface(
storageDriverPosixNew(
storageHelper.storageSpoolWrite = storageDriverPosixNew(
cfgOptionStr(cfgOptSpoolPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true,
storageSpoolPathExpression));
storageSpoolPathExpression);
}
MEM_CONTEXT_END();
}

View File

@ -348,7 +348,7 @@ storageMove(const Storage *this, StorageFileRead *source, StorageFileWrite *dest
MEM_CONTEXT_TEMP_BEGIN()
{
// If the file can't be moved it will need to be copied
if (!this->interface.move(this->driver, storageFileReadDriver(source), storageFileWriteFileDriver(destination)))
if (!this->interface.move(this->driver, source, destination))
{
// Perform the copy
storageCopyNP(source, destination);

View File

@ -4,6 +4,8 @@ Storage Interface Internal
#ifndef STORAGE_STORAGE_INTERN_H
#define STORAGE_STORAGE_INTERN_H
#include "storage/fileRead.intern.h"
#include "storage/fileWrite.intern.h"
#include "storage/storage.h"
/***********************************************************************************************************************************
@ -20,35 +22,21 @@ typedef String *(*StoragePathExpressionCallback)(const String *expression, const
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
typedef bool (*StorageInterfaceExists)(void *driver, const String *path);
typedef StorageInfo (*StorageInterfaceInfo)(void *driver, const String *path, bool ignoreMissing, bool followLink);
typedef bool (*StorageInterfaceInfoList)(
void *driver, const String *file, bool ignoreMissing, StorageInfoListCallback callback, void *callbackData);
typedef StringList *(*StorageInterfaceList)(void *driver, const String *path, bool errorOnMissing, const String *expression);
typedef bool (*StorageInterfaceMove)(void *driver, void *source, void *destination);
typedef StorageFileRead *(*StorageInterfaceNewRead)(void *driver, const String *file, bool ignoreMissing);
typedef StorageFileWrite *(*StorageInterfaceNewWrite)(
void *driver, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
typedef void (*StorageInterfacePathCreate)(
void *driver, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode);
typedef void (*StorageInterfacePathRemove)(void *driver, const String *path, bool errorOnMissing, bool recurse);
typedef void (*StorageInterfacePathSync)(void *driver, const String *path, bool ignoreMissing);
typedef void (*StorageInterfaceRemove)(void *driver, const String *file, bool errorOnMissing);
typedef struct StorageInterface
{
StorageInterfaceExists exists;
StorageInterfaceInfo info;
StorageInterfaceInfoList infoList;
StorageInterfaceList list;
StorageInterfaceMove move;
StorageInterfaceNewRead newRead;
StorageInterfaceNewWrite newWrite;
StorageInterfacePathCreate pathCreate;
StorageInterfacePathRemove pathRemove;
StorageInterfacePathSync pathSync;
StorageInterfaceRemove remove;
bool (*exists)(void *driver, const String *path);
StorageInfo (*info)(void *driver, const String *path, bool ignoreMissing, bool followLink);
bool (*infoList)(void *driver, const String *file, bool ignoreMissing, StorageInfoListCallback callback, void *callbackData);
StringList *(*list)(void *driver, const String *path, bool errorOnMissing, const String *expression);
bool (*move)(void *driver, StorageFileRead *source, StorageFileWrite *destination);
StorageFileRead *(*newRead)(void *driver, const String *file, bool ignoreMissing);
StorageFileWrite *(*newWrite)(
void *driver, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
void (*pathCreate)(void *driver, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode);
void (*pathRemove)(void *driver, const String *path, bool errorOnMissing, bool recurse);
void (*pathSync)(void *driver, const String *path, bool ignoreMissing);
void (*remove)(void *driver, const String *file, bool errorOnMissing);
} StorageInterface;
#define storageNewP(type, path, modeFile, modePath, write, pathExpressionFunction, driver, ...) \

View File

@ -498,6 +498,7 @@ unit:
coverage:
storage/driver/cifs/storage: full
storage/driver/posix/storage: full
storage/helper: full
storage/storage: full

View File

@ -59,7 +59,7 @@ sub run
$self->testException(
sub {new pgBackRest::Storage::Filter::CipherBlock(
$oDriver->openRead($strFile), BOGUS, $tCipherPass)},
ERROR_ASSERT, "unable to load cipher '" . BOGUS . "'");
ERROR_ASSERT, "invalid cipher name '" . BOGUS . "'");
$self->testException(
sub {new pgBackRest::Storage::Filter::CipherBlock(
@ -69,7 +69,7 @@ sub run
$self->testException(
sub {new pgBackRest::Storage::Filter::CipherBlock(
$oDriver->openWrite($strFile), BOGUS, $tCipherPass)},
ERROR_ASSERT, "unable to load cipher '" . BOGUS . "'");
ERROR_ASSERT, "invalid cipher name '" . BOGUS . "'");
}
################################################################################################################################

View File

@ -36,7 +36,7 @@ harnessInfoChecksum(const String *info)
// Write to a buffer
result = bufNew(0);
iniSave(ini, ioBufferWriteIo(ioBufferWriteNew(result)));
iniSave(ini, ioBufferWriteNew(result));
bufMove(result, MEM_CONTEXT_OLD());
}
MEM_CONTEXT_TEMP_END();

View File

@ -17,8 +17,8 @@ testRun(void)
FUNCTION_HARNESS_VOID();
// Create default storage object for testing
Storage *storageTest = storageDriverPosixInterface(
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
Storage *storageTest = storageDriverPosixNew(
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
// *****************************************************************************************************************************
if (testBegin("archiveAsyncStatus()"))

View File

@ -20,16 +20,16 @@ testRun(void)
{
FUNCTION_HARNESS_VOID();
Storage *storageTest = storageDriverPosixInterface(
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
Storage *storageTest = storageDriverPosixNew(
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
// Start a protocol server to test the protocol directly
Buffer *serverWrite = bufNew(8192);
IoWrite *serverWriteIo = ioBufferWriteIo(ioBufferWriteNew(serverWrite));
IoWrite *serverWriteIo = ioBufferWriteNew(serverWrite);
ioWriteOpen(serverWriteIo);
ProtocolServer *server = protocolServerNew(
strNew("test"), strNew("test"), ioBufferReadIo(ioBufferReadNew(bufNew(0))), serverWriteIo);
strNew("test"), strNew("test"), ioBufferReadNew(bufNew(0)), serverWriteIo);
bufUsedSet(serverWrite, 0);
@ -189,8 +189,7 @@ testRun(void)
ioWriteFilterGroupSet(
storageFileWriteIo(infoWrite),
ioFilterGroupAdd(
ioFilterGroupNew(),
cipherBlockFilter(cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("12345678"), NULL))));
ioFilterGroupNew(), cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("12345678"), NULL)));
storagePutNP(
infoWrite,
@ -210,11 +209,9 @@ testRun(void)
"repo/archive/test1/10-1/01ABCDEF01ABCDEF/01ABCDEF01ABCDEF01ABCDEF-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.gz"));
IoFilterGroup *filterGroup = ioFilterGroupNew();
ioFilterGroupAdd(filterGroup, gzipCompressFilter(gzipCompressNew(3, false)));
ioFilterGroupAdd(filterGroup, gzipCompressNew(3, false));
ioFilterGroupAdd(
filterGroup,
cipherBlockFilter(
cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("worstpassphraseever"), NULL)));
filterGroup, cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("worstpassphraseever"), NULL));
ioWriteFilterGroupSet(storageFileWriteIo(destination), filterGroup);
storagePutNP(destination, buffer);

View File

@ -22,16 +22,16 @@ testRun(void)
FUNCTION_HARNESS_VOID();
// Create default storage object for testing
Storage *storageTest = storageDriverPosixInterface(
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
Storage *storageTest = storageDriverPosixNew(
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
// Start a protocol server to test the protocol directly
Buffer *serverWrite = bufNew(8192);
IoWrite *serverWriteIo = ioBufferWriteIo(ioBufferWriteNew(serverWrite));
IoWrite *serverWriteIo = ioBufferWriteNew(serverWrite);
ioWriteOpen(serverWriteIo);
ProtocolServer *server = protocolServerNew(
strNew("test"), strNew("test"), ioBufferReadIo(ioBufferReadNew(bufNew(0))), serverWriteIo);
strNew("test"), strNew("test"), ioBufferReadNew(bufNew(0)), serverWriteIo);
bufUsedSet(serverWrite, 0);
@ -376,9 +376,7 @@ testRun(void)
ioWriteFilterGroupSet(
storageFileWriteIo(infoWrite),
ioFilterGroupAdd(
ioFilterGroupNew(),
cipherBlockFilter(
cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("badpassphrase"), NULL))));
ioFilterGroupNew(), cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("badpassphrase"), NULL)));
storagePutNP(
infoWrite,
@ -492,9 +490,9 @@ testRun(void)
{
HARNESS_FORK_CHILD_BEGIN(0, true)
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("child read"), HARNESS_FORK_CHILD_READ(), 2000));
IoRead *read = ioHandleReadNew(strNew("child read"), HARNESS_FORK_CHILD_READ(), 2000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("child write"), HARNESS_FORK_CHILD_WRITE()));
IoWrite *write = ioHandleWriteNew(strNew("child write"), HARNESS_FORK_CHILD_WRITE());
ioWriteOpen(write);
lockAcquire(cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), cfgLockType(), 30000, true);
@ -510,9 +508,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN()
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("parent read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
IoRead *read = ioHandleReadNew(strNew("parent read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("parent write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
IoWrite *write = ioHandleWriteNew(strNew("parent write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
ioWriteOpen(write);
// Wait for the child to acquire the lock

View File

@ -13,8 +13,8 @@ testRun(void)
FUNCTION_HARNESS_VOID();
// Create default storage object for testing
Storage *storageTest = storageDriverPosixInterface(
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
Storage *storageTest = storageDriverPosixNew(
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
// *****************************************************************************************************************************
if (testBegin("lockStopFileName()"))

View File

@ -386,8 +386,8 @@ testRun(void)
// Restore normal stdout
dup2(stdoutSave, STDOUT_FILENO);
Storage *storage = storageDriverPosixInterface(
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL));
Storage *storage = storageDriverPosixNew(
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL);
TEST_RESULT_STR(strPtr(strNewBuf(storageGetNP(storageNewReadNP(storage, stdoutFile)))), generalHelp, " check text");
}

View File

@ -824,8 +824,8 @@ testRun(void)
// Restore normal stdout
dup2(stdoutSave, STDOUT_FILENO);
Storage *storage = storageDriverPosixInterface(
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL));
Storage *storage = storageDriverPosixNew(
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL);
TEST_RESULT_STR(
strPtr(strNewBuf(storageGetNP(storageNewReadNP(storage, stdoutFile)))), "No stanzas exist in the repository.\n",
" check text");

View File

@ -46,9 +46,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN()
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
ioWriteOpen(write);
ProtocolClient *client = protocolClientNew(strNew("test"), PROTOCOL_SERVICE_LOCAL_STR, read, write);

View File

@ -22,8 +22,8 @@ testRun(void)
if (testBegin("cmdRemote()"))
{
// Create default storage object for testing
Storage *storageTest = storageDriverPosixInterface(
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
Storage *storageTest = storageDriverPosixNew(
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
// No remote lock required
// -------------------------------------------------------------------------------------------------------------------------
@ -46,9 +46,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN()
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
ioWriteOpen(write);
ProtocolClient *client = protocolClientNew(strNew("test"), PROTOCOL_SERVICE_REMOTE_STR, read, write);
@ -80,9 +80,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN()
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
ioWriteOpen(write);
ProtocolClient *client = NULL;
@ -116,9 +116,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN()
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
ioWriteOpen(write);
TEST_ERROR(
@ -151,9 +151,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN()
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
ioWriteOpen(write);
ProtocolClient *client = NULL;

View File

@ -10,15 +10,15 @@ Test Gzip
Compress data
***********************************************************************************************************************************/
static Buffer *
testCompress(GzipCompress *compress, Buffer *decompressed, size_t inputSize, size_t outputSize)
testCompress(IoFilter *compress, Buffer *decompressed, size_t inputSize, size_t outputSize)
{
Buffer *compressed = bufNew(1024 * 1024);
size_t inputTotal = 0;
ioBufferSizeSet(outputSize);
IoFilterGroup *filterGroup = ioFilterGroupNew();
ioFilterGroupAdd(filterGroup, gzipCompressFilter(compress));
IoWrite *write = ioBufferWriteIo(ioBufferWriteNew(compressed));
ioFilterGroupAdd(filterGroup, compress);
IoWrite *write = ioBufferWriteNew(compressed);
ioWriteFilterGroupSet(write, filterGroup);
ioWriteOpen(write);
@ -37,7 +37,7 @@ testCompress(GzipCompress *compress, Buffer *decompressed, size_t inputSize, siz
}
ioWriteClose(write);
gzipCompressFree(compress);
gzipCompressFree(ioFilterDriver(compress));
return compressed;
}
@ -46,15 +46,15 @@ testCompress(GzipCompress *compress, Buffer *decompressed, size_t inputSize, siz
Decompress data
***********************************************************************************************************************************/
static Buffer *
testDecompress(GzipDecompress *decompress, Buffer *compressed, size_t inputSize, size_t outputSize)
testDecompress(IoFilter *decompress, Buffer *compressed, size_t inputSize, size_t outputSize)
{
Buffer *decompressed = bufNew(1024 * 1024);
Buffer *output = bufNew(outputSize);
ioBufferSizeSet(inputSize);
IoFilterGroup *filterGroup = ioFilterGroupNew();
ioFilterGroupAdd(filterGroup, gzipDecompressFilter(decompress));
IoRead *read = ioBufferReadIo(ioBufferReadNew(compressed));
ioFilterGroupAdd(filterGroup, decompress);
IoRead *read = ioBufferReadNew(compressed);
ioReadFilterGroupSet(read, filterGroup);
ioReadOpen(read);
@ -67,7 +67,7 @@ testDecompress(GzipDecompress *decompress, Buffer *compressed, size_t inputSize,
ioReadClose(read);
bufFree(output);
gzipDecompressFree(decompress);
gzipDecompressFree(ioFilterDriver(decompress));
return decompressed;
}
@ -164,13 +164,15 @@ testRun(void)
// *****************************************************************************************************************************
if (testBegin("gzipDecompressToLog() and gzipCompressToLog()"))
{
GzipDecompress *decompress = gzipDecompressNew(false);
GzipDecompress *decompress = (GzipDecompress *)ioFilterDriver(gzipDecompressNew(false));
TEST_RESULT_STR(strPtr(gzipDecompressToLog(decompress)), "{inputSame: false, done: false, availIn: 0}", "format object");
decompress->inputSame = true;
decompress->done = true;
TEST_RESULT_STR(strPtr(gzipDecompressToLog(decompress)), "{inputSame: true, done: true, availIn: 0}", "format object");
gzipDecompressFree(decompress);
}
FUNCTION_HARNESS_RESULT_VOID();

View File

@ -8,7 +8,6 @@ Data for testing
***********************************************************************************************************************************/
#define TEST_CIPHER "aes-256-cbc"
#define TEST_PASS "areallybadpassphrase"
#define TEST_PASS_SIZE strlen(TEST_PASS)
#define TEST_PLAINTEXT "plaintext"
#define TEST_BUFFER_SIZE 256
@ -78,21 +77,21 @@ testRun(void)
// Cipher and digest errors
// -------------------------------------------------------------------------------------------------------------------------
TEST_ERROR(
cipherBlockNewC(
cipherModeEncrypt, BOGUS_STR, (unsigned char *)TEST_PASS, TEST_PASS_SIZE, NULL), AssertError,
"unable to load cipher 'BOGUS'");
cipherBlockNew(
cipherModeEncrypt, cipherTypeNone, BUFSTRZ(TEST_PASS), NULL), AssertError,
"unable to load cipher 'none'");
TEST_ERROR(
cipherBlockNew(
cipherModeEncrypt, cipherTypeAes256Cbc, testPass, strNew(BOGUS_STR)), AssertError, "unable to load digest 'BOGUS'");
// Initialization of object
// -------------------------------------------------------------------------------------------------------------------------
CipherBlock *cipherBlock = cipherBlockNewC(
cipherModeEncrypt, TEST_CIPHER, (unsigned char *)TEST_PASS, TEST_PASS_SIZE, NULL);
TEST_RESULT_STR(memContextName(cipherBlock->memContext), "cipherBlock", "mem context name is valid");
CipherBlock *cipherBlock = (CipherBlock *)ioFilterDriver(
cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRZ(TEST_PASS), NULL));
TEST_RESULT_STR(memContextName(cipherBlock->memContext), "CipherBlock", "mem context name is valid");
TEST_RESULT_INT(cipherBlock->mode, cipherModeEncrypt, "mode is valid");
TEST_RESULT_INT(cipherBlock->passSize, TEST_PASS_SIZE, "passphrase size is valid");
TEST_RESULT_BOOL(memcmp(cipherBlock->pass, TEST_PASS, TEST_PASS_SIZE) == 0, true, "passphrase is valid");
TEST_RESULT_INT(cipherBlock->passSize, strlen(TEST_PASS), "passphrase size is valid");
TEST_RESULT_BOOL(memcmp(cipherBlock->pass, TEST_PASS, strlen(TEST_PASS)) == 0, true, "passphrase is valid");
TEST_RESULT_BOOL(cipherBlock->saltDone, false, "salt done is false");
TEST_RESULT_BOOL(cipherBlock->processDone, false, "process done is false");
TEST_RESULT_INT(cipherBlock->headerSize, 0, "header size is 0");
@ -107,11 +106,11 @@ testRun(void)
// -------------------------------------------------------------------------------------------------------------------------
Buffer *encryptBuffer = bufNew(TEST_BUFFER_SIZE);
CipherBlock *blockEncrypt = cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, testPass, NULL);
IoFilter *blockEncryptFilter = cipherBlockFilter(blockEncrypt);
IoFilter *blockEncryptFilter = cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, testPass, NULL);
CipherBlock *blockEncrypt = (CipherBlock *)ioFilterDriver(blockEncryptFilter);
TEST_RESULT_INT(
cipherBlockProcessSizeC(blockEncrypt, strlen(TEST_PLAINTEXT)),
cipherBlockProcessSize(blockEncrypt, strlen(TEST_PLAINTEXT)),
strlen(TEST_PLAINTEXT) + EVP_MAX_BLOCK_LENGTH + CIPHER_BLOCK_MAGIC_SIZE + PKCS5_SALT_LEN, "check process size");
bufLimitSet(encryptBuffer, CIPHER_BLOCK_MAGIC_SIZE);
@ -129,7 +128,7 @@ testRun(void)
TEST_RESULT_INT(bufUsed(encryptBuffer), CIPHER_BLOCK_HEADER_SIZE, "cipher size is header len");
TEST_RESULT_INT(
cipherBlockProcessSizeC(blockEncrypt, strlen(TEST_PLAINTEXT)),
cipherBlockProcessSize(blockEncrypt, strlen(TEST_PLAINTEXT)),
strlen(TEST_PLAINTEXT) + EVP_MAX_BLOCK_LENGTH, "check process size");
bufLimitSet(
@ -157,11 +156,11 @@ testRun(void)
// -------------------------------------------------------------------------------------------------------------------------
Buffer *decryptBuffer = bufNew(TEST_BUFFER_SIZE);
CipherBlock *blockDecrypt = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
IoFilter *blockDecryptFilter = cipherBlockFilter(blockDecrypt);
IoFilter *blockDecryptFilter = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
CipherBlock *blockDecrypt = (CipherBlock *)ioFilterDriver(blockDecryptFilter);
TEST_RESULT_INT(
cipherBlockProcessSizeC(blockDecrypt, bufUsed(encryptBuffer)), bufUsed(encryptBuffer) + EVP_MAX_BLOCK_LENGTH,
cipherBlockProcessSize(blockDecrypt, bufUsed(encryptBuffer)), bufUsed(encryptBuffer) + EVP_MAX_BLOCK_LENGTH,
"check process size");
ioFilterProcessInOut(blockDecryptFilter, encryptBuffer, decryptBuffer);
@ -176,8 +175,8 @@ testRun(void)
// Decrypt in small chunks to test buffering
// -------------------------------------------------------------------------------------------------------------------------
blockDecrypt = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
blockDecryptFilter = cipherBlockFilter(blockDecrypt);
blockDecryptFilter = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
blockDecrypt = (CipherBlock *)ioFilterDriver(blockDecryptFilter);
bufUsedZero(decryptBuffer);
@ -216,8 +215,8 @@ testRun(void)
// Encrypt zero byte file and decrypt it
// -------------------------------------------------------------------------------------------------------------------------
blockEncrypt = cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, testPass, NULL);
blockEncryptFilter = cipherBlockFilter(blockEncrypt);
blockEncryptFilter = cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, testPass, NULL);
blockEncrypt = (CipherBlock *)ioFilterDriver(blockEncryptFilter);
bufUsedZero(encryptBuffer);
@ -226,8 +225,8 @@ testRun(void)
cipherBlockFree(blockEncrypt);
blockDecrypt = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
blockDecryptFilter = cipherBlockFilter(blockDecrypt);
blockDecryptFilter = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
blockDecrypt = (CipherBlock *)ioFilterDriver(blockDecryptFilter);
bufUsedZero(decryptBuffer);
@ -240,8 +239,8 @@ testRun(void)
// Invalid cipher header
// -------------------------------------------------------------------------------------------------------------------------
blockDecrypt = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
blockDecryptFilter = cipherBlockFilter(blockDecrypt);
blockDecryptFilter = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
blockDecrypt = (CipherBlock *)ioFilterDriver(blockDecryptFilter);
TEST_ERROR(
ioFilterProcessInOut(blockDecryptFilter, BUFSTRDEF("1234567890123456"), decryptBuffer), CryptoError,
@ -251,8 +250,8 @@ testRun(void)
// Invalid encrypted data cannot be flushed
// -------------------------------------------------------------------------------------------------------------------------
blockDecrypt = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
blockDecryptFilter = cipherBlockFilter(blockDecrypt);
blockDecryptFilter = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
blockDecrypt = (CipherBlock *)ioFilterDriver(blockDecryptFilter);
bufUsedZero(decryptBuffer);
@ -265,8 +264,8 @@ testRun(void)
// File with no header should not flush
// -------------------------------------------------------------------------------------------------------------------------
blockDecrypt = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
blockDecryptFilter = cipherBlockFilter(blockDecrypt);
blockDecryptFilter = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
blockDecrypt = (CipherBlock *)ioFilterDriver(blockDecryptFilter);
bufUsedZero(decryptBuffer);
@ -276,8 +275,8 @@ testRun(void)
// File with header only should error
// -------------------------------------------------------------------------------------------------------------------------
blockDecrypt = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
blockDecryptFilter = cipherBlockFilter(blockDecrypt);
blockDecryptFilter = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
blockDecrypt = (CipherBlock *)ioFilterDriver(blockDecryptFilter);
bufUsedZero(decryptBuffer);
@ -290,43 +289,44 @@ testRun(void)
// *****************************************************************************************************************************
if (testBegin("CryptoHash"))
{
CryptoHash *hash = NULL;
IoFilter *hashFilter = NULL;
IoFilter *hash = NULL;
TEST_ERROR(cryptoHashNew(strNew(BOGUS_STR)), AssertError, "unable to load hash 'BOGUS'");
// -------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN(hash, cryptoHashNew(strNew(HASH_TYPE_SHA1)), "create sha1 hash");
TEST_RESULT_VOID(cryptoHashFree(hash), " free hash");
TEST_RESULT_VOID(cryptoHashFree(NULL), " free null hash");
TEST_RESULT_VOID(ioFilterFree(hash), " free hash");
// -------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN(hash, cryptoHashNew(strNew(HASH_TYPE_SHA1)), "create sha1 hash");
TEST_RESULT_STR(strPtr(bufHex(cryptoHash(hash))), "da39a3ee5e6b4b0d3255bfef95601890afd80709", " check empty hash");
TEST_RESULT_STR(strPtr(bufHex(cryptoHash(hash))), "da39a3ee5e6b4b0d3255bfef95601890afd80709", " check empty hash again");
TEST_RESULT_VOID(cryptoHashFree(hash), " free hash");
TEST_RESULT_STR(
strPtr(bufHex(cryptoHash((CryptoHash *)ioFilterDriver(hash)))), "da39a3ee5e6b4b0d3255bfef95601890afd80709",
" check empty hash");
TEST_RESULT_STR(
strPtr(bufHex(cryptoHash((CryptoHash *)ioFilterDriver(hash)))), "da39a3ee5e6b4b0d3255bfef95601890afd80709",
" check empty hash again");
TEST_RESULT_VOID(ioFilterFree(hash), " free hash");
// -------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN(hash, cryptoHashNew(strNew(HASH_TYPE_SHA1)), "create sha1 hash");
TEST_ASSIGN(hashFilter, cryptoHashFilter(hash), "create sha1 hash");
TEST_RESULT_VOID(cryptoHashProcessC(hash, (const unsigned char *)"1", 1), " add 1");
TEST_RESULT_VOID(cryptoHashProcessStr(hash, strNew("2")), " add 2");
TEST_RESULT_VOID(ioFilterProcessIn(hashFilter, BUFSTRDEF("3")), " add 3");
TEST_RESULT_VOID(ioFilterProcessIn(hashFilter, BUFSTRDEF("4")), " add 4");
TEST_RESULT_VOID(ioFilterProcessIn(hashFilter, BUFSTRDEF("5")), " add 5");
TEST_RESULT_VOID(ioFilterProcessIn(hash, BUFSTRZ("1")), " add 1");
TEST_RESULT_VOID(ioFilterProcessIn(hash, BUFSTR(strNew("2"))), " add 2");
TEST_RESULT_VOID(ioFilterProcessIn(hash, BUFSTRDEF("3")), " add 3");
TEST_RESULT_VOID(ioFilterProcessIn(hash, BUFSTRDEF("4")), " add 4");
TEST_RESULT_VOID(ioFilterProcessIn(hash, BUFSTRDEF("5")), " add 5");
TEST_RESULT_STR(
strPtr(varStr(ioFilterResult(hashFilter))), "8cb2237d0679ca88db6464eac60da96345513964", " check small hash");
TEST_RESULT_VOID(cryptoHashFree(hash), " free hash");
strPtr(varStr(ioFilterResult(hash))), "8cb2237d0679ca88db6464eac60da96345513964", " check small hash");
TEST_RESULT_VOID(ioFilterFree(hash), " free hash");
// -------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN(hash, cryptoHashNew(strNew(HASH_TYPE_MD5)), "create md5 hash");
TEST_RESULT_STR(strPtr(bufHex(cryptoHash(hash))), "d41d8cd98f00b204e9800998ecf8427e", " check empty hash");
TEST_RESULT_STR(strPtr(varStr(ioFilterResult(hash))), "d41d8cd98f00b204e9800998ecf8427e", " check empty hash");
// -------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN(hash, cryptoHashNew(strNew(HASH_TYPE_SHA256)), "create sha256 hash");
TEST_RESULT_STR(
strPtr(bufHex(cryptoHash(hash))), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
strPtr(varStr(ioFilterResult(hash))), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
" check empty hash");
// -------------------------------------------------------------------------------------------------------------------------
@ -334,8 +334,8 @@ testRun(void)
strPtr(bufHex(cryptoHashOne(strNew(HASH_TYPE_SHA1), BUFSTRDEF("12345")))), "8cb2237d0679ca88db6464eac60da96345513964",
" check small hash");
TEST_RESULT_STR(
strPtr(bufHex(cryptoHashOneStr(strNew(HASH_TYPE_SHA1), strNew("12345")))), "8cb2237d0679ca88db6464eac60da96345513964",
" check small hash");
strPtr(bufHex(cryptoHashOne(strNew(HASH_TYPE_SHA1), BUFSTRDEF("")))), "da39a3ee5e6b4b0d3255bfef95601890afd80709",
" check empty hash");
// -------------------------------------------------------------------------------------------------------------------------
TEST_RESULT_STR(

View File

@ -11,8 +11,8 @@ testRun(void)
{
FUNCTION_HARNESS_VOID();
Storage *storageTest = storageDriverPosixInterface(
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
Storage *storageTest = storageDriverPosixNew(
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
// *****************************************************************************************************************************
if (testBegin("iniNew() and iniFree()"))

View File

@ -18,10 +18,13 @@ testIoReadOpen(void *driver)
}
static size_t
testIoRead(void *driver, Buffer *buffer)
testIoRead(void *driver, Buffer *buffer, bool block)
{
ASSERT(driver == (void *)999);
(void)block;
bufCat(buffer, BUFSTRDEF("Z"));
return 1;
}
@ -69,16 +72,16 @@ typedef struct IoTestFilterSize
{
MemContext *memContext;
size_t size;
IoFilter *filter;
} IoTestFilterSize;
static void
ioTestFilterSizeProcess(IoTestFilterSize *this, const Buffer *buffer)
ioTestFilterSizeProcess(THIS_VOID, const Buffer *buffer)
{
THIS(IoTestFilterSize);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM_P(VOID, this);
FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_PARAM(STRING, ioFilterType(this->filter));
FUNCTION_LOG_PARAM(SIZE, this->size);
FUNCTION_LOG_END();
@ -90,25 +93,25 @@ ioTestFilterSizeProcess(IoTestFilterSize *this, const Buffer *buffer)
FUNCTION_LOG_RETURN_VOID();
}
static const Variant *
ioTestFilterSizeResult(IoTestFilterSize *this)
static Variant *
ioTestFilterSizeResult(THIS_VOID)
{
THIS(IoTestFilterSize);
return varNewUInt64(this->size);
}
static IoTestFilterSize *
static IoFilter *
ioTestFilterSizeNew(const char *type)
{
IoTestFilterSize *this = NULL;
IoFilter *this = NULL;
MEM_CONTEXT_NEW_BEGIN("IoTestFilterSize")
{
this = memNew(sizeof(IoTestFilterSize));
this->memContext = MEM_CONTEXT_NEW();
IoTestFilterSize *driver = memNew(sizeof(IoTestFilterSize));
driver->memContext = MEM_CONTEXT_NEW();
this->filter = ioFilterNewP(
strNew(type), this, .in = (IoFilterInterfaceProcessIn)ioTestFilterSizeProcess,
.result = (IoFilterInterfaceResult)ioTestFilterSizeResult);
this = ioFilterNewP(strNew(type), driver, .in = ioTestFilterSizeProcess, .result = ioTestFilterSizeResult);
}
MEM_CONTEXT_NEW_END();
@ -127,12 +130,13 @@ typedef struct IoTestFilterMultiply
Buffer *multiplyBuffer;
unsigned int multiplier;
IoFilter *bufferFilter;
IoFilter *filter;
} IoTestFilterMultiply;
static void
ioTestFilterMultiplyProcess(IoTestFilterMultiply *this, const Buffer *input, Buffer *output)
ioTestFilterMultiplyProcess(THIS_VOID, const Buffer *input, Buffer *output)
{
THIS(IoTestFilterMultiply);
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM_P(VOID, this);
FUNCTION_LOG_PARAM(BUFFER, input);
@ -183,35 +187,38 @@ ioTestFilterMultiplyProcess(IoTestFilterMultiply *this, const Buffer *input, Buf
}
static bool
ioTestFilterMultiplyDone(IoTestFilterMultiply *this)
ioTestFilterMultiplyDone(const THIS_VOID)
{
THIS(const IoTestFilterMultiply);
return this->flushTotal == 0;
}
static bool
ioTestFilterMultiplyInputSame(IoTestFilterMultiply *this)
ioTestFilterMultiplyInputSame(const THIS_VOID)
{
THIS(const IoTestFilterMultiply);
return ioFilterInputSame(this->bufferFilter);
}
static IoTestFilterMultiply *
static IoFilter *
ioTestFilterMultiplyNew(const char *type, unsigned int multiplier, unsigned int flushTotal, char flushChar)
{
IoTestFilterMultiply *this = NULL;
IoFilter *this = NULL;
MEM_CONTEXT_NEW_BEGIN("IoTestFilterMultiply")
{
this = memNew(sizeof(IoTestFilterMultiply));
this->memContext = MEM_CONTEXT_NEW();
this->bufferFilter = ioBufferFilter(ioBufferNew());
this->multiplier = multiplier;
this->flushTotal = flushTotal;
this->flushChar = flushChar;
IoTestFilterMultiply *driver = memNew(sizeof(IoTestFilterMultiply));
driver->memContext = MEM_CONTEXT_NEW();
driver->bufferFilter = ioBufferNew();
driver->multiplier = multiplier;
driver->flushTotal = flushTotal;
driver->flushChar = flushChar;
this->filter = ioFilterNewP(
strNew(type), this, .done = (IoFilterInterfaceDone)ioTestFilterMultiplyDone,
.inOut = (IoFilterInterfaceProcessInOut)ioTestFilterMultiplyProcess,
.inputSame = (IoFilterInterfaceInputSame)ioTestFilterMultiplyInputSame);
this = ioFilterNewP(
strNew(type), driver, .done = ioTestFilterMultiplyDone, .inOut = ioTestFilterMultiplyProcess,
.inputSame = ioTestFilterMultiplyInputSame);
}
MEM_CONTEXT_NEW_END();
@ -242,17 +249,13 @@ testRun(void)
ioBufferSizeSet(2);
TEST_ASSIGN(
read,
ioReadNewP((void *)998, .close = (IoReadInterfaceClose)testIoReadClose, .open = (IoReadInterfaceOpen)testIoReadOpen,
.read = (IoReadInterfaceRead)testIoRead),
read, ioReadNewP((void *)998, .close = testIoReadClose, .open = testIoReadOpen, .read = testIoRead),
"create io read object");
TEST_RESULT_BOOL(ioReadOpen(read), false, " open io object");
TEST_ASSIGN(
read,
ioReadNewP((void *)999, .close = (IoReadInterfaceClose)testIoReadClose, .open = (IoReadInterfaceOpen)testIoReadOpen,
.read = (IoReadInterfaceRead)testIoRead),
read, ioReadNewP((void *)999, .close = testIoReadClose, .open = testIoReadOpen, .read = testIoRead),
"create io read object");
TEST_RESULT_BOOL(ioReadOpen(read), true, " open io object");
@ -266,81 +269,71 @@ testRun(void)
// Read a zero-length buffer to be sure it is not passed on to the filter group
// -------------------------------------------------------------------------------------------------------------------------
IoBufferRead *bufferRead = NULL;
IoRead *bufferRead = NULL;
ioBufferSizeSet(2);
buffer = bufNew(2);
Buffer *bufferOriginal = bufNew(0);
TEST_ASSIGN(bufferRead, ioBufferReadNew(bufferOriginal), "create empty buffer read object");
TEST_RESULT_BOOL(ioReadOpen(ioBufferReadIo(bufferRead)), true, " open");
TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), false, " not eof");
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 0, " read 0 bytes");
TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), true, " now eof");
TEST_RESULT_BOOL(ioReadOpen(bufferRead), true, " open");
TEST_RESULT_BOOL(ioReadEof(bufferRead), false, " not eof");
TEST_RESULT_SIZE(ioRead(bufferRead, buffer), 0, " read 0 bytes");
TEST_RESULT_BOOL(ioReadEof(bufferRead), true, " now eof");
// -------------------------------------------------------------------------------------------------------------------------
ioBufferSizeSet(2);
buffer = bufNew(2);
bufferOriginal = bufNewC("123", 3);
MEM_CONTEXT_TEMP_BEGIN()
{
TEST_ASSIGN(bufferRead, ioBufferReadNew(bufferOriginal), "create buffer read object");
TEST_RESULT_VOID(ioBufferReadMove(bufferRead, MEM_CONTEXT_OLD()), " move object to new context");
TEST_RESULT_VOID(ioBufferReadMove(NULL, MEM_CONTEXT_OLD()), " move NULL object to new context");
}
MEM_CONTEXT_TEMP_END();
IoFilterGroup *filterGroup = NULL;
TEST_ASSIGN(filterGroup, ioFilterGroupNew(), " create new filter group");
IoSize *sizeFilter = ioSizeNew();
TEST_RESULT_PTR(ioFilterGroupAdd(filterGroup, ioSizeFilter(sizeFilter)), filterGroup, " add filter to filter group");
IoFilter *sizeFilter = ioSizeNew();
TEST_RESULT_PTR(ioFilterGroupAdd(filterGroup, sizeFilter), filterGroup, " add filter to filter group");
TEST_RESULT_VOID(
ioFilterGroupAdd(filterGroup, ioTestFilterMultiplyNew("double", 2, 1, 'X')->filter), " add filter to filter group");
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, ioSizeFilter(ioSizeNew())), " add filter to filter group");
IoBuffer *bufferFilter = ioBufferNew();
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, ioBufferFilter(bufferFilter)), " add filter to filter group");
TEST_RESULT_VOID(ioReadFilterGroupSet(ioBufferReadIo(bufferRead), filterGroup), " add filter group to read io");
ioFilterGroupAdd(filterGroup, ioTestFilterMultiplyNew("double", 2, 1, 'X')), " add filter to filter group");
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, ioSizeNew()), " add filter to filter group");
IoFilter *bufferFilter = ioBufferNew();
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, bufferFilter), " add filter to filter group");
TEST_RESULT_VOID(ioReadFilterGroupSet(bufferRead, filterGroup), " add filter group to read io");
TEST_RESULT_PTR(ioFilterMove(NULL, memContextTop()), NULL, " move NULL filter to top context");
TEST_RESULT_BOOL(ioReadOpen(ioBufferReadIo(bufferRead)), true, " open");
TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), false, " not eof");
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 2, " read 2 bytes");
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 0, " read 0 bytes (full buffer)");
TEST_RESULT_BOOL(ioReadOpen(bufferRead), true, " open");
TEST_RESULT_BOOL(ioReadEof(bufferRead), false, " not eof");
TEST_RESULT_SIZE(ioRead(bufferRead, buffer), 2, " read 2 bytes");
TEST_RESULT_SIZE(ioRead(bufferRead, buffer), 0, " read 0 bytes (full buffer)");
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "11", " check read");
TEST_RESULT_STR(strPtr(ioFilterType(ioSizeFilter(sizeFilter))), "size", "check filter type");
TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), false, " not eof");
TEST_RESULT_STR(strPtr(ioFilterType(sizeFilter)), "size", "check filter type");
TEST_RESULT_BOOL(ioReadEof(bufferRead), false, " not eof");
TEST_RESULT_VOID(bufUsedZero(buffer), " zero buffer");
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 2, " read 2 bytes");
TEST_RESULT_SIZE(ioRead(bufferRead, buffer), 2, " read 2 bytes");
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "22", " check read");
TEST_ASSIGN(buffer, bufNew(3), "change output buffer size to 3");
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 3, " read 3 bytes");
TEST_RESULT_SIZE(ioRead(bufferRead, buffer), 3, " read 3 bytes");
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "33X", " check read");
TEST_RESULT_VOID(bufUsedZero(buffer), " zero buffer");
TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), true, " eof");
TEST_RESULT_BOOL(ioBufferRead(bufferRead, buffer, true), 0, " eof from driver");
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 0, " read 0 bytes");
TEST_RESULT_VOID(ioReadClose(ioBufferReadIo(bufferRead)), " close buffer read object");
TEST_RESULT_BOOL(ioReadEof(bufferRead), true, " eof");
TEST_RESULT_BOOL(ioBufferRead(ioReadDriver(bufferRead), buffer, true), 0, " eof from driver");
TEST_RESULT_SIZE(ioRead(bufferRead, buffer), 0, " read 0 bytes");
TEST_RESULT_VOID(ioReadClose(bufferRead), " close buffer read object");
TEST_RESULT_PTR(ioReadFilterGroup(ioBufferReadIo(bufferRead)), filterGroup, " check filter group");
TEST_RESULT_PTR(ioReadFilterGroup(bufferRead), filterGroup, " check filter group");
TEST_RESULT_UINT(
varUInt64(varLstGet(varVarLst(ioFilterGroupResult(filterGroup, ioFilterType(ioSizeFilter(sizeFilter)))), 0)), 3,
varUInt64(varLstGet(varVarLst(ioFilterGroupResult(filterGroup, ioFilterType(sizeFilter))), 0)), 3,
" check filter result");
TEST_RESULT_PTR(ioFilterGroupResult(filterGroup, strNew("double")), NULL, " check filter result is NULL");
TEST_RESULT_UINT(
varUInt64(varLstGet(varVarLst(ioFilterGroupResult(filterGroup, ioFilterType(ioSizeFilter(sizeFilter)))), 1)), 7,
varUInt64(varLstGet(varVarLst(ioFilterGroupResult(filterGroup, ioFilterType(sizeFilter))), 1)), 7,
" check filter result");
TEST_RESULT_VOID(ioBufferReadFree(bufferRead), " free buffer read object");
TEST_RESULT_VOID(ioBufferReadFree(NULL), " free NULL buffer read object");
TEST_RESULT_PTR(ioFilterDriver(bufferFilter), bufferFilter->driver, " check filter driver");
TEST_RESULT_PTR(ioFilterInterface(bufferFilter), &bufferFilter->interface, " check filter interface");
TEST_RESULT_VOID(ioSizeFree(sizeFilter), " free size filter object");
TEST_RESULT_VOID(ioSizeFree(NULL), " free null size filter object");
TEST_RESULT_VOID(ioBufferFree(bufferFilter), " free buffer filter object");
TEST_RESULT_VOID(ioBufferFree(NULL), " free null buffer filter object");
TEST_RESULT_VOID(ioFilterFree(bufferFilter), " free buffer filter");
TEST_RESULT_VOID(ioFilterFree(NULL), " free NULL filter");
TEST_RESULT_VOID(ioFilterGroupFree(filterGroup), " free filter group object");
TEST_RESULT_VOID(ioFilterGroupFree(NULL), " free NULL filter group object");
@ -348,7 +341,7 @@ testRun(void)
// Mixed line and buffer read
// -------------------------------------------------------------------------------------------------------------------------
ioBufferSizeSet(5);
read = ioBufferReadIo(ioBufferReadNew(BUFSTRDEF("AAA123\n1234\n\n12\nBDDDEFF")));
read = ioBufferReadNew(BUFSTRDEF("AAA123\n1234\n\n12\nBDDDEFF"));
ioReadOpen(read);
buffer = bufNew(3);
@ -391,7 +384,7 @@ testRun(void)
// Error if buffer is full and there is no linefeed
ioBufferSizeSet(10);
read = ioBufferReadIo(ioBufferReadNew(BUFSTRDEF("0123456789")));
read = ioBufferReadNew(BUFSTRDEF("0123456789"));
ioReadOpen(read);
TEST_ERROR(ioReadLine(read), FileReadError, "unable to find line in 10 byte buffer");
@ -400,9 +393,9 @@ testRun(void)
ioBufferSizeSet(8);
bufferRead = ioBufferReadNew(BUFSTRDEF("a test string"));
ioReadOpen(ioBufferReadIo(bufferRead));
ioReadOpen(bufferRead);
TEST_RESULT_STR(strPtr(strNewBuf(ioReadBuf(ioBufferReadIo(bufferRead)))), "a test string", "read into buffer");
TEST_RESULT_STR(strPtr(strNewBuf(ioReadBuf(bufferRead))), "a test string", "read into buffer");
}
// *****************************************************************************************************************************
@ -412,10 +405,7 @@ testRun(void)
ioBufferSizeSet(3);
TEST_ASSIGN(
write,
ioWriteNewP(
(void *)999, .close = (IoWriteInterfaceClose)testIoWriteClose, .open = (IoWriteInterfaceOpen)testIoWriteOpen,
.write = (IoWriteInterfaceWrite)testIoWrite),
write, ioWriteNewP((void *)999, .close = testIoWriteClose, .open = testIoWriteOpen, .write = testIoWrite),
"create io write object");
TEST_RESULT_VOID(ioWriteOpen(write), " open io object");
@ -429,50 +419,40 @@ testRun(void)
// -------------------------------------------------------------------------------------------------------------------------
ioBufferSizeSet(3);
IoBufferWrite *bufferWrite = NULL;
IoWrite *bufferWrite = NULL;
Buffer *buffer = bufNew(0);
MEM_CONTEXT_TEMP_BEGIN()
{
TEST_ASSIGN(bufferWrite, ioBufferWriteNew(buffer), "create buffer write object");
TEST_RESULT_VOID(ioBufferWriteMove(bufferWrite, MEM_CONTEXT_OLD()), " move object to new context");
TEST_RESULT_VOID(ioBufferWriteMove(NULL, MEM_CONTEXT_OLD()), " move NULL object to new context");
}
MEM_CONTEXT_TEMP_END();
IoFilterGroup *filterGroup = NULL;
TEST_ASSIGN(filterGroup, ioFilterGroupNew(), " create new filter group");
IoSize *sizeFilter = ioSizeNew();
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, ioSizeFilter(sizeFilter)), " add filter to filter group");
IoFilter *sizeFilter = ioSizeNew();
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, sizeFilter), " add filter to filter group");
TEST_RESULT_VOID(
ioFilterGroupAdd(filterGroup, ioTestFilterMultiplyNew("double", 2, 3, 'X')->filter), " add filter to filter group");
ioFilterGroupAdd(filterGroup, ioTestFilterMultiplyNew("double", 2, 3, 'X')), " add filter to filter group");
TEST_RESULT_VOID(
ioFilterGroupAdd(filterGroup, ioTestFilterMultiplyNew("single", 1, 1, 'Y')->filter),
ioFilterGroupAdd(filterGroup, ioTestFilterMultiplyNew("single", 1, 1, 'Y')),
" add filter to filter group");
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, ioTestFilterSizeNew("size2")->filter), " add filter to filter group");
TEST_RESULT_VOID(ioWriteFilterGroupSet(ioBufferWriteIo(bufferWrite), filterGroup), " add filter group to write io");
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, ioTestFilterSizeNew("size2")), " add filter to filter group");
TEST_RESULT_VOID(ioWriteFilterGroupSet(bufferWrite, filterGroup), " add filter group to write io");
TEST_RESULT_VOID(ioWriteOpen(ioBufferWriteIo(bufferWrite)), " open buffer write object");
TEST_RESULT_VOID(ioWriteLine(ioBufferWriteIo(bufferWrite), BUFSTRDEF("AB")), " write line");
TEST_RESULT_VOID(ioWrite(ioBufferWriteIo(bufferWrite), bufNew(0)), " write 0 bytes");
TEST_RESULT_VOID(ioWrite(ioBufferWriteIo(bufferWrite), NULL), " write 0 bytes");
TEST_RESULT_VOID(ioWriteOpen(bufferWrite), " open buffer write object");
TEST_RESULT_VOID(ioWriteLine(bufferWrite, BUFSTRDEF("AB")), " write line");
TEST_RESULT_VOID(ioWrite(bufferWrite, bufNew(0)), " write 0 bytes");
TEST_RESULT_VOID(ioWrite(bufferWrite, NULL), " write 0 bytes");
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "AABB\n\n", " check write");
TEST_RESULT_VOID(ioWriteStr(ioBufferWriteIo(bufferWrite), STRDEF("Z")), " write string");
TEST_RESULT_VOID(ioWriteStr(bufferWrite, STRDEF("Z")), " write string");
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "AABB\n\n", " no change because output buffer is not full");
TEST_RESULT_VOID(ioWriteStr(ioBufferWriteIo(bufferWrite), STRDEF("12345")), " write bytes");
TEST_RESULT_VOID(ioWriteStr(bufferWrite, STRDEF("12345")), " write bytes");
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "AABB\n\nZZ1122334455", " check write");
TEST_RESULT_VOID(ioWriteClose(ioBufferWriteIo(bufferWrite)), " close buffer write object");
TEST_RESULT_VOID(ioWriteClose(bufferWrite), " close buffer write object");
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "AABB\n\nZZ1122334455XXXY", " check write after close");
TEST_RESULT_PTR(ioWriteFilterGroup(ioBufferWriteIo(bufferWrite)), filterGroup, " check filter group");
TEST_RESULT_PTR(ioWriteFilterGroup(bufferWrite), filterGroup, " check filter group");
TEST_RESULT_UINT(
varUInt64(ioFilterGroupResult(filterGroup, ioFilterType(ioSizeFilter(sizeFilter)))), 9, " check filter result");
varUInt64(ioFilterGroupResult(filterGroup, ioFilterType(sizeFilter))), 9, " check filter result");
TEST_RESULT_UINT(varUInt64(ioFilterGroupResult(filterGroup, strNew("size2"))), 22, " check filter result");
TEST_RESULT_VOID(ioBufferWriteFree(bufferWrite), " free buffer write object");
TEST_RESULT_VOID(ioBufferWriteFree(NULL), " free NULL buffer write object");
}
// *****************************************************************************************************************************
@ -484,88 +464,65 @@ testRun(void)
{
HARNESS_FORK_CHILD_BEGIN(0, true)
{
IoHandleWrite *write = NULL;
IoWrite *write = NULL;
MEM_CONTEXT_TEMP_BEGIN()
{
TEST_RESULT_VOID(ioHandleWriteMove(NULL, MEM_CONTEXT_OLD()), "move null write");
TEST_ASSIGN(
write,
ioHandleWriteMove(ioHandleWriteNew(strNew("write test"), HARNESS_FORK_CHILD_WRITE()), MEM_CONTEXT_OLD()),
"move write");
}
MEM_CONTEXT_TEMP_END();
ioWriteOpen(ioHandleWriteIo(write));
TEST_RESULT_INT(ioWriteHandle(ioHandleWriteIo(write)), write->handle, "check write handle");
TEST_ASSIGN(write, ioHandleWriteNew(strNew("write test"), HARNESS_FORK_CHILD_WRITE()), "move write");
ioWriteOpen(write);
TEST_RESULT_INT(
ioWriteHandle(write), ((IoHandleWrite *)ioWriteDriver(write))->handle, "check write handle");
TEST_RESULT_PTR(ioWriteDriver(write), write->driver, "check write driver");
TEST_RESULT_PTR(ioWriteInterface(write), &write->interface, "check write interface");
// Write a line to be read
TEST_RESULT_VOID(ioWriteStrLine(ioHandleWriteIo(write), strNew("test string 1")), "write test string");
ioWriteFlush(ioHandleWriteIo(write));
ioWriteFlush(ioHandleWriteIo(write));
TEST_RESULT_VOID(ioWriteStrLine(write, strNew("test string 1")), "write test string");
ioWriteFlush(write);
ioWriteFlush(write);
// Sleep so the other side will timeout
const Buffer *buffer = BUFSTRDEF("12345678");
TEST_RESULT_VOID(ioWrite(ioHandleWriteIo(write), buffer), "write buffer");
TEST_RESULT_VOID(ioWrite(write, buffer), "write buffer");
sleepMSec(1250);
// Write a buffer in two parts and sleep in the middle so it will be read on the other side in two parts
TEST_RESULT_VOID(ioWrite(ioHandleWriteIo(write), buffer), "write buffer");
TEST_RESULT_VOID(ioWrite(write, buffer), "write buffer");
sleepMSec(500);
TEST_RESULT_VOID(ioWrite(ioHandleWriteIo(write), buffer), "write buffer");
ioWriteFlush(ioHandleWriteIo(write));
// Free object
TEST_RESULT_VOID(ioHandleWriteFree(NULL), "free null write");
TEST_RESULT_VOID(ioHandleWriteFree(write), "free write");
TEST_RESULT_VOID(ioWrite(write, buffer), "write buffer");
ioWriteFlush(write);
}
HARNESS_FORK_CHILD_END();
HARNESS_FORK_PARENT_BEGIN()
{
IoHandleRead *read = NULL;
IoRead *read = ioHandleReadNew(strNew("read test"), HARNESS_FORK_PARENT_READ_PROCESS(0), 1000);
MEM_CONTEXT_TEMP_BEGIN()
{
TEST_RESULT_VOID(ioHandleReadMove(NULL, MEM_CONTEXT_OLD()), "move null read");
TEST_ASSIGN(
read,
ioHandleReadMove(
ioHandleReadNew(strNew("read test"), HARNESS_FORK_PARENT_READ_PROCESS(0), 1000), MEM_CONTEXT_OLD()),
"move read");
}
MEM_CONTEXT_TEMP_END();
ioReadOpen(ioHandleReadIo(read));
TEST_RESULT_INT(ioReadHandle(ioHandleReadIo(read)), read->handle, "check handle");
ioReadOpen(read);
TEST_RESULT_INT(ioReadHandle(read), ((IoHandleRead *)ioReadDriver(read))->handle, "check handle");
TEST_RESULT_PTR(ioReadInterface(read), &read->interface, "check interface");
TEST_RESULT_PTR(ioReadDriver(read), read->driver, "check driver");
// Read a string
TEST_RESULT_STR(strPtr(ioReadLine(ioHandleReadIo(read))), "test string 1", "read test string");
TEST_RESULT_STR(strPtr(ioReadLine(read)), "test string 1", "read test string");
// Only part of the buffer is written before timeout
Buffer *buffer = bufNew(16);
TEST_ERROR(ioRead(ioHandleReadIo(read), buffer), FileReadError, "unable to read data from read test after 1000ms");
TEST_ERROR(ioRead(read, buffer), FileReadError, "unable to read data from read test after 1000ms");
TEST_RESULT_UINT(bufSize(buffer), 16, "buffer is only partially read");
// Read a buffer that is transmitted in two parts with blocking on the read side
buffer = bufNew(16);
bufLimitSet(buffer, 12);
TEST_RESULT_UINT(ioRead(ioHandleReadIo(read), buffer), 12, "read buffer");
TEST_RESULT_UINT(ioRead(read, buffer), 12, "read buffer");
bufLimitClear(buffer);
TEST_RESULT_UINT(ioRead(ioHandleReadIo(read), buffer), 4, "read buffer");
TEST_RESULT_UINT(ioRead(read, buffer), 4, "read buffer");
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "1234567812345678", "check buffer");
// Check EOF
buffer = bufNew(16);
TEST_RESULT_UINT(ioHandleRead(read, buffer, true), 0, "read buffer at eof");
TEST_RESULT_UINT(ioHandleRead(read, buffer, true), 0, "read buffer at eof again");
// Free object
TEST_RESULT_VOID(ioHandleReadFree(NULL), "free null read");
TEST_RESULT_VOID(ioHandleReadFree(read), "free read");
TEST_RESULT_UINT(ioHandleRead(ioReadDriver(read), buffer, true), 0, "read buffer at eof");
TEST_RESULT_UINT(ioHandleRead(ioReadDriver(read), buffer, true), 0, "read buffer at eof again");
}
HARNESS_FORK_PARENT_END();
}

View File

@ -15,8 +15,8 @@ testRun(void)
FUNCTION_HARNESS_VOID();
// Create default storage object for testing
Storage *storageTest = storageDriverPosixInterface(
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
Storage *storageTest = storageDriverPosixNew(
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
// *****************************************************************************************************************************
if (testBegin("lockAcquireFile() and lockReleaseFile()"))

View File

@ -24,9 +24,9 @@ testRun(void)
{
HARNESS_FORK_CHILD_BEGIN(0, true)
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("client read"), HARNESS_FORK_CHILD_READ(), 2000));
IoRead *read = ioHandleReadNew(strNew("client read"), HARNESS_FORK_CHILD_READ(), 2000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("client write"), HARNESS_FORK_CHILD_WRITE()));
IoWrite *write = ioHandleWriteNew(strNew("client write"), HARNESS_FORK_CHILD_WRITE());
ioWriteOpen(write);
StringList *argList = strLstNew();
@ -45,9 +45,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN()
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
ioWriteOpen(write);
ProtocolClient *client = protocolClientNew(strNew("test"), strNew("config"), read, write);

View File

@ -10,8 +10,8 @@ void
testRun(void)
{
// Create default storage object for testing
Storage *storageTest = storageDriverPosixInterface(
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
Storage *storageTest = storageDriverPosixNew(
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
// *****************************************************************************************************************************
if (testBegin("infoNewLoad(), infoFileName(), infoIni()"))
@ -66,8 +66,7 @@ testRun(void)
ioWriteFilterGroupSet(
storageFileWriteIo(infoWrite),
ioFilterGroupAdd(
ioFilterGroupNew(),
cipherBlockFilter(cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("12345678"), NULL))));
ioFilterGroupNew(), cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("12345678"), NULL)));
storageRemoveNP(storageLocalWrite(), fileNameCopy);
storagePutNP(

View File

@ -11,8 +11,8 @@ testRun(void)
{
FUNCTION_HARNESS_VOID();
Storage *storageTest = storageDriverPosixInterface(
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
Storage *storageTest = storageDriverPosixNew(
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
// *****************************************************************************************************************************
if (testBegin("pgVersionFromStr() and pgVersionToStr()"))

View File

@ -62,8 +62,8 @@ testRun(void)
{
FUNCTION_HARNESS_VOID();
Storage *storageTest = storageDriverPosixInterface(
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
Storage *storageTest = storageDriverPosixNew(
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
// *****************************************************************************************************************************
if (testBegin("repoIsLocal()"))
@ -224,9 +224,9 @@ testRun(void)
{
HARNESS_FORK_CHILD_BEGIN(0, true)
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_CHILD_READ(), 2000));
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_CHILD_READ(), 2000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_CHILD_WRITE()));
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_CHILD_WRITE());
ioWriteOpen(write);
// Various bogus greetings
@ -277,9 +277,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN()
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("client read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
IoRead *read = ioHandleReadNew(strNew("client read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("client write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
IoWrite *write = ioHandleWriteNew(strNew("client write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
ioWriteOpen(write);
// Various bogus greetings
@ -353,9 +353,9 @@ testRun(void)
{
HARNESS_FORK_CHILD_BEGIN(0, true)
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("client read"), HARNESS_FORK_CHILD_READ(), 2000));
IoRead *read = ioHandleReadNew(strNew("client read"), HARNESS_FORK_CHILD_READ(), 2000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("client write"), HARNESS_FORK_CHILD_WRITE()));
IoWrite *write = ioHandleWriteNew(strNew("client write"), HARNESS_FORK_CHILD_WRITE());
ioWriteOpen(write);
// Check greeting
@ -405,9 +405,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN()
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
ioWriteOpen(write);
// Send greeting
@ -470,9 +470,9 @@ testRun(void)
// Local 1
HARNESS_FORK_CHILD_BEGIN(0, true)
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_CHILD_READ(), 10000));
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_CHILD_READ(), 10000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_CHILD_WRITE()));
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_CHILD_WRITE());
ioWriteOpen(write);
// Greeting with noop
@ -496,9 +496,9 @@ testRun(void)
// Local 2
HARNESS_FORK_CHILD_BEGIN(0, true)
{
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_CHILD_READ(), 10000));
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_CHILD_READ(), 10000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_CHILD_WRITE()));
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_CHILD_WRITE());
ioWriteOpen(write);
// Greeting with noop
@ -538,11 +538,11 @@ testRun(void)
for (unsigned int clientIdx = 0; clientIdx < clientTotal; clientIdx++)
{
IoRead *read = ioHandleReadIo(
ioHandleReadNew(strNewFmt("client %u read", clientIdx), HARNESS_FORK_PARENT_READ_PROCESS(clientIdx), 2000));
IoRead *read = ioHandleReadNew(
strNewFmt("client %u read", clientIdx), HARNESS_FORK_PARENT_READ_PROCESS(clientIdx), 2000);
ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(
ioHandleWriteNew(strNewFmt("client %u write", clientIdx), HARNESS_FORK_PARENT_WRITE_PROCESS(clientIdx)));
IoWrite *write = ioHandleWriteNew(
strNewFmt("client %u write", clientIdx), HARNESS_FORK_PARENT_WRITE_PROCESS(clientIdx));
ioWriteOpen(write);
TEST_ASSIGN(
@ -557,9 +557,9 @@ testRun(void)
"{\"name\":\"pgBackRest\",\"service\":\"error\",\"version\":\"" PROJECT_VERSION "\"}\n"
"{}\n");
IoRead *read = ioBufferReadIo(ioBufferReadNew(BUFSTR(protocolString)));
IoRead *read = ioBufferReadNew(BUFSTR(protocolString));
ioReadOpen(read);
IoWrite *write = ioBufferWriteIo(ioBufferWriteNew(bufNew(1024)));
IoWrite *write = ioBufferWriteNew(bufNew(1024));
ioWriteOpen(write);
ProtocolClient *clientError = protocolClientNew(strNew("error"), strNew("error"), read, write);

Some files were not shown because too many files have changed in this diff Show More