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

Diff of /sourceforge.net/branches/seamlessrdp-branch/rdesktop/rdesktop.c

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

revision 38 by matthewc, Thu Apr 4 12:04:33 2002 UTC revision 520 by matthewc, Tue Oct 28 05:07:00 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 <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;  
 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\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
100            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: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 106  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 119  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);                                  if (!strcmp(optarg, "workarea"))
293                                    {
294                                            g_width = g_height = 0;
295                                            break;
296                                    }
297    
298                                    g_width = strtol(optarg, &p, 10);
299                                    if (g_width <= 0)
300                                    {
301                                            error("invalid geometry\n");
302                                            return 1;
303                                    }
304    
305                                  if (*p == 'x')                                  if (*p == 'x')
306                                          height = strtol(p+1, NULL, 10);                                          g_height = strtol(p + 1, NULL, 10);
307    
308                                  if ((width == 0) || (height == 0))                                  if (g_height <= 0)
309                                  {                                  {
310                                          error("invalid geometry\n");                                          error("invalid geometry\n");
311                                          return 1;                                          return 1;
312                                  }                                  }
313    
314                                    if (*p == '%')
315                                            g_width = -g_width;
316    
317                                  break;                                  break;
318    
319                          case 'f':                          case 'f':
320                                  fullscreen = True;                                  g_fullscreen = True;
321                                  break;                                  break;
322    
323                          case 'b':                          case 'b':
324                                  orders = False;                                  g_orders = False;
325                                  break;                                  break;
326    
327                          case 'e':                          case 'e':
328                                  encryption = False;                                  g_encryption = False;
329                                    break;
330                            case 'E':
331                                    packet_encryption = False;
332                                  break;                                  break;
   
333                          case 'm':                          case 'm':
334                                  sendmotion = False;                                  g_sendmotion = False;
335                                  break;                                  break;
336    
337                          case 'l':                          case 'C':
338                                  licence = False;                                  g_owncolmap = True;
339                                    break;
340    
341                            case 'D':
342                                    g_hide_decorations = True;
343                                    break;
344    
345                            case 'K':
346                                    g_grab_keyboard = False;
347                                    break;
348    
349                            case 'S':
350                                    if (!strcmp(optarg, "standard"))
351                                    {
352                                            g_win_button_size = 18;
353                                            break;
354                                    }
355    
356                                    g_win_button_size = strtol(optarg, &p, 10);
357    
358                                    if (*p)
359                                    {
360                                            error("invalid button size\n");
361                                            return 1;
362                                    }
363    
364                                    break;
365    
366                            case 'T':
367                                    STRNCPY(g_title, optarg, sizeof(g_title));
368                                    break;
369    
370                            case 'a':
371                                    g_server_bpp = strtol(optarg, NULL, 10);
372                                    if (g_server_bpp != 8 && g_server_bpp != 16 && g_server_bpp != 15
373                                        && g_server_bpp != 24)
374                                    {
375                                            error("invalid server bpp\n");
376                                            return 1;
377                                    }
378                                    break;
379    
380                            case 'r':
381                                    if (!strcmp(optarg, "sound"))
382    #ifdef WITH_RDPSND
383                                            g_rdpsnd = True;
384    #else
385                                            warning("Not compiled with sound support");
386    #endif
387                                    break;
388    
389                            case '0':
390                                    g_console_session = True;
391                                    break;
392    
393                            case '4':
394                                    g_use_rdp5 = False;
395                                    break;
396    
397                            case '5':
398                                    g_use_rdp5 = True;
399                                  break;                                  break;
400    
401                          case 'h':                          case 'h':
# Line 164  main(int argc, char *argv[]) Line 412  main(int argc, char *argv[])
412                  return 1;                  return 1;
413          }          }
414    
415          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
416            parse_server_and_port(server);
417    
418          if (username[0] == 0)          if (!username_option)
419          {          {
420                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
421                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
# Line 175  main(int argc, char *argv[]) Line 424  main(int argc, char *argv[])
424                          return 1;                          return 1;
425                  }                  }
426    
427                  STRNCPY(username, pw->pw_name, sizeof(username));                  STRNCPY(g_username, pw->pw_name, sizeof(g_username));
428          }          }
429    
430          if (hostname[0] == 0)          if (hostname[0] == 0)
# Line 193  main(int argc, char *argv[]) Line 442  main(int argc, char *argv[])
442                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(hostname, fullhostname, sizeof(hostname));
443          }          }
444    
445          if (!strcmp(password, "-"))          if (prompt_password && read_password(password, sizeof(password)))
446          {                  flags |= RDP_LOGON_AUTO;
                 p = getpass("Password: ");  
                 if (p == NULL)  
                 {  
                         error("failed to read password\n");  
                         return 0;  
                 }  
                 STRNCPY(password, p, sizeof(password));  
         }  
