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

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

  ViewVC Help
Powered by ViewVC 1.1.26