/[rdesktop]/jpeg/rdesktop/trunk/rdesktop.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /jpeg/rdesktop/trunk/rdesktop.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 646 by forsberg, Fri Apr 2 15:34:38 2004 UTC revision 1271 by stargo, Mon Sep 18 21:42:50 2006 UTC
# Line 1  Line 1 
1  /* -*- c-basic-offset: 8 -*-  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Entrypoint and utility functions     Entrypoint and utility functions
4     Copyright (C) Matthew Chapman 1999-2003     Copyright (C) Matthew Chapman 1999-2005
5    
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 30  Line 30 
30  #include <errno.h>  #include <errno.h>
31  #include "rdesktop.h"  #include "rdesktop.h"
32    
33    #ifdef HAVE_LOCALE_H
34    #include <locale.h>
35    #endif
36    #ifdef HAVE_ICONV
37    #ifdef HAVE_LANGINFO_H
38    #include <langinfo.h>
39    #endif
40    #endif
41    
42  #ifdef EGD_SOCKET  #ifdef EGD_SOCKET
43    #include <sys/types.h>
44  #include <sys/socket.h>         /* socket connect */  #include <sys/socket.h>         /* socket connect */
45  #include <sys/un.h>             /* sockaddr_un */  #include <sys/un.h>             /* sockaddr_un */
46  #endif  #endif
47    
 #ifdef WITH_OPENSSL  
48  #include <openssl/md5.h>  #include <openssl/md5.h>
 #else  
 #include "crypto/md5.h"  
 #endif  
