/[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 329 by astrand, Tue Feb 18 13:07:29 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  /* Display usage information */  /* Display usage information */
65  static void  static void
66  usage(char *program)  usage(char *program)
67  {  {
68          printf("Usage: %s [options] server\n", program);          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
69          printf("   -u: user name\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2003 Matt Chapman.\n");
70          printf("   -d: domain\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
71          printf("   -s: shell\n");  
72          printf("   -c: working directory\n");          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
73          printf("   -p: password (autologon)\n");          fprintf(stderr, "   -u: user name\n");
74          printf("   -n: client hostname\n");          fprintf(stderr, "   -d: domain\n");
75          printf("   -k: keyboard layout on terminal server (us,sv,gr etc.)\n");          fprintf(stderr, "   -s: shell\n");
76          printf("   -g: desktop geometry (WxH)\n");          fprintf(stderr, "   -S: caption button size (single application mode)\n");
77          printf("   -f: full-screen mode\n");          fprintf(stderr, "   -c: working directory\n");
78          printf("   -b: force bitmap updates\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
79          printf("   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -n: client hostname\n");
80          printf("   -m: do not send motion events\n");          fprintf(stderr, "   -k: keyboard layout on terminal server (us,sv,gr,etc.)\n");
81          printf("   -l: do not request licence\n");          fprintf(stderr, "   -g: desktop geometry (WxH)\n");
82          printf("   -t: rdp tcp port\n");          fprintf(stderr, "   -f: full-screen mode\n");
83          printf("   -K: keep window manager key bindings\n");          fprintf(stderr, "   -b: force bitmap updates\n");
84            fprintf(stderr, "   -e: disable encryption (French TS)\n");
85            fprintf(stderr, "   -m: do not send motion events\n");
86            fprintf(stderr, "   -C: use private colour map\n");
87            fprintf(stderr, "   -K: keep window manager key bindings\n");
88            fprintf(stderr, "   -T: window title\n");
89            fprintf(stderr, "   -D: hide window manager decorations\n");
90            fprintf(stderr, "   -a: server bpp\n");
91    }
92    
93    static BOOL
94    read_password(char *password, int size)
95    {
96            struct termios tios;
97            BOOL ret = False;
98            int istty = 0;
99            char *p;
100    
101            if (tcgetattr(STDIN_FILENO, &tios) == 0)
102            {
103                    fprintf(stderr, "Password: ");
104                    tios.c_lflag &= ~ECHO;
105                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
106                    istty = 1;
107            }
108    
109            if (fgets(password, size, stdin) != NULL)
110            {
111                    ret = True;
112    
113                    /* strip final newline */
114                    p = strchr(password, '\n');
115                    if (p != NULL)
116                            *p = 0;
117            }
118    
119            if (istty)
120            {
121                    tios.c_lflag |= ECHO;
122                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
123                    fprintf(stderr, "\n");
124            }
125    
126            return ret;
127  }  }
128    
129  /* Client program */  /* Client program */
130  int  int
131  main(int argc, char *argv[])  main(int argc, char *argv[])
132  {  {
133            char server[64];
134          char fullhostname[64];          char fullhostname[64];
135          char domain[16];          char domain[16];
136          char password[16];          char password[16];
137          char shell[32];          char shell[128];
138          char directory[32];          char directory[32];
139          char title[32];          BOOL prompt_password;
140          struct passwd *pw;          struct passwd *pw;
         char *server, *p;  
141          uint32 flags;          uint32 flags;
142            char *p;
143          int c;          int c;
144            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");  
145    
146          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
147            prompt_password = False;
148          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
149          strcpy(keymapname, "us");          strcpy(keymapname, "en-us");
150    
151          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:t:fbemlKh?")) != -1)          while ((c = getopt(argc, argv, "u:d:s:S:c:p:n:k:g:a:fbemCKT:Dh?")) != -1)
152          {          {
153                  switch (c)                  switch (c)
154                  {                  {
155                          case 'u':                          case 'u':
156                                  STRNCPY(username, optarg, sizeof(username));                                  STRNCPY(username, optarg, sizeof(username));
157                                    username_option = 1;
158                                  break;                                  break;
159    
160                          case 'd':                          case 'd':
# Line 107  main(int argc, char *argv[]) Line 165  main(int argc, char *argv[])
165                                  STRNCPY(shell, optarg, sizeof(shell));                                  STRNCPY(shell, optarg, sizeof(shell));
166                                  break;                                  break;
167    
168                            case 'S':
169                                    if (!strcmp(optarg, "standard"))
170                                    {
171                                            win_button_size = 18;
172                                            break;
173                                    }
174    
175                                    win_button_size = strtol(optarg, &p, 10);
176    
177                                    if (*p)
178                                    {
179                                            error("invalid button size\n");
180                                            return 1;
181                                    }
182    
183                                    break;
184    
185                          case 'c':                          case 'c':
186                                  STRNCPY(directory, optarg, sizeof(directory));                                  STRNCPY(directory, optarg, sizeof(directory));
187                                  break;                                  break;
188    
189                          case 'p':                          case 'p':
190                                    if ((optarg[0] == '-') && (optarg[1] == 0))
191                                    {
192                                            prompt_password = True;
193                                            break;
194                                    }
195    
196                                  STRNCPY(password, optarg, sizeof(password));                                  STRNCPY(password, optarg, sizeof(password));
197                                  flags |= RDP_LOGON_AUTO;                                  flags |= RDP_LOGON_AUTO;
198    
199                                    /* try to overwrite argument so it won't appear in ps */
200                                    p = optarg;
201                                    while (*p)
202                                            *(p++) = 'X';
203                                  break;                                  break;
204    
205                          case 'n':                          case 'n':
# Line 121  main(int argc, char *argv[]) Line 207  main(int argc, char *argv[])
207                                  break;                                  break;
208    
209                          case 'k':                          case 'k':
210                                  STRNCPY(keymapname, optarg,                                  STRNCPY(keymapname, optarg, sizeof(keymapname));
                                         sizeof(keymapname));  
211                                  break;                                  break;
212    
213                          case 'g':                          case 'g':
214                                    if (!strcmp(optarg, "workarea"))
215                                    {
216                                            width = height = 0;
217                                            break;
218                                    }
219    
220                                  width = strtol(optarg, &p, 10);                                  width = strtol(optarg, &p, 10);
221                                  if (*p == 'x')                                  if (*p == 'x')
222                                          height = strtol(p + 1, NULL, 10);                                          height = strtol(p + 1, NULL, 10);
# Line 153  main(int argc, char *argv[]) Line 244  main(int argc, char *argv[])
244                                  sendmotion = False;                                  sendmotion = False;
245                                  break;                                  break;
246    
247                          case 'l':                          case 'C':
248                                  licence = False;                                  owncolmap = True;
                                 break;  
   
                         case 't':  
                                 tcp_port_rdp = strtol(optarg, NULL, 10);  
249                                  break;                                  break;
250    
251                          case 'K':                          case 'K':
252                                  grab_keyboard = False;                                  grab_keyboard = False;
253                                  break;                                  break;
254    
255                            case 'T':
256                                    STRNCPY(title, optarg, sizeof(title));
257                                    break;
258    
259                            case 'D':
260                                    hide_decorations = True;
261                                    break;
262    
263                            case 'a':
264                                    server_bpp = strtol(optarg, NULL, 10);
265                                    if (server_bpp != 8 && server_bpp != 16 && server_bpp != 15
266                                        && server_bpp != 24)
267                                    {
268                                            error("invalid server bpp\n");
269                                            return 1;
270                                    }
271                                    break;
272    
273                          case 'h':                          case 'h':
274                          case '?':                          case '?':
275                          default:                          default:
# Line 179  main(int argc, char *argv[]) Line 284  main(int argc, char *argv[])
284                  return 1;                  return 1;
285          }          }
286    
287          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
288            p = strchr(server, ':');
289            if (p != NULL)
290            {
291                    tcp_port_rdp = strtol(p + 1, NULL, 10);
292                    *p = 0;
293            }
294    
295          if (username[0] == 0)          if (!username_option)
296          {          {
297                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
298                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
# Line 208  main(int argc, char *argv[]) Line 319  main(int argc, char *argv[])
319                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(hostname, fullhostname, sizeof(hostname));
320          }          }
321    
322          if (!strcmp(password, "-"))          if (prompt_password && read_password(password, sizeof(password)))
323          {                  flags |= RDP_LOGON_AUTO;
                 p = getpass("Password: ");  
                 if (p == NULL)  
                 {  
                         error("failed to read password\n");  
                         return 0;  
                 }  
                 STRNCPY(password, p, sizeof(password));  
         }  
324    
325          if ((width == 0) || (height == 0))          if (title[0] == 0)
326          {          {
327                  width = 800;                  strcpy(title, "rdesktop - ");
328                  height = 600;                  strncat(title, server, sizeof(title) - sizeof("rdesktop - "));
329          }          }
330    
331          strcpy(title, "rdesktop - ");          if (!ui_init())
332          strncat(title, server, sizeof(title) - sizeof("rdesktop - "));                  return 1;
   
         xkeymap_init1();  
333    
334          if (!rdp_connect(server, flags, domain, password, shell, directory))          if (!rdp_connect(server, flags, domain, password, shell, directory))
335                  return 1;                  return 1;
336    
337          printf("Connection successful.\n");          DEBUG(("Connection successful.\n"));
338            memset(password, 0, sizeof(password));
339    
340          if (ui_create_window(title))          if (ui_create_window())
341          {          {
342                  rdp_main_loop();                  rdp_main_loop();
343                  ui_destroy_window();                  ui_destroy_window();
344          }          }
345    
346          printf("Disconnecting...\n");          DEBUG(("Disconnecting...\n"));
347          rdp_disconnect();          rdp_disconnect();
348            ui_deinit();
349          return 0;          return 0;
350  }  }
351    
352    #ifdef EGD_SOCKET
353    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
354    static BOOL
355    generate_random_egd(uint8 * buf)
356    {
357            struct sockaddr_un addr;
358            BOOL ret = False;
359            int fd;
360    
361            fd = socket(AF_UNIX, SOCK_STREAM, 0);
362            if (fd == -1)
363                    return False;
364    
365            addr.sun_family = AF_UNIX;
366            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
367            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
368                    goto err;
369    
370            /* PRNGD and EGD use a simple communications protocol */
371            buf[0] = 1;             /* Non-blocking (similar to /dev/urandom) */
372            buf[1] = 32;            /* Number of requested random bytes */
373            if (write(fd, buf, 2) != 2)
374                    goto err;
375    
376            if ((read(fd, buf, 1) != 1) || (buf[0] == 0))   /* Available? */
377                    goto err;
378    
379            if (read(fd, buf, 32) != 32)
380                    goto err;
381    
382            ret = True;
383    
384          err:
385            close(fd);
386            return ret;
387    }
388    #endif
389    
390  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
391  void  void
392  generate_random(uint8 * random)  generate_random(uint8 * random)
393  {  {
394          struct stat st;          struct stat st;
395          struct tms tmsbuf;          struct tms tmsbuf;
396          uint32 *r = (uint32 *) random;          MD5_CTX md5;
397          int fd;          uint32 *r;
398            int fd, n;
399    
400          /* If we have a kernel random device, use it. */          /* If we have a kernel random device, try that first */
401          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
402              || ((fd = open("/dev/random", O_RDONLY)) != -1))              || ((fd = open("/dev/random", O_RDONLY)) != -1))
403          {          {
404                  read(fd, random, 32);                  n = read(fd, random, 32);
405                  close(fd);                  close(fd);
406                  return;                  if (n == 32)
407                            return;
408          }          }
409    
410    #ifdef EGD_SOCKET
411            /* As a second preference use an EGD */
412            if (generate_random_egd(random))
413                    return;
414    #endif
415    
416          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
417            r = (uint32 *) random;
418          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
419          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
420          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 273  generate_random(uint8 * random) Line 423  generate_random(uint8 * random)
423          r[5] = st.st_atime;          r[5] = st.st_atime;
424          r[6] = st.st_mtime;          r[6] = st.st_mtime;
425          r[7] = st.st_ctime;          r[7] = st.st_ctime;
426    
427            /* Hash both halves with MD5 to obscure possible patterns */
428            MD5_Init(&md5);
429            MD5_Update(&md5, random, 16);
430            MD5_Final(random, &md5);
431            MD5_Update(&md5, random + 16, 16);
432            MD5_Final(random + 16, &md5);
433  }  }
434    
435  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 321  error(char *format, ...) Line 478  error(char *format, ...)
478          va_end(ap);          va_end(ap);
479  }  }
480    
481    /* report a warning */
482    void
483    warning(char *format, ...)
484    {
485            va_list ap;
486    
487            fprintf(stderr, "WARNING: ");
488    
489            va_start(ap, format);
490            vfprintf(stderr, format, ap);
491            va_end(ap);
492    }
493    
494  /* report an unimplemented protocol feature */  /* report an unimplemented protocol feature */
495  void  void
496  unimpl(char *format, ...)  unimpl(char *format, ...)
# Line 356  hexdump(unsigned char *p, unsigned int l Line 526  hexdump(unsigned char *p, unsigned int l
526                          printf("   ");                          printf("   ");
527    
528                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
529                          printf("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
530    
531                  printf("\n");                  printf("\n");
532                  offset += thisline;                  offset += thisline;
# Line 366  hexdump(unsigned char *p, unsigned int l Line 534  hexdump(unsigned char *p, unsigned int l
534          }          }
535  }  }
536    
537    
538  int  int
539  load_licence(unsigned char **data)  load_licence(unsigned char **data)
540  {  {
541          char path[PATH_MAX];          char *path;
542          char *home;          char *home;
543          struct stat st;          struct stat st;
544          int fd;          int fd;
# Line 378  load_licence(unsigned char **data) Line 547  load_licence(unsigned char **data)
547          if (home == NULL)          if (home == NULL)
548                  return -1;                  return -1;
549    
550          STRNCPY(path, home, sizeof(path));          path = xmalloc(strlen(home) + strlen(hostname) + 20);
551          strncat(path, "/.rdesktop/licence", sizeof(path) - strlen(path) - 1);          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
552    
553          fd = open(path, O_RDONLY);          fd = open(path, O_RDONLY);
554          if (fd == -1)          if (fd == -1)
# Line 395  load_licence(unsigned char **data) Line 564  load_licence(unsigned char **data)
564  void  void
565  save_licence(unsigned char *data, int length)  save_licence(unsigned char *data, int length)
566  {  {
567          char path[PATH_MAX];          char *fpath;            /* file path for licence */
568            char *fname, *fnamewrk; /* file name for licence .inkl path. */
569          char *home;          char *home;
570          int fd;          uint32 y;
571            struct flock fnfl;
572            int fnfd, fnwrkfd, i, wlen;
573            struct stream s, *s_ptr;
574            uint32 len;
575    
576            /* Construct a stream, so that we can use macros to extract the
577             * licence.
578             */
579            s_ptr = &s;
580            s_ptr->p = data;
581            /* Skip first two bytes */
582            in_uint16(s_ptr, len);
583    
584            /* Skip three strings */
585            for (i = 0; i < 3; i++)
586            {
587                    in_uint32(s_ptr, len);
588                    s_ptr->p += len;
589                    /* Make sure that we won't be past the end of data after
590                     * reading the next length value
591                     */
592                    if ((s_ptr->p) + 4 > data + length)
593                    {
594                            printf("Error in parsing licence key.\n");
595                            printf("Strings %d end value %x > supplied length (%x)\n", i,
596                                   (unsigned int) s_ptr->p, (unsigned int) data + length);
597                            return;
598                    }
599            }
600            in_uint32(s_ptr, len);
601            if (s_ptr->p + len > data + length)
602            {
603                    printf("Error in parsing licence key.\n");
604                    printf("End of licence %x > supplied length (%x)\n",
605                           (unsigned int) s_ptr->p + len, (unsigned int) data + length);
606                    return;
607            }
608    
609          home = getenv("HOME");          home = getenv("HOME");
610          if (home == NULL)          if (home == NULL)
611                  return;                  return;
612    
613          STRNCPY(path, home, sizeof(path));          /* set and create the directory -- if it doesn't exist. */
614          strncat(path, "/.rdesktop", sizeof(path) - strlen(path) - 1);          fpath = xmalloc(strlen(home) + 11);
615          mkdir(path, 0700);          STRNCPY(fpath, home, strlen(home) + 1);
616    
617          strncat(path, "/licence", sizeof(path) - strlen(path) - 1);          sprintf(fpath, "%s/.rdesktop", fpath);
618            if (mkdir(fpath, 0700) == -1 && errno != EEXIST)
619            {
620                    perror("mkdir");
621                    exit(1);
622            }
623    
624          fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);          /* set the real licence filename, and put a write lock on it. */
625          if (fd == -1)          fname = xmalloc(strlen(fpath) + strlen(hostname) + 10);
626            sprintf(fname, "%s/licence.%s", fpath, hostname);
627            fnfd = open(fname, O_RDONLY);
628            if (fnfd != -1)
629            {
630                    fnfl.l_type = F_WRLCK;
631                    fnfl.l_whence = SEEK_SET;
632                    fnfl.l_start = 0;
633                    fnfl.l_len = 1;
634                    fcntl(fnfd, F_SETLK, &fnfl);
635            }
636    
637            /* create a temporary licence file */
638            fnamewrk = xmalloc(strlen(fname) + 12);
639            for (y = 0;; y++)
640            {
641                    sprintf(fnamewrk, "%s.%lu", fname, (long unsigned int) y);
642                    fnwrkfd = open(fnamewrk, O_WRONLY | O_CREAT | O_EXCL, 0600);
643                    if (fnwrkfd == -1)
644                    {
645                            if (errno == EINTR || errno == EEXIST)
646                                    continue;
647                            perror("create");
648                            exit(1);
649                    }
650                    break;
651            }
652            /* write to the licence file */
653            for (y = 0; y < len;)
654          {          {
655                  perror("open");                  do
656                  return;                  {
657                            wlen = write(fnwrkfd, s_ptr->p + y, len - y);
658                    }
659                    while (wlen == -1 && errno == EINTR);
660                    if (wlen < 1)
661                    {
662                            perror("write");
663                            unlink(fnamewrk);
664                            exit(1);
665                    }
666                    y += wlen;
667            }
668    
669            /* close the file and rename it to fname */
670            if (close(fnwrkfd) == -1)
671            {
672                    perror("close");
673                    unlink(fnamewrk);
674                    exit(1);
675            }
676            if (rename(fnamewrk, fname) == -1)
677            {
678                    perror("rename");
679                    unlink(fnamewrk);
680                    exit(1);
681            }
682            /* close the file lock on fname */
683            if (fnfd != -1)
684            {
685                    fnfl.l_type = F_UNLCK;
686                    fnfl.l_whence = SEEK_SET;
687                    fnfl.l_start = 0;
688                    fnfl.l_len = 1;
689                    fcntl(fnfd, F_SETLK, &fnfl);
690                    close(fnfd);
691          }          }
692    
         write(fd, data, length);  
         close(fd);  
693  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26