bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen#include "lib.h"
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen#include "fs-sis-common.h"
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen#include <sys/stat.h>
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainenint fs_sis_path_parse(struct fs *fs, const char *path,
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen const char **dir_r, const char **hash_r)
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen{
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen const char *fname, *p;
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen fname = strrchr(path, '/');
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen if (fname == NULL) {
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen *dir_r = ".";
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen fname = path;
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen } else {
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen *dir_r = t_strdup_until(path, fname);
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen fname++;
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen }
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen /* assume filename begins with "<hash>-" */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen p = strchr(fname, '-');
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen if (p == NULL) {
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen fs_set_error(fs, "open(%s) failed: "
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen "Filenames must begin with '<hash>-'", path);
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen return -1;
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen }
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen *hash_r = t_strdup_until(fname, p);
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen return 0;
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen}
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainenvoid fs_sis_try_unlink_hash_file(struct fs *sis_fs, struct fs_file *super_file)
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen{
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen struct fs_file *hash_file;
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen struct stat st1, st2;
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen const char *dir, *hash, *hash_path;
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen if (fs_sis_path_parse(sis_fs, super_file->path, &dir, &hash) == 0 &&
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen fs_stat(super_file, &st1) == 0 && st1.st_nlink == 2) {
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen /* this may be the last link. if hashes/ file is the same,
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen delete it. */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen hash_path = t_strdup_printf("%s/"HASH_DIR_NAME"/%s", dir, hash);
fc59aba4be5d2f57908e84f0f7477c467a72d567Timo Sirainen hash_file = fs_file_init_with_event(super_file->fs,
fc59aba4be5d2f57908e84f0f7477c467a72d567Timo Sirainen super_file->event, hash_path,
fc59aba4be5d2f57908e84f0f7477c467a72d567Timo Sirainen FS_OPEN_MODE_READONLY);
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen if (fs_stat(hash_file, &st2) == 0 &&
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen st1.st_ino == st2.st_ino &&
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen CMP_DEV_T(st1.st_dev, st2.st_dev)) {
b254b8ec1ea03f400f1390ec24afd826a8c335d9Timo Sirainen if (fs_delete(hash_file) < 0) {
b254b8ec1ea03f400f1390ec24afd826a8c335d9Timo Sirainen e_error(hash_file->event, "%s",
b254b8ec1ea03f400f1390ec24afd826a8c335d9Timo Sirainen fs_last_error(hash_file->fs));
b254b8ec1ea03f400f1390ec24afd826a8c335d9Timo Sirainen }
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen }
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen fs_file_deinit(&hash_file);
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen }
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen}
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen