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

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

  ViewVC Help
Powered by ViewVC 1.1.26