/[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 447 by jsorg71, Thu Aug 21 23:23:15 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 title[32] = "";
44    char g_username[16];
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 */
48  int width;  int g_width = 800;              /* If width or height are reset to zero, the geometry will
49  int height;                                     be fetched from _NET_WORKAREA */
50    int g_height = 600;
51  int tcp_port_rdp = TCP_PORT_RDP;  int tcp_port_rdp = TCP_PORT_RDP;
52  BOOL bitmap_compression = True;  int g_server_bpp = 8;
53  BOOL sendmotion = True;  int win_button_size = 0;        /* If zero, disable single app mode */
54  BOOL orders = True;  BOOL g_bitmap_compression = True;
55  BOOL licence = True;  BOOL g_sendmotion = True;
56  BOOL encryption = True;  BOOL g_orders = True;
57  BOOL desktop_save = True;  BOOL g_encryption = True;
58  BOOL fullscreen = False;  BOOL packet_encryption = True;
59    BOOL g_desktop_save = True;
60    BOOL g_fullscreen = False;
61    BOOL grab_keyboard = True;
62    BOOL hide_decorations = False;
63    BOOL g_use_rdp5 = False;
64    extern BOOL owncolmap;
65    
66    #ifdef RDP2VNC
67    extern int rfb_port;
68    extern int defer_time;
69    void
70    rdp2vnc_connect(char *server, uint32 flags, char *domain, char *password,
71                    char *shell, char *directory);
72    #endif
73  /* Display usage information */  /* Display usage information */
74  static void  static void
75  usage(char *program)  usage(char *program)
76  {  {
77          printf("Usage: %s [options] server\n", program);          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
78          printf("   -u: user name\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2003 Matt Chapman.\n");
79          printf("   -d: domain\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
80          printf("   -s: shell\n");  
81          printf("   -c: working directory\n");          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
82          printf("   -p: password (autologon)\n");  #ifdef RDP2VNC
83          printf("   -n: client hostname\n");          fprintf(stderr, "   -V: vnc port\n");
84          printf("   -k: keyboard layout\n");          fprintf(stderr, "   -E: defer time (ms)\n");
85          printf("   -g: desktop geometry (WxH)\n");  #endif
86          printf("   -f: full-screen mode\n");          fprintf(stderr, "   -u: user name\n");
87          printf("   -b: force bitmap updates\n");          fprintf(stderr, "   -d: domain\n");
88          printf("   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -s: shell\n");
89          printf("   -m: do not send motion events\n");          fprintf(stderr, "   -S: caption button size (single application mode)\n");
90          printf("   -l: do not request licence\n");          fprintf(stderr, "   -c: working directory\n");
91          printf("   -t: rdp tcp port\n\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
92            fprintf(stderr, "   -n: client hostname\n");
93            fprintf(stderr, "   -k: keyboard layout on terminal server (us,sv,gr,etc.)\n");
94            fprintf(stderr, "   -g: desktop geometry (WxH)\n");
95            fprintf(stderr, "   -f: full-screen mode\n");
96            fprintf(stderr, "   -b: force bitmap updates\n");
97            fprintf(stderr, "   -e: disable encryption (French TS)\n");
98            fprintf(stderr, "   -E: disable encryption of everything but the logon packet\n");
99            fprintf(stderr, "   -m: do not send motion events\n");
100            fprintf(stderr, "   -C: use private colour map\n");
101            fprintf(stderr, "   -K: keep window manager key bindings\n");
102            fprintf(stderr, "   -T: window title\n");
103            fprintf(stderr, "   -D: hide window manager decorations\n");
104            fprintf(stderr, "   -a: server bpp\n");
105            fprintf(stderr, "   -5: Use RDP5 (EXPERIMENTAL!)\n");
106    }
107    
108    static BOOL
109    read_password(char *password, int size)
110    {
111            struct termios tios;
112            BOOL ret = False;
113            int istty = 0;
114            char *p;
115    
116            if (tcgetattr(STDIN_FILENO, &tios) == 0)
117            {
118                    fprintf(stderr, "Password: ");
119                    tios.c_lflag &= ~ECHO;
120                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
121                    istty = 1;
122            }
123    
124            if (fgets(password, size, stdin) != NULL)
125            {
126                    ret = True;
127    
128                    /* strip final newline */
129                    p = strchr(password, '\n');
130                    if (p != NULL)
131                            *p = 0;
132            }
133    
134            if (istty)
135            {
136                    tios.c_lflag |= ECHO;
137                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
138                    fprintf(stderr, "\n");
139            }
140    
141            return ret;
142    }
143    
144    static void
145    parse_server_and_port(char *server)
146    {
147            char *p;
148    #ifdef IPv6
149            int addr_colons;
150    #endif
151    
152    #ifdef IPv6
153            p = server;
154            addr_colons = 0;
155            while (*p)
156                    if (*p++ == ':')
157                            addr_colons++;
158            if (addr_colons >= 2)
159            {
160                    /* numeric IPv6 style address format - [1:2:3::4]:port */
161                    p = strchr(server, ']');
162                    if (*server == '[' && p != NULL)
163                    {
164                            if (*(p + 1) == ':' && *(p + 2) != '\0')
165                                    tcp_port_rdp = strtol(p + 2, NULL, 10);
166                            /* remove the port number and brackets from the address */
167                            *p = '\0';
168                            strncpy(server, server + 1, strlen(server));
169                    }
170            }
171            else
172            {
173                    /* dns name or IPv4 style address format - server.example.com:port or 1.2.3.4:port */
174                    p = strchr(server, ':');
175                    if (p != NULL)
176                    {
177                            tcp_port_rdp = strtol(p + 1, NULL, 10);
178                            *p = 0;
179                    }
180            }
181    #else /* no IPv6 support */
182            p = strchr(server, ':');
183            if (p != NULL)
184            {
185                    tcp_port_rdp = strtol(p + 1, NULL, 10);
186                    *p = 0;
187            }
188    #endif /* IPv6 */
189    
190  }  }
191    
192  /* Client program */  /* Client program */
193  int  int
194  main(int argc, char *argv[])  main(int argc, char *argv[])
195  {  {
196            char server[64];
197          char fullhostname[64];          char fullhostname[64];
198          char domain[16];          char domain[16];
199          char password[16];          char password[16];
200          char shell[32];          char shell[128];
201          char directory[32];          char directory[32];
202          char title[32];          BOOL prompt_password, rdp_retval = False;
203          struct passwd *pw;          struct passwd *pw;
         char *server, *p;  
204          uint32 flags;          uint32 flags;
205            char *p;
206          int c;          int c;
207            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");  
208    
209          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
210            prompt_password = False;
211          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
212          strcpy(keymapname, "us");          strcpy(keymapname, "en-us");
213    
214    #ifdef RDP2VNC
215    #define VNCOPT "V:E:"
216    #else
217    #define VNCOPT
218    #endif
219    
220          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:t:fbemlh?")) != -1)          while ((c = getopt(argc, argv, VNCOPT "u:d:s:S:c:p:n:k:g:a:fbeEmCKT:Dh?54")) != -1)
221          {          {
222                  switch (c)                  switch (c)
223                  {                  {
224    #ifdef RDP2VNC
225                            case 'V':
226                                    rfb_port = strtol(optarg, NULL, 10);
227                                    if (rfb_port < 100)
228                                            rfb_port += 5900;
229                                    break;
230    
231                            case 'E':
232                                    defer_time = strtol(optarg, NULL, 10);
233                                    if (defer_time < 0)
234                                            defer_time = 0;
235                                    break;
236    #endif
237    
238                          case 'u':                          case 'u':
239                                  STRNCPY(username, optarg, sizeof(username));                                  STRNCPY(g_username, optarg, sizeof(g_username));
240                                    username_option = 1;
241                                  break;                                  break;
242    
243                          case 'd':                          case 'd':
# Line 104  main(int argc, char *argv[]) Line 248  main(int argc, char *argv[])
248                                  STRNCPY(shell, optarg, sizeof(shell));                                  STRNCPY(shell, optarg, sizeof(shell));
249                                  break;                                  break;
250    
251                            case 'S':
252                                    if (!strcmp(optarg, "standard"))
253                                    {
254                                            win_button_size = 18;
255                                            break;
256                                    }
257    
258                                    win_button_size = strtol(optarg, &p, 10);
259    
260                                    if (*p)
261                                    {
262                                            error("invalid button size\n");
263                                            return 1;
264                                    }
265    
266                                    break;
267    
268                          case 'c':                          case 'c':
269                                  STRNCPY(directory, optarg, sizeof(directory));                                  STRNCPY(directory, optarg, sizeof(directory));
270                                  break;                                  break;
271    
272                          case 'p':                          case 'p':
273                                    if ((optarg[0] == '-') && (optarg[1] == 0))
274                                    {
275                                            prompt_password = True;
276                                            break;
277                                    }
278    
279                                  STRNCPY(password, optarg, sizeof(password));                                  STRNCPY(password, optarg, sizeof(password));
280                                  flags |= RDP_LOGON_AUTO;                                  flags |= RDP_LOGON_AUTO;
281    
282                                    /* try to overwrite argument so it won't appear in ps */
283                                    p = optarg;
284                                    while (*p)
285                                            *(p++) = 'X';
286                                  break;                                  break;
287    
288                          case 'n':                          case 'n':
# Line 122  main(int argc, char *argv[]) Line 294  main(int argc, char *argv[])
294                                  break;                                  break;
295    
296                          case 'g':                          case 'g':
297                                  width = strtol(optarg, &p, 10);                                  if (!strcmp(optarg, "workarea"))
298                                    {
299                                            g_width = g_height = 0;
300                                            break;
301                                    }
302    
303                                    g_width = strtol(optarg, &p, 10);
304                                  if (*p == 'x')                                  if (*p == 'x')
305                                          height = strtol(p+1, NULL, 10);                                          g_height = strtol(p + 1, NULL, 10);
306    
307                                  if ((width == 0) || (height == 0))                                  if ((g_width == 0) || (g_height == 0))
308                                  {                                  {
309                                          error("invalid geometry\n");                                          error("invalid geometry\n");
310                                          return 1;                                          return 1;
# Line 134  main(int argc, char *argv[]) Line 312  main(int argc, char *argv[])
312                                  break;                                  break;
313    
314                          case 'f':                          case 'f':
315                                  fullscreen = True;                                  g_fullscreen = True;
316                                  break;                                  break;
317    
318                          case 'b':                          case 'b':
319                                  orders = False;                                  g_orders = False;
320                                  break;                                  break;
321    
322                          case 'e':                          case 'e':
323                                  encryption = False;                                  g_encryption = False;
324                                    break;
325                            case 'E':
326                                    packet_encryption = False;
327                                  break;                                  break;
   
328                          case 'm':                          case 'm':
329                                  sendmotion = False;                                  g_sendmotion = False;
330                                    break;
331    
332                            case 'C':
333                                    owncolmap = True;
334                                    break;
335    
336                            case 'K':
337                                    grab_keyboard = False;
338                                  break;                                  break;
339    
340                          case 'l':                          case 'T':
341                                  licence = False;                                  STRNCPY(title, optarg, sizeof(title));
342                                  break;                                  break;
343    
344                          case 't':                          case 'D':
345                                  tcp_port_rdp = strtol(optarg, NULL, 10);                                  hide_decorations = True;
346                                  break;                                  break;
347    
348                            case 'a':
349                                    g_server_bpp = strtol(optarg, NULL, 10);
350                                    if (g_server_bpp != 8 && g_server_bpp != 16 && g_server_bpp != 15
351                                        && g_server_bpp != 24)
352                                    {
353                                            error("invalid server bpp\n");
354                                            return 1;
355                                    }
356                                    break;
357    
358                            case '5':
359                                    g_use_rdp5 = True;
360                                    break;
361                          case 'h':                          case 'h':
362                          case '?':                          case '?':
363                          default:                          default:
# Line 171  main(int argc, char *argv[]) Line 372  main(int argc, char *argv[])
372                  return 1;                  return 1;
373          }          }
374    
375          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
376            parse_server_and_port(server);
377    
378          if (username[0] == 0)          if (!username_option)
379          {          {
380                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
381                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
# Line 182  main(int argc, char *argv[]) Line 384  main(int argc, char *argv[])
384                          return 1;                          return 1;
385                  }                  }
386    
387                  STRNCPY(username, pw->pw_name, sizeof(username));                  STRNCPY(g_username, pw->pw_name, sizeof(g_username));
388          }          }
389    
390          if (hostname[0] == 0)          if (hostname[0] == 0)
# Line 200  main(int argc, char *argv[]) Line 402  main(int argc, char *argv[])
402                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(hostname, fullhostname, sizeof(hostname));
403          }          }
404    
405          if (!strcmp(password, "-"))          if (prompt_password && read_password(password, sizeof(password)))
406          {                  flags |= RDP_LOGON_AUTO;
                 p = getpass("Password: ");  
                 if (p == NULL)  
                 {  
                         error("failed to read password\n");  
                         return 0;  
                 }  
                 STRNCPY(password, p, sizeof(password));  
         }  
407    
408          if ((width == 0) || (height == 0))          if (title[0] == 0)
409          {          {
410                  width = 800;                  strcpy(title, "rdesktop - ");
411                  height = 600;                  strncat(title, server, sizeof(title) - sizeof("rdesktop - "));
412          }          }
413    
414          strcpy(title, "rdesktop - ");  #ifdef RDP2VNC
415          strncat(title, server, sizeof(title) - sizeof("rdesktop - "));          rdp2vnc_connect(server, flags, domain, password, shell, directory);
416            return 0;
417    #else
418    
419            if (!ui_init())
420                    return 1;
421    
422            /* rdpsnd_init(); */
423            /* rdpdr_init(); */
424    
425          if (!rdp_connect(server, flags, domain, password, shell, directory))          if (!rdp_connect(server, flags, domain, password, shell, directory))
426                  return 1;                  return 1;
427    
428          printf("Connection successful.\n");          /* By setting encryption to False here, we have an encrypted login
429               packet but unencrypted transfer of other packets */
430            if (!packet_encryption)
431                    g_encryption = False;
432    
433    
434            DEBUG(("Connection successful.\n"));
435            memset(password, 0, sizeof(password));
436    
437          if (ui_create_window(title))          if (ui_create_window())
438          {          {
439                  rdp_main_loop();                  rdp_retval = rdp_main_loop();
440                  ui_destroy_window();                  ui_destroy_window();
441          }          }
442    
443          printf("Disconnecting...\n");          DEBUG(("Disconnecting...\n"));
444          rdp_disconnect();          rdp_disconnect();
445          return 0;          ui_deinit();
446    
447            if (True == rdp_retval)
448                    return 0;
449            else
450                    return 2;
451    
452    #endif
453    
454    }
455    
456    #ifdef EGD_SOCKET
457    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
458    static BOOL
459    generate_random_egd(uint8 * buf)
460    {
461            struct sockaddr_un addr;
462            BOOL ret = False;
463            int fd;
464    
465            fd = socket(AF_UNIX, SOCK_STREAM, 0);
466            if (fd == -1)
467                    return False;
468    
469            addr.sun_family = AF_UNIX;
470            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
471            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
472                    goto err;
473    
474            /* PRNGD and EGD use a simple communications protocol */
475            buf[0] = 1;             /* Non-blocking (similar to /dev/urandom) */
476            buf[1] = 32;            /* Number of requested random bytes */
477            if (write(fd, buf, 2) != 2)
478                    goto err;
479    
480            if ((read(fd, buf, 1) != 1) || (buf[0] == 0))   /* Available? */
481                    goto err;
482    
483            if (read(fd, buf, 32) != 32)
484                    goto err;
485    
486            ret = True;
487    
488          err:
489            close(fd);
490            return ret;
491  }  }
492    #endif
493    
494  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
495  void  void
496  generate_random(uint8 *random)  generate_random(uint8 * random)
497  {  {
498          struct stat st;          struct stat st;
499          struct tms tmsbuf;          struct tms tmsbuf;
500          uint32 *r = (uint32 *) random;          MD5_CTX md5;
501          int fd;          uint32 *r;
502            int fd, n;
503    
504          /* If we have a kernel random device, use it. */          /* If we have a kernel random device, try that first */
505          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
506              || ((fd = open("/dev/random", O_RDONLY)) != -1))              || ((fd = open("/dev/random", O_RDONLY)) != -1))
507          {          {
508                  read(fd, random, 32);                  n = read(fd, random, 32);
509                  close(fd);                  close(fd);
510                  return;                  if (n == 32)
511                            return;
512          }          }
513    
514    #ifdef EGD_SOCKET
515            /* As a second preference use an EGD */
516            if (generate_random_egd(random))
517                    return;
518    #endif
519    
520          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
521            r = (uint32 *) random;
522          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
523          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
524          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 263  generate_random(uint8 *random) Line 527  generate_random(uint8 *random)
527          r[5] = st.st_atime;          r[5] = st.st_atime;
528          r[6] = st.st_mtime;          r[6] = st.st_mtime;
529          r[7] = st.st_ctime;          r[7] = st.st_ctime;
530    
531            /* Hash both halves with MD5 to obscure possible patterns */
532            MD5_Init(&md5);
533            MD5_Update(&md5, random, 16);
534            MD5_Final(random, &md5);
535            MD5_Update(&md5, random + 16, 16);
536            MD5_Final(random + 16, &md5);
537  }  }
538    
539  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 311  error(char *format, ...) Line 582  error(char *format, ...)
582          va_end(ap);          va_end(ap);
583  }  }
584    
585    /* report a warning */
586    void
587    warning(char *format, ...)
588    {
589            va_list ap;
590    
591            fprintf(stderr, "WARNING: ");
592    
593            va_start(ap, format);
594            vfprintf(stderr, format, ap);
595            va_end(ap);
596    }
597    
598  /* report an unimplemented protocol feature */  /* report an unimplemented protocol feature */
599  void  void
600  unimpl(char *format, ...)  unimpl(char *format, ...)
# Line 326  unimpl(char *format, ...) Line 610  unimpl(char *format, ...)
610    
611  /* produce a hex dump */  /* produce a hex dump */
612  void  void
613  hexdump(unsigned char *p, unsigned int len)  hexdump(unsigned char *p, int len)
614  {  {
615          unsigned char *line = p;          unsigned char *line = p;
616          unsigned int thisline, offset = 0;          int i, thisline, offset = 0;
         int i;  
617    
618          while (offset < len)          while (offset < len)
619          {          {
# Line 343  hexdump(unsigned char *p, unsigned int l Line 626  hexdump(unsigned char *p, unsigned int l
626                          printf("%02x ", line[i]);                          printf("%02x ", line[i]);
627    
628                  for (; i < 16; i++)                  for (; i < 16; i++)
629                                  printf("   ");                          printf("   ");
630    
631                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
632                          printf("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
633    
634                  printf("\n");                  printf("\n");
635                  offset += thisline;                  offset += thisline;
# Line 356  hexdump(unsigned char *p, unsigned int l Line 637  hexdump(unsigned char *p, unsigned int l
637          }          }
638  }  }
639    
640    
641  int  int
642  load_licence(unsigned char **data)  load_licence(unsigned char **data)
643  {  {
644          char path[PATH_MAX];          char *home, *path;
         char *home;  
645          struct stat st;          struct stat st;
646          int fd;          int fd, length;
647    
648          home = getenv("HOME");          home = getenv("HOME");
649          if (home == NULL)          if (home == NULL)
650                  return -1;                  return -1;
651    
652          STRNCPY(path, home, sizeof(path));          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));
653          strncat(path, "/.rdesktop/licence", sizeof(path)-strlen(path)-1);          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
654    
655          fd = open(path, O_RDONLY);          fd = open(path, O_RDONLY);
656          if (fd == -1)          if (fd == -1)
# Line 378  load_licence(unsigned char **data) Line 659  load_licence(unsigned char **data)
659          if (fstat(fd, &st))          if (fstat(fd, &st))
660                  return -1;                  return -1;
661    
662          *data = xmalloc(st.st_size);          *data = (uint8 *) xmalloc(st.st_size);
663          return read(fd, *data, st.st_size);          length = read(fd, *data, st.st_size);
664            close(fd);
665            xfree(path);
666            return length;
667  }  }
668    
669  void  void
670  save_licence(unsigned char *data, int length)  save_licence(unsigned char *data, int length)
671  {  {
672          char path[PATH_MAX];          char *home, *path, *tmppath;
         char *home;  
673          int fd;          int fd;
674    
675          home = getenv("HOME");          home = getenv("HOME");
676          if (home == NULL)          if (home == NULL)
677                  return;                  return;
678    
679          STRNCPY(path, home, sizeof(path));          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));
680          strncat(path, "/.rdesktop", sizeof(path)-strlen(path)-1);  
681          mkdir(path, 0700);          sprintf(path, "%s/.rdesktop", home);
682            if ((mkdir(path, 0700) == -1) && errno != EEXIST)
683            {
684                    perror(path);
685                    return;
686            }
687    
688          strncat(path, "/licence", sizeof(path)-strlen(path)-1);          /* write licence to licence.hostname.new, then atomically rename to licence.hostname */
689    
690          fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0600);          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
691            tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));
692            strcpy(tmppath, path);
693            strcat(tmppath, ".new");
694    
695            fd = open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0600);
696          if (fd == -1)          if (fd == -1)
697          {          {
698                  perror("open");                  perror(tmppath);
699                  return;                  return;
700          }          }
701    
702          write(fd, data, length);          if (write(fd, data, length) != length)
703            {
704                    perror(tmppath);
705                    unlink(tmppath);
706            }
707            else if (rename(tmppath, path) == -1)
708            {
709                    perror(path);
710                    unlink(tmppath);
711            }
712    
713          close(fd);          close(fd);
714            xfree(tmppath);
715            xfree(path);
716  }  }
   

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

  ViewVC Help
Powered by ViewVC 1.1.26