Skip to content

Changelog.txt implementation #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 20, 2024
Merged
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Currently can upload new files, and update existing ones, and delete files from
# todos:
- ~~add deletion~~
- ~~update files~~
- ~~changelog.txt~~

compile:
```
Expand Down
37 changes: 29 additions & 8 deletions server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ bool fileExists(const std::string& filename) { // check if the file exists
}

time_t getFileLastModifiedTime(const std::string& filename) { // get the last modified time of the file
struct stat buffer;
stat(filename.c_str(), &buffer);
return buffer.st_mtime;
struct stat buffer; // create a buffer to store the file information
stat(filename.c_str(), &buffer); // get the file information and store it in the buffer
return buffer.st_mtime; // return the last modified time
}

void receiveFile(int clientSocket, const std::string& filename) {
Expand Down Expand Up @@ -69,8 +69,18 @@ void receiveFile(int clientSocket, const std::string& filename) {
}

void synchronizeFiles(int clientSocket) { // synchronize the files
#include <fstream> // Add missing include directive for the <fstream> library

std::vector<std::string> files; // vector to store received filenames from local directory

// create changelog if it doesn't exist
std::ofstream changelog(SERVER_FOLDER "changelog.txt", std::ios::app); // open the changelog file in append mode (to append new logs to the end of the file)
if (!changelog.is_open()) {
std::cerr << "Error opening changelog file" << std::endl;
return;
}


// Receive missing files and update existing ones
while (true) {
// Receive file name from the client
Expand All @@ -82,26 +92,35 @@ void synchronizeFiles(int clientSocket) { // synchronize the files
break; // End of file list
}
std::string filename(buffer); // convert the buffer to a string to get the file name
files.push_back(filename);
files.push_back(filename); // add the file name to the vector of files to compare later on the server side (to delete files that are no longer existing on client side)
send(clientSocket, "OK", 2, 0); // send the acknowledgment to the client that the file name was received successfully

time_t lastModifiedTime; // create a variable to store the last modified time
std::memset(buffer, 0, sizeof(buffer)); // reset the buffer
bytesRead = recv(clientSocket, buffer, sizeof(buffer), 0); // receive the last modified time from the client
if (bytesRead != sizeof(lastModifiedTime)) {
if (bytesRead != sizeof(lastModifiedTime)) { // if the last modified time is not received correctly
std::cerr << "Error receiving last modified time for: " << filename << std::endl;
continue; // continue to the next file
}

std::memcpy(&lastModifiedTime, buffer, sizeof(lastModifiedTime)); // copy the last modified time from the buffer to the variable

if (!fileExists(SERVER_FOLDER + filename) || lastModifiedTime > getFileLastModifiedTime(SERVER_FOLDER + filename)) {
bool existing = fileExists(SERVER_FOLDER + filename); // check if the file already exists before receiving it, to know if we need to log an update or a receive
send(clientSocket, "SEND", 4, 0); // send the message to the client to send the file
if (fileExists(SERVER_FOLDER + filename)) std::cout<<"[UPDATED]";
receiveFile(clientSocket, filename); // receive the file from the client
time_t now = time(0); // get the current time to log it
if (existing){ // if the file already existed before receiving, we log an update
changelog << now << " [UPDATED] "<< filename << " from " << getFileLastModifiedTime(SERVER_FOLDER + filename) << " to " << lastModifiedTime << std::endl;
} else {
changelog << now << " RECEIVED "<< filename << std::endl; // if the file didn't exist before receiving, we log a receive
}

} else {
send(clientSocket, "SKIP", 4, 0); // send the message to the client to skip the file if the file already exists
}

changelog.close(); // close the changelog file
}

// compare client names to files on remote directory, to delete files that are no longer existing on client side
Expand All @@ -110,10 +129,12 @@ void synchronizeFiles(int clientSocket) { // synchronize the files
// check all files in server directory to see if they are in the vector, if not, we delete
if ((dir = opendir(SERVER_FOLDER)) != nullptr) { // open the server folder and check if it is not null (nullptr)
while ((ent = readdir(dir)) != nullptr) { // read the directory entries one by one and check if it is not null (nullptr)
if ((ent->d_type == DT_REG) && (strcmp(ent->d_name, "server") != 0)) { // regular file and not "server"
if ((ent->d_type == DT_REG) && (strcmp(ent->d_name, "server") != 0) && (strcmp(ent->d_name, "changelog.txt") != 0)) { // regular file and not "server" or "changelog.txt"
std::string filename(ent->d_name); // get the filename from the directory entry
if (std::find(files.begin(), files.end(), filename) == files.end()) { // if the file is not found in the vector
std::cout << "[DELETED] " << filename << std::endl;
time_t now = time(0);
changelog << now << " [DELETED] " << filename << std::endl;
std::cout << now << " [DELETED] " << filename << std::endl;
remove((SERVER_FOLDER + filename).c_str()); // delete the file
}
}
Expand Down