Skip to content
Permalink
Browse files

Allow StorageFileWrite to set user, group, and modification time.

The S3 driver will throw an error if these options are set since they are not supported.
  • Loading branch information...
dwsteele committed Apr 29, 2019
1 parent d0c296b commit af33126cb68915db9644ca941fc2490d09107b0c
@@ -47,6 +47,10 @@
<p>Allow <code>storageInfo()</code> to follow links.</p>
</release-item>

<release-item>
<p>Allow <code>StorageFileWrite</code> to set user, group, and modification time.</p>
</release-item>

<release-item>
<p>Add <code>ioWriteStr()</code> and <code>ioWriteStrLine()</code>.</p>
</release-item>
@@ -74,14 +74,17 @@ New file write object
***********************************************************************************************************************************/
StorageFileWrite *
storageDriverCifsNewWrite(
StorageDriverCifs *this, const String *file, mode_t modeFile, mode_t modePath, bool createPath, bool syncFile, bool syncPath,
bool atomic)
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);
@@ -95,7 +98,8 @@ storageDriverCifsNewWrite(
STORAGE_FILE_WRITE,
storageDriverPosixFileWriteInterface(
storageDriverPosixFileWriteNew(
(StorageDriverPosix *)this, file, modeFile, modePath, createPath, syncFile, false, atomic)));
(StorageDriverPosix *)this, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, false,
atomic)));
}

/***********************************************************************************************************************************
@@ -34,8 +34,8 @@ StorageDriverCifs *storageDriverCifsNew(
Functions
***********************************************************************************************************************************/
StorageFileWrite *storageDriverCifsNewWrite(
StorageDriverCifs *this, const String *file, mode_t modeFile, mode_t modePath, bool createPath, bool syncFile, bool syncPath,
bool atomic);
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);

/***********************************************************************************************************************************
@@ -4,8 +4,11 @@ Posix Storage File Write Driver
#include "build.auto.h"

#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <unistd.h>
#include <utime.h>

#include "common/debug.h"
#include "common/io/write.intern.h"
@@ -24,12 +27,16 @@ struct StorageDriverPosixFileWrite
StorageDriverPosix *storage;
StorageFileWrite *interface;
IoWrite *io;
String *nameTmp;

String *path;
String *name;
String *nameTmp;
mode_t modeFile;
mode_t modePath;
const String *user;
const String *group;
time_t timeModified;

bool createPath;
bool syncFile;
bool syncPath;
@@ -51,14 +58,17 @@ Create a new file
***********************************************************************************************************************************/
StorageDriverPosixFileWrite *
storageDriverPosixFileWriteNew(
StorageDriverPosix *storage, const String *name, mode_t modeFile, mode_t modePath, bool createPath, bool syncFile,
bool syncPath, bool atomic)
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)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, 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);
@@ -100,6 +110,9 @@ storageDriverPosixFileWriteNew(
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;
@@ -143,6 +156,33 @@ storageDriverPosixFileWriteOpen(StorageDriverPosixFileWrite *this)
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();
}

@@ -190,6 +230,15 @@ storageDriverPosixFileWriteClose(StorageDriverPosixFileWrite *this)
// 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)
{
@@ -19,8 +19,8 @@ typedef struct StorageDriverPosixFileWrite StorageDriverPosixFileWrite;
Constructor
***********************************************************************************************************************************/
StorageDriverPosixFileWrite *storageDriverPosixFileWriteNew(
StorageDriverPosix *storage, const String *name, mode_t modeFile, mode_t modePath, bool createPath, bool syncFile,
bool syncPath, bool atomic);
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
@@ -451,14 +451,17 @@ New file write object
***********************************************************************************************************************************/
StorageFileWrite *
storageDriverPosixNewWrite(
StorageDriverPosix *this, const String *file, mode_t modeFile, mode_t modePath, bool createPath, bool syncFile, bool syncPath,
bool atomic)
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)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_POSIX, 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);
@@ -471,7 +474,8 @@ storageDriverPosixNewWrite(
FUNCTION_LOG_RETURN(
STORAGE_FILE_WRITE,
storageDriverPosixFileWriteInterface(
storageDriverPosixFileWriteNew(this, file, modeFile, modePath, createPath, syncFile, syncPath, atomic)));
storageDriverPosixFileWriteNew(
this, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, syncPath, atomic)));
}

