You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-06-14 23:44:58 +02:00
Improve type safety of interfaces and drivers.
The function pointer casting used when creating drivers made changing interfaces difficult and led to slightly divergent driver implementations. Unit testing caught production-level errors but there were a lot of small issues and the process was harder than it should have been. Use void pointers instead so that no casts are required. Introduce the THIS_VOID and THIS() macros to make dealing with void pointers a little safer. Since we don't want to expose void pointers in header files, driver functions have been removed from the headers and the various driver objects return their interface type. This cuts down on accessor methods and the vast majority of those functions were not being used. Move functions that are still required to .intern.h. Remove the special "C" crypto functions that were used in libc and instead use the standard interface.
This commit is contained in:
@ -55,6 +55,14 @@
|
||||
<p>Don't append <code>strerror()</code> to error message when <code>errno</code> is 0.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<release-item-contributor-list>
|
||||
<release-item-reviewer id="cynthia.shang"/>
|
||||
</release-item-contributor-list>
|
||||
|
||||
<p>Improve type safety of interfaces and drivers.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Various <code>Buffer</code> improvements.</p>
|
||||
</release-item>
|
||||
|
@ -18,6 +18,10 @@ new(class, mode, type, key, keySize, digest = NULL)
|
||||
CODE:
|
||||
RETVAL = NULL;
|
||||
|
||||
CHECK(type != NULL);
|
||||
CHECK(key != NULL);
|
||||
CHECK(keySize != 0);
|
||||
|
||||
// Not much point to this but it keeps the var from being unused
|
||||
if (strcmp(class, PACKAGE_NAME_LIBC "::Cipher::Block") != 0)
|
||||
croak("unexpected class name '%s'", class);
|
||||
@ -25,10 +29,9 @@ CODE:
|
||||
MEM_CONTEXT_XS_NEW_BEGIN("cipherBlockXs")
|
||||
{
|
||||
RETVAL = memNew(sizeof(CipherBlockXs));
|
||||
|
||||
RETVAL->memContext = MEM_COMTEXT_XS();
|
||||
|
||||
RETVAL->pxPayload = cipherBlockNewC(mode, type, key, keySize, digest);
|
||||
RETVAL->pxPayload = cipherBlockNew(mode, cipherType(STR(type)), BUF(key, keySize), digest == NULL ? NULL : STR(digest));
|
||||
}
|
||||
MEM_CONTEXT_XS_NEW_END();
|
||||
OUTPUT:
|
||||
@ -47,10 +50,27 @@ CODE:
|
||||
STRLEN tSize;
|
||||
const unsigned char *sourcePtr = (const unsigned char *)SvPV(source, tSize);
|
||||
|
||||
RETVAL = NEWSV(0, cipherBlockProcessSizeC(self->pxPayload, tSize));
|
||||
RETVAL = NEWSV(0, ioBufferSize());
|
||||
SvPOK_only(RETVAL);
|
||||
|
||||
SvCUR_set(RETVAL, cipherBlockProcessC(self->pxPayload, sourcePtr, tSize, (unsigned char *)SvPV_nolen(RETVAL)));
|
||||
if (tSize > 0)
|
||||
{
|
||||
size_t outBufferUsed = 0;
|
||||
|
||||
do
|
||||
{
|
||||
SvGROW(RETVAL, outBufferUsed + ioBufferSize());
|
||||
Buffer *outBuffer = bufNewUseC((unsigned char *)SvPV_nolen(RETVAL) + outBufferUsed, ioBufferSize());
|
||||
|
||||
ioFilterProcessInOut(self->pxPayload, BUF(sourcePtr, tSize), outBuffer);
|
||||
outBufferUsed += bufUsed(outBuffer);
|
||||
}
|
||||
while (ioFilterInputSame(self->pxPayload));
|
||||
|
||||
SvCUR_set(RETVAL, outBufferUsed);
|
||||
}
|
||||
else
|
||||
SvCUR_set(RETVAL, 0);
|
||||
}
|
||||
MEM_CONTEXT_XS_END();
|
||||
OUTPUT:
|
||||
@ -65,10 +85,22 @@ CODE:
|
||||
|
||||
MEM_CONTEXT_XS_BEGIN(self->memContext)
|
||||
{
|
||||
RETVAL = NEWSV(0, cipherBlockProcessSizeC(self->pxPayload, 0));
|
||||
RETVAL = NEWSV(0, ioBufferSize());
|
||||
SvPOK_only(RETVAL);
|
||||
|
||||
SvCUR_set(RETVAL, cipherBlockFlushC(self->pxPayload, (unsigned char *)SvPV_nolen(RETVAL)));
|
||||
size_t outBufferUsed = 0;
|
||||
|
||||
do
|
||||
{
|
||||
SvGROW(RETVAL, outBufferUsed + ioBufferSize());
|
||||
Buffer *outBuffer = bufNewUseC((unsigned char *)SvPV_nolen(RETVAL) + outBufferUsed, ioBufferSize());
|
||||
|
||||
ioFilterProcessInOut(self->pxPayload, NULL, outBuffer);
|
||||
outBufferUsed += bufUsed(outBuffer);
|
||||
}
|
||||
while (!ioFilterDone(self->pxPayload));
|
||||
|
||||
SvCUR_set(RETVAL, outBufferUsed);
|
||||
}
|
||||
MEM_CONTEXT_XS_END();
|
||||
OUTPUT:
|
||||
|
@ -1,7 +1,9 @@
|
||||
/***********************************************************************************************************************************
|
||||
Block Cipher XS Header
|
||||
***********************************************************************************************************************************/
|
||||
#include "common/assert.h"
|
||||
#include "common/crypto/cipherBlock.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/memContext.h"
|
||||
|
||||
// Encrypt/decrypt modes
|
||||
@ -11,5 +13,5 @@ Block Cipher XS Header
|
||||
typedef struct CipherBlockXs
|
||||
{
|
||||
MemContext *memContext;
|
||||
CipherBlock *pxPayload;
|
||||
IoFilter *pxPayload;
|
||||
} CipherBlockXs, *pgBackRest__LibC__Cipher__Block;
|
||||
|
@ -36,9 +36,10 @@ CODE:
|
||||
MEM_CONTEXT_XS_TEMP_BEGIN()
|
||||
{
|
||||
STRLEN messageSize;
|
||||
const unsigned char *messagePtr = (const unsigned char *)SvPV(message, messageSize);
|
||||
const void *messagePtr = SvPV(message, messageSize);
|
||||
|
||||
cryptoHashProcessC(self->pxPayload, messagePtr, messageSize);
|
||||
if (messageSize > 0)
|
||||
ioFilterProcessIn(self->pxPayload, BUF(messagePtr, messageSize));
|
||||
}
|
||||
MEM_CONTEXT_XS_TEMP_END();
|
||||
|
||||
@ -51,7 +52,7 @@ CODE:
|
||||
|
||||
MEM_CONTEXT_XS_TEMP_BEGIN()
|
||||
{
|
||||
String *hash = bufHex(cryptoHash(self->pxPayload));
|
||||
const String *hash = varStr(ioFilterResult(self->pxPayload));
|
||||
|
||||
RETVAL = newSV(strSize(hash));
|
||||
SvPOK_only(RETVAL);
|
||||
@ -82,9 +83,9 @@ CODE:
|
||||
MEM_CONTEXT_XS_TEMP_BEGIN()
|
||||
{
|
||||
STRLEN messageSize;
|
||||
const unsigned char *messagePtr = (const unsigned char *)SvPV(message, messageSize);
|
||||
const void *messagePtr = SvPV(message, messageSize);
|
||||
|
||||
String *hash = bufHex(cryptoHashOneC(strNew(type), messagePtr, messageSize));
|
||||
String *hash = bufHex(cryptoHashOne(strNew(type), BUF(messagePtr, messageSize)));
|
||||
|
||||
RETVAL = newSV(strSize(hash));
|
||||
SvPOK_only(RETVAL);
|
||||
|
@ -2,10 +2,11 @@
|
||||
Cryptographic Hashes XS Header
|
||||
***********************************************************************************************************************************/
|
||||
#include "common/crypto/hash.h"
|
||||
#include "common/io/filter/filter.intern.h"
|
||||
#include "common/memContext.h"
|
||||
|
||||
typedef struct CryptoHashXs
|
||||
{
|
||||
MemContext *memContext;
|
||||
CryptoHash *pxPayload;
|
||||
IoFilter *pxPayload;
|
||||
} CryptoHashXs, *pgBackRest__LibC__Crypto__Hash;
|
||||
|
@ -13,6 +13,8 @@ storageDriverPosixPathRemove(path, errorOnMissing, recurse)
|
||||
CODE:
|
||||
MEM_CONTEXT_XS_TEMP_BEGIN()
|
||||
{
|
||||
storageDriverPosixPathRemove(storageDriverPosixNew(strNew("/"), 0640, 750, true, NULL), strNew(path), errorOnMissing, recurse);
|
||||
storagePathRemoveP(
|
||||
storageDriverPosixNew(strNew("/"), 0640, 750, true, NULL), strNew(path), .errorOnMissing = errorOnMissing,
|
||||
.recurse = recurse);
|
||||
}
|
||||
MEM_CONTEXT_XS_TEMP_END();
|
||||
|
@ -232,19 +232,19 @@ command/remote/remote.o: command/remote/remote.c build.auto.h common/assert.h co
|
||||
common/compress/gzip/common.o: common/compress/gzip/common.c build.auto.h common/assert.h common/compress/gzip/common.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/convert.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/compress/gzip/common.c -o common/compress/gzip/common.o
|
||||
|
||||
common/compress/gzip/compress.o: common/compress/gzip/compress.c build.auto.h common/assert.h common/compress/gzip/common.h common/compress/gzip/compress.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
common/compress/gzip/compress.o: common/compress/gzip/compress.c build.auto.h common/assert.h common/compress/gzip/common.h common/compress/gzip/compress.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/compress/gzip/compress.c -o common/compress/gzip/compress.o
|
||||
|
||||
common/compress/gzip/decompress.o: common/compress/gzip/decompress.c build.auto.h common/assert.h common/compress/gzip/common.h common/compress/gzip/decompress.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
common/compress/gzip/decompress.o: common/compress/gzip/decompress.c build.auto.h common/assert.h common/compress/gzip/common.h common/compress/gzip/decompress.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/compress/gzip/decompress.c -o common/compress/gzip/decompress.o
|
||||
|
||||
common/crypto/cipherBlock.o: common/crypto/cipherBlock.c build.auto.h common/assert.h common/crypto/cipherBlock.h common/crypto/common.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
common/crypto/cipherBlock.o: common/crypto/cipherBlock.c build.auto.h common/assert.h common/crypto/cipherBlock.h common/crypto/common.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/crypto/cipherBlock.c -o common/crypto/cipherBlock.o
|
||||
|
||||
common/crypto/common.o: common/crypto/common.c build.auto.h common/assert.h common/crypto/common.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/stackTrace.h common/type/convert.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/crypto/common.c -o common/crypto/common.o
|
||||
|
||||
common/crypto/hash.o: common/crypto/hash.c build.auto.h common/assert.h common/crypto/common.h common/crypto/hash.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
common/crypto/hash.o: common/crypto/hash.c build.auto.h common/assert.h common/crypto/common.h common/crypto/hash.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/crypto/hash.c -o common/crypto/hash.o
|
||||
|
||||
common/debug.o: common/debug.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/stackTrace.h common/type/convert.h
|
||||
@ -259,7 +259,7 @@ common/encode/base64.o: common/encode/base64.c build.auto.h common/assert.h comm
|
||||
common/error.o: common/error.c build.auto.h common/error.auto.c common/error.auto.h common/error.h common/logLevel.h common/stackTrace.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/error.c -o common/error.o
|
||||
|
||||
common/exec.o: common/exec.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/exec.h common/io/filter/filter.h common/io/filter/group.h common/io/handleRead.h common/io/handleWrite.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h
|
||||
common/exec.o: common/exec.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/exec.h common/io/filter/filter.h common/io/filter/group.h common/io/handleRead.h common/io/handleWrite.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h common/wait.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/exec.c -o common/exec.o
|
||||
|
||||
common/exit.o: common/exit.c build.auto.h command/command.h common/assert.h common/debug.h common/error.auto.h common/error.h common/exit.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h perl/exec.h protocol/client.h protocol/command.h protocol/helper.h
|
||||
@ -271,13 +271,13 @@ common/fork.o: common/fork.c build.auto.h common/assert.h common/debug.h common/
|
||||
common/ini.o: common/ini.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/write.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/ini.c -o common/ini.o
|
||||
|
||||
common/io/bufferRead.o: common/io/bufferRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/bufferRead.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
common/io/bufferRead.o: common/io/bufferRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/bufferRead.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/io/bufferRead.c -o common/io/bufferRead.o
|
||||
|
||||
common/io/bufferWrite.o: common/io/bufferWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/bufferWrite.h common/io/filter/filter.h common/io/filter/group.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
common/io/bufferWrite.o: common/io/bufferWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/bufferWrite.h common/io/filter/filter.h common/io/filter/group.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/io/bufferWrite.c -o common/io/bufferWrite.o
|
||||
|
||||
common/io/filter/buffer.o: common/io/filter/buffer.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/buffer.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
common/io/filter/buffer.o: common/io/filter/buffer.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/buffer.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/io/filter/buffer.c -o common/io/filter/buffer.o
|
||||
|
||||
common/io/filter/filter.o: common/io/filter/filter.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
@ -286,16 +286,16 @@ common/io/filter/filter.o: common/io/filter/filter.c build.auto.h common/assert.
|
||||
common/io/filter/group.o: common/io/filter/group.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/buffer.h common/io/filter/filter.h common/io/filter/filter.intern.h common/io/filter/group.h common/io/io.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/list.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/io/filter/group.c -o common/io/filter/group.o
|
||||
|
||||
common/io/filter/size.o: common/io/filter/size.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/io/filter/size.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
common/io/filter/size.o: common/io/filter/size.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/io/filter/size.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/io/filter/size.c -o common/io/filter/size.o
|
||||
|
||||
common/io/handleRead.o: common/io/handleRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/handleRead.h common/io/read.h common/io/read.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
common/io/handleRead.o: common/io/handleRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/handleRead.h common/io/read.h common/io/read.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/io/handleRead.c -o common/io/handleRead.o
|
||||
|
||||
common/io/handleWrite.o: common/io/handleWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/handleWrite.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
common/io/handleWrite.o: common/io/handleWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/handleWrite.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/io/handleWrite.c -o common/io/handleWrite.o
|
||||
|
||||
common/io/http/client.o: common/io/http/client.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/common.h common/io/http/header.h common/io/http/query.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/tls/client.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h
|
||||
common/io/http/client.o: common/io/http/client.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/common.h common/io/http/header.h common/io/http/query.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/tls/client.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/io/http/client.c -o common/io/http/client.o
|
||||
|
||||
common/io/http/common.o: common/io/http/common.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/http/common.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h
|
||||
@ -313,13 +313,13 @@ common/io/io.o: common/io/io.c build.auto.h common/assert.h common/debug.h commo
|
||||
common/io/read.o: common/io/read.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/read.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/io/read.c -o common/io/read.o
|
||||
|
||||
common/io/tls/client.o: common/io/tls/client.c build.auto.h common/assert.h common/crypto/common.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/tls/client.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h common/wait.h
|
||||
common/io/tls/client.o: common/io/tls/client.c build.auto.h common/assert.h common/crypto/common.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/tls/client.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h common/wait.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/io/tls/client.c -o common/io/tls/client.o
|
||||
|
||||
common/io/write.o: common/io/write.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/io/write.c -o common/io/write.o
|
||||
|
||||
common/lock.o: common/lock.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/handleWrite.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
common/lock.o: common/lock.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/handleWrite.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/helper.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c common/lock.c -o common/lock.o
|
||||
|
||||
common/log.o: common/log.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/stackTrace.h common/time.h common/type/convert.h
|
||||
@ -388,7 +388,7 @@ config/parse.o: config/parse.c build.auto.h common/assert.h common/debug.h commo
|
||||
config/protocol.o: config/protocol.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/protocol.h protocol/client.h protocol/command.h protocol/server.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c config/protocol.c -o config/protocol.o
|
||||
|
||||
info/info.o: info/info.c build.auto.h common/assert.h common/crypto/cipherBlock.h common/crypto/common.h common/crypto/hash.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/json.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h info/info.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
|
||||
info/info.o: info/info.c build.auto.h common/assert.h common/crypto/cipherBlock.h common/crypto/common.h common/crypto/hash.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/filter.intern.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/json.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h info/info.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c info/info.c -o info/info.o
|
||||
|
||||
info/infoArchive.o: info/infoArchive.c build.auto.h common/assert.h common/crypto/common.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h info/info.h info/infoArchive.h info/infoPg.h postgres/interface.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
|
||||
@ -409,7 +409,7 @@ main.o: main.c build.auto.h command/archive/get/get.h command/archive/push/push.
|
||||
perl/config.o: perl/config.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/json.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c perl/config.c -o perl/config.o
|
||||
|
||||
perl/exec.o: perl/exec.c ../libc/LibC.h build.auto.h common/assert.h common/crypto/cipherBlock.h common/crypto/common.h common/crypto/hash.h common/debug.h common/encode.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h config/parse.h perl/config.h perl/embed.auto.c perl/exec.h perl/libc.auto.c postgres/pageChecksum.h storage/driver/posix/fileRead.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h version.h ../libc/xs/common/encode.xsh ../libc/xs/crypto/cipherBlock.xsh ../libc/xs/crypto/hash.xsh
|
||||
perl/exec.o: perl/exec.c ../libc/LibC.h build.auto.h common/assert.h common/crypto/cipherBlock.h common/crypto/common.h common/crypto/hash.h common/debug.h common/encode.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h config/parse.h perl/config.h perl/embed.auto.c perl/exec.h perl/libc.auto.c postgres/pageChecksum.h storage/driver/posix/storage.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h ../libc/xs/common/encode.xsh ../libc/xs/crypto/cipherBlock.xsh ../libc/xs/crypto/hash.xsh
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c perl/exec.c -o perl/exec.o
|
||||
|
||||
postgres/interface.o: postgres/interface.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h postgres/interface.h postgres/interface/version.h postgres/version.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
|
||||
@ -469,50 +469,50 @@ protocol/parallelJob.o: protocol/parallelJob.c build.auto.h common/assert.h comm
|
||||
protocol/server.o: protocol/server.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/json.h common/type/keyValue.h common/type/list.h common/type/string.h common/type/variant.h common/type/variantList.h protocol/client.h protocol/command.h protocol/server.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c protocol/server.c -o protocol/server.o
|
||||
|
||||
storage/driver/cifs/storage.o: storage/driver/cifs/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/cifs/storage.h storage/driver/posix/fileRead.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
|
||||
storage/driver/cifs/storage.o: storage/driver/cifs/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/cifs/storage.h storage/driver/posix/storage.h storage/driver/posix/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/cifs/storage.c -o storage/driver/cifs/storage.o
|
||||
|
||||
storage/driver/posix/common.o: storage/driver/posix/common.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h storage/driver/posix/common.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/posix/common.c -o storage/driver/posix/common.o
|
||||
|
||||
storage/driver/posix/fileRead.o: storage/driver/posix/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h storage/driver/posix/common.h storage/driver/posix/fileRead.h storage/driver/posix/storage.h storage/fileRead.h storage/fileRead.intern.h
|
||||
storage/driver/posix/fileRead.o: storage/driver/posix/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/posix/common.h storage/driver/posix/fileRead.h storage/driver/posix/storage.h storage/driver/posix/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/posix/fileRead.c -o storage/driver/posix/fileRead.o
|
||||
|
||||
storage/driver/posix/fileWrite.o: storage/driver/posix/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h storage/driver/posix/common.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/fileWrite.h storage/fileWrite.intern.h version.h
|
||||
storage/driver/posix/fileWrite.o: storage/driver/posix/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/posix/common.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/driver/posix/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/posix/fileWrite.c -o storage/driver/posix/fileWrite.o
|
||||
|
||||
storage/driver/posix/storage.o: storage/driver/posix/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/posix/common.h storage/driver/posix/fileRead.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
|
||||
storage/driver/posix/storage.o: storage/driver/posix/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/posix/common.h storage/driver/posix/fileRead.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/driver/posix/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/posix/storage.c -o storage/driver/posix/storage.o
|
||||
|
||||
storage/driver/remote/fileRead.o: storage/driver/remote/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/read.intern.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/client.h protocol/command.h protocol/server.h storage/driver/remote/fileRead.h storage/driver/remote/protocol.h storage/driver/remote/storage.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
|
||||
storage/driver/remote/fileRead.o: storage/driver/remote/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/client.h protocol/command.h protocol/server.h storage/driver/remote/fileRead.h storage/driver/remote/protocol.h storage/driver/remote/storage.h storage/driver/remote/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/remote/fileRead.c -o storage/driver/remote/fileRead.o
|
||||
|
||||
storage/driver/remote/fileWrite.o: storage/driver/remote/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/client.h protocol/command.h protocol/server.h storage/driver/remote/fileWrite.h storage/driver/remote/protocol.h storage/driver/remote/storage.h storage/fileRead.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
storage/driver/remote/fileWrite.o: storage/driver/remote/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/client.h protocol/command.h protocol/server.h storage/driver/remote/fileWrite.h storage/driver/remote/protocol.h storage/driver/remote/storage.h storage/driver/remote/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/remote/fileWrite.c -o storage/driver/remote/fileWrite.o
|
||||
|
||||
storage/driver/remote/protocol.o: storage/driver/remote/protocol.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/server.h storage/driver/remote/protocol.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h storage/storage.intern.h
|
||||
storage/driver/remote/protocol.o: storage/driver/remote/protocol.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/server.h storage/driver/remote/protocol.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/helper.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/remote/protocol.c -o storage/driver/remote/protocol.o
|
||||
|
||||
storage/driver/remote/storage.o: storage/driver/remote/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/client.h protocol/command.h protocol/helper.h protocol/server.h storage/driver/remote/fileRead.h storage/driver/remote/fileWrite.h storage/driver/remote/protocol.h storage/driver/remote/storage.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
|
||||
storage/driver/remote/storage.o: storage/driver/remote/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h protocol/client.h protocol/command.h protocol/server.h storage/driver/remote/fileRead.h storage/driver/remote/fileWrite.h storage/driver/remote/protocol.h storage/driver/remote/storage.h storage/driver/remote/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/remote/storage.c -o storage/driver/remote/storage.o
|
||||
|
||||
storage/driver/s3/fileRead.o: storage/driver/s3/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/read.intern.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/s3/fileRead.h storage/driver/s3/storage.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
|
||||
storage/driver/s3/fileRead.o: storage/driver/s3/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/s3/fileRead.h storage/driver/s3/storage.h storage/driver/s3/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/s3/fileRead.c -o storage/driver/s3/fileRead.o
|
||||
|
||||
storage/driver/s3/fileWrite.o: storage/driver/s3/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/type/xml.h storage/driver/s3/fileWrite.h storage/driver/s3/storage.h storage/fileRead.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
storage/driver/s3/fileWrite.o: storage/driver/s3/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/type/xml.h storage/driver/s3/fileWrite.h storage/driver/s3/storage.h storage/driver/s3/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/s3/fileWrite.c -o storage/driver/s3/fileWrite.o
|
||||
|
||||
storage/driver/s3/storage.o: storage/driver/s3/storage.c build.auto.h common/assert.h common/crypto/hash.h common/debug.h common/encode.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/common.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/type/xml.h storage/driver/s3/fileRead.h storage/driver/s3/fileWrite.h storage/driver/s3/storage.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
|
||||
storage/driver/s3/storage.o: storage/driver/s3/storage.c build.auto.h common/assert.h common/crypto/hash.h common/debug.h common/encode.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/common.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/object.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/type/xml.h storage/driver/s3/fileRead.h storage/driver/s3/fileWrite.h storage/driver/s3/storage.h storage/driver/s3/storage.intern.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/driver/s3/storage.c -o storage/driver/s3/storage.o
|
||||
|
||||
storage/fileRead.o: storage/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h storage/fileRead.h storage/fileRead.intern.h
|
||||
storage/fileRead.o: storage/fileRead.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h storage/fileRead.h storage/fileRead.intern.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/fileRead.c -o storage/fileRead.o
|
||||
|
||||
storage/fileWrite.o: storage/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h storage/fileWrite.h storage/fileWrite.intern.h version.h
|
||||
storage/fileWrite.o: storage/fileWrite.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h storage/fileWrite.h storage/fileWrite.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/fileWrite.c -o storage/fileWrite.o
|
||||
|
||||
storage/helper.o: storage/helper.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h protocol/client.h protocol/command.h protocol/helper.h storage/driver/cifs/storage.h storage/driver/posix/fileRead.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/driver/remote/storage.h storage/driver/s3/storage.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h storage/storage.intern.h
|
||||
storage/helper.o: storage/helper.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h protocol/client.h protocol/command.h protocol/helper.h storage/driver/cifs/storage.h storage/driver/posix/storage.h storage/driver/remote/storage.h storage/driver/s3/storage.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/helper.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/helper.c -o storage/helper.o
|
||||
|
||||
storage/storage.o: storage/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
|
||||
storage/storage.o: storage/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h storage/fileRead.h storage/fileRead.intern.h storage/fileWrite.h storage/fileWrite.intern.h storage/info.h storage/storage.h storage/storage.intern.h version.h
|
||||
$(CC) $(CFLAGS) $(CMAKE) -c storage/storage.c -o storage/storage.o
|
||||
|
@ -153,14 +153,12 @@ archiveGetFile(
|
||||
if (cipherType != cipherTypeNone)
|
||||
{
|
||||
ioFilterGroupAdd(
|
||||
filterGroup,
|
||||
cipherBlockFilter(
|
||||
cipherBlockNew(cipherModeDecrypt, cipherType, BUFSTR(archiveGetCheckResult.cipherPass), NULL)));
|
||||
filterGroup, cipherBlockNew(cipherModeDecrypt, cipherType, BUFSTR(archiveGetCheckResult.cipherPass), NULL));
|
||||
}
|
||||
|
||||
// If file is compressed then add the decompression filter
|
||||
if (strEndsWithZ(archiveGetCheckResult.archiveFileActual, "." GZIP_EXT))
|
||||
ioFilterGroupAdd(filterGroup, gzipDecompressFilter(gzipDecompressNew(false)));
|
||||
ioFilterGroupAdd(filterGroup, gzipDecompressNew(false));
|
||||
|
||||
ioWriteFilterGroupSet(storageFileWriteIo(destination), filterGroup);
|
||||
|
||||
|
@ -74,7 +74,7 @@ archivePushFile(
|
||||
{
|
||||
// Generate a sha1 checksum for the wal segment. ??? Probably need a function in storage for this.
|
||||
IoRead *read = storageFileReadIo(storageNewReadNP(storageLocal(), walSource));
|
||||
IoFilterGroup *filterGroup = ioFilterGroupAdd(ioFilterGroupNew(), cryptoHashFilter(cryptoHashNew(HASH_TYPE_SHA1_STR)));
|
||||
IoFilterGroup *filterGroup = ioFilterGroupAdd(ioFilterGroupNew(), cryptoHashNew(HASH_TYPE_SHA1_STR));
|
||||
ioReadFilterGroupSet(read, filterGroup);
|
||||
|
||||
Buffer *buffer = bufNew(ioBufferSize());
|
||||
@ -126,15 +126,12 @@ archivePushFile(
|
||||
if (isSegment && compress)
|
||||
{
|
||||
strCat(archiveDestination, "." GZIP_EXT);
|
||||
ioFilterGroupAdd(filterGroup, gzipCompressFilter(gzipCompressNew(compressLevel, false)));
|
||||
ioFilterGroupAdd(filterGroup, gzipCompressNew(compressLevel, false));
|
||||
}
|
||||
|
||||
// If there is a cipher then add the encrypt filter
|
||||
if (cipherType != cipherTypeNone)
|
||||
{
|
||||
ioFilterGroupAdd(
|
||||
filterGroup, cipherBlockFilter(cipherBlockNew(cipherModeEncrypt, cipherType, BUFSTR(cipherPass), NULL)));
|
||||
}
|
||||
ioFilterGroupAdd(filterGroup, cipherBlockNew(cipherModeEncrypt, cipherType, BUFSTR(cipherPass), NULL));
|
||||
|
||||
ioReadFilterGroupSet(storageFileReadIo(source), filterGroup);
|
||||
|
||||
|
@ -25,9 +25,9 @@ cmdLocal(int handleRead, int handleWrite)
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
String *name = strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u", cfgOptionUInt(cfgOptProcess));
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(name, handleRead, (TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * 1000)));
|
||||
IoRead *read = ioHandleReadNew(name, handleRead, (TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * 1000));
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(name, handleWrite));
|
||||
IoWrite *write = ioHandleWriteNew(name, handleWrite);
|
||||
ioWriteOpen(write);
|
||||
|
||||
ProtocolServer *server = protocolServerNew(name, PROTOCOL_SERVICE_LOCAL_STR, read, write);
|
||||
|
@ -26,9 +26,9 @@ cmdRemote(int handleRead, int handleWrite)
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
String *name = strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u", cfgOptionUInt(cfgOptProcess));
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(name, handleRead, (TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * 1000)));
|
||||
IoRead *read = ioHandleReadNew(name, handleRead, (TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * 1000));
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(name, handleWrite));
|
||||
IoWrite *write = ioHandleWriteNew(name, handleWrite);
|
||||
ioWriteOpen(write);
|
||||
|
||||
ProtocolServer *server = protocolServerNew(name, PROTOCOL_SERVICE_REMOTE_STR, read, write);
|
||||
|
@ -12,6 +12,7 @@ Gzip Compress
|
||||
#include "common/io/filter/filter.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Filter type constant
|
||||
@ -22,67 +23,45 @@ Filter type constant
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct GzipCompress
|
||||
typedef struct GzipCompress
|
||||
{
|
||||
MemContext *memContext; // Context to store data
|
||||
z_stream *stream; // Compression stream state
|
||||
IoFilter *filter; // Filter interface
|
||||
|
||||
bool inputSame; // Is the same input required on the next process call?
|
||||
bool flush; // Is input complete and flushing in progress?
|
||||
bool done; // Is compression done?
|
||||
};
|
||||
} GzipCompress;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
static String *
|
||||
gzipCompressToLog(const GzipCompress *this)
|
||||
{
|
||||
return strNewFmt(
|
||||
"{inputSame: %s, done: %s, flushing: %s, availIn: %u}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done),
|
||||
cvtBoolToConstZ(this->done), this->stream->avail_in);
|
||||
}
|
||||
|
||||
#define FUNCTION_LOG_GZIP_COMPRESS_TYPE \
|
||||
GzipCompress *
|
||||
#define FUNCTION_LOG_GZIP_COMPRESS_FORMAT(value, buffer, bufferSize) \
|
||||
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, gzipCompressToLog, buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Compression constants
|
||||
***********************************************************************************************************************************/
|
||||
#define MEM_LEVEL 9
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
GzipCompress *
|
||||
gzipCompressNew(int level, bool raw)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(INT, level);
|
||||
FUNCTION_LOG_PARAM(BOOL, raw);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(level >= -1 && level <= 9);
|
||||
|
||||
GzipCompress *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("GzipCompress")
|
||||
{
|
||||
// Allocate state and set context
|
||||
this = memNew(sizeof(GzipCompress));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
// Create gzip stream
|
||||
this->stream = memNew(sizeof(z_stream));
|
||||
gzipError(deflateInit2(this->stream, level, Z_DEFLATED, gzipWindowBits(raw), MEM_LEVEL, Z_DEFAULT_STRATEGY));
|
||||
|
||||
// Set free callback to ensure gzip context is freed
|
||||
memContextCallback(this->memContext, (MemContextCallback)gzipCompressFree, this);
|
||||
|
||||
// Create filter interface
|
||||
this->filter = ioFilterNewP(
|
||||
GZIP_COMPRESS_FILTER_TYPE_STR, this, .done = (IoFilterInterfaceDone)gzipCompressDone,
|
||||
.inOut = (IoFilterInterfaceProcessInOut)gzipCompressProcess,
|
||||
.inputSame = (IoFilterInterfaceInputSame)gzipCompressInputSame);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(GZIP_COMPRESS, this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Compress data
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
gzipCompressProcess(GzipCompress *this, const Buffer *uncompressed, Buffer *compressed)
|
||||
static void
|
||||
gzipCompressProcess(THIS_VOID, const Buffer *uncompressed, Buffer *compressed)
|
||||
{
|
||||
THIS(GzipCompress);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(GZIP_COMPRESS, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, uncompressed);
|
||||
@ -136,9 +115,11 @@ gzipCompressProcess(GzipCompress *this, const Buffer *uncompressed, Buffer *comp
|
||||
/***********************************************************************************************************************************
|
||||
Is compress done?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
gzipCompressDone(const GzipCompress *this)
|
||||
static bool
|
||||
gzipCompressDone(const THIS_VOID)
|
||||
{
|
||||
THIS(const GzipCompress);
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(GZIP_COMPRESS, this);
|
||||
FUNCTION_TEST_END();
|
||||
@ -148,27 +129,14 @@ gzipCompressDone(const GzipCompress *this)
|
||||
FUNCTION_TEST_RETURN(this->done);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get filter interface
|
||||
***********************************************************************************************************************************/
|
||||
IoFilter *
|
||||
gzipCompressFilter(const GzipCompress *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(GZIP_COMPRESS, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->filter);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Is the same input required on the next process call?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
gzipCompressInputSame(const GzipCompress *this)
|
||||
static bool
|
||||
gzipCompressInputSame(const THIS_VOID)
|
||||
{
|
||||
THIS(const GzipCompress);
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(GZIP_COMPRESS, this);
|
||||
FUNCTION_TEST_END();
|
||||
@ -178,21 +146,10 @@ gzipCompressInputSame(const GzipCompress *this)
|
||||
FUNCTION_TEST_RETURN(this->inputSame);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Render as string for logging
|
||||
***********************************************************************************************************************************/
|
||||
String *
|
||||
gzipCompressToLog(const GzipCompress *this)
|
||||
{
|
||||
return strNewFmt(
|
||||
"{inputSame: %s, done: %s, flushing: %s, availIn: %u}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done),
|
||||
cvtBoolToConstZ(this->done), this->stream->avail_in);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free memory
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
static void
|
||||
gzipCompressFree(GzipCompress *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
@ -210,3 +167,40 @@ gzipCompressFree(GzipCompress *this)
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
IoFilter *
|
||||
gzipCompressNew(int level, bool raw)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(INT, level);
|
||||
FUNCTION_LOG_PARAM(BOOL, raw);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(level >= -1 && level <= 9);
|
||||
|
||||
IoFilter *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("GzipCompress")
|
||||
{
|
||||
GzipCompress *driver = memNew(sizeof(GzipCompress));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
// Create gzip stream
|
||||
driver->stream = memNew(sizeof(z_stream));
|
||||
gzipError(deflateInit2(driver->stream, level, Z_DEFLATED, gzipWindowBits(raw), MEM_LEVEL, Z_DEFAULT_STRATEGY));
|
||||
|
||||
// Set free callback to ensure gzip context is freed
|
||||
memContextCallback(driver->memContext, (MemContextCallback)gzipCompressFree, driver);
|
||||
|
||||
// Create filter interface
|
||||
this = ioFilterNewP(
|
||||
GZIP_COMPRESS_FILTER_TYPE_STR, driver, .done = gzipCompressDone, .inOut = gzipCompressProcess,
|
||||
.inputSame = gzipCompressInputSame);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_FILTER, this);
|
||||
}
|
||||
|
@ -6,44 +6,11 @@ Compress IO using the gzip format.
|
||||
#ifndef COMMON_COMPRESS_GZIP_COMPRESS_H
|
||||
#define COMMON_COMPRESS_GZIP_COMPRESS_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct GzipCompress GzipCompress;
|
||||
|
||||
#include "common/io/filter/filter.h"
|
||||
#include "common/type/buffer.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
GzipCompress *gzipCompressNew(int level, bool raw);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
void gzipCompressProcess(GzipCompress *this, const Buffer *uncompressed, Buffer *compressed);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool gzipCompressDone(const GzipCompress *this);
|
||||
IoFilter *gzipCompressFilter(const GzipCompress *this);
|
||||
bool gzipCompressInputSame(const GzipCompress *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void gzipCompressFree(GzipCompress *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
String *gzipCompressToLog(const GzipCompress *this);
|
||||
|
||||
#define FUNCTION_LOG_GZIP_COMPRESS_TYPE \
|
||||
GzipCompress *
|
||||
#define FUNCTION_LOG_GZIP_COMPRESS_FORMAT(value, buffer, bufferSize) \
|
||||
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, gzipCompressToLog, buffer, bufferSize)
|
||||
IoFilter *gzipCompressNew(int level, bool raw);
|
||||
|
||||
#endif
|
||||
|
@ -12,6 +12,7 @@ Gzip Decompress
|
||||
#include "common/io/filter/filter.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Filter type constant
|
||||
@ -22,59 +23,40 @@ Filter type constant
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct GzipDecompress
|
||||
typedef struct GzipDecompress
|
||||
{
|
||||
MemContext *memContext; // Context to store data
|
||||
z_stream *stream; // Decompression stream state
|
||||
IoFilter *filter; // Filter interface
|
||||
|
||||
int result; // Result of last operation
|
||||
bool inputSame; // Is the same input required on the next process call?
|
||||
bool done; // Is decompression done?
|
||||
};
|
||||
} GzipDecompress;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
String *
|
||||
gzipDecompressToLog(const GzipDecompress *this)
|
||||
{
|
||||
return strNewFmt(
|
||||
"{inputSame: %s, done: %s, availIn: %u}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done),
|
||||
this->stream->avail_in);
|
||||
}
|
||||
|
||||
#define FUNCTION_LOG_GZIP_DECOMPRESS_TYPE \
|
||||
GzipDecompress *
|
||||
gzipDecompressNew(bool raw)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(BOOL, raw);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
GzipDecompress *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("GzipDecompress")
|
||||
{
|
||||
// Allocate state and set context
|
||||
this = memNew(sizeof(GzipDecompress));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
// Create gzip stream
|
||||
this->stream = memNew(sizeof(z_stream));
|
||||
gzipError(this->result = inflateInit2(this->stream, gzipWindowBits(raw)));
|
||||
|
||||
// Set free callback to ensure gzip context is freed
|
||||
memContextCallback(this->memContext, (MemContextCallback)gzipDecompressFree, this);
|
||||
|
||||
// Create filter interface
|
||||
this->filter = ioFilterNewP(
|
||||
GZIP_DECOMPRESS_FILTER_TYPE_STR, this, .done = (IoFilterInterfaceDone)gzipDecompressDone,
|
||||
.inOut = (IoFilterInterfaceProcessInOut)gzipDecompressProcess,
|
||||
.inputSame = (IoFilterInterfaceInputSame)gzipDecompressInputSame);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(GZIP_DECOMPRESS, this);
|
||||
}
|
||||
#define FUNCTION_LOG_GZIP_DECOMPRESS_FORMAT(value, buffer, bufferSize) \
|
||||
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, gzipDecompressToLog, buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Decompress data
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
gzipDecompressProcess(GzipDecompress *this, const Buffer *compressed, Buffer *uncompressed)
|
||||
gzipDecompressProcess(THIS_VOID, const Buffer *compressed, Buffer *uncompressed)
|
||||
{
|
||||
THIS(GzipDecompress);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(GZIP_DECOMPRESS, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, compressed);
|
||||
@ -113,8 +95,10 @@ gzipDecompressProcess(GzipDecompress *this, const Buffer *compressed, Buffer *un
|
||||
Is decompress done?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
gzipDecompressDone(const GzipDecompress *this)
|
||||
gzipDecompressDone(const THIS_VOID)
|
||||
{
|
||||
THIS(const GzipDecompress);
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(GZIP_DECOMPRESS, this);
|
||||
FUNCTION_TEST_END();
|
||||
@ -124,27 +108,14 @@ gzipDecompressDone(const GzipDecompress *this)
|
||||
FUNCTION_TEST_RETURN(this->done);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get filter interface
|
||||
***********************************************************************************************************************************/
|
||||
IoFilter *
|
||||
gzipDecompressFilter(const GzipDecompress *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(GZIP_DECOMPRESS, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->filter);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Is the same input required on the next process call?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
gzipDecompressInputSame(const GzipDecompress *this)
|
||||
gzipDecompressInputSame(const THIS_VOID)
|
||||
{
|
||||
THIS(const GzipDecompress);
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(GZIP_DECOMPRESS, this);
|
||||
FUNCTION_TEST_END();
|
||||
@ -154,21 +125,10 @@ gzipDecompressInputSame(const GzipDecompress *this)
|
||||
FUNCTION_TEST_RETURN(this->inputSame);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Render as string for logging
|
||||
***********************************************************************************************************************************/
|
||||
String *
|
||||
gzipDecompressToLog(const GzipDecompress *this)
|
||||
{
|
||||
return strNewFmt(
|
||||
"{inputSame: %s, done: %s, availIn: %u}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done),
|
||||
this->stream->avail_in);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free memory
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
static void
|
||||
gzipDecompressFree(GzipDecompress *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
@ -185,3 +145,38 @@ gzipDecompressFree(GzipDecompress *this)
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
IoFilter *
|
||||
gzipDecompressNew(bool raw)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(BOOL, raw);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
IoFilter *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("GzipDecompress")
|
||||
{
|
||||
// Allocate state and set context
|
||||
GzipDecompress *driver = memNew(sizeof(GzipDecompress));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
// Create gzip stream
|
||||
driver->stream = memNew(sizeof(z_stream));
|
||||
gzipError(driver->result = inflateInit2(driver->stream, gzipWindowBits(raw)));
|
||||
|
||||
// Set free callback to ensure gzip context is freed
|
||||
memContextCallback(driver->memContext, (MemContextCallback)gzipDecompressFree, driver);
|
||||
|
||||
// Create filter interface
|
||||
this = ioFilterNewP(
|
||||
GZIP_DECOMPRESS_FILTER_TYPE_STR, driver, .done = gzipDecompressDone, .inOut = gzipDecompressProcess,
|
||||
.inputSame = gzipDecompressInputSame);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_FILTER, this);
|
||||
}
|
||||
|
@ -6,44 +6,11 @@ Decompress IO from the gzip format.
|
||||
#ifndef COMMON_COMPRESS_GZIP_DECOMPRESS_H
|
||||
#define COMMON_COMPRESS_GZIP_DECOMPRESS_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct GzipDecompress GzipDecompress;
|
||||
|
||||
#include "common/io/filter/filter.h"
|
||||
#include "common/type/string.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
GzipDecompress *gzipDecompressNew(bool raw);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
void gzipDecompressProcess(GzipDecompress *this, const Buffer *compressed, Buffer *uncompressed);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool gzipDecompressDone(const GzipDecompress *this);
|
||||
IoFilter *gzipDecompressFilter(const GzipDecompress *this);
|
||||
bool gzipDecompressInputSame(const GzipDecompress *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void gzipDecompressFree(GzipDecompress *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
String *gzipDecompressToLog(const GzipDecompress *this);
|
||||
|
||||
#define FUNCTION_LOG_GZIP_DECOMPRESS_TYPE \
|
||||
GzipDecompress *
|
||||
#define FUNCTION_LOG_GZIP_DECOMPRESS_FORMAT(value, buffer, bufferSize) \
|
||||
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, gzipDecompressToLog, buffer, bufferSize)
|
||||
IoFilter *gzipDecompressNew(bool raw);
|
||||
|
||||
#endif
|
||||
|
@ -14,6 +14,7 @@ Block Cipher
|
||||
#include "common/io/filter/filter.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Filter type constant
|
||||
@ -35,7 +36,7 @@ Header constants and sizes
|
||||
/***********************************************************************************************************************************
|
||||
Track state during block encrypt/decrypt
|
||||
***********************************************************************************************************************************/
|
||||
struct CipherBlock
|
||||
typedef struct CipherBlock
|
||||
{
|
||||
MemContext *memContext; // Context to store data
|
||||
CipherMode mode; // Mode encrypt/decrypt
|
||||
@ -49,106 +50,55 @@ struct CipherBlock
|
||||
const EVP_MD *digest; // Message digest object
|
||||
EVP_CIPHER_CTX *cipherContext; // Encrypt/decrypt context
|
||||
|
||||
IoFilter *filter; // Filter interface
|
||||
Buffer *buffer; // Internal buffer in case destination buffer isn't large enough
|
||||
bool inputSame; // Is the same input required on next process call?
|
||||
bool done; // Is processing done?
|
||||
};
|
||||
} CipherBlock;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New block encrypt/decrypt object
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
CipherBlock *
|
||||
cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, const String *digestName)
|
||||
String *
|
||||
cipherBlockToLog(const CipherBlock *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(ENUM, mode);
|
||||
FUNCTION_LOG_PARAM(ENUM, cipherType);
|
||||
FUNCTION_LOG_PARAM(BUFFER, pass);
|
||||
FUNCTION_LOG_PARAM(STRING, digestName);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(cipherType == cipherTypeAes256Cbc);
|
||||
ASSERT(pass != NULL);
|
||||
ASSERT(bufSize(pass) > 0);
|
||||
|
||||
FUNCTION_LOG_RETURN(
|
||||
CIPHER_BLOCK, cipherBlockNewC(mode, CIPHER_TYPE_AES_256_CBC, bufPtr(pass), bufSize(pass), strPtr(digestName)));
|
||||
return strNewFmt(
|
||||
"{inputSame: %s, done: %s}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done));
|
||||
}
|
||||
|
||||
#define FUNCTION_LOG_CIPHER_BLOCK_TYPE \
|
||||
CipherBlock *
|
||||
cipherBlockNewC(CipherMode mode, const char *cipherName, const unsigned char *pass, size_t passSize, const char *digestName)
|
||||
#define FUNCTION_LOG_CIPHER_BLOCK_FORMAT(value, buffer, bufferSize) \
|
||||
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, cipherBlockToLog, buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free object
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
cipherBlockFree(CipherBlock *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(ENUM, mode);
|
||||
FUNCTION_LOG_PARAM(STRINGZ, cipherName);
|
||||
FUNCTION_LOG_PARAM_P(UCHARDATA, pass);
|
||||
FUNCTION_LOG_PARAM(SIZE, passSize);
|
||||
FUNCTION_LOG_PARAM(STRINGZ, digestName);
|
||||
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(cipherName != NULL);
|
||||
ASSERT(pass != NULL);
|
||||
ASSERT(passSize > 0);
|
||||
|
||||
// Init crypto subsystem
|
||||
cryptoInit();
|
||||
|
||||
// Lookup cipher by name. This means the ciphers passed in must exactly match a name expected by OpenSSL. This is a good
|
||||
// thing since the name required by the openssl command-line tool will match what is used by pgBackRest.
|
||||
const EVP_CIPHER *cipher = EVP_get_cipherbyname(cipherName);
|
||||
|
||||
if (!cipher)
|
||||
THROW_FMT(AssertError, "unable to load cipher '%s'", cipherName);
|
||||
|
||||
// Lookup digest. If not defined it will be set to sha1.
|
||||
const EVP_MD *digest = NULL;
|
||||
|
||||
if (digestName)
|
||||
digest = EVP_get_digestbyname(digestName);
|
||||
else
|
||||
digest = EVP_sha1();
|
||||
|
||||
if (!digest)
|
||||
THROW_FMT(AssertError, "unable to load digest '%s'", digestName);
|
||||
|
||||
// Allocate memory to hold process state
|
||||
CipherBlock *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("cipherBlock")
|
||||
if (this != NULL)
|
||||
{
|
||||
// Allocate state and set context
|
||||
this = memNew(sizeof(CipherBlock));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
// Free cipher context
|
||||
if (this->cipherContext)
|
||||
EVP_CIPHER_CTX_cleanup(this->cipherContext);
|
||||
|
||||
// Set mode, encrypt or decrypt
|
||||
this->mode = mode;
|
||||
|
||||
// Set cipher and digest
|
||||
this->cipher = cipher;
|
||||
this->digest = digest;
|
||||
|
||||
// Store the passphrase
|
||||
this->passSize = passSize;
|
||||
this->pass = memNewRaw(this->passSize);
|
||||
memcpy(this->pass, pass, this->passSize);
|
||||
|
||||
// Create filter interface
|
||||
this->filter = ioFilterNewP(
|
||||
CIPHER_BLOCK_FILTER_TYPE_STR, this, .done = (IoFilterInterfaceDone)cipherBlockDone,
|
||||
.inOut = (IoFilterInterfaceProcessInOut)cipherBlockProcess,
|
||||
.inputSame = (IoFilterInterfaceInputSame)cipherBlockInputSame);
|
||||
// Free mem context
|
||||
memContextCallbackClear(this->memContext);
|
||||
memContextFree(this->memContext);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(CIPHER_BLOCK, this);
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Determine how large the destination buffer should be
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
cipherBlockProcessSizeC(CipherBlock *this, size_t sourceSize)
|
||||
static size_t
|
||||
cipherBlockProcessSize(CipherBlock *this, size_t sourceSize)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
|
||||
@ -170,8 +120,8 @@ cipherBlockProcessSizeC(CipherBlock *this, size_t sourceSize)
|
||||
/***********************************************************************************************************************************
|
||||
Encrypt/decrypt data
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
cipherBlockProcessC(CipherBlock *this, const unsigned char *source, size_t sourceSize, unsigned char *destination)
|
||||
static size_t
|
||||
cipherBlockProcessBlock(CipherBlock *this, const unsigned char *source, size_t sourceSize, unsigned char *destination)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
|
||||
@ -285,12 +235,12 @@ cipherBlockProcessC(CipherBlock *this, const unsigned char *source, size_t sourc
|
||||
/***********************************************************************************************************************************
|
||||
Flush the remaining data
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
cipherBlockFlushC(CipherBlock *this, unsigned char *destination)
|
||||
static size_t
|
||||
cipherBlockFlush(CipherBlock *this, Buffer *destination)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
|
||||
FUNCTION_LOG_PARAM_P(UCHARDATA, destination);
|
||||
FUNCTION_LOG_PARAM(BUFFER, destination);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
@ -304,7 +254,7 @@ cipherBlockFlushC(CipherBlock *this, unsigned char *destination)
|
||||
THROW(CryptoError, "cipher header missing");
|
||||
|
||||
// Only flush remaining data if some data was processed
|
||||
if (!EVP_CipherFinal(this->cipherContext, destination, (int *)&destinationSize))
|
||||
if (!EVP_CipherFinal(this->cipherContext, bufRemainsPtr(destination), (int *)&destinationSize))
|
||||
THROW(CryptoError, "unable to flush");
|
||||
|
||||
// Return actual destination size
|
||||
@ -314,9 +264,11 @@ cipherBlockFlushC(CipherBlock *this, unsigned char *destination)
|
||||
/***********************************************************************************************************************************
|
||||
Process function used by C filter
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
cipherBlockProcess(CipherBlock *this, const Buffer *source, Buffer *destination)
|
||||
static void
|
||||
cipherBlockProcess(THIS_VOID, const Buffer *source, Buffer *destination)
|
||||
{
|
||||
THIS(CipherBlock);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, source);
|
||||
@ -355,7 +307,7 @@ cipherBlockProcess(CipherBlock *this, const Buffer *source, Buffer *destination)
|
||||
// Determine how much space is required in the output buffer
|
||||
Buffer *outputActual = destination;
|
||||
|
||||
size_t destinationSize = cipherBlockProcessSizeC(this, source == NULL ? 0 : bufUsed(source));
|
||||
size_t destinationSize = cipherBlockProcessSize(this, source == NULL ? 0 : bufUsed(source));
|
||||
|
||||
if (destinationSize > bufRemains(destination))
|
||||
{
|
||||
@ -384,15 +336,15 @@ cipherBlockProcess(CipherBlock *this, const Buffer *source, Buffer *destination)
|
||||
// file but we need to call process to generate the header.
|
||||
if (!this->saltDone)
|
||||
{
|
||||
destinationSizeActual = cipherBlockProcessC(this, NULL, 0, bufRemainsPtr(outputActual));
|
||||
destinationSizeActual = cipherBlockProcessBlock(this, NULL, 0, bufRemainsPtr(outputActual));
|
||||
bufUsedInc(outputActual, destinationSizeActual);
|
||||
}
|
||||
|
||||
destinationSizeActual = cipherBlockFlushC(this, bufRemainsPtr(outputActual));
|
||||
destinationSizeActual = cipherBlockFlush(this, outputActual);
|
||||
this->done = true;
|
||||
}
|
||||
else
|
||||
destinationSizeActual = cipherBlockProcessC(this, bufPtr(source), bufUsed(source), bufRemainsPtr(outputActual));
|
||||
destinationSizeActual = cipherBlockProcessBlock(this, bufPtr(source), bufUsed(source), bufRemainsPtr(outputActual));
|
||||
|
||||
bufUsedInc(outputActual, destinationSizeActual);
|
||||
|
||||
@ -407,9 +359,11 @@ cipherBlockProcess(CipherBlock *this, const Buffer *source, Buffer *destination)
|
||||
/***********************************************************************************************************************************
|
||||
Is cipher done?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
cipherBlockDone(const CipherBlock *this)
|
||||
static bool
|
||||
cipherBlockDone(const THIS_VOID)
|
||||
{
|
||||
THIS(const CipherBlock);
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(CIPHER_BLOCK, this);
|
||||
FUNCTION_TEST_END();
|
||||
@ -419,27 +373,14 @@ cipherBlockDone(const CipherBlock *this)
|
||||
FUNCTION_TEST_RETURN(this->done && !this->inputSame);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get filter interface
|
||||
***********************************************************************************************************************************/
|
||||
IoFilter *
|
||||
cipherBlockFilter(const CipherBlock *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(CIPHER_BLOCK, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->filter);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Should the same input be provided again?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
cipherBlockInputSame(const CipherBlock *this)
|
||||
static bool
|
||||
cipherBlockInputSame(const THIS_VOID)
|
||||
{
|
||||
THIS(const CipherBlock);
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(CIPHER_BLOCK, this);
|
||||
FUNCTION_TEST_END();
|
||||
@ -450,35 +391,68 @@ cipherBlockInputSame(const CipherBlock *this)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Render as string for logging
|
||||
New block encrypt/decrypt object
|
||||
***********************************************************************************************************************************/
|
||||
String *
|
||||
cipherBlockToLog(const CipherBlock *this)
|
||||
{
|
||||
return strNewFmt(
|
||||
"{inputSame: %s, done: %s}", cvtBoolToConstZ(this->inputSame), cvtBoolToConstZ(this->done));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free memory
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
cipherBlockFree(CipherBlock *this)
|
||||
IoFilter *
|
||||
cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, const String *digestName)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(CIPHER_BLOCK, this);
|
||||
FUNCTION_LOG_PARAM(ENUM, mode);
|
||||
FUNCTION_LOG_PARAM(ENUM, cipherType);
|
||||
FUNCTION_LOG_PARAM(BUFFER, pass);
|
||||
FUNCTION_LOG_PARAM(STRING, digestName);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
ASSERT(pass != NULL);
|
||||
ASSERT(bufSize(pass) > 0);
|
||||
|
||||
// Init crypto subsystem
|
||||
cryptoInit();
|
||||
|
||||
// Lookup cipher by name. This means the ciphers passed in must exactly match a name expected by OpenSSL. This is a good
|
||||
// thing since the name required by the openssl command-line tool will match what is used by pgBackRest.
|
||||
const EVP_CIPHER *cipher = EVP_get_cipherbyname(strPtr(cipherTypeName(cipherType)));
|
||||
|
||||
if (!cipher)
|
||||
THROW_FMT(AssertError, "unable to load cipher '%s'", strPtr(cipherTypeName(cipherType)));
|
||||
|
||||
// Lookup digest. If not defined it will be set to sha1.
|
||||
const EVP_MD *digest = NULL;
|
||||
|
||||
if (digestName)
|
||||
digest = EVP_get_digestbyname(strPtr(digestName));
|
||||
else
|
||||
digest = EVP_sha1();
|
||||
|
||||
if (!digest)
|
||||
THROW_FMT(AssertError, "unable to load digest '%s'", strPtr(digestName));
|
||||
|
||||
// Allocate memory to hold process state
|
||||
IoFilter *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("CipherBlock")
|
||||
{
|
||||
// Free cipher context
|
||||
if (this->cipherContext)
|
||||
EVP_CIPHER_CTX_cleanup(this->cipherContext);
|
||||
CipherBlock *driver = memNew(sizeof(CipherBlock));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
// Free mem context
|
||||
memContextCallbackClear(this->memContext);
|
||||
memContextFree(this->memContext);
|
||||
}
|
||||
// Set mode, encrypt or decrypt
|
||||
driver->mode = mode;
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
// Set cipher and digest
|
||||
driver->cipher = cipher;
|
||||
driver->digest = digest;
|
||||
|
||||
// Store the passphrase
|
||||
driver->passSize = bufUsed(pass);
|
||||
driver->pass = memNewRaw(driver->passSize);
|
||||
memcpy(driver->pass, bufPtr(pass), driver->passSize);
|
||||
|
||||
// Create filter interface
|
||||
this = ioFilterNewP(
|
||||
CIPHER_BLOCK_FILTER_TYPE_STR, driver, .done = cipherBlockDone, .inOut = cipherBlockProcess,
|
||||
.inputSame = cipherBlockInputSame);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_FILTER, this);
|
||||
}
|
||||
|
@ -4,54 +4,12 @@ Block Cipher Header
|
||||
#ifndef COMMON_CRYPTO_CIPHERBLOCK_H
|
||||
#define COMMON_CRYPTO_CIPHERBLOCK_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
CipherBlock object
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct CipherBlock CipherBlock;
|
||||
|
||||
#include "common/io/filter/filter.h"
|
||||
#include "common/type/buffer.h"
|
||||
#include "common/crypto/common.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
CipherBlock *cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, const String *digestName);
|
||||
|
||||
// Deprecated constructor with C-style call signatures now needed only for the Perl interface
|
||||
CipherBlock *cipherBlockNewC(
|
||||
CipherMode mode, const char *cipherName, const unsigned char *pass, size_t passSize, const char *digestName);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
void cipherBlockProcess(CipherBlock *this, const Buffer *source, Buffer *destination);
|
||||
|
||||
// Deprecated functions with C-style call signatures now needed only for the Perl interface
|
||||
size_t cipherBlockProcessSizeC(CipherBlock *this, size_t sourceSize);
|
||||
size_t cipherBlockProcessC(CipherBlock *this, const unsigned char *source, size_t sourceSize, unsigned char *destination);
|
||||
size_t cipherBlockFlushC(CipherBlock *this, unsigned char *destination);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool cipherBlockDone(const CipherBlock *this);
|
||||
IoFilter *cipherBlockFilter(const CipherBlock *this);
|
||||
bool cipherBlockInputSame(const CipherBlock *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void cipherBlockFree(CipherBlock *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
String *cipherBlockToLog(const CipherBlock *this);
|
||||
|
||||
#define FUNCTION_LOG_CIPHER_BLOCK_TYPE \
|
||||
CipherBlock *
|
||||
#define FUNCTION_LOG_CIPHER_BLOCK_FORMAT(value, buffer, bufferSize) \
|
||||
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, cipherBlockToLog, buffer, bufferSize)
|
||||
IoFilter *cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, const String *digestName);
|
||||
|
||||
#endif
|
||||
|
@ -14,6 +14,7 @@ Cryptographic Hash
|
||||
#include "common/io/filter/filter.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
#include "common/crypto/common.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -31,125 +32,49 @@ STRING_EXTERN(HASH_TYPE_SHA256_STR, HASH_TYPE_SH
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct CryptoHash
|
||||
typedef struct CryptoHash
|
||||
{
|
||||
MemContext *memContext; // Context to store data
|
||||
const EVP_MD *hashType; // Hash type (sha1, md5, etc.)
|
||||
EVP_MD_CTX *hashContext; // Message hash context
|
||||
Buffer *hash; // Hash in binary form
|
||||
IoFilter *filter; // Filter interface
|
||||
};
|
||||
} CryptoHash;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_CRYPTO_HASH_TYPE \
|
||||
CryptoHash *
|
||||
cryptoHashNew(const String *type)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STRING, type);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(type != NULL);
|
||||
|
||||
// Init crypto subsystem
|
||||
cryptoInit();
|
||||
|
||||
// Allocate memory to hold process state
|
||||
CryptoHash *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("CryptoHash")
|
||||
{
|
||||
// Allocate state and set context
|
||||
this = memNew(sizeof(CryptoHash));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
// Lookup digest
|
||||
if ((this->hashType = EVP_get_digestbyname(strPtr(type))) == NULL)
|
||||
THROW_FMT(AssertError, "unable to load hash '%s'", strPtr(type));
|
||||
|
||||
// Create context
|
||||
cryptoError((this->hashContext = EVP_MD_CTX_create()) == NULL, "unable to create hash context");
|
||||
|
||||
// Set free callback to ensure hash context is freed
|
||||
memContextCallback(this->memContext, (MemContextCallback)cryptoHashFree, this);
|
||||
|
||||
// Initialize context
|
||||
cryptoError(!EVP_DigestInit_ex(this->hashContext, this->hashType, NULL), "unable to initialize hash context");
|
||||
|
||||
// Create filter interface
|
||||
this->filter = ioFilterNewP(
|
||||
CRYPTO_HASH_FILTER_TYPE_STR, this, .in = (IoFilterInterfaceProcessIn)cryptoHashProcess,
|
||||
.result = (IoFilterInterfaceResult)cryptoHashResult);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(CRYPTO_HASH, this);
|
||||
}
|
||||
#define FUNCTION_LOG_CRYPTO_HASH_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "CryptoHash", buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Add message data to the hash
|
||||
Add message data to the hash from a Buffer
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
cryptoHashProcessC(CryptoHash *this, const unsigned char *message, size_t messageSize)
|
||||
static void
|
||||
cryptoHashProcess(THIS_VOID, const Buffer *message)
|
||||
{
|
||||
THIS(CryptoHash);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(CRYPTO_HASH, this);
|
||||
FUNCTION_LOG_PARAM_P(UCHARDATA, message);
|
||||
FUNCTION_LOG_PARAM(SIZE, messageSize);
|
||||
FUNCTION_LOG_PARAM(BUFFER, message);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->hashContext != NULL);
|
||||
ASSERT(this->hash == NULL);
|
||||
ASSERT(message != NULL);
|
||||
|
||||
cryptoError(!EVP_DigestUpdate(this->hashContext, message, messageSize), "unable to process message hash");
|
||||
cryptoError(!EVP_DigestUpdate(this->hashContext, bufPtr(message), bufUsed(message)), "unable to process message hash");
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Add message data to the hash from a Buffer
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
cryptoHashProcess(CryptoHash *this, const Buffer *message)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(CRYPTO_HASH, this);
|
||||
FUNCTION_TEST_PARAM(BUFFER, message);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(message != NULL);
|
||||
|
||||
cryptoHashProcessC(this, bufPtr(message), bufUsed(message));
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Add message data to the hash from a String
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
cryptoHashProcessStr(CryptoHash *this, const String *message)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(CRYPTO_HASH, this);
|
||||
FUNCTION_TEST_PARAM(STRING, message);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(message != NULL);
|
||||
|
||||
cryptoHashProcessC(this, (const unsigned char *)strPtr(message), strSize(message));
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get binary representation of the hash
|
||||
***********************************************************************************************************************************/
|
||||
const Buffer *
|
||||
static const Buffer *
|
||||
cryptoHash(CryptoHash *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
@ -166,10 +91,6 @@ cryptoHash(CryptoHash *this)
|
||||
bufUsedSet(this->hash, bufSize(this->hash));
|
||||
|
||||
cryptoError(!EVP_DigestFinal_ex(this->hashContext, bufPtr(this->hash), NULL), "unable to finalize message hash");
|
||||
|
||||
// Free the context
|
||||
EVP_MD_CTX_destroy(this->hashContext);
|
||||
this->hashContext = NULL;
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
@ -177,74 +98,91 @@ cryptoHash(CryptoHash *this)
|
||||
FUNCTION_LOG_RETURN(BUFFER, this->hash);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get filter interface
|
||||
***********************************************************************************************************************************/
|
||||
IoFilter *
|
||||
cryptoHashFilter(CryptoHash *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(CRYPTO_HASH, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_FILTER, this->filter);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get string representation of the hash as a filter result
|
||||
***********************************************************************************************************************************/
|
||||
const Variant *
|
||||
cryptoHashResult(CryptoHash *this)
|
||||
static Variant *
|
||||
cryptoHashResult(THIS_VOID)
|
||||
{
|
||||
THIS(CryptoHash);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(CRYPTO_HASH, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
Variant *result = NULL;
|
||||
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
result = varNewStr(bufHex(cryptoHash(this)));
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(VARIANT, result);
|
||||
FUNCTION_LOG_RETURN(VARIANT, varNewStr(bufHex(cryptoHash(this))));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free memory
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
cryptoHashFree(CryptoHash *this)
|
||||
static void
|
||||
cryptoHashFreeCallback(CryptoHash *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(CRYPTO_HASH, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
{
|
||||
EVP_MD_CTX_destroy(this->hashContext);
|
||||
|
||||
memContextCallbackClear(this->memContext);
|
||||
memContextFree(this->memContext);
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
IoFilter *
|
||||
cryptoHashNew(const String *type)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STRING, type);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(type != NULL);
|
||||
|
||||
// Init crypto subsystem
|
||||
cryptoInit();
|
||||
|
||||
// Allocate memory to hold process state
|
||||
IoFilter *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("CryptoHash")
|
||||
{
|
||||
CryptoHash *driver = memNew(sizeof(CryptoHash));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
// Lookup digest
|
||||
if ((driver->hashType = EVP_get_digestbyname(strPtr(type))) == NULL)
|
||||
THROW_FMT(AssertError, "unable to load hash '%s'", strPtr(type));
|
||||
|
||||
// Create context
|
||||
cryptoError((driver->hashContext = EVP_MD_CTX_create()) == NULL, "unable to create hash context");
|
||||
|
||||
// Set free callback to ensure hash context is freed
|
||||
memContextCallback(driver->memContext, (MemContextCallback)cryptoHashFreeCallback, driver);
|
||||
|
||||
// Initialize context
|
||||
cryptoError(!EVP_DigestInit_ex(driver->hashContext, driver->hashType, NULL), "unable to initialize hash context");
|
||||
|
||||
// Create filter interface
|
||||
this = ioFilterNewP(CRYPTO_HASH_FILTER_TYPE_STR, driver, .in = cryptoHashProcess, .result = cryptoHashResult);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_FILTER, this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get hash for one C buffer
|
||||
***********************************************************************************************************************************/
|
||||
Buffer *
|
||||
cryptoHashOneC(const String *type, const unsigned char *message, size_t messageSize)
|
||||
cryptoHashOne(const String *type, const Buffer *message)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STRING, type);
|
||||
FUNCTION_LOG_PARAM_P(UCHARDATA, message);
|
||||
FUNCTION_LOG_PARAM(BUFFER, message);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(type != NULL);
|
||||
@ -254,11 +192,15 @@ cryptoHashOneC(const String *type, const unsigned char *message, size_t messageS
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
CryptoHash *hash = cryptoHashNew(type);
|
||||
cryptoHashProcessC(hash, message, messageSize);
|
||||
IoFilter *hash = cryptoHashNew(type);
|
||||
|
||||
if (bufUsed(message) > 0)
|
||||
ioFilterProcessIn(hash, message);
|
||||
|
||||
const Buffer *buffer = cryptoHash((CryptoHash *)ioFilterDriver(hash));
|
||||
|
||||
memContextSwitch(MEM_CONTEXT_OLD());
|
||||
result = bufDup(cryptoHash(hash));
|
||||
result = bufDup(buffer);
|
||||
memContextSwitch(MEM_CONTEXT_TEMP());
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
@ -266,40 +208,6 @@ cryptoHashOneC(const String *type, const unsigned char *message, size_t messageS
|
||||
FUNCTION_LOG_RETURN(BUFFER, result);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get hash for one Buffer
|
||||
***********************************************************************************************************************************/
|
||||
Buffer *
|
||||
cryptoHashOne(const String *type, const Buffer *message)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRING, type);
|
||||
FUNCTION_TEST_PARAM(BUFFER, message);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(type != NULL);
|
||||
ASSERT(message != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(cryptoHashOneC(type, bufPtr(message), bufUsed(message)));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get hash for one String
|
||||
***********************************************************************************************************************************/
|
||||
Buffer *
|
||||
cryptoHashOneStr(const String *type, const String *message)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRING, type);
|
||||
FUNCTION_TEST_PARAM(STRING, message);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(type != NULL);
|
||||
ASSERT(message != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(cryptoHashOneC(type, (const unsigned char *)strPtr(message), strSize(message)));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get hmac for one message/key
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -6,11 +6,6 @@ Generate a hash (sha1, md5, etc.) from a string, Buffer, or using an IoFilter.
|
||||
#ifndef COMMON_CRYPTO_HASH_H
|
||||
#define COMMON_CRYPTO_HASH_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Hash object
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct CryptoHash CryptoHash;
|
||||
|
||||
#include "common/io/filter/filter.h"
|
||||
#include "common/type/string.h"
|
||||
|
||||
@ -45,42 +40,12 @@ Hash type sizes
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
CryptoHash *cryptoHashNew(const String *type);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
void cryptoHashProcess(CryptoHash *this, const Buffer *message);
|
||||
void cryptoHashProcessC(CryptoHash *this, const unsigned char *message, size_t messageSize);
|
||||
void cryptoHashProcessStr(CryptoHash *this, const String *message);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
const Buffer *cryptoHash(CryptoHash *this);
|
||||
IoFilter *cryptoHashFilter(CryptoHash *this);
|
||||
const Variant *cryptoHashResult(CryptoHash *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void cryptoHashFree(CryptoHash *this);
|
||||
IoFilter *cryptoHashNew(const String *type);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Helper functions
|
||||
***********************************************************************************************************************************/
|
||||
Buffer *cryptoHashOne(const String *type, const Buffer *message);
|
||||
Buffer *cryptoHashOneC(const String *type, const unsigned char *message, size_t messageSize);
|
||||
Buffer *cryptoHashOneStr(const String *type, const String *message);
|
||||
|
||||
Buffer *cryptoHmacOne(const String *type, const Buffer *key, const Buffer *message);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_CRYPTO_HASH_TYPE \
|
||||
CryptoHash *
|
||||
#define FUNCTION_LOG_CRYPTO_HASH_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "CryptoHash", buffer, bufferSize)
|
||||
|
||||
#endif
|
||||
|
@ -18,6 +18,7 @@ Execute Process
|
||||
#include "common/io/io.h"
|
||||
#include "common/io/read.intern.h"
|
||||
#include "common/io/write.intern.h"
|
||||
#include "common/object.h"
|
||||
#include "common/wait.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -37,7 +38,7 @@ struct Exec
|
||||
int handleWrite; // Write handle
|
||||
int handleError; // Error handle
|
||||
|
||||
IoHandleRead *ioReadHandle; // Handle read driver
|
||||
IoRead *ioReadHandle; // Handle read driver
|
||||
IoWrite *ioWriteHandle; // Handle write interface
|
||||
|
||||
IoRead *ioReadExec; // Wrapper for handle read interface
|
||||
@ -110,6 +111,155 @@ execNew(const String *command, const StringList *param, const String *name, Time
|
||||
FUNCTION_LOG_RETURN(EXEC, this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Check if the process is still running
|
||||
|
||||
This should be called when anything unexpected happens while reading or writing, including errors and eof. If this function returns
|
||||
then the original error should be rethrown.
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
execCheck(Exec *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(EXEC, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
int processStatus;
|
||||
int processResult;
|
||||
|
||||
THROW_ON_SYS_ERROR(
|
||||
(processResult = waitpid(this->processId, &processStatus, WNOHANG)) == -1, ExecuteError, "unable to wait on child process");
|
||||
|
||||
if (processResult != 0)
|
||||
{
|
||||
// Clear the process id so we don't try to wait for this process on free
|
||||
this->processId = 0;
|
||||
|
||||
// If the process exited normally
|
||||
if (WIFEXITED(processStatus))
|
||||
{
|
||||
// Get data from stderr to help diagnose the problem
|
||||
IoRead *ioReadError = ioHandleReadNew(strNewFmt("%s error", strPtr(this->name)), this->handleError, 0);
|
||||
ioReadOpen(ioReadError);
|
||||
String *errorStr = strTrim(strNewBuf(ioReadBuf(ioReadError)));
|
||||
|
||||
// Throw the error with as much information as is available
|
||||
THROWP_FMT(
|
||||
errorTypeFromCode(WEXITSTATUS(processStatus)), "%s terminated unexpectedly [%d]%s%s", strPtr(this->name),
|
||||
WEXITSTATUS(processStatus), strSize(errorStr) > 0 ? ": " : "", strSize(errorStr) > 0 ? strPtr(errorStr) : "");
|
||||
}
|
||||
|
||||
// If the process did not exit normally then it must have been a signal
|
||||
THROW_FMT(ExecuteError, "%s terminated unexpectedly on signal %d", strPtr(this->name), WTERMSIG(processStatus));
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Read from the process
|
||||
***********************************************************************************************************************************/
|
||||
static size_t
|
||||
execRead(THIS_VOID, Buffer *buffer, bool block)
|
||||
{
|
||||
THIS(Exec);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(EXEC, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_PARAM(BOOL, block);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
size_t result = 0;
|
||||
|
||||
TRY_BEGIN()
|
||||
{
|
||||
result = ioReadInterface(this->ioReadHandle)->read(ioReadDriver(this->ioReadHandle), buffer, block);
|
||||
}
|
||||
CATCH_ANY()
|
||||
{
|
||||
execCheck(this);
|
||||
RETHROW();
|
||||
}
|
||||
TRY_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(SIZE, result);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Write to the process
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
execWrite(THIS_VOID, const Buffer *buffer)
|
||||
{
|
||||
THIS(Exec);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(EXEC, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
TRY_BEGIN()
|
||||
{
|
||||
ioWrite(this->ioWriteHandle, buffer);
|
||||
ioWriteFlush(this->ioWriteHandle);
|
||||
}
|
||||
CATCH_ANY()
|
||||
{
|
||||
execCheck(this);
|
||||
RETHROW();
|
||||
}
|
||||
TRY_END();
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Is the process eof?
|
||||
***********************************************************************************************************************************/
|
||||
static bool
|
||||
execEof(THIS_VOID)
|
||||
{
|
||||
THIS(Exec);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(EXEC, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
// Check if the process is still running on eof
|
||||
if (ioReadInterface(this->ioReadHandle)->eof(ioReadDriver(this->ioReadHandle)))
|
||||
execCheck(this);
|
||||
|
||||
FUNCTION_LOG_RETURN(BOOL, false);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get the read handle
|
||||
***********************************************************************************************************************************/
|
||||
static int
|
||||
execHandleRead(const THIS_VOID)
|
||||
{
|
||||
THIS(const Exec);
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(EXEC, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->handleRead);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Execute command
|
||||
***********************************************************************************************************************************/
|
||||
@ -171,15 +321,13 @@ execOpen(Exec *this)
|
||||
|
||||
// Assign handles to io interfaces
|
||||
this->ioReadHandle = ioHandleReadNew(strNewFmt("%s read", strPtr(this->name)), this->handleRead, this->timeout);
|
||||
this->ioWriteHandle = ioHandleWriteIo(ioHandleWriteNew(strNewFmt("%s write", strPtr(this->name)), this->handleWrite));
|
||||
this->ioWriteHandle = ioHandleWriteNew(strNewFmt("%s write", strPtr(this->name)), this->handleWrite);
|
||||
ioWriteOpen(this->ioWriteHandle);
|
||||
|
||||
// Create wrapper interfaces that check process state
|
||||
this->ioReadExec = ioReadNewP(
|
||||
this, .block = true, .read = (IoReadInterfaceRead)execRead, .eof = (IoReadInterfaceEof)execEof,
|
||||
.handle = (IoReadInterfaceHandle)execHandleRead);
|
||||
this->ioReadExec = ioReadNewP(this, .block = true, .read = execRead, .eof = execEof, .handle = execHandleRead);
|
||||
ioReadOpen(this->ioReadExec);
|
||||
this->ioWriteExec = ioWriteNewP(this, .write = (IoWriteInterfaceWrite)execWrite);
|
||||
this->ioWriteExec = ioWriteNewP(this, .write = execWrite);
|
||||
ioWriteOpen(this->ioWriteExec);
|
||||
|
||||
// Set a callback so the handles will get freed
|
||||
@ -188,132 +336,6 @@ execOpen(Exec *this)
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Check if the process is still running
|
||||
|
||||
This should be called when anything unexpected happens while reading or writing, including errors and eof. If this function returns
|
||||
then the original error should be rethrown.
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
execCheck(Exec *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(EXEC, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
int processStatus;
|
||||
int processResult;
|
||||
|
||||
THROW_ON_SYS_ERROR(
|
||||
(processResult = waitpid(this->processId, &processStatus, WNOHANG)) == -1, ExecuteError, "unable to wait on child process");
|
||||
|
||||
if (processResult != 0)
|
||||
{
|
||||
// Clear the process id so we don't try to wait for this process on free
|
||||
this->processId = 0;
|
||||
|
||||
// If the process exited normally
|
||||
if (WIFEXITED(processStatus))
|
||||
{
|
||||
// Get data from stderr to help diagnose the problem
|
||||
IoRead *ioReadError = ioHandleReadIo(ioHandleReadNew(strNewFmt("%s error", strPtr(this->name)), this->handleError, 0));
|
||||
ioReadOpen(ioReadError);
|
||||
String *errorStr = strTrim(strNewBuf(ioReadBuf(ioReadError)));
|
||||
|
||||
// Throw the error with as much information as is available
|
||||
THROWP_FMT(
|
||||
errorTypeFromCode(WEXITSTATUS(processStatus)), "%s terminated unexpectedly [%d]%s%s", strPtr(this->name),
|
||||
WEXITSTATUS(processStatus), strSize(errorStr) > 0 ? ": " : "", strSize(errorStr) > 0 ? strPtr(errorStr) : "");
|
||||
}
|
||||
|
||||
// If the process did not exit normally then it must have been a signal
|
||||
THROW_FMT(ExecuteError, "%s terminated unexpectedly on signal %d", strPtr(this->name), WTERMSIG(processStatus));
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Read from the process
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
execRead(Exec *this, Buffer *buffer, bool block)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(EXEC, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_PARAM(BOOL, block);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
size_t result = 0;
|
||||
|
||||
TRY_BEGIN()
|
||||
{
|
||||
result = ioHandleRead(this->ioReadHandle, buffer, block);
|
||||
}
|
||||
CATCH_ANY()
|
||||
{
|
||||
execCheck(this);
|
||||
RETHROW();
|
||||
}
|
||||
TRY_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(SIZE, result);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Write to the process
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
execWrite(Exec *this, Buffer *buffer)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(EXEC, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
TRY_BEGIN()
|
||||
{
|
||||
ioWrite(this->ioWriteHandle, buffer);
|
||||
ioWriteFlush(this->ioWriteHandle);
|
||||
}
|
||||
CATCH_ANY()
|
||||
{
|
||||
execCheck(this);
|
||||
RETHROW();
|
||||
}
|
||||
TRY_END();
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Is the process eof?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
execEof(Exec *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(EXEC, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
// Check that the process is still running on eof
|
||||
if (ioHandleReadEof(this->ioReadHandle))
|
||||
execCheck(this);
|
||||
|
||||
FUNCTION_LOG_RETURN(BOOL, false);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get read interface
|
||||
***********************************************************************************************************************************/
|
||||
@ -359,21 +381,6 @@ execMemContext(const Exec *this)
|
||||
FUNCTION_TEST_RETURN(this->memContext);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get the read handle
|
||||
***********************************************************************************************************************************/
|
||||
int
|
||||
execHandleRead(Exec *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(EXEC, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->handleRead);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the object
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -17,7 +17,6 @@ typedef struct Exec Exec;
|
||||
#include "common/io/read.h"
|
||||
#include "common/io/write.h"
|
||||
#include "common/time.h"
|
||||
#include "common/type/stringList.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
@ -28,17 +27,12 @@ Exec *execNew(const String *command, const StringList *param, const String *name
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
void execOpen(Exec *this);
|
||||
size_t execRead(Exec *this, Buffer *buffer, bool block);
|
||||
void execWrite(Exec *this, Buffer *buffer);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool execEof(Exec *this);
|
||||
IoRead *execIoRead(const Exec *this);
|
||||
IoWrite *execIoWrite(const Exec *this);
|
||||
MemContext *execMemContext(const Exec *this);
|
||||
int execHandleRead(Exec *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
|
@ -8,52 +8,36 @@ Buffer IO Read
|
||||
#include "common/io/read.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct IoBufferRead
|
||||
typedef struct IoBufferRead
|
||||
{
|
||||
MemContext *memContext; // Object memory context
|
||||
IoRead *io; // IoRead interface
|
||||
const Buffer *read; // Buffer to read data from
|
||||
|
||||
size_t readPos; // Current position in the read buffer
|
||||
bool eof; // Has the end of the buffer been reached?
|
||||
};
|
||||
} IoBufferRead;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_IO_BUFFER_READ_TYPE \
|
||||
IoBufferRead *
|
||||
ioBufferReadNew(const Buffer *buffer)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
IoBufferRead *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("IoBufferRead")
|
||||
{
|
||||
this = memNew(sizeof(IoBufferRead));
|
||||
this->memContext = memContextCurrent();
|
||||
this->io = ioReadNewP(this, .eof = (IoReadInterfaceEof)ioBufferReadEof, .read = (IoReadInterfaceRead)ioBufferRead);
|
||||
this->read = buffer;
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_BUFFER_READ, this);
|
||||
}
|
||||
#define FUNCTION_LOG_IO_BUFFER_READ_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "IoBufferRead", buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Read data from the buffer
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
ioBufferRead(IoBufferRead *this, Buffer *buffer, bool block)
|
||||
static size_t
|
||||
ioBufferRead(THIS_VOID, Buffer *buffer, bool block)
|
||||
{
|
||||
THIS(IoBufferRead);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_BUFFER_READ, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
@ -83,31 +67,14 @@ ioBufferRead(IoBufferRead *this, Buffer *buffer, bool block)
|
||||
FUNCTION_LOG_RETURN(SIZE, actualBytes);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Move the object to a new context
|
||||
***********************************************************************************************************************************/
|
||||
IoBufferRead *
|
||||
ioBufferReadMove(IoBufferRead *this, MemContext *parentNew)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_BUFFER_READ, this);
|
||||
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(parentNew != NULL);
|
||||
|
||||
if (this != NULL)
|
||||
memContextMove(this->memContext, parentNew);
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Have all bytes been read from the buffer?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
ioBufferReadEof(const IoBufferRead *this)
|
||||
static bool
|
||||
ioBufferReadEof(THIS_VOID)
|
||||
{
|
||||
THIS(IoBufferRead);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_BUFFER_READ, this);
|
||||
FUNCTION_LOG_END();
|
||||
@ -118,32 +85,28 @@ ioBufferReadEof(const IoBufferRead *this)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get io interface
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
IoRead *
|
||||
ioBufferReadIo(const IoBufferRead *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_BUFFER_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->io);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the object
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
ioBufferReadFree(IoBufferRead *this)
|
||||
ioBufferReadNew(const Buffer *buffer)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_BUFFER_READ, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
memContextFree(this->memContext);
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
IoRead *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("IoBufferRead")
|
||||
{
|
||||
IoBufferRead *driver = memNew(sizeof(IoBufferRead));
|
||||
driver->memContext = memContextCurrent();
|
||||
driver->read = buffer;
|
||||
|
||||
this = ioReadNewP(driver, .eof = ioBufferReadEof, .read = ioBufferRead);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_READ, this);
|
||||
}
|
||||
|
@ -6,41 +6,11 @@ Read from a Buffer object using the IoRead interface.
|
||||
#ifndef COMMON_IO_BUFFERREAD_H
|
||||
#define COMMON_IO_BUFFERREAD_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct IoBufferRead IoBufferRead;
|
||||
|
||||
#include "common/io/read.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
IoBufferRead *ioBufferReadNew(const Buffer *buffer);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
size_t ioBufferRead(IoBufferRead *this, Buffer *buffer, bool block);
|
||||
IoBufferRead *ioBufferReadMove(IoBufferRead *this, MemContext *parentNew);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool ioBufferReadEof(const IoBufferRead *this);
|
||||
IoRead *ioBufferReadIo(const IoBufferRead *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void ioBufferReadFree(IoBufferRead *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_IO_BUFFER_READ_TYPE \
|
||||
IoBufferRead *
|
||||
#define FUNCTION_LOG_IO_BUFFER_READ_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "IoBufferRead", buffer, bufferSize)
|
||||
IoRead *ioBufferReadNew(const Buffer *buffer);
|
||||
|
||||
#endif
|
||||
|
@ -8,49 +8,33 @@ Buffer IO Write
|
||||
#include "common/io/write.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct IoBufferWrite
|
||||
typedef struct IoBufferWrite
|
||||
{
|
||||
MemContext *memContext; // Object memory context
|
||||
IoWrite *io; // IoWrite interface
|
||||
Buffer *write; // Buffer to write into
|
||||
};
|
||||
} IoBufferWrite;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_IO_BUFFER_WRITE_TYPE \
|
||||
IoBufferWrite *
|
||||
ioBufferWriteNew(Buffer *buffer)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
IoBufferWrite *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("IoBufferWrite")
|
||||
{
|
||||
this = memNew(sizeof(IoBufferWrite));
|
||||
this->memContext = memContextCurrent();
|
||||
this->io = ioWriteNewP(this, .write = (IoWriteInterfaceWrite)ioBufferWrite);
|
||||
this->write = buffer;
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_BUFFER_WRITE, this);
|
||||
}
|
||||
#define FUNCTION_LOG_IO_BUFFER_WRITE_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "IoBufferWrite", buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Write to the buffer
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
ioBufferWrite(IoBufferWrite *this, Buffer *buffer)
|
||||
static void
|
||||
ioBufferWrite(THIS_VOID, const Buffer *buffer)
|
||||
{
|
||||
THIS(IoBufferWrite);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_BUFFER_WRITE, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
@ -65,51 +49,28 @@ ioBufferWrite(IoBufferWrite *this, Buffer *buffer)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Move the object to a new context
|
||||
***********************************************************************************************************************************/
|
||||
IoBufferWrite *
|
||||
ioBufferWriteMove(IoBufferWrite *this, MemContext *parentNew)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_BUFFER_WRITE, this);
|
||||
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(parentNew != NULL);
|
||||
|
||||
if (this != NULL)
|
||||
memContextMove(this->memContext, parentNew);
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get io interface
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
IoWrite *
|
||||
ioBufferWriteIo(const IoBufferWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_BUFFER_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->io);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the object
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
ioBufferWriteFree(IoBufferWrite *this)
|
||||
ioBufferWriteNew(Buffer *buffer)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_BUFFER_WRITE, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
memContextFree(this->memContext);
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
IoWrite *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("IoBufferWrite")
|
||||
{
|
||||
IoBufferWrite *driver = memNew(sizeof(IoBufferWrite));
|
||||
driver->memContext = memContextCurrent();
|
||||
driver->write = buffer;
|
||||
|
||||
this = ioWriteNewP(driver, .write = ioBufferWrite);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_WRITE, this);
|
||||
}
|
||||
|
@ -6,40 +6,11 @@ Write to a Buffer object using the IoWrite interface.
|
||||
#ifndef COMMON_IO_BUFFERWRITE_H
|
||||
#define COMMON_IO_BUFFERWRITE_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct IoBufferWrite IoBufferWrite;
|
||||
|
||||
#include "common/io/write.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
IoBufferWrite *ioBufferWriteNew(Buffer *buffer);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
void ioBufferWrite(IoBufferWrite *this, Buffer *buffer);
|
||||
IoBufferWrite *ioBufferWriteMove(IoBufferWrite *this, MemContext *parentNew);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
IoWrite *ioBufferWriteIo(const IoBufferWrite *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void ioBufferWriteFree(IoBufferWrite *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_IO_BUFFER_WRITE_TYPE \
|
||||
IoBufferWrite *
|
||||
#define FUNCTION_LOG_IO_BUFFER_WRITE_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "IoBufferWrite", buffer, bufferSize)
|
||||
IoWrite *ioBufferWriteNew(Buffer *buffer);
|
||||
|
||||
#endif
|
||||
|
@ -10,6 +10,7 @@ IO Buffer Filter
|
||||
#include "common/io/filter/filter.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Filter type constant
|
||||
@ -20,46 +21,36 @@ Filter type constant
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct IoBuffer
|
||||
typedef struct IoBuffer
|
||||
{
|
||||
MemContext *memContext; // Mem context of filter
|
||||
IoFilter *filter; // Filter interface
|
||||
|
||||
size_t inputPos; // Position in input buffer
|
||||
bool inputSame; // Is the same input required again?
|
||||
};
|
||||
} IoBuffer;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
String *
|
||||
ioBufferToLog(const IoBuffer *this)
|
||||
{
|
||||
return strNewFmt("{inputSame: %s, inputPos: %zu}", cvtBoolToConstZ(this->inputSame), this->inputPos);
|
||||
}
|
||||
|
||||
#define FUNCTION_LOG_IO_BUFFER_TYPE \
|
||||
IoBuffer *
|
||||
ioBufferNew(void)
|
||||
{
|
||||
FUNCTION_LOG_VOID(logLevelTrace);
|
||||
|
||||
IoBuffer *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("IoBuffer")
|
||||
{
|
||||
this = memNew(sizeof(IoBuffer));
|
||||
this->memContext = memContextCurrent();
|
||||
|
||||
// Create filter interface
|
||||
this->filter = ioFilterNewP(
|
||||
BUFFER_FILTER_TYPE_STR, this, .inOut = (IoFilterInterfaceProcessInOut)ioBufferProcess,
|
||||
.inputSame = (IoFilterInterfaceInputSame)ioBufferInputSame);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_BUFFER, this);
|
||||
}
|
||||
#define FUNCTION_LOG_IO_BUFFER_FORMAT(value, buffer, bufferSize) \
|
||||
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, ioBufferToLog, buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Move data from the input buffer to the output buffer
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
ioBufferProcess(IoBuffer *this, const Buffer *input, Buffer *output)
|
||||
static void
|
||||
ioBufferProcess(THIS_VOID, const Buffer *input, Buffer *output)
|
||||
{
|
||||
THIS(IoBuffer)
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_BUFFER, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, input);
|
||||
@ -101,9 +92,11 @@ Is the same input required again?
|
||||
If the remaining space in the output buffer is smaller than the used space in the input buffer then the same input must be provided
|
||||
again.
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
ioBufferInputSame(const IoBuffer *this)
|
||||
static bool
|
||||
ioBufferInputSame(const THIS_VOID)
|
||||
{
|
||||
THIS(const IoBuffer)
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_BUFFER, this);
|
||||
FUNCTION_TEST_END();
|
||||
@ -114,41 +107,23 @@ ioBufferInputSame(const IoBuffer *this)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get filter interface
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
IoFilter *
|
||||
ioBufferFilter(const IoBuffer *this)
|
||||
ioBufferNew(void)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_BUFFER, this);
|
||||
FUNCTION_TEST_END();
|
||||
FUNCTION_LOG_VOID(logLevelTrace);
|
||||
|
||||
ASSERT(this != NULL);
|
||||
IoFilter *this = NULL;
|
||||
|
||||
FUNCTION_TEST_RETURN(this->filter);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Render as string for logging
|
||||
***********************************************************************************************************************************/
|
||||
String *
|
||||
ioBufferToLog(const IoBuffer *this)
|
||||
MEM_CONTEXT_NEW_BEGIN("IoBuffer")
|
||||
{
|
||||
return strNewFmt("{inputSame: %s, inputPos: %zu}", cvtBoolToConstZ(this->inputSame), this->inputPos);
|
||||
IoBuffer *driver = memNew(sizeof(IoBuffer));
|
||||
driver->memContext = memContextCurrent();
|
||||
|
||||
this = ioFilterNewP(BUFFER_FILTER_TYPE_STR, driver, .inOut = ioBufferProcess, .inputSame = ioBufferInputSame);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the filter group
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
ioBufferFree(IoBuffer *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_BUFFER, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
memContextFree(this->memContext);
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
FUNCTION_LOG_RETURN(IO_FILTER, this);
|
||||
}
|
||||
|
@ -7,43 +7,12 @@ in a FilterGroup if the last filter is not already an InOut filter, so there is
|
||||
#ifndef COMMON_IO_FILTER_BUFFER_H
|
||||
#define COMMON_IO_FILTER_BUFFER_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct IoBuffer IoBuffer;
|
||||
|
||||
#include "common/io/filter/filter.h"
|
||||
#include "common/type/buffer.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
IoBuffer *ioBufferNew(void);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
void ioBufferProcess(IoBuffer *this, const Buffer *input, Buffer *output);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
IoFilter *ioBufferFilter(const IoBuffer *this);
|
||||
bool ioBufferInputSame(const IoBuffer *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void ioBufferFree(IoBuffer *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
String *ioBufferToLog(const IoBuffer *this);
|
||||
|
||||
#define FUNCTION_LOG_IO_BUFFER_TYPE \
|
||||
IoBuffer *
|
||||
#define FUNCTION_LOG_IO_BUFFER_FORMAT(value, buffer, bufferSize) \
|
||||
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, ioBufferToLog, buffer, bufferSize)
|
||||
IoFilter *ioBufferNew(void);
|
||||
|
||||
#endif
|
||||
|
@ -132,6 +132,21 @@ ioFilterDone(const IoFilter *this)
|
||||
FUNCTION_TEST_RETURN(this->interface.done != NULL ? this->interface.done(this->driver) : !ioFilterInputSame(this));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Driver for the filter
|
||||
***********************************************************************************************************************************/
|
||||
void *
|
||||
ioFilterDriver(IoFilter *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_FILTER, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->driver);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Does the filter need the same input again?
|
||||
|
||||
@ -149,6 +164,21 @@ ioFilterInputSame(const IoFilter *this)
|
||||
FUNCTION_TEST_RETURN(this->interface.inputSame != NULL ? this->interface.inputSame(this->driver) : false);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Interface for the filter
|
||||
***********************************************************************************************************************************/
|
||||
const IoFilterInterface *
|
||||
ioFilterInterface(const IoFilter *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_FILTER, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(&this->interface);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Does filter produce output?
|
||||
|
||||
@ -169,7 +199,7 @@ ioFilterOutput(const IoFilter *this)
|
||||
/***********************************************************************************************************************************
|
||||
Get filter result
|
||||
***********************************************************************************************************************************/
|
||||
const Variant *
|
||||
Variant *
|
||||
ioFilterResult(const IoFilter *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
@ -197,3 +227,19 @@ ioFilterType(const IoFilter *this)
|
||||
|
||||
FUNCTION_TEST_RETURN(this->type);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free object
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
ioFilterFree(IoFilter *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_FILTER, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
if (this != NULL)
|
||||
memContextFree(this->memContext);
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
@ -22,9 +22,14 @@ typedef struct IoFilter IoFilter;
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
const Variant *ioFilterResult(const IoFilter *this);
|
||||
Variant *ioFilterResult(const IoFilter *this);
|
||||
const String *ioFilterType(const IoFilter *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void ioFilterFree(IoFilter *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -23,35 +23,29 @@ Each filter has a type that allows it to be identified in the filter list.
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
typedef bool (*IoFilterInterfaceDone)(const void *driver);
|
||||
typedef void (*IoFilterInterfaceProcessIn)(void *driver, const Buffer *);
|
||||
typedef void (*IoFilterInterfaceProcessInOut)(void *driver, const Buffer *, Buffer *);
|
||||
typedef bool (*IoFilterInterfaceInputSame)(const void *driver);
|
||||
typedef Variant *(*IoFilterInterfaceResult)(const void *driver);
|
||||
|
||||
typedef struct IoFilterInterface
|
||||
{
|
||||
// Indicates that filter processing is done. This is used for filters that have additional data to be flushed even after all
|
||||
// input has been processed. Compression and encryption filters will usually need to implement done. If done is not
|
||||
// implemented then it will always return true if all input has been consumed, i.e. if inputSame returns false.
|
||||
IoFilterInterfaceDone done;
|
||||
bool (*done)(const void *driver);
|
||||
|
||||
// Processing function for filters that do not produce output. Note that result must be implemented in this case (or else what
|
||||
// would be the point.
|
||||
IoFilterInterfaceProcessIn in;
|
||||
void (*in)(void *driver, const Buffer *);
|
||||
|
||||
// Processing function for filters that produce output. InOut filters will typically implement inputSame and may also implement
|
||||
// done.
|
||||
IoFilterInterfaceProcessInOut inOut;
|
||||
void (*inOut)(void *driver, const Buffer *, Buffer *);
|
||||
|
||||
// InOut filters must be prepared for an output buffer that is too small to accept all the processed output. In this case the
|
||||
// filter must implement inputSame and set it to true when there is more output to be produced for a given input. On the next
|
||||
// call to inOut the same input will be passed along with a fresh output buffer with space for more processed output.
|
||||
IoFilterInterfaceInputSame inputSame;
|
||||
bool (*inputSame)(const void *driver);
|
||||
|
||||
// If the filter produces a result then this function must be implemented to return the result. A result can be anything that
|
||||
// is not processed output, e.g. a count of total bytes or a cryptographic hash.
|
||||
IoFilterInterfaceResult result;
|
||||
Variant *(*result)(void *driver);
|
||||
} IoFilterInterface;
|
||||
|
||||
#define ioFilterNewP(type, driver, ...) \
|
||||
@ -70,7 +64,9 @@ IoFilter *ioFilterMove(IoFilter *this, MemContext *parentNew);
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool ioFilterDone(const IoFilter *this);
|
||||
void *ioFilterDriver(IoFilter *this);
|
||||
bool ioFilterInputSame(const IoFilter *this);
|
||||
const IoFilterInterface *ioFilterInterface(const IoFilter *this);
|
||||
bool ioFilterOutput(const IoFilter *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
|
@ -134,7 +134,7 @@ ioFilterGroupOpen(IoFilterGroup *this)
|
||||
// If the last filter is not an output filter then add a filter to buffer/copy data. Input filters won't copy to an output
|
||||
// buffer so we need some way to get the data to the output buffer.
|
||||
if (lstSize(this->filterList) == 0 || !ioFilterOutput((ioFilterGroupGet(this, lstSize(this->filterList) - 1))->filter))
|
||||
ioFilterGroupAdd(this, ioBufferFilter(ioBufferNew()));
|
||||
ioFilterGroupAdd(this, ioBufferNew());
|
||||
|
||||
// Create filter input/output buffers. Input filters do not get an output buffer since they don't produce output.
|
||||
Buffer *lastOutputBuffer = NULL;
|
||||
|
@ -10,6 +10,7 @@ IO Size Filter
|
||||
#include "common/io/filter/size.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Filter type constant
|
||||
@ -20,45 +21,35 @@ Filter type constant
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct IoSize
|
||||
typedef struct IoSize
|
||||
{
|
||||
MemContext *memContext; // Mem context of filter
|
||||
IoFilter *filter; // Filter interface
|
||||
|
||||
uint64_t size; // Total size of al input
|
||||
};
|
||||
} IoSize;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
String *
|
||||
ioSizeToLog(const IoSize *this)
|
||||
{
|
||||
return strNewFmt("{size: %" PRIu64 "}", this->size);
|
||||
}
|
||||
|
||||
#define FUNCTION_LOG_IO_SIZE_TYPE \
|
||||
IoSize *
|
||||
ioSizeNew(void)
|
||||
{
|
||||
FUNCTION_LOG_VOID(logLevelTrace);
|
||||
|
||||
IoSize *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("IoSize")
|
||||
{
|
||||
this = memNew(sizeof(IoSize));
|
||||
this->memContext = memContextCurrent();
|
||||
|
||||
// Create filter interface
|
||||
this->filter = ioFilterNewP(
|
||||
SIZE_FILTER_TYPE_STR, this, .in = (IoFilterInterfaceProcessIn)ioSizeProcess,
|
||||
.result = (IoFilterInterfaceResult)ioSizeResult);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_SIZE, this);
|
||||
}
|
||||
#define FUNCTION_LOG_IO_SIZE_FORMAT(value, buffer, bufferSize) \
|
||||
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, ioSizeToLog, buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Count bytes in the input
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
ioSizeProcess(IoSize *this, const Buffer *input)
|
||||
static void
|
||||
ioSizeProcess(THIS_VOID, const Buffer *input)
|
||||
{
|
||||
THIS(IoSize);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_SIZE, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, input);
|
||||
@ -72,65 +63,41 @@ ioSizeProcess(IoSize *this, const Buffer *input)
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get filter interface
|
||||
***********************************************************************************************************************************/
|
||||
IoFilter *
|
||||
ioSizeFilter(const IoSize *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_SIZE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->filter);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Render as string for logging
|
||||
***********************************************************************************************************************************/
|
||||
String *
|
||||
ioSizeToLog(const IoSize *this)
|
||||
{
|
||||
return strNewFmt("{size: %" PRIu64 "}", this->size);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Return filter result
|
||||
***********************************************************************************************************************************/
|
||||
const Variant *
|
||||
ioSizeResult(IoSize *this)
|
||||
static Variant *
|
||||
ioSizeResult(THIS_VOID)
|
||||
{
|
||||
THIS(IoSize);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_SIZE, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
Variant *result = NULL;
|
||||
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
result = varNewUInt64(this->size);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(VARIANT, result);
|
||||
FUNCTION_LOG_RETURN(VARIANT, varNewUInt64(this->size));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the filter group
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
ioSizeFree(IoSize *this)
|
||||
IoFilter *
|
||||
ioSizeNew(void)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_SIZE, this);
|
||||
FUNCTION_LOG_END();
|
||||
FUNCTION_LOG_VOID(logLevelTrace);
|
||||
|
||||
if (this != NULL)
|
||||
memContextFree(this->memContext);
|
||||
IoFilter *this = NULL;
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
MEM_CONTEXT_NEW_BEGIN("IoSize")
|
||||
{
|
||||
IoSize *driver = memNew(sizeof(IoSize));
|
||||
driver->memContext = memContextCurrent();
|
||||
|
||||
this = ioFilterNewP(SIZE_FILTER_TYPE_STR, driver, .in = ioSizeProcess, .result = ioSizeResult);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_FILTER, this);
|
||||
}
|
||||
|
@ -7,43 +7,11 @@ in a FilterGroup with IoWrite.
|
||||
#ifndef COMMON_IO_FILTER_SIZE_H
|
||||
#define COMMON_IO_FILTER_SIZE_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct IoSize IoSize;
|
||||
|
||||
#include "common/io/filter/filter.h"
|
||||
#include "common/type/buffer.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
IoSize *ioSizeNew(void);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
void ioSizeProcess(IoSize *this, const Buffer *input);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
IoFilter *ioSizeFilter(const IoSize *this);
|
||||
const Variant *ioSizeResult(IoSize *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void ioSizeFree(IoSize *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
String *ioSizeToLog(const IoSize *this);
|
||||
|
||||
#define FUNCTION_LOG_IO_SIZE_TYPE \
|
||||
IoSize *
|
||||
#define FUNCTION_LOG_IO_SIZE_FORMAT(value, buffer, bufferSize) \
|
||||
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, ioSizeToLog, buffer, bufferSize)
|
||||
IoFilter *ioSizeNew(void);
|
||||
|
||||
#endif
|
||||
|
@ -11,56 +11,36 @@ Handle IO Read
|
||||
#include "common/io/read.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct IoHandleRead
|
||||
typedef struct IoHandleRead
|
||||
{
|
||||
MemContext *memContext; // Object memory context
|
||||
IoRead *io; // IoRead interface
|
||||
const String *name; // Handle name for error messages
|
||||
int handle; // Handle to read data from
|
||||
TimeMSec timeout; // Timeout for read operation
|
||||
bool eof; // Has the end of the stream been reached?
|
||||
};
|
||||
} IoHandleRead;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_IO_HANDLE_READ_TYPE \
|
||||
IoHandleRead *
|
||||
ioHandleReadNew(const String *name, int handle, TimeMSec timeout)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(INT, handle);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(handle != -1);
|
||||
|
||||
IoHandleRead *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("IoHandleRead")
|
||||
{
|
||||
this = memNew(sizeof(IoHandleRead));
|
||||
this->memContext = memContextCurrent();
|
||||
this->io = ioReadNewP(
|
||||
this, .block = true, .eof = (IoReadInterfaceEof)ioHandleReadEof, .handle = (IoReadInterfaceHandle)ioHandleReadHandle,
|
||||
.read = (IoReadInterfaceRead)ioHandleRead);
|
||||
this->name = strDup(name);
|
||||
this->handle = handle;
|
||||
this->timeout = timeout;
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_HANDLE_READ, this);
|
||||
}
|
||||
#define FUNCTION_LOG_IO_HANDLE_READ_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "IoHandleRead", buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Read data from the handle
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
ioHandleRead(IoHandleRead *this, Buffer *buffer, bool block)
|
||||
static size_t
|
||||
ioHandleRead(THIS_VOID, Buffer *buffer, bool block)
|
||||
{
|
||||
THIS(IoHandleRead);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_HANDLE_READ, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
@ -116,31 +96,14 @@ ioHandleRead(IoHandleRead *this, Buffer *buffer, bool block)
|
||||
FUNCTION_LOG_RETURN(SIZE, (size_t)actualBytes);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Move the object to a new context
|
||||
***********************************************************************************************************************************/
|
||||
IoHandleRead *
|
||||
ioHandleReadMove(IoHandleRead *this, MemContext *parentNew)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_HANDLE_READ, this);
|
||||
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(parentNew != NULL);
|
||||
|
||||
if (this != NULL)
|
||||
memContextMove(this->memContext, parentNew);
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Have all bytes been read from the buffer?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
ioHandleReadEof(const IoHandleRead *this)
|
||||
static bool
|
||||
ioHandleReadEof(THIS_VOID)
|
||||
{
|
||||
THIS(IoHandleRead);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_HANDLE_READ, this);
|
||||
FUNCTION_LOG_END();
|
||||
@ -153,9 +116,11 @@ ioHandleReadEof(const IoHandleRead *this)
|
||||
/***********************************************************************************************************************************
|
||||
Get handle (file descriptor)
|
||||
***********************************************************************************************************************************/
|
||||
int
|
||||
ioHandleReadHandle(const IoHandleRead *this)
|
||||
static int
|
||||
ioHandleReadHandle(const THIS_VOID)
|
||||
{
|
||||
THIS(const IoHandleRead);
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_HANDLE_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
@ -166,32 +131,30 @@ ioHandleReadHandle(const IoHandleRead *this)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get io interface
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
IoRead *
|
||||
ioHandleReadIo(const IoHandleRead *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_HANDLE_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->io);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the object
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
ioHandleReadFree(IoHandleRead *this)
|
||||
ioHandleReadNew(const String *name, int handle, TimeMSec timeout)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_HANDLE_READ, this);
|
||||
FUNCTION_LOG_PARAM(INT, handle);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
memContextFree(this->memContext);
|
||||
ASSERT(handle != -1);
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
IoRead *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("IoHandleRead")
|
||||
{
|
||||
IoHandleRead *driver = memNew(sizeof(IoHandleRead));
|
||||
driver->memContext = memContextCurrent();
|
||||
driver->name = strDup(name);
|
||||
driver->handle = handle;
|
||||
driver->timeout = timeout;
|
||||
|
||||
this = ioReadNewP(driver, .block = true, .eof = ioHandleReadEof, .handle = ioHandleReadHandle, .read = ioHandleRead);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_READ, this);
|
||||
}
|
||||
|
@ -6,43 +6,12 @@ Read from a handle using the IoRead interface.
|
||||
#ifndef COMMON_IO_HANDLEREAD_H
|
||||
#define COMMON_IO_HANDLEREAD_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct IoHandleRead IoHandleRead;
|
||||
|
||||
#include "common/io/read.h"
|
||||
#include "common/time.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
IoHandleRead *ioHandleReadNew(const String *name, int handle, TimeMSec timeout);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
size_t ioHandleRead(IoHandleRead *this, Buffer *buffer, bool block);
|
||||
IoHandleRead *ioHandleReadMove(IoHandleRead *this, MemContext *parentNew);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool ioHandleReadEof(const IoHandleRead *this);
|
||||
int ioHandleReadHandle(const IoHandleRead *this);
|
||||
IoRead *ioHandleReadIo(const IoHandleRead *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void ioHandleReadFree(IoHandleRead *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_IO_HANDLE_READ_TYPE \
|
||||
IoHandleRead *
|
||||
#define FUNCTION_LOG_IO_HANDLE_READ_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "IoHandleRead", buffer, bufferSize)
|
||||
IoRead *ioHandleReadNew(const String *name, int handle, TimeMSec timeout);
|
||||
|
||||
#endif
|
||||
|
@ -10,50 +10,34 @@ Handle IO Write
|
||||
#include "common/io/write.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct IoHandleWrite
|
||||
typedef struct IoHandleWrite
|
||||
{
|
||||
MemContext *memContext; // Object memory context
|
||||
IoWrite *io; // IoWrite interface
|
||||
const String *name; // Handle name for error messages
|
||||
int handle; // Handle to write to
|
||||
};
|
||||
} IoHandleWrite;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_IO_HANDLE_WRITE_TYPE \
|
||||
IoHandleWrite *
|
||||
ioHandleWriteNew(const String *name, int handle)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(INT, handle);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
IoHandleWrite *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("IoHandleWrite")
|
||||
{
|
||||
this = memNew(sizeof(IoHandleWrite));
|
||||
this->memContext = memContextCurrent();
|
||||
this->io = ioWriteNewP(
|
||||
this, .handle = (IoWriteInterfaceHandle)ioHandleWriteHandle, .write = (IoWriteInterfaceWrite)ioHandleWrite);
|
||||
this->name = strDup(name);
|
||||
this->handle = handle;
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_HANDLE_WRITE, this);
|
||||
}
|
||||
#define FUNCTION_LOG_IO_HANDLE_WRITE_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "IoHandleWrite", buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Write to the handle
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
ioHandleWrite(IoHandleWrite *this, Buffer *buffer)
|
||||
static void
|
||||
ioHandleWrite(THIS_VOID, const Buffer *buffer)
|
||||
{
|
||||
THIS(IoHandleWrite);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_HANDLE_WRITE, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
@ -68,31 +52,14 @@ ioHandleWrite(IoHandleWrite *this, Buffer *buffer)
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Move the object to a new context
|
||||
***********************************************************************************************************************************/
|
||||
IoHandleWrite *
|
||||
ioHandleWriteMove(IoHandleWrite *this, MemContext *parentNew)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_HANDLE_WRITE, this);
|
||||
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(parentNew != NULL);
|
||||
|
||||
if (this != NULL)
|
||||
memContextMove(this->memContext, parentNew);
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get handle (file descriptor)
|
||||
***********************************************************************************************************************************/
|
||||
int
|
||||
ioHandleWriteHandle(const IoHandleWrite *this)
|
||||
static int
|
||||
ioHandleWriteHandle(const THIS_VOID)
|
||||
{
|
||||
THIS(const IoHandleWrite);
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_HANDLE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
@ -103,34 +70,29 @@ ioHandleWriteHandle(const IoHandleWrite *this)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get io interface
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
IoWrite *
|
||||
ioHandleWriteIo(const IoHandleWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_HANDLE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->io);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the object
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
ioHandleWriteFree(IoHandleWrite *this)
|
||||
ioHandleWriteNew(const String *name, int handle)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(IO_HANDLE_WRITE, this);
|
||||
FUNCTION_LOG_PARAM(INT, handle);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
memContextFree(this->memContext);
|
||||
IoWrite *this = NULL;
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
MEM_CONTEXT_NEW_BEGIN("IoHandleWrite")
|
||||
{
|
||||
IoHandleWrite *driver = memNew(sizeof(IoHandleWrite));
|
||||
driver->memContext = memContextCurrent();
|
||||
driver->name = strDup(name);
|
||||
driver->handle = handle;
|
||||
|
||||
this = ioWriteNewP(driver, .handle = ioHandleWriteHandle, .write = ioHandleWrite);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(IO_WRITE, this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
|
@ -6,46 +6,16 @@ Write to a handle using the IoWrite interface.
|
||||
#ifndef COMMON_IO_HANDLEWRITE_H
|
||||
#define COMMON_IO_HANDLEWRITE_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct IoHandleWrite IoHandleWrite;
|
||||
|
||||
#include "common/io/write.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
IoHandleWrite *ioHandleWriteNew(const String *name, int handle);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
void ioHandleWrite(IoHandleWrite *this, Buffer *buffer);
|
||||
IoHandleWrite *ioHandleWriteMove(IoHandleWrite *this, MemContext *parentNew);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
int ioHandleWriteHandle(const IoHandleWrite *this);
|
||||
IoWrite *ioHandleWriteIo(const IoHandleWrite *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void ioHandleWriteFree(IoHandleWrite *this);
|
||||
IoWrite *ioHandleWriteNew(const String *name, int handle);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Helper functions
|
||||
***********************************************************************************************************************************/
|
||||
void ioHandleWriteOneStr(int handle, const String *string);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_IO_HANDLE_WRITE_TYPE \
|
||||
IoHandleWrite *
|
||||
#define FUNCTION_LOG_IO_HANDLE_WRITE_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "IoHandleWrite", buffer, bufferSize)
|
||||
|
||||
#endif
|
||||
|
@ -10,6 +10,7 @@ Http Client
|
||||
#include "common/io/read.intern.h"
|
||||
#include "common/io/tls/client.h"
|
||||
#include "common/log.h"
|
||||
#include "common/object.h"
|
||||
#include "common/wait.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -64,8 +65,10 @@ struct HttpClient
|
||||
Read content
|
||||
***********************************************************************************************************************************/
|
||||
static size_t
|
||||
httpClientRead(HttpClient *this, Buffer *buffer, bool block)
|
||||
httpClientRead(THIS_VOID, Buffer *buffer, bool block)
|
||||
{
|
||||
THIS(HttpClient);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(HTTP_CLIENT, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
@ -145,8 +148,10 @@ httpClientRead(HttpClient *this, Buffer *buffer, bool block)
|
||||
Has all content been read?
|
||||
***********************************************************************************************************************************/
|
||||
static bool
|
||||
httpClientEof(const HttpClient *this)
|
||||
httpClientEof(THIS_VOID)
|
||||
{
|
||||
THIS(HttpClient);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(HTTP_CLIENT, this);
|
||||
FUNCTION_LOG_END();
|
||||
@ -388,8 +393,7 @@ httpClientRequest(
|
||||
{
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
this->ioRead = ioReadNewP(
|
||||
this, .eof = (IoReadInterfaceEof)httpClientEof, .read = (IoReadInterfaceRead)httpClientRead);
|
||||
this->ioRead = ioReadNewP(this, .eof = httpClientEof, .read = httpClientRead);
|
||||
ioReadOpen(this->ioRead);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
@ -322,6 +322,21 @@ ioReadBlock(const IoRead *this)
|
||||
FUNCTION_TEST_RETURN(this->interface.block);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Driver for the read object
|
||||
***********************************************************************************************************************************/
|
||||
void *
|
||||
ioReadDriver(IoRead *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->driver);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Is IO at EOF?
|
||||
|
||||
@ -393,6 +408,21 @@ ioReadHandle(const IoRead *this)
|
||||
FUNCTION_LOG_RETURN(INT, this->interface.handle == NULL ? -1 : this->interface.handle(this->driver));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Interface for the read object
|
||||
***********************************************************************************************************************************/
|
||||
const IoReadInterface *
|
||||
ioReadInterface(const IoRead *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(&this->interface);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the object
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -4,25 +4,23 @@ IO Read Interface Internal
|
||||
#ifndef COMMON_IO_READ_INTERN_H
|
||||
#define COMMON_IO_READ_INTERN_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
#include "common/io/read.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
typedef bool (*IoReadInterfaceEof)(void *driver);
|
||||
typedef void (*IoReadInterfaceClose)(void *driver);
|
||||
typedef bool (*IoReadInterfaceOpen)(void *driver);
|
||||
typedef int (*IoReadInterfaceHandle)(void *driver);
|
||||
typedef size_t (*IoReadInterfaceRead)(void *driver, Buffer *buffer, bool block);
|
||||
|
||||
typedef struct IoReadInterface
|
||||
{
|
||||
bool block; // Do reads block when buffer is larger than available bytes?
|
||||
IoReadInterfaceEof eof;
|
||||
IoReadInterfaceClose close;
|
||||
IoReadInterfaceHandle handle;
|
||||
IoReadInterfaceOpen open;
|
||||
IoReadInterfaceRead read;
|
||||
|
||||
bool (*eof)(void *driver);
|
||||
void (*close)(void *driver);
|
||||
bool (*open)(void *driver);
|
||||
int (*handle)(const void *driver);
|
||||
size_t (*read)(void *driver, Buffer *buffer, bool block);
|
||||
} IoReadInterface;
|
||||
|
||||
#define ioReadNewP(driver, ...) \
|
||||
@ -30,6 +28,12 @@ typedef struct IoReadInterface
|
||||
|
||||
IoRead *ioReadNew(void *driver, IoReadInterface interface);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
void *ioReadDriver(IoRead *this);
|
||||
const IoReadInterface *ioReadInterface(const IoRead *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -24,6 +24,7 @@ TLS Client
|
||||
#include "common/io/read.intern.h"
|
||||
#include "common/io/write.intern.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
#include "common/time.h"
|
||||
#include "common/type/keyValue.h"
|
||||
#include "common/wait.h"
|
||||
@ -258,6 +259,147 @@ tlsClientHostVerify(const String *host, X509 *certificate)
|
||||
FUNCTION_LOG_RETURN(BOOL, result);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Read from the TLS session
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
tlsClientRead(THIS_VOID, Buffer *buffer, bool block)
|
||||
{
|
||||
THIS(TlsClient);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_PARAM(BOOL, block);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->session != NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT(!bufFull(buffer));
|
||||
|
||||
ssize_t actualBytes = 0;
|
||||
|
||||
// If blocking read keep reading until buffer is full
|
||||
do
|
||||
{
|
||||
// If no tls data pending then check the socket
|
||||
if (!SSL_pending(this->session))
|
||||
{
|
||||
// Initialize the file descriptor set used for select
|
||||
fd_set selectSet;
|
||||
FD_ZERO(&selectSet);
|
||||
|
||||
// We know the socket is not negative because it passed error handling, so it is safe to cast to unsigned
|
||||
FD_SET((unsigned int)this->socket, &selectSet);
|
||||
|
||||
// Initialize timeout struct used for select. Recreate this structure each time since Linux (at least) will modify it.
|
||||
struct timeval timeoutSelect;
|
||||
timeoutSelect.tv_sec = (time_t)(this->timeout / MSEC_PER_SEC);
|
||||
timeoutSelect.tv_usec = (time_t)(this->timeout % MSEC_PER_SEC * 1000);
|
||||
|
||||
// Determine if there is data to be read
|
||||
int result = select(this->socket + 1, &selectSet, NULL, NULL, &timeoutSelect);
|
||||
THROW_ON_SYS_ERROR_FMT(result == -1, AssertError, "unable to select from '%s:%u'", strPtr(this->host), this->port);
|
||||
|
||||
// If no data read after time allotted then error
|
||||
if (!result)
|
||||
{
|
||||
THROW_FMT(
|
||||
FileReadError, "unable to read data from '%s:%u' after %" PRIu64 "ms",
|
||||
strPtr(this->host), this->port, this->timeout);
|
||||
}
|
||||
}
|
||||
|
||||
// Read and handle errors
|
||||
size_t expectedBytes = bufRemains(buffer);
|
||||
actualBytes = SSL_read(this->session, bufRemainsPtr(buffer), (int)expectedBytes);
|
||||
|
||||
cryptoError(actualBytes < 0, "unable to read from TLS");
|
||||
|
||||
// Update amount of buffer used
|
||||
bufUsedInc(buffer, (size_t)actualBytes);
|
||||
|
||||
// If zero bytes were returned then the connection was closed
|
||||
if (actualBytes == 0)
|
||||
{
|
||||
tlsClientClose(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (block && bufRemains(buffer) > 0);
|
||||
|
||||
FUNCTION_LOG_RETURN(SIZE, (size_t)actualBytes);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Write to the tls session
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
tlsClientWrite(THIS_VOID, const Buffer *buffer)
|
||||
{
|
||||
THIS(TlsClient);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->session != NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
cryptoError(SSL_write(this->session, bufPtr(buffer), (int)bufUsed(buffer)) != (int)bufUsed(buffer), "unable to write");
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Close the connection
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
tlsClientClose(TlsClient *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
// Close the socket
|
||||
if (this->socket != -1)
|
||||
{
|
||||
close(this->socket);
|
||||
this->socket = -1;
|
||||
}
|
||||
|
||||
// Free the TLS session
|
||||
if (this->session != NULL)
|
||||
{
|
||||
SSL_free(this->session);
|
||||
this->session = NULL;
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Has session been closed by the server?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
tlsClientEof(THIS_VOID)
|
||||
{
|
||||
THIS(TlsClient);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_LOG_RETURN(BOOL, this->session == NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Open connection if this is a new client or if the connection was closed by the server
|
||||
***********************************************************************************************************************************/
|
||||
@ -414,10 +556,9 @@ tlsClientOpen(TlsClient *this)
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
// Create read and write interfaces
|
||||
this->write = ioWriteNewP(this, .write = (IoWriteInterfaceWrite)tlsClientWrite);
|
||||
this->write = ioWriteNewP(this, .write = tlsClientWrite);
|
||||
ioWriteOpen(this->write);
|
||||
this->read = ioReadNewP(
|
||||
this, .block = true, .eof = (IoReadInterfaceEof)tlsClientEof, .read = (IoReadInterfaceRead)tlsClientRead);
|
||||
this->read = ioReadNewP(this, .block = true, .eof = tlsClientEof, .read = tlsClientRead);
|
||||
ioReadOpen(this->read);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
@ -426,141 +567,6 @@ tlsClientOpen(TlsClient *this)
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Read from the TLS session
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
tlsClientRead(TlsClient *this, Buffer *buffer, bool block)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_PARAM(BOOL, block);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->session != NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT(!bufFull(buffer));
|
||||
|
||||
ssize_t actualBytes = 0;
|
||||
|
||||
// If blocking read keep reading until buffer is full
|
||||
do
|
||||
{
|
||||
// If no tls data pending then check the socket
|
||||
if (!SSL_pending(this->session))
|
||||
{
|
||||
// Initialize the file descriptor set used for select
|
||||
fd_set selectSet;
|
||||
FD_ZERO(&selectSet);
|
||||
|
||||
// We know the socket is not negative because it passed error handling, so it is safe to cast to unsigned
|
||||
FD_SET((unsigned int)this->socket, &selectSet);
|
||||
|
||||
// Initialize timeout struct used for select. Recreate this structure each time since Linux (at least) will modify it.
|
||||
struct timeval timeoutSelect;
|
||||
timeoutSelect.tv_sec = (time_t)(this->timeout / MSEC_PER_SEC);
|
||||
timeoutSelect.tv_usec = (time_t)(this->timeout % MSEC_PER_SEC * 1000);
|
||||
|
||||
// Determine if there is data to be read
|
||||
int result = select(this->socket + 1, &selectSet, NULL, NULL, &timeoutSelect);
|
||||
THROW_ON_SYS_ERROR_FMT(result == -1, AssertError, "unable to select from '%s:%u'", strPtr(this->host), this->port);
|
||||
|
||||
// If no data read after time allotted then error
|
||||
if (!result)
|
||||
{
|
||||
THROW_FMT(
|
||||
FileReadError, "unable to read data from '%s:%u' after %" PRIu64 "ms",
|
||||
strPtr(this->host), this->port, this->timeout);
|
||||
}
|
||||
}
|
||||
|
||||
// Read and handle errors
|
||||
size_t expectedBytes = bufRemains(buffer);
|
||||
actualBytes = SSL_read(this->session, bufRemainsPtr(buffer), (int)expectedBytes);
|
||||
|
||||
cryptoError(actualBytes < 0, "unable to read from TLS");
|
||||
|
||||
// Update amount of buffer used
|
||||
bufUsedInc(buffer, (size_t)actualBytes);
|
||||
|
||||
// If zero bytes were returned then the connection was closed
|
||||
if (actualBytes == 0)
|
||||
{
|
||||
tlsClientClose(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (block && bufRemains(buffer) > 0);
|
||||
|
||||
FUNCTION_LOG_RETURN(SIZE, (size_t)actualBytes);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Write to the tls session
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
tlsClientWrite(TlsClient *this, const Buffer *buffer)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->session != NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
cryptoError(SSL_write(this->session, bufPtr(buffer), (int)bufUsed(buffer)) != (int)bufUsed(buffer), "unable to write");
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Close the connection
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
tlsClientClose(TlsClient *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
// Close the socket
|
||||
if (this->socket != -1)
|
||||
{
|
||||
close(this->socket);
|
||||
this->socket = -1;
|
||||
}
|
||||
|
||||
// Free the TLS session
|
||||
if (this->session != NULL)
|
||||
{
|
||||
SSL_free(this->session);
|
||||
this->session = NULL;
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Has session been closed by the server?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
tlsClientEof(const TlsClient *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_LOG_RETURN(BOOL, this->session == NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get read interface
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -36,14 +36,11 @@ TlsClient *tlsClientNew(
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
void tlsClientOpen(TlsClient *this);
|
||||
size_t tlsClientRead(TlsClient *this, Buffer *buffer, bool block);
|
||||
void tlsClientWrite(TlsClient *this, const Buffer *buffer);
|
||||
void tlsClientClose(TlsClient *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool tlsClientEof(const TlsClient *this);
|
||||
IoRead *tlsClientIoRead(const TlsClient *this);
|
||||
IoWrite *tlsClientIoWrite(const TlsClient *this);
|
||||
|
||||
|
@ -246,6 +246,21 @@ ioWriteClose(IoWrite *this)
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Interface for the write object
|
||||
***********************************************************************************************************************************/
|
||||
void *
|
||||
ioWriteDriver(IoWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->driver);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get/set filters
|
||||
|
||||
@ -304,6 +319,21 @@ ioWriteHandle(const IoWrite *this)
|
||||
FUNCTION_LOG_RETURN(INT, this->interface.handle == NULL ? -1 : this->interface.handle(this->driver));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Interface for the write object
|
||||
***********************************************************************************************************************************/
|
||||
const IoWriteInterface *
|
||||
ioWriteInterface(const IoWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(IO_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(&this->interface);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the object
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -3,7 +3,7 @@ IO Write Interface
|
||||
|
||||
Objects that write to some IO destination (file, socket, etc.) are implemented using this interface. All objects are required to
|
||||
implement IoWriteProcess and can optionally implement IoWriteOpen or IoWriteClose. IoWriteOpen and IoWriteClose can be used to
|
||||
allocate/open or deallocate/free resources. An example of an IoWrite object is IoBufferRead.
|
||||
allocate/open or deallocate/free resources. An example of an IoWrite object is IoBufferWrite.
|
||||
***********************************************************************************************************************************/
|
||||
#ifndef COMMON_IO_WRITE_H
|
||||
#define COMMON_IO_WRITE_H
|
||||
|
@ -9,17 +9,12 @@ IO Write Interface Internal
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
typedef void (*IoWriteInterfaceClose)(void *driver);
|
||||
typedef int (*IoWriteInterfaceHandle)(void *driver);
|
||||
typedef void (*IoWriteInterfaceOpen)(void *driver);
|
||||
typedef void (*IoWriteInterfaceWrite)(void *driver, const Buffer *buffer);
|
||||
|
||||
typedef struct IoWriteInterface
|
||||
{
|
||||
IoWriteInterfaceClose close;
|
||||
IoWriteInterfaceHandle handle;
|
||||
IoWriteInterfaceOpen open;
|
||||
IoWriteInterfaceWrite write;
|
||||
void (*close)(void *driver);
|
||||
int (*handle)(const void *driver);
|
||||
void (*open)(void *driver);
|
||||
void (*write)(void *driver, const Buffer *buffer);
|
||||
} IoWriteInterface;
|
||||
|
||||
#define ioWriteNewP(driver, ...) \
|
||||
@ -27,6 +22,12 @@ typedef struct IoWriteInterface
|
||||
|
||||
IoWrite *ioWriteNew(void *driver, IoWriteInterface interface);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
void *ioWriteDriver(IoWrite *this);
|
||||
const IoWriteInterface *ioWriteInterface(const IoWrite *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
|
20
src/common/object.h
Normal file
20
src/common/object.h
Normal 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
|
@ -10,6 +10,7 @@ Info Handler
|
||||
#include "common/crypto/cipherBlock.h"
|
||||
#include "common/crypto/hash.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/io/filter/filter.intern.h"
|
||||
#include "common/ini.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
@ -56,11 +57,11 @@ infoHash(const Ini *ini)
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
CryptoHash *hash = cryptoHashNew(HASH_TYPE_SHA1_STR);
|
||||
IoFilter *hash = cryptoHashNew(HASH_TYPE_SHA1_STR);
|
||||
StringList *sectionList = strLstSort(iniSectionList(ini), sortOrderAsc);
|
||||
|
||||
// Initial JSON opening bracket
|
||||
cryptoHashProcessC(hash, (const unsigned char *)"{", 1);
|
||||
ioFilterProcessIn(hash, BUFSTRDEF("{"));
|
||||
|
||||
// Loop through sections and create hash for checking checksum
|
||||
for (unsigned int sectionIdx = 0; sectionIdx < strLstSize(sectionList); sectionIdx++)
|
||||
@ -69,12 +70,12 @@ infoHash(const Ini *ini)
|
||||
|
||||
// Add a comma before additional sections
|
||||
if (sectionIdx != 0)
|
||||
cryptoHashProcessC(hash, (const unsigned char *)",", 1);
|
||||
ioFilterProcessIn(hash, BUFSTRDEF(","));
|
||||
|
||||
// Create the section header
|
||||
cryptoHashProcessC(hash, (const unsigned char *)"\"", 1);
|
||||
cryptoHashProcessStr(hash, section);
|
||||
cryptoHashProcessC(hash, (const unsigned char *)"\":{", 3);
|
||||
ioFilterProcessIn(hash, BUFSTRDEF("\""));
|
||||
ioFilterProcessIn(hash, BUFSTR(section));
|
||||
ioFilterProcessIn(hash, BUFSTRDEF("\":{"));
|
||||
|
||||
StringList *keyList = strLstSort(iniSectionKeyList(ini, section), sortOrderAsc);
|
||||
unsigned int keyListSize = strLstSize(keyList);
|
||||
@ -88,25 +89,27 @@ infoHash(const Ini *ini)
|
||||
if ((strEq(section, INFO_SECTION_BACKREST_STR) && !strEq(key, INFO_KEY_CHECKSUM_STR)) ||
|
||||
!strEq(section, INFO_SECTION_BACKREST_STR))
|
||||
{
|
||||
cryptoHashProcessC(hash, (const unsigned char *)"\"", 1);
|
||||
cryptoHashProcessStr(hash, key);
|
||||
cryptoHashProcessC(hash, (const unsigned char *)"\":", 2);
|
||||
cryptoHashProcessStr(hash, iniGet(ini, section, strLstGet(keyList, keyIdx)));
|
||||
ioFilterProcessIn(hash, BUFSTRDEF("\""));
|
||||
ioFilterProcessIn(hash, BUFSTR(key));
|
||||
ioFilterProcessIn(hash, BUFSTRDEF("\":"));
|
||||
ioFilterProcessIn(hash, BUFSTR(iniGet(ini, section, strLstGet(keyList, keyIdx))));
|
||||
|
||||
if ((keyListSize > 1) && (keyIdx < keyListSize - 1))
|
||||
cryptoHashProcessC(hash, (const unsigned char *)",", 1);
|
||||
ioFilterProcessIn(hash, BUFSTRDEF(","));
|
||||
}
|
||||
}
|
||||
|
||||
// Close the key/value list
|
||||
cryptoHashProcessC(hash, (const unsigned char *)"}", 1);
|
||||
ioFilterProcessIn(hash, BUFSTRDEF("}"));
|
||||
}
|
||||
|
||||
// JSON closing bracket
|
||||
cryptoHashProcessC(hash, (const unsigned char *)"}", 1);
|
||||
ioFilterProcessIn(hash, BUFSTRDEF("}"));
|
||||
|
||||
Variant *resultVar = ioFilterResult(hash);
|
||||
|
||||
memContextSwitch(MEM_CONTEXT_OLD());
|
||||
result = bufHex(cryptoHash(hash));
|
||||
result = strDup(varStr(resultVar));
|
||||
memContextSwitch(MEM_CONTEXT_TEMP());
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
@ -145,9 +148,7 @@ infoLoad(Info *this, const Storage *storage, const String *fileName, bool copyFi
|
||||
{
|
||||
ioReadFilterGroupSet(
|
||||
storageFileReadIo(infoRead),
|
||||
ioFilterGroupAdd(
|
||||
ioFilterGroupNew(), cipherBlockFilter(cipherBlockNew(cipherModeDecrypt, cipherType, BUFSTR(cipherPass),
|
||||
NULL))));
|
||||
ioFilterGroupAdd(ioFilterGroupNew(), cipherBlockNew(cipherModeDecrypt, cipherType, BUFSTR(cipherPass), NULL)));
|
||||
}
|
||||
|
||||
// Load and parse the info file
|
||||
@ -333,9 +334,7 @@ infoSave(
|
||||
{
|
||||
ioWriteFilterGroupSet(
|
||||
infoWrite,
|
||||
ioFilterGroupAdd(
|
||||
ioFilterGroupNew(), cipherBlockFilter(cipherBlockNew(cipherModeEncrypt, cipherType, BUFSTR(cipherPass),
|
||||
NULL))));
|
||||
ioFilterGroupAdd(ioFilterGroupNew(), cipherBlockNew(cipherModeEncrypt, cipherType, BUFSTR(cipherPass), NULL)));
|
||||
}
|
||||
|
||||
iniSave(ini, infoWrite);
|
||||
|
@ -289,7 +289,9 @@ XS_EUPXS(XS_pgBackRest__LibC_storageDriverPosixPathRemove)
|
||||
;
|
||||
MEM_CONTEXT_XS_TEMP_BEGIN()
|
||||
{
|
||||
storageDriverPosixPathRemove(storageDriverPosixNew(strNew("/"), 0640, 750, true, NULL), strNew(path), errorOnMissing, recurse);
|
||||
storagePathRemoveP(
|
||||
storageDriverPosixNew(strNew("/"), 0640, 750, true, NULL), strNew(path), .errorOnMissing = errorOnMissing,
|
||||
.recurse = recurse);
|
||||
}
|
||||
MEM_CONTEXT_XS_TEMP_END();
|
||||
}
|
||||
@ -482,9 +484,10 @@ XS_EUPXS(XS_pgBackRest__LibC__Crypto__Hash_process)
|
||||
MEM_CONTEXT_XS_TEMP_BEGIN()
|
||||
{
|
||||
STRLEN messageSize;
|
||||
const unsigned char *messagePtr = (const unsigned char *)SvPV(message, messageSize);
|
||||
const void *messagePtr = SvPV(message, messageSize);
|
||||
|
||||
cryptoHashProcessC(self->pxPayload, messagePtr, messageSize);
|
||||
if (messageSize > 0)
|
||||
ioFilterProcessIn(self->pxPayload, BUF(messagePtr, messageSize));
|
||||
}
|
||||
MEM_CONTEXT_XS_TEMP_END();
|
||||
}
|
||||
@ -515,7 +518,7 @@ XS_EUPXS(XS_pgBackRest__LibC__Crypto__Hash_result)
|
||||
|
||||
MEM_CONTEXT_XS_TEMP_BEGIN()
|
||||
{
|
||||
String *hash = bufHex(cryptoHash(self->pxPayload));
|
||||
const String *hash = varStr(ioFilterResult(self->pxPayload));
|
||||
|
||||
RETVAL = newSV(strSize(hash));
|
||||
SvPOK_only(RETVAL);
|
||||
@ -571,9 +574,9 @@ XS_EUPXS(XS_pgBackRest__LibC_cryptoHashOne)
|
||||
MEM_CONTEXT_XS_TEMP_BEGIN()
|
||||
{
|
||||
STRLEN messageSize;
|
||||
const unsigned char *messagePtr = (const unsigned char *)SvPV(message, messageSize);
|
||||
const void *messagePtr = SvPV(message, messageSize);
|
||||
|
||||
String *hash = bufHex(cryptoHashOneC(strNew(type), messagePtr, messageSize));
|
||||
String *hash = bufHex(cryptoHashOne(strNew(type), BUF(messagePtr, messageSize)));
|
||||
|
||||
RETVAL = newSV(strSize(hash));
|
||||
SvPOK_only(RETVAL);
|
||||
@ -619,6 +622,10 @@ XS_EUPXS(XS_pgBackRest__LibC__Cipher__Block_new)
|
||||
}
|
||||
RETVAL = NULL;
|
||||
|
||||
CHECK(type != NULL);
|
||||
CHECK(key != NULL);
|
||||
CHECK(keySize != 0);
|
||||
|
||||
// Not much point to this but it keeps the var from being unused
|
||||
if (strcmp(class, PACKAGE_NAME_LIBC "::Cipher::Block") != 0)
|
||||
croak("unexpected class name '%s'", class);
|
||||
@ -626,10 +633,9 @@ XS_EUPXS(XS_pgBackRest__LibC__Cipher__Block_new)
|
||||
MEM_CONTEXT_XS_NEW_BEGIN("cipherBlockXs")
|
||||
{
|
||||
RETVAL = memNew(sizeof(CipherBlockXs));
|
||||
|
||||
RETVAL->memContext = MEM_COMTEXT_XS();
|
||||
|
||||
RETVAL->pxPayload = cipherBlockNewC(mode, type, key, keySize, digest);
|
||||
RETVAL->pxPayload = cipherBlockNew(mode, cipherType(STR(type)), BUF(key, keySize), digest == NULL ? NULL : STR(digest));
|
||||
}
|
||||
MEM_CONTEXT_XS_NEW_END();
|
||||
{
|
||||
@ -671,10 +677,27 @@ XS_EUPXS(XS_pgBackRest__LibC__Cipher__Block_process)
|
||||
STRLEN tSize;
|
||||
const unsigned char *sourcePtr = (const unsigned char *)SvPV(source, tSize);
|
||||
|
||||
RETVAL = NEWSV(0, cipherBlockProcessSizeC(self->pxPayload, tSize));
|
||||
RETVAL = NEWSV(0, ioBufferSize());
|
||||
SvPOK_only(RETVAL);
|
||||
|
||||
SvCUR_set(RETVAL, cipherBlockProcessC(self->pxPayload, sourcePtr, tSize, (unsigned char *)SvPV_nolen(RETVAL)));
|
||||
if (tSize > 0)
|
||||
{
|
||||
size_t outBufferUsed = 0;
|
||||
|
||||
do
|
||||
{
|
||||
SvGROW(RETVAL, outBufferUsed + ioBufferSize());
|
||||
Buffer *outBuffer = bufNewUseC((unsigned char *)SvPV_nolen(RETVAL) + outBufferUsed, ioBufferSize());
|
||||
|
||||
ioFilterProcessInOut(self->pxPayload, BUF(sourcePtr, tSize), outBuffer);
|
||||
outBufferUsed += bufUsed(outBuffer);
|
||||
}
|
||||
while (ioFilterInputSame(self->pxPayload));
|
||||
|
||||
SvCUR_set(RETVAL, outBufferUsed);
|
||||
}
|
||||
else
|
||||
SvCUR_set(RETVAL, 0);
|
||||
}
|
||||
MEM_CONTEXT_XS_END();
|
||||
RETVAL = sv_2mortal(RETVAL);
|
||||
@ -707,10 +730,22 @@ XS_EUPXS(XS_pgBackRest__LibC__Cipher__Block_flush)
|
||||
|
||||
MEM_CONTEXT_XS_BEGIN(self->memContext)
|
||||
{
|
||||
RETVAL = NEWSV(0, cipherBlockProcessSizeC(self->pxPayload, 0));
|
||||
RETVAL = NEWSV(0, ioBufferSize());
|
||||
SvPOK_only(RETVAL);
|
||||
|
||||
SvCUR_set(RETVAL, cipherBlockFlushC(self->pxPayload, (unsigned char *)SvPV_nolen(RETVAL)));
|
||||
size_t outBufferUsed = 0;
|
||||
|
||||
do
|
||||
{
|
||||
SvGROW(RETVAL, outBufferUsed + ioBufferSize());
|
||||
Buffer *outBuffer = bufNewUseC((unsigned char *)SvPV_nolen(RETVAL) + outBufferUsed, ioBufferSize());
|
||||
|
||||
ioFilterProcessInOut(self->pxPayload, NULL, outBuffer);
|
||||
outBufferUsed += bufUsed(outBuffer);
|
||||
}
|
||||
while (!ioFilterDone(self->pxPayload));
|
||||
|
||||
SvCUR_set(RETVAL, outBufferUsed);
|
||||
}
|
||||
MEM_CONTEXT_XS_END();
|
||||
RETVAL = sv_2mortal(RETVAL);
|
||||
|
@ -8,28 +8,17 @@ CIFS Storage Driver
|
||||
#include "common/memContext.h"
|
||||
#include "common/regExp.h"
|
||||
#include "storage/driver/cifs/storage.h"
|
||||
#include "storage/driver/posix/storage.h"
|
||||
#include "storage/driver/posix/storage.intern.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Driver type constant string
|
||||
***********************************************************************************************************************************/
|
||||
STRING_EXTERN(STORAGE_DRIVER_CIFS_TYPE_STR, STORAGE_DRIVER_CIFS_TYPE);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
|
||||
This type *must* stay in sync with StorageDriverPosix since it is cast to StorageDriverPosix.
|
||||
***********************************************************************************************************************************/
|
||||
struct StorageDriverCifs
|
||||
{
|
||||
MemContext *memContext; // Object memory context
|
||||
Storage *interface; // Driver interface
|
||||
};
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverCifs *
|
||||
Storage *
|
||||
storageDriverCifsNew(
|
||||
const String *path, mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction)
|
||||
{
|
||||
@ -41,114 +30,8 @@ storageDriverCifsNew(
|
||||
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(path != NULL);
|
||||
ASSERT(modeFile != 0);
|
||||
ASSERT(modePath != 0);
|
||||
|
||||
// Create the object
|
||||
StorageDriverCifs *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageDriverCifs")
|
||||
{
|
||||
this = memNew(sizeof(StorageDriverCifs));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
this->interface = storageNewP(
|
||||
STORAGE_DRIVER_CIFS_TYPE_STR, path, modeFile, modePath, write, pathExpressionFunction, this,
|
||||
.exists = (StorageInterfaceExists)storageDriverPosixExists, .info = (StorageInterfaceInfo)storageDriverPosixInfo,
|
||||
.list = (StorageInterfaceList)storageDriverPosixList, .move = (StorageInterfaceMove)storageDriverPosixMove,
|
||||
.newRead = (StorageInterfaceNewRead)storageDriverPosixNewRead,
|
||||
.newWrite = (StorageInterfaceNewWrite)storageDriverCifsNewWrite,
|
||||
.pathCreate = (StorageInterfacePathCreate)storageDriverPosixPathCreate,
|
||||
.pathRemove = (StorageInterfacePathRemove)storageDriverPosixPathRemove,
|
||||
.pathSync = (StorageInterfacePathSync)storageDriverCifsPathSync,
|
||||
.remove = (StorageInterfaceRemove)storageDriverPosixRemove);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_DRIVER_CIFS, this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New file write object
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileWrite *
|
||||
storageDriverCifsNewWrite(
|
||||
StorageDriverCifs *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_CIFS, this);
|
||||
FUNCTION_LOG_PARAM(STRING, file);
|
||||
FUNCTION_LOG_PARAM(MODE, modeFile);
|
||||
FUNCTION_LOG_PARAM(MODE, modePath);
|
||||
FUNCTION_LOG_PARAM(STRING, user);
|
||||
FUNCTION_LOG_PARAM(STRING, group);
|
||||
FUNCTION_LOG_PARAM(INT64, timeModified);
|
||||
FUNCTION_LOG_PARAM(BOOL, createPath);
|
||||
FUNCTION_LOG_PARAM(BOOL, syncFile);
|
||||
FUNCTION_LOG_PARAM(BOOL, syncPath);
|
||||
FUNCTION_LOG_PARAM(BOOL, atomic);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(file != NULL);
|
||||
|
||||
FUNCTION_LOG_RETURN(
|
||||
STORAGE_FILE_WRITE,
|
||||
storageDriverPosixFileWriteInterface(
|
||||
storageDriverPosixFileWriteNew(
|
||||
(StorageDriverPosix *)this, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, false,
|
||||
atomic)));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Sync a path
|
||||
|
||||
CIFS does not support explicit syncs.
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverCifsPathSync(StorageDriverCifs *this, const String *path, bool ignoreMissing)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_CIFS, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(path != NULL);
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
Storage *
|
||||
storageDriverCifsInterface(const StorageDriverCifs *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_CIFS, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverCifsFree(StorageDriverCifs *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_CIFS, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
memContextFree(this->memContext);
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
STORAGE,
|
||||
storageDriverPosixNewInternal(
|
||||
STORAGE_DRIVER_CIFS_TYPE_STR, path, modeFile, modePath, write, pathExpressionFunction, false));
|
||||
}
|
||||
|
@ -4,18 +4,6 @@ CIFS Storage Driver
|
||||
#ifndef STORAGE_DRIVER_CIFS_STORAGE_H
|
||||
#define STORAGE_DRIVER_CIFS_STORAGE_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct StorageDriverCifs StorageDriverCifs;
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "common/type/buffer.h"
|
||||
#include "common/type/stringList.h"
|
||||
#include "storage/driver/posix/fileRead.h"
|
||||
#include "storage/driver/posix/fileWrite.h"
|
||||
#include "storage/info.h"
|
||||
#include "storage/storage.intern.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -27,33 +15,7 @@ Driver type constant
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverCifs *storageDriverCifsNew(
|
||||
Storage *storageDriverCifsNew(
|
||||
const String *path, mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileWrite *storageDriverCifsNewWrite(
|
||||
StorageDriverCifs *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
|
||||
void storageDriverCifsPathSync(StorageDriverCifs *this, const String *path, bool ignoreMissing);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
Storage *storageDriverCifsInterface(const StorageDriverCifs *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void storageDriverCifsFree(StorageDriverCifs *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_CIFS_TYPE \
|
||||
StorageDriverCifs *
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_CIFS_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageDriverCifs", buffer, bufferSize)
|
||||
|
||||
#endif
|
||||
|
@ -10,77 +10,90 @@ Posix Storage File Read Driver
|
||||
#include "common/io/read.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
#include "storage/driver/posix/common.h"
|
||||
#include "storage/driver/posix/fileRead.h"
|
||||
#include "storage/driver/posix/storage.intern.h"
|
||||
#include "storage/fileRead.intern.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
Object types
|
||||
***********************************************************************************************************************************/
|
||||
struct StorageDriverPosixFileRead
|
||||
typedef struct StorageFileReadDriverPosix
|
||||
{
|
||||
MemContext *memContext;
|
||||
StorageDriverPosix *storage;
|
||||
StorageFileRead *interface;
|
||||
IoRead *io;
|
||||
String *name;
|
||||
bool ignoreMissing;
|
||||
MemContext *memContext; // Object mem context
|
||||
StorageFileReadInterface interface; // Driver interface
|
||||
StorageDriverPosix *storage; // Storage that created this object
|
||||
|
||||
int handle;
|
||||
bool eof;
|
||||
};
|
||||
} StorageFileReadDriverPosix;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a new file
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverPosixFileRead *
|
||||
storageDriverPosixFileReadNew(StorageDriverPosix *storage, const String *name, bool ignoreMissing)
|
||||
#define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_POSIX_TYPE \
|
||||
StorageFileReadDriverPosix *
|
||||
#define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_POSIX_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageFileReadDriverPosix", buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Close the file
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
storageFileReadDriverPosixClose(THIS_VOID)
|
||||
{
|
||||
THIS(StorageFileReadDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STRING, name);
|
||||
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(name != NULL);
|
||||
ASSERT(this != NULL);
|
||||
|
||||
StorageDriverPosixFileRead *this = NULL;
|
||||
|
||||
// Create the file object
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageDriverPosixFileRead")
|
||||
// Close if the file has not already been closed
|
||||
if (this->handle != -1)
|
||||
{
|
||||
this = memNew(sizeof(StorageDriverPosixFileRead));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
this->storage = storage;
|
||||
this->name = strDup(name);
|
||||
this->ignoreMissing = ignoreMissing;
|
||||
// Close the file
|
||||
storageDriverPosixFileClose(this->handle, this->interface.name, true);
|
||||
|
||||
this->handle = -1;
|
||||
|
||||
this->interface = storageFileReadNewP(
|
||||
STORAGE_DRIVER_POSIX_TYPE_STR, this,
|
||||
.ignoreMissing = (StorageFileReadInterfaceIgnoreMissing)storageDriverPosixFileReadIgnoreMissing,
|
||||
.io = (StorageFileReadInterfaceIo)storageDriverPosixFileReadIo,
|
||||
.name = (StorageFileReadInterfaceName)storageDriverPosixFileReadName);
|
||||
|
||||
this->io = ioReadNewP(
|
||||
this, .eof = (IoReadInterfaceEof)storageDriverPosixFileReadEof,
|
||||
.close = (IoReadInterfaceClose)storageDriverPosixFileReadClose,
|
||||
.handle = (IoReadInterfaceHandle)storageDriverPosixFileReadHandle,
|
||||
.open = (IoReadInterfaceOpen)storageDriverPosixFileReadOpen, .read = (IoReadInterfaceRead)storageDriverPosixFileRead);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_DRIVER_POSIX_FILE_READ, this);
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the object
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
storageFileReadDriverPosixFree(StorageFileReadDriverPosix *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
{
|
||||
storageFileReadDriverPosixClose(this);
|
||||
|
||||
memContextCallbackClear(this->memContext);
|
||||
memContextFree(this->memContext);
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Open the file
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this)
|
||||
static bool
|
||||
storageFileReadDriverPosixOpen(THIS_VOID)
|
||||
{
|
||||
THIS(StorageFileReadDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
@ -89,12 +102,12 @@ storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this)
|
||||
bool result = false;
|
||||
|
||||
// Open the file and handle errors
|
||||
this->handle = storageDriverPosixFileOpen(this->name, O_RDONLY, 0, this->ignoreMissing, true, "read");
|
||||
this->handle = storageDriverPosixFileOpen(this->interface.name, O_RDONLY, 0, this->interface.ignoreMissing, true, "read");
|
||||
|
||||
// On success set free callback to ensure file handle is freed
|
||||
if (this->handle != -1)
|
||||
{
|
||||
memContextCallback(this->memContext, (MemContextCallback)storageDriverPosixFileReadFree, this);
|
||||
memContextCallback(this->memContext, (MemContextCallback)storageFileReadDriverPosixFree, this);
|
||||
result = true;
|
||||
}
|
||||
|
||||
@ -104,11 +117,13 @@ storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this)
|
||||
/***********************************************************************************************************************************
|
||||
Read from a file
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, bool block)
|
||||
static size_t
|
||||
storageFileReadDriverPosix(THIS_VOID, Buffer *buffer, bool block)
|
||||
{
|
||||
THIS(StorageFileReadDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_PARAM(BOOL, block);
|
||||
FUNCTION_LOG_END();
|
||||
@ -127,7 +142,7 @@ storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, boo
|
||||
|
||||
// Error occurred during read
|
||||
if (actualBytes == -1)
|
||||
THROW_SYS_ERROR_FMT(FileReadError, "unable to read '%s'", strPtr(this->name));
|
||||
THROW_SYS_ERROR_FMT(FileReadError, "unable to read '%s'", strPtr(this->interface.name));
|
||||
|
||||
// Update amount of buffer used
|
||||
bufUsedInc(buffer, (size_t)actualBytes);
|
||||
@ -141,38 +156,16 @@ storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, boo
|
||||
FUNCTION_LOG_RETURN(SIZE, (size_t)actualBytes);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Close the file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverPosixFileReadClose(StorageDriverPosixFileRead *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
// Close if the file has not already been closed
|
||||
if (this->handle != -1)
|
||||
{
|
||||
// Close the file
|
||||
storageDriverPosixFileClose(this->handle, this->name, true);
|
||||
|
||||
this->handle = -1;
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Has file reached EOF?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverPosixFileReadEof(const StorageDriverPosixFileRead *this)
|
||||
static bool
|
||||
storageFileReadDriverPosixEof(THIS_VOID)
|
||||
{
|
||||
THIS(StorageFileReadDriverPosix);
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
|
||||
FUNCTION_TEST_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
@ -183,11 +176,13 @@ storageDriverPosixFileReadEof(const StorageDriverPosixFileRead *this)
|
||||
/***********************************************************************************************************************************
|
||||
Get handle (file descriptor)
|
||||
***********************************************************************************************************************************/
|
||||
int
|
||||
storageDriverPosixFileReadHandle(const StorageDriverPosixFileRead *this)
|
||||
static int
|
||||
storageFileReadDriverPosixHandle(const THIS_VOID)
|
||||
{
|
||||
THIS(const StorageFileReadDriverPosix);
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
|
||||
FUNCTION_TEST_PARAM(STORAGE_FILE_READ_DRIVER_POSIX, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
@ -196,82 +191,46 @@ storageDriverPosixFileReadHandle(const StorageDriverPosixFileRead *this)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Should a missing file be ignored?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverPosixFileReadIgnoreMissing(const StorageDriverPosixFileRead *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->ignoreMissing);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get the interface
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileRead *
|
||||
storageDriverPosixFileReadInterface(const StorageDriverPosixFileRead *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get the I/O interface
|
||||
***********************************************************************************************************************************/
|
||||
IoRead *
|
||||
storageDriverPosixFileReadIo(const StorageDriverPosixFileRead *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->io);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
File name
|
||||
***********************************************************************************************************************************/
|
||||
const String *
|
||||
storageDriverPosixFileReadName(const StorageDriverPosixFileRead *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->name);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverPosixFileReadFree(StorageDriverPosixFileRead *this)
|
||||
storageFileReadDriverPosixNew(StorageDriverPosix *storage, const String *name, bool ignoreMissing)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
|
||||
FUNCTION_LOG_PARAM(STRING, name);
|
||||
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
ASSERT(name != NULL);
|
||||
|
||||
StorageFileRead *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageFileReadDriverPosix")
|
||||
{
|
||||
storageDriverPosixFileReadClose(this);
|
||||
StorageFileReadDriverPosix *driver = memNew(sizeof(StorageFileReadDriverPosix));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
memContextCallbackClear(this->memContext);
|
||||
memContextFree(this->memContext);
|
||||
}
|
||||
driver->interface = (StorageFileReadInterface)
|
||||
{
|
||||
.type = STORAGE_DRIVER_POSIX_TYPE_STR,
|
||||
.name = strDup(name),
|
||||
.ignoreMissing = ignoreMissing,
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
.ioInterface = (IoReadInterface)
|
||||
{
|
||||
.eof = storageFileReadDriverPosixEof,
|
||||
.handle = storageFileReadDriverPosixHandle,
|
||||
.open = storageFileReadDriverPosixOpen,
|
||||
.read = storageFileReadDriverPosix,
|
||||
},
|
||||
};
|
||||
|
||||
driver->storage = storage;
|
||||
driver->handle = -1;
|
||||
|
||||
this = storageFileReadNew(driver, &driver->interface);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, this);
|
||||
}
|
||||
|
@ -4,49 +4,12 @@ Posix Storage File Read Driver
|
||||
#ifndef STORAGE_DRIVER_POSIX_FILEREAD_H
|
||||
#define STORAGE_DRIVER_POSIX_FILEREAD_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct StorageDriverPosixFileRead StorageDriverPosixFileRead;
|
||||
|
||||
#include "common/type/buffer.h"
|
||||
#include "common/type/string.h"
|
||||
#include "storage/driver/posix/storage.h"
|
||||
#include "storage/fileRead.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverPosixFileRead *storageDriverPosixFileReadNew(StorageDriverPosix *storage, const String *name, bool ignoreMissing);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
bool storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this);
|
||||
size_t storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, bool block);
|
||||
void storageDriverPosixFileReadClose(StorageDriverPosixFileRead *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool storageDriverPosixFileReadEof(const StorageDriverPosixFileRead *this);
|
||||
int storageDriverPosixFileReadHandle(const StorageDriverPosixFileRead *this);
|
||||
bool storageDriverPosixFileReadIgnoreMissing(const StorageDriverPosixFileRead *this);
|
||||
StorageFileRead *storageDriverPosixFileReadInterface(const StorageDriverPosixFileRead *this);
|
||||
IoRead *storageDriverPosixFileReadIo(const StorageDriverPosixFileRead *this);
|
||||
const String *storageDriverPosixFileReadName(const StorageDriverPosixFileRead *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void storageDriverPosixFileReadFree(StorageDriverPosixFileRead *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_POSIX_FILE_READ_TYPE \
|
||||
StorageDriverPosixFileRead *
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_POSIX_FILE_READ_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageDriverPosixFileRead", buffer, bufferSize)
|
||||
StorageFileRead *storageFileReadDriverPosixNew(StorageDriverPosix *storage, const String *name, bool ignoreMissing);
|
||||
|
||||
#endif
|
||||
|
@ -14,36 +14,33 @@ Posix Storage File Write Driver
|
||||
#include "common/io/write.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
#include "storage/driver/posix/common.h"
|
||||
#include "storage/driver/posix/fileWrite.h"
|
||||
#include "storage/driver/posix/storage.intern.h"
|
||||
#include "storage/fileWrite.intern.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct StorageDriverPosixFileWrite
|
||||
typedef struct StorageFileWriteDriverPosix
|
||||
{
|
||||
MemContext *memContext;
|
||||
StorageDriverPosix *storage;
|
||||
StorageFileWrite *interface;
|
||||
IoWrite *io;
|
||||
String *nameTmp;
|
||||
|
||||
String *path;
|
||||
String *name;
|
||||
mode_t modeFile;
|
||||
mode_t modePath;
|
||||
const String *user;
|
||||
const String *group;
|
||||
time_t timeModified;
|
||||
|
||||
bool createPath;
|
||||
bool syncFile;
|
||||
bool syncPath;
|
||||
bool atomic;
|
||||
MemContext *memContext; // Object mem context
|
||||
StorageFileWriteInterface interface; // Driver interface
|
||||
StorageDriverPosix *storage; // Storage that created this object
|
||||
|
||||
const String *nameTmp;
|
||||
const String *path;
|
||||
int handle;
|
||||
};
|
||||
} StorageFileWriteDriverPosix;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_POSIX_TYPE \
|
||||
StorageFileWriteDriverPosix *
|
||||
#define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_POSIX_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageFileWriteDriverPosix", buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
File open constants
|
||||
@ -54,10 +51,195 @@ Since open is called more than once use constants to make sure these parameters
|
||||
#define FILE_OPEN_PURPOSE "write"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a new file
|
||||
Close the file
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverPosixFileWrite *
|
||||
storageDriverPosixFileWriteNew(
|
||||
static void
|
||||
storageFileWriteDriverPosixClose(THIS_VOID)
|
||||
{
|
||||
THIS(StorageFileWriteDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
// Close if the file has not already been closed
|
||||
if (this->handle != -1)
|
||||
{
|
||||
// Sync the file
|
||||
if (this->interface.syncFile)
|
||||
storageDriverPosixFileSync(this->handle, this->nameTmp, true, false);
|
||||
|
||||
// Close the file
|
||||
storageDriverPosixFileClose(this->handle, this->nameTmp, true);
|
||||
|
||||
// Update modified time
|
||||
if (this->interface.timeModified != 0)
|
||||
{
|
||||
THROW_ON_SYS_ERROR_FMT(
|
||||
utime(
|
||||
strPtr(this->nameTmp),
|
||||
&((struct utimbuf){.actime = this->interface.timeModified, .modtime = this->interface.timeModified})) == -1,
|
||||
FileInfoError, "unable to set time for '%s'", strPtr(this->nameTmp));
|
||||
}
|
||||
|
||||
// Rename from temp file
|
||||
if (this->interface.atomic)
|
||||
{
|
||||
if (rename(strPtr(this->nameTmp), strPtr(this->interface.name)) == -1)
|
||||
{
|
||||
THROW_SYS_ERROR_FMT(
|
||||
FileMoveError, "unable to move '%s' to '%s'", strPtr(this->nameTmp), strPtr(this->interface.name));
|
||||
}
|
||||
}
|
||||
|
||||
// Sync the path
|
||||
if (this->interface.syncPath)
|
||||
storageDriverPosixPathSync(this->storage, this->path, false);
|
||||
|
||||
// This marks the file as closed
|
||||
this->handle = -1;
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free object
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
storageFileWriteDriverPosixFree(StorageFileWriteDriverPosix *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
{
|
||||
memContextCallbackClear(this->memContext);
|
||||
|
||||
// Close the temp file. *Close() must be called explicitly in order for the file to be sycn'ed, renamed, etc. If *Free()
|
||||
// is called first the assumption is that some kind of error occurred and we should only close the handle to free
|
||||
// resources.
|
||||
if (this->handle != -1)
|
||||
storageDriverPosixFileClose(this->handle, this->interface.name, true);
|
||||
|
||||
memContextFree(this->memContext);
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Open the file
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
storageFileWriteDriverPosixOpen(THIS_VOID)
|
||||
{
|
||||
THIS(StorageFileWriteDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->handle == -1);
|
||||
|
||||
// Open the file and handle errors
|
||||
this->handle = storageDriverPosixFileOpen(
|
||||
this->nameTmp, FILE_OPEN_FLAGS, this->interface.modeFile, this->interface.createPath, true, FILE_OPEN_PURPOSE);
|
||||
|
||||
// If path is missing
|
||||
if (this->handle == -1)
|
||||
{
|
||||
// Create the path
|
||||
storageDriverPosixPathCreate(this->storage, this->path, false, false, this->interface.modePath);
|
||||
|
||||
// Try the open again
|
||||
this->handle = storageDriverPosixFileOpen(
|
||||
this->nameTmp, FILE_OPEN_FLAGS, this->interface.modeFile, false, true, FILE_OPEN_PURPOSE);
|
||||
}
|
||||
|
||||
// Set free callback to ensure file handle is freed
|
||||
memContextCallback(this->memContext, (MemContextCallback)storageFileWriteDriverPosixFree, this);
|
||||
|
||||
// Update user/group owner
|
||||
if (this->interface.user != NULL || this->interface.group != NULL)
|
||||
{
|
||||
struct passwd *userData = NULL;
|
||||
struct group *groupData = NULL;
|
||||
|
||||
if (this->interface.user != NULL)
|
||||
{
|
||||
THROW_ON_SYS_ERROR_FMT(
|
||||
(userData = getpwnam(strPtr(this->interface.user))) == NULL, UserMissingError, "unable to find user '%s'",
|
||||
strPtr(this->interface.user));
|
||||
}
|
||||
|
||||
if (this->interface.group != NULL)
|
||||
{
|
||||
THROW_ON_SYS_ERROR_FMT(
|
||||
(groupData = getgrnam(strPtr(this->interface.group))) == NULL, GroupMissingError, "unable to find group '%s'",
|
||||
strPtr(this->interface.group));
|
||||
}
|
||||
|
||||
THROW_ON_SYS_ERROR_FMT(
|
||||
chown(
|
||||
strPtr(this->nameTmp), userData != NULL ? userData->pw_uid : (uid_t)-1,
|
||||
groupData != NULL ? groupData->gr_gid : (gid_t)-1) == -1,
|
||||
FileOwnerError, "unable to set ownership for '%s'", strPtr(this->nameTmp));
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Write to the file
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
storageFileWriteDriverPosix(THIS_VOID, const Buffer *buffer)
|
||||
{
|
||||
THIS(StorageFileWriteDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT(this->handle != -1);
|
||||
|
||||
// Write the data
|
||||
if (write(this->handle, bufPtr(buffer), bufUsed(buffer)) != (ssize_t)bufUsed(buffer))
|
||||
THROW_SYS_ERROR_FMT(FileWriteError, "unable to write '%s'", strPtr(this->nameTmp));
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get handle (file descriptor)
|
||||
***********************************************************************************************************************************/
|
||||
static int
|
||||
storageFileWriteDriverPosixHandle(const THIS_VOID)
|
||||
{
|
||||
THIS(const StorageFileWriteDriverPosix);
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE_DRIVER_POSIX, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->handle);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileWrite *
|
||||
storageFileWriteDriverPosixNew(
|
||||
StorageDriverPosix *storage, const String *name, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
|
||||
{
|
||||
@ -80,357 +262,44 @@ storageDriverPosixFileWriteNew(
|
||||
ASSERT(modeFile != 0);
|
||||
ASSERT(modePath != 0);
|
||||
|
||||
StorageDriverPosixFileWrite *this = NULL;
|
||||
StorageFileWrite *this = NULL;
|
||||
|
||||
// Create the file
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageDriverPosixFileWrite")
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageFileWriteDriverPosix")
|
||||
{
|
||||
this = memNew(sizeof(StorageDriverPosixFileWrite));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
this->storage = storage;
|
||||
StorageFileWriteDriverPosix *driver = memNew(sizeof(StorageFileWriteDriverPosix));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
this->interface = storageFileWriteNewP(
|
||||
STORAGE_DRIVER_POSIX_TYPE_STR, this, .atomic = (StorageFileWriteInterfaceAtomic)storageDriverPosixFileWriteAtomic,
|
||||
.createPath = (StorageFileWriteInterfaceCreatePath)storageDriverPosixFileWriteCreatePath,
|
||||
.io = (StorageFileWriteInterfaceIo)storageDriverPosixFileWriteIo,
|
||||
.modeFile = (StorageFileWriteInterfaceModeFile)storageDriverPosixFileWriteModeFile,
|
||||
.modePath = (StorageFileWriteInterfaceModePath)storageDriverPosixFileWriteModePath,
|
||||
.name = (StorageFileWriteInterfaceName)storageDriverPosixFileWriteName,
|
||||
.syncFile = (StorageFileWriteInterfaceSyncFile)storageDriverPosixFileWriteSyncFile,
|
||||
.syncPath = (StorageFileWriteInterfaceSyncPath)storageDriverPosixFileWriteSyncPath);
|
||||
driver->interface = (StorageFileWriteInterface)
|
||||
{
|
||||
.type = STORAGE_DRIVER_POSIX_TYPE_STR,
|
||||
.name = strDup(name),
|
||||
.atomic = atomic,
|
||||
.createPath = createPath,
|
||||
.group = strDup(group),
|
||||
.modeFile = modeFile,
|
||||
.modePath = modePath,
|
||||
.syncFile = syncFile,
|
||||
.syncPath = syncPath,
|
||||
.user = strDup(user),
|
||||
.timeModified = timeModified,
|
||||
|
||||
this->io = ioWriteNewP(
|
||||
this, .close = (IoWriteInterfaceClose)storageDriverPosixFileWriteClose,
|
||||
.handle = (IoWriteInterfaceHandle)storageDriverPosixFileWriteHandle,
|
||||
.open = (IoWriteInterfaceOpen)storageDriverPosixFileWriteOpen,
|
||||
.write = (IoWriteInterfaceWrite)storageDriverPosixFileWrite);
|
||||
.ioInterface = (IoWriteInterface)
|
||||
{
|
||||
.close = storageFileWriteDriverPosixClose,
|
||||
.handle = storageFileWriteDriverPosixHandle,
|
||||
.open = storageFileWriteDriverPosixOpen,
|
||||
.write = storageFileWriteDriverPosix,
|
||||
},
|
||||
};
|
||||
|
||||
this->path = strPath(name);
|
||||
this->name = strDup(name);
|
||||
this->nameTmp = atomic ? strNewFmt("%s." STORAGE_FILE_TEMP_EXT, strPtr(name)) : this->name;
|
||||
this->modeFile = modeFile;
|
||||
this->modePath = modePath;
|
||||
this->user = strDup(user);
|
||||
this->group = strDup(group);
|
||||
this->timeModified = timeModified;
|
||||
this->createPath = createPath;
|
||||
this->syncFile = syncFile;
|
||||
this->syncPath = syncPath;
|
||||
this->atomic = atomic;
|
||||
driver->storage = storage;
|
||||
driver->nameTmp = atomic ? strNewFmt("%s." STORAGE_FILE_TEMP_EXT, strPtr(name)) : driver->interface.name;
|
||||
driver->path = strPath(name);
|
||||
driver->handle = -1;
|
||||
|
||||
this->handle = -1;
|
||||
this = storageFileWriteNew(driver, &driver->interface);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Open the file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverPosixFileWriteOpen(StorageDriverPosixFileWrite *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->handle == -1);
|
||||
|
||||
// Open the file and handle errors
|
||||
this->handle = storageDriverPosixFileOpen(
|
||||
this->nameTmp, FILE_OPEN_FLAGS, this->modeFile, this->createPath, true, FILE_OPEN_PURPOSE);
|
||||
|
||||
// If path is missing
|
||||
if (this->handle == -1)
|
||||
{
|
||||
// Create the path
|
||||
storageDriverPosixPathCreate(this->storage, this->path, false, false, this->modePath);
|
||||
|
||||
// Try the open again
|
||||
this->handle = storageDriverPosixFileOpen(
|
||||
this->nameTmp, FILE_OPEN_FLAGS, this->modeFile, false, true, FILE_OPEN_PURPOSE);
|
||||
}
|
||||
// On success set free callback to ensure file handle is freed
|
||||
else
|
||||
memContextCallback(this->memContext, (MemContextCallback)storageDriverPosixFileWriteFree, this);
|
||||
|
||||
// Update user/group owner
|
||||
if (this->user != NULL || this->group != NULL)
|
||||
{
|
||||
struct passwd *userData = NULL;
|
||||
struct group *groupData = NULL;
|
||||
|
||||
if (this->user != NULL)
|
||||
{
|
||||
THROW_ON_SYS_ERROR_FMT(
|
||||
(userData = getpwnam(strPtr(this->user))) == NULL, UserMissingError, "unable to find user '%s'",
|
||||
strPtr(this->user));
|
||||
}
|
||||
|
||||
if (this->group != NULL)
|
||||
{
|
||||
THROW_ON_SYS_ERROR_FMT(
|
||||
(groupData = getgrnam(strPtr(this->group))) == NULL, GroupMissingError, "unable to find group '%s'",
|
||||
strPtr(this->group));
|
||||
}
|
||||
|
||||
THROW_ON_SYS_ERROR_FMT(
|
||||
chown(
|
||||
strPtr(this->nameTmp), userData != NULL ? userData->pw_uid : (uid_t)-1,
|
||||
groupData != NULL ? groupData->gr_gid : (gid_t)-1) == -1,
|
||||
FileOwnerError, "unable to set ownership for '%s'", strPtr(this->nameTmp));
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Write to a file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverPosixFileWrite(StorageDriverPosixFileWrite *this, const Buffer *buffer)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT(this->handle != -1);
|
||||
|
||||
// Write the data
|
||||
if (write(this->handle, bufPtr(buffer), bufUsed(buffer)) != (ssize_t)bufUsed(buffer))
|
||||
THROW_SYS_ERROR_FMT(FileWriteError, "unable to write '%s'", strPtr(this->nameTmp));
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Close the file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverPosixFileWriteClose(StorageDriverPosixFileWrite *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
// Close if the file has not already been closed
|
||||
if (this->handle != -1)
|
||||
{
|
||||
// Sync the file
|
||||
if (this->syncFile)
|
||||
storageDriverPosixFileSync(this->handle, this->nameTmp, true, false);
|
||||
|
||||
// Close the file
|
||||
storageDriverPosixFileClose(this->handle, this->nameTmp, true);
|
||||
|
||||
// Update modified time
|
||||
if (this->timeModified != 0)
|
||||
{
|
||||
THROW_ON_SYS_ERROR_FMT(
|
||||
utime(
|
||||
strPtr(this->nameTmp), &((struct utimbuf){.actime = this->timeModified, .modtime = this->timeModified})) == -1,
|
||||
FileInfoError, "unable to set time for '%s'", strPtr(this->nameTmp));
|
||||
}
|
||||
|
||||
// Rename from temp file
|
||||
if (this->atomic)
|
||||
{
|
||||
if (rename(strPtr(this->nameTmp), strPtr(this->name)) == -1)
|
||||
THROW_SYS_ERROR_FMT(FileMoveError, "unable to move '%s' to '%s'", strPtr(this->nameTmp), strPtr(this->name));
|
||||
}
|
||||
|
||||
// Sync the path
|
||||
if (this->syncPath)
|
||||
storageDriverPosixPathSync(this->storage, this->path, false);
|
||||
|
||||
// This marks the file as closed
|
||||
this->handle = -1;
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Will the file be written atomically?
|
||||
|
||||
For the posix driver this means writing to a temp file first and then renaming once it is closed and synced.
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverPosixFileWriteAtomic(const StorageDriverPosixFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->atomic);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Will the path be created for the file if it does not exist?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverPosixFileWriteCreatePath(const StorageDriverPosixFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->createPath);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get handle (file descriptor)
|
||||
***********************************************************************************************************************************/
|
||||
int
|
||||
storageDriverPosixFileWriteHandle(const StorageDriverPosixFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->handle);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get interface
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileWrite *
|
||||
storageDriverPosixFileWriteInterface(const StorageDriverPosixFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get I/O interface
|
||||
***********************************************************************************************************************************/
|
||||
IoWrite *
|
||||
storageDriverPosixFileWriteIo(const StorageDriverPosixFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->io);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Mode for the file to be created
|
||||
***********************************************************************************************************************************/
|
||||
mode_t
|
||||
storageDriverPosixFileWriteModeFile(const StorageDriverPosixFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->modeFile);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Mode for any paths that are created while writing the file
|
||||
***********************************************************************************************************************************/
|
||||
mode_t
|
||||
storageDriverPosixFileWriteModePath(const StorageDriverPosixFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->modePath);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
File name
|
||||
***********************************************************************************************************************************/
|
||||
const String *
|
||||
storageDriverPosixFileWriteName(const StorageDriverPosixFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->name);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Will the file be synced after it is closed?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverPosixFileWriteSyncFile(const StorageDriverPosixFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->syncFile);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Will the directory be synced to disk after the write is completed?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverPosixFileWriteSyncPath(const StorageDriverPosixFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->syncPath);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverPosixFileWriteFree(StorageDriverPosixFileWrite *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
{
|
||||
memContextCallbackClear(this->memContext);
|
||||
|
||||
// Close the temp file. *Close() must be called explicitly in order for the file to be sycn'ed, renamed, etc. If *Free()
|
||||
// is called first the assumption is that some kind of error occurred and we should only close the handle to free
|
||||
// resources.
|
||||
if (this->handle != -1)
|
||||
storageDriverPosixFileClose(this->handle, this->name, true);
|
||||
|
||||
memContextFree(this->memContext);
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
FUNCTION_LOG_RETURN(STORAGE_FILE_WRITE, this);
|
||||
}
|
||||
|
@ -4,57 +4,15 @@ Posix Storage File Write Driver
|
||||
#ifndef STORAGE_DRIVER_POSIX_FILEWRITE_H
|
||||
#define STORAGE_DRIVER_POSIX_FILEWRITE_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct StorageDriverPosixFileWrite StorageDriverPosixFileWrite;
|
||||
|
||||
#include "common/type/buffer.h"
|
||||
#include "storage/fileWrite.intern.h"
|
||||
#include "storage/driver/posix/storage.h"
|
||||
#include "storage/fileWrite.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverPosixFileWrite *storageDriverPosixFileWriteNew(
|
||||
StorageFileWrite *storageFileWriteDriverPosixNew(
|
||||
StorageDriverPosix *storage, const String *name, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
void storageDriverPosixFileWriteOpen(StorageDriverPosixFileWrite *this);
|
||||
void storageDriverPosixFileWrite(StorageDriverPosixFileWrite *this, const Buffer *buffer);
|
||||
void storageDriverPosixFileWriteClose(StorageDriverPosixFileWrite *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool storageDriverPosixFileWriteAtomic(const StorageDriverPosixFileWrite *this);
|
||||
bool storageDriverPosixFileWriteCreatePath(const StorageDriverPosixFileWrite *this);
|
||||
mode_t storageDriverPosixFileWriteModeFile(const StorageDriverPosixFileWrite *this);
|
||||
int storageDriverPosixFileWriteHandle(const StorageDriverPosixFileWrite *this);
|
||||
StorageFileWrite* storageDriverPosixFileWriteInterface(const StorageDriverPosixFileWrite *this);
|
||||
IoWrite *storageDriverPosixFileWriteIo(const StorageDriverPosixFileWrite *this);
|
||||
mode_t storageDriverPosixFileWriteModePath(const StorageDriverPosixFileWrite *this);
|
||||
const String *storageDriverPosixFileWriteName(const StorageDriverPosixFileWrite *this);
|
||||
const StorageDriverPosix *storageDriverPosixFileWriteStorage(const StorageDriverPosixFileWrite *this);
|
||||
bool storageDriverPosixFileWriteSyncFile(const StorageDriverPosixFileWrite *this);
|
||||
bool storageDriverPosixFileWriteSyncPath(const StorageDriverPosixFileWrite *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void storageDriverPosixFileWriteFree(StorageDriverPosixFileWrite *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_POSIX_FILE_WRITE_TYPE \
|
||||
StorageDriverPosixFileWrite *
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_POSIX_FILE_WRITE_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageDriverPosixFileWrite", buffer, bufferSize)
|
||||
|
||||
#endif
|
||||
|
@ -7,6 +7,7 @@ Posix Storage Driver
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -17,16 +18,11 @@ Posix Storage Driver
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/regExp.h"
|
||||
#include "storage/driver/posix/storage.h"
|
||||
#include "storage/driver/posix/fileRead.h"
|
||||
#include "storage/driver/posix/fileWrite.h"
|
||||
#include "storage/driver/posix/storage.intern.h"
|
||||
#include "storage/driver/posix/common.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Define PATH_MAX if it is not defined
|
||||
***********************************************************************************************************************************/
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX (4 * 1024)
|
||||
#endif
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Driver type constant string
|
||||
***********************************************************************************************************************************/
|
||||
@ -38,58 +34,17 @@ Object type
|
||||
struct StorageDriverPosix
|
||||
{
|
||||
MemContext *memContext; // Object memory context
|
||||
Storage *interface; // Driver interface
|
||||
bool syncPath; // Will paths be synced?
|
||||
};
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverPosix *
|
||||
storageDriverPosixNew(
|
||||
const String *path, mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
FUNCTION_LOG_PARAM(MODE, modeFile);
|
||||
FUNCTION_LOG_PARAM(MODE, modePath);
|
||||
FUNCTION_LOG_PARAM(BOOL, write);
|
||||
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(path != NULL);
|
||||
ASSERT(modeFile != 0);
|
||||
ASSERT(modePath != 0);
|
||||
|
||||
// Create the object
|
||||
StorageDriverPosix *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageDriverPosix")
|
||||
{
|
||||
this = memNew(sizeof(StorageDriverPosix));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
this->interface = storageNewP(
|
||||
STORAGE_DRIVER_POSIX_TYPE_STR, path, modeFile, modePath, write, pathExpressionFunction, this,
|
||||
.exists = (StorageInterfaceExists)storageDriverPosixExists, .info = (StorageInterfaceInfo)storageDriverPosixInfo,
|
||||
.infoList = (StorageInterfaceInfoList)storageDriverPosixInfoList, .list = (StorageInterfaceList)storageDriverPosixList,
|
||||
.move = (StorageInterfaceMove)storageDriverPosixMove, .newRead = (StorageInterfaceNewRead)storageDriverPosixNewRead,
|
||||
.newWrite = (StorageInterfaceNewWrite)storageDriverPosixNewWrite,
|
||||
.pathCreate = (StorageInterfacePathCreate)storageDriverPosixPathCreate,
|
||||
.pathRemove = (StorageInterfacePathRemove)storageDriverPosixPathRemove,
|
||||
.pathSync = (StorageInterfacePathSync)storageDriverPosixPathSync,
|
||||
.remove = (StorageInterfaceRemove)storageDriverPosixRemove);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_DRIVER_POSIX, this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Does a file exist? This function is only for files, not paths.
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverPosixExists(StorageDriverPosix *this, const String *path)
|
||||
static bool
|
||||
storageDriverPosixExists(THIS_VOID, const String *path)
|
||||
{
|
||||
THIS(StorageDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -119,9 +74,11 @@ storageDriverPosixExists(StorageDriverPosix *this, const String *path)
|
||||
/***********************************************************************************************************************************
|
||||
File/path info
|
||||
***********************************************************************************************************************************/
|
||||
StorageInfo
|
||||
storageDriverPosixInfo(StorageDriverPosix *this, const String *file, bool ignoreMissing, bool followLink)
|
||||
static StorageInfo
|
||||
storageDriverPosixInfo(THIS_VOID, const String *file, bool ignoreMissing, bool followLink)
|
||||
{
|
||||
THIS(StorageDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_PARAM(STRING, file);
|
||||
@ -227,10 +184,12 @@ storageDriverPosixInfoListEntry(
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
||||
bool
|
||||
static bool
|
||||
storageDriverPosixInfoList(
|
||||
StorageDriverPosix *this, const String *path, bool errorOnMissing, StorageInfoListCallback callback, void *callbackData)
|
||||
THIS_VOID, const String *path, bool errorOnMissing, StorageInfoListCallback callback, void *callbackData)
|
||||
{
|
||||
THIS(StorageDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -292,9 +251,11 @@ storageDriverPosixInfoList(
|
||||
/***********************************************************************************************************************************
|
||||
Get a list of files from a directory
|
||||
***********************************************************************************************************************************/
|
||||
StringList *
|
||||
storageDriverPosixList(StorageDriverPosix *this, const String *path, bool errorOnMissing, const String *expression)
|
||||
static StringList *
|
||||
storageDriverPosixList(THIS_VOID, const String *path, bool errorOnMissing, const String *expression)
|
||||
{
|
||||
THIS(StorageDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -362,13 +323,15 @@ storageDriverPosixList(StorageDriverPosix *this, const String *path, bool errorO
|
||||
/***********************************************************************************************************************************
|
||||
Move a path/file
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *source, StorageDriverPosixFileWrite *destination)
|
||||
static bool
|
||||
storageDriverPosixMove(THIS_VOID, StorageFileRead *source, StorageFileWrite *destination)
|
||||
{
|
||||
THIS(StorageDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, source);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX_FILE_WRITE, destination);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_READ, source);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE, destination);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
@ -379,8 +342,8 @@ storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *sou
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
const String *sourceFile = storageDriverPosixFileReadName(source);
|
||||
const String *destinationFile = storageDriverPosixFileWriteName(destination);
|
||||
const String *sourceFile = storageFileReadName(source);
|
||||
const String *destinationFile = storageFileWriteName(destination);
|
||||
const String *destinationPath = strPath(destinationFile);
|
||||
|
||||
// Attempt to move the file
|
||||
@ -392,13 +355,13 @@ storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *sou
|
||||
if (!storageDriverPosixExists(this, sourceFile))
|
||||
THROW_SYS_ERROR_FMT(FileMissingError, "unable to move missing file '%s'", strPtr(sourceFile));
|
||||
|
||||
if (!storageDriverPosixFileWriteCreatePath(destination))
|
||||
if (!storageFileWriteCreatePath(destination))
|
||||
{
|
||||
THROW_SYS_ERROR_FMT(
|
||||
PathMissingError, "unable to move '%s' to missing path '%s'", strPtr(sourceFile), strPtr(destinationPath));
|
||||
}
|
||||
|
||||
storageDriverPosixPathCreate(this, destinationPath, false, false, storageDriverPosixFileWriteModePath(destination));
|
||||
storageDriverPosixPathCreate(this, destinationPath, false, false, storageFileWriteModePath(destination));
|
||||
result = storageDriverPosixMove(this, source, destination);
|
||||
}
|
||||
// Else the destination is on a different device so a copy will be needed
|
||||
@ -413,7 +376,7 @@ storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *sou
|
||||
else
|
||||
{
|
||||
// Sync source path if the destination path was synced and the paths are not equal
|
||||
if (storageDriverPosixFileWriteSyncPath(destination))
|
||||
if (storageFileWriteSyncPath(destination))
|
||||
{
|
||||
String *sourcePath = strPath(sourceFile);
|
||||
|
||||
@ -430,9 +393,11 @@ storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *sou
|
||||
/***********************************************************************************************************************************
|
||||
New file read object
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileRead *
|
||||
storageDriverPosixNewRead(StorageDriverPosix *this, const String *file, bool ignoreMissing)
|
||||
static StorageFileRead *
|
||||
storageDriverPosixNewRead(THIS_VOID, const String *file, bool ignoreMissing)
|
||||
{
|
||||
THIS(StorageDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_PARAM(STRING, file);
|
||||
@ -442,18 +407,19 @@ storageDriverPosixNewRead(StorageDriverPosix *this, const String *file, bool ign
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(file != NULL);
|
||||
|
||||
FUNCTION_LOG_RETURN(
|
||||
STORAGE_FILE_READ, storageDriverPosixFileReadInterface(storageDriverPosixFileReadNew(this, file, ignoreMissing)));
|
||||
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, storageFileReadDriverPosixNew(this, file, ignoreMissing));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New file write object
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileWrite *
|
||||
static StorageFileWrite *
|
||||
storageDriverPosixNewWrite(
|
||||
StorageDriverPosix *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
THIS_VOID, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
|
||||
{
|
||||
THIS(StorageDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_PARAM(STRING, file);
|
||||
@ -473,17 +439,19 @@ storageDriverPosixNewWrite(
|
||||
|
||||
FUNCTION_LOG_RETURN(
|
||||
STORAGE_FILE_WRITE,
|
||||
storageDriverPosixFileWriteInterface(
|
||||
storageDriverPosixFileWriteNew(
|
||||
this, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, syncPath, atomic)));
|
||||
storageFileWriteDriverPosixNew(
|
||||
this, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, this->syncPath ? syncPath : false,
|
||||
atomic));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a path
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverPosixPathCreate(StorageDriverPosix *this, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
|
||||
storageDriverPosixPathCreate(THIS_VOID, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
|
||||
{
|
||||
THIS(StorageDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -515,9 +483,11 @@ storageDriverPosixPathCreate(StorageDriverPosix *this, const String *path, bool
|
||||
/***********************************************************************************************************************************
|
||||
Remove a path
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverPosixPathRemove(StorageDriverPosix *this, const String *path, bool errorOnMissing, bool recurse)
|
||||
static void
|
||||
storageDriverPosixPathRemove(THIS_VOID, const String *path, bool errorOnMissing, bool recurse)
|
||||
{
|
||||
THIS(StorageDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -574,8 +544,10 @@ storageDriverPosixPathRemove(StorageDriverPosix *this, const String *path, bool
|
||||
Sync a path
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverPosixPathSync(StorageDriverPosix *this, const String *path, bool ignoreMissing)
|
||||
storageDriverPosixPathSync(THIS_VOID, const String *path, bool ignoreMissing)
|
||||
{
|
||||
THIS(StorageDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -585,6 +557,8 @@ storageDriverPosixPathSync(StorageDriverPosix *this, const String *path, bool ig
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(path != NULL);
|
||||
|
||||
if (this->syncPath)
|
||||
{
|
||||
// Open directory and handle errors
|
||||
int handle = storageDriverPosixFileOpen(path, O_RDONLY, 0, ignoreMissing, false, "sync");
|
||||
|
||||
@ -597,6 +571,7 @@ storageDriverPosixPathSync(StorageDriverPosix *this, const String *path, bool ig
|
||||
// Close the directory
|
||||
storageDriverPosixFileClose(handle, path, false);
|
||||
}
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
@ -604,9 +579,11 @@ storageDriverPosixPathSync(StorageDriverPosix *this, const String *path, bool ig
|
||||
/***********************************************************************************************************************************
|
||||
Remove a file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverPosixRemove(StorageDriverPosix *this, const String *file, bool errorOnMissing)
|
||||
static void
|
||||
storageDriverPosixRemove(THIS_VOID, const String *file, bool errorOnMissing)
|
||||
{
|
||||
THIS(StorageDriverPosix);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_PARAM(STRING, file);
|
||||
@ -627,32 +604,63 @@ storageDriverPosixRemove(StorageDriverPosix *this, const String *file, bool erro
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
Storage *
|
||||
storageDriverPosixInterface(const StorageDriverPosix *this)
|
||||
storageDriverPosixNewInternal(
|
||||
const String *type, const String *path, mode_t modeFile, mode_t modePath, bool write,
|
||||
StoragePathExpressionCallback pathExpressionFunction, bool syncPath)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverPosixFree(StorageDriverPosix *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, this);
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STRING, type);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
FUNCTION_LOG_PARAM(MODE, modeFile);
|
||||
FUNCTION_LOG_PARAM(MODE, modePath);
|
||||
FUNCTION_LOG_PARAM(BOOL, write);
|
||||
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
|
||||
FUNCTION_LOG_PARAM(BOOL, syncPath);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
memContextFree(this->memContext);
|
||||
ASSERT(type != NULL);
|
||||
ASSERT(path != NULL);
|
||||
ASSERT(modeFile != 0);
|
||||
ASSERT(modePath != 0);
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
// Create the object
|
||||
Storage *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageDriverPosix")
|
||||
{
|
||||
StorageDriverPosix *driver = memNew(sizeof(StorageDriverPosix));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
driver->syncPath = syncPath;
|
||||
|
||||
this = storageNewP(
|
||||
type, path, modeFile, modePath, write, pathExpressionFunction, driver, .exists = storageDriverPosixExists,
|
||||
.info = storageDriverPosixInfo, .infoList = storageDriverPosixInfoList, .list = storageDriverPosixList,
|
||||
.move = storageDriverPosixMove, .newRead = storageDriverPosixNewRead, .newWrite = storageDriverPosixNewWrite,
|
||||
.pathCreate = storageDriverPosixPathCreate, .pathRemove = storageDriverPosixPathRemove,
|
||||
.pathSync = storageDriverPosixPathSync, .remove = storageDriverPosixRemove);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE, this);
|
||||
}
|
||||
|
||||
Storage *
|
||||
storageDriverPosixNew(
|
||||
const String *path, mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
FUNCTION_LOG_PARAM(MODE, modeFile);
|
||||
FUNCTION_LOG_PARAM(MODE, modePath);
|
||||
FUNCTION_LOG_PARAM(BOOL, write);
|
||||
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(
|
||||
STORAGE,
|
||||
storageDriverPosixNewInternal(
|
||||
STORAGE_DRIVER_POSIX_TYPE_STR, path, modeFile, modePath, write, pathExpressionFunction, true));
|
||||
}
|
||||
|
@ -9,13 +9,6 @@ Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct StorageDriverPosix StorageDriverPosix;
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "common/type/buffer.h"
|
||||
#include "common/type/stringList.h"
|
||||
#include "storage/driver/posix/fileRead.h"
|
||||
#include "storage/driver/posix/fileWrite.h"
|
||||
#include "storage/info.h"
|
||||
#include "storage/storage.intern.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -27,44 +20,7 @@ Driver type constant
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverPosix *storageDriverPosixNew(
|
||||
Storage *storageDriverPosixNew(
|
||||
const String *path, mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
bool storageDriverPosixExists(StorageDriverPosix *this, const String *path);
|
||||
StorageInfo storageDriverPosixInfo(StorageDriverPosix *this, const String *file, bool ignoreMissing, bool followLink);
|
||||
bool storageDriverPosixInfoList(
|
||||
StorageDriverPosix *this, const String *path, bool errorOnMissing, StorageInfoListCallback callback, void *callbackData);
|
||||
StringList *storageDriverPosixList(StorageDriverPosix *this, const String *path, bool errorOnMissing, const String *expression);
|
||||
bool storageDriverPosixMove(StorageDriverPosix *this, StorageDriverPosixFileRead *source, StorageDriverPosixFileWrite *destination);
|
||||
StorageFileRead *storageDriverPosixNewRead(StorageDriverPosix *this, const String *file, bool ignoreMissing);
|
||||
StorageFileWrite *storageDriverPosixNewWrite(
|
||||
StorageDriverPosix *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
|
||||
void storageDriverPosixPathCreate(
|
||||
StorageDriverPosix *this, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode);
|
||||
void storageDriverPosixPathRemove(StorageDriverPosix *this, const String *path, bool errorOnMissing, bool recurse);
|
||||
void storageDriverPosixPathSync(StorageDriverPosix *this, const String *path, bool ignoreMissing);
|
||||
void storageDriverPosixRemove(StorageDriverPosix *this, const String *file, bool errorOnMissing);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
Storage *storageDriverPosixInterface(const StorageDriverPosix *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void storageDriverPosixFree(StorageDriverPosix *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_POSIX_TYPE \
|
||||
StorageDriverPosix *
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_POSIX_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageDriverPosix", buffer, bufferSize)
|
||||
|
||||
#endif
|
||||
|
31
src/storage/driver/posix/storage.intern.h
Normal file
31
src/storage/driver/posix/storage.intern.h
Normal 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
|
@ -10,6 +10,7 @@ Remote Storage File Read Driver
|
||||
#include "common/io/read.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
#include "common/type/convert.h"
|
||||
#include "storage/driver/remote/fileRead.h"
|
||||
#include "storage/driver/remote/protocol.h"
|
||||
@ -18,73 +19,35 @@ Remote Storage File Read Driver
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct StorageDriverRemoteFileRead
|
||||
typedef struct StorageFileReadDriverRemote
|
||||
{
|
||||
MemContext *memContext;
|
||||
StorageDriverRemote *storage;
|
||||
StorageFileRead *interface;
|
||||
IoRead *io;
|
||||
String *name;
|
||||
bool ignoreMissing;
|
||||
MemContext *memContext; // Object mem context
|
||||
StorageFileReadInterface interface; // Driver interface
|
||||
StorageDriverRemote *storage; // Storage that created this object
|
||||
|
||||
ProtocolClient *client; // Protocol client for requests
|
||||
size_t remaining; // Bytes remaining to be read
|
||||
size_t remaining; // Bytes remaining to be read in block
|
||||
bool eof; // Has the file reached eof?
|
||||
};
|
||||
} StorageFileReadDriverRemote;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a new file
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverRemoteFileRead *
|
||||
storageDriverRemoteFileReadNew(StorageDriverRemote *storage, ProtocolClient *client, const String *name, bool ignoreMissing)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, storage);
|
||||
FUNCTION_LOG_PARAM(PROTOCOL_CLIENT, client);
|
||||
FUNCTION_LOG_PARAM(STRING, name);
|
||||
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(storage != NULL);
|
||||
ASSERT(client != NULL);
|
||||
ASSERT(name != NULL);
|
||||
|
||||
StorageDriverRemoteFileRead *this = NULL;
|
||||
|
||||
// Create the file object
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageDriverRemoteFileRead")
|
||||
{
|
||||
this = memNew(sizeof(StorageDriverRemoteFileRead));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
this->storage = storage;
|
||||
this->name = strDup(name);
|
||||
this->ignoreMissing = ignoreMissing;
|
||||
|
||||
this->client = client;
|
||||
|
||||
this->interface = storageFileReadNewP(
|
||||
strNew(STORAGE_DRIVER_REMOTE_TYPE), this,
|
||||
.ignoreMissing = (StorageFileReadInterfaceIgnoreMissing)storageDriverRemoteFileReadIgnoreMissing,
|
||||
.io = (StorageFileReadInterfaceIo)storageDriverRemoteFileReadIo,
|
||||
.name = (StorageFileReadInterfaceName)storageDriverRemoteFileReadName);
|
||||
|
||||
this->io = ioReadNewP(
|
||||
this, .eof = (IoReadInterfaceEof)storageDriverRemoteFileReadEof,
|
||||
.open = (IoReadInterfaceOpen)storageDriverRemoteFileReadOpen, .read = (IoReadInterfaceRead)storageDriverRemoteFileRead);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_DRIVER_REMOTE_FILE_READ, this);
|
||||
}
|
||||
#define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_REMOTE_TYPE \
|
||||
StorageFileReadDriverRemote *
|
||||
#define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_REMOTE_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageFileReadDriverRemote", buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Open the file
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverRemoteFileReadOpen(StorageDriverRemoteFileRead *this)
|
||||
static bool
|
||||
storageFileReadDriverRemoteOpen(THIS_VOID)
|
||||
{
|
||||
THIS(StorageFileReadDriverRemote);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
@ -94,8 +57,8 @@ storageDriverRemoteFileReadOpen(StorageDriverRemoteFileRead *this)
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
ProtocolCommand *command = protocolCommandNew(PROTOCOL_COMMAND_STORAGE_OPEN_READ_STR);
|
||||
protocolCommandParamAdd(command, VARSTR(this->name));
|
||||
protocolCommandParamAdd(command, VARBOOL(this->ignoreMissing));
|
||||
protocolCommandParamAdd(command, VARSTR(this->interface.name));
|
||||
protocolCommandParamAdd(command, VARBOOL(this->interface.ignoreMissing));
|
||||
|
||||
result = varBool(protocolClientExecute(this->client, command, true));
|
||||
}
|
||||
@ -107,11 +70,13 @@ storageDriverRemoteFileReadOpen(StorageDriverRemoteFileRead *this)
|
||||
/***********************************************************************************************************************************
|
||||
Read from a file
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
storageDriverRemoteFileRead(StorageDriverRemoteFileRead *this, Buffer *buffer, bool block)
|
||||
static size_t
|
||||
storageFileReadDriverRemote(THIS_VOID, Buffer *buffer, bool block)
|
||||
{
|
||||
THIS(StorageFileReadDriverRemote);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_PARAM(BOOL, block);
|
||||
FUNCTION_LOG_END();
|
||||
@ -164,11 +129,13 @@ storageDriverRemoteFileRead(StorageDriverRemoteFileRead *this, Buffer *buffer, b
|
||||
/***********************************************************************************************************************************
|
||||
Has file reached EOF?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverRemoteFileReadEof(const StorageDriverRemoteFileRead *this)
|
||||
static bool
|
||||
storageFileReadDriverRemoteEof(THIS_VOID)
|
||||
{
|
||||
THIS(StorageFileReadDriverRemote);
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this);
|
||||
FUNCTION_TEST_PARAM(STORAGE_FILE_READ_DRIVER_REMOTE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
@ -177,61 +144,49 @@ storageDriverRemoteFileReadEof(const StorageDriverRemoteFileRead *this)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Should a missing file be ignored?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverRemoteFileReadIgnoreMissing(const StorageDriverRemoteFileRead *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->ignoreMissing);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get the interface
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileRead *
|
||||
storageDriverRemoteFileReadInterface(const StorageDriverRemoteFileRead *this)
|
||||
storageFileReadDriverRemoteNew(StorageDriverRemote *storage, ProtocolClient *client, const String *name, bool ignoreMissing)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, storage);
|
||||
FUNCTION_LOG_PARAM(PROTOCOL_CLIENT, client);
|
||||
FUNCTION_LOG_PARAM(STRING, name);
|
||||
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(storage != NULL);
|
||||
ASSERT(client != NULL);
|
||||
ASSERT(name != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface);
|
||||
}
|
||||
StorageFileRead *this = NULL;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get the I/O interface
|
||||
***********************************************************************************************************************************/
|
||||
IoRead *
|
||||
storageDriverRemoteFileReadIo(const StorageDriverRemoteFileRead *this)
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageFileReadDriverRemote")
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
StorageFileReadDriverRemote *driver = memNew(sizeof(StorageFileReadDriverRemote));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->io);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
File name
|
||||
***********************************************************************************************************************************/
|
||||
const String *
|
||||
storageDriverRemoteFileReadName(const StorageDriverRemoteFileRead *this)
|
||||
driver->interface = (StorageFileReadInterface)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
.type = STORAGE_DRIVER_REMOTE_TYPE_STR,
|
||||
.name = strDup(name),
|
||||
.ignoreMissing = ignoreMissing,
|
||||
|
||||
ASSERT(this != NULL);
|
||||
.ioInterface = (IoReadInterface)
|
||||
{
|
||||
.eof = storageFileReadDriverRemoteEof,
|
||||
.open = storageFileReadDriverRemoteOpen,
|
||||
.read = storageFileReadDriverRemote,
|
||||
},
|
||||
};
|
||||
|
||||
FUNCTION_TEST_RETURN(this->name);
|
||||
driver->storage = storage;
|
||||
driver->client = client;
|
||||
|
||||
this = storageFileReadNew(driver, &driver->interface);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, this);
|
||||
}
|
||||
|
@ -4,49 +4,14 @@ Remote Storage File Read Driver
|
||||
#ifndef STORAGE_DRIVER_REMOTE_FILEREAD_H
|
||||
#define STORAGE_DRIVER_REMOTE_FILEREAD_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct StorageDriverRemoteFileRead StorageDriverRemoteFileRead;
|
||||
|
||||
#include "common/type/buffer.h"
|
||||
#include "common/type/string.h"
|
||||
#include "protocol/client.h"
|
||||
#include "storage/driver/remote/storage.h"
|
||||
#include "storage/driver/remote/storage.intern.h"
|
||||
#include "storage/fileRead.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverRemoteFileRead *storageDriverRemoteFileReadNew(
|
||||
StorageFileRead *storageFileReadDriverRemoteNew(
|
||||
StorageDriverRemote *storage, ProtocolClient *client, const String *name, bool ignoreMissing);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
bool storageDriverRemoteFileReadOpen(StorageDriverRemoteFileRead *this);
|
||||
size_t storageDriverRemoteFileRead(StorageDriverRemoteFileRead *this, Buffer *buffer, bool block);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool storageDriverRemoteFileReadEof(const StorageDriverRemoteFileRead *this);
|
||||
bool storageDriverRemoteFileReadIgnoreMissing(const StorageDriverRemoteFileRead *this);
|
||||
StorageFileRead *storageDriverRemoteFileReadInterface(const StorageDriverRemoteFileRead *this);
|
||||
IoRead *storageDriverRemoteFileReadIo(const StorageDriverRemoteFileRead *this);
|
||||
const String *storageDriverRemoteFileReadName(const StorageDriverRemoteFileRead *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void storageDriverRemoteFileReadFree(StorageDriverRemoteFileRead *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_REMOTE_FILE_READ_TYPE \
|
||||
StorageDriverRemoteFileRead *
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_REMOTE_FILE_READ_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageDriverRemoteFileRead", buffer, bufferSize)
|
||||
|
||||
#endif
|
||||
|
@ -7,6 +7,7 @@ Remote Storage File Write Driver
|
||||
#include "common/io/write.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
#include "storage/driver/remote/fileWrite.h"
|
||||
#include "storage/driver/remote/protocol.h"
|
||||
#include "storage/fileWrite.intern.h"
|
||||
@ -14,157 +15,32 @@ Remote Storage File Write Driver
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct StorageDriverRemoteFileWrite
|
||||
typedef struct StorageFileWriteDriverRemote
|
||||
{
|
||||
MemContext *memContext;
|
||||
StorageDriverRemote *storage;
|
||||
ProtocolClient *client;
|
||||
StorageFileWrite *interface;
|
||||
IoWrite *io;
|
||||
|
||||
String *name;
|
||||
mode_t modeFile;
|
||||
mode_t modePath;
|
||||
const String *user;
|
||||
const String *group;
|
||||
time_t timeModified;
|
||||
|
||||
bool createPath;
|
||||
bool syncFile;
|
||||
bool syncPath;
|
||||
bool atomic;
|
||||
};
|
||||
MemContext *memContext; // Object mem context
|
||||
StorageFileWriteInterface interface; // Driver interface
|
||||
StorageDriverRemote *storage; // Storage that created this object
|
||||
ProtocolClient *client; // Protocol client to make requests with
|
||||
} StorageFileWriteDriverRemote;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a new file
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverRemoteFileWrite *
|
||||
storageDriverRemoteFileWriteNew(
|
||||
StorageDriverRemote *storage, ProtocolClient *client, const String *name, mode_t modeFile, mode_t modePath, const String *user,
|
||||
const String *group, time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, storage);
|
||||
FUNCTION_LOG_PARAM(STRING, name);
|
||||
FUNCTION_LOG_PARAM(MODE, modeFile);
|
||||
FUNCTION_LOG_PARAM(MODE, modePath);
|
||||
FUNCTION_LOG_PARAM(STRING, user);
|
||||
FUNCTION_LOG_PARAM(STRING, group);
|
||||
FUNCTION_LOG_PARAM(INT64, timeModified);
|
||||
FUNCTION_LOG_PARAM(BOOL, createPath);
|
||||
FUNCTION_LOG_PARAM(BOOL, syncFile);
|
||||
FUNCTION_LOG_PARAM(BOOL, syncPath);
|
||||
FUNCTION_LOG_PARAM(BOOL, atomic);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(storage != NULL);
|
||||
ASSERT(name != NULL);
|
||||
ASSERT(modeFile != 0);
|
||||
ASSERT(modePath != 0);
|
||||
|
||||
StorageDriverRemoteFileWrite *this = NULL;
|
||||
|
||||
// Create the file
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageDriverRemoteFileWrite")
|
||||
{
|
||||
this = memNew(sizeof(StorageDriverRemoteFileWrite));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
this->storage = storage;
|
||||
this->client = client;
|
||||
|
||||
this->interface = storageFileWriteNewP(
|
||||
STORAGE_DRIVER_REMOTE_TYPE_STR, this, .atomic = (StorageFileWriteInterfaceAtomic)storageDriverRemoteFileWriteAtomic,
|
||||
.createPath = (StorageFileWriteInterfaceCreatePath)storageDriverRemoteFileWriteCreatePath,
|
||||
.io = (StorageFileWriteInterfaceIo)storageDriverRemoteFileWriteIo,
|
||||
.modeFile = (StorageFileWriteInterfaceModeFile)storageDriverRemoteFileWriteModeFile,
|
||||
.modePath = (StorageFileWriteInterfaceModePath)storageDriverRemoteFileWriteModePath,
|
||||
.name = (StorageFileWriteInterfaceName)storageDriverRemoteFileWriteName,
|
||||
.syncFile = (StorageFileWriteInterfaceSyncFile)storageDriverRemoteFileWriteSyncFile,
|
||||
.syncPath = (StorageFileWriteInterfaceSyncPath)storageDriverRemoteFileWriteSyncPath);
|
||||
|
||||
this->io = ioWriteNewP(
|
||||
this, .close = (IoWriteInterfaceClose)storageDriverRemoteFileWriteClose,
|
||||
.open = (IoWriteInterfaceOpen)storageDriverRemoteFileWriteOpen,
|
||||
.write = (IoWriteInterfaceWrite)storageDriverRemoteFileWrite);
|
||||
|
||||
this->name = strDup(name);
|
||||
this->modeFile = modeFile;
|
||||
this->modePath = modePath;
|
||||
this->user = strDup(user);
|
||||
this->group = strDup(group);
|
||||
this->timeModified = timeModified;
|
||||
this->createPath = createPath;
|
||||
this->syncFile = syncFile;
|
||||
this->syncPath = syncPath;
|
||||
this->atomic = atomic;
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Open the file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverRemoteFileWriteOpen(StorageDriverRemoteFileWrite *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
ProtocolCommand *command = protocolCommandNew(PROTOCOL_COMMAND_STORAGE_OPEN_WRITE_STR);
|
||||
protocolCommandParamAdd(command, VARSTR(this->name));
|
||||
protocolCommandParamAdd(command, VARUINT(this->modeFile));
|
||||
protocolCommandParamAdd(command, VARUINT(this->modePath));
|
||||
protocolCommandParamAdd(command, VARSTR(this->user));
|
||||
protocolCommandParamAdd(command, VARSTR(this->group));
|
||||
protocolCommandParamAdd(command, VARINT64(this->timeModified));
|
||||
protocolCommandParamAdd(command, VARBOOL(this->createPath));
|
||||
protocolCommandParamAdd(command, VARBOOL(this->syncFile));
|
||||
protocolCommandParamAdd(command, VARBOOL(this->syncPath));
|
||||
protocolCommandParamAdd(command, VARBOOL(this->atomic));
|
||||
|
||||
protocolClientExecute(this->client, command, false);
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Write to the file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverRemoteFileWrite(StorageDriverRemoteFileWrite *this, const Buffer *buffer)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
ioWriteStrLine(protocolClientIoWrite(this->client), strNewFmt(PROTOCOL_BLOCK_HEADER "%zu", bufUsed(buffer)));
|
||||
ioWrite(protocolClientIoWrite(this->client), buffer);
|
||||
ioWriteFlush(protocolClientIoWrite(this->client));
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
#define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_REMOTE_TYPE \
|
||||
StorageFileWriteDriverRemote *
|
||||
#define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_REMOTE_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageFileWriteDriverRemote", buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Close the file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverRemoteFileWriteClose(StorageDriverRemoteFileWrite *this)
|
||||
static void
|
||||
storageFileWriteDriverRemoteClose(THIS_VOID)
|
||||
{
|
||||
THIS(StorageFileWriteDriverRemote);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
@ -182,149 +58,14 @@ storageDriverRemoteFileWriteClose(StorageDriverRemoteFileWrite *this)
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Will the file be written atomically?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverRemoteFileWriteAtomic(const StorageDriverRemoteFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->atomic);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Will the path be created for the file if it does not exist?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverRemoteFileWriteCreatePath(const StorageDriverRemoteFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->createPath);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get interface
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileWrite *
|
||||
storageDriverRemoteFileWriteInterface(const StorageDriverRemoteFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get I/O interface
|
||||
***********************************************************************************************************************************/
|
||||
IoWrite *
|
||||
storageDriverRemoteFileWriteIo(const StorageDriverRemoteFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->io);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Mode for the file to be created
|
||||
***********************************************************************************************************************************/
|
||||
mode_t
|
||||
storageDriverRemoteFileWriteModeFile(const StorageDriverRemoteFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->modeFile);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Mode for any paths that are created while writing the file
|
||||
***********************************************************************************************************************************/
|
||||
mode_t
|
||||
storageDriverRemoteFileWriteModePath(const StorageDriverRemoteFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->modePath);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
File name
|
||||
***********************************************************************************************************************************/
|
||||
const String *
|
||||
storageDriverRemoteFileWriteName(const StorageDriverRemoteFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->name);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Will the file be synced after it is closed?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverRemoteFileWriteSyncFile(const StorageDriverRemoteFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->syncFile);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Will the directory be synced to disk after the write is completed?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverRemoteFileWriteSyncPath(const StorageDriverRemoteFileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->syncPath);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverRemoteFileWriteFree(StorageDriverRemoteFileWrite *this)
|
||||
static void
|
||||
storageFileWriteDriverRemoteFree(StorageFileWriteDriverRemote *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE_FILE_WRITE, this);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
@ -346,3 +87,131 @@ storageDriverRemoteFileWriteFree(StorageDriverRemoteFileWrite *this)
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Open the file
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
storageFileWriteDriverRemoteOpen(THIS_VOID)
|
||||
{
|
||||
THIS(StorageFileWriteDriverRemote);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
ProtocolCommand *command = protocolCommandNew(PROTOCOL_COMMAND_STORAGE_OPEN_WRITE_STR);
|
||||
protocolCommandParamAdd(command, VARSTR(this->interface.name));
|
||||
protocolCommandParamAdd(command, VARUINT(this->interface.modeFile));
|
||||
protocolCommandParamAdd(command, VARUINT(this->interface.modePath));
|
||||
protocolCommandParamAdd(command, VARSTR(this->interface.user));
|
||||
protocolCommandParamAdd(command, VARSTR(this->interface.group));
|
||||
protocolCommandParamAdd(command, VARINT64(this->interface.timeModified));
|
||||
protocolCommandParamAdd(command, VARBOOL(this->interface.createPath));
|
||||
protocolCommandParamAdd(command, VARBOOL(this->interface.syncFile));
|
||||
protocolCommandParamAdd(command, VARBOOL(this->interface.syncPath));
|
||||
protocolCommandParamAdd(command, VARBOOL(this->interface.atomic));
|
||||
|
||||
protocolClientExecute(this->client, command, false);
|
||||
|
||||
// Set free callback to ensure remote file is freed
|
||||
memContextCallback(this->memContext, (MemContextCallback)storageFileWriteDriverRemoteFree, this);
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Write to the file
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
storageFileWriteDriverRemote(THIS_VOID, const Buffer *buffer)
|
||||
{
|
||||
THIS(StorageFileWriteDriverRemote);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
ioWriteStrLine(protocolClientIoWrite(this->client), strNewFmt(PROTOCOL_BLOCK_HEADER "%zu", bufUsed(buffer)));
|
||||
ioWrite(protocolClientIoWrite(this->client), buffer);
|
||||
ioWriteFlush(protocolClientIoWrite(this->client));
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a new file
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileWrite *
|
||||
storageFileWriteDriverRemoteNew(
|
||||
StorageDriverRemote *storage, ProtocolClient *client, const String *name, mode_t modeFile, mode_t modePath, const String *user,
|
||||
const String *group, time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, storage);
|
||||
FUNCTION_LOG_PARAM(STRING, name);
|
||||
FUNCTION_LOG_PARAM(MODE, modeFile);
|
||||
FUNCTION_LOG_PARAM(MODE, modePath);
|
||||
FUNCTION_LOG_PARAM(STRING, user);
|
||||
FUNCTION_LOG_PARAM(STRING, group);
|
||||
FUNCTION_LOG_PARAM(INT64, timeModified);
|
||||
FUNCTION_LOG_PARAM(BOOL, createPath);
|
||||
FUNCTION_LOG_PARAM(BOOL, syncFile);
|
||||
FUNCTION_LOG_PARAM(BOOL, syncPath);
|
||||
FUNCTION_LOG_PARAM(BOOL, atomic);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(storage != NULL);
|
||||
ASSERT(client != NULL);
|
||||
ASSERT(name != NULL);
|
||||
ASSERT(modeFile != 0);
|
||||
ASSERT(modePath != 0);
|
||||
|
||||
StorageFileWrite *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageFileWriteDriverRemote")
|
||||
{
|
||||
StorageFileWriteDriverRemote *driver = memNew(sizeof(StorageFileWriteDriverRemote));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
driver->interface = (StorageFileWriteInterface)
|
||||
{
|
||||
.type = STORAGE_DRIVER_REMOTE_TYPE_STR,
|
||||
.name = strDup(name),
|
||||
.atomic = atomic,
|
||||
.createPath = createPath,
|
||||
.group = strDup(group),
|
||||
.modeFile = modeFile,
|
||||
.modePath = modePath,
|
||||
.syncFile = syncFile,
|
||||
.syncPath = syncPath,
|
||||
.user = strDup(user),
|
||||
.timeModified = timeModified,
|
||||
|
||||
.ioInterface = (IoWriteInterface)
|
||||
{
|
||||
.close = storageFileWriteDriverRemoteClose,
|
||||
.open = storageFileWriteDriverRemoteOpen,
|
||||
.write = storageFileWriteDriverRemote,
|
||||
},
|
||||
};
|
||||
|
||||
driver->storage = storage;
|
||||
driver->client = client;
|
||||
|
||||
this = storageFileWriteNew(driver, &driver->interface);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_FILE_WRITE, this);
|
||||
}
|
||||
|
@ -4,57 +4,15 @@ Remote Storage File Write Driver
|
||||
#ifndef STORAGE_DRIVER_REMOTE_FILEWRITE_H
|
||||
#define STORAGE_DRIVER_REMOTE_FILEWRITE_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct StorageDriverRemoteFileWrite StorageDriverRemoteFileWrite;
|
||||
|
||||
#include "common/type/buffer.h"
|
||||
#include "protocol/client.h"
|
||||
#include "storage/driver/remote/storage.h"
|
||||
#include "storage/driver/remote/storage.intern.h"
|
||||
#include "storage/fileWrite.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverRemoteFileWrite *storageDriverRemoteFileWriteNew(
|
||||
StorageFileWrite *storageFileWriteDriverRemoteNew(
|
||||
StorageDriverRemote *storage, ProtocolClient *client, const String *name, mode_t modeFile, mode_t modePath, const String *user,
|
||||
const String *group, time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
void storageDriverRemoteFileWriteOpen(StorageDriverRemoteFileWrite *this);
|
||||
void storageDriverRemoteFileWrite(StorageDriverRemoteFileWrite *this, const Buffer *buffer);
|
||||
void storageDriverRemoteFileWriteClose(StorageDriverRemoteFileWrite *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool storageDriverRemoteFileWriteAtomic(const StorageDriverRemoteFileWrite *this);
|
||||
bool storageDriverRemoteFileWriteCreatePath(const StorageDriverRemoteFileWrite *this);
|
||||
mode_t storageDriverRemoteFileWriteModeFile(const StorageDriverRemoteFileWrite *this);
|
||||
StorageFileWrite* storageDriverRemoteFileWriteInterface(const StorageDriverRemoteFileWrite *this);
|
||||
IoWrite *storageDriverRemoteFileWriteIo(const StorageDriverRemoteFileWrite *this);
|
||||
mode_t storageDriverRemoteFileWriteModePath(const StorageDriverRemoteFileWrite *this);
|
||||
const String *storageDriverRemoteFileWriteName(const StorageDriverRemoteFileWrite *this);
|
||||
const StorageDriverRemote *storageDriverRemoteFileWriteStorage(const StorageDriverRemoteFileWrite *this);
|
||||
bool storageDriverRemoteFileWriteSyncFile(const StorageDriverRemoteFileWrite *this);
|
||||
bool storageDriverRemoteFileWriteSyncPath(const StorageDriverRemoteFileWrite *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void storageDriverRemoteFileWriteFree(StorageDriverRemoteFileWrite *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_REMOTE_FILE_WRITE_TYPE \
|
||||
StorageDriverRemoteFileWrite *
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_REMOTE_FILE_WRITE_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageDriverRemoteFileWrite", buffer, bufferSize)
|
||||
|
||||
#endif
|
||||
|
@ -6,12 +6,11 @@ Remote Storage Driver
|
||||
#include "common/debug.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "protocol/client.h"
|
||||
#include "protocol/helper.h"
|
||||
#include "common/object.h"
|
||||
#include "storage/driver/remote/fileRead.h"
|
||||
#include "storage/driver/remote/fileWrite.h"
|
||||
#include "storage/driver/remote/protocol.h"
|
||||
#include "storage/driver/remote/storage.h"
|
||||
#include "storage/driver/remote/storage.intern.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Driver type constant string
|
||||
@ -24,61 +23,17 @@ Object type
|
||||
struct StorageDriverRemote
|
||||
{
|
||||
MemContext *memContext;
|
||||
Storage *interface; // Driver interface
|
||||
ProtocolClient *client; // Protocol client
|
||||
};
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverRemote *
|
||||
storageDriverRemoteNew(
|
||||
mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction, ProtocolClient *client)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(MODE, modeFile);
|
||||
FUNCTION_LOG_PARAM(MODE, modePath);
|
||||
FUNCTION_LOG_PARAM(BOOL, write);
|
||||
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
|
||||
FUNCTION_LOG_PARAM(PROTOCOL_CLIENT, client);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(modeFile != 0);
|
||||
ASSERT(modePath != 0);
|
||||
ASSERT(client != NULL);
|
||||
|
||||
// Create the object
|
||||
StorageDriverRemote *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageDriverRemote")
|
||||
{
|
||||
this = memNew(sizeof(StorageDriverRemote));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
this->client = client;
|
||||
|
||||
// Create the storage interface
|
||||
this->interface = storageNewP(
|
||||
STORAGE_DRIVER_REMOTE_TYPE_STR, NULL, modeFile, modePath, write, pathExpressionFunction, this,
|
||||
.exists = (StorageInterfaceExists)storageDriverRemoteExists, .info = (StorageInterfaceInfo)storageDriverRemoteInfo,
|
||||
.list = (StorageInterfaceList)storageDriverRemoteList, .newRead = (StorageInterfaceNewRead)storageDriverRemoteNewRead,
|
||||
.newWrite = (StorageInterfaceNewWrite)storageDriverRemoteNewWrite,
|
||||
.pathCreate = (StorageInterfacePathCreate)storageDriverRemotePathCreate,
|
||||
.pathRemove = (StorageInterfacePathRemove)storageDriverRemotePathRemove,
|
||||
.pathSync = (StorageInterfacePathSync)storageDriverRemotePathSync,
|
||||
.remove = (StorageInterfaceRemove)storageDriverRemoteRemove);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_DRIVER_REMOTE, this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Does a file exist? This function is only for files, not paths.
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverRemoteExists(StorageDriverRemote *this, const String *path)
|
||||
static bool
|
||||
storageDriverRemoteExists(THIS_VOID, const String *path)
|
||||
{
|
||||
THIS(StorageDriverRemote);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -104,9 +59,11 @@ storageDriverRemoteExists(StorageDriverRemote *this, const String *path)
|
||||
/***********************************************************************************************************************************
|
||||
File/path info
|
||||
***********************************************************************************************************************************/
|
||||
StorageInfo
|
||||
storageDriverRemoteInfo(StorageDriverRemote *this, const String *file, bool ignoreMissing, bool followLink)
|
||||
static StorageInfo
|
||||
storageDriverRemoteInfo(THIS_VOID, const String *file, bool ignoreMissing, bool followLink)
|
||||
{
|
||||
THIS(StorageDriverRemote);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_PARAM(STRING, file);
|
||||
@ -125,9 +82,11 @@ storageDriverRemoteInfo(StorageDriverRemote *this, const String *file, bool igno
|
||||
/***********************************************************************************************************************************
|
||||
Get a list of files from a directory
|
||||
***********************************************************************************************************************************/
|
||||
StringList *
|
||||
storageDriverRemoteList(StorageDriverRemote *this, const String *path, bool errorOnMissing, const String *expression)
|
||||
static StringList *
|
||||
storageDriverRemoteList(THIS_VOID, const String *path, bool errorOnMissing, const String *expression)
|
||||
{
|
||||
THIS(StorageDriverRemote);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -157,9 +116,11 @@ storageDriverRemoteList(StorageDriverRemote *this, const String *path, bool erro
|
||||
/***********************************************************************************************************************************
|
||||
New file read object
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileRead *
|
||||
storageDriverRemoteNewRead(StorageDriverRemote *this, const String *file, bool ignoreMissing)
|
||||
static StorageFileRead *
|
||||
storageDriverRemoteNewRead(THIS_VOID, const String *file, bool ignoreMissing)
|
||||
{
|
||||
THIS(StorageDriverRemote);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_PARAM(STRING, file);
|
||||
@ -168,19 +129,19 @@ storageDriverRemoteNewRead(StorageDriverRemote *this, const String *file, bool i
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_LOG_RETURN(
|
||||
STORAGE_FILE_READ,
|
||||
storageDriverRemoteFileReadInterface(storageDriverRemoteFileReadNew(this, this->client, file, ignoreMissing)));
|
||||
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, storageFileReadDriverRemoteNew(this, this->client, file, ignoreMissing));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New file write object
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileWrite *
|
||||
static StorageFileWrite *
|
||||
storageDriverRemoteNewWrite(
|
||||
StorageDriverRemote *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
THIS_VOID, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
|
||||
{
|
||||
THIS(StorageDriverRemote);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_PARAM(STRING, file);
|
||||
@ -200,17 +161,18 @@ storageDriverRemoteNewWrite(
|
||||
|
||||
FUNCTION_LOG_RETURN(
|
||||
STORAGE_FILE_WRITE,
|
||||
storageDriverRemoteFileWriteInterface(
|
||||
storageDriverRemoteFileWriteNew(
|
||||
this, this->client, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, syncPath, atomic)));
|
||||
storageFileWriteDriverRemoteNew(
|
||||
this, this->client, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, syncPath, atomic));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a path. There are no physical paths on S3 so just return success.
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverRemotePathCreate(StorageDriverRemote *this, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
|
||||
static void
|
||||
storageDriverRemotePathCreate(THIS_VOID, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
|
||||
{
|
||||
THIS(StorageDriverRemote);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -230,9 +192,11 @@ storageDriverRemotePathCreate(StorageDriverRemote *this, const String *path, boo
|
||||
/***********************************************************************************************************************************
|
||||
Remove a path
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverRemotePathRemove(StorageDriverRemote *this, const String *path, bool errorOnMissing, bool recurse)
|
||||
static void
|
||||
storageDriverRemotePathRemove(THIS_VOID, const String *path, bool errorOnMissing, bool recurse)
|
||||
{
|
||||
THIS(StorageDriverRemote);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -251,9 +215,11 @@ storageDriverRemotePathRemove(StorageDriverRemote *this, const String *path, boo
|
||||
/***********************************************************************************************************************************
|
||||
Sync a path. There's no need for this on S3 so just return success.
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverRemotePathSync(StorageDriverRemote *this, const String *path, bool ignoreMissing)
|
||||
static void
|
||||
storageDriverRemotePathSync(THIS_VOID, const String *path, bool ignoreMissing)
|
||||
{
|
||||
THIS(StorageDriverRemote);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -271,9 +237,11 @@ storageDriverRemotePathSync(StorageDriverRemote *this, const String *path, bool
|
||||
/***********************************************************************************************************************************
|
||||
Remove a file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverRemoteRemove(StorageDriverRemote *this, const String *file, bool errorOnMissing)
|
||||
static void
|
||||
storageDriverRemoteRemove(THIS_VOID, const String *file, bool errorOnMissing)
|
||||
{
|
||||
THIS(StorageDriverRemote);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
|
||||
FUNCTION_LOG_PARAM(STRING, file);
|
||||
@ -289,16 +257,40 @@ storageDriverRemoteRemove(StorageDriverRemote *this, const String *file, bool er
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get storage interface
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
Storage *
|
||||
storageDriverRemoteInterface(const StorageDriverRemote *this)
|
||||
storageDriverRemoteNew(
|
||||
mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction, ProtocolClient *client)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, this);
|
||||
FUNCTION_TEST_END();
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(MODE, modeFile);
|
||||
FUNCTION_LOG_PARAM(MODE, modePath);
|
||||
FUNCTION_LOG_PARAM(BOOL, write);
|
||||
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
|
||||
FUNCTION_LOG_PARAM(PROTOCOL_CLIENT, client);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(modeFile != 0);
|
||||
ASSERT(modePath != 0);
|
||||
ASSERT(client != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface);
|
||||
Storage *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageDriverRemote")
|
||||
{
|
||||
StorageDriverRemote *driver = memNew(sizeof(StorageDriverRemote));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
driver->client = client;
|
||||
|
||||
this = storageNewP(
|
||||
STORAGE_DRIVER_REMOTE_TYPE_STR, NULL, modeFile, modePath, write, pathExpressionFunction, driver,
|
||||
.exists = storageDriverRemoteExists, .info = storageDriverRemoteInfo, .list = storageDriverRemoteList,
|
||||
.newRead = storageDriverRemoteNewRead, .newWrite = storageDriverRemoteNewWrite,
|
||||
.pathCreate = storageDriverRemotePathCreate, .pathRemove = storageDriverRemotePathRemove,
|
||||
.pathSync = storageDriverRemotePathSync, .remove = storageDriverRemoteRemove);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE, this);
|
||||
}
|
||||
|
@ -4,13 +4,7 @@ Remote Storage Driver
|
||||
#ifndef STORAGE_DRIVER_REMOTE_STORAGE_H
|
||||
#define STORAGE_DRIVER_REMOTE_STORAGE_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct StorageDriverRemote StorageDriverRemote;
|
||||
|
||||
#include "common/io/http/client.h"
|
||||
#include "common/type/string.h"
|
||||
#include "protocol/client.h"
|
||||
#include "storage/storage.intern.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -22,41 +16,7 @@ Driver type constant
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverRemote *storageDriverRemoteNew(
|
||||
Storage *storageDriverRemoteNew(
|
||||
mode_t modeFile, mode_t modePath, bool write, StoragePathExpressionCallback pathExpressionFunction, ProtocolClient *client);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
bool storageDriverRemoteExists(StorageDriverRemote *this, const String *path);
|
||||
StorageInfo storageDriverRemoteInfo(StorageDriverRemote *this, const String *file, bool ignoreMissing, bool followLink);
|
||||
StringList *storageDriverRemoteList(StorageDriverRemote *this, const String *path, bool errorOnMissing, const String *expression);
|
||||
StorageFileRead *storageDriverRemoteNewRead(StorageDriverRemote *this, const String *file, bool ignoreMissing);
|
||||
StorageFileWrite *storageDriverRemoteNewWrite(
|
||||
StorageDriverRemote *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
|
||||
void storageDriverRemotePathCreate(
|
||||
StorageDriverRemote *this, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode);
|
||||
void storageDriverRemotePathRemove(StorageDriverRemote *this, const String *path, bool errorOnMissing, bool recurse);
|
||||
void storageDriverRemotePathSync(StorageDriverRemote *this, const String *path, bool ignoreMissing);
|
||||
void storageDriverRemoteRemove(StorageDriverRemote *this, const String *file, bool errorOnMissing);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
Storage *storageDriverRemoteInterface(const StorageDriverRemote *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void storageDriverRemoteFree(StorageDriverRemote *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_REMOTE_TYPE \
|
||||
StorageDriverRemote *
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_REMOTE_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageDriverRemote", buffer, bufferSize)
|
||||
|
||||
#endif
|
||||
|
22
src/storage/driver/remote/storage.intern.h
Normal file
22
src/storage/driver/remote/storage.intern.h
Normal 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
|
@ -11,73 +11,40 @@ S3 Storage File Read Driver
|
||||
#include "common/io/read.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
#include "storage/driver/s3/fileRead.h"
|
||||
#include "storage/fileRead.intern.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct StorageDriverS3FileRead
|
||||
typedef struct StorageFileReadDriverS3
|
||||
{
|
||||
MemContext *memContext;
|
||||
StorageDriverS3 *storage;
|
||||
StorageFileRead *interface;
|
||||
IoRead *io;
|
||||
String *name;
|
||||
bool ignoreMissing;
|
||||
MemContext *memContext; // Object mem context
|
||||
StorageFileReadInterface interface; // Driver interface
|
||||
StorageDriverS3 *storage; // Storage that created this object
|
||||
|
||||
HttpClient *httpClient; // Http client for requests
|
||||
};
|
||||
} StorageFileReadDriverS3;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a new file
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverS3FileRead *
|
||||
storageDriverS3FileReadNew(StorageDriverS3 *storage, const String *name, bool ignoreMissing)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, storage);
|
||||
FUNCTION_LOG_PARAM(STRING, name);
|
||||
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(storage != NULL);
|
||||
ASSERT(name != NULL);
|
||||
|
||||
StorageDriverS3FileRead *this = NULL;
|
||||
|
||||
// Create the file object
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageDriverS3FileRead")
|
||||
{
|
||||
this = memNew(sizeof(StorageDriverS3FileRead));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
this->storage = storage;
|
||||
this->name = strDup(name);
|
||||
this->ignoreMissing = ignoreMissing;
|
||||
|
||||
this->interface = storageFileReadNewP(
|
||||
strNew(STORAGE_DRIVER_S3_TYPE), this,
|
||||
.ignoreMissing = (StorageFileReadInterfaceIgnoreMissing)storageDriverS3FileReadIgnoreMissing,
|
||||
.io = (StorageFileReadInterfaceIo)storageDriverS3FileReadIo,
|
||||
.name = (StorageFileReadInterfaceName)storageDriverS3FileReadName);
|
||||
|
||||
this->io = ioReadNewP(
|
||||
this, .eof = (IoReadInterfaceEof)storageDriverS3FileReadEof,
|
||||
.open = (IoReadInterfaceOpen)storageDriverS3FileReadOpen, .read = (IoReadInterfaceRead)storageDriverS3FileRead);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_DRIVER_S3_FILE_READ, this);
|
||||
}
|
||||
#define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_S3_TYPE \
|
||||
StorageFileReadDriverS3 *
|
||||
#define FUNCTION_LOG_STORAGE_FILE_READ_DRIVER_S3_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageFileReadDriverS3", buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Open the file
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverS3FileReadOpen(StorageDriverS3FileRead *this)
|
||||
static bool
|
||||
storageFileReadDriverS3Open(THIS_VOID)
|
||||
{
|
||||
THIS(StorageFileReadDriverS3);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_S3, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
@ -86,7 +53,7 @@ storageDriverS3FileReadOpen(StorageDriverS3FileRead *this)
|
||||
bool result = false;
|
||||
|
||||
// Request the file
|
||||
storageDriverS3Request(this->storage, HTTP_VERB_GET_STR, this->name, NULL, NULL, false, true);
|
||||
storageDriverS3Request(this->storage, HTTP_VERB_GET_STR, this->interface.name, NULL, NULL, false, true);
|
||||
|
||||
// On success
|
||||
this->httpClient = storageDriverS3HttpClient(this->storage);
|
||||
@ -95,8 +62,8 @@ storageDriverS3FileReadOpen(StorageDriverS3FileRead *this)
|
||||
result = true;
|
||||
|
||||
// Else error unless ignore missing
|
||||
else if (!this->ignoreMissing)
|
||||
THROW_FMT(FileMissingError, "unable to open '%s': No such file or directory", strPtr(this->name));
|
||||
else if (!this->interface.ignoreMissing)
|
||||
THROW_FMT(FileMissingError, "unable to open '%s': No such file or directory", strPtr(this->interface.name));
|
||||
|
||||
FUNCTION_LOG_RETURN(BOOL, result);
|
||||
}
|
||||
@ -104,11 +71,13 @@ storageDriverS3FileReadOpen(StorageDriverS3FileRead *this)
|
||||
/***********************************************************************************************************************************
|
||||
Read from a file
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer, bool block)
|
||||
static size_t
|
||||
storageFileReadDriverS3(THIS_VOID, Buffer *buffer, bool block)
|
||||
{
|
||||
THIS(StorageFileReadDriverS3);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_DRIVER_S3, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_PARAM(BOOL, block);
|
||||
FUNCTION_LOG_END();
|
||||
@ -122,11 +91,13 @@ storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer, bool bloc
|
||||
/***********************************************************************************************************************************
|
||||
Has file reached EOF?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverS3FileReadEof(const StorageDriverS3FileRead *this)
|
||||
static bool
|
||||
storageFileReadDriverS3Eof(THIS_VOID)
|
||||
{
|
||||
THIS(StorageFileReadDriverS3);
|
||||
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
|
||||
FUNCTION_TEST_PARAM(STORAGE_FILE_READ_DRIVER_S3, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL && this->httpClient != NULL);
|
||||
@ -135,61 +106,46 @@ storageDriverS3FileReadEof(const StorageDriverS3FileRead *this)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Should a missing file be ignored?
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverS3FileReadIgnoreMissing(const StorageDriverS3FileRead *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->ignoreMissing);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get the interface
|
||||
Create a new file
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileRead *
|
||||
storageDriverS3FileReadInterface(const StorageDriverS3FileRead *this)
|
||||
storageFileReadDriverS3New(StorageDriverS3 *storage, const String *name, bool ignoreMissing)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, storage);
|
||||
FUNCTION_LOG_PARAM(STRING, name);
|
||||
FUNCTION_LOG_PARAM(BOOL, ignoreMissing);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(storage != NULL);
|
||||
ASSERT(name != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface);
|
||||
}
|
||||
StorageFileRead *this = NULL;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get the I/O interface
|
||||
***********************************************************************************************************************************/
|
||||
IoRead *
|
||||
storageDriverS3FileReadIo(const StorageDriverS3FileRead *this)
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageFileReadDriverS3")
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
StorageFileReadDriverS3 *driver = memNew(sizeof(StorageFileReadDriverS3));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->io);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
File name
|
||||
***********************************************************************************************************************************/
|
||||
const String *
|
||||
storageDriverS3FileReadName(const StorageDriverS3FileRead *this)
|
||||
driver->interface = (StorageFileReadInterface)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
.type = STORAGE_DRIVER_S3_TYPE_STR,
|
||||
.name = strDup(name),
|
||||
.ignoreMissing = ignoreMissing,
|
||||
|
||||
ASSERT(this != NULL);
|
||||
.ioInterface = (IoReadInterface)
|
||||
{
|
||||
.eof = storageFileReadDriverS3Eof,
|
||||
.open = storageFileReadDriverS3Open,
|
||||
.read = storageFileReadDriverS3,
|
||||
},
|
||||
};
|
||||
|
||||
FUNCTION_TEST_RETURN(this->name);
|
||||
driver->storage = storage;
|
||||
|
||||
this = storageFileReadNew(driver, &driver->interface);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, this);
|
||||
}
|
||||
|
@ -4,47 +4,12 @@ S3 Storage File Read Driver
|
||||
#ifndef STORAGE_DRIVER_S3_FILEREAD_H
|
||||
#define STORAGE_DRIVER_S3_FILEREAD_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct StorageDriverS3FileRead StorageDriverS3FileRead;
|
||||
|
||||
#include "common/type/buffer.h"
|
||||
#include "common/type/string.h"
|
||||
#include "storage/driver/s3/storage.h"
|
||||
#include "storage/driver/s3/storage.intern.h"
|
||||
#include "storage/fileRead.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverS3FileRead *storageDriverS3FileReadNew(StorageDriverS3 *storage, const String *name, bool ignoreMissing);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
bool storageDriverS3FileReadOpen(StorageDriverS3FileRead *this);
|
||||
size_t storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer, bool block);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool storageDriverS3FileReadEof(const StorageDriverS3FileRead *this);
|
||||
bool storageDriverS3FileReadIgnoreMissing(const StorageDriverS3FileRead *this);
|
||||
StorageFileRead *storageDriverS3FileReadInterface(const StorageDriverS3FileRead *this);
|
||||
IoRead *storageDriverS3FileReadIo(const StorageDriverS3FileRead *this);
|
||||
const String *storageDriverS3FileReadName(const StorageDriverS3FileRead *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void storageDriverS3FileReadFree(StorageDriverS3FileRead *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_S3_FILE_READ_TYPE \
|
||||
StorageDriverS3FileRead *
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_S3_FILE_READ_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageDriverS3FileRead", buffer, bufferSize)
|
||||
StorageFileRead *storageFileReadDriverS3New(StorageDriverS3 *storage, const String *name, bool ignoreMissing);
|
||||
|
||||
#endif
|
||||
|
@ -7,6 +7,7 @@ S3 Storage File Write Driver
|
||||
#include "common/io/write.intern.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
#include "common/type/xml.h"
|
||||
#include "storage/driver/s3/fileWrite.h"
|
||||
#include "storage/fileWrite.intern.h"
|
||||
@ -30,76 +31,36 @@ STRING_STATIC(S3_XML_TAG_PART_NUMBER_STR, "PartNumber"
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct StorageDriverS3FileWrite
|
||||
typedef struct StorageFileWriteDriverS3
|
||||
{
|
||||
MemContext *memContext;
|
||||
StorageDriverS3 *storage;
|
||||
StorageFileWrite *interface;
|
||||
IoWrite *io;
|
||||
MemContext *memContext; // Object mem context
|
||||
StorageFileWriteInterface interface; // Driver interface
|
||||
StorageDriverS3 *storage; // Storage that created this object
|
||||
|
||||
const String *path;
|
||||
const String *name;
|
||||
size_t partSize;
|
||||
Buffer *partBuffer;
|
||||
const String *uploadId;
|
||||
StringList *uploadPartList;
|
||||
};
|
||||
} StorageFileWriteDriverS3;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a new file
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverS3FileWrite *
|
||||
storageDriverS3FileWriteNew(StorageDriverS3 *storage, const String *name, size_t partSize)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, storage);
|
||||
FUNCTION_LOG_PARAM(STRING, name);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(storage != NULL);
|
||||
ASSERT(name != NULL);
|
||||
|
||||
StorageDriverS3FileWrite *this = NULL;
|
||||
|
||||
// Create the file
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageDriverS3FileWrite")
|
||||
{
|
||||
this = memNew(sizeof(StorageDriverS3FileWrite));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
this->storage = storage;
|
||||
|
||||
this->interface = storageFileWriteNewP(
|
||||
STORAGE_DRIVER_S3_TYPE_STR, this, .atomic = (StorageFileWriteInterfaceAtomic)storageDriverS3FileWriteAtomic,
|
||||
.createPath = (StorageFileWriteInterfaceCreatePath)storageDriverS3FileWriteCreatePath,
|
||||
.io = (StorageFileWriteInterfaceIo)storageDriverS3FileWriteIo,
|
||||
.modeFile = (StorageFileWriteInterfaceModeFile)storageDriverS3FileWriteModeFile,
|
||||
.modePath = (StorageFileWriteInterfaceModePath)storageDriverS3FileWriteModePath,
|
||||
.name = (StorageFileWriteInterfaceName)storageDriverS3FileWriteName,
|
||||
.syncFile = (StorageFileWriteInterfaceSyncFile)storageDriverS3FileWriteSyncFile,
|
||||
.syncPath = (StorageFileWriteInterfaceSyncPath)storageDriverS3FileWriteSyncPath);
|
||||
|
||||
this->io = ioWriteNewP(
|
||||
this, .close = (IoWriteInterfaceClose)storageDriverS3FileWriteClose,
|
||||
.open = (IoWriteInterfaceOpen)storageDriverS3FileWriteOpen,
|
||||
.write = (IoWriteInterfaceWrite)storageDriverS3FileWrite);
|
||||
|
||||
this->path = strPath(name);
|
||||
this->name = strDup(name);
|
||||
this->partSize = partSize;
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
}
|
||||
#define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_S3_TYPE \
|
||||
StorageFileWriteDriverS3 *
|
||||
#define FUNCTION_LOG_STORAGE_FILE_WRITE_DRIVER_S3_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageFileWriteDriverS3", buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Open the file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverS3FileWriteOpen(StorageDriverS3FileWrite *this)
|
||||
static void
|
||||
storageFileWriteDriverS3Open(THIS_VOID)
|
||||
{
|
||||
THIS(StorageFileWriteDriverS3);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_S3, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
@ -119,10 +80,10 @@ storageDriverS3FileWriteOpen(StorageDriverS3FileWrite *this)
|
||||
Flush bytes to upload part
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
storageDriverS3FileWritePart(StorageDriverS3FileWrite *this)
|
||||
storageFileWriteDriverS3Part(StorageFileWriteDriverS3 *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_S3, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
@ -138,7 +99,7 @@ storageDriverS3FileWritePart(StorageDriverS3FileWrite *this)
|
||||
XmlNode *xmlRoot = xmlDocumentRoot(
|
||||
xmlDocumentNewBuf(
|
||||
storageDriverS3Request(
|
||||
this->storage, HTTP_VERB_POST_STR, this->name,
|
||||
this->storage, HTTP_VERB_POST_STR, this->interface.name,
|
||||
httpQueryAdd(httpQueryNew(), S3_QUERY_UPLOADS_STR, EMPTY_STR), NULL, true, false).response));
|
||||
|
||||
// Store the upload id
|
||||
@ -159,7 +120,7 @@ storageDriverS3FileWritePart(StorageDriverS3FileWrite *this)
|
||||
this->uploadPartList,
|
||||
httpHeaderGet(
|
||||
storageDriverS3Request(
|
||||
this->storage, HTTP_VERB_PUT_STR, this->name, query, this->partBuffer, true, false).responseHeader,
|
||||
this->storage, HTTP_VERB_PUT_STR, this->interface.name, query, this->partBuffer, true, false).responseHeader,
|
||||
HTTP_HEADER_ETAG_STR));
|
||||
|
||||
ASSERT(strLstGet(this->uploadPartList, strLstSize(this->uploadPartList) - 1) != NULL);
|
||||
@ -172,11 +133,13 @@ storageDriverS3FileWritePart(StorageDriverS3FileWrite *this)
|
||||
/***********************************************************************************************************************************
|
||||
Write to internal buffer
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverS3FileWrite(StorageDriverS3FileWrite *this, const Buffer *buffer)
|
||||
static void
|
||||
storageFileWriteDriverS3(THIS_VOID, const Buffer *buffer)
|
||||
{
|
||||
THIS(StorageFileWriteDriverS3);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_S3, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
@ -197,7 +160,7 @@ storageDriverS3FileWrite(StorageDriverS3FileWrite *this, const Buffer *buffer)
|
||||
// If the part buffer is full then write it
|
||||
if (bufRemains(this->partBuffer) == 0)
|
||||
{
|
||||
storageDriverS3FileWritePart(this);
|
||||
storageFileWriteDriverS3Part(this);
|
||||
bufUsedZero(this->partBuffer);
|
||||
}
|
||||
}
|
||||
@ -209,11 +172,13 @@ storageDriverS3FileWrite(StorageDriverS3FileWrite *this, const Buffer *buffer)
|
||||
/***********************************************************************************************************************************
|
||||
Close the file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverS3FileWriteClose(StorageDriverS3FileWrite *this)
|
||||
static void
|
||||
storageFileWriteDriverS3Close(THIS_VOID)
|
||||
{
|
||||
THIS(StorageFileWriteDriverS3);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_DRIVER_S3, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
@ -228,7 +193,7 @@ storageDriverS3FileWriteClose(StorageDriverS3FileWrite *this)
|
||||
{
|
||||
// If there is anything left in the part buffer then write it
|
||||
if (bufUsed(this->partBuffer) > 0)
|
||||
storageDriverS3FileWritePart(this);
|
||||
storageFileWriteDriverS3Part(this);
|
||||
|
||||
// Generate the xml part list
|
||||
XmlDocument *partList = xmlDocumentNew(S3_XML_TAG_COMPLETE_MULTIPART_UPLOAD_STR);
|
||||
@ -242,12 +207,15 @@ storageDriverS3FileWriteClose(StorageDriverS3FileWrite *this)
|
||||
|
||||
// Finalize the multi-part upload
|
||||
storageDriverS3Request(
|
||||
this->storage, HTTP_VERB_POST_STR, this->name,
|
||||
this->storage, HTTP_VERB_POST_STR, this->interface.name,
|
||||
httpQueryAdd(httpQueryNew(), S3_QUERY_UPLOAD_ID_STR, this->uploadId), xmlDocumentBuf(partList), false, false);
|
||||
}
|
||||
// Else upload all the data in a single put
|
||||
else
|
||||
storageDriverS3Request(this->storage, HTTP_VERB_PUT_STR, this->name, NULL, this->partBuffer, false, false);
|
||||
{
|
||||
storageDriverS3Request(
|
||||
this->storage, HTTP_VERB_PUT_STR, this->interface.name, NULL, this->partBuffer, false, false);
|
||||
}
|
||||
|
||||
bufFree(this->partBuffer);
|
||||
this->partBuffer = NULL;
|
||||
@ -259,158 +227,49 @@ storageDriverS3FileWriteClose(StorageDriverS3FileWrite *this)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
S3 operations are always atomic, so return true
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverS3FileWriteAtomic(const StorageDriverS3FileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
(void)this;
|
||||
|
||||
FUNCTION_TEST_RETURN(true);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
S3 paths are always implicitly created
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverS3FileWriteCreatePath(const StorageDriverS3FileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
(void)this;
|
||||
|
||||
FUNCTION_TEST_RETURN(true);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get interface
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileWrite *
|
||||
storageDriverS3FileWriteInterface(const StorageDriverS3FileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get I/O interface
|
||||
***********************************************************************************************************************************/
|
||||
IoWrite *
|
||||
storageDriverS3FileWriteIo(const StorageDriverS3FileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->io);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
S3 does not support Posix-style mode
|
||||
***********************************************************************************************************************************/
|
||||
mode_t
|
||||
storageDriverS3FileWriteModeFile(const StorageDriverS3FileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
(void)this;
|
||||
|
||||
FUNCTION_TEST_RETURN(0);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
S3 does not support Posix-style mode
|
||||
***********************************************************************************************************************************/
|
||||
mode_t
|
||||
storageDriverS3FileWriteModePath(const StorageDriverS3FileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
(void)this;
|
||||
|
||||
FUNCTION_TEST_RETURN(0);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
File name
|
||||
***********************************************************************************************************************************/
|
||||
const String *
|
||||
storageDriverS3FileWriteName(const StorageDriverS3FileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->name);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
S3 operations are always atomic, so return true
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverS3FileWriteSyncFile(const StorageDriverS3FileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
(void)this;
|
||||
|
||||
FUNCTION_TEST_RETURN(true);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
S3 operations are always atomic, so return true
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverS3FileWriteSyncPath(const StorageDriverS3FileWrite *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
(void)this;
|
||||
|
||||
FUNCTION_TEST_RETURN(true);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverS3FileWriteFree(StorageDriverS3FileWrite *this)
|
||||
storageFileWriteDriverS3New(StorageDriverS3 *storage, const String *name, size_t partSize)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3_FILE_WRITE, this);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, storage);
|
||||
FUNCTION_LOG_PARAM(STRING, name);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
if (this != NULL)
|
||||
memContextFree(this->memContext);
|
||||
ASSERT(storage != NULL);
|
||||
ASSERT(name != NULL);
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
StorageFileWrite *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageFileWriteDriverS3")
|
||||
{
|
||||
StorageFileWriteDriverS3 *driver = memNew(sizeof(StorageFileWriteDriverS3));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
driver->interface = (StorageFileWriteInterface)
|
||||
{
|
||||
.type = STORAGE_DRIVER_S3_TYPE_STR,
|
||||
.name = strDup(name),
|
||||
.atomic = true,
|
||||
.createPath = true,
|
||||
.syncFile = true,
|
||||
.syncPath = true,
|
||||
|
||||
.ioInterface = (IoWriteInterface)
|
||||
{
|
||||
.close = storageFileWriteDriverS3Close,
|
||||
.open = storageFileWriteDriverS3Open,
|
||||
.write = storageFileWriteDriverS3,
|
||||
},
|
||||
};
|
||||
|
||||
driver->storage = storage;
|
||||
driver->partSize = partSize;
|
||||
|
||||
this = storageFileWriteNew(driver, &driver->interface);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_FILE_WRITE, this);
|
||||
}
|
||||
|
@ -4,54 +4,12 @@ S3 Storage File Write Driver
|
||||
#ifndef STORAGE_DRIVER_S3_FILEWRITE_H
|
||||
#define STORAGE_DRIVER_S3_FILEWRITE_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct StorageDriverS3FileWrite StorageDriverS3FileWrite;
|
||||
|
||||
#include "common/type/buffer.h"
|
||||
#include "storage/driver/s3/storage.h"
|
||||
#include "storage/fileWrite.h"
|
||||
#include "storage/driver/s3/storage.intern.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverS3FileWrite *storageDriverS3FileWriteNew(StorageDriverS3 *storage, const String *name, size_t partSize);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
void storageDriverS3FileWriteOpen(StorageDriverS3FileWrite *this);
|
||||
void storageDriverS3FileWrite(StorageDriverS3FileWrite *this, const Buffer *buffer);
|
||||
void storageDriverS3FileWriteClose(StorageDriverS3FileWrite *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool storageDriverS3FileWriteAtomic(const StorageDriverS3FileWrite *this);
|
||||
bool storageDriverS3FileWriteCreatePath(const StorageDriverS3FileWrite *this);
|
||||
mode_t storageDriverS3FileWriteModeFile(const StorageDriverS3FileWrite *this);
|
||||
StorageFileWrite* storageDriverS3FileWriteInterface(const StorageDriverS3FileWrite *this);
|
||||
IoWrite *storageDriverS3FileWriteIo(const StorageDriverS3FileWrite *this);
|
||||
mode_t storageDriverS3FileWriteModePath(const StorageDriverS3FileWrite *this);
|
||||
const String *storageDriverS3FileWriteName(const StorageDriverS3FileWrite *this);
|
||||
const StorageDriverS3 *storageDriverS3FileWriteStorage(const StorageDriverS3FileWrite *this);
|
||||
bool storageDriverS3FileWriteSyncFile(const StorageDriverS3FileWrite *this);
|
||||
bool storageDriverS3FileWriteSyncPath(const StorageDriverS3FileWrite *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void storageDriverS3FileWriteFree(StorageDriverS3FileWrite *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_S3_FILE_WRITE_TYPE \
|
||||
StorageDriverS3FileWrite *
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_S3_FILE_WRITE_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageDriverS3FileWrite", buffer, bufferSize)
|
||||
StorageFileWrite *storageFileWriteDriverS3New(StorageDriverS3 *storage, const String *name, size_t partSize);
|
||||
|
||||
#endif
|
||||
|
@ -12,11 +12,12 @@ S3 Storage Driver
|
||||
#include "common/io/http/common.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/object.h"
|
||||
#include "common/regExp.h"
|
||||
#include "common/type/xml.h"
|
||||
#include "storage/driver/s3/fileRead.h"
|
||||
#include "storage/driver/s3/fileWrite.h"
|
||||
#include "storage/driver/s3/storage.h"
|
||||
#include "storage/driver/s3/storage.intern.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Driver type constant string
|
||||
@ -72,7 +73,6 @@ Object type
|
||||
struct StorageDriverS3
|
||||
{
|
||||
MemContext *memContext;
|
||||
Storage *interface; // Driver interface
|
||||
HttpClient *httpClient; // Http client to service requests
|
||||
const StringList *headerRedactList; // List of headers to redact from logging
|
||||
|
||||
@ -182,7 +182,7 @@ storageDriverS3Auth(
|
||||
// Generate string to sign
|
||||
const String *stringToSign = strNewFmt(
|
||||
AWS4_HMAC_SHA256 "\n%s\n%s/%s/" S3 "/" AWS4_REQUEST "\n%s", strPtr(dateTime), strPtr(date), strPtr(this->region),
|
||||
strPtr(bufHex(cryptoHashOneStr(HASH_TYPE_SHA256_STR, canonicalRequest))));
|
||||
strPtr(bufHex(cryptoHashOne(HASH_TYPE_SHA256_STR, BUFSTR(canonicalRequest)))));
|
||||
|
||||
// Generate signing key. This key only needs to be regenerated every seven days but we'll do it once a day to keep the
|
||||
// logic simple. It's a relatively expensive operation so we'd rather not do it for every request.
|
||||
@ -216,81 +216,6 @@ storageDriverS3Auth(
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverS3 *
|
||||
storageDriverS3New(
|
||||
const String *path, bool write, StoragePathExpressionCallback pathExpressionFunction, const String *bucket,
|
||||
const String *endPoint, const String *region, const String *accessKey, const String *secretAccessKey,
|
||||
const String *securityToken, size_t partSize, const String *host, unsigned int port, TimeMSec timeout, bool verifyPeer,
|
||||
const String *caFile, const String *caPath)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
FUNCTION_LOG_PARAM(BOOL, write);
|
||||
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
|
||||
FUNCTION_LOG_PARAM(STRING, bucket);
|
||||
FUNCTION_LOG_PARAM(STRING, endPoint);
|
||||
FUNCTION_LOG_PARAM(STRING, region);
|
||||
FUNCTION_TEST_PARAM(STRING, accessKey);
|
||||
FUNCTION_TEST_PARAM(STRING, secretAccessKey);
|
||||
FUNCTION_TEST_PARAM(STRING, securityToken);
|
||||
FUNCTION_TEST_PARAM(SIZE, partSize);
|
||||
FUNCTION_LOG_PARAM(STRING, host);
|
||||
FUNCTION_LOG_PARAM(UINT, port);
|
||||
FUNCTION_LOG_PARAM(TIME_MSEC, timeout);
|
||||
FUNCTION_LOG_PARAM(BOOL, verifyPeer);
|
||||
FUNCTION_LOG_PARAM(STRING, caFile);
|
||||
FUNCTION_LOG_PARAM(STRING, caPath);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(path != NULL);
|
||||
ASSERT(bucket != NULL);
|
||||
ASSERT(endPoint != NULL);
|
||||
ASSERT(region != NULL);
|
||||
ASSERT(accessKey != NULL);
|
||||
ASSERT(secretAccessKey != NULL);
|
||||
|
||||
// Create the object
|
||||
StorageDriverS3 *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageDriverS3")
|
||||
{
|
||||
this = memNew(sizeof(StorageDriverS3));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
this->bucket = strDup(bucket);
|
||||
this->region = strDup(region);
|
||||
this->accessKey = strDup(accessKey);
|
||||
this->secretAccessKey = strDup(secretAccessKey);
|
||||
this->securityToken = strDup(securityToken);
|
||||
this->partSize = partSize;
|
||||
this->host = host == NULL ? strNewFmt("%s.%s", strPtr(bucket), strPtr(endPoint)) : strDup(host);
|
||||
this->port = port;
|
||||
|
||||
// Force the signing key to be generated on the first run
|
||||
this->signingKeyDate = YYYYMMDD_STR;
|
||||
|
||||
// Create the storage interface
|
||||
this->interface = storageNewP(
|
||||
STORAGE_DRIVER_S3_TYPE_STR, path, 0, 0, write, pathExpressionFunction, this,
|
||||
.exists = (StorageInterfaceExists)storageDriverS3Exists, .info = (StorageInterfaceInfo)storageDriverS3Info,
|
||||
.list = (StorageInterfaceList)storageDriverS3List, .newRead = (StorageInterfaceNewRead)storageDriverS3NewRead,
|
||||
.newWrite = (StorageInterfaceNewWrite)storageDriverS3NewWrite,
|
||||
.pathCreate = (StorageInterfacePathCreate)storageDriverS3PathCreate,
|
||||
.pathRemove = (StorageInterfacePathRemove)storageDriverS3PathRemove,
|
||||
.pathSync = (StorageInterfacePathSync)storageDriverS3PathSync, .remove = (StorageInterfaceRemove)storageDriverS3Remove);
|
||||
|
||||
// Create the http client used to service requests
|
||||
this->httpClient = httpClientNew(this->host, this->port, timeout, verifyPeer, caFile, caPath);
|
||||
this->headerRedactList = strLstAdd(strLstNew(), S3_HEADER_AUTHORIZATION_STR);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_DRIVER_S3, this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Process S3 request
|
||||
***********************************************************************************************************************************/
|
||||
@ -410,9 +335,11 @@ storageDriverS3Request(
|
||||
/***********************************************************************************************************************************
|
||||
Does a file exist? This function is only for files, not paths.
|
||||
***********************************************************************************************************************************/
|
||||
bool
|
||||
storageDriverS3Exists(StorageDriverS3 *this, const String *path)
|
||||
static bool
|
||||
storageDriverS3Exists(THIS_VOID, const String *path)
|
||||
{
|
||||
THIS(StorageDriverS3);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -459,9 +386,11 @@ storageDriverS3Exists(StorageDriverS3 *this, const String *path)
|
||||
/***********************************************************************************************************************************
|
||||
File/path info
|
||||
***********************************************************************************************************************************/
|
||||
StorageInfo
|
||||
storageDriverS3Info(StorageDriverS3 *this, const String *file, bool ignoreMissing, bool followLink)
|
||||
static StorageInfo
|
||||
storageDriverS3Info(THIS_VOID, const String *file, bool ignoreMissing, bool followLink)
|
||||
{
|
||||
THIS(StorageDriverS3);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
|
||||
FUNCTION_LOG_PARAM(STRING, file);
|
||||
@ -481,9 +410,11 @@ storageDriverS3Info(StorageDriverS3 *this, const String *file, bool ignoreMissin
|
||||
/***********************************************************************************************************************************
|
||||
Get a list of files from a directory
|
||||
***********************************************************************************************************************************/
|
||||
StringList *
|
||||
storageDriverS3List(StorageDriverS3 *this, const String *path, bool errorOnMissing, const String *expression)
|
||||
static StringList *
|
||||
storageDriverS3List(THIS_VOID, const String *path, bool errorOnMissing, const String *expression)
|
||||
{
|
||||
THIS(StorageDriverS3);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -608,9 +539,11 @@ storageDriverS3List(StorageDriverS3 *this, const String *path, bool errorOnMissi
|
||||
/***********************************************************************************************************************************
|
||||
New file read object
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileRead *
|
||||
storageDriverS3NewRead(StorageDriverS3 *this, const String *file, bool ignoreMissing)
|
||||
static StorageFileRead *
|
||||
storageDriverS3NewRead(THIS_VOID, const String *file, bool ignoreMissing)
|
||||
{
|
||||
THIS(StorageDriverS3);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
|
||||
FUNCTION_LOG_PARAM(STRING, file);
|
||||
@ -620,18 +553,19 @@ storageDriverS3NewRead(StorageDriverS3 *this, const String *file, bool ignoreMis
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(file != NULL);
|
||||
|
||||
FUNCTION_LOG_RETURN(
|
||||
STORAGE_FILE_READ, storageDriverS3FileReadInterface(storageDriverS3FileReadNew(this, file, ignoreMissing)));
|
||||
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, storageFileReadDriverS3New(this, file, ignoreMissing));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New file write object
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileWrite *
|
||||
static StorageFileWrite *
|
||||
storageDriverS3NewWrite(
|
||||
StorageDriverS3 *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
THIS_VOID, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic)
|
||||
{
|
||||
THIS(StorageDriverS3);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
|
||||
FUNCTION_LOG_PARAM(STRING, file);
|
||||
@ -653,8 +587,7 @@ storageDriverS3NewWrite(
|
||||
ASSERT(group == NULL);
|
||||
ASSERT(timeModified == 0);
|
||||
|
||||
FUNCTION_LOG_RETURN(
|
||||
STORAGE_FILE_WRITE, storageDriverS3FileWriteInterface(storageDriverS3FileWriteNew(this, file, this->partSize)));
|
||||
FUNCTION_LOG_RETURN(STORAGE_FILE_WRITE, storageFileWriteDriverS3New(this, file, this->partSize));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -662,9 +595,11 @@ Create a path
|
||||
|
||||
There are no physical paths on S3 so just return success.
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverS3PathCreate(StorageDriverS3 *this, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
|
||||
static void
|
||||
storageDriverS3PathCreate(THIS_VOID, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
|
||||
{
|
||||
THIS(StorageDriverS3);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -683,9 +618,11 @@ storageDriverS3PathCreate(StorageDriverS3 *this, const String *path, bool errorO
|
||||
/***********************************************************************************************************************************
|
||||
Remove a path
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverS3PathRemove(StorageDriverS3 *this, const String *path, bool errorOnMissing, bool recurse)
|
||||
static void
|
||||
storageDriverS3PathRemove(THIS_VOID, const String *path, bool errorOnMissing, bool recurse)
|
||||
{
|
||||
THIS(StorageDriverS3);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -706,9 +643,11 @@ Sync a path
|
||||
|
||||
There's no need for this on S3 so just return success.
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverS3PathSync(StorageDriverS3 *this, const String *path, bool ignoreMissing)
|
||||
static void
|
||||
storageDriverS3PathSync(THIS_VOID, const String *path, bool ignoreMissing)
|
||||
{
|
||||
THIS(StorageDriverS3);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
@ -724,9 +663,11 @@ storageDriverS3PathSync(StorageDriverS3 *this, const String *path, bool ignoreMi
|
||||
/***********************************************************************************************************************************
|
||||
Remove a file
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
storageDriverS3Remove(StorageDriverS3 *this, const String *file, bool errorOnMissing)
|
||||
static void
|
||||
storageDriverS3Remove(THIS_VOID, const String *file, bool errorOnMissing)
|
||||
{
|
||||
THIS(StorageDriverS3);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
|
||||
FUNCTION_LOG_PARAM(STRING, file);
|
||||
@ -757,16 +698,71 @@ storageDriverS3HttpClient(const StorageDriverS3 *this)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get storage interface
|
||||
New object
|
||||
***********************************************************************************************************************************/
|
||||
Storage *
|
||||
storageDriverS3Interface(const StorageDriverS3 *this)
|
||||
storageDriverS3New(
|
||||
const String *path, bool write, StoragePathExpressionCallback pathExpressionFunction, const String *bucket,
|
||||
const String *endPoint, const String *region, const String *accessKey, const String *secretAccessKey,
|
||||
const String *securityToken, size_t partSize, const String *host, unsigned int port, TimeMSec timeout, bool verifyPeer,
|
||||
const String *caFile, const String *caPath)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, this);
|
||||
FUNCTION_TEST_END();
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
FUNCTION_LOG_PARAM(BOOL, write);
|
||||
FUNCTION_LOG_PARAM(FUNCTIONP, pathExpressionFunction);
|
||||
FUNCTION_LOG_PARAM(STRING, bucket);
|
||||
FUNCTION_LOG_PARAM(STRING, endPoint);
|
||||
FUNCTION_LOG_PARAM(STRING, region);
|
||||
FUNCTION_TEST_PARAM(STRING, accessKey);
|
||||
FUNCTION_TEST_PARAM(STRING, secretAccessKey);
|
||||
FUNCTION_TEST_PARAM(STRING, securityToken);
|
||||
FUNCTION_TEST_PARAM(SIZE, partSize);
|
||||
FUNCTION_LOG_PARAM(STRING, host);
|
||||
FUNCTION_LOG_PARAM(UINT, port);
|
||||
FUNCTION_LOG_PARAM(TIME_MSEC, timeout);
|
||||
FUNCTION_LOG_PARAM(BOOL, verifyPeer);
|
||||
FUNCTION_LOG_PARAM(STRING, caFile);
|
||||
FUNCTION_LOG_PARAM(STRING, caPath);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(path != NULL);
|
||||
ASSERT(bucket != NULL);
|
||||
ASSERT(endPoint != NULL);
|
||||
ASSERT(region != NULL);
|
||||
ASSERT(accessKey != NULL);
|
||||
ASSERT(secretAccessKey != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface);
|
||||
Storage *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("StorageDriverS3")
|
||||
{
|
||||
StorageDriverS3 *driver = memNew(sizeof(StorageDriverS3));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
driver->bucket = strDup(bucket);
|
||||
driver->region = strDup(region);
|
||||
driver->accessKey = strDup(accessKey);
|
||||
driver->secretAccessKey = strDup(secretAccessKey);
|
||||
driver->securityToken = strDup(securityToken);
|
||||
driver->partSize = partSize;
|
||||
driver->host = host == NULL ? strNewFmt("%s.%s", strPtr(bucket), strPtr(endPoint)) : strDup(host);
|
||||
driver->port = port;
|
||||
|
||||
// Force the signing key to be generated on the first run
|
||||
driver->signingKeyDate = YYYYMMDD_STR;
|
||||
|
||||
// Create the http client used to service requests
|
||||
driver->httpClient = httpClientNew(driver->host, driver->port, timeout, verifyPeer, caFile, caPath);
|
||||
driver->headerRedactList = strLstAdd(strLstNew(), S3_HEADER_AUTHORIZATION_STR);
|
||||
|
||||
this = storageNewP(
|
||||
STORAGE_DRIVER_S3_TYPE_STR, path, 0, 0, write, pathExpressionFunction, driver,
|
||||
.exists = storageDriverS3Exists, .info = storageDriverS3Info, .list = storageDriverS3List,
|
||||
.newRead = storageDriverS3NewRead, .newWrite = storageDriverS3NewWrite, .pathCreate = storageDriverS3PathCreate,
|
||||
.pathRemove = storageDriverS3PathRemove, .pathSync = storageDriverS3PathSync, .remove = storageDriverS3Remove);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE, this);
|
||||
}
|
||||
|
@ -4,13 +4,6 @@ S3 Storage Driver
|
||||
#ifndef STORAGE_DRIVER_S3_STORAGE_H
|
||||
#define STORAGE_DRIVER_S3_STORAGE_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct StorageDriverS3 StorageDriverS3;
|
||||
|
||||
#include "common/io/http/client.h"
|
||||
#include "common/type/string.h"
|
||||
#include "storage/storage.intern.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -24,66 +17,15 @@ Defaults
|
||||
***********************************************************************************************************************************/
|
||||
#define STORAGE_DRIVER_S3_PORT_DEFAULT 443
|
||||
#define STORAGE_DRIVER_S3_TIMEOUT_DEFAULT 60000
|
||||
#define STORAGE_DRIVER_S3_PARTSIZE_MIN ((size_t)5 * 1024 * 1024)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
StorageDriverS3 *storageDriverS3New(
|
||||
Storage *storageDriverS3New(
|
||||
const String *path, bool write, StoragePathExpressionCallback pathExpressionFunction, const String *bucket,
|
||||
const String *endPoint, const String *region, const String *accessKey, const String *secretAccessKey,
|
||||
const String *securityToken, size_t partSize, const String *host, unsigned int port, TimeMSec timeout, bool verifyPeer,
|
||||
const String *caFile, const String *caPath);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
bool storageDriverS3Exists(StorageDriverS3 *this, const String *path);
|
||||
StorageInfo storageDriverS3Info(StorageDriverS3 *this, const String *file, bool ignoreMissing, bool followLink);
|
||||
StringList *storageDriverS3List(StorageDriverS3 *this, const String *path, bool errorOnMissing, const String *expression);
|
||||
StorageFileRead *storageDriverS3NewRead(StorageDriverS3 *this, const String *file, bool ignoreMissing);
|
||||
StorageFileWrite *storageDriverS3NewWrite(
|
||||
StorageDriverS3 *this, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
|
||||
void storageDriverS3PathCreate(StorageDriverS3 *this, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode);
|
||||
void storageDriverS3PathRemove(StorageDriverS3 *this, const String *path, bool errorOnMissing, bool recurse);
|
||||
void storageDriverS3PathSync(StorageDriverS3 *this, const String *path, bool ignoreMissing);
|
||||
void storageDriverS3Remove(StorageDriverS3 *this, const String *file, bool errorOnMissing);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Perform an S3 Request
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_S3_REQUEST_RESULT_TYPE \
|
||||
StorageDriverS3RequestResult
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_S3_REQUEST_RESULT_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(&value, "StorageDriverS3RequestResult", buffer, bufferSize)
|
||||
|
||||
typedef struct StorageDriverS3RequestResult
|
||||
{
|
||||
HttpHeader *responseHeader;
|
||||
Buffer *response;
|
||||
} StorageDriverS3RequestResult;
|
||||
|
||||
StorageDriverS3RequestResult storageDriverS3Request(
|
||||
StorageDriverS3 *this, const String *verb, const String *uri, const HttpQuery *query, const Buffer *body, bool returnContent,
|
||||
bool allowMissing);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
HttpClient *storageDriverS3HttpClient(const StorageDriverS3 *this);
|
||||
Storage *storageDriverS3Interface(const StorageDriverS3 *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void storageDriverS3Free(StorageDriverS3 *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_S3_TYPE \
|
||||
StorageDriverS3 *
|
||||
#define FUNCTION_LOG_STORAGE_DRIVER_S3_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(value, "StorageDriverS3", buffer, bufferSize)
|
||||
|
||||
#endif
|
||||
|
46
src/storage/driver/s3/storage.intern.h
Normal file
46
src/storage/driver/s3/storage.intern.h
Normal 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
|
@ -13,37 +13,42 @@ Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct StorageFileRead
|
||||
{
|
||||
MemContext *memContext;
|
||||
const String *type;
|
||||
MemContext *memContext; // Object mem context
|
||||
void *driver;
|
||||
StorageFileReadInterface interface;
|
||||
const StorageFileReadInterface *interface;
|
||||
IoRead *io;
|
||||
};
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_FILE_READ_INTERFACE_TYPE \
|
||||
StorageFileReadInterface
|
||||
#define FUNCTION_LOG_STORAGE_FILE_READ_INTERFACE_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(&value, "StorageFileReadInterface", buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a new storage file
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileRead *
|
||||
storageFileReadNew(const String *type, void *driver, StorageFileReadInterface interface)
|
||||
storageFileReadNew(void *driver, const StorageFileReadInterface *interface)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STRING, type);
|
||||
FUNCTION_LOG_PARAM_P(VOID, driver);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_READ_INTERFACE, interface);
|
||||
FUNCTION_LOG_PARAM_P(STORAGE_FILE_READ_INTERFACE, interface);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(type != NULL);
|
||||
ASSERT(driver != NULL);
|
||||
ASSERT(interface.ignoreMissing != NULL);
|
||||
ASSERT(interface.io != NULL);
|
||||
ASSERT(interface.name != NULL);
|
||||
ASSERT(interface != NULL);
|
||||
|
||||
StorageFileRead *this = NULL;
|
||||
|
||||
this = memNew(sizeof(StorageFileRead));
|
||||
this->memContext = memContextCurrent();
|
||||
this->type = type;
|
||||
this->interface = interface;
|
||||
this->driver = driver;
|
||||
this->interface = interface;
|
||||
|
||||
this->io = ioReadNew(driver, interface->ioInterface);
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_FILE_READ, this);
|
||||
}
|
||||
@ -94,7 +99,7 @@ storageFileReadIgnoreMissing(const StorageFileRead *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface.ignoreMissing(this->driver));
|
||||
FUNCTION_TEST_RETURN(this->interface->ignoreMissing);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -109,7 +114,7 @@ storageFileReadIo(const StorageFileRead *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface.io(this->driver));
|
||||
FUNCTION_TEST_RETURN(this->io);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -124,7 +129,7 @@ storageFileReadName(const StorageFileRead *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface.name(this->driver));
|
||||
FUNCTION_TEST_RETURN(this->interface->name);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -139,7 +144,7 @@ storageFileReadType(const StorageFileRead *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->type);
|
||||
FUNCTION_TEST_RETURN(this->interface->type);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -149,8 +154,8 @@ String *
|
||||
storageFileReadToLog(const StorageFileRead *this)
|
||||
{
|
||||
return strNewFmt(
|
||||
"{type: %s, name: %s, ignoreMissing: %s}", strPtr(this->type), strPtr(strToLog(storageFileReadName(this))),
|
||||
cvtBoolToConstZ(storageFileReadIgnoreMissing(this)));
|
||||
"{type: %s, name: %s, ignoreMissing: %s}", strPtr(this->interface->type), strPtr(strToLog(this->interface->name)),
|
||||
cvtBoolToConstZ(this->interface->ignoreMissing));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
|
@ -19,7 +19,6 @@ StorageFileRead *storageFileReadMove(StorageFileRead *this, MemContext *parentNe
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
***********************************************************************************************************************************/
|
||||
void *storageFileReadDriver(const StorageFileRead *this);
|
||||
IoRead *storageFileReadIo(const StorageFileRead *this);
|
||||
bool storageFileReadIgnoreMissing(const StorageFileRead *this);
|
||||
const String *storageFileReadName(const StorageFileRead *this);
|
||||
|
@ -4,33 +4,25 @@ Storage File Read Interface Internal
|
||||
#ifndef STORAGE_FILEREAD_INTERN_H
|
||||
#define STORAGE_FILEREAD_INTERN_H
|
||||
|
||||
#include "common/io/read.intern.h"
|
||||
#include "storage/fileRead.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
typedef bool (*StorageFileReadInterfaceIgnoreMissing)(const void *driver);
|
||||
typedef IoRead *(*StorageFileReadInterfaceIo)(const void *driver);
|
||||
typedef const String *(*StorageFileReadInterfaceName)(const void *driver);
|
||||
|
||||
typedef struct StorageFileReadInterface
|
||||
{
|
||||
StorageFileReadInterfaceIgnoreMissing ignoreMissing;
|
||||
StorageFileReadInterfaceIo io;
|
||||
StorageFileReadInterfaceName name;
|
||||
const String * type;
|
||||
const String * name;
|
||||
bool ignoreMissing;
|
||||
IoReadInterface ioInterface;
|
||||
} StorageFileReadInterface;
|
||||
|
||||
#define storageFileReadNewP(type, driver, ...) \
|
||||
storageFileReadNew(type, driver, (StorageFileReadInterface){__VA_ARGS__})
|
||||
|
||||
StorageFileRead *storageFileReadNew(const String *type, void *driver, StorageFileReadInterface interface);
|
||||
StorageFileRead *storageFileReadNew(void *driver, const StorageFileReadInterface *interface);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_FILE_READ_INTERFACE_TYPE \
|
||||
StorageFileReadInterface
|
||||
#define FUNCTION_LOG_STORAGE_FILE_READ_INTERFACE_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(&value, "StorageFileReadInterface", buffer, bufferSize)
|
||||
void *storageFileReadDriver(const StorageFileRead *this);
|
||||
|
||||
#endif
|
||||
|
@ -13,12 +13,20 @@ Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct StorageFileWrite
|
||||
{
|
||||
MemContext *memContext;
|
||||
const String *type;
|
||||
MemContext *memContext; // Object mem context
|
||||
void *driver;
|
||||
StorageFileWriteInterface interface;
|
||||
const StorageFileWriteInterface *interface;
|
||||
IoWrite *io;
|
||||
};
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_FILE_WRITE_INTERFACE_TYPE \
|
||||
StorageFileWriteInterface
|
||||
#define FUNCTION_LOG_STORAGE_FILE_WRITE_INTERFACE_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(&value, "StorageFileWriteInterface", buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a new storage file
|
||||
|
||||
@ -26,32 +34,24 @@ This object expects its context to be created in advance. This is so the callin
|
||||
required multiple functions and contexts to make it safe.
|
||||
***********************************************************************************************************************************/
|
||||
StorageFileWrite *
|
||||
storageFileWriteNew(const String *type, void *driver, StorageFileWriteInterface interface)
|
||||
storageFileWriteNew(void *driver, const StorageFileWriteInterface *interface)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STRING, type);
|
||||
FUNCTION_LOG_PARAM_P(VOID, driver);
|
||||
FUNCTION_LOG_PARAM(STORAGE_FILE_WRITE_INTERFACE, interface);
|
||||
FUNCTION_LOG_PARAM_P(STORAGE_FILE_WRITE_INTERFACE, interface);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(type != NULL);
|
||||
ASSERT(driver != NULL);
|
||||
ASSERT(interface.atomic != NULL);
|
||||
ASSERT(interface.createPath != NULL);
|
||||
ASSERT(interface.io != NULL);
|
||||
ASSERT(interface.modeFile != NULL);
|
||||
ASSERT(interface.modePath != NULL);
|
||||
ASSERT(interface.name != NULL);
|
||||
ASSERT(interface.syncFile != NULL);
|
||||
ASSERT(interface.syncPath != NULL);
|
||||
ASSERT(interface != NULL);
|
||||
|
||||
StorageFileWrite *this = memNew(sizeof(StorageFileWrite));
|
||||
this->memContext = memContextCurrent();
|
||||
|
||||
this->type = type;
|
||||
this->driver = driver;
|
||||
this->interface = interface;
|
||||
|
||||
this->io = ioWriteNew(driver, interface->ioInterface);
|
||||
|
||||
FUNCTION_LOG_RETURN(STORAGE_FILE_WRITE, this);
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ storageFileWriteAtomic(const StorageFileWrite *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface.atomic(this->driver));
|
||||
FUNCTION_TEST_RETURN(this->interface->atomic);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -103,7 +103,7 @@ storageFileWriteCreatePath(const StorageFileWrite *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface.createPath(this->driver));
|
||||
FUNCTION_TEST_RETURN(this->interface->createPath);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -133,7 +133,7 @@ storageFileWriteIo(const StorageFileWrite *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface.io(this->driver));
|
||||
FUNCTION_TEST_RETURN(this->io);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -148,7 +148,7 @@ storageFileWriteModeFile(const StorageFileWrite *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface.modeFile(this->driver));
|
||||
FUNCTION_TEST_RETURN(this->interface->modeFile);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -163,7 +163,7 @@ storageFileWriteModePath(const StorageFileWrite *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface.modePath(this->driver));
|
||||
FUNCTION_TEST_RETURN(this->interface->modePath);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -178,7 +178,7 @@ storageFileWriteName(const StorageFileWrite *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface.name(this->driver));
|
||||
FUNCTION_TEST_RETURN(this->interface->name);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -193,7 +193,7 @@ storageFileWriteSyncFile(const StorageFileWrite *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface.syncFile(this->driver));
|
||||
FUNCTION_TEST_RETURN(this->interface->syncFile);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -208,7 +208,7 @@ storageFileWriteSyncPath(const StorageFileWrite *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->interface.syncPath(this->driver));
|
||||
FUNCTION_TEST_RETURN(this->interface->syncPath);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -223,7 +223,7 @@ storageFileWriteType(const StorageFileWrite *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->type);
|
||||
FUNCTION_TEST_RETURN(this->interface->type);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -234,7 +234,7 @@ storageFileWriteToLog(const StorageFileWrite *this)
|
||||
{
|
||||
return strNewFmt(
|
||||
"{type: %s, name: %s, modeFile: %04o, modePath: %04o, createPath: %s, syncFile: %s, syncPath: %s, atomic: %s}",
|
||||
strPtr(this->type), strPtr(strToLog(storageFileWriteName(this))), storageFileWriteModeFile(this),
|
||||
strPtr(storageFileWriteType(this)), strPtr(strToLog(storageFileWriteName(this))), storageFileWriteModeFile(this),
|
||||
storageFileWriteModePath(this), cvtBoolToConstZ(storageFileWriteCreatePath(this)),
|
||||
cvtBoolToConstZ(storageFileWriteSyncFile(this)), cvtBoolToConstZ(storageFileWriteSyncPath(this)),
|
||||
cvtBoolToConstZ(storageFileWriteAtomic(this)));
|
||||
|
@ -4,10 +4,8 @@ Storage File Write Interface
|
||||
#ifndef STORAGE_FILEWRITE_H
|
||||
#define STORAGE_FILEWRITE_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
Object types
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct StorageFileWrite StorageFileWrite;
|
||||
|
||||
@ -25,7 +23,6 @@ Getters
|
||||
***********************************************************************************************************************************/
|
||||
bool storageFileWriteAtomic(const StorageFileWrite *this);
|
||||
bool storageFileWriteCreatePath(const StorageFileWrite *this);
|
||||
void *storageFileWriteFileDriver(const StorageFileWrite *this);
|
||||
IoWrite *storageFileWriteIo(const StorageFileWrite *this);
|
||||
mode_t storageFileWriteModeFile(const StorageFileWrite *this);
|
||||
mode_t storageFileWriteModePath(const StorageFileWrite *this);
|
||||
|
@ -4,6 +4,7 @@ Storage File Write Internal
|
||||
#ifndef STORAGE_FILEWRITE_INTERN_H
|
||||
#define STORAGE_FILEWRITE_INTERN_H
|
||||
|
||||
#include "common/io/write.intern.h"
|
||||
#include "storage/fileWrite.h"
|
||||
#include "version.h"
|
||||
|
||||
@ -15,38 +16,29 @@ Temporary file extension
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
typedef bool (*StorageFileWriteInterfaceAtomic)(const void *data);
|
||||
typedef bool (*StorageFileWriteInterfaceCreatePath)(const void *data);
|
||||
typedef IoWrite *(*StorageFileWriteInterfaceIo)(const void *data);
|
||||
typedef mode_t (*StorageFileWriteInterfaceModeFile)(const void *data);
|
||||
typedef mode_t (*StorageFileWriteInterfaceModePath)(const void *data);
|
||||
typedef const String *(*StorageFileWriteInterfaceName)(const void *data);
|
||||
typedef bool (*StorageFileWriteInterfaceSyncFile)(const void *data);
|
||||
typedef bool (*StorageFileWriteInterfaceSyncPath)(const void *data);
|
||||
|
||||
typedef struct StorageFileWriteInterface
|
||||
{
|
||||
StorageFileWriteInterfaceAtomic atomic;
|
||||
StorageFileWriteInterfaceCreatePath createPath;
|
||||
StorageFileWriteInterfaceIo io;
|
||||
StorageFileWriteInterfaceModeFile modeFile;
|
||||
StorageFileWriteInterfaceModePath modePath;
|
||||
StorageFileWriteInterfaceName name;
|
||||
StorageFileWriteInterfaceSyncFile syncFile;
|
||||
StorageFileWriteInterfaceSyncPath syncPath;
|
||||
const String *type;
|
||||
const String *name;
|
||||
|
||||
bool atomic;
|
||||
bool createPath;
|
||||
const String *group; // Group that owns the file
|
||||
mode_t modeFile;
|
||||
mode_t modePath;
|
||||
bool syncFile;
|
||||
bool syncPath;
|
||||
time_t timeModified; // Time file was last modified
|
||||
const String *user; // User that owns the file
|
||||
|
||||
IoWriteInterface ioInterface;
|
||||
} StorageFileWriteInterface;
|
||||
|
||||
#define storageFileWriteNewP(type, driver, ...) \
|
||||
storageFileWriteNew(type, driver, (StorageFileWriteInterface){__VA_ARGS__})
|
||||
|
||||
StorageFileWrite *storageFileWriteNew(const String *type, void *driver, StorageFileWriteInterface interface);
|
||||
StorageFileWrite *storageFileWriteNew(void *driver, const StorageFileWriteInterface *interface);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
#define FUNCTION_LOG_STORAGE_FILE_WRITE_INTERFACE_TYPE \
|
||||
StorageFileWriteInterface
|
||||
#define FUNCTION_LOG_STORAGE_FILE_WRITE_INTERFACE_FORMAT(value, buffer, bufferSize) \
|
||||
objToLog(&value, "StorageFileWriteInterface", buffer, bufferSize)
|
||||
void *storageFileWriteFileDriver(const StorageFileWrite *this);
|
||||
|
||||
#endif
|
||||
|
@ -105,9 +105,8 @@ storageLocal(void)
|
||||
|
||||
MEM_CONTEXT_BEGIN(storageHelper.memContext)
|
||||
{
|
||||
storageHelper.storageLocal = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(
|
||||
FSLASH_STR, STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL));
|
||||
storageHelper.storageLocal = storageDriverPosixNew(
|
||||
FSLASH_STR, STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
@ -131,9 +130,8 @@ storageLocalWrite(void)
|
||||
|
||||
MEM_CONTEXT_BEGIN(storageHelper.memContext)
|
||||
{
|
||||
storageHelper.storageLocalWrite = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(
|
||||
FSLASH_STR, STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
|
||||
storageHelper.storageLocalWrite = storageDriverPosixNew(
|
||||
FSLASH_STR, STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
@ -155,9 +153,8 @@ storagePg(void)
|
||||
|
||||
MEM_CONTEXT_BEGIN(storageHelper.memContext)
|
||||
{
|
||||
storageHelper.storagePg = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(
|
||||
cfgOptionStr(cfgOptPgPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL));
|
||||
storageHelper.storagePg = storageDriverPosixNew(
|
||||
cfgOptionStr(cfgOptPgPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
@ -179,9 +176,8 @@ storagePgWrite(void)
|
||||
|
||||
MEM_CONTEXT_BEGIN(storageHelper.memContext)
|
||||
{
|
||||
storageHelper.storagePgWrite = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(
|
||||
cfgOptionStr(cfgOptPgPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
|
||||
storageHelper.storagePgWrite = storageDriverPosixNew(
|
||||
cfgOptionStr(cfgOptPgPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
@ -280,26 +276,21 @@ storageRepoGet(const String *type, bool write)
|
||||
// Use remote storage
|
||||
if (!repoIsLocal())
|
||||
{
|
||||
result = storageDriverRemoteInterface(
|
||||
storageDriverRemoteNew(
|
||||
result = storageDriverRemoteNew(
|
||||
STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, write, storageRepoPathExpression,
|
||||
protocolRemoteGet(protocolStorageTypeRepo)));
|
||||
protocolRemoteGet(protocolStorageTypeRepo));
|
||||
}
|
||||
// Use the CIFS driver
|
||||
else if (strEqZ(type, STORAGE_TYPE_CIFS))
|
||||
{
|
||||
result = storageDriverCifsInterface(
|
||||
storageDriverCifsNew(
|
||||
cfgOptionStr(cfgOptRepoPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, write,
|
||||
storageRepoPathExpression));
|
||||
result = storageDriverCifsNew(
|
||||
cfgOptionStr(cfgOptRepoPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, write, storageRepoPathExpression);
|
||||
}
|
||||
// Use the Posix driver
|
||||
else if (strEqZ(type, STORAGE_TYPE_POSIX))
|
||||
{
|
||||
result = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(
|
||||
cfgOptionStr(cfgOptRepoPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, write,
|
||||
storageRepoPathExpression));
|
||||
result = storageDriverPosixNew(
|
||||
cfgOptionStr(cfgOptRepoPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, write, storageRepoPathExpression);
|
||||
}
|
||||
// Use the S3 driver
|
||||
else if (strEqZ(type, STORAGE_TYPE_S3))
|
||||
@ -311,14 +302,13 @@ storageRepoGet(const String *type, bool write)
|
||||
const String *endPoint = cfgOptionHostPort(cfgOptRepoS3Endpoint, &port);
|
||||
const String *host = cfgOptionHostPort(cfgOptRepoS3Host, &port);
|
||||
|
||||
result = storageDriverS3Interface(
|
||||
storageDriverS3New(
|
||||
cfgOptionStr(cfgOptRepoPath), write, storageRepoPathExpression, cfgOptionStr(cfgOptRepoS3Bucket),
|
||||
endPoint, cfgOptionStr(cfgOptRepoS3Region), cfgOptionStr(cfgOptRepoS3Key), cfgOptionStr(cfgOptRepoS3KeySecret),
|
||||
cfgOptionTest(cfgOptRepoS3Token) ? cfgOptionStr(cfgOptRepoS3Token) : NULL, (size_t)5 * 1024 * 1024, host, port,
|
||||
result = storageDriverS3New(
|
||||
cfgOptionStr(cfgOptRepoPath), write, storageRepoPathExpression, cfgOptionStr(cfgOptRepoS3Bucket), endPoint,
|
||||
cfgOptionStr(cfgOptRepoS3Region), cfgOptionStr(cfgOptRepoS3Key), cfgOptionStr(cfgOptRepoS3KeySecret),
|
||||
cfgOptionTest(cfgOptRepoS3Token) ? cfgOptionStr(cfgOptRepoS3Token) : NULL, STORAGE_DRIVER_S3_PARTSIZE_MIN, host, port,
|
||||
STORAGE_DRIVER_S3_TIMEOUT_DEFAULT, cfgOptionBool(cfgOptRepoS3VerifySsl),
|
||||
cfgOptionTest(cfgOptRepoS3CaFile) ? cfgOptionStr(cfgOptRepoS3CaFile) : NULL,
|
||||
cfgOptionTest(cfgOptRepoS3CaPath) ? cfgOptionStr(cfgOptRepoS3CaPath) : NULL));
|
||||
cfgOptionTest(cfgOptRepoS3CaPath) ? cfgOptionStr(cfgOptRepoS3CaPath) : NULL);
|
||||
}
|
||||
else
|
||||
THROW_FMT(AssertError, "invalid storage type '%s'", strPtr(type));
|
||||
@ -425,10 +415,9 @@ storageSpool(void)
|
||||
|
||||
MEM_CONTEXT_BEGIN(storageHelper.memContext)
|
||||
{
|
||||
storageHelper.storageSpool = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(
|
||||
storageHelper.storageSpool = storageDriverPosixNew(
|
||||
cfgOptionStr(cfgOptSpoolPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false,
|
||||
storageSpoolPathExpression));
|
||||
storageSpoolPathExpression);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
@ -451,10 +440,9 @@ storageSpoolWrite(void)
|
||||
|
||||
MEM_CONTEXT_BEGIN(storageHelper.memContext)
|
||||
{
|
||||
storageHelper.storageSpoolWrite = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(
|
||||
storageHelper.storageSpoolWrite = storageDriverPosixNew(
|
||||
cfgOptionStr(cfgOptSpoolPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true,
|
||||
storageSpoolPathExpression));
|
||||
storageSpoolPathExpression);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
|
@ -348,7 +348,7 @@ storageMove(const Storage *this, StorageFileRead *source, StorageFileWrite *dest
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
// If the file can't be moved it will need to be copied
|
||||
if (!this->interface.move(this->driver, storageFileReadDriver(source), storageFileWriteFileDriver(destination)))
|
||||
if (!this->interface.move(this->driver, source, destination))
|
||||
{
|
||||
// Perform the copy
|
||||
storageCopyNP(source, destination);
|
||||
|
@ -4,6 +4,8 @@ Storage Interface Internal
|
||||
#ifndef STORAGE_STORAGE_INTERN_H
|
||||
#define STORAGE_STORAGE_INTERN_H
|
||||
|
||||
#include "storage/fileRead.intern.h"
|
||||
#include "storage/fileWrite.intern.h"
|
||||
#include "storage/storage.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -20,35 +22,21 @@ typedef String *(*StoragePathExpressionCallback)(const String *expression, const
|
||||
/***********************************************************************************************************************************
|
||||
Constructor
|
||||
***********************************************************************************************************************************/
|
||||
typedef bool (*StorageInterfaceExists)(void *driver, const String *path);
|
||||
typedef StorageInfo (*StorageInterfaceInfo)(void *driver, const String *path, bool ignoreMissing, bool followLink);
|
||||
typedef bool (*StorageInterfaceInfoList)(
|
||||
void *driver, const String *file, bool ignoreMissing, StorageInfoListCallback callback, void *callbackData);
|
||||
typedef StringList *(*StorageInterfaceList)(void *driver, const String *path, bool errorOnMissing, const String *expression);
|
||||
typedef bool (*StorageInterfaceMove)(void *driver, void *source, void *destination);
|
||||
typedef StorageFileRead *(*StorageInterfaceNewRead)(void *driver, const String *file, bool ignoreMissing);
|
||||
typedef StorageFileWrite *(*StorageInterfaceNewWrite)(
|
||||
void *driver, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
|
||||
typedef void (*StorageInterfacePathCreate)(
|
||||
void *driver, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode);
|
||||
typedef void (*StorageInterfacePathRemove)(void *driver, const String *path, bool errorOnMissing, bool recurse);
|
||||
typedef void (*StorageInterfacePathSync)(void *driver, const String *path, bool ignoreMissing);
|
||||
typedef void (*StorageInterfaceRemove)(void *driver, const String *file, bool errorOnMissing);
|
||||
|
||||
typedef struct StorageInterface
|
||||
{
|
||||
StorageInterfaceExists exists;
|
||||
StorageInterfaceInfo info;
|
||||
StorageInterfaceInfoList infoList;
|
||||
StorageInterfaceList list;
|
||||
StorageInterfaceMove move;
|
||||
StorageInterfaceNewRead newRead;
|
||||
StorageInterfaceNewWrite newWrite;
|
||||
StorageInterfacePathCreate pathCreate;
|
||||
StorageInterfacePathRemove pathRemove;
|
||||
StorageInterfacePathSync pathSync;
|
||||
StorageInterfaceRemove remove;
|
||||
bool (*exists)(void *driver, const String *path);
|
||||
StorageInfo (*info)(void *driver, const String *path, bool ignoreMissing, bool followLink);
|
||||
bool (*infoList)(void *driver, const String *file, bool ignoreMissing, StorageInfoListCallback callback, void *callbackData);
|
||||
StringList *(*list)(void *driver, const String *path, bool errorOnMissing, const String *expression);
|
||||
bool (*move)(void *driver, StorageFileRead *source, StorageFileWrite *destination);
|
||||
StorageFileRead *(*newRead)(void *driver, const String *file, bool ignoreMissing);
|
||||
StorageFileWrite *(*newWrite)(
|
||||
void *driver, const String *file, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
time_t timeModified, bool createPath, bool syncFile, bool syncPath, bool atomic);
|
||||
void (*pathCreate)(void *driver, const String *path, bool errorOnExists, bool noParentCreate, mode_t mode);
|
||||
void (*pathRemove)(void *driver, const String *path, bool errorOnMissing, bool recurse);
|
||||
void (*pathSync)(void *driver, const String *path, bool ignoreMissing);
|
||||
void (*remove)(void *driver, const String *file, bool errorOnMissing);
|
||||
} StorageInterface;
|
||||
|
||||
#define storageNewP(type, path, modeFile, modePath, write, pathExpressionFunction, driver, ...) \
|
||||
|
@ -498,6 +498,7 @@ unit:
|
||||
|
||||
coverage:
|
||||
storage/driver/cifs/storage: full
|
||||
storage/driver/posix/storage: full
|
||||
storage/helper: full
|
||||
storage/storage: full
|
||||
|
||||
|
@ -59,7 +59,7 @@ sub run
|
||||
$self->testException(
|
||||
sub {new pgBackRest::Storage::Filter::CipherBlock(
|
||||
$oDriver->openRead($strFile), BOGUS, $tCipherPass)},
|
||||
ERROR_ASSERT, "unable to load cipher '" . BOGUS . "'");
|
||||
ERROR_ASSERT, "invalid cipher name '" . BOGUS . "'");
|
||||
|
||||
$self->testException(
|
||||
sub {new pgBackRest::Storage::Filter::CipherBlock(
|
||||
@ -69,7 +69,7 @@ sub run
|
||||
$self->testException(
|
||||
sub {new pgBackRest::Storage::Filter::CipherBlock(
|
||||
$oDriver->openWrite($strFile), BOGUS, $tCipherPass)},
|
||||
ERROR_ASSERT, "unable to load cipher '" . BOGUS . "'");
|
||||
ERROR_ASSERT, "invalid cipher name '" . BOGUS . "'");
|
||||
}
|
||||
|
||||
################################################################################################################################
|
||||
|
@ -36,7 +36,7 @@ harnessInfoChecksum(const String *info)
|
||||
|
||||
// Write to a buffer
|
||||
result = bufNew(0);
|
||||
iniSave(ini, ioBufferWriteIo(ioBufferWriteNew(result)));
|
||||
iniSave(ini, ioBufferWriteNew(result));
|
||||
bufMove(result, MEM_CONTEXT_OLD());
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
@ -17,8 +17,8 @@ testRun(void)
|
||||
FUNCTION_HARNESS_VOID();
|
||||
|
||||
// Create default storage object for testing
|
||||
Storage *storageTest = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
|
||||
Storage *storageTest = storageDriverPosixNew(
|
||||
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("archiveAsyncStatus()"))
|
||||
|
@ -20,16 +20,16 @@ testRun(void)
|
||||
{
|
||||
FUNCTION_HARNESS_VOID();
|
||||
|
||||
Storage *storageTest = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
|
||||
Storage *storageTest = storageDriverPosixNew(
|
||||
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
|
||||
|
||||
// Start a protocol server to test the protocol directly
|
||||
Buffer *serverWrite = bufNew(8192);
|
||||
IoWrite *serverWriteIo = ioBufferWriteIo(ioBufferWriteNew(serverWrite));
|
||||
IoWrite *serverWriteIo = ioBufferWriteNew(serverWrite);
|
||||
ioWriteOpen(serverWriteIo);
|
||||
|
||||
ProtocolServer *server = protocolServerNew(
|
||||
strNew("test"), strNew("test"), ioBufferReadIo(ioBufferReadNew(bufNew(0))), serverWriteIo);
|
||||
strNew("test"), strNew("test"), ioBufferReadNew(bufNew(0)), serverWriteIo);
|
||||
|
||||
bufUsedSet(serverWrite, 0);
|
||||
|
||||
@ -189,8 +189,7 @@ testRun(void)
|
||||
ioWriteFilterGroupSet(
|
||||
storageFileWriteIo(infoWrite),
|
||||
ioFilterGroupAdd(
|
||||
ioFilterGroupNew(),
|
||||
cipherBlockFilter(cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("12345678"), NULL))));
|
||||
ioFilterGroupNew(), cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("12345678"), NULL)));
|
||||
|
||||
storagePutNP(
|
||||
infoWrite,
|
||||
@ -210,11 +209,9 @@ testRun(void)
|
||||
"repo/archive/test1/10-1/01ABCDEF01ABCDEF/01ABCDEF01ABCDEF01ABCDEF-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.gz"));
|
||||
|
||||
IoFilterGroup *filterGroup = ioFilterGroupNew();
|
||||
ioFilterGroupAdd(filterGroup, gzipCompressFilter(gzipCompressNew(3, false)));
|
||||
ioFilterGroupAdd(filterGroup, gzipCompressNew(3, false));
|
||||
ioFilterGroupAdd(
|
||||
filterGroup,
|
||||
cipherBlockFilter(
|
||||
cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("worstpassphraseever"), NULL)));
|
||||
filterGroup, cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("worstpassphraseever"), NULL));
|
||||
ioWriteFilterGroupSet(storageFileWriteIo(destination), filterGroup);
|
||||
storagePutNP(destination, buffer);
|
||||
|
||||
|
@ -22,16 +22,16 @@ testRun(void)
|
||||
FUNCTION_HARNESS_VOID();
|
||||
|
||||
// Create default storage object for testing
|
||||
Storage *storageTest = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
|
||||
Storage *storageTest = storageDriverPosixNew(
|
||||
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
|
||||
|
||||
// Start a protocol server to test the protocol directly
|
||||
Buffer *serverWrite = bufNew(8192);
|
||||
IoWrite *serverWriteIo = ioBufferWriteIo(ioBufferWriteNew(serverWrite));
|
||||
IoWrite *serverWriteIo = ioBufferWriteNew(serverWrite);
|
||||
ioWriteOpen(serverWriteIo);
|
||||
|
||||
ProtocolServer *server = protocolServerNew(
|
||||
strNew("test"), strNew("test"), ioBufferReadIo(ioBufferReadNew(bufNew(0))), serverWriteIo);
|
||||
strNew("test"), strNew("test"), ioBufferReadNew(bufNew(0)), serverWriteIo);
|
||||
|
||||
bufUsedSet(serverWrite, 0);
|
||||
|
||||
@ -376,9 +376,7 @@ testRun(void)
|
||||
ioWriteFilterGroupSet(
|
||||
storageFileWriteIo(infoWrite),
|
||||
ioFilterGroupAdd(
|
||||
ioFilterGroupNew(),
|
||||
cipherBlockFilter(
|
||||
cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("badpassphrase"), NULL))));
|
||||
ioFilterGroupNew(), cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("badpassphrase"), NULL)));
|
||||
|
||||
storagePutNP(
|
||||
infoWrite,
|
||||
@ -492,9 +490,9 @@ testRun(void)
|
||||
{
|
||||
HARNESS_FORK_CHILD_BEGIN(0, true)
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("child read"), HARNESS_FORK_CHILD_READ(), 2000));
|
||||
IoRead *read = ioHandleReadNew(strNew("child read"), HARNESS_FORK_CHILD_READ(), 2000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("child write"), HARNESS_FORK_CHILD_WRITE()));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("child write"), HARNESS_FORK_CHILD_WRITE());
|
||||
ioWriteOpen(write);
|
||||
|
||||
lockAcquire(cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), cfgLockType(), 30000, true);
|
||||
@ -510,9 +508,9 @@ testRun(void)
|
||||
|
||||
HARNESS_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("parent read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
|
||||
IoRead *read = ioHandleReadNew(strNew("parent read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("parent write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("parent write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
|
||||
ioWriteOpen(write);
|
||||
|
||||
// Wait for the child to acquire the lock
|
||||
|
@ -13,8 +13,8 @@ testRun(void)
|
||||
FUNCTION_HARNESS_VOID();
|
||||
|
||||
// Create default storage object for testing
|
||||
Storage *storageTest = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
|
||||
Storage *storageTest = storageDriverPosixNew(
|
||||
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("lockStopFileName()"))
|
||||
|
@ -386,8 +386,8 @@ testRun(void)
|
||||
// Restore normal stdout
|
||||
dup2(stdoutSave, STDOUT_FILENO);
|
||||
|
||||
Storage *storage = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL));
|
||||
Storage *storage = storageDriverPosixNew(
|
||||
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL);
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(storageGetNP(storageNewReadNP(storage, stdoutFile)))), generalHelp, " check text");
|
||||
}
|
||||
|
||||
|
@ -824,8 +824,8 @@ testRun(void)
|
||||
// Restore normal stdout
|
||||
dup2(stdoutSave, STDOUT_FILENO);
|
||||
|
||||
Storage *storage = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL));
|
||||
Storage *storage = storageDriverPosixNew(
|
||||
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL);
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strNewBuf(storageGetNP(storageNewReadNP(storage, stdoutFile)))), "No stanzas exist in the repository.\n",
|
||||
" check text");
|
||||
|
@ -46,9 +46,9 @@ testRun(void)
|
||||
|
||||
HARNESS_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
|
||||
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
|
||||
ioWriteOpen(write);
|
||||
|
||||
ProtocolClient *client = protocolClientNew(strNew("test"), PROTOCOL_SERVICE_LOCAL_STR, read, write);
|
||||
|
@ -22,8 +22,8 @@ testRun(void)
|
||||
if (testBegin("cmdRemote()"))
|
||||
{
|
||||
// Create default storage object for testing
|
||||
Storage *storageTest = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
|
||||
Storage *storageTest = storageDriverPosixNew(
|
||||
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
|
||||
|
||||
// No remote lock required
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -46,9 +46,9 @@ testRun(void)
|
||||
|
||||
HARNESS_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
|
||||
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
|
||||
ioWriteOpen(write);
|
||||
|
||||
ProtocolClient *client = protocolClientNew(strNew("test"), PROTOCOL_SERVICE_REMOTE_STR, read, write);
|
||||
@ -80,9 +80,9 @@ testRun(void)
|
||||
|
||||
HARNESS_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
|
||||
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
|
||||
ioWriteOpen(write);
|
||||
|
||||
ProtocolClient *client = NULL;
|
||||
@ -116,9 +116,9 @@ testRun(void)
|
||||
|
||||
HARNESS_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
|
||||
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
|
||||
ioWriteOpen(write);
|
||||
|
||||
TEST_ERROR(
|
||||
@ -151,9 +151,9 @@ testRun(void)
|
||||
|
||||
HARNESS_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
|
||||
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
|
||||
ioWriteOpen(write);
|
||||
|
||||
ProtocolClient *client = NULL;
|
||||
|
@ -10,15 +10,15 @@ Test Gzip
|
||||
Compress data
|
||||
***********************************************************************************************************************************/
|
||||
static Buffer *
|
||||
testCompress(GzipCompress *compress, Buffer *decompressed, size_t inputSize, size_t outputSize)
|
||||
testCompress(IoFilter *compress, Buffer *decompressed, size_t inputSize, size_t outputSize)
|
||||
{
|
||||
Buffer *compressed = bufNew(1024 * 1024);
|
||||
size_t inputTotal = 0;
|
||||
ioBufferSizeSet(outputSize);
|
||||
|
||||
IoFilterGroup *filterGroup = ioFilterGroupNew();
|
||||
ioFilterGroupAdd(filterGroup, gzipCompressFilter(compress));
|
||||
IoWrite *write = ioBufferWriteIo(ioBufferWriteNew(compressed));
|
||||
ioFilterGroupAdd(filterGroup, compress);
|
||||
IoWrite *write = ioBufferWriteNew(compressed);
|
||||
ioWriteFilterGroupSet(write, filterGroup);
|
||||
ioWriteOpen(write);
|
||||
|
||||
@ -37,7 +37,7 @@ testCompress(GzipCompress *compress, Buffer *decompressed, size_t inputSize, siz
|
||||
}
|
||||
|
||||
ioWriteClose(write);
|
||||
gzipCompressFree(compress);
|
||||
gzipCompressFree(ioFilterDriver(compress));
|
||||
|
||||
return compressed;
|
||||
}
|
||||
@ -46,15 +46,15 @@ testCompress(GzipCompress *compress, Buffer *decompressed, size_t inputSize, siz
|
||||
Decompress data
|
||||
***********************************************************************************************************************************/
|
||||
static Buffer *
|
||||
testDecompress(GzipDecompress *decompress, Buffer *compressed, size_t inputSize, size_t outputSize)
|
||||
testDecompress(IoFilter *decompress, Buffer *compressed, size_t inputSize, size_t outputSize)
|
||||
{
|
||||
Buffer *decompressed = bufNew(1024 * 1024);
|
||||
Buffer *output = bufNew(outputSize);
|
||||
ioBufferSizeSet(inputSize);
|
||||
|
||||
IoFilterGroup *filterGroup = ioFilterGroupNew();
|
||||
ioFilterGroupAdd(filterGroup, gzipDecompressFilter(decompress));
|
||||
IoRead *read = ioBufferReadIo(ioBufferReadNew(compressed));
|
||||
ioFilterGroupAdd(filterGroup, decompress);
|
||||
IoRead *read = ioBufferReadNew(compressed);
|
||||
ioReadFilterGroupSet(read, filterGroup);
|
||||
ioReadOpen(read);
|
||||
|
||||
@ -67,7 +67,7 @@ testDecompress(GzipDecompress *decompress, Buffer *compressed, size_t inputSize,
|
||||
|
||||
ioReadClose(read);
|
||||
bufFree(output);
|
||||
gzipDecompressFree(decompress);
|
||||
gzipDecompressFree(ioFilterDriver(decompress));
|
||||
|
||||
return decompressed;
|
||||
}
|
||||
@ -164,13 +164,15 @@ testRun(void)
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("gzipDecompressToLog() and gzipCompressToLog()"))
|
||||
{
|
||||
GzipDecompress *decompress = gzipDecompressNew(false);
|
||||
GzipDecompress *decompress = (GzipDecompress *)ioFilterDriver(gzipDecompressNew(false));
|
||||
|
||||
TEST_RESULT_STR(strPtr(gzipDecompressToLog(decompress)), "{inputSame: false, done: false, availIn: 0}", "format object");
|
||||
|
||||
decompress->inputSame = true;
|
||||
decompress->done = true;
|
||||
TEST_RESULT_STR(strPtr(gzipDecompressToLog(decompress)), "{inputSame: true, done: true, availIn: 0}", "format object");
|
||||
|
||||
gzipDecompressFree(decompress);
|
||||
}
|
||||
|
||||
FUNCTION_HARNESS_RESULT_VOID();
|
||||
|
@ -8,7 +8,6 @@ Data for testing
|
||||
***********************************************************************************************************************************/
|
||||
#define TEST_CIPHER "aes-256-cbc"
|
||||
#define TEST_PASS "areallybadpassphrase"
|
||||
#define TEST_PASS_SIZE strlen(TEST_PASS)
|
||||
#define TEST_PLAINTEXT "plaintext"
|
||||
#define TEST_BUFFER_SIZE 256
|
||||
|
||||
@ -78,21 +77,21 @@ testRun(void)
|
||||
// Cipher and digest errors
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR(
|
||||
cipherBlockNewC(
|
||||
cipherModeEncrypt, BOGUS_STR, (unsigned char *)TEST_PASS, TEST_PASS_SIZE, NULL), AssertError,
|
||||
"unable to load cipher 'BOGUS'");
|
||||
cipherBlockNew(
|
||||
cipherModeEncrypt, cipherTypeNone, BUFSTRZ(TEST_PASS), NULL), AssertError,
|
||||
"unable to load cipher 'none'");
|
||||
TEST_ERROR(
|
||||
cipherBlockNew(
|
||||
cipherModeEncrypt, cipherTypeAes256Cbc, testPass, strNew(BOGUS_STR)), AssertError, "unable to load digest 'BOGUS'");
|
||||
|
||||
// Initialization of object
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
CipherBlock *cipherBlock = cipherBlockNewC(
|
||||
cipherModeEncrypt, TEST_CIPHER, (unsigned char *)TEST_PASS, TEST_PASS_SIZE, NULL);
|
||||
TEST_RESULT_STR(memContextName(cipherBlock->memContext), "cipherBlock", "mem context name is valid");
|
||||
CipherBlock *cipherBlock = (CipherBlock *)ioFilterDriver(
|
||||
cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRZ(TEST_PASS), NULL));
|
||||
TEST_RESULT_STR(memContextName(cipherBlock->memContext), "CipherBlock", "mem context name is valid");
|
||||
TEST_RESULT_INT(cipherBlock->mode, cipherModeEncrypt, "mode is valid");
|
||||
TEST_RESULT_INT(cipherBlock->passSize, TEST_PASS_SIZE, "passphrase size is valid");
|
||||
TEST_RESULT_BOOL(memcmp(cipherBlock->pass, TEST_PASS, TEST_PASS_SIZE) == 0, true, "passphrase is valid");
|
||||
TEST_RESULT_INT(cipherBlock->passSize, strlen(TEST_PASS), "passphrase size is valid");
|
||||
TEST_RESULT_BOOL(memcmp(cipherBlock->pass, TEST_PASS, strlen(TEST_PASS)) == 0, true, "passphrase is valid");
|
||||
TEST_RESULT_BOOL(cipherBlock->saltDone, false, "salt done is false");
|
||||
TEST_RESULT_BOOL(cipherBlock->processDone, false, "process done is false");
|
||||
TEST_RESULT_INT(cipherBlock->headerSize, 0, "header size is 0");
|
||||
@ -107,11 +106,11 @@ testRun(void)
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
Buffer *encryptBuffer = bufNew(TEST_BUFFER_SIZE);
|
||||
|
||||
CipherBlock *blockEncrypt = cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
IoFilter *blockEncryptFilter = cipherBlockFilter(blockEncrypt);
|
||||
IoFilter *blockEncryptFilter = cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
CipherBlock *blockEncrypt = (CipherBlock *)ioFilterDriver(blockEncryptFilter);
|
||||
|
||||
TEST_RESULT_INT(
|
||||
cipherBlockProcessSizeC(blockEncrypt, strlen(TEST_PLAINTEXT)),
|
||||
cipherBlockProcessSize(blockEncrypt, strlen(TEST_PLAINTEXT)),
|
||||
strlen(TEST_PLAINTEXT) + EVP_MAX_BLOCK_LENGTH + CIPHER_BLOCK_MAGIC_SIZE + PKCS5_SALT_LEN, "check process size");
|
||||
|
||||
bufLimitSet(encryptBuffer, CIPHER_BLOCK_MAGIC_SIZE);
|
||||
@ -129,7 +128,7 @@ testRun(void)
|
||||
TEST_RESULT_INT(bufUsed(encryptBuffer), CIPHER_BLOCK_HEADER_SIZE, "cipher size is header len");
|
||||
|
||||
TEST_RESULT_INT(
|
||||
cipherBlockProcessSizeC(blockEncrypt, strlen(TEST_PLAINTEXT)),
|
||||
cipherBlockProcessSize(blockEncrypt, strlen(TEST_PLAINTEXT)),
|
||||
strlen(TEST_PLAINTEXT) + EVP_MAX_BLOCK_LENGTH, "check process size");
|
||||
|
||||
bufLimitSet(
|
||||
@ -157,11 +156,11 @@ testRun(void)
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
Buffer *decryptBuffer = bufNew(TEST_BUFFER_SIZE);
|
||||
|
||||
CipherBlock *blockDecrypt = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
IoFilter *blockDecryptFilter = cipherBlockFilter(blockDecrypt);
|
||||
IoFilter *blockDecryptFilter = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
CipherBlock *blockDecrypt = (CipherBlock *)ioFilterDriver(blockDecryptFilter);
|
||||
|
||||
TEST_RESULT_INT(
|
||||
cipherBlockProcessSizeC(blockDecrypt, bufUsed(encryptBuffer)), bufUsed(encryptBuffer) + EVP_MAX_BLOCK_LENGTH,
|
||||
cipherBlockProcessSize(blockDecrypt, bufUsed(encryptBuffer)), bufUsed(encryptBuffer) + EVP_MAX_BLOCK_LENGTH,
|
||||
"check process size");
|
||||
|
||||
ioFilterProcessInOut(blockDecryptFilter, encryptBuffer, decryptBuffer);
|
||||
@ -176,8 +175,8 @@ testRun(void)
|
||||
|
||||
// Decrypt in small chunks to test buffering
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
blockDecrypt = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
blockDecryptFilter = cipherBlockFilter(blockDecrypt);
|
||||
blockDecryptFilter = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
blockDecrypt = (CipherBlock *)ioFilterDriver(blockDecryptFilter);
|
||||
|
||||
bufUsedZero(decryptBuffer);
|
||||
|
||||
@ -216,8 +215,8 @@ testRun(void)
|
||||
|
||||
// Encrypt zero byte file and decrypt it
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
blockEncrypt = cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
blockEncryptFilter = cipherBlockFilter(blockEncrypt);
|
||||
blockEncryptFilter = cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
blockEncrypt = (CipherBlock *)ioFilterDriver(blockEncryptFilter);
|
||||
|
||||
bufUsedZero(encryptBuffer);
|
||||
|
||||
@ -226,8 +225,8 @@ testRun(void)
|
||||
|
||||
cipherBlockFree(blockEncrypt);
|
||||
|
||||
blockDecrypt = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
blockDecryptFilter = cipherBlockFilter(blockDecrypt);
|
||||
blockDecryptFilter = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
blockDecrypt = (CipherBlock *)ioFilterDriver(blockDecryptFilter);
|
||||
|
||||
bufUsedZero(decryptBuffer);
|
||||
|
||||
@ -240,8 +239,8 @@ testRun(void)
|
||||
|
||||
// Invalid cipher header
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
blockDecrypt = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
blockDecryptFilter = cipherBlockFilter(blockDecrypt);
|
||||
blockDecryptFilter = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
blockDecrypt = (CipherBlock *)ioFilterDriver(blockDecryptFilter);
|
||||
|
||||
TEST_ERROR(
|
||||
ioFilterProcessInOut(blockDecryptFilter, BUFSTRDEF("1234567890123456"), decryptBuffer), CryptoError,
|
||||
@ -251,8 +250,8 @@ testRun(void)
|
||||
|
||||
// Invalid encrypted data cannot be flushed
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
blockDecrypt = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
blockDecryptFilter = cipherBlockFilter(blockDecrypt);
|
||||
blockDecryptFilter = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
blockDecrypt = (CipherBlock *)ioFilterDriver(blockDecryptFilter);
|
||||
|
||||
bufUsedZero(decryptBuffer);
|
||||
|
||||
@ -265,8 +264,8 @@ testRun(void)
|
||||
|
||||
// File with no header should not flush
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
blockDecrypt = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
blockDecryptFilter = cipherBlockFilter(blockDecrypt);
|
||||
blockDecryptFilter = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
blockDecrypt = (CipherBlock *)ioFilterDriver(blockDecryptFilter);
|
||||
|
||||
bufUsedZero(decryptBuffer);
|
||||
|
||||
@ -276,8 +275,8 @@ testRun(void)
|
||||
|
||||
// File with header only should error
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
blockDecrypt = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
blockDecryptFilter = cipherBlockFilter(blockDecrypt);
|
||||
blockDecryptFilter = cipherBlockNew(cipherModeDecrypt, cipherTypeAes256Cbc, testPass, NULL);
|
||||
blockDecrypt = (CipherBlock *)ioFilterDriver(blockDecryptFilter);
|
||||
|
||||
bufUsedZero(decryptBuffer);
|
||||
|
||||
@ -290,43 +289,44 @@ testRun(void)
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("CryptoHash"))
|
||||
{
|
||||
CryptoHash *hash = NULL;
|
||||
IoFilter *hashFilter = NULL;
|
||||
IoFilter *hash = NULL;
|
||||
|
||||
TEST_ERROR(cryptoHashNew(strNew(BOGUS_STR)), AssertError, "unable to load hash 'BOGUS'");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ASSIGN(hash, cryptoHashNew(strNew(HASH_TYPE_SHA1)), "create sha1 hash");
|
||||
TEST_RESULT_VOID(cryptoHashFree(hash), " free hash");
|
||||
TEST_RESULT_VOID(cryptoHashFree(NULL), " free null hash");
|
||||
TEST_RESULT_VOID(ioFilterFree(hash), " free hash");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ASSIGN(hash, cryptoHashNew(strNew(HASH_TYPE_SHA1)), "create sha1 hash");
|
||||
TEST_RESULT_STR(strPtr(bufHex(cryptoHash(hash))), "da39a3ee5e6b4b0d3255bfef95601890afd80709", " check empty hash");
|
||||
TEST_RESULT_STR(strPtr(bufHex(cryptoHash(hash))), "da39a3ee5e6b4b0d3255bfef95601890afd80709", " check empty hash again");
|
||||
TEST_RESULT_VOID(cryptoHashFree(hash), " free hash");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(bufHex(cryptoHash((CryptoHash *)ioFilterDriver(hash)))), "da39a3ee5e6b4b0d3255bfef95601890afd80709",
|
||||
" check empty hash");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(bufHex(cryptoHash((CryptoHash *)ioFilterDriver(hash)))), "da39a3ee5e6b4b0d3255bfef95601890afd80709",
|
||||
" check empty hash again");
|
||||
TEST_RESULT_VOID(ioFilterFree(hash), " free hash");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ASSIGN(hash, cryptoHashNew(strNew(HASH_TYPE_SHA1)), "create sha1 hash");
|
||||
TEST_ASSIGN(hashFilter, cryptoHashFilter(hash), "create sha1 hash");
|
||||
TEST_RESULT_VOID(cryptoHashProcessC(hash, (const unsigned char *)"1", 1), " add 1");
|
||||
TEST_RESULT_VOID(cryptoHashProcessStr(hash, strNew("2")), " add 2");
|
||||
TEST_RESULT_VOID(ioFilterProcessIn(hashFilter, BUFSTRDEF("3")), " add 3");
|
||||
TEST_RESULT_VOID(ioFilterProcessIn(hashFilter, BUFSTRDEF("4")), " add 4");
|
||||
TEST_RESULT_VOID(ioFilterProcessIn(hashFilter, BUFSTRDEF("5")), " add 5");
|
||||
TEST_RESULT_VOID(ioFilterProcessIn(hash, BUFSTRZ("1")), " add 1");
|
||||
TEST_RESULT_VOID(ioFilterProcessIn(hash, BUFSTR(strNew("2"))), " add 2");
|
||||
TEST_RESULT_VOID(ioFilterProcessIn(hash, BUFSTRDEF("3")), " add 3");
|
||||
TEST_RESULT_VOID(ioFilterProcessIn(hash, BUFSTRDEF("4")), " add 4");
|
||||
TEST_RESULT_VOID(ioFilterProcessIn(hash, BUFSTRDEF("5")), " add 5");
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(varStr(ioFilterResult(hashFilter))), "8cb2237d0679ca88db6464eac60da96345513964", " check small hash");
|
||||
TEST_RESULT_VOID(cryptoHashFree(hash), " free hash");
|
||||
strPtr(varStr(ioFilterResult(hash))), "8cb2237d0679ca88db6464eac60da96345513964", " check small hash");
|
||||
TEST_RESULT_VOID(ioFilterFree(hash), " free hash");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ASSIGN(hash, cryptoHashNew(strNew(HASH_TYPE_MD5)), "create md5 hash");
|
||||
TEST_RESULT_STR(strPtr(bufHex(cryptoHash(hash))), "d41d8cd98f00b204e9800998ecf8427e", " check empty hash");
|
||||
TEST_RESULT_STR(strPtr(varStr(ioFilterResult(hash))), "d41d8cd98f00b204e9800998ecf8427e", " check empty hash");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ASSIGN(hash, cryptoHashNew(strNew(HASH_TYPE_SHA256)), "create sha256 hash");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(bufHex(cryptoHash(hash))), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
strPtr(varStr(ioFilterResult(hash))), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
" check empty hash");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -334,8 +334,8 @@ testRun(void)
|
||||
strPtr(bufHex(cryptoHashOne(strNew(HASH_TYPE_SHA1), BUFSTRDEF("12345")))), "8cb2237d0679ca88db6464eac60da96345513964",
|
||||
" check small hash");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(bufHex(cryptoHashOneStr(strNew(HASH_TYPE_SHA1), strNew("12345")))), "8cb2237d0679ca88db6464eac60da96345513964",
|
||||
" check small hash");
|
||||
strPtr(bufHex(cryptoHashOne(strNew(HASH_TYPE_SHA1), BUFSTRDEF("")))), "da39a3ee5e6b4b0d3255bfef95601890afd80709",
|
||||
" check empty hash");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_STR(
|
||||
|
@ -11,8 +11,8 @@ testRun(void)
|
||||
{
|
||||
FUNCTION_HARNESS_VOID();
|
||||
|
||||
Storage *storageTest = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
|
||||
Storage *storageTest = storageDriverPosixNew(
|
||||
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("iniNew() and iniFree()"))
|
||||
|
@ -18,10 +18,13 @@ testIoReadOpen(void *driver)
|
||||
}
|
||||
|
||||
static size_t
|
||||
testIoRead(void *driver, Buffer *buffer)
|
||||
testIoRead(void *driver, Buffer *buffer, bool block)
|
||||
{
|
||||
ASSERT(driver == (void *)999);
|
||||
(void)block;
|
||||
|
||||
bufCat(buffer, BUFSTRDEF("Z"));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -69,16 +72,16 @@ typedef struct IoTestFilterSize
|
||||
{
|
||||
MemContext *memContext;
|
||||
size_t size;
|
||||
IoFilter *filter;
|
||||
} IoTestFilterSize;
|
||||
|
||||
static void
|
||||
ioTestFilterSizeProcess(IoTestFilterSize *this, const Buffer *buffer)
|
||||
ioTestFilterSizeProcess(THIS_VOID, const Buffer *buffer)
|
||||
{
|
||||
THIS(IoTestFilterSize);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM_P(VOID, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_LOG_PARAM(STRING, ioFilterType(this->filter));
|
||||
FUNCTION_LOG_PARAM(SIZE, this->size);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
@ -90,25 +93,25 @@ ioTestFilterSizeProcess(IoTestFilterSize *this, const Buffer *buffer)
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
static const Variant *
|
||||
ioTestFilterSizeResult(IoTestFilterSize *this)
|
||||
static Variant *
|
||||
ioTestFilterSizeResult(THIS_VOID)
|
||||
{
|
||||
THIS(IoTestFilterSize);
|
||||
|
||||
return varNewUInt64(this->size);
|
||||
}
|
||||
|
||||
static IoTestFilterSize *
|
||||
static IoFilter *
|
||||
ioTestFilterSizeNew(const char *type)
|
||||
{
|
||||
IoTestFilterSize *this = NULL;
|
||||
IoFilter *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("IoTestFilterSize")
|
||||
{
|
||||
this = memNew(sizeof(IoTestFilterSize));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
IoTestFilterSize *driver = memNew(sizeof(IoTestFilterSize));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
this->filter = ioFilterNewP(
|
||||
strNew(type), this, .in = (IoFilterInterfaceProcessIn)ioTestFilterSizeProcess,
|
||||
.result = (IoFilterInterfaceResult)ioTestFilterSizeResult);
|
||||
this = ioFilterNewP(strNew(type), driver, .in = ioTestFilterSizeProcess, .result = ioTestFilterSizeResult);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
@ -127,12 +130,13 @@ typedef struct IoTestFilterMultiply
|
||||
Buffer *multiplyBuffer;
|
||||
unsigned int multiplier;
|
||||
IoFilter *bufferFilter;
|
||||
IoFilter *filter;
|
||||
} IoTestFilterMultiply;
|
||||
|
||||
static void
|
||||
ioTestFilterMultiplyProcess(IoTestFilterMultiply *this, const Buffer *input, Buffer *output)
|
||||
ioTestFilterMultiplyProcess(THIS_VOID, const Buffer *input, Buffer *output)
|
||||
{
|
||||
THIS(IoTestFilterMultiply);
|
||||
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM_P(VOID, this);
|
||||
FUNCTION_LOG_PARAM(BUFFER, input);
|
||||
@ -183,35 +187,38 @@ ioTestFilterMultiplyProcess(IoTestFilterMultiply *this, const Buffer *input, Buf
|
||||
}
|
||||
|
||||
static bool
|
||||
ioTestFilterMultiplyDone(IoTestFilterMultiply *this)
|
||||
ioTestFilterMultiplyDone(const THIS_VOID)
|
||||
{
|
||||
THIS(const IoTestFilterMultiply);
|
||||
|
||||
return this->flushTotal == 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
ioTestFilterMultiplyInputSame(IoTestFilterMultiply *this)
|
||||
ioTestFilterMultiplyInputSame(const THIS_VOID)
|
||||
{
|
||||
THIS(const IoTestFilterMultiply);
|
||||
|
||||
return ioFilterInputSame(this->bufferFilter);
|
||||
}
|
||||
|
||||
static IoTestFilterMultiply *
|
||||
static IoFilter *
|
||||
ioTestFilterMultiplyNew(const char *type, unsigned int multiplier, unsigned int flushTotal, char flushChar)
|
||||
{
|
||||
IoTestFilterMultiply *this = NULL;
|
||||
IoFilter *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("IoTestFilterMultiply")
|
||||
{
|
||||
this = memNew(sizeof(IoTestFilterMultiply));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
this->bufferFilter = ioBufferFilter(ioBufferNew());
|
||||
this->multiplier = multiplier;
|
||||
this->flushTotal = flushTotal;
|
||||
this->flushChar = flushChar;
|
||||
IoTestFilterMultiply *driver = memNew(sizeof(IoTestFilterMultiply));
|
||||
driver->memContext = MEM_CONTEXT_NEW();
|
||||
driver->bufferFilter = ioBufferNew();
|
||||
driver->multiplier = multiplier;
|
||||
driver->flushTotal = flushTotal;
|
||||
driver->flushChar = flushChar;
|
||||
|
||||
this->filter = ioFilterNewP(
|
||||
strNew(type), this, .done = (IoFilterInterfaceDone)ioTestFilterMultiplyDone,
|
||||
.inOut = (IoFilterInterfaceProcessInOut)ioTestFilterMultiplyProcess,
|
||||
.inputSame = (IoFilterInterfaceInputSame)ioTestFilterMultiplyInputSame);
|
||||
this = ioFilterNewP(
|
||||
strNew(type), driver, .done = ioTestFilterMultiplyDone, .inOut = ioTestFilterMultiplyProcess,
|
||||
.inputSame = ioTestFilterMultiplyInputSame);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
@ -242,17 +249,13 @@ testRun(void)
|
||||
ioBufferSizeSet(2);
|
||||
|
||||
TEST_ASSIGN(
|
||||
read,
|
||||
ioReadNewP((void *)998, .close = (IoReadInterfaceClose)testIoReadClose, .open = (IoReadInterfaceOpen)testIoReadOpen,
|
||||
.read = (IoReadInterfaceRead)testIoRead),
|
||||
read, ioReadNewP((void *)998, .close = testIoReadClose, .open = testIoReadOpen, .read = testIoRead),
|
||||
"create io read object");
|
||||
|
||||
TEST_RESULT_BOOL(ioReadOpen(read), false, " open io object");
|
||||
|
||||
TEST_ASSIGN(
|
||||
read,
|
||||
ioReadNewP((void *)999, .close = (IoReadInterfaceClose)testIoReadClose, .open = (IoReadInterfaceOpen)testIoReadOpen,
|
||||
.read = (IoReadInterfaceRead)testIoRead),
|
||||
read, ioReadNewP((void *)999, .close = testIoReadClose, .open = testIoReadOpen, .read = testIoRead),
|
||||
"create io read object");
|
||||
|
||||
TEST_RESULT_BOOL(ioReadOpen(read), true, " open io object");
|
||||
@ -266,81 +269,71 @@ testRun(void)
|
||||
|
||||
// Read a zero-length buffer to be sure it is not passed on to the filter group
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
IoBufferRead *bufferRead = NULL;
|
||||
IoRead *bufferRead = NULL;
|
||||
ioBufferSizeSet(2);
|
||||
buffer = bufNew(2);
|
||||
Buffer *bufferOriginal = bufNew(0);
|
||||
|
||||
TEST_ASSIGN(bufferRead, ioBufferReadNew(bufferOriginal), "create empty buffer read object");
|
||||
TEST_RESULT_BOOL(ioReadOpen(ioBufferReadIo(bufferRead)), true, " open");
|
||||
TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), false, " not eof");
|
||||
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 0, " read 0 bytes");
|
||||
TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), true, " now eof");
|
||||
TEST_RESULT_BOOL(ioReadOpen(bufferRead), true, " open");
|
||||
TEST_RESULT_BOOL(ioReadEof(bufferRead), false, " not eof");
|
||||
TEST_RESULT_SIZE(ioRead(bufferRead, buffer), 0, " read 0 bytes");
|
||||
TEST_RESULT_BOOL(ioReadEof(bufferRead), true, " now eof");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
ioBufferSizeSet(2);
|
||||
buffer = bufNew(2);
|
||||
bufferOriginal = bufNewC("123", 3);
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
TEST_ASSIGN(bufferRead, ioBufferReadNew(bufferOriginal), "create buffer read object");
|
||||
TEST_RESULT_VOID(ioBufferReadMove(bufferRead, MEM_CONTEXT_OLD()), " move object to new context");
|
||||
TEST_RESULT_VOID(ioBufferReadMove(NULL, MEM_CONTEXT_OLD()), " move NULL object to new context");
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
IoFilterGroup *filterGroup = NULL;
|
||||
TEST_ASSIGN(filterGroup, ioFilterGroupNew(), " create new filter group");
|
||||
IoSize *sizeFilter = ioSizeNew();
|
||||
TEST_RESULT_PTR(ioFilterGroupAdd(filterGroup, ioSizeFilter(sizeFilter)), filterGroup, " add filter to filter group");
|
||||
IoFilter *sizeFilter = ioSizeNew();
|
||||
TEST_RESULT_PTR(ioFilterGroupAdd(filterGroup, sizeFilter), filterGroup, " add filter to filter group");
|
||||
TEST_RESULT_VOID(
|
||||
ioFilterGroupAdd(filterGroup, ioTestFilterMultiplyNew("double", 2, 1, 'X')->filter), " add filter to filter group");
|
||||
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, ioSizeFilter(ioSizeNew())), " add filter to filter group");
|
||||
IoBuffer *bufferFilter = ioBufferNew();
|
||||
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, ioBufferFilter(bufferFilter)), " add filter to filter group");
|
||||
TEST_RESULT_VOID(ioReadFilterGroupSet(ioBufferReadIo(bufferRead), filterGroup), " add filter group to read io");
|
||||
ioFilterGroupAdd(filterGroup, ioTestFilterMultiplyNew("double", 2, 1, 'X')), " add filter to filter group");
|
||||
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, ioSizeNew()), " add filter to filter group");
|
||||
IoFilter *bufferFilter = ioBufferNew();
|
||||
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, bufferFilter), " add filter to filter group");
|
||||
TEST_RESULT_VOID(ioReadFilterGroupSet(bufferRead, filterGroup), " add filter group to read io");
|
||||
TEST_RESULT_PTR(ioFilterMove(NULL, memContextTop()), NULL, " move NULL filter to top context");
|
||||
|
||||
TEST_RESULT_BOOL(ioReadOpen(ioBufferReadIo(bufferRead)), true, " open");
|
||||
TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), false, " not eof");
|
||||
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 2, " read 2 bytes");
|
||||
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 0, " read 0 bytes (full buffer)");
|
||||
TEST_RESULT_BOOL(ioReadOpen(bufferRead), true, " open");
|
||||
TEST_RESULT_BOOL(ioReadEof(bufferRead), false, " not eof");
|
||||
TEST_RESULT_SIZE(ioRead(bufferRead, buffer), 2, " read 2 bytes");
|
||||
TEST_RESULT_SIZE(ioRead(bufferRead, buffer), 0, " read 0 bytes (full buffer)");
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "11", " check read");
|
||||
TEST_RESULT_STR(strPtr(ioFilterType(ioSizeFilter(sizeFilter))), "size", "check filter type");
|
||||
TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), false, " not eof");
|
||||
TEST_RESULT_STR(strPtr(ioFilterType(sizeFilter)), "size", "check filter type");
|
||||
TEST_RESULT_BOOL(ioReadEof(bufferRead), false, " not eof");
|
||||
|
||||
TEST_RESULT_VOID(bufUsedZero(buffer), " zero buffer");
|
||||
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 2, " read 2 bytes");
|
||||
TEST_RESULT_SIZE(ioRead(bufferRead, buffer), 2, " read 2 bytes");
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "22", " check read");
|
||||
|
||||
TEST_ASSIGN(buffer, bufNew(3), "change output buffer size to 3");
|
||||
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 3, " read 3 bytes");
|
||||
TEST_RESULT_SIZE(ioRead(bufferRead, buffer), 3, " read 3 bytes");
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "33X", " check read");
|
||||
|
||||
TEST_RESULT_VOID(bufUsedZero(buffer), " zero buffer");
|
||||
TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), true, " eof");
|
||||
TEST_RESULT_BOOL(ioBufferRead(bufferRead, buffer, true), 0, " eof from driver");
|
||||
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 0, " read 0 bytes");
|
||||
TEST_RESULT_VOID(ioReadClose(ioBufferReadIo(bufferRead)), " close buffer read object");
|
||||
TEST_RESULT_BOOL(ioReadEof(bufferRead), true, " eof");
|
||||
TEST_RESULT_BOOL(ioBufferRead(ioReadDriver(bufferRead), buffer, true), 0, " eof from driver");
|
||||
TEST_RESULT_SIZE(ioRead(bufferRead, buffer), 0, " read 0 bytes");
|
||||
TEST_RESULT_VOID(ioReadClose(bufferRead), " close buffer read object");
|
||||
|
||||
TEST_RESULT_PTR(ioReadFilterGroup(ioBufferReadIo(bufferRead)), filterGroup, " check filter group");
|
||||
TEST_RESULT_PTR(ioReadFilterGroup(bufferRead), filterGroup, " check filter group");
|
||||
TEST_RESULT_UINT(
|
||||
varUInt64(varLstGet(varVarLst(ioFilterGroupResult(filterGroup, ioFilterType(ioSizeFilter(sizeFilter)))), 0)), 3,
|
||||
varUInt64(varLstGet(varVarLst(ioFilterGroupResult(filterGroup, ioFilterType(sizeFilter))), 0)), 3,
|
||||
" check filter result");
|
||||
TEST_RESULT_PTR(ioFilterGroupResult(filterGroup, strNew("double")), NULL, " check filter result is NULL");
|
||||
TEST_RESULT_UINT(
|
||||
varUInt64(varLstGet(varVarLst(ioFilterGroupResult(filterGroup, ioFilterType(ioSizeFilter(sizeFilter)))), 1)), 7,
|
||||
varUInt64(varLstGet(varVarLst(ioFilterGroupResult(filterGroup, ioFilterType(sizeFilter))), 1)), 7,
|
||||
" check filter result");
|
||||
|
||||
TEST_RESULT_VOID(ioBufferReadFree(bufferRead), " free buffer read object");
|
||||
TEST_RESULT_VOID(ioBufferReadFree(NULL), " free NULL buffer read object");
|
||||
TEST_RESULT_PTR(ioFilterDriver(bufferFilter), bufferFilter->driver, " check filter driver");
|
||||
TEST_RESULT_PTR(ioFilterInterface(bufferFilter), &bufferFilter->interface, " check filter interface");
|
||||
|
||||
TEST_RESULT_VOID(ioSizeFree(sizeFilter), " free size filter object");
|
||||
TEST_RESULT_VOID(ioSizeFree(NULL), " free null size filter object");
|
||||
|
||||
TEST_RESULT_VOID(ioBufferFree(bufferFilter), " free buffer filter object");
|
||||
TEST_RESULT_VOID(ioBufferFree(NULL), " free null buffer filter object");
|
||||
TEST_RESULT_VOID(ioFilterFree(bufferFilter), " free buffer filter");
|
||||
TEST_RESULT_VOID(ioFilterFree(NULL), " free NULL filter");
|
||||
|
||||
TEST_RESULT_VOID(ioFilterGroupFree(filterGroup), " free filter group object");
|
||||
TEST_RESULT_VOID(ioFilterGroupFree(NULL), " free NULL filter group object");
|
||||
@ -348,7 +341,7 @@ testRun(void)
|
||||
// Mixed line and buffer read
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
ioBufferSizeSet(5);
|
||||
read = ioBufferReadIo(ioBufferReadNew(BUFSTRDEF("AAA123\n1234\n\n12\nBDDDEFF")));
|
||||
read = ioBufferReadNew(BUFSTRDEF("AAA123\n1234\n\n12\nBDDDEFF"));
|
||||
ioReadOpen(read);
|
||||
buffer = bufNew(3);
|
||||
|
||||
@ -391,7 +384,7 @@ testRun(void)
|
||||
|
||||
// Error if buffer is full and there is no linefeed
|
||||
ioBufferSizeSet(10);
|
||||
read = ioBufferReadIo(ioBufferReadNew(BUFSTRDEF("0123456789")));
|
||||
read = ioBufferReadNew(BUFSTRDEF("0123456789"));
|
||||
ioReadOpen(read);
|
||||
TEST_ERROR(ioReadLine(read), FileReadError, "unable to find line in 10 byte buffer");
|
||||
|
||||
@ -400,9 +393,9 @@ testRun(void)
|
||||
ioBufferSizeSet(8);
|
||||
|
||||
bufferRead = ioBufferReadNew(BUFSTRDEF("a test string"));
|
||||
ioReadOpen(ioBufferReadIo(bufferRead));
|
||||
ioReadOpen(bufferRead);
|
||||
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(ioReadBuf(ioBufferReadIo(bufferRead)))), "a test string", "read into buffer");
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(ioReadBuf(bufferRead))), "a test string", "read into buffer");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
@ -412,10 +405,7 @@ testRun(void)
|
||||
ioBufferSizeSet(3);
|
||||
|
||||
TEST_ASSIGN(
|
||||
write,
|
||||
ioWriteNewP(
|
||||
(void *)999, .close = (IoWriteInterfaceClose)testIoWriteClose, .open = (IoWriteInterfaceOpen)testIoWriteOpen,
|
||||
.write = (IoWriteInterfaceWrite)testIoWrite),
|
||||
write, ioWriteNewP((void *)999, .close = testIoWriteClose, .open = testIoWriteOpen, .write = testIoWrite),
|
||||
"create io write object");
|
||||
|
||||
TEST_RESULT_VOID(ioWriteOpen(write), " open io object");
|
||||
@ -429,50 +419,40 @@ testRun(void)
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
ioBufferSizeSet(3);
|
||||
IoBufferWrite *bufferWrite = NULL;
|
||||
IoWrite *bufferWrite = NULL;
|
||||
Buffer *buffer = bufNew(0);
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
TEST_ASSIGN(bufferWrite, ioBufferWriteNew(buffer), "create buffer write object");
|
||||
TEST_RESULT_VOID(ioBufferWriteMove(bufferWrite, MEM_CONTEXT_OLD()), " move object to new context");
|
||||
TEST_RESULT_VOID(ioBufferWriteMove(NULL, MEM_CONTEXT_OLD()), " move NULL object to new context");
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
IoFilterGroup *filterGroup = NULL;
|
||||
TEST_ASSIGN(filterGroup, ioFilterGroupNew(), " create new filter group");
|
||||
IoSize *sizeFilter = ioSizeNew();
|
||||
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, ioSizeFilter(sizeFilter)), " add filter to filter group");
|
||||
IoFilter *sizeFilter = ioSizeNew();
|
||||
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, sizeFilter), " add filter to filter group");
|
||||
TEST_RESULT_VOID(
|
||||
ioFilterGroupAdd(filterGroup, ioTestFilterMultiplyNew("double", 2, 3, 'X')->filter), " add filter to filter group");
|
||||
ioFilterGroupAdd(filterGroup, ioTestFilterMultiplyNew("double", 2, 3, 'X')), " add filter to filter group");
|
||||
TEST_RESULT_VOID(
|
||||
ioFilterGroupAdd(filterGroup, ioTestFilterMultiplyNew("single", 1, 1, 'Y')->filter),
|
||||
ioFilterGroupAdd(filterGroup, ioTestFilterMultiplyNew("single", 1, 1, 'Y')),
|
||||
" add filter to filter group");
|
||||
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, ioTestFilterSizeNew("size2")->filter), " add filter to filter group");
|
||||
TEST_RESULT_VOID(ioWriteFilterGroupSet(ioBufferWriteIo(bufferWrite), filterGroup), " add filter group to write io");
|
||||
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, ioTestFilterSizeNew("size2")), " add filter to filter group");
|
||||
TEST_RESULT_VOID(ioWriteFilterGroupSet(bufferWrite, filterGroup), " add filter group to write io");
|
||||
|
||||
TEST_RESULT_VOID(ioWriteOpen(ioBufferWriteIo(bufferWrite)), " open buffer write object");
|
||||
TEST_RESULT_VOID(ioWriteLine(ioBufferWriteIo(bufferWrite), BUFSTRDEF("AB")), " write line");
|
||||
TEST_RESULT_VOID(ioWrite(ioBufferWriteIo(bufferWrite), bufNew(0)), " write 0 bytes");
|
||||
TEST_RESULT_VOID(ioWrite(ioBufferWriteIo(bufferWrite), NULL), " write 0 bytes");
|
||||
TEST_RESULT_VOID(ioWriteOpen(bufferWrite), " open buffer write object");
|
||||
TEST_RESULT_VOID(ioWriteLine(bufferWrite, BUFSTRDEF("AB")), " write line");
|
||||
TEST_RESULT_VOID(ioWrite(bufferWrite, bufNew(0)), " write 0 bytes");
|
||||
TEST_RESULT_VOID(ioWrite(bufferWrite, NULL), " write 0 bytes");
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "AABB\n\n", " check write");
|
||||
|
||||
TEST_RESULT_VOID(ioWriteStr(ioBufferWriteIo(bufferWrite), STRDEF("Z")), " write string");
|
||||
TEST_RESULT_VOID(ioWriteStr(bufferWrite, STRDEF("Z")), " write string");
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "AABB\n\n", " no change because output buffer is not full");
|
||||
TEST_RESULT_VOID(ioWriteStr(ioBufferWriteIo(bufferWrite), STRDEF("12345")), " write bytes");
|
||||
TEST_RESULT_VOID(ioWriteStr(bufferWrite, STRDEF("12345")), " write bytes");
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "AABB\n\nZZ1122334455", " check write");
|
||||
|
||||
TEST_RESULT_VOID(ioWriteClose(ioBufferWriteIo(bufferWrite)), " close buffer write object");
|
||||
TEST_RESULT_VOID(ioWriteClose(bufferWrite), " close buffer write object");
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "AABB\n\nZZ1122334455XXXY", " check write after close");
|
||||
|
||||
TEST_RESULT_PTR(ioWriteFilterGroup(ioBufferWriteIo(bufferWrite)), filterGroup, " check filter group");
|
||||
TEST_RESULT_PTR(ioWriteFilterGroup(bufferWrite), filterGroup, " check filter group");
|
||||
TEST_RESULT_UINT(
|
||||
varUInt64(ioFilterGroupResult(filterGroup, ioFilterType(ioSizeFilter(sizeFilter)))), 9, " check filter result");
|
||||
varUInt64(ioFilterGroupResult(filterGroup, ioFilterType(sizeFilter))), 9, " check filter result");
|
||||
TEST_RESULT_UINT(varUInt64(ioFilterGroupResult(filterGroup, strNew("size2"))), 22, " check filter result");
|
||||
|
||||
TEST_RESULT_VOID(ioBufferWriteFree(bufferWrite), " free buffer write object");
|
||||
TEST_RESULT_VOID(ioBufferWriteFree(NULL), " free NULL buffer write object");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
@ -484,88 +464,65 @@ testRun(void)
|
||||
{
|
||||
HARNESS_FORK_CHILD_BEGIN(0, true)
|
||||
{
|
||||
IoHandleWrite *write = NULL;
|
||||
IoWrite *write = NULL;
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
TEST_RESULT_VOID(ioHandleWriteMove(NULL, MEM_CONTEXT_OLD()), "move null write");
|
||||
TEST_ASSIGN(
|
||||
write,
|
||||
ioHandleWriteMove(ioHandleWriteNew(strNew("write test"), HARNESS_FORK_CHILD_WRITE()), MEM_CONTEXT_OLD()),
|
||||
"move write");
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
ioWriteOpen(ioHandleWriteIo(write));
|
||||
TEST_RESULT_INT(ioWriteHandle(ioHandleWriteIo(write)), write->handle, "check write handle");
|
||||
TEST_ASSIGN(write, ioHandleWriteNew(strNew("write test"), HARNESS_FORK_CHILD_WRITE()), "move write");
|
||||
ioWriteOpen(write);
|
||||
TEST_RESULT_INT(
|
||||
ioWriteHandle(write), ((IoHandleWrite *)ioWriteDriver(write))->handle, "check write handle");
|
||||
TEST_RESULT_PTR(ioWriteDriver(write), write->driver, "check write driver");
|
||||
TEST_RESULT_PTR(ioWriteInterface(write), &write->interface, "check write interface");
|
||||
|
||||
// Write a line to be read
|
||||
TEST_RESULT_VOID(ioWriteStrLine(ioHandleWriteIo(write), strNew("test string 1")), "write test string");
|
||||
ioWriteFlush(ioHandleWriteIo(write));
|
||||
ioWriteFlush(ioHandleWriteIo(write));
|
||||
TEST_RESULT_VOID(ioWriteStrLine(write, strNew("test string 1")), "write test string");
|
||||
ioWriteFlush(write);
|
||||
ioWriteFlush(write);
|
||||
|
||||
// Sleep so the other side will timeout
|
||||
const Buffer *buffer = BUFSTRDEF("12345678");
|
||||
TEST_RESULT_VOID(ioWrite(ioHandleWriteIo(write), buffer), "write buffer");
|
||||
TEST_RESULT_VOID(ioWrite(write, buffer), "write buffer");
|
||||
sleepMSec(1250);
|
||||
|
||||
// Write a buffer in two parts and sleep in the middle so it will be read on the other side in two parts
|
||||
TEST_RESULT_VOID(ioWrite(ioHandleWriteIo(write), buffer), "write buffer");
|
||||
TEST_RESULT_VOID(ioWrite(write, buffer), "write buffer");
|
||||
sleepMSec(500);
|
||||
TEST_RESULT_VOID(ioWrite(ioHandleWriteIo(write), buffer), "write buffer");
|
||||
ioWriteFlush(ioHandleWriteIo(write));
|
||||
|
||||
// Free object
|
||||
TEST_RESULT_VOID(ioHandleWriteFree(NULL), "free null write");
|
||||
TEST_RESULT_VOID(ioHandleWriteFree(write), "free write");
|
||||
TEST_RESULT_VOID(ioWrite(write, buffer), "write buffer");
|
||||
ioWriteFlush(write);
|
||||
}
|
||||
HARNESS_FORK_CHILD_END();
|
||||
|
||||
HARNESS_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoHandleRead *read = NULL;
|
||||
IoRead *read = ioHandleReadNew(strNew("read test"), HARNESS_FORK_PARENT_READ_PROCESS(0), 1000);
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
TEST_RESULT_VOID(ioHandleReadMove(NULL, MEM_CONTEXT_OLD()), "move null read");
|
||||
TEST_ASSIGN(
|
||||
read,
|
||||
ioHandleReadMove(
|
||||
ioHandleReadNew(strNew("read test"), HARNESS_FORK_PARENT_READ_PROCESS(0), 1000), MEM_CONTEXT_OLD()),
|
||||
"move read");
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
ioReadOpen(ioHandleReadIo(read));
|
||||
TEST_RESULT_INT(ioReadHandle(ioHandleReadIo(read)), read->handle, "check handle");
|
||||
ioReadOpen(read);
|
||||
TEST_RESULT_INT(ioReadHandle(read), ((IoHandleRead *)ioReadDriver(read))->handle, "check handle");
|
||||
TEST_RESULT_PTR(ioReadInterface(read), &read->interface, "check interface");
|
||||
TEST_RESULT_PTR(ioReadDriver(read), read->driver, "check driver");
|
||||
|
||||
// Read a string
|
||||
TEST_RESULT_STR(strPtr(ioReadLine(ioHandleReadIo(read))), "test string 1", "read test string");
|
||||
TEST_RESULT_STR(strPtr(ioReadLine(read)), "test string 1", "read test string");
|
||||
|
||||
// Only part of the buffer is written before timeout
|
||||
Buffer *buffer = bufNew(16);
|
||||
|
||||
TEST_ERROR(ioRead(ioHandleReadIo(read), buffer), FileReadError, "unable to read data from read test after 1000ms");
|
||||
TEST_ERROR(ioRead(read, buffer), FileReadError, "unable to read data from read test after 1000ms");
|
||||
TEST_RESULT_UINT(bufSize(buffer), 16, "buffer is only partially read");
|
||||
|
||||
// Read a buffer that is transmitted in two parts with blocking on the read side
|
||||
buffer = bufNew(16);
|
||||
bufLimitSet(buffer, 12);
|
||||
|
||||
TEST_RESULT_UINT(ioRead(ioHandleReadIo(read), buffer), 12, "read buffer");
|
||||
TEST_RESULT_UINT(ioRead(read, buffer), 12, "read buffer");
|
||||
bufLimitClear(buffer);
|
||||
TEST_RESULT_UINT(ioRead(ioHandleReadIo(read), buffer), 4, "read buffer");
|
||||
TEST_RESULT_UINT(ioRead(read, buffer), 4, "read buffer");
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "1234567812345678", "check buffer");
|
||||
|
||||
// Check EOF
|
||||
buffer = bufNew(16);
|
||||
|
||||
TEST_RESULT_UINT(ioHandleRead(read, buffer, true), 0, "read buffer at eof");
|
||||
TEST_RESULT_UINT(ioHandleRead(read, buffer, true), 0, "read buffer at eof again");
|
||||
|
||||
// Free object
|
||||
TEST_RESULT_VOID(ioHandleReadFree(NULL), "free null read");
|
||||
TEST_RESULT_VOID(ioHandleReadFree(read), "free read");
|
||||
TEST_RESULT_UINT(ioHandleRead(ioReadDriver(read), buffer, true), 0, "read buffer at eof");
|
||||
TEST_RESULT_UINT(ioHandleRead(ioReadDriver(read), buffer, true), 0, "read buffer at eof again");
|
||||
}
|
||||
HARNESS_FORK_PARENT_END();
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ testRun(void)
|
||||
FUNCTION_HARNESS_VOID();
|
||||
|
||||
// Create default storage object for testing
|
||||
Storage *storageTest = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
|
||||
Storage *storageTest = storageDriverPosixNew(
|
||||
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("lockAcquireFile() and lockReleaseFile()"))
|
||||
|
@ -24,9 +24,9 @@ testRun(void)
|
||||
{
|
||||
HARNESS_FORK_CHILD_BEGIN(0, true)
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("client read"), HARNESS_FORK_CHILD_READ(), 2000));
|
||||
IoRead *read = ioHandleReadNew(strNew("client read"), HARNESS_FORK_CHILD_READ(), 2000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("client write"), HARNESS_FORK_CHILD_WRITE()));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("client write"), HARNESS_FORK_CHILD_WRITE());
|
||||
ioWriteOpen(write);
|
||||
|
||||
StringList *argList = strLstNew();
|
||||
@ -45,9 +45,9 @@ testRun(void)
|
||||
|
||||
HARNESS_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
|
||||
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
|
||||
ioWriteOpen(write);
|
||||
|
||||
ProtocolClient *client = protocolClientNew(strNew("test"), strNew("config"), read, write);
|
||||
|
@ -10,8 +10,8 @@ void
|
||||
testRun(void)
|
||||
{
|
||||
// Create default storage object for testing
|
||||
Storage *storageTest = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
|
||||
Storage *storageTest = storageDriverPosixNew(
|
||||
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("infoNewLoad(), infoFileName(), infoIni()"))
|
||||
@ -66,8 +66,7 @@ testRun(void)
|
||||
ioWriteFilterGroupSet(
|
||||
storageFileWriteIo(infoWrite),
|
||||
ioFilterGroupAdd(
|
||||
ioFilterGroupNew(),
|
||||
cipherBlockFilter(cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("12345678"), NULL))));
|
||||
ioFilterGroupNew(), cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("12345678"), NULL)));
|
||||
|
||||
storageRemoveNP(storageLocalWrite(), fileNameCopy);
|
||||
storagePutNP(
|
||||
|
@ -11,8 +11,8 @@ testRun(void)
|
||||
{
|
||||
FUNCTION_HARNESS_VOID();
|
||||
|
||||
Storage *storageTest = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
|
||||
Storage *storageTest = storageDriverPosixNew(
|
||||
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("pgVersionFromStr() and pgVersionToStr()"))
|
||||
|
@ -62,8 +62,8 @@ testRun(void)
|
||||
{
|
||||
FUNCTION_HARNESS_VOID();
|
||||
|
||||
Storage *storageTest = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
|
||||
Storage *storageTest = storageDriverPosixNew(
|
||||
strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL);
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("repoIsLocal()"))
|
||||
@ -224,9 +224,9 @@ testRun(void)
|
||||
{
|
||||
HARNESS_FORK_CHILD_BEGIN(0, true)
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_CHILD_READ(), 2000));
|
||||
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_CHILD_READ(), 2000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_CHILD_WRITE()));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_CHILD_WRITE());
|
||||
ioWriteOpen(write);
|
||||
|
||||
// Various bogus greetings
|
||||
@ -277,9 +277,9 @@ testRun(void)
|
||||
|
||||
HARNESS_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("client read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
|
||||
IoRead *read = ioHandleReadNew(strNew("client read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("client write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("client write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
|
||||
ioWriteOpen(write);
|
||||
|
||||
// Various bogus greetings
|
||||
@ -353,9 +353,9 @@ testRun(void)
|
||||
{
|
||||
HARNESS_FORK_CHILD_BEGIN(0, true)
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("client read"), HARNESS_FORK_CHILD_READ(), 2000));
|
||||
IoRead *read = ioHandleReadNew(strNew("client read"), HARNESS_FORK_CHILD_READ(), 2000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("client write"), HARNESS_FORK_CHILD_WRITE()));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("client write"), HARNESS_FORK_CHILD_WRITE());
|
||||
ioWriteOpen(write);
|
||||
|
||||
// Check greeting
|
||||
@ -405,9 +405,9 @@ testRun(void)
|
||||
|
||||
HARNESS_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000));
|
||||
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0)));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0));
|
||||
ioWriteOpen(write);
|
||||
|
||||
// Send greeting
|
||||
@ -470,9 +470,9 @@ testRun(void)
|
||||
// Local 1
|
||||
HARNESS_FORK_CHILD_BEGIN(0, true)
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_CHILD_READ(), 10000));
|
||||
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_CHILD_READ(), 10000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_CHILD_WRITE()));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_CHILD_WRITE());
|
||||
ioWriteOpen(write);
|
||||
|
||||
// Greeting with noop
|
||||
@ -496,9 +496,9 @@ testRun(void)
|
||||
// Local 2
|
||||
HARNESS_FORK_CHILD_BEGIN(0, true)
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(ioHandleReadNew(strNew("server read"), HARNESS_FORK_CHILD_READ(), 10000));
|
||||
IoRead *read = ioHandleReadNew(strNew("server read"), HARNESS_FORK_CHILD_READ(), 10000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(ioHandleWriteNew(strNew("server write"), HARNESS_FORK_CHILD_WRITE()));
|
||||
IoWrite *write = ioHandleWriteNew(strNew("server write"), HARNESS_FORK_CHILD_WRITE());
|
||||
ioWriteOpen(write);
|
||||
|
||||
// Greeting with noop
|
||||
@ -538,11 +538,11 @@ testRun(void)
|
||||
|
||||
for (unsigned int clientIdx = 0; clientIdx < clientTotal; clientIdx++)
|
||||
{
|
||||
IoRead *read = ioHandleReadIo(
|
||||
ioHandleReadNew(strNewFmt("client %u read", clientIdx), HARNESS_FORK_PARENT_READ_PROCESS(clientIdx), 2000));
|
||||
IoRead *read = ioHandleReadNew(
|
||||
strNewFmt("client %u read", clientIdx), HARNESS_FORK_PARENT_READ_PROCESS(clientIdx), 2000);
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioHandleWriteIo(
|
||||
ioHandleWriteNew(strNewFmt("client %u write", clientIdx), HARNESS_FORK_PARENT_WRITE_PROCESS(clientIdx)));
|
||||
IoWrite *write = ioHandleWriteNew(
|
||||
strNewFmt("client %u write", clientIdx), HARNESS_FORK_PARENT_WRITE_PROCESS(clientIdx));
|
||||
ioWriteOpen(write);
|
||||
|
||||
TEST_ASSIGN(
|
||||
@ -557,9 +557,9 @@ testRun(void)
|
||||
"{\"name\":\"pgBackRest\",\"service\":\"error\",\"version\":\"" PROJECT_VERSION "\"}\n"
|
||||
"{}\n");
|
||||
|
||||
IoRead *read = ioBufferReadIo(ioBufferReadNew(BUFSTR(protocolString)));
|
||||
IoRead *read = ioBufferReadNew(BUFSTR(protocolString));
|
||||
ioReadOpen(read);
|
||||
IoWrite *write = ioBufferWriteIo(ioBufferWriteNew(bufNew(1024)));
|
||||
IoWrite *write = ioBufferWriteNew(bufNew(1024));
|
||||
ioWriteOpen(write);
|
||||
|
||||
ProtocolClient *clientError = protocolClientNew(strNew("error"), strNew("error"), read, write);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user