diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 9d20fbd..a653445 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -3455,9 +3455,6 @@ void Client::start_up() { set_context(context); set_tag(bot_token_id_); - auto r_absolute_dir = td::realpath(td::string(".") + TD_DIR_SLASH, true); - CHECK(r_absolute_dir.is_ok()); - absolute_dir_ = r_absolute_dir.move_as_ok(); auto suff = bot_token_with_dc_ + TD_DIR_SLASH; #if TD_PORT_WINDOWS for (auto &c : suff) { @@ -3466,11 +3463,7 @@ void Client::start_up() { } } #endif - dir_ = td::string(".") + TD_DIR_SLASH + suff; - if (absolute_dir_.back() != TD_DIR_SLASH) { - absolute_dir_ += TD_DIR_SLASH; - } - absolute_dir_ += suff; + dir_ = parameters_->working_directory_ + suff; class TdCallback : public td::TdCallback { public: @@ -4464,8 +4457,8 @@ void Client::on_closed() { td::ActorId parent_; void start_up() override { - CHECK(!dir_.empty()); - CHECK(dir_[0] == '.'); + CHECK(dir_.size() >= 24); + CHECK(dir_.back() == TD_DIR_SLASH); td::rmrf(dir_).ignore(); stop(); } @@ -7657,7 +7650,7 @@ void Client::do_get_file(object_ptr file, PromisedQueryPtr query) auto file_id = file->id_; file_download_listeners_[file_id].push_back(std::move(query)); if (file->local_->is_downloading_completed_) { - Slice relative_path = td::PathView::relative(file->local_->path_, absolute_dir_, true); + Slice relative_path = td::PathView::relative(file->local_->path_, dir_, true); if (!relative_path.empty()) { auto r_stat = td::stat(file->local_->path_); if (r_stat.is_ok() && r_stat.ok().is_reg_ && r_stat.ok().size_ == file->size_) { @@ -8293,7 +8286,7 @@ void Client::json_store_file(td::JsonObjectScope &object, const td_api::file *fi object("file_path", td::JsonRawString(file->local_->path_)); } } else { - Slice relative_path = td::PathView::relative(file->local_->path_, absolute_dir_, true); + Slice relative_path = td::PathView::relative(file->local_->path_, dir_, true); if (!relative_path.empty() && file->local_->downloaded_size_ <= MAX_DOWNLOAD_FILE_SIZE) { object("file_path", relative_path); } diff --git a/telegram-bot-api/Client.h b/telegram-bot-api/Client.h index 7b93838..40224b5 100644 --- a/telegram-bot-api/Client.h +++ b/telegram-bot-api/Client.h @@ -902,7 +902,6 @@ class Client : public WebhookActor::Callback { int64 current_bot_resolve_query_id_ = 1; td::string dir_; - td::string absolute_dir_; td::ActorOwn td_client_; td::ActorContext context_; std::queue cmd_queue_; diff --git a/telegram-bot-api/ClientManager.cpp b/telegram-bot-api/ClientManager.cpp index a1347ea..6f8cabb 100644 --- a/telegram-bot-api/ClientManager.cpp +++ b/telegram-bot-api/ClientManager.cpp @@ -266,7 +266,7 @@ void ClientManager::start_up() { td::vector failed_to_replay_log_event_ids; td::int64 loaded_event_count = 0; binlog - ->init("tqueue.binlog", + ->init(parameters_->working_directory_ + "tqueue.binlog", [&](const td::BinlogEvent &event) { if (tqueue_binlog->replay(event, *tqueue).is_error()) { failed_to_replay_log_event_ids.push_back(event.id_); @@ -295,7 +295,8 @@ void ClientManager::start_up() { // init webhook_db auto concurrent_webhook_db = td::make_unique>(); - auto status = concurrent_webhook_db->init("webhooks_db.binlog", td::DbKey::empty(), scheduler_id); + auto status = concurrent_webhook_db->init(parameters_->working_directory_ + "webhooks_db.binlog", td::DbKey::empty(), + scheduler_id); LOG_IF(FATAL, status.is_error()) << "Can't open webhooks_db.binlog " << status.error(); parameters_->shared_data_->webhook_db_ = std::move(concurrent_webhook_db); diff --git a/telegram-bot-api/ClientParameters.h b/telegram-bot-api/ClientParameters.h index 6ca1432..e686887 100644 --- a/telegram-bot-api/ClientParameters.h +++ b/telegram-bot-api/ClientParameters.h @@ -54,6 +54,8 @@ struct SharedData { }; struct ClientParameters { + td::string working_directory_; + bool local_mode_ = false; td::int32 api_id_ = 0; diff --git a/telegram-bot-api/telegram-bot-api.cpp b/telegram-bot-api/telegram-bot-api.cpp index 3de714a..6454651 100644 --- a/telegram-bot-api/telegram-bot-api.cpp +++ b/telegram-bot-api/telegram-bot-api.cpp @@ -36,6 +36,7 @@ #include "td/utils/MemoryLog.h" #include "td/utils/misc.h" #include "td/utils/OptionParser.h" +#include "td/utils/PathView.h" #include "td/utils/port/IPAddress.h" #include "td/utils/port/path.h" #include "td/utils/port/rlimit.h" @@ -208,7 +209,7 @@ int main(int argc, char *argv[]) { int default_verbosity_level = 0; int memory_verbosity_level = VERBOSITY_NAME(INFO); td::int64 log_max_file_size = 2000000000; - td::string working_directory; + td::string working_directory = PSTRING() << "." << TD_DIR_SLASH; td::string temporary_directory; td::string username; td::string groupname; @@ -362,29 +363,54 @@ int main(int argc, char *argv[]) { TRY_STATUS_PREFIX(td::change_user(username, groupname), "Can't change effective user: "); } - if (!working_directory.empty()) { - TRY_STATUS_PREFIX(td::chdir(working_directory), "Can't set working directory: "); + { + TRY_RESULT_PREFIX_ASSIGN(working_directory, td::realpath(working_directory, true), + "Invalid working directory specified: "); + if (working_directory.empty()) { + return td::Status::Error("Working directory can't be empty"); + } + if (working_directory.back() != TD_DIR_SLASH) { + working_directory += TD_DIR_SLASH; + } + + TRY_STATUS_PREFIX(td::mkpath(working_directory, 0750), "Failed to create working directory: "); + + auto r_temp_file = td::mkstemp(working_directory); + if (r_temp_file.is_error()) { + return td::Status::Error(PSLICE() << "Can't create files in the directory \"" << working_directory + << "\". Use --dir option to specify a writable working directory"); + } + r_temp_file.ok_ref().first.close(); + td::unlink(r_temp_file.ok().second).ensure(); } if (!temporary_directory.empty()) { + if (td::PathView(temporary_directory).is_relative()) { + temporary_directory = working_directory + temporary_directory; + } TRY_STATUS_PREFIX(td::set_temporary_dir(temporary_directory), "Can't set temporary directory: "); } - auto temp_dir = td::get_temporary_dir(); - if (temp_dir.empty()) { - return td::Status::Error("Can't find directory for temporary files. Use --temp-dir option to specify it"); - } + { // check temporary directory + auto temp_dir = td::get_temporary_dir(); + if (temp_dir.empty()) { + return td::Status::Error("Can't find directory for temporary files. Use --temp-dir option to specify it"); + } - auto r_temp_file = td::mkstemp(temp_dir); - if (r_temp_file.is_error()) { - return td::Status::Error( - PSLICE() << "Can't create files in the directory \"" << temp_dir - << "\". Use --temp-dir option to specify another directory for temporary files"); + auto r_temp_file = td::mkstemp(temp_dir); + if (r_temp_file.is_error()) { + return td::Status::Error(PSLICE() + << "Can't create files in the directory \"" << temp_dir + << "\". Use --temp-dir option to specify another directory for temporary files"); + } + r_temp_file.ok_ref().first.close(); + td::unlink(r_temp_file.ok().second).ensure(); } - r_temp_file.ok_ref().first.close(); - td::unlink(r_temp_file.ok().second).ensure(); if (!log_file_path.empty()) { + if (td::PathView(log_file_path).is_relative()) { + log_file_path = working_directory + log_file_path; + } TRY_STATUS_PREFIX(file_log.init(log_file_path, log_max_file_size), "Can't open log file: "); log.set_first(&ts_log); } @@ -397,6 +423,8 @@ int main(int argc, char *argv[]) { return 1; } + parameters->working_directory_ = std::move(working_directory); + if (parameters->default_max_webhook_connections_ <= 0) { parameters->default_max_webhook_connections_ = parameters->local_mode_ ? 100 : 40; }