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

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

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

revision 435 by astrand, Wed Jul 9 09:18:20 2003 UTC revision 1309 by stargo, Wed Nov 1 20:52:01 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 title[32] = "";  char g_title[64] = "";
51  char 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 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 height = 600;  int g_keyboard_functionkeys = 0xc;      /* Defaults to US keyboard layout */
58  int tcp_port_rdp = TCP_PORT_RDP;  
59  int server_bpp = 8;  int g_width = 800;              /* width is special: If 0, the
60  int win_button_size = 0;        /* If zero, disable single app mode */                                     geometry will be fetched from
61  BOOL bitmap_compression = True;                                     _NET_WORKAREA. If negative,
62  BOOL sendmotion = True;                                     absolute value specifies the
63  BOOL orders = True;                                     percent of the whole screen. */
64  BOOL encryption = True;  int g_height = 600;
65    int g_xpos = 0;
66    int g_ypos = 0;
67    int g_pos = 0;                  /* 0 position unspecified,
68                                       1 specified,
69                                       2 xpos neg,
70                                       4 ypos neg  */
71    extern int g_tcp_port_rdp;
72    int g_server_depth = -1;
73    int g_win_button_size = 0;      /* If zero, disable single app mode */
74    BOOL g_bitmap_compression = True;
75    BOOL g_sendmotion = True;
76    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;
80  BOOL packet_encryption = True;  BOOL packet_encryption = True;
81  BOOL desktop_save = True;  BOOL g_desktop_save = True;     /* desktop save order */
82  BOOL fullscreen = False;  BOOL g_polygon_ellipse_orders = True;   /* polygon / ellipse orders */
83  BOOL grab_keyboard = True;  BOOL g_fullscreen = False;
84  BOOL hide_decorations = False;  BOOL g_grab_keyboard = True;
85  BOOL use_rdp5 = False;  BOOL g_hide_decorations = False;
86  extern BOOL owncolmap;  BOOL g_use_rdp5 = True;
87    BOOL g_rdpclip = True;
88    BOOL g_console_session = False;
89    BOOL g_numlock_sync = False;
90    BOOL lspci_enabled = False;
91    BOOL g_owncolmap = False;
92    BOOL g_ownbackstore = True;     /* We can't rely on external BackingStore */
93    BOOL g_seamless_rdp = False;
94    uint32 g_embed_wnd;
95    uint32 g_rdp5_performanceflags =
96            RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
97    /* Session Directory redirection */
98    BOOL g_redirect = False;
99    char g_redirect_server[64];
100    char g_redirect_domain[16];
101    char g_redirect_password[64];
102    char g_redirect_username[64];
103    char g_redirect_cookie[128];
104    uint32 g_redirect_flags = 0;
105    
106    #ifdef WITH_RDPSND
107    BOOL g_rdpsnd = False;
108    #endif
109    
110    #ifdef HAVE_ICONV
111    char g_codepage[16] = "";
112    #endif
113    
114    extern RDPDR_DEVICE g_rdpdr_device[];
115    extern uint32 g_num_devices;
116    extern char *g_rdpdr_clientname;
117    
118  #ifdef RDP2VNC  #ifdef RDP2VNC
119  extern int rfb_port;  extern int rfb_port;
# Line 75  static void Line 127  static void
127  usage(char *program)  usage(char *program)
128  {  {
129          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
130          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2003 Matt Chapman.\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2005 Matt Chapman.\n");
131          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
132    
133          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
134  #ifdef RDP2VNC  #ifdef RDP2VNC
135          fprintf(stderr, "   -V: vnc port\n");          fprintf(stderr, "   -V: vnc port\n");
136          fprintf(stderr, "   -E: defer time (ms)\n");          fprintf(stderr, "   -Q: defer time (ms)\n");
137  #endif  #endif
138          fprintf(stderr, "   -u: user name\n");          fprintf(stderr, "   -u: user name\n");
139          fprintf(stderr, "   -d: domain\n");          fprintf(stderr, "   -d: domain\n");
140          fprintf(stderr, "   -s: shell\n");          fprintf(stderr, "   -s: shell\n");
         fprintf(stderr, "   -S: caption button size (single application mode)\n");  
141          fprintf(stderr, "   -c: working directory\n");          fprintf(stderr, "   -c: working directory\n");
142          fprintf(stderr, "   -p: password (- to prompt)\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
143          fprintf(stderr, "   -n: client hostname\n");          fprintf(stderr, "   -n: client hostname\n");
144          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");
145          fprintf(stderr, "   -g: desktop geometry (WxH)\n");          fprintf(stderr, "   -g: desktop geometry (WxH)\n");
146          fprintf(stderr, "   -f: full-screen mode\n");          fprintf(stderr, "   -f: full-screen mode\n");
147          fprintf(stderr, "   -b: force bitmap updates\n");          fprintf(stderr, "   -b: force bitmap updates\n");
148    #ifdef HAVE_ICONV
149            fprintf(stderr, "   -L: local codepage\n");
150    #endif
151            fprintf(stderr, "   -A: enable SeamlessRDP mode\n");
152            fprintf(stderr, "   -B: use BackingStore of X-server (if available)\n");
153          fprintf(stderr, "   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -e: disable encryption (French TS)\n");
154          fprintf(stderr, "   -E: disable encryption of everything but the logon packet\n");          fprintf(stderr, "   -E: disable encryption from client to server\n");
155          fprintf(stderr, "   -m: do not send motion events\n");          fprintf(stderr, "   -m: do not send motion events\n");
156          fprintf(stderr, "   -C: use private colour map\n");          fprintf(stderr, "   -C: use private colour map\n");
157            fprintf(stderr, "   -D: hide window manager decorations\n");
158          fprintf(stderr, "   -K: keep window manager key bindings\n");          fprintf(stderr, "   -K: keep window manager key bindings\n");
159            fprintf(stderr, "   -S: caption button size (single application mode)\n");
160          fprintf(stderr, "   -T: window title\n");          fprintf(stderr, "   -T: window title\n");
161          fprintf(stderr, "   -D: hide window manager decorations\n");          fprintf(stderr, "   -N: enable numlock syncronization\n");
162          fprintf(stderr, "   -a: server bpp\n");          fprintf(stderr, "   -X: embed into another window with a given id.\n");
163          fprintf(stderr, "   -5: Use RDP5 (EXPERIMENTAL!)\n");          fprintf(stderr, "   -a: connection colour depth\n");
164            fprintf(stderr, "   -z: enable rdp compression\n");
165            fprintf(stderr, "   -x: RDP5 experience (m[odem 28.8], b[roadband], l[an] or hex nr.)\n");
166            fprintf(stderr, "   -P: use persistent bitmap caching\n");
167            fprintf(stderr, "   -r: enable specified device redirection (this flag can be repeated)\n");
168            fprintf(stderr,
169                    "         '-r comport:COM1=/dev/ttyS0': enable serial redirection of /dev/ttyS0 to COM1\n");
170            fprintf(stderr, "             or      COM1=/dev/ttyS0,COM2=/dev/ttyS1\n");
171            fprintf(stderr,
172                    "         '-r disk:floppy=/mnt/floppy': enable redirection of /mnt/floppy to 'floppy' share\n");
173            fprintf(stderr, "             or   'floppy=/mnt/floppy,cdrom=/mnt/cdrom'\n");
174            fprintf(stderr, "         '-r clientname=<client name>': Set the client name displayed\n");
175            fprintf(stderr, "             for redirected disks\n");
176            fprintf(stderr,
177                    "         '-r lptport:LPT1=/dev/lp0': enable parallel redirection of /dev/lp0 to LPT1\n");
178            fprintf(stderr, "             or      LPT1=/dev/lp0,LPT2=/dev/lp1\n");
179            fprintf(stderr, "         '-r printer:mydeskjet': enable printer redirection\n");
180            fprintf(stderr,
181                    "             or      mydeskjet=\"HP LaserJet IIIP\" to enter server driver as well\n");
182    #ifdef WITH_RDPSND
183            fprintf(stderr,
184                    "         '-r sound:[local[:driver[:device]]|off|remote]': enable sound redirection\n");
185            fprintf(stderr, "                     remote would leave sound on server\n");
186            fprintf(stderr, "                     available drivers for 'local':\n");
187            rdpsnd_show_help();
188    #endif
189            fprintf(stderr,
190                    "         '-r clipboard:[off|PRIMARYCLIPBOARD|CLIPBOARD]': enable clipboard\n");
191            fprintf(stderr, "                      redirection.\n");
192            fprintf(stderr,
193                    "                      'PRIMARYCLIPBOARD' looks at both PRIMARY and CLIPBOARD\n");
194            fprintf(stderr, "                      when sending data to server.\n");
195            fprintf(stderr, "                      'CLIPBOARD' looks at only CLIPBOARD.\n");
196    #ifdef WITH_SCARD
197            fprintf(stderr, "         '-r scard[:\"Scard Name\"=\"Alias Name[;Vendor Name]\"[,...]]\n");
198            fprintf(stderr, "          example: -r scard:\"eToken PRO 00 00\"=\"AKS ifdh 0\"\n");
199            fprintf(stderr,
200                    "                   \"eToken PRO 00 00\" -> Device in Linux/Unix enviroment\n");
201            fprintf(stderr,
202                    "                   \"AKS ifdh 0\"       -> Device shown in Windows enviroment \n");
203            fprintf(stderr, "          example: -r scard:\"eToken PRO 00 00\"=\"AKS ifdh 0;AKS\"\n");
204            fprintf(stderr,
205                    "                   \"eToken PRO 00 00\" -> Device in Linux/Unix enviroment\n");
206            fprintf(stderr,
207                    "                   \"AKS ifdh 0\"       -> Device shown in Windows enviroment \n");
208            fprintf(stderr,
209                    "                   \"AKS\"              -> Device vendor name                 \n");
210    #endif
211            fprintf(stderr, "   -0: attach to console\n");
212            fprintf(stderr, "   -4: use RDP version 4\n");
213            fprintf(stderr, "   -5: use RDP version 5 (default)\n");
214    }
215    
216    static void
217    print_disconnect_reason(uint16 reason)
218    {
219            char *text;
220    
221            switch (reason)
222            {
223                    case exDiscReasonNoInfo:
224                            text = "No information available";
225                            break;
226    
227                    case exDiscReasonAPIInitiatedDisconnect:
228                            text = "Server initiated disconnect";
229                            break;
230    
231                    case exDiscReasonAPIInitiatedLogoff:
232                            text = "Server initiated logoff";
233                            break;
234    
235                    case exDiscReasonServerIdleTimeout:
236                            text = "Server idle timeout reached";
237                            break;
238    
239                    case exDiscReasonServerLogonTimeout:
240                            text = "Server logon timeout reached";
241                            break;
242    
243                    case exDiscReasonReplacedByOtherConnection:
244                            text = "The session was replaced";
245                            break;
246    
247                    case exDiscReasonOutOfMemory:
248                            text = "The server is out of memory";
249                            break;
250    
251                    case exDiscReasonServerDeniedConnection:
252                            text = "The server denied the connection";
253                            break;
254    
255                    case exDiscReasonServerDeniedConnectionFips:
256                            text = "The server denied the connection for security reason";
257                            break;
258    
259                    case exDiscReasonLicenseInternal:
260                            text = "Internal licensing error";
261                            break;
262    
263                    case exDiscReasonLicenseNoLicenseServer:
264                            text = "No license server available";
265                            break;
266    
267                    case exDiscReasonLicenseNoLicense:
268                            text = "No valid license available";
269                            break;
270    
271                    case exDiscReasonLicenseErrClientMsg:
272                            text = "Invalid licensing message";
273                            break;
274    
275                    case exDiscReasonLicenseHwidDoesntMatchLicense:
276                            text = "Hardware id doesn't match software license";
277                            break;
278    
279                    case exDiscReasonLicenseErrClientLicense:
280                            text = "Client license error";
281                            break;
282    
283                    case exDiscReasonLicenseCantFinishProtocol:
284                            text = "Network error during licensing protocol";
285                            break;
286    
287                    case exDiscReasonLicenseClientEndedProtocol:
288                            text = "Licensing protocol was not completed";
289                            break;
290    
291                    case exDiscReasonLicenseErrClientEncryption:
292                            text = "Incorrect client license enryption";
293                            break;
294    
295                    case exDiscReasonLicenseCantUpgradeLicense:
296                            text = "Can't upgrade license";
297                            break;
298    
299                    case exDiscReasonLicenseNoRemoteConnections:
300                            text = "The server is not licensed to accept remote connections";
301                            break;
302    
303                    default:
304                            if (reason > 0x1000 && reason < 0x7fff)
305                            {
306                                    text = "Internal protocol error";
307                            }
308                            else
309                            {
310                                    text = "Unknown reason";
311                            }
312            }
313            fprintf(stderr, "disconnect: %s.\n", text);
314    }
315    
316    static void
317    rdesktop_reset_state(void)
318    {
319            rdp_reset_state();
320  }  }
321    
322  static BOOL  static BOOL
# Line 141  read_password(char *password, int size) Line 355  read_password(char *password, int size)
355          return ret;          return ret;
356  }  }
357    
358    static void
359    parse_server_and_port(char *server)
360    {
361            char *p;
362    #ifdef IPv6
363            int addr_colons;
364    #endif
365    
366    #ifdef IPv6
367            p = server;
368            addr_colons = 0;
369            while (*p)
370                    if (*p++ == ':')
371                            addr_colons++;
372            if (addr_colons >= 2)
373            {
374                    /* numeric IPv6 style address format - [1:2:3::4]:port */
375                    p = strchr(server, ']');
376                    if (*server == '[' && p != NULL)
377                    {
378                            if (*(p + 1) == ':' && *(p + 2) != '\0')
379                                    g_tcp_port_rdp = strtol(p + 2, NULL, 10);
380                            /* remove the port number and brackets from the address */
381                            *p = '\0';
382                            strncpy(server, server + 1, strlen(server));
383                    }
384            }
385            else
386            {
387                    /* dns name or IPv4 style address format - server.example.com:port or 1.2.3.4:port */
388                    p = strchr(server, ':');
389                    if (p != NULL)
390                    {
391                            g_tcp_port_rdp = strtol(p + 1, NULL, 10);
392                            *p = 0;
393                    }
394            }
395    #else /* no IPv6 support */
396            p = strchr(server, ':');
397            if (p != NULL)
398            {
399                    g_tcp_port_rdp = strtol(p + 1, NULL, 10);
400                    *p = 0;
401            }
402    #endif /* IPv6 */
403    
404    }
405    
406  /* Client program */  /* Client program */
407  int  int
408  main(int argc, char *argv[])  main(int argc, char *argv[])
# Line 148  main(int argc, char *argv[]) Line 410  main(int argc, char *argv[])
410          char server[64];          char server[64];
411          char fullhostname[64];          char fullhostname[64];
412          char domain[16];          char domain[16];
413          char password[16];          char password[64];
414          char shell[128];          char shell[256];
415          char directory[32];          char directory[256];
416          BOOL prompt_password, rdp_retval = False;          BOOL prompt_password, deactivated;
417          struct passwd *pw;          struct passwd *pw;
418          uint32 flags;          uint32 flags, ext_disc_reason = 0;
419          char *p;          char *p;
420          int c;          int c;
421            char *locale = NULL;
422          int username_option = 0;          int username_option = 0;
423            BOOL geometry_option = False;
424            int run_count = 0;      /* Session Directory support */
425            BOOL continue_connect = True;   /* Session Directory support */
426            char *rdpsnd_optarg = NULL;
427    
428    #ifdef HAVE_LOCALE_H
429            /* Set locale according to environment */
430            locale = setlocale(LC_ALL, "");
431            if (locale)
432            {
433                    locale = xstrdup(locale);
434            }
435    
436    #endif
437          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
438          prompt_password = False;          prompt_password = False;
439          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
440          strcpy(keymapname, "en-us");          g_embed_wnd = 0;
441    
442            g_num_devices = 0;
443    
444  #ifdef RDP2VNC  #ifdef RDP2VNC
445  #define VNCOPT "V:E:"  #define VNCOPT "V:Q:"
446  #else  #else
447  #define VNCOPT  #define VNCOPT
448  #endif  #endif
449    
450          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,
451                               VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1)
452          {          {
453                  switch (c)                  switch (c)
454                  {                  {
# Line 180  main(int argc, char *argv[]) Line 459  main(int argc, char *argv[])
459                                          rfb_port += 5900;                                          rfb_port += 5900;
460                                  break;                                  break;
461    
462                          case 'E':                          case 'Q':
463                                  defer_time = strtol(optarg, NULL, 10);                                  defer_time = strtol(optarg, NULL, 10);
464                                  if (defer_time < 0)                                  if (defer_time < 0)
465                                          defer_time = 0;                                          defer_time = 0;
466                                  break;                                  break;
467  #endif  #endif
468    
469                            case 'A':
470                                    g_seamless_rdp = True;
471                                    break;
472    
473                          case 'u':                          case 'u':
474                                  STRNCPY(username, optarg, sizeof(username));                                  STRNCPY(g_username, optarg, sizeof(g_username));
475                                  username_option = 1;                                  username_option = 1;
476                                  break;                                  break;
477    
478                            case 'L':
479    #ifdef HAVE_ICONV
480                                    STRNCPY(g_codepage, optarg, sizeof(g_codepage));
481    #else
482                                    error("iconv support not available\n");
483    #endif
484                                    break;
485    
486                          case 'd':                          case 'd':
487                                  STRNCPY(domain, optarg, sizeof(domain));                                  STRNCPY(domain, optarg, sizeof(domain));
488                                  break;                                  break;
# Line 200  main(int argc, char *argv[]) Line 491  main(int argc, char *argv[])
491                                  STRNCPY(shell, optarg, sizeof(shell));                                  STRNCPY(shell, optarg, sizeof(shell));
492                                  break;                                  break;
493    
                         case 'S':  
                                 if (!strcmp(optarg, "standard"))  
                                 {  
                                         win_button_size = 18;  
                                         break;  
                                 }  
   
                                 win_button_size = strtol(optarg, &p, 10);  
   
                                 if (*p)  
                                 {  
                                         error("invalid button size\n");  
                                         return 1;  
                                 }  
   
                                 break;  
   
494                          case 'c':                          case 'c':
495                                  STRNCPY(directory, optarg, sizeof(directory));                                  STRNCPY(directory, optarg, sizeof(directory));
496                                  break;                                  break;
# Line 238  main(int argc, char *argv[]) Line 512  main(int argc, char *argv[])
512                                  break;                                  break;
513    
514                          case 'n':                          case 'n':
515                                  STRNCPY(hostname, optarg, sizeof(hostname));                                  STRNCPY(g_hostname, optarg, sizeof(g_hostname));
516                                  break;                                  break;
517    
518                          case 'k':                          case 'k':
519                                  STRNCPY(keymapname, optarg, sizeof(keymapname));                                  STRNCPY(g_keymapname, optarg, sizeof(g_keymapname));
520                                  break;                                  break;
521    
522                          case 'g':                          case 'g':
523                                    geometry_option = True;
524                                    g_fullscreen = False;
525                                  if (!strcmp(optarg, "workarea"))                                  if (!strcmp(optarg, "workarea"))
526                                  {                                  {
527                                          width = height = 0;                                          g_width = g_height = 0;
528                                          break;                                          break;
529                                  }                                  }
530    
531                                  width = strtol(optarg, &p, 10);                                  g_width = strtol(optarg, &p, 10);
532                                    if (g_width <= 0)
533                                    {
534                                            error("invalid geometry\n");
535                                            return 1;
536                                    }
537    
538                                  if (*p == 'x')                                  if (*p == 'x')
539                                          height = strtol(p + 1, NULL, 10);                                          g_height = strtol(p + 1, &p, 10);
540    
541                                  if ((width == 0) || (height == 0))                                  if (g_height <= 0)
542                                  {                                  {
543                                          error("invalid geometry\n");                                          error("invalid geometry\n");
544                                          return 1;                                          return 1;
545                                  }                                  }
546    
547                                    if (*p == '%')
548                                    {
549                                            g_width = -g_width;
550                                            p++;
551                                    }
552    
553                                    if (*p == '+' || *p == '-')
554                                    {
555                                            g_pos |= (*p == '-') ? 2 : 1;
556                                            g_xpos = strtol(p, &p, 10);
557    
558                                    }
559                                    if (*p == '+' || *p == '-')
560                                    {
561                                            g_pos |= (*p == '-') ? 4 : 1;
562                                            g_ypos = strtol(p, NULL, 10);
563                                    }
564    
565                                  break;                                  break;
566    
567                          case 'f':                          case 'f':
568                                  fullscreen = True;                                  g_fullscreen = True;
569                                  break;                                  break;
570    
571                          case 'b':                          case 'b':
572                                  orders = False;                                  g_bitmap_cache = False;
573                                    break;
574    
575                            case 'B':
576                                    g_ownbackstore = False;
577                                  break;                                  break;
578    
579                          case 'e':                          case 'e':
580                                  encryption = False;                                  g_encryption = False;
581                                  break;                                  break;
582                          case 'E':                          case 'E':
583                                  packet_encryption = False;                                  packet_encryption = False;
584                                  break;                                  break;
585                          case 'm':                          case 'm':
586                                  sendmotion = False;                                  g_sendmotion = False;
587                                  break;                                  break;
588    
589                          case 'C':                          case 'C':
590                                  owncolmap = True;                                  g_owncolmap = True;
591                                    break;
592    
593                            case 'D':
594                                    g_hide_decorations = True;
595                                  break;                                  break;
596    
597                          case 'K':                          case 'K':
598                                  grab_keyboard = False;                                  g_grab_keyboard = False;
599                                    break;
600    
601                            case 'S':
602                                    if (!strcmp(optarg, "standard"))
603                                    {
604                                            g_win_button_size = 18;
605                                            break;
606                                    }
607    
608                                    g_win_button_size = strtol(optarg, &p, 10);
609    
610                                    if (*p)
611                                    {
612                                            error("invalid button size\n");
613                                            return 1;
614                                    }
615    
616                                  break;                                  break;
617    
618                          case 'T':                          case 'T':
619                                  STRNCPY(title, optarg, sizeof(title));                                  STRNCPY(g_title, optarg, sizeof(g_title));
620                                  break;                                  break;
621    
622                          case 'D':                          case 'N':
623                                  hide_decorations = True;                                  g_numlock_sync = True;
624                                    break;
625    
626                            case 'X':
627                                    g_embed_wnd = strtol(optarg, NULL, 0);
628                                  break;                                  break;
629    
630                          case 'a':                          case 'a':
631                                  server_bpp = strtol(optarg, NULL, 10);                                  g_server_depth = strtol(optarg, NULL, 10);
632                                  if (server_bpp != 8 && server_bpp != 16 && server_bpp != 15                                  if (g_server_depth != 8 &&
633                                      && server_bpp != 24)                                      g_server_depth != 16 &&
634                                        g_server_depth != 15 && g_server_depth != 24)
635                                  {                                  {
636                                          error("invalid server bpp\n");                                          error("Invalid server colour depth.\n");
637                                          return 1;                                          return 1;
638                                  }                                  }
639                                  break;                                  break;
640    
641                            case 'z':
642                                    DEBUG(("rdp compression enabled\n"));
643                                    flags |= (RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2);
644                                    break;
645    
646                            case 'x':
647                                    if (str_startswith(optarg, "m"))        /* modem */
648                                    {
649                                            g_rdp5_performanceflags =
650                                                    RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG |
651                                                    RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;
652                                    }
653                                    else if (str_startswith(optarg, "b"))   /* broadband */
654                                    {
655                                            g_rdp5_performanceflags = RDP5_NO_WALLPAPER;
656                                    }
657                                    else if (str_startswith(optarg, "l"))   /* lan */
658                                    {
659                                            g_rdp5_performanceflags = RDP5_DISABLE_NOTHING;
660                                    }
661                                    else
662                                    {
663                                            g_rdp5_performanceflags = strtol(optarg, NULL, 16);
664                                    }
665                                    break;
666    
667                            case 'P':
668                                    g_bitmap_cache_persist_enable = True;
669                                    break;
670    
671                            case 'r':
672    
673                                    if (str_startswith(optarg, "sound"))
674                                    {
675                                            optarg += 5;
676    
677                                            if (*optarg == ':')
678                                            {
679                                                    optarg++;
680                                                    while ((p = next_arg(optarg, ',')))
681                                                    {
682                                                            if (str_startswith(optarg, "remote"))
683                                                                    flags |= RDP_LOGON_LEAVE_AUDIO;
684    
685                                                            if (str_startswith(optarg, "local"))
686    #ifdef WITH_RDPSND
687                                                            {
688                                                                    rdpsnd_optarg =
689                                                                            next_arg(optarg, ':');
690                                                                    g_rdpsnd = True;
691                                                            }
692    
693    #else
694                                                                    warning("Not compiled with sound support\n");
695    #endif
696    
697                                                            if (str_startswith(optarg, "off"))
698    #ifdef WITH_RDPSND
699                                                                    g_rdpsnd = False;
700    #else
701                                                                    warning("Not compiled with sound support\n");
702    #endif
703    
704                                                            optarg = p;
705                                                    }
706                                            }
707                                            else
708                                            {
709    #ifdef WITH_RDPSND
710                                                    g_rdpsnd = True;
711    #else
712                                                    warning("Not compiled with sound support\n");
713    #endif
714                                            }
715                                    }
716                                    else if (str_startswith(optarg, "disk"))
717                                    {
718                                            /* -r disk:h:=/mnt/floppy */
719                                            disk_enum_devices(&g_num_devices, optarg + 4);
720                                    }
721                                    else if (str_startswith(optarg, "comport"))
722                                    {
723                                            serial_enum_devices(&g_num_devices, optarg + 7);
724                                    }
725                                    else if (str_startswith(optarg, "lspci"))
726                                    {
727                                            lspci_enabled = True;
728                                    }
729                                    else if (str_startswith(optarg, "lptport"))
730                                    {
731                                            parallel_enum_devices(&g_num_devices, optarg + 7);
732                                    }
733                                    else if (str_startswith(optarg, "printer"))
734                                    {
735                                            printer_enum_devices(&g_num_devices, optarg + 7);
736                                    }
737                                    else if (str_startswith(optarg, "clientname"))
738                                    {
739                                            g_rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1);
740                                            strcpy(g_rdpdr_clientname, optarg + 11);
741                                    }
742                                    else if (str_startswith(optarg, "clipboard"))
743                                    {
744                                            optarg += 9;
745    
746                                            if (*optarg == ':')
747                                            {
748                                                    optarg++;
749    
750                                                    if (str_startswith(optarg, "off"))
751                                                            g_rdpclip = False;
752                                                    else
753                                                            cliprdr_set_mode(optarg);
754                                            }
755                                            else
756                                                    g_rdpclip = True;
757                                    }
758                                    else if (strncmp("scard", optarg, 5) == 0)
759                                    {
760    #ifdef WITH_SCARD
761                                            scard_enum_devices(&g_num_devices, optarg + 5);
762    #else
763                                            warning("Not compiled with smartcard support\n");
764    #endif
765                                    }
766                                    else
767                                    {
768                                            warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound, clipboard, scard\n");
769                                    }
770                                    break;
771    
772                            case '0':
773                                    g_console_session = True;
774                                    break;
775    
776                            case '4':
777                                    g_use_rdp5 = False;
778                                    break;
779    
780                          case '5':                          case '5':
781                                  use_rdp5 = True;                                  g_use_rdp5 = True;
782                                  break;                                  break;
783    
784                          case 'h':                          case 'h':
785                          case '?':                          case '?':
786                          default:                          default:
# Line 318  main(int argc, char *argv[]) Line 789  main(int argc, char *argv[])
789                  }                  }
790          }          }
791    
792          if (argc - optind < 1)          if (argc - optind != 1)
793          {          {
794                  usage(argv[0]);                  usage(argv[0]);
795                  return 1;                  return 1;
796          }          }
797    
798          STRNCPY(server, argv[optind], sizeof(server));          STRNCPY(server, argv[optind], sizeof(server));
799          p = strchr(server, ':');          parse_server_and_port(server);
800          if (p != NULL)  
801            if (g_seamless_rdp)
802          {          {
803                  tcp_port_rdp = strtol(p + 1, NULL, 10);                  if (g_win_button_size)
804                  *p = 0;                  {
805                            error("You cannot use -S and -A at the same time\n");
806                            return 1;
807                    }
808                    g_rdp5_performanceflags &= ~RDP5_NO_FULLWINDOWDRAG;
809                    if (geometry_option)
810                    {
811                            error("You cannot use -g and -A at the same time\n");
812                            return 1;
813                    }
814                    if (g_fullscreen)
815                    {
816                            error("You cannot use -f and -A at the same time\n");
817                            return 1;
818                    }
819                    if (g_hide_decorations)
820                    {
821                            error("You cannot use -D and -A at the same time\n");
822                            return 1;
823                    }
824                    if (g_embed_wnd)
825                    {
826                            error("You cannot use -X and -A at the same time\n");
827                            return 1;
828                    }
829                    if (!g_use_rdp5)
830                    {
831                            error("You cannot use -4 and -A at the same time\n");
832                            return 1;
833                    }
834                    g_width = -100;
835                    g_grab_keyboard = False;
836          }          }
837    
838          if (!username_option)          if (!username_option)
# Line 341  main(int argc, char *argv[]) Line 844  main(int argc, char *argv[])
844                          return 1;                          return 1;
845                  }                  }
846    
847                  STRNCPY(username, pw->pw_name, sizeof(username));                  STRNCPY(g_username, pw->pw_name, sizeof(g_username));
848            }
849    
850    #ifdef HAVE_ICONV
851            if (g_codepage[0] == 0)
852            {
853                    if (setlocale(LC_CTYPE, ""))
854                    {
855                            STRNCPY(g_codepage, nl_langinfo(CODESET), sizeof(g_codepage));
856                    }
857                    else
858                    {
859                            STRNCPY(g_codepage, DEFAULT_CODEPAGE, sizeof(g_codepage));
860                    }
861          }          }
862    #endif
863    
864          if (hostname[0] == 0)          if (g_hostname[0] == 0)
865          {          {
866                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
867                  {                  {
# Line 356  main(int argc, char *argv[]) Line 873  main(int argc, char *argv[])
873                  if (p != NULL)                  if (p != NULL)
874                          *p = 0;                          *p = 0;
875    
876                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
877          }          }
878    
879            if (g_keymapname[0] == 0)
880            {
881                    if (locale && xkeymap_from_locale(locale))
882                    {
883                            fprintf(stderr, "Autoselected keyboard map %s\n", g_keymapname);
884                    }
885                    else
886                    {
887                            STRNCPY(g_keymapname, "en-us", sizeof(g_keymapname));
888                    }
889            }
890            if (locale)
891                    xfree(locale);
892    
893    
894          if (prompt_password && read_password(password, sizeof(password)))          if (prompt_password && read_password(password, sizeof(password)))
895                  flags |= RDP_LOGON_AUTO;                  flags |= RDP_LOGON_AUTO;
896    
897          if (title[0] == 0)          if (g_title[0] == 0)
898          {          {
899                  strcpy(title, "rdesktop - ");                  strcpy(g_title, "rdesktop - ");
900                  strncat(title, server, sizeof(title) - sizeof("rdesktop - "));                  strncat(g_title, server, sizeof(g_title) - sizeof("rdesktop - "));
901          }          }
902    
903  #ifdef RDP2VNC  #ifdef RDP2VNC
# Line 376  main(int argc, char *argv[]) Line 908  main(int argc, char *argv[])
908          if (!ui_init())          if (!ui_init())
909                  return 1;                  return 1;
910    
911          /* rdpsnd_init(); */  #ifdef WITH_RDPSND
912          /* rdpdr_init(); */          if (g_rdpsnd)
913            {
914                    if (!rdpsnd_init(rdpsnd_optarg))
915                    {
916                            warning("Initializing sound-support failed!\n");
917                    }
918            }
919    #endif
920    
921          if (!rdp_connect(server, flags, domain, password, shell, directory))          if (lspci_enabled)
922                  return 1;                  lspci_init();
923    
924          /* By setting encryption to False here, we have an encrypted login          rdpdr_init();
            packet but unencrypted transfer of other packets */  
         if (!packet_encryption)  
                 encryption = False;  
925    
926            while (run_count < 2 && continue_connect)       /* add support for Session Directory; only reconnect once */
927            {
928                    if (run_count == 0)
929                    {
930                            if (!rdp_connect(server, flags, domain, password, shell, directory))
931                                    return 1;
932                    }
933                    else if (!rdp_reconnect
934                             (server, flags, domain, password, shell, directory, g_redirect_cookie))
935                            return 1;
936    
937          DEBUG(("Connection successful.\n"));                  /* By setting encryption to False here, we have an encrypted login
938          memset(password, 0, sizeof(password));                     packet but unencrypted transfer of other packets */
939                    if (!packet_encryption)
940                            g_encryption = False;
941    
942          if (ui_create_window())  
943          {                  DEBUG(("Connection successful.\n"));
944                  rdp_retval = rdp_main_loop();                  memset(password, 0, sizeof(password));
945                  ui_destroy_window();  
946                    if (run_count == 0)
947                            if (!ui_create_window())
948                                    continue_connect = False;
949    
950                    if (continue_connect)
951                            rdp_main_loop(&deactivated, &ext_disc_reason);
952    
953                    DEBUG(("Disconnecting...\n"));
954                    rdp_disconnect();
955    
956                    if ((g_redirect == True) && (run_count == 0))   /* Support for Session Directory */
957                    {
958                            /* reset state of major globals */
959                            rdesktop_reset_state();
960    
961                            STRNCPY(domain, g_redirect_domain, sizeof(domain));
962                            STRNCPY(g_username, g_redirect_username, sizeof(g_username));
963                            STRNCPY(password, g_redirect_password, sizeof(password));
964                            STRNCPY(server, g_redirect_server, sizeof(server));
965                            flags |= RDP_LOGON_AUTO;
966    
967                            g_redirect = False;
968                    }
969                    else
970                    {
971                            continue_connect = False;
972                            ui_destroy_window();
973                            break;
974                    }
975    
976                    run_count++;
977          }          }
978    
979          DEBUG(("Disconnecting...\n"));          cache_save_state();
         rdp_disconnect();  
980          ui_deinit();          ui_deinit();
981    
982          if (True == rdp_retval)          if (ext_disc_reason >= 2)
983                    print_disconnect_reason(ext_disc_reason);
984    
985            if (deactivated)
986            {
987                    /* clean disconnect */
988                  return 0;                  return 0;
989            }
990          else          else
991                  return 2;          {
992                    if (ext_disc_reason == exDiscReasonAPIInitiatedDisconnect
993                        || ext_disc_reason == exDiscReasonAPIInitiatedLogoff)
994                    {
995                            /* not so clean disconnect, but nothing to worry about */
996                            return 0;
997                    }
998                    else
999                    {
1000                            /* return error */
1001                            return 2;
1002                    }
1003            }
1004    
1005  #endif  #endif
1006    
# Line 506  xmalloc(int size) Line 1102  xmalloc(int size)
1102          return mem;          return mem;
1103  }  }
1104    
1105    /* Exit on NULL pointer. Use to verify result from XGetImage etc */
1106    void
1107    exit_if_null(void *ptr)
1108    {
1109            if (ptr == NULL)
1110            {
1111                    error("unexpected null pointer. Out of memory?\n");
1112                    exit(1);
1113            }
1114    }
1115    
1116    /* strdup */
1117    char *
1118    xstrdup(const char *s)
1119    {
1120            char *mem = strdup(s);
1121            if (mem == NULL)
1122            {
1123                    perror("strdup");
1124                    exit(1);
1125            }
1126            return mem;
1127    }
1128    
1129  /* realloc; exit if out of memory */  /* realloc; exit if out of memory */
1130  void *  void *
1131  xrealloc(void *oldmem, int size)  xrealloc(void *oldmem, int size)
1132  {  {
1133          void *mem = realloc(oldmem, size);          void *mem;
1134    
1135            if (size < 1)
1136                    size = 1;
1137            mem = realloc(oldmem, size);
1138          if (mem == NULL)          if (mem == NULL)
1139          {          {
1140                  error("xrealloc %d\n", size);                  error("xrealloc %d\n", size);
# Line 567  unimpl(char *format, ...) Line 1191  unimpl(char *format, ...)
1191    
1192  /* produce a hex dump */  /* produce a hex dump */
1193  void  void
1194  hexdump(unsigned char *p, int len)  hexdump(unsigned char *p, unsigned int len)
1195  {  {
1196          unsigned char *line = p;          unsigned char *line = p;
1197          int i, thisline, offset = 0;          int i, thisline, offset = 0;
# Line 594  hexdump(unsigned char *p, int len) Line 1218  hexdump(unsigned char *p, int len)
1218          }          }
1219  }  }
1220    
1221    /*
1222      input: src is the string we look in for needle.
1223             Needle may be escaped by a backslash, in
1224             that case we ignore that particular needle.
1225      return value: returns next src pointer, for
1226            succesive executions, like in a while loop
1227            if retval is 0, then there are no more args.
1228      pitfalls:
1229            src is modified. 0x00 chars are inserted to
1230            terminate strings.
1231            return val, points on the next val chr after ins
1232            0x00
1233    
1234            example usage:
1235            while( (pos = next_arg( optarg, ',')) ){
1236                    printf("%s\n",optarg);
1237                    optarg=pos;
1238            }
1239    
1240    */
1241    char *
1242    next_arg(char *src, char needle)
1243    {
1244            char *nextval;
1245            char *p;
1246            char *mvp = 0;
1247    
1248            /* EOS */
1249            if (*src == (char) 0x00)
1250                    return 0;
1251    
1252            p = src;
1253            /*  skip escaped needles */
1254            while ((nextval = strchr(p, needle)))
1255            {
1256                    mvp = nextval - 1;
1257                    /* found backslashed needle */
1258                    if (*mvp == '\\' && (mvp > src))
1259                    {
1260                            /* move string one to the left */
1261                            while (*(mvp + 1) != (char) 0x00)
1262                            {
1263                                    *mvp = *(mvp + 1);
1264                                    mvp++;
1265                            }
1266                            *mvp = (char) 0x00;
1267                            p = nextval;
1268                    }
1269                    else
1270                    {
1271                            p = nextval + 1;
1272                            break;
1273                    }
1274    
1275            }
1276    
1277            /* more args available */
1278            if (nextval)
1279            {
1280                    *nextval = (char) 0x00;
1281                    return ++nextval;
1282            }
1283    
1284            /* no more args after this, jump to EOS */
1285            nextval = src + strlen(src);
1286            return nextval;
1287    }
1288    
1289    
1290    void
1291    toupper_str(char *p)
1292    {
1293            while (*p)
1294            {
1295                    if ((*p >= 'a') && (*p <= 'z'))
1296                            *p = toupper((int) *p);
1297                    p++;
1298            }
1299    }
1300    
1301    
1302    BOOL
1303    str_startswith(const char *s, const char *prefix)
1304    {
1305            return (strncmp(s, prefix, strlen(prefix)) == 0);
1306    }
1307    
1308    
1309    /* Split input into lines, and call linehandler for each
1310       line. Incomplete lines are saved in the rest variable, which should
1311       initially point to NULL. When linehandler returns False, stop and
1312       return False. Otherwise, return True.  */
1313    BOOL
1314    str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data)
1315    {
1316            char *buf, *p;
1317            char *oldrest;
1318            size_t inputlen;
1319            size_t buflen;
1320            size_t restlen = 0;
1321            BOOL ret = True;
1322    
1323            /* Copy data to buffer */
1324            inputlen = strlen(input);
1325            if (*rest)
1326                    restlen = strlen(*rest);
1327            buflen = restlen + inputlen + 1;
1328            buf = (char *) xmalloc(buflen);
1329            buf[0] = '\0';
1330            if (*rest)
1331                    STRNCPY(buf, *rest, buflen);
1332            strncat(buf, input, inputlen);
1333            p = buf;
1334    
1335            while (1)
1336            {
1337                    char *newline = strchr(p, '\n');
1338                    if (newline)
1339                    {
1340                            *newline = '\0';
1341                            if (!linehandler(p, data))
1342                            {
1343                                    p = newline + 1;
1344                                    ret = False;
1345                                    break;
1346                            }
1347                            p = newline + 1;
1348                    }
1349                    else
1350                    {
1351                            break;
1352    
1353                    }
1354            }
1355    
1356            /* Save in rest */
1357            oldrest = *rest;
1358            restlen = buf + buflen - p;
1359            *rest = (char *) xmalloc(restlen);
1360            STRNCPY((*rest), p, restlen);
1361            xfree(oldrest);
1362    
1363            xfree(buf);
1364            return ret;
1365    }
1366    
1367    /* Execute the program specified by argv. For each line in
1368       stdout/stderr output, call linehandler. Returns false on failure. */
1369    BOOL
1370    subprocess(char *const argv[], str_handle_lines_t linehandler, void *data)
1371    {
1372            pid_t child;
1373            int fd[2];
1374            int n = 1;
1375            char output[256];
1376            char *rest = NULL;
1377    
1378            if (pipe(fd) < 0)
1379            {
1380                    perror("pipe");
1381                    return False;
1382            }
1383    
1384            if ((child = fork()) < 0)
1385            {
1386                    perror("fork");
1387                    return False;
1388            }
1389    
1390            /* Child */
1391            if (child == 0)
1392            {
1393                    /* Close read end */
1394                    close(fd[0]);
1395    
1396                    /* Redirect stdout and stderr to pipe */
1397                    dup2(fd[1], 1);
1398                    dup2(fd[1], 2);
1399    
1400                    /* Execute */
1401                    execvp(argv[0], argv);
1402                    perror("Error executing child");
1403                    _exit(128);
1404            }
1405    
1406            /* Parent. Close write end. */
1407            close(fd[1]);
1408            while (n > 0)
1409            {
1410                    n = read(fd[0], output, 255);
1411                    output[n] = '\0';
1412                    str_handle_lines(output, &rest, linehandler, data);
1413            }
1414            xfree(rest);
1415    
1416            return True;
1417    }
1418    
1419    
1420    /* not all clibs got ltoa */
1421    #define LTOA_BUFSIZE (sizeof(long) * 8 + 1)
1422    
1423    char *
1424    l_to_a(long N, int base)
1425    {
1426            static char ret[LTOA_BUFSIZE];
1427    
1428            char *head = ret, buf[LTOA_BUFSIZE], *tail = buf + sizeof(buf);
1429    
1430            register int divrem;
1431    
1432            if (base < 36 || 2 > base)
1433                    base = 10;
1434    
1435            if (N < 0)
1436            {
1437                    *head++ = '-';
1438                    N = -N;
1439            }
1440    
1441            tail = buf + sizeof(buf);
1442            *--tail = 0;
1443    
1444            do
1445            {
1446                    divrem = N % base;
1447                    *--tail = (divrem <= 9) ? divrem + '0' : divrem + 'a' - 10;
1448                    N /= base;
1449            }
1450            while (N);
1451    
1452            strcpy(head, tail);
1453            return ret;
1454    }
1455    
1456    
1457  int  int
1458  load_licence(unsigned char **data)  load_licence(unsigned char **data)
# Line 606  load_licence(unsigned char **data) Line 1465  load_licence(unsigned char **data)
1465          if (home == NULL)          if (home == NULL)
1466                  return -1;                  return -1;
1467    
1468          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));          path = (char *) xmalloc(strlen(home) + strlen(g_hostname) + sizeof("/.rdesktop/licence."));
1469          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);          sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname);
1470    
1471          fd = open(path, O_RDONLY);          fd = open(path, O_RDONLY);
1472          if (fd == -1)          if (fd == -1)
# Line 633  save_licence(unsigned char *data, int le Line 1492  save_licence(unsigned char *data, int le
1492          if (home == NULL)          if (home == NULL)
1493                  return;                  return;
1494    
1495          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));          path = (char *) xmalloc(strlen(home) + strlen(g_hostname) + sizeof("/.rdesktop/licence."));
1496    
1497          sprintf(path, "%s/.rdesktop", home);          sprintf(path, "%s/.rdesktop", home);
1498          if ((mkdir(path, 0700) == -1) && errno != EEXIST)          if ((mkdir(path, 0700) == -1) && errno != EEXIST)
# Line 644  save_licence(unsigned char *data, int le Line 1503  save_licence(unsigned char *data, int le
1503    
1504          /* write licence to licence.hostname.new, then atomically rename to licence.hostname */          /* write licence to licence.hostname.new, then atomically rename to licence.hostname */
1505    
1506          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);          sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname);
1507          tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));          tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));
1508          strcpy(tmppath, path);          strcpy(tmppath, path);
1509          strcat(tmppath, ".new");          strcat(tmppath, ".new");
# Line 671  save_licence(unsigned char *data, int le Line 1530  save_licence(unsigned char *data, int le
1530          xfree(tmppath);          xfree(tmppath);
1531          xfree(path);          xfree(path);
1532  }  }
1533    
1534    /* Create the bitmap cache directory */
1535    BOOL
1536    rd_pstcache_mkdir(void)
1537    {
1538            char *home;
1539            char bmpcache_dir[256];
1540    
1541            home = getenv("HOME");
1542    
1543            if (home == NULL)
1544                    return False;
1545    
1546            sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop");
1547    
1548            if ((mkdir(bmpcache_dir, S_IRWXU) == -1) && errno != EEXIST)
1549            {
1550                    perror(bmpcache_dir);
1551                    return False;
1552            }
1553    
1554            sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop/cache");
1555    
1556            if ((mkdir(bmpcache_dir, S_IRWXU) == -1) && errno != EEXIST)
1557            {
1558                    perror(bmpcache_dir);
1559                    return False;
1560            }
1561    
1562            return True;
1563    }
1564    
1565    /* open a file in the .rdesktop directory */
1566    int
1567    rd_open_file(char *filename)
1568    {
1569            char *home;
1570            char fn[256];
1571            int fd;
1572    
1573            home = getenv("HOME");
1574            if (home == NULL)
1575                    return -1;
1576            sprintf(fn, "%s/.rdesktop/%s", home, filename);
1577            fd = open(fn, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
1578            if (fd == -1)
1579                    perror(fn);
1580            return fd;
1581    }
1582    
1583    /* close file */
1584    void
1585    rd_close_file(int fd)
1586    {
1587            close(fd);
1588    }
1589    
1590    /* read from file*/
1591    int
1592    rd_read_file(int fd, void *ptr, int len)
1593    {
1594            return read(fd, ptr, len);
1595    }
1596    
1597    /* write to file */
1598    int
1599    rd_write_file(int fd, void *ptr, int len)
1600    {
1601            return write(fd, ptr, len);
1602    }
1603    
1604    /* move file pointer */
1605    int
1606    rd_lseek_file(int fd, int offset)
1607    {
1608            return lseek(fd, offset, SEEK_SET);
1609    }
1610    
1611    /* do a write lock on a file */
1612    BOOL
1613    rd_lock_file(int fd, int start, int len)
1614    {
1615            struct flock lock;
1616    
1617            lock.l_type = F_WRLCK;
1618            lock.l_whence = SEEK_SET;
1619            lock.l_start = start;
1620            lock.l_len = len;
1621            if (fcntl(fd, F_SETLK, &lock) == -1)
1622                    return False;
1623            return True;
1624    }

Legend:
Removed from v.435  
changed lines
  Added in v.1309

  ViewVC Help
Powered by ViewVC 1.1.26