diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9bbd7daf6061f8f2cdee67ade8ce119c94665c0c..c925aab3c2f19f8186937f474eff05ab4cc219b9 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -36,7 +36,7 @@ stages:
   interruptible: true
   variables:
     
-    PATCH_NUM_MAIN: "${release_5_3_PATCH_NUM}"
+    PATCH_NUM_MAIN: "${master_PATCH_NUM}"
 
   rules:
     - if: $CI_COMMIT_REF_NAME =~ /-asan$/
@@ -135,7 +135,7 @@ amd64:linux.rwd:
       - *fill_version_mk
     script:
       - echo "Do hard work"
-      - /opt/buildtools/deploy_files.sh pub_cellframe linux/cellframe-node/$CI_COMMIT_REF_NAME/ build_*/*.deb 
+      - /opt/buildtools/deploy_files.sh pub_cellframe linux/cellframe-node/$CI_COMMIT_REF_NAME/ build_*/*.deb --redirect-from linux/cellframe-node/$CI_COMMIT_REF_NAME/latest-amd64
       
 
 amd64:windows.rwd:
@@ -195,7 +195,7 @@ amd64:linux.rwd.opt:
       - /opt/buildtools/deploy_files.sh pub_cellframe linux/cellframe-node/$CI_COMMIT_REF_NAME/ build_*/*.deb  --redirect-from linux/cellframe-node/$CI_COMMIT_REF_NAME/latest-amd64.opt
 
 
-.amd64:linux.tps:
+amd64:linux.tps:
     extends: .build
     image: demlabs/debian/amd64:qt5
     before_script: 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index daf05d31a6f21918aec1eb2575360b017f8208d0..98e95ca60c75143ef6762720fcfaddb913d33ec3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,6 +23,17 @@ SET(CMAKE_INSTALL_PREFIX "/opt/${PROJECT_NAME}")
 SET(CPACK_INSTALL_PREFIX "/opt/${PROJECT_NAME}")
 SET(DESTDIR "/opt/${PROJECT_NAME}")
 
+string(TIMESTAMP BUILD_TIMESTAMP "%d.%m.%Y")
+
+execute_process(
+    COMMAND git log -1 --format=%h
+    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+    OUTPUT_VARIABLE GIT_COMMIT_HASH
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+message("Build date: ${BUILD_TIMESTAMP}")
+message("Git SHA: ${GIT_COMMIT_HASH}")
+
 #SET(DAP_PQLR OFF)
 #possible need be setted during crosscompily
 #by default it uses dpkg --print-architecture
@@ -32,6 +43,8 @@ SET(DESTDIR "/opt/${PROJECT_NAME}")
 
 # init CellFrame SDK
 add_definitions("-DDAP_VERSION=\"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}-${CPACK_PACKAGE_VERSION_PATCH}\"")
+add_definitions("-DBUILD_TS=\"${BUILD_TIMESTAMP}\"")
+add_definitions("-DBUILD_HASH=\"${GIT_COMMIT_HASH}\"")
 set(SUBMODULES_NO_BUILD ON)
 option(CELLFRAME_NO_OPTIMIZATION "Build without BMI BMI2 CPU instruction." ON)
 
diff --git a/conftool/commands/ConfigCommand.cpp b/conftool/commands/ConfigCommand.cpp
index 29d59a8a5a36109aacdbddbd7d90015b347e9af1..a7db2f321c4a6ee473b743bca4b2256907d153e7 100644
--- a/conftool/commands/ConfigCommand.cpp
+++ b/conftool/commands/ConfigCommand.cpp
@@ -132,11 +132,11 @@ bool CConfigCommand::execute(bool non_intercative, int flags)
         std::string cfg_val;
         bool param_exists = cfg.exists(this->group, this->param, &cfg_val);
         std::cout << this->cfg_name << ": ["<<this->group<<"] " << this->param+"="+cfg_val<<std::endl;
-        return true;
+        return false;
     };
     
     //actions return true if config was altered and need to be saved
     bool res =  actions[this->action]();
     if (res) cfg.save();
-    return res;
+    return true;
 }
diff --git a/conftool/service/service_win.cpp b/conftool/service/service_win.cpp
index fedeb37496cde298e0d14248cba24c41be3a8cbf..bc39b583e651038f184475c73bc7fc6d1e7e9e51 100644
--- a/conftool/service/service_win.cpp
+++ b/conftool/service/service_win.cpp
@@ -15,7 +15,7 @@ bool isProcessRunning(const TCHAR* const executableName) {
     PROCESSENTRY32 entry;
     entry.dwSize = sizeof(PROCESSENTRY32);
 
-    const auto snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
+    const auto snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 
     if (!Process32First(snapshot, &entry)) {
         CloseHandle(snapshot);
diff --git a/dist/share/configs/cellframe-node.cfg b/dist/share/configs/cellframe-node.cfg
index c1f66cb450692c483e122630c72553655ffd1978..5b1601e21d6ca11486973d9e7ab92efc5bfc9b10 100644
--- a/dist/share/configs/cellframe-node.cfg
+++ b/dist/share/configs/cellframe-node.cfg
@@ -38,9 +38,8 @@ listen_address=
 
 [notify_server]
 # Listening path have priority above listening address examples to use
-# listen_path=[listen_path1:listen_path_mode,listen_path2:listen_path_mode,...]
+# listen_path=[listen/path1,listen/path2,...]
 # listen_address=[listen_address1:port1,port2,listen_address2:port3,...]
-#listen_path=[{CONFIGS_PATH}/var/run/node_notify:600]
 listen_address=
 
 [stream]
@@ -164,21 +163,14 @@ network_mask=255.255.255.0
 enabled=true
 # debug_more=false
 # debug-cli=false
-#listen_port_tcp=12345
-#listen_unix_socket_path=../var/run/node_cli
-# Default permissions 770
-# IMPORTANT! Its accessible for all the users in system!
-listen_unix_socket_permissions=777
+#unix-only
+#listen-path=[../var/run/node_cli]
+#listen-address=[127.0.0.1:12345]
 
 # Application Resources
 [resources]
 #   0 means auto detect
 threads_cnt=0 
-# By default notify opens at {CONFIGS_PATH}/var/run/node_notify
-notify_path=../var/run/node_notify
-#notify_permissions=770
-#notify_user=myuser
-#notify_group=mygroup
 pid_path=../var/run/cellframe-node.pid
 log_file=../var/log/cellframe-node.log
 wallets_path=../var/lib/wallet
@@ -187,6 +179,7 @@ ca_folders=[../var/lib/ca,../share/ca]
 # datum_folder=
 
 [global_db]
+#debug_more=true
 path=../var/lib/global_db
 driver=
 #debug_more=true
@@ -198,4 +191,4 @@ enabled=true
 # Load Python-based plugins
 #py_load=true   
 # Path to Pyhon-based plugins
-#py_path={CONFIGS_PATH}/var/lib/plugins
+#py_path=../var/lib/plugins
diff --git a/sources/cellframe-node.c b/sources/cellframe-node.c
index 250ec008d56560cca0cf3acd9d7b459848c75620..ac8bd2c510661a8385aa3a0db8d418067a4b3d9c 100755
--- a/sources/cellframe-node.c
+++ b/sources/cellframe-node.c
@@ -33,6 +33,8 @@
 #include <sys/types.h>
 #include <getopt.h>
 #include <signal.h>
+#include <errno.h>
+#include <unistd.h>
 
 #ifdef _WIN32
 #include <winsock2.h>
@@ -124,13 +126,8 @@
 
 #define MEMPOOL_URL "/mempool"
 #define MAIN_URL "/"
-
-void parse_args( int argc, const char **argv );
-void exit_if_server_already_running( void );
-
-#ifndef DAP_OS_WINDOWS
-static const char *s_pid_file_path = NULL;
-#endif
+const char *dap_node_version();
+static int s_proc_running_check(const char *a_path);
 
 #ifdef DAP_OS_ANDROID
 #include "dap_app_cli.h"
@@ -138,6 +135,18 @@ static const char *s_pid_file_path = NULL;
 #include <jni.h>
 #endif
 
+#ifndef BUILD_HASH
+#define BUILD_HASH "0000000" // 0000000 means uninitialized
+#endif
+
+#ifndef BUILD_TS
+#define BUILD_TS "undefined"
+#endif
+
+const char *dap_node_version() {
+    return "CellframeNode, " DAP_VERSION ", " BUILD_TS ", " BUILD_HASH;
+}
+
 void set_global_sys_dir(const char *dir)
 {
     g_sys_dir_path = dap_strdup(dir);
@@ -145,6 +154,9 @@ void set_global_sys_dir(const char *dir)
 
 int main( int argc, const char **argv )
 {
+    if ( argv[1] && !dap_strcmp("-version", argv[1]) )
+        return printf("%s\n", dap_node_version()), 0;
+        
     dap_server_t *l_server = NULL; // DAP Server instance
     bool l_debug_mode = true;
     bool bServerEnabled = false;
@@ -211,15 +223,18 @@ int main( int argc, const char **argv )
 #ifndef DAP_OS_WINDOWS
     char l_default_dir[MAX_PATH] = {'\0'};
     sprintf(l_default_dir, "%s/tmp", g_sys_dir_path);
-    s_pid_file_path = dap_config_get_item_str_path_default(g_config,  "resources", "pid_path", l_default_dir) ;
-    save_process_pid_in_file(s_pid_file_path);
+    char *l_pid_file_path = dap_config_get_item_str_path_default(g_config,  "resources", "pid_path", l_default_dir);
+    int l_pid_check = s_proc_running_check(l_pid_file_path);
+    DAP_DELETE(l_pid_file_path);
+    if (l_pid_check)
+        return 2;
+#else
+    if ( s_proc_running_check("DAP_CELLFRAME_NODE_74E9201D33F7F7F684D2FEF1982799A79B6BF94"
+                              "B568446A8D1DE947B00E3C75060F3FD5BF277592D02F77D7E50935E56") )
+        return 2;
 #endif
 
     log_it(L_DEBUG, "Parsing command line args");
-    
-#if !DAP_OS_ANDROID
-    parse_args( argc, argv );
-#endif
 
     l_debug_mode = dap_config_get_item_bool_default( g_config,"general","debug_mode", false );
 
@@ -238,7 +253,7 @@ int main( int argc, const char **argv )
         log_it(L_NOTICE, "Log rotation every %lu min enabled, max log file size %lu MB",
                          l_timeout_minutes, l_max_file_size);
         int64_t l_timeout = l_timeout_minutes * 60000;
-        dap_common_enable_cleaner_log(l_timeout_minutes * 60000, &l_max_file_size);
+        dap_common_enable_cleaner_log(l_timeout_minutes * 60000, l_max_file_size);
     }
 
     if ( dap_enc_init() != 0 ){
@@ -540,7 +555,7 @@ static struct option long_options[] = {
     { NULL,   0, NULL, 0 } // must be a last element
 };
 
-void parse_args( int argc, const char **argv ) {
+/*void parse_args( int argc, const char **argv ) {
 
     int opt, option_index = 0, is_daemon = 0;
 
@@ -575,7 +590,7 @@ void parse_args( int argc, const char **argv ) {
         case 'D':
         {
             log_it( L_INFO, "Daemonize server starting..." );
-            exit_if_server_already_running( );
+            //exit_if_server_already_running( );
             is_daemon = 1;
             daemonize_process( );
             break;
@@ -586,27 +601,33 @@ void parse_args( int argc, const char **argv ) {
         }
     }
 
-    if( !is_daemon )
-        exit_if_server_already_running( );
-}
-
-void exit_if_server_already_running( void ) {
+    //if( !is_daemon )
+    //    exit_if_server_already_running( );
+}*/
 
