doveadm-fs.c revision 4d981bcd01bd1dd5248095b0e59957949332657e
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2013-2014 Dovecot authors, see the included COPYING file */
2b8ff102f5117f917248f98ccbdc8e6a6af83c87Aki Tuomistatic struct fs *
2b8ff102f5117f917248f98ccbdc8e6a6af83c87Aki Tuomicmd_fs_init(int *argc, char **argv[], int own_arg_count, doveadm_command_t *cmd)
2b8ff102f5117f917248f98ccbdc8e6a6af83c87Aki Tuomi const char *error;
2b8ff102f5117f917248f98ccbdc8e6a6af83c87Aki Tuomi ssl_set.ca_dir = doveadm_settings->ssl_client_ca_dir;
2b8ff102f5117f917248f98ccbdc8e6a6af83c87Aki Tuomi ssl_set.ca_file = doveadm_settings->ssl_client_ca_file;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (fs_init((*argv)[1], (*argv)[2], &fs_set, &fs, &error) < 0)
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen const unsigned char *data;
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen fs = cmd_fs_init(&argc, &argv, 1, cmd_fs_get);
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen file = fs_file_init(fs, argv[0], FS_OPEN_MODE_READONLY);
e376693bfa3985232c41df99c7010fca22612c89Timo Sirainen while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) {
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainen i_error("%s doesn't exist", fs_file_path(file));
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen i_error("read(%s) failed: %m", fs_file_path(file));
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen hash = buffer_create_dynamic(pool_datastack_create(), 32);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen i_fatal("Invalid -h parameter: Hash not in hex");
7212243efb0d8fa1cd8b2e37b7498323540b9e97Timo Sirainen fs = cmd_fs_init(&argc, &argv, 2, cmd_fs_put);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen file = fs_file_init(fs, dest_path, FS_OPEN_MODE_REPLACE);
7212243efb0d8fa1cd8b2e37b7498323540b9e97Timo Sirainen else if (hash->used == hash_method_md5.digest_size) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if ((props & FS_PROPERTY_WRITE_HASH_MD5) == 0)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen i_fatal("fs backend doesn't support MD5 hashes");
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen hash_method_lookup(hash_method_md5.name), hash->data);
7212243efb0d8fa1cd8b2e37b7498323540b9e97Timo Sirainen } else if (hash->used == hash_method_sha256.digest_size) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if ((props & FS_PROPERTY_WRITE_HASH_SHA256) == 0)
7212243efb0d8fa1cd8b2e37b7498323540b9e97Timo Sirainen i_fatal("fs backend doesn't support SHA256 hashes");
515f81466f673c1b4f72e053f1a9686e6fca6b61Timo Sirainen hash_method_lookup(hash_method_sha256.name), hash->data);
515f81466f673c1b4f72e053f1a9686e6fca6b61Timo Sirainen input = i_stream_create_file(src_path, IO_BLOCK_SIZE);
515f81466f673c1b4f72e053f1a9686e6fca6b61Timo Sirainen if ((ret = o_stream_send_istream(output, input)) < 0) {
515f81466f673c1b4f72e053f1a9686e6fca6b61Timo Sirainen if (fs_write_stream_finish(file, &output) < 0) {
515f81466f673c1b4f72e053f1a9686e6fca6b61Timo Sirainen i_error("fs_write_stream_finish() failed: %s",
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic void cmd_fs_copy(int argc, char *argv[])
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen fs = cmd_fs_init(&argc, &argv, 2, cmd_fs_copy);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen src_file = fs_file_init(fs, src_path, FS_OPEN_MODE_READONLY);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen dest_file = fs_file_init(fs, dest_path, FS_OPEN_MODE_REPLACE);
e6f0cbdb1eb604f21a65cd45072febe678187054Timo Sirainenstatic void cmd_fs_stat(int argc, char *argv[])
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen fs = cmd_fs_init(&argc, &argv, 1, cmd_fs_stat);
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen file = fs_file_init(fs, argv[0], FS_OPEN_MODE_READONLY);
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen i_error("%s doesn't exist", fs_file_path(file));
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen fs_file_path(file), fs_file_last_error(file));
9e6d83a3ef6abb393eeebca423cfd0d8cb08d430Timo Sirainenstatic void cmd_fs_metadata(int argc, char *argv[])
d2470b3dfe91ca07459185384ee25080b42a1636Timo Sirainen const struct fs_metadata *m;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen fs = cmd_fs_init(&argc, &argv, 1, cmd_fs_metadata);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen file = fs_file_init(fs, argv[0], FS_OPEN_MODE_READONLY);
9e6d83a3ef6abb393eeebca423cfd0d8cb08d430Timo Sirainen i_error("%s doesn't exist", fs_file_path(file));
3b426f49d36187895debdda67fff09f97941881cTimo Sirainen fs_file_path(file), fs_file_last_error(file));
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic bool cmd_fs_delete_ctx_run(struct fs_delete_ctx *ctx)
5ada3f57a970f226eb29956d30f66afc3537200dTimo Sirainen unsigned int i;
5d1833b98fa85d8061626aa986f38dcbcd70553eTimo Sirainencmd_fs_delete_dir_recursive(struct fs *fs, unsigned int async_count,
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen unsigned int i;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen ctx.files = t_new(struct fs_file *, ctx.files_count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* delete subdirs first. all fs backends can't handle recursive
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen lookups, so save the list first. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen iter = fs_iter_init(fs, path, FS_ITER_FLAG_DIRS);
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen while ((fname = fs_iter_next(iter)) != NULL) {
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen /* delete files. again because we're doing this asynchronously finish
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen the iteration first. */
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen if ((fs_get_properties(fs) & FS_PROPERTY_DIRECTORIES) != 0) {
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen /* we need to explicitly delete also the directories */
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen while ((fname = fs_iter_next(iter)) != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_error("fs_wait_async() failed: %s", fs_last_error(fs));
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen while (doveadm_exit_code == 0 && cmd_fs_delete_ctx_run(&ctx)) {
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen i_error("fs_wait_async() failed: %s", fs_last_error(fs));
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainencmd_fs_delete_recursive(int argc, char *argv[], unsigned int async_count)
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen fs = cmd_fs_init(&argc, &argv, 1, cmd_fs_delete);
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen cmd_fs_delete_dir_recursive(fs, async_count, argv[0]);
439942f89a77180719644e7af3752a8329259eb9Timo Sirainenstatic void cmd_fs_delete(int argc, char *argv[])
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen unsigned int async_count = 0;
26e5bdf37d7d0deed1e2e8483366c83631b9d251Aki Tuomi switch (c) {
if (recursive) {
const char *fname;
i_unreached();
void doveadm_register_fs_commands(void)