/[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 471 by forsberg, Mon Sep 22 12:33:21 2003 UTC sourceforge.net/branches/seamlessrdp-branch/rdesktop/rdesktop.c revision 1058, Tue Mar 7 08:17:41 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 26  Line 26 
26  #include <sys/stat.h>           /* stat */  #include <sys/stat.h>           /* stat */
27  #include <sys/time.h>           /* gettimeofday */  #include <sys/time.h>           /* gettimeofday */
28  #include <sys/times.h>          /* times */  #include <sys/times.h>          /* times */
29    #include <ctype.h>              /* toupper */
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[32] = "";  char g_title[64] = "";
51  char g_username[16];  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_width = 800;              /* If width or height are reset to zero, the geometry will  int g_keyboard_type = 0x4;      /* Defaults to US keyboard layout */
56                                     be fetched from _NET_WORKAREA */  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
60                                       geometry will be fetched from
61                                       _NET_WORKAREA. If negative,
62                                       absolute value specifies the
63                                       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  extern BOOL g_owncolmap;  BOOL g_console_session = False;
88    BOOL g_numlock_sync = False;
89    BOOL lspci_enabled = False;
90    BOOL g_owncolmap = False;
91    BOOL g_ownbackstore = True;     /* We can't rely on external BackingStore */
92    uint32 g_embed_wnd;
93    uint32 g_rdp5_performanceflags =
94            RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
95    /* Session Directory redirection */
96    BOOL g_redirect = False;
97    char g_redirect_server[64];
98    char g_redirect_domain[16];
99    char g_redirect_password[64];
100    char g_redirect_username[64];
101    char g_redirect_cookie[128];
102    uint32 g_redirect_flags = 0;
103    
104    #ifdef WITH_RDPSND
105    BOOL g_rdpsnd = False;
106    #endif
107    
108    #ifdef HAVE_ICONV
109    char g_codepage[16] = "";
110    #endif
111    
112    extern RDPDR_DEVICE g_rdpdr_device[];
113    extern uint32 g_num_devices;
114    extern char *g_rdpdr_clientname;
115    
116  #ifdef RDP2VNC  #ifdef RDP2VNC
117  extern int rfb_port;  extern int rfb_port;
# Line 75  static void Line 125  static void
125  usage(char *program)  usage(char *program)
126  {  {
127          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
128          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2003 Matt Chapman.\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2005 Matt Chapman.\n");
129          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
130    
131          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
# Line 86  usage(char *program) Line 136  usage(char *program)
136          fprintf(stderr, "   -u: user name\n");          fprintf(stderr, "   -u: user name\n");
137          fprintf(stderr, "   -d: domain\n");          fprintf(stderr, "   -d: domain\n");
138          fprintf(stderr, "   -s: shell\n");          fprintf(stderr, "   -s: shell\n");
         fprintf(stderr, "   -S: caption button size (single application mode)\n");  
139          fprintf(stderr, "   -c: working directory\n");          fprintf(stderr, "   -c: working directory\n");
140          fprintf(stderr, "   -p: password (- to prompt)\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
141          fprintf(stderr, "   -n: client hostname\n");          fprintf(stderr, "   -n: client hostname\n");
142          fprintf(stderr, "   -k: keyboard layout on terminal server (us,sv,gr,etc.)\n");          fprintf(stderr, "   -k: keyboard layout on server (en-us, de, sv, etc.)\n");
143          fprintf(stderr, "   -g: desktop geometry (WxH)\n");          fprintf(stderr, "   -g: desktop geometry (WxH)\n");
144          fprintf(stderr, "   -f: full-screen mode\n");          fprintf(stderr, "   -f: full-screen mode\n");
145          fprintf(stderr, "   -b: force bitmap updates\n");          fprintf(stderr, "   -b: force bitmap updates\n");
146    #ifdef HAVE_ICONV
147            fprintf(stderr, "   -L: local codepage\n");
148    #endif
149            fprintf(stderr, "   -B: use BackingStore of X-server (if available)\n");
150          fprintf(stderr, "   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -e: disable encryption (French TS)\n");
151          fprintf(stderr, "   -E: disable encryption from client to server\n");          fprintf(stderr, "   -E: disable encryption from client to server\n");
152          fprintf(stderr, "   -m: do not send motion events\n");          fprintf(stderr, "   -m: do not send motion events\n");
153          fprintf(stderr, "   -C: use private colour map\n");          fprintf(stderr, "   -C: use private colour map\n");
154            fprintf(stderr, "   -D: hide window manager decorations\n");
155          fprintf(stderr, "   -K: keep window manager key bindings\n");          fprintf(stderr, "   -K: keep window manager key bindings\n");
156            fprintf(stderr, "   -S: caption button size (single application mode)\n");
157          fprintf(stderr, "   -T: window title\n");          fprintf(stderr, "   -T: window title\n");
158          fprintf(stderr, "   -D: hide window manager decorations\n");          fprintf(stderr, "   -N: enable numlock syncronization\n");
159          fprintf(stderr, "   -a: server bpp\n");          fprintf(stderr, "   -X: embed into another window with a given id.\n");
160          fprintf(stderr, "   -4: Use RDP version 4\n");          fprintf(stderr, "   -a: connection colour depth\n");
161          fprintf(stderr, "   -5: Use RDP version 5 (default)\n");          fprintf(stderr, "   -z: enable rdp compression\n");
162            fprintf(stderr, "   -x: RDP5 experience (m[odem 28.8], b[roadband], l[an] or hex nr.)\n");
163            fprintf(stderr, "   -P: use persistent bitmap caching\n");
164            fprintf(stderr, "   -r: enable specified device redirection (this flag can be repeated)\n");
165            fprintf(stderr,
166                    "         '-r comport:COM1=/dev/ttyS0': enable serial redirection of /dev/ttyS0 to COM1\n");
167            fprintf(stderr, "             or      COM1=/dev/ttyS0,COM2=/dev/ttyS1\n");
168            fprintf(stderr,
169                    "         '-r disk:floppy=/mnt/floppy': enable redirection of /mnt/floppy to 'floppy' share\n");
170            fprintf(stderr, "             or   'floppy=/mnt/floppy,cdrom=/mnt/cdrom'\n");
171            fprintf(stderr, "         '-r clientname=<client name>': Set the client name displayed\n");
172            fprintf(stderr, "             for redirected disks\n");
173            fprintf(stderr,
174                    "         '-r lptport:LPT1=/dev/lp0': enable parallel redirection of /dev/lp0 to LPT1\n");
175            fprintf(stderr, "             or      LPT1=/dev/lp0,LPT2=/dev/lp1\n");
176            fprintf(stderr, "         '-r printer:mydeskjet': enable printer redirection\n");
177            fprintf(stderr,
178                    "             or      mydeskjet=\"HP LaserJet IIIP\" to enter server driver as well\n");
179            fprintf(stderr, "         '-r sound:[local|off|remote]': enable sound redirection\n");
180            fprintf(stderr, "                     remote would leave sound on server\n");
181            fprintf(stderr, "   -0: attach to console\n");
182            fprintf(stderr, "   -4: use RDP version 4\n");
183            fprintf(stderr, "   -5: use RDP version 5 (default)\n");
184    }
185    
186    static void
187    print_disconnect_reason(uint16 reason)
188    {
189            char *text;
190    
191            switch (reason)
192            {
193                    case exDiscReasonNoInfo:
194                            text = "No information available";
195                            break;
196    
197                    case exDiscReasonAPIInitiatedDisconnect:
198                            text = "Server initiated disconnect";
199                            break;
200    
201                    case exDiscReasonAPIInitiatedLogoff:
202                            text = "Server initiated logoff";
203                            break;
204    
205                    case exDiscReasonServerIdleTimeout:
206                            text = "Server idle timeout reached";
207                            break;
208    
209                    case exDiscReasonServerLogonTimeout:
210                            text = "Server logon timeout reached";
211                            break;
212    
213                    case exDiscReasonReplacedByOtherConnection:
214                            text = "The session was replaced";
215                            break;
216    
217                    case exDiscReasonOutOfMemory:
218                            text = "The server is out of memory";
219                            break;
220    
221                    case exDiscReasonServerDeniedConnection:
222                            text = "The server denied the connection";
223                            break;
224    
225                    case exDiscReasonServerDeniedConnectionFips:
226                            text = "The server denied the connection for security reason";
227                            break;
228    
229                    case exDiscReasonLicenseInternal:
230                            text = "Internal licensing error";
231                            break;
232    
233                    case exDiscReasonLicenseNoLicenseServer:
234                            text = "No license server available";
235                            break;
236    
237                    case exDiscReasonLicenseNoLicense:
238                            text = "No valid license available";
239                            break;
240    
241                    case exDiscReasonLicenseErrClientMsg:
242                            text = "Invalid licensing message";
243                            break;
244    
245                    case exDiscReasonLicenseHwidDoesntMatchLicense:
246                            text = "Hardware id doesn't match software license";
247                            break;
248    
249                    case exDiscReasonLicenseErrClientLicense:
250                            text = "Client license error";
251                            break;
252    
253                    case exDiscReasonLicenseCantFinishProtocol:
254                            text = "Network error during licensing protocol";
255                            break;
256    
257                    case exDiscReasonLicenseClientEndedProtocol:
258                            text = "Licensing protocol was not completed";
259                            break;
260    
261                    case exDiscReasonLicenseErrClientEncryption:
262                            text = "Incorrect client license enryption";
263                            break;
264    
265                    case exDiscReasonLicenseCantUpgradeLicense:
266                            text = "Can't upgrade license";
267                            break;
268    
269                    case exDiscReasonLicenseNoRemoteConnections:
270                            text = "The server is not licensed to accept remote connections";
271                            break;
272    
273                    default:
274                            if (reason > 0x1000 && reason < 0x7fff)
275                            {
276                                    text = "Internal protocol error";
277                            }
278                            else
279                            {
280                                    text = "Unknown reason";
281                            }
282            }
283            fprintf(stderr, "disconnect: %s.\n", text);
284    }
285    
286    static void
287    rdesktop_reset_state(void)
288    {
289            rdp_reset_state();
290  }  }
291    
292  static BOOL  static BOOL
# Line 163  parse_server_and_port(char *server) Line 346  parse_server_and_port(char *server)
346                  if (*server == '[' && p != NULL)                  if (*server == '[' && p != NULL)
347                  {                  {
348                          if (*(p + 1) == ':' && *(p + 2) != '\0')                          if (*(p + 1) == ':' && *(p + 2) != '\0')
349                                  tcp_port_rdp = strtol(p + 2, NULL, 10);                                  g_tcp_port_rdp = strtol(p + 2, NULL, 10);
350                          /* remove the port number and brackets from the address */                          /* remove the port number and brackets from the address */
351                          *p = '\0';                          *p = '\0';
352                          strncpy(server, server + 1, strlen(server));                          strncpy(server, server + 1, strlen(server));
# Line 175  parse_server_and_port(char *server) Line 358  parse_server_and_port(char *server)
358                  p = strchr(server, ':');                  p = strchr(server, ':');
359                  if (p != NULL)                  if (p != NULL)
360                  {                  {
361                          tcp_port_rdp = strtol(p + 1, NULL, 10);                          g_tcp_port_rdp = strtol(p + 1, NULL, 10);
362                          *p = 0;                          *p = 0;
363                  }                  }
364          }          }
# Line 183  parse_server_and_port(char *server) Line 366  parse_server_and_port(char *server)
366          p = strchr(server, ':');          p = strchr(server, ':');
367          if (p != NULL)          if (p != NULL)
368          {          {
369                  tcp_port_rdp = strtol(p + 1, NULL, 10);                  g_tcp_port_rdp = strtol(p + 1, NULL, 10);
370                  *p = 0;                  *p = 0;
371          }          }
372  #endif /* IPv6 */  #endif /* IPv6 */
# Line 197  main(int argc, char *argv[]) Line 380  main(int argc, char *argv[])
380          char server[64];          char server[64];
381          char fullhostname[64];          char fullhostname[64];
382          char domain[16];          char domain[16];
383          char password[16];          char password[64];
384          char shell[128];          char shell[256];
385          char directory[32];          char directory[256];
386          BOOL prompt_password, rdp_retval = False;          BOOL prompt_password, deactivated;
387          struct passwd *pw;          struct passwd *pw;
388          uint32 flags;          uint32 flags, ext_disc_reason = 0;
389          char *p;          char *p;
390          int c;          int c;
391            char *locale = NULL;
392          int username_option = 0;          int username_option = 0;
393            int run_count = 0;      /* Session Directory support */
394            BOOL continue_connect = True;   /* Session Directory support */
395    
396    #ifdef HAVE_LOCALE_H
397            /* Set locale according to environment */
398            locale = setlocale(LC_ALL, "");
399            if (locale)
400            {
401                    locale = xstrdup(locale);
402            }
403    
404    #endif
405          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
406          prompt_password = False;          prompt_password = False;
407          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
408          strcpy(keymapname, "en-us");          g_embed_wnd = 0;
409    
410            g_num_devices = 0;
411    
412  #ifdef RDP2VNC  #ifdef RDP2VNC
413  #define VNCOPT "V:Q:"  #define VNCOPT "V:Q:"
# Line 218  main(int argc, char *argv[]) Line 415  main(int argc, char *argv[])
415  #define VNCOPT  #define VNCOPT
416  #endif  #endif
417    
418          while ((c = getopt(argc, argv, VNCOPT "u:d:s:S:c:p:n:k:g:a:fbeEmCKT:Dh?54")) != -1)          while ((c = getopt(argc, argv,
419                               VNCOPT "u:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1)
420          {          {
421                  switch (c)                  switch (c)
422                  {                  {
# Line 241  main(int argc, char *argv[]) Line 439  main(int argc, char *argv[])
439                                  username_option = 1;                                  username_option = 1;
440                                  break;                                  break;
441    
442                            case 'L':
443    #ifdef HAVE_ICONV
444                                    STRNCPY(g_codepage, optarg, sizeof(g_codepage));
445    #else
446                                    error("iconv support not available\n");
447    #endif
448                                    break;
449    
450                          case 'd':                          case 'd':
451                                  STRNCPY(domain, optarg, sizeof(domain));                                  STRNCPY(domain, optarg, sizeof(domain));
452                                  break;                                  break;
# Line 249  main(int argc, char *argv[]) Line 455  main(int argc, char *argv[])
455                                  STRNCPY(shell, optarg, sizeof(shell));                                  STRNCPY(shell, optarg, sizeof(shell));
456                                  break;                                  break;
457    
                         case 'S':  
                                 if (!strcmp(optarg, "standard"))  
                                 {  
                                         g_win_button_size = 18;  
                                         break;  
                                 }  
   
                                 g_win_button_size = strtol(optarg, &p, 10);  
   
                                 if (*p)  
                                 {  
                                         error("invalid button size\n");  
                                         return 1;  
                                 }  
   
                                 break;  
   
458                          case 'c':                          case 'c':
459                                  STRNCPY(directory, optarg, sizeof(directory));                                  STRNCPY(directory, optarg, sizeof(directory));
460                                  break;                                  break;
# Line 287  main(int argc, char *argv[]) Line 476  main(int argc, char *argv[])
476                                  break;                                  break;
477    
478                          case 'n':                          case 'n':
479                                  STRNCPY(hostname, optarg, sizeof(hostname));                                  STRNCPY(g_hostname, optarg, sizeof(g_hostname));
480                                  break;                                  break;
481    
482                          case 'k':                          case 'k':
483                                  STRNCPY(keymapname, optarg, sizeof(keymapname));                                  STRNCPY(g_keymapname, optarg, sizeof(g_keymapname));
484                                  break;                                  break;
485    
486                          case 'g':                          case 'g':
487                                    g_fullscreen = False;
488                                  if (!strcmp(optarg, "workarea"))                                  if (!strcmp(optarg, "workarea"))
489                                  {                                  {
490                                          g_width = g_height = 0;                                          g_width = g_height = 0;
# Line 302  main(int argc, char *argv[]) Line 492  main(int argc, char *argv[])
492                                  }                                  }
493    
494                                  g_width = strtol(optarg, &p, 10);                                  g_width = strtol(optarg, &p, 10);
495                                    if (g_width <= 0)
496                                    {
497                                            error("invalid geometry\n");
498                                            return 1;
499                                    }
500    
501                                  if (*p == 'x')                                  if (*p == 'x')
502                                          g_height = strtol(p + 1, NULL, 10);                                          g_height = strtol(p + 1, &p, 10);
503    
504                                  if ((g_width == 0) || (g_height == 0))                                  if (g_height <= 0)
505                                  {                                  {
506                                          error("invalid geometry\n");                                          error("invalid geometry\n");
507                                          return 1;                                          return 1;
508                                  }                                  }
509    
510                                    if (*p == '%')
511                                    {
512                                            g_width = -g_width;
513                                            p++;
514                                    }
515    
516                                    if (*p == '+' || *p == '-')
517                                    {
518                                            g_pos |= (*p == '-') ? 2 : 1;
519                                            g_xpos = strtol(p, &p, 10);
520    
521                                    }
522                                    if (*p == '+' || *p == '-')
523                                    {
524                                            g_pos |= (*p == '-') ? 4 : 1;
525                                            g_ypos = strtol(p, NULL, 10);
526                                    }
527    
528                                  break;                                  break;
529    
530                          case 'f':                          case 'f':
# Line 317  main(int argc, char *argv[]) Line 532  main(int argc, char *argv[])
532                                  break;                                  break;
533    
534                          case 'b':                          case 'b':
535                                  g_orders = False;                                  g_bitmap_cache = False;
536                                    break;
537    
538                            case 'B':
539                                    g_ownbackstore = False;
540                                  break;                                  break;
541    
542                          case 'e':                          case 'e':
# Line 334  main(int argc, char *argv[]) Line 553  main(int argc, char *argv[])
553                                  g_owncolmap = True;                                  g_owncolmap = True;
554                                  break;                                  break;
555    
556                            case 'D':
557                                    g_hide_decorations = True;
558                                    break;
559    
560                          case 'K':                          case 'K':
561                                  g_grab_keyboard = False;                                  g_grab_keyboard = False;
562                                  break;                                  break;
563    
564                            case 'S':
565                                    if (!strcmp(optarg, "standard"))
566                                    {
567                                            g_win_button_size = 18;
568                                            break;
569                                    }
570    
571                                    g_win_button_size = strtol(optarg, &p, 10);
572    
573                                    if (*p)
574                                    {
575                                            error("invalid button size\n");
576                                            return 1;
577                                    }
578    
579                                    break;
580    
581                          case 'T':                          case 'T':
582                                  STRNCPY(g_title, optarg, sizeof(g_title));                                  STRNCPY(g_title, optarg, sizeof(g_title));
583                                  break;                                  break;
584    
585                          case 'D':                          case 'N':
586                                  g_hide_decorations = True;                                  g_numlock_sync = True;
587                                    break;
588    
589                            case 'X':
590                                    g_embed_wnd = strtol(optarg, NULL, 0);
591                                  break;                                  break;
592    
593                          case 'a':                          case 'a':
594                                  g_server_bpp = strtol(optarg, NULL, 10);                                  g_server_depth = strtol(optarg, NULL, 10);
595                                  if (g_server_bpp != 8 && g_server_bpp != 16 && g_server_bpp != 15                                  if (g_server_depth != 8 &&
596                                      && g_server_bpp != 24)                                      g_server_depth != 16 &&
597                                        g_server_depth != 15 && g_server_depth != 24)
598                                  {                                  {
599                                          error("invalid server bpp\n");                                          error("Invalid server colour depth.\n");
600                                          return 1;                                          return 1;
601                                  }                                  }
602                                  break;                                  break;
603    
604                            case 'z':
605                                    DEBUG(("rdp compression enabled\n"));
606                                    flags |= (RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2);
607                                    break;
608    
609                            case 'x':
610                                    if (str_startswith(optarg, "m"))        /* modem */
611                                    {
612                                            g_rdp5_performanceflags =
613                                                    RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG |
614                                                    RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;
615                                    }
616                                    else if (str_startswith(optarg, "b"))   /* broadband */
617                                    {
618                                            g_rdp5_performanceflags = RDP5_NO_WALLPAPER;
619                                    }
620                                    else if (str_startswith(optarg, "l"))   /* lan */
621                                    {
622                                            g_rdp5_performanceflags = RDP5_DISABLE_NOTHING;
623                                    }
624                                    else
625                                    {
626                                            g_rdp5_performanceflags = strtol(optarg, NULL, 16);
627                                    }
628                                    break;
629    
630                            case 'P':
631                                    g_bitmap_cache_persist_enable = True;
632                                    break;
633    
634                            case 'r':
635    
636                                    if (str_startswith(optarg, "sound"))
637                                    {
638                                            optarg += 5;
639    
640                                            if (*optarg == ':')
641                                            {
642                                                    *optarg++;
643                                                    while ((p = next_arg(optarg, ',')))
644                                                    {
645                                                            if (str_startswith(optarg, "remote"))
646                                                                    flags |= RDP_LOGON_LEAVE_AUDIO;
647    
648                                                            if (str_startswith(optarg, "local"))
649    #ifdef WITH_RDPSND
650                                                                    g_rdpsnd = True;
651    #else
652                                                                    warning("Not compiled with sound support\n");
653    #endif
654    
655                                                            if (str_startswith(optarg, "off"))
656    #ifdef WITH_RDPSND
657                                                                    g_rdpsnd = False;
658    #else
659                                                                    warning("Not compiled with sound support\n");
660    #endif
661    
662                                                            optarg = p;
663                                                    }
664                                            }
665                                            else
666                                            {
667    #ifdef WITH_RDPSND
668                                                    g_rdpsnd = True;
669    #else
670                                                    warning("Not compiled with sound support\n");
671    #endif
672                                            }
673                                    }
674                                    else if (str_startswith(optarg, "disk"))
675                                    {
676                                            /* -r disk:h:=/mnt/floppy */
677                                            disk_enum_devices(&g_num_devices, optarg + 4);
678                                    }
679                                    else if (str_startswith(optarg, "comport"))
680                                    {
681                                            serial_enum_devices(&g_num_devices, optarg + 7);
682                                    }
683                                    else if (str_startswith(optarg, "lspci"))
684                                    {
685                                            lspci_enabled = True;
686                                    }
687                                    else if (str_startswith(optarg, "lptport"))
688                                    {
689                                            parallel_enum_devices(&g_num_devices, optarg + 7);
690                                    }
691                                    else if (str_startswith(optarg, "printer"))
692                                    {
693                                            printer_enum_devices(&g_num_devices, optarg + 7);
694                                    }
695                                    else if (str_startswith(optarg, "clientname"))
696                                    {
697                                            g_rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1);
698                                            strcpy(g_rdpdr_clientname, optarg + 11);
699                                    }
700                                    else
701                                    {
702                                            warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound\n");
703                                    }
704                                    break;
705    
706                            case '0':
707                                    g_console_session = True;
708                                    break;
709    
710                          case '4':                          case '4':
711                                  g_use_rdp5 = False;                                  g_use_rdp5 = False;
712                                  break;                                  break;
# Line 372  main(int argc, char *argv[]) Line 723  main(int argc, char *argv[])
723                  }                  }
724          }          }
725    
726          if (argc - optind < 1)          if (argc - optind != 1)
727          {          {
728                  usage(argv[0]);                  usage(argv[0]);
729                  return 1;                  return 1;
# Line 393  main(int argc, char *argv[]) Line 744  main(int argc, char *argv[])
744                  STRNCPY(g_username, pw->pw_name, sizeof(g_username));                  STRNCPY(g_username, pw->pw_name, sizeof(g_username));
745          }          }
746    
747          if (hostname[0] == 0)  #ifdef HAVE_ICONV
748            if (g_codepage[0] == 0)
749            {
750                    if (setlocale(LC_CTYPE, ""))
751                    {
752                            STRNCPY(g_codepage, nl_langinfo(CODESET), sizeof(g_codepage));
753                    }
754                    else
755                    {
756                            STRNCPY(g_codepage, DEFAULT_CODEPAGE, sizeof(g_codepage));
757                    }
758            }
759    #endif
760    
761            if (g_hostname[0] == 0)
762          {          {
763                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
764                  {                  {
# Line 405  main(int argc, char *argv[]) Line 770  main(int argc, char *argv[])
770                  if (p != NULL)                  if (p != NULL)
771                          *p = 0;                          *p = 0;
772    
773                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
774            }
775    
776            if (g_keymapname[0] == 0)
777            {
778                    if (locale && xkeymap_from_locale(locale))
779                    {
780                            fprintf(stderr, "Autoselected keyboard map %s\n", g_keymapname);
781                    }
782                    else
783                    {
784                            STRNCPY(g_keymapname, "en-us", sizeof(g_keymapname));
785                    }
786          }          }
787            if (locale)
788                    xfree(locale);
789    
790    
791          if (prompt_password && read_password(password, sizeof(password)))          if (prompt_password && read_password(password, sizeof(password)))
792                  flags |= RDP_LOGON_AUTO;                  flags |= RDP_LOGON_AUTO;
# Line 425  main(int argc, char *argv[]) Line 805  main(int argc, char *argv[])
805          if (!ui_init())          if (!ui_init())
806                  return 1;                  return 1;
807    
808          /* rdpsnd_init(); */  #ifdef WITH_RDPSND
809          /* rdpdr_init(); */          if (g_rdpsnd)
810                    rdpsnd_init();
811    #endif
812    
813          if (!rdp_connect(server, flags, domain, password, shell, directory))          if (lspci_enabled)
814                  return 1;                  lspci_init();
815    
816            rdpdr_init();
817    
818            while (run_count < 2 && continue_connect)       /* add support for Session Directory; only reconnect once */
819            {
820                    if (run_count == 0)
821                    {
822                            if (!rdp_connect(server, flags, domain, password, shell, directory))
823                                    return 1;
824                    }
825                    else if (!rdp_reconnect
826                             (server, flags, domain, password, shell, directory, g_redirect_cookie))
827                            return 1;
828    
829          /* By setting encryption to False here, we have an encrypted login                  /* By setting encryption to False here, we have an encrypted login
830             packet but unencrypted transfer of other packets */                     packet but unencrypted transfer of other packets */
831          if (!packet_encryption)                  if (!packet_encryption)
832                  g_encryption = False;                          g_encryption = False;
833    
834    
835          DEBUG(("Connection successful.\n"));                  DEBUG(("Connection successful.\n"));
836          memset(password, 0, sizeof(password));                  memset(password, 0, sizeof(password));
837    
838          if (ui_create_window())                  if (run_count == 0)
839          {                          if (!ui_create_window())
840                  rdp_retval = rdp_main_loop();                                  continue_connect = False;
841                  ui_destroy_window();  
842                    if (continue_connect)
843                            rdp_main_loop(&deactivated, &ext_disc_reason);
844    
845                    DEBUG(("Disconnecting...\n"));
846                    rdp_disconnect();
847    
848                    if ((g_redirect == True) && (run_count == 0))   /* Support for Session Directory */
849                    {
850                            /* reset state of major globals */
851                            rdesktop_reset_state();
852    
853                            STRNCPY(domain, g_redirect_domain, sizeof(domain));
854                            STRNCPY(g_username, g_redirect_username, sizeof(g_username));
855                            STRNCPY(password, g_redirect_password, sizeof(password));
856                            STRNCPY(server, g_redirect_server, sizeof(server));
857                            flags |= RDP_LOGON_AUTO;
858    
859                            g_redirect = False;
860                    }
861                    else
862                    {
863                            continue_connect = False;
864                            ui_destroy_window();
865                            break;
866                    }
867    
868                    run_count++;
869          }          }
870    
871          DEBUG(("Disconnecting...\n"));          cache_save_state();
         rdp_disconnect();  
872          ui_deinit();          ui_deinit();
873    
874          if (True == rdp_retval)          if (ext_disc_reason >= 2)
875                    print_disconnect_reason(ext_disc_reason);
876    
877            if (deactivated)
878            {
879                    /* clean disconnect */
880                  return 0;                  return 0;
881            }
882          else          else
883                  return 2;          {
884                    if (ext_disc_reason == exDiscReasonAPIInitiatedDisconnect
885                        || ext_disc_reason == exDiscReasonAPIInitiatedLogoff)
886                    {
887                            /* not so clean disconnect, but nothing to worry about */
888                            return 0;
889                    }
890                    else
891                    {
892                            /* return error */
893                            return 2;
894                    }
895            }
896    
897  #endif  #endif
898    
# Line 555  xmalloc(int size) Line 994  xmalloc(int size)
994          return mem;          return mem;
995  }  }
996    
997    /* strdup */
998    char *
999    xstrdup(const char *s)
1000    {
1001            char *mem = strdup(s);
1002            if (mem == NULL)
1003            {
1004                    perror("strdup");
1005                    exit(1);
1006            }
1007            return mem;
1008    }
1009    
1010  /* realloc; exit if out of memory */  /* realloc; exit if out of memory */
1011  void *  void *
1012  xrealloc(void *oldmem, int size)  xrealloc(void *oldmem, int size)
1013  {  {
1014          void *mem = realloc(oldmem, size);          void *mem;
1015    
1016            if (size < 1)
1017                    size = 1;
1018            mem = realloc(oldmem, size);
1019          if (mem == NULL)          if (mem == NULL)
1020          {          {
1021                  error("xrealloc %d\n", size);                  error("xrealloc %d\n", size);
# Line 616  unimpl(char *format, ...) Line 1072  unimpl(char *format, ...)
1072    
1073  /* produce a hex dump */  /* produce a hex dump */
1074  void  void
1075  hexdump(unsigned char *p, int len)  hexdump(unsigned char *p, unsigned int len)
1076  {  {
1077          unsigned char *line = p;          unsigned char *line = p;
1078          int i, thisline, offset = 0;          int i, thisline, offset = 0;
# Line 643  hexdump(unsigned char *p, int len) Line 1099  hexdump(unsigned char *p, int len)
1099          }          }
1100  }  }
1101    
1102    /*
1103      input: src is the string we look in for needle.
1104             Needle may be escaped by a backslash, in
1105             that case we ignore that particular needle.
1106      return value: returns next src pointer, for
1107            succesive executions, like in a while loop
1108            if retval is 0, then there are no more args.
1109      pitfalls:
1110            src is modified. 0x00 chars are inserted to
1111            terminate strings.
1112            return val, points on the next val chr after ins
1113            0x00
1114    
1115            example usage:
1116            while( (pos = next_arg( optarg, ',')) ){
1117                    printf("%s\n",optarg);
1118                    optarg=pos;
1119            }
1120    
1121    */
1122    char *
1123    next_arg(char *src, char needle)
1124    {
1125            char *nextval;
1126            char *p;
1127            char *mvp = 0;
1128    
1129            /* EOS */
1130            if (*src == (char) 0x00)
1131                    return 0;
1132    
1133            p = src;
1134            /*  skip escaped needles */
1135            while ((nextval = strchr(p, needle)))
1136            {
1137                    mvp = nextval - 1;
1138                    /* found backslashed needle */
1139                    if (*mvp == '\\' && (mvp > src))
1140                    {
1141                            /* move string one to the left */
1142                            while (*(mvp + 1) != (char) 0x00)
1143                            {
1144                                    *mvp = *(mvp + 1);
1145                                    *mvp++;
1146                            }
1147                            *mvp = (char) 0x00;
1148                            p = nextval;
1149                    }
1150                    else
1151                    {
1152                            p = nextval + 1;
1153                            break;
1154                    }
1155    
1156            }
1157    
1158            /* more args available */
1159            if (nextval)
1160            {
1161                    *nextval = (char) 0x00;
1162                    return ++nextval;
1163            }
1164    
1165            /* no more args after this, jump to EOS */
1166            nextval = src + strlen(src);
1167            return nextval;
1168    }
1169    
1170    
1171    void
1172    toupper_str(char *p)
1173    {
1174            while (*p)
1175            {
1176                    if ((*p >= 'a') && (*p <= 'z'))
1177                            *p = toupper((int) *p);
1178                    p++;
1179            }
1180    }
1181    
1182    
1183    BOOL
1184    str_startswith(const char *s, const char *prefix)
1185    {
1186            return (strncmp(s, prefix, strlen(prefix)) == 0);
1187    }
1188    
1189    
1190    /* Split input into lines, and call linehandler for each
1191       line. Incomplete lines are saved in the rest variable, which should
1192       initially point to NULL. When linehandler returns False, stop and
1193       return False. Otherwise, return True.  */
1194    BOOL
1195    str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data)
1196    {
1197            char *buf, *p;
1198            char *oldrest;
1199            size_t inputlen;
1200            size_t buflen;
1201            size_t restlen = 0;
1202            BOOL ret = True;
1203    
1204            /* Copy data to buffer */
1205            inputlen = strlen(input);
1206            if (*rest)
1207                    restlen = strlen(*rest);
1208            buflen = restlen + inputlen + 1;
1209            buf = (char *) xmalloc(buflen);
1210            buf[0] = '\0';
1211            if (*rest)
1212                    STRNCPY(buf, *rest, buflen);
1213            strncat(buf, input, inputlen);
1214            p = buf;
1215    
1216            while (1)
1217            {
1218                    char *newline = strchr(p, '\n');
1219                    if (newline)
1220                    {
1221                            *newline = '\0';
1222                            if (!linehandler(p, data))
1223                            {
1224                                    p = newline + 1;
1225                                    ret = False;
1226                                    break;
1227                            }
1228                            p = newline + 1;
1229                    }
1230                    else
1231                    {
1232                            break;
1233    
1234                    }
1235            }
1236    
1237            /* Save in rest */
1238            oldrest = *rest;
1239            restlen = buf + buflen - p;
1240            *rest = (char *) xmalloc(restlen);
1241            STRNCPY((*rest), p, restlen);
1242            xfree(oldrest);
1243    
1244            xfree(buf);
1245            return ret;
1246    }
1247    
1248    /* Execute the program specified by argv. For each line in
1249       stdout/stderr output, call linehandler. Returns false on failure. */
1250    BOOL
1251    subprocess(char *const argv[], str_handle_lines_t linehandler, void *data)
1252    {
1253            pid_t child;
1254            int fd[2];
1255            int n = 1;
1256            char output[256];
1257            char *rest = NULL;
1258    
1259            if (pipe(fd) < 0)
1260            {
1261                    perror("pipe");
1262                    return False;
1263            }
1264    
1265            if ((child = fork()) < 0)
1266            {
1267                    perror("fork");
1268                    return False;
1269            }
1270    
1271            /* Child */
1272            if (child == 0)
1273            {
1274                    /* Close read end */
1275                    close(fd[0]);
1276    
1277                    /* Redirect stdout and stderr to pipe */
1278                    dup2(fd[1], 1);
1279                    dup2(fd[1], 2);
1280    
1281                    /* Execute */
1282                    execvp(argv[0], argv);
1283                    perror("Error executing child");
1284                    _exit(128);
1285            }
1286    
1287            /* Parent. Close write end. */
1288            close(fd[1]);
1289            while (n > 0)
1290            {
1291                    n = read(fd[0], output, 255);
1292                    output[n] = '\0';
1293                    str_handle_lines(output, &rest, linehandler, data);
1294            }
1295            xfree(rest);
1296    
1297            return True;
1298    }
1299    
1300    
1301    /* not all clibs got ltoa */
1302    #define LTOA_BUFSIZE (sizeof(long) * 8 + 1)
1303    
1304    char *
1305    l_to_a(long N, int base)
1306    {
1307            static char ret[LTOA_BUFSIZE];
1308    
1309            char *head = ret, buf[LTOA_BUFSIZE], *tail = buf + sizeof(buf);
1310    
1311            register int divrem;
1312    
1313            if (base < 36 || 2 > base)
1314                    base = 10;
1315    
1316            if (N < 0)
1317            {
1318                    *head++ = '-';
1319                    N = -N;
1320            }
1321    
1322            tail = buf + sizeof(buf);
1323            *--tail = 0;
1324    
1325            do
1326            {
1327                    divrem = N % base;
1328                    *--tail = (divrem <= 9) ? divrem + '0' : divrem + 'a' - 10;
1329                    N /= base;
1330            }
1331            while (N);
1332    
1333            strcpy(head, tail);
1334            return ret;
1335    }
1336    
1337    
1338  int  int
1339  load_licence(unsigned char **data)  load_licence(unsigned char **data)
# Line 655  load_licence(unsigned char **data) Line 1346  load_licence(unsigned char **data)
1346          if (home == NULL)          if (home == NULL)
1347                  return -1;                  return -1;
1348    
1349          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));          path = (char *) xmalloc(strlen(home) + strlen(g_hostname) + sizeof("/.rdesktop/licence."));
1350          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);          sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname);
1351    
1352          fd = open(path, O_RDONLY);          fd = open(path, O_RDONLY);
1353          if (fd == -1)          if (fd == -1)
# Line 682  save_licence(unsigned char *data, int le Line 1373  save_licence(unsigned char *data, int le
1373          if (home == NULL)          if (home == NULL)
1374                  return;                  return;
1375    
1376          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));          path = (char *) xmalloc(strlen(home) + strlen(g_hostname) + sizeof("/.rdesktop/licence."));
1377    
1378          sprintf(path, "%s/.rdesktop", home);          sprintf(path, "%s/.rdesktop", home);
1379          if ((mkdir(path, 0700) == -1) && errno != EEXIST)          if ((mkdir(path, 0700) == -1) && errno != EEXIST)
# Line 693  save_licence(unsigned char *data, int le Line 1384  save_licence(unsigned char *data, int le
1384    
1385          /* write licence to licence.hostname.new, then atomically rename to licence.hostname */          /* write licence to licence.hostname.new, then atomically rename to licence.hostname */
1386    
1387          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);          sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname);
1388          tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));          tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));
1389          strcpy(tmppath, path);          strcpy(tmppath, path);
1390          strcat(tmppath, ".new");          strcat(tmppath, ".new");
# Line 720  save_licence(unsigned char *data, int le Line 1411  save_licence(unsigned char *data, int le
1411          xfree(tmppath);          xfree(tmppath);
1412          xfree(path);          xfree(path);
1413  }  }
1414    
1415    /* Create the bitmap cache directory */
1416    BOOL
1417    rd_pstcache_mkdir(void)
1418    {
1419            char *home;
1420            char bmpcache_dir[256];
1421    
1422            home = getenv("HOME");
1423    
1424            if (home == NULL)
1425                    return False;
1426    
1427            sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop");
1428    
1429            if ((mkdir(bmpcache_dir, S_IRWXU) == -1) && errno != EEXIST)
1430            {
1431                    perror(bmpcache_dir);
1432                    return False;
1433            }
1434    
1435            sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop/cache");
1436    
1437            if ((mkdir(bmpcache_dir, S_IRWXU) == -1) && errno != EEXIST)
1438            {
1439                    perror(bmpcache_dir);
1440                    return False;
1441            }
1442    
1443            return True;
1444    }
1445    
1446    /* open a file in the .rdesktop directory */
1447    int
1448    rd_open_file(char *filename)
1449    {
1450            char *home;
1451            char fn[256];
1452            int fd;
1453    
1454            home = getenv("HOME");
1455            if (home == NULL)
1456                    return -1;
1457            sprintf(fn, "%s/.rdesktop/%s", home, filename);
1458            fd = open(fn, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
1459            if (fd == -1)
1460                    perror(fn);
1461            return fd;
1462    }
1463    
1464    /* close file */
1465    void
1466    rd_close_file(int fd)
1467    {
1468            close(fd);
1469    }
1470    
1471    /* read from file*/
1472    int
1473    rd_read_file(int fd, void *ptr, int len)
1474    {
1475            return read(fd, ptr, len);
1476    }
1477    
1478    /* write to file */
1479    int
1480    rd_write_file(int fd, void *ptr, int len)
1481    {
1482            return write(fd, ptr, len);
1483    }
1484    
1485    /* move file pointer */
1486    int
1487    rd_lseek_file(int fd, int offset)
1488    {
1489            return lseek(fd, offset, SEEK_SET);
1490    }
1491    
1492    /* do a write lock on a file */
1493    BOOL
1494    rd_lock_file(int fd, int start, int len)
1495    {
1496            struct flock lock;
1497    
1498            lock.l_type = F_WRLCK;
1499            lock.l_whence = SEEK_SET;
1500            lock.l_start = start;
1501            lock.l_len = len;
1502            if (fcntl(fd, F_SETLK, &lock) == -1)
1503                    return False;
1504            return True;
1505    }

Legend:
Removed from v.471  
changed lines
  Added in v.1058

  ViewVC Help
Powered by ViewVC 1.1.26