1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-06-16 23:47:38 +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> <p>Don't append <code>strerror()</code> to error message when <code>errno</code> is 0.</p>
</release-item> </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> <release-item>
<p>Various <code>Buffer</code> improvements.</p> <p>Various <code>Buffer</code> improvements.</p>
</release-item> </release-item>

View File

@ -18,6 +18,10 @@ new(class, mode, type, key, keySize, digest = NULL)
CODE: CODE:
RETVAL = NULL; RETVAL = NULL;
CHECK(type != NULL);
CHECK(key != NULL);
CHECK(keySize != 0);
// Not much point to this but it keeps the var from being unused // Not much point to this but it keeps the var from being unused
if (strcmp(class, PACKAGE_NAME_LIBC "::Cipher::Block") != 0) if (strcmp(class, PACKAGE_NAME_LIBC "::Cipher::Block") != 0)
croak("unexpected class name '%s'", class); croak("unexpected class name '%s'", class);
@ -25,10 +29,9 @@ CODE:
MEM_CONTEXT_XS_NEW_BEGIN("cipherBlockXs") MEM_CONTEXT_XS_NEW_BEGIN("cipherBlockXs")
{ {
RETVAL = memNew(sizeof(CipherBlockXs)); RETVAL = memNew(sizeof(CipherBlockXs));
RETVAL->memContext = MEM_COMTEXT_XS(); 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(); MEM_CONTEXT_XS_NEW_END();
OUTPUT: OUTPUT:
@ -47,10 +50,27 @@ CODE:
STRLEN tSize; STRLEN tSize;
const unsigned char *sourcePtr = (const unsigned char *)SvPV(source, 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); 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(); MEM_CONTEXT_XS_END();
OUTPUT: OUTPUT:
@ -65,10 +85,22 @@ CODE:
MEM_CONTEXT_XS_BEGIN(self->memContext) MEM_CONTEXT_XS_BEGIN(self->memContext)
{ {
RETVAL = NEWSV(0, cipherBlockProcessSizeC(self->pxPayload, 0)); RETVAL = NEWSV(0, ioBufferSize());
SvPOK_only(RETVAL); 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(); MEM_CONTEXT_XS_END();
OUTPUT: OUTPUT:

View File

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

View File

@ -36,9 +36,10 @@ CODE:
MEM_CONTEXT_XS_TEMP_BEGIN() MEM_CONTEXT_XS_TEMP_BEGIN()
{ {
STRLEN messageSize; 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(); MEM_CONTEXT_XS_TEMP_END();
@ -51,7 +52,7 @@ CODE:
MEM_CONTEXT_XS_TEMP_BEGIN() MEM_CONTEXT_XS_TEMP_BEGIN()
{ {
String *hash = bufHex(cryptoHash(self->pxPayload)); const String *hash = varStr(ioFilterResult(self->pxPayload));
RETVAL = newSV(strSize(hash)); RETVAL = newSV(strSize(hash));
SvPOK_only(RETVAL); SvPOK_only(RETVAL);
@ -82,9 +83,9 @@ CODE:
MEM_CONTEXT_XS_TEMP_BEGIN() MEM_CONTEXT_XS_TEMP_BEGIN()
{ {
STRLEN messageSize; 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)); RETVAL = newSV(strSize(hash));
SvPOK_only(RETVAL); SvPOK_only(RETVAL);

View File

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

View File

@ -13,6 +13,8 @@ storageDriverPosixPathRemove(path, errorOnMissing, recurse)
CODE: CODE:
MEM_CONTEXT_XS_TEMP_BEGIN() 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(); 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 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 $(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 $(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 $(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 $(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 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 $(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 $(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 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 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 $(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 $(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 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 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 $(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 $(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 $(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 $(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 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 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 $(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 $(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 $(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 $(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 $(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 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 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 $(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 $(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 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 $(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 $(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 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 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 $(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 $(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 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 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 $(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 $(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 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 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 $(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 $(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 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 $(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 $(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 $(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 $(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 $(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 $(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 $(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 $(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 $(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 $(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 $(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 $(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 $(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 $(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 $(CC) $(CFLAGS) $(CMAKE) -c storage/storage.c -o storage/storage.o

View File

@ -153,14 +153,12 @@ archiveGetFile(
if (cipherType != cipherTypeNone) if (cipherType != cipherTypeNone)
{ {
ioFilterGroupAdd( ioFilterGroupAdd(
filterGroup, filterGroup, cipherBlockNew(cipherModeDecrypt, cipherType, BUFSTR(archiveGetCheckResult.cipherPass), NULL));
cipherBlockFilter(
cipherBlockNew(cipherModeDecrypt, cipherType, BUFSTR(archiveGetCheckResult.cipherPass), NULL)));
} }
// If file is compressed then add the decompression filter // If file is compressed then add the decompression filter
if (strEndsWithZ(archiveGetCheckResult.archiveFileActual, "." GZIP_EXT)) if (strEndsWithZ(archiveGetCheckResult.archiveFileActual, "." GZIP_EXT))
ioFilterGroupAdd(filterGroup, gzipDecompressFilter(gzipDecompressNew(false))); ioFilterGroupAdd(filterGroup, gzipDecompressNew(false));
ioWriteFilterGroupSet(storageFileWriteIo(destination), filterGroup); 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. // Generate a sha1 checksum for the wal segment. ??? Probably need a function in storage for this.
IoRead *read = storageFileReadIo(storageNewReadNP(storageLocal(), walSource)); 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); ioReadFilterGroupSet(read, filterGroup);
Buffer *buffer = bufNew(ioBufferSize()); Buffer *buffer = bufNew(ioBufferSize());
@ -126,15 +126,12 @@ archivePushFile(
if (isSegment && compress) if (isSegment && compress)
{ {
strCat(archiveDestination, "." GZIP_EXT); 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 there is a cipher then add the encrypt filter
if (cipherType != cipherTypeNone) if (cipherType != cipherTypeNone)
{ ioFilterGroupAdd(filterGroup, cipherBlockNew(cipherModeEncrypt, cipherType, BUFSTR(cipherPass), NULL));
ioFilterGroupAdd(
filterGroup, cipherBlockFilter(cipherBlockNew(cipherModeEncrypt, cipherType, BUFSTR(cipherPass), NULL)));
}
ioReadFilterGroupSet(storageFileReadIo(source), filterGroup); ioReadFilterGroupSet(storageFileReadIo(source), filterGroup);

View File

@ -25,9 +25,9 @@ cmdLocal(int handleRead, int handleWrite)
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
String *name = strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u", cfgOptionUInt(cfgOptProcess)); 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); ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(name, handleWrite)); IoWrite *write = ioHandleWriteNew(name, handleWrite);
ioWriteOpen(write); ioWriteOpen(write);
ProtocolServer *server = protocolServerNew(name, PROTOCOL_SERVICE_LOCAL_STR, read, 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() MEM_CONTEXT_TEMP_BEGIN()
{ {
String *name = strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u", cfgOptionUInt(cfgOptProcess)); 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); ioReadOpen(read);
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(name, handleWrite)); IoWrite *write = ioHandleWriteNew(name, handleWrite);
ioWriteOpen(write); ioWriteOpen(write);
ProtocolServer *server = protocolServerNew(name, PROTOCOL_SERVICE_REMOTE_STR, read, 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/io/filter/filter.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Filter type constant Filter type constant
@ -22,67 +23,45 @@ Filter type constant
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct GzipCompress typedef struct GzipCompress
{ {
MemContext *memContext; // Context to store data MemContext *memContext; // Context to store data
z_stream *stream; // Compression stream state z_stream *stream; // Compression stream state
IoFilter *filter; // Filter interface
bool inputSame; // Is the same input required on the next process call? bool inputSame; // Is the same input required on the next process call?
bool flush; // Is input complete and flushing in progress? bool flush; // Is input complete and flushing in progress?
bool done; // Is compression done? 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 Compression constants
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#define MEM_LEVEL 9 #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 Compress data
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
gzipCompressProcess(GzipCompress *this, const Buffer *uncompressed, Buffer *compressed) gzipCompressProcess(THIS_VOID, const Buffer *uncompressed, Buffer *compressed)
{ {
THIS(GzipCompress);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(GZIP_COMPRESS, this); FUNCTION_LOG_PARAM(GZIP_COMPRESS, this);
FUNCTION_LOG_PARAM(BUFFER, uncompressed); FUNCTION_LOG_PARAM(BUFFER, uncompressed);
@ -136,9 +115,11 @@ gzipCompressProcess(GzipCompress *this, const Buffer *uncompressed, Buffer *comp
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Is compress done? Is compress done?
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
gzipCompressDone(const GzipCompress *this) gzipCompressDone(const THIS_VOID)
{ {
THIS(const GzipCompress);
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(GZIP_COMPRESS, this); FUNCTION_TEST_PARAM(GZIP_COMPRESS, this);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
@ -148,27 +129,14 @@ gzipCompressDone(const GzipCompress *this)
FUNCTION_TEST_RETURN(this->done); 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? Is the same input required on the next process call?
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
gzipCompressInputSame(const GzipCompress *this) gzipCompressInputSame(const THIS_VOID)
{ {
THIS(const GzipCompress);
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(GZIP_COMPRESS, this); FUNCTION_TEST_PARAM(GZIP_COMPRESS, this);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
@ -178,21 +146,10 @@ gzipCompressInputSame(const GzipCompress *this)
FUNCTION_TEST_RETURN(this->inputSame); 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 Free memory
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
gzipCompressFree(GzipCompress *this) gzipCompressFree(GzipCompress *this)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
@ -210,3 +167,40 @@ gzipCompressFree(GzipCompress *this)
FUNCTION_LOG_RETURN_VOID(); 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 #ifndef COMMON_COMPRESS_GZIP_COMPRESS_H
#define 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/io/filter/filter.h"
#include "common/type/buffer.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
GzipCompress *gzipCompressNew(int level, bool raw); IoFilter *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)
#endif #endif

View File

@ -12,6 +12,7 @@ Gzip Decompress
#include "common/io/filter/filter.intern.h" #include "common/io/filter/filter.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Filter type constant Filter type constant
@ -22,59 +23,40 @@ Filter type constant
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct GzipDecompress typedef struct GzipDecompress
{ {
MemContext *memContext; // Context to store data MemContext *memContext; // Context to store data
z_stream *stream; // Decompression stream state z_stream *stream; // Decompression stream state
IoFilter *filter; // Filter interface
int result; // Result of last operation int result; // Result of last operation
bool inputSame; // Is the same input required on the next process call? bool inputSame; // Is the same input required on the next process call?
bool done; // Is decompression done? bool done; // Is decompression done?
}; } GzipDecompress;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New object Macros for function logging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
GzipDecompress * String *
gzipDecompressNew(bool raw) gzipDecompressToLog(const GzipDecompress *this)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); return strNewFmt(
FUNCTION_LOG_PARAM(BOOL, raw); "{inputSame: %s, done: %s, availIn: %u}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done),
FUNCTION_LOG_END(); this->stream->avail_in);
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_TYPE \
GzipDecompress *
#define FUNCTION_LOG_GZIP_DECOMPRESS_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, gzipDecompressToLog, buffer, bufferSize)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Decompress data Decompress data
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void 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_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(GZIP_DECOMPRESS, this); FUNCTION_LOG_PARAM(GZIP_DECOMPRESS, this);
FUNCTION_LOG_PARAM(BUFFER, compressed); FUNCTION_LOG_PARAM(BUFFER, compressed);
@ -113,8 +95,10 @@ gzipDecompressProcess(GzipDecompress *this, const Buffer *compressed, Buffer *un
Is decompress done? Is decompress done?
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool bool
gzipDecompressDone(const GzipDecompress *this) gzipDecompressDone(const THIS_VOID)
{ {
THIS(const GzipDecompress);
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(GZIP_DECOMPRESS, this); FUNCTION_TEST_PARAM(GZIP_DECOMPRESS, this);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
@ -124,27 +108,14 @@ gzipDecompressDone(const GzipDecompress *this)
FUNCTION_TEST_RETURN(this->done); 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? Is the same input required on the next process call?
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool bool
gzipDecompressInputSame(const GzipDecompress *this) gzipDecompressInputSame(const THIS_VOID)
{ {
THIS(const GzipDecompress);
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(GZIP_DECOMPRESS, this); FUNCTION_TEST_PARAM(GZIP_DECOMPRESS, this);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
@ -154,21 +125,10 @@ gzipDecompressInputSame(const GzipDecompress *this)
FUNCTION_TEST_RETURN(this->inputSame); 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 Free memory
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
gzipDecompressFree(GzipDecompress *this) gzipDecompressFree(GzipDecompress *this)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
@ -185,3 +145,38 @@ gzipDecompressFree(GzipDecompress *this)
FUNCTION_LOG_RETURN_VOID(); 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 #ifndef COMMON_COMPRESS_GZIP_DECOMPRESS_H
#define 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/io/filter/filter.h"
#include "common/type/string.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
GzipDecompress *gzipDecompressNew(bool raw); IoFilter *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)
#endif #endif

View File

@ -14,6 +14,7 @@ Block Cipher
#include "common/io/filter/filter.intern.h" #include "common/io/filter/filter.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Filter type constant Filter type constant
@ -35,7 +36,7 @@ Header constants and sizes
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Track state during block encrypt/decrypt Track state during block encrypt/decrypt
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct CipherBlock typedef struct CipherBlock
{ {
MemContext *memContext; // Context to store data MemContext *memContext; // Context to store data
CipherMode mode; // Mode encrypt/decrypt CipherMode mode; // Mode encrypt/decrypt
@ -49,106 +50,55 @@ struct CipherBlock
const EVP_MD *digest; // Message digest object const EVP_MD *digest; // Message digest object
EVP_CIPHER_CTX *cipherContext; // Encrypt/decrypt context EVP_CIPHER_CTX *cipherContext; // Encrypt/decrypt context
IoFilter *filter; // Filter interface
Buffer *buffer; // Internal buffer in case destination buffer isn't large enough Buffer *buffer; // Internal buffer in case destination buffer isn't large enough
bool inputSame; // Is the same input required on next process call? bool inputSame; // Is the same input required on next process call?
bool done; // Is processing done? bool done; // Is processing done?
}; } CipherBlock;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New block encrypt/decrypt object Macros for function logging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
CipherBlock * String *
cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, const String *digestName) cipherBlockToLog(const CipherBlock *this)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); return strNewFmt(
FUNCTION_LOG_PARAM(ENUM, mode); "{inputSame: %s, done: %s}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done));
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)));
} }
CipherBlock * #define FUNCTION_LOG_CIPHER_BLOCK_TYPE \
cipherBlockNewC(CipherMode mode, const char *cipherName, const unsigned char *pass, size_t passSize, const char *digestName) CipherBlock *
#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_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(ENUM, mode); FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
FUNCTION_LOG_PARAM(STRINGZ, cipherName);
FUNCTION_LOG_PARAM_P(UCHARDATA, pass);
FUNCTION_LOG_PARAM(SIZE, passSize);
FUNCTION_LOG_PARAM(STRINGZ, digestName);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
ASSERT(cipherName != NULL); if (this != 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")
{ {
// Allocate state and set context // Free cipher context
this = memNew(sizeof(CipherBlock)); if (this->cipherContext)
this->memContext = MEM_CONTEXT_NEW(); EVP_CIPHER_CTX_cleanup(this->cipherContext);
// Set mode, encrypt or decrypt // Free mem context
this->mode = mode; memContextCallbackClear(this->memContext);
memContextFree(this->memContext);
// 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);
} }
MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(CIPHER_BLOCK, this); FUNCTION_LOG_RETURN_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Determine how large the destination buffer should be Determine how large the destination buffer should be
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
size_t static size_t
cipherBlockProcessSizeC(CipherBlock *this, size_t sourceSize) cipherBlockProcessSize(CipherBlock *this, size_t sourceSize)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this); FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
@ -170,8 +120,8 @@ cipherBlockProcessSizeC(CipherBlock *this, size_t sourceSize)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Encrypt/decrypt data Encrypt/decrypt data
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
size_t static size_t
cipherBlockProcessC(CipherBlock *this, const unsigned char *source, size_t sourceSize, unsigned char *destination) cipherBlockProcessBlock(CipherBlock *this, const unsigned char *source, size_t sourceSize, unsigned char *destination)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this); FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
@ -285,12 +235,12 @@ cipherBlockProcessC(CipherBlock *this, const unsigned char *source, size_t sourc
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Flush the remaining data Flush the remaining data
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
size_t static size_t
cipherBlockFlushC(CipherBlock *this, unsigned char *destination) cipherBlockFlush(CipherBlock *this, Buffer *destination)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this); FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
FUNCTION_LOG_PARAM_P(UCHARDATA, destination); FUNCTION_LOG_PARAM(BUFFER, destination);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
ASSERT(this != NULL); ASSERT(this != NULL);
@ -304,7 +254,7 @@ cipherBlockFlushC(CipherBlock *this, unsigned char *destination)
THROW(CryptoError, "cipher header missing"); THROW(CryptoError, "cipher header missing");
// Only flush remaining data if some data was processed // 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"); THROW(CryptoError, "unable to flush");
// Return actual destination size // Return actual destination size
@ -314,9 +264,11 @@ cipherBlockFlushC(CipherBlock *this, unsigned char *destination)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Process function used by C filter Process function used by C filter
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
cipherBlockProcess(CipherBlock *this, const Buffer *source, Buffer *destination) cipherBlockProcess(THIS_VOID, const Buffer *source, Buffer *destination)
{ {
THIS(CipherBlock);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this); FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
FUNCTION_LOG_PARAM(BUFFER, source); 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 // Determine how much space is required in the output buffer
Buffer *outputActual = destination; 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)) 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. // file but we need to call process to generate the header.
if (!this->saltDone) if (!this->saltDone)
{ {
destinationSizeActual = cipherBlockProcessC(this, NULL, 0, bufRemainsPtr(outputActual)); destinationSizeActual = cipherBlockProcessBlock(this, NULL, 0, bufRemainsPtr(outputActual));
bufUsedInc(outputActual, destinationSizeActual); bufUsedInc(outputActual, destinationSizeActual);
} }
destinationSizeActual = cipherBlockFlushC(this, bufRemainsPtr(outputActual)); destinationSizeActual = cipherBlockFlush(this, outputActual);
this->done = true; this->done = true;
} }
else else
destinationSizeActual = cipherBlockProcessC(this, bufPtr(source), bufUsed(source), bufRemainsPtr(outputActual)); destinationSizeActual = cipherBlockProcessBlock(this, bufPtr(source), bufUsed(source), bufRemainsPtr(outputActual));
bufUsedInc(outputActual, destinationSizeActual); bufUsedInc(outputActual, destinationSizeActual);
@ -407,9 +359,11 @@ cipherBlockProcess(CipherBlock *this, const Buffer *source, Buffer *destination)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Is cipher done? Is cipher done?
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
cipherBlockDone(const CipherBlock *this) cipherBlockDone(const THIS_VOID)
{ {
THIS(const CipherBlock);
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(CIPHER_BLOCK, this); FUNCTION_TEST_PARAM(CIPHER_BLOCK, this);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
@ -419,27 +373,14 @@ cipherBlockDone(const CipherBlock *this)
FUNCTION_TEST_RETURN(this->done && !this->inputSame); 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? Should the same input be provided again?
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
cipherBlockInputSame(const CipherBlock *this) cipherBlockInputSame(const THIS_VOID)
{ {
THIS(const CipherBlock);
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(CIPHER_BLOCK, this); FUNCTION_TEST_PARAM(CIPHER_BLOCK, this);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
@ -450,35 +391,68 @@ cipherBlockInputSame(const CipherBlock *this)
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Render as string for logging New block encrypt/decrypt object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
String * IoFilter *
cipherBlockToLog(const CipherBlock *this) cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, const String *digestName)
{
return strNewFmt(
"{inputSame: %s, done: %s}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done));
}
/***********************************************************************************************************************************
Free memory
***********************************************************************************************************************************/
void
cipherBlockFree(CipherBlock *this)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); 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(); 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 CipherBlock *driver = memNew(sizeof(CipherBlock));
if (this->cipherContext) driver->memContext = MEM_CONTEXT_NEW();
EVP_CIPHER_CTX_cleanup(this->cipherContext);
// Free mem context // Set mode, encrypt or decrypt
memContextCallbackClear(this->memContext); driver->mode = mode;
memContextFree(this->memContext);
// 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_VOID(); FUNCTION_LOG_RETURN(IO_FILTER, this);
} }

View File

@ -4,54 +4,12 @@ Block Cipher Header
#ifndef COMMON_CRYPTO_CIPHERBLOCK_H #ifndef COMMON_CRYPTO_CIPHERBLOCK_H
#define COMMON_CRYPTO_CIPHERBLOCK_H #define COMMON_CRYPTO_CIPHERBLOCK_H
/***********************************************************************************************************************************
CipherBlock object
***********************************************************************************************************************************/
typedef struct CipherBlock CipherBlock;
#include "common/io/filter/filter.h" #include "common/io/filter/filter.h"
#include "common/type/buffer.h"
#include "common/crypto/common.h" #include "common/crypto/common.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
CipherBlock *cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, const String *digestName); IoFilter *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)
#endif #endif

View File

@ -14,6 +14,7 @@ Cryptographic Hash
#include "common/io/filter/filter.intern.h" #include "common/io/filter/filter.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
#include "common/crypto/common.h" #include "common/crypto/common.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@ -31,125 +32,49 @@ STRING_EXTERN(HASH_TYPE_SHA256_STR, HASH_TYPE_SH
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct CryptoHash typedef struct CryptoHash
{ {
MemContext *memContext; // Context to store data MemContext *memContext; // Context to store data
const EVP_MD *hashType; // Hash type (sha1, md5, etc.) const EVP_MD *hashType; // Hash type (sha1, md5, etc.)
EVP_MD_CTX *hashContext; // Message hash context EVP_MD_CTX *hashContext; // Message hash context
Buffer *hash; // Hash in binary form Buffer *hash; // Hash in binary form
IoFilter *filter; // Filter interface } CryptoHash;
};
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New object Macros for function logging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
CryptoHash * #define FUNCTION_LOG_CRYPTO_HASH_TYPE \
cryptoHashNew(const String *type) CryptoHash *
{ #define FUNCTION_LOG_CRYPTO_HASH_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_BEGIN(logLevelTrace); objToLog(value, "CryptoHash", buffer, bufferSize)
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);
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Add message data to the hash Add message data to the hash from a Buffer
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
cryptoHashProcessC(CryptoHash *this, const unsigned char *message, size_t messageSize) cryptoHashProcess(THIS_VOID, const Buffer *message)
{ {
THIS(CryptoHash);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CRYPTO_HASH, this); FUNCTION_LOG_PARAM(CRYPTO_HASH, this);
FUNCTION_LOG_PARAM_P(UCHARDATA, message); FUNCTION_LOG_PARAM(BUFFER, message);
FUNCTION_LOG_PARAM(SIZE, messageSize);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
ASSERT(this != NULL); ASSERT(this != NULL);
ASSERT(this->hashContext != NULL); ASSERT(this->hashContext != NULL);
ASSERT(this->hash == NULL);
ASSERT(message != 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(); 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 Get binary representation of the hash
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
const Buffer * static const Buffer *
cryptoHash(CryptoHash *this) cryptoHash(CryptoHash *this)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
@ -166,10 +91,6 @@ cryptoHash(CryptoHash *this)
bufUsedSet(this->hash, bufSize(this->hash)); bufUsedSet(this->hash, bufSize(this->hash));
cryptoError(!EVP_DigestFinal_ex(this->hashContext, bufPtr(this->hash), NULL), "unable to finalize message 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(); MEM_CONTEXT_END();
} }
@ -177,74 +98,91 @@ cryptoHash(CryptoHash *this)
FUNCTION_LOG_RETURN(BUFFER, this->hash); 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 Get string representation of the hash as a filter result
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
const Variant * static Variant *
cryptoHashResult(CryptoHash *this) cryptoHashResult(THIS_VOID)
{ {
THIS(CryptoHash);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CRYPTO_HASH, this); FUNCTION_LOG_PARAM(CRYPTO_HASH, this);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
ASSERT(this != NULL); ASSERT(this != NULL);
Variant *result = NULL; FUNCTION_LOG_RETURN(VARIANT, varNewStr(bufHex(cryptoHash(this))));
MEM_CONTEXT_BEGIN(this->memContext)
{
result = varNewStr(bufHex(cryptoHash(this)));
}
MEM_CONTEXT_END();
FUNCTION_LOG_RETURN(VARIANT, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Free memory Free memory
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
cryptoHashFree(CryptoHash *this) cryptoHashFreeCallback(CryptoHash *this)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(CRYPTO_HASH, this); FUNCTION_LOG_PARAM(CRYPTO_HASH, this);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
if (this != NULL) EVP_MD_CTX_destroy(this->hashContext);
{
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 Get hash for one C buffer
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
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_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, type); FUNCTION_LOG_PARAM(STRING, type);
FUNCTION_LOG_PARAM_P(UCHARDATA, message); FUNCTION_LOG_PARAM(BUFFER, message);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
ASSERT(type != NULL); ASSERT(type != NULL);
@ -254,11 +192,15 @@ cryptoHashOneC(const String *type, const unsigned char *message, size_t messageS
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
CryptoHash *hash = cryptoHashNew(type); IoFilter *hash = cryptoHashNew(type);
cryptoHashProcessC(hash, message, messageSize);
if (bufUsed(message) > 0)
ioFilterProcessIn(hash, message);
const Buffer *buffer = cryptoHash((CryptoHash *)ioFilterDriver(hash));
memContextSwitch(MEM_CONTEXT_OLD()); memContextSwitch(MEM_CONTEXT_OLD());
result = bufDup(cryptoHash(hash)); result = bufDup(buffer);
memContextSwitch(MEM_CONTEXT_TEMP()); memContextSwitch(MEM_CONTEXT_TEMP());
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
@ -266,40 +208,6 @@ cryptoHashOneC(const String *type, const unsigned char *message, size_t messageS
FUNCTION_LOG_RETURN(BUFFER, result); 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 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 #ifndef COMMON_CRYPTO_HASH_H
#define COMMON_CRYPTO_HASH_H #define COMMON_CRYPTO_HASH_H
/***********************************************************************************************************************************
Hash object
***********************************************************************************************************************************/
typedef struct CryptoHash CryptoHash;
#include "common/io/filter/filter.h" #include "common/io/filter/filter.h"
#include "common/type/string.h" #include "common/type/string.h"
@ -45,42 +40,12 @@ Hash type sizes
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
CryptoHash *cryptoHashNew(const String *type); IoFilter *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);
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Helper functions Helper functions
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
Buffer *cryptoHashOne(const String *type, const Buffer *message); 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); 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 #endif

View File

@ -18,6 +18,7 @@ Execute Process
#include "common/io/io.h" #include "common/io/io.h"
#include "common/io/read.intern.h" #include "common/io/read.intern.h"
#include "common/io/write.intern.h" #include "common/io/write.intern.h"
#include "common/object.h"
#include "common/wait.h" #include "common/wait.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@ -37,7 +38,7 @@ struct Exec
int handleWrite; // Write handle int handleWrite; // Write handle
int handleError; // Error handle int handleError; // Error handle
IoHandleRead *ioReadHandle; // Handle read driver IoRead *ioReadHandle; // Handle read driver
IoWrite *ioWriteHandle; // Handle write interface IoWrite *ioWriteHandle; // Handle write interface
IoRead *ioReadExec; // Wrapper for handle read 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); 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 Execute command
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@ -171,15 +321,13 @@ execOpen(Exec *this)
// Assign handles to io interfaces // Assign handles to io interfaces
this->ioReadHandle = ioHandleReadNew(strNewFmt("%s read", strPtr(this->name)), this->handleRead, this->timeout); 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); ioWriteOpen(this->ioWriteHandle);
// Create wrapper interfaces that check process state // Create wrapper interfaces that check process state
this->ioReadExec = ioReadNewP( this->ioReadExec = ioReadNewP(this, .block = true, .read = execRead, .eof = execEof, .handle = execHandleRead);
this, .block = true, .read = (IoReadInterfaceRead)execRead, .eof = (IoReadInterfaceEof)execEof,
.handle = (IoReadInterfaceHandle)execHandleRead);
ioReadOpen(this->ioReadExec); ioReadOpen(this->ioReadExec);
this->ioWriteExec = ioWriteNewP(this, .write = (IoWriteInterfaceWrite)execWrite); this->ioWriteExec = ioWriteNewP(this, .write = execWrite);
ioWriteOpen(this->ioWriteExec); ioWriteOpen(this->ioWriteExec);
// Set a callback so the handles will get freed // Set a callback so the handles will get freed
@ -188,132 +336,6 @@ execOpen(Exec *this)
FUNCTION_LOG_RETURN_VOID(); 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 Get read interface
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@ -359,21 +381,6 @@ execMemContext(const Exec *this)
FUNCTION_TEST_RETURN(this->memContext); 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 Free the object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/

View File

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

View File

@ -8,52 +8,36 @@ Buffer IO Read
#include "common/io/read.intern.h" #include "common/io/read.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct IoBufferRead typedef struct IoBufferRead
{ {
MemContext *memContext; // Object memory context MemContext *memContext; // Object memory context
IoRead *io; // IoRead interface
const Buffer *read; // Buffer to read data from const Buffer *read; // Buffer to read data from
size_t readPos; // Current position in the read buffer size_t readPos; // Current position in the read buffer
bool eof; // Has the end of the buffer been reached? bool eof; // Has the end of the buffer been reached?
}; } IoBufferRead;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New object Macros for function logging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoBufferRead * #define FUNCTION_LOG_IO_BUFFER_READ_TYPE \
ioBufferReadNew(const Buffer *buffer) IoBufferRead *
{ #define FUNCTION_LOG_IO_BUFFER_READ_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_BEGIN(logLevelTrace); objToLog(value, "IoBufferRead", buffer, bufferSize)
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);
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Read data from the buffer Read data from the buffer
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
size_t static size_t
ioBufferRead(IoBufferRead *this, Buffer *buffer, bool block) ioBufferRead(THIS_VOID, Buffer *buffer, bool block)
{ {
THIS(IoBufferRead);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_BUFFER_READ, this); FUNCTION_LOG_PARAM(IO_BUFFER_READ, this);
FUNCTION_LOG_PARAM(BUFFER, buffer); FUNCTION_LOG_PARAM(BUFFER, buffer);
@ -83,31 +67,14 @@ ioBufferRead(IoBufferRead *this, Buffer *buffer, bool block)
FUNCTION_LOG_RETURN(SIZE, actualBytes); 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? Have all bytes been read from the buffer?
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
ioBufferReadEof(const IoBufferRead *this) ioBufferReadEof(THIS_VOID)
{ {
THIS(IoBufferRead);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_BUFFER_READ, this); FUNCTION_LOG_PARAM(IO_BUFFER_READ, this);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
@ -118,32 +85,28 @@ ioBufferReadEof(const IoBufferRead *this)
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Get io interface New object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoRead * IoRead *
ioBufferReadIo(const IoBufferRead *this) ioBufferReadNew(const Buffer *buffer)
{
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)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_BUFFER_READ, this); FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
if (this != NULL) ASSERT(buffer != NULL);
memContextFree(this->memContext);
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 #ifndef COMMON_IO_BUFFERREAD_H
#define COMMON_IO_BUFFERREAD_H #define COMMON_IO_BUFFERREAD_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct IoBufferRead IoBufferRead;
#include "common/io/read.h" #include "common/io/read.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoBufferRead *ioBufferReadNew(const Buffer *buffer); IoRead *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)
#endif #endif

View File

@ -8,49 +8,33 @@ Buffer IO Write
#include "common/io/write.intern.h" #include "common/io/write.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct IoBufferWrite typedef struct IoBufferWrite
{ {
MemContext *memContext; // Object memory context MemContext *memContext; // Object memory context
IoWrite *io; // IoWrite interface
Buffer *write; // Buffer to write into Buffer *write; // Buffer to write into
}; } IoBufferWrite;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New object Macros for function logging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoBufferWrite * #define FUNCTION_LOG_IO_BUFFER_WRITE_TYPE \
ioBufferWriteNew(Buffer *buffer) IoBufferWrite *
{ #define FUNCTION_LOG_IO_BUFFER_WRITE_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_BEGIN(logLevelTrace); objToLog(value, "IoBufferWrite", buffer, bufferSize)
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);
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Write to the buffer Write to the buffer
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
ioBufferWrite(IoBufferWrite *this, Buffer *buffer) ioBufferWrite(THIS_VOID, const Buffer *buffer)
{ {
THIS(IoBufferWrite);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_BUFFER_WRITE, this); FUNCTION_LOG_PARAM(IO_BUFFER_WRITE, this);
FUNCTION_LOG_PARAM(BUFFER, buffer); FUNCTION_LOG_PARAM(BUFFER, buffer);
@ -65,51 +49,28 @@ ioBufferWrite(IoBufferWrite *this, Buffer *buffer)
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Move the object to a new context New object
***********************************************************************************************************************************/
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
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoWrite * IoWrite *
ioBufferWriteIo(const IoBufferWrite *this) ioBufferWriteNew(Buffer *buffer)
{
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)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_BUFFER_WRITE, this); FUNCTION_LOG_PARAM(BUFFER, buffer);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
if (this != NULL) ASSERT(buffer != NULL);
memContextFree(this->memContext);
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 #ifndef COMMON_IO_BUFFERWRITE_H
#define COMMON_IO_BUFFERWRITE_H #define COMMON_IO_BUFFERWRITE_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct IoBufferWrite IoBufferWrite;
#include "common/io/write.h" #include "common/io/write.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoBufferWrite *ioBufferWriteNew(Buffer *buffer); IoWrite *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)
#endif #endif

View File

@ -10,6 +10,7 @@ IO Buffer Filter
#include "common/io/filter/filter.intern.h" #include "common/io/filter/filter.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Filter type constant Filter type constant
@ -20,46 +21,36 @@ Filter type constant
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct IoBuffer typedef struct IoBuffer
{ {
MemContext *memContext; // Mem context of filter MemContext *memContext; // Mem context of filter
IoFilter *filter; // Filter interface
size_t inputPos; // Position in input buffer size_t inputPos; // Position in input buffer
bool inputSame; // Is the same input required again? bool inputSame; // Is the same input required again?
}; } IoBuffer;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New object Macros for function logging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoBuffer * String *
ioBufferNew(void) ioBufferToLog(const IoBuffer *this)
{ {
FUNCTION_LOG_VOID(logLevelTrace); return strNewFmt("{inputSame: %s, inputPos: %zu}", cvtBoolToConstZ(this->inputSame), this->inputPos);
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_TYPE \
IoBuffer *
#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 Move data from the input buffer to the output buffer
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
ioBufferProcess(IoBuffer *this, const Buffer *input, Buffer *output) ioBufferProcess(THIS_VOID, const Buffer *input, Buffer *output)
{ {
THIS(IoBuffer)
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_BUFFER, this); FUNCTION_LOG_PARAM(IO_BUFFER, this);
FUNCTION_LOG_PARAM(BUFFER, input); 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 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. again.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
ioBufferInputSame(const IoBuffer *this) ioBufferInputSame(const THIS_VOID)
{ {
THIS(const IoBuffer)
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_BUFFER, this); FUNCTION_TEST_PARAM(IO_BUFFER, this);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
@ -114,41 +107,23 @@ ioBufferInputSame(const IoBuffer *this)
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Get filter interface New object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoFilter * IoFilter *
ioBufferFilter(const IoBuffer *this) ioBufferNew(void)
{ {
FUNCTION_TEST_BEGIN(); FUNCTION_LOG_VOID(logLevelTrace);
FUNCTION_TEST_PARAM(IO_BUFFER, this);
FUNCTION_TEST_END();
ASSERT(this != NULL); IoFilter *this = NULL;
FUNCTION_TEST_RETURN(this->filter); MEM_CONTEXT_NEW_BEGIN("IoBuffer")
} {
IoBuffer *driver = memNew(sizeof(IoBuffer));
/*********************************************************************************************************************************** driver->memContext = memContextCurrent();
Render as string for logging
***********************************************************************************************************************************/ this = ioFilterNewP(BUFFER_FILTER_TYPE_STR, driver, .inOut = ioBufferProcess, .inputSame = ioBufferInputSame);
String * }
ioBufferToLog(const IoBuffer *this) MEM_CONTEXT_NEW_END();
{
return strNewFmt("{inputSame: %s, inputPos: %zu}", cvtBoolToConstZ(this->inputSame), this->inputPos); FUNCTION_LOG_RETURN(IO_FILTER, this);
}
/***********************************************************************************************************************************
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();
} }

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 #ifndef COMMON_IO_FILTER_BUFFER_H
#define 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/io/filter/filter.h"
#include "common/type/buffer.h" #include "common/type/buffer.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoBuffer *ioBufferNew(void); IoFilter *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)
#endif #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)); 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? 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); 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? Does filter produce output?
@ -169,7 +199,7 @@ ioFilterOutput(const IoFilter *this)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Get filter result Get filter result
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
const Variant * Variant *
ioFilterResult(const IoFilter *this) ioFilterResult(const IoFilter *this)
{ {
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
@ -197,3 +227,19 @@ ioFilterType(const IoFilter *this)
FUNCTION_TEST_RETURN(this->type); 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 Getters
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
const Variant *ioFilterResult(const IoFilter *this); Variant *ioFilterResult(const IoFilter *this);
const String *ioFilterType(const IoFilter *this); const String *ioFilterType(const IoFilter *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void ioFilterFree(IoFilter *this);
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Macros for function logging 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 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 typedef struct IoFilterInterface
{ {
// Indicates that filter processing is done. This is used for filters that have additional data to be flushed even after all // 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 // 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. // 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 // 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. // 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 // Processing function for filters that produce output. InOut filters will typically implement inputSame and may also implement
// done. // 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 // 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 // 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. // 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 // 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. // is not processed output, e.g. a count of total bytes or a cryptographic hash.
IoFilterInterfaceResult result; Variant *(*result)(void *driver);
} IoFilterInterface; } IoFilterInterface;
#define ioFilterNewP(type, driver, ...) \ #define ioFilterNewP(type, driver, ...) \
@ -70,7 +64,9 @@ IoFilter *ioFilterMove(IoFilter *this, MemContext *parentNew);
Getters Getters
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool ioFilterDone(const IoFilter *this); bool ioFilterDone(const IoFilter *this);
void *ioFilterDriver(IoFilter *this);
bool ioFilterInputSame(const IoFilter *this); bool ioFilterInputSame(const IoFilter *this);
const IoFilterInterface *ioFilterInterface(const IoFilter *this);
bool ioFilterOutput(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 // 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. // 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)) 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. // Create filter input/output buffers. Input filters do not get an output buffer since they don't produce output.
Buffer *lastOutputBuffer = NULL; Buffer *lastOutputBuffer = NULL;

View File

@ -10,6 +10,7 @@ IO Size Filter
#include "common/io/filter/size.h" #include "common/io/filter/size.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Filter type constant Filter type constant
@ -20,45 +21,35 @@ Filter type constant
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct IoSize typedef struct IoSize
{ {
MemContext *memContext; // Mem context of filter MemContext *memContext; // Mem context of filter
IoFilter *filter; // Filter interface
uint64_t size; // Total size of al input uint64_t size; // Total size of al input
}; } IoSize;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New object Macros for function logging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoSize * String *
ioSizeNew(void) ioSizeToLog(const IoSize *this)
{ {
FUNCTION_LOG_VOID(logLevelTrace); return strNewFmt("{size: %" PRIu64 "}", this->size);
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_TYPE \
IoSize *
#define FUNCTION_LOG_IO_SIZE_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, ioSizeToLog, buffer, bufferSize)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Count bytes in the input Count bytes in the input
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
ioSizeProcess(IoSize *this, const Buffer *input) ioSizeProcess(THIS_VOID, const Buffer *input)
{ {
THIS(IoSize);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_SIZE, this); FUNCTION_LOG_PARAM(IO_SIZE, this);
FUNCTION_LOG_PARAM(BUFFER, input); FUNCTION_LOG_PARAM(BUFFER, input);
@ -72,65 +63,41 @@ ioSizeProcess(IoSize *this, const Buffer *input)
FUNCTION_LOG_RETURN_VOID(); 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 Return filter result
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
const Variant * static Variant *
ioSizeResult(IoSize *this) ioSizeResult(THIS_VOID)
{ {
THIS(IoSize);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_SIZE, this); FUNCTION_LOG_PARAM(IO_SIZE, this);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
ASSERT(this != NULL); ASSERT(this != NULL);
Variant *result = NULL; FUNCTION_LOG_RETURN(VARIANT, varNewUInt64(this->size));
MEM_CONTEXT_BEGIN(this->memContext)
{
result = varNewUInt64(this->size);
}
MEM_CONTEXT_END();
FUNCTION_LOG_RETURN(VARIANT, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Free the filter group New object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void IoFilter *
ioSizeFree(IoSize *this) ioSizeNew(void)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_VOID(logLevelTrace);
FUNCTION_LOG_PARAM(IO_SIZE, this);
FUNCTION_LOG_END();
if (this != NULL) IoFilter *this = NULL;
memContextFree(this->memContext);
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 #ifndef COMMON_IO_FILTER_SIZE_H
#define 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/io/filter/filter.h"
#include "common/type/buffer.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoSize *ioSizeNew(void); IoFilter *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)
#endif #endif

View File

@ -11,56 +11,36 @@ Handle IO Read
#include "common/io/read.intern.h" #include "common/io/read.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct IoHandleRead typedef struct IoHandleRead
{ {
MemContext *memContext; // Object memory context MemContext *memContext; // Object memory context
IoRead *io; // IoRead interface
const String *name; // Handle name for error messages const String *name; // Handle name for error messages
int handle; // Handle to read data from int handle; // Handle to read data from
TimeMSec timeout; // Timeout for read operation TimeMSec timeout; // Timeout for read operation
bool eof; // Has the end of the stream been reached? bool eof; // Has the end of the stream been reached?
}; } IoHandleRead;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New object Macros for function logging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoHandleRead * #define FUNCTION_LOG_IO_HANDLE_READ_TYPE \
ioHandleReadNew(const String *name, int handle, TimeMSec timeout) IoHandleRead *
{ #define FUNCTION_LOG_IO_HANDLE_READ_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_BEGIN(logLevelTrace); objToLog(value, "IoHandleRead", buffer, bufferSize)
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);
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Read data from the handle Read data from the handle
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
size_t static size_t
ioHandleRead(IoHandleRead *this, Buffer *buffer, bool block) ioHandleRead(THIS_VOID, Buffer *buffer, bool block)
{ {
THIS(IoHandleRead);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_HANDLE_READ, this); FUNCTION_LOG_PARAM(IO_HANDLE_READ, this);
FUNCTION_LOG_PARAM(BUFFER, buffer); FUNCTION_LOG_PARAM(BUFFER, buffer);
@ -116,31 +96,14 @@ ioHandleRead(IoHandleRead *this, Buffer *buffer, bool block)
FUNCTION_LOG_RETURN(SIZE, (size_t)actualBytes); 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? Have all bytes been read from the buffer?
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
ioHandleReadEof(const IoHandleRead *this) ioHandleReadEof(THIS_VOID)
{ {
THIS(IoHandleRead);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_HANDLE_READ, this); FUNCTION_LOG_PARAM(IO_HANDLE_READ, this);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
@ -153,9 +116,11 @@ ioHandleReadEof(const IoHandleRead *this)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Get handle (file descriptor) Get handle (file descriptor)
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
int static int
ioHandleReadHandle(const IoHandleRead *this) ioHandleReadHandle(const THIS_VOID)
{ {
THIS(const IoHandleRead);
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_HANDLE_READ, this); FUNCTION_TEST_PARAM(IO_HANDLE_READ, this);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
@ -166,32 +131,30 @@ ioHandleReadHandle(const IoHandleRead *this)
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Get io interface New object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoRead * IoRead *
ioHandleReadIo(const IoHandleRead *this) ioHandleReadNew(const String *name, int handle, TimeMSec timeout)
{
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)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_HANDLE_READ, this); FUNCTION_LOG_PARAM(INT, handle);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
if (this != NULL) ASSERT(handle != -1);
memContextFree(this->memContext);
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 #ifndef COMMON_IO_HANDLEREAD_H
#define COMMON_IO_HANDLEREAD_H #define COMMON_IO_HANDLEREAD_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct IoHandleRead IoHandleRead;
#include "common/io/read.h" #include "common/io/read.h"
#include "common/time.h" #include "common/time.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoHandleRead *ioHandleReadNew(const String *name, int handle, TimeMSec timeout); IoRead *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)
#endif #endif

View File

@ -10,50 +10,34 @@ Handle IO Write
#include "common/io/write.intern.h" #include "common/io/write.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct IoHandleWrite typedef struct IoHandleWrite
{ {
MemContext *memContext; // Object memory context MemContext *memContext; // Object memory context
IoWrite *io; // IoWrite interface
const String *name; // Handle name for error messages const String *name; // Handle name for error messages
int handle; // Handle to write to int handle; // Handle to write to
}; } IoHandleWrite;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New object Macros for function logging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoHandleWrite * #define FUNCTION_LOG_IO_HANDLE_WRITE_TYPE \
ioHandleWriteNew(const String *name, int handle) IoHandleWrite *
{ #define FUNCTION_LOG_IO_HANDLE_WRITE_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_BEGIN(logLevelTrace); objToLog(value, "IoHandleWrite", buffer, bufferSize)
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);
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Write to the handle Write to the handle
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
ioHandleWrite(IoHandleWrite *this, Buffer *buffer) ioHandleWrite(THIS_VOID, const Buffer *buffer)
{ {
THIS(IoHandleWrite);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_HANDLE_WRITE, this); FUNCTION_LOG_PARAM(IO_HANDLE_WRITE, this);
FUNCTION_LOG_PARAM(BUFFER, buffer); FUNCTION_LOG_PARAM(BUFFER, buffer);
@ -68,31 +52,14 @@ ioHandleWrite(IoHandleWrite *this, Buffer *buffer)
FUNCTION_LOG_RETURN_VOID(); 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) Get handle (file descriptor)
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
int static int
ioHandleWriteHandle(const IoHandleWrite *this) ioHandleWriteHandle(const THIS_VOID)
{ {
THIS(const IoHandleWrite);
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_HANDLE_WRITE, this); FUNCTION_TEST_PARAM(IO_HANDLE_WRITE, this);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
@ -103,34 +70,29 @@ ioHandleWriteHandle(const IoHandleWrite *this)
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Get io interface New object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoWrite * IoWrite *
ioHandleWriteIo(const IoHandleWrite *this) ioHandleWriteNew(const String *name, int handle)
{
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)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_HANDLE_WRITE, this); FUNCTION_LOG_PARAM(INT, handle);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
if (this != NULL) IoWrite *this = NULL;
memContextFree(this->memContext);
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 #ifndef COMMON_IO_HANDLEWRITE_H
#define COMMON_IO_HANDLEWRITE_H #define COMMON_IO_HANDLEWRITE_H
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct IoHandleWrite IoHandleWrite;
#include "common/io/write.h" #include "common/io/write.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
IoHandleWrite *ioHandleWriteNew(const String *name, int handle); IoWrite *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);
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Helper functions Helper functions
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void ioHandleWriteOneStr(int handle, const String *string); 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 #endif

View File

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

View File

@ -322,6 +322,21 @@ ioReadBlock(const IoRead *this)
FUNCTION_TEST_RETURN(this->interface.block); 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? 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)); 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 Free the object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/

View File

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

View File

@ -24,6 +24,7 @@ TLS Client
#include "common/io/read.intern.h" #include "common/io/read.intern.h"
#include "common/io/write.intern.h" #include "common/io/write.intern.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
#include "common/time.h" #include "common/time.h"
#include "common/type/keyValue.h" #include "common/type/keyValue.h"
#include "common/wait.h" #include "common/wait.h"
@ -258,6 +259,147 @@ tlsClientHostVerify(const String *host, X509 *certificate)
FUNCTION_LOG_RETURN(BOOL, result); 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 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) MEM_CONTEXT_BEGIN(this->memContext)
{ {
// Create read and write interfaces // Create read and write interfaces
this->write = ioWriteNewP(this, .write = (IoWriteInterfaceWrite)tlsClientWrite); this->write = ioWriteNewP(this, .write = tlsClientWrite);
ioWriteOpen(this->write); ioWriteOpen(this->write);
this->read = ioReadNewP( this->read = ioReadNewP(this, .block = true, .eof = tlsClientEof, .read = tlsClientRead);
this, .block = true, .eof = (IoReadInterfaceEof)tlsClientEof, .read = (IoReadInterfaceRead)tlsClientRead);
ioReadOpen(this->read); ioReadOpen(this->read);
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
@ -426,141 +567,6 @@ tlsClientOpen(TlsClient *this)
FUNCTION_LOG_RETURN_VOID(); 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 Get read interface
***********************************************************************************************************************************/ ***********************************************************************************************************************************/

View File

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

View File

@ -246,6 +246,21 @@ ioWriteClose(IoWrite *this)
FUNCTION_LOG_RETURN_VOID(); 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 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)); 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 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 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 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 #ifndef COMMON_IO_WRITE_H
#define COMMON_IO_WRITE_H #define COMMON_IO_WRITE_H

View File

@ -9,17 +9,12 @@ IO Write Interface Internal
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor 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 typedef struct IoWriteInterface
{ {
IoWriteInterfaceClose close; void (*close)(void *driver);
IoWriteInterfaceHandle handle; int (*handle)(const void *driver);
IoWriteInterfaceOpen open; void (*open)(void *driver);
IoWriteInterfaceWrite write; void (*write)(void *driver, const Buffer *buffer);
} IoWriteInterface; } IoWriteInterface;
#define ioWriteNewP(driver, ...) \ #define ioWriteNewP(driver, ...) \
@ -27,6 +22,12 @@ typedef struct IoWriteInterface
IoWrite *ioWriteNew(void *driver, IoWriteInterface interface); IoWrite *ioWriteNew(void *driver, IoWriteInterface interface);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
void *ioWriteDriver(IoWrite *this);
const IoWriteInterface *ioWriteInterface(const IoWrite *this);
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Macros for function logging 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/cipherBlock.h"
#include "common/crypto/hash.h" #include "common/crypto/hash.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/io/filter/filter.intern.h"
#include "common/ini.h" #include "common/ini.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
@ -56,11 +57,11 @@ infoHash(const Ini *ini)
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
CryptoHash *hash = cryptoHashNew(HASH_TYPE_SHA1_STR); IoFilter *hash = cryptoHashNew(HASH_TYPE_SHA1_STR);
StringList *sectionList = strLstSort(iniSectionList(ini), sortOrderAsc); StringList *sectionList = strLstSort(iniSectionList(ini), sortOrderAsc);
// Initial JSON opening bracket // Initial JSON opening bracket
cryptoHashProcessC(hash, (const unsigned char *)"{", 1); ioFilterProcessIn(hash, BUFSTRDEF("{"));
// Loop through sections and create hash for checking checksum // Loop through sections and create hash for checking checksum
for (unsigned int sectionIdx = 0; sectionIdx < strLstSize(sectionList); sectionIdx++) for (unsigned int sectionIdx = 0; sectionIdx < strLstSize(sectionList); sectionIdx++)
@ -69,12 +70,12 @@ infoHash(const Ini *ini)
// Add a comma before additional sections // Add a comma before additional sections
if (sectionIdx != 0) if (sectionIdx != 0)
cryptoHashProcessC(hash, (const unsigned char *)",", 1); ioFilterProcessIn(hash, BUFSTRDEF(","));
// Create the section header // Create the section header
cryptoHashProcessC(hash, (const unsigned char *)"\"", 1); ioFilterProcessIn(hash, BUFSTRDEF("\""));
cryptoHashProcessStr(hash, section); ioFilterProcessIn(hash, BUFSTR(section));
cryptoHashProcessC(hash, (const unsigned char *)"\":{", 3); ioFilterProcessIn(hash, BUFSTRDEF("\":{"));
StringList *keyList = strLstSort(iniSectionKeyList(ini, section), sortOrderAsc); StringList *keyList = strLstSort(iniSectionKeyList(ini, section), sortOrderAsc);
unsigned int keyListSize = strLstSize(keyList); 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)) || if ((strEq(section, INFO_SECTION_BACKREST_STR) && !strEq(key, INFO_KEY_CHECKSUM_STR)) ||
!strEq(section, INFO_SECTION_BACKREST_STR)) !strEq(section, INFO_SECTION_BACKREST_STR))
{ {
cryptoHashProcessC(hash, (const unsigned char *)"\"", 1); ioFilterProcessIn(hash, BUFSTRDEF("\""));
cryptoHashProcessStr(hash, key); ioFilterProcessIn(hash, BUFSTR(key));
cryptoHashProcessC(hash, (const unsigned char *)"\":", 2); ioFilterProcessIn(hash, BUFSTRDEF("\":"));
cryptoHashProcessStr(hash, iniGet(ini, section, strLstGet(keyList, keyIdx))); ioFilterProcessIn(hash, BUFSTR(iniGet(ini, section, strLstGet(keyList, keyIdx))));
if ((keyListSize > 1) && (keyIdx < keyListSize - 1)) if ((keyListSize > 1) && (keyIdx < keyListSize - 1))
cryptoHashProcessC(hash, (const unsigned char *)",", 1); ioFilterProcessIn(hash, BUFSTRDEF(","));
} }
} }
// Close the key/value list // Close the key/value list
cryptoHashProcessC(hash, (const unsigned char *)"}", 1); ioFilterProcessIn(hash, BUFSTRDEF("}"));
} }
// JSON closing bracket // JSON closing bracket
cryptoHashProcessC(hash, (const unsigned char *)"}", 1); ioFilterProcessIn(hash, BUFSTRDEF("}"));
Variant *resultVar = ioFilterResult(hash);
memContextSwitch(MEM_CONTEXT_OLD()); memContextSwitch(MEM_CONTEXT_OLD());
result = bufHex(cryptoHash(hash)); result = strDup(varStr(resultVar));
memContextSwitch(MEM_CONTEXT_TEMP()); memContextSwitch(MEM_CONTEXT_TEMP());
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
@ -145,9 +148,7 @@ infoLoad(Info *this, const Storage *storage, const String *fileName, bool copyFi
{ {
ioReadFilterGroupSet( ioReadFilterGroupSet(
storageFileReadIo(infoRead), storageFileReadIo(infoRead),
ioFilterGroupAdd( ioFilterGroupAdd(ioFilterGroupNew(), cipherBlockNew(cipherModeDecrypt, cipherType, BUFSTR(cipherPass), NULL)));
ioFilterGroupNew(), cipherBlockFilter(cipherBlockNew(cipherModeDecrypt, cipherType, BUFSTR(cipherPass),
NULL))));
} }
// Load and parse the info file // Load and parse the info file
@ -333,9 +334,7 @@ infoSave(
{ {
ioWriteFilterGroupSet( ioWriteFilterGroupSet(
infoWrite, infoWrite,
ioFilterGroupAdd( ioFilterGroupAdd(ioFilterGroupNew(), cipherBlockNew(cipherModeEncrypt, cipherType, BUFSTR(cipherPass), NULL)));
ioFilterGroupNew(), cipherBlockFilter(cipherBlockNew(cipherModeEncrypt, cipherType, BUFSTR(cipherPass),
NULL))));
} }
iniSave(ini, infoWrite); iniSave(ini, infoWrite);

View File

@ -289,7 +289,9 @@ XS_EUPXS(XS_pgBackRest__LibC_storageDriverPosixPathRemove)
; ;
MEM_CONTEXT_XS_TEMP_BEGIN() 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(); MEM_CONTEXT_XS_TEMP_END();
} }
@ -482,9 +484,10 @@ XS_EUPXS(XS_pgBackRest__LibC__Crypto__Hash_process)
MEM_CONTEXT_XS_TEMP_BEGIN() MEM_CONTEXT_XS_TEMP_BEGIN()
{ {
STRLEN messageSize; 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(); MEM_CONTEXT_XS_TEMP_END();
} }
@ -515,7 +518,7 @@ XS_EUPXS(XS_pgBackRest__LibC__Crypto__Hash_result)
MEM_CONTEXT_XS_TEMP_BEGIN() MEM_CONTEXT_XS_TEMP_BEGIN()
{ {
String *hash = bufHex(cryptoHash(self->pxPayload)); const String *hash = varStr(ioFilterResult(self->pxPayload));
RETVAL = newSV(strSize(hash)); RETVAL = newSV(strSize(hash));
SvPOK_only(RETVAL); SvPOK_only(RETVAL);
@ -571,9 +574,9 @@ XS_EUPXS(XS_pgBackRest__LibC_cryptoHashOne)
MEM_CONTEXT_XS_TEMP_BEGIN() MEM_CONTEXT_XS_TEMP_BEGIN()
{ {
STRLEN messageSize; 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)); RETVAL = newSV(strSize(hash));
SvPOK_only(RETVAL); SvPOK_only(RETVAL);
@ -619,6 +622,10 @@ XS_EUPXS(XS_pgBackRest__LibC__Cipher__Block_new)
} }
RETVAL = NULL; RETVAL = NULL;
CHECK(type != NULL);
CHECK(key != NULL);
CHECK(keySize != 0);
// Not much point to this but it keeps the var from being unused // Not much point to this but it keeps the var from being unused
if (strcmp(class, PACKAGE_NAME_LIBC "::Cipher::Block") != 0) if (strcmp(class, PACKAGE_NAME_LIBC "::Cipher::Block") != 0)
croak("unexpected class name '%s'", class); croak("unexpected class name '%s'", class);
@ -626,10 +633,9 @@ XS_EUPXS(XS_pgBackRest__LibC__Cipher__Block_new)
MEM_CONTEXT_XS_NEW_BEGIN("cipherBlockXs") MEM_CONTEXT_XS_NEW_BEGIN("cipherBlockXs")
{ {
RETVAL = memNew(sizeof(CipherBlockXs)); RETVAL = memNew(sizeof(CipherBlockXs));
RETVAL->memContext = MEM_COMTEXT_XS(); 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(); MEM_CONTEXT_XS_NEW_END();
{ {
@ -671,10 +677,27 @@ XS_EUPXS(XS_pgBackRest__LibC__Cipher__Block_process)
STRLEN tSize; STRLEN tSize;
const unsigned char *sourcePtr = (const unsigned char *)SvPV(source, 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); 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(); MEM_CONTEXT_XS_END();
RETVAL = sv_2mortal(RETVAL); RETVAL = sv_2mortal(RETVAL);
@ -707,10 +730,22 @@ XS_EUPXS(XS_pgBackRest__LibC__Cipher__Block_flush)
MEM_CONTEXT_XS_BEGIN(self->memContext) MEM_CONTEXT_XS_BEGIN(self->memContext)
{ {
RETVAL = NEWSV(0, cipherBlockProcessSizeC(self->pxPayload, 0)); RETVAL = NEWSV(0, ioBufferSize());
SvPOK_only(RETVAL); 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(); MEM_CONTEXT_XS_END();
RETVAL = sv_2mortal(RETVAL); RETVAL = sv_2mortal(RETVAL);

View File

@ -8,28 +8,17 @@ CIFS Storage Driver
#include "common/memContext.h" #include "common/memContext.h"
#include "common/regExp.h" #include "common/regExp.h"
#include "storage/driver/cifs/storage.h" #include "storage/driver/cifs/storage.h"
#include "storage/driver/posix/storage.h" #include "storage/driver/posix/storage.intern.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Driver type constant string Driver type constant string
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
STRING_EXTERN(STORAGE_DRIVER_CIFS_TYPE_STR, STORAGE_DRIVER_CIFS_TYPE); 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 New object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverCifs * Storage *
storageDriverCifsNew( storageDriverCifsNew(
const String *path, mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction) 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_PARAM(FUNCTIONP, pathExpressionFunction);
FUNCTION_LOG_END(); 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( FUNCTION_LOG_RETURN(
STORAGE_FILE_WRITE, STORAGE,
storageDriverPosixFileWriteInterface( storageDriverPosixNewInternal(
storageDriverPosixFileWriteNew( STORAGE_DRIVER_CIFS_TYPE_STR, path, modeFile, modePath, write, pathExpressionFunction, false));
(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();
} }

View File

@ -4,18 +4,6 @@ CIFS Storage Driver
#ifndef STORAGE_DRIVER_CIFS_STORAGE_H #ifndef STORAGE_DRIVER_CIFS_STORAGE_H
#define 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" #include "storage/storage.intern.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@ -27,33 +15,7 @@ Driver type constant
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverCifs *storageDriverCifsNew( Storage *storageDriverCifsNew(
const String *path, mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction); 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 #endif

View File

@ -10,77 +10,90 @@ Posix Storage File Read Driver
#include "common/io/read.intern.h" #include "common/io/read.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
#include "storage/driver/posix/common.h" #include "storage/driver/posix/common.h"
#include "storage/driver/posix/fileRead.h" #include "storage/driver/posix/fileRead.h"
#include "storage/driver/posix/storage.intern.h"
#include "storage/fileRead.intern.h" #include "storage/fileRead.intern.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object types
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct StorageDriverPosixFileRead typedef struct StorageFileReadDriverPosix
{ {
MemContext *memContext; MemContext *memContext; // Object mem context
StorageDriverPosix *storage; StorageFileReadInterface interface; // Driver interface
StorageFileRead *interface; StorageDriverPosix *storage; // Storage that created this object
IoRead *io;
String *name;
bool ignoreMissing;
int handle; int handle;
bool eof; bool eof;
}; } StorageFileReadDriverPosix;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Create a new file Macros for function logging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverPosixFileRead * #define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_POSIX_TYPE \
storageDriverPosixFileReadNew(StorageDriverPosix *storage, const String *name, bool ignoreMissing) 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_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, name); FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
ASSERT(name != NULL); ASSERT(this != NULL);
StorageDriverPosixFileRead *this = NULL; // Close if the file has not already been closed
if (this->handle != -1)
// Create the file object
MEM_CONTEXT_NEW_BEGIN("StorageDriverPosixFileRead")
{ {
this = memNew(sizeof(StorageDriverPosixFileRead)); // Close the file
this->memContext = MEM_CONTEXT_NEW(); storageDriverPosixFileClose(this->handle, this->interface.name, true);
this->storage = storage;
this->name = strDup(name);
this->ignoreMissing = ignoreMissing;
this->handle = -1; 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 Open the file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this) storageFileReadDriverPosixOpen(THIS_VOID)
{ {
THIS(StorageFileReadDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace); 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(); FUNCTION_LOG_END();
ASSERT(this != NULL); ASSERT(this != NULL);
@ -89,12 +102,12 @@ storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this)
bool result = false; bool result = false;
// Open the file and handle errors // 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 // On success set free callback to ensure file handle is freed
if (this->handle != -1) if (this->handle != -1)
{ {
memContextCallback(this->memContext, (MemContextCallback)storageDriverPosixFileReadFree, this); memContextCallback(this->memContext, (MemContextCallback)storageFileReadDriverPosixFree, this);
result = true; result = true;
} }
@ -104,11 +117,13 @@ storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Read from a file Read from a file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
size_t static size_t
storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, bool block) storageFileReadDriverPosix(THIS_VOID, Buffer *buffer, bool block)
{ {
THIS(StorageFileReadDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace); 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(BUFFER, buffer);
FUNCTION_LOG_PARAM(BOOL, block); FUNCTION_LOG_PARAM(BOOL, block);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
@ -127,7 +142,7 @@ storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, boo
// Error occurred during read // Error occurred during read
if (actualBytes == -1) 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 // Update amount of buffer used
bufUsedInc(buffer, (size_t)actualBytes); bufUsedInc(buffer, (size_t)actualBytes);
@ -141,38 +156,16 @@ storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, boo
FUNCTION_LOG_RETURN(SIZE, (size_t)actualBytes); 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? Has file reached EOF?
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
storageDriverPosixFileReadEof(const StorageDriverPosixFileRead *this) storageFileReadDriverPosixEof(THIS_VOID)
{ {
THIS(StorageFileReadDriverPosix);
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this); FUNCTION_TEST_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
ASSERT(this != NULL); ASSERT(this != NULL);
@ -183,11 +176,13 @@ storageDriverPosixFileReadEof(const StorageDriverPosixFileRead *this)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Get handle (file descriptor) Get handle (file descriptor)
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
int static int
storageDriverPosixFileReadHandle(const StorageDriverPosixFileRead *this) storageFileReadDriverPosixHandle(const THIS_VOID)
{ {
THIS(const StorageFileReadDriverPosix);
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this); FUNCTION_TEST_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
ASSERT(this != NULL); ASSERT(this != NULL);
@ -196,82 +191,46 @@ storageDriverPosixFileReadHandle(const StorageDriverPosixFileRead *this)
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Should a missing file be ignored? New object
***********************************************************************************************************************************/
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
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageFileRead * StorageFileRead *
storageDriverPosixFileReadInterface(const StorageDriverPosixFileRead *this) storageFileReadDriverPosixNew(StorageDriverPosix *storage, const String *name, bool ignoreMissing)
{
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)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); 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(); 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); driver->interface = (StorageFileReadInterface)
memContextFree(this->memContext); {
.type = STORAGE_DRIVER_POSIX_TYPE_STR,
.name = strDup(name),
.ignoreMissing = ignoreMissing,
.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_VOID(); FUNCTION_LOG_RETURN(STORAGE_FILE_READ, this);
} }

View File

@ -4,49 +4,12 @@ Posix Storage File Read Driver
#ifndef STORAGE_DRIVER_POSIX_FILEREAD_H #ifndef STORAGE_DRIVER_POSIX_FILEREAD_H
#define 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/driver/posix/storage.h"
#include "storage/fileRead.h" #include "storage/fileRead.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverPosixFileRead *storageDriverPosixFileReadNew(StorageDriverPosix *storage, const String *name, bool ignoreMissing); StorageFileRead *storageFileReadDriverPosixNew(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)
#endif #endif

View File

@ -14,36 +14,33 @@ Posix Storage File Write Driver
#include "common/io/write.intern.h" #include "common/io/write.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
#include "storage/driver/posix/common.h" #include "storage/driver/posix/common.h"
#include "storage/driver/posix/fileWrite.h" #include "storage/driver/posix/fileWrite.h"
#include "storage/driver/posix/storage.intern.h"
#include "storage/fileWrite.intern.h" #include "storage/fileWrite.intern.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct StorageDriverPosixFileWrite typedef struct StorageFileWriteDriverPosix
{ {
MemContext *memContext; MemContext *memContext; // Object mem context
StorageDriverPosix *storage; StorageFileWriteInterface interface; // Driver interface
StorageFileWrite *interface; StorageDriverPosix *storage; // Storage that created this object
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;
const String *nameTmp;
const String *path;
int handle; 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 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" #define FILE_OPEN_PURPOSE "write"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Create a new file Close the file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverPosixFileWrite * static void
storageDriverPosixFileWriteNew( 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, 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) time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
{ {
@ -80,357 +262,44 @@ storageDriverPosixFileWriteNew(
ASSERT(modeFile != 0); ASSERT(modeFile != 0);
ASSERT(modePath != 0); ASSERT(modePath != 0);
StorageDriverPosixFileWrite *this = NULL; StorageFileWrite *this = NULL;
// Create the file MEM_CONTEXT_NEW_BEGIN("StorageFileWriteDriverPosix")
MEM_CONTEXT_NEW_BEGIN("StorageDriverPosixFileWrite")
{ {
this = memNew(sizeof(StorageDriverPosixFileWrite)); StorageFileWriteDriverPosix *driver = memNew(sizeof(StorageFileWriteDriverPosix));
this->memContext = MEM_CONTEXT_NEW(); driver->memContext = MEM_CONTEXT_NEW();
this->storage = storage;
this->interface = storageFileWriteNewP( driver->interface = (StorageFileWriteInterface)
STORAGE_DRIVER_POSIX_TYPE_STR, this, .atomic = (StorageFileWriteInterfaceAtomic)storageDriverPosixFileWriteAtomic, {
.createPath = (StorageFileWriteInterfaceCreatePath)storageDriverPosixFileWriteCreatePath, .type = STORAGE_DRIVER_POSIX_TYPE_STR,
.io = (StorageFileWriteInterfaceIo)storageDriverPosixFileWriteIo, .name = strDup(name),
.modeFile = (StorageFileWriteInterfaceModeFile)storageDriverPosixFileWriteModeFile, .atomic = atomic,
.modePath = (StorageFileWriteInterfaceModePath)storageDriverPosixFileWriteModePath, .createPath = createPath,
.name = (StorageFileWriteInterfaceName)storageDriverPosixFileWriteName, .group = strDup(group),
.syncFile = (StorageFileWriteInterfaceSyncFile)storageDriverPosixFileWriteSyncFile, .modeFile = modeFile,
.syncPath = (StorageFileWriteInterfaceSyncPath)storageDriverPosixFileWriteSyncPath); .modePath = modePath,
.syncFile = syncFile,
.syncPath = syncPath,
.user = strDup(user),
.timeModified = timeModified,
this->io = ioWriteNewP( .ioInterface = (IoWriteInterface)
this, .close = (IoWriteInterfaceClose)storageDriverPosixFileWriteClose, {
.handle = (IoWriteInterfaceHandle)storageDriverPosixFileWriteHandle, .close = storageFileWriteDriverPosixClose,
.open = (IoWriteInterfaceOpen)storageDriverPosixFileWriteOpen, .handle = storageFileWriteDriverPosixHandle,
.write = (IoWriteInterfaceWrite)storageDriverPosixFileWrite); .open = storageFileWriteDriverPosixOpen,
.write = storageFileWriteDriverPosix,
},
};
this->path = strPath(name); driver->storage = storage;
this->name = strDup(name); driver->nameTmp = atomic ? strNewFmt("%s." STORAGE_FILE_TEMP_EXT, strPtr(name)) : driver->interface.name;
this->nameTmp = atomic ? strNewFmt("%s." STORAGE_FILE_TEMP_EXT, strPtr(name)) : this->name; driver->path = strPath(name);
this->modeFile = modeFile; driver->handle = -1;
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;
this->handle = -1; this = storageFileWriteNew(driver, &driver->interface);
} }
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
FUNCTION_LOG_RETURN(STORAGE_DRIVER_POSIX_FILE_WRITE, this); FUNCTION_LOG_RETURN(STORAGE_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();
} }

View File

@ -4,57 +4,15 @@ Posix Storage File Write Driver
#ifndef STORAGE_DRIVER_POSIX_FILEWRITE_H #ifndef STORAGE_DRIVER_POSIX_FILEWRITE_H
#define STORAGE_DRIVER_POSIX_FILEWRITE_H #define STORAGE_DRIVER_POSIX_FILEWRITE_H
#include <sys/types.h> #include "storage/fileWrite.intern.h"
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
typedef struct StorageDriverPosixFileWrite StorageDriverPosixFileWrite;
#include "common/type/buffer.h"
#include "storage/driver/posix/storage.h" #include "storage/driver/posix/storage.h"
#include "storage/fileWrite.h" #include "storage/fileWrite.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverPosixFileWrite *storageDriverPosixFileWriteNew( StorageFileWrite *storageFileWriteDriverPosixNew(
StorageDriverPosix *storage, const String *name, mode_t modeFile, mode_t modePath, const String *user, const String *group, 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); 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 #endif

View File

@ -7,6 +7,7 @@ Posix Storage Driver
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <grp.h> #include <grp.h>
#include <limits.h>
#include <pwd.h> #include <pwd.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -17,16 +18,11 @@ Posix Storage Driver
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/regExp.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" #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 Driver type constant string
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@ -38,58 +34,17 @@ Object type
struct StorageDriverPosix struct StorageDriverPosix
{ {
MemContext *memContext; // Object memory context 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. Does a file exist? This function is only for files, not paths.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
storageDriverPosixExists(StorageDriverPosix *this, const String *path) storageDriverPosixExists(THIS_VOID, const String *path)
{ {
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -119,9 +74,11 @@ storageDriverPosixExists(StorageDriverPosix *this, const String *path)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
File/path info File/path info
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageInfo static StorageInfo
storageDriverPosixInfo(StorageDriverPosix *this, const String *file, bool ignoreMissing, bool followLink) storageDriverPosixInfo(THIS_VOID, const String *file, bool ignoreMissing, bool followLink)
{ {
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, file); FUNCTION_LOG_PARAM(STRING, file);
@ -227,10 +184,12 @@ storageDriverPosixInfoListEntry(
FUNCTION_TEST_RETURN_VOID(); FUNCTION_TEST_RETURN_VOID();
} }
bool static bool
storageDriverPosixInfoList( 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_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -292,9 +251,11 @@ storageDriverPosixInfoList(
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Get a list of files from a directory Get a list of files from a directory
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StringList * static StringList *
storageDriverPosixList(StorageDriverPosix *this, const String *path, bool errorOnMissing, const String *expression) storageDriverPosixList(THIS_VOID, const String *path, bool errorOnMissing, const String *expression)
{ {
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -362,13 +323,15 @@ storageDriverPosixList(StorageDriverPosix *this, const String *path, bool errorO
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Move a path/file Move a path/file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *source, StorageDriverPosixFileWrite *destination) storageDriverPosixMove(THIS_VOID, StorageFileRead *source, StorageFileWrite *destination)
{ {
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, source); FUNCTION_LOG_PARAM(STORAGE_FILE_READ, source);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, destination); FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE, destination);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
ASSERT(this != NULL); ASSERT(this != NULL);
@ -379,8 +342,8 @@ storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *sou
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
const String *sourceFile = storageDriverPosixFileReadName(source); const String *sourceFile = storageFileReadName(source);
const String *destinationFile = storageDriverPosixFileWriteName(destination); const String *destinationFile = storageFileWriteName(destination);
const String *destinationPath = strPath(destinationFile); const String *destinationPath = strPath(destinationFile);
// Attempt to move the file // Attempt to move the file
@ -392,13 +355,13 @@ storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *sou
if (!storageDriverPosixExists(this, sourceFile)) if (!storageDriverPosixExists(this, sourceFile))
THROW_SYS_ERROR_FMT(FileMissingError, "unable to move missing file '%s'", strPtr(sourceFile)); THROW_SYS_ERROR_FMT(FileMissingError, "unable to move missing file '%s'", strPtr(sourceFile));
if (!storageDriverPosixFileWriteCreatePath(destination)) if (!storageFileWriteCreatePath(destination))
{ {
THROW_SYS_ERROR_FMT( THROW_SYS_ERROR_FMT(
PathMissingError, "unable to move '%s' to missing path '%s'", strPtr(sourceFile), strPtr(destinationPath)); 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); result = storageDriverPosixMove(this, source, destination);
} }
// Else the destination is on a different device so a copy will be needed // Else the destination is on a different device so a copy will be needed
@ -413,7 +376,7 @@ storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *sou
else else
{ {
// Sync source path if the destination path was synced and the paths are not equal // 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); String *sourcePath = strPath(sourceFile);
@ -430,9 +393,11 @@ storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *sou
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New file read object New file read object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageFileRead * static StorageFileRead *
storageDriverPosixNewRead(StorageDriverPosix *this, const String *file, bool ignoreMissing) storageDriverPosixNewRead(THIS_VOID, const String *file, bool ignoreMissing)
{ {
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, file); FUNCTION_LOG_PARAM(STRING, file);
@ -442,18 +407,19 @@ storageDriverPosixNewRead(StorageDriverPosix *this, const String *file, bool ign
ASSERT(this != NULL); ASSERT(this != NULL);
ASSERT(file != NULL); ASSERT(file != NULL);
FUNCTION_LOG_RETURN( FUNCTION_LOG_RETURN(STORAGE_FILE_READ, storageFileReadDriverPosixNew(this, file, ignoreMissing));
STORAGE_FILE_READ, storageDriverPosixFileReadInterface(storageDriverPosixFileReadNew(this, file, ignoreMissing)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New file write object New file write object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageFileWrite * static StorageFileWrite *
storageDriverPosixNewWrite( 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) time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
{ {
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, file); FUNCTION_LOG_PARAM(STRING, file);
@ -473,17 +439,19 @@ storageDriverPosixNewWrite(
FUNCTION_LOG_RETURN( FUNCTION_LOG_RETURN(
STORAGE_FILE_WRITE, STORAGE_FILE_WRITE,
storageDriverPosixFileWriteInterface( storageFileWriteDriverPosixNew(
storageDriverPosixFileWriteNew( this, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, this->syncPath ? syncPath : false,
this, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, syncPath, atomic))); atomic));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Create a path Create a path
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void 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_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -515,9 +483,11 @@ storageDriverPosixPathCreate(StorageDriverPosix *this, const String *path, bool
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Remove a path Remove a path
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverPosixPathRemove(StorageDriverPosix *this, const String *path, bool errorOnMissing, bool recurse) storageDriverPosixPathRemove(THIS_VOID, const String *path, bool errorOnMissing, bool recurse)
{ {
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -574,8 +544,10 @@ storageDriverPosixPathRemove(StorageDriverPosix *this, const String *path, bool
Sync a path Sync a path
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void 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_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -585,17 +557,20 @@ storageDriverPosixPathSync(StorageDriverPosix *this, const String *path, bool ig
ASSERT(this != NULL); ASSERT(this != NULL);
ASSERT(path != NULL); ASSERT(path != NULL);
// Open directory and handle errors if (this->syncPath)
int handle = storageDriverPosixFileOpen(path, O_RDONLY, 0, ignoreMissing, false, "sync");
// On success
if (handle != -1)
{ {
// Attempt to sync the directory // Open directory and handle errors
storageDriverPosixFileSync(handle, path, false, true); int handle = storageDriverPosixFileOpen(path, O_RDONLY, 0, ignoreMissing, false, "sync");
// Close the directory // On success
storageDriverPosixFileClose(handle, path, false); if (handle != -1)
{
// Attempt to sync the directory
storageDriverPosixFileSync(handle, path, false, true);
// Close the directory
storageDriverPosixFileClose(handle, path, false);
}
} }
FUNCTION_LOG_RETURN_VOID(); FUNCTION_LOG_RETURN_VOID();
@ -604,9 +579,11 @@ storageDriverPosixPathSync(StorageDriverPosix *this, const String *path, bool ig
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Remove a file Remove a file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverPosixRemove(StorageDriverPosix *this, const String *file, bool errorOnMissing) storageDriverPosixRemove(THIS_VOID, const String *file, bool errorOnMissing)
{ {
THIS(StorageDriverPosix);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_PARAM(STRING, file); FUNCTION_LOG_PARAM(STRING, file);
@ -627,32 +604,63 @@ storageDriverPosixRemove(StorageDriverPosix *this, const String *file, bool erro
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Getters New object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
Storage * 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_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this); FUNCTION_LOG_PARAM(STRING, type);
FUNCTION_TEST_END(); FUNCTION_LOG_PARAM(STRING, path);
FUNCTION_LOG_PARAM(MODE, modeFile);
ASSERT(this != NULL); FUNCTION_LOG_PARAM(MODE, modePath);
FUNCTION_LOG_PARAM(BOOL, write);
FUNCTION_TEST_RETURN(this->interface); FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
} FUNCTION_LOG_PARAM(BOOL, syncPath);
/***********************************************************************************************************************************
Free the file
***********************************************************************************************************************************/
void
storageDriverPosixFree(StorageDriverPosix *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
if (this != NULL) ASSERT(type != NULL);
memContextFree(this->memContext); 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; 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" #include "storage/storage.intern.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@ -27,44 +20,7 @@ Driver type constant
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverPosix *storageDriverPosixNew( Storage *storageDriverPosixNew(
const String *path, mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction); 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 #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/io/read.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
#include "common/type/convert.h" #include "common/type/convert.h"
#include "storage/driver/remote/fileRead.h" #include "storage/driver/remote/fileRead.h"
#include "storage/driver/remote/protocol.h" #include "storage/driver/remote/protocol.h"
@ -18,73 +19,35 @@ Remote Storage File Read Driver
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct StorageDriverRemoteFileRead typedef struct StorageFileReadDriverRemote
{ {
MemContext *memContext; MemContext *memContext; // Object mem context
StorageDriverRemote *storage; StorageFileReadInterface interface; // Driver interface
StorageFileRead *interface; StorageDriverRemote *storage; // Storage that created this object
IoRead *io;
String *name;
bool ignoreMissing;
ProtocolClient *client; // Protocol client for requests 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? bool eof; // Has the file reached eof?
}; } StorageFileReadDriverRemote;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Create a new file Macros for function logging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverRemoteFileRead * #define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_REMOTE_TYPE \
storageDriverRemoteFileReadNew(StorageDriverRemote *storage, ProtocolClient *client, const String *name, bool ignoreMissing) StorageFileReadDriverRemote *
{ #define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_REMOTE_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_BEGIN(logLevelTrace); objToLog(value, "StorageFileReadDriverRemote", buffer, bufferSize)
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);
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Open the file Open the file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
storageDriverRemoteFileReadOpen(StorageDriverRemoteFileRead *this) storageFileReadDriverRemoteOpen(THIS_VOID)
{ {
THIS(StorageFileReadDriverRemote);
FUNCTION_LOG_BEGIN(logLevelTrace); 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(); FUNCTION_LOG_END();
ASSERT(this != NULL); ASSERT(this != NULL);
@ -94,8 +57,8 @@ storageDriverRemoteFileReadOpen(StorageDriverRemoteFileRead *this)
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
ProtocolCommand *command = protocolCommandNew(PROTOCOL_COMMAND_STORAGE_OPEN_READ_STR); ProtocolCommand *command = protocolCommandNew(PROTOCOL_COMMAND_STORAGE_OPEN_READ_STR);
protocolCommandParamAdd(command, VARSTR(this->name)); protocolCommandParamAdd(command, VARSTR(this->interface.name));
protocolCommandParamAdd(command, VARBOOL(this->ignoreMissing)); protocolCommandParamAdd(command, VARBOOL(this->interface.ignoreMissing));
result = varBool(protocolClientExecute(this->client, command, true)); result = varBool(protocolClientExecute(this->client, command, true));
} }
@ -107,11 +70,13 @@ storageDriverRemoteFileReadOpen(StorageDriverRemoteFileRead *this)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Read from a file Read from a file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
size_t static size_t
storageDriverRemoteFileRead(StorageDriverRemoteFileRead *this, Buffer *buffer, bool block) storageFileReadDriverRemote(THIS_VOID, Buffer *buffer, bool block)
{ {
THIS(StorageFileReadDriverRemote);
FUNCTION_LOG_BEGIN(logLevelTrace); 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(BUFFER, buffer);
FUNCTION_LOG_PARAM(BOOL, block); FUNCTION_LOG_PARAM(BOOL, block);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
@ -164,11 +129,13 @@ storageDriverRemoteFileRead(StorageDriverRemoteFileRead *this, Buffer *buffer, b
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Has file reached EOF? Has file reached EOF?
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
storageDriverRemoteFileReadEof(const StorageDriverRemoteFileRead *this) storageFileReadDriverRemoteEof(THIS_VOID)
{ {
THIS(StorageFileReadDriverRemote);
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this); FUNCTION_TEST_PARAM(STORAGE_FILE_READ_DRIVER_REMOTE, this);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
ASSERT(this != NULL); ASSERT(this != NULL);
@ -177,61 +144,49 @@ storageDriverRemoteFileReadEof(const StorageDriverRemoteFileRead *this)
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Should a missing file be ignored? New object
***********************************************************************************************************************************/
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
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageFileRead * StorageFileRead *
storageDriverRemoteFileReadInterface(const StorageDriverRemoteFileRead *this) storageFileReadDriverRemoteNew(StorageDriverRemote *storage, ProtocolClient *client, const String *name, bool ignoreMissing)
{ {
FUNCTION_TEST_BEGIN(); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, storage);
FUNCTION_TEST_END(); 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;
}
MEM_CONTEXT_NEW_BEGIN("StorageFileReadDriverRemote")
/*********************************************************************************************************************************** {
Get the I/O interface StorageFileReadDriverRemote *driver = memNew(sizeof(StorageFileReadDriverRemote));
***********************************************************************************************************************************/ driver->memContext = MEM_CONTEXT_NEW();
IoRead *
storageDriverRemoteFileReadIo(const StorageDriverRemoteFileRead *this) driver->interface = (StorageFileReadInterface)
{ {
FUNCTION_TEST_BEGIN(); .type = STORAGE_DRIVER_REMOTE_TYPE_STR,
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this); .name = strDup(name),
FUNCTION_TEST_END(); .ignoreMissing = ignoreMissing,
ASSERT(this != NULL); .ioInterface = (IoReadInterface)
{
FUNCTION_TEST_RETURN(this->io); .eof = storageFileReadDriverRemoteEof,
} .open = storageFileReadDriverRemoteOpen,
.read = storageFileReadDriverRemote,
/*********************************************************************************************************************************** },
File name };
***********************************************************************************************************************************/
const String * driver->storage = storage;
storageDriverRemoteFileReadName(const StorageDriverRemoteFileRead *this) driver->client = client;
{
FUNCTION_TEST_BEGIN(); this = storageFileReadNew(driver, &driver->interface);
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this); }
FUNCTION_TEST_END(); MEM_CONTEXT_NEW_END();
ASSERT(this != NULL); FUNCTION_LOG_RETURN(STORAGE_FILE_READ, this);
FUNCTION_TEST_RETURN(this->name);
} }

View File

@ -4,49 +4,14 @@ Remote Storage File Read Driver
#ifndef STORAGE_DRIVER_REMOTE_FILEREAD_H #ifndef STORAGE_DRIVER_REMOTE_FILEREAD_H
#define 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 "protocol/client.h"
#include "storage/driver/remote/storage.h" #include "storage/driver/remote/storage.intern.h"
#include "storage/fileRead.h" #include "storage/fileRead.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverRemoteFileRead *storageDriverRemoteFileReadNew( StorageFileRead *storageFileReadDriverRemoteNew(
StorageDriverRemote *storage, ProtocolClient *client, const String *name, bool ignoreMissing); 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 #endif

View File

@ -7,6 +7,7 @@ Remote Storage File Write Driver
#include "common/io/write.intern.h" #include "common/io/write.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
#include "storage/driver/remote/fileWrite.h" #include "storage/driver/remote/fileWrite.h"
#include "storage/driver/remote/protocol.h" #include "storage/driver/remote/protocol.h"
#include "storage/fileWrite.intern.h" #include "storage/fileWrite.intern.h"
@ -14,157 +15,32 @@ Remote Storage File Write Driver
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct StorageDriverRemoteFileWrite typedef struct StorageFileWriteDriverRemote
{ {
MemContext *memContext; MemContext *memContext; // Object mem context
StorageDriverRemote *storage; StorageFileWriteInterface interface; // Driver interface
ProtocolClient *client; StorageDriverRemote *storage; // Storage that created this object
StorageFileWrite *interface; ProtocolClient *client; // Protocol client to make requests with
IoWrite *io; } StorageFileWriteDriverRemote;
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;
};
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Create a new file Macros for function logging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverRemoteFileWrite * #define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_REMOTE_TYPE \
storageDriverRemoteFileWriteNew( StorageFileWriteDriverRemote *
StorageDriverRemote *storage, ProtocolClient *client, const String *name, mode_t modeFile, mode_t modePath, const String *user, #define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_REMOTE_FORMAT(value, buffer, bufferSize) \
const String *group, time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic) objToLog(value, "StorageFileWriteDriverRemote", buffer, bufferSize)
{
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();
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Close the file Close the file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverRemoteFileWriteClose(StorageDriverRemoteFileWrite *this) storageFileWriteDriverRemoteClose(THIS_VOID)
{ {
THIS(StorageFileWriteDriverRemote);
FUNCTION_LOG_BEGIN(logLevelTrace); 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(); FUNCTION_LOG_END();
ASSERT(this != NULL); ASSERT(this != NULL);
@ -182,149 +58,14 @@ storageDriverRemoteFileWriteClose(StorageDriverRemoteFileWrite *this)
FUNCTION_LOG_RETURN_VOID(); 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 Free the file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverRemoteFileWriteFree(StorageDriverRemoteFileWrite *this) storageFileWriteDriverRemoteFree(StorageFileWriteDriverRemote *this)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); 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(); FUNCTION_LOG_END();
if (this != NULL) if (this != NULL)
@ -346,3 +87,131 @@ storageDriverRemoteFileWriteFree(StorageDriverRemoteFileWrite *this)
FUNCTION_LOG_RETURN_VOID(); 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 #ifndef STORAGE_DRIVER_REMOTE_FILEWRITE_H
#define 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 "protocol/client.h"
#include "storage/driver/remote/storage.h" #include "storage/driver/remote/storage.intern.h"
#include "storage/fileWrite.h" #include "storage/fileWrite.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverRemoteFileWrite *storageDriverRemoteFileWriteNew( StorageFileWrite *storageFileWriteDriverRemoteNew(
StorageDriverRemote *storage, ProtocolClient *client, const String *name, mode_t modeFile, mode_t modePath, const String *user, 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); 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 #endif

View File

@ -6,12 +6,11 @@ Remote Storage Driver
#include "common/debug.h" #include "common/debug.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "protocol/client.h" #include "common/object.h"
#include "protocol/helper.h"
#include "storage/driver/remote/fileRead.h" #include "storage/driver/remote/fileRead.h"
#include "storage/driver/remote/fileWrite.h" #include "storage/driver/remote/fileWrite.h"
#include "storage/driver/remote/protocol.h" #include "storage/driver/remote/protocol.h"
#include "storage/driver/remote/storage.h" #include "storage/driver/remote/storage.intern.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Driver type constant string Driver type constant string
@ -24,61 +23,17 @@ Object type
struct StorageDriverRemote struct StorageDriverRemote
{ {
MemContext *memContext; MemContext *memContext;
Storage *interface; // Driver interface
ProtocolClient *client; // Protocol client 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. Does a file exist? This function is only for files, not paths.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
storageDriverRemoteExists(StorageDriverRemote *this, const String *path) storageDriverRemoteExists(THIS_VOID, const String *path)
{ {
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -104,9 +59,11 @@ storageDriverRemoteExists(StorageDriverRemote *this, const String *path)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
File/path info File/path info
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageInfo static StorageInfo
storageDriverRemoteInfo(StorageDriverRemote *this, const String *file, bool ignoreMissing, bool followLink) storageDriverRemoteInfo(THIS_VOID, const String *file, bool ignoreMissing, bool followLink)
{ {
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, file); 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 Get a list of files from a directory
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StringList * static StringList *
storageDriverRemoteList(StorageDriverRemote *this, const String *path, bool errorOnMissing, const String *expression) storageDriverRemoteList(THIS_VOID, const String *path, bool errorOnMissing, const String *expression)
{ {
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -157,9 +116,11 @@ storageDriverRemoteList(StorageDriverRemote *this, const String *path, bool erro
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New file read object New file read object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageFileRead * static StorageFileRead *
storageDriverRemoteNewRead(StorageDriverRemote *this, const String *file, bool ignoreMissing) storageDriverRemoteNewRead(THIS_VOID, const String *file, bool ignoreMissing)
{ {
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, file); FUNCTION_LOG_PARAM(STRING, file);
@ -168,19 +129,19 @@ storageDriverRemoteNewRead(StorageDriverRemote *this, const String *file, bool i
ASSERT(this != NULL); ASSERT(this != NULL);
FUNCTION_LOG_RETURN( FUNCTION_LOG_RETURN(STORAGE_FILE_READ, storageFileReadDriverRemoteNew(this, this->client, file, ignoreMissing));
STORAGE_FILE_READ,
storageDriverRemoteFileReadInterface(storageDriverRemoteFileReadNew(this, this->client, file, ignoreMissing)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New file write object New file write object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageFileWrite * static StorageFileWrite *
storageDriverRemoteNewWrite( 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) time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
{ {
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, file); FUNCTION_LOG_PARAM(STRING, file);
@ -200,17 +161,18 @@ storageDriverRemoteNewWrite(
FUNCTION_LOG_RETURN( FUNCTION_LOG_RETURN(
STORAGE_FILE_WRITE, STORAGE_FILE_WRITE,
storageDriverRemoteFileWriteInterface( storageFileWriteDriverRemoteNew(
storageDriverRemoteFileWriteNew( this, this->client, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, syncPath, atomic));
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. Create a path. There are no physical paths on S3 so just return success.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverRemotePathCreate(StorageDriverRemote *this, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode) storageDriverRemotePathCreate(THIS_VOID, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
{ {
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -230,9 +192,11 @@ storageDriverRemotePathCreate(StorageDriverRemote *this, const String *path, boo
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Remove a path Remove a path
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverRemotePathRemove(StorageDriverRemote *this, const String *path, bool errorOnMissing, bool recurse) storageDriverRemotePathRemove(THIS_VOID, const String *path, bool errorOnMissing, bool recurse)
{ {
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, path); 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. Sync a path. There's no need for this on S3 so just return success.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverRemotePathSync(StorageDriverRemote *this, const String *path, bool ignoreMissing) storageDriverRemotePathSync(THIS_VOID, const String *path, bool ignoreMissing)
{ {
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -271,9 +237,11 @@ storageDriverRemotePathSync(StorageDriverRemote *this, const String *path, bool
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Remove a file Remove a file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverRemoteRemove(StorageDriverRemote *this, const String *file, bool errorOnMissing) storageDriverRemoteRemove(THIS_VOID, const String *file, bool errorOnMissing)
{ {
THIS(StorageDriverRemote);
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
FUNCTION_LOG_PARAM(STRING, file); FUNCTION_LOG_PARAM(STRING, file);
@ -289,16 +257,40 @@ storageDriverRemoteRemove(StorageDriverRemote *this, const String *file, bool er
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Get storage interface New object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
Storage * Storage *
storageDriverRemoteInterface(const StorageDriverRemote *this) storageDriverRemoteNew(
mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction, ProtocolClient *client)
{ {
FUNCTION_TEST_BEGIN(); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this); FUNCTION_LOG_PARAM(MODE, modeFile);
FUNCTION_TEST_END(); 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 #ifndef STORAGE_DRIVER_REMOTE_STORAGE_H
#define STORAGE_DRIVER_REMOTE_STORAGE_H #define STORAGE_DRIVER_REMOTE_STORAGE_H
/*********************************************************************************************************************************** #include "protocol/client.h"
Object type
***********************************************************************************************************************************/
typedef struct StorageDriverRemote StorageDriverRemote;
#include "common/io/http/client.h"
#include "common/type/string.h"
#include "storage/storage.intern.h" #include "storage/storage.intern.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@ -22,41 +16,7 @@ Driver type constant
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverRemote *storageDriverRemoteNew( Storage *storageDriverRemoteNew(
mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction, ProtocolClient *client); 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 #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/io/read.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
#include "storage/driver/s3/fileRead.h" #include "storage/driver/s3/fileRead.h"
#include "storage/fileRead.intern.h" #include "storage/fileRead.intern.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct StorageDriverS3FileRead typedef struct StorageFileReadDriverS3
{ {
MemContext *memContext; MemContext *memContext; // Object mem context
StorageDriverS3 *storage; StorageFileReadInterface interface; // Driver interface
StorageFileRead *interface; StorageDriverS3 *storage; // Storage that created this object
IoRead *io;
String *name;
bool ignoreMissing;
HttpClient *httpClient; // Http client for requests HttpClient *httpClient; // Http client for requests
}; } StorageFileReadDriverS3;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Create a new file Macros for function logging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverS3FileRead * #define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_S3_TYPE \
storageDriverS3FileReadNew(StorageDriverS3 *storage, const String *name, bool ignoreMissing) StorageFileReadDriverS3 *
{ #define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_S3_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_BEGIN(logLevelTrace); objToLog(value, "StorageFileReadDriverS3", buffer, bufferSize)
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);
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Open the file Open the file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
storageDriverS3FileReadOpen(StorageDriverS3FileRead *this) storageFileReadDriverS3Open(THIS_VOID)
{ {
THIS(StorageFileReadDriverS3);
FUNCTION_LOG_BEGIN(logLevelTrace); 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(); FUNCTION_LOG_END();
ASSERT(this != NULL); ASSERT(this != NULL);
@ -86,7 +53,7 @@ storageDriverS3FileReadOpen(StorageDriverS3FileRead *this)
bool result = false; bool result = false;
// Request the file // 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 // On success
this->httpClient = storageDriverS3HttpClient(this->storage); this->httpClient = storageDriverS3HttpClient(this->storage);
@ -95,8 +62,8 @@ storageDriverS3FileReadOpen(StorageDriverS3FileRead *this)
result = true; result = true;
// Else error unless ignore missing // Else error unless ignore missing
else if (!this->ignoreMissing) else if (!this->interface.ignoreMissing)
THROW_FMT(FileMissingError, "unable to open '%s': No such file or directory", strPtr(this->name)); THROW_FMT(FileMissingError, "unable to open '%s': No such file or directory", strPtr(this->interface.name));
FUNCTION_LOG_RETURN(BOOL, result); FUNCTION_LOG_RETURN(BOOL, result);
} }
@ -104,11 +71,13 @@ storageDriverS3FileReadOpen(StorageDriverS3FileRead *this)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Read from a file Read from a file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
size_t static size_t
storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer, bool block) storageFileReadDriverS3(THIS_VOID, Buffer *buffer, bool block)
{ {
THIS(StorageFileReadDriverS3);
FUNCTION_LOG_BEGIN(logLevelTrace); 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(BUFFER, buffer);
FUNCTION_LOG_PARAM(BOOL, block); FUNCTION_LOG_PARAM(BOOL, block);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
@ -122,11 +91,13 @@ storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer, bool bloc
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Has file reached EOF? Has file reached EOF?
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
storageDriverS3FileReadEof(const StorageDriverS3FileRead *this) storageFileReadDriverS3Eof(THIS_VOID)
{ {
THIS(StorageFileReadDriverS3);
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_READ, this); FUNCTION_TEST_PARAM(STORAGE_FILE_READ_DRIVER_S3, this);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
ASSERT(this != NULL && this->httpClient != NULL); ASSERT(this != NULL && this->httpClient != NULL);
@ -135,61 +106,46 @@ storageDriverS3FileReadEof(const StorageDriverS3FileRead *this)
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Should a missing file be ignored? Create a new file
***********************************************************************************************************************************/
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
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageFileRead * StorageFileRead *
storageDriverS3FileReadInterface(const StorageDriverS3FileRead *this) storageFileReadDriverS3New(StorageDriverS3 *storage, const String *name, bool ignoreMissing)
{ {
FUNCTION_TEST_BEGIN(); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_READ, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, storage);
FUNCTION_TEST_END(); 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;
}
MEM_CONTEXT_NEW_BEGIN("StorageFileReadDriverS3")
/*********************************************************************************************************************************** {
Get the I/O interface StorageFileReadDriverS3 *driver = memNew(sizeof(StorageFileReadDriverS3));
***********************************************************************************************************************************/ driver->memContext = MEM_CONTEXT_NEW();
IoRead *
storageDriverS3FileReadIo(const StorageDriverS3FileRead *this) driver->interface = (StorageFileReadInterface)
{ {
FUNCTION_TEST_BEGIN(); .type = STORAGE_DRIVER_S3_TYPE_STR,
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_READ, this); .name = strDup(name),
FUNCTION_TEST_END(); .ignoreMissing = ignoreMissing,
ASSERT(this != NULL); .ioInterface = (IoReadInterface)
{
FUNCTION_TEST_RETURN(this->io); .eof = storageFileReadDriverS3Eof,
} .open = storageFileReadDriverS3Open,
.read = storageFileReadDriverS3,
/*********************************************************************************************************************************** },
File name };
***********************************************************************************************************************************/
const String * driver->storage = storage;
storageDriverS3FileReadName(const StorageDriverS3FileRead *this)
{ this = storageFileReadNew(driver, &driver->interface);
FUNCTION_TEST_BEGIN(); }
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_READ, this); MEM_CONTEXT_NEW_END();
FUNCTION_TEST_END();
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, this);
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->name);
} }

View File

@ -4,47 +4,12 @@ S3 Storage File Read Driver
#ifndef STORAGE_DRIVER_S3_FILEREAD_H #ifndef STORAGE_DRIVER_S3_FILEREAD_H
#define STORAGE_DRIVER_S3_FILEREAD_H #define STORAGE_DRIVER_S3_FILEREAD_H
/*********************************************************************************************************************************** #include "storage/driver/s3/storage.intern.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/fileRead.h" #include "storage/fileRead.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverS3FileRead *storageDriverS3FileReadNew(StorageDriverS3 *storage, const String *name, bool ignoreMissing); StorageFileRead *storageFileReadDriverS3New(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)
#endif #endif

View File

@ -7,6 +7,7 @@ S3 Storage File Write Driver
#include "common/io/write.intern.h" #include "common/io/write.intern.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
#include "common/type/xml.h" #include "common/type/xml.h"
#include "storage/driver/s3/fileWrite.h" #include "storage/driver/s3/fileWrite.h"
#include "storage/fileWrite.intern.h" #include "storage/fileWrite.intern.h"
@ -30,76 +31,36 @@ STRING_STATIC(S3_XML_TAG_PART_NUMBER_STR, "PartNumber"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Object type Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct StorageDriverS3FileWrite typedef struct StorageFileWriteDriverS3
{ {
MemContext *memContext; MemContext *memContext; // Object mem context
StorageDriverS3 *storage; StorageFileWriteInterface interface; // Driver interface
StorageFileWrite *interface; StorageDriverS3 *storage; // Storage that created this object
IoWrite *io;
const String *path;
const String *name;
size_t partSize; size_t partSize;
Buffer *partBuffer; Buffer *partBuffer;
const String *uploadId; const String *uploadId;
StringList *uploadPartList; StringList *uploadPartList;
}; } StorageFileWriteDriverS3;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Create a new file Macros for function logging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverS3FileWrite * #define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_S3_TYPE \
storageDriverS3FileWriteNew(StorageDriverS3 *storage, const String *name, size_t partSize) StorageFileWriteDriverS3 *
{ #define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_S3_FORMAT(value, buffer, bufferSize) \
FUNCTION_LOG_BEGIN(logLevelTrace); objToLog(value, "StorageFileWriteDriverS3", buffer, bufferSize)
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);
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Open the file Open the file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverS3FileWriteOpen(StorageDriverS3FileWrite *this) storageFileWriteDriverS3Open(THIS_VOID)
{ {
THIS(StorageFileWriteDriverS3);
FUNCTION_LOG_BEGIN(logLevelTrace); 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(); FUNCTION_LOG_END();
ASSERT(this != NULL); ASSERT(this != NULL);
@ -119,10 +80,10 @@ storageDriverS3FileWriteOpen(StorageDriverS3FileWrite *this)
Flush bytes to upload part Flush bytes to upload part
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
static void static void
storageDriverS3FileWritePart(StorageDriverS3FileWrite *this) storageFileWriteDriverS3Part(StorageFileWriteDriverS3 *this)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); 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(); FUNCTION_LOG_END();
ASSERT(this != NULL); ASSERT(this != NULL);
@ -138,7 +99,7 @@ storageDriverS3FileWritePart(StorageDriverS3FileWrite *this)
XmlNode *xmlRoot = xmlDocumentRoot( XmlNode *xmlRoot = xmlDocumentRoot(
xmlDocumentNewBuf( xmlDocumentNewBuf(
storageDriverS3Request( 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)); httpQueryAdd(httpQueryNew(), S3_QUERY_UPLOADS_STR, EMPTY_STR), NULL, true, false).response));
// Store the upload id // Store the upload id
@ -159,7 +120,7 @@ storageDriverS3FileWritePart(StorageDriverS3FileWrite *this)
this->uploadPartList, this->uploadPartList,
httpHeaderGet( httpHeaderGet(
storageDriverS3Request( 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)); HTTP_HEADER_ETAG_STR));
ASSERT(strLstGet(this->uploadPartList, strLstSize(this->uploadPartList) - 1) != NULL); ASSERT(strLstGet(this->uploadPartList, strLstSize(this->uploadPartList) - 1) != NULL);
@ -172,11 +133,13 @@ storageDriverS3FileWritePart(StorageDriverS3FileWrite *this)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Write to internal buffer Write to internal buffer
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverS3FileWrite(StorageDriverS3FileWrite *this, const Buffer *buffer) storageFileWriteDriverS3(THIS_VOID, const Buffer *buffer)
{ {
THIS(StorageFileWriteDriverS3);
FUNCTION_LOG_BEGIN(logLevelTrace); 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_PARAM(BUFFER, buffer);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
@ -197,7 +160,7 @@ storageDriverS3FileWrite(StorageDriverS3FileWrite *this, const Buffer *buffer)
// If the part buffer is full then write it // If the part buffer is full then write it
if (bufRemains(this->partBuffer) == 0) if (bufRemains(this->partBuffer) == 0)
{ {
storageDriverS3FileWritePart(this); storageFileWriteDriverS3Part(this);
bufUsedZero(this->partBuffer); bufUsedZero(this->partBuffer);
} }
} }
@ -209,11 +172,13 @@ storageDriverS3FileWrite(StorageDriverS3FileWrite *this, const Buffer *buffer)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Close the file Close the file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverS3FileWriteClose(StorageDriverS3FileWrite *this) storageFileWriteDriverS3Close(THIS_VOID)
{ {
THIS(StorageFileWriteDriverS3);
FUNCTION_LOG_BEGIN(logLevelTrace); 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(); FUNCTION_LOG_END();
ASSERT(this != NULL); ASSERT(this != NULL);
@ -228,7 +193,7 @@ storageDriverS3FileWriteClose(StorageDriverS3FileWrite *this)
{ {
// If there is anything left in the part buffer then write it // If there is anything left in the part buffer then write it
if (bufUsed(this->partBuffer) > 0) if (bufUsed(this->partBuffer) > 0)
storageDriverS3FileWritePart(this); storageFileWriteDriverS3Part(this);
// Generate the xml part list // Generate the xml part list
XmlDocument *partList = xmlDocumentNew(S3_XML_TAG_COMPLETE_MULTIPART_UPLOAD_STR); XmlDocument *partList = xmlDocumentNew(S3_XML_TAG_COMPLETE_MULTIPART_UPLOAD_STR);
@ -242,12 +207,15 @@ storageDriverS3FileWriteClose(StorageDriverS3FileWrite *this)
// Finalize the multi-part upload // Finalize the multi-part upload
storageDriverS3Request( 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); httpQueryAdd(httpQueryNew(), S3_QUERY_UPLOAD_ID_STR, this->uploadId), xmlDocumentBuf(partList), false, false);
} }
// Else upload all the data in a single put // Else upload all the data in a single put
else 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); bufFree(this->partBuffer);
this->partBuffer = NULL; this->partBuffer = NULL;
@ -259,158 +227,49 @@ storageDriverS3FileWriteClose(StorageDriverS3FileWrite *this)
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
S3 operations are always atomic, so return true New object
***********************************************************************************************************************************/
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
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageFileWrite * StorageFileWrite *
storageDriverS3FileWriteInterface(const StorageDriverS3FileWrite *this) storageFileWriteDriverS3New(StorageDriverS3 *storage, const String *name, size_t partSize)
{
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)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); 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(); FUNCTION_LOG_END();
if (this != NULL) ASSERT(storage != NULL);
memContextFree(this->memContext); 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 #ifndef STORAGE_DRIVER_S3_FILEWRITE_H
#define 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/fileWrite.h"
#include "storage/driver/s3/storage.intern.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverS3FileWrite *storageDriverS3FileWriteNew(StorageDriverS3 *storage, const String *name, size_t partSize); StorageFileWrite *storageFileWriteDriverS3New(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)
#endif #endif

View File

@ -12,11 +12,12 @@ S3 Storage Driver
#include "common/io/http/common.h" #include "common/io/http/common.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/object.h"
#include "common/regExp.h" #include "common/regExp.h"
#include "common/type/xml.h" #include "common/type/xml.h"
#include "storage/driver/s3/fileRead.h" #include "storage/driver/s3/fileRead.h"
#include "storage/driver/s3/fileWrite.h" #include "storage/driver/s3/fileWrite.h"
#include "storage/driver/s3/storage.h" #include "storage/driver/s3/storage.intern.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Driver type constant string Driver type constant string
@ -72,7 +73,6 @@ Object type
struct StorageDriverS3 struct StorageDriverS3
{ {
MemContext *memContext; MemContext *memContext;
Storage *interface; // Driver interface
HttpClient *httpClient; // Http client to service requests HttpClient *httpClient; // Http client to service requests
const StringList *headerRedactList; // List of headers to redact from logging const StringList *headerRedactList; // List of headers to redact from logging
@ -182,7 +182,7 @@ storageDriverS3Auth(
// Generate string to sign // Generate string to sign
const String *stringToSign = strNewFmt( const String *stringToSign = strNewFmt(
AWS4_HMAC_SHA256 "\n%s\n%s/%s/" S3 "/" AWS4_REQUEST "\n%s", strPtr(dateTime), strPtr(date), strPtr(this->region), 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 // 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. // 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(); 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 Process S3 request
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@ -410,9 +335,11 @@ storageDriverS3Request(
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Does a file exist? This function is only for files, not paths. Does a file exist? This function is only for files, not paths.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool static bool
storageDriverS3Exists(StorageDriverS3 *this, const String *path) storageDriverS3Exists(THIS_VOID, const String *path)
{ {
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -459,9 +386,11 @@ storageDriverS3Exists(StorageDriverS3 *this, const String *path)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
File/path info File/path info
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageInfo static StorageInfo
storageDriverS3Info(StorageDriverS3 *this, const String *file, bool ignoreMissing, bool followLink) storageDriverS3Info(THIS_VOID, const String *file, bool ignoreMissing, bool followLink)
{ {
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, file); 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 Get a list of files from a directory
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StringList * static StringList *
storageDriverS3List(StorageDriverS3 *this, const String *path, bool errorOnMissing, const String *expression) storageDriverS3List(THIS_VOID, const String *path, bool errorOnMissing, const String *expression)
{ {
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -608,9 +539,11 @@ storageDriverS3List(StorageDriverS3 *this, const String *path, bool errorOnMissi
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New file read object New file read object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageFileRead * static StorageFileRead *
storageDriverS3NewRead(StorageDriverS3 *this, const String *file, bool ignoreMissing) storageDriverS3NewRead(THIS_VOID, const String *file, bool ignoreMissing)
{ {
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, file); FUNCTION_LOG_PARAM(STRING, file);
@ -620,18 +553,19 @@ storageDriverS3NewRead(StorageDriverS3 *this, const String *file, bool ignoreMis
ASSERT(this != NULL); ASSERT(this != NULL);
ASSERT(file != NULL); ASSERT(file != NULL);
FUNCTION_LOG_RETURN( FUNCTION_LOG_RETURN(STORAGE_FILE_READ, storageFileReadDriverS3New(this, file, ignoreMissing));
STORAGE_FILE_READ, storageDriverS3FileReadInterface(storageDriverS3FileReadNew(this, file, ignoreMissing)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New file write object New file write object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageFileWrite * static StorageFileWrite *
storageDriverS3NewWrite( 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) time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
{ {
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, file); FUNCTION_LOG_PARAM(STRING, file);
@ -653,8 +587,7 @@ storageDriverS3NewWrite(
ASSERT(group == NULL); ASSERT(group == NULL);
ASSERT(timeModified == 0); ASSERT(timeModified == 0);
FUNCTION_LOG_RETURN( FUNCTION_LOG_RETURN(STORAGE_FILE_WRITE, storageFileWriteDriverS3New(this, file, this->partSize));
STORAGE_FILE_WRITE, storageDriverS3FileWriteInterface(storageDriverS3FileWriteNew(this, file, this->partSize)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@ -662,9 +595,11 @@ Create a path
There are no physical paths on S3 so just return success. There are no physical paths on S3 so just return success.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverS3PathCreate(StorageDriverS3 *this, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode) storageDriverS3PathCreate(THIS_VOID, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
{ {
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -683,9 +618,11 @@ storageDriverS3PathCreate(StorageDriverS3 *this, const String *path, bool errorO
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Remove a path Remove a path
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverS3PathRemove(StorageDriverS3 *this, const String *path, bool errorOnMissing, bool recurse) storageDriverS3PathRemove(THIS_VOID, const String *path, bool errorOnMissing, bool recurse)
{ {
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -706,9 +643,11 @@ Sync a path
There's no need for this on S3 so just return success. There's no need for this on S3 so just return success.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverS3PathSync(StorageDriverS3 *this, const String *path, bool ignoreMissing) storageDriverS3PathSync(THIS_VOID, const String *path, bool ignoreMissing)
{ {
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, path); FUNCTION_LOG_PARAM(STRING, path);
@ -724,9 +663,11 @@ storageDriverS3PathSync(StorageDriverS3 *this, const String *path, bool ignoreMi
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Remove a file Remove a file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void static void
storageDriverS3Remove(StorageDriverS3 *this, const String *file, bool errorOnMissing) storageDriverS3Remove(THIS_VOID, const String *file, bool errorOnMissing)
{ {
THIS(StorageDriverS3);
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this); FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
FUNCTION_LOG_PARAM(STRING, file); FUNCTION_LOG_PARAM(STRING, file);
@ -757,16 +698,71 @@ storageDriverS3HttpClient(const StorageDriverS3 *this)
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Get storage interface New object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
Storage * 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_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this); FUNCTION_LOG_PARAM(STRING, path);
FUNCTION_TEST_END(); 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 #ifndef STORAGE_DRIVER_S3_STORAGE_H
#define 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" #include "storage/storage.intern.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@ -24,66 +17,15 @@ Defaults
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#define STORAGE_DRIVER_S3_PORT_DEFAULT 443 #define STORAGE_DRIVER_S3_PORT_DEFAULT 443
#define STORAGE_DRIVER_S3_TIMEOUT_DEFAULT 60000 #define STORAGE_DRIVER_S3_TIMEOUT_DEFAULT 60000
#define STORAGE_DRIVER_S3_PARTSIZE_MIN ((size_t)5 * 1024 * 1024)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageDriverS3 *storageDriverS3New( Storage *storageDriverS3New(
const String *path, bool write, StoragePathExpressionCallback pathExpressionFunction, const String *bucket, const String *path, bool write, StoragePathExpressionCallback pathExpressionFunction, const String *bucket,
const String *endPoint, const String *region, const String *accessKey, const String *secretAccessKey, 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 *securityToken, size_t partSize, const String *host, unsigned int port, TimeMSec timeout, bool verifyPeer,
const String *caFile, const String *caPath); 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 #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 struct StorageFileRead
{ {
MemContext *memContext; MemContext *memContext; // Object mem context
const String *type;
void *driver; 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 Create a new storage file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageFileRead * StorageFileRead *
storageFileReadNew(const String *type, void *driver, StorageFileReadInterface interface) storageFileReadNew(void *driver, const StorageFileReadInterface *interface)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, type);
FUNCTION_LOG_PARAM_P(VOID, driver); 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(); FUNCTION_LOG_END();
ASSERT(type != NULL);
ASSERT(driver != NULL); ASSERT(driver != NULL);
ASSERT(interface.ignoreMissing != NULL); ASSERT(interface != NULL);
ASSERT(interface.io != NULL);
ASSERT(interface.name != NULL);
StorageFileRead *this = NULL; StorageFileRead *this = NULL;
this = memNew(sizeof(StorageFileRead)); this = memNew(sizeof(StorageFileRead));
this->memContext = memContextCurrent(); this->memContext = memContextCurrent();
this->type = type;
this->interface = interface;
this->driver = driver; this->driver = driver;
this->interface = interface;
this->io = ioReadNew(driver, interface->ioInterface);
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, this); FUNCTION_LOG_RETURN(STORAGE_FILE_READ, this);
} }
@ -94,7 +99,7 @@ storageFileReadIgnoreMissing(const StorageFileRead *this)
ASSERT(this != NULL); 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); 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); 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); ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->type); FUNCTION_TEST_RETURN(this->interface->type);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@ -149,8 +154,8 @@ String *
storageFileReadToLog(const StorageFileRead *this) storageFileReadToLog(const StorageFileRead *this)
{ {
return strNewFmt( return strNewFmt(
"{type: %s, name: %s, ignoreMissing: %s}", strPtr(this->type), strPtr(strToLog(storageFileReadName(this))), "{type: %s, name: %s, ignoreMissing: %s}", strPtr(this->interface->type), strPtr(strToLog(this->interface->name)),
cvtBoolToConstZ(storageFileReadIgnoreMissing(this))); cvtBoolToConstZ(this->interface->ignoreMissing));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************

View File

@ -19,7 +19,6 @@ StorageFileRead *storageFileReadMove(StorageFileRead *this, MemContext *parentNe
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Getters Getters
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void *storageFileReadDriver(const StorageFileRead *this);
IoRead *storageFileReadIo(const StorageFileRead *this); IoRead *storageFileReadIo(const StorageFileRead *this);
bool storageFileReadIgnoreMissing(const StorageFileRead *this); bool storageFileReadIgnoreMissing(const StorageFileRead *this);
const String *storageFileReadName(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 #ifndef STORAGE_FILEREAD_INTERN_H
#define STORAGE_FILEREAD_INTERN_H #define STORAGE_FILEREAD_INTERN_H
#include "common/io/read.intern.h"
#include "storage/fileRead.h" #include "storage/fileRead.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructor Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
typedef bool (*StorageFileReadInterfaceIgnoreMissing)(const void *driver);
typedef IoRead *(*StorageFileReadInterfaceIo)(const void *driver);
typedef const String *(*StorageFileReadInterfaceName)(const void *driver);
typedef struct StorageFileReadInterface typedef struct StorageFileReadInterface
{ {
StorageFileReadInterfaceIgnoreMissing ignoreMissing; const String * type;
StorageFileReadInterfaceIo io; const String * name;
StorageFileReadInterfaceName name; bool ignoreMissing;
IoReadInterface ioInterface;
} StorageFileReadInterface; } StorageFileReadInterface;
#define storageFileReadNewP(type, driver, ...) \ StorageFileRead *storageFileReadNew(void *driver, const StorageFileReadInterface *interface);
storageFileReadNew(type, driver, (StorageFileReadInterface){__VA_ARGS__})
StorageFileRead *storageFileReadNew(const String *type, void *driver, StorageFileReadInterface interface);
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Macros for function logging Constructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#define FUNCTION_LOG_STORAGE_FILE_READ_INTERFACE_TYPE \ void *storageFileReadDriver(const StorageFileRead *this);
StorageFileReadInterface
#define FUNCTION_LOG_STORAGE_FILE_READ_INTERFACE_FORMAT(value, buffer, bufferSize) \
objToLog(&value, "StorageFileReadInterface", buffer, bufferSize)
#endif #endif

View File

@ -13,12 +13,20 @@ Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct StorageFileWrite struct StorageFileWrite
{ {
MemContext *memContext; MemContext *memContext; // Object mem context
const String *type;
void *driver; 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 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. required multiple functions and contexts to make it safe.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StorageFileWrite * StorageFileWrite *
storageFileWriteNew(const String *type, void *driver, StorageFileWriteInterface interface) storageFileWriteNew(void *driver, const StorageFileWriteInterface *interface)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, type);
FUNCTION_LOG_PARAM_P(VOID, driver); 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(); FUNCTION_LOG_END();
ASSERT(type != NULL);
ASSERT(driver != NULL); ASSERT(driver != NULL);
ASSERT(interface.atomic != NULL); ASSERT(interface != 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);
StorageFileWrite *this = memNew(sizeof(StorageFileWrite)); StorageFileWrite *this = memNew(sizeof(StorageFileWrite));
this->memContext = memContextCurrent(); this->memContext = memContextCurrent();
this->type = type;
this->driver = driver; this->driver = driver;
this->interface = interface; this->interface = interface;
this->io = ioWriteNew(driver, interface->ioInterface);
FUNCTION_LOG_RETURN(STORAGE_FILE_WRITE, this); FUNCTION_LOG_RETURN(STORAGE_FILE_WRITE, this);
} }
@ -88,7 +88,7 @@ storageFileWriteAtomic(const StorageFileWrite *this)
ASSERT(this != NULL); 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); 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); 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); 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); 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); 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); 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); 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); ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->type); FUNCTION_TEST_RETURN(this->interface->type);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@ -234,7 +234,7 @@ storageFileWriteToLog(const StorageFileWrite *this)
{ {
return strNewFmt( return strNewFmt(
"{type: %s, name: %s, modeFile: %04o, modePath: %04o, createPath: %s, syncFile: %s, syncPath: %s, atomic: %s}", "{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)), storageFileWriteModePath(this), cvtBoolToConstZ(storageFileWriteCreatePath(this)),
cvtBoolToConstZ(storageFileWriteSyncFile(this)), cvtBoolToConstZ(storageFileWriteSyncPath(this)), cvtBoolToConstZ(storageFileWriteSyncFile(this)), cvtBoolToConstZ(storageFileWriteSyncPath(this)),
cvtBoolToConstZ(storageFileWriteAtomic(this))); cvtBoolToConstZ(storageFileWriteAtomic(this)));

View File

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

View File

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

View File

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

View File

@ -348,7 +348,7 @@ storageMove(const Storage *this, StorageFileRead *source, StorageFileWrite *dest
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
// If the file can't be moved it will need to be copied // 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 // Perform the copy
storageCopyNP(source, destination); storageCopyNP(source, destination);

View File

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

View File

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

View File

@ -59,7 +59,7 @@ sub run
$self->testException( $self->testException(
sub {new pgBackRest::Storage::Filter::CipherBlock( sub {new pgBackRest::Storage::Filter::CipherBlock(
$oDriver->openRead($strFile), BOGUS, $tCipherPass)}, $oDriver->openRead($strFile), BOGUS, $tCipherPass)},
ERROR_ASSERT, "unable to load cipher '" . BOGUS . "'"); ERROR_ASSERT, "invalid cipher name '" . BOGUS . "'");
$self->testException( $self->testException(
sub {new pgBackRest::Storage::Filter::CipherBlock( sub {new pgBackRest::Storage::Filter::CipherBlock(
@ -69,7 +69,7 @@ sub run
$self->testException( $self->testException(
sub {new pgBackRest::Storage::Filter::CipherBlock( sub {new pgBackRest::Storage::Filter::CipherBlock(
$oDriver->openWrite($strFile), BOGUS, $tCipherPass)}, $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 // Write to a buffer
result = bufNew(0); result = bufNew(0);
iniSave(ini, ioBufferWriteIo(ioBufferWriteNew(result))); iniSave(ini, ioBufferWriteNew(result));
bufMove(result, MEM_CONTEXT_OLD()); bufMove(result, MEM_CONTEXT_OLD());
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -46,9 +46,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN() 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); 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); ioWriteOpen(write);
ProtocolClient *client = protocolClientNew(strNew("test"), PROTOCOL_SERVICE_LOCAL_STR, read, write); ProtocolClient *client = protocolClientNew(strNew("test"), PROTOCOL_SERVICE_LOCAL_STR, read, write);

View File

@ -22,8 +22,8 @@ testRun(void)
if (testBegin("cmdRemote()")) if (testBegin("cmdRemote()"))
{ {
// Create default storage object for testing // Create default storage object for testing
Storage *storageTest = storageDriverPosixInterface( Storage *storageTest = storageDriverPosixNew(
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL)); strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
// No remote lock required // No remote lock required
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
@ -46,9 +46,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN() 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); 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); ioWriteOpen(write);
ProtocolClient *client = protocolClientNew(strNew("test"), PROTOCOL_SERVICE_REMOTE_STR, read, write); ProtocolClient *client = protocolClientNew(strNew("test"), PROTOCOL_SERVICE_REMOTE_STR, read, write);
@ -80,9 +80,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN() 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); 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); ioWriteOpen(write);
ProtocolClient *client = NULL; ProtocolClient *client = NULL;
@ -116,9 +116,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN() 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); 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); ioWriteOpen(write);
TEST_ERROR( TEST_ERROR(
@ -151,9 +151,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN() 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); 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); ioWriteOpen(write);
ProtocolClient *client = NULL; ProtocolClient *client = NULL;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,9 +24,9 @@ testRun(void)
{ {
HARNESS_FORK_CHILD_BEGIN(0, true) 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); 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); ioWriteOpen(write);
StringList *argList = strLstNew(); StringList *argList = strLstNew();
@ -45,9 +45,9 @@ testRun(void)
HARNESS_FORK_PARENT_BEGIN() 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); 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); ioWriteOpen(write);
ProtocolClient *client = protocolClientNew(strNew("test"), strNew("config"), read, write); ProtocolClient *client = protocolClientNew(strNew("test"), strNew("config"), read, write);

View File

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

View File

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

View File

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