/[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 29 by matty, Fri Sep 14 03:38:39 2001 UTC revision 280 by n-ki, Tue Nov 26 14:39:50 2002 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 bitmap_compression = True;  BOOL bitmap_compression = True;
53  BOOL sendmotion = True;  BOOL sendmotion = True;
54  BOOL orders = True;  BOOL orders = True;
55  BOOL licence = True;  BOOL encryption = True;
 BOOL use_encryption = True;  
56  BOOL desktop_save = True;  BOOL desktop_save = True;
57  BOOL fullscreen = False;  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    
         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          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
142            prompt_password = False;
143          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
144            strcpy(keymapname, "en-us");
145    
146          while ((c = getopt(argc, argv, "u:d:s:c:p:n:g:k:mbleKFVh?")) != -1)          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:fbemCKT:Dh?")) != -1)
147          {          {
148                  switch (c)                  switch (c)
149                  {                  {
150                          case 'u':                          case 'u':
151                                  strncpy(username, optarg, sizeof(username));                                  STRNCPY(username, optarg, sizeof(username));
152                                  break;                                  break;
153    
154                          case 'd':                          case 'd':
155                                  strncpy(domain, optarg, sizeof(domain));                                  STRNCPY(domain, optarg, sizeof(domain));
                                 break;  
   
                         case 'p':  
                                 flags |= RDP_LOGON_AUTO;  
                                 strncpy(password, optarg, sizeof(password));  
156                                  break;                                  break;
157    
158                          case 's':                          case 's':
159                                  strncpy(shell, optarg, sizeof(shell));                                  STRNCPY(shell, optarg, sizeof(shell));
160                                  break;                                  break;
161    
162                          case 'c':                          case 'c':
163                                  strncpy(directory, optarg, sizeof(directory));                                  STRNCPY(directory, optarg, sizeof(directory));
164                                    break;
165    
166                            case 'p':
167                                    if ((optarg[0] == '-') && (optarg[1] == 0))
168                                    {
169                                            prompt_password = True;
170                                            break;
171                                    }
172    
173                                    STRNCPY(password, optarg, sizeof(password));
174                                    flags |= RDP_LOGON_AUTO;
175    
176                                    /* try to overwrite argument so it won't appear in ps */
177                                    p = optarg;
178                                    while (*p)
179                                            *(p++) = 'X';
180                                  break;                                  break;
181    
182                          case 'n':                          case 'n':
183                                  strncpy(hostname, optarg, sizeof(hostname));                                  STRNCPY(hostname, optarg, sizeof(hostname));
184                                    break;
185    
186                            case 'k':
187                                    STRNCPY(keymapname, optarg, sizeof(keymapname));
188                                  break;                                  break;
189    
190                          case 'g':                          case 'g':
191                                    if (!strcmp(optarg, "workarea"))
192                                  {                                  {
193                                          char *tgem = 0;                                          width = height = 0;
194                                          width = strtol(optarg, NULL, 10);                                          break;
195                                          tgem = strchr(optarg, 'x');                                  }
196                                          if ((tgem == 0) || (strlen(tgem) < 2))  
197                                          {                                  width = strtol(optarg, &p, 10);
198                                                  ERROR                                  if (*p == 'x')
199                                                          ("-g: invalid parameter. Syntax example: -g 1024x768\n");                                          height = strtol(p + 1, NULL, 10);
200                                                  exit(1);  
201                                          }                                  if ((width == 0) || (height == 0))
202                                          height = strtol(tgem + 1, NULL, 10);                                  {
203                                            error("invalid geometry\n");
204                                            return 1;
205                                  }                                  }
206                                  break;                                  break;
207    
208                          case 'k':                          case 'f':
209                                  keylayout = strtol(optarg, NULL, 16);                                  fullscreen = True;
210                                  /* keylayout = find_keyb_code(optarg); */                                  break;
211                                  if (keylayout == 0)  
212                                          return 0;                          case 'b':
213                                    orders = False;
214                                    break;
215    
216                            case 'e':
217                                    encryption = False;
218                                  break;                                  break;
219    
220                          case 'm':                          case 'm':
221                                  sendmotion = False;                                  sendmotion = False;
222                                  break;                                  break;
223    
224                          case 'b':                          case 'C':
225                                  orders = False;                                  owncolmap = True;
226                                  break;                                  break;
227    
228                          case 'l':                          case 'K':
229                                  licence = False;                                  grab_keyboard = False;
230                                  break;                                  break;
231    
232                          case 'e':                          case 'T':
233                                  use_encryption = False;                                  STRNCPY(title, optarg, sizeof(title));
234                                  break;                                  break;
235    
236                          case 'F':                          case 'D':
237                                  fullscreen = True;                                  hide_decorations = True;
238                                  break;                                  break;
239    
240                          case 'h':                          case 'h':
# Line 165  main(int argc, char *argv[]) Line 251  main(int argc, char *argv[])
251                  return 1;                  return 1;
252          }          }
253    
254          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
255            p = strchr(server, ':');
256            if (p != NULL)
257            {
258                    tcp_port_rdp = strtol(p + 1, NULL, 10);
259                    *p = 0;
260            }
261    
262          if (username[0] == 0)          if (username[0] == 0)
263          {          {
264                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
265                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
266                  {                  {
267                          STATUS("Could not determine user name.\n");                          error("could not determine username, use -u\n");
268                          return 1;                          return 1;
269                  }                  }
270    
271                  strncpy(username, pw->pw_name, sizeof(username));                  STRNCPY(username, pw->pw_name, sizeof(username));
272          }          }
273    
274          if (hostname[0] == 0)          if (hostname[0] == 0)
275          {          {
276                  if (gethostname(hostname, sizeof(hostname)) == -1)                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
277                  {                  {
278                          STATUS("Could not determine host name.\n");                          error("could not determine local hostname, use -n\n");
279                          return 1;                          return 1;
280                  }                  }
281    
282                    p = strchr(fullhostname, '.');
283                    if (p != NULL)
284                            *p = 0;
285    
286                    STRNCPY(hostname, fullhostname, sizeof(hostname));
287          }          }
288    
289          strcpy(title, "rdesktop - ");          if (prompt_password && read_password(password, sizeof(password)))
290          strncat(title, server, sizeof(title));                  flags |= RDP_LOGON_AUTO;
291    
292          if (ui_create_window(title))          if (title[0] == 0)
293          {          {
294                  if (!rdp_connect(server, flags, domain, password, shell,                  strcpy(title, "rdesktop - ");
295                                   directory))                  strncat(title, server, sizeof(title) - sizeof("rdesktop - "));
296                          return 1;          }
297    
298            if (!ui_init())
299                    return 1;
300    
301            if (!rdp_connect(server, flags, domain, password, shell, directory))
302                    return 1;
303    
304                  STATUS("Connection successful.\n");          DEBUG(("Connection successful.\n"));
305            memset(password, 0, sizeof(password));
306    
307            if (ui_create_window())
308            {
309                  rdp_main_loop();                  rdp_main_loop();
310                  ui_destroy_window();                  ui_destroy_window();
311          }          }
312    
313            DEBUG(("Disconnecting...\n"));
314          rdp_disconnect();          rdp_disconnect();
315            ui_deinit();
316          return 0;          return 0;
317  }  }
318    
319    #ifdef EGD_SOCKET
320    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
321    static BOOL
322    generate_random_egd(uint8 * buf)
323    {
324            struct sockaddr_un addr;
325            BOOL ret = False;
326            int fd;
327    
328            fd = socket(AF_UNIX, SOCK_STREAM, 0);
329            if (fd == -1)
330                    return False;
331    
332            addr.sun_family = AF_UNIX;
333            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
334            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
335                    goto err;
336    
337            /* PRNGD and EGD use a simple communications protocol */
338            buf[0] = 1;             /* Non-blocking (similar to /dev/urandom) */
339            buf[1] = 32;            /* Number of requested random bytes */
340            if (write(fd, buf, 2) != 2)
341                    goto err;
342    
343            if ((read(fd, buf, 1) != 1) || (buf[0] == 0))   /* Available? */
344                    goto err;
345    
346            if (read(fd, buf, 32) != 32)
347                    goto err;
348    
349            ret = True;
350    
351          err:
352            close(fd);
353            return ret;
354    }
355    #endif
356    
357  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
358  void  void
359  generate_random(uint8 *random)  generate_random(uint8 * random)
360  {  {
361          struct stat st;          struct stat st;
362          struct tms tmsbuf;          struct tms tmsbuf;
363          uint32 *r = (uint32 *) random;          MD5_CTX md5;
364          int fd;          uint32 *r;
365            int fd, n;
366          /* If we have a kernel random device, use it. */  
367          if ((fd = open("/dev/urandom", O_RDONLY)) != -1)          /* If we have a kernel random device, try that first */
368            if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
369                || ((fd = open("/dev/random", O_RDONLY)) != -1))
370          {          {
371                  read(fd, random, 32);                  n = read(fd, random, 32);
372                  close(fd);                  close(fd);
373                  return;                  if (n == 32)
374                            return;
375          }          }
376    
377    #ifdef EGD_SOCKET
378            /* As a second preference use an EGD */
379            if (generate_random_egd(random))
380                    return;
381    #endif
382    
383          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
384            r = (uint32 *) random;
385          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
386          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
387          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 232  generate_random(uint8 *random) Line 390  generate_random(uint8 *random)
390          r[5] = st.st_atime;          r[5] = st.st_atime;
391          r[6] = st.st_mtime;          r[6] = st.st_mtime;
392          r[7] = st.st_ctime;          r[7] = st.st_ctime;
393    
394            /* Hash both halves with MD5 to obscure possible patterns */
395            MD5_Init(&md5);
396            MD5_Update(&md5, random, 16);
397            MD5_Final(random, &md5);
398            MD5_Update(&md5, random + 16, 16);
399            MD5_Final(random + 16, &md5);
400  }  }
401    
402  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 241  xmalloc(int size) Line 406  xmalloc(int size)
406          void *mem = malloc(size);          void *mem = malloc(size);
407          if (mem == NULL)          if (mem == NULL)
408          {          {
409                  ERROR("xmalloc %d\n", size);                  error("xmalloc %d\n", size);
410                  exit(1);                  exit(1);
411          }          }
412          return mem;          return mem;
# Line 254  xrealloc(void *oldmem, int size) Line 419  xrealloc(void *oldmem, int size)
419          void *mem = realloc(oldmem, size);          void *mem = realloc(oldmem, size);
420          if (mem == NULL)          if (mem == NULL)
421          {          {
422                  ERROR("xrealloc %d\n", size);                  error("xrealloc %d\n", size);
423                  exit(1);                  exit(1);
424          }          }
425          return mem;          return mem;
# Line 267  xfree(void *mem) Line 432  xfree(void *mem)
432          free(mem);          free(mem);
433  }  }
434    
435  /* Produce a hex dump */  /* report an error */
436    void
437    error(char *format, ...)
438    {
439            va_list ap;
440    
441            fprintf(stderr, "ERROR: ");
442    
443            va_start(ap, format);
444            vfprintf(stderr, format, ap);
445            va_end(ap);
446    }
447    
448    /* report an unimplemented protocol feature */
449    void
450    unimpl(char *format, ...)
451    {
452            va_list ap;
453    
454            fprintf(stderr, "NOT IMPLEMENTED: ");
455    
456            va_start(ap, format);
457            vfprintf(stderr, format, ap);
458            va_end(ap);
459    }
460    
461    /* produce a hex dump */
462  void  void
463  hexdump(unsigned char *p, unsigned int len)  hexdump(unsigned char *p, unsigned int len)
464  {  {
# Line 277  hexdump(unsigned char *p, unsigned int l Line 468  hexdump(unsigned char *p, unsigned int l
468    
469          while (offset < len)          while (offset < len)
470          {          {
471                  STATUS("%04x ", offset);                  printf("%04x ", offset);
472                  thisline = len - offset;                  thisline = len - offset;
473                  if (thisline > 16)                  if (thisline > 16)
474                          thisline = 16;                          thisline = 16;
475    
476                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
477                          STATUS("%02x ", line[i]) for (; i < 16; i++)                          printf("%02x ", line[i]);
478                                  STATUS("   ");  
479                    for (; i < 16; i++)
480                            printf("   ");
481    
482                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
483                          STATUS("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
484    
485                  STATUS("\n");                  printf("\n");
486                  offset += thisline;                  offset += thisline;
487                  line += thisline;                  line += thisline;
488          }          }
489  }  }
490    
491    #ifdef SAVE_LICENCE
492    int
493    load_licence(unsigned char **data)
494    {
495            char *path;
496            char *home;
497            struct stat st;
498            int fd;
499    
500            home = getenv("HOME");
501            if (home == NULL)
502                    return -1;
503    
504            path = xmalloc(strlen(home) + strlen(hostname) + 20);
505            sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
506    
507            fd = open(path, O_RDONLY);
508            if (fd == -1)
509                    return -1;
510    
511            if (fstat(fd, &st))
512                    return -1;
513    
514            *data = xmalloc(st.st_size);
515            return read(fd, *data, st.st_size);
516    }
517    
518    void
519    save_licence(unsigned char *data, int length)
520    {
521            char *fpath;            /* file path for licence */
522            char *fname, *fnamewrk; /* file name for licence .inkl path. */
523            char *home;
524            uint32 y;
525            struct flock fnfl;
526            int fnfd, fnwrkfd, i, wlen;
527            struct stream s, *s_ptr;
528            uint32 len;
529    
530            /* Construct a stream, so that we can use macros to extract the
531             * licence.
532             */
533            s_ptr = &s;
534            s_ptr->p = data;
535            /* Skip first two bytes */
536            in_uint16(s_ptr, len);
537    
538            /* Skip three strings */
539            for (i = 0; i < 3; i++)
540            {
541                    in_uint32(s_ptr, len);
542                    s_ptr->p += len;
543                    /* Make sure that we won't be past the end of data after
544                     * reading the next length value
545                     */
546                    if ((s_ptr->p) + 4 > data + length)
547                    {
548                            printf("Error in parsing licence key.\n");
549                            printf("Strings %d end value %x > supplied length (%x)\n",
550                                   i, s_ptr->p, data + length);
551                            return;
552                    }
553            }
554            in_uint32(s_ptr, len);
555            if (s_ptr->p + len > data + length)
556            {
557                    printf("Error in parsing licence key.\n");
558                    printf("End of licence %x > supplied length (%x)\n", s_ptr->p + len, data + length);
559                    return;
560            }
561    
562            home = getenv("HOME");
563            if (home == NULL)
564                    return;
565    
566            /* set and create the directory -- if it doesn't exist. */
567            fpath = xmalloc(strlen(home) + 11);
568            STRNCPY(fpath, home, strlen(home) + 1);
569    
570            sprintf(fpath, "%s/.rdesktop", fpath);
571            if (mkdir(fpath, 0700) == -1 && errno != EEXIST)
572            {
573                    perror("mkdir");
574                    exit(1);
575            }
576    
577            /* set the real licence filename, and put a write lock on it. */
578            fname = xmalloc(strlen(fpath) + strlen(hostname) + 10);
579            sprintf(fname, "%s/licence.%s", fpath, hostname);
580            fnfd = open(fname, O_RDONLY);
581            if (fnfd != -1)
582            {
583                    fnfl.l_type = F_WRLCK;
584                    fnfl.l_whence = SEEK_SET;
585                    fnfl.l_start = 0;
586                    fnfl.l_len = 1;
587                    fcntl(fnfd, F_SETLK, &fnfl);
588            }
589    
590            /* create a temporary licence file */
591            fnamewrk = xmalloc(strlen(fname) + 12);
592            for (y = 0;; y++)
593            {
594                    sprintf(fnamewrk, "%s.%lu", fname, y);
595                    fnwrkfd = open(fnamewrk, O_WRONLY | O_CREAT | O_EXCL, 0600);
596                    if (fnwrkfd == -1)
597                    {
598                            if (errno == EINTR || errno == EEXIST)
599                                    continue;
600                            perror("create");
601                            exit(1);
602                    }
603                    break;
604            }
605            /* write to the licence file */
606            for (y = 0; y < len;)
607            {
608                    do
609                    {
610                            wlen = write(fnwrkfd, s_ptr->p + y, len - y);
611                    }
612                    while (wlen == -1 && errno == EINTR);
613                    if (wlen < 1)
614                    {
615                            perror("write");
616                            unlink(fnamewrk);
617                            exit(1);
618                    }
619                    y += wlen;
620            }
621    
622            /* close the file and rename it to fname */
623            if (close(fnwrkfd) == -1)
624            {
625                    perror("close");
626                    unlink(fnamewrk);
627                    exit(1);
628            }
629            if (rename(fnamewrk, fname) == -1)
630            {
631                    perror("rename");
632                    unlink(fnamewrk);
633                    exit(1);
634            }
635            /* close the file lock on fname */
636            if (fnfd != -1)
637            {
638                    fnfl.l_type = F_UNLCK;
639                    fnfl.l_whence = SEEK_SET;
640                    fnfl.l_start = 0;
641                    fnfl.l_len = 1;
642                    fcntl(fnfd, F_SETLK, &fnfl);
643                    close(fnfd);
644            }
645    
646    }
647    #endif

Legend:
Removed from v.29  
changed lines
  Added in v.280

  ViewVC Help
Powered by ViewVC 1.1.26