From e99a1447c4c426fb4ed7355162664d256cbc31d3 Mon Sep 17 00:00:00 2001
From: Dmitry Puzyrkov <dmitry.puzyrkov@demlabs.net>
Date: Thu, 25 Aug 2022 17:42:55 +0000
Subject: [PATCH] [*] windows-related stuff fixed.

---
 CMakeLists.txt                                |   6 +-
 dap-sdk/io/CMakeLists.txt                     |  12 +-
 dap-sdk/io/dap_context.c                      |   1 -
 dap-sdk/io/dap_net.c                          |   4 +
 dap-sdk/io/dap_server.c                       |  10 +-
 dap-sdk/io/dap_timerfd.c                      |   4 +-
 dap-sdk/io/dap_worker.c                       |   2 +-
 .../net/server/cli_server/dap_cli_server.c    | 761 +++++++++---------
 dap-sdk/net/server/enc_server/CMakeLists.txt  |  28 +-
 dap-sdk/net/server/http_server/CMakeLists.txt |  28 +-
 dap-sdk/plugin/CMakeLists.txt                 |   6 +-
 11 files changed, 439 insertions(+), 423 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0cf516a405..536279c694 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -245,9 +245,9 @@ if (CELLFRAME_MODULES MATCHES "modules-dynamic")
 endif()
 
 if (WIN32)
-    set(CELLFRAME_LIBS ${CELLFRAME_LIBS} KERNEL32 USER32 SHELL32 WINMM GDI32 ADVAPI32
-					 Ole32 Version Imm32 OleAut32 ws2_32 ntdll psapi 
-                                         Shlwapi Bcrypt Crypt32 Secur32 userenv mqrt)
+    set(CELLFRAME_LIBS ${CELLFRAME_LIBS} kernel32 user32 shell32 winmm gdi32 advapi32
+					 ole32 version imm32 oleaut32 ws2_32 ntdll psapi 
+                                         shlwapi bcrypt crypt32 secur32 userenv mqrt)
 endif()
 
 if (DARWIN)
diff --git a/dap-sdk/io/CMakeLists.txt b/dap-sdk/io/CMakeLists.txt
index fc87bf0605..88f6d4d421 100644
--- a/dap-sdk/io/CMakeLists.txt
+++ b/dap-sdk/io/CMakeLists.txt
@@ -6,8 +6,11 @@ set(CMAKE_C_STANDARD 11)
 add_definitions ("-D_GNU_SOURCE")
 
 if(WIN32)
