void xrdp_shutdown(int sig) { LONG_PTR threadid; threadid = tc_get_threadid(); g_writeln("shutting down"); g_writeln("signal %d threadid %p", sig, threadid); if (WaitForSingleObject(g_TermEvent, 0) != WAIT_OBJECT_0) SetEvent(g_TermEvent); }
void DEFAULT_CC xrdp_shutdown(int sig) { tbus threadid; threadid = tc_get_threadid(); g_writeln("shutting down"); g_writeln("signal %d threadid %p", sig, threadid); if (!g_is_wait_obj_set(g_term_event)) { g_set_wait_obj(g_term_event); } }
/* This function is used to run a function from the main thread. Sync_func is the function pointer that will run from main thread The function can have two long in parameters and must return long */ long g_xrdp_sync(long(*sync_func)(long param1, long param2), long sync_param1, long sync_param2) { long sync_result; int sync_command; /* If the function is called from the main thread, the function can * be called directly. g_threadid= main thread ID*/ if (tc_threadid_equal(tc_get_threadid(), g_threadid)) { /* this is the main thread, call the function directly */ /* in fork mode, this always happens too */ sync_result = sync_func(sync_param1, sync_param2); /*g_writeln("g_xrdp_sync processed IN main thread -> continue");*/ } else { /* All threads have to wait here until the main thread * process the function. g_process_waiting_function() is called * from the listening thread. g_process_waiting_function() process the function*/ tc_mutex_lock(g_sync1_mutex); tc_mutex_lock(g_sync_mutex); g_sync_param1 = sync_param1; g_sync_param2 = sync_param2; g_sync_func = sync_func; /* set a value THREAD_WAITING so the g_process_waiting_function function * know if any function must be processed */ g_sync_command = THREAD_WAITING; tc_mutex_unlock(g_sync_mutex); /* set this event so that the main thread know if * g_process_waiting_function() must be called */ SetEvent(g_SyncEvent); do { g_sleep(100); tc_mutex_lock(g_sync_mutex); /* load new value from global to see if the g_process_waiting_function() * function has processed the function */ sync_command = g_sync_command; sync_result = g_sync_result; tc_mutex_unlock(g_sync_mutex); } while (sync_command != 0); /* loop until g_process_waiting_function() * has processed the request */ tc_mutex_unlock(g_sync1_mutex); /*g_writeln("g_xrdp_sync processed BY main thread -> continue");*/ } return sync_result; }
long APP_CC g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1, long sync_param2) { long sync_result; int sync_command; if (tc_threadid_equal(tc_get_threadid(), g_threadid)) { /* this is the main thread, call the function directly */ sync_result = sync_func(sync_param1, sync_param2); } else { tc_mutex_lock(g_sync1_mutex); tc_mutex_lock(g_sync_mutex); g_sync_param1 = sync_param1; g_sync_param2 = sync_param2; g_sync_func = sync_func; g_sync_command = 100; tc_mutex_unlock(g_sync_mutex); g_set_wait_obj(g_sync_event); do { g_sleep(100); tc_mutex_lock(g_sync_mutex); sync_command = g_sync_command; sync_result = g_sync_result; tc_mutex_unlock(g_sync_mutex); } while (sync_command != 0); tc_mutex_unlock(g_sync1_mutex); } return sync_result; }
int DEFAULT_CC main(int argc, char **argv) { int test; int host_be; #if defined(_WIN32) WSADATA w; SC_HANDLE sc_man; SC_HANDLE sc_ser; int run_as_service; SERVICE_TABLE_ENTRY te[2]; #else int pid; int fd; int no_daemon; char text[256]; char pid_file[256]; #endif g_init(); ssl_init(); /* check compiled endian with actual endian */ test = 1; host_be = !((int)(*(unsigned char *)(&test))); #if defined(B_ENDIAN) if (!host_be) #endif #if defined(L_ENDIAN) if (host_be) #endif { g_writeln("endian wrong, edit arch.h"); return 0; } /* check long, int and void* sizes */ if (sizeof(int) != 4) { g_writeln("unusable int size, must be 4"); return 0; } if (sizeof(long) != sizeof(void *)) { g_writeln("long size must match void* size"); return 0; } if (sizeof(long) != 4 && sizeof(long) != 8) { g_writeln("unusable long size, must be 4 or 8"); return 0; } if (sizeof(tui64) != 8) { g_writeln("unusable tui64 size, must be 8"); return 0; } #if defined(_WIN32) run_as_service = 1; if (argc == 2) { if (g_strncasecmp(argv[1], "-help", 255) == 0 || g_strncasecmp(argv[1], "--help", 255) == 0 || g_strncasecmp(argv[1], "-h", 255) == 0) { g_writeln(""); g_writeln("xrdp: A Remote Desktop Protocol server."); g_writeln("Copyright (C) Jay Sorg 2004-2011"); g_writeln("See http://xrdp.sourceforge.net for more information."); g_writeln(""); g_writeln("Usage: xrdp [options]"); g_writeln(" -h: show help"); g_writeln(" -install: install service"); g_writeln(" -remove: remove service"); g_writeln(""); g_exit(0); } else if (g_strncasecmp(argv[1], "-install", 255) == 0 || g_strncasecmp(argv[1], "--install", 255) == 0 || g_strncasecmp(argv[1], "-i", 255) == 0) { /* open service manager */ sc_man = OpenSCManager(0, 0, GENERIC_WRITE); if (sc_man == 0) { g_writeln("error OpenSCManager, do you have rights?"); g_exit(0); } /* check if service is allready installed */ sc_ser = OpenService(sc_man, "xrdp", SERVICE_ALL_ACCESS); if (sc_ser == 0) { /* install service */ CreateService(sc_man, "xrdp", "xrdp", SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, "c:\\temp\\xrdp\\xrdp.exe", 0, 0, 0, 0, 0); } else { g_writeln("error service is allready installed"); CloseServiceHandle(sc_ser); CloseServiceHandle(sc_man); g_exit(0); } CloseServiceHandle(sc_man); g_exit(0); } else if (g_strncasecmp(argv[1], "-remove", 255) == 0 || g_strncasecmp(argv[1], "--remove", 255) == 0 || g_strncasecmp(argv[1], "-r", 255) == 0) { /* open service manager */ sc_man = OpenSCManager(0, 0, GENERIC_WRITE); if (sc_man == 0) { g_writeln("error OpenSCManager, do you have rights?"); g_exit(0); } /* check if service is allready installed */ sc_ser = OpenService(sc_man, "xrdp", SERVICE_ALL_ACCESS); if (sc_ser == 0) { g_writeln("error service is not installed"); CloseServiceHandle(sc_man); g_exit(0); } DeleteService(sc_ser); CloseServiceHandle(sc_man); g_exit(0); } else { g_writeln("Unknown Parameter"); g_writeln("xrdp -h for help"); g_writeln(""); g_exit(0); } } else if (argc > 1) { g_writeln("Unknown Parameter"); g_writeln("xrdp -h for help"); g_writeln(""); g_exit(0); } if (run_as_service) { g_memset(&te, 0, sizeof(te)); te[0].lpServiceName = "xrdp"; te[0].lpServiceProc = MyServiceMain; StartServiceCtrlDispatcher(&te); g_exit(0); } WSAStartup(2, &w); #else /* _WIN32 */ g_snprintf(pid_file, 255, "%s/xrdp.pid", XRDP_PID_PATH); no_daemon = 0; if (argc == 2) { if ((g_strncasecmp(argv[1], "-kill", 255) == 0) || (g_strncasecmp(argv[1], "--kill", 255) == 0) || (g_strncasecmp(argv[1], "-k", 255) == 0)) { g_writeln("stopping xrdp"); /* read the xrdp.pid file */ fd = -1; if (g_file_exist(pid_file)) /* xrdp.pid */ { fd = g_file_open(pid_file); /* xrdp.pid */ } if (fd == -1) { g_writeln("problem opening to xrdp.pid"); g_writeln("maybe its not running"); } else { g_memset(text, 0, 32); g_file_read(fd, text, 31); pid = g_atoi(text); g_writeln("stopping process id %d", pid); if (pid > 0) { g_sigterm(pid); } g_file_close(fd); } g_exit(0); } else if (g_strncasecmp(argv[1], "-nodaemon", 255) == 0 || g_strncasecmp(argv[1], "--nodaemon", 255) == 0 || g_strncasecmp(argv[1], "-nd", 255) == 0 || g_strncasecmp(argv[1], "--nd", 255) == 0 || g_strncasecmp(argv[1], "-ns", 255) == 0 || g_strncasecmp(argv[1], "--ns", 255) == 0) { no_daemon = 1; } else if (g_strncasecmp(argv[1], "-help", 255) == 0 || g_strncasecmp(argv[1], "--help", 255) == 0 || g_strncasecmp(argv[1], "-h", 255) == 0) { g_writeln(""); g_writeln("xrdp: A Remote Desktop Protocol server."); g_writeln("Copyright (C) Jay Sorg 2004-2011"); g_writeln("See http://xrdp.sourceforge.net for more information."); g_writeln(""); g_writeln("Usage: xrdp [options]"); g_writeln(" -h: show help"); g_writeln(" -nodaemon: don't fork into background"); g_writeln(" -kill: shut down xrdp"); g_writeln(""); g_exit(0); } else if ((g_strncasecmp(argv[1], "-v", 255) == 0) || (g_strncasecmp(argv[1], "--version", 255) == 0)) { g_writeln(""); g_writeln("xrdp: A Remote Desktop Protocol server."); g_writeln("Copyright (C) Jay Sorg 2004-2011"); g_writeln("See http://xrdp.sourceforge.net for more information."); g_writeln("Version %s", PACKAGE_VERSION); g_writeln(""); g_exit(0); } else { g_writeln("Unknown Parameter"); g_writeln("xrdp -h for help"); g_writeln(""); g_exit(0); } } else if (argc > 1) { g_writeln("Unknown Parameter"); g_writeln("xrdp -h for help"); g_writeln(""); g_exit(0); } if (g_file_exist(pid_file)) /* xrdp.pid */ { g_writeln("It looks like xrdp is allready running,"); g_writeln("if not delete the xrdp.pid file and try again"); g_exit(0); } if (!no_daemon) { /* make sure we can write to pid file */ fd = g_file_open(pid_file); /* xrdp.pid */ if (fd == -1) { g_writeln("running in daemon mode with no access to pid files, quitting"); g_exit(0); } if (g_file_write(fd, "0", 1) == -1) { g_writeln("running in daemon mode with no access to pid files, quitting"); g_exit(0); } g_file_close(fd); g_file_delete(pid_file); } if (!no_daemon) { /* start of daemonizing code */ pid = g_fork(); if (pid == -1) { g_writeln("problem forking"); g_exit(1); } if (0 != pid) { g_writeln("process %d started ok", pid); /* exit, this is the main process */ g_exit(0); } g_sleep(1000); g_file_close(0); g_file_close(1); g_file_close(2); g_file_open("/dev/null"); g_file_open("/dev/null"); g_file_open("/dev/null"); /* end of daemonizing code */ } if (!no_daemon) { /* write the pid to file */ pid = g_getpid(); fd = g_file_open(pid_file); /* xrdp.pid */ if (fd == -1) { g_writeln("trying to write process id to xrdp.pid"); g_writeln("problem opening xrdp.pid"); g_writeln("maybe no rights"); } else { g_sprintf(text, "%d", pid); g_file_write(fd, text, g_strlen(text)); g_file_close(fd); } } #endif g_threadid = tc_get_threadid(); g_listen = xrdp_listen_create(); g_signal_user_interrupt(xrdp_shutdown); /* SIGINT */ g_signal_kill(xrdp_shutdown); /* SIGKILL */ g_signal_pipe(pipe_sig); /* SIGPIPE */ g_signal_terminate(xrdp_shutdown); /* SIGTERM */ g_sync_mutex = tc_mutex_create(); g_sync1_mutex = tc_mutex_create(); pid = g_getpid(); g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); g_term_event = g_create_wait_obj(text); g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); g_sync_event = g_create_wait_obj(text); if (g_term_event == 0) { g_writeln("error creating g_term_event"); } xrdp_listen_main_loop(g_listen); xrdp_listen_delete(g_listen); tc_mutex_delete(g_sync_mutex); tc_mutex_delete(g_sync1_mutex); g_delete_wait_obj(g_term_event); g_delete_wait_obj(g_sync_event); #if defined(_WIN32) /* I don't think it ever gets here */ /* when running in win32 app mode, control c exits right away */ WSACleanup(); #else /* delete the xrdp.pid file */ g_file_delete(pid_file); #endif return 0; }
VOID WINAPI MyServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) { WSADATA w; char text[256]; int pid; //HANDLE event_han; // int fd; // char text[256]; // fd = g_file_open("c:\\temp\\xrdp\\log.txt"); // g_file_write(fd, "hi\r\n", 4); //event_han = RegisterEventSource(0, "xrdp"); //log_event(event_han, "hi xrdp log"); g_threadid = tc_get_threadid(); g_set_current_dir("c:\\temp\\xrdp"); g_listen = 0; WSAStartup(2, &w); g_sync_mutex = tc_mutex_create(); g_sync1_mutex = tc_mutex_create(); pid = g_getpid(); g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); g_term_event = g_create_wait_obj(text); g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); g_sync_event = g_create_wait_obj(text); g_memset(&g_service_status, 0, sizeof(SERVICE_STATUS)); g_service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; g_service_status.dwCurrentState = SERVICE_RUNNING; g_service_status.dwControlsAccepted = SERVICE_CONTROL_INTERROGATE | SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; g_service_status.dwWin32ExitCode = NO_ERROR; g_service_status.dwServiceSpecificExitCode = 0; g_service_status.dwCheckPoint = 0; g_service_status.dwWaitHint = 0; // g_sprintf(text, "calling RegisterServiceCtrlHandler\r\n"); // g_file_write(fd, text, g_strlen(text)); g_ssh = RegisterServiceCtrlHandler("xrdp", MyHandler); if (g_ssh != 0) { // g_sprintf(text, "ok\r\n"); // g_file_write(fd, text, g_strlen(text)); SetServiceStatus(g_ssh, &g_service_status); g_listen = xrdp_listen_create(); xrdp_listen_main_loop(g_listen); g_sleep(100); g_service_status.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(g_ssh, &g_service_status); } else { //g_sprintf(text, "RegisterServiceCtrlHandler failed\r\n"); //g_file_write(fd, text, g_strlen(text)); } xrdp_listen_delete(g_listen); tc_mutex_delete(g_sync_mutex); tc_mutex_delete(g_sync1_mutex); g_destroy_wait_obj(g_term_event); g_destroy_wait_obj(g_sync_event); WSACleanup(); //CloseHandle(event_han); }
int main(int argc, char **argv) { int fd; int pid; int no_daemon; char text[256]; char pid_file[256]; char cfg_file[256]; enum logReturns error; xrdpStartupParams* startup_params; g_init("xrdp"); g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); /* starting logging subsystem */ error = log_start(cfg_file, "XRDP"); if (error != LOG_STARTUP_OK) { switch (error) { case LOG_ERROR_MALLOC: g_writeln("error on malloc. cannot start logging. quitting."); break; case LOG_ERROR_FILE_OPEN: g_writeln("error opening log file [%s]. quitting.", getLogFile(text, 255)); break; default: g_writeln("log_start error"); break; } g_deinit(); g_exit(1); } startup_params = (xrdpStartupParams *) g_malloc(sizeof(xrdpStartupParams), 1); if (xrdp_process_params(argc, argv, startup_params) != 0) { g_writeln("Unknown Parameter"); g_writeln("xrdp -h for help"); g_writeln(""); g_deinit(); g_exit(0); } g_snprintf(pid_file, 255, "%s/xrdp-ng.pid", XRDP_PID_PATH); no_daemon = 0; if (startup_params->kill) { g_writeln("stopping xrdp"); /* read the xrdp.pid file */ fd = -1; if (g_file_exist(pid_file)) /* xrdp-ng.pid */ { fd = g_file_open(pid_file); /* xrdp-ng.pid */ } if (fd == -1) { g_writeln("problem opening to xrdp-ng.pid [%s]", pid_file); g_writeln("maybe its not running"); } else { g_memset(text, 0, 32); g_file_read(fd, (unsigned char*) text, 31); pid = g_atoi(text); g_writeln("stopping process id %d", pid); if (pid > 0) { g_sigterm(pid); } g_file_close(fd); } g_deinit(); g_exit(0); } if (startup_params->no_daemon) { no_daemon = 1; } if (startup_params->help) { g_writeln(""); g_writeln("xrdp: A Remote Desktop Protocol server."); g_writeln("Copyright (C) Jay Sorg 2004-2011"); g_writeln("See http://xrdp.sourceforge.net for more information."); g_writeln(""); g_writeln("Usage: xrdp [options]"); g_writeln(" --help: show help"); g_writeln(" --nodaemon: don't fork into background"); g_writeln(" --kill: shut down xrdp"); g_writeln(" --port: tcp listen port"); g_writeln(" --fork: fork on new connection"); g_writeln(""); g_deinit(); g_exit(0); } if (startup_params->version) { g_writeln(""); g_writeln("xrdp: A Remote Desktop Protocol server."); g_writeln("Copyright (C) Jay Sorg 2004-2011"); g_writeln("See http://xrdp.sourceforge.net for more information."); g_writeln("Version %s", XRDP_NG_VERSION_FULL); g_writeln(""); g_deinit(); g_exit(0); } if (g_file_exist(pid_file)) /* xrdp-ng.pid */ { g_writeln("It looks like xrdp is already running,"); g_writeln("if not delete the xrdp-ng.pid file and try again"); g_deinit(); g_exit(0); } if (!no_daemon) { /* make sure containing directory exists */ g_create_path(pid_file); /* make sure we can write to pid file */ fd = g_file_open(pid_file); /* xrdp-ng.pid */ if (fd == -1) { g_writeln("running in daemon mode with no access to pid files, quitting"); g_deinit(); g_exit(0); } if (g_file_write(fd, (unsigned char*) "0", 1) == -1) { g_writeln("running in daemon mode with no access to pid files, quitting"); g_deinit(); g_exit(0); } g_file_close(fd); g_file_delete(pid_file); } if (!no_daemon) { /* start of daemonizing code */ pid = g_fork(); if (pid == -1) { g_writeln("problem forking"); g_deinit(); g_exit(1); } if (0 != pid) { g_writeln("process %d started ok", pid); /* exit, this is the main process */ g_deinit(); g_exit(0); } g_sleep(1000); /* write the pid to file */ pid = g_getpid(); fd = g_file_open(pid_file); /* xrdp-ng.pid */ if (fd == -1) { g_writeln("trying to write process id to xrdp-ng.pid"); g_writeln("problem opening xrdp-ng.pid"); g_writeln("maybe no rights"); } else { g_sprintf(text, "%d", pid); g_file_write(fd, (unsigned char*) text, g_strlen(text)); g_file_close(fd); } g_sleep(1000); g_file_close(0); g_file_close(1); g_file_close(2); g_file_open("/dev/null"); g_file_open("/dev/null"); g_file_open("/dev/null"); /* end of daemonizing code */ } g_threadid = tc_get_threadid(); g_listen = xrdp_listen_create(); g_signal_user_interrupt(xrdp_shutdown); /* SIGINT */ g_signal_kill(xrdp_shutdown); /* SIGKILL */ g_signal_pipe(pipe_sig); /* SIGPIPE */ g_signal_terminate(xrdp_shutdown); /* SIGTERM */ g_signal_child_stop(xrdp_child); /* SIGCHLD */ g_sync_mutex = tc_mutex_create(); g_sync1_mutex = tc_mutex_create(); pid = g_getpid(); g_TermEvent = CreateEvent(NULL, TRUE, FALSE, NULL); g_SyncEvent = CreateEvent(NULL, TRUE, FALSE, NULL); xrdp_listen_main_loop(g_listen); xrdp_listen_delete(g_listen); tc_mutex_delete(g_sync_mutex); tc_mutex_delete(g_sync1_mutex); CloseHandle(g_TermEvent); CloseHandle(g_SyncEvent); /* only main process should delete pid file */ if ((!no_daemon) && (pid == g_getpid())) { /* delete the xrdp-ng.pid file */ g_file_delete(pid_file); } free(startup_params); g_deinit(); return 0; }
enum logReturns DEFAULT_CC log_message(const enum logLevels lvl, const char *msg, ...) { char buff[LOG_BUFFER_SIZE + 31]; /* 19 (datetime) 4 (space+cr+lf+\0) */ va_list ap; int len = 0; enum logReturns rv = LOG_STARTUP_OK; int writereply = 0; time_t now_t; struct tm *now; if (g_staticLogConfig == NULL) { g_writeln("The log reference is NULL - log not initialized properly"); return LOG_ERROR_NO_CFG; } if (0 > g_staticLogConfig->fd && g_staticLogConfig->enable_syslog == 0) { return LOG_ERROR_FILE_NOT_OPEN; } now_t = time(&now_t); now = localtime(&now_t); snprintf(buff, 21, "[%.4d%.2d%.2d-%.2d:%.2d:%.2d] ", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec); internal_log_lvl2str(lvl, buff + 20); va_start(ap, msg); len = vsnprintf(buff + 28, LOG_BUFFER_SIZE, msg, ap); va_end(ap); /* checking for truncated messages */ if (len > LOG_BUFFER_SIZE) { log_message(LOG_LEVEL_WARNING, "next message will be truncated"); } /* forcing the end of message string */ #ifdef _WIN32 buff[len + 28] = '\r'; buff[len + 29] = '\n'; buff[len + 30] = '\0'; #else #ifdef _MACOS buff[len + 28] = '\r'; buff[len + 29] = '\0'; #else buff[len + 28] = '\n'; buff[len + 29] = '\0'; #endif #endif if (g_staticLogConfig->enable_syslog && (lvl <= g_staticLogConfig->syslog_level)) { /* log to syslog*/ /* %s fix compiler warning 'not a string literal' */ syslog(internal_log_xrdp2syslog(lvl), "(%d)(%ld)%s", g_getpid(), tc_get_threadid(), buff + 20); } if (lvl <= g_staticLogConfig->log_level) { /* log to console */ g_printf("%s", buff); /* log to application logfile */ #ifdef LOG_ENABLE_THREAD pthread_mutex_lock(&(g_staticLogConfig->log_lock)); #endif if (g_staticLogConfig->fd > 0) { writereply = g_file_write(g_staticLogConfig->fd, buff, g_strlen(buff)); if (writereply <= 0) { rv = LOG_ERROR_NULL_FILE; } } #ifdef LOG_ENABLE_THREAD pthread_mutex_unlock(&(g_staticLogConfig->log_lock)); #endif } return rv; }