diff --git a/TODO.md b/TODO.md index 37d60e3..29d8f3e 100644 --- a/TODO.md +++ b/TODO.md @@ -1,9 +1,8 @@ ## Tasks # Development plans -- [ ] make print_log to write a file log -- [ ] Remove file when error while saving the data in DB -- [ ] Colorize server messages +- [x] make print_log to write a file log +- [x] Colorize server messages - [ ] Unified list of exit codes ## Features diff --git a/src/components/file_p/file_p.c b/src/components/file_p/file_p.c index 2f1e0ba..eb8d2bc 100644 --- a/src/components/file_p/file_p.c +++ b/src/components/file_p/file_p.c @@ -172,8 +172,7 @@ int32_t file_send_prepare(session *sess, char *line, server_data_t *s_d) { } int name_len = name_end - name_begin; if (name_len == 0) { - session_send_string( - sess, "File name should not be empty"); + session_send_string(sess, "File name should not be empty"); clear_file_from_sess(sess); return -6; } @@ -238,8 +237,7 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) { } int name_len = name_end - name_begin; if (name_len == 0) { - session_send_string( - sess, "File name should not be empty"); + session_send_string(sess, "File name should not be empty"); clear_file_from_sess(sess); return -7; } @@ -367,7 +365,7 @@ void file_download(session *sess) { int rlen = read(source_d, buf, read_len); if (rlen == 0) { if (sess->file->rest) { - print_log(stdout, pl_error, "Error downloading file %s!\n", + print_log(stdout, pl_fail, "Fail while downloading file %s!\n", sess->file->name); clear_file_from_sess(sess); } @@ -377,7 +375,7 @@ void file_download(session *sess) { int ret = write(dest_d, buf, rlen); if (ret == -1) { const char *err_mes = strerror(errno); - print_log(stdout, pl_error, "Error downloading file %s! %s\n", + print_log(stdout, pl_fail, "Fail while downloading file %s! %s\n", sess->file->name, err_mes); sess->state = ERR; clear_file_from_sess(sess); @@ -386,7 +384,7 @@ void file_download(session *sess) { sess->file->rest -= rlen; sess->file->package_rest -= rlen; if (!sess->file->rest) { - print_log(stdout, pl_info, "File %s is downloaded from the server\n", + print_log(stdout, pl_success, "File %s is downloaded from the server\n", sess->file->name); clear_file_from_sess(sess); sess->state = OP_WAIT; @@ -402,10 +400,10 @@ void file_download(session *sess) { { \ int res = write(dest_d, buf, len); \ if (res == -1) { \ - session_send_string( \ - sess, "There is an error sending the file named \"%s\"\n"); \ + session_send_string(sess, \ + "There is an error sending the file name \"%s\"\n"); \ char *err_mes = strerror(errno); \ - print_log(stdout, pl_error, "Error uploading the file \"%s\": %s\n", \ + print_log(stdout, pl_fail, "Fail while uploading the file \"%s\": %s\n", \ sess->file->name, err_mes); \ close(dest_d); \ unlink(sess->file->path); /* remove file */ \ @@ -425,7 +423,7 @@ void file_upload(session *sess) { if (rlen == 0) { if (sess->file->rest) { - print_log(stdout, pl_error, "Error uploading file %s!\n", + print_log(stdout, pl_fail, "Fail while uploading file %s!\n", sess->file->name); unlink(sess->file->path); /* remove file */ clear_file_from_sess(sess); @@ -460,7 +458,7 @@ void file_upload(session *sess) { sess->file->package_rest = fpd->package_size - rlen; break; case sig_cancel: - print_log(stdout, pl_error, "Upload of %s is cancelled!\n", + print_log(stdout, pl_fail, "Upload of %s is cancelled!\n", sess->file->name); unlink(sess->file->path); /* remove file */ clear_file_from_sess(sess); @@ -479,7 +477,7 @@ void file_upload(session *sess) { } fin: if (!sess->file->rest) { - print_log(stdout, pl_info, "File %s is uploaded to the server\n", + print_log(stdout, pl_success, "File %s is uploaded to the server\n", sess->file->name); session_send_string(sess, "finished\n"); sess->state = OP_UPLOAD_DESCRIPTION; diff --git a/src/components/utils/utils.c b/src/components/utils/utils.c index 0a40fd6..43b61de 100644 --- a/src/components/utils/utils.c +++ b/src/components/utils/utils.c @@ -1,9 +1,63 @@ #include "utils.h" +#include +#include +#include #include #include #include #include #include +#include + +#define LOGFILE_NAME "bbs-server.log" +/* COLORS */ +#define INFO_COLOR "\033[0m" +#define WARN_COLOR "\033[0m\033[33m" +#define ERR_COLOR "\033[0m\033[31m" +#define FATAL_COLOR "\033[0m\033[31m\033[1m" +#define FATAL_COLOR "\033[0m\033[31m\033[1m" +#define SUCCESS_COLOR "\033[0m\033[32m" +#define FAIL_COLOR "\033[0m\033[35m" + +static struct { + int fd; +} file; + +int open_log_file(char *path, int *_fd) { + int fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0666); + if (fd == -1) { + return errno; + } + *_fd = fd; + return 0; +} + +void close_log_file() { close(file.fd); } + +/* TODO: create recursive backups 5 times */ +int init_log_file() { + int fd; + int res = open_log_file(LOGFILE_NAME, &fd); + if (res == EEXIST) { + int res = open_log_file(LOGFILE_NAME ".old", &fd); + if (res == EEXIST) { + unlink(LOGFILE_NAME ".old"); + } else { + close(fd); + } + rename(LOGFILE_NAME, LOGFILE_NAME ".old"); + res = open_log_file(LOGFILE_NAME, &fd); + if (res != 0) { + return -1; + } + } + file.fd = fd; + return fd; +} + +int write_into_log_file(char *fmt, va_list args) { + return vdprintf(file.fd, fmt, args); +} int print_log(FILE *output, enum pl_type type, const char *format_message, ...) { @@ -15,24 +69,39 @@ int print_log(FILE *output, enum pl_type type, const char *format_message, va_list args; sprintf(date_preffix, "[%s] ", ctime(&t)); strftime(date_preffix, 128, "[%d.%m.%y %T]", tm); + const char *tcolor; switch (type) { case pl_info: - uff_str = "%s %s"; + uff_str = "%s%s %s"; + tcolor = INFO_COLOR; break; case pl_warning: - uff_str = "%s Warning: %s"; + uff_str = "%s%s Warning: %s"; + tcolor = WARN_COLOR; break; case pl_error: - uff_str = "%s Error: %s"; + uff_str = "%s%s Error: %s"; + tcolor = ERR_COLOR; break; case pl_fatal: - uff_str = "%s Fatal: %s"; + uff_str = "%s%s Fatal: %s"; + tcolor = FATAL_COLOR; + break; + case pl_success: + uff_str = "%s%s %s"; + tcolor = SUCCESS_COLOR; + break; + case pl_fail: + uff_str = "%s%s Fail: %s"; + tcolor = FAIL_COLOR; break; } - char *uf_str = malloc(strlen(date_preffix) + 16 + strlen(format_message) + 4); - sprintf(uf_str, uff_str, date_preffix, format_message); + char *uf_str = malloc(strlen(date_preffix) + 32 + strlen(format_message) + 4); + sprintf(uf_str, uff_str, tcolor, date_preffix, format_message); va_start(args, format_message); ret = vfprintf(output, uf_str, args); + write_into_log_file(uf_str + strlen(tcolor), args); + free(uf_str); va_end(args); return ret; } \ No newline at end of file diff --git a/src/components/utils/utils.h b/src/components/utils/utils.h index 940e6f4..ec7f1f4 100644 --- a/src/components/utils/utils.h +++ b/src/components/utils/utils.h @@ -4,11 +4,15 @@ #include enum pl_type { pl_info, + pl_success, + pl_fail, pl_warning, pl_error, pl_fatal, }; int print_log(FILE * output, enum pl_type type, const char *format_message, ...); +int init_log_file(); +void close_log_file(); #endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index 8058ba0..031452c 100644 --- a/src/main.c +++ b/src/main.c @@ -14,8 +14,10 @@ int main(int argc, char *argv[]) { init_db_connection(); server_data.ls = start_server(); /* TODO: display server port */ + init_log_file(); print_log(stdout, pl_info, "Server is started!\n"); server_main_loop(&server_data); db_close_connection(); + close_log_file(); return 0; } \ No newline at end of file