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

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

  ViewVC Help
Powered by ViewVC 1.1.26