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

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

  ViewVC Help
Powered by ViewVC 1.1.26