-    file(GLOB DAP_IO_SOURCES *.c ../../../3rdparty/wepoll/*.c)
-    file(GLOB DAP_IO_HEADERS include/*.h ../../../3rdparty/wepoll/*.h)
+    file(GLOB DAP_IO_SOURCES *.c ${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/wepoll/*.c)
+    file(GLOB DAP_IO_HEADERS include/*.h ${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/wepoll/*.h)
+
+    
+
 else()
     file(GLOB DAP_IO_SOURCES *.c)
     file(GLOB DAP_IO_HEADERS include/*.h)
@@ -34,10 +37,11 @@ endif()
 
 target_include_directories(${PROJECT_NAME} PUBLIC include)
 target_include_directories(${PROJECT_NAME} PRIVATE src)
-target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/uthash/src)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/uthash/src)
+
 
 if (WIN32)
-    target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wepoll)
+    target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/wepoll)
 endif()
 
 if (${BUILD_DAP_IO_TESTS} MATCHES ON)
diff --git a/dap-sdk/io/dap_context.c b/dap-sdk/io/dap_context.c
index 99c1329b3a..8e3625e5ca 100644
--- a/dap-sdk/io/dap_context.c
+++ b/dap-sdk/io/dap_context.c
@@ -1816,7 +1816,6 @@ dap_events_socket_t * dap_context_create_event(dap_context_t * a_context, dap_ev
 dap_events_socket_t * dap_context_create_pipe(dap_context_t * a_context, dap_events_socket_callback_t a_callback, uint32_t a_flags)
 {
 #ifdef DAP_OS_WINDOWS
-    UNUSED(a_w);
     UNUSED(a_callback);
     UNUSED(a_flags);
     return NULL;
diff --git a/dap-sdk/io/dap_net.c b/dap-sdk/io/dap_net.c
index 8625166953..c4b9fb3b9e 100644
--- a/dap-sdk/io/dap_net.c
+++ b/dap-sdk/io/dap_net.c
@@ -29,6 +29,10 @@
 
 #define LOG_TAG "dap_net"
 
+#ifdef _WIN32
+  #define poll WSAPoll
+#endif
+
 /**
  * @brief dap_net_resolve_host
  * @param a_host hostname
diff --git a/dap-sdk/io/dap_server.c b/dap-sdk/io/dap_server.c
index f9d38db30e..497b8d062e 100644
--- a/dap-sdk/io/dap_server.c
+++ b/dap-sdk/io/dap_server.c
@@ -289,10 +289,10 @@ static int s_server_run(dap_server_t * a_server, dap_events_socket_callbacks_t *
     }
 
 #ifdef DAP_EVENTS_CAPS_EPOLL
-    for(size_t l_worker_id = 0; l_worker_id < dap_events_worker_get_count() ; l_worker_id++){
+    for(size_t l_worker_id = 0; l_worker_id < dap_events_thread_get_count() ; l_worker_id++){
         dap_worker_t *l_w = dap_events_worker_get(l_worker_id);
         assert(l_w);
-        dap_events_socket_t * l_es = dap_events_socket_wrap2( a_server, a_server->events, a_server->socket_listener, &l_callbacks);
+        dap_events_socket_t * l_es = dap_events_socket_wrap2( a_server, a_server->socket_listener, &l_callbacks);
         a_server->es_listeners = dap_list_append(a_server->es_listeners, l_es);
 
         if (l_es) {
@@ -319,6 +319,12 @@ static int s_server_run(dap_server_t * a_server, dap_events_socket_callbacks_t *
     assert(l_w);
     dap_events_socket_t * l_es = dap_events_socket_wrap2( a_server, a_server->socket_listener, &l_callbacks);
     if (l_es) {
+        #ifdef DAP_EVENTS_CAPS_EPOLL
+            l_es->ev_base_flags = EPOLLIN;
+        #ifdef EPOLLEXCLUSIVE
+            l_es->ev_base_flags |= EPOLLET | EPOLLEXCLUSIVE;
+        #endif
+        #endif
         a_server->es_listeners = dap_list_append(a_server->es_listeners, l_es);
         l_es->type = a_server->type == SERVER_TCP ? DESCRIPTOR_TYPE_SOCKET_LISTENING : DESCRIPTOR_TYPE_SOCKET_UDP;
         l_es->_inheritor = a_server;
diff --git a/dap-sdk/io/dap_timerfd.c b/dap-sdk/io/dap_timerfd.c
index b9323e8ece..a8c494426c 100644
--- a/dap-sdk/io/dap_timerfd.c
+++ b/dap-sdk/io/dap_timerfd.c
@@ -283,7 +283,7 @@ static void s_es_callback_timer(struct dap_events_socket *a_event_sock)
         s_timerfd_reset(l_timer_fd, a_event_sock);
     } else {  
 #ifdef _WIN32
-        DeleteTimerQueueTimer(hTimerQueue, l_timerfd->th, NULL);
+        DeleteTimerQueueTimer(hTimerQueue, l_timer_fd->th, NULL);
 #endif
         l_timer_fd->events_socket->flags |= DAP_SOCK_SIGNAL_CLOSE;
     }
@@ -347,7 +347,7 @@ void dap_timerfd_delete(dap_timerfd_t *a_timerfd)
     if (!a_timerfd)
         return; 
 #ifdef _WIN32
-    DeleteTimerQueueTimer(hTimerQueue, l_timerfd->th, NULL);
+    DeleteTimerQueueTimer(hTimerQueue, a_timerfd->th, NULL);
 #endif
     if (a_timerfd->events_socket->context->worker)
         dap_events_socket_remove_and_delete_mt(a_timerfd->events_socket->context->worker, a_timerfd->esocket_uuid);
diff --git a/dap-sdk/io/dap_worker.c b/dap-sdk/io/dap_worker.c
index 0c6133276f..f3a116e183 100644
--- a/dap-sdk/io/dap_worker.c
+++ b/dap-sdk/io/dap_worker.c
@@ -305,7 +305,7 @@ static bool s_socket_all_check_activity( void * a_arg)
     //dap_ctime_r(&l_curtime, l_curtimebuf);
     //log_it(L_DEBUG,"Check sockets activity on worker #%u at %s", l_worker->id, l_curtimebuf);
     size_t l_esockets_counter = 0;
-    uint l_esockets_count = HASH_CNT(hh, l_worker->context->esockets);
+    u_int l_esockets_count = HASH_CNT(hh, l_worker->context->esockets);
     HASH_ITER(hh, l_worker->context->esockets, l_es, tmp ) {
         if (l_esockets_counter >= l_worker->context->event_sockets_count || l_esockets_counter >= l_esockets_count){
             log_it(L_ERROR, "Something wrong with context's esocket table: %u esockets in context, %u in table but we're on %zu iteration",
diff --git a/dap-sdk/net/server/cli_server/dap_cli_server.c b/dap-sdk/net/server/cli_server/dap_cli_server.c
index 0d8a22796e..daa4002500 100644
--- a/dap-sdk/net/server/cli_server/dap_cli_server.c
+++ b/dap-sdk/net/server/cli_server/dap_cli_server.c
@@ -84,6 +84,301 @@ static void* s_thread_main_func(void *args);
 static inline void s_cmd_add_ex(const char * a_name, dap_cli_server_cmd_callback_ex_t a_func, void *a_arg_func, const char *a_doc, const char *a_doc_ex);
 
 
+#ifdef _WIN32
+
+/**
+ * @brief p_get_next_str
+ *
+ * @param hPipe
+ * @param dwLen
+ * @param stop_str
+ * @param del_stop_str
+ * @param timeout
+ * @return char*
+ */
+char *p_get_next_str( HANDLE hPipe, int *dwLen, const char *stop_str, bool del_stop_str, int timeout )
+{
+    UNUSED(timeout);
+    bool bSuccess = false;
+    long nRecv = 0; // count of bytes received
+    size_t stop_str_len = (stop_str) ? strlen(stop_str) : 0;
+    // if there is nothing to look for
+
+    if(!stop_str_len)
+        return NULL;
+
+    size_t lpszBuffer_len = 256;
+    char *lpszBuffer = DAP_NEW_Z_SIZE(char, lpszBuffer_len);
+    // received string will not be larger than MAX_REPLY_LEN
+
+    while( 1 ) //nRecv < MAX_REPLY_LEN)
+    {
+      long ret = 0;
+        // read one byte
+//        long ret = s_recv( nSocket, (unsigned char *) (lpszBuffer + nRecv), 1, timeout);
+
+      bSuccess = ReadFile( hPipe, lpszBuffer + nRecv,
+         lpszBuffer_len - nRecv, (LPDWORD)&ret, NULL );
+
+        //int ret = recv(nSocket,lpszBuffer+nRecv,1, 0);
+        if ( ret <= 0 || !bSuccess )
+            break;
+
+        nRecv += ret;
+        //printf("**debug** socket=%d read  %d bytes '%0s'",nSocket, ret, (lpszBuffer + nRecv));
+
+        while((nRecv + 1) >= (long) lpszBuffer_len)
+        {
+            lpszBuffer_len *= 2;
+            lpszBuffer = (char*) realloc(lpszBuffer, lpszBuffer_len);
+        }
+
+        // search for the required string
+        if(nRecv >=  (long) stop_str_len) {
+            // found the required string
+            if(!strncasecmp(lpszBuffer + nRecv - stop_str_len, stop_str, stop_str_len)) {
+                bSuccess = true;
+                break;
+            }
+        }
+    };
+
+    // end reading
+
+    if(bSuccess) {
+        // delete the searched string
+        if(del_stop_str) {
+            lpszBuffer[nRecv -  (long) stop_str_len] = '\0';
+            if(dwLen)
+                *dwLen =(int) nRecv - (int) stop_str_len;
+        }
+        else {
+            lpszBuffer[nRecv] = '\0';
+            if(dwLen)
+                *dwLen = (int) nRecv;
+        }
+        lpszBuffer = DAP_REALLOC(lpszBuffer,(size_t) *dwLen + 1);
+        return lpszBuffer;
+    }
+
+    // in case of an error or missing string
+
+    if(dwLen)
+        *dwLen = 0;
+
+    free(lpszBuffer);
+
+    return NULL;
+}
+
+/**
+ * @brief thread_pipe_client_func
+ * threading function for processing a request from a client
+ * @param args
+ * @return void*
+ */
+static void *thread_pipe_client_func( void *args )
+{
+    HANDLE hPipe = (HANDLE)args;
+
+//    SOCKET newsockfd = (SOCKET) (intptr_t) args;
+    if(s_debug_cli)
+        log_it(L_INFO, "new connection pipe = %p", hPipe);
+
+    int str_len, marker = 0;
+    int timeout = 5000; // 5 sec
+    int argc = 0;
+
+    dap_list_t *cmd_param_list = NULL;
+
+    while( 1 )
+    {
+        // wait data from client
+//        int is_data = s_poll( newsockfd, timeout );
+        // timeout
+//        if(!is_data)
+//            continue;
+        // error (may be socket closed)
+//        if(is_data < 0)
+//            break;
+
+//        int is_valid = is_valid_socket(newsockfd);
+//        if(!is_valid)
+//        {
+//            break;
+//        }
+
+        // receiving http header
+        char *str_header = p_get_next_str( hPipe, &str_len, "\r\n", true, timeout );
+
+        // bad format
+        if(!str_header)
+            break;
+
+        if ( str_header && strlen(str_header) == 0) {
+            marker++;
+            if(marker == 1)
+                continue;
+        }
+
+        // filling parameters of command
+        if ( marker == 1 ) {
+            cmd_param_list = dap_list_append( cmd_param_list, str_header );
+            //printf("g_list_append argc=%d command=%s ", argc, str_header);
+            argc ++;
+        }
+        else
+            free( str_header );
+
+        if ( marker == 2 ) {
+
+            dap_list_t *list = cmd_param_list;
+            // form command
+
+            unsigned int argc = dap_list_length( list );
+            // command is found
+
+            if ( argc >= 1) {
+
+                int l_verbose = 0;
+                char *cmd_name = list->data;
+                list = dap_list_next( list );
+
+                // execute command
+                char *str_cmd = dap_strdup_printf( "%s", cmd_name );
+                dap_cli_cmd_t *l_cmd = dap_cli_server_cmd_find( cmd_name );
+                int res = -1;
+                char *str_reply = NULL;
+
+                if ( l_cmd ) {
+
+                    while( list ) {
+                        str_cmd = dap_strdup_printf( "%s;%s", str_cmd, list->data );
+                        list = dap_list_next(list);
+                    }
+
+                    log_it(L_INFO, "execute command = %s", str_cmd );
+                    // exec command
+
+                    char **l_argv = dap_strsplit( str_cmd, ";", -1 );
+                    // Call the command function
+
+                    if ( l_cmd &&  l_argv && l_cmd->func ) {
+                        if (l_cmd->arg_func) {
+                            res = l_cmd->func_ex(argc, l_argv, l_cmd->arg_func, &str_reply);
+                        } else {
+                            res = l_cmd->func(argc, l_argv, &str_reply);
+                        }
+                    }
+
+                    else if ( l_cmd ) {
+                        log_it(L_WARNING,"NULL arguments for input for command \"%s\"", str_cmd );
+                    }else {
+                        log_it(L_WARNING,"No function for command \"%s\" but it registred?!", str_cmd );
+                    }
+
+                    // find '-verbose' command
+                    l_verbose = dap_cli_server_cmd_find_option_val( l_argv, 1, argc, "-verbose", NULL );
+                    dap_strfreev( l_argv );
+
+                } else {
+                    str_reply = dap_strdup_printf("can't recognize command = %s", str_cmd );
+                    log_it( L_ERROR, str_reply );
+                }
+
+                char *reply_body;
+
+                if(l_verbose)
+                  reply_body = dap_strdup_printf("%d\r\nret_code: %d\r\n%s\r\n", res, res, (str_reply) ? str_reply : "");
+                else
+                  reply_body = dap_strdup_printf("%d\r\n%s\r\n", res, (str_reply) ? str_reply : "");
+
+                // return the result of the command function
+                char *reply_str = dap_strdup_printf( "HTTP/1.1 200 OK\r\n"
+                                                    "Content-Length: %d\r\n\r\n"
+                                                    "%s",
+                        strlen(reply_body), reply_body );
+
+                int ret;// = send( newsockfd, reply_str, strlen(reply_str) ,0 );
+
+                WriteFile( hPipe, reply_str, strlen(reply_str), (LPDWORD)&ret, NULL );
+
+                DAP_DELETE(str_reply);
+                DAP_DELETE(reply_str);
+                DAP_DELETE(reply_body);
+
+                DAP_DELETE(str_cmd);
+            }
+            dap_list_free_full(cmd_param_list, free);
+            break;
+        }
+    }
+
+    // close connection
+//    int cs = closesocket(newsockfd);
+
+    log_it( L_INFO, "close connection pipe = %p", hPipe );
+
+    FlushFileBuffers( hPipe );
+    DisconnectNamedPipe( hPipe );
+    CloseHandle( hPipe );
+
+    return NULL;
+}
+
+
+/**
+ * @brief thread_pipe_func
+ * main threading server function pipe win32
+ * @param args
+ * @return void*
+ */
+static void* thread_pipe_func( void *args )
+{
+   UNUSED(args);
+   BOOL   fConnected = FALSE;
+   pthread_t threadId;
+   HANDLE hPipe = INVALID_HANDLE_VALUE;
+   static const char *cPipeName = "\\\\.\\pipe\\node_cli.pipe";
+
+   for (;;)
+   {
+///      printf( "\nPipe Server: Main thread awaiting client connection on %s\n", lpszPipename );
+
+      hPipe = CreateNamedPipe(
+          cPipeName,                // pipe name
+          PIPE_ACCESS_DUPLEX,       // read/write access
+          PIPE_TYPE_MESSAGE |       // message type pipe
+          PIPE_READMODE_MESSAGE |   // message-read mode
+          PIPE_WAIT,                // blocking mode
+          PIPE_UNLIMITED_INSTANCES, // max. instances
+          4096,                     // output buffer size
+          4096,                     // input buffer size
+          0,                        // client time-out
+          NULL );                   // default security attribute
+
+      if ( hPipe == INVALID_HANDLE_VALUE ) {
+          log_it( L_ERROR, "CreateNamedPipe failed, GLE = %lu.\n", GetLastError() );
+          return NULL;
+      }
+
+      fConnected = ConnectNamedPipe( hPipe, NULL ) ? TRUE : ( GetLastError() == ERROR_PIPE_CONNECTED );
+
+      if ( fConnected )
+      {
+        log_it( L_INFO, "Client %p connected, creating a processing thread.\n", hPipe );
+
+        pthread_create( &threadId, NULL, thread_pipe_client_func, hPipe );
+        pthread_detach( threadId );
+      }
+      else
+         CloseHandle( hPipe );
+    }
+
+    return NULL;
+}
+#endif
+
 
 /**
  * @brief dap_cli_server_init
@@ -328,280 +623,62 @@ int res;
 
         // feature of disconnection under Unix (QNX)
         // under Windows, with socket closed res = 0, in Unix res = -1
-        char buf[2];
-        if ( 0 > (res = recv(sd, buf, 1, MSG_PEEK)) ) // MSG_PEEK  The data is treated as unread and the next recv() function shall still return this data.
-            return false;
-
-        // data in the buffer must be(count_desc>0), but read 0 bytes(res=0)
-        if(!res && (fds.revents & POLLIN))
-            return false;
-    }
-
-    return true;
-}
-
-
-/**
- * @brief s_get_next_str
- * Reading from the socket till arrival the specified string
- *
- * stop_str - string to which reading will continue
- * del_stop_str - удалять ли строку для поиска в конце
- * timeout - in ms
- * return: string (if waited for final characters) or NULL, if the string requires deletion
- * @param nSocket
- * @param dwLen
- * @param stop_str
- * @param del_stop_str
- * @param timeout
- * @return char*
- */
-char* s_get_next_str( SOCKET nSocket, int *dwLen, const char *stop_str, bool del_stop_str, int timeout )
-{
-    bool bSuccess = false;
-    long nRecv = 0; // count of bytes received
-    size_t stop_str_len = (stop_str) ? strlen(stop_str) : 0;
-    // if there is nothing to look for
-    if(!stop_str_len)
-        return NULL;
-    size_t lpszBuffer_len = 256;
-    char *lpszBuffer = DAP_NEW_Z_SIZE(char, lpszBuffer_len);
-    // received string will not be larger than MAX_REPLY_LEN
-
-    while(1) //nRecv < MAX_REPLY_LEN)
-    {
-        // read one byte
-        long ret = dap_net_recv(nSocket, (unsigned char *) (lpszBuffer + nRecv), 1, timeout);
-        //int ret = recv(nSocket,lpszBuffer+nRecv,1, 0);
-        if(ret <= 0)
-                {
-            break;
-        }
-        nRecv += ret;
-        //printf("**debug** socket=%d read  %d bytes '%0s'",nSocket, ret, (lpszBuffer + nRecv));
-        while((nRecv + 1) >= (long) lpszBuffer_len)
-        {
-            lpszBuffer_len *= 2;
-            lpszBuffer = (char*) realloc(lpszBuffer, lpszBuffer_len);
-        }
-        // search for the required string
-        if(nRecv >=  (long) stop_str_len) {
-            // found the required string
-            if(!strncasecmp(lpszBuffer + nRecv - stop_str_len, stop_str, stop_str_len)) {
-                bSuccess = true;
-                break;
-            }
-        }
-    };
-
-    // end reading
-
-    if(bSuccess) {
-        // delete the searched string
-        if(del_stop_str) {
-            lpszBuffer[nRecv -  (long) stop_str_len] = '\0';
-            if(dwLen)
-                *dwLen =(int) nRecv - (int) stop_str_len;
-        }
-        else {
-            lpszBuffer[nRecv] = '\0';
-            if(dwLen)
-                *dwLen = (int) nRecv;
-        }
-        char * l_buf_realloc = DAP_REALLOC(lpszBuffer,(size_t) *dwLen + 1);
-        if( l_buf_realloc)
-            lpszBuffer = l_buf_realloc;
-        return lpszBuffer;
-    }
-
-    // in case of an error or missing string
-
-    if(dwLen)
-        *dwLen = 0;
-
-    free(lpszBuffer);
-
-    return NULL;
-}
-
-/**
- * threading function for processing a request from a client
- */
-static void* s_thread_one_client_func(void *args)
-{
-SOCKET  newsockfd = (SOCKET) (intptr_t) args;
-int     str_len, marker = 0, timeout = 5000, argc = 0, is_data;
-dap_list_t *cmd_param_list = NULL;
-char    *str_header;
-
-    if(s_debug_cli)
-        log_it(L_DEBUG, "new connection sockfd=%"DAP_FORMAT_SOCKET, newsockfd);
-
-
-    while ( !(0 > (is_data = s_poll(newsockfd, timeout))) )                 // wait data from client
-    {
-        if ( !(is_data) )                                                   // timeout
-            continue;
-
-        if ( !is_valid_socket(newsockfd) )
-            break;
-
-        // receiving http header
-        if ( !(str_header = s_get_next_str(newsockfd, &str_len, "\r\n", true, timeout)) )
-            break;                                                          // bad format
-
-        if(str_header && !strlen(str_header) ) {
-            marker++;
-            if(marker == 1){
-                DAP_DELETE(str_header);
-                continue;
-            }
-        }
-
-        // filling parameters of command
-        if(marker == 1) {
-            cmd_param_list = dap_list_append(cmd_param_list, str_header);
-            //printf("g_list_append argc=%d command=%s ", argc, str_header);
-            argc++;
-        }
-        else
-            DAP_DEL_Z(str_header);
-
-        if(marker == 2 &&  cmd_param_list) {
-            dap_list_t *list = cmd_param_list;
-            // form command
-            argc = dap_list_length(list);
-            // command is found
-            if(argc >= 1) {
-              int l_verbose = 0;
-                char *cmd_name = list->data;
-                list = dap_list_next(list);
-                // execute command
-                char *str_cmd = dap_strdup_printf("%s", cmd_name);
-                dap_cli_cmd_t *l_cmd = dap_cli_server_cmd_find(cmd_name);
-                int res = -1;
-                char *str_reply = NULL;
-                if(l_cmd){
-                    while(list) {
-                        char *str_cmd_prev = str_cmd;
-                        str_cmd = dap_strdup_printf("%s;%s", str_cmd, list->data);
-                        list = dap_list_next(list);
-                        DAP_DELETE(str_cmd_prev);
-                    }
-                    if(l_cmd->overrides.log_cmd_call)
-                        l_cmd->overrides.log_cmd_call(str_cmd);
-                    else
-                        log_it(L_DEBUG, "execute command=%s", str_cmd);
-                    // exec command
-
-                    char **l_argv = dap_strsplit(str_cmd, ";", -1);
-                    // Call the command function
-                    if(l_cmd &&  l_argv && l_cmd->func) {
-                        if (l_cmd->arg_func) {
-                            res = l_cmd->func_ex(argc, l_argv, l_cmd->arg_func, &str_reply);
-                        } else {
-                            res = l_cmd->func(argc, l_argv, &str_reply);
-                        }
-                    } else if (l_cmd) {
-                        log_it(L_WARNING,"NULL arguments for input for command \"%s\"", str_cmd);
-                    }else {
-                        log_it(L_WARNING,"No function for command \"%s\" but it registred?!", str_cmd);
-                    }
-                    // find '-verbose' command
-                    l_verbose = dap_cli_server_cmd_find_option_val(l_argv, 1, argc, "-verbose", NULL);
-                    dap_strfreev(l_argv);
-                } else {
-                    str_reply = dap_strdup_printf("can't recognize command=%s", str_cmd);
-                    log_it(L_ERROR,"Reply string: \"%s\"", str_reply);
-                }
-                char *reply_body;
-                if(l_verbose)
-                  reply_body = dap_strdup_printf("%d\r\nret_code: %d\r\n%s\r\n", res, res, (str_reply) ? str_reply : "");
-                else
-                  reply_body = dap_strdup_printf("%d\r\n%s\r\n", res, (str_reply) ? str_reply : "");
-                // return the result of the command function
-                char *reply_str = dap_strdup_printf("HTTP/1.1 200 OK\r\n"
-                                                    "Content-Length: %d\r\n\r\n"
-                                                    "%s", strlen(reply_body), reply_body);
-                size_t l_reply_step = 32768;
-                size_t l_reply_len = strlen(reply_str);
-                size_t l_reply_rest = l_reply_len;
-
-                while(l_reply_rest) {
-                    size_t l_send_bytes = min(l_reply_step, l_reply_rest);
-                    int ret = send(newsockfd, reply_str + l_reply_len - l_reply_rest, l_send_bytes, 0);
-                    if(ret<=0)
-                        break;
-                    l_reply_rest-=l_send_bytes;
-                };
-
-                DAP_DELETE(str_reply);
-                DAP_DELETE(reply_str);
-                DAP_DELETE(reply_body);
+        char buf[2];
+        if ( 0 > (res = recv(sd, buf, 1, MSG_PEEK)) ) // MSG_PEEK  The data is treated as unread and the next recv() function shall still return this data.
+            return false;
 
-                DAP_DELETE(str_cmd);
-            }
-            dap_list_free_full(cmd_param_list, NULL);
-            break;
-        }
+        // data in the buffer must be(count_desc>0), but read 0 bytes(res=0)
+        if(!res && (fds.revents & POLLIN))
+            return false;
     }
-    // close connection
-    int cs = closesocket(newsockfd);
-    if (s_debug_cli)
-        log_it(L_DEBUG, "close connection=%d sockfd=%"DAP_FORMAT_SOCKET, cs, newsockfd);
 
-    return NULL;
+    return true;
 }
 
-#ifdef _WIN32
 
 /**
- * @brief p_get_next_str
+ * @brief s_get_next_str
+ * Reading from the socket till arrival the specified string
  *
- * @param hPipe
+ * stop_str - string to which reading will continue
+ * del_stop_str - удалять ли строку для поиска в конце
+ * timeout - in ms
+ * return: string (if waited for final characters) or NULL, if the string requires deletion
+ * @param nSocket
  * @param dwLen
  * @param stop_str
  * @param del_stop_str
  * @param timeout
  * @return char*
  */
-char *p_get_next_str( HANDLE hPipe, int *dwLen, const char *stop_str, bool del_stop_str, int timeout )
+char* s_get_next_str( SOCKET nSocket, int *dwLen, const char *stop_str, bool del_stop_str, int timeout )
 {
-    UNUSED(timeout);
     bool bSuccess = false;
     long nRecv = 0; // count of bytes received
     size_t stop_str_len = (stop_str) ? strlen(stop_str) : 0;
     // if there is nothing to look for
-
     if(!stop_str_len)
         return NULL;
-
     size_t lpszBuffer_len = 256;
     char *lpszBuffer = DAP_NEW_Z_SIZE(char, lpszBuffer_len);
     // received string will not be larger than MAX_REPLY_LEN
 
-    while( 1 ) //nRecv < MAX_REPLY_LEN)
+    while(1) //nRecv < MAX_REPLY_LEN)
     {
-      long ret = 0;
         // read one byte
-//        long ret = s_recv( nSocket, (unsigned char *) (lpszBuffer + nRecv), 1, timeout);
-
-      bSuccess = ReadFile( hPipe, lpszBuffer + nRecv,
-         lpszBuffer_len - nRecv, (LPDWORD)&ret, NULL );
-
+        long ret = dap_net_recv(nSocket, (unsigned char *) (lpszBuffer + nRecv), 1, timeout);
         //int ret = recv(nSocket,lpszBuffer+nRecv,1, 0);
-        if ( ret <= 0 || !bSuccess )
+        if(ret <= 0)
+                {
             break;
-
+        }
         nRecv += ret;
         //printf("**debug** socket=%d read  %d bytes '%0s'",nSocket, ret, (lpszBuffer + nRecv));
-
         while((nRecv + 1) >= (long) lpszBuffer_len)
         {
             lpszBuffer_len *= 2;
             lpszBuffer = (char*) realloc(lpszBuffer, lpszBuffer_len);
         }
-
         // search for the required string
         if(nRecv >=  (long) stop_str_len) {
             // found the required string
@@ -626,7 +703,9 @@ char *p_get_next_str( HANDLE hPipe, int *dwLen, const char *stop_str, bool del_s
             if(dwLen)
                 *dwLen = (int) nRecv;
         }
-        lpszBuffer = DAP_REALLOC(lpszBuffer,(size_t) *dwLen + 1);
+        char * l_buf_realloc = DAP_REALLOC(lpszBuffer,(size_t) *dwLen + 1);
+        if( l_buf_realloc)
+            lpszBuffer = l_buf_realloc;
         return lpszBuffer;
     }
 
@@ -641,136 +720,115 @@ char *p_get_next_str( HANDLE hPipe, int *dwLen, const char *stop_str, bool del_s
 }
 
 /**
- * @brief thread_pipe_client_func
  * threading function for processing a request from a client
- * @param args
- * @return void*
  */
-static void *thread_pipe_client_func( void *args )
+static void* s_thread_one_client_func(void *args)
 {
-    HANDLE hPipe = (HANDLE)args;
+SOCKET  newsockfd = (SOCKET) (intptr_t) args;
+int     str_len, marker = 0, timeout = 5000, argc = 0, is_data;
+dap_list_t *cmd_param_list = NULL;
+char    *str_header;
 
-//    SOCKET newsockfd = (SOCKET) (intptr_t) args;
     if(s_debug_cli)
-        log_it(L_INFO, "new connection pipe = %p", hPipe);
-
-    int str_len, marker = 0;
-    int timeout = 5000; // 5 sec
-    int argc = 0;
+        log_it(L_DEBUG, "new connection sockfd=%"DAP_FORMAT_SOCKET, newsockfd);
 
-    dap_list_t *cmd_param_list = NULL;
 
-    while( 1 )
+    while ( !(0 > (is_data = s_poll(newsockfd, timeout))) )                 // wait data from client
     {
-        // wait data from client
-//        int is_data = s_poll( newsockfd, timeout );
-        // timeout
-//        if(!is_data)
-//            continue;
-        // error (may be socket closed)
-//        if(is_data < 0)
-//            break;
+        if ( !(is_data) )                                                   // timeout
+            continue;
 
-//        int is_valid = is_valid_socket(newsockfd);
-//        if(!is_valid)
-//        {
-//            break;
-//        }
+        if ( !is_valid_socket(newsockfd) )
+            break;
 
         // receiving http header
-        char *str_header = p_get_next_str( hPipe, &str_len, "\r\n", true, timeout );
-
-        // bad format
-        if(!str_header)
-            break;
+        if ( !(str_header = s_get_next_str(newsockfd, &str_len, "\r\n", true, timeout)) )
+            break;                                                          // bad format
 
-        if ( str_header && strlen(str_header) == 0) {
+        if(str_header && !strlen(str_header) ) {
             marker++;
-            if(marker == 1)
+            if(marker == 1){
+                DAP_DELETE(str_header);
                 continue;
+            }
         }
 
         // filling parameters of command
-        if ( marker == 1 ) {
-            cmd_param_list = dap_list_append( cmd_param_list, str_header );
+        if(marker == 1) {
+            cmd_param_list = dap_list_append(cmd_param_list, str_header);
             //printf("g_list_append argc=%d command=%s ", argc, str_header);
-            argc ++;
+            argc++;
         }
         else
-            free( str_header );
-
-        if ( marker == 2 ) {
+            DAP_DEL_Z(str_header);
 
+        if(marker == 2 &&  cmd_param_list) {
             dap_list_t *list = cmd_param_list;
             // form command
-
-            unsigned int argc = dap_list_length( list );
+            argc = dap_list_length(list);
             // command is found
-
-            if ( argc >= 1) {
-
-                int l_verbose = 0;
+            if(argc >= 1) {
+              int l_verbose = 0;
                 char *cmd_name = list->data;
-                list = dap_list_next( list );
-
+                list = dap_list_next(list);
                 // execute command
-                char *str_cmd = dap_strdup_printf( "%s", cmd_name );
-                dap_cli_cmd_t *l_cmd = dap_cli_server_cmd_find( cmd_name );
+                char *str_cmd = dap_strdup_printf("%s", cmd_name);
+                dap_cli_cmd_t *l_cmd = dap_cli_server_cmd_find(cmd_name);
                 int res = -1;
                 char *str_reply = NULL;
-
-                if ( l_cmd ) {
-
-                    while( list ) {
-                        str_cmd = dap_strdup_printf( "%s;%s", str_cmd, list->data );
+                if(l_cmd){
+                    while(list) {
+                        char *str_cmd_prev = str_cmd;
+                        str_cmd = dap_strdup_printf("%s;%s", str_cmd, list->data);
                         list = dap_list_next(list);
+                        DAP_DELETE(str_cmd_prev);
                     }
-
-                    log_it(L_INFO, "execute command = %s", str_cmd );
+                    if(l_cmd->overrides.log_cmd_call)
+                        l_cmd->overrides.log_cmd_call(str_cmd);
+                    else
+                        log_it(L_DEBUG, "execute command=%s", str_cmd);
                     // exec command
 
-                    char **l_argv = dap_strsplit( str_cmd, ";", -1 );
+                    char **l_argv = dap_strsplit(str_cmd, ";", -1);
                     // Call the command function
-
-                    if ( l_cmd &&  l_argv && l_cmd->func ) {
+                    if(l_cmd &&  l_argv && l_cmd->func) {
                         if (l_cmd->arg_func) {
                             res = l_cmd->func_ex(argc, l_argv, l_cmd->arg_func, &str_reply);
                         } else {
                             res = l_cmd->func(argc, l_argv, &str_reply);
                         }
-                    }
-
-                    else if ( l_cmd ) {
-                        log_it(L_WARNING,"NULL arguments for input for command \"%s\"", str_cmd );
+                    } else if (l_cmd) {
+                        log_it(L_WARNING,"NULL arguments for input for command \"%s\"", str_cmd);
                     }else {
-                        log_it(L_WARNING,"No function for command \"%s\" but it registred?!", str_cmd );
+                        log_it(L_WARNING,"No function for command \"%s\" but it registred?!", str_cmd);
                     }
-
                     // find '-verbose' command
-                    l_verbose = dap_cli_server_cmd_find_option_val( l_argv, 1, argc, "-verbose", NULL );
-                    dap_strfreev( l_argv );
-
+                    l_verbose = dap_cli_server_cmd_find_option_val(l_argv, 1, argc, "-verbose", NULL);
+                    dap_strfreev(l_argv);
                 } else {
-                    str_reply = dap_strdup_printf("can't recognize command = %s", str_cmd );
-                    log_it( L_ERROR, str_reply );
+                    str_reply = dap_strdup_printf("can't recognize command=%s", str_cmd);
+                    log_it(L_ERROR,"Reply string: \"%s\"", str_reply);
                 }
-
                 char *reply_body;
-
                 if(l_verbose)
                   reply_body = dap_strdup_printf("%d\r\nret_code: %d\r\n%s\r\n", res, res, (str_reply) ? str_reply : "");
                 else
                   reply_body = dap_strdup_printf("%d\r\n%s\r\n", res, (str_reply) ? str_reply : "");
-
                 // return the result of the command function
-                char *reply_str = dap_strdup_printf( "HTTP/1.1 200 OK\r\n"
+                char *reply_str = dap_strdup_printf("HTTP/1.1 200 OK\r\n"
                                                     "Content-Length: %d\r\n\r\n"
-                                                    "%s",
-                        strlen(reply_body), reply_body );
-
-                int ret;// = send( newsockfd, reply_str, strlen(reply_str) ,0 );
+                                                    "%s", strlen(reply_body), reply_body);
+                size_t l_reply_step = 32768;
+                size_t l_reply_len = strlen(reply_str);
+                size_t l_reply_rest = l_reply_len;
 
-                WriteFile( hPipe, reply_str, strlen(reply_str), (LPDWORD)&ret, NULL );
+                while(l_reply_rest) {
+                    size_t l_send_bytes = min(l_reply_step, l_reply_rest);
+                    int ret = send(newsockfd, reply_str + l_reply_len - l_reply_rest, l_send_bytes, 0);
+                    if(ret<=0)
+                        break;
+                    l_reply_rest-=l_send_bytes;
+                };
 
                 DAP_DELETE(str_reply);
                 DAP_DELETE(reply_str);
@@ -778,76 +836,17 @@ static void *thread_pipe_client_func( void *args )
 
                 DAP_DELETE(str_cmd);
             }
-            dap_list_free_full(cmd_param_list, free);
+            dap_list_free_full(cmd_param_list, NULL);
             break;
         }
     }
-
     // close connection
-//    int cs = closesocket(newsockfd);
-
-    log_it( L_INFO, "close connection pipe = %p", hPipe );
-
-    FlushFileBuffers( hPipe );
-    DisconnectNamedPipe( hPipe );
-    CloseHandle( hPipe );
-
-    return NULL;
-}
-
-
-/**
- * @brief thread_pipe_func
- * main threading server function pipe win32
- * @param args
- * @return void*
- */
-static void* thread_pipe_func( void *args )
-{
-   UNUSED(args);
-   BOOL   fConnected = FALSE;
-   pthread_t threadId;
-   HANDLE hPipe = INVALID_HANDLE_VALUE;
-   static const char *cPipeName = "\\\\.\\pipe\\node_cli.pipe";
-
-   for (;;)
-   {
-///      printf( "\nPipe Server: Main thread awaiting client connection on %s\n", lpszPipename );
-
-      hPipe = CreateNamedPipe(
-          cPipeName,                // pipe name
-          PIPE_ACCESS_DUPLEX,       // read/write access
-          PIPE_TYPE_MESSAGE |       // message type pipe
-          PIPE_READMODE_MESSAGE |   // message-read mode
-          PIPE_WAIT,                // blocking mode
-          PIPE_UNLIMITED_INSTANCES, // max. instances
-          4096,                     // output buffer size
-          4096,                     // input buffer size
-          0,                        // client time-out
-          NULL );                   // default security attribute
-
-      if ( hPipe == INVALID_HANDLE_VALUE ) {
-          log_it( L_ERROR, "CreateNamedPipe failed, GLE = %lu.\n", GetLastError() );
-          return NULL;
-      }
-
-      fConnected = ConnectNamedPipe( hPipe, NULL ) ? TRUE : ( GetLastError() == ERROR_PIPE_CONNECTED );
-
-      if ( fConnected )
-      {
-        log_it( L_INFO, "Client %p connected, creating a processing thread.\n", hPipe );
-
-        pthread_create( &threadId, NULL, thread_pipe_client_func, hPipe );
-        pthread_detach( threadId );
-      }
-      else
-         CloseHandle( hPipe );
-    }
+    int cs = closesocket(newsockfd);
+    if (s_debug_cli)
+        log_it(L_DEBUG, "close connection=%d sockfd=%"DAP_FORMAT_SOCKET, cs, newsockfd);
 
     return NULL;
 }
-#endif
-
 
 /**
  * @brief thread_main_func
diff --git a/dap-sdk/net/server/enc_server/CMakeLists.txt b/dap-sdk/net/server/enc_server/CMakeLists.txt
index 8aaba2be3c..e29d8f7368 100644
--- a/dap-sdk/net/server/enc_server/CMakeLists.txt
+++ b/dap-sdk/net/server/enc_server/CMakeLists.txt
@@ -20,23 +20,23 @@ target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..
 
 if(WIN32)
   target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_io dap_http_server json-c
-  KERNEL32
-  USER32
-  SHELL32
-  WINMM
-  GDI32
-  ADVAPI32
-  Ole32
-  Version
-  Imm32
-  OleAut32
+  kernel32
+  user32
+  shell32
+  winmm
+  gdi32
+  advapi32
+  ole32
+  version
+  imm32
+  oleaut32
   ws2_32
   ntdll
   psapi
-  Shlwapi
-  Bcrypt
-  Crypt32
-  Secur32
+  shlwapi
+  bcrypt
+  crypt32
+  secur32
 )
 endif()
 
diff --git a/dap-sdk/net/server/http_server/CMakeLists.txt b/dap-sdk/net/server/http_server/CMakeLists.txt
index 2af0aec59f..b2b3d166ac 100644
--- a/dap-sdk/net/server/http_server/CMakeLists.txt
+++ b/dap-sdk/net/server/http_server/CMakeLists.txt
@@ -27,23 +27,23 @@ endif()
 
 if(WIN32)
   target_link_libraries(dap_http_server dap_core dap_crypto dap_io magic regex tre intl iconv
-  KERNEL32
-  USER32
-  SHELL32
-  WINMM
-  GDI32
-  ADVAPI32
-  Ole32
-  Version
-  Imm32
-  OleAut32
+  kernel32
+  user32
+  shell32
+  winmm
+  gdi32
+  advapi32
+  ole32
+  version
+  imm32
+  oleaut32
   ws2_32
   ntdll
   psapi
-  Shlwapi
-  Bcrypt
-  Crypt32
-  Secur32
+  shlwapi
+  bcrypt
+  crypt32
+  secur32
 )
 endif()
 
diff --git a/dap-sdk/plugin/CMakeLists.txt b/dap-sdk/plugin/CMakeLists.txt
index 1406a0fc98..b403250922 100644
--- a/dap-sdk/plugin/CMakeLists.txt
+++ b/dap-sdk/plugin/CMakeLists.txt
@@ -12,7 +12,11 @@ add_library(${PROJECT_NAME} STATIC ${DAP_PLUGIN_SRCS} ${DAP_PLUGIN_HEADERS})
 
 target_link_libraries(${PROJECT_NAME})
 
-target_link_libraries(${PROJECT_NAME} dap_core dap_cli_server dl)
+target_link_libraries(${PROJECT_NAME} dap_core dap_cli_server )
+
+if(NOT WIN32)
+    target_link_libraries(${PROJECT_NAME} dl )
+endif()
 
 target_include_directories(${PROJECT_NAME} PUBLIC include/ )
 
-- 
GitLab