Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Umnov.Sergei/lab_01/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

rm -f daemon

g++ -Wall -Werror -o daemon main.cpp daemon.cpp
if [ $? -eq 0 ]; then
echo "Build successful"
else
echo "Build failed"
fi
2 changes: 2 additions & 0 deletions Umnov.Sergei/lab_01/config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/home/vinetiger/study/Operating-Systems-labs-2024/Umnov.Sergei/lab_01/test1 txt
/home/vinetiger/study/Operating-Systems-labs-2024/Umnov.Sergei/lab_01/test2 py
203 changes: 203 additions & 0 deletions Umnov.Sergei/lab_01/daemon.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
#include <string>
#include <vector>
#include <syslog.h>
#include <signal.h>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <csignal>
#include <cstdlib>
#include <dirent.h>
#include <ctime>
#include <sstream>
#include <iomanip>
#include <cstring>
#include <filesystem>

namespace fs = std::filesystem;

class Daemon {
public:
static Daemon& getInstance() {
static Daemon instance;
return instance;
}

void setConfigFilePath(const std::string& path) {
configFilePath = path;
}

void reloadConfig() {
syslog(LOG_INFO, "Reloading configuration file");
readConfigFile();
}

void stop() {
syslog(LOG_INFO, "Daemon is stopping");
closelog();
removePidFile();
exit(0);
}

void start() {
checkAndTerminateExistingDaemon();
daemonize();
handleSignals();
readConfigFile();
writePidFile();

while (true) {
for (const auto& config : folderConfigs) {
processFolder(config.folderPath, config.extension);
}
sleep(interval);
}
}

Daemon(const Daemon&) = delete;
Daemon& operator=(const Daemon&) = delete;

private:
Daemon() : interval(30), pid(0), pidFilePath("/tmp/daemon.pid") {
openlog("daemon", LOG_PID | LOG_CONS, LOG_DAEMON);
}

~Daemon() {
closelog();
removePidFile();
}

void removePidFile() {
std::remove(pidFilePath.c_str());
}

void daemonize() {
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)) != nullptr) {
currentWorkingDir = std::string(cwd);
}
else {
syslog(LOG_ERR, "Failed to get current working directory");
}

pid = fork();
if (pid < 0) {
syslog(LOG_ERR, "Fork failed");
exit(1);
}
if (pid > 0) {
exit(0);
}

umask(0);
setsid();

if (chdir("/") < 0) {
syslog(LOG_ERR, "Chdir failed");
exit(1);
}

close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);

open("/dev/null", O_RDONLY);
open("/dev/null", O_RDWR);
open("/dev/null", O_RDWR);
}

void handleSignals() {
signal(SIGHUP, [](int) { Daemon::getInstance().reloadConfig(); });
signal(SIGTERM, [](int) { Daemon::getInstance().stop(); });
}

void readConfigFile() {
std::ifstream configFile(configFilePath);
if (!configFile.is_open()) {
syslog(LOG_ERR, "Failed to open config file: %s", configFilePath.c_str());
exit(1);
}

std::string line;
while (std::getline(configFile, line)) {
std::istringstream iss(line);
std::string folderPath, extension;
if (iss >> folderPath >> extension) {
folderConfigs.push_back({folderPath, extension});
}
}

configFile.close();
}

void processFolder(const std::string& folderPath, const std::string& extension) {
try {
for (const auto& entry : fs::directory_iterator(folderPath)) {
if (entry.is_regular_file()) {
std::string filename = entry.path().filename().string();
if (filename.substr(filename.find_last_of(".") + 1) == extension) {
logFileDetails(folderPath, filename);
}
}
}
} catch (const fs::filesystem_error& e) {
std::cerr << "Failed to open directory: " << folderPath << " - " << e.what() << std::endl;
}
}

void logFileDetails(const std::string& folderPath, const std::string& filename) {
std::string filePath = folderPath + "/" + filename;
struct stat fileStat;
if (stat(filePath.c_str(), &fileStat) == 0) {
char timeBuffer[80];
struct tm *timeInfo = localtime(&fileStat.st_mtime);
strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %H:%M:%S", timeInfo);

syslog(LOG_INFO, "Folder: %s, File: %s, Size: %ld bytes, Last Modified: %s",
folderPath.c_str(), filename.c_str(), fileStat.st_size, timeBuffer);
} else {
syslog(LOG_ERR, "Failed to get stats for file: %s", filePath.c_str());
}
}

void checkAndTerminateExistingDaemon() {
std::ifstream pidFile(pidFilePath);
if (pidFile.is_open()) {
pid_t existingPid;
pidFile >> existingPid;
pidFile.close();

if (kill(existingPid, 0) == 0) {
syslog(LOG_INFO, "Terminating existing daemon with PID %d", existingPid);
kill(existingPid, SIGTERM);
sleep(1);
}
}
}

void writePidFile() {
std::ofstream pidFile(pidFilePath);
if (pidFile.is_open()) {
pidFile << getpid();
pidFile.close();
}
else {
syslog(LOG_ERR, "Failed to write PID file");
}
}

struct FolderConfig {
std::string folderPath;
std::string extension;
};

std::vector<FolderConfig> folderConfigs;
std::string configFilePath;
int interval;
pid_t pid;
std::string pidFilePath;
std::string currentWorkingDir;
};
33 changes: 33 additions & 0 deletions Umnov.Sergei/lab_01/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "daemon.cpp"
#include <iostream>
#include <limits.h>
#include <unistd.h>



