/[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 12 by matty, Tue Aug 15 12:01:01 2000 UTC revision 297 by matthewc, Tue Jan 28 12:27:28 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 <pwd.h>        /* getpwuid */  #include <errno.h>              /* save licence uses it. */
25  #include <sys/stat.h>   /* stat */  #include <pwd.h>                /* getpwuid */
26  #include <sys/time.h>   /* gettimeofday */  #include <termios.h>            /* tcgetattr tcsetattr */
27  #include <sys/times.h>  /* times */  #include <sys/stat.h>           /* stat */
28    #include <sys/time.h>           /* gettimeofday */
29    #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 = False;  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 usage(char *program)  static void
64    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("   -n: client hostname\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
69          STATUS("   -w: desktop width\n");  
70          STATUS("   -h: desktop height\n");          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
71          STATUS("   -k: keyboard layout (hex)\n");          fprintf(stderr, "   -u: user name\n");
72          STATUS("   -m: send motion events\n");          fprintf(stderr, "   -d: domain\n");
73          STATUS("   -b: force bitmap updates\n");          fprintf(stderr, "   -s: shell\n");
74          STATUS("   -l: do not request licence\n\n");          fprintf(stderr, "   -c: working directory\n");
75            fprintf(stderr, "   -p: password (- to prompt)\n");
76            fprintf(stderr, "   -n: client hostname\n");
77            fprintf(stderr, "   -k: keyboard layout on terminal server (us,sv,gr,etc.)\n");
78            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 main(int argc, char *argv[])  int
127    main(int argc, char *argv[])
128  {  {
129            char server[64];
130            char fullhostname[64];
131            char domain[16];
132            char password[16];
133            char shell[128];
134            char directory[32];
135            BOOL prompt_password;
136          struct passwd *pw;          struct passwd *pw;
137          char *server;          uint32 flags;
138          char title[32];          char *p;
139          int c;          int c;
140            int username_option = 0;
141    
142          STATUS("rdesktop: A Remote Desktop Protocol client.\n");          flags = RDP_LOGON_NORMAL;
143          STATUS("Version "VERSION". Copyright (C) 1999-2000 Matt Chapman.\n\n");          prompt_password = False;
144            domain[0] = password[0] = shell[0] = directory[0] = 0;
145            strcpy(keymapname, "en-us");
146    
147          while ((c = getopt(argc, argv, "u:n:w:h:k:mbl?")) != -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 'n':                          case 'd':
157                                  strncpy(hostname, optarg, sizeof(hostname));                                  STRNCPY(domain, optarg, sizeof(domain));
158                                  break;                                  break;
159    
160                          case 'w':                          case 's':
161                                  width = strtol(optarg, NULL, 10);                                  STRNCPY(shell, optarg, sizeof(shell));
162                                  break;                                  break;
163    
164                          case 'h':                          case 'c':
165                                  height = strtol(optarg, NULL, 10);                                  STRNCPY(directory, optarg, sizeof(directory));
166                                    break;
167    
168                            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;
177    
178                                    /* try to overwrite argument so it won't appear in ps */
179                                    p = optarg;
180                                    while (*p)
181                                            *(p++) = 'X';
182                                    break;
183    
184                            case 'n':
185                                    STRNCPY(hostname, optarg, sizeof(hostname));
186                                  break;                                  break;
187    
188                          case 'k':                          case 'k':
189                                  keylayout = strtol(optarg, NULL, 16);                                  STRNCPY(keymapname, optarg, sizeof(keymapname));
190                                  break;                                  break;
191    
192                          case 'm':                          case 'g':
193                                  motion = True;                                  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;
209    
210                            case 'f':
211                                    fullscreen = True;
212                                  break;                                  break;
213    
214                          case 'b':                          case 'b':
215                                  orders = False;                                  orders = False;
216                                  break;                                  break;
217    
218                          case 'l':                          case 'e':
219                                  licence = False;                                  encryption = False;
220                                  break;                                  break;
221    
222                            case 'm':
223                                    sendmotion = False;
224                                    break;
225    
226                            case 'C':
227                                    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;
237    
238                            case 'D':
239                                    hide_decorations = True;
240                                    break;
241    
242                            case 'h':
243                          case '?':                          case '?':
244                          default:                          default:
245                                  usage(argv[0]);                                  usage(argv[0]);
# Line 110  int main(int argc, char *argv[]) Line 253  int 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 (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 (!rdp_connect(server))          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  /* Generate a 32-byte random for the secure transport code. */  #ifdef EGD_SOCKET
322  void generate_random(uint8 *random)  /* 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 stat st;          struct sockaddr_un addr;
327          uint32 *r = (uint32 *)random;          BOOL ret = False;
328          int fd;          int fd;
329    
330          /* If we have a kernel random device, use it. */          fd = socket(AF_UNIX, SOCK_STREAM, 0);
331          if ((fd = open("/dev/urandom", O_RDONLY)) != -1)          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. */
360    void
361    generate_random(uint8 * random)
362    {
363            struct stat st;
364            struct tms tmsbuf;
365            MD5_CTX md5;
366            uint32 *r;
367            int fd, n;
368    
369            /* 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(NULL); /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
390          gettimeofday((struct timeval *)&r[3], NULL); /* sec and usec */          gettimeofday((struct timeval *) &r[3], NULL);   /* sec and usec */
391          stat("/tmp", &st);          stat("/tmp", &st);
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 */
405  void *xmalloc(int size)  void *
406    xmalloc(int size)
407  {  {
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;
415  }  }
416    
417  /* realloc; exit if out of memory */  /* realloc; exit if out of memory */
418  void *xrealloc(void *oldmem, int size)  void *
419    xrealloc(void *oldmem, int size)
420  {  {
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;
428  }  }
429    
430  /* free */  /* free */
431  void xfree(void *mem)  void
432    xfree(void *mem)
433  {  {
434          free(mem);          free(mem);
435  }  }
436    
437  /* Produce a hex dump */  /* report an error */
438  void hexdump(unsigned char *p, unsigned int len)  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 a warning */
451    void
452    warning(char *format, ...)
453    {
454            va_list ap;
455    
456            fprintf(stderr, "WARNING: ");
457    
458            va_start(ap, format);
459            vfprintf(stderr, format, ap);
460            va_end(ap);
461    }
462    
463    /* report an unimplemented protocol feature */
464    void
465    unimpl(char *format, ...)
466    {
467            va_list ap;
468    
469            fprintf(stderr, "NOT IMPLEMENTED: ");
470    
471            va_start(ap, format);
472            vfprintf(stderr, format, ap);
473            va_end(ap);
474    }
475    
476    /* produce a hex dump */
477    void
478    hexdump(unsigned char *p, unsigned int len)
479  {  {
480          unsigned char *line = p;          unsigned char *line = p;
481          unsigned int thisline, offset = 0;          unsigned int thisline, offset = 0;
# Line 216  void hexdump(unsigned char *p, unsigned Line 483  void hexdump(unsigned char *p, unsigned
483    
484          while (offset < len)          while (offset < len)
485          {          {
486                  STATUS("%04x ", offset);                  printf("%04x ", offset);
487                  thisline = len - offset;                  thisline = len - offset;
488                  if (thisline > 16)                  if (thisline > 16)
489                          thisline = 16;                          thisline = 16;
490    
491                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
492                          STATUS("%02x ", line[i])                          printf("%02x ", line[i]);
493    
494                  for (; i < 16; i++)                  for (; i < 16; i++)
495                          STATUS("   ");                          printf("   ");
496    
497                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
498                          STATUS("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
499    
500                  STATUS("\n");                  printf("\n");
501                  offset += thisline;                  offset += thisline;
502                  line += thisline;                  line += thisline;
503          }          }
504  }  }
505    
506    #ifdef SAVE_LICENCE
507    int
508    load_licence(unsigned char **data)
509    {
510            char *path;
511            char *home;
512            struct stat st;
513            int fd;
514    
515            home = getenv("HOME");
516            if (home == NULL)
517                    return -1;
518    
519            path = xmalloc(strlen(home) + strlen(hostname) + 20);
520            sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
521    
522            fd = open(path, O_RDONLY);
523            if (fd == -1)
524                    return -1;
525    
526            if (fstat(fd, &st))
527                    return -1;
528    
529            *data = xmalloc(st.st_size);
530            return read(fd, *data, st.st_size);
531    }
532    
533    void
534    save_licence(unsigned char *data, int length)
535    {
536            char *fpath;            /* file path for licence */
537            char *fname, *fnamewrk; /* file name for licence .inkl path. */
538            char *home;
539            uint32 y;
540            struct flock fnfl;
541            int fnfd, fnwrkfd, i, wlen;
542            struct stream s, *s_ptr;
543            uint32 len;
544    
545            /* Construct a stream, so that we can use macros to extract the
546             * licence.
547             */
548            s_ptr = &s;
549            s_ptr->p = data;
550            /* Skip first two bytes */
551            in_uint16(s_ptr, len);
552    
553            /* Skip three strings */
554            for (i = 0; i < 3; i++)
555            {
556                    in_uint32(s_ptr, len);
557                    s_ptr->p += len;
558                    /* Make sure that we won't be past the end of data after
559                     * reading the next length value
560                     */
561                    if ((s_ptr->p) + 4 > data + length)
562                    {
563                            printf("Error in parsing licence key.\n");
564                            printf("Strings %d end value %x > supplied length (%x)\n",
565                                   i, s_ptr->p, data + length);
566                            return;
567                    }
568            }
569            in_uint32(s_ptr, len);
570            if (s_ptr->p + len > data + length)
571            {
572                    printf("Error in parsing licence key.\n");
573                    printf("End of licence %x > supplied length (%x)\n", s_ptr->p + len, data + length);
574                    return;
575            }
576    
577            home = getenv("HOME");
578            if (home == NULL)
579                    return;
580    
581            /* set and create the directory -- if it doesn't exist. */
582            fpath = xmalloc(strlen(home) + 11);
583            STRNCPY(fpath, home, strlen(home) + 1);
584    
585            sprintf(fpath, "%s/.rdesktop", fpath);
586            if (mkdir(fpath, 0700) == -1 && errno != EEXIST)
587            {
588                    perror("mkdir");
589                    exit(1);
590            }
591    
592            /* set the real licence filename, and put a write lock on it. */
593            fname = xmalloc(strlen(fpath) + strlen(hostname) + 10);
594            sprintf(fname, "%s/licence.%s", fpath, hostname);
595            fnfd = open(fname, O_RDONLY);
596            if (fnfd != -1)
597            {
598                    fnfl.l_type = F_WRLCK;
599                    fnfl.l_whence = SEEK_SET;
600                    fnfl.l_start = 0;
601                    fnfl.l_len = 1;
602                    fcntl(fnfd, F_SETLK, &fnfl);
603            }
604    
605            /* create a temporary licence file */
606            fnamewrk = xmalloc(strlen(fname) + 12);
607            for (y = 0;; y++)
608            {
609                    sprintf(fnamewrk, "%s.%lu", fname, y);
610                    fnwrkfd = open(fnamewrk, O_WRONLY | O_CREAT | O_EXCL, 0600);
611                    if (fnwrkfd == -1)
612                    {
613                            if (errno == EINTR || errno == EEXIST)
614                                    continue;
615                            perror("create");
616                            exit(1);
617                    }
618                    break;
619            }
620            /* write to the licence file */
621            for (y = 0; y < len;)
622            {
623                    do
624                    {
625                            wlen = write(fnwrkfd, s_ptr->p + y, len - y);
626                    }
627                    while (wlen == -1 && errno == EINTR);
628                    if (wlen < 1)
629                    {
630                            perror("write");
631                            unlink(fnamewrk);
632                            exit(1);
633                    }
634                    y += wlen;
635            }
636    
637            /* close the file and rename it to fname */
638            if (close(fnwrkfd) == -1)
639            {
640                    perror("close");
641                    unlink(fnamewrk);
642                    exit(1);
643            }
644            if (rename(fnamewrk, fname) == -1)
645            {
646                    perror("rename");
647                    unlink(fnamewrk);
648                    exit(1);
649            }
650            /* close the file lock on fname */
651            if (fnfd != -1)
652            {
653                    fnfl.l_type = F_UNLCK;
654                    fnfl.l_whence = SEEK_SET;
655                    fnfl.l_start = 0;
656                    fnfl.l_len = 1;
657                    fcntl(fnfd, F_SETLK, &fnfl);
658                    close(fnfd);
659            }
660    
661    }
662    #endif

Legend:
Removed from v.12  
changed lines
  Added in v.297

  ViewVC Help
Powered by ViewVC 1.1.26