From 83bd6fb796baa53b81cb5e2c823b4b1126d62519 Mon Sep 17 00:00:00 2001 From: afonso Date: Fri, 10 May 2024 20:34:01 +0100 Subject: [PATCH] basic structure and client process chain done --- .clang-format | 10 +++ .gitignore | 1 + Makefile | 43 ++++++++++++ README.md | 4 +- libs/communication/communication.c | 11 +++ libs/communication/communication.h | 9 +++ libs/protocol/protocol.c | 13 ++++ libs/protocol/protocol.h | 34 ++++++++++ src/client.c | 4 -- src/client/client.c | 68 +++++++++++++++++++ src/client/client.h | 12 ++++ .../djumbai_client_receive.c | 3 + .../djumbai_client_receive.h} | 0 src/djumbai_client_send/djumbai_client_send.c | 47 +++++++++++++ .../djumbai_client_send.h} | 0 src/djumbai_dequeue/djumbai_dequeue.c | 8 +++ src/djumbai_dequeue/djumbai_dequeue.h | 8 +++ src/djumbai_enqueue/djumbai_enqueue.c | 30 ++++++++ src/djumbai_enqueue/djumbai_enqueue.h | 12 ++++ src/djumbai_send/djumbai_send.c | 3 + src/djumbai_send/djumbai_send.h | 0 21 files changed, 313 insertions(+), 7 deletions(-) create mode 100644 .clang-format create mode 100644 Makefile create mode 100644 libs/communication/communication.c create mode 100644 libs/communication/communication.h create mode 100644 libs/protocol/protocol.c create mode 100644 libs/protocol/protocol.h delete mode 100644 src/client.c create mode 100644 src/client/client.c create mode 100644 src/client/client.h create mode 100644 src/djumbai_client_receive/djumbai_client_receive.c rename src/{djumbai_dequeue.c => djumbai_client_receive/djumbai_client_receive.h} (100%) create mode 100644 src/djumbai_client_send/djumbai_client_send.c rename src/{djumbai_send.c => djumbai_client_send/djumbai_client_send.h} (100%) create mode 100644 src/djumbai_dequeue/djumbai_dequeue.c create mode 100644 src/djumbai_dequeue/djumbai_dequeue.h create mode 100644 src/djumbai_enqueue/djumbai_enqueue.c create mode 100644 src/djumbai_enqueue/djumbai_enqueue.h create mode 100644 src/djumbai_send/djumbai_send.c create mode 100644 src/djumbai_send/djumbai_send.h diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..b77286f --- /dev/null +++ b/.clang-format @@ -0,0 +1,10 @@ +BasedOnStyle: LLVM +UseTab: Always +IndentWidth: 4 +TabWidth: 4 +BreakBeforeBraces: Attach +ColumnLimit: 100 +PenaltyReturnTypeOnItsOwnLine: 1000000 +AlwaysBreakAfterDefinitionReturnType: None +SeparateDefinitionBlocks: Always +AlignConsecutiveMacros: Consecutive diff --git a/.gitignore b/.gitignore index cd531cf..ffa947d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # ---> C # Prerequisites *.d +bin/ # Object files *.o diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9b4532c --- /dev/null +++ b/Makefile @@ -0,0 +1,43 @@ +# Compiler +CC := /opt/homebrew/opt/llvm/bin/clang +# Compiler flags +CFLAGS := -Wall -Wextra -Werror -Ilibs -fsanitize=address + +# Directories +SRCDIR := src +BINDIR := bin +LIBDIR := libs + +# Source files +SRCS := $(wildcard $(SRCDIR)/*.c) +# Object files +OBJS := $(patsubst $(SRCDIR)/%.c,$(BINDIR)/%.o,$(SRCS)) + +# Libraries +LIBS := $(wildcard $(LIBDIR)/*/*.c) +# Library object files +LIBOBJS := $(patsubst %.c,%.o,$(LIBS)) + +# Target executables +EXECUTABLES := $(patsubst $(SRCDIR)/%,$(BINDIR)/%,$(basename $(wildcard $(SRCDIR)/*/*.c))) + +.PHONY: all clean + +all: $(EXECUTABLES) + +$(BINDIR)/%: $(BINDIR)/%.o $(LIBOBJS) + $(CC) $(CFLAGS) $^ -o $@ + +$(BINDIR)/%.o: $(SRCDIR)/%.c | $(BINDIR) + $(CC) $(CFLAGS) -c $< -o $@ + +$(BINDIR): + mkdir -p $(BINDIR) + +permissions: $(BINDIR)/djumbai_enqueue/djumbai_enqueue + chown djumbaiq $(BINDIR)/djumbai_enqueue/djumbai_enqueue + chmod u+s $(BINDIR)/djumbai_enqueue/djumbai_enqueue + +clean: + rm -rf $(BINDIR) + diff --git a/README.md b/README.md index 61771d5..775940f 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ This structured breakdown elucidates the sequential steps involved in the Unix m ## Cenas concretas -Mail queue - FIFO em /opt/djumbai/mailqueue e so pode ser acedida por users do grupo djumbai-queue, que contem djumbai-enqueue e djumbai-dequeue +Mail queue - FIFO em /opt/djumbai/queue/mailqueue e so pode ser acedida por users do grupo djumbai-queue, que contem djumbai-enqueue e djumbai-dequeue Mailbox pessoal - Diretoria em /opt/djumbai/mailbox/user/$uid, que so pode ser acedida pelo user com UID $uid @@ -40,8 +40,6 @@ Mailbox grupo - Diretoria em /opt/djumbai/mailbox/group/$gid, que so pode ser ac SentBox pessoal - Diretoria em /opt/djumbai/sentbox/user/$uid, que so pode ser acedida pelo user com UID $uid -SentBox grupo - Diretoria em /opt/djumbai/sentbox/grupo/$gid, que so pode ser acedida pelo grupo com GID $gid - Repositorio de chaves publicas de utilizadores - Diretoria em /opt/djumbai/pub_keys/user/$uid que contem as chaves publicas de cada utilizador. Apenas o proprio user tem acesso de escrita no ficheiro da sua chave publica Repositorio de chaves publicas de grupos - Diretoria em /opt/djumbai/pub_keys/group/$gid que contem as chaves publicas de cada grupo. Apenas membros do proprio grupo tem acesso de escrita no ficheiro da sua chave publica diff --git a/libs/communication/communication.c b/libs/communication/communication.c new file mode 100644 index 0000000..bfeb6e9 --- /dev/null +++ b/libs/communication/communication.c @@ -0,0 +1,11 @@ +#include "communication.h" + +int serialize_message(void *msg,long msg_size, unsigned char *out) { + memcpy(out, msg, msg_size); + return 0; +} + +int deserialize_message(unsigned char *in,long msg_size, void *msg) { + memcpy(msg, in, msg_size); + return 0; +} diff --git a/libs/communication/communication.h b/libs/communication/communication.h new file mode 100644 index 0000000..389d02e --- /dev/null +++ b/libs/communication/communication.h @@ -0,0 +1,9 @@ +#ifndef COMMUNICATION_H +#define COMMUNICATION_H + +#include + +int serialize_message(void *msg, long msg_size, unsigned char *out); +int deserialize_message(unsigned char *in, long msg_size, void *msg); + +#endif // !COMMUNICATION_H diff --git a/libs/protocol/protocol.c b/libs/protocol/protocol.c new file mode 100644 index 0000000..a0e721e --- /dev/null +++ b/libs/protocol/protocol.c @@ -0,0 +1,13 @@ +#include "protocol.h" + +int new_message(message *m, unsigned int sender, unsigned int receiver, char *content) { + if (strlen(content) > MAX_CONTENT_SIZE) { + return 1; + } + m->header.version = VERSION; + m->header.sender = sender; + m->header.receiver = receiver; + time(&m->header.timestamp); + strncpy(m->content, content, MAX_CONTENT_SIZE); + return 0; +} diff --git a/libs/protocol/protocol.h b/libs/protocol/protocol.h new file mode 100644 index 0000000..e8c42c6 --- /dev/null +++ b/libs/protocol/protocol.h @@ -0,0 +1,34 @@ +#ifndef PROTOCOL_H +#define PROTOCOL_H + +#include +#include +#include +#include + +#define VERSION 1 +#define MAX_CONTENT_SIZE (PIPE_BUF - sizeof(struct MessageHeader)) +#define MESSAGE_SIZE sizeof(struct Message) + +typedef struct MessageHeader { + // The protocol's version + unsigned int version; + // The sender is a user + unsigned int sender; + // The receiver is either a user or a group + unsigned int receiver; + // The message was sent at this timestamp + time_t timestamp; +} message_header; + +typedef struct Message { + // The message's header + message_header header; + // The buffer holding the message + char content[MAX_CONTENT_SIZE]; +} message; + + +int new_message(message *m, unsigned int sender, unsigned int receiver, char *content); + +#endif // !PROTOCOL_H diff --git a/src/client.c b/src/client.c deleted file mode 100644 index 70f9af9..0000000 --- a/src/client.c +++ /dev/null @@ -1,4 +0,0 @@ -#include - -int main(){ -} diff --git a/src/client/client.c b/src/client/client.c new file mode 100644 index 0000000..32e4b6b --- /dev/null +++ b/src/client/client.c @@ -0,0 +1,68 @@ +#include "client.h" +#include + +int send_message(unsigned int sender, unsigned int receiver) { + int pipe_to_child[2]; + + if (pipe(pipe_to_child) == -1) { + perror("pipe"); + exit(EXIT_FAILURE); + } + + pid_t pid = fork(); + if (pid == -1) { + perror("fork"); + exit(EXIT_FAILURE); + } + + if (pid == 0) { // Child process + close(pipe_to_child[1]); // Close write end of pipe + + // Redirect stdin to read from pipe_to_child + dup2(pipe_to_child[0], STDIN_FILENO); + + + // Execute a command, for example, a simple "cat" command + execlp("./bin/djumbai_client_send/djumbai_client_send", "djumbai_client_send", NULL); + + // If execlp fails + perror("execlp"); + close(pipe_to_child[0]); + exit(EXIT_FAILURE); + } else { // Parent process + close(pipe_to_child[0]); // Close read end of pipe + + printf("Please enter your message (Max of %ld bytes):\n", MAX_CONTENT_SIZE); + char content[MAX_CONTENT_SIZE]; + fgets(content, MAX_CONTENT_SIZE, stdin); + + message msg; + if (new_message(&msg, sender, receiver, content) != 0) { + printf("Error when creating new message\n"); + } + + // Serialize the message + unsigned char buffer[sizeof(struct Message)]; + if (serialize_message(&msg, sizeof(struct Message), buffer) == -1) { + fprintf(stderr, "Error: Serialization failed\n"); + return 1; + } + + write(pipe_to_child[1], buffer, sizeof(buffer)); + + // Close the write end of the pipe + close(pipe_to_child[1]); + // Wait for the child process to finish + wait(NULL); + } + + return 0; +} + +int main() { + // TODO: Client parsing to be done + unsigned int sender = getuid(); + unsigned int receiver = 1000; + send_message(sender, receiver); + return 0; +} diff --git a/src/client/client.h b/src/client/client.h new file mode 100644 index 0000000..4d190be --- /dev/null +++ b/src/client/client.h @@ -0,0 +1,12 @@ +#ifndef CLIENT_H +#define CLIENT_H + +#include "../../libs/communication/communication.h" +#include "../../libs/protocol/protocol.h" +#include +#include +#include +#include + +int send_message(unsigned int sender, unsigned int receiver); +#endif // !CLIENT_H diff --git a/src/djumbai_client_receive/djumbai_client_receive.c b/src/djumbai_client_receive/djumbai_client_receive.c new file mode 100644 index 0000000..bc2486d --- /dev/null +++ b/src/djumbai_client_receive/djumbai_client_receive.c @@ -0,0 +1,3 @@ +int main(){ + +} diff --git a/src/djumbai_dequeue.c b/src/djumbai_client_receive/djumbai_client_receive.h similarity index 100% rename from src/djumbai_dequeue.c rename to src/djumbai_client_receive/djumbai_client_receive.h diff --git a/src/djumbai_client_send/djumbai_client_send.c b/src/djumbai_client_send/djumbai_client_send.c new file mode 100644 index 0000000..fe645a3 --- /dev/null +++ b/src/djumbai_client_send/djumbai_client_send.c @@ -0,0 +1,47 @@ +#include "../../libs/protocol/protocol.h" +#include +#include +#include + +int main() { + + int pipe_to_child[2]; + + if (pipe(pipe_to_child) == -1) { + perror("pipe"); + exit(EXIT_FAILURE); + } + + pid_t pid = fork(); + if (pid == -1) { + perror("fork"); + exit(EXIT_FAILURE); + } + + if (pid == 0) { // Child process + close(pipe_to_child[1]); // Close write end of pipe + + // Redirect stdin to read from pipe_to_child + dup2(pipe_to_child[0], STDIN_FILENO); + + execlp("./bin/djumbai_enqueue/djumbai_enqueue", "djumbai_enqueue", NULL); + + // If execlp fails + perror("execlp"); + close(pipe_to_child[0]); + exit(EXIT_FAILURE); + } else { // Parent process + close(pipe_to_child[0]); // Close read end of pipe + + unsigned char buffer[sizeof(struct Message)]; + read(0, buffer, sizeof(struct Message)); + write(pipe_to_child[1], buffer, sizeof(buffer)); + + // Close the write end of the pipe + close(pipe_to_child[1]); + // Wait for the child process to finish + wait(NULL); + } + + return 0; +} diff --git a/src/djumbai_send.c b/src/djumbai_client_send/djumbai_client_send.h similarity index 100% rename from src/djumbai_send.c rename to src/djumbai_client_send/djumbai_client_send.h diff --git a/src/djumbai_dequeue/djumbai_dequeue.c b/src/djumbai_dequeue/djumbai_dequeue.c new file mode 100644 index 0000000..34638cb --- /dev/null +++ b/src/djumbai_dequeue/djumbai_dequeue.c @@ -0,0 +1,8 @@ +#include + +int main(){ + //Make stdin the FIFO + //Read from FIFO + //Make stdout the output FIFO + //Write to another FIFO +} diff --git a/src/djumbai_dequeue/djumbai_dequeue.h b/src/djumbai_dequeue/djumbai_dequeue.h new file mode 100644 index 0000000..34638cb --- /dev/null +++ b/src/djumbai_dequeue/djumbai_dequeue.h @@ -0,0 +1,8 @@ +#include + +int main(){ + //Make stdin the FIFO + //Read from FIFO + //Make stdout the output FIFO + //Write to another FIFO +} diff --git a/src/djumbai_enqueue/djumbai_enqueue.c b/src/djumbai_enqueue/djumbai_enqueue.c new file mode 100644 index 0000000..d63ca42 --- /dev/null +++ b/src/djumbai_enqueue/djumbai_enqueue.c @@ -0,0 +1,30 @@ +#include "djumbai_enqueue.h" + +int main() { + //Change the root of the djumbai_enqueue process so it doesn't have access to anything else. + chroot("/opt/djumbai/queue/"); + const char *message_queue_path = + "mailqueue"; // Replace this with the path to your FIFO + + // Open the FIFO for writing + int queue_fd; + queue_fd = open(message_queue_path, O_WRONLY); + if (queue_fd == -1) { + if (errno == ENOENT) { + // FIFO does not exist + printf("FIFO '%s' does not exist. Exiting...\n", message_queue_path); + return 1; + } else { + perror("open"); + return 1; + } + } + + // Read message from stdin + unsigned char buffer[MESSAGE_SIZE]; + read(0, buffer, MESSAGE_SIZE); + + // Write message to message queue + write(queue_fd, buffer, MESSAGE_SIZE); + close(queue_fd); +} diff --git a/src/djumbai_enqueue/djumbai_enqueue.h b/src/djumbai_enqueue/djumbai_enqueue.h new file mode 100644 index 0000000..cec1784 --- /dev/null +++ b/src/djumbai_enqueue/djumbai_enqueue.h @@ -0,0 +1,12 @@ +#ifndef DJUMBAI_ENQUEUE_H +#define DJUMBAI_ENQUEUE_H + +#include "../../libs/protocol/protocol.h" +#include +#include +#include +#include + +int main(); + +#endif // !DJUMBAI_ENQUEUE_H diff --git a/src/djumbai_send/djumbai_send.c b/src/djumbai_send/djumbai_send.c new file mode 100644 index 0000000..bc2486d --- /dev/null +++ b/src/djumbai_send/djumbai_send.c @@ -0,0 +1,3 @@ +int main(){ + +} diff --git a/src/djumbai_send/djumbai_send.h b/src/djumbai_send/djumbai_send.h new file mode 100644 index 0000000..e69de29