49    
50  char g_title[64] = "";  char g_title[64] = "";
51  char g_username[64];  char g_username[64];
52  char hostname[16];  char g_hostname[16];
53  char keymapname[16];  char g_keymapname[PATH_MAX] = "";
54  int keylayout = 0x409;          /* Defaults to US keyboard layout */  unsigned int g_keylayout = 0x409;       /* Defaults to US keyboard layout */
55    int g_keyboard_type = 0x4;      /* Defaults to US keyboard layout */
56    int g_keyboard_subtype = 0x0;   /* Defaults to US keyboard layout */
57    int g_keyboard_functionkeys = 0xc;      /* Defaults to US keyboard layout */
58    
59  int g_width = 800;              /* width is special: If 0, the  int g_width = 800;              /* width is special: If 0, the
60                                     geometry will be fetched from                                     geometry will be fetched from
# Line 53  int g_width = 800;             /* width is special: Line 62  int g_width = 800;             /* width is special:
62                                     absolute value specifies the                                     absolute value specifies the
63                                     percent of the whole screen. */                                     percent of the whole screen. */
64  int g_height = 600;  int g_height = 600;
65  int tcp_port_rdp = TCP_PORT_RDP;  int g_xpos = 0;
66  int g_server_bpp = 8;  int g_ypos = 0;
67    int g_pos = 0;                  /* 0 position unspecified,
68                                       1 specified,
69                                       2 xpos neg,
70                                       4 ypos neg  */
71    extern int g_tcp_port_rdp;
72    int g_server_depth = -1;
73  int g_win_button_size = 0;      /* If zero, disable single app mode */  int g_win_button_size = 0;      /* If zero, disable single app mode */
74  BOOL g_bitmap_compression = True;  BOOL g_bitmap_compression = True;
75  BOOL g_sendmotion = True;  BOOL g_sendmotion = True;
76  BOOL g_orders = True;  BOOL g_bitmap_cache = True;
77    BOOL g_bitmap_cache_persist_enable = False;
78    BOOL g_bitmap_cache_precache = True;
79  BOOL g_encryption = True;  BOOL g_encryption = True;
80  BOOL packet_encryption = True;  BOOL packet_encryption = True;
81  BOOL g_desktop_save = True;  BOOL g_desktop_save = True;     /* desktop save order */
82    BOOL g_polygon_ellipse_orders = True;   /* polygon / ellipse orders */
83  BOOL g_fullscreen = False;  BOOL g_fullscreen = False;
84  BOOL g_grab_keyboard = True;  BOOL g_grab_keyboard = True;
85  BOOL g_hide_decorations = False;  BOOL g_hide_decorations = False;
86  BOOL g_use_rdp5 = True;  BOOL g_use_rdp5 = True;
87    BOOL g_rdpclip = True;
88  BOOL g_console_session = False;  BOOL g_console_session = False;
89  BOOL g_numlock_sync = False;  BOOL g_numlock_sync = False;
90  extern BOOL g_owncolmap;  BOOL lspci_enabled = False;
91  extern BOOL g_ownbackstore;  BOOL g_owncolmap = False;
92  extern uint32 g_embed_wnd;  BOOL g_ownbackstore = True;     /* We can't rely on external BackingStore */
93  uint32 g_rdp5_performanceflags = RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;  BOOL g_seamless_rdp = False;
94    uint32 g_embed_wnd;
95    uint32 g_rdp5_performanceflags =
96            RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
97    /* Session Directory redirection */
98    BOOL g_redirect = False;
99    char g_redirect_server[64];
100    char g_redirect_domain[16];
101    char g_redirect_password[64];
102    char g_redirect_username[64];
103    char g_redirect_cookie[128];
104    uint32 g_redirect_flags = 0;
105    
106  #ifdef WITH_RDPSND  #ifdef WITH_RDPSND
107  BOOL g_rdpsnd = False;  BOOL g_rdpsnd = False;
108  #endif  #endif
109    
110    #ifdef HAVE_ICONV
111    char g_codepage[16] = "";
112    #endif
113    
114  extern RDPDR_DEVICE g_rdpdr_device[];  extern RDPDR_DEVICE g_rdpdr_device[];
115  extern uint32 g_num_devices;  extern uint32 g_num_devices;
116  extern char * g_rdpdr_clientname;  extern char *g_rdpdr_clientname;
117    
118  #ifdef RDP2VNC  #ifdef RDP2VNC
119  extern int rfb_port;  extern int rfb_port;
# Line 93  static void Line 127  static void
127  usage(char *program)  usage(char *program)
128  {  {
129          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
130          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2003 Matt Chapman.\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2005 Matt Chapman.\n");
131          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
132    
133          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
# Line 111  usage(char *program) Line 145  usage(char *program)
145          fprintf(stderr, "   -g: desktop geometry (WxH)\n");          fprintf(stderr, "   -g: desktop geometry (WxH)\n");
146          fprintf(stderr, "   -f: full-screen mode\n");          fprintf(stderr, "   -f: full-screen mode\n");
147          fprintf(stderr, "   -b: force bitmap updates\n");          fprintf(stderr, "   -b: force bitmap updates\n");
148    #ifdef HAVE_ICONV
149            fprintf(stderr, "   -L: local codepage\n");
150    #endif
151            fprintf(stderr, "   -A: enable SeamlessRDP mode\n");
152          fprintf(stderr, "   -B: use BackingStore of X-server (if available)\n");          fprintf(stderr, "   -B: use BackingStore of X-server (if available)\n");
153          fprintf(stderr, "   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -e: disable encryption (French TS)\n");
154          fprintf(stderr, "   -E: disable encryption from client to server\n");          fprintf(stderr, "   -E: disable encryption from client to server\n");
# Line 123  usage(char *program) Line 161  usage(char *program)
161          fprintf(stderr, "   -N: enable numlock syncronization\n");          fprintf(stderr, "   -N: enable numlock syncronization\n");
162          fprintf(stderr, "   -X: embed into another window with a given id.\n");          fprintf(stderr, "   -X: embed into another window with a given id.\n");
163          fprintf(stderr, "   -a: connection colour depth\n");          fprintf(stderr, "   -a: connection colour depth\n");
164          fprintf(stderr, "   -x: RDP5 experience (m[odem 28.8], b[roadband], l[an] or hex number)\n");          fprintf(stderr, "   -z: enable rdp compression\n");
165            fprintf(stderr, "   -x: RDP5 experience (m[odem 28.8], b[roadband], l[an] or hex nr.)\n");
166            fprintf(stderr, "   -P: use persistent bitmap caching\n");
167          fprintf(stderr, "   -r: enable specified device redirection (this flag can be repeated)\n");          fprintf(stderr, "   -r: enable specified device redirection (this flag can be repeated)\n");
168          fprintf(stderr,          fprintf(stderr,
169                  "         '-r comport:COM1=/dev/ttyS0': enable serial redirection of /dev/ttyS0 to COM1\n");                  "         '-r comport:COM1=/dev/ttyS0': enable serial redirection of /dev/ttyS0 to COM1\n");
170          fprintf(stderr, "             or      COM1=/dev/ttyS0,COM2=/dev/ttyS1\n");          fprintf(stderr, "             or      COM1=/dev/ttyS0,COM2=/dev/ttyS1\n");
171          fprintf(stderr,          fprintf(stderr,
172                  "         '-r disk:A=/mnt/floppy': enable redirection of /mnt/floppy to A:\n");                  "         '-r disk:floppy=/mnt/floppy': enable redirection of /mnt/floppy to 'floppy' share\n");
173          fprintf(stderr, "             or   A=/mnt/floppy,D=/mnt/cdrom'\n");          fprintf(stderr, "             or   'floppy=/mnt/floppy,cdrom=/mnt/cdrom'\n");
174          fprintf(stderr, "         '-r clientname=<client name>': Set the client name displayed\n");          fprintf(stderr, "         '-r clientname=<client name>': Set the client name displayed\n");
175          fprintf(stderr, "             for redirected disks\n");          fprintf(stderr, "             for redirected disks\n");
176          fprintf(stderr,          fprintf(stderr,
# Line 139  usage(char *program) Line 179  usage(char *program)
179          fprintf(stderr, "         '-r printer:mydeskjet': enable printer redirection\n");          fprintf(stderr, "         '-r printer:mydeskjet': enable printer redirection\n");
180          fprintf(stderr,          fprintf(stderr,
181                  "             or      mydeskjet=\"HP LaserJet IIIP\" to enter server driver as well\n");                  "             or      mydeskjet=\"HP LaserJet IIIP\" to enter server driver as well\n");
182          fprintf(stderr, "         '-r sound:[local|off|remote]': enable sound redirection\n");  #ifdef WITH_RDPSND
183            fprintf(stderr,
184                    "         '-r sound:[local[:driver[:device]]|off|remote]': enable sound redirection\n");
185          fprintf(stderr, "                     remote would leave sound on server\n");          fprintf(stderr, "                     remote would leave sound on server\n");
186            fprintf(stderr, "                     available drivers for 'local':\n");
187            rdpsnd_show_help();
188    #endif
189            fprintf(stderr,
190                    "         '-r clipboard:[off|PRIMARYCLIPBOARD|CLIPBOARD]': enable clipboard\n");
191            fprintf(stderr, "                      redirection.\n");
192            fprintf(stderr,
193                    "                      'PRIMARYCLIPBOARD' looks at both PRIMARY and CLIPBOARD\n");
194            fprintf(stderr, "                      when sending data to server.\n");
195            fprintf(stderr, "                      'CLIPBOARD' looks at only CLIPBOARD.\n");
196          fprintf(stderr, "   -0: attach to console\n");          fprintf(stderr, "   -0: attach to console\n");
197          fprintf(stderr, "   -4: use RDP version 4\n");          fprintf(stderr, "   -4: use RDP version 4\n");
198          fprintf(stderr, "   -5: use RDP version 5 (default)\n");          fprintf(stderr, "   -5: use RDP version 5 (default)\n");
199  }  }
200    
201    static void
202    print_disconnect_reason(uint16 reason)
203    {
204            char *text;
205    
206            switch (reason)
207            {
208                    case exDiscReasonNoInfo:
209                            text = "No information available";
210                            break;
211    
212                    case exDiscReasonAPIInitiatedDisconnect:
213                            text = "Server initiated disconnect";
214                            break;
215    
216                    case exDiscReasonAPIInitiatedLogoff:
217                            text = "Server initiated logoff";
218                            break;
219    
220                    case exDiscReasonServerIdleTimeout:
221                            text = "Server idle timeout reached";
222                            break;
223    
224                    case exDiscReasonServerLogonTimeout:
225                            text = "Server logon timeout reached";
226                            break;
227    
228                    case exDiscReasonReplacedByOtherConnection:
229                            text = "The session was replaced";
230                            break;
231    
232                    case exDiscReasonOutOfMemory:
233                            text = "The server is out of memory";
234                            break;
235    
236                    case exDiscReasonServerDeniedConnection:
237                            text = "The server denied the connection";
238                            break;
239    
240                    case exDiscReasonServerDeniedConnectionFips:
241                            text = "The server denied the connection for security reason";
242                            break;
243    
244                    case exDiscReasonLicenseInternal:
245                            text = "Internal licensing error";
246                            break;
247    
248                    case exDiscReasonLicenseNoLicenseServer:
249                            text = "No license server available";
250                            break;
251    
252                    case exDiscReasonLicenseNoLicense:
253                            text = "No valid license available";
254                            break;
255    
256                    case exDiscReasonLicenseErrClientMsg:
257                            text = "Invalid licensing message";
258                            break;
259    
260                    case exDiscReasonLicenseHwidDoesntMatchLicense:
261                            text = "Hardware id doesn't match software license";
262                            break;
263    
264                    case exDiscReasonLicenseErrClientLicense:
265                            text = "Client license error";
266                            break;
267    
268                    case exDiscReasonLicenseCantFinishProtocol:
269                            text = "Network error during licensing protocol";
270                            break;
271    
272                    case exDiscReasonLicenseClientEndedProtocol:
273                            text = "Licensing protocol was not completed";
274                            break;
275    
276                    case exDiscReasonLicenseErrClientEncryption:
277                            text = "Incorrect client license enryption";
278                            break;
279    
280                    case exDiscReasonLicenseCantUpgradeLicense:
281                            text = "Can't upgrade license";
282                            break;
283    
284                    case exDiscReasonLicenseNoRemoteConnections:
285                            text = "The server is not licensed to accept remote connections";
286                            break;
287    
288                    default:
289                            if (reason > 0x1000 && reason < 0x7fff)
290                            {
291                                    text = "Internal protocol error";
292                            }
293                            else
294                            {
295                                    text = "Unknown reason";
296                            }
297            }
298            fprintf(stderr, "disconnect: %s.\n", text);
299    }
300    
301    static void
302    rdesktop_reset_state(void)
303    {
304            rdp_reset_state();
305    }
306    
307  static BOOL  static BOOL
308  read_password(char *password, int size)  read_password(char *password, int size)
309  {  {
# Line 203  parse_server_and_port(char *server) Line 361  parse_server_and_port(char *server)
361                  if (*server == '[' && p != NULL)                  if (*server == '[' && p != NULL)
362                  {                  {
363                          if (*(p + 1) == ':' && *(p + 2) != '\0')                          if (*(p + 1) == ':' && *(p + 2) != '\0')
364                                  tcp_port_rdp = strtol(p + 2, NULL, 10);                                  g_tcp_port_rdp = strtol(p + 2, NULL, 10);
365                          /* remove the port number and brackets from the address */                          /* remove the port number and brackets from the address */
366                          *p = '\0';                          *p = '\0';
367                          strncpy(server, server + 1, strlen(server));                          strncpy(server, server + 1, strlen(server));
# Line 215  parse_server_and_port(char *server) Line 373  parse_server_and_port(char *server)
373                  p = strchr(server, ':');                  p = strchr(server, ':');
374                  if (p != NULL)                  if (p != NULL)
375                  {                  {
376                          tcp_port_rdp = strtol(p + 1, NULL, 10);                          g_tcp_port_rdp = strtol(p + 1, NULL, 10);
377                          *p = 0;                          *p = 0;
378                  }                  }
379          }          }
# Line 223  parse_server_and_port(char *server) Line 381  parse_server_and_port(char *server)
381          p = strchr(server, ':');          p = strchr(server, ':');
382          if (p != NULL)          if (p != NULL)
383          {          {
384                  tcp_port_rdp = strtol(p + 1, NULL, 10);                  g_tcp_port_rdp = strtol(p + 1, NULL, 10);
385                  *p = 0;                  *p = 0;
386          }          }
387  #endif /* IPv6 */  #endif /* IPv6 */
# Line 238  main(int argc, char *argv[]) Line 396  main(int argc, char *argv[])
396          char fullhostname[64];          char fullhostname[64];
397          char domain[16];          char domain[16];
398          char password[64];          char password[64];
399          char shell[128];          char shell[256];
400          char directory[32];          char directory[256];
401          BOOL prompt_password, rdp_retval = False;          BOOL prompt_password, deactivated;
402          struct passwd *pw;          struct passwd *pw;
403          uint32 flags;          uint32 flags, ext_disc_reason = 0;
404          char *p;          char *p;
405          int c;          int c;
406            char *locale = NULL;
407          int username_option = 0;          int username_option = 0;
408            BOOL geometry_option = False;
409            int run_count = 0;      /* Session Directory support */
410            BOOL continue_connect = True;   /* Session Directory support */
411    
412    #ifdef HAVE_LOCALE_H
413            /* Set locale according to environment */
414            locale = setlocale(LC_ALL, "");
415            if (locale)
416            {
417                    locale = xstrdup(locale);
418            }
419    
420    #endif
421          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
422          prompt_password = False;          prompt_password = False;
423          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
         strcpy(keymapname, "en-us");  
424          g_embed_wnd = 0;          g_embed_wnd = 0;
425    
426          g_num_devices = 0;          g_num_devices = 0;
# Line 262  main(int argc, char *argv[]) Line 431  main(int argc, char *argv[])
431  #define VNCOPT  #define VNCOPT
432  #endif  #endif
433    
434          while ((c = getopt(argc, argv, VNCOPT "u:d:s:c:p:n:k:g:fbBeEmCDKS:T:NX:a:x:r:045h?")) != -1)          while ((c = getopt(argc, argv,
435                               VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1)
436          {          {
437                  switch (c)                  switch (c)
438                  {                  {
# Line 280  main(int argc, char *argv[]) Line 450  main(int argc, char *argv[])
450                                  break;                                  break;
451  #endif  #endif
452    
453                            case 'A':
454                                    g_seamless_rdp = True;
455                                    break;
456    
457                          case 'u':                          case 'u':
458                                  STRNCPY(g_username, optarg, sizeof(g_username));                                  STRNCPY(g_username, optarg, sizeof(g_username));
459                                  username_option = 1;                                  username_option = 1;
460                                  break;                                  break;
461    
462                            case 'L':
463    #ifdef HAVE_ICONV
464                                    STRNCPY(g_codepage, optarg, sizeof(g_codepage));
465    #else
466                                    error("iconv support not available\n");
467    #endif
468                                    break;
469    
470                          case 'd':                          case 'd':
471                                  STRNCPY(domain, optarg, sizeof(domain));                                  STRNCPY(domain, optarg, sizeof(domain));
472                                  break;                                  break;
# Line 314  main(int argc, char *argv[]) Line 496  main(int argc, char *argv[])
496                                  break;                                  break;
497    
498                          case 'n':                          case 'n':
499                                  STRNCPY(hostname, optarg, sizeof(hostname));                                  STRNCPY(g_hostname, optarg, sizeof(g_hostname));
500                                  break;                                  break;
501    
502                          case 'k':                          case 'k':
503                                  STRNCPY(keymapname, optarg, sizeof(keymapname));                                  STRNCPY(g_keymapname, optarg, sizeof(g_keymapname));
504                                  break;                                  break;
505    
506                          case 'g':                          case 'g':
507                                    geometry_option = True;
508                                  g_fullscreen = False;                                  g_fullscreen = False;
509                                  if (!strcmp(optarg, "workarea"))                                  if (!strcmp(optarg, "workarea"))
510                                  {                                  {
# Line 337  main(int argc, char *argv[]) Line 520  main(int argc, char *argv[])
520                                  }                                  }
521    
522                                  if (*p == 'x')                                  if (*p == 'x')
523                                          g_height = strtol(p + 1, NULL, 10);                                          g_height = strtol(p + 1, &p, 10);
524    
525                                  if (g_height <= 0)                                  if (g_height <= 0)
526                                  {                                  {
# Line 346  main(int argc, char *argv[]) Line 529  main(int argc, char *argv[])
529                                  }                                  }
530    
531                                  if (*p == '%')                                  if (*p == '%')
532                                    {
533                                          g_width = -g_width;                                          g_width = -g_width;
534                                            p++;
535                                    }
536    
537                                    if (*p == '+' || *p == '-')
538                                    {
539                                            g_pos |= (*p == '-') ? 2 : 1;
540                                            g_xpos = strtol(p, &p, 10);
541    
542                                    }
543                                    if (*p == '+' || *p == '-')
544                                    {
545                                            g_pos |= (*p == '-') ? 4 : 1;
546                                            g_ypos = strtol(p, NULL, 10);
547                                    }
548    
549                                  break;                                  break;
550    
# Line 355  main(int argc, char *argv[]) Line 553  main(int argc, char *argv[])
553                                  break;                                  break;
554    
555                          case 'b':                          case 'b':
556                                  g_orders = False;                                  g_bitmap_cache = False;
557                                  break;                                  break;
558    
559                          case 'B':                          case 'B':
# Line 410  main(int argc, char *argv[]) Line 608  main(int argc, char *argv[])
608                                  break;                                  break;
609    
610                          case 'X':                          case 'X':
611                                  g_embed_wnd = strtol(optarg, NULL, 10);                                  g_embed_wnd = strtol(optarg, NULL, 0);
612                                  break;                                  break;
613                                    
614                          case 'a':                          case 'a':
615                                  g_server_bpp = strtol(optarg, NULL, 10);                                  g_server_depth = strtol(optarg, NULL, 10);
616                                  if (g_server_bpp != 8 && g_server_bpp != 16 && g_server_bpp != 15                                  if (g_server_depth != 8 &&
617                                      && g_server_bpp != 24)                                      g_server_depth != 16 &&
618                                        g_server_depth != 15 && g_server_depth != 24)
619                                  {                                  {
620                                          error("invalid server bpp\n");                                          error("Invalid server colour depth.\n");
621                                          return 1;                                          return 1;
622                                  }                                  }
623                                  break;                                  break;
624    
625                            case 'z':
626                                    DEBUG(("rdp compression enabled\n"));
627                                    flags |= (RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2);
628                                    break;
629    
630                          case 'x':                          case 'x':
631                                                                    if (str_startswith(optarg, "m"))        /* modem */
                                 if (strncmp("modem", optarg, 1) == 0)  
632                                  {                                  {
633                                          g_rdp5_performanceflags = RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;                                          g_rdp5_performanceflags =
634                                                    RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG |
635                                                    RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;
636                                  }                                  }
637                                  else if (strncmp("broadband", optarg, 1) == 0)                                  else if (str_startswith(optarg, "b"))   /* broadband */
638                                  {                                  {
639                                          g_rdp5_performanceflags = RDP5_NO_WALLPAPER;                                          g_rdp5_performanceflags = RDP5_NO_WALLPAPER;
640                                  }                                  }
641                                  else if (strncmp("lan", optarg, 1) == 0)                                  else if (str_startswith(optarg, "l"))   /* lan */
642                                  {                                  {
643                                          g_rdp5_performanceflags = RDP5_DISABLE_NOTHING;                                          g_rdp5_performanceflags = RDP5_DISABLE_NOTHING;
644                                  }                                  }
# Line 442  main(int argc, char *argv[]) Line 647  main(int argc, char *argv[])
647                                          g_rdp5_performanceflags = strtol(optarg, NULL, 16);                                          g_rdp5_performanceflags = strtol(optarg, NULL, 16);
648                                  }                                  }
649                                  break;                                  break;
650                                    
651                            case 'P':
652                                    g_bitmap_cache_persist_enable = True;
653                                    break;
654    
655                          case 'r':                          case 'r':
656    
657                                  if (strncmp("sound", optarg, 5) == 0)                                  if (str_startswith(optarg, "sound"))
658                                  {                                  {
659                                          optarg += 5;                                          optarg += 5;
660    
661                                          if (*optarg == ':')                                          if (*optarg == ':')
662                                          {                                          {
663                                                  *optarg++;                                                  optarg++;
664                                                  while ((p = next_arg(optarg, ',')))                                                  while ((p = next_arg(optarg, ',')))
665                                                  {                                                  {
666                                                          if (strncmp("remote", optarg, 6) == 0)                                                          if (str_startswith(optarg, "remote"))
667                                                                  flags |= RDP_LOGON_LEAVE_AUDIO;                                                                  flags |= RDP_LOGON_LEAVE_AUDIO;
668    
669                                                          if (strncmp("local", optarg, 5) == 0)                                                          if (str_startswith(optarg, "local"))
670  #ifdef WITH_RDPSND  #ifdef WITH_RDPSND
671                                                                  g_rdpsnd = True;                                                          {
672                                                                    char *driver = NULL, *options =
673                                                                            NULL;
674    
675                                                                    if ((driver =
676                                                                         next_arg(optarg, ':')))
677                                                                    {
678                                                                            if (!strlen(driver))
679                                                                            {
680                                                                                    driver = NULL;
681                                                                            }
682                                                                            else if ((options =
683                                                                                      next_arg(driver,
684                                                                                               ':')))
685                                                                            {
686                                                                                    if (!strlen
687                                                                                        (options))
688                                                                                            options =
689                                                                                                    NULL;
690                                                                            }
691                                                                    }
692    
693                                                                    if (!rdpsnd_select_driver
694                                                                        (driver, options))
695                                                                    {
696                                                                            warning("Driver not available\n");
697                                                                    }
698                                                                    else
699                                                                    {
700                                                                            g_rdpsnd = True;
701                                                                    }
702                                                            }
703    
704  #else  #else
705                                                                  warning("Not compiled with sound support");                                                                  warning("Not compiled with sound support\n");
706  #endif  #endif
707    
708                                                          if (strncmp("off", optarg, 3) == 0)                                                          if (str_startswith(optarg, "off"))
709    #ifdef WITH_RDPSND
710                                                                  g_rdpsnd = False;                                                                  g_rdpsnd = False;
711    #else
712                                                                    warning("Not compiled with sound support\n");
713    #endif
714    
715                                                          optarg = p;                                                          optarg = p;
716                                                  }                                                  }
# Line 473  main(int argc, char *argv[]) Line 718  main(int argc, char *argv[])
718                                          else                                          else
719                                          {                                          {
720  #ifdef WITH_RDPSND  #ifdef WITH_RDPSND
721                                                  g_rdpsnd = True;                                                  if (!rdpsnd_select_driver(NULL, NULL))
722                                                    {
723                                                            warning("No sound-driver available\n");
724                                                    }
725                                                    else
726                                                    {
727                                                            g_rdpsnd = True;
728                                                    }
729  #else  #else
730                                                  warning("Not compiled with sound support");                                                  warning("Not compiled with sound support\n");
731  #endif  #endif
732                                          }                                          }
733                                  }                                  }
734                                  else if (strncmp("disk", optarg, 4) == 0)                                  else if (str_startswith(optarg, "disk"))
735                                  {                                  {
736                                          /* -r disk:h:=/mnt/floppy */                                          /* -r disk:h:=/mnt/floppy */
737                                          disk_enum_devices(&g_num_devices, optarg + 4);                                          disk_enum_devices(&g_num_devices, optarg + 4);
738                                  }                                  }
739                                  else if (strncmp("comport", optarg, 7) == 0)                                  else if (str_startswith(optarg, "comport"))
740                                  {                                  {
741                                          serial_enum_devices(&g_num_devices, optarg + 7);                                          serial_enum_devices(&g_num_devices, optarg + 7);
742                                  }                                  }
743                                  else if (strncmp("lptport", optarg, 7) == 0)                                  else if (str_startswith(optarg, "lspci"))
744                                    {
745                                            lspci_enabled = True;
746                                    }
747                                    else if (str_startswith(optarg, "lptport"))
748                                  {                                  {
749                                          parallel_enum_devices(&g_num_devices, optarg + 7);                                          parallel_enum_devices(&g_num_devices, optarg + 7);
750                                  }                                  }
751                                  else if (strncmp("printer", optarg, 7) == 0)                                  else if (str_startswith(optarg, "printer"))
752                                  {                                  {
753                                          printer_enum_devices(&g_num_devices, optarg + 7);                                          printer_enum_devices(&g_num_devices, optarg + 7);
754                                  }                                  }
755                                  else if (strncmp("clientname", optarg, 7) == 0)                                  else if (str_startswith(optarg, "clientname"))
756                                  {                                  {
757                                          g_rdpdr_clientname = xmalloc(strlen(optarg+11)+1);                                          g_rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1);
758                                          strcpy(g_rdpdr_clientname, optarg + 11);                                          strcpy(g_rdpdr_clientname, optarg + 11);
759                                  }                                  }
760                                    else if (str_startswith(optarg, "clipboard"))
761                                    {
762                                            optarg += 9;
763    
764                                            if (*optarg == ':')
765                                            {
766                                                    optarg++;
767    
768                                                    if (str_startswith(optarg, "off"))
769                                                            g_rdpclip = False;
770                                                    else
771                                                            cliprdr_set_mode(optarg);
772                                            }
773                                            else
774                                                    g_rdpclip = True;
775                                    }
776                                  else                                  else
777                                  {                                  {
778                                          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");
779                                  }                                  }
780                                  break;                                  break;
781    
# Line 536  main(int argc, char *argv[]) Line 808  main(int argc, char *argv[])
808          STRNCPY(server, argv[optind], sizeof(server));          STRNCPY(server, argv[optind], sizeof(server));
809          parse_server_and_port(server);          parse_server_and_port(server);
810    
811            if (g_seamless_rdp)
812            {
813                    if (g_win_button_size)
814                    {
815                            error("You cannot use -S and -A at the same time\n");
816                            return 1;
817                    }
818                    g_rdp5_performanceflags &= ~RDP5_NO_FULLWINDOWDRAG;
819                    if (geometry_option)
820                    {
821                            error("You cannot use -g and -A at the same time\n");
822                            return 1;
823                    }
824                    if (g_fullscreen)
825                    {
826                            error("You cannot use -f and -A at the same time\n");
827                            return 1;
828                    }
829                    if (g_hide_decorations)
830                    {
831                            error("You cannot use -D and -A at the same time\n");
832                            return 1;
833                    }
834                    if (g_embed_wnd)
835                    {
836                            error("You cannot use -X and -A at the same time\n");
837                            return 1;
838                    }
839                    if (!g_use_rdp5)
840                    {
841                            error("You cannot use -4 and -A at the same time\n");
842                            return 1;
843                    }
844                    g_width = -100;
845                    g_grab_keyboard = False;
846            }
847    
848          if (!username_option)          if (!username_option)
849          {          {
850                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
# Line 548  main(int argc, char *argv[]) Line 857  main(int argc, char *argv[])
857                  STRNCPY(g_username, pw->pw_name, sizeof(g_username));                  STRNCPY(g_username, pw->pw_name, sizeof(g_username));
858          }          }
859    
860          if (hostname[0] == 0)  #ifdef HAVE_ICONV
861            if (g_codepage[0] == 0)
862            {
863                    if (setlocale(LC_CTYPE, ""))
864                    {
865                            STRNCPY(g_codepage, nl_langinfo(CODESET), sizeof(g_codepage));
866                    }
867                    else
868                    {
869                            STRNCPY(g_codepage, DEFAULT_CODEPAGE, sizeof(g_codepage));
870                    }
871            }
872    #endif
873    
874            if (g_hostname[0] == 0)
875          {          {
876                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
877                  {                  {
# Line 560  main(int argc, char *argv[]) Line 883  main(int argc, char *argv[])
883                  if (p != NULL)                  if (p != NULL)
884                          *p = 0;                          *p = 0;
885    
886                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
887            }
888    
889            if (g_keymapname[0] == 0)
890            {
891                    if (locale && xkeymap_from_locale(locale))
892                    {
893                            fprintf(stderr, "Autoselected keyboard map %s\n", g_keymapname);
894                    }
895                    else
896                    {
897                            STRNCPY(g_keymapname, "en-us", sizeof(g_keymapname));
898                    }
899          }          }
900            if (locale)
901                    xfree(locale);
902    
903    
904          if (prompt_password && read_password(password, sizeof(password)))          if (prompt_password && read_password(password, sizeof(password)))
905                  flags |= RDP_LOGON_AUTO;                  flags |= RDP_LOGON_AUTO;
# Line 584  main(int argc, char *argv[]) Line 922  main(int argc, char *argv[])
922          if (g_rdpsnd)          if (g_rdpsnd)
923                  rdpsnd_init();                  rdpsnd_init();
924  #endif  #endif
925    
926            if (lspci_enabled)
927                    lspci_init();
928    
929          rdpdr_init();          rdpdr_init();
930    
931          if (!rdp_connect(server, flags, domain, password, shell, directory))          while (run_count < 2 && continue_connect)       /* add support for Session Directory; only reconnect once */
932                  return 1;          {
933                    if (run_count == 0)
934                    {
935                            if (!rdp_connect(server, flags, domain, password, shell, directory))
936                                    return 1;
937                    }
938                    else if (!rdp_reconnect
939                             (server, flags, domain, password, shell, directory, g_redirect_cookie))
940                            return 1;
941    
942          /* By setting encryption to False here, we have an encrypted login                  /* By setting encryption to False here, we have an encrypted login
943             packet but unencrypted transfer of other packets */                     packet but unencrypted transfer of other packets */
944          if (!packet_encryption)                  if (!packet_encryption)
945                  g_encryption = False;                          g_encryption = False;
946    
947    
948          DEBUG(("Connection successful.\n"));                  DEBUG(("Connection successful.\n"));
949          memset(password, 0, sizeof(password));                  memset(password, 0, sizeof(password));
950    
951          if (ui_create_window())                  if (run_count == 0)
952          {                          if (!ui_create_window())
953                  rdp_retval = rdp_main_loop();                                  continue_connect = False;
954                  ui_destroy_window();  
955                    if (continue_connect)
956                            rdp_main_loop(&deactivated, &ext_disc_reason);
957    
958                    DEBUG(("Disconnecting...\n"));
959                    rdp_disconnect();
960    
961                    if ((g_redirect == True) && (run_count == 0))   /* Support for Session Directory */
962                    {
963                            /* reset state of major globals */
964                            rdesktop_reset_state();
965    
966                            STRNCPY(domain, g_redirect_domain, sizeof(domain));
967                            STRNCPY(g_username, g_redirect_username, sizeof(g_username));
968                            STRNCPY(password, g_redirect_password, sizeof(password));
969                            STRNCPY(server, g_redirect_server, sizeof(server));
970                            flags |= RDP_LOGON_AUTO;
971    
972                            g_redirect = False;
973                    }
974                    else
975                    {
976                            continue_connect = False;
977                            ui_destroy_window();
978                            break;
979                    }
980    
981                    run_count++;
982          }          }
983    
984          DEBUG(("Disconnecting...\n"));          cache_save_state();
         rdp_disconnect();  
985          ui_deinit();          ui_deinit();
986    
987          if (True == rdp_retval)          if (ext_disc_reason >= 2)
988                    print_disconnect_reason(ext_disc_reason);
989    
990            if (deactivated)
991            {
992                    /* clean disconnect */
993                  return 0;                  return 0;
994            }
995          else          else
996                  return 2;          {
997                    if (ext_disc_reason == exDiscReasonAPIInitiatedDisconnect
998                        || ext_disc_reason == exDiscReasonAPIInitiatedLogoff)
999                    {
1000                            /* not so clean disconnect, but nothing to worry about */
1001                            return 0;
1002                    }
1003                    else
1004                    {
1005                            /* return error */
1006                            return 2;
1007                    }
1008            }
1009    
1010  #endif  #endif
1011    
# Line 713  xmalloc(int size) Line 1107  xmalloc(int size)
1107          return mem;          return mem;
1108  }  }
1109    
1110    /* strdup */
1111    char *
1112    xstrdup(const char *s)
1113    {
1114            char *mem = strdup(s);
1115            if (mem == NULL)
1116            {
1117                    perror("strdup");
1118                    exit(1);
1119            }
1120            return mem;
1121    }
1122    
1123  /* realloc; exit if out of memory */  /* realloc; exit if out of memory */
1124  void *  void *
1125  xrealloc(void *oldmem, int size)  xrealloc(void *oldmem, int size)
1126  {  {
1127          void *mem = realloc(oldmem, size);          void *mem;
1128    
1129            if (size < 1)
1130                    size = 1;
1131            mem = realloc(oldmem, size);
1132          if (mem == NULL)          if (mem == NULL)
1133          {          {
1134                  error("xrealloc %d\n", size);                  error("xrealloc %d\n", size);
# Line 844  next_arg(char *src, char needle) Line 1255  next_arg(char *src, char needle)
1255                          while (*(mvp + 1) != (char) 0x00)                          while (*(mvp + 1) != (char) 0x00)
1256                          {                          {
1257                                  *mvp = *(mvp + 1);                                  *mvp = *(mvp + 1);
1258                                  *mvp++;                                  mvp++;
1259                          }                          }
1260                          *mvp = (char) 0x00;                          *mvp = (char) 0x00;
1261                          p = nextval;                          p = nextval;
# Line 882  toupper_str(char *p) Line 1293  toupper_str(char *p)
1293  }  }
1294    
1295    
1296    BOOL
1297    str_startswith(const char *s, const char *prefix)
1298    {
1299            return (strncmp(s, prefix, strlen(prefix)) == 0);
1300    }
1301    
1302    
1303    /* Split input into lines, and call linehandler for each
1304       line. Incomplete lines are saved in the rest variable, which should
1305       initially point to NULL. When linehandler returns False, stop and
1306       return False. Otherwise, return True.  */
1307    BOOL
1308    str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data)
1309    {
1310            char *buf, *p;
1311            char *oldrest;
1312            size_t inputlen;
1313            size_t buflen;
1314            size_t restlen = 0;
1315            BOOL ret = True;
1316    
1317            /* Copy data to buffer */
1318            inputlen = strlen(input);
1319            if (*rest)
1320                    restlen = strlen(*rest);
1321            buflen = restlen + inputlen + 1;
1322            buf = (char *) xmalloc(buflen);
1323            buf[0] = '\0';
1324            if (*rest)
1325                    STRNCPY(buf, *rest, buflen);
1326            strncat(buf, input, inputlen);
1327            p = buf;
1328    
1329            while (1)
1330            {
1331                    char *newline = strchr(p, '\n');
1332                    if (newline)
1333                    {
1334                            *newline = '\0';
1335                            if (!linehandler(p, data))
1336                            {
1337                                    p = newline + 1;
1338                                    ret = False;
1339                                    break;
1340                            }
1341                            p = newline + 1;
1342                    }
1343                    else
1344                    {
1345                            break;
1346    
1347                    }
1348            }
1349    
1350            /* Save in rest */
1351            oldrest = *rest;
1352            restlen = buf + buflen - p;
1353            *rest = (char *) xmalloc(restlen);
1354            STRNCPY((*rest), p, restlen);
1355            xfree(oldrest);
1356    
1357            xfree(buf);
1358            return ret;
1359    }
1360    
1361    /* Execute the program specified by argv. For each line in
1362       stdout/stderr output, call linehandler. Returns false on failure. */
1363    BOOL
1364    subprocess(char *const argv[], str_handle_lines_t linehandler, void *data)
1365    {
1366            pid_t child;
1367            int fd[2];
1368            int n = 1;
1369            char output[256];
1370            char *rest = NULL;
1371    
1372            if (pipe(fd) < 0)
1373            {
1374                    perror("pipe");
1375                    return False;
1376            }
1377    
1378            if ((child = fork()) < 0)
1379            {
1380                    perror("fork");
1381                    return False;
1382            }
1383    
1384            /* Child */
1385            if (child == 0)
1386            {
1387                    /* Close read end */
1388                    close(fd[0]);
1389    
1390                    /* Redirect stdout and stderr to pipe */
1391                    dup2(fd[1], 1);
1392                    dup2(fd[1], 2);
1393    
1394                    /* Execute */
1395                    execvp(argv[0], argv);
1396                    perror("Error executing child");
1397                    _exit(128);
1398            }
1399    
1400            /* Parent. Close write end. */
1401            close(fd[1]);
1402            while (n > 0)
1403            {
1404                    n = read(fd[0], output, 255);
1405                    output[n] = '\0';
1406                    str_handle_lines(output, &rest, linehandler, data);
1407            }
1408            xfree(rest);
1409    
1410            return True;
1411    }
1412    
1413    
1414  /* not all clibs got ltoa */  /* not all clibs got ltoa */
1415  #define LTOA_BUFSIZE (sizeof(long) * 8 + 1)  #define LTOA_BUFSIZE (sizeof(long) * 8 + 1)
1416    
# Line 930  load_licence(unsigned char **data) Line 1459  load_licence(unsigned char **data)
1459          if (home == NULL)          if (home == NULL)
1460                  return -1;                  return -1;
1461    
1462          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));          path = (char *) xmalloc(strlen(home) + strlen(g_hostname) + sizeof("/.rdesktop/licence."));
1463          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);          sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname);
1464    
1465          fd = open(path, O_RDONLY);          fd = open(path, O_RDONLY);
1466          if (fd == -1)          if (fd == -1)
# Line 957  save_licence(unsigned char *data, int le Line 1486  save_licence(unsigned char *data, int le
1486          if (home == NULL)          if (home == NULL)
1487                  return;                  return;
1488    
1489          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));          path = (char *) xmalloc(strlen(home) + strlen(g_hostname) + sizeof("/.rdesktop/licence."));
1490    
1491          sprintf(path, "%s/.rdesktop", home);          sprintf(path, "%s/.rdesktop", home);
1492          if ((mkdir(path, 0700) == -1) && errno != EEXIST)          if ((mkdir(path, 0700) == -1) && errno != EEXIST)
# Line 968  save_licence(unsigned char *data, int le Line 1497  save_licence(unsigned char *data, int le
1497    
1498          /* write licence to licence.hostname.new, then atomically rename to licence.hostname */          /* write licence to licence.hostname.new, then atomically rename to licence.hostname */
1499    
1500          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);          sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname);
1501          tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));          tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));
1502          strcpy(tmppath, path);          strcpy(tmppath, path);
1503          strcat(tmppath, ".new");          strcat(tmppath, ".new");
# Line 995  save_licence(unsigned char *data, int le Line 1524  save_licence(unsigned char *data, int le
1524          xfree(tmppath);          xfree(tmppath);
1525          xfree(path);          xfree(path);
1526  }  }
1527    
1528    /* Create the bitmap cache directory */
1529    BOOL
1530    rd_pstcache_mkdir(void)
1531    {
1532            char *home;
1533            char bmpcache_dir[256];
1534    
1535            home = getenv("HOME");
1536    
1537            if (home == NULL)
1538                    return False;
1539    
1540            sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop");
1541    
1542            if ((mkdir(bmpcache_dir, S_IRWXU) == -1) && errno != EEXIST)
1543            {
1544                    perror(bmpcache_dir);
1545                    return False;
1546            }
1547    
1548            sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop/cache");
1549    
1550            if ((mkdir(bmpcache_dir, S_IRWXU) == -1) && errno != EEXIST)
1551            {
1552                    perror(bmpcache_dir);
1553                    return False;
1554            }
1555    
1556            return True;
1557    }
1558    
1559    /* open a file in the .rdesktop directory */
1560    int
1561    rd_open_file(char *filename)
1562    {
1563            char *home;
1564            char fn[256];
1565            int fd;
1566    
1567            home = getenv("HOME");
1568            if (home == NULL)
1569                    return -1;
1570            sprintf(fn, "%s/.rdesktop/%s", home, filename);
1571            fd = open(fn, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
1572            if (fd == -1)
1573                    perror(fn);
1574            return fd;
1575    }
1576    
1577    /* close file */
1578    void
1579    rd_close_file(int fd)
1580    {
1581            close(fd);
1582    }
1583    
1584    /* read from file*/
1585    int
1586    rd_read_file(int fd, void *ptr, int len)
1587    {
1588            return read(fd, ptr, len);
1589    }
1590    
1591    /* write to file */
1592    int
1593    rd_write_file(int fd, void *ptr, int len)
1594    {
1595            return write(fd, ptr, len);
1596    }
1597    
1598    /* move file pointer */
1599    int
1600    rd_lseek_file(int fd, int offset)
1601    {
1602            return lseek(fd, offset, SEEK_SET);
1603    }
1604    
1605    /* do a write lock on a file */
1606    BOOL
1607    rd_lock_file(int fd, int start, int len)
1608    {
1609            struct flock lock;
1610    
1611            lock.l_type = F_WRLCK;
1612            lock.l_whence = SEEK_SET;
1613            lock.l_start = start;
1614            lock.l_len = len;
1615            if (fcntl(fd, F_SETLK, &lock) == -1)
1616                    return False;
1617            return True;
1618    }

Legend:
Removed from v.646  
changed lines
  Added in v.1271

  ViewVC Help
Powered by ViewVC 1.1.26