447    
448          if ((width == 0) || (height == 0))          if (g_title[0] == 0)
449          {          {
450                  width = 800;                  strcpy(g_title, "rdesktop - ");
451                  height = 600;                  strncat(g_title, server, sizeof(g_title) - sizeof("rdesktop - "));
452          }          }
453    
454          strcpy(title, "rdesktop - ");  #ifdef RDP2VNC
455          strncat(title, server, sizeof(title) - sizeof("rdesktop - "));          rdp2vnc_connect(server, flags, domain, password, shell, directory);
456            return 0;
457    #else
458    
459          if (ui_create_window(title))          if (!ui_init())
460          {                  return 1;
461                  if (!rdp_connect(server, flags, domain, password, shell,  
462                                   directory))  #ifdef WITH_RDPSND
463                          return 1;          if (g_rdpsnd)
464                    rdpsnd_init();
465    #endif
466            /* rdpdr_init(); */
467    
468            if (!rdp_connect(server, flags, domain, password, shell, directory))
469                    return 1;
470    
471                  printf("Connection successful.\n");          /* By setting encryption to False here, we have an encrypted login
472                  rdp_main_loop();             packet but unencrypted transfer of other packets */
473                  printf("Disconnecting...\n");          if (!packet_encryption)
474                    g_encryption = False;
475    
476    
477            DEBUG(("Connection successful.\n"));
478            memset(password, 0, sizeof(password));
479    
480            if (ui_create_window())
481            {
482                    rdp_retval = rdp_main_loop();
483                  ui_destroy_window();                  ui_destroy_window();
                 rdp_disconnect();  
484          }          }
485    
486          return 0;          DEBUG(("Disconnecting...\n"));
487            rdp_disconnect();
488            ui_deinit();
489    
490            if (True == rdp_retval)
491                    return 0;
492            else
493                    return 2;
494    
495    #endif
496    
497  }  }
498    
499    #ifdef EGD_SOCKET
500    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
501    static BOOL
502    generate_random_egd(uint8 * buf)
503    {
504            struct sockaddr_un addr;
505            BOOL ret = False;
506            int fd;
507    
508            fd = socket(AF_UNIX, SOCK_STREAM, 0);
509            if (fd == -1)
510                    return False;
511    
512            addr.sun_family = AF_UNIX;
513            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
514            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
515                    goto err;
516    
517            /* PRNGD and EGD use a simple communications protocol */
518            buf[0] = 1;             /* Non-blocking (similar to /dev/urandom) */
519            buf[1] = 32;            /* Number of requested random bytes */
520            if (write(fd, buf, 2) != 2)
521                    goto err;
522    
523            if ((read(fd, buf, 1) != 1) || (buf[0] == 0))   /* Available? */
524                    goto err;
525    
526            if (read(fd, buf, 32) != 32)
527                    goto err;
528    
529            ret = True;
530    
531          err:
532            close(fd);
533            return ret;
534    }
535    #endif
536    
537  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
538  void  void
539  generate_random(uint8 *random)  generate_random(uint8 * random)
540  {  {
541          struct stat st;          struct stat st;
542          struct tms tmsbuf;          struct tms tmsbuf;
543          uint32 *r = (uint32 *) random;          MD5_CTX md5;
544          int fd;          uint32 *r;
545            int fd, n;
546    
547          /* If we have a kernel random device, use it. */          /* If we have a kernel random device, try that first */
548          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
549              || ((fd = open("/dev/random", O_RDONLY)) != -1))              || ((fd = open("/dev/random", O_RDONLY)) != -1))
550          {          {
551                  read(fd, random, 32);                  n = read(fd, random, 32);
552                  close(fd);                  close(fd);
553                  return;                  if (n == 32)
554                            return;
555          }          }
556    
557    #ifdef EGD_SOCKET
558            /* As a second preference use an EGD */
559            if (generate_random_egd(random))
560                    return;
561    #endif
562    
563          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
564            r = (uint32 *) random;
565          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
566          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
567          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 256  generate_random(uint8 *random) Line 570  generate_random(uint8 *random)
570          r[5] = st.st_atime;          r[5] = st.st_atime;
571          r[6] = st.st_mtime;          r[6] = st.st_mtime;
572          r[7] = st.st_ctime;          r[7] = st.st_ctime;
573    
574            /* Hash both halves with MD5 to obscure possible patterns */
575            MD5_Init(&md5);
576            MD5_Update(&md5, random, 16);
577            MD5_Final(random, &md5);
578            MD5_Update(&md5, random + 16, 16);
579            MD5_Final(random + 16, &md5);
580  }  }
581    
582  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 304  error(char *format, ...) Line 625  error(char *format, ...)
625          va_end(ap);          va_end(ap);
626  }  }
627    
628    /* report a warning */
629    void
630    warning(char *format, ...)
631    {
632            va_list ap;
633    
634            fprintf(stderr, "WARNING: ");
635    
636            va_start(ap, format);
637            vfprintf(stderr, format, ap);
638            va_end(ap);
639    }
640    
641  /* report an unimplemented protocol feature */  /* report an unimplemented protocol feature */
642  void  void
643  unimpl(char *format, ...)  unimpl(char *format, ...)
# Line 319  unimpl(char *format, ...) Line 653  unimpl(char *format, ...)
653    
654  /* produce a hex dump */  /* produce a hex dump */
655  void  void
656  hexdump(unsigned char *p, unsigned int len)  hexdump(unsigned char *p, int len)
657  {  {
658          unsigned char *line = p;          unsigned char *line = p;
659          unsigned int thisline, offset = 0;          int i, thisline, offset = 0;
         int i;  
660    
661          while (offset < len)          while (offset < len)
662          {          {
# Line 336  hexdump(unsigned char *p, unsigned int l Line 669  hexdump(unsigned char *p, unsigned int l
669                          printf("%02x ", line[i]);                          printf("%02x ", line[i]);
670    
671                  for (; i < 16; i++)                  for (; i < 16; i++)
672                                  printf("   ");                          printf("   ");
673    
674                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
675                          printf("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
676    
677                  printf("\n");                  printf("\n");
678                  offset += thisline;                  offset += thisline;
679                  line += thisline;                  line += thisline;
680          }          }
681  }  }
682    
683    
684    int
685    load_licence(unsigned char **data)
686    {
687            char *home, *path;
688            struct stat st;
689            int fd, length;
690    
691            home = getenv("HOME");
692            if (home == NULL)
693                    return -1;
694    
695            path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));
696            sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
697    
698            fd = open(path, O_RDONLY);
699            if (fd == -1)
700                    return -1;
701    
702            if (fstat(fd, &st))
703                    return -1;
704    
705            *data = (uint8 *) xmalloc(st.st_size);
706            length = read(fd, *data, st.st_size);
707            close(fd);
708            xfree(path);
709            return length;
710    }
711    
712    void
713    save_licence(unsigned char *data, int length)
714    {
715            char *home, *path, *tmppath;
716            int fd;
717    
718            home = getenv("HOME");
719            if (home == NULL)
720                    return;
721    
722            path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));
723    
724            sprintf(path, "%s/.rdesktop", home);
725            if ((mkdir(path, 0700) == -1) && errno != EEXIST)
726            {
727                    perror(path);
728                    return;
729            }
730    
731            /* write licence to licence.hostname.new, then atomically rename to licence.hostname */
732    
733            sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
734            tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));
735            strcpy(tmppath, path);
736            strcat(tmppath, ".new");
737    
738            fd = open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0600);
739            if (fd == -1)
740            {
741                    perror(tmppath);
742                    return;
743            }
744    
745            if (write(fd, data, length) != length)
746            {
747                    perror(tmppath);
748                    unlink(tmppath);
749            }
750            else if (rename(tmppath, path) == -1)
751            {
752                    perror(path);
753                    unlink(tmppath);
754            }
755    
756            close(fd);
757            xfree(tmppath);
758            xfree(path);
759    }

Legend:
Removed from v.38  
changed lines
  Added in v.520

  ViewVC Help
Powered by ViewVC 1.1.26