diff --git a/src/client.c b/src/client.c index b642bc2..fc4409e 100644 --- a/src/client.c +++ b/src/client.c @@ -7,7 +7,6 @@ #include #include -// TODO: синхронизовать c C++ void process_client_command(char *line, session *sess, server_data_t *s_d) { char arg_1[32]; char arg_2[32]; diff --git a/src/db.c b/src/db.c index b5dc93e..63917de 100644 --- a/src/db.c +++ b/src/db.c @@ -10,6 +10,8 @@ #define UNUSED(x) (void)(x) #define Q_LEN 128 +#define BIN 1 +#define TEXT 0 static PGconn *conn = NULL; static PGresult *res = NULL; @@ -91,7 +93,7 @@ int init_db_connection() { return exit_query(0); } -int db_user_auth(i_auth_t *credentials, o_auth_t *response) { +int32_t db_user_auth(i_auth_t *credentials, o_auth_t *response) { const char *paramValues[1]; paramValues[0] = credentials->name; @@ -108,13 +110,38 @@ int db_user_auth(i_auth_t *credentials, o_auth_t *response) { if (!strcmp(pass, credentials->pass)) { response->privileges = PQgetvalue(res, 0, 3)[0]; response->uid = atoi(PQgetvalue(res, 0, 0)); + clearRes(); + char u_buf[128]; + sprintf(u_buf, "UPDATE users SET last_login = NOW() WHERE id = %u", + response->uid); + res = PQexec(conn, u_buf); + if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res)) + return exit_query(3); return exit_query(0); } return exit_query(2); } -#define BIN 1 -#define TEXT 0 +int32_t db_user_create(i_db_user_create *args) { + const char *paramValues[3]; + paramValues[0] = args->uname; + paramValues[1] = args->pass; + paramValues[2] = args->email; + uint32_t ret_value; + + res = PQexecParams( + conn, + "INSERT INTO users (username, password, email, privileges, created_at, last_login)" + " VALUES ($1, $2, $3, 1, NOW(), NOW()) RETURNING id", + 3, NULL, paramValues, NULL, NULL, TEXT); + + if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res)) + return exit_query(-1); + + ret_value = atoi(PQgetvalue(res, 0, 0)); + clearRes(); + return ret_value; +} int32_t db_save_file(session *s) { const char *paramValues[6]; @@ -189,10 +216,11 @@ s_file_t *db_get_file(i_get_file_db *arg) { paramValues[0] = value; - sprintf(query, - "SELECT files.id, user_id, name, size, description, permissions, hash " - "FROM files JOIN users ON user_id = users.id WHERE files.%s = $1%n", - s_field, &q_len); + sprintf( + query, + "SELECT files.id, user_id, name, size, description, permissions, hash " + "FROM files JOIN users ON user_id = users.id WHERE files.%s = $1%n", + s_field, &q_len); res = PQexecParams(conn, query, 1, NULL, paramValues, NULL, NULL, TEXT); @@ -303,7 +331,7 @@ uint64_t db_get_files_data(i_get_files_db *arg, fl_t **fl_start, clearRes(); res = PQexec(conn, "SELECT COUNT(id) " - "FROM files "); // TODO: finish + "FROM files "); if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res)) return exit_query_2(0); diff --git a/src/db.h b/src/db.h index 19ba890..960f09f 100644 --- a/src/db.h +++ b/src/db.h @@ -20,7 +20,7 @@ typedef struct { typedef struct { uint32_t id; uint32_t user_id; - char name[64]; + char name[FILE_NAME_LEN]; } i_get_file_db; enum sort_direction { ASC, DESC }; @@ -28,17 +28,24 @@ enum sort_by { ID, NAME, CREATED_AT, USER_ID }; typedef struct { uint32_t user_id; // TODO: implement - char name[12]; // TODO: implement + char name[FILE_NAME_LEN]; // TODO: implement uint32_t limit; uint32_t offset; enum sort_by sort_by; enum sort_direction sort_direction; } i_get_files_db; +typedef struct { + char uname[UNAME_LEN]; + char pass[PASS_LEN]; + char email[EMAIL_LEN]; +} i_db_user_create; + int32_t init_db_connection(); int32_t db_save_file(session *s); int32_t db_user_auth(i_auth_t *credentials, o_auth_t *response); s_file_t *db_get_file(i_get_file_db *arg); uint64_t db_get_files_data(i_get_files_db *arg, fl_t **fl_start, uint64_t *full_count); +int32_t db_user_create(i_db_user_create *); #endif \ No newline at end of file diff --git a/src/deps.mk b/src/deps.mk index e602749..8c8f8b1 100644 --- a/src/deps.mk +++ b/src/deps.mk @@ -1,9 +1,10 @@ -client.o: src/client.c src/client.h src/main.h src/file_p.h src/session.h -db.o: src/db.c src/db.h src/main.h -file_p.o: src/file_p.c src/file_p.h src/main.h src/db.h \ +client.o: src/client.c src/client.h src/main.h src/types.h src/file_p.h \ + src/session.h +db.o: src/db.c src/db.h src/main.h src/types.h +file_p.o: src/file_p.c src/file_p.h src/main.h src/types.h src/db.h \ src/libs/murmur3/murmur3.h src/session.h -main.o: src/main.c src/main.h src/server.h src/db.h -server.o: src/server.c src/main.h src/session.h src/user.h -session.o: src/session.c src/session.h src/main.h src/client.h src/db.h \ - src/file_p.h src/user.h -user.o: src/user.c src/main.h src/session.h src/db.h +main.o: src/main.c src/main.h src/types.h src/server.h src/db.h +server.o: src/server.c src/main.h src/types.h src/session.h src/user.h +session.o: src/session.c src/session.h src/main.h src/types.h \ + src/client.h src/db.h src/file_p.h src/user.h +user.o: src/user.c src/db.h src/main.h src/types.h src/session.h diff --git a/src/main.h b/src/main.h index e559fff..9163b47 100644 --- a/src/main.h +++ b/src/main.h @@ -2,6 +2,7 @@ #define MAIN_H #include #include +#include "types.h" #define PORT 2000 #define MAX_CONNECTIONS 1024 #define INBUFSIZE 1024 @@ -24,7 +25,6 @@ enum sess_states { OP_WAIT, OP_UPLOAD, OP_UPLOAD_DESCRIPTION, - OP_REGISTER, ERR, FIN }; @@ -70,14 +70,14 @@ typedef struct session { unsigned long from_ip; unsigned short from_port; char buf[INBUFSIZE]; - int buf_used; + uint32_t buf_used; enum sess_states state; enum error_reason reason; char privileges; char *uname; uint32_t uid; - int fd; - int sd; /* session descriptor */ + int32_t fd; + int32_t sd; /* session descriptor */ s_file_t *file; fl_t *fl_start; fl_t *fl_current; diff --git a/src/session.c b/src/session.c index f189d1d..54a8841 100644 --- a/src/session.c +++ b/src/session.c @@ -17,7 +17,7 @@ session *make_new_session(int fd, struct sockaddr_in *from, char *wm); -int accept_client(int ls, session *connections[], char *wm) { +int32_t accept_client(int ls, session *connections[], char *wm) { int sd; struct sockaddr_in addr; socklen_t len = sizeof(addr); @@ -83,7 +83,6 @@ int session_do_read(session *sess, char **read_str) { return 1; } -// TODO: синхронизовать c C++ int query_extract_from_buf(session *sess, char **output_line) { char *line; int pos = -1; @@ -162,9 +161,6 @@ void perform_session_action(session *sess, char *line, server_data_t *s_d) { process_client_command(line, sess, s_d); } break; - case OP_REGISTER: - // TODO: - break; } /* } */ } diff --git a/src/types.h b/src/types.h new file mode 100644 index 0000000..61eb662 --- /dev/null +++ b/src/types.h @@ -0,0 +1,11 @@ +#ifndef D_TYPES_H +#define D_TYPES_H + +/* user */ +#define EMAIL_LEN 256 +#define UNAME_LEN 51 +#define PASS_LEN 51 +/* file */ +#define FILE_NAME_LEN 65 + +#endif \ No newline at end of file diff --git a/src/user.c b/src/user.c index 643ff73..709c43b 100644 --- a/src/user.c +++ b/src/user.c @@ -1,24 +1,43 @@ +#include "db.h" #include "main.h" #include "session.h" +#include #include #include #include -#include "db.h" -int process_user_name(char *uname, session *sess) { - if (!strncmp(uname, "exit", sizeof "exit")) { +int32_t create_user(session *sess, char *line) { + i_db_user_create p; + uint32_t privileges; + uint32_t res; + if (sscanf(line, "register %s %s %s", p.uname, p.pass, p.email) == 3) { + res = db_user_create(&p); + if (res) { + sess->state = OP_WAIT; + sess->uname = malloc(strlen(p.uname)); + strcpy(sess->uname, p.uname); + sess->uid = res; + sess->privileges = 1; // by default + session_send_string(sess, "ok"); + } + return res; + }; + return 0; +} + +uint32_t process_user_name(char *line, session *sess) { + if (!strncmp(line, "exit", sizeof "exit")) { sess->state = ERR; sess->reason = EXIT; session_send_string(sess, "Bye!"); return 1; } - if (!strncmp(uname, "register", sizeof "register"-1)) { - sess->state = OP_REGISTER; - return 2; + if (!strncmp(line, "register", sizeof "register" - 1)) { + return create_user(sess, line); } - if (!strncmp(uname, "anonymous", sizeof "anonymous")) { + if (!strncmp(line, "anonymous", sizeof "anonymous")) { sess->uname = malloc(sizeof "anonymous"); strcpy(sess->uname, "anonymous"); sess->state = OP_WAIT; @@ -26,8 +45,8 @@ int process_user_name(char *uname, session *sess) { return 3; } - sess->uname = malloc(strlen(uname) + 1); - strcpy(sess->uname, uname); + sess->uname = malloc(strlen(line) + 1); + strcpy(sess->uname, line); sess->state = OP_LOGIN_PSS; session_send_string(sess, "password> "); @@ -57,7 +76,6 @@ int login(session *sess, char *pass) { } } -// TODO: синхронизовать c C++ /* returns 1 if session needs to be closed, 0 - in the opposite case */ int process_error(session *sess) { if (sess->state == ERR) {