/* Client program */ int main(int argc, char *argv[]) { char server[256]; char fullhostname[64]; char domain[256]; char shell[256]; char directory[256]; RD_BOOL prompt_password, deactivated; struct passwd *pw; uint32 flags, ext_disc_reason = 0; char *p; int c; char *locale = NULL; int username_option = 0; RD_BOOL geometry_option = False; #ifdef WITH_RDPSND char *rdpsnd_optarg = NULL; #endif #ifdef HAVE_LOCALE_H /* Set locale according to environment */ locale = setlocale(LC_ALL, ""); if (locale) { locale = xstrdup(locale); } #endif /* Ignore SIGPIPE, since we are using popen() */ struct sigaction act; memset(&act, 0, sizeof(act)); act.sa_handler = SIG_IGN; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGPIPE, &act, NULL); /* setup default flags for TS_INFO_PACKET */ flags = RDP_INFO_MOUSE | RDP_INFO_DISABLECTRLALTDEL | RDP_INFO_UNICODE | RDP_INFO_MAXIMIZESHELL | RDP_INFO_ENABLEWINDOWSKEY; prompt_password = False; g_seamless_spawn_cmd[0] = domain[0] = g_password[0] = shell[0] = directory[0] = 0; g_embed_wnd = 0; g_num_devices = 0; #ifdef RDP2VNC #define VNCOPT "V:Q:" #else #define VNCOPT #endif while ((c = getopt(argc, argv, VNCOPT "A:u:L:d:s:c:p:n:k:g:o:fbBeEitmzCDKS:T:UNX:a:x:Pr:045h?")) != -1) { switch (c) { #ifdef RDP2VNC case 'V': rfb_port = strtol(optarg, NULL, 10); if (rfb_port < 100) rfb_port += 5900; break; case 'Q': defer_time = strtol(optarg, NULL, 10); if (defer_time < 0) defer_time = 0; break; #endif case 'A': g_seamless_rdp = True; STRNCPY(g_seamless_shell, optarg, sizeof(g_seamless_shell)); break; case 'u': g_username = (char *) xmalloc(strlen(optarg) + 1); STRNCPY(g_username, optarg, strlen(optarg) + 1); username_option = 1; break; case 'L': #ifdef HAVE_ICONV STRNCPY(g_codepage, optarg, sizeof(g_codepage)); #else error("iconv support not available\n"); #endif break; case 'd': STRNCPY(domain, optarg, sizeof(domain)); break; case 's': STRNCPY(shell, optarg, sizeof(shell)); g_seamless_persistent_mode = False; break; case 'c': STRNCPY(directory, optarg, sizeof(directory)); break; case 'p': if ((optarg[0] == '-') && (optarg[1] == 0)) { prompt_password = True; break; } STRNCPY(g_password, optarg, sizeof(g_password)); flags |= RDP_INFO_AUTOLOGON; /* try to overwrite argument so it won't appear in ps */ p = optarg; while (*p) *(p++) = 'X'; break; #ifdef WITH_SCARD case 'i': flags |= RDP_INFO_PASSWORD_IS_SC_PIN; g_use_password_as_pin = True; break; #endif case 't': g_use_ctrl = False; break; case 'n': STRNCPY(g_hostname, optarg, sizeof(g_hostname)); break; case 'k': STRNCPY(g_keymapname, optarg, sizeof(g_keymapname)); break; case 'g': geometry_option = True; g_fullscreen = False; if (!strcmp(optarg, "workarea")) { g_sizeopt = 1; break; } g_width = strtol(optarg, &p, 10); if (g_width <= 0) { error("invalid geometry\n"); return EX_USAGE; } if (*p == 'x') g_height = strtol(p + 1, &p, 10); if (g_height <= 0) { error("invalid geometry\n"); return EX_USAGE; } if (*p == '%') { g_sizeopt = -g_width; g_width = 800; p++; } if (*p == '+' || *p == '-') { g_pos |= (*p == '-') ? 2 : 1; g_xpos = strtol(p, &p, 10); } if (*p == '+' || *p == '-') { g_pos |= (*p == '-') ? 4 : 1; g_ypos = strtol(p, NULL, 10); } break; case 'f': g_fullscreen = True; break; case 'b': g_bitmap_cache = False; break; case 'B': g_ownbackstore = False; break; case 'e': g_encryption_initial = g_encryption = False; break; case 'E': g_packet_encryption = False; break; case 'm': g_sendmotion = False; break; case 'C': g_owncolmap = True; break; case 'D': g_hide_decorations = True; break; case 'K': g_grab_keyboard = False; break; case 'U': g_ungrab_on_ctrlalt = True; break; case 'S': if (!strcmp(optarg, "standard")) { g_win_button_size = 18; break; } g_win_button_size = strtol(optarg, &p, 10); if (*p) { error("invalid button size\n"); return EX_USAGE; } break; case 'T': STRNCPY(g_title, optarg, sizeof(g_title)); break; case 'N': g_numlock_sync = True; break; case 'X': g_embed_wnd = strtol(optarg, NULL, 0); break; case 'a': g_server_depth = strtol(optarg, NULL, 10); if (g_server_depth != 8 && g_server_depth != 16 && g_server_depth != 15 && g_server_depth != 24 && g_server_depth != 32) { error("Invalid server colour depth.\n"); return EX_USAGE; } break; case 'z': DEBUG(("rdp compression enabled\n")); flags |= (RDP_INFO_COMPRESSION | RDP_INFO_COMPRESSION2); break; case 'x': if (str_startswith(optarg, "m")) /* modem */ { g_rdp5_performanceflags = RDP5_NO_CURSOR_SHADOW | RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING; } else if (str_startswith(optarg, "b")) /* broadband */ { g_rdp5_performanceflags = RDP5_NO_CURSOR_SHADOW | RDP5_NO_WALLPAPER; } else if (str_startswith(optarg, "l")) /* lan */ { g_rdp5_performanceflags = RDP5_NO_CURSOR_SHADOW | RDP5_DISABLE_NOTHING; } else { g_rdp5_performanceflags = RDP5_NO_CURSOR_SHADOW | strtol(optarg, NULL, 16); } break; case 'P': g_bitmap_cache_persist_enable = True; break; case 'r': if (str_startswith(optarg, "sound")) { optarg += 5; if (*optarg == ':') { optarg++; while ((p = next_arg(optarg, ','))) { if (str_startswith(optarg, "remote")) flags |= RDP_INFO_REMOTE_CONSOLE_AUDIO; if (str_startswith(optarg, "local")) #ifdef WITH_RDPSND { rdpsnd_optarg = next_arg(optarg, ':'); g_rdpsnd = True; } #else warning("Not compiled with sound support\n"); #endif if (str_startswith(optarg, "off")) #ifdef WITH_RDPSND g_rdpsnd = False; #else warning("Not compiled with sound support\n"); #endif optarg = p; } } else { #ifdef WITH_RDPSND g_rdpsnd = True; #else warning("Not compiled with sound support\n"); #endif } } else if (str_startswith(optarg, "disk")) { /* -r disk:h:=/mnt/floppy */ disk_enum_devices(&g_num_devices, optarg + 4); } else if (str_startswith(optarg, "comport")) { serial_enum_devices(&g_num_devices, optarg + 7); } else if (str_startswith(optarg, "lspci")) { g_lspci_enabled = True; } else if (str_startswith(optarg, "lptport")) { parallel_enum_devices(&g_num_devices, optarg + 7); } else if (str_startswith(optarg, "printer")) { printer_enum_devices(&g_num_devices, optarg + 7); } else if (str_startswith(optarg, "clientname")) { g_rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1); strcpy(g_rdpdr_clientname, optarg + 11); } else if (str_startswith(optarg, "clipboard")) { optarg += 9; if (*optarg == ':') { optarg++; if (str_startswith(optarg, "off")) g_rdpclip = False; else cliprdr_set_mode(optarg); } else g_rdpclip = True; } else if (strncmp("scard", optarg, 5) == 0) { #ifdef WITH_SCARD scard_enum_devices(&g_num_devices, optarg + 5); #else warning("Not compiled with smartcard support\n"); #endif } else { warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound, clipboard, scard\n"); } break; case '0': g_console_session = True; break; case '4': g_rdp_version = RDP_V4; break; case '5': g_rdp_version = RDP_V5; break; #if WITH_SCARD case 'o': { char *p = strchr(optarg, '='); if (p == NULL) { warning("Skipping option '%s' specified, lacks name=value format.\n"); continue; } if (strncmp(optarg, "sc-csp-name", strlen("sc-scp-name")) == 0) g_sc_csp_name = strdup(p + 1); else if (strncmp (optarg, "sc-reader-name", strlen("sc-reader-name")) == 0) g_sc_reader_name = strdup(p + 1); else if (strncmp (optarg, "sc-card-name", strlen("sc-card-name")) == 0) g_sc_card_name = strdup(p + 1); else if (strncmp (optarg, "sc-container-name", strlen("sc-container-name")) == 0) g_sc_container_name = strdup(p + 1); } break; #endif case 'h': case '?': default: usage(argv[0]); return EX_USAGE; } } if (argc - optind != 1) { usage(argv[0]); return EX_USAGE; } STRNCPY(server, argv[optind], sizeof(server)); parse_server_and_port(server); if (g_seamless_rdp) { if (shell[0]) STRNCPY(g_seamless_spawn_cmd, shell, sizeof(g_seamless_spawn_cmd)); STRNCPY(shell, g_seamless_shell, sizeof(shell)); if (g_win_button_size) { error("You cannot use -S and -A at the same time\n"); return EX_USAGE; } g_rdp5_performanceflags &= ~RDP5_NO_FULLWINDOWDRAG; if (geometry_option) { error("You cannot use -g and -A at the same time\n"); return EX_USAGE; } if (g_fullscreen) { error("You cannot use -f and -A at the same time\n"); return EX_USAGE; } if (g_hide_decorations) { error("You cannot use -D and -A at the same time\n"); return EX_USAGE; } if (g_embed_wnd) { error("You cannot use -X and -A at the same time\n"); return EX_USAGE; } if (g_rdp_version < RDP_V5) { error("You cannot use -4 and -A at the same time\n"); return EX_USAGE; } g_sizeopt = -100; g_grab_keyboard = False; } if (!username_option) { pw = getpwuid(getuid()); if ((pw == NULL) || (pw->pw_name == NULL)) { error("could not determine username, use -u\n"); return EX_OSERR; } /* +1 for trailing \0 */ int pwlen = strlen(pw->pw_name) + 1; g_username = (char *) xmalloc(pwlen); STRNCPY(g_username, pw->pw_name, pwlen); } #ifdef HAVE_ICONV if (g_codepage[0] == 0) { if (setlocale(LC_CTYPE, "")) { STRNCPY(g_codepage, nl_langinfo(CODESET), sizeof(g_codepage)); } else { STRNCPY(g_codepage, DEFAULT_CODEPAGE, sizeof(g_codepage)); } } #endif if (g_hostname[0] == 0) { if (gethostname(fullhostname, sizeof(fullhostname)) == -1) { error("could not determine local hostname, use -n\n"); return EX_OSERR; } p = strchr(fullhostname, '.'); if (p != NULL) *p = 0; STRNCPY(g_hostname, fullhostname, sizeof(g_hostname)); } if (g_keymapname[0] == 0) { if (locale && xkeymap_from_locale(locale)) { fprintf(stderr, "Autoselected keyboard map %s\n", g_keymapname); } else { STRNCPY(g_keymapname, "en-us", sizeof(g_keymapname)); } } if (locale) xfree(locale); if (prompt_password && read_password(g_password, sizeof(g_password))) flags |= RDP_INFO_AUTOLOGON; if (g_title[0] == 0) { strcpy(g_title, "rdesktop - "); strncat(g_title, server, sizeof(g_title) - sizeof("rdesktop - ")); } #ifdef RDP2VNC rdp2vnc_connect(server, flags, domain, g_password, shell, directory); return EX_OK; #else /* Only startup ctrl functionality is seamless are used for now. */ if (g_use_ctrl && g_seamless_rdp) { if (ctrl_init(server, domain, g_username) < 0) { error("Failed to initialize ctrl mode."); exit(1); } if (ctrl_is_slave()) { fprintf(stdout, "rdesktop in slave mode sending command to master process.\n"); if (g_seamless_spawn_cmd[0]) return ctrl_send_command("seamless.spawn", g_seamless_spawn_cmd); fprintf(stdout, "No command specified to be spawn in seamless mode.\n"); return EX_USAGE; } } if (!ui_init()) return EX_OSERR; #ifdef WITH_RDPSND if (!rdpsnd_init(rdpsnd_optarg)) warning("Initializing sound-support failed!\n"); #endif if (g_lspci_enabled) lspci_init(); rdpdr_init(); g_reconnect_loop = False; while (1) { rdesktop_reset_state(); if (g_redirect) { STRNCPY(domain, g_redirect_domain, sizeof(domain)); xfree(g_username); g_username = (char *) xmalloc(strlen(g_redirect_username) + 1); STRNCPY(g_username, g_redirect_username, strlen(g_redirect_username) + 1); STRNCPY(server, g_redirect_server, sizeof(server)); flags |= RDP_INFO_AUTOLOGON; fprintf(stderr, "Redirected to %s@%s session %d.\n", g_redirect_username, g_redirect_server, g_redirect_session_id); /* A redirect on SSL from a 2003 WTS will result in a 'connection reset by peer' and therefor we just clear this error before we connect to redirected server. */ g_network_error = False; g_redirect = False; } ui_init_connection(); if (!rdp_connect (server, flags, domain, g_password, shell, directory, g_reconnect_loop)) { g_network_error = False; if (g_reconnect_loop == False) return EX_PROTOCOL; /* check if auto reconnect cookie has timed out */ if (time(NULL) - g_reconnect_random_ts > RECONNECT_TIMEOUT) { fprintf(stderr, "Tried to reconnect for %d minutes, giving up.\n", RECONNECT_TIMEOUT / 60); return EX_PROTOCOL; } sleep(4); continue; } if (g_redirect) { rdp_disconnect(); continue; } /* By setting encryption to False here, we have an encrypted login packet but unencrypted transfer of other packets */ if (!g_packet_encryption) g_encryption_initial = g_encryption = False; DEBUG(("Connection successful.\n")); rd_create_ui(); tcp_run_ui(True); deactivated = False; g_reconnect_loop = False; rdp_main_loop(&deactivated, &ext_disc_reason); tcp_run_ui(False); DEBUG(("Disconnecting...\n")); rdp_disconnect(); if (g_redirect) continue; /* handle network error and start autoreconnect */ if (g_network_error && !deactivated) { fprintf(stderr, "Disconnected due to network error, retrying to reconnect for %d minutes.\n", RECONNECT_TIMEOUT / 60); g_network_error = False; g_reconnect_loop = True; continue; } ui_seamless_end(); ui_destroy_window(); /* Enter a reconnect loop if we have a pending resize request */ if (g_pending_resize) { g_pending_resize = False; g_reconnect_loop = True; continue; } break; } cache_save_state(); ui_deinit(); if (g_user_quit) return EXRD_WINDOW_CLOSED; return handle_disconnect_reason(deactivated, ext_disc_reason); #endif if (g_redirect_username) xfree(g_redirect_username); xfree(g_username); }
/* Client program */ int main(int argc, char *argv[]) { char server[64]; char fullhostname[64]; char domain[16]; char password[64]; char shell[256]; char directory[256]; RD_BOOL prompt_password, deactivated; struct passwd *pw; uint32 flags, ext_disc_reason = 0; char *p; int c; char *locale = NULL; int username_option = 0; RD_BOOL geometry_option = False; int run_count = 0; /* Session Directory support */ RD_BOOL continue_connect = True; /* Session Directory support */ #ifdef WITH_RDPSND char *rdpsnd_optarg = NULL; #endif #ifdef HAVE_LOCALE_H /* Set locale according to environment */ locale = setlocale(LC_ALL, ""); if (locale) { locale = xstrdup(locale); } #endif flags = RDP_LOGON_NORMAL; prompt_password = False; domain[0] = password[0] = shell[0] = directory[0] = 0; g_embed_wnd = 0; g_num_devices = 0; #ifdef RDP2VNC #define VNCOPT "V:Q:" #else #define VNCOPT #endif while ((c = getopt(argc, argv, VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1) { switch (c) { #ifdef RDP2VNC case 'V': rfb_port = strtol(optarg, NULL, 10); if (rfb_port < 100) rfb_port += 5900; break; case 'Q': defer_time = strtol(optarg, NULL, 10); if (defer_time < 0) defer_time = 0; break; #endif case 'A': g_seamless_rdp = True; break; case 'u': STRNCPY(g_username, optarg, sizeof(g_username)); username_option = 1; break; case 'L': #ifdef HAVE_ICONV STRNCPY(g_codepage, optarg, sizeof(g_codepage)); #else error("iconv support not available\n"); #endif break; case 'd': STRNCPY(domain, optarg, sizeof(domain)); break; case 's': STRNCPY(shell, optarg, sizeof(shell)); break; case 'c': STRNCPY(directory, optarg, sizeof(directory)); break; case 'p': if ((optarg[0] == '-') && (optarg[1] == 0)) { prompt_password = True; break; } STRNCPY(password, optarg, sizeof(password)); flags |= RDP_LOGON_AUTO; /* try to overwrite argument so it won't appear in ps */ p = optarg; while (*p) *(p++) = 'X'; break; case 'n': STRNCPY(g_hostname, optarg, sizeof(g_hostname)); break; case 'k': STRNCPY(g_keymapname, optarg, sizeof(g_keymapname)); break; case 'g': geometry_option = True; g_fullscreen = False; if (!strcmp(optarg, "workarea")) { g_width = g_height = 0; break; } g_width = strtol(optarg, &p, 10); if (g_width <= 0) { error("invalid geometry\n"); return 1; } if (*p == 'x') g_height = strtol(p + 1, &p, 10); if (g_height <= 0) { error("invalid geometry\n"); return 1; } if (*p == '%') { g_width = -g_width; p++; } if (*p == '+' || *p == '-') { g_pos |= (*p == '-') ? 2 : 1; g_xpos = strtol(p, &p, 10); } if (*p == '+' || *p == '-') { g_pos |= (*p == '-') ? 4 : 1; g_ypos = strtol(p, NULL, 10); } break; case 'f': g_fullscreen = True; break; case 'b': g_bitmap_cache = False; break; case 'B': g_ownbackstore = False; break; case 'e': g_encryption = False; break; case 'E': g_packet_encryption = False; break; case 'm': g_sendmotion = False; break; case 'C': g_owncolmap = True; break; case 'D': g_hide_decorations = True; break; case 'K': g_grab_keyboard = False; break; case 'S': if (!strcmp(optarg, "standard")) { g_win_button_size = 18; break; } g_win_button_size = strtol(optarg, &p, 10); if (*p) { error("invalid button size\n"); return 1; } break; case 'T': STRNCPY(g_title, optarg, sizeof(g_title)); break; case 'N': g_numlock_sync = True; break; case 'X': g_embed_wnd = strtol(optarg, NULL, 0); break; case 'a': g_server_depth = strtol(optarg, NULL, 10); if (g_server_depth != 8 && g_server_depth != 16 && g_server_depth != 15 && g_server_depth != 24 && g_server_depth != 32) { error("Invalid server colour depth.\n"); return 1; } break; case 'z': DEBUG(("rdp compression enabled\n")); flags |= (RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2); break; case 'x': if (str_startswith(optarg, "m")) /* modem */ { g_rdp5_performanceflags = RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING; } else if (str_startswith(optarg, "b")) /* broadband */ { g_rdp5_performanceflags = RDP5_NO_WALLPAPER; } else if (str_startswith(optarg, "l")) /* lan */ { g_rdp5_performanceflags = RDP5_DISABLE_NOTHING; } else { g_rdp5_performanceflags = strtol(optarg, NULL, 16); } break; case 'P': g_bitmap_cache_persist_enable = True; break; case 'r': if (str_startswith(optarg, "sound")) { optarg += 5; if (*optarg == ':') { optarg++; while ((p = next_arg(optarg, ','))) { if (str_startswith(optarg, "remote")) flags |= RDP_LOGON_LEAVE_AUDIO; if (str_startswith(optarg, "local")) #ifdef WITH_RDPSND { rdpsnd_optarg = next_arg(optarg, ':'); g_rdpsnd = True; } #else warning("Not compiled with sound support\n"); #endif if (str_startswith(optarg, "off")) #ifdef WITH_RDPSND g_rdpsnd = False; #else warning("Not compiled with sound support\n"); #endif optarg = p; } } else { #ifdef WITH_RDPSND g_rdpsnd = True; #else warning("Not compiled with sound support\n"); #endif } } else if (str_startswith(optarg, "disk")) { /* -r disk:h:=/mnt/floppy */ disk_enum_devices(&g_num_devices, optarg + 4); } else if (str_startswith(optarg, "comport")) { serial_enum_devices(&g_num_devices, optarg + 7); } else if (str_startswith(optarg, "lspci")) { g_lspci_enabled = True; } else if (str_startswith(optarg, "lptport")) { parallel_enum_devices(&g_num_devices, optarg + 7); } else if (str_startswith(optarg, "printer")) { printer_enum_devices(&g_num_devices, optarg + 7); } else if (str_startswith(optarg, "clientname")) { g_rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1); strcpy(g_rdpdr_clientname, optarg + 11); } else if (str_startswith(optarg, "clipboard")) { optarg += 9; if (*optarg == ':') { optarg++; if (str_startswith(optarg, "off")) g_rdpclip = False; else cliprdr_set_mode(optarg); } else g_rdpclip = True; } else if (strncmp("scard", optarg, 5) == 0) { #ifdef WITH_SCARD scard_enum_devices(&g_num_devices, optarg + 5); #else warning("Not compiled with smartcard support\n"); #endif } else { warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound, clipboard, scard\n"); } break; case '0': g_console_session = True; break; case '4': g_use_rdp5 = False; break; case '5': g_use_rdp5 = True; break; case 'h': case '?': default: usage(argv[0]); return 1; } } if (argc - optind != 1) { usage(argv[0]); return 1; } STRNCPY(server, argv[optind], sizeof(server)); parse_server_and_port(server); if (g_seamless_rdp) { if (g_win_button_size) { error("You cannot use -S and -A at the same time\n"); return 1; } g_rdp5_performanceflags &= ~RDP5_NO_FULLWINDOWDRAG; if (geometry_option) { error("You cannot use -g and -A at the same time\n"); return 1; } if (g_fullscreen) { error("You cannot use -f and -A at the same time\n"); return 1; } if (g_hide_decorations) { error("You cannot use -D and -A at the same time\n"); return 1; } if (g_embed_wnd) { error("You cannot use -X and -A at the same time\n"); return 1; } if (!g_use_rdp5) { error("You cannot use -4 and -A at the same time\n"); return 1; } g_width = -100; g_grab_keyboard = False; } if (!username_option) { pw = getpwuid(getuid()); if ((pw == NULL) || (pw->pw_name == NULL)) { error("could not determine username, use -u\n"); return 1; } STRNCPY(g_username, pw->pw_name, sizeof(g_username)); } #ifdef HAVE_ICONV if (g_codepage[0] == 0) { if (setlocale(LC_CTYPE, "")) { STRNCPY(g_codepage, nl_langinfo(CODESET), sizeof(g_codepage)); } else { STRNCPY(g_codepage, DEFAULT_CODEPAGE, sizeof(g_codepage)); } } #endif if (g_hostname[0] == 0) { if (gethostname(fullhostname, sizeof(fullhostname)) == -1) { error("could not determine local hostname, use -n\n"); return 1; } p = strchr(fullhostname, '.'); if (p != NULL) *p = 0; STRNCPY(g_hostname, fullhostname, sizeof(g_hostname)); } if (g_keymapname[0] == 0) { if (locale && xkeymap_from_locale(locale)) { fprintf(stderr, "Autoselected keyboard map %s\n", g_keymapname); } else { STRNCPY(g_keymapname, "en-us", sizeof(g_keymapname)); } } if (locale) xfree(locale); if (prompt_password && read_password(password, sizeof(password))) flags |= RDP_LOGON_AUTO; if (g_title[0] == 0) { strcpy(g_title, "rdesktop - "); strncat(g_title, server, sizeof(g_title) - sizeof("rdesktop - ")); } #ifdef RDP2VNC rdp2vnc_connect(server, flags, domain, password, shell, directory); return 0; #else if (!ui_init()) return 1; #ifdef WITH_RDPSND if (g_rdpsnd) { if (!rdpsnd_init(rdpsnd_optarg)) { warning("Initializing sound-support failed!\n"); } } #endif if (g_lspci_enabled) lspci_init(); rdpdr_init(); while (run_count < 2 && continue_connect) /* add support for Session Directory; only reconnect once */ { if (run_count == 0) { if (!rdp_connect(server, flags, domain, password, shell, directory)) return 1; } else if (!rdp_reconnect (server, flags, domain, password, shell, directory, g_redirect_cookie)) return 1; /* By setting encryption to False here, we have an encrypted login packet but unencrypted transfer of other packets */ if (!g_packet_encryption) g_encryption = False; DEBUG(("Connection successful.\n")); memset(password, 0, sizeof(password)); if (run_count == 0) if (!ui_create_window()) continue_connect = False; if (continue_connect) rdp_main_loop(&deactivated, &ext_disc_reason); DEBUG(("Disconnecting...\n")); rdp_disconnect(); if ((g_redirect == True) && (run_count == 0)) /* Support for Session Directory */ { /* reset state of major globals */ rdesktop_reset_state(); STRNCPY(domain, g_redirect_domain, sizeof(domain)); STRNCPY(g_username, g_redirect_username, sizeof(g_username)); STRNCPY(password, g_redirect_password, sizeof(password)); STRNCPY(server, g_redirect_server, sizeof(server)); flags |= RDP_LOGON_AUTO; g_redirect = False; } else { continue_connect = False; ui_destroy_window(); break; } run_count++; } cache_save_state(); ui_deinit(); if (ext_disc_reason >= 2) print_disconnect_reason(ext_disc_reason); if (deactivated) { /* clean disconnect */ return 0; } else { if (ext_disc_reason == exDiscReasonAPIInitiatedDisconnect || ext_disc_reason == exDiscReasonAPIInitiatedLogoff) { /* not so clean disconnect, but nothing to worry about */ return 0; } else { /* return error */ return 2; } } #endif }