/[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 76 by astrand, Mon Jul 29 20:16:22 2002 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-2001     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    
 #include <stdlib.h>             /* malloc realloc free */  
21  #include <stdarg.h>             /* va_list va_start va_end */  #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 <limits.h>             /* PATH_MAX */  #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  char keymapname[16];  char keymapname[16];
47  int keylayout = 0x409;          /* Defaults to US keyboard layout */  int keylayout = 0x409;          /* Defaults to US keyboard layout */
 int width;  
 int height;  
 int tcp_port_rdp = TCP_PORT_RDP;  
 BOOL bitmap_compression = True;  
 BOOL sendmotion = True;  
 BOOL orders = True;  
 BOOL licence = True;  
 BOOL encryption = True;  
 BOOL desktop_save = True;  
 BOOL fullscreen = False;  
 BOOL grab_keyboard = 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 = 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          printf("Usage: %s [options] server\n", program);          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
87          printf("   -u: user name\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2003 Matt Chapman.\n");
88          printf("   -d: domain\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
89          printf("   -s: shell\n");  
90          printf("   -c: working directory\n");          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
91          printf("   -p: password (autologon)\n");  #ifdef RDP2VNC
92          printf("   -n: client hostname\n");          fprintf(stderr, "   -V: vnc port\n");
93          printf("   -k: keyboard layout on terminal server (us,sv,gr etc.)\n");          fprintf(stderr, "   -Q: defer time (ms)\n");
94          printf("   -g: desktop geometry (WxH)\n");  #endif
95          printf("   -f: full-screen mode\n");          fprintf(stderr, "   -u: user name\n");
96          printf("   -b: force bitmap updates\n");          fprintf(stderr, "   -d: domain\n");
97          printf("   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -s: shell\n");
98          printf("   -m: do not send motion events\n");          fprintf(stderr, "   -S: caption button size (single application mode)\n");
99          printf("   -l: do not request licence\n");          fprintf(stderr, "   -c: working directory\n");
100          printf("   -t: rdp tcp port\n\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
101          printf("   -K: keep window manager key bindings\n");          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            char server[64];
211          char fullhostname[64];          char fullhostname[64];
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;          struct passwd *pw;
         char *server, *p;  
218          uint32 flags;          uint32 flags;
219            char *p;
220          int c;          int c;
221            int username_option = 0;
         printf("rdesktop: A Remote Desktop Protocol client.\n");  
         printf("Version " VERSION  
                ". Copyright (C) 1999-2001 Matt Chapman.\n");  
         printf("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, "us");          strcpy(keymapname, "en-us");
227    
228          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:t:fbemlKh?")) != -1)  #ifdef RDP2VNC
229    #define VNCOPT "V:Q:"
230    #else
231    #define VNCOPT
232    #endif
233    
234            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':
# Line 107  main(int argc, char *argv[]) Line 262  main(int argc, char *argv[])
262                                  STRNCPY(shell, optarg, sizeof(shell));                                  STRNCPY(shell, optarg, sizeof(shell));
263                                  break;                                  break;
264    
265                            case 'S':
266                                    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;
281    
282                          case 'c':                          case 'c':
283                                  STRNCPY(directory, optarg, sizeof(directory));                                  STRNCPY(directory, optarg, sizeof(directory));
284                                  break;                                  break;
285    
286                          case 'p':                          case 'p':
287                                    if ((optarg[0] == '-') && (optarg[1] == 0))
288                                    {
289                                            prompt_password = True;
290                                            break;
291                                    }
292    
293                                  STRNCPY(password, optarg, sizeof(password));                                  STRNCPY(password, optarg, sizeof(password));
294                                  flags |= RDP_LOGON_AUTO;                                  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':
# Line 121  main(int argc, char *argv[]) Line 304  main(int argc, char *argv[])
304                                  break;                                  break;
305    
306                          case 'k':                          case 'k':
307                                  STRNCPY(keymapname, optarg,                                  STRNCPY(keymapname, optarg, sizeof(keymapname));
                                         sizeof(keymapname));  
308                                  break;                                  break;
309    
310                          case 'g':                          case 'g':
311                                  width = strtol(optarg, &p, 10);                                  if (!strcmp(optarg, "workarea"))
312                                    {
313                                            g_width = g_height = 0;
314                                            break;
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')                                  if (*p == 'x')
325                                          height = strtol(p + 1, NULL, 10);                                          g_height = strtol(p + 1, NULL, 10);
326    
327                                  if ((width == 0) || (height == 0))                                  if (g_height <= 0)
328                                  {                                  {
329                                          error("invalid geometry\n");                                          error("invalid geometry\n");
330                                          return 1;                                          return 1;
331                                  }                                  }
332    
333                                    if (*p == '%')
334                                            g_width = -g_width;
335    
336                                  break;                                  break;
337    
338                          case 'f':                          case 'f':
339                                  fullscreen = True;                                  g_fullscreen = True;
340                                  break;                                  break;
341    
342                          case 'b':                          case 'b':
343                                  orders = False;                                  g_orders = False;
344                                  break;                                  break;
345    
346                          case 'e':                          case 'e':
347                                  encryption = False;                                  g_encryption = False;
348                                    break;
349                            case 'E':
350                                    packet_encryption = False;
351                                  break;                                  break;
   
352                          case 'm':                          case 'm':
353                                  sendmotion = False;                                  g_sendmotion = False;
354                                  break;                                  break;
355    
356                          case 'l':                          case 'C':
357                                  licence = False;                                  g_owncolmap = True;
358                                  break;                                  break;
359    
360                          case 't':                          case 'K':
361                                  tcp_port_rdp = strtol(optarg, NULL, 10);                                  g_grab_keyboard = False;
362                                  break;                                  break;
363    
364                          case 'K':                          case 'T':
365                                  grab_keyboard = 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;
394    
395                            case '5':
396                                    g_use_rdp5 = True;
397                                  break;                                  break;
398    
399                          case 'h':                          case 'h':
# Line 179  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))
# Line 190  main(int argc, char *argv[]) Line 422  main(int argc, char *argv[])
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)
# Line 208  main(int argc, char *argv[]) Line 440  main(int argc, char *argv[])
440                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(hostname, fullhostname, sizeof(hostname));
441          }          }
442    
443          if (!strcmp(password, "-"))          if (prompt_password && read_password(password, sizeof(password)))
444          {                  flags |= RDP_LOGON_AUTO;
                 p = getpass("Password: ");  
                 if (p == NULL)  
                 {  
                         error("failed to read password\n");  
                         return 0;  
                 }  
                 STRNCPY(password, p, sizeof(password));  
         }  
445    
446          if ((width == 0) || (height == 0))          if (g_title[0] == 0)
447          {          {
448                  width = 800;                  strcpy(g_title, "rdesktop - ");
449                  height = 600;                  strncat(g_title, server, sizeof(g_title) - sizeof("rdesktop - "));
450          }          }
451    
452          strcpy(title, "rdesktop - ");  #ifdef RDP2VNC
453          strncat(title, server, sizeof(title) - sizeof("rdesktop - "));          rdp2vnc_connect(server, flags, domain, password, shell, directory);
454            return 0;
455    #else
456    
457          xkeymap_init1();          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))          if (!rdp_connect(server, flags, domain, password, shell, directory))
469                  return 1;                  return 1;
470    
471          printf("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    
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          printf("Disconnecting...\n");          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    
547          /* If we have a kernel random device, use it. */          /* If we have a kernel random device, try that first */
548          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
549              || ((fd = open("/dev/random", O_RDONLY)) != -1))              || ((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 273  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 321  error(char *format, ...) Line 625  error(char *format, ...)
625          va_end(ap);          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 */  /* report an unimplemented protocol feature */
642  void  void
643  unimpl(char *format, ...)  unimpl(char *format, ...)
# Line 336  unimpl(char *format, ...) Line 653  unimpl(char *format, ...)
653    
654  /* produce a hex dump */  /* produce a hex dump */
655  void  void
656  hexdump(unsigned char *p, unsigned int len)  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          {          {
# Line 356  hexdump(unsigned char *p, unsigned int l Line 672  hexdump(unsigned char *p, unsigned int l
672                          printf("   ");                          printf("   ");
673    
674                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
675                          printf("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
676    
677                  printf("\n");                  printf("\n");
678                  offset += thisline;                  offset += thisline;
# Line 366  hexdump(unsigned char *p, unsigned int l Line 680  hexdump(unsigned char *p, unsigned int l
680          }          }
681  }  }
682    
683    
684  int  int
685  load_licence(unsigned char **data)  load_licence(unsigned char **data)
686  {  {
687          char path[PATH_MAX];          char *home, *path;
         char *home;  
688          struct stat st;          struct stat st;
689          int fd;          int fd, length;
690    
691          home = getenv("HOME");          home = getenv("HOME");
692          if (home == NULL)          if (home == NULL)
693                  return -1;                  return -1;
694    
695          STRNCPY(path, home, sizeof(path));          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));
696          strncat(path, "/.rdesktop/licence", sizeof(path) - strlen(path) - 1);          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
697    
698          fd = open(path, O_RDONLY);          fd = open(path, O_RDONLY);
699          if (fd == -1)          if (fd == -1)
# Line 388  load_licence(unsigned char **data) Line 702  load_licence(unsigned char **data)
702          if (fstat(fd, &st))          if (fstat(fd, &st))
703                  return -1;                  return -1;
704    
705          *data = xmalloc(st.st_size);          *data = (uint8 *) xmalloc(st.st_size);
706          return read(fd, *data, st.st_size);          length = read(fd, *data, st.st_size);
707            close(fd);
708            xfree(path);
709            return length;
710  }  }
711    
712  void  void
713  save_licence(unsigned char *data, int length)  save_licence(unsigned char *data, int length)
714  {  {
715          char path[PATH_MAX];          char *home, *path, *tmppath;
         char *home;  
716          int fd;          int fd;
717    
718          home = getenv("HOME");          home = getenv("HOME");
719          if (home == NULL)          if (home == NULL)
720                  return;                  return;
721    
722          STRNCPY(path, home, sizeof(path));          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));
         strncat(path, "/.rdesktop", sizeof(path) - strlen(path) - 1);  
         mkdir(path, 0700);  
723    
724          strncat(path, "/licence", sizeof(path) - strlen(path) - 1);          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          fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);          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)          if (fd == -1)
740          {          {
741                  perror("open");                  perror(tmppath);
742                  return;                  return;
743          }          }
744    
745          write(fd, data, length);          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);          close(fd);
757            xfree(tmppath);
758            xfree(path);
759  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26