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

Legend:
Removed from v.29  
changed lines
  Added in v.482

  ViewVC Help
Powered by ViewVC 1.1.26