+int s_proc_running_check(const char *a_path) {
 #ifdef DAP_OS_WINDOWS
-    CreateEvent(0, TRUE, FALSE, "DAP_CELLFRAME_NODE_74E9201D33F7F7F684D2FEF1982799A79B6BF94B568446A8D1DE947B00E3C75060F3FD5BF277592D02F77D7E50935E56");
-    if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
-        log_it( L_WARNING, "DapServer is already running, multiple instances are prohibited by config. Exiting...");
-        exit( -2 );
-    }
+    CreateEvent(0, TRUE, FALSE, a_path);
+    return GetLastError() == ERROR_ALREADY_EXISTS ? ( log_it(L_ERROR, "dap_server is already running"), 1 ) : 0;
 #else
-    pid_t pid = get_pid_from_file(s_pid_file_path);
-    struct flock lock = { .l_type = F_WRLCK };
-    int fd = open(s_pid_file_path, O_WRONLY);
-    if (fcntl(fd, F_SETLK, &lock) == -1) {
-        log_it( L_WARNING, "DapServer is already running, pid %"DAP_UINT64_FORMAT_U
-                          ", multiple instances are prohibited by config. Exiting...", (uint64_t)pid);
-        exit( -2 );
-    }
+    FILE *l_pidfile = fopen(a_path, "r");
+    if (l_pidfile) {
+        pid_t f_pid = 0;
+        fscanf( l_pidfile, "%d", &f_pid );
+        if (lockf(fileno(l_pidfile), F_TEST, 0) == -1) {
+            return log_it(L_ERROR, "Error %ld: \"%s\", dap_server is already running with PID %d",
+                           errno, dap_strerror(errno), f_pid), 1;
+        }
+        else
+            l_pidfile = freopen(a_path, "w", l_pidfile);
+    } else
+        l_pidfile = fopen(a_path, "w");
+    
+    if (!l_pidfile)
+        return log_it(L_ERROR, "Can't open file %s for writing, error %d: %s", 
+                                a_path, errno, dap_strerror(errno)), 2;
+    fprintf(l_pidfile, "%d", getpid());
+    fflush(l_pidfile);
+    return lockf(fileno(l_pidfile), F_TLOCK, sizeof(pid_t));
 #endif
-}
-
+}
\ No newline at end of file
diff --git a/sources/cellframe-node.h b/sources/cellframe-node.h
index 4519196419d00c14859c5d4e4b2c8f8af893de93..f3677cbbac0a67cb6ac68c95d9cb6a87aab7b3ac 100644
--- a/sources/cellframe-node.h
+++ b/sources/cellframe-node.h
@@ -13,6 +13,7 @@ void set_global_sys_dir(const char *dir);
 typedef bool (*dap_notify_data_user_callback_t)(const char *data);
 void dap_notify_data_set_user_callback(dap_notify_data_user_callback_t callback);
 char *dap_cli_exec(int argc, char **argv);
+const char *dap_node_version();
 
 };
 #endif //NODE_CELLFRAME_NODE_H