123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- /*
- * This is the source code of tgnet library v. 1.1
- * It is licensed under GNU GPL v. 2 or later.
- * You should have received a copy of the license in this archive (see LICENSE).
- *
- * Copyright Nikolai Kudashov, 2015-2018.
- */
- #include <sys/stat.h>
- #include <unistd.h>
- #include <errno.h>
- #include <cstring>
- #include "Config.h"
- #include "ConnectionsManager.h"
- #include "FileLog.h"
- #include "BuffersStorage.h"
- Config::Config(int32_t instance, std::string fileName) {
- instanceNum = instance;
- configPath = ConnectionsManager::getInstance(instanceNum).currentConfigPath + fileName;
- backupPath = configPath + ".bak";
- FILE *backup = fopen(backupPath.c_str(), "rb");
- if (backup != nullptr) {
- if (LOGS_ENABLED) DEBUG_D("Config(%p, %s) backup file found %s", this, configPath.c_str(), backupPath.c_str());
- fclose(backup);
- remove(configPath.c_str());
- rename(backupPath.c_str(), configPath.c_str());
- }
- }
- NativeByteBuffer *Config::readConfig() {
- NativeByteBuffer *buffer = nullptr;
- FILE *file = fopen(configPath.c_str(), "rb");
- if (file != nullptr) {
- fseek(file, 0, SEEK_END);
- long fileSize = ftell(file);
- if (fseek(file, 0, SEEK_SET)) {
- if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) failed fseek to begin, reopen it", this, configPath.c_str());
- fclose(file);
- file = fopen(configPath.c_str(), "rb");
- }
- uint32_t size = 0;
- size_t bytesRead = fread(&size, sizeof(uint32_t), 1, file);
- if (LOGS_ENABLED) DEBUG_D("Config(%p, %s) load, size = %u, fileSize = %u", this, configPath.c_str(), size, (uint32_t) fileSize);
- if (bytesRead > 0 && size > 0 && (int32_t) size < fileSize) {
- buffer = BuffersStorage::getInstance().getFreeBuffer(size);
- if (fread(buffer->bytes(), sizeof(uint8_t), size, file) != size) {
- buffer->reuse();
- buffer = nullptr;
- }
- }
- fclose(file);
- }
- return buffer;
- }
- void Config::writeConfig(NativeByteBuffer *buffer) {
- if (LOGS_ENABLED) DEBUG_D("Config(%p, %s) start write config", this, configPath.c_str());
- FILE *file = fopen(configPath.c_str(), "rb");
- FILE *backup = fopen(backupPath.c_str(), "rb");
- bool error = false;
- bool hasBackupFile = false;
- if (file != nullptr) {
- if (backup == nullptr) {
- fclose(file);
- if (rename(configPath.c_str(), backupPath.c_str()) != 0) {
- if (LOGS_ENABLED) DEBUG_E("Config(%p) unable to rename file %s to backup file %s", this, configPath.c_str(), backupPath.c_str());
- error = true;
- } else {
- hasBackupFile = true;
- }
- } else {
- fclose(file);
- fclose(backup);
- remove(configPath.c_str());
- }
- }
- if (error) {
- return;
- }
- file = fopen(configPath.c_str(), "wb");
- if (chmod(configPath.c_str(), 0660)) {
- if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) chmod failed", this, configPath.c_str());
- }
- if (file == nullptr) {
- if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) unable to open file for writing", this, configPath.c_str());
- return;
- }
- uint32_t size = buffer->position();
- if (fwrite(&size, sizeof(uint32_t), 1, file) == 1) {
- if (fwrite(buffer->bytes(), sizeof(uint8_t), size, file) != size) {
- if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) failed to write config data to file", this, configPath.c_str());
- error = true;
- }
- } else {
- if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) failed to write config size to file", this, configPath.c_str());
- error = true;
- }
- if (fflush(file)) {
- if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) fflush failed", this, configPath.c_str());
- error = true;
- }
- int fd = fileno(file);
- if (fd == -1) {
- if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) fileno failed", this, configPath.c_str());
- error = true;
- } else {
- if (LOGS_ENABLED) DEBUG_D("Config(%p, %s) fileno = %d", this, configPath.c_str(), fd);
- }
- if (fd != -1 && fsync(fd) == -1) {
- if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) fsync failed", this, configPath.c_str());
- error = true;
- }
- if (fclose(file)) {
- if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) fclose failed", this, configPath.c_str());
- error = true;
- }
- if (error) {
- if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) failed to write config", this, configPath.c_str());
- if (remove(configPath.c_str())) {
- if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) remove config failed", this, configPath.c_str());
- }
- } else {
- if (hasBackupFile && remove(backupPath.c_str())) {
- if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) remove backup failed, %s", this, backupPath.c_str(), strerror(errno));
- }
- }
- if (!error) {
- if (LOGS_ENABLED) DEBUG_D("Config(%p, %s) config write ok", this, configPath.c_str());
- }
- }
|