?? rdesktop.c
字號:
/* -*- c-basic-offset: 8 -*- rdesktop: A Remote Desktop Protocol client. Entrypoint and utility functions Copyright (C) Matthew Chapman 1999-2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <stdarg.h> /* va_list va_start va_end */#include <unistd.h> /* read close getuid getgid getpid getppid gethostname */#include <fcntl.h> /* open */#include <pwd.h> /* getpwuid */#include <termios.h> /* tcgetattr tcsetattr */#include <sys/stat.h> /* stat */#include <sys/time.h> /* gettimeofday */#include <sys/times.h> /* times */#include <ctype.h> /* toupper */#include <errno.h>#include "rdesktop.h"#ifdef HAVE_LOCALE_H#include <locale.h>#endif#ifdef HAVE_ICONV#ifdef HAVE_LANGINFO_H#include <langinfo.h>#endif#endif#ifdef EGD_SOCKET#include <sys/types.h>#include <sys/socket.h> /* socket connect */#include <sys/un.h> /* sockaddr_un */#endif#include "ssl.h"char g_title[64] = "";char g_username[64];char g_hostname[16];char g_keymapname[PATH_MAX] = "";unsigned int g_keylayout = 0x409; /* Defaults to US keyboard layout */int g_keyboard_type = 0x4; /* Defaults to US keyboard layout */int g_keyboard_subtype = 0x0; /* Defaults to US keyboard layout */int g_keyboard_functionkeys = 0xc; /* Defaults to US keyboard layout */int g_width = 800; /* width is special: If 0, the geometry will be fetched from _NET_WORKAREA. If negative, absolute value specifies the percent of the whole screen. */int g_height = 600;int g_xpos = 0;int g_ypos = 0;int g_pos = 0; /* 0 position unspecified, 1 specified, 2 xpos neg, 4 ypos neg */extern int g_tcp_port_rdp;int g_server_depth = -1;int g_win_button_size = 0; /* If zero, disable single app mode */RD_BOOL g_bitmap_compression = True;RD_BOOL g_sendmotion = True;RD_BOOL g_bitmap_cache = True;RD_BOOL g_bitmap_cache_persist_enable = False;RD_BOOL g_bitmap_cache_precache = True;RD_BOOL g_encryption = True;RD_BOOL g_packet_encryption = True;RD_BOOL g_desktop_save = True; /* desktop save order */RD_BOOL g_polygon_ellipse_orders = True; /* polygon / ellipse orders */RD_BOOL g_fullscreen = False;RD_BOOL g_grab_keyboard = True;RD_BOOL g_hide_decorations = False;RD_BOOL g_use_rdp5 = True;RD_BOOL g_rdpclip = True;RD_BOOL g_console_session = False;RD_BOOL g_numlock_sync = False;RD_BOOL g_lspci_enabled = False;RD_BOOL g_owncolmap = False;RD_BOOL g_ownbackstore = True; /* We can't rely on external BackingStore */RD_BOOL g_seamless_rdp = False;uint32 g_embed_wnd;uint32 g_rdp5_performanceflags = RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;/* Session Directory redirection */RD_BOOL g_redirect = False;char g_redirect_server[64];char g_redirect_domain[16];char g_redirect_password[64];char g_redirect_username[64];char g_redirect_cookie[128];uint32 g_redirect_flags = 0;#ifdef WITH_RDPSNDRD_BOOL g_rdpsnd = False;#endif#ifdef HAVE_ICONVchar g_codepage[16] = "";#endifextern RDPDR_DEVICE g_rdpdr_device[];extern uint32 g_num_devices;extern char *g_rdpdr_clientname;#ifdef RDP2VNCextern int rfb_port;extern int defer_time;voidrdp2vnc_connect(char *server, uint32 flags, char *domain, char *password, char *shell, char *directory);#endif/* Display usage information */static voidusage(char *program){ fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n"); fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2008 Matthew Chapman.\n"); fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n"); fprintf(stderr, "Usage: %s [options] server[:port]\n", program);#ifdef RDP2VNC fprintf(stderr, " -V: vnc port\n"); fprintf(stderr, " -Q: defer time (ms)\n");#endif fprintf(stderr, " -u: user name\n"); fprintf(stderr, " -d: domain\n"); fprintf(stderr, " -s: shell\n"); fprintf(stderr, " -c: working directory\n"); fprintf(stderr, " -p: password (- to prompt)\n"); fprintf(stderr, " -n: client hostname\n"); fprintf(stderr, " -k: keyboard layout on server (en-us, de, sv, etc.)\n"); fprintf(stderr, " -g: desktop geometry (WxH)\n"); fprintf(stderr, " -f: full-screen mode\n"); fprintf(stderr, " -b: force bitmap updates\n");#ifdef HAVE_ICONV fprintf(stderr, " -L: local codepage\n");#endif fprintf(stderr, " -A: enable SeamlessRDP mode\n"); fprintf(stderr, " -B: use BackingStore of X-server (if available)\n"); fprintf(stderr, " -e: disable encryption (French TS)\n"); fprintf(stderr, " -E: disable encryption from client to server\n"); fprintf(stderr, " -m: do not send motion events\n"); fprintf(stderr, " -C: use private colour map\n"); fprintf(stderr, " -D: hide window manager decorations\n"); fprintf(stderr, " -K: keep window manager key bindings\n"); fprintf(stderr, " -S: caption button size (single application mode)\n"); fprintf(stderr, " -T: window title\n"); fprintf(stderr, " -N: enable numlock syncronization\n"); fprintf(stderr, " -X: embed into another window with a given id.\n"); fprintf(stderr, " -a: connection colour depth\n"); fprintf(stderr, " -z: enable rdp compression\n"); fprintf(stderr, " -x: RDP5 experience (m[odem 28.8], b[roadband], l[an] or hex nr.)\n"); fprintf(stderr, " -P: use persistent bitmap caching\n"); fprintf(stderr, " -r: enable specified device redirection (this flag can be repeated)\n"); fprintf(stderr, " '-r comport:COM1=/dev/ttyS0': enable serial redirection of /dev/ttyS0 to COM1\n"); fprintf(stderr, " or COM1=/dev/ttyS0,COM2=/dev/ttyS1\n"); fprintf(stderr, " '-r disk:floppy=/mnt/floppy': enable redirection of /mnt/floppy to 'floppy' share\n"); fprintf(stderr, " or 'floppy=/mnt/floppy,cdrom=/mnt/cdrom'\n"); fprintf(stderr, " '-r clientname=<client name>': Set the client name displayed\n"); fprintf(stderr, " for redirected disks\n"); fprintf(stderr, " '-r lptport:LPT1=/dev/lp0': enable parallel redirection of /dev/lp0 to LPT1\n"); fprintf(stderr, " or LPT1=/dev/lp0,LPT2=/dev/lp1\n"); fprintf(stderr, " '-r printer:mydeskjet': enable printer redirection\n"); fprintf(stderr, " or mydeskjet=\"HP LaserJet IIIP\" to enter server driver as well\n");#ifdef WITH_RDPSND fprintf(stderr, " '-r sound:[local[:driver[:device]]|off|remote]': enable sound redirection\n"); fprintf(stderr, " remote would leave sound on server\n"); fprintf(stderr, " available drivers for 'local':\n"); rdpsnd_show_help();#endif fprintf(stderr, " '-r clipboard:[off|PRIMARYCLIPBOARD|CLIPBOARD]': enable clipboard\n"); fprintf(stderr, " redirection.\n"); fprintf(stderr, " 'PRIMARYCLIPBOARD' looks at both PRIMARY and CLIPBOARD\n"); fprintf(stderr, " when sending data to server.\n"); fprintf(stderr, " 'CLIPBOARD' looks at only CLIPBOARD.\n");#ifdef WITH_SCARD fprintf(stderr, " '-r scard[:\"Scard Name\"=\"Alias Name[;Vendor Name]\"[,...]]\n"); fprintf(stderr, " example: -r scard:\"eToken PRO 00 00\"=\"AKS ifdh 0\"\n"); fprintf(stderr, " \"eToken PRO 00 00\" -> Device in Linux/Unix enviroment\n"); fprintf(stderr, " \"AKS ifdh 0\" -> Device shown in Windows enviroment \n"); fprintf(stderr, " example: -r scard:\"eToken PRO 00 00\"=\"AKS ifdh 0;AKS\"\n"); fprintf(stderr, " \"eToken PRO 00 00\" -> Device in Linux/Unix enviroment\n"); fprintf(stderr, " \"AKS ifdh 0\" -> Device shown in Windows enviroment \n"); fprintf(stderr, " \"AKS\" -> Device vendor name \n");#endif fprintf(stderr, " -0: attach to console\n"); fprintf(stderr, " -4: use RDP version 4\n"); fprintf(stderr, " -5: use RDP version 5 (default)\n");}static voidprint_disconnect_reason(uint16 reason){ char *text; switch (reason) { case exDiscReasonNoInfo: text = "No information available"; break; case exDiscReasonAPIInitiatedDisconnect: text = "Server initiated disconnect"; break; case exDiscReasonAPIInitiatedLogoff: text = "Server initiated logoff"; break; case exDiscReasonServerIdleTimeout: text = "Server idle timeout reached"; break; case exDiscReasonServerLogonTimeout: text = "Server logon timeout reached"; break; case exDiscReasonReplacedByOtherConnection: text = "The session was replaced"; break; case exDiscReasonOutOfMemory: text = "The server is out of memory"; break; case exDiscReasonServerDeniedConnection: text = "The server denied the connection"; break; case exDiscReasonServerDeniedConnectionFips: text = "The server denied the connection for security reason"; break; case exDiscReasonLicenseInternal: text = "Internal licensing error"; break; case exDiscReasonLicenseNoLicenseServer: text = "No license server available"; break; case exDiscReasonLicenseNoLicense: text = "No valid license available"; break; case exDiscReasonLicenseErrClientMsg: text = "Invalid licensing message"; break; case exDiscReasonLicenseHwidDoesntMatchLicense: text = "Hardware id doesn't match software license"; break; case exDiscReasonLicenseErrClientLicense: text = "Client license error"; break; case exDiscReasonLicenseCantFinishProtocol: text = "Network error during licensing protocol"; break; case exDiscReasonLicenseClientEndedProtocol: text = "Licensing protocol was not completed"; break; case exDiscReasonLicenseErrClientEncryption: text = "Incorrect client license enryption"; break; case exDiscReasonLicenseCantUpgradeLicense: text = "Can't upgrade license"; break; case exDiscReasonLicenseNoRemoteConnections: text = "The server is not licensed to accept remote connections"; break; default: if (reason > 0x1000 && reason < 0x7fff) { text = "Internal protocol error"; } else { text = "Unknown reason"; } } fprintf(stderr, "disconnect: %s.\n", text);}static voidrdesktop_reset_state(void){ rdp_reset_state();}static RD_BOOLread_password(char *password, int size){ struct termios tios; RD_BOOL ret = False; int istty = 0; char *p; if (tcgetattr(STDIN_FILENO, &tios) == 0) { fprintf(stderr, "Password: "); tios.c_lflag &= ~ECHO; tcsetattr(STDIN_FILENO, TCSANOW, &tios); istty = 1; } if (fgets(password, size, stdin) != NULL) { ret = True; /* strip final newline */ p = strchr(password, '\n'); if (p != NULL) *p = 0; } if (istty) { tios.c_lflag |= ECHO; tcsetattr(STDIN_FILENO, TCSANOW, &tios); fprintf(stderr, "\n"); } return ret;}static voidparse_server_and_port(char *server){ char *p;#ifdef IPv6 int addr_colons;#endif#ifdef IPv6 p = server; addr_colons = 0; while (*p) if (*p++ == ':') addr_colons++; if (addr_colons >= 2) { /* numeric IPv6 style address format - [1:2:3::4]:port */ p = strchr(server, ']'); if (*server == '[' && p != NULL) { if (*(p + 1) == ':' && *(p + 2) != '\0') g_tcp_port_rdp = strtol(p + 2, NULL, 10); /* remove the port number and brackets from the address */ *p = '\0'; strncpy(server, server + 1, strlen(server)); } } else { /* dns name or IPv4 style address format - server.example.com:port or 1.2.3.4:port */ p = strchr(server, ':'); if (p != NULL) { g_tcp_port_rdp = strtol(p + 1, NULL, 10); *p = 0; } }#else /* no IPv6 support */ p = strchr(server, ':'); if (p != NULL) { g_tcp_port_rdp = strtol(p + 1, NULL, 10); *p = 0; }#endif /* IPv6 */}/* Client program */intmain(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)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -