/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/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/branches/seamlessrdp-branch/rdesktop/rdesktop.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 25 by matty, Sat Jan 6 03:47:04 2001 UTC revision 520 by matthewc, Tue Oct 28 05:07:00 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 motion = True;  
 BOOL orders = True;  
 BOOL licence = True;  
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 = False;
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, "   -c: working directory\n");
99            fprintf(stderr, "   -p: password (- to prompt)\n");
100            fprintf(stderr, "   -n: client hostname\n");
101            fprintf(stderr, "   -k: keyboard layout on server (en-us, de, sv, etc.)\n");
102            fprintf(stderr, "   -g: desktop geometry (WxH)\n");
103            fprintf(stderr, "   -f: full-screen mode\n");
104            fprintf(stderr, "   -b: force bitmap updates\n");
105            fprintf(stderr, "   -e: disable encryption (French TS)\n");
106            fprintf(stderr, "   -E: disable encryption from client to server\n");
107            fprintf(stderr, "   -m: do not send motion events\n");
108            fprintf(stderr, "   -C: use private colour map\n");
109            fprintf(stderr, "   -D: hide window manager decorations\n");
110            fprintf(stderr, "   -K: keep window manager key bindings\n");
111            fprintf(stderr, "   -S: caption button size (single application mode)\n");
112            fprintf(stderr, "   -T: window title\n");
113            fprintf(stderr, "   -a: connection colour depth\n");
114            fprintf(stderr, "   -r: enable specified device redirection (currently: sound)\n");
115            fprintf(stderr, "   -0: attach to console\n");
116            fprintf(stderr, "   -4: use RDP version 4\n");
117            fprintf(stderr, "   -5: use RDP version 5 (default)\n");
118    }
119    
120    static BOOL
121    read_password(char *password, int size)
122    {
123            struct termios tios;
124            BOOL ret = False;
125            int istty = 0;
126            char *p;
127    
128            if (tcgetattr(STDIN_FILENO, &tios) == 0)
129            {
130                    fprintf(stderr, "Password: ");
131                    tios.c_lflag &= ~ECHO;
132                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
133                    istty = 1;
134            }
135    
136            if (fgets(password, size, stdin) != NULL)
137            {
138                    ret = True;
139    
140                    /* strip final newline */
141                    p = strchr(password, '\n');
142                    if (p != NULL)
143                            *p = 0;
144            }
145    
146            if (istty)
147            {
148                    tios.c_lflag |= ECHO;
149                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
150                    fprintf(stderr, "\n");
151            }
152    
153            return ret;
154    }
155    
156    static void
157    parse_server_and_port(char *server)
158    {
159            char *p;
160    #ifdef IPv6
161            int addr_colons;
162    #endif
163    
164    #ifdef IPv6
165            p = server;
166            addr_colons = 0;
167            while (*p)
168                    if (*p++ == ':')
169                            addr_colons++;
170            if (addr_colons >= 2)
171            {
172                    /* numeric IPv6 style address format - [1:2:3::4]:port */
173                    p = strchr(server, ']');
174                    if (*server == '[' && p != NULL)
175                    {
176                            if (*(p + 1) == ':' && *(p + 2) != '\0')
177                                    tcp_port_rdp = strtol(p + 2, NULL, 10);
178                            /* remove the port number and brackets from the address */
179                            *p = '\0';
180                            strncpy(server, server + 1, strlen(server));
181                    }
182            }
183            else
184            {
185                    /* dns name or IPv4 style address format - server.example.com:port or 1.2.3.4:port */
186                    p = strchr(server, ':');
187                    if (p != NULL)
188                    {
189                            tcp_port_rdp = strtol(p + 1, NULL, 10);
190                            *p = 0;
191                    }
192            }
193    #else /* no IPv6 support */
194            p = strchr(server, ':');
195            if (p != NULL)
196            {
197                    tcp_port_rdp = strtol(p + 1, NULL, 10);
198                    *p = 0;
199            }
200    #endif /* IPv6 */
201    
202  }  }
203    
204  /* Client program */  /* Client program */
205  int  int
206  main(int argc, char *argv[])  main(int argc, char *argv[])
207  {  {
208          struct passwd *pw;          char server[64];
209          char *server;          char fullhostname[64];
         uint32 flags;  
210          char domain[16];          char domain[16];
211          char password[16];          char password[64];
212          char shell[32];          char shell[128];
213          char directory[32];          char directory[32];
214          char title[32];          BOOL prompt_password, rdp_retval = False;
215            struct passwd *pw;
216            uint32 flags;
217            char *p;
218          int c;          int c;
219            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");  
220    
221          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
222            prompt_password = False;
223          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
224            strcpy(keymapname, "en-us");
225    
226    #ifdef RDP2VNC
227    #define VNCOPT "V:Q:"
228    #else
229    #define VNCOPT
230    #endif
231    
232          while ((c = getopt(argc, argv, "u:d:s:c:p:n:w:h:k:bml?")) != -1)          while ((c = getopt(argc, argv, VNCOPT "u:d:s:c:p:n:k:g:fbeEmCDKS:T:a:r:045h?")) != -1)
233          {          {
234                  switch (c)                  switch (c)
235                  {                  {
236                          case 'u':  #ifdef RDP2VNC
237                                  strncpy(username, optarg, sizeof(username));                          case 'V':
238                                    rfb_port = strtol(optarg, NULL, 10);
239                                    if (rfb_port < 100)
240                                            rfb_port += 5900;
241                                  break;                                  break;
242    
243                          case 'd':                          case 'Q':
244                                  strncpy(domain, optarg, sizeof(domain));                                  defer_time = strtol(optarg, NULL, 10);
245                                    if (defer_time < 0)
246                                            defer_time = 0;
247                                  break;                                  break;
248    #endif
249    
250                          case 'p':                          case 'u':
251                                  flags |= RDP_LOGON_AUTO;                                  STRNCPY(g_username, optarg, sizeof(g_username));
252                                  strncpy(password, optarg, sizeof(password));                                  username_option = 1;
253                                    break;
254    
255                            case 'd':
256                                    STRNCPY(domain, optarg, sizeof(domain));
257                                  break;                                  break;
258    
259                          case 's':                          case 's':
260                                  strncpy(shell, optarg, sizeof(shell));                                  STRNCPY(shell, optarg, sizeof(shell));
261                                  break;                                  break;
262    
263                          case 'c':                          case 'c':
264                                  strncpy(directory, optarg, sizeof(directory));                                  STRNCPY(directory, optarg, sizeof(directory));
265                                    break;
266    
267                            case 'p':
268                                    if ((optarg[0] == '-') && (optarg[1] == 0))
269                                    {
270                                            prompt_password = True;
271                                            break;
272                                    }
273    
274                                    STRNCPY(password, optarg, sizeof(password));
275                                    flags |= RDP_LOGON_AUTO;
276    
277                                    /* try to overwrite argument so it won't appear in ps */
278                                    p = optarg;
279                                    while (*p)
280                                            *(p++) = 'X';
281                                  break;                                  break;
282    
283                          case 'n':                          case 'n':
284                                  strncpy(hostname, optarg, sizeof(hostname));                                  STRNCPY(hostname, optarg, sizeof(hostname));
285                                  break;                                  break;
286    
287                          case 'w':                          case 'k':
288                                  width = strtol(optarg, NULL, 10);                                  STRNCPY(keymapname, optarg, sizeof(keymapname));
289                                  break;                                  break;
290    
291                          case 'h':                          case 'g':
292                                  height = strtol(optarg, NULL, 10);                                  if (!strcmp(optarg, "workarea"))
293                                    {
294                                            g_width = g_height = 0;
295                                            break;
296                                    }
297    
298                                    g_width = strtol(optarg, &p, 10);
299                                    if (g_width <= 0)
300                                    {
301                                            error("invalid geometry\n");
302                                            return 1;
303                                    }
304    
305                                    if (*p == 'x')
306                                            g_height = strtol(p + 1, NULL, 10);
307    
308                                    if (g_height <= 0)
309                                    {
310                                            error("invalid geometry\n");
311                                            return 1;
312                                    }
313    
314                                    if (*p == '%')
315                                            g_width = -g_width;
316    
317                                  break;                                  break;
318    
319                          case 'k':                          case 'f':
320                                  keylayout = strtol(optarg, NULL, 16);                                  g_fullscreen = True;
321                                  break;                                  break;
322    
323                            case 'b':
324                                    g_orders = False;
325                                    break;
326    
327                            case 'e':
328                                    g_encryption = False;
329                                    break;
330                            case 'E':
331                                    packet_encryption = False;
332                                    break;
333                          case 'm':                          case 'm':
334                                  motion = False;                                  g_sendmotion = False;
335                                  break;                                  break;
336    
337                          case 'b':                          case 'C':
338                                  orders = False;                                  g_owncolmap = True;
339                                    break;
340    
341                            case 'D':
342                                    g_hide_decorations = True;
343                                    break;
344    
345                            case 'K':
346                                    g_grab_keyboard = False;
347                                    break;
348    
349                            case 'S':
350                                    if (!strcmp(optarg, "standard"))
351                                    {
352                                            g_win_button_size = 18;
353                                            break;
354                                    }
355    
356                                    g_win_button_size = strtol(optarg, &p, 10);
357    
358                                    if (*p)
359                                    {
360                                            error("invalid button size\n");
361                                            return 1;
362                                    }
363    
364                                    break;
365    
366                            case 'T':
367                                    STRNCPY(g_title, optarg, sizeof(g_title));
368                                    break;
369    
370                            case 'a':
371                                    g_server_bpp = strtol(optarg, NULL, 10);
372                                    if (g_server_bpp != 8 && g_server_bpp != 16 && g_server_bpp != 15
373                                        && g_server_bpp != 24)
374                                    {
375                                            error("invalid server bpp\n");
376                                            return 1;
377                                    }
378                                    break;
379    
380                            case 'r':
381                                    if (!strcmp(optarg, "sound"))
382    #ifdef WITH_RDPSND
383                                            g_rdpsnd = True;
384    #else
385                                            warning("Not compiled with sound support");
386    #endif
387                                  break;                                  break;
388    
389                          case 'l':                          case '0':
390                                  licence = False;                                  g_console_session = True;
391                                  break;                                  break;
392    
393                            case '4':
394                                    g_use_rdp5 = False;
395                                    break;
396    
397                            case '5':
398                                    g_use_rdp5 = True;
399                                    break;
400    
401                            case 'h':
402                          case '?':                          case '?':
403                          default:                          default:
404                                  usage(argv[0]);                                  usage(argv[0]);
# Line 143  main(int argc, char *argv[]) Line 412  main(int argc, char *argv[])
412                  return 1;                  return 1;
413          }          }
414    
415          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
416            parse_server_and_port(server);
417    
418          if (username[0] == 0)          if (!username_option)
419          {          {
420                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
421                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
422                  {                  {
423                          STATUS("Could not determine user name.\n");                          error("could not determine username, use -u\n");
424                          return 1;                          return 1;
425                  }                  }
426    
427                  strncpy(username, pw->pw_name, sizeof(username));                  STRNCPY(g_username, pw->pw_name, sizeof(g_username));
428          }          }
429    
430          if (hostname[0] == 0)          if (hostname[0] == 0)
431          {          {
432                  if (gethostname(hostname, sizeof(hostname)) == -1)                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
433                  {                  {
434                          STATUS("Could not determine host name.\n");                          error("could not determine local hostname, use -n\n");
435                          return 1;                          return 1;
436                  }                  }
437    
438                    p = strchr(fullhostname, '.');
439                    if (p != NULL)
440                            *p = 0;
441    
442                    STRNCPY(hostname, fullhostname, sizeof(hostname));
443            }
444    
445            if (prompt_password && read_password(password, sizeof(password)))
446                    flags |= RDP_LOGON_AUTO;
447    
448            if (g_title[0] == 0)
449            {
450                    strcpy(g_title, "rdesktop - ");
451                    strncat(g_title, server, sizeof(g_title) - sizeof("rdesktop - "));
452          }          }
453    
454    #ifdef RDP2VNC
455            rdp2vnc_connect(server, flags, domain, password, shell, directory);
456            return 0;
457    #else
458    
459            if (!ui_init())
460                    return 1;
461    
462    #ifdef WITH_RDPSND
463            if (g_rdpsnd)
464                    rdpsnd_init();
465    #endif
466            /* rdpdr_init(); */
467    
468          if (!rdp_connect(server, flags, domain, password, shell, directory))          if (!rdp_connect(server, flags, domain, password, shell, directory))
469                  return 1;                  return 1;
470    
471          STATUS("Connection successful.\n");          /* 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    
         strcpy(title, "rdesktop - ");  
         strncat(title, server, sizeof(title));  
476    
477          if (ui_create_window(title))          DEBUG(("Connection successful.\n"));
478            memset(password, 0, sizeof(password));
479    
480            if (ui_create_window())
481          {          {
482                  rdp_main_loop();                  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 210  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 219  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 232  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 245  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
630    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  void
643  hexdump(unsigned char *p, unsigned int len)  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.25  
changed lines
  Added in v.520

  ViewVC Help
Powered by ViewVC 1.1.26