Share durable encrypted file publication with direct messages
This commit is contained in:
1 parent
4844253f12
commit
3c395dfe5d
3 files changed
+45
-41
No files matched your search
+5
-41
@@ -112,42 +112,6 @@ fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Сделать создание/удаление имён durable на POSIX. */
|
||||
static int dm_dir_sync(const char* path) {
|
||||
#ifndef _WIN32
|
||||
char parent[1024];
|
||||
snprintf(parent, sizeof(parent), "%s", path);
|
||||
char* slash = strrchr(parent, '/');
|
||||
if (!slash) { DEBUG_ERROR(DEBUG_CATEGORY_DM, "dm_media: path without parent: %s", path); return -1; }
|
||||
*slash = '\0';
|
||||
int fd = open(parent, O_RDONLY | O_DIRECTORY);
|
||||
if (fd < 0) { DEBUG_ERROR(DEBUG_CATEGORY_DM, "dm_media: directory open failed: %s: %s", parent, strerror(errno)); return -1; }
|
||||
int rc = fsync(fd);
|
||||
if (rc) DEBUG_ERROR(DEBUG_CATEGORY_DM, "dm_media: directory sync failed: %s: %s", parent, strerror(errno));
|
||||
close(fd);
|
||||
return rc ? -1 : 0;
|
||||
#else
|
||||
(void)path;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Windows MoveFileEx обеспечивает замену и write-through существующего артефакта. */
|
||||
static int dm_file_publish(const char* temp, const char* path) {
|
||||
#ifdef _WIN32
|
||||
if (!MoveFileExA(temp, path, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_DM, "dm_media: publish failed %s -> %s winerr=%lu", temp, path, GetLastError());
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (rename(temp, path) != 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_DM, "dm_media: publish failed %s -> %s: %s", temp, path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return dm_dir_sync(path);
|
||||
}
|
||||
|
||||
static int dm_file_remove(const char* path) {
|
||||
if (remove(path) != 0 && errno != ENOENT) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_DM, "dm_media: remove failed path=%s: %s", path, strerror(errno));
|
||||
@@ -189,7 +153,7 @@ static void dm_cleanup_pump(struct dm_media_state* media);
|
||||
static void dm_cleanup_work(void* arg) {
|
||||
struct dm_cleanup_job* job = arg;
|
||||
job->error = dm_file_remove(job->path);
|
||||
if (!job->error) job->error = dm_dir_sync(job->path);
|
||||
if (!job->error) job->error = encrypted_file_sync_directory(job->path);
|
||||
}
|
||||
|
||||
static void dm_cleanup_done(void* arg, int error) {
|
||||
@@ -523,7 +487,7 @@ static void dm_file_work(void* arg) {
|
||||
struct dm_file_job* job = arg;
|
||||
job->error = -1;
|
||||
if (job->work == DM_FILE_DELETE) {
|
||||
if (!dm_file_remove(job->cipher) && !dm_file_remove(job->temp)) job->error = dm_dir_sync(job->cipher);
|
||||
if (!dm_file_remove(job->cipher) && !dm_file_remove(job->temp)) job->error = encrypted_file_sync_directory(job->cipher);
|
||||
return;
|
||||
}
|
||||
if (job->work == DM_FILE_PREPARE) {
|
||||
@@ -565,9 +529,9 @@ done:
|
||||
if (out && fclose(out)) { DEBUG_ERROR(DEBUG_CATEGORY_DM, "dm_media: worker output close failed"); job->error = -1; }
|
||||
if (!job->error) {
|
||||
if (job->work == DM_FILE_PREPARE) {
|
||||
job->error = dm_file_publish(job->temp, job->cipher);
|
||||
if (!job->error) job->error = dm_dir_sync(job->plain);
|
||||
} else job->error = dm_file_publish(job->work == DM_FILE_CUSTODY ? job->cipher : job->temp, job->output);
|
||||
job->error = encrypted_file_publish(job->temp, job->cipher);
|
||||
if (!job->error) job->error = encrypted_file_sync_directory(job->plain);
|
||||
} else job->error = encrypted_file_publish(job->work == DM_FILE_CUSTODY ? job->cipher : job->temp, job->output);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,47 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
/* Сделать создание/удаление имён durable на POSIX. */
|
||||
int encrypted_file_sync_directory(const char* path) {
|
||||
#ifndef _WIN32
|
||||
char parent[1024];
|
||||
snprintf(parent, sizeof(parent), "%s", path);
|
||||
char* slash = strrchr(parent, '/');
|
||||
if (!slash) { DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "encrypted file: path without parent: %s", path); return -1; }
|
||||
*slash = '\0';
|
||||
int fd = open(parent, O_RDONLY | O_DIRECTORY);
|
||||
if (fd < 0) { DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "encrypted file: directory open failed: %s: %s", parent, strerror(errno)); return -1; }
|
||||
int rc = fsync(fd);
|
||||
if (rc) DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "encrypted file: directory sync failed: %s: %s", parent, strerror(errno));
|
||||
close(fd);
|
||||
return rc ? -1 : 0;
|
||||
#else
|
||||
(void)path;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Windows MoveFileEx обеспечивает замену и write-through существующего артефакта. */
|
||||
int encrypted_file_publish(const char* temp, const char* path) {
|
||||
#ifdef _WIN32
|
||||
if (!MoveFileExA(temp, path, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "encrypted file: publish failed %s -> %s winerr=%lu", temp, path, GetLastError());
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (rename(temp, path) != 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "encrypted file: publish failed %s -> %s: %s", temp, path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return encrypted_file_sync_directory(path);
|
||||
}
|
||||
|
||||
#define EF_HEADER 66
|
||||
#define EF_META (32 + ATTACHMENT_WIRE_MAX)
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@ int encrypted_file_read(const char* source, const char* destination, const uint8
|
||||
const uint8_t id[16], const uint8_t hash[32], struct attachment_info* info, char type[32]);
|
||||
/* Flush/fsync и close проверяет владелец; этот примитив сохраняет уже закрытый файл. */
|
||||
int encrypted_file_sync(const char* path);
|
||||
/* Durable rename (write-through на Windows) и сохранение каталога на POSIX. */
|
||||
int encrypted_file_publish(const char* temporary, const char* path);
|
||||
int encrypted_file_sync_directory(const char* path);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in new issue
Block a user