int main(int argc, char* argv[]) {
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " <config_file>" << std::endl;
return 1;
}

char configFilePath[PATH_MAX];
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)) != nullptr) {
std::string fullPath = std::string(cwd) + "/" + argv[1];
if (realpath(fullPath.c_str(), configFilePath) == nullptr) {
std::cerr << "Error: Cannot resolve config file path: " << argv[1] << std::endl;
return 1;
}
}
else {
std::cerr << "Error: Cannot get current working directory" << std::endl;
return 1;
}

Daemon& daemon = Daemon::getInstance();
daemon.setConfigFilePath(configFilePath);
daemon.start();

return 0;
}
1 change: 1 addition & 0 deletions Umnov.Sergei/lab_01/test1/sample.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Bruh
1 change: 1 addition & 0 deletions Umnov.Sergei/lab_01/test1/temp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
print('Bruh')
1 change: 1 addition & 0 deletions Umnov.Sergei/lab_01/test2/sample.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
print('test')
1 change: 1 addition & 0 deletions Umnov.Sergei/lab_01/test2/sample1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
print('test')
1 change: 1 addition & 0 deletions Umnov.Sergei/lab_01/test2/temp.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Bruh
91 changes: 91 additions & 0 deletions Umnov.Sergei/lab_02/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
cmake_minimum_required(VERSION 3.10)

# Проект
project(LocalChatApp)

# Стандарт C++
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror")

# Путь для поиска Qt6
set(CMAKE_PREFIX_PATH "/usr/lib/x86_64-linux-gnu/cmake/Qt6")

# Находим Qt6 и нужные компоненты
find_package(Qt6 REQUIRED COMPONENTS Widgets)

# Пути для исходников и заголовков
include_directories(src/connections src/host src/client)

# Определяем пути до заголовочных файлов и используем moc с ними
qt6_wrap_cpp(MOC_SOURCES
src/host/host_gui.hpp
src/client/client_gui.hpp
)

# Определяем исходники для FIFO
set(HOST_FIFO_SRC_FILES
src/host/host_fifo.cpp
src/connections/conn_fifo.cpp
src/host/host_gui.cpp
)

set(CLIENT_FIFO_SRC_FILES
src/client/client_fifo.cpp
src/connections/conn_fifo.cpp
src/client/client_gui.cpp
)

# Определяем исходники для очередей сообщений
set(HOST_QUEUE_SRC_FILES
src/host/host_mq.cpp
src/connections/conn_mq.cpp
src/host/host_gui.cpp
)

set(CLIENT_QUEUE_SRC_FILES
src/client/client_mq.cpp
src/connections/conn_mq.cpp
src/client/client_gui.cpp
)

# Определяем исходники для разделяемой памяти
set(HOST_SHM_SRC_FILES
src/host/host_seg.cpp
src/connections/conn_seg.cpp
src/host/host_gui.cpp
)

set(CLIENT_SHM_SRC_FILES
src/client/client_seg.cpp
src/connections/conn_seg.cpp
src/client/client_gui.cpp
)

# Определяем цели для FIFO
add_executable(host_fifo ${HOST_FIFO_SRC_FILES} ${MOC_SOURCES})
add_executable(client_fifo ${CLIENT_FIFO_SRC_FILES} ${MOC_SOURCES})

# Определяем цели для очередей сообщений
add_executable(host_mq ${HOST_QUEUE_SRC_FILES} ${MOC_SOURCES})
add_executable(client_mq ${CLIENT_QUEUE_SRC_FILES} ${MOC_SOURCES})

# Определяем цели для разделяемой памяти
add_executable(host_seg ${HOST_SHM_SRC_FILES} ${MOC_SOURCES})
add_executable(client_seg ${CLIENT_SHM_SRC_FILES} ${MOC_SOURCES})

# Привязка библиотек Qt6
target_link_libraries(host_fifo Qt6::Widgets)
target_link_libraries(client_fifo Qt6::Widgets)
target_link_libraries(host_mq Qt6::Widgets)
target_link_libraries(client_mq Qt6::Widgets)
target_link_libraries(host_seg Qt6::Widgets)
target_link_libraries(client_seg Qt6::Widgets)

# Путь для исполняемых файлов
set_target_properties(host_fifo PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(client_fifo PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(host_mq PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(client_mq PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(host_seg PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set_target_properties(client_seg PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
23 changes: 23 additions & 0 deletions Umnov.Sergei/lab_02/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

# Удаляем старые файлы сборки
echo "Удаляем старую директорию сборки..."
rm -rf build

# Создаём новую директорию сборки
echo "Создаём директорию сборки..."
mkdir build

# Переходим в директорию сборки
cd build || { echo "Ошибка: не удалось перейти в директорию сборки."; exit 1; }

# Запускаем CMake
echo "Запускаем CMake..."
cmake .. || { echo "Ошибка при запуске cmake."; exit 1; }

# Компилируем проект
echo "Компиляция проекта..."
make -j$(nproc) || { echo "Ошибка при компиляции."; exit 1; }

# Завершаем
echo "Сборка завершена успешно. Исполняемые файлы находятся в 'build/bin'."
Loading