/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "eacces-error.h"
#include "fdatasync-path.h"
#include "mkdir-parents.h"
#include "istream.h"
#include "ostream.h"
#include "str.h"
#include "fs-api.h"
#include "dbox-attachment.h"
#include "sdbox-storage.h"
#include "sdbox-file.h"
#include <stdio.h>
#include <utime.h>
{
const char *alt_path;
&alt_path) > 0)
}
{
const char *fname;
T_BEGIN {
if (uid != 0) {
} else {
}
} T_END;
}
{
return file;
}
{
}
{
const char *line;
bool deleted;
int ret;
/* read the metadata */
if (ret > 0) {
if (deleted)
return 0;
}
if (ret <= 0) {
if (ret < 0)
return -1;
/* corrupted file. we're deleting it anyway. */
} else {
}
/* no attachments */
return 0;
}
return 1;
}
const char *
{
const char *p;
if (p == NULL) {
"sdbox attachment path in invalid format: %s", srcpath);
} else {
}
return t_strdup_printf("%s-%s-%u",
}
{
int ret = 0;
ret = -1;
}
} T_END;
return ret;
}
bool ignore_if_exists)
{
"sdbox: %s already exists, rebuilding index", new_path);
return -1;
}
"rename(%s, %s) failed: %m",
return -1;
}
if (sdbox_file_rename_attachments(file) < 0)
return -1;
}
return 0;
}
{
int ret = 0;
/* we don't know if we aborted before renaming this attachment,
so try deleting both source and dest path. the source paths
point to temporary files (not to source messages'
attachment paths), so it's safe to delete them. */
*pathp);
fs_last_error(fs));
ret = -1;
}
fs_last_error(fs));
ret = -1;
}
} T_END;
return ret;
}
{
int ret = 0;
ret = -1;
}
ret = -1;
}
return ret;
}
{
const char *p, *dir;
int fd;
perm->file_create_gid_origin) < 0 &&
"mkdir_parents(%s) failed: %m", dir);
return -1;
}
/* try again */
}
if (fd == -1) {
/* no group change */
} else {
"fchown(%s, -1, %ld) failed: %m",
}
/* continue anyway */
}
return fd;
}
{
bool deleted;
return 0;
return 0;
return 0;
}
/* first copy the file. make sure to catch every possible error
since we really don't want to break the file. */
if (out_fd == -1)
return -1;
if (o_stream_finish(output) < 0) {
ret = -1;
}
"fsync(%s) failed: %m", temp_path);
ret = -1;
}
}
"close(%s) failed: %m", temp_path);
ret = -1;
}
if (ret < 0) {
return -1;
}
but could be useful for external reasons. */
"utime(%s) failed: %m", temp_path);
}
/* the temp file was successfully written. rename it now to the
destination file. the destination shouldn't exist, but if it does
its contents should be the same (except for maybe older metadata) */
return -1;
}
if (fdatasync_path(dest_dir) < 0) {
"fdatasync(%s) failed: %m", dest_dir);
return -1;
}
}
/* configuration problem? revert the write */
}
/* who knows what happened to the file. keep both just to be
sure both won't get deleted. */
return -1;
}
/* file was successfully moved - reopen it */
"dbox_file_move(%s): reopening file failed", dest_path);
return -1;
}
return 0;
}
static int
{
const char *path;
int ret = 0;
ret = -1;
} T_END;
return ret;
}
{
const char *extrefs_line;
int ret;
if (ret < 0)
return -1;
if (ret == 0) {
/* no attachments */
}
i_warning("%s: Ignoring corrupted extref: %s",
}
/* try to delete the file first, so if it fails we don't have
missing attachments */
pool_unref(&pool);
return ret;
}