/[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 79 by astrand, Mon Jul 29 20:35:13 2002 UTC revision 333 by astrand, Thu Feb 20 12:14:13 2003 UTC
# Line 1  Line 1 
1  /*  /*
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    #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 title[32] = "";
44  char username[16];  char username[16];
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 */
48  int width;  int width = 800;                /* If width or height are reset to zero, the geometry will
49  int height;                                     be fetched from _NET_WORKAREA */
50    int height = 600;
51  int tcp_port_rdp = TCP_PORT_RDP;  int tcp_port_rdp = TCP_PORT_RDP;
52    int server_bpp = 8;
53    int win_button_size = 0;        /* If zero, disable single app mode */
54  BOOL bitmap_compression = True;  BOOL bitmap_compression = True;
55  BOOL sendmotion = True;  BOOL sendmotion = True;
56  BOOL orders = True;  BOOL orders = True;
 BOOL licence = True;  
57  BOOL encryption = True;  BOOL encryption = True;
58  BOOL desktop_save = True;  BOOL desktop_save = True;
59  BOOL fullscreen = False;  BOOL fullscreen = False;
60  BOOL grab_keyboard = True;  BOOL grab_keyboard = True;
61    BOOL hide_decorations = False;
62    extern BOOL owncolmap;
63    
64    #ifdef RDP2VNC
65    extern int rfb_port;
66    extern int defer_time;
67    void
68    rdp2vnc_connect(char *server, uint32 flags, char *domain, char *password,
69                    char *shell, char *directory);
70    #endif
71  /* Display usage information */  /* Display usage information */
72  static void  static void
73  usage(char *program)  usage(char *program)
74  {  {
75          printf("Usage: %s [options] server\n", program);          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
76          printf("   -u: user name\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2003 Matt Chapman.\n");
77          printf("   -d: domain\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
78          printf("   -s: shell\n");  
79          printf("   -c: working directory\n");          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
80          printf("   -p: password (autologon)\n");  #ifdef RDP2VNC
81          printf("   -n: client hostname\n");          fprintf(stderr, "   -V: vnc port\n");
82          printf("   -k: keyboard layout on terminal server (us,sv,gr etc.)\n");          fprintf(stderr, "   -E: defer time (ms)\n");
83          printf("   -g: desktop geometry (WxH)\n");  #endif
84          printf("   -f: full-screen mode\n");          fprintf(stderr, "   -u: user name\n");
85          printf("   -b: force bitmap updates\n");          fprintf(stderr, "   -d: domain\n");
86          printf("   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -s: shell\n");
87          printf("   -m: do not send motion events\n");          fprintf(stderr, "   -S: caption button size (single application mode)\n");
88          printf("   -l: do not request licence\n");          fprintf(stderr, "   -c: working directory\n");
89          printf("   -t: rdp tcp port\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
90          printf("   -K: keep window manager key bindings\n");          fprintf(stderr, "   -n: client hostname\n");
91            fprintf(stderr, "   -k: keyboard layout on terminal server (us,sv,gr,etc.)\n");
92            fprintf(stderr, "   -g: desktop geometry (WxH)\n");
93            fprintf(stderr, "   -f: full-screen mode\n");
94            fprintf(stderr, "   -b: force bitmap updates\n");
95            fprintf(stderr, "   -e: disable encryption (French TS)\n");
96            fprintf(stderr, "   -m: do not send motion events\n");
97            fprintf(stderr, "   -C: use private colour map\n");
98            fprintf(stderr, "   -K: keep window manager key bindings\n");
99            fprintf(stderr, "   -T: window title\n");
100            fprintf(stderr, "   -D: hide window manager decorations\n");
101            fprintf(stderr, "   -a: server bpp\n");
102    }
103    
104    static BOOL
105    read_password(char *password, int size)
106    {
107            struct termios tios;
108            BOOL ret = False;
109            int istty = 0;
110            char *p;
111    
112            if (tcgetattr(STDIN_FILENO, &tios) == 0)
113            {
114                    fprintf(stderr, "Password: ");
115                    tios.c_lflag &= ~ECHO;
116                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
117                    istty = 1;
118            }
119    
120            if (fgets(password, size, stdin) != NULL)
121            {
122                    ret = True;
123    
124                    /* strip final newline */
125                    p = strchr(password, '\n');
126                    if (p != NULL)
127                            *p = 0;
128            }
129    
130            if (istty)
131            {
132                    tios.c_lflag |= ECHO;
133                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
134                    fprintf(stderr, "\n");
135            }
136    
137            return ret;
138  }  }
139    
140  /* Client program */  /* Client program */
141  int  int
142  main(int argc, char *argv[])  main(int argc, char *argv[])
143  {  {
144            char server[64];
145          char fullhostname[64];          char fullhostname[64];
146          char domain[16];          char domain[16];
147          char password[16];          char password[16];
148          char shell[32];          char shell[128];
149          char directory[32];          char directory[32];
150          char title[32];          BOOL prompt_password;
151          struct passwd *pw;          struct passwd *pw;
         char *server, *p;  
152          uint32 flags;          uint32 flags;
153            char *p;
154          int c;          int c;
155            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");  
156    
157          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
158            prompt_password = False;
159          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
160          strcpy(keymapname, "us");          strcpy(keymapname, "en-us");
161    
162          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:t:fbemlKh?")) != -1)  #ifdef RDP2VNC
163    #define VNCOPT "V:E:"
164    #else
165    #define VNCOPT
166    #endif
167    
168            while ((c = getopt(argc, argv, VNCOPT "u:d:s:S:c:p:n:k:g:a:fbemCKT:Dh?")) != -1)
169          {          {
170                  switch (c)                  switch (c)
171                  {                  {
172    #ifdef RDP2VNC
173                            case 'V':
174                                    rfb_port = strtol(optarg, NULL, 10);
175                                    if (rfb_port < 100)
176                                            rfb_port += 5900;
177                                    break;
178    
179                            case 'E':
180                                    defer_time = strtol(optarg, NULL, 10);
181                                    if (defer_time < 0)
182                                            defer_time = 0;
183                                    break;
184    #endif
185    
186                          case 'u':                          case 'u':
187                                  STRNCPY(username, optarg, sizeof(username));                                  STRNCPY(username, optarg, sizeof(username));
188                                    username_option = 1;
189                                  break;                                  break;
190    
191                          case 'd':                          case 'd':
# Line 107  main(int argc, char *argv[]) Line 196  main(int argc, char *argv[])
196                                  STRNCPY(shell, optarg, sizeof(shell));                                  STRNCPY(shell, optarg, sizeof(shell));
197                                  break;                                  break;
198    
199                            case 'S':
200                                    if (!strcmp(optarg, "standard"))
201                                    {
202                                            win_button_size = 18;
203                                            break;
204                                    }
205    
206                                    win_button_size = strtol(optarg, &p, 10);
207    
208                                    if (*p)
209                                    {
210                                            error("invalid button size\n");
211                                            return 1;
212                                    }
213    
214                                    break;
215    
216                          case 'c':                          case 'c':
217                                  STRNCPY(directory, optarg, sizeof(directory));                                  STRNCPY(directory, optarg, sizeof(directory));
218                                  break;                                  break;
219    
220                          case 'p':                          case 'p':
221                                    if ((optarg[0] == '-') && (optarg[1] == 0))
222                                    {
223                                            prompt_password = True;
224                                            break;
225                                    }
226    
227                                  STRNCPY(password, optarg, sizeof(password));                                  STRNCPY(password, optarg, sizeof(password));
228                                  flags |= RDP_LOGON_AUTO;                                  flags |= RDP_LOGON_AUTO;
229    
230                                    /* try to overwrite argument so it won't appear in ps */
231                                    p = optarg;
232                                    while (*p)
233                                            *(p++) = 'X';
234                                  break;                                  break;
235    
236                          case 'n':                          case 'n':
# Line 121  main(int argc, char *argv[]) Line 238  main(int argc, char *argv[])
238                                  break;                                  break;
239    
240                          case 'k':                          case 'k':
241                                  STRNCPY(keymapname, optarg,                                  STRNCPY(keymapname, optarg, sizeof(keymapname));
                                         sizeof(keymapname));  
242                                  break;                                  break;
243    
244                          case 'g':                          case 'g':
245                                    if (!strcmp(optarg, "workarea"))
246                                    {
247                                            width = height = 0;
248                                            break;
249                                    }
250    
251                                  width = strtol(optarg, &p, 10);                                  width = strtol(optarg, &p, 10);
252                                  if (*p == 'x')                                  if (*p == 'x')
253                                          height = strtol(p + 1, NULL, 10);                                          height = strtol(p + 1, NULL, 10);
# Line 153  main(int argc, char *argv[]) Line 275  main(int argc, char *argv[])
275                                  sendmotion = False;                                  sendmotion = False;
276                                  break;                                  break;
277    
278                          case 'l':                          case 'C':
279                                  licence = False;                                  owncolmap = True;
                                 break;  
   
                         case 't':  
                                 tcp_port_rdp = strtol(optarg, NULL, 10);  
280                                  break;                                  break;
281    
282                          case 'K':                          case 'K':
283                                  grab_keyboard = False;                                  grab_keyboard = False;
284                                  break;                                  break;
285    
286                            case 'T':
287                                    STRNCPY(title, optarg, sizeof(title));
288                                    break;
289    
290                            case 'D':
291                                    hide_decorations = True;
292                                    break;
293    
294                            case 'a':
295                                    server_bpp = strtol(optarg, NULL, 10);
296                                    if (server_bpp != 8 && server_bpp != 16 && server_bpp != 15
297                                        && server_bpp != 24)
298                                    {
299                                            error("invalid server bpp\n");
300                                            return 1;
301                                    }
302                                    break;
303    
304                          case 'h':                          case 'h':
305                          case '?':                          case '?':
306                          default:                          default:
# Line 179  main(int argc, char *argv[]) Line 315  main(int argc, char *argv[])
315                  return 1;                  return 1;
316          }          }
317    
318          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
319            p = strchr(server, ':');
320            if (p != NULL)
321            {
322                    tcp_port_rdp = strtol(p + 1, NULL, 10);
323                    *p = 0;
324            }
325    
326          if (username[0] == 0)          if (!username_option)
327          {          {
328                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
329                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
# Line 208  main(int argc, char *argv[]) Line 350  main(int argc, char *argv[])
350                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(hostname, fullhostname, sizeof(hostname));
351          }          }
352    
353          if (!strcmp(password, "-"))          if (prompt_password && read_password(password, sizeof(password)))
354          {                  flags |= RDP_LOGON_AUTO;
                 p = getpass("Password: ");  
                 if (p == NULL)  
                 {  
                         error("failed to read password\n");  
                         return 0;  
                 }  
                 STRNCPY(password, p, sizeof(password));  
         }  
355    
356          if ((width == 0) || (height == 0))          if (title[0] == 0)
357          {          {
358                  width = 800;                  strcpy(title, "rdesktop - ");
359                  height = 600;                  strncat(title, server, sizeof(title) - sizeof("rdesktop - "));
360          }          }
361    
362          strcpy(title, "rdesktop - ");  #ifdef RDP2VNC
363          strncat(title, server, sizeof(title) - sizeof("rdesktop - "));          rdp2vnc_connect(server, flags, domain, password, shell, directory);
364    #else
365    
366          xkeymap_init1();          if (!ui_init())
367                    return 1;
368    
369          if (!rdp_connect(server, flags, domain, password, shell, directory))          if (!rdp_connect(server, flags, domain, password, shell, directory))
370                  return 1;                  return 1;
371    
372          printf("Connection successful.\n");          DEBUG(("Connection successful.\n"));
373            memset(password, 0, sizeof(password));
374    
375          if (ui_create_window(title))          if (ui_create_window())
376          {          {
377                  rdp_main_loop();                  rdp_main_loop();
378                  ui_destroy_window();                  ui_destroy_window();
379          }          }
380    
381          printf("Disconnecting...\n");          DEBUG(("Disconnecting...\n"));
382          rdp_disconnect();          rdp_disconnect();
383            ui_deinit();
384    
385    #endif
386    
387          return 0;          return 0;
388  }  }
389    
390    #ifdef EGD_SOCKET
391    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
392    static BOOL
393    generate_random_egd(uint8 * buf)
394    {
395            struct sockaddr_un addr;
396            BOOL ret = False;
397            int fd;
398    
399            fd = socket(AF_UNIX, SOCK_STREAM, 0);
400            if (fd == -1)
401                    return False;
402    
403            addr.sun_family = AF_UNIX;
404            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
405            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
406                    goto err;
407    
408            /* PRNGD and EGD use a simple communications protocol */
409            buf[0] = 1;             /* Non-blocking (similar to /dev/urandom) */
410            buf[1] = 32;            /* Number of requested random bytes */
411            if (write(fd, buf, 2) != 2)
412                    goto err;
413    
414            if ((read(fd, buf, 1) != 1) || (buf[0] == 0))   /* Available? */
415                    goto err;
416    
417            if (read(fd, buf, 32) != 32)
418                    goto err;
419    
420            ret = True;
421    
422          err:
423            close(fd);
424            return ret;
425    }
426    #endif
427    
428  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
429  void  void
430  generate_random(uint8 * random)  generate_random(uint8 * random)
431  {  {
432          struct stat st;          struct stat st;
433          struct tms tmsbuf;          struct tms tmsbuf;
434          uint32 *r = (uint32 *) random;          MD5_CTX md5;
435          int fd;          uint32 *r;
436            int fd, n;
437    
438          /* If we have a kernel random device, use it. */          /* If we have a kernel random device, try that first */
439          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
440              || ((fd = open("/dev/random", O_RDONLY)) != -1))              || ((fd = open("/dev/random", O_RDONLY)) != -1))
441          {          {
442                  read(fd, random, 32);                  n = read(fd, random, 32);
443                  close(fd);                  close(fd);
444                  return;                  if (n == 32)
445                            return;
446          }          }
447    
448    #ifdef EGD_SOCKET
449            /* As a second preference use an EGD */
450            if (generate_random_egd(random))
451                    return;
452    #endif
453    
454          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
455            r = (uint32 *) random;
456          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
457          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
458          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 273  generate_random(uint8 * random) Line 461  generate_random(uint8 * random)
461          r[5] = st.st_atime;          r[5] = st.st_atime;
462          r[6] = st.st_mtime;          r[6] = st.st_mtime;
463          r[7] = st.st_ctime;          r[7] = st.st_ctime;
464    
465            /* Hash both halves with MD5 to obscure possible patterns */
466            MD5_Init(&md5);
467            MD5_Update(&md5, random, 16);
468            MD5_Final(random, &md5);
469            MD5_Update(&md5, random + 16, 16);
470            MD5_Final(random + 16, &md5);
471  }  }
472    
473  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 321  error(char *format, ...) Line 516  error(char *format, ...)
516          va_end(ap);          va_end(ap);
517  }  }
518    
519    /* report a warning */
520    void
521    warning(char *format, ...)
522    {
523            va_list ap;
524    
525            fprintf(stderr, "WARNING: ");
526    
527            va_start(ap, format);
528            vfprintf(stderr, format, ap);
529            va_end(ap);
530    }
531    
532  /* report an unimplemented protocol feature */  /* report an unimplemented protocol feature */
533  void  void
534  unimpl(char *format, ...)  unimpl(char *format, ...)
# Line 356  hexdump(unsigned char *p, unsigned int l Line 564  hexdump(unsigned char *p, unsigned int l
564                          printf("   ");                          printf("   ");
565    
566                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
567                          printf("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
568    
569                  printf("\n");                  printf("\n");
570                  offset += thisline;                  offset += thisline;
# Line 366  hexdump(unsigned char *p, unsigned int l Line 572  hexdump(unsigned char *p, unsigned int l
572          }          }
573  }  }
574    
575    
576  int  int
577  load_licence(unsigned char **data)  load_licence(unsigned char **data)
578  {  {
579          char path[PATH_MAX];          char *path;
580          char *home;          char *home;
581          struct stat st;          struct stat st;
582          int fd;          int fd;
# Line 378  load_licence(unsigned char **data) Line 585  load_licence(unsigned char **data)
585          if (home == NULL)          if (home == NULL)
586                  return -1;                  return -1;
587    
588          STRNCPY(path, home, sizeof(path));          path = xmalloc(strlen(home) + strlen(hostname) + 20);
589          strncat(path, "/.rdesktop/licence", sizeof(path) - strlen(path) - 1);          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
590    
591          fd = open(path, O_RDONLY);          fd = open(path, O_RDONLY);
592          if (fd == -1)          if (fd == -1)
# Line 395  load_licence(unsigned char **data) Line 602  load_licence(unsigned char **data)
602  void  void
603  save_licence(unsigned char *data, int length)  save_licence(unsigned char *data, int length)
604  {  {
605          char path[PATH_MAX];          char *fpath;            /* file path for licence */
606            char *fname, *fnamewrk; /* file name for licence .inkl path. */
607          char *home;          char *home;
608          int fd;          uint32 y;
609            struct flock fnfl;
610            int fnfd, fnwrkfd, i, wlen;
611            struct stream s, *s_ptr;
612            uint32 len;
613    
614            /* Construct a stream, so that we can use macros to extract the
615             * licence.
616             */
617            s_ptr = &s;
618            s_ptr->p = data;
619            /* Skip first two bytes */
620            in_uint16(s_ptr, len);
621    
622            /* Skip three strings */
623            for (i = 0; i < 3; i++)
624            {
625                    in_uint32(s_ptr, len);
626                    s_ptr->p += len;
627                    /* Make sure that we won't be past the end of data after
628                     * reading the next length value
629                     */
630                    if ((s_ptr->p) + 4 > data + length)
631                    {
632                            printf("Error in parsing licence key.\n");
633                            printf("Strings %d end value %x > supplied length (%x)\n", i,
634                                   (unsigned int) s_ptr->p, (unsigned int) data + length);
635                            return;
636                    }
637            }
638            in_uint32(s_ptr, len);
639            if (s_ptr->p + len > data + length)
640            {
641                    printf("Error in parsing licence key.\n");
642                    printf("End of licence %x > supplied length (%x)\n",
643                           (unsigned int) s_ptr->p + len, (unsigned int) data + length);
644                    return;
645            }
646    
647          home = getenv("HOME");          home = getenv("HOME");
648          if (home == NULL)          if (home == NULL)
649                  return;                  return;
650    
651          STRNCPY(path, home, sizeof(path));          /* set and create the directory -- if it doesn't exist. */
652          strncat(path, "/.rdesktop", sizeof(path) - strlen(path) - 1);          fpath = xmalloc(strlen(home) + 11);
653          mkdir(path, 0700);          STRNCPY(fpath, home, strlen(home) + 1);
654    
655          strncat(path, "/licence", sizeof(path) - strlen(path) - 1);          sprintf(fpath, "%s/.rdesktop", fpath);
656            if (mkdir(fpath, 0700) == -1 && errno != EEXIST)
657            {
658                    perror("mkdir");
659                    exit(1);
660            }
661    
662          fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);          /* set the real licence filename, and put a write lock on it. */
663          if (fd == -1)          fname = xmalloc(strlen(fpath) + strlen(hostname) + 10);
664            sprintf(fname, "%s/licence.%s", fpath, hostname);
665            fnfd = open(fname, O_RDONLY);
666            if (fnfd != -1)
667            {
668                    fnfl.l_type = F_WRLCK;
669                    fnfl.l_whence = SEEK_SET;
670                    fnfl.l_start = 0;
671                    fnfl.l_len = 1;
672                    fcntl(fnfd, F_SETLK, &fnfl);
673            }
674    
675            /* create a temporary licence file */
676            fnamewrk = xmalloc(strlen(fname) + 12);
677            for (y = 0;; y++)
678            {
679                    sprintf(fnamewrk, "%s.%lu", fname, (long unsigned int) y);
680                    fnwrkfd = open(fnamewrk, O_WRONLY | O_CREAT | O_EXCL, 0600);
681                    if (fnwrkfd == -1)
682                    {
683                            if (errno == EINTR || errno == EEXIST)
684                                    continue;
685                            perror("create");
686                            exit(1);
687                    }
688                    break;
689            }
690            /* write to the licence file */
691            for (y = 0; y < len;)
692          {          {
693                  perror("open");                  do
694                  return;                  {
695                            wlen = write(fnwrkfd, s_ptr->p + y, len - y);
696                    }
697                    while (wlen == -1 && errno == EINTR);
698                    if (wlen < 1)
699                    {
700                            perror("write");
701                            unlink(fnamewrk);
702                            exit(1);
703                    }
704                    y += wlen;
705            }
706    
707            /* close the file and rename it to fname */
708            if (close(fnwrkfd) == -1)
709            {
710                    perror("close");
711                    unlink(fnamewrk);
712                    exit(1);
713            }
714            if (rename(fnamewrk, fname) == -1)
715            {
716                    perror("rename");
717                    unlink(fnamewrk);
718                    exit(1);
719            }
720            /* close the file lock on fname */
721            if (fnfd != -1)
722            {
723                    fnfl.l_type = F_UNLCK;
724                    fnfl.l_whence = SEEK_SET;
725                    fnfl.l_start = 0;
726                    fnfl.l_len = 1;
727                    fcntl(fnfd, F_SETLK, &fnfl);
728                    close(fnfd);
729          }          }
730    
         write(fd, data, length);  
         close(fd);  
731  }  }

Legend:
Removed from v.79  
changed lines
  Added in v.333

  ViewVC Help
Powered by ViewVC 1.1.26