/[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 25 by matty, Sat Jan 6 03:47:04 2001 UTC revision 289 by astrand, Thu Jan 16 13:48:02 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-2000     Copyright (C) Matthew Chapman 1999-2002
5      
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21  #include <stdlib.h>             /* malloc realloc free */  #include <stdarg.h>             /* va_list va_start va_end */
22  #include <unistd.h>             /* read close getuid getgid getpid getppid gethostname */  #include <unistd.h>             /* read close getuid getgid getpid getppid gethostname */
23  #include <fcntl.h>              /* open */  #include <fcntl.h>              /* open */
24    #include <errno.h>              /* save licence uses it. */
25  #include <pwd.h>                /* getpwuid */  #include <pwd.h>                /* getpwuid */
26    #include <termios.h>            /* tcgetattr tcsetattr */
27  #include <sys/stat.h>           /* stat */  #include <sys/stat.h>           /* stat */
28  #include <sys/time.h>           /* gettimeofday */  #include <sys/time.h>           /* gettimeofday */
29  #include <sys/times.h>          /* times */  #include <sys/times.h>          /* times */
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  int width = 800;  char keymapname[16];
47    int keylayout = 0x409;          /* Defaults to US keyboard layout */
48    int width = 800;                /* If width or height are reset to zero, the geometry will
49                                       be fetched from _NET_WORKAREA */
50  int height = 600;  int height = 600;
51  int keylayout = 0x409;  int tcp_port_rdp = TCP_PORT_RDP;
52  BOOL motion = True;  BOOL bitmap_compression = True;
53    BOOL sendmotion = True;
54  BOOL orders = True;  BOOL orders = True;
55  BOOL licence = True;  BOOL encryption = True;
56    BOOL desktop_save = True;
57    BOOL fullscreen = False;
58    BOOL grab_keyboard = True;
59    BOOL hide_decorations = False;
60    extern BOOL owncolmap;
61    
62  /* Display usage information */  /* Display usage information */
63  static void  static void
64  usage(char *program)  usage(char *program)
65  {  {
66          STATUS("Usage: %s [options] server\n", program);          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
67          STATUS("   -u: user name\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2002 Matt Chapman.\n");
68          STATUS("   -d: domain\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
69          STATUS("   -s: shell\n");  
70          STATUS("   -c: working directory\n");          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
71          STATUS("   -p: password (autologon)\n");          fprintf(stderr, "   -u: user name\n");
72          STATUS("   -n: client hostname\n");          fprintf(stderr, "   -d: domain\n");
73          STATUS("   -w: desktop width\n");          fprintf(stderr, "   -s: shell\n");
74          STATUS("   -h: desktop height\n");          fprintf(stderr, "   -c: working directory\n");
75          STATUS("   -k: keyboard layout (hex)\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
76          STATUS("   -b: force bitmap updates\n");          fprintf(stderr, "   -n: client hostname\n");
77          STATUS("   -m: do not send motion events\n");          fprintf(stderr, "   -k: keyboard layout on terminal server (us,sv,gr,etc.)\n");
78          STATUS("   -l: do not request licence\n\n");          fprintf(stderr, "   -g: desktop geometry (WxH)\n");
79            fprintf(stderr, "   -f: full-screen mode\n");
80            fprintf(stderr, "   -b: force bitmap updates\n");
81            fprintf(stderr, "   -e: disable encryption (French TS)\n");
82            fprintf(stderr, "   -m: do not send motion events\n");
83            fprintf(stderr, "   -C: use private colour map\n");
84            fprintf(stderr, "   -K: keep window manager key bindings\n");
85            fprintf(stderr, "   -T: window title\n");
86            fprintf(stderr, "   -D: hide window manager decorations\n");
87    }
88    
89    static BOOL
90    read_password(char *password, int size)
91    {
92            struct termios tios;
93            BOOL ret = False;
94            int istty = 0;
95            char *p;
96    
97            if (tcgetattr(STDIN_FILENO, &tios) == 0)
98            {
99                    fprintf(stderr, "Password: ");
100                    tios.c_lflag &= ~ECHO;
101                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
102                    istty = 1;
103            }
104    
105            if (fgets(password, size, stdin) != NULL)
106            {
107                    ret = True;
108    
109                    /* strip final newline */
110                    p = strchr(password, '\n');
111                    if (p != NULL)
112                            *p = 0;
113            }
114    
115            if (istty)
116            {
117                    tios.c_lflag |= ECHO;
118                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
119                    fprintf(stderr, "\n");
120            }
121    
122            return ret;
123  }  }
124    
125  /* Client program */  /* Client program */
126  int  int
127  main(int argc, char *argv[])  main(int argc, char *argv[])
128  {  {
129          struct passwd *pw;          char server[64];
130          char *server;          char fullhostname[64];
         uint32 flags;  
131          char domain[16];          char domain[16];
132          char password[16];          char password[16];
133          char shell[32];          char shell[128];
134          char directory[32];          char directory[32];
135          char title[32];          BOOL prompt_password;
136            struct passwd *pw;
137            uint32 flags;
138            char *p;
139          int c;          int c;
140            int username_option = 0;
         STATUS("rdesktop: A Remote Desktop Protocol client.\n");  
         STATUS("Version " VERSION  
                ". Copyright (C) 1999-2000 Matt Chapman.\n");  
         STATUS("See http://www.rdesktop.org/ for more information.\n\n");  
141    
142          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
143            prompt_password = False;
144          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
145            strcpy(keymapname, "en-us");
146    
147          while ((c = getopt(argc, argv, "u:d:s:c:p:n:w:h:k:bml?")) != -1)          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:fbemCKT:Dh?")) != -1)
148          {          {
149                  switch (c)                  switch (c)
150                  {                  {
151                          case 'u':                          case 'u':
152                                  strncpy(username, optarg, sizeof(username));                                  STRNCPY(username, optarg, sizeof(username));
153                                    username_option = 1;
154                                  break;                                  break;
155    
156                          case 'd':                          case 'd':
157                                  strncpy(domain, optarg, sizeof(domain));                                  STRNCPY(domain, optarg, sizeof(domain));
158                                    break;
159    
160                            case 's':
161                                    STRNCPY(shell, optarg, sizeof(shell));
162                                    break;
163    
164                            case 'c':
165                                    STRNCPY(directory, optarg, sizeof(directory));
166                                  break;                                  break;
167    
168                          case 'p':                          case 'p':
169                                    if ((optarg[0] == '-') && (optarg[1] == 0))
170                                    {
171                                            prompt_password = True;
172                                            break;
173                                    }
174    
175                                    STRNCPY(password, optarg, sizeof(password));
176                                  flags |= RDP_LOGON_AUTO;                                  flags |= RDP_LOGON_AUTO;
177                                  strncpy(password, optarg, sizeof(password));  
178                                    /* try to overwrite argument so it won't appear in ps */
179                                    p = optarg;
180                                    while (*p)
181                                            *(p++) = 'X';
182                                  break;                                  break;
183    
184                          case 's':                          case 'n':
185                                  strncpy(shell, optarg, sizeof(shell));                                  STRNCPY(hostname, optarg, sizeof(hostname));
186                                  break;                                  break;
187    
188                          case 'c':                          case 'k':
189                                  strncpy(directory, optarg, sizeof(directory));                                  STRNCPY(keymapname, optarg, sizeof(keymapname));
190                                  break;                                  break;
191    
192                          case 'n':                          case 'g':
193                                  strncpy(hostname, optarg, sizeof(hostname));                                  if (!strcmp(optarg, "workarea"))
194                                    {
195                                            width = height = 0;
196                                            break;
197                                    }
198    
199                                    width = strtol(optarg, &p, 10);
200                                    if (*p == 'x')
201                                            height = strtol(p + 1, NULL, 10);
202    
203                                    if ((width == 0) || (height == 0))
204                                    {
205                                            error("invalid geometry\n");
206                                            return 1;
207                                    }
208                                  break;                                  break;
209    
210                          case 'w':                          case 'f':
211                                  width = strtol(optarg, NULL, 10);                                  fullscreen = True;
212                                  break;                                  break;
213    
214                          case 'h':                          case 'b':
215                                  height = strtol(optarg, NULL, 10);                                  orders = False;
216                                  break;                                  break;
217    
218                          case 'k':                          case 'e':
219                                  keylayout = strtol(optarg, NULL, 16);                                  encryption = False;
220                                  break;                                  break;
221    
222                          case 'm':                          case 'm':
223                                  motion = False;                                  sendmotion = False;
224                                  break;                                  break;
225    
226                          case 'b':                          case 'C':
227                                  orders = False;                                  owncolmap = True;
228                                    break;
229    
230                            case 'K':
231                                    grab_keyboard = False;
232                                    break;
233    
234                            case 'T':
235                                    STRNCPY(title, optarg, sizeof(title));
236                                  break;                                  break;
237    
238                          case 'l':                          case 'D':
239                                  licence = False;                                  hide_decorations = True;
240                                  break;                                  break;
241    
242                            case 'h':
243                          case '?':                          case '?':
244                          default:                          default:
245                                  usage(argv[0]);                                  usage(argv[0]);
# Line 143  main(int argc, char *argv[]) Line 253  main(int argc, char *argv[])
253                  return 1;                  return 1;
254          }          }
255    
256          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
257            p = strchr(server, ':');
258            if (p != NULL)
259            {
260                    tcp_port_rdp = strtol(p + 1, NULL, 10);
261                    *p = 0;
262            }
263    
264          if (username[0] == 0)          if (!username_option)
265          {          {
266                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
267                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
268                  {                  {
269                          STATUS("Could not determine user name.\n");                          error("could not determine username, use -u\n");
270                          return 1;                          return 1;
271                  }                  }
272    
273                  strncpy(username, pw->pw_name, sizeof(username));                  STRNCPY(username, pw->pw_name, sizeof(username));
274          }          }
275    
276          if (hostname[0] == 0)          if (hostname[0] == 0)
277          {          {
278                  if (gethostname(hostname, sizeof(hostname)) == -1)                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
279                  {                  {
280                          STATUS("Could not determine host name.\n");                          error("could not determine local hostname, use -n\n");
281                          return 1;                          return 1;
282                  }                  }
283    
284                    p = strchr(fullhostname, '.');
285                    if (p != NULL)
286                            *p = 0;
287    
288                    STRNCPY(hostname, fullhostname, sizeof(hostname));
289          }          }
290    
291          if (!rdp_connect(server, flags, domain, password, shell, directory))          if (prompt_password && read_password(password, sizeof(password)))
292                    flags |= RDP_LOGON_AUTO;
293    
294            if (title[0] == 0)
295            {
296                    strcpy(title, "rdesktop - ");
297                    strncat(title, server, sizeof(title) - sizeof("rdesktop - "));
298            }
299    
300            if (!ui_init())
301                  return 1;                  return 1;
302    
303          STATUS("Connection successful.\n");          if (!rdp_connect(server, flags, domain, password, shell, directory))
304                    return 1;
305    
306          strcpy(title, "rdesktop - ");          DEBUG(("Connection successful.\n"));
307          strncat(title, server, sizeof(title));          memset(password, 0, sizeof(password));
308    
309          if (ui_create_window(title))          if (ui_create_window())
310          {          {
311                  rdp_main_loop();                  rdp_main_loop();
312                  ui_destroy_window();                  ui_destroy_window();
313          }          }
314    
315            DEBUG(("Disconnecting...\n"));
316          rdp_disconnect();          rdp_disconnect();
317            ui_deinit();
318          return 0;          return 0;
319  }  }
320    
321    #ifdef EGD_SOCKET
322    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
323    static BOOL
324    generate_random_egd(uint8 * buf)
325    {
326            struct sockaddr_un addr;
327            BOOL ret = False;
328            int fd;
329    
330            fd = socket(AF_UNIX, SOCK_STREAM, 0);
331            if (fd == -1)
332                    return False;
333    
334            addr.sun_family = AF_UNIX;
335            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
336            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
337                    goto err;
338    
339            /* PRNGD and EGD use a simple communications protocol */
340            buf[0] = 1;             /* Non-blocking (similar to /dev/urandom) */
341            buf[1] = 32;            /* Number of requested random bytes */
342            if (write(fd, buf, 2) != 2)
343                    goto err;
344    
345            if ((read(fd, buf, 1) != 1) || (buf[0] == 0))   /* Available? */
346                    goto err;
347    
348            if (read(fd, buf, 32) != 32)
349                    goto err;
350    
351            ret = True;
352    
353          err:
354            close(fd);
355            return ret;
356    }
357    #endif
358    
359  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
360  void  void
361  generate_random(uint8 *random)  generate_random(uint8 * random)
362  {  {
363          struct stat st;          struct stat st;
364          struct tms tmsbuf;          struct tms tmsbuf;
365          uint32 *r = (uint32 *) random;          MD5_CTX md5;
366          int fd;          uint32 *r;
367            int fd, n;
368          /* If we have a kernel random device, use it. */  
369          if ((fd = open("/dev/urandom", O_RDONLY)) != -1)          /* If we have a kernel random device, try that first */
370            if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
371                || ((fd = open("/dev/random", O_RDONLY)) != -1))
372          {          {
373                  read(fd, random, 32);                  n = read(fd, random, 32);
374                  close(fd);                  close(fd);
375                  return;                  if (n == 32)
376                            return;
377          }          }
378    
379    #ifdef EGD_SOCKET
380            /* As a second preference use an EGD */
381            if (generate_random_egd(random))
382                    return;
383    #endif
384    
385          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
386            r = (uint32 *) random;
387          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
388          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
389          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 210  generate_random(uint8 *random) Line 392  generate_random(uint8 *random)
392          r[5] = st.st_atime;          r[5] = st.st_atime;
393          r[6] = st.st_mtime;          r[6] = st.st_mtime;
394          r[7] = st.st_ctime;          r[7] = st.st_ctime;
395    
396            /* Hash both halves with MD5 to obscure possible patterns */
397            MD5_Init(&md5);
398            MD5_Update(&md5, random, 16);
399            MD5_Final(random, &md5);
400            MD5_Update(&md5, random + 16, 16);
401            MD5_Final(random + 16, &md5);
402  }  }
403    
404  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 219  xmalloc(int size) Line 408  xmalloc(int size)
408          void *mem = malloc(size);          void *mem = malloc(size);
409          if (mem == NULL)          if (mem == NULL)
410          {          {
411                  ERROR("xmalloc %d\n", size);                  error("xmalloc %d\n", size);
412                  exit(1);                  exit(1);
413          }          }
414          return mem;          return mem;
# Line 232  xrealloc(void *oldmem, int size) Line 421  xrealloc(void *oldmem, int size)
421          void *mem = realloc(oldmem, size);          void *mem = realloc(oldmem, size);
422          if (mem == NULL)          if (mem == NULL)
423          {          {
424                  ERROR("xrealloc %d\n", size);                  error("xrealloc %d\n", size);
425                  exit(1);                  exit(1);
426          }          }
427          return mem;          return mem;
# Line 245  xfree(void *mem) Line 434  xfree(void *mem)
434          free(mem);          free(mem);
435  }  }
436    
437  /* Produce a hex dump */  /* report an error */
438    void
439    error(char *format, ...)
440    {
441            va_list ap;
442    
443            fprintf(stderr, "ERROR: ");
444    
445            va_start(ap, format);
446            vfprintf(stderr, format, ap);
447            va_end(ap);
448    }
449    
450    /* report an unimplemented protocol feature */
451    void
452    unimpl(char *format, ...)
453    {
454            va_list ap;
455    
456            fprintf(stderr, "NOT IMPLEMENTED: ");
457    
458            va_start(ap, format);
459            vfprintf(stderr, format, ap);
460            va_end(ap);
461    }
462    
463    /* produce a hex dump */
464  void  void
465  hexdump(unsigned char *p, unsigned int len)  hexdump(unsigned char *p, unsigned int len)
466  {  {
# Line 255  hexdump(unsigned char *p, unsigned int l Line 470  hexdump(unsigned char *p, unsigned int l
470    
471          while (offset < len)          while (offset < len)
472          {          {
473                  STATUS("%04x ", offset);                  printf("%04x ", offset);
474                  thisline = len - offset;                  thisline = len - offset;
475                  if (thisline > 16)                  if (thisline > 16)
476                          thisline = 16;                          thisline = 16;
477    
478                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
479                          STATUS("%02x ", line[i]) for (; i < 16; i++)                          printf("%02x ", line[i]);
480                                  STATUS("   ");  
481                    for (; i < 16; i++)
482                            printf("   ");
483    
484                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
485                          STATUS("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
486    
487                  STATUS("\n");                  printf("\n");
488                  offset += thisline;                  offset += thisline;
489                  line += thisline;                  line += thisline;
490          }          }
491  }  }
492    
493    #ifdef SAVE_LICENCE
494    int
495    load_licence(unsigned char **data)
496    {
497            char *path;
498            char *home;
499            struct stat st;
500            int fd;
501    
502            home = getenv("HOME");
503            if (home == NULL)
504                    return -1;
505    
506            path = xmalloc(strlen(home) + strlen(hostname) + 20);
507            sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
508    
509            fd = open(path, O_RDONLY);
510            if (fd == -1)
511                    return -1;
512    
513            if (fstat(fd, &st))
514                    return -1;
515    
516            *data = xmalloc(st.st_size);
517            return read(fd, *data, st.st_size);
518    }
519    
520    void
521    save_licence(unsigned char *data, int length)
522    {
523            char *fpath;            /* file path for licence */
524            char *fname, *fnamewrk; /* file name for licence .inkl path. */
525            char *home;
526            uint32 y;
527            struct flock fnfl;
528            int fnfd, fnwrkfd, i, wlen;
529            struct stream s, *s_ptr;
530            uint32 len;
531    
532            /* Construct a stream, so that we can use macros to extract the
533             * licence.
534             */
535            s_ptr = &s;
536            s_ptr->p = data;
537            /* Skip first two bytes */
538            in_uint16(s_ptr, len);
539    
540            /* Skip three strings */
541            for (i = 0; i < 3; i++)
542            {
543                    in_uint32(s_ptr, len);
544                    s_ptr->p += len;
545                    /* Make sure that we won't be past the end of data after
546                     * reading the next length value
547                     */
548                    if ((s_ptr->p) + 4 > data + length)
549                    {
550                            printf("Error in parsing licence key.\n");
551                            printf("Strings %d end value %x > supplied length (%x)\n",
552                                   i, s_ptr->p, data + length);
553                            return;
554                    }
555            }
556            in_uint32(s_ptr, len);
557            if (s_ptr->p + len > data + length)
558            {
559                    printf("Error in parsing licence key.\n");
560                    printf("End of licence %x > supplied length (%x)\n", s_ptr->p + len, data + length);
561                    return;
562            }
563    
564            home = getenv("HOME");
565            if (home == NULL)
566                    return;
567    
568            /* set and create the directory -- if it doesn't exist. */
569            fpath = xmalloc(strlen(home) + 11);
570            STRNCPY(fpath, home, strlen(home) + 1);
571    
572            sprintf(fpath, "%s/.rdesktop", fpath);
573            if (mkdir(fpath, 0700) == -1 && errno != EEXIST)
574            {
575                    perror("mkdir");
576                    exit(1);
577            }
578    
579            /* set the real licence filename, and put a write lock on it. */
580            fname = xmalloc(strlen(fpath) + strlen(hostname) + 10);
581            sprintf(fname, "%s/licence.%s", fpath, hostname);
582            fnfd = open(fname, O_RDONLY);
583            if (fnfd != -1)
584            {
585                    fnfl.l_type = F_WRLCK;
586                    fnfl.l_whence = SEEK_SET;
587                    fnfl.l_start = 0;
588                    fnfl.l_len = 1;
589                    fcntl(fnfd, F_SETLK, &fnfl);
590            }
591    
592            /* create a temporary licence file */
593            fnamewrk = xmalloc(strlen(fname) + 12);
594            for (y = 0;; y++)
595            {
596                    sprintf(fnamewrk, "%s.%lu", fname, y);
597                    fnwrkfd = open(fnamewrk, O_WRONLY | O_CREAT | O_EXCL, 0600);
598                    if (fnwrkfd == -1)
599                    {
600                            if (errno == EINTR || errno == EEXIST)
601                                    continue;
602                            perror("create");
603                            exit(1);
604                    }
605                    break;
606            }
607            /* write to the licence file */
608            for (y = 0; y < len;)
609            {
610                    do
611                    {
612                            wlen = write(fnwrkfd, s_ptr->p + y, len - y);
613                    }
614                    while (wlen == -1 && errno == EINTR);
615                    if (wlen < 1)
616                    {
617                            perror("write");
618                            unlink(fnamewrk);
619                            exit(1);
620                    }
621                    y += wlen;
622            }
623    
624            /* close the file and rename it to fname */
625            if (close(fnwrkfd) == -1)
626            {
627                    perror("close");
628                    unlink(fnamewrk);
629                    exit(1);
630            }
631            if (rename(fnamewrk, fname) == -1)
632            {
633                    perror("rename");
634                    unlink(fnamewrk);
635                    exit(1);
636            }
637            /* close the file lock on fname */
638            if (fnfd != -1)
639            {
640                    fnfl.l_type = F_UNLCK;
641                    fnfl.l_whence = SEEK_SET;
642                    fnfl.l_start = 0;
643                    fnfl.l_len = 1;
644                    fcntl(fnfd, F_SETLK, &fnfl);
645                    close(fnfd);
646            }
647    
648    }
649    #endif

Legend:
Removed from v.25  
changed lines
  Added in v.289

  ViewVC Help
Powered by ViewVC 1.1.26