--- sourceforge.net/trunk/rdesktop/rdesktop.c 2006/01/24 12:40:24 1042 +++ sourceforge.net/trunk/rdesktop/rdesktop.c 2006/03/28 14:46:47 1215 @@ -84,10 +84,13 @@ BOOL g_grab_keyboard = True; BOOL g_hide_decorations = False; BOOL g_use_rdp5 = True; +BOOL g_rdpclip = True; BOOL g_console_session = False; BOOL g_numlock_sync = False; +BOOL lspci_enabled = False; BOOL g_owncolmap = False; BOOL g_ownbackstore = True; /* We can't rely on external BackingStore */ +BOOL g_seamless_rdp = False; uint32 g_embed_wnd; uint32 g_rdp5_performanceflags = RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS; @@ -145,6 +148,7 @@ #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"); @@ -177,6 +181,13 @@ " or mydeskjet=\"HP LaserJet IIIP\" to enter server driver as well\n"); fprintf(stderr, " '-r sound:[local|off|remote]': enable sound redirection\n"); fprintf(stderr, " remote would leave sound on server\n"); + 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"); fprintf(stderr, " -0: attach to console\n"); fprintf(stderr, " -4: use RDP version 4\n"); fprintf(stderr, " -5: use RDP version 5 (default)\n"); @@ -380,8 +391,8 @@ char fullhostname[64]; char domain[16]; char password[64]; - char shell[128]; - char directory[32]; + char shell[256]; + char directory[256]; BOOL prompt_password, deactivated; struct passwd *pw; uint32 flags, ext_disc_reason = 0; @@ -389,6 +400,7 @@ int c; char *locale = NULL; int username_option = 0; + BOOL geometry_option = False; int run_count = 0; /* Session Directory support */ BOOL continue_connect = True; /* Session Directory support */ @@ -415,7 +427,7 @@ #endif while ((c = getopt(argc, argv, - VNCOPT "u:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1) + VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1) { switch (c) { @@ -433,6 +445,10 @@ break; #endif + case 'A': + g_seamless_rdp = True; + break; + case 'u': STRNCPY(g_username, optarg, sizeof(g_username)); username_option = 1; @@ -483,6 +499,7 @@ break; case 'g': + geometry_option = True; g_fullscreen = False; if (!strcmp(optarg, "workarea")) { @@ -679,6 +696,10 @@ { serial_enum_devices(&g_num_devices, optarg + 7); } + else if (str_startswith(optarg, "lspci")) + { + lspci_enabled = True; + } else if (str_startswith(optarg, "lptport")) { parallel_enum_devices(&g_num_devices, optarg + 7); @@ -692,9 +713,25 @@ 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 { - warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound\n"); + warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound, clipboard\n"); } break; @@ -727,6 +764,43 @@ 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()); @@ -804,6 +878,10 @@ if (g_rdpsnd) rdpsnd_init(); #endif + + if (lspci_enabled) + lspci_init(); + rdpdr_init(); while (run_count < 2 && continue_connect) /* add support for Session Directory; only reconnect once */ @@ -1178,6 +1256,117 @@ } +/* Split input into lines, and call linehandler for each + line. Incomplete lines are saved in the rest variable, which should + initially point to NULL. When linehandler returns False, stop and + return False. Otherwise, return True. */ +BOOL +str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data) +{ + char *buf, *p; + char *oldrest; + size_t inputlen; + size_t buflen; + size_t restlen = 0; + BOOL ret = True; + + /* Copy data to buffer */ + inputlen = strlen(input); + if (*rest) + restlen = strlen(*rest); + buflen = restlen + inputlen + 1; + buf = (char *) xmalloc(buflen); + buf[0] = '\0'; + if (*rest) + STRNCPY(buf, *rest, buflen); + strncat(buf, input, inputlen); + p = buf; + + while (1) + { + char *newline = strchr(p, '\n'); + if (newline) + { + *newline = '\0'; + if (!linehandler(p, data)) + { + p = newline + 1; + ret = False; + break; + } + p = newline + 1; + } + else + { + break; + + } + } + + /* Save in rest */ + oldrest = *rest; + restlen = buf + buflen - p; + *rest = (char *) xmalloc(restlen); + STRNCPY((*rest), p, restlen); + xfree(oldrest); + + xfree(buf); + return ret; +} + +/* Execute the program specified by argv. For each line in + stdout/stderr output, call linehandler. Returns false on failure. */ +BOOL +subprocess(char *const argv[], str_handle_lines_t linehandler, void *data) +{ + pid_t child; + int fd[2]; + int n = 1; + char output[256]; + char *rest = NULL; + + if (pipe(fd) < 0) + { + perror("pipe"); + return False; + } + + if ((child = fork()) < 0) + { + perror("fork"); + return False; + } + + /* Child */ + if (child == 0) + { + /* Close read end */ + close(fd[0]); + + /* Redirect stdout and stderr to pipe */ + dup2(fd[1], 1); + dup2(fd[1], 2); + + /* Execute */ + execvp(argv[0], argv); + perror("Error executing child"); + _exit(128); + } + + /* Parent. Close write end. */ + close(fd[1]); + while (n > 0) + { + n = read(fd[0], output, 255); + output[n] = '\0'; + str_handle_lines(output, &rest, linehandler, data); + } + xfree(rest); + + return True; +} + + /* not all clibs got ltoa */ #define LTOA_BUFSIZE (sizeof(long) * 8 + 1)