/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "buffer.h"
#include "str.h"
#include "guid.h"
#include "istream.h"
#include "ostream.h"
#include "safe-mkstemp.h"
#include "mkdir-parents.h"
#include "write-full.h"
#include "file-lock.h"
#include "file-dotlock.h"
#include "fs-api-private.h"
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
enum fs_posix_lock_method {
};
struct posix_fs {
bool mode_auto;
bool have_dirs;
bool disable_fsync;
};
struct posix_fs_file {
int fd;
bool seek_to_beginning;
};
struct posix_fs_lock {
};
struct posix_fs_iter {
char *path;
int err;
};
{
}
static int
{
const char *const *tmp;
unsigned int mode;
return -1;
}
return -1;
}
} else {
return -1;
}
}
return 0;
}
{
}
{
/* FS_PROPERTY_DIRECTORIES is not returned normally because fs_delete()
automatically rmdir()s parents. For backwards compatibility
(especially with SIS code) we'll do it that way, but optionally with
"dirs" parameter enable them. This is especially important to be
able to use doveadm fs commands to delete empty directories. */
return props;
}
static int
{
const char *p;
return -1;
}
if (p != NULL)
path = ".";
else
return 0;
}
/* setgid set - copy mode from parent */
}
return 0;
}
{
return 1;
return -1;
return 0;
return 1;
else {
return -1;
}
}
{
const char *p;
return 0;
return 0;
break;
/* success, continue to parent */
/* there are other entries in this directory */
break;
/* some other not-unexpected error */
break;
} else {
return -1;
}
}
return 0;
}
{
const char *slash;
unsigned int try_count = 0;
int fd;
return -1;
} else {
return -1;
}
return -1;
try_count++;
}
if (fd == -1) {
return -1;
}
return fd;
}
{
case FS_OPEN_MODE_READONLY:
break;
case FS_OPEN_MODE_APPEND:
break;
case FS_OPEN_MODE_CREATE:
case FS_OPEN_MODE_REPLACE:
T_BEGIN {
} T_END;
break;
}
return -1;
return 0;
}
{
}
static void
{
if (mode != FS_OPEN_MODE_CREATE_UNIQUE_128)
else {
}
}
{
}
}
}
{
case FS_OPEN_MODE_READONLY:
case FS_OPEN_MODE_APPEND:
break;
case FS_OPEN_MODE_CREATE:
case FS_OPEN_MODE_REPLACE:
break;
}
break;
}
}
{
if (fs_posix_open(file) < 0)
return -1;
}
return 0;
}
{
if (fs_posix_open_for_read(file) < 0)
return TRUE;
/* HAVE_POSIX_FADVISE alone isn't enough for CentOS 4.9 */
#if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
return TRUE;
}
#endif
return FALSE;
}
{
if (fs_posix_open_for_read(file) < 0)
return -1;
if (file->seek_to_beginning) {
return -1;
}
}
if (ret < 0)
return ret;
}
static struct istream *
{
if (fs_posix_open_for_read(file) < 0)
else {
/* the stream could live even after the fs_file */
}
return input;
}
{
return;
if (p == NULL)
new_prefix = "";
else
}
{
!fs->disable_fsync) {
return -1;
}
}
case FS_OPEN_MODE_CREATE:
}
}
if (ret < 0) {
return -1;
}
break;
case FS_OPEN_MODE_REPLACE:
return -1;
}
break;
default:
i_unreached();
}
/* allow opening the file after writing to it */
return 0;
}
{
if (fs_posix_open(file) < 0)
return -1;
}
return -1;
}
return fs_posix_write_finish(file);
}
/* atomic append - it should either succeed or fail */
if (ret < 0) {
return -1;
}
return -1;
}
return 0;
}
{
} else {
}
}
{
case FS_OPEN_MODE_APPEND:
if (ret == 0) {
}
break;
case FS_OPEN_MODE_CREATE:
case FS_OPEN_MODE_REPLACE:
if (ret == 0)
break;
case FS_OPEN_MODE_READONLY:
i_unreached();
}
}
static int
{
switch (fs->lock_method) {
#ifndef HAVE_FLOCK
#else
if (secs == 0) {
} else {
}
if (ret < 0) {
}
#endif
break;
secs == 0 ? 0 :
if (ret < 0) {
"file_dotlock_create(%s) failed: %m",
}
break;
}
if (ret <= 0)
return ret;
return 1;
}
{
}
{
return -1;
}
return 0;
}
return 1;
}
{
/* in case output != NULL it means that we're still writing to the file
and fs_stat() shouldn't stat the unfinished file. this is done by
fs-sis after fs_copy(). */
return -1;
}
} else {
return -1;
}
}
return 0;
}
{
unsigned int try_count = 0;
int ret;
/* destination file already exists - replace it */
}
return -1;
try_count++;
}
if (ret < 0) {
return -1;
}
return 0;
}
{
unsigned int try_count = 0;
int ret;
return -1;
try_count++;
}
if (ret < 0) {
return -1;
}
return 0;
}
{
if (!UNLINK_EISDIR(errno)) {
return -1;
}
/* attempting to delete a directory. convert it to rmdir()
automatically. */
return -1;
}
}
return 0;
}
{
}
static void
{
}
}
}
{
bool ret;
T_BEGIN {
else
} T_END;
return ret;
}
{
struct dirent *d;
return NULL;
errno = 0;
continue;
fs->temp_file_prefix_len) == 0)
continue;
#ifdef HAVE_DIRENT_D_TYPE
switch (d->d_type) {
case DT_UNKNOWN:
return d->d_name;
break;
case DT_REG:
case DT_LNK:
return d->d_name;
break;
case DT_DIR:
return d->d_name;
break;
default:
break;
}
#else
return d->d_name;
#endif
}
if (errno != 0) {
}
return NULL;
}
{
int ret = 0;
}
ret = -1;
}
return ret;
}
.name = "posix",
.v = {
NULL,
NULL,
NULL,
NULL,
}
};