fixes to saving userdata

This commit is contained in:
Benedikt Galbavy 2023-10-17 19:00:20 +02:00
parent a330eeeeb1
commit 0118f251a1
5 changed files with 54 additions and 67 deletions

2
mail.h
View File

@ -2,12 +2,14 @@
#include "user_handler.h" #include "user_handler.h"
#include <nlohmann/json_fwd.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
namespace fs = std::filesystem; namespace fs = std::filesystem;
using json = nlohmann::json;
struct mail { struct mail {
std::string filename; std::string filename;

View File

@ -49,7 +49,6 @@ std::string get_sha1(const std::string& p_arg);
// from myserver.c // from myserver.c
void *clientCommunication(void *data); void *clientCommunication(void *data);
inline std::string recvToStr(int __fd, size_t __n, int __flags);
void signalHandler(int sig); void signalHandler(int sig);
inline void exiting(); inline void exiting();
@ -193,15 +192,31 @@ void *clientCommunication(void *data)
} }
do { do {
std::string message; size = recv(*current_socket, buffer, BUF - 1, 0);
try { if (size == -1) {
message = recvToStr(*current_socket, BUF - 1, 0); if (abortRequested) {
perror("recv error after aborted");
} else {
perror("recv error");
} }
catch(...) {
break; break;
} }
std::stringstream ss(message.c_str()); if (size == 0) {
printf("Client closed remote socket\n"); // ignore error
break;
}
// remove ugly debug message, because of the sent newline of client
if (buffer[size - 2] == '\r' && buffer[size - 1] == '\n') {
size -= 2;
} else if (buffer[size - 1] == '\n') {
--size;
}
buffer[size] = '\0';
std::stringstream ss(buffer);
std::string line; std::string line;
std::vector<std::string> lines; std::vector<std::string> lines;
@ -219,22 +234,6 @@ void *clientCommunication(void *data)
else if (boost::iequals(lines.at(0), "DEL")) cmd = DEL; else if (boost::iequals(lines.at(0), "DEL")) cmd = DEL;
else if (boost::iequals(lines.at(0), "QUIT")) cmd = QUIT; else if (boost::iequals(lines.at(0), "QUIT")) cmd = QUIT;
if (cmd == SEND && !boost::equals(lines.back(), ".\n")) {
try {
message.append(recvToStr(*current_socket, BUF - 1, 0));
std::stringstream ss(message.c_str()); // inefficient to repeat
std::string line;
lines.clear();
while (std::getline(ss, line, '\n')) {
lines.push_back(line);
}
}
catch(...) {
break;
}
}
switch (cmd) { switch (cmd) {
case SEND: case SEND:
if (lines.at(3).length() > 80) { if (lines.at(3).length() > 80) {
@ -242,6 +241,12 @@ void *clientCommunication(void *data)
break; break;
} }
if (lines.size() > 5) {
for (std::vector<std::string>::iterator it = lines.begin() + 5; it != lines.end() && *it != "."; it++) {
lines.at(4).append("\n").append(*it);
}
}
user_handler::getInstance()->getUser(lines.at(1))->sendMail( user_handler::getInstance()->getUser(lines.at(1))->sendMail(
new struct mail(saveToFile(user_handler::getInstance()->getSpoolDir()/"messages", lines.at(4)), std::time(0), lines.at(3)), new struct mail(saveToFile(user_handler::getInstance()->getSpoolDir()/"messages", lines.at(4)), std::time(0), lines.at(3)),
{lines.at(2)} {lines.at(2)}
@ -276,38 +281,6 @@ void *clientCommunication(void *data)
return NULL; return NULL;
} }
inline std::string recvToStr(int __fd, size_t __n, int __flags)
{
char buffer[BUF];
int size;
size = recv(__fd, buffer, __n, __flags);
if (size == -1) {
if (abortRequested) {
perror("recv error after aborted");
} else {
perror("recv error");
}
throw std::exception().what();
}
if (size == 0) {
printf("Client closed remote socket\n"); // ignore error
throw std::exception().what();
}
// remove ugly debug message, because of the sent newline of client
if (buffer[size - 2] == '\r' && buffer[size - 1] == '\n') {
size -= 2;
} else if (buffer[size - 1] == '\n') {
--size;
}
buffer[size] = '\0';
return buffer;
}
void signalHandler(int sig) void signalHandler(int sig)
{ {
if (sig == SIGINT) { if (sig == SIGINT) {
@ -370,5 +343,5 @@ std::string get_sha1(const std::string& p_arg)
inline void exiting() inline void exiting()
{ {
user_handler::getInstance()->saveAll(); user_handler::getInstance()->saveAll();
printf("Saving...\n"); printf("Saving... \n");
} }

View File

@ -16,6 +16,18 @@ user::user(fs::path user_data_json)
json user = json::parse(ifs); json user = json::parse(ifs);
this->name = user["name"]; this->name = user["name"];
for ( auto& mail_json : user["mails"]["received"] ) {
mail* mail = new struct mail(
mail_json["filename"],
mail_json["timestamp"],
mail_json["subject"]
);
mail->id = mail_json["id"];
mail->sender = mail_json["sender"];
mail->recipients = mail_json["recipients"].get<std::vector<std::string>>();
this->inbox.insert(mail);
}
} }
user::user(std::string name, fs::path user_dir) user::user(std::string name, fs::path user_dir)
@ -42,6 +54,8 @@ void user::addMail(mail* mail)
this->inbox.insert(mail); this->inbox.insert(mail);
this->user_data["mails"]["received"][std::to_string(mail->id)] = mail->mailToJson(); this->user_data["mails"]["received"][std::to_string(mail->id)] = mail->mailToJson();
printf("%s\n", this->user_data.dump().c_str());
} }
void user::sendMail(mail* mail, std::vector<std::string> recipients) void user::sendMail(mail* mail, std::vector<std::string> recipients)

14
user.h
View File

@ -1,20 +1,18 @@
#pragma once #pragma once
#include "mail.h"
#include <string> #include <string>
#include <set> #include <set>
#include <vector> #include <vector>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
namespace fs = std::filesystem; struct comp {
using json = nlohmann::json; bool operator()(mail* left, mail* right) const { return *left < *right; };
};
struct mail; typedef std::set<mail*, comp> maillist;
template <typename T>
static const bool ptr_cmp(T* left, T* right) { return *left < *right; };
typedef std::set<mail*, decltype(ptr_cmp<mail>)*> maillist;
class user { class user {
public: public:

View File

@ -1,11 +1,11 @@
#pragma once #pragma once
#include "user.h"
#include <filesystem> #include <filesystem>
#include <map> #include <map>
#include <string> #include <string>
class user;
namespace fs = std::filesystem; namespace fs = std::filesystem;
/* singleton for handling users */ /* singleton for handling users */