diff --git a/TODO.md b/TODO.md index 65c86ed..89f1d83 100644 --- a/TODO.md +++ b/TODO.md @@ -3,7 +3,7 @@ # Development plans - [ ] Remove file when error while saving the data in DB -- [ ] Show date in server log +- [ ] Colorize server messages ## Features @@ -27,4 +27,5 @@ - [x] Close the DB correctly in any quit case (also by SIGTERM) - [x] Get rid of unsigned integers - [x] Check registration -- [x] Auto create a database when one is missing. \ No newline at end of file +- [x] Auto create a database when one is missing +- [x] Show date in server log \ No newline at end of file diff --git a/src/db/db_postgresql.c b/src/db/db_postgresql.c index 5de312a..8d09ab7 100644 --- a/src/db/db_postgresql.c +++ b/src/db/db_postgresql.c @@ -4,6 +4,7 @@ /* TODO: variadic function for preparing parameters */ #include "../main.h" +#include "../utils.h" #include "db_common.h" #include #include @@ -34,7 +35,7 @@ static void clearRes(void) { static int terminate(int code) { if (code != 0) - fprintf(stderr, "%s\n", PQerrorMessage(conn)); + print_log(stdout, pl_error, "%s\n", PQerrorMessage(conn)); if (res != NULL) PQclear(res); @@ -47,7 +48,7 @@ static int terminate(int code) { static int exit_query(int code) { if (code != 0) - fprintf(stderr, "%s\n", PQerrorMessage(conn)); + print_log(stdout, pl_error, "%s\n", PQerrorMessage(conn)); if (res != NULL) PQclear(res); @@ -57,7 +58,7 @@ static int exit_query(int code) { static int exit_query_2(int code) { if (code == 0) - fprintf(stderr, "%s\n", PQerrorMessage(conn)); + print_log(stdout, pl_error, "%s\n", PQerrorMessage(conn)); if (res != NULL) PQclear(res); @@ -66,7 +67,7 @@ static int exit_query_2(int code) { } static void *exit_query_3(void *ptr) { - fprintf(stderr, "%s\n", PQerrorMessage(conn)); + print_log(stdout, pl_error, "%s\n", PQerrorMessage(conn)); if (res != NULL) PQclear(res); @@ -99,8 +100,9 @@ int init_db_connection() { // return terminate(2); // } - printf("Connection established! server version: %d, user: %s, db: %s\n", - server_ver, user, db_name); + print_log(stdout, pl_info, + "Connection established! server version: %d, user: %s, db: %s\n", + server_ver, user, db_name); return exit_query(0); } @@ -271,7 +273,8 @@ s_file_t *db_get_file(i_get_file_db *arg) { strcpy(s_field, "user_id"); sprintf(value, "%u", arg->user_id); } else { - fprintf(stderr, "db_get_file: none of the args is specified!\n"); + print_log(stdout, pl_error, + "db_get_file: none of the args is specified!\n"); return NULL; } @@ -307,7 +310,7 @@ s_file_t *db_get_file(i_get_file_db *arg) { } int32_t db_get_files_data(i_get_files_db *arg, fl_t **fl_start, - int32_t *full_count) { + int32_t *full_count) { fl_t *fl_current; char query[512]; char sort_by[16] = "id"; diff --git a/src/db/db_sqlite.c b/src/db/db_sqlite.c index be70c05..8a8f357 100644 --- a/src/db/db_sqlite.c +++ b/src/db/db_sqlite.c @@ -2,6 +2,7 @@ /* Copyright (c) 2026 Oleksandr Zhylin */ #include "../main.h" +#include "../utils.h" #include "db_common.h" #include #include @@ -40,7 +41,7 @@ typedef enum db_cb_resp (*db_callback)(sqlite3_stmt *stmt, void *resp); void print_err(char **err) { if (*err != NULL) { - printf("%s\n", *err); + print_log(stdout, pl_error, "%s\n", *err); sqlite3_free(*err); *err = NULL; } @@ -128,7 +129,7 @@ enum db_cb_resp vdb_query(const char *zSql, db_callback callback, void *a_resp, /* Prepare arguments */ if ((sqlite3_prepare_v2(db, zSql, -1, &stmt, &pzTail)) != SQLITE_OK) { - fprintf(stderr, "SQL Error: %s\n", sqlite3_errmsg(db)); + print_log(stdout, pl_error, "SQL Error: %s\n", sqlite3_errmsg(db)); return db_err; } @@ -150,7 +151,8 @@ enum db_cb_resp vdb_query(const char *zSql, db_callback callback, void *a_resp, sqlite3_bind_blob(stmt, i + 1, va_arg(va_list, void *), size, NULL); size = 0; } else { - fprintf(stderr, "SQL ERROR: Size for a blob must be specified!\n"); + print_log(stdout, pl_error, + "SQL ERROR: Size for a blob must be specified!\n"); return db_err; } break; @@ -353,7 +355,8 @@ s_file_t *db_get_file(i_get_file_db *arg) { } else if (strlen(arg->name)) { strcpy(s_field, "name"); } else { - fprintf(stderr, "db_get_file: none of the args is specified!\n"); + print_log(stdout, pl_error, + "db_get_file: none of the args is specified!\n"); return NULL; } @@ -423,7 +426,7 @@ enum db_cb_resp db_get_files_count_db(sqlite3_stmt *stmt, void *resp) { } int32_t db_get_files_data(i_get_files_db *arg, fl_t **fl_start, - int32_t *full_count) { + int32_t *full_count) { fl_t *fl_current = NULL; char zSql[512]; struct db_get_files_data data = {.fl_current = &fl_current, diff --git a/src/file_p.c b/src/file_p.c index 9181f41..3e5031b 100644 --- a/src/file_p.c +++ b/src/file_p.c @@ -4,6 +4,7 @@ #include "file_p.h" #include "main.h" #include "session.h" +#include "utils.h" #include #include #include @@ -162,7 +163,7 @@ int32_t file_send_prepare(session *sess, char *line, server_data_t *s_d) { file_d = open(sess->file->path, O_RDONLY); if (file_d == -1) { - fprintf(stdout, "Error opening file: %d\n", errno); + print_log(stdout, pl_error, "Error opening file: %d\n", errno); mlen = sprintf(err_mes, "Can't open file with id = %u\n", sess->file->id); write(sd, err_mes, mlen); return -2; @@ -295,7 +296,8 @@ void file_download(session *sess) { int rlen = read(source_d, buf, INBUFSIZE); if (rlen == 0) { if (sess->file->rest) { - fprintf(stderr, "Error downloading file %s!\n", sess->file->name); + print_log(stdout, pl_error, "Error downloading file %s!\n", + sess->file->name); clear_file_from_sess(sess); } sess->state = OP_WAIT; @@ -304,7 +306,8 @@ void file_download(session *sess) { write(dest_d, buf, rlen); sess->file->rest -= rlen; if (!sess->file->rest) { - printf("File %s is downloaded from the server\n", sess->file->name); + print_log(stdout, pl_info, "File %s is downloaded from the server\n", + sess->file->name); clear_file_from_sess(sess); sess->state = OP_WAIT; } @@ -318,7 +321,8 @@ void file_upload(session *sess) { int rlen = read(source_d, buf, INBUFSIZE); if (rlen == 0) { if (sess->file->rest) { - fprintf(stderr, "Error uploading file %s!\n", sess->file->name); + print_log(stdout, pl_error, "Error uploading file %s!\n", + sess->file->name); unlink(sess->file->path); /* remove file */ clear_file_from_sess(sess); } @@ -329,19 +333,22 @@ void file_upload(session *sess) { write(dest_d, buf, sess->file->package_rest); rlen -= sess->file->package_rest; sess->file->rest -= sess->file->package_rest; - if (rlen == 0) return; - s_file_pd_t *fpd = (s_file_pd_t *) (buf + sess->file->package_rest); + if (rlen == 0) + return; + s_file_pd_t *fpd = (s_file_pd_t *)(buf + sess->file->package_rest); switch (fpd->signal) { case sig_continue: rlen -= sizeof(s_file_pd_t); if (rlen > 0) { - write(dest_d, buf + sess->file->package_rest + sizeof(s_file_pd_t), rlen); - sess->file->rest -= rlen; - } + write(dest_d, buf + sess->file->package_rest + sizeof(s_file_pd_t), + rlen); + sess->file->rest -= rlen; + } sess->file->package_rest = fpd->package_size - rlen; break; case sig_cancel: - fprintf(stderr, "Upload of %s is cancelled!\n", sess->file->name); + print_log(stdout, pl_error, "Upload of %s is cancelled!\n", + sess->file->name); unlink(sess->file->path); /* remove file */ clear_file_from_sess(sess); sess->state = OP_WAIT; @@ -359,7 +366,8 @@ void file_upload(session *sess) { } if (!sess->file->rest) { - printf("File %s is uploaded to the server\n", sess->file->name); + print_log(stdout, pl_info, "File %s is uploaded to the server\n", + sess->file->name); session_send_string(sess, "finished\n"); if (db_save_file(sess)) { clear_file_from_sess(sess); diff --git a/src/main.c b/src/main.c index 076e2c3..9c927bc 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,7 @@ #include "main.h" #include "server.h" +#include "utils.h" #include #include @@ -14,7 +15,7 @@ int main(int argc, char *argv[]) { init_db_connection(); server_data.ls = start_server(); /* TODO: display server port */ - printf("Server is started!\n"); + print_log(stdout, pl_info, "Server is started!\n"); server_main_loop(&server_data); db_close_connection(); return 0; diff --git a/src/server.c b/src/server.c index ff468fc..8902f15 100644 --- a/src/server.c +++ b/src/server.c @@ -5,6 +5,7 @@ #include "file_p.h" #include "main.h" #include "session.h" +#include "utils.h" #include #include #include @@ -21,8 +22,8 @@ volatile sig_atomic_t shutdown_requested = 0; volatile sig_atomic_t signal_received = 0; -void term_int_handler(int s) { - shutdown_requested = 1; +void term_int_handler(int s) { + shutdown_requested = 1; signal_received = s; } @@ -69,7 +70,7 @@ void server_main_loop(server_data_t *s_d) { if (shutdown_requested != 0) { db_close_connection(); - printf("\nStopping the server...\n"); + print_log(stdout, pl_info, "\nStopping the server...\n"); exit(signal_received); } @@ -80,7 +81,8 @@ void server_main_loop(server_data_t *s_d) { if (FD_ISSET(s_d->ls, &readfds)) { if (-1 == accept_client(s_d->ls, connections, s_d->welcome_message)) { - fprintf(stderr, "Can't accept connection, error: %d\n", errno); + print_log(stdout, pl_error, "Can't accept connection, error: %d\n", + errno); } } @@ -159,7 +161,7 @@ int start_server(void) { void prepare_start(int argc, char *argv[]) { if (argc != 2) { - fprintf(stderr, "Usage: %s \n", argv[0]); + print_log(stdout, pl_error, "Usage: %s \n", argv[0]); exit(1); } diff --git a/src/session.c b/src/session.c index 461ba90..dd66c31 100644 --- a/src/session.c +++ b/src/session.c @@ -3,11 +3,12 @@ #include "session.h" #include "client.h" -#include #include "file_p.h" #include "main.h" #include "user.h" +#include "utils.h" #include +#include #include #include #include @@ -31,8 +32,8 @@ int32_t accept_client(int ls, session *connections[], char *wm) { return -1; } session *sess = make_new_session(sd, &addr, wm); - fprintf(stdout, "New connection: %s:%u\n", inet_ntoa(addr.sin_addr), - ntohs(addr.sin_port)); + print_log(stdout, pl_info, "New connection: %s:%u\n", + inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); connections[sd] = sess; return 0; } @@ -158,7 +159,8 @@ void perform_session_action(session *sess, char *line, server_data_t *s_d) { res = file_upload_description(sess, line, s_d); if (res) { if (db_save_file(sess)) { - session_send_string(sess, "File \"%s\" is saved!\04\n", sess->file->name); + session_send_string(sess, "File \"%s\" is saved!\04\n", + sess->file->name); clear_file_from_sess(sess); sess->state = OP_WAIT; } else { diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 0000000..97a1892 --- /dev/null +++ b/src/utils.c @@ -0,0 +1,38 @@ +#include "utils.h" +#include +#include +#include +#include +#include + +int print_log(FILE *output, enum pl_type type, const char *format_message, + ...) { + time_t t = time(NULL); + struct tm *tm = localtime(&t); + char date_preffix[128]; + const char *uff_str; + int ret; + va_list args; + sprintf(date_preffix, "[%s] ", ctime(&t)); + strftime(date_preffix, 128, "[%d.%m.%y %T]", tm); + switch (type) { + case pl_info: + uff_str = "%s %s"; + break; + case pl_warning: + uff_str = "%s Warning: %s"; + break; + case pl_error: + uff_str = "%s Error: %s"; + break; + case pl_fatal: + uff_str = "%s Fatal: %s"; + break; + } + char *uf_str = malloc(strlen(date_preffix) + 16 + strlen(format_message) + 4); + sprintf(uf_str, uff_str, date_preffix, format_message); + va_start(args, format_message); + ret = vfprintf(stdout, uf_str, args); + va_end(args); + return ret; +} \ No newline at end of file diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 0000000..940e6f4 --- /dev/null +++ b/src/utils.h @@ -0,0 +1,14 @@ +#ifndef UTILS_H +#define UTILS_H + +#include +enum pl_type { + pl_info, + pl_warning, + pl_error, + pl_fatal, +}; + +int print_log(FILE * output, enum pl_type type, const char *format_message, ...); + +#endif \ No newline at end of file