Share durable encrypted file publication with direct messages

This commit is contained in:
evgeny committed 2026-10-18 10:39:03 +02:00
1 parent 4844253f12
commit 3c395dfe5d
3 files changed
+45 -41

No files matched your search

+5 -41
View File
@@ -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);
}
}
+37
View File
@@ -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)
+3
View File
@@ -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