/***********************************************************************************************************************************
@@ -41,8 +41,8 @@ StringList *storageDriverPosixList(StorageDriverPosix *this, const String *path,
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, bool createPath, bool syncFile, bool syncPath,
bool atomic);
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);
@@ -25,6 +25,10 @@ struct StorageDriverRemoteFileWrite
String *name;
mode_t modeFile;
mode_t modePath;
const String *user;
const String *group;
time_t timeModified;

bool createPath;
bool syncFile;
bool syncPath;
@@ -36,14 +40,17 @@ Create a new file
***********************************************************************************************************************************/
StorageDriverRemoteFileWrite *
storageDriverRemoteFileWriteNew(
StorageDriverRemote *storage, ProtocolClient *client, const String *name, mode_t modeFile, mode_t modePath, bool createPath,
bool syncFile, bool syncPath, bool atomic)
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);
@@ -83,6 +90,9 @@ storageDriverRemoteFileWriteNew(
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;
@@ -111,6 +121,9 @@ storageDriverRemoteFileWriteOpen(StorageDriverRemoteFileWrite *this)
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));
@@ -20,8 +20,8 @@ typedef struct StorageDriverRemoteFileWrite StorageDriverRemoteFileWrite;
Constructor
***********************************************************************************************************************************/
StorageDriverRemoteFileWrite *storageDriverRemoteFileWriteNew(
StorageDriverRemote *storage, ProtocolClient *client, const String *name, mode_t modeFile, mode_t modePath, bool createPath,
bool syncFile, bool syncPath, bool atomic);
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
@@ -115,9 +115,10 @@ storageDriverRemoteProtocol(const String *command, const VariantList *paramList,
// Create the write object
IoWrite *fileWrite = storageFileWriteIo(
interface.newWrite(
driver, storagePathNP(storage, varStr(varLstGet(paramList, 0))), (mode_t)varUIntForce(varLstGet(paramList, 1)),
(mode_t)varUIntForce(varLstGet(paramList, 2)), varBool(varLstGet(paramList, 3)),
varBool(varLstGet(paramList, 4)), varBool(varLstGet(paramList, 5)), varBool(varLstGet(paramList, 6))));
driver, storagePathNP(storage, varStr(varLstGet(paramList, 0))), varUIntForce(varLstGet(paramList, 1)),
varUIntForce(varLstGet(paramList, 2)), varStr(varLstGet(paramList, 3)), varStr(varLstGet(paramList, 4)),
(time_t)varIntForce(varLstGet(paramList, 5)), varBool(varLstGet(paramList, 6)),
varBool(varLstGet(paramList, 7)), varBool(varLstGet(paramList, 8)), varBool(varLstGet(paramList, 9))));

// Open file
ioWriteOpen(fileWrite);
@@ -177,14 +177,17 @@ New file write object
***********************************************************************************************************************************/
StorageFileWrite *
storageDriverRemoteNewWrite(
StorageDriverRemote *this, const String *file, mode_t modeFile, mode_t modePath, bool createPath, bool syncFile,
bool syncPath, bool atomic)
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)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_REMOTE, 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);
@@ -197,7 +200,8 @@ storageDriverRemoteNewWrite(
FUNCTION_LOG_RETURN(
STORAGE_FILE_WRITE,
storageDriverRemoteFileWriteInterface(
storageDriverRemoteFileWriteNew(this, this->client, file, modeFile, modePath, createPath, syncFile, syncPath, atomic)));
storageDriverRemoteFileWriteNew(
this, this->client, file, modeFile, modePath, user, group, timeModified, createPath, syncFile, syncPath, atomic)));
}

/***********************************************************************************************************************************
@@ -33,8 +33,8 @@ StorageInfo storageDriverRemoteInfo(StorageDriverRemote *this, const String *fil
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, bool createPath, bool syncFile, bool syncPath,
bool atomic);
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);
@@ -629,14 +629,17 @@ New file write object
***********************************************************************************************************************************/
StorageFileWrite *
storageDriverS3NewWrite(
StorageDriverS3 *this, const String *file, mode_t modeFile, mode_t modePath, bool createPath, bool syncFile,
bool syncPath, bool atomic)
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)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE_DRIVER_S3, 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);
@@ -646,6 +649,9 @@ storageDriverS3NewWrite(
ASSERT(this != NULL);
ASSERT(file != NULL);
ASSERT(createPath);
ASSERT(user == NULL);
ASSERT(group == NULL);
ASSERT(timeModified == 0);

FUNCTION_LOG_RETURN(
STORAGE_FILE_WRITE, storageDriverS3FileWriteInterface(storageDriverS3FileWriteNew(this, file, this->partSize)));
@@ -42,8 +42,8 @@ StorageInfo storageDriverS3Info(StorageDriverS3 *this, const String *file, bool
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, bool createPath, bool syncFile, bool syncPath,
bool atomic);
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);
Oops, something went wrong.

0 comments on commit af33126

Please sign in to comment.
You can’t perform that action at this time.