/[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 552 by astrand, Mon Dec 8 12:01:25 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    BOOL g_numlock_sync = False;
70    extern BOOL g_owncolmap;
71    
72    #ifdef WITH_RDPSND
73    BOOL g_rdpsnd = False;
74    #endif
75    
76    #ifdef RDP2VNC
77    extern int rfb_port;
78    extern int defer_time;
79    void
80    rdp2vnc_connect(char *server, uint32 flags, char *domain, char *password,
81                    char *shell, char *directory);
82    #endif
83  /* Display usage information */  /* Display usage information */
84  static void  static void
85  usage(char *program)  usage(char *program)
86  {  {
87          STATUS("Usage: %s [options] server\n", program);          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
88          STATUS("   -u: user name\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2003 Matt Chapman.\n");
89          STATUS("   -d: domain\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
90          STATUS("   -s: shell\n");  
91          STATUS("   -c: working directory\n");          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
92          STATUS("   -p: password (autologon)\n");  #ifdef RDP2VNC
93          STATUS("   -n: client hostname\n");          fprintf(stderr, "   -V: vnc port\n");
94          STATUS("   -w: desktop width\n");          fprintf(stderr, "   -Q: defer time (ms)\n");
95          STATUS("   -h: desktop height\n");  #endif
96          STATUS("   -k: keyboard layout (hex)\n");          fprintf(stderr, "   -u: user name\n");
97          STATUS("   -b: force bitmap updates\n");          fprintf(stderr, "   -d: domain\n");
98          STATUS("   -m: do not send motion events\n");          fprintf(stderr, "   -s: shell\n");
99          STATUS("   -l: do not request licence\n\n");          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 server (en-us, de, sv, 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, "   -D: hide window manager decorations\n");
111            fprintf(stderr, "   -K: keep window manager key bindings\n");
112            fprintf(stderr, "   -S: caption button size (single application mode)\n");
113            fprintf(stderr, "   -T: window title\n");
114            fprintf(stderr, "   -N: enable numlock syncronization\n");
115            fprintf(stderr, "   -a: connection colour depth\n");
116            fprintf(stderr, "   -r: enable specified device redirection (currently: sound)\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:c:p:n:k:g:fbeEmCDKS:T:Na:r:045h?")) != -1)
235          {          {
236                  switch (c)                  switch (c)
237                  {                  {
238                          case 'u':  #ifdef RDP2VNC
239                                  strncpy(username, optarg, sizeof(username));                          case 'V':
240                                    rfb_port = strtol(optarg, NULL, 10);
241                                    if (rfb_port < 100)
242                                            rfb_port += 5900;
243                                  break;                                  break;
244    
245                          case 'd':                          case 'Q':
246                                  strncpy(domain, optarg, sizeof(domain));                                  defer_time = strtol(optarg, NULL, 10);
247                                    if (defer_time < 0)
248                                            defer_time = 0;
249                                  break;                                  break;
250    #endif
251    
252                          case 'p':                          case 'u':
253                                  flags |= RDP_LOGON_AUTO;                                  STRNCPY(g_username, optarg, sizeof(g_username));
254                                  strncpy(password, optarg, sizeof(password));                                  username_option = 1;
255                                    break;
256    
257                            case 'd':
258                                    STRNCPY(domain, optarg, sizeof(domain));
259                                  break;                                  break;
260    
261                          case 's':                          case 's':
262                                  strncpy(shell, optarg, sizeof(shell));                                  STRNCPY(shell, optarg, sizeof(shell));
263                                  break;                                  break;
264    
265                          case 'c':                          case 'c':
266                                  strncpy(directory, optarg, sizeof(directory));                                  STRNCPY(directory, optarg, sizeof(directory));
267                                    break;
268    
269                            case 'p':
270                                    if ((optarg[0] == '-') && (optarg[1] == 0))
271                                    {
272                                            prompt_password = True;
273                                            break;
274                                    }
275    
276                                    STRNCPY(password, optarg, sizeof(password));
277                                    flags |= RDP_LOGON_AUTO;
278    
279                                    /* try to overwrite argument so it won't appear in ps */
280                                    p = optarg;
281                                    while (*p)
282                                            *(p++) = 'X';
283                                  break;                                  break;
284    
285                          case 'n':                          case 'n':
286                                  strncpy(hostname, optarg, sizeof(hostname));                                  STRNCPY(hostname, optarg, sizeof(hostname));
287                                  break;                                  break;
288    
289                            case 'k':
290                                    STRNCPY(keymapname, optarg, sizeof(keymapname));
291                                    break;
292    
293                          case 'g':                          case 'g':
294                                    g_fullscreen = False;
295                                    if (!strcmp(optarg, "workarea"))
296                                    {
297                                            g_width = g_height = 0;
298                                            break;
299                                    }
300    
301                                    g_width = strtol(optarg, &p, 10);
302                                    if (g_width <= 0)
303                                  {                                  {
304                                          char *tgem = 0;                                          error("invalid geometry\n");
305                                          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);  
306                                  }                                  }
307    
308                                    if (*p == 'x')
309                                            g_height = strtol(p + 1, NULL, 10);
310    
311                                    if (g_height <= 0)
312                                    {
313                                            error("invalid geometry\n");
314                                            return 1;
315                                    }
316    
317                                    if (*p == '%')
318                                            g_width = -g_width;
319    
320                                  break;                                  break;
321    
322                          case 'k':                          case 'f':
323                                  keylayout = strtol(optarg, NULL, 16);                                  g_fullscreen = True;
324                                  /* keylayout = find_keyb_code(optarg); */                                  break;
325                                  if (keylayout == 0)  
326                                          return 0;                          case 'b':
327                                    g_orders = False;
328                                  break;                                  break;
329    
330                            case 'e':
331                                    g_encryption = False;
332                                    break;
333                            case 'E':
334                                    packet_encryption = False;
335                                    break;
336                          case 'm':                          case 'm':
337                                  sendmotion = False;                                  g_sendmotion = False;
338                                  break;                                  break;
339    
340                          case 'b':                          case 'C':
341                                  orders = False;                                  g_owncolmap = True;
342                                  break;                                  break;
343    
344                          case 'l':                          case 'D':
345                                  licence = False;                                  g_hide_decorations = True;
346                                  break;                                  break;
347    
348                          case 'e':                          case 'K':
349                                  use_encryption = False;                                  g_grab_keyboard = False;
350                                    break;
351    
352                            case 'S':
353                                    if (!strcmp(optarg, "standard"))
354                                    {
355                                            g_win_button_size = 18;
356                                            break;
357                                    }
358    
359                                    g_win_button_size = strtol(optarg, &p, 10);
360    
361                                    if (*p)
362                                    {
363                                            error("invalid button size\n");
364                                            return 1;
365                                    }
366    
367                                    break;
368    
369                            case 'T':
370                                    STRNCPY(g_title, optarg, sizeof(g_title));
371                                  break;                                  break;
372    
373                          case 'F':                          case 'N':
374                                  fullscreen = True;                                  g_numlock_sync = True;
375                                    break;
376    
377                            case 'a':
378                                    g_server_bpp = strtol(optarg, NULL, 10);
379                                    if (g_server_bpp != 8 && g_server_bpp != 16 && g_server_bpp != 15
380                                        && g_server_bpp != 24)
381                                    {
382                                            error("invalid server bpp\n");
383                                            return 1;
384                                    }
385                                    break;
386    
387                            case 'r':
388                                    if (!strcmp(optarg, "sound"))
389    #ifdef WITH_RDPSND
390                                            g_rdpsnd = True;
391    #else
392                                            warning("Not compiled with sound support");
393    #endif
394                                    break;
395    
396                            case '0':
397                                    g_console_session = True;
398                                    break;
399    
400                            case '4':
401                                    g_use_rdp5 = False;
402                                    break;
403    
404                            case '5':
405                                    g_use_rdp5 = True;
406                                  break;                                  break;
407    
408                          case 'h':                          case 'h':
# Line 165  main(int argc, char *argv[]) Line 419  main(int argc, char *argv[])
419                  return 1;                  return 1;
420          }          }
421    
422          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
423            parse_server_and_port(server);
424    
425          if (username[0] == 0)          if (!username_option)
426          {          {
427                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
428                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
429                  {                  {
430                          STATUS("Could not determine user name.\n");                          error("could not determine username, use -u\n");
431                          return 1;                          return 1;
432                  }                  }
433    
434                  strncpy(username, pw->pw_name, sizeof(username));                  STRNCPY(g_username, pw->pw_name, sizeof(g_username));
435          }          }
436    
437          if (hostname[0] == 0)          if (hostname[0] == 0)
438          {          {
439                  if (gethostname(hostname, sizeof(hostname)) == -1)                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
440                  {                  {
441                          STATUS("Could not determine host name.\n");                          error("could not determine local hostname, use -n\n");
442                          return 1;                          return 1;
443                  }                  }
444    
445                    p = strchr(fullhostname, '.');
446                    if (p != NULL)
447                            *p = 0;
448    
449                    STRNCPY(hostname, fullhostname, sizeof(hostname));
450          }          }
451    
452          strcpy(title, "rdesktop - ");          if (prompt_password && read_password(password, sizeof(password)))
453          strncat(title, server, sizeof(title));                  flags |= RDP_LOGON_AUTO;
454    
455          if (ui_create_window(title))          if (g_title[0] == 0)
456          {          {
457                  if (!rdp_connect(server, flags, domain, password, shell,                  strcpy(g_title, "rdesktop - ");
458                                   directory))                  strncat(g_title, server, sizeof(g_title) - sizeof("rdesktop - "));
459                          return 1;          }
460    
461    #ifdef RDP2VNC
462            rdp2vnc_connect(server, flags, domain, password, shell, directory);
463            return 0;
464    #else
465    
466            if (!ui_init())
467                    return 1;
468    
469    #ifdef WITH_RDPSND
470            if (g_rdpsnd)
471                    rdpsnd_init();
472    #endif
473            /* rdpdr_init(); */
474    
475            if (!rdp_connect(server, flags, domain, password, shell, directory))
476                    return 1;
477    
478            /* By setting encryption to False here, we have an encrypted login
479               packet but unencrypted transfer of other packets */
480            if (!packet_encryption)
481                    g_encryption = False;
482    
483    
484                  STATUS("Connection successful.\n");          DEBUG(("Connection successful.\n"));
485                  rdp_main_loop();          memset(password, 0, sizeof(password));
486    
487            if (ui_create_window())
488            {
489                    rdp_retval = rdp_main_loop();
490                  ui_destroy_window();                  ui_destroy_window();
491          }          }
492    
493            DEBUG(("Disconnecting...\n"));
494          rdp_disconnect();          rdp_disconnect();
495          return 0;          ui_deinit();
496    
497            if (True == rdp_retval)
498                    return 0;
499            else
500                    return 2;
501    
502    #endif
503    
504    }
505    
506    #ifdef EGD_SOCKET
507    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
508    static BOOL
509    generate_random_egd(uint8 * buf)
510    {
511            struct sockaddr_un addr;
512            BOOL ret = False;
513            int fd;
514    
515            fd = socket(AF_UNIX, SOCK_STREAM, 0);
516            if (fd == -1)
517                    return False;
518    
519            addr.sun_family = AF_UNIX;
520            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
521            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
522                    goto err;
523    
524            /* PRNGD and EGD use a simple communications protocol */
525            buf[0] = 1;             /* Non-blocking (similar to /dev/urandom) */
526            buf[1] = 32;            /* Number of requested random bytes */
527            if (write(fd, buf, 2) != 2)
528                    goto err;
529    
530            if ((read(fd, buf, 1) != 1) || (buf[0] == 0))   /* Available? */
531                    goto err;
532    
533            if (read(fd, buf, 32) != 32)
534                    goto err;
535    
536            ret = True;
537    
538          err:
539            close(fd);
540            return ret;
541  }  }
542    #endif
543    
544  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
545  void  void
546  generate_random(uint8 *random)  generate_random(uint8 * random)
547  {  {
548          struct stat st;          struct stat st;
549          struct tms tmsbuf;          struct tms tmsbuf;
550          uint32 *r = (uint32 *) random;          MD5_CTX md5;
551          int fd;          uint32 *r;
552            int fd, n;
553          /* If we have a kernel random device, use it. */  
554          if ((fd = open("/dev/urandom", O_RDONLY)) != -1)          /* If we have a kernel random device, try that first */
555            if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
556                || ((fd = open("/dev/random", O_RDONLY)) != -1))
557          {          {
558                  read(fd, random, 32);                  n = read(fd, random, 32);
559                  close(fd);                  close(fd);
560                  return;                  if (n == 32)
561                            return;
562          }          }
563    
564    #ifdef EGD_SOCKET
565            /* As a second preference use an EGD */
566            if (generate_random_egd(random))
567                    return;
568    #endif
569    
570          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
571            r = (uint32 *) random;
572          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
573          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
574          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 232  generate_random(uint8 *random) Line 577  generate_random(uint8 *random)
577          r[5] = st.st_atime;          r[5] = st.st_atime;
578          r[6] = st.st_mtime;          r[6] = st.st_mtime;
579          r[7] = st.st_ctime;          r[7] = st.st_ctime;
580    
581            /* Hash both halves with MD5 to obscure possible patterns */
582            MD5_Init(&md5);
583            MD5_Update(&md5, random, 16);
584            MD5_Final(random, &md5);
585            MD5_Update(&md5, random + 16, 16);
586            MD5_Final(random + 16, &md5);
587  }  }
588    
589  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 241  xmalloc(int size) Line 593  xmalloc(int size)
593          void *mem = malloc(size);          void *mem = malloc(size);
594          if (mem == NULL)          if (mem == NULL)
595          {          {
596                  ERROR("xmalloc %d\n", size);                  error("xmalloc %d\n", size);
597                  exit(1);                  exit(1);
598          }          }
599          return mem;          return mem;
# Line 254  xrealloc(void *oldmem, int size) Line 606  xrealloc(void *oldmem, int size)
606          void *mem = realloc(oldmem, size);          void *mem = realloc(oldmem, size);
607          if (mem == NULL)          if (mem == NULL)
608          {          {
609                  ERROR("xrealloc %d\n", size);                  error("xrealloc %d\n", size);
610                  exit(1);                  exit(1);
611          }          }
612          return mem;          return mem;
# Line 267  xfree(void *mem) Line 619  xfree(void *mem)
619          free(mem);          free(mem);
620  }  }
621    
622  /* Produce a hex dump */  /* report an error */
623    void
624    error(char *format, ...)
625    {
626            va_list ap;
627    
628            fprintf(stderr, "ERROR: ");
629    
630            va_start(ap, format);
631            vfprintf(stderr, format, ap);
632            va_end(ap);
633    }
634    
635    /* report a warning */
636    void
637    warning(char *format, ...)
638    {
639            va_list ap;
640    
641            fprintf(stderr, "WARNING: ");
642    
643            va_start(ap, format);
644            vfprintf(stderr, format, ap);
645            va_end(ap);
646    }
647    
648    /* report an unimplemented protocol feature */
649  void  void
650  hexdump(unsigned char *p, unsigned int len)  unimpl(char *format, ...)
651    {
652            va_list ap;
653    
654            fprintf(stderr, "NOT IMPLEMENTED: ");
655    
656            va_start(ap, format);
657            vfprintf(stderr, format, ap);
658            va_end(ap);
659    }
660    
661    /* produce a hex dump */
662    void
663    hexdump(unsigned char *p, int len)
664  {  {
665          unsigned char *line = p;          unsigned char *line = p;
666          unsigned int thisline, offset = 0;          int i, thisline, offset = 0;
         int i;  
667    
668          while (offset < len)          while (offset < len)
669          {          {
670                  STATUS("%04x ", offset);                  printf("%04x ", offset);
671                  thisline = len - offset;                  thisline = len - offset;
672                  if (thisline > 16)                  if (thisline > 16)
673                          thisline = 16;                          thisline = 16;
674    
675                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
676                          STATUS("%02x ", line[i]) for (; i < 16; i++)                          printf("%02x ", line[i]);
677                                  STATUS("   ");  
678                    for (; i < 16; i++)
679                            printf("   ");
680    
681                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
682                          STATUS("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
683    
684                  STATUS("\n");                  printf("\n");
685                  offset += thisline;                  offset += thisline;
686                  line += thisline;                  line += thisline;
687          }          }
688  }  }
689    
690    
691    int
692    load_licence(unsigned char **data)
693    {
694            char *home, *path;
695            struct stat st;
696            int fd, length;
697    
698            home = getenv("HOME");
699            if (home == NULL)
700                    return -1;
701    
702            path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));
703            sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
704    
705            fd = open(path, O_RDONLY);
706            if (fd == -1)
707                    return -1;
708    
709            if (fstat(fd, &st))
710                    return -1;
711    
712            *data = (uint8 *) xmalloc(st.st_size);
713            length = read(fd, *data, st.st_size);
714            close(fd);
715            xfree(path);
716            return length;
717    }
718    
719    void
720    save_licence(unsigned char *data, int length)
721    {
722            char *home, *path, *tmppath;
723            int fd;
724    
725            home = getenv("HOME");
726            if (home == NULL)
727                    return;
728    
729            path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));
730    
731            sprintf(path, "%s/.rdesktop", home);
732            if ((mkdir(path, 0700) == -1) && errno != EEXIST)
733            {
734                    perror(path);
735                    return;
736            }
737    
738            /* write licence to licence.hostname.new, then atomically rename to licence.hostname */
739    
740            sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
741            tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));
742            strcpy(tmppath, path);
743            strcat(tmppath, ".new");
744    
745            fd = open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0600);
746            if (fd == -1)
747            {
748                    perror(tmppath);
749                    return;
750            }
751    
752            if (write(fd, data, length) != length)
753            {
754                    perror(tmppath);
755                    unlink(tmppath);
756            }
757            else if (rename(tmppath, path) == -1)
758            {
759                    perror(path);
760                    unlink(tmppath);
761            }
762    
763            close(fd);
764            xfree(tmppath);
765            xfree(path);
766    }

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

  ViewVC Help
Powered by ViewVC 1.1.26