From c80e3e85312fe7bf76e808fd67d46b9784780b4c Mon Sep 17 00:00:00 2001 From: Pavel Solikov Date: Sun, 17 Feb 2019 15:25:14 +0300 Subject: [PATCH 01/11] Added protocol --- tcp/server/protocol.md | 142 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 tcp/server/protocol.md diff --git a/tcp/server/protocol.md b/tcp/server/protocol.md new file mode 100644 index 0000000..2444aac --- /dev/null +++ b/tcp/server/protocol.md @@ -0,0 +1,142 @@ +# Протокол взаимодействия в Bug tracker + +## Общий формат + +Символ, разделяющий сообщения - это \n, поэтому внутри сообщений его использоват нельзя. + +Первые 5 символов - код запроса, остальное до \n - тело запроса + +Последний символ кода - пробел + +Ответ на запрос начинается с того же кода, затем идёт 3 символа на код ошибки, а дальше тело запроса до \n + +Последний символ кода ошибки - тоже пробел + +Пользователь регистрируется один раз как разработчик или тестер + +Логины тестеров и разработчиков из одного множества + +### Коды ошибок: + +- OK - всё хорошо + +- UN - такого пользователя нет + +- UE - такой пользователь уже существует + +- NA - пользователь не авторизован + +- DN - разработчика с таким id нет + +- PN - проекта с таким id нет + +- BN - бага с таким id нет + +- BE - баг с таким id уже есть + +- BC - баг с таким id уже закрыт + +- BI - баг еще не исправили + +- BR - неверно сформулированный запрос + +## Запросы + +- **Регистрация тестера** + +Код - REGT + +Тело запроса - логин нового тестера + +Тело ответа - пустое + +Возможные ошибки: UE + +- **Регистрация разработчика** + +Код - REGD + +Тело запроса - логин нового разработчика + +Тело ответа - пустое + +Возможные ошибки: UE + +- **Авторизация** + +Код - AUTH + +Тело запроса - логин пользователя + +Тело ответа - + +Возможные ошибки: UN + +- **Список исправленных багов (тестеру)** + +Код - BCLS + +Тело запроса - пустое + +Тело ответа - список багов (пустое, если еще ничего не исправленно) + +Возможные ошибки: NA, BR (если запрос от dev) + +- **Список активных багов** + +Код - BACT + +Тело запроса - пустое + +Тело ответа - список багов (пустое, если еще ничего не исправленно) + +Возможные ошибки: NA, BR (если запрос от dev) + +- **Отправить новый баг (тестер)** + +Код - BREP + +Тело запроса - баг репорт + +Тело ответа - пустое + +Возможные ошибки: NA, BR (dev), DN, PN, BE + +- **Подтверждение или отклонение исправленного бага (тестер)** + +Код - BREV + +Тело запроса - bug_id|| + +Тело ответа - пустое + +Возможные ошибки: NA, BR (dev), BN, BI + +- **Список багов во всех проектах разработчика (с учетом закрытых)** + +Код - LIST + +Тело запроса - пустое + +Тело ответа - список багов (пустое, если нет багов ни в 1 проекте) + +Возможные ошибки: NA, BR(qa) + +- **Bugfix (разработчик)** + +Код - BFIX + +Тело запроса - bug_id + +Тело ответа - пустое + +Возможные ошибки: NA, BR(qa), BN, BC + + +### Баг репорт + +dev_id|proj_id|bug_id|bug_text| + +### Список багов + +proj_id1&bug_id1&bug_text1|proj_id2&bug_id2&bug_text2| From bcac782de10d6332142a1cb3ff7e4384d16ac342 Mon Sep 17 00:00:00 2001 From: Pavel Solikov Date: Sun, 17 Feb 2019 16:46:19 +0300 Subject: [PATCH 02/11] Fixed --- tcp/server/protocol.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tcp/server/protocol.md b/tcp/server/protocol.md index 2444aac..98dc658 100644 --- a/tcp/server/protocol.md +++ b/tcp/server/protocol.md @@ -38,7 +38,9 @@ - BI - баг еще не исправили -- BR - неверно сформулированный запрос +- PE - неверно сформулированный запрос + +- BR - неправильный запрос ## Запросы @@ -50,7 +52,7 @@ Тело ответа - пустое -Возможные ошибки: UE +Возможные ошибки: UE, BR - **Регистрация разработчика** @@ -60,7 +62,7 @@ Тело ответа - пустое -Возможные ошибки: UE +Возможные ошибки: UE, BR - **Авторизация** @@ -70,7 +72,7 @@ Тело ответа - -Возможные ошибки: UN +Возможные ошибки: UN, BR - **Список исправленных багов (тестеру)** @@ -80,7 +82,7 @@ Тело ответа - список багов (пустое, если еще ничего не исправленно) -Возможные ошибки: NA, BR (если запрос от dev) +Возможные ошибки: NA, PE (если запрос от dev), BR - **Список активных багов** @@ -90,7 +92,7 @@ Тело ответа - список багов (пустое, если еще ничего не исправленно) -Возможные ошибки: NA, BR (если запрос от dev) +Возможные ошибки: NA, PE (если запрос от dev), BR - **Отправить новый баг (тестер)** @@ -100,7 +102,7 @@ Тело ответа - пустое -Возможные ошибки: NA, BR (dev), DN, PN, BE +Возможные ошибки: NA, PE (dev), DN, PN, BE, BR - **Подтверждение или отклонение исправленного бага (тестер)** @@ -110,7 +112,7 @@ Тело ответа - пустое -Возможные ошибки: NA, BR (dev), BN, BI +Возможные ошибки: NA, PE (dev), BN, BI, BR - **Список багов во всех проектах разработчика (с учетом закрытых)** @@ -120,7 +122,7 @@ Тело ответа - список багов (пустое, если нет багов ни в 1 проекте) -Возможные ошибки: NA, BR(qa) +Возможные ошибки: NA, PE(qa), BR - **Bugfix (разработчик)** @@ -130,7 +132,7 @@ Тело ответа - пустое -Возможные ошибки: NA, BR(qa), BN, BC +Возможные ошибки: NA, PE(qa), BN, BC, BR ### Баг репорт From 73d1ba565750b1e12c5e033ccf08db598a11c297 Mon Sep 17 00:00:00 2001 From: Pavel Solikov Date: Tue, 19 Feb 2019 23:54:02 +0300 Subject: [PATCH 03/11] Server code --- tcp/server/CMakeLists.txt | 40 ++++++++ tcp/server/main.c | 190 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 tcp/server/CMakeLists.txt create mode 100644 tcp/server/main.c diff --git a/tcp/server/CMakeLists.txt b/tcp/server/CMakeLists.txt new file mode 100644 index 0000000..2424c49 --- /dev/null +++ b/tcp/server/CMakeLists.txt @@ -0,0 +1,40 @@ +#[[ +cmake_minimum_required(VERSION 3.13) +project(server C) + +set(CMAKE_C_STANDARD 11) + +add_executable(server main.c) + +]] + +#### +# +#cmake_minimum_required(VERSION 3.8) +#project(msync_server) +#FIND_PACKAGE(PkgConfig) +#PKG_CHECK_MODULES(GLIB glib-2.0) +#include_directories(${GLIB_INCLUDE_DIRS}) +#link_directories(${GLIB_LIBRARY_DIRS}) +#add_definitions(${GLIB_CFLAGS_OTHER}) +#set(CMAKE_C_STANDARD 11) +#set(SOURCE_FILES main.c) +#add_executable(server ${SOURCE_FILES} ${Glib_LIBRARY}) + +###### + +cmake_minimum_required(VERSION 3.1) +project(server) +#CFLAGS= +set(CMAKE_C_FLAGS "-L/opt/local/lib -I/opt/local/include") + +include(FindPkgConfig) +pkg_check_modules(GLIB glib-2.0 REQUIRED) +include_directories(${GLIB_INCLUDE_DIRS}) + +set(SOURCE_FILES main.c) +#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread") +#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -iglib-2.0") + +add_executable(${PROJECT_NAME} ${SOURCE_FILES}) +target_link_libraries(${PROJECT_NAME} ${GLIB_LIBRARIES}) \ No newline at end of file diff --git a/tcp/server/main.c b/tcp/server/main.c new file mode 100644 index 0000000..7bf14ee --- /dev/null +++ b/tcp/server/main.c @@ -0,0 +1,190 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define srverror(msg) fprintf(stderr, "tid %llu: %s Error: %s\n",\ + (unsigned long long) pthread_self(), msg, strerror(errno)) +#define srvprintf(msg) printf("tid %llu: %s", (unsigned long long) pthread_self(), msg) +#define TM_PRINTF(f_, ...) srvprintf((f_), ##__VA_ARGS__) +#define TM_PRINTF_TH(f_, ...) TM_PRINTF((printf(f_)), ##__VA_ARGS__) + +typedef struct Server { + int sockfd; + GHashTable *clients; +// GArray *clients; + pthread_mutex_t clients_array_mutex; +} Server_t; + +typedef struct Client_arg { + int newsockfd; + Server_t *server; +} Client_arg_t; + +typedef struct Client { + char *name; + pthread_t t; +} Client_t; + +void clients_iterator(gpointer key, gpointer value, gpointer user_data) { + //мб нужно kill + int a = pthread_join(*(pthread_t *) key, NULL); + perror("pep"); + printf("on delete:%d\n", a); +} + +void stop_server(Server_t *server) { + pthread_mutex_lock(&server->clients_array_mutex); + g_hash_table_foreach(server->clients, (GHFunc) clients_iterator, NULL); +// for (int i = 0; i < server->clients->len; ++i) { +// //мб стоит хранить только треды и иметь мап из имен в треды +// GList g_hash_table_get_keys(server->clients); +// Client_t *c = g_array_index(server->clients, Client_t *, i); +// pthread_join(c->t, NULL); +// } + g_hash_table_destroy(server->clients); + pthread_mutex_unlock(&server->clients_array_mutex); +} + +void delete_client(Server_t *server, pthread_t *pthread) { + pthread_mutex_lock(&server->clients_array_mutex); +// g_set_ +// server->clients; + pthread_mutex_unlock(&server->clients_array_mutex); +} + +void *client_worker(void *argp) { + ssize_t n; + Client_arg_t *cl_arg = (Client_arg_t *) argp; + char buffer[256]; + + if (cl_arg->newsockfd < 0) { + srverror("ERROR on accept"); + return 0; + } + + /* If connection is established then start communicating */ + bzero(buffer, 256); + n = read(cl_arg->newsockfd, buffer, 255); // recv on Windows + + if (n < 0) { + srverror("ERROR reading from socket"); + return 0; + } + + printf("tid %llu: %s: %s\n", (unsigned long long) pthread_self(), "Here is the message", buffer); +// TM_PRINTF_TH("Here is the message: %s\n", buffer); + + /* Write a response to the client */ + n = write(cl_arg->newsockfd, "I got your message", 18); // send on Windows + + if (n < 0) { + srverror("ERROR writing to socket"); + return 0; + } + return 0; +} + +void create_client(Server_t *server, Client_arg_t *client_arg) { + pthread_t pthread; + pthread_create(&pthread, NULL, client_worker, client_arg); + pthread_mutex_lock(&server->clients_array_mutex); + g_hash_table_add(server->clients, &pthread); + pthread_mutex_unlock(&server->clients_array_mutex); +} + +void *server_listener(void *argp) { + int newsockfd; + Server_t *server = (Server_t *) argp; + socklen_t clilen; + struct sockaddr_in cli_addr; + clilen = sizeof(cli_addr); + + while (g_hash_table_size(server->clients) < 10) { + newsockfd = accept(server->sockfd, (struct sockaddr *) &cli_addr, &clilen); + pthread_t pthread; + const pthread_attr_t *attr; + Client_arg_t cl_arg; + bzero(&cl_arg, sizeof(cl_arg)); + cl_arg.server = server; + cl_arg.newsockfd = newsockfd; + create_client(server, &cl_arg); + } + stop_server(server); + printf("Clients: %d", g_hash_table_size(server->clients)); + return 0; +} + +//todo сделать main с kill/list +int main(int argc, char *argv[]) { + Server_t server; + int newsockfd; + uint16_t portno; + unsigned int clilen; + char buffer[256]; + struct sockaddr_in serv_addr, cli_addr; + ssize_t n; + + bzero(&server, sizeof(server)); + /* First call to socket() function */ + server.sockfd = socket(AF_INET, SOCK_STREAM, 0); + server.clients = g_hash_table_new(g_int64_hash, g_int64_equal); + pthread_mutex_init(&server.clients_array_mutex, NULL); + + if (server.sockfd < 0) { + srverror("ERROR opening socket"); + exit(1); + } + + /* Initialize socket structure */ + bzero((char *) &serv_addr, sizeof(serv_addr)); + portno = 5002; + + int enable = 1; + if (setsockopt(server.sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) + srverror("setsockopt(SO_REUSEADDR) failed"); + + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(portno); + + /* Now bind the host address using bind() call.*/ + if (bind(server.sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { + srverror("ERROR on binding"); + exit(1); + } + + /* Now start listening for the clients, here process will + * go in sleep mode and will wait for the incoming connection + */ + + listen(server.sockfd, 5); + clilen = sizeof(cli_addr); + + pthread_t server_pthread; + pthread_create(&server_pthread, NULL, server_listener, &server); + while (1) { + printf("len(clients)=%d | Available command: \"exit\", \"list\": ", g_hash_table_size(server.clients)); + + bzero(buffer, 256); + fgets(buffer, 255, stdin); + if (!strcmp(buffer, "exit") || !strcmp(buffer, "exit\n")) { + stop_server(&server); + pthread_kill(server_pthread, 0); + shutdown(server.sockfd, SHUT_RDWR); + close(server.sockfd); + exit(0); + } else { + printf("Unknown command\n"); + } + } +} + +int main1(int argc, char **argv) { + return 0; +} \ No newline at end of file From 862fb73f64887ef1b51647560e238ed8a7b2d660 Mon Sep 17 00:00:00 2001 From: Pavel Solikov Date: Wed, 20 Feb 2019 02:56:37 +0300 Subject: [PATCH 04/11] Some fixes --- tcp/server/main.c | 139 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 125 insertions(+), 14 deletions(-) diff --git a/tcp/server/main.c b/tcp/server/main.c index 7bf14ee..df39cb3 100644 --- a/tcp/server/main.c +++ b/tcp/server/main.c @@ -17,7 +17,7 @@ typedef struct Server { int sockfd; GHashTable *clients; -// GArray *clients; + GHashTable *logins; pthread_mutex_t clients_array_mutex; } Server_t; @@ -33,31 +33,91 @@ typedef struct Client { void clients_iterator(gpointer key, gpointer value, gpointer user_data) { //мб нужно kill - int a = pthread_join(*(pthread_t *) key, NULL); - perror("pep"); - printf("on delete:%d\n", a); + int a = pthread_kill(*(pthread_t *) key, NULL); } void stop_server(Server_t *server) { pthread_mutex_lock(&server->clients_array_mutex); g_hash_table_foreach(server->clients, (GHFunc) clients_iterator, NULL); -// for (int i = 0; i < server->clients->len; ++i) { -// //мб стоит хранить только треды и иметь мап из имен в треды -// GList g_hash_table_get_keys(server->clients); -// Client_t *c = g_array_index(server->clients, Client_t *, i); -// pthread_join(c->t, NULL); -// } g_hash_table_destroy(server->clients); pthread_mutex_unlock(&server->clients_array_mutex); } -void delete_client(Server_t *server, pthread_t *pthread) { +void delete_client(Server_t *server) { + //todo pthread_mutex_lock(&server->clients_array_mutex); // g_set_ // server->clients; pthread_mutex_unlock(&server->clients_array_mutex); } +gboolean get_val(gpointer key, gpointer value, gpointer user_data) { + gchar *pkey = (gchar *) key; + gchar *pdata = (gchar *) user_data; + printf("get_val: %s and %s \n", pkey, pdata); + return !strcmp(pkey, pdata); +} + +int reg_or_login(Client_arg_t *cl_arg){ + ssize_t n; + char buffer[256]; + bzero(buffer, 256); + n = read(cl_arg->newsockfd, buffer, 255); // recv on Windows + + if (n < 0) { + srverror("ERROR reading from socket"); + return -1; + } else if (n == 0) { + //todo + } + + printf("tid %llu: %s: %s\n", (unsigned long long) pthread_self(), "Frst msg", buffer); + if (!strncmp(buffer, "REGT ", 5)) { + int i = 5; + char login[256]; + for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { + login[i - 5] = buffer[i]; + } + pthread_mutex_lock(&cl_arg->server->clients_array_mutex); + gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); + pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); + if (p == NULL) { + printf("REGT: free login\n"); + pthread_mutex_lock(&cl_arg->server->clients_array_mutex); + printf("Inserting data: %s", login); + g_hash_table_insert(cl_arg->server->logins, g_strdup(login), "T"); + pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); + bzero(buffer, 256); + strcpy(buffer, "REGT OK \n"); + printf("Send: %s\n", buffer); + n = write(cl_arg->newsockfd, buffer, strlen(buffer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return 0; + } + } else { + printf("REGT: login already in use\n"); + bzero(buffer, 256); + strcpy(buffer, "REGT UE \n"); + printf("Send: %s\n", buffer); + n = write(cl_arg->newsockfd, buffer, strlen(buffer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return 0; + } + } + } else if (!strncmp(buffer, "REGD ", 5)) { + + } else { + srverror("Bad registration\n"); + close(cl_arg->newsockfd); + delete_client(cl_arg); +// bzero(buffer, 256); +// strcpy(buffer, "BR \n"); +// n = write(cl_arg->newsockfd, "", ); + } +} + void *client_worker(void *argp) { ssize_t n; Client_arg_t *cl_arg = (Client_arg_t *) argp; @@ -75,10 +135,57 @@ void *client_worker(void *argp) { if (n < 0) { srverror("ERROR reading from socket"); return 0; + } else if (n == 0) { + //todo } - printf("tid %llu: %s: %s\n", (unsigned long long) pthread_self(), "Here is the message", buffer); -// TM_PRINTF_TH("Here is the message: %s\n", buffer); + printf("tid %llu: %s: %s\n", (unsigned long long) pthread_self(), "Frst msg", buffer); + if (!strncmp(buffer, "REGT ", 5)) { + int i = 5; + char login[256]; + for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { + login[i - 5] = buffer[i]; + } + pthread_mutex_lock(&cl_arg->server->clients_array_mutex); + gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); + pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); + int tester = 0; + if (p == NULL) { + printf("REGT: free login\n"); + pthread_mutex_lock(&cl_arg->server->clients_array_mutex); + printf("Inserting data: %s", login); + g_hash_table_insert(cl_arg->server->logins, g_strdup(login), "T"); + pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); + bzero(buffer, 256); + strcpy(buffer, "REGT OK \n"); + printf("Send: %s\n", buffer); + n = write(cl_arg->newsockfd, buffer, strlen(buffer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return 0; + } + tester = 1; + } else { + printf("REGT: login already in use\n"); + bzero(buffer, 256); + strcpy(buffer, "REGT UE \n"); + printf("Send: %s\n", buffer); + n = write(cl_arg->newsockfd, buffer, strlen(buffer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return 0; + } + } + } else if (!strncmp(buffer, "REGD ", 5)) { + + } else { + srverror("Bad registration\n"); + close(cl_arg->newsockfd); + delete_client(cl_arg); +// bzero(buffer, 256); +// strcpy(buffer, "BR \n"); +// n = write(cl_arg->newsockfd, "", ); + } /* Write a response to the client */ n = write(cl_arg->newsockfd, "I got your message", 18); // send on Windows @@ -105,8 +212,11 @@ void *server_listener(void *argp) { struct sockaddr_in cli_addr; clilen = sizeof(cli_addr); - while (g_hash_table_size(server->clients) < 10) { + while (1) { newsockfd = accept(server->sockfd, (struct sockaddr *) &cli_addr, &clilen); + if (newsockfd < 0) { + continue; + } pthread_t pthread; const pthread_attr_t *attr; Client_arg_t cl_arg; @@ -134,6 +244,7 @@ int main(int argc, char *argv[]) { /* First call to socket() function */ server.sockfd = socket(AF_INET, SOCK_STREAM, 0); server.clients = g_hash_table_new(g_int64_hash, g_int64_equal); + server.logins = g_hash_table_new(g_str_hash, g_str_equal); pthread_mutex_init(&server.clients_array_mutex, NULL); if (server.sockfd < 0) { From b2d60ee83ef13355f04b1cec4fa5ec2de5cb3077 Mon Sep 17 00:00:00 2001 From: Pavel Solikov Date: Fri, 22 Feb 2019 14:39:28 +0300 Subject: [PATCH 05/11] Added some code --- tcp/server/main.c | 254 ++++++++++++++++++++++++++-------------------- 1 file changed, 145 insertions(+), 109 deletions(-) diff --git a/tcp/server/main.c b/tcp/server/main.c index df39cb3..3d50ec8 100644 --- a/tcp/server/main.c +++ b/tcp/server/main.c @@ -58,63 +58,161 @@ gboolean get_val(gpointer key, gpointer value, gpointer user_data) { return !strcmp(pkey, pdata); } -int reg_or_login(Client_arg_t *cl_arg){ +//0,1 - зарегались успешно +//-1 - ошибка +int reg_or_login(Client_arg_t *cl_arg) { ssize_t n; char buffer[256]; bzero(buffer, 256); - n = read(cl_arg->newsockfd, buffer, 255); // recv on Windows - - if (n < 0) { - srverror("ERROR reading from socket"); - return -1; - } else if (n == 0) { - //todo - } - - printf("tid %llu: %s: %s\n", (unsigned long long) pthread_self(), "Frst msg", buffer); - if (!strncmp(buffer, "REGT ", 5)) { - int i = 5; - char login[256]; - for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { - login[i - 5] = buffer[i]; + while (1) { + n = read(cl_arg->newsockfd, buffer, 255); // recv on Windows + if (n < 0) { + srverror("ERROR reading from socket"); + return -1; + } else if (n == 0) { + printf("Client's socket closed\n"); + return -1; } - pthread_mutex_lock(&cl_arg->server->clients_array_mutex); - gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); - pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); - if (p == NULL) { - printf("REGT: free login\n"); + printf("tid %llu: %s: %s\n", (unsigned long long) pthread_self(), "Client's registration msg:", buffer); + if (!strncmp(buffer, "REGT ", 5)) { + int i = 5; + char login[256]; + for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { + login[i - 5] = buffer[i]; + } pthread_mutex_lock(&cl_arg->server->clients_array_mutex); - printf("Inserting data: %s", login); - g_hash_table_insert(cl_arg->server->logins, g_strdup(login), "T"); + gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); - bzero(buffer, 256); - strcpy(buffer, "REGT OK \n"); - printf("Send: %s\n", buffer); - n = write(cl_arg->newsockfd, buffer, strlen(buffer)); - if (n < 0) { - srverror("ERROR writing to socket"); + if (p == NULL) { + printf("REGT: free login\n"); + pthread_mutex_lock(&cl_arg->server->clients_array_mutex); + printf("Inserting data: %s", login); + g_hash_table_insert(cl_arg->server->logins, g_strdup(login), "T"); + pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); + bzero(buffer, 256); + strcpy(buffer, "REGT OK \n"); + printf("Send: %s\n", buffer); + n = write(cl_arg->newsockfd, buffer, strlen(buffer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return -1; + } else if (n == 0) { + printf("Client's socket closed\n"); + return -1; + } + return 1; + } else { + printf("REGT: login already in use\n"); + bzero(buffer, 256); + strcpy(buffer, "REGT UE \n"); + printf("Send: %s\n", buffer); + n = write(cl_arg->newsockfd, buffer, strlen(buffer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return -1; + } else if (n == 0) { + printf("Client's socket closed\n"); + return -1; + } + } + } else if (!strncmp(buffer, "REGD ", 5)) { + int i = 5; + char login[256]; + for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { + login[i - 5] = buffer[i]; + } + pthread_mutex_lock(&cl_arg->server->clients_array_mutex); + gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); + pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); + if (p == NULL) { + printf("REGD: free login\n"); + pthread_mutex_lock(&cl_arg->server->clients_array_mutex); + printf("Inserting data: %s", login); + g_hash_table_insert(cl_arg->server->logins, g_strdup(login), "D"); + pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); + bzero(buffer, 256); + strcpy(buffer, "REGD OK \n"); + printf("Send: %s\n", buffer); + n = write(cl_arg->newsockfd, buffer, strlen(buffer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return -1; + } else if (n == 0) { + printf("Client's socket closed\n"); + return -1; + } return 0; + } else { + printf("REGD: login already in use\n"); + bzero(buffer, 256); + strcpy(buffer, "REGD UE \n"); + printf("Send: %s\n", buffer); + n = write(cl_arg->newsockfd, buffer, strlen(buffer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return -1; + } else if (n == 0) { + printf("Client's socket closed\n"); + return -1; + } + } + } else if (!strncmp(buffer, "AUTH ", 5)) { + int i = 5; + char login[256]; + for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { + login[i - 5] = buffer[i]; + } + pthread_mutex_lock(&cl_arg->server->clients_array_mutex); + gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); + pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); + if (p == NULL) { + printf("AUTH: no such login\n"); + bzero(buffer, 256); + strcpy(buffer, "AUTH UN \n"); + printf("Send: %s\n", buffer); + n = write(cl_arg->newsockfd, buffer, strlen(buffer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return -1; + } else if (n == 0) { + printf("Client's socket closed\n"); + return -1; + } + } else { + printf("AUTH: hashtable item:"); + printf(p); + printf("\n"); + printf("AUTH: found login\n"); + bzero(buffer, 256); + int kind; + if (!strcmp((char *) p, "T")) { + strcpy(buffer, "AUTH OK T\n"); + kind = 1; + } else { + strcpy(buffer, "AUTH OK D\n"); + kind = 0; + } + printf("Send: %s\n", buffer); + n = write(cl_arg->newsockfd, buffer, strlen(buffer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return -1; + } else if (n == 0) { + printf("Client's socket closed\n"); + return -1; + } + return kind; } } else { - printf("REGT: login already in use\n"); + srverror("Bad registration\n"); + close(cl_arg->newsockfd); + //todo + delete_client(cl_arg); bzero(buffer, 256); - strcpy(buffer, "REGT UE \n"); - printf("Send: %s\n", buffer); + strcpy(buffer, "BR \n"); n = write(cl_arg->newsockfd, buffer, strlen(buffer)); - if (n < 0) { - srverror("ERROR writing to socket"); - return 0; - } + return -1; } - } else if (!strncmp(buffer, "REGD ", 5)) { - - } else { - srverror("Bad registration\n"); - close(cl_arg->newsockfd); - delete_client(cl_arg); -// bzero(buffer, 256); -// strcpy(buffer, "BR \n"); -// n = write(cl_arg->newsockfd, "", ); } } @@ -128,72 +226,10 @@ void *client_worker(void *argp) { return 0; } - /* If connection is established then start communicating */ - bzero(buffer, 256); - n = read(cl_arg->newsockfd, buffer, 255); // recv on Windows - - if (n < 0) { - srverror("ERROR reading from socket"); - return 0; - } else if (n == 0) { - //todo - } - - printf("tid %llu: %s: %s\n", (unsigned long long) pthread_self(), "Frst msg", buffer); - if (!strncmp(buffer, "REGT ", 5)) { - int i = 5; - char login[256]; - for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { - login[i - 5] = buffer[i]; - } - pthread_mutex_lock(&cl_arg->server->clients_array_mutex); - gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); - pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); - int tester = 0; - if (p == NULL) { - printf("REGT: free login\n"); - pthread_mutex_lock(&cl_arg->server->clients_array_mutex); - printf("Inserting data: %s", login); - g_hash_table_insert(cl_arg->server->logins, g_strdup(login), "T"); - pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); - bzero(buffer, 256); - strcpy(buffer, "REGT OK \n"); - printf("Send: %s\n", buffer); - n = write(cl_arg->newsockfd, buffer, strlen(buffer)); - if (n < 0) { - srverror("ERROR writing to socket"); - return 0; - } - tester = 1; - } else { - printf("REGT: login already in use\n"); - bzero(buffer, 256); - strcpy(buffer, "REGT UE \n"); - printf("Send: %s\n", buffer); - n = write(cl_arg->newsockfd, buffer, strlen(buffer)); - if (n < 0) { - srverror("ERROR writing to socket"); - return 0; - } - } - } else if (!strncmp(buffer, "REGD ", 5)) { - - } else { - srverror("Bad registration\n"); - close(cl_arg->newsockfd); - delete_client(cl_arg); -// bzero(buffer, 256); -// strcpy(buffer, "BR \n"); -// n = write(cl_arg->newsockfd, "", ); - } + int kind = reg_or_login(cl_arg); - /* Write a response to the client */ - n = write(cl_arg->newsockfd, "I got your message", 18); // send on Windows + if (kind == -1) return 0; - if (n < 0) { - srverror("ERROR writing to socket"); - return 0; - } return 0; } From 496b333729e8917f92e4405285c2c877ec339c91 Mon Sep 17 00:00:00 2001 From: Pavel Solikov Date: Fri, 22 Feb 2019 18:59:54 +0300 Subject: [PATCH 06/11] Correct BREP --- tcp/server/main.c | 240 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 220 insertions(+), 20 deletions(-) diff --git a/tcp/server/main.c b/tcp/server/main.c index 3d50ec8..7df8a46 100644 --- a/tcp/server/main.c +++ b/tcp/server/main.c @@ -18,7 +18,12 @@ typedef struct Server { int sockfd; GHashTable *clients; GHashTable *logins; - pthread_mutex_t clients_array_mutex; + GHashTable *devs; + GHashTable *bugs; + GHashTable *closed_bugs; + pthread_mutex_t client_mutex; + pthread_mutex_t logins_mutex; + pthread_mutex_t devs_mutex; } Server_t; typedef struct Client_arg { @@ -31,24 +36,59 @@ typedef struct Client { pthread_t t; } Client_t; +//typedef struct Project { +// char *id; +// GHashTable +//} Project_t; + +typedef struct Dev { + char *id; + GHashTable *projects; +} Dev_t; + +typedef struct Bug { + char *id; + int closed; + int fixed; + char *proj_id; + Dev_t *dev; + char *text; +} Bug_t; + +void dev_session(Client_arg_t *pArg); + +void qa_session(Client_arg_t *cl_arg); + +void process_list_closed_bugs(Client_arg_t *pArg); + +void process_list_active_bugs(Client_arg_t *pArg); + +void process_report_new_bug(Client_arg_t *cl_arg, const char *buffer); + +void process_review_bug_fix(Client_arg_t *pArg); + +void printf_tid(char *msg, char *buffer) { + printf("tid %llu: %s: %s\n", (unsigned long long) pthread_self(), msg, buffer); +} + void clients_iterator(gpointer key, gpointer value, gpointer user_data) { //мб нужно kill int a = pthread_kill(*(pthread_t *) key, NULL); } void stop_server(Server_t *server) { - pthread_mutex_lock(&server->clients_array_mutex); + pthread_mutex_lock(&server->client_mutex); g_hash_table_foreach(server->clients, (GHFunc) clients_iterator, NULL); g_hash_table_destroy(server->clients); - pthread_mutex_unlock(&server->clients_array_mutex); + pthread_mutex_unlock(&server->client_mutex); } void delete_client(Server_t *server) { //todo - pthread_mutex_lock(&server->clients_array_mutex); + pthread_mutex_lock(&server->client_mutex); // g_set_ // server->clients; - pthread_mutex_unlock(&server->clients_array_mutex); + pthread_mutex_unlock(&server->client_mutex); } gboolean get_val(gpointer key, gpointer value, gpointer user_data) { @@ -67,28 +107,28 @@ int reg_or_login(Client_arg_t *cl_arg) { while (1) { n = read(cl_arg->newsockfd, buffer, 255); // recv on Windows if (n < 0) { - srverror("ERROR reading from socket"); + srverror("reg_or_login: ERROR reading from socket"); return -1; } else if (n == 0) { printf("Client's socket closed\n"); return -1; } - printf("tid %llu: %s: %s\n", (unsigned long long) pthread_self(), "Client's registration msg:", buffer); + printf_tid("Client's registration msg:", buffer); if (!strncmp(buffer, "REGT ", 5)) { int i = 5; char login[256]; for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { login[i - 5] = buffer[i]; } - pthread_mutex_lock(&cl_arg->server->clients_array_mutex); + pthread_mutex_lock(&cl_arg->server->logins_mutex); gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); - pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); + pthread_mutex_unlock(&cl_arg->server->logins_mutex); if (p == NULL) { printf("REGT: free login\n"); - pthread_mutex_lock(&cl_arg->server->clients_array_mutex); + pthread_mutex_lock(&cl_arg->server->logins_mutex); printf("Inserting data: %s", login); g_hash_table_insert(cl_arg->server->logins, g_strdup(login), "T"); - pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); + pthread_mutex_unlock(&cl_arg->server->logins_mutex); bzero(buffer, 256); strcpy(buffer, "REGT OK \n"); printf("Send: %s\n", buffer); @@ -121,15 +161,24 @@ int reg_or_login(Client_arg_t *cl_arg) { for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { login[i - 5] = buffer[i]; } - pthread_mutex_lock(&cl_arg->server->clients_array_mutex); + pthread_mutex_lock(&cl_arg->server->logins_mutex); gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); - pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); + pthread_mutex_unlock(&cl_arg->server->logins_mutex); if (p == NULL) { printf("REGD: free login\n"); - pthread_mutex_lock(&cl_arg->server->clients_array_mutex); + pthread_mutex_lock(&cl_arg->server->logins_mutex); printf("Inserting data: %s", login); g_hash_table_insert(cl_arg->server->logins, g_strdup(login), "D"); - pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); + pthread_mutex_unlock(&cl_arg->server->logins_mutex); + //create new dev + pthread_mutex_lock(&cl_arg->server->devs_mutex); + //todo delete для Dev + Dev_t *dev = malloc(sizeof(*dev)); + dev->id = login; + dev->projects = g_hash_table_new(g_str_hash, g_str_equal); + //test proj + g_hash_table_insert(dev->projects, "1", ""); + pthread_mutex_unlock(&cl_arg->server->devs_mutex); bzero(buffer, 256); strcpy(buffer, "REGD OK \n"); printf("Send: %s\n", buffer); @@ -162,9 +211,9 @@ int reg_or_login(Client_arg_t *cl_arg) { for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { login[i - 5] = buffer[i]; } - pthread_mutex_lock(&cl_arg->server->clients_array_mutex); + pthread_mutex_lock(&cl_arg->server->logins_mutex); gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); - pthread_mutex_unlock(&cl_arg->server->clients_array_mutex); + pthread_mutex_unlock(&cl_arg->server->logins_mutex); if (p == NULL) { printf("AUTH: no such login\n"); bzero(buffer, 256); @@ -230,15 +279,163 @@ void *client_worker(void *argp) { if (kind == -1) return 0; + if (kind == 0) { + dev_session(cl_arg); + } else if (kind == 1) { + qa_session(cl_arg); + } else { + srverror("reg_or_login returned something different from 0/-1/1"); + } + return 0; } +void qa_session(Client_arg_t *cl_arg) { + ssize_t n; + char buffer[256]; + bzero(buffer, 256); + while (1) { + n = read(cl_arg->newsockfd, buffer, 255); + if (n < 0) { + srverror("qa_session: ERROR reading from socket"); + return; + } else if (n == 0) { + printf("qa_session: Client's socket closed\n"); + return; + } + printf_tid("qa's msg:", buffer); + if (!strncmp(buffer, "BCLS ", 5)) { + int i = 5; + char login[256]; + for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { + login[i - 5] = buffer[i]; + } + process_list_closed_bugs(cl_arg); + } else if (!strncmp(buffer, "BACT ", 5)) { + process_list_active_bugs(cl_arg); + } else if (!strncmp(buffer, "BREP ", 5)) { + process_report_new_bug(cl_arg, buffer); + } else if (!strncmp(buffer, "BREV ", 5)) { + process_review_bug_fix(cl_arg); + } else { + srverror("dev_session: Bad request\n"); + close(cl_arg->newsockfd); + //todo нормально освободить ресурсы + delete_client(cl_arg); + bzero(buffer, 256); + strcpy(buffer, "BR \n"); + n = write(cl_arg->newsockfd, buffer, strlen(buffer)); + return; + } + } +} + +void process_review_bug_fix(Client_arg_t *pArg) { + +} + +void write_br(Client_arg_t *cl_arg) { + ssize_t n; + char answer[10]; + strcat(answer, "BR \n"); + n = write(cl_arg->newsockfd, answer, strlen(answer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + return; + } +} + +void process_report_new_bug(Client_arg_t *cl_arg, const char *buffer) { + ssize_t n; +// bzero(buffer, 256); + /*n = read(cl_arg->newsockfd, buffer, 255); + if (n < 0) { + srverror("process_report_new_bug: ERROR reading from socket"); + return; + } else if (n == 0) { + printf("process_report_new_bug: Client's socket closed\n"); + return; + }*/ + int i = 5; + char dev_id[256] = "\0"; + char proj_id[256] = "\0"; + char bug_id[256] = "\0"; + char bug_text[256] = "\0"; + while (buffer[i] != '|' && i < strlen(buffer)) { + char curChar[2] = "\0"; + curChar[0] = buffer[i]; + strcat(dev_id, curChar); + i++; + } + if (buffer[i] != '|' || i >= strlen(buffer) - 2) { + write_br(cl_arg); + return; + } + i++; + while (buffer[i] != '|' && i < strlen(buffer)) { + char curChar[2] = "\0"; + curChar[0] = buffer[i]; + strcat(proj_id, curChar); + i++; + } + if (buffer[i] != '|' || i >= strlen(buffer) - 2) { + write_br(cl_arg); + return; + } + i++; + while (buffer[i] != '|' && i < strlen(buffer)) { + char curChar[2] = "\0"; + curChar[0] = buffer[i]; + strcat(bug_id, curChar); + i++; + } + if (buffer[i] != '|' || i >= strlen(buffer) - 2) { + write_br(cl_arg); + return; + } + i++; + while (buffer[i] != '|' && i < strlen(buffer)) { + char curChar[2] = "\0"; + curChar[0] = buffer[i]; + strcat(bug_text, curChar); + i++; + } + if (i < strlen(buffer) && buffer[i] != '|') { + write_br(cl_arg); + return; + } + printf("Dev_id: %s\n", dev_id); + printf("Proj_id: %s\n", proj_id); + printf("Bug_id: %s\n", bug_id); + printf("Bug_text: %s\n", bug_text); +} + +void process_list_active_bugs(Client_arg_t *pArg) { + +} + +void process_list_closed_bugs(Client_arg_t *pArg) { + +} + +void dev_session(Client_arg_t *pArg) { + ssize_t n; + char buffer[256]; + bzero(buffer, 256); + while (1) { + + } +} + void create_client(Server_t *server, Client_arg_t *client_arg) { pthread_t pthread; pthread_create(&pthread, NULL, client_worker, client_arg); - pthread_mutex_lock(&server->clients_array_mutex); + pthread_mutex_lock(&server->client_mutex); g_hash_table_add(server->clients, &pthread); - pthread_mutex_unlock(&server->clients_array_mutex); + pthread_mutex_unlock(&server->client_mutex); } void *server_listener(void *argp) { @@ -281,7 +478,10 @@ int main(int argc, char *argv[]) { server.sockfd = socket(AF_INET, SOCK_STREAM, 0); server.clients = g_hash_table_new(g_int64_hash, g_int64_equal); server.logins = g_hash_table_new(g_str_hash, g_str_equal); - pthread_mutex_init(&server.clients_array_mutex, NULL); + server.devs = g_hash_table_new(g_str_hash, g_str_equal); + pthread_mutex_init(&server.client_mutex, NULL); + pthread_mutex_init(&server.logins_mutex, NULL); + pthread_mutex_init(&server.devs_mutex, NULL); if (server.sockfd < 0) { srverror("ERROR opening socket"); From 42749a3d9e5e6faa563308881be3aad70790891f Mon Sep 17 00:00:00 2001 From: Pavel Solikov Date: Sat, 23 Feb 2019 00:35:20 +0300 Subject: [PATCH 07/11] BREV --- tcp/server/main.c | 178 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 154 insertions(+), 24 deletions(-) diff --git a/tcp/server/main.c b/tcp/server/main.c index 7df8a46..2f011d9 100644 --- a/tcp/server/main.c +++ b/tcp/server/main.c @@ -24,6 +24,7 @@ typedef struct Server { pthread_mutex_t client_mutex; pthread_mutex_t logins_mutex; pthread_mutex_t devs_mutex; + pthread_mutex_t bugs_mutex; } Server_t; typedef struct Client_arg { @@ -51,7 +52,7 @@ typedef struct Bug { int closed; int fixed; char *proj_id; - Dev_t *dev; + char *dev; char *text; } Bug_t; @@ -65,12 +66,26 @@ void process_list_active_bugs(Client_arg_t *pArg); void process_report_new_bug(Client_arg_t *cl_arg, const char *buffer); -void process_review_bug_fix(Client_arg_t *pArg); +void process_review_bug_fix(Client_arg_t *cl_arg, char *buffer); void printf_tid(char *msg, char *buffer) { printf("tid %llu: %s: %s\n", (unsigned long long) pthread_self(), msg, buffer); } +void write_br(Client_arg_t *cl_arg) { + ssize_t n; + char answer[10]; + strcat(answer, "BR \n"); + n = write(cl_arg->newsockfd, answer, strlen(answer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + return; + } +} + void clients_iterator(gpointer key, gpointer value, gpointer user_data) { //мб нужно kill int a = pthread_kill(*(pthread_t *) key, NULL); @@ -316,7 +331,7 @@ void qa_session(Client_arg_t *cl_arg) { } else if (!strncmp(buffer, "BREP ", 5)) { process_report_new_bug(cl_arg, buffer); } else if (!strncmp(buffer, "BREV ", 5)) { - process_review_bug_fix(cl_arg); + process_review_bug_fix(cl_arg, buffer); } else { srverror("dev_session: Bad request\n"); close(cl_arg->newsockfd); @@ -330,35 +345,109 @@ void qa_session(Client_arg_t *cl_arg) { } } -void process_review_bug_fix(Client_arg_t *pArg) { - -} - -void write_br(Client_arg_t *cl_arg) { +void process_review_bug_fix(Client_arg_t *cl_arg, char *buffer) { ssize_t n; - char answer[10]; - strcat(answer, "BR \n"); - n = write(cl_arg->newsockfd, answer, strlen(answer)); - if (n < 0) { - srverror("ERROR writing to socket"); + int i = 5; + char bug_id[256] = "\0"; + char decision[256] = "\0"; + while (buffer[i] != '|' && i < strlen(buffer)) { + char curChar[2] = "\0"; + curChar[0] = buffer[i]; + strcat(bug_id, curChar); + i++; + } + if (buffer[i] != '|' || i >= strlen(buffer) - 2) { + write_br(cl_arg); return; - } else if (n == 0) { - printf("Client's socket closed\n"); + } + i++; + while (buffer[i] != '|' && i < strlen(buffer)) { + char curChar[2] = "\0"; + curChar[0] = buffer[i]; + strcat(decision, curChar); + i++; + } + if (i < strlen(buffer) && buffer[i] != '|') { + write_br(cl_arg); return; } + pthread_mutex_lock(&cl_arg->server->bugs_mutex); + gpointer p = g_hash_table_find(cl_arg->server->bugs, (GHRFunc) get_val, bug_id); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + if (p == NULL) { + char *answer = "BREV BN\n"; + n = write(cl_arg->newsockfd, answer, strlen(answer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + return; + } + return; + } else { + pthread_mutex_lock(&cl_arg->server->bugs_mutex); + Bug_t *b = (Bug_t *) p; + if (b->closed) { + char *answer = "BREV BC\n"; + n = write(cl_arg->newsockfd, answer, strlen(answer)); + if (n < 0) { + srverror("ERROR writing to socket"); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } + } + if (!b->fixed) { + char *answer = "BREV BI\n"; + n = write(cl_arg->newsockfd, answer, strlen(answer)); + if (n < 0) { + srverror("ERROR writing to socket"); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } + } + if (!strcmp(decision, "accept")) { + b->closed = 1; + } else if (!strcmp(decision, "reject")) { + b->closed = 0; + } else { + char *answer = "BREV PE\n"; + n = write(cl_arg->newsockfd, answer, strlen(answer)); + if (n < 0) { + srverror("ERROR writing to socket"); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } + } + char *answer = "BREV OK\n"; + n = write(cl_arg->newsockfd, answer, strlen(answer)); + if (n < 0) { + srverror("ERROR writing to socket"); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + } } void process_report_new_bug(Client_arg_t *cl_arg, const char *buffer) { ssize_t n; -// bzero(buffer, 256); - /*n = read(cl_arg->newsockfd, buffer, 255); - if (n < 0) { - srverror("process_report_new_bug: ERROR reading from socket"); - return; - } else if (n == 0) { - printf("process_report_new_bug: Client's socket closed\n"); - return; - }*/ int i = 5; char dev_id[256] = "\0"; char proj_id[256] = "\0"; @@ -407,6 +496,45 @@ void process_report_new_bug(Client_arg_t *cl_arg, const char *buffer) { write_br(cl_arg); return; } + //todo no such ids + pthread_mutex_lock(&cl_arg->server->bugs_mutex); + gpointer p = g_hash_table_find(cl_arg->server->bugs, (GHRFunc) get_val, bug_id); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + if (p == NULL) { + Bug_t *b = malloc(sizeof(b)); + b->id = bug_id; + b->closed = 0; + b->dev = dev_id; + b->fixed = 0; + b->proj_id = proj_id; + b->text = bug_text; + pthread_mutex_lock(&cl_arg->server->bugs_mutex); + g_hash_table_insert(cl_arg->server->bugs, g_strdup(bug_id), b); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + char answer[10]; + strcat(answer, "BREP OK\n"); + n = write(cl_arg->newsockfd, answer, strlen(answer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + return; + } + } else { + Bug_t *b = (Bug_t *) p; + printf("BugReport: Bug exists: %s", b->id); + char answer[10]; + strcat(answer, "BREP BE\n"); + n = write(cl_arg->newsockfd, answer, strlen(answer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + return; + } + } printf("Dev_id: %s\n", dev_id); printf("Proj_id: %s\n", proj_id); printf("Bug_id: %s\n", bug_id); @@ -479,9 +607,11 @@ int main(int argc, char *argv[]) { server.clients = g_hash_table_new(g_int64_hash, g_int64_equal); server.logins = g_hash_table_new(g_str_hash, g_str_equal); server.devs = g_hash_table_new(g_str_hash, g_str_equal); + server.bugs = g_hash_table_new(g_str_hash, g_str_equal); pthread_mutex_init(&server.client_mutex, NULL); pthread_mutex_init(&server.logins_mutex, NULL); pthread_mutex_init(&server.devs_mutex, NULL); + pthread_mutex_init(&server.bugs_mutex, NULL); if (server.sockfd < 0) { srverror("ERROR opening socket"); From 21a03b7eb7d094789a68ba998509781b71057a38 Mon Sep 17 00:00:00 2001 From: Pavel Solikov Date: Sat, 23 Feb 2019 16:17:35 +0300 Subject: [PATCH 08/11] BACT --- tcp/server/main.c | 128 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 98 insertions(+), 30 deletions(-) diff --git a/tcp/server/main.c b/tcp/server/main.c index 2f011d9..ed06fb2 100644 --- a/tcp/server/main.c +++ b/tcp/server/main.c @@ -25,6 +25,7 @@ typedef struct Server { pthread_mutex_t logins_mutex; pthread_mutex_t devs_mutex; pthread_mutex_t bugs_mutex; + pthread_mutex_t closed_bugs_mutex; } Server_t; typedef struct Client_arg { @@ -60,9 +61,9 @@ void dev_session(Client_arg_t *pArg); void qa_session(Client_arg_t *cl_arg); -void process_list_closed_bugs(Client_arg_t *pArg); +void process_list_closed_bugs(Client_arg_t *cl_arg); -void process_list_active_bugs(Client_arg_t *pArg); +void process_list_active_bugs(Client_arg_t *cl_arg); void process_report_new_bug(Client_arg_t *cl_arg, const char *buffer); @@ -72,9 +73,19 @@ void printf_tid(char *msg, char *buffer) { printf("tid %llu: %s: %s\n", (unsigned long long) pthread_self(), msg, buffer); } +char* my_strcpy(char *a, char *b) { + + if (a == NULL || b == NULL) { + return NULL; + } + + memmove(a, b, strlen(b) + 1); + return a; +} + void write_br(Client_arg_t *cl_arg) { ssize_t n; - char answer[10]; + char answer[10] = "\0"; strcat(answer, "BR \n"); n = write(cl_arg->newsockfd, answer, strlen(answer)); if (n < 0) { @@ -109,7 +120,7 @@ void delete_client(Server_t *server) { gboolean get_val(gpointer key, gpointer value, gpointer user_data) { gchar *pkey = (gchar *) key; gchar *pdata = (gchar *) user_data; - printf("get_val: %s and %s \n", pkey, pdata); + printf("get_val: %s and %s (%d)\n", pkey, pdata, !strcmp(pkey, pdata)); return !strcmp(pkey, pdata); } @@ -131,18 +142,18 @@ int reg_or_login(Client_arg_t *cl_arg) { printf_tid("Client's registration msg:", buffer); if (!strncmp(buffer, "REGT ", 5)) { int i = 5; - char login[256]; + char login[256] = "\0"; for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { login[i - 5] = buffer[i]; } pthread_mutex_lock(&cl_arg->server->logins_mutex); - gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); + gpointer p = g_hash_table_lookup(cl_arg->server->logins, login); pthread_mutex_unlock(&cl_arg->server->logins_mutex); if (p == NULL) { printf("REGT: free login\n"); pthread_mutex_lock(&cl_arg->server->logins_mutex); printf("Inserting data: %s", login); - g_hash_table_insert(cl_arg->server->logins, g_strdup(login), "T"); + g_hash_table_insert(cl_arg->server->logins, g_strdup(login), g_strdup("T")); pthread_mutex_unlock(&cl_arg->server->logins_mutex); bzero(buffer, 256); strcpy(buffer, "REGT OK \n"); @@ -172,18 +183,19 @@ int reg_or_login(Client_arg_t *cl_arg) { } } else if (!strncmp(buffer, "REGD ", 5)) { int i = 5; - char login[256]; + char login[256] = "\0"; for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { login[i - 5] = buffer[i]; } pthread_mutex_lock(&cl_arg->server->logins_mutex); - gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); + gpointer p = g_hash_table_lookup(cl_arg->server->logins, login); +// gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); pthread_mutex_unlock(&cl_arg->server->logins_mutex); if (p == NULL) { printf("REGD: free login\n"); pthread_mutex_lock(&cl_arg->server->logins_mutex); printf("Inserting data: %s", login); - g_hash_table_insert(cl_arg->server->logins, g_strdup(login), "D"); + g_hash_table_insert(cl_arg->server->logins, g_strdup(login), g_strdup("D")); pthread_mutex_unlock(&cl_arg->server->logins_mutex); //create new dev pthread_mutex_lock(&cl_arg->server->devs_mutex); @@ -192,7 +204,7 @@ int reg_or_login(Client_arg_t *cl_arg) { dev->id = login; dev->projects = g_hash_table_new(g_str_hash, g_str_equal); //test proj - g_hash_table_insert(dev->projects, "1", ""); + g_hash_table_insert(dev->projects, g_strdup("1"), g_strdup("")); pthread_mutex_unlock(&cl_arg->server->devs_mutex); bzero(buffer, 256); strcpy(buffer, "REGD OK \n"); @@ -222,12 +234,13 @@ int reg_or_login(Client_arg_t *cl_arg) { } } else if (!strncmp(buffer, "AUTH ", 5)) { int i = 5; - char login[256]; + char login[256] = "\0"; for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { login[i - 5] = buffer[i]; } pthread_mutex_lock(&cl_arg->server->logins_mutex); - gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); +// gpointer p = g_hash_table_find(cl_arg->server->logins, (GHRFunc) get_val, login); + gpointer p = g_hash_table_lookup(cl_arg->server->logins, login); pthread_mutex_unlock(&cl_arg->server->logins_mutex); if (p == NULL) { printf("AUTH: no such login\n"); @@ -283,7 +296,7 @@ int reg_or_login(Client_arg_t *cl_arg) { void *client_worker(void *argp) { ssize_t n; Client_arg_t *cl_arg = (Client_arg_t *) argp; - char buffer[256]; + char buffer[256] = "\0"; if (cl_arg->newsockfd < 0) { srverror("ERROR on accept"); @@ -307,9 +320,10 @@ void *client_worker(void *argp) { void qa_session(Client_arg_t *cl_arg) { ssize_t n; - char buffer[256]; + char buffer[256] = "\0"; bzero(buffer, 256); while (1) { + bzero(buffer, 256); n = read(cl_arg->newsockfd, buffer, 255); if (n < 0) { srverror("qa_session: ERROR reading from socket"); @@ -320,11 +334,6 @@ void qa_session(Client_arg_t *cl_arg) { } printf_tid("qa's msg:", buffer); if (!strncmp(buffer, "BCLS ", 5)) { - int i = 5; - char login[256]; - for (; i < strlen(buffer) && buffer[i] != '\n'; ++i) { - login[i - 5] = buffer[i]; - } process_list_closed_bugs(cl_arg); } else if (!strncmp(buffer, "BACT ", 5)) { process_list_active_bugs(cl_arg); @@ -333,7 +342,7 @@ void qa_session(Client_arg_t *cl_arg) { } else if (!strncmp(buffer, "BREV ", 5)) { process_review_bug_fix(cl_arg, buffer); } else { - srverror("dev_session: Bad request\n"); + srverror("qa_session: Bad request\n"); close(cl_arg->newsockfd); //todo нормально освободить ресурсы delete_client(cl_arg); @@ -372,7 +381,8 @@ void process_review_bug_fix(Client_arg_t *cl_arg, char *buffer) { return; } pthread_mutex_lock(&cl_arg->server->bugs_mutex); - gpointer p = g_hash_table_find(cl_arg->server->bugs, (GHRFunc) get_val, bug_id); + gpointer p = g_hash_table_lookup(cl_arg->server->bugs, bug_id); +// gpointer p = g_hash_table_find(cl_arg->server->bugs, (GHRFunc) get_val, bug_id); pthread_mutex_unlock(&cl_arg->server->bugs_mutex); if (p == NULL) { char *answer = "BREV BN\n"; @@ -400,6 +410,7 @@ void process_review_bug_fix(Client_arg_t *cl_arg, char *buffer) { pthread_mutex_unlock(&cl_arg->server->bugs_mutex); return; } + return; } if (!b->fixed) { char *answer = "BREV BI\n"; @@ -413,9 +424,13 @@ void process_review_bug_fix(Client_arg_t *cl_arg, char *buffer) { pthread_mutex_unlock(&cl_arg->server->bugs_mutex); return; } + return; } if (!strcmp(decision, "accept")) { b->closed = 1; + pthread_mutex_lock(&cl_arg->server->closed_bugs_mutex); + g_hash_table_insert(cl_arg->server->closed_bugs, g_strdup(b->id), g_strdup("")); + pthread_mutex_unlock(&cl_arg->server->closed_bugs_mutex); } else if (!strcmp(decision, "reject")) { b->closed = 0; } else { @@ -430,6 +445,7 @@ void process_review_bug_fix(Client_arg_t *cl_arg, char *buffer) { pthread_mutex_unlock(&cl_arg->server->bugs_mutex); return; } + return; } char *answer = "BREV OK\n"; n = write(cl_arg->newsockfd, answer, strlen(answer)); @@ -498,7 +514,8 @@ void process_report_new_bug(Client_arg_t *cl_arg, const char *buffer) { } //todo no such ids pthread_mutex_lock(&cl_arg->server->bugs_mutex); - gpointer p = g_hash_table_find(cl_arg->server->bugs, (GHRFunc) get_val, bug_id); +// gpointer p = g_hash_table_find(cl_arg->server->bugs, (GHRFunc) get_val, bug_id); + gpointer p = g_hash_table_lookup(cl_arg->server->bugs, bug_id); pthread_mutex_unlock(&cl_arg->server->bugs_mutex); if (p == NULL) { Bug_t *b = malloc(sizeof(b)); @@ -511,7 +528,7 @@ void process_report_new_bug(Client_arg_t *cl_arg, const char *buffer) { pthread_mutex_lock(&cl_arg->server->bugs_mutex); g_hash_table_insert(cl_arg->server->bugs, g_strdup(bug_id), b); pthread_mutex_unlock(&cl_arg->server->bugs_mutex); - char answer[10]; + char answer[10] = "\0"; strcat(answer, "BREP OK\n"); n = write(cl_arg->newsockfd, answer, strlen(answer)); if (n < 0) { @@ -524,7 +541,7 @@ void process_report_new_bug(Client_arg_t *cl_arg, const char *buffer) { } else { Bug_t *b = (Bug_t *) p; printf("BugReport: Bug exists: %s", b->id); - char answer[10]; + char answer[10] = "\0"; strcat(answer, "BREP BE\n"); n = write(cl_arg->newsockfd, answer, strlen(answer)); if (n < 0) { @@ -534,6 +551,7 @@ void process_report_new_bug(Client_arg_t *cl_arg, const char *buffer) { printf("Client's socket closed\n"); return; } + return; } printf("Dev_id: %s\n", dev_id); printf("Proj_id: %s\n", proj_id); @@ -541,17 +559,65 @@ void process_report_new_bug(Client_arg_t *cl_arg, const char *buffer) { printf("Bug_text: %s\n", bug_text); } -void process_list_active_bugs(Client_arg_t *pArg) { - +void process_list_active_bugs(Client_arg_t *cl_arg) { + ssize_t n; + int i = 5; + char buffer[1000] = "BACT OK "; + pthread_mutex_lock(&cl_arg->server->closed_bugs_mutex); + pthread_mutex_lock(&cl_arg->server->bugs_mutex); + GList *lb = g_hash_table_get_keys(cl_arg->server->bugs); + GList *lcb = g_hash_table_get_keys(cl_arg->server->closed_bugs); + for (guint j = 0; j < g_list_length(lb); j++) { + gpointer item = g_list_nth(lb, j); + if (lcb == NULL || g_list_find(lcb, g_list_nth(lb, j)) == NULL) { + char *s = (char *)item; + printf("%s", s); + strcat(buffer, *((char **) item)); + strcat(buffer, "|"); + } + } + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + pthread_mutex_unlock(&cl_arg->server->closed_bugs_mutex); + strcat(buffer, "\n"); + n = write(cl_arg->newsockfd, buffer, strlen(buffer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + return; + } } -void process_list_closed_bugs(Client_arg_t *pArg) { +void keys_to_buffer(gpointer key, gpointer user_data) { + printf("keys_to_buffer: %s and %s;\n", (char *) user_data, (char *) key); + strcat((char *) user_data, (char *) key); + strcat((char *) user_data, "|"); +} +void process_list_closed_bugs(Client_arg_t *cl_arg) { + ssize_t n; + int i = 5; + pthread_mutex_lock(&cl_arg->server->closed_bugs_mutex); + GList *l = g_hash_table_get_keys(cl_arg->server->closed_bugs); + char buffer[1000] = "BCLS "; + //todo список не id, а (id, proj_id, dev_id) + g_list_foreach(l, keys_to_buffer, buffer); + pthread_mutex_unlock(&cl_arg->server->closed_bugs_mutex); + strcat(buffer, "\n"); + n = write(cl_arg->newsockfd, buffer, strlen(buffer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + return; + } } void dev_session(Client_arg_t *pArg) { ssize_t n; - char buffer[256]; + char buffer[256] = "\0"; bzero(buffer, 256); while (1) { @@ -597,7 +663,7 @@ int main(int argc, char *argv[]) { int newsockfd; uint16_t portno; unsigned int clilen; - char buffer[256]; + char buffer[256] = "\0"; struct sockaddr_in serv_addr, cli_addr; ssize_t n; @@ -608,10 +674,12 @@ int main(int argc, char *argv[]) { server.logins = g_hash_table_new(g_str_hash, g_str_equal); server.devs = g_hash_table_new(g_str_hash, g_str_equal); server.bugs = g_hash_table_new(g_str_hash, g_str_equal); + server.closed_bugs = g_hash_table_new(g_str_hash, g_str_equal); pthread_mutex_init(&server.client_mutex, NULL); pthread_mutex_init(&server.logins_mutex, NULL); pthread_mutex_init(&server.devs_mutex, NULL); pthread_mutex_init(&server.bugs_mutex, NULL); + pthread_mutex_init(&server.closed_bugs_mutex, NULL); if (server.sockfd < 0) { srverror("ERROR opening socket"); From c78ed8a77d876446092c445d5613ea80ba2ed594 Mon Sep 17 00:00:00 2001 From: Pavel Solikov Date: Sat, 23 Feb 2019 18:12:37 +0300 Subject: [PATCH 09/11] kick client --- tcp/server/main.c | 60 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/tcp/server/main.c b/tcp/server/main.c index ed06fb2..51dc52f 100644 --- a/tcp/server/main.c +++ b/tcp/server/main.c @@ -26,6 +26,7 @@ typedef struct Server { pthread_mutex_t devs_mutex; pthread_mutex_t bugs_mutex; pthread_mutex_t closed_bugs_mutex; + int tid; } Server_t; typedef struct Client_arg { @@ -73,7 +74,7 @@ void printf_tid(char *msg, char *buffer) { printf("tid %llu: %s: %s\n", (unsigned long long) pthread_self(), msg, buffer); } -char* my_strcpy(char *a, char *b) { +char *my_strcpy(char *a, char *b) { if (a == NULL || b == NULL) { return NULL; @@ -99,7 +100,7 @@ void write_br(Client_arg_t *cl_arg) { void clients_iterator(gpointer key, gpointer value, gpointer user_data) { //мб нужно kill - int a = pthread_kill(*(pthread_t *) key, NULL); + int a = pthread_kill(*(pthread_t *) value, NULL); } void stop_server(Server_t *server) { @@ -117,6 +118,20 @@ void delete_client(Server_t *server) { pthread_mutex_unlock(&server->client_mutex); } +void list_clients(Server_t *server) { + pthread_mutex_lock(&server->client_mutex); + GList *l = g_hash_table_get_keys(server->clients); + printf("Clients: \n"); + for (guint i = 0; i < g_list_length(l); i++) { + printf("%s\n", (char *) g_list_nth_data(l, i)); + } + pthread_mutex_unlock(&server->client_mutex); +} + +void kick_client(pthread_t *p) { + int a = pthread_kill(*p, NULL); +} + gboolean get_val(gpointer key, gpointer value, gpointer user_data) { gchar *pkey = (gchar *) key; gchar *pdata = (gchar *) user_data; @@ -568,9 +583,9 @@ void process_list_active_bugs(Client_arg_t *cl_arg) { GList *lb = g_hash_table_get_keys(cl_arg->server->bugs); GList *lcb = g_hash_table_get_keys(cl_arg->server->closed_bugs); for (guint j = 0; j < g_list_length(lb); j++) { - gpointer item = g_list_nth(lb, j); - if (lcb == NULL || g_list_find(lcb, g_list_nth(lb, j)) == NULL) { - char *s = (char *)item; + gpointer item = g_list_nth_data(lb, j); + if (lcb == NULL || g_list_find(lcb, item) == NULL) { + char *s = (char *) item; printf("%s", s); strcat(buffer, *((char **) item)); strcat(buffer, "|"); @@ -625,16 +640,19 @@ void dev_session(Client_arg_t *pArg) { } void create_client(Server_t *server, Client_arg_t *client_arg) { - pthread_t pthread; - pthread_create(&pthread, NULL, client_worker, client_arg); + pthread_t *pthread = malloc(sizeof(pthread)); + pthread_create(pthread, NULL, client_worker, client_arg); pthread_mutex_lock(&server->client_mutex); - g_hash_table_add(server->clients, &pthread); + char str[12]; + sprintf(str, "%d", server->tid++); + g_hash_table_insert(server->clients, g_strdup(str), pthread); pthread_mutex_unlock(&server->client_mutex); } void *server_listener(void *argp) { int newsockfd; Server_t *server = (Server_t *) argp; + server->tid = 0; socklen_t clilen; struct sockaddr_in cli_addr; clilen = sizeof(cli_addr); @@ -670,7 +688,7 @@ int main(int argc, char *argv[]) { bzero(&server, sizeof(server)); /* First call to socket() function */ server.sockfd = socket(AF_INET, SOCK_STREAM, 0); - server.clients = g_hash_table_new(g_int64_hash, g_int64_equal); + server.clients = g_hash_table_new(g_str_hash, g_str_hash); server.logins = g_hash_table_new(g_str_hash, g_str_equal); server.devs = g_hash_table_new(g_str_hash, g_str_equal); server.bugs = g_hash_table_new(g_str_hash, g_str_equal); @@ -714,7 +732,8 @@ int main(int argc, char *argv[]) { pthread_t server_pthread; pthread_create(&server_pthread, NULL, server_listener, &server); while (1) { - printf("len(clients)=%d | Available command: \"exit\", \"list\": ", g_hash_table_size(server.clients)); + printf("len(clients)=%d | Available command: \"exit\", \"list\", \"kick \": ", + g_hash_table_size(server.clients)); bzero(buffer, 256); fgets(buffer, 255, stdin); @@ -724,12 +743,25 @@ int main(int argc, char *argv[]) { shutdown(server.sockfd, SHUT_RDWR); close(server.sockfd); exit(0); + } else if (!strcmp(buffer, "list") || !strcmp(buffer, "list\n")) { + list_clients(&server); + } else if (!strncmp(buffer, "kick ", 5)) { + int i = 5; + char cl[100] = "\0"; + while (buffer[i] != ' ' && buffer[i] != '\n') { + char curChar[2] = "\0"; + curChar[0] = buffer[i]; + strcat(cl, curChar); + i++; + } + gpointer p = g_hash_table_lookup(server.clients, cl); + if (p == NULL) { + printf("No such client\n"); + } else { + kick_client((pthread_t *) p); + } } else { printf("Unknown command\n"); } } } - -int main1(int argc, char **argv) { - return 0; -} \ No newline at end of file From ce52bdc6949ec40d025eadc753c3f0151837c30a Mon Sep 17 00:00:00 2001 From: Pavel Solikov Date: Sat, 23 Feb 2019 22:56:42 +0300 Subject: [PATCH 10/11] BFIX --- tcp/server/main.c | 75 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/tcp/server/main.c b/tcp/server/main.c index 51dc52f..5054643 100644 --- a/tcp/server/main.c +++ b/tcp/server/main.c @@ -58,7 +58,7 @@ typedef struct Bug { char *text; } Bug_t; -void dev_session(Client_arg_t *pArg); +void dev_session(Client_arg_t *cl_arg); void qa_session(Client_arg_t *cl_arg); @@ -630,12 +630,83 @@ void process_list_closed_bugs(Client_arg_t *cl_arg) { } } -void dev_session(Client_arg_t *pArg) { +void dev_session(Client_arg_t *cl_arg) { ssize_t n; char buffer[256] = "\0"; bzero(buffer, 256); while (1) { + bzero(buffer, 256); + n = read(cl_arg->newsockfd, buffer, 255); + if (n < 0) { + srverror("qa_session: ERROR reading from socket"); + return; + } else if (n == 0) { + printf("qa_session: Client's socket closed\n"); + return; + } + printf_tid("dev's msg:", buffer); + if (!strncmp(buffer, "BFIX ", 5)) { + int i = 5; + char bug_id[256] = "\0"; + while (i < strlen(buffer) && buffer[i] != '\n') { + char curChar[2] = "\0"; + curChar[0] = buffer[i]; + strcat(bug_id, curChar); + i++; + } + printf("BFIX: %s, %d", bug_id, g_hash_table_size(cl_arg->server->bugs)); + pthread_mutex_lock(&cl_arg->server->bugs_mutex); + Bug_t *bug = (Bug_t *) g_hash_table_lookup(cl_arg->server->bugs, bug_id); + if (bug == NULL) { + char answer[10] = "\0"; + strcat(answer, "BFIX BN \n"); + n = write(cl_arg->newsockfd, answer, strlen(answer)); + if (n < 0) { + srverror("ERROR writing to socket"); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } + if (bug->closed){ + char answer[10] = "\0"; + strcat(answer, "BFIX BC \n"); + n = write(cl_arg->newsockfd, answer, strlen(answer)); + if (n < 0) { + srverror("ERROR writing to socket"); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } + bug->fixed = 1; + char answer[10] = "\0"; + strcat(answer, "BFIX OK \n"); + n = write(cl_arg->newsockfd, answer, strlen(answer)); + if (n < 0) { + srverror("ERROR writing to socket"); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + return; + } else if (!strncmp(buffer, "LIST ", 5)){ + } } } From 702486738489e0080bb08e693b91a9ae48342e6e Mon Sep 17 00:00:00 2001 From: Pavel Solikov Date: Sun, 24 Feb 2019 00:23:57 +0300 Subject: [PATCH 11/11] LIST --- tcp/server/main.c | 58 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/tcp/server/main.c b/tcp/server/main.c index 5054643..09e526f 100644 --- a/tcp/server/main.c +++ b/tcp/server/main.c @@ -29,8 +29,14 @@ typedef struct Server { int tid; } Server_t; +typedef struct Dev { + char *id; + GHashTable *projects; +} Dev_t; + typedef struct Client_arg { int newsockfd; + Dev_t *dev; Server_t *server; } Client_arg_t; @@ -44,11 +50,6 @@ typedef struct Client { // GHashTable //} Project_t; -typedef struct Dev { - char *id; - GHashTable *projects; -} Dev_t; - typedef struct Bug { char *id; int closed; @@ -145,6 +146,7 @@ int reg_or_login(Client_arg_t *cl_arg) { ssize_t n; char buffer[256]; bzero(buffer, 256); + cl_arg->dev = 0; while (1) { n = read(cl_arg->newsockfd, buffer, 255); // recv on Windows if (n < 0) { @@ -218,6 +220,7 @@ int reg_or_login(Client_arg_t *cl_arg) { Dev_t *dev = malloc(sizeof(*dev)); dev->id = login; dev->projects = g_hash_table_new(g_str_hash, g_str_equal); + cl_arg->dev = dev; //test proj g_hash_table_insert(dev->projects, g_strdup("1"), g_strdup("")); pthread_mutex_unlock(&cl_arg->server->devs_mutex); @@ -673,7 +676,7 @@ void dev_session(Client_arg_t *cl_arg) { pthread_mutex_unlock(&cl_arg->server->bugs_mutex); return; } - if (bug->closed){ + if (bug->closed) { char answer[10] = "\0"; strcat(answer, "BFIX BC \n"); n = write(cl_arg->newsockfd, answer, strlen(answer)); @@ -704,8 +707,47 @@ void dev_session(Client_arg_t *cl_arg) { } pthread_mutex_unlock(&cl_arg->server->bugs_mutex); return; - } else if (!strncmp(buffer, "LIST ", 5)){ - + } else if (!strncmp(buffer, "LIST ", 5)) { + if (!cl_arg->dev) { + srverror("Request not from dev\n"); + char answer[10] = "\0"; + strcat(answer, "LIST PE \n"); + n = write(cl_arg->newsockfd, answer, strlen(answer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + return; + } + return; + } + pthread_mutex_lock(&cl_arg->server->bugs_mutex); + GList *lp = g_hash_table_get_keys(cl_arg->dev->projects); + GList *lb = g_hash_table_get_keys(cl_arg->server->bugs); + char answer[1000] = "\0"; + for (guint i = 0; i < g_list_length(lb); ++i) { + Bug_t *b = g_list_nth_data(lb, i); + if (g_hash_table_lookup(cl_arg->dev->projects, b->proj_id) != NULL) { + strcat(answer, b->proj_id); + strcat(answer, "&"); + strcat(answer, b->id); + strcat(answer, "&"); + strcat(answer, b->text); + strcat(answer, "&"); + strcat(answer, "|"); + } + } + pthread_mutex_unlock(&cl_arg->server->bugs_mutex); + n = write(cl_arg->newsockfd, answer, strlen(answer)); + if (n < 0) { + srverror("ERROR writing to socket"); + return; + } else if (n == 0) { + printf("Client's socket closed\n"); + return; + } + return; } } }