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

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

revision 58 by jsorg71, Sun Jul 14 00:34:21 2002 UTC revision 547 by astrand, Mon Nov 10 15:09:49 2003 UTC
# Line 1  Line 1 
1  /*  /* -*- 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-2001     Copyright (C) Matthew Chapman 1999-2003
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
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
 #include <stdlib.h>             /* malloc realloc free */  
21  #include <stdarg.h>             /* va_list va_start va_end */  #include <stdarg.h>             /* va_list va_start va_end */
22  #include <unistd.h>             /* read close getuid getgid getpid getppid gethostname */  #include <unistd.h>             /* read close getuid getgid getpid getppid gethostname */
23  #include <fcntl.h>              /* open */  #include <fcntl.h>              /* open */
24  #include <pwd.h>                /* getpwuid */  #include <pwd.h>                /* getpwuid */
25  #include <limits.h>             /* PATH_MAX */  #include <termios.h>            /* tcgetattr tcsetattr */
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 <errno.h>
30  #include "rdesktop.h"  #include "rdesktop.h"
31    
32  char username[16];  #ifdef EGD_SOCKET
33    #include <sys/socket.h>         /* socket connect */
34    #include <sys/un.h>             /* sockaddr_un */
35    #endif
36    
37    #ifdef WITH_OPENSSL
38    #include <openssl/md5.h>
39    #else
40    #include "crypto/md5.h"
41    #endif
42    
43    char g_title[64] = "";
44    char g_username[64];
45  char hostname[16];  char hostname[16];
46  char keymapname[16];  char keymapname[16];
47  int keylayout;  int keylayout = 0x409;          /* Defaults to US keyboard layout */
 int width;  
 int height;  
 int tcp_port_rdp = TCP_PORT_RDP;  
 BOOL bitmap_compression = True;  
 BOOL sendmotion = True;  
 BOOL orders = True;  
 BOOL licence = True;  
 BOOL encryption = True;  
 BOOL desktop_save = True;  
 BOOL fullscreen = False;  
48    
49    int g_width = 800;              /* width is special: If 0, the
50                                       geometry will be fetched from
51                                       _NET_WORKAREA. If negative,
52                                       absolute value specifies the
53                                       percent of the whole screen. */
54    int g_height = 600;
55    int tcp_port_rdp = TCP_PORT_RDP;
56    int g_server_bpp = 8;
57    int g_win_button_size = 0;      /* If zero, disable single app mode */
58    BOOL g_bitmap_compression = True;
59    BOOL g_sendmotion = True;
60    BOOL g_orders = True;
61    BOOL g_encryption = True;
62    BOOL packet_encryption = True;
63    BOOL g_desktop_save = True;
64    BOOL g_fullscreen = False;
65    BOOL g_grab_keyboard = True;
66    BOOL g_hide_decorations = False;
67    BOOL g_use_rdp5 = True;
68    BOOL g_console_session = False;
69    extern BOOL g_owncolmap;
70    
71    #ifdef WITH_RDPSND
72    BOOL g_rdpsnd = False;
73    #endif
74    
75    #ifdef RDP2VNC
76    extern int rfb_port;
77    extern int defer_time;
78    void
79    rdp2vnc_connect(char *server, uint32 flags, char *domain, char *password,
80                    char *shell, char *directory);
81    #endif
82  /* Display usage information */  /* Display usage information */
83  static void  static void
84  usage(char *program)  usage(char *program)
85  {  {
86          printf("Usage: %s [options] server\n", program);          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
87          printf("   -u: user name\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2003 Matt Chapman.\n");
88          printf("   -d: domain\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
89          printf("   -s: shell\n");  
90          printf("   -c: working directory\n");          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
91          printf("   -p: password (autologon)\n");  #ifdef RDP2VNC
92          printf("   -n: client hostname\n");          fprintf(stderr, "   -V: vnc port\n");
93          printf("   -k: keyboard layout\n");          fprintf(stderr, "   -Q: defer time (ms)\n");
94          printf("   -g: desktop geometry (WxH)\n");  #endif
95          printf("   -f: full-screen mode\n");          fprintf(stderr, "   -u: user name\n");
96          printf("   -b: force bitmap updates\n");          fprintf(stderr, "   -d: domain\n");
97          printf("   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -s: shell\n");
98          printf("   -m: do not send motion events\n");          fprintf(stderr, "   -c: working directory\n");
99          printf("   -l: do not request licence\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
100          printf("   -t: rdp tcp port\n\n");          fprintf(stderr, "   -n: client hostname\n");
101            fprintf(stderr, "   -k: keyboard layout on server (en-us, de, sv, etc.)\n");
102            fprintf(stderr, "   -g: desktop geometry (WxH)\n");
103            fprintf(stderr, "   -f: full-screen mode\n");
104            fprintf(stderr, "   -b: force bitmap updates\n");
105            fprintf(stderr, "   -e: disable encryption (French TS)\n");
106            fprintf(stderr, "   -E: disable encryption from client to server\n");
107            fprintf(stderr, "   -m: do not send motion events\n");
108            fprintf(stderr, "   -C: use private colour map\n");
109            fprintf(stderr, "   -D: hide window manager decorations\n");
110            fprintf(stderr, "   -K: keep window manager key bindings\n");
111            fprintf(stderr, "   -S: caption button size (single application mode)\n");
112            fprintf(stderr, "   -T: window title\n");
113            fprintf(stderr, "   -a: connection colour depth\n");
114            fprintf(stderr, "   -r: enable specified device redirection (currently: sound)\n");
115            fprintf(stderr, "   -0: attach to console\n");
116            fprintf(stderr, "   -4: use RDP version 4\n");
117            fprintf(stderr, "   -5: use RDP version 5 (default)\n");
118    }
119    
120    static BOOL
121    read_password(char *password, int size)
122    {
123            struct termios tios;
124            BOOL ret = False;
125            int istty = 0;
126            char *p;
127    
128            if (tcgetattr(STDIN_FILENO, &tios) == 0)
129            {
130                    fprintf(stderr, "Password: ");
131                    tios.c_lflag &= ~ECHO;
132                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
133                    istty = 1;
134            }
135    
136            if (fgets(password, size, stdin) != NULL)
137            {
138                    ret = True;
139    
140                    /* strip final newline */
141                    p = strchr(password, '\n');
142                    if (p != NULL)
143                            *p = 0;
144            }
145    
146            if (istty)
147            {
148                    tios.c_lflag |= ECHO;
149                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
150                    fprintf(stderr, "\n");
151            }
152    
153            return ret;
154    }
155    
156    static void
157    parse_server_and_port(char *server)
158    {
159            char *p;
160    #ifdef IPv6
161            int addr_colons;
162    #endif
163    
164    #ifdef IPv6
165            p = server;
166            addr_colons = 0;
167            while (*p)
168                    if (*p++ == ':')
169                            addr_colons++;
170            if (addr_colons >= 2)
171            {
172                    /* numeric IPv6 style address format - [1:2:3::4]:port */
173                    p = strchr(server, ']');
174                    if (*server == '[' && p != NULL)
175                    {
176                            if (*(p + 1) == ':' && *(p + 2) != '\0')
177                                    tcp_port_rdp = strtol(p + 2, NULL, 10);
178                            /* remove the port number and brackets from the address */
179                            *p = '\0';
180                            strncpy(server, server + 1, strlen(server));
181                    }
182            }
183            else
184            {
185                    /* dns name or IPv4 style address format - server.example.com:port or 1.2.3.4:port */
186                    p = strchr(server, ':');
187                    if (p != NULL)
188                    {
189                            tcp_port_rdp = strtol(p + 1, NULL, 10);
190                            *p = 0;
191                    }
192            }
193    #else /* no IPv6 support */
194            p = strchr(server, ':');
195            if (p != NULL)
196            {
197                    tcp_port_rdp = strtol(p + 1, NULL, 10);
198                    *p = 0;
199            }
200    #endif /* IPv6 */
201    
202  }  }
203    
204  /* Client program */  /* Client program */
205  int  int
206  main(int argc, char *argv[])  main(int argc, char *argv[])
207  {  {
208            char server[64];
209          char fullhostname[64];          char fullhostname[64];
210          char domain[16];          char domain[16];
211          char password[16];          char password[64];
212          char shell[32];          char shell[128];
213          char directory[32];          char directory[32];
214          char title[32];          BOOL prompt_password, rdp_retval = False;
215          struct passwd *pw;          struct passwd *pw;
         char *server, *p;  
216          uint32 flags;          uint32 flags;
217            char *p;
218          int c;          int c;
219            int username_option = 0;
         printf("rdesktop: A Remote Desktop Protocol client.\n");  
         printf("Version " VERSION ". Copyright (C) 1999-2001 Matt Chapman.\n");  
         printf("See http://www.rdesktop.org/ for more information.\n\n");  
220    
221          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
222            prompt_password = False;
223          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
224          strcpy(keymapname, "us");          strcpy(keymapname, "en-us");
225    
226          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:t:fbemlh?")) != -1)  #ifdef RDP2VNC
227    #define VNCOPT "V:Q:"
228    #else
229    #define VNCOPT
230    #endif
231    
232            while ((c = getopt(argc, argv, VNCOPT "u:d:s:c:p:n:k:g:fbeEmCDKS:T:a:r:045h?")) != -1)
233          {          {
234                  switch (c)                  switch (c)
235                  {                  {
236    #ifdef RDP2VNC
237                            case 'V':
238                                    rfb_port = strtol(optarg, NULL, 10);
239                                    if (rfb_port < 100)
240                                            rfb_port += 5900;
241                                    break;
242    
243                            case 'Q':
244                                    defer_time = strtol(optarg, NULL, 10);
245                                    if (defer_time < 0)
246                                            defer_time = 0;
247                                    break;
248    #endif
249    
250                          case 'u':                          case 'u':
251                                  STRNCPY(username, optarg, sizeof(username));                                  STRNCPY(g_username, optarg, sizeof(g_username));
252                                    username_option = 1;
253                                  break;                                  break;
254    
255                          case 'd':                          case 'd':
# Line 109  main(int argc, char *argv[]) Line 265  main(int argc, char *argv[])
265                                  break;                                  break;
266    
267                          case 'p':                          case 'p':
268                                    if ((optarg[0] == '-') && (optarg[1] == 0))
269                                    {
270                                            prompt_password = True;
271                                            break;
272                                    }
273    
274                                  STRNCPY(password, optarg, sizeof(password));                                  STRNCPY(password, optarg, sizeof(password));
275                                  flags |= RDP_LOGON_AUTO;                                  flags |= RDP_LOGON_AUTO;
276    
277                                    /* try to overwrite argument so it won't appear in ps */
278                                    p = optarg;
279                                    while (*p)
280                                            *(p++) = 'X';
281                                  break;                                  break;
282    
283                          case 'n':                          case 'n':
# Line 122  main(int argc, char *argv[]) Line 289  main(int argc, char *argv[])
289                                  break;                                  break;
290    
291                          case 'g':                          case 'g':
292                                  width = strtol(optarg, &p, 10);                                  g_fullscreen = False;
293                                    if (!strcmp(optarg, "workarea"))
294                                    {
295                                            g_width = g_height = 0;
296                                            break;
297                                    }
298    
299                                    g_width = strtol(optarg, &p, 10);
300                                    if (g_width <= 0)
301                                    {
302                                            error("invalid geometry\n");
303                                            return 1;
304                                    }
305    
306                                  if (*p == 'x')                                  if (*p == 'x')
307                                          height = strtol(p+1, NULL, 10);                                          g_height = strtol(p + 1, NULL, 10);
308    
309                                  if ((width == 0) || (height == 0))                                  if (g_height <= 0)
310                                  {                                  {
311                                          error("invalid geometry\n");                                          error("invalid geometry\n");
312                                          return 1;                                          return 1;
313                                  }                                  }
314    
315                                    if (*p == '%')
316                                            g_width = -g_width;
317    
318                                  break;                                  break;
319    
320                          case 'f':                          case 'f':
321                                  fullscreen = True;                                  g_fullscreen = True;
322                                  break;                                  break;
323    
324                          case 'b':                          case 'b':
325                                  orders = False;                                  g_orders = False;
326                                  break;                                  break;
327    
328                          case 'e':                          case 'e':
329                                  encryption = False;                                  g_encryption = False;
330                                    break;
331                            case 'E':
332                                    packet_encryption = False;
333                                  break;                                  break;
   
334                          case 'm':                          case 'm':
335                                  sendmotion = False;                                  g_sendmotion = False;
336                                    break;
337    
338                            case 'C':
339                                    g_owncolmap = True;
340                                    break;
341    
342                            case 'D':
343                                    g_hide_decorations = True;
344                                    break;
345    
346                            case 'K':
347                                    g_grab_keyboard = False;
348                                  break;                                  break;
349    
350                          case 'l':                          case 'S':
351                                  licence = False;                                  if (!strcmp(optarg, "standard"))
352                                    {
353                                            g_win_button_size = 18;
354                                            break;
355                                    }
356    
357                                    g_win_button_size = strtol(optarg, &p, 10);
358    
359                                    if (*p)
360                                    {
361                                            error("invalid button size\n");
362                                            return 1;
363                                    }
364    
365                                  break;                                  break;
366    
367                          case 't':                          case 'T':
368                                  tcp_port_rdp = strtol(optarg, NULL, 10);                                  STRNCPY(g_title, optarg, sizeof(g_title));
369                                    break;
370    
371                            case 'a':
372                                    g_server_bpp = strtol(optarg, NULL, 10);
373                                    if (g_server_bpp != 8 && g_server_bpp != 16 && g_server_bpp != 15
374                                        && g_server_bpp != 24)
375                                    {
376                                            error("invalid server bpp\n");
377                                            return 1;
378                                    }
379                                    break;
380    
381                            case 'r':
382                                    if (!strcmp(optarg, "sound"))
383    #ifdef WITH_RDPSND
384                                            g_rdpsnd = True;
385    #else
386                                            warning("Not compiled with sound support");
387    #endif
388                                    break;
389    
390                            case '0':
391                                    g_console_session = True;
392                                    break;
393    
394                            case '4':
395                                    g_use_rdp5 = False;
396                                    break;
397    
398                            case '5':
399                                    g_use_rdp5 = True;
400                                  break;                                  break;
401    
402                          case 'h':                          case 'h':
# Line 171  main(int argc, char *argv[]) Line 413  main(int argc, char *argv[])
413                  return 1;                  return 1;
414          }          }
415    
416          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
417            parse_server_and_port(server);
418    
419          if (username[0] == 0)          if (!username_option)
420          {          {
421                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
422                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
# Line 182  main(int argc, char *argv[]) Line 425  main(int argc, char *argv[])
425                          return 1;                          return 1;
426                  }                  }
427    
428                  STRNCPY(username, pw->pw_name, sizeof(username));                  STRNCPY(g_username, pw->pw_name, sizeof(g_username));
429          }          }
430    
431          if (hostname[0] == 0)          if (hostname[0] == 0)
# Line 200  main(int argc, char *argv[]) Line 443  main(int argc, char *argv[])
443                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(hostname, fullhostname, sizeof(hostname));
444          }          }
445    
446          if (!strcmp(password, "-"))          if (prompt_password && read_password(password, sizeof(password)))
447          {                  flags |= RDP_LOGON_AUTO;
                 p = getpass("Password: ");  
                 if (p == NULL)  
                 {  
                         error("failed to read password\n");  
                         return 0;  
                 }  
                 STRNCPY(password, p, sizeof(password));  
         }  
448    
449          if ((width == 0) || (height == 0))          if (g_title[0] == 0)
450          {          {
451                  width = 800;                  strcpy(g_title, "rdesktop - ");
452                  height = 600;                  strncat(g_title, server, sizeof(g_title) - sizeof("rdesktop - "));
453          }          }
454    
455          strcpy(title, "rdesktop - ");  #ifdef RDP2VNC
456          strncat(title, server, sizeof(title) - sizeof("rdesktop - "));          rdp2vnc_connect(server, flags, domain, password, shell, directory);
457            return 0;
458    #else
459    
460            if (!ui_init())
461                    return 1;
462    
463    #ifdef WITH_RDPSND
464            if (g_rdpsnd)
465                    rdpsnd_init();
466    #endif
467            /* rdpdr_init(); */
468    
469          if (!rdp_connect(server, flags, domain, password, shell, directory))          if (!rdp_connect(server, flags, domain, password, shell, directory))
470                  return 1;                  return 1;
471    
472          printf("Connection successful.\n");          /* By setting encryption to False here, we have an encrypted login
473               packet but unencrypted transfer of other packets */
474            if (!packet_encryption)
475                    g_encryption = False;
476    
477    
478            DEBUG(("Connection successful.\n"));
479            memset(password, 0, sizeof(password));
480    
481          if (ui_create_window(title))          if (ui_create_window())
482          {          {
483                  rdp_main_loop();                  rdp_retval = rdp_main_loop();
484                  ui_destroy_window();                  ui_destroy_window();
485          }          }
486    
487          printf("Disconnecting...\n");          DEBUG(("Disconnecting...\n"));
488          rdp_disconnect();          rdp_disconnect();
489          return 0;          ui_deinit();
490    
491            if (True == rdp_retval)
492                    return 0;
493            else
494                    return 2;
495    
496    #endif
497    
498  }  }
499    
500    #ifdef EGD_SOCKET
501    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
502    static BOOL
503    generate_random_egd(uint8 * buf)
504    {
505            struct sockaddr_un addr;
506            BOOL ret = False;
507            int fd;
508    
509            fd = socket(AF_UNIX, SOCK_STREAM, 0);
510            if (fd == -1)
511                    return False;
512    
513            addr.sun_family = AF_UNIX;
514            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
515            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
516                    goto err;
517    
518            /* PRNGD and EGD use a simple communications protocol */
519            buf[0] = 1;             /* Non-blocking (similar to /dev/urandom) */
520            buf[1] = 32;            /* Number of requested random bytes */
521            if (write(fd, buf, 2) != 2)
522                    goto err;
523    
524            if ((read(fd, buf, 1) != 1) || (buf[0] == 0))   /* Available? */
525                    goto err;
526    
527            if (read(fd, buf, 32) != 32)
528                    goto err;
529    
530            ret = True;
531    
532          err:
533            close(fd);
534            return ret;
535    }
536    #endif
537    
538  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
539  void  void
540  generate_random(uint8 *random)  generate_random(uint8 * random)
541  {  {
542          struct stat st;          struct stat st;
543          struct tms tmsbuf;          struct tms tmsbuf;
544          uint32 *r = (uint32 *) random;          MD5_CTX md5;
545          int fd;          uint32 *r;
546            int fd, n;
547    
548          /* If we have a kernel random device, use it. */          /* If we have a kernel random device, try that first */
549          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
550              || ((fd = open("/dev/random", O_RDONLY)) != -1))              || ((fd = open("/dev/random", O_RDONLY)) != -1))
551          {          {
552                  read(fd, random, 32);                  n = read(fd, random, 32);
553                  close(fd);                  close(fd);
554                  return;                  if (n == 32)
555                            return;
556          }          }
557    
558    #ifdef EGD_SOCKET
559            /* As a second preference use an EGD */
560            if (generate_random_egd(random))
561                    return;
562    #endif
563    
564          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
565            r = (uint32 *) random;
566          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
567          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
568          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 263  generate_random(uint8 *random) Line 571  generate_random(uint8 *random)
571          r[5] = st.st_atime;          r[5] = st.st_atime;
572          r[6] = st.st_mtime;          r[6] = st.st_mtime;
573          r[7] = st.st_ctime;          r[7] = st.st_ctime;
574    
575            /* Hash both halves with MD5 to obscure possible patterns */
576            MD5_Init(&md5);
577            MD5_Update(&md5, random, 16);
578            MD5_Final(random, &md5);
579            MD5_Update(&md5, random + 16, 16);
580            MD5_Final(random + 16, &md5);
581  }  }
582    
583  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 311  error(char *format, ...) Line 626  error(char *format, ...)
626          va_end(ap);          va_end(ap);
627  }  }
628    
629    /* report a warning */
630    void
631    warning(char *format, ...)
632    {
633            va_list ap;
634    
635            fprintf(stderr, "WARNING: ");
636    
637            va_start(ap, format);
638            vfprintf(stderr, format, ap);
639            va_end(ap);
640    }
641    
642  /* report an unimplemented protocol feature */  /* report an unimplemented protocol feature */
643  void  void
644  unimpl(char *format, ...)  unimpl(char *format, ...)
# Line 326  unimpl(char *format, ...) Line 654  unimpl(char *format, ...)
654    
655  /* produce a hex dump */  /* produce a hex dump */
656  void  void
657  hexdump(unsigned char *p, unsigned int len)  hexdump(unsigned char *p, int len)
658  {  {
659          unsigned char *line = p;          unsigned char *line = p;
660          unsigned int thisline, offset = 0;          int i, thisline, offset = 0;
         int i;  
661    
662          while (offset < len)          while (offset < len)
663          {          {
# Line 343  hexdump(unsigned char *p, unsigned int l Line 670  hexdump(unsigned char *p, unsigned int l
670                          printf("%02x ", line[i]);                          printf("%02x ", line[i]);
671    
672                  for (; i < 16; i++)                  for (; i < 16; i++)
673                                  printf("   ");                          printf("   ");
674    
675                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
676                          printf("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
677    
678                  printf("\n");                  printf("\n");
679                  offset += thisline;                  offset += thisline;
# Line 356  hexdump(unsigned char *p, unsigned int l Line 681  hexdump(unsigned char *p, unsigned int l
681          }          }
682  }  }
683    
684    
685  int  int
686  load_licence(unsigned char **data)  load_licence(unsigned char **data)
687  {  {
688          char path[PATH_MAX];          char *home, *path;
         char *home;  
689          struct stat st;          struct stat st;
690          int fd;          int fd, length;
691    
692          home = getenv("HOME");          home = getenv("HOME");
693          if (home == NULL)          if (home == NULL)
694                  return -1;                  return -1;
695    
696          STRNCPY(path, home, sizeof(path));          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));
697          strncat(path, "/.rdesktop/licence", sizeof(path)-strlen(path)-1);          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
698    
699          fd = open(path, O_RDONLY);          fd = open(path, O_RDONLY);
700          if (fd == -1)          if (fd == -1)
# Line 378  load_licence(unsigned char **data) Line 703  load_licence(unsigned char **data)
703          if (fstat(fd, &st))          if (fstat(fd, &st))
704                  return -1;                  return -1;
705    
706          *data = xmalloc(st.st_size);          *data = (uint8 *) xmalloc(st.st_size);
707          return read(fd, *data, st.st_size);          length = read(fd, *data, st.st_size);
708            close(fd);
709            xfree(path);
710            return length;
711  }  }
712    
713  void  void
714  save_licence(unsigned char *data, int length)  save_licence(unsigned char *data, int length)
715  {  {
716          char path[PATH_MAX];          char *home, *path, *tmppath;
         char *home;  
717          int fd;          int fd;
718    
719          home = getenv("HOME");          home = getenv("HOME");
720          if (home == NULL)          if (home == NULL)
721                  return;                  return;
722    
723          STRNCPY(path, home, sizeof(path));          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));
         strncat(path, "/.rdesktop", sizeof(path)-strlen(path)-1);  
         mkdir(path, 0700);  
724    
725          strncat(path, "/licence", sizeof(path)-strlen(path)-1);          sprintf(path, "%s/.rdesktop", home);
726            if ((mkdir(path, 0700) == -1) && errno != EEXIST)
727            {
728                    perror(path);
729                    return;
730            }
731    
732          fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0600);          /* write licence to licence.hostname.new, then atomically rename to licence.hostname */
733    
734            sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
735            tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));
736            strcpy(tmppath, path);
737            strcat(tmppath, ".new");
738    
739            fd = open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0600);
740          if (fd == -1)          if (fd == -1)
741          {          {
742                  perror("open");                  perror(tmppath);
743                  return;                  return;
744          }          }
745    
746          write(fd, data, length);          if (write(fd, data, length) != length)
747            {
748                    perror(tmppath);
749                    unlink(tmppath);
750            }
751            else if (rename(tmppath, path) == -1)
752            {
753                    perror(path);
754                    unlink(tmppath);
755            }
756    
757          close(fd);          close(fd);
758            xfree(tmppath);
759            xfree(path);
760  }  }
   

Legend:
Removed from v.58  
changed lines
  Added in v.547

  ViewVC Help
Powered by ViewVC 1.1.26