/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/rdesktop/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 /sourceforge.net/branches/seamlessrdp-branch/rdesktop/rdesktop.c

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

sourceforge.net/trunk/rdesktop/rdesktop.c revision 570 by stargo, Wed Jan 21 18:02:38 2004 UTC sourceforge.net/branches/seamlessrdp-branch/rdesktop/rdesktop.c revision 1089 by astrand, Fri Mar 10 08:50:43 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 = 8;
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_console_session = False;  BOOL g_console_session = False;
88  BOOL g_numlock_sync = False;  BOOL g_numlock_sync = False;
89  extern BOOL g_owncolmap;  BOOL lspci_enabled = False;
90    BOOL g_owncolmap = False;
91    BOOL g_ownbackstore = True;     /* We can't rely on external BackingStore */
92    BOOL g_seamless_rdp = False;
93    uint32 g_embed_wnd;
94    uint32 g_rdp5_performanceflags =
95            RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
96    /* Session Directory redirection */
97    BOOL g_redirect = False;
98    char g_redirect_server[64];
99    char g_redirect_domain[16];
100    char g_redirect_password[64];
101    char g_redirect_username[64];
102    char g_redirect_cookie[128];
103    uint32 g_redirect_flags = 0;
104    
105  #ifdef WITH_RDPSND  #ifdef WITH_RDPSND
106  BOOL g_rdpsnd = False;  BOOL g_rdpsnd = False;
107  #endif  #endif
108    
109    #ifdef HAVE_ICONV
110    char g_codepage[16] = "";
111    #endif
112    
113  extern RDPDR_DEVICE g_rdpdr_device[];  extern RDPDR_DEVICE g_rdpdr_device[];
114  extern uint32 g_num_devices;  extern uint32 g_num_devices;
115    extern char *g_rdpdr_clientname;
116    
117  #ifdef RDP2VNC  #ifdef RDP2VNC
118  extern int rfb_port;  extern int rfb_port;
# Line 89  static void Line 126  static void
126  usage(char *program)  usage(char *program)
127  {  {
128          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
129          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2003 Matt Chapman.\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2005 Matt Chapman.\n");
130          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
131    
132          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
# Line 107  usage(char *program) Line 144  usage(char *program)
144          fprintf(stderr, "   -g: desktop geometry (WxH)\n");          fprintf(stderr, "   -g: desktop geometry (WxH)\n");
145          fprintf(stderr, "   -f: full-screen mode\n");          fprintf(stderr, "   -f: full-screen mode\n");
146          fprintf(stderr, "   -b: force bitmap updates\n");          fprintf(stderr, "   -b: force bitmap updates\n");
147    #ifdef HAVE_ICONV
148            fprintf(stderr, "   -L: local codepage\n");
149    #endif
150            fprintf(stderr, "   -A: enable SeamlessRDP mode\n");
151            fprintf(stderr, "   -B: use BackingStore of X-server (if available)\n");
152          fprintf(stderr, "   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -e: disable encryption (French TS)\n");
153          fprintf(stderr, "   -E: disable encryption from client to server\n");          fprintf(stderr, "   -E: disable encryption from client to server\n");
154          fprintf(stderr, "   -m: do not send motion events\n");          fprintf(stderr, "   -m: do not send motion events\n");
# Line 116  usage(char *program) Line 158  usage(char *program)
158          fprintf(stderr, "   -S: caption button size (single application mode)\n");          fprintf(stderr, "   -S: caption button size (single application mode)\n");
159          fprintf(stderr, "   -T: window title\n");          fprintf(stderr, "   -T: window title\n");
160          fprintf(stderr, "   -N: enable numlock syncronization\n");          fprintf(stderr, "   -N: enable numlock syncronization\n");
161            fprintf(stderr, "   -X: embed into another window with a given id.\n");
162          fprintf(stderr, "   -a: connection colour depth\n");          fprintf(stderr, "   -a: connection colour depth\n");
163            fprintf(stderr, "   -z: enable rdp compression\n");
164            fprintf(stderr, "   -x: RDP5 experience (m[odem 28.8], b[roadband], l[an] or hex nr.)\n");
165            fprintf(stderr, "   -P: use persistent bitmap caching\n");
166          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");
167          fprintf(stderr, "         '-r comport:COM1=/dev/ttyS0': enable serial redirection of /dev/ttyS0 to COM1\n");          fprintf(stderr,
168          fprintf(stderr, "             or    :COM1=/dev/ttyS0:9600,0|1|2,0|2,5|6|7|8:dtr \n");                  "         '-r comport:COM1=/dev/ttyS0': enable serial redirection of /dev/ttyS0 to COM1\n");
169          fprintf(stderr, "         '-r disk:A=/mnt/floppy': enable redirection of /mnt/floppy to A:\n");          fprintf(stderr, "             or      COM1=/dev/ttyS0,COM2=/dev/ttyS1\n");
170          fprintf(stderr, "             or   A=/mnt/floppy,D=/mnt/cdrom'\n");          fprintf(stderr,
171          fprintf(stderr, "         '-r lptport:LPT1=/dev/lp0': enable parallel redirection of /dev/lp0 to LPT1\n");                  "         '-r disk:floppy=/mnt/floppy': enable redirection of /mnt/floppy to 'floppy' share\n");
172          fprintf(stderr, "             or       LPT1=/dev/lp0,LPT2=/dev/lp1\n");          fprintf(stderr, "             or   'floppy=/mnt/floppy,cdrom=/mnt/cdrom'\n");
173            fprintf(stderr, "         '-r clientname=<client name>': Set the client name displayed\n");
174            fprintf(stderr, "             for redirected disks\n");
175            fprintf(stderr,
176                    "         '-r lptport:LPT1=/dev/lp0': enable parallel redirection of /dev/lp0 to LPT1\n");
177            fprintf(stderr, "             or      LPT1=/dev/lp0,LPT2=/dev/lp1\n");
178          fprintf(stderr, "         '-r printer:mydeskjet': enable printer redirection\n");          fprintf(stderr, "         '-r printer:mydeskjet': enable printer redirection\n");
179          fprintf(stderr, "             or       mydeskjet:\"HP Laserjet IIIP\" to enter server driver as well\n");          fprintf(stderr,
180          fprintf(stderr, "         '-r sound': enable sound redirection\n");                  "             or      mydeskjet=\"HP LaserJet IIIP\" to enter server driver as well\n");
181            fprintf(stderr, "         '-r sound:[local|off|remote]': enable sound redirection\n");
182            fprintf(stderr, "                     remote would leave sound on server\n");
183          fprintf(stderr, "   -0: attach to console\n");          fprintf(stderr, "   -0: attach to console\n");
184          fprintf(stderr, "   -4: use RDP version 4\n");          fprintf(stderr, "   -4: use RDP version 4\n");
185          fprintf(stderr, "   -5: use RDP version 5 (default)\n");          fprintf(stderr, "   -5: use RDP version 5 (default)\n");
186  }  }
187    
188    static void
189    print_disconnect_reason(uint16 reason)
190    {
191            char *text;
192    
193            switch (reason)
194            {
195                    case exDiscReasonNoInfo:
196                            text = "No information available";
197                            break;
198    
199                    case exDiscReasonAPIInitiatedDisconnect:
200                            text = "Server initiated disconnect";
201                            break;
202    
203                    case exDiscReasonAPIInitiatedLogoff:
204                            text = "Server initiated logoff";
205                            break;
206    
207                    case exDiscReasonServerIdleTimeout:
208                            text = "Server idle timeout reached";
209                            break;
210    
211                    case exDiscReasonServerLogonTimeout:
212                            text = "Server logon timeout reached";
213                            break;
214    
215                    case exDiscReasonReplacedByOtherConnection:
216                            text = "The session was replaced";
217                            break;
218    
219                    case exDiscReasonOutOfMemory:
220                            text = "The server is out of memory";
221                            break;
222    
223                    case exDiscReasonServerDeniedConnection:
224                            text = "The server denied the connection";
225                            break;
226    
227                    case exDiscReasonServerDeniedConnectionFips:
228                            text = "The server denied the connection for security reason";
229                            break;
230    
231                    case exDiscReasonLicenseInternal:
232                            text = "Internal licensing error";
233                            break;
234    
235                    case exDiscReasonLicenseNoLicenseServer:
236                            text = "No license server available";
237                            break;
238    
239                    case exDiscReasonLicenseNoLicense:
240                            text = "No valid license available";
241                            break;
242    
243                    case exDiscReasonLicenseErrClientMsg:
244                            text = "Invalid licensing message";
245                            break;
246    
247                    case exDiscReasonLicenseHwidDoesntMatchLicense:
248                            text = "Hardware id doesn't match software license";
249                            break;
250    
251                    case exDiscReasonLicenseErrClientLicense:
252                            text = "Client license error";
253                            break;
254    
255                    case exDiscReasonLicenseCantFinishProtocol:
256                            text = "Network error during licensing protocol";
257                            break;
258    
259                    case exDiscReasonLicenseClientEndedProtocol:
260                            text = "Licensing protocol was not completed";
261                            break;
262    
263                    case exDiscReasonLicenseErrClientEncryption:
264                            text = "Incorrect client license enryption";
265                            break;
266    
267                    case exDiscReasonLicenseCantUpgradeLicense:
268                            text = "Can't upgrade license";
269                            break;
270    
271                    case exDiscReasonLicenseNoRemoteConnections:
272                            text = "The server is not licensed to accept remote connections";
273                            break;
274    
275                    default:
276                            if (reason > 0x1000 && reason < 0x7fff)
277                            {
278                                    text = "Internal protocol error";
279                            }
280                            else
281                            {
282                                    text = "Unknown reason";
283                            }
284            }
285            fprintf(stderr, "disconnect: %s.\n", text);
286    }
287    
288    static void
289    rdesktop_reset_state(void)
290    {
291            rdp_reset_state();
292    }
293    
294  static BOOL  static BOOL
295  read_password(char *password, int size)  read_password(char *password, int size)
296  {  {
# Line 189  parse_server_and_port(char *server) Line 348  parse_server_and_port(char *server)
348                  if (*server == '[' && p != NULL)                  if (*server == '[' && p != NULL)
349                  {                  {
350                          if (*(p + 1) == ':' && *(p + 2) != '\0')                          if (*(p + 1) == ':' && *(p + 2) != '\0')
351                                  tcp_port_rdp = strtol(p + 2, NULL, 10);                                  g_tcp_port_rdp = strtol(p + 2, NULL, 10);
352                          /* remove the port number and brackets from the address */                          /* remove the port number and brackets from the address */
353                          *p = '\0';                          *p = '\0';
354                          strncpy(server, server + 1, strlen(server));                          strncpy(server, server + 1, strlen(server));
# Line 201  parse_server_and_port(char *server) Line 360  parse_server_and_port(char *server)
360                  p = strchr(server, ':');                  p = strchr(server, ':');
361                  if (p != NULL)                  if (p != NULL)
362                  {                  {
363                          tcp_port_rdp = strtol(p + 1, NULL, 10);                          g_tcp_port_rdp = strtol(p + 1, NULL, 10);
364                          *p = 0;                          *p = 0;
365                  }                  }
366          }          }
# Line 209  parse_server_and_port(char *server) Line 368  parse_server_and_port(char *server)
368          p = strchr(server, ':');          p = strchr(server, ':');
369          if (p != NULL)          if (p != NULL)
370          {          {
371                  tcp_port_rdp = strtol(p + 1, NULL, 10);                  g_tcp_port_rdp = strtol(p + 1, NULL, 10);
372                  *p = 0;                  *p = 0;
373          }          }
374  #endif /* IPv6 */  #endif /* IPv6 */
# Line 224  main(int argc, char *argv[]) Line 383  main(int argc, char *argv[])
383          char fullhostname[64];          char fullhostname[64];
384          char domain[16];          char domain[16];
385          char password[64];          char password[64];
386          char shell[128];          char shell[256];
387          char directory[32];          char directory[256];
388          BOOL prompt_password, rdp_retval = False;          BOOL prompt_password, deactivated;
389          struct passwd *pw;          struct passwd *pw;
390          uint32 flags;          uint32 flags, ext_disc_reason = 0;
391          char *p;          char *p;
392          int c;          int c;
393            char *locale = NULL;
394          int username_option = 0;          int username_option = 0;
395            BOOL geometry_option = False;
396            int run_count = 0;      /* Session Directory support */
397            BOOL continue_connect = True;   /* Session Directory support */
398    
399    #ifdef HAVE_LOCALE_H
400            /* Set locale according to environment */
401            locale = setlocale(LC_ALL, "");
402            if (locale)
403            {
404                    locale = xstrdup(locale);
405            }
406    
407    #endif
408          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
409          prompt_password = False;          prompt_password = False;
410          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
411          strcpy(keymapname, "en-us");          g_embed_wnd = 0;
412    
413          g_num_devices = 0;          g_num_devices = 0;
414    
# Line 247  main(int argc, char *argv[]) Line 418  main(int argc, char *argv[])
418  #define VNCOPT  #define VNCOPT
419  #endif  #endif
420    
421          while ((c = getopt(argc, argv, VNCOPT "u:d:s:c:p:n:k:g:fbeEmCDKS:T:Na:r:045h?")) != -1)          while ((c = getopt(argc, argv,
422                               VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1)
423          {          {
424                  switch (c)                  switch (c)
425                  {                  {
# Line 265  main(int argc, char *argv[]) Line 437  main(int argc, char *argv[])
437                                  break;                                  break;
438  #endif  #endif
439    
440                            case 'A':
441                                    g_seamless_rdp = True;
442                                    break;
443    
444                          case 'u':                          case 'u':
445                                  STRNCPY(g_username, optarg, sizeof(g_username));                                  STRNCPY(g_username, optarg, sizeof(g_username));
446                                  username_option = 1;                                  username_option = 1;
447                                  break;                                  break;
448    
449                            case 'L':
450    #ifdef HAVE_ICONV
451                                    STRNCPY(g_codepage, optarg, sizeof(g_codepage));
452    #else
453                                    error("iconv support not available\n");
454    #endif
455                                    break;
456    
457                          case 'd':                          case 'd':
458                                  STRNCPY(domain, optarg, sizeof(domain));                                  STRNCPY(domain, optarg, sizeof(domain));
459                                  break;                                  break;
# Line 299  main(int argc, char *argv[]) Line 483  main(int argc, char *argv[])
483                                  break;                                  break;
484    
485                          case 'n':                          case 'n':
486                                  STRNCPY(hostname, optarg, sizeof(hostname));                                  STRNCPY(g_hostname, optarg, sizeof(g_hostname));
487                                  break;                                  break;
488    
489                          case 'k':                          case 'k':
490                                  STRNCPY(keymapname, optarg, sizeof(keymapname));                                  STRNCPY(g_keymapname, optarg, sizeof(g_keymapname));
491                                  break;                                  break;
492    
493                          case 'g':                          case 'g':
494                                    geometry_option = True;
495                                  g_fullscreen = False;                                  g_fullscreen = False;
496                                  if (!strcmp(optarg, "workarea"))                                  if (!strcmp(optarg, "workarea"))
497                                  {                                  {
# Line 322  main(int argc, char *argv[]) Line 507  main(int argc, char *argv[])
507                                  }                                  }
508    
509                                  if (*p == 'x')                                  if (*p == 'x')
510                                          g_height = strtol(p + 1, NULL, 10);                                          g_height = strtol(p + 1, &p, 10);
511    
512                                  if (g_height <= 0)                                  if (g_height <= 0)
513                                  {                                  {
# Line 331  main(int argc, char *argv[]) Line 516  main(int argc, char *argv[])
516                                  }                                  }
517    
518                                  if (*p == '%')                                  if (*p == '%')
519                                    {
520                                          g_width = -g_width;                                          g_width = -g_width;
521                                            p++;
522                                    }
523    
524                                    if (*p == '+' || *p == '-')
525                                    {
526                                            g_pos |= (*p == '-') ? 2 : 1;
527                                            g_xpos = strtol(p, &p, 10);
528    
529                                    }
530                                    if (*p == '+' || *p == '-')
531                                    {
532                                            g_pos |= (*p == '-') ? 4 : 1;
533                                            g_ypos = strtol(p, NULL, 10);
534                                    }
535    
536                                  break;                                  break;
537    
# Line 340  main(int argc, char *argv[]) Line 540  main(int argc, char *argv[])
540                                  break;                                  break;
541    
542                          case 'b':                          case 'b':
543                                  g_orders = False;                                  g_bitmap_cache = False;
544                                    break;
545    
546                            case 'B':
547                                    g_ownbackstore = False;
548                                  break;                                  break;
549    
550                          case 'e':                          case 'e':
# Line 390  main(int argc, char *argv[]) Line 594  main(int argc, char *argv[])
594                                  g_numlock_sync = True;                                  g_numlock_sync = True;
595                                  break;                                  break;
596    
597                            case 'X':
598                                    g_embed_wnd = strtol(optarg, NULL, 0);
599                                    break;
600    
601                          case 'a':                          case 'a':
602                                  g_server_bpp = strtol(optarg, NULL, 10);                                  g_server_depth = strtol(optarg, NULL, 10);
603                                  if (g_server_bpp != 8 && g_server_bpp != 16 && g_server_bpp != 15                                  if (g_server_depth != 8 &&
604                                      && g_server_bpp != 24)                                      g_server_depth != 16 &&
605                                        g_server_depth != 15 && g_server_depth != 24)
606                                  {                                  {
607                                          error("invalid server bpp\n");                                          error("Invalid server colour depth.\n");
608                                          return 1;                                          return 1;
609                                  }                                  }
610                                  break;                                  break;
611    
612                            case 'z':
613                                    DEBUG(("rdp compression enabled\n"));
614                                    flags |= (RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2);
615                                    break;
616    
617                            case 'x':
618                                    if (str_startswith(optarg, "m"))        /* modem */
619                                    {
620                                            g_rdp5_performanceflags =
621                                                    RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG |
622                                                    RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;
623                                    }
624                                    else if (str_startswith(optarg, "b"))   /* broadband */
625                                    {
626                                            g_rdp5_performanceflags = RDP5_NO_WALLPAPER;
627                                    }
628                                    else if (str_startswith(optarg, "l"))   /* lan */
629                                    {
630                                            g_rdp5_performanceflags = RDP5_DISABLE_NOTHING;
631                                    }
632                                    else
633                                    {
634                                            g_rdp5_performanceflags = strtol(optarg, NULL, 16);
635                                    }
636                                    break;
637    
638                            case 'P':
639                                    g_bitmap_cache_persist_enable = True;
640                                    break;
641    
642                          case 'r':                          case 'r':
643    
644                                  if (strncmp("sound", optarg, 5) == 0)                                  if (str_startswith(optarg, "sound"))
645                                  {                                  {
646                                            optarg += 5;
647    
648                                            if (*optarg == ':')
649                                            {
650                                                    *optarg++;
651                                                    while ((p = next_arg(optarg, ',')))
652                                                    {
653                                                            if (str_startswith(optarg, "remote"))
654                                                                    flags |= RDP_LOGON_LEAVE_AUDIO;
655    
656                                                            if (str_startswith(optarg, "local"))
657    #ifdef WITH_RDPSND
658                                                                    g_rdpsnd = True;
659    #else
660                                                                    warning("Not compiled with sound support\n");
661    #endif
662    
663                                                            if (str_startswith(optarg, "off"))
664    #ifdef WITH_RDPSND
665                                                                    g_rdpsnd = False;
666    #else
667                                                                    warning("Not compiled with sound support\n");
668    #endif
669    
670                                                            optarg = p;
671                                                    }
672                                            }
673                                            else
674                                            {
675  #ifdef WITH_RDPSND  #ifdef WITH_RDPSND
676                                          g_rdpsnd = True;                                                  g_rdpsnd = True;
677  #else  #else
678                                          warning("Not compiled with sound support");                                                  warning("Not compiled with sound support\n");
679  #endif  #endif
680                                            }
681                                  }                                  }
682                                  else if (strncmp("disk", optarg, 4) == 0)                                  else if (str_startswith(optarg, "disk"))
683                                  {                                  {
684                                          /* -r disk:h:=/mnt/floppy */                                          /* -r disk:h:=/mnt/floppy */
685                                          disk_enum_devices(&g_num_devices, optarg + 4);                                          disk_enum_devices(&g_num_devices, optarg + 4);
686                                  }                                  }
687                                  else if (strncmp("comport", optarg, 7) == 0)                                  else if (str_startswith(optarg, "comport"))
688                                  {                                  {
689                                          serial_enum_devices(&g_num_devices, optarg + 7);                                          serial_enum_devices(&g_num_devices, optarg + 7);
690                                  }                                  }
691                                  else if (strncmp("lptport", optarg, 7) == 0)                                  else if (str_startswith(optarg, "lspci"))
692                                    {
693                                            lspci_enabled = True;
694                                    }
695                                    else if (str_startswith(optarg, "lptport"))
696                                  {                                  {
697                                          parallel_enum_devices(&g_num_devices, optarg + 7);                                          parallel_enum_devices(&g_num_devices, optarg + 7);
698                                  }                                  }
699                                  else if (strncmp("printer", optarg, 7) == 0)                                  else if (str_startswith(optarg, "printer"))
700                                  {                                  {
701                                          printer_enum_devices(&g_num_devices, optarg + 7);                                          printer_enum_devices(&g_num_devices, optarg + 7);
702                                  }                                  }
703                                    else if (str_startswith(optarg, "clientname"))
704                                    {
705                                            g_rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1);
706                                            strcpy(g_rdpdr_clientname, optarg + 11);
707                                    }
708                                  else                                  else
709                                  {                                  {
710                                          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\n");
# Line 453  main(int argc, char *argv[]) Line 731  main(int argc, char *argv[])
731                  }                  }
732          }          }
733    
734          if (argc - optind < 1)          if (argc - optind != 1)
735          {          {
736                  usage(argv[0]);                  usage(argv[0]);
737                  return 1;                  return 1;
# Line 462  main(int argc, char *argv[]) Line 740  main(int argc, char *argv[])
740          STRNCPY(server, argv[optind], sizeof(server));          STRNCPY(server, argv[optind], sizeof(server));
741          parse_server_and_port(server);          parse_server_and_port(server);
742    
743            if (g_seamless_rdp)
744            {
745                    if (g_win_button_size)
746                    {
747                            error("You cannot use -S and -A at the same time\n");
748                            return 1;
749                    }
750                    g_rdp5_performanceflags &= ~RDP5_NO_FULLWINDOWDRAG;
751                    if (geometry_option)
752                    {
753                            error("You cannot use -g and -A at the same time\n");
754                            return 1;
755                    }
756                    if (g_fullscreen)
757                    {
758                            error("You cannot use -f and -A at the same time\n");
759                            return 1;
760                    }
761                    if (g_hide_decorations)
762                    {
763                            error("You cannot use -D and -A at the same time\n");
764                            return 1;
765                    }
766                    if (g_embed_wnd)
767                    {
768                            error("You cannot use -X and -A at the same time\n");
769                            return 1;
770                    }
771                    if (!g_use_rdp5)
772                    {
773                            error("You cannot use -4 and -A at the same time\n");
774                            return 1;
775                    }
776                    g_width = -100;
777                    g_grab_keyboard = False;
778            }
779    
780          if (!username_option)          if (!username_option)
781          {          {
782                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
# Line 474  main(int argc, char *argv[]) Line 789  main(int argc, char *argv[])
789                  STRNCPY(g_username, pw->pw_name, sizeof(g_username));                  STRNCPY(g_username, pw->pw_name, sizeof(g_username));
790          }          }
791    
792          if (hostname[0] == 0)  #ifdef HAVE_ICONV
793            if (g_codepage[0] == 0)
794            {
795                    if (setlocale(LC_CTYPE, ""))
796                    {
797                            STRNCPY(g_codepage, nl_langinfo(CODESET), sizeof(g_codepage));
798                    }
799                    else
800                    {
801                            STRNCPY(g_codepage, DEFAULT_CODEPAGE, sizeof(g_codepage));
802                    }
803            }
804    #endif
805    
806            if (g_hostname[0] == 0)
807          {          {
808                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
809                  {                  {
# Line 486  main(int argc, char *argv[]) Line 815  main(int argc, char *argv[])
815                  if (p != NULL)                  if (p != NULL)
816                          *p = 0;                          *p = 0;
817    
818                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
819            }
820    
821            if (g_keymapname[0] == 0)
822            {
823                    if (locale && xkeymap_from_locale(locale))
824                    {
825                            fprintf(stderr, "Autoselected keyboard map %s\n", g_keymapname);
826                    }
827                    else
828                    {
829                            STRNCPY(g_keymapname, "en-us", sizeof(g_keymapname));
830                    }
831          }          }
832            if (locale)
833                    xfree(locale);
834    
835    
836          if (prompt_password && read_password(password, sizeof(password)))          if (prompt_password && read_password(password, sizeof(password)))
837                  flags |= RDP_LOGON_AUTO;                  flags |= RDP_LOGON_AUTO;
# Line 510  main(int argc, char *argv[]) Line 854  main(int argc, char *argv[])
854          if (g_rdpsnd)          if (g_rdpsnd)
855                  rdpsnd_init();                  rdpsnd_init();
856  #endif  #endif
857    
858            if (lspci_enabled)
859                    lspci_init();
860    
861          rdpdr_init();          rdpdr_init();
862    
863          if (!rdp_connect(server, flags, domain, password, shell, directory))          while (run_count < 2 && continue_connect)       /* add support for Session Directory; only reconnect once */
864                  return 1;          {
865                    if (run_count == 0)
866                    {
867                            if (!rdp_connect(server, flags, domain, password, shell, directory))
868                                    return 1;
869                    }
870                    else if (!rdp_reconnect
871                             (server, flags, domain, password, shell, directory, g_redirect_cookie))
872                            return 1;
873    
874          /* By setting encryption to False here, we have an encrypted login                  /* By setting encryption to False here, we have an encrypted login
875             packet but unencrypted transfer of other packets */                     packet but unencrypted transfer of other packets */
876          if (!packet_encryption)                  if (!packet_encryption)
877                  g_encryption = False;                          g_encryption = False;
878    
879    
880          DEBUG(("Connection successful.\n"));                  DEBUG(("Connection successful.\n"));
881          memset(password, 0, sizeof(password));                  memset(password, 0, sizeof(password));
882    
883          if (ui_create_window())                  if (run_count == 0)
884          {                          if (!ui_create_window())
885                  rdp_retval = rdp_main_loop();                                  continue_connect = False;
886                  ui_destroy_window();  
887                    if (continue_connect)
888                            rdp_main_loop(&deactivated, &ext_disc_reason);
889    
890                    DEBUG(("Disconnecting...\n"));
891                    rdp_disconnect();
892    
893                    if ((g_redirect == True) && (run_count == 0))   /* Support for Session Directory */
894                    {
895                            /* reset state of major globals */
896                            rdesktop_reset_state();
897    
898                            STRNCPY(domain, g_redirect_domain, sizeof(domain));
899                            STRNCPY(g_username, g_redirect_username, sizeof(g_username));
900                            STRNCPY(password, g_redirect_password, sizeof(password));
901                            STRNCPY(server, g_redirect_server, sizeof(server));
902                            flags |= RDP_LOGON_AUTO;
903    
904                            g_redirect = False;
905                    }
906                    else
907                    {
908                            continue_connect = False;
909                            ui_destroy_window();
910                            break;
911                    }
912    
913                    run_count++;
914          }          }
915    
916          DEBUG(("Disconnecting...\n"));          cache_save_state();
         rdp_disconnect();  
917          ui_deinit();          ui_deinit();
918    
919          if (True == rdp_retval)          if (ext_disc_reason >= 2)
920                    print_disconnect_reason(ext_disc_reason);
921    
922            if (deactivated)
923            {
924                    /* clean disconnect */
925                  return 0;                  return 0;
926            }
927          else          else
928                  return 2;          {
929                    if (ext_disc_reason == exDiscReasonAPIInitiatedDisconnect
930                        || ext_disc_reason == exDiscReasonAPIInitiatedLogoff)
931                    {
932                            /* not so clean disconnect, but nothing to worry about */
933                            return 0;
934                    }
935                    else
936                    {
937                            /* return error */
938                            return 2;
939                    }
940            }
941    
942  #endif  #endif
943    
# Line 639  xmalloc(int size) Line 1039  xmalloc(int size)
1039          return mem;          return mem;
1040  }  }
1041    
1042    /* strdup */
1043    char *
1044    xstrdup(const char *s)
1045    {
1046            char *mem = strdup(s);
1047            if (mem == NULL)
1048            {
1049                    perror("strdup");
1050                    exit(1);
1051            }
1052            return mem;
1053    }
1054    
1055  /* realloc; exit if out of memory */  /* realloc; exit if out of memory */
1056  void *  void *
1057  xrealloc(void *oldmem, int size)  xrealloc(void *oldmem, int size)
1058  {  {
1059          void *mem = realloc(oldmem, size);          void *mem;
1060    
1061            if (size < 1)
1062                    size = 1;
1063            mem = realloc(oldmem, size);
1064          if (mem == NULL)          if (mem == NULL)
1065          {          {
1066                  error("xrealloc %d\n", size);                  error("xrealloc %d\n", size);
# Line 728  hexdump(unsigned char *p, unsigned int l Line 1145  hexdump(unsigned char *p, unsigned int l
1145  }  }
1146    
1147  /*  /*
1148    input: src is the string we look in for needle    input: src is the string we look in for needle.
1149             Needle may be escaped by a backslash, in
1150             that case we ignore that particular needle.
1151    return value: returns next src pointer, for    return value: returns next src pointer, for
1152          succesive executions, like in a while loop          succesive executions, like in a while loop
1153          if retval is 0, then there are no more args.          if retval is 0, then there are no more args.
# Line 749  char * Line 1168  char *
1168  next_arg(char *src, char needle)  next_arg(char *src, char needle)
1169  {  {
1170          char *nextval;          char *nextval;
1171            char *p;
1172            char *mvp = 0;
1173    
1174          // EOS          /* EOS */
1175          if (*src == (char) 0x00)          if (*src == (char) 0x00)
1176                  return 0;                  return 0;
1177    
1178          // more args available.          p = src;
1179          nextval = strchr(src, needle);          /*  skip escaped needles */
1180            while ((nextval = strchr(p, needle)))
1181            {
1182                    mvp = nextval - 1;
1183                    /* found backslashed needle */
1184                    if (*mvp == '\\' && (mvp > src))
1185                    {
1186                            /* move string one to the left */
1187                            while (*(mvp + 1) != (char) 0x00)
1188                            {
1189                                    *mvp = *(mvp + 1);
1190                                    *mvp++;
1191                            }
1192                            *mvp = (char) 0x00;
1193                            p = nextval;
1194                    }
1195                    else
1196                    {
1197                            p = nextval + 1;
1198                            break;
1199                    }
1200    
1201            }
1202    
1203            /* more args available */
1204          if (nextval)          if (nextval)
1205          {          {
1206                  *nextval = (char) 0x00;                  *nextval = (char) 0x00;
1207                  return ++nextval;                  return ++nextval;
1208          }          }
1209    
1210          // no more args after this, jump to EOS          /* no more args after this, jump to EOS */
1211          nextval = src + strlen(src);          nextval = src + strlen(src);
1212          return nextval;          return nextval;
1213  }  }
1214    
1215    
1216  void  void
1217  toupper_str(char* p)  toupper_str(char *p)
1218  {  {
1219          while( *p ){          while (*p)
1220                  if( (*p >= 'a') && (*p <= 'z') )          {
1221                    if ((*p >= 'a') && (*p <= 'z'))
1222                          *p = toupper((int) *p);                          *p = toupper((int) *p);
1223                  p++;                  p++;
1224          }          }
1225  }  }
1226    
1227    
1228    BOOL
1229    str_startswith(const char *s, const char *prefix)
1230    {
1231            return (strncmp(s, prefix, strlen(prefix)) == 0);
1232    }
1233    
1234    
1235    /* Split input into lines, and call linehandler for each
1236       line. Incomplete lines are saved in the rest variable, which should
1237       initially point to NULL. When linehandler returns False, stop and
1238       return False. Otherwise, return True.  */
1239    BOOL
1240    str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data)
1241    {
1242            char *buf, *p;
1243            char *oldrest;
1244            size_t inputlen;
1245            size_t buflen;
1246            size_t restlen = 0;
1247            BOOL ret = True;
1248    
1249            /* Copy data to buffer */
1250            inputlen = strlen(input);
1251            if (*rest)
1252                    restlen = strlen(*rest);
1253            buflen = restlen + inputlen + 1;
1254            buf = (char *) xmalloc(buflen);
1255            buf[0] = '\0';
1256            if (*rest)
1257                    STRNCPY(buf, *rest, buflen);
1258            strncat(buf, input, inputlen);
1259            p = buf;
1260    
1261            while (1)
1262            {
1263                    char *newline = strchr(p, '\n');
1264                    if (newline)
1265                    {
1266                            *newline = '\0';
1267                            if (!linehandler(p, data))
1268                            {
1269                                    p = newline + 1;
1270                                    ret = False;
1271                                    break;
1272                            }
1273                            p = newline + 1;
1274                    }
1275                    else
1276                    {
1277                            break;
1278    
1279                    }
1280            }
1281    
1282            /* Save in rest */
1283            oldrest = *rest;
1284            restlen = buf + buflen - p;
1285            *rest = (char *) xmalloc(restlen);
1286            STRNCPY((*rest), p, restlen);
1287            xfree(oldrest);
1288    
1289            xfree(buf);
1290            return ret;
1291    }
1292    
1293    /* Execute the program specified by argv. For each line in
1294       stdout/stderr output, call linehandler. Returns false on failure. */
1295    BOOL
1296    subprocess(char *const argv[], str_handle_lines_t linehandler, void *data)
1297    {
1298            pid_t child;
1299            int fd[2];
1300            int n = 1;
1301            char output[256];
1302            char *rest = NULL;
1303    
1304            if (pipe(fd) < 0)
1305            {
1306                    perror("pipe");
1307                    return False;
1308            }
1309    
1310            if ((child = fork()) < 0)
1311            {
1312                    perror("fork");
1313                    return False;
1314            }
1315    
1316            /* Child */
1317            if (child == 0)
1318            {
1319                    /* Close read end */
1320                    close(fd[0]);
1321    
1322                    /* Redirect stdout and stderr to pipe */
1323                    dup2(fd[1], 1);
1324                    dup2(fd[1], 2);
1325    
1326                    /* Execute */
1327                    execvp(argv[0], argv);
1328                    perror("Error executing child");
1329                    _exit(128);
1330            }
1331    
1332            /* Parent. Close write end. */
1333            close(fd[1]);
1334            while (n > 0)
1335            {
1336                    n = read(fd[0], output, 255);
1337                    output[n] = '\0';
1338                    str_handle_lines(output, &rest, linehandler, data);
1339            }
1340            xfree(rest);
1341    
1342            return True;
1343    }
1344    
1345    
1346  /* not all clibs got ltoa */  /* not all clibs got ltoa */
1347  #define LTOA_BUFSIZE (sizeof(long) * 8 + 1)  #define LTOA_BUFSIZE (sizeof(long) * 8 + 1)
1348    
1349  char *  char *
1350  ltoa(long N, int base)  l_to_a(long N, int base)
1351  {  {
1352          static char ret[LTOA_BUFSIZE];          static char ret[LTOA_BUFSIZE];
1353    
1354          register int i = 2;          char *head = ret, buf[LTOA_BUFSIZE], *tail = buf + sizeof(buf);
         long uarg;  
         char *tail, *head = ret, buf[LTOA_BUFSIZE];  
1355    
1356          if (36 < base || 2 > base)          register int divrem;
                 base = 10;  
1357    
1358          tail = &buf[LTOA_BUFSIZE - 1];          if (base < 36 || 2 > base)
1359          *tail-- = '\0';                  base = 10;
1360    
1361          if (10 == base && N < 0L)          if (N < 0)
1362          {          {
1363                  *head++ = '-';                  *head++ = '-';
1364                  uarg = -N;                  N = -N;
1365          }          }
         else  
                 uarg = N;  
1366    
1367          if (uarg)          tail = buf + sizeof(buf);
1368          {          *--tail = 0;
                 for (i = 1; uarg; ++i)  
                 {  
                         register ldiv_t r;  
1369    
1370                          r = ldiv(uarg, base);          do
1371                          *tail-- = (char) (r.rem + ((9L < r.rem) ? ('A' - 10L) : '0'));          {
1372                          uarg = r.quot;                  divrem = N % base;
1373                  }                  *--tail = (divrem <= 9) ? divrem + '0' : divrem + 'a' - 10;
1374                    N /= base;
1375          }          }
1376          else          while (N);
                 *tail-- = '0';  
1377    
1378          memcpy(head, ++tail, i);          strcpy(head, tail);
1379          return ret;          return ret;
1380  }  }
1381    
# Line 835  load_licence(unsigned char **data) Line 1391  load_licence(unsigned char **data)
1391          if (home == NULL)          if (home == NULL)
1392                  return -1;                  return -1;
1393    
1394          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));          path = (char *) xmalloc(strlen(home) + strlen(g_hostname) + sizeof("/.rdesktop/licence."));
1395          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);          sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname);
1396    
1397          fd = open(path, O_RDONLY);          fd = open(path, O_RDONLY);
1398          if (fd == -1)          if (fd == -1)
# Line 862  save_licence(unsigned char *data, int le Line 1418  save_licence(unsigned char *data, int le
1418          if (home == NULL)          if (home == NULL)
1419                  return;                  return;
1420    
1421          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));          path = (char *) xmalloc(strlen(home) + strlen(g_hostname) + sizeof("/.rdesktop/licence."));
1422    
1423          sprintf(path, "%s/.rdesktop", home);          sprintf(path, "%s/.rdesktop", home);
1424          if ((mkdir(path, 0700) == -1) && errno != EEXIST)          if ((mkdir(path, 0700) == -1) && errno != EEXIST)
# Line 873  save_licence(unsigned char *data, int le Line 1429  save_licence(unsigned char *data, int le
1429    
1430          /* write licence to licence.hostname.new, then atomically rename to licence.hostname */          /* write licence to licence.hostname.new, then atomically rename to licence.hostname */
1431    
1432          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);          sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname);
1433          tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));          tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));
1434          strcpy(tmppath, path);          strcpy(tmppath, path);
1435          strcat(tmppath, ".new");          strcat(tmppath, ".new");
# Line 900  save_licence(unsigned char *data, int le Line 1456  save_licence(unsigned char *data, int le
1456          xfree(tmppath);          xfree(tmppath);
1457          xfree(path);          xfree(path);
1458  }  }
1459    
1460    /* Create the bitmap cache directory */
1461    BOOL
1462    rd_pstcache_mkdir(void)
1463    {
1464            char *home;
1465            char bmpcache_dir[256];
1466    
1467            home = getenv("HOME");
1468    
1469            if (home == NULL)
1470                    return False;
1471    
1472            sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop");
1473    
1474            if ((mkdir(bmpcache_dir, S_IRWXU) == -1) && errno != EEXIST)
1475            {
1476                    perror(bmpcache_dir);
1477                    return False;
1478            }
1479    
1480            sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop/cache");
1481    
1482            if ((mkdir(bmpcache_dir, S_IRWXU) == -1) && errno != EEXIST)
1483            {
1484                    perror(bmpcache_dir);
1485                    return False;
1486            }
1487    
1488            return True;
1489    }
1490    
1491    /* open a file in the .rdesktop directory */
1492    int
1493    rd_open_file(char *filename)
1494    {
1495            char *home;
1496            char fn[256];
1497            int fd;
1498    
1499            home = getenv("HOME");
1500            if (home == NULL)
1501                    return -1;
1502            sprintf(fn, "%s/.rdesktop/%s", home, filename);
1503            fd = open(fn, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
1504            if (fd == -1)
1505                    perror(fn);
1506            return fd;
1507    }
1508    
1509    /* close file */
1510    void
1511    rd_close_file(int fd)
1512    {
1513            close(fd);
1514    }
1515    
1516    /* read from file*/
1517    int
1518    rd_read_file(int fd, void *ptr, int len)
1519    {
1520            return read(fd, ptr, len);
1521    }
1522    
1523    /* write to file */
1524    int
1525    rd_write_file(int fd, void *ptr, int len)
1526    {
1527            return write(fd, ptr, len);
1528    }
1529    
1530    /* move file pointer */
1531    int
1532    rd_lseek_file(int fd, int offset)
1533    {
1534            return lseek(fd, offset, SEEK_SET);
1535    }
1536    
1537    /* do a write lock on a file */
1538    BOOL
1539    rd_lock_file(int fd, int start, int len)
1540    {
1541            struct flock lock;
1542    
1543            lock.l_type = F_WRLCK;
1544            lock.l_whence = SEEK_SET;
1545            lock.l_start = start;
1546            lock.l_len = len;
1547            if (fcntl(fd, F_SETLK, &lock) == -1)
1548                    return False;
1549            return True;
1550    }

Legend:
Removed from v.570  
changed lines
  Added in v.1089

  ViewVC Help
Powered by ViewVC 1.1.26