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

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

  ViewVC Help
Powered by ViewVC 1.1.26