gpg: Fix bug parsing a zero length user id.
[gnupg.git] / common / dotlock.c
1 /* dotlock.c - dotfile locking
2  * Copyright (C) 1998, 2000, 2001, 2003, 2004,
3  *               2005, 2006, 2008, 2010, 2011 Free Software Foundation, Inc.
4  *
5  * This file is part of JNLIB, which is a subsystem of GnuPG.
6  *
7  * JNLIB is free software; you can redistribute it and/or modify it
8  * under the terms of either
9  *
10  *   - the GNU Lesser General Public License as published by the Free
11  *     Software Foundation; either version 3 of the License, or (at
12  *     your option) any later version.
13  *
14  * or
15  *
16  *   - the GNU General Public License as published by the Free
17  *     Software Foundation; either version 2 of the License, or (at
18  *     your option) any later version.
19  *
20  * or both in parallel, as here.
21  *
22  * JNLIB is distributed in the hope that it will be useful, but
23  * WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * General Public License for more details.
26  *
27  * You should have received a copies of the GNU General Public License
28  * and the GNU Lesser General Public License along with this program;
29  * if not, see <http://www.gnu.org/licenses/>.
30  *
31  * ALTERNATIVELY, this file may be distributed under the terms of the
32  * following license, in which case the provisions of this license are
33  * required INSTEAD OF the GNU Lesser General License or the GNU
34  * General Public License. If you wish to allow use of your version of
35  * this file only under the terms of the GNU Lesser General License or
36  * the GNU General Public License, and not to allow others to use your
37  * version of this file under the terms of the following license,
38  * indicate your decision by deleting this paragraph and the license
39  * below.
40  *
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that the following conditions
43  * are met:
44  *
45  * 1. Redistributions of source code must retain the above copyright
46  *    notice, and the entire permission notice in its entirety,
47  *    including the disclaimer of warranties.
48  * 2. Redistributions in binary form must reproduce the above copyright
49  *    notice, this list of conditions and the following disclaimer in the
50  *    documentation and/or other materials provided with the distribution.
51  * 3. The name of the author may not be used to endorse or promote
52  *    products derived from this software without specific prior
53  *    written permission.
54  *
55  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
56  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
57  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
58  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
59  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
60  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
61  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
63  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
64  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
65  * OF THE POSSIBILITY OF SUCH DAMAGE.
66  */
67
68 /*
69    Overview:
70    =========
71
72    This module implements advisory file locking in a portable way.
73    Due to the problems with POSIX fcntl locking a separate lock file
74    is used.  It would be possible to use fcntl locking on this lock
75    file and thus avoid the weird auto unlock bug of POSIX while still
76    having an unproved better performance of fcntl locking.  However
77    there are still problems left, thus we resort to use a hardlink
78    which has the well defined property that a link call will fail if
79    the target file already exists.
80
81    Given that hardlinks are also available on NTFS file systems since
82    Windows XP; it will be possible to enhance this module to use
83    hardlinks even on Windows and thus allow Windows and Posix clients
84    to use locking on the same directory.  This is not yet implemented;
85    instead we use a lockfile on Windows along with W32 style file
86    locking.
87
88    On FAT file systems hardlinks are not supported.  Thus this method
89    does not work.  Our solution is to use a O_EXCL locking instead.
90    Querying the type of the file system is not easy to do in a
91    portable way (e.g. Linux has a statfs, BSDs have a the same call
92    but using different structures and constants).  What we do instead
93    is to check at runtime whether link(2) works for a specific lock
94    file.
95
96
97    How to use:
98    ===========
99
100    At program initialization time, the module should be explicitly
101    initialized:
102
103       dotlock_create (NULL, 0);
104
105    This installs an atexit handler and may also initialize mutex etc.
106    It is optional for non-threaded applications.  Only the first call
107    has an effect.  This needs to be done before any extra threads are
108    started.
109
110    To create a lock file (which  prepares it but does not take the
111    lock) you do:
112
113      dotlock_t h
114
115      h = dotlock_create (fname, 0);
116      if (!h)
117        error ("error creating lock file: %s\n", strerror (errno));
118
119    It is important to handle the error.  For example on a read-only
120    file system a lock can't be created (but is usually not needed).
121    FNAME is the file you want to lock; the actual lockfile is that
122    name with the suffix ".lock" appended.  On success a handle to be
123    used with the other functions is returned or NULL on error.  Note
124    that the handle shall only be used by one thread at a time.  This
125    function creates a unique file temporary file (".#lk*") in the same
126    directory as FNAME and returns a handle for further operations.
127    The module keeps track of theses unique files so that they will be
128    unlinked using the atexit handler.  If you don't need the lock file
129    anymore, you may also explicitly remove it with a call to:
130
131      dotlock_destroy (h);
132
133    To actually lock the file, you use:
134
135      if (dotlock_take (h, -1))
136        error ("error taking lock: %s\n", strerror (errno));
137
138    This function will wait until the lock is acquired.  If an
139    unexpected error occurs if will return non-zero and set ERRNO.  If
140    you pass (0) instead of (-1) the function does not wait in case the
141    file is already locked but returns -1 and sets ERRNO to EACCES.
142    Any other positive value for the second parameter is considered a
143    timeout valuie in milliseconds.
144
145    To release the lock you call:
146
147      if (dotlock_release (h))
148        error ("error releasing lock: %s\n", strerror (errno));
149
150    or, if the lock file is not anymore needed, you may just call
151    dotlock_destroy.  However dotlock_release does some extra checks
152    before releasing the lock and prints diagnostics to help detecting
153    bugs.
154
155    If you want to explicitly destroy all lock files you may call
156
157      dotlock_remove_lockfiles ();
158
159    which is the core of the installed atexit handler.  In case your
160    application wants to disable locking completely it may call
161
162      disable_locking ()
163
164    before any locks are created.
165
166    There are two convenience functions to store an integer (e.g. a
167    file descriptor) value with the handle:
168
169      void dotlock_set_fd (dotlock_t h, int fd);
170      int  dotlock_get_fd (dotlock_t h);
171
172    If nothing has been stored dotlock_get_fd returns -1.
173
174
175
176    How to build:
177    =============
178
179    This module was originally developed for GnuPG but later changed to
180    allow its use without any GnuPG dependency.  If you want to use it
181    with you application you may simply use it and it should figure out
182    most things automagically.
183
184    You may use the common config.h file to pass macros, but take care
185    to pass -DHAVE_CONFIG_H to the compiler.  Macros used by this
186    module are:
187
188      DOTLOCK_USE_PTHREAD  - Define if POSIX threads are in use.
189
190      DOTLOCK_GLIB_LOGGING - Define this to use Glib logging functions.
191
192      DOTLOCK_EXT_SYM_PREFIX - Prefix all external symbols with the
193                               string to which this macro evaluates.
194
195      GNUPG_MAJOR_VERSION - Defined when used by GnuPG.
196
197      HAVE_DOSISH_SYSTEM  - Defined for Windows etc.  Will be
198                            automatically defined if a the target is
199                            Windows.
200
201      HAVE_POSIX_SYSTEM   - Internally defined to !HAVE_DOSISH_SYSTEM.
202
203      HAVE_SIGNAL_H       - Should be defined on Posix systems.  If config.h
204                            is not used defaults to defined.
205
206      DIRSEP_C            - Separation character for file name parts.
207                            Usually not redefined.
208
209      EXTSEP_S            - Separation string for file name suffixes.
210                            Usually not redefined.
211
212      HAVE_W32CE_SYSTEM   - Currently only used by GnuPG.
213
214    Note that there is a test program t-dotlock which has compile
215    instructions at its end.  At least for SMBFS and CIFS it is
216    important that 64 bit versions of stat are used; most programming
217    environments do this these days, just in case you want to compile
218    it on the command line, remember to pass -D_FILE_OFFSET_BITS=64
219
220
221    Bugs:
222    =====
223
224    On Windows this module is not yet thread-safe.
225
226
227    Miscellaneous notes:
228    ====================
229
230    On hardlinks:
231    - Hardlinks are supported under Windows with NTFS since XP/Server2003.
232    - In Linux 2.6.33 both SMBFS and CIFS seem to support hardlinks.
233    - NFS supports hard links.  But there are solvable problems.
234    - FAT does not support links
235
236    On the file locking API:
237    - CIFS on Linux 2.6.33 supports several locking methods.
238      SMBFS seems not to support locking.  No closer checks done.
239    - NFS supports Posix locks.  flock is emulated in the server.
240      However there are a couple of problems; see below.
241    - FAT does not support locks.
242    - An advantage of fcntl locking is that R/W locks can be
243      implemented which is not easy with a straight lock file.
244
245    On O_EXCL:
246    - Does not work reliable on NFS
247    - Should work on CIFS and SMBFS but how can we delete lockfiles?
248
249    On NFS problems:
250    - Locks vanish if the server crashes and reboots.
251    - Client crashes keep the lock in the server until the client
252      re-connects.
253    - Communication problems may return unreliable error codes.  The
254      MUA Postfix's workaround is to compare the link count after
255      seeing an error for link.  However that gives a race.  If using a
256      unique file to link to a lockfile and using stat to check the
257      link count instead of looking at the error return of link(2) is
258      the best solution.
259    - O_EXCL seems to have a race and may re-create a file anyway.
260
261 */
262
263 #ifdef HAVE_CONFIG_H
264 # include <config.h>
265 #endif
266
267 /* Some quick replacements for stuff we usually expect to be defined
268    in config.h.  Define HAVE_POSIX_SYSTEM for better readability. */
269 #if !defined (HAVE_DOSISH_SYSTEM) && defined(_WIN32)
270 # define HAVE_DOSISH_SYSTEM 1
271 #endif
272 #if !defined (HAVE_DOSISH_SYSTEM) && !defined (HAVE_POSIX_SYSTEM)
273 # define HAVE_POSIX_SYSTEM 1
274 #endif
275
276 /* With no config.h assume that we have sitgnal.h.  */
277 #if !defined (HAVE_CONFIG_H) && defined (HAVE_POSIX_SYSTEM)
278 # define HAVE_SIGNAL_H 1
279 #endif
280
281 /* Standard headers.  */
282 #include <stdlib.h>
283 #include <stdio.h>
284 #include <string.h>
285 #include <errno.h>
286 #include <ctype.h>
287 #include <errno.h>
288 #include <unistd.h>
289 #ifdef  HAVE_DOSISH_SYSTEM
290 # define WIN32_LEAN_AND_MEAN  /* We only need the OS core stuff.  */
291 # include <windows.h>
292 #else
293 # include <sys/types.h>
294 # include <sys/stat.h>
295 # include <sys/utsname.h>
296 #endif
297 #include <sys/types.h>
298 #include <sys/time.h>
299 #include <sys/stat.h>
300 #include <fcntl.h>
301 #ifdef HAVE_SIGNAL_H
302 # include <signal.h>
303 #endif
304 #ifdef DOTLOCK_USE_PTHREAD
305 # include <pthread.h>
306 #endif
307
308 #ifdef DOTLOCK_GLIB_LOGGING
309 # include <glib.h>
310 #endif
311
312 #ifdef GNUPG_MAJOR_VERSION
313 # include "libjnlib-config.h"
314 # include "stringhelp.h"  /* For stpcpy and w32_strerror. */
315 #endif
316 #ifdef HAVE_W32CE_SYSTEM
317 # include "utf8conv.h"  /* WindowsCE requires filename conversion.  */
318 #endif
319
320 #include "dotlock.h"
321
322
323 /* Define constants for file name construction.  */
324 #if !defined(DIRSEP_C) && !defined(EXTSEP_S)
325 # ifdef HAVE_DOSISH_SYSTEM
326 #  define DIRSEP_C '\\'
327 #  define EXTSEP_S "."
328 #else
329 #  define DIRSEP_C '/'
330 #  define EXTSEP_S "."
331 # endif
332 #endif
333
334 /* In GnuPG we use wrappers around the malloc fucntions.  If they are
335    not defined we assume that this code is used outside of GnuPG and
336    fall back to the regular malloc functions.  */
337 #ifndef jnlib_malloc
338 # define jnlib_malloc(a)     malloc ((a))
339 # define jnlib_calloc(a,b)   calloc ((a), (b))
340 # define jnlib_free(a)       free ((a))
341 #endif
342
343 /* Wrapper to set ERRNO.  */
344 #ifndef jnlib_set_errno
345 # ifdef HAVE_W32CE_SYSTEM
346 #  define jnlib_set_errno(e)  gpg_err_set_errno ((e))
347 # else
348 #  define jnlib_set_errno(e)  do { errno = (e); } while (0)
349 # endif
350 #endif
351
352 /* Gettext macro replacement.  */
353 #ifndef _
354 # define _(a) (a)
355 #endif
356
357 #ifdef GNUPG_MAJOR_VERSION
358 # define my_info_0(a)       log_info ((a))
359 # define my_info_1(a,b)     log_info ((a), (b))
360 # define my_info_2(a,b,c)   log_info ((a), (b), (c))
361 # define my_info_3(a,b,c,d) log_info ((a), (b), (c), (d))
362 # define my_error_0(a)      log_error ((a))
363 # define my_error_1(a,b)    log_error ((a), (b))
364 # define my_error_2(a,b,c)  log_error ((a), (b), (c))
365 # define my_debug_1(a,b)    log_debug ((a), (b))
366 # define my_fatal_0(a)      log_fatal ((a))
367 #elif defined (DOTLOCK_GLIB_LOGGING)
368 # define my_info_0(a)       g_message ((a))
369 # define my_info_1(a,b)     g_message ((a), (b))
370 # define my_info_2(a,b,c)   g_message ((a), (b), (c))
371 # define my_info_3(a,b,c,d) g_message ((a), (b), (c), (d))
372 # define my_error_0(a)      g_warning ((a))
373 # define my_error_1(a,b)    g_warning ((a), (b))
374 # define my_error_2(a,b,c)  g_warning ((a), (b), (c))
375 # define my_debug_1(a,b)    g_debug ((a), (b))
376 # define my_fatal_0(a)      g_error ((a))
377 #else
378 # define my_info_0(a)       fprintf (stderr, (a))
379 # define my_info_1(a,b)     fprintf (stderr, (a), (b))
380 # define my_info_2(a,b,c)   fprintf (stderr, (a), (b), (c))
381 # define my_info_3(a,b,c,d) fprintf (stderr, (a), (b), (c), (d))
382 # define my_error_0(a)      fprintf (stderr, (a))
383 # define my_error_1(a,b)    fprintf (stderr, (a), (b))
384 # define my_error_2(a,b,c)  fprintf (stderr, (a), (b), (c))
385 # define my_debug_1(a,b)    fprintf (stderr, (a), (b))
386 # define my_fatal_0(a)      do { fprintf (stderr,(a)); fflush (stderr); \
387                                  abort (); } while (0)
388 #endif
389
390
391
392
393 \f
394 /* The object describing a lock.  */
395 struct dotlock_handle
396 {
397   struct dotlock_handle *next;
398   char *lockname;            /* Name of the actual lockfile.          */
399   unsigned int locked:1;     /* Lock status.                          */
400   unsigned int disable:1;    /* If true, locking is disabled.         */
401   unsigned int use_o_excl:1; /* Use open (O_EXCL) for locking.        */
402
403   int extra_fd;              /* A place for the caller to store an FD.  */
404
405 #ifdef HAVE_DOSISH_SYSTEM
406   HANDLE lockhd;       /* The W32 handle of the lock file.      */
407 #else /*!HAVE_DOSISH_SYSTEM */
408   char *tname;         /* Name of the lockfile template.        */
409   size_t nodename_off; /* Offset in TNAME of the nodename part. */
410   size_t nodename_len; /* Length of the nodename part.          */
411 #endif /*!HAVE_DOSISH_SYSTEM */
412 };
413
414
415 /* A list of of all lock handles.  The volatile attribute might help
416    if used in an atexit handler.  */
417 static volatile dotlock_t all_lockfiles;
418 #ifdef DOTLOCK_USE_PTHREAD
419 static pthread_mutex_t all_lockfiles_mutex = PTHREAD_MUTEX_INITIALIZER;
420 # define LOCK_all_lockfiles() do {                               \
421         if (pthread_mutex_lock (&all_lockfiles_mutex))           \
422           my_fatal_0 ("locking all_lockfiles_mutex failed\n");   \
423       } while (0)
424 # define UNLOCK_all_lockfiles() do {                             \
425         if (pthread_mutex_unlock (&all_lockfiles_mutex))         \
426           my_fatal_0 ("unlocking all_lockfiles_mutex failed\n"); \
427       } while (0)
428 #else  /*!DOTLOCK_USE_PTHREAD*/
429 # define LOCK_all_lockfiles()   do { } while (0)
430 # define UNLOCK_all_lockfiles() do { } while (0)
431 #endif /*!DOTLOCK_USE_PTHREAD*/
432
433 /* If this has the value true all locking is disabled.  */
434 static int never_lock;
435
436
437
438
439 \f
440 /* Entirely disable all locking.  This function should be called
441    before any locking is done.  It may be called right at startup of
442    the process as it only sets a global value.  */
443 void
444 dotlock_disable (void)
445 {
446   never_lock = 1;
447 }
448
449
450 #ifdef HAVE_POSIX_SYSTEM
451 static int
452 maybe_deadlock (dotlock_t h)
453 {
454   dotlock_t r;
455   int res = 0;
456
457   LOCK_all_lockfiles ();
458   for (r=all_lockfiles; r; r = r->next)
459     {
460       if ( r != h && r->locked )
461         {
462           res = 1;
463           break;
464         }
465     }
466   UNLOCK_all_lockfiles ();
467   return res;
468 }
469 #endif /*HAVE_POSIX_SYSTEM*/
470
471
472 /* Read the lock file and return the pid, returns -1 on error.  True
473    will be stored in the integer at address SAME_NODE if the lock file
474    has been created on the same node. */
475 #ifdef HAVE_POSIX_SYSTEM
476 static int
477 read_lockfile (dotlock_t h, int *same_node )
478 {
479   char buffer_space[10+1+70+1]; /* 70 is just an estimated value; node
480                                    names are usually shorter. */
481   int fd;
482   int pid = -1;
483   char *buffer, *p;
484   size_t expected_len;
485   int res, nread;
486
487   *same_node = 0;
488   expected_len = 10 + 1 + h->nodename_len + 1;
489   if ( expected_len >= sizeof buffer_space)
490     {
491       buffer = jnlib_malloc (expected_len);
492       if (!buffer)
493         return -1;
494     }
495   else
496     buffer = buffer_space;
497
498   if ( (fd = open (h->lockname, O_RDONLY)) == -1 )
499     {
500       int e = errno;
501       my_info_2 ("error opening lockfile '%s': %s\n",
502                  h->lockname, strerror(errno) );
503       if (buffer != buffer_space)
504         jnlib_free (buffer);
505       jnlib_set_errno (e); /* Need to return ERRNO here. */
506       return -1;
507     }
508
509   p = buffer;
510   nread = 0;
511   do
512     {
513       res = read (fd, p, expected_len - nread);
514       if (res == -1 && errno == EINTR)
515         continue;
516       if (res < 0)
517         {
518           my_info_1 ("error reading lockfile '%s'\n", h->lockname );
519           close (fd);
520           if (buffer != buffer_space)
521             jnlib_free (buffer);
522           jnlib_set_errno (0); /* Do not return an inappropriate ERRNO. */
523           return -1;
524         }
525       p += res;
526       nread += res;
527     }
528   while (res && nread != expected_len);
529   close(fd);
530
531   if (nread < 11)
532     {
533       my_info_1 ("invalid size of lockfile '%s'\n", h->lockname);
534       if (buffer != buffer_space)
535         jnlib_free (buffer);
536       jnlib_set_errno (0); /* Better don't return an inappropriate ERRNO. */
537       return -1;
538     }
539
540   if (buffer[10] != '\n'
541       || (buffer[10] = 0, pid = atoi (buffer)) == -1
542       || !pid )
543     {
544       my_error_2 ("invalid pid %d in lockfile '%s'\n", pid, h->lockname);
545       if (buffer != buffer_space)
546         jnlib_free (buffer);
547       jnlib_set_errno (0);
548       return -1;
549     }
550
551   if (nread == expected_len
552       && !memcmp (h->tname+h->nodename_off, buffer+11, h->nodename_len)
553       && buffer[11+h->nodename_len] == '\n')
554     *same_node = 1;
555
556   if (buffer != buffer_space)
557     jnlib_free (buffer);
558   return pid;
559 }
560 #endif /*HAVE_POSIX_SYSTEM */
561
562
563 /* Check whether the file system which stores TNAME supports
564    hardlinks.  Instead of using the non-portable statsfs call which
565    differs between various Unix versions, we do a runtime test.
566    Returns: 0 supports hardlinks; 1 no hardlink support, -1 unknown
567    (test error).  */
568 #ifdef HAVE_POSIX_SYSTEM
569 static int
570 use_hardlinks_p (const char *tname)
571 {
572   char *lname;
573   struct stat sb;
574   unsigned int nlink;
575   int res;
576
577   if (stat (tname, &sb))
578     return -1;
579   nlink = (unsigned int)sb.st_nlink;
580
581   lname = jnlib_malloc (strlen (tname) + 1 + 1);
582   if (!lname)
583     return -1;
584   strcpy (lname, tname);
585   strcat (lname, "x");
586
587   /* We ignore the return value of link() because it is unreliable.  */
588   (void) link (tname, lname);
589
590   if (stat (tname, &sb))
591     res = -1;  /* Ooops.  */
592   else if (sb.st_nlink == nlink + 1)
593     res = 0;   /* Yeah, hardlinks are supported.  */
594   else
595     res = 1;   /* No hardlink support.  */
596
597   unlink (lname);
598   jnlib_free (lname);
599   return res;
600 }
601 #endif /*HAVE_POSIX_SYSTEM */
602
603
604 \f
605 #ifdef  HAVE_POSIX_SYSTEM
606 /* Locking core for Unix.  It used a temporary file and the link
607    system call to make locking an atomic operation. */
608 static dotlock_t
609 dotlock_create_unix (dotlock_t h, const char *file_to_lock)
610 {
611   int  fd = -1;
612   char pidstr[16];
613   const char *nodename;
614   const char *dirpart;
615   int dirpartlen;
616   struct utsname utsbuf;
617   size_t tnamelen;
618
619   snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid() );
620
621   /* Create a temporary file. */
622   if ( uname ( &utsbuf ) )
623     nodename = "unknown";
624   else
625     nodename = utsbuf.nodename;
626
627   if ( !(dirpart = strrchr (file_to_lock, DIRSEP_C)) )
628     {
629       dirpart = EXTSEP_S;
630       dirpartlen = 1;
631     }
632   else
633     {
634       dirpartlen = dirpart - file_to_lock;
635       dirpart = file_to_lock;
636     }
637
638   LOCK_all_lockfiles ();
639   h->next = all_lockfiles;
640   all_lockfiles = h;
641
642   tnamelen = dirpartlen + 6 + 30 + strlen(nodename) + 10 + 1;
643   h->tname = jnlib_malloc (tnamelen + 1);
644   if (!h->tname)
645     {
646       all_lockfiles = h->next;
647       UNLOCK_all_lockfiles ();
648       jnlib_free (h);
649       return NULL;
650     }
651   h->nodename_len = strlen (nodename);
652
653   snprintf (h->tname, tnamelen, "%.*s/.#lk%p.", dirpartlen, dirpart, h );
654   h->nodename_off = strlen (h->tname);
655   snprintf (h->tname+h->nodename_off, tnamelen - h->nodename_off,
656            "%s.%d", nodename, (int)getpid ());
657
658   do
659     {
660       jnlib_set_errno (0);
661       fd = open (h->tname, O_WRONLY|O_CREAT|O_EXCL,
662                  S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
663     }
664   while (fd == -1 && errno == EINTR);
665
666   if ( fd == -1 )
667     {
668       all_lockfiles = h->next;
669       UNLOCK_all_lockfiles ();
670       my_error_2 (_("failed to create temporary file '%s': %s\n"),
671                   h->tname, strerror(errno));
672       jnlib_free (h->tname);
673       jnlib_free (h);
674       return NULL;
675     }
676   if ( write (fd, pidstr, 11 ) != 11 )
677     goto write_failed;
678   if ( write (fd, nodename, strlen (nodename) ) != strlen (nodename) )
679     goto write_failed;
680   if ( write (fd, "\n", 1 ) != 1 )
681     goto write_failed;
682   if ( close (fd) )
683     goto write_failed;
684
685   /* Check whether we support hard links.  */
686   switch (use_hardlinks_p (h->tname))
687     {
688     case 0: /* Yes.  */
689       break;
690     case 1: /* No.  */
691       unlink (h->tname);
692       h->use_o_excl = 1;
693       break;
694     default:
695       my_error_2 ("can't check whether hardlinks are supported for '%s': %s\n",
696                   h->tname, strerror(errno));
697       goto write_failed;
698     }
699
700   h->lockname = jnlib_malloc (strlen (file_to_lock) + 6 );
701   if (!h->lockname)
702     {
703       all_lockfiles = h->next;
704       UNLOCK_all_lockfiles ();
705       unlink (h->tname);
706       jnlib_free (h->tname);
707       jnlib_free (h);
708       return NULL;
709     }
710   strcpy (stpcpy (h->lockname, file_to_lock), EXTSEP_S "lock");
711   UNLOCK_all_lockfiles ();
712   if (h->use_o_excl)
713     my_debug_1 ("locking for '%s' done via O_EXCL\n", h->lockname);
714
715   return h;
716
717  write_failed:
718   all_lockfiles = h->next;
719   UNLOCK_all_lockfiles ();
720   my_error_2 (_("error writing to '%s': %s\n"), h->tname, strerror (errno));
721   close (fd);
722   unlink (h->tname);
723   jnlib_free (h->tname);
724   jnlib_free (h);
725   return NULL;
726 }
727 #endif /*HAVE_POSIX_SYSTEM*/
728
729
730 #ifdef HAVE_DOSISH_SYSTEM
731 /* Locking core for Windows.  This version does not need a temporary
732    file but uses the plain lock file along with record locking.  We
733    create this file here so that we later only need to do the file
734    locking.  For error reporting it is useful to keep the name of the
735    file in the handle.  */
736 static dotlock_t
737 dotlock_create_w32 (dotlock_t h, const char *file_to_lock)
738 {
739   LOCK_all_lockfiles ();
740   h->next = all_lockfiles;
741   all_lockfiles = h;
742
743   h->lockname = jnlib_malloc ( strlen (file_to_lock) + 6 );
744   if (!h->lockname)
745     {
746       all_lockfiles = h->next;
747       UNLOCK_all_lockfiles ();
748       jnlib_free (h);
749       return NULL;
750     }
751   strcpy (stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock");
752
753   /* If would be nice if we would use the FILE_FLAG_DELETE_ON_CLOSE
754      along with FILE_SHARE_DELETE but that does not work due to a race
755      condition: Despite the OPEN_ALWAYS flag CreateFile may return an
756      error and we can't reliable create/open the lock file unless we
757      would wait here until it works - however there are other valid
758      reasons why a lock file can't be created and thus the process
759      would not stop as expected but spin until Windows crashes.  Our
760      solution is to keep the lock file open; that does not harm. */
761   {
762 #ifdef HAVE_W32CE_SYSTEM
763     wchar_t *wname = utf8_to_wchar (h->lockname);
764
765     if (wname)
766       h->lockhd = CreateFile (wname,
767                               GENERIC_READ|GENERIC_WRITE,
768                               FILE_SHARE_READ|FILE_SHARE_WRITE,
769                               NULL, OPEN_ALWAYS, 0, NULL);
770     else
771       h->lockhd = INVALID_HANDLE_VALUE;
772     jnlib_free (wname);
773 #else
774     h->lockhd = CreateFile (h->lockname,
775                             GENERIC_READ|GENERIC_WRITE,
776                             FILE_SHARE_READ|FILE_SHARE_WRITE,
777                             NULL, OPEN_ALWAYS, 0, NULL);
778 #endif
779   }
780   if (h->lockhd == INVALID_HANDLE_VALUE)
781     {
782       all_lockfiles = h->next;
783       UNLOCK_all_lockfiles ();
784       my_error_2 (_("can't create '%s': %s\n"), h->lockname, w32_strerror (-1));
785       jnlib_free (h->lockname);
786       jnlib_free (h);
787       return NULL;
788     }
789   return h;
790 }
791 #endif /*HAVE_DOSISH_SYSTEM*/
792
793
794 /* Create a lockfile for a file name FILE_TO_LOCK and returns an
795    object of type dotlock_t which may be used later to actually acquire
796    the lock.  A cleanup routine gets installed to cleanup left over
797    locks or other files used internally by the lock mechanism.
798
799    Calling this function with NULL does only install the atexit
800    handler and may thus be used to assure that the cleanup is called
801    after all other atexit handlers.
802
803    This function creates a lock file in the same directory as
804    FILE_TO_LOCK using that name and a suffix of ".lock".  Note that on
805    POSIX systems a temporary file ".#lk.<hostname>.pid[.threadid] is
806    used.
807
808    FLAGS must be 0.
809
810    The function returns an new handle which needs to be released using
811    destroy_dotlock but gets also released at the termination of the
812    process.  On error NULL is returned.
813  */
814
815 dotlock_t
816 dotlock_create (const char *file_to_lock, unsigned int flags)
817 {
818   static int initialized;
819   dotlock_t h;
820
821   if ( !initialized )
822     {
823       atexit (dotlock_remove_lockfiles);
824       initialized = 1;
825     }
826
827   if ( !file_to_lock )
828     return NULL;  /* Only initialization was requested.  */
829
830   if (flags)
831     {
832       jnlib_set_errno (EINVAL);
833       return NULL;
834     }
835
836   h = jnlib_calloc (1, sizeof *h);
837   if (!h)
838     return NULL;
839   h->extra_fd = -1;
840
841   if (never_lock)
842     {
843       h->disable = 1;
844       LOCK_all_lockfiles ();
845       h->next = all_lockfiles;
846       all_lockfiles = h;
847       UNLOCK_all_lockfiles ();
848       return h;
849     }
850
851 #ifdef HAVE_DOSISH_SYSTEM
852   return dotlock_create_w32 (h, file_to_lock);
853 #else /*!HAVE_DOSISH_SYSTEM */
854   return dotlock_create_unix (h, file_to_lock);
855 #endif /*!HAVE_DOSISH_SYSTEM*/
856 }
857
858
859 \f
860 /* Convenience function to store a file descriptor (or any any other
861    integer value) in the context of handle H.  */
862 void
863 dotlock_set_fd (dotlock_t h, int fd)
864 {
865   h->extra_fd = fd;
866 }
867
868 /* Convenience function to retrieve a file descriptor (or any any other
869    integer value) stored in the context of handle H.  */
870 int
871 dotlock_get_fd (dotlock_t h)
872 {
873   return h->extra_fd;
874 }
875
876
877 \f
878 #ifdef HAVE_POSIX_SYSTEM
879 /* Unix specific code of destroy_dotlock.  */
880 static void
881 dotlock_destroy_unix (dotlock_t h)
882 {
883   if (h->locked && h->lockname)
884     unlink (h->lockname);
885   if (h->tname && !h->use_o_excl)
886     unlink (h->tname);
887   jnlib_free (h->tname);
888 }
889 #endif /*HAVE_POSIX_SYSTEM*/
890
891
892 #ifdef HAVE_DOSISH_SYSTEM
893 /* Windows specific code of destroy_dotlock.  */
894 static void
895 dotlock_destroy_w32 (dotlock_t h)
896 {
897   if (h->locked)
898     {
899       OVERLAPPED ovl;
900
901       memset (&ovl, 0, sizeof ovl);
902       UnlockFileEx (h->lockhd, 0, 1, 0, &ovl);
903     }
904   CloseHandle (h->lockhd);
905 }
906 #endif /*HAVE_DOSISH_SYSTEM*/
907
908
909 /* Destroy the locck handle H and release the lock.  */
910 void
911 dotlock_destroy (dotlock_t h)
912 {
913   dotlock_t hprev, htmp;
914
915   if ( !h )
916     return;
917
918   /* First remove the handle from our global list of all locks. */
919   LOCK_all_lockfiles ();
920   for (hprev=NULL, htmp=all_lockfiles; htmp; hprev=htmp, htmp=htmp->next)
921     if (htmp == h)
922       {
923         if (hprev)
924           hprev->next = htmp->next;
925         else
926           all_lockfiles = htmp->next;
927         h->next = NULL;
928         break;
929       }
930   UNLOCK_all_lockfiles ();
931
932   /* Then destroy the lock. */
933   if (!h->disable)
934     {
935 #ifdef HAVE_DOSISH_SYSTEM
936       dotlock_destroy_w32 (h);
937 #else /* !HAVE_DOSISH_SYSTEM */
938       dotlock_destroy_unix (h);
939 #endif /* HAVE_DOSISH_SYSTEM */
940       jnlib_free (h->lockname);
941     }
942   jnlib_free(h);
943 }
944
945
946 \f
947 #ifdef HAVE_POSIX_SYSTEM
948 /* Unix specific code of make_dotlock.  Returns 0 on success and -1 on
949    error.  */
950 static int
951 dotlock_take_unix (dotlock_t h, long timeout)
952 {
953   int wtime = 0;
954   int sumtime = 0;
955   int pid;
956   int lastpid = -1;
957   int ownerchanged;
958   const char *maybe_dead="";
959   int same_node;
960
961  again:
962   if (h->use_o_excl)
963     {
964       /* No hardlink support - use open(O_EXCL).  */
965       int fd;
966
967       do
968         {
969           jnlib_set_errno (0);
970           fd = open (h->lockname, O_WRONLY|O_CREAT|O_EXCL,
971                      S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
972         }
973       while (fd == -1 && errno == EINTR);
974
975       if (fd == -1 && errno == EEXIST)
976         ; /* Lock held by another process.  */
977       else if (fd == -1)
978         {
979           my_error_2 ("lock not made: open(O_EXCL) of '%s' failed: %s\n",
980                       h->lockname, strerror (errno));
981           return -1;
982         }
983       else
984         {
985           char pidstr[16];
986
987           snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid());
988           if (write (fd, pidstr, 11 ) == 11
989               && write (fd, h->tname + h->nodename_off,h->nodename_len)
990               == h->nodename_len
991               && write (fd, "\n", 1) == 1
992               && !close (fd))
993             {
994               h->locked = 1;
995               return 0;
996             }
997           /* Write error.  */
998           my_error_2 ("lock not made: writing to '%s' failed: %s\n",
999                       h->lockname, strerror (errno));
1000           close (fd);
1001           unlink (h->lockname);
1002           return -1;
1003         }
1004     }
1005   else /* Standard method:  Use hardlinks.  */
1006     {
1007       struct stat sb;
1008
1009       /* We ignore the return value of link() because it is unreliable.  */
1010       (void) link (h->tname, h->lockname);
1011
1012       if (stat (h->tname, &sb))
1013         {
1014           my_error_1 ("lock not made: Oops: stat of tmp file failed: %s\n",
1015                       strerror (errno));
1016           /* In theory this might be a severe error: It is possible
1017              that link succeeded but stat failed due to changed
1018              permissions.  We can't do anything about it, though.  */
1019           return -1;
1020         }
1021
1022       if (sb.st_nlink == 2)
1023         {
1024           h->locked = 1;
1025           return 0; /* Okay.  */
1026         }
1027     }
1028
1029   /* Check for stale lock files.  */
1030   if ( (pid = read_lockfile (h, &same_node)) == -1 )
1031     {
1032       if ( errno != ENOENT )
1033         {
1034           my_info_0 ("cannot read lockfile\n");
1035           return -1;
1036         }
1037       my_info_0 ("lockfile disappeared\n");
1038       goto again;
1039     }
1040   else if ( pid == getpid() && same_node )
1041     {
1042       my_info_0 ("Oops: lock already held by us\n");
1043       h->locked = 1;
1044       return 0; /* okay */
1045     }
1046   else if ( same_node && kill (pid, 0) && errno == ESRCH )
1047     {
1048       /* Note: It is unlikley that we get a race here unless a pid is
1049          reused too fast or a new process with the same pid as the one
1050          of the stale file tries to lock right at the same time as we.  */
1051       my_info_1 (_("removing stale lockfile (created by %d)\n"), pid);
1052       unlink (h->lockname);
1053       goto again;
1054     }
1055
1056   if (lastpid == -1)
1057     lastpid = pid;
1058   ownerchanged = (pid != lastpid);
1059
1060   if (timeout)
1061     {
1062       struct timeval tv;
1063
1064       /* Wait until lock has been released.  We use increasing retry
1065          intervals of 50ms, 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s
1066          but reset it if the lock owner meanwhile changed.  */
1067       if (!wtime || ownerchanged)
1068         wtime = 50;
1069       else if (wtime < 800)
1070         wtime *= 2;
1071       else if (wtime == 800)
1072         wtime = 2000;
1073       else if (wtime < 8000)
1074         wtime *= 2;
1075
1076       if (timeout > 0)
1077         {
1078           if (wtime > timeout)
1079             wtime = timeout;
1080           timeout -= wtime;
1081         }
1082
1083       sumtime += wtime;
1084       if (sumtime >= 1500)
1085         {
1086           sumtime = 0;
1087           my_info_3 (_("waiting for lock (held by %d%s) %s...\n"),
1088                      pid, maybe_dead, maybe_deadlock(h)? _("(deadlock?) "):"");
1089         }
1090
1091
1092       tv.tv_sec = wtime / 1000;
1093       tv.tv_usec = (wtime % 1000) * 1000;
1094       select (0, NULL, NULL, NULL, &tv);
1095       goto again;
1096     }
1097
1098   jnlib_set_errno (EACCES);
1099   return -1;
1100 }
1101 #endif /*HAVE_POSIX_SYSTEM*/
1102
1103
1104 #ifdef HAVE_DOSISH_SYSTEM
1105 /* Windows specific code of make_dotlock.  Returns 0 on success and -1 on
1106    error.  */
1107 static int
1108 dotlock_take_w32 (dotlock_t h, long timeout)
1109 {
1110   int wtime = 0;
1111   int w32err;
1112   OVERLAPPED ovl;
1113
1114  again:
1115   /* Lock one byte at offset 0.  The offset is given by OVL.  */
1116   memset (&ovl, 0, sizeof ovl);
1117   if (LockFileEx (h->lockhd, (LOCKFILE_EXCLUSIVE_LOCK
1118                               | LOCKFILE_FAIL_IMMEDIATELY), 0, 1, 0, &ovl))
1119     {
1120       h->locked = 1;
1121       return 0; /* okay */
1122     }
1123
1124   w32err = GetLastError ();
1125   if (w32err != ERROR_LOCK_VIOLATION)
1126     {
1127       my_error_2 (_("lock '%s' not made: %s\n"),
1128                   h->lockname, w32_strerror (w32err));
1129       return -1;
1130     }
1131
1132   if (timeout)
1133     {
1134       /* Wait until lock has been released.  We use retry intervals of
1135          50ms, 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s.  */
1136       if (!wtime)
1137         wtime = 50;
1138       else if (wtime < 800)
1139         wtime *= 2;
1140       else if (wtime == 800)
1141         wtime = 2000;
1142       else if (wtime < 8000)
1143         wtime *= 2;
1144
1145       if (timeout > 0)
1146         {
1147           if (wtime > timeout)
1148             wtime = timeout;
1149           timeout -= wtime;
1150         }
1151
1152       if (wtime >= 800)
1153         my_info_1 (_("waiting for lock %s...\n"), h->lockname);
1154
1155       Sleep (wtime);
1156       goto again;
1157     }
1158
1159   return -1;
1160 }
1161 #endif /*HAVE_DOSISH_SYSTEM*/
1162
1163
1164 /* Take a lock on H.  A value of 0 for TIMEOUT returns immediately if
1165    the lock can't be taked, -1 waits forever (hopefully not), other
1166    values wait for TIMEOUT milliseconds.  Returns: 0 on success  */
1167 int
1168 dotlock_take (dotlock_t h, long timeout)
1169 {
1170   int ret;
1171
1172   if ( h->disable )
1173     return 0; /* Locks are completely disabled.  Return success. */
1174
1175   if ( h->locked )
1176     {
1177       my_debug_1 ("Oops, '%s' is already locked\n", h->lockname);
1178       return 0;
1179     }
1180
1181 #ifdef HAVE_DOSISH_SYSTEM
1182   ret = dotlock_take_w32 (h, timeout);
1183 #else /*!HAVE_DOSISH_SYSTEM*/
1184   ret = dotlock_take_unix (h, timeout);
1185 #endif /*!HAVE_DOSISH_SYSTEM*/
1186
1187   return ret;
1188 }
1189
1190
1191 \f
1192 #ifdef HAVE_POSIX_SYSTEM
1193 /* Unix specific code of release_dotlock.  */
1194 static int
1195 dotlock_release_unix (dotlock_t h)
1196 {
1197   int pid, same_node;
1198
1199   pid = read_lockfile (h, &same_node);
1200   if ( pid == -1 )
1201     {
1202       my_error_0 ("release_dotlock: lockfile error\n");
1203       return -1;
1204     }
1205   if ( pid != getpid() || !same_node )
1206     {
1207       my_error_1 ("release_dotlock: not our lock (pid=%d)\n", pid);
1208       return -1;
1209     }
1210
1211   if ( unlink( h->lockname ) )
1212     {
1213       my_error_1 ("release_dotlock: error removing lockfile '%s'\n",
1214                   h->lockname);
1215       return -1;
1216     }
1217   /* Fixme: As an extra check we could check whether the link count is
1218      now really at 1. */
1219   return 0;
1220 }
1221 #endif /*HAVE_POSIX_SYSTEM */
1222
1223
1224 #ifdef HAVE_DOSISH_SYSTEM
1225 /* Windows specific code of release_dotlock.  */
1226 static int
1227 dotlock_release_w32 (dotlock_t h)
1228 {
1229   OVERLAPPED ovl;
1230
1231   memset (&ovl, 0, sizeof ovl);
1232   if (!UnlockFileEx (h->lockhd, 0, 1, 0, &ovl))
1233     {
1234       my_error_2 ("release_dotlock: error removing lockfile '%s': %s\n",
1235                   h->lockname, w32_strerror (-1));
1236       return -1;
1237     }
1238
1239   return 0;
1240 }
1241 #endif /*HAVE_DOSISH_SYSTEM */
1242
1243
1244 /* Release a lock.  Returns 0 on success.  */
1245 int
1246 dotlock_release (dotlock_t h)
1247 {
1248   int ret;
1249
1250   /* To avoid atexit race conditions we first check whether there are
1251      any locks left.  It might happen that another atexit handler
1252      tries to release the lock while the atexit handler of this module
1253      already ran and thus H is undefined.  */
1254   LOCK_all_lockfiles ();
1255   ret = !all_lockfiles;
1256   UNLOCK_all_lockfiles ();
1257   if (ret)
1258     return 0;
1259
1260   if ( h->disable )
1261     return 0;
1262
1263   if ( !h->locked )
1264     {
1265       my_debug_1 ("Oops, '%s' is not locked\n", h->lockname);
1266       return 0;
1267     }
1268
1269 #ifdef HAVE_DOSISH_SYSTEM
1270   ret = dotlock_release_w32 (h);
1271 #else
1272   ret = dotlock_release_unix (h);
1273 #endif
1274
1275   if (!ret)
1276     h->locked = 0;
1277   return ret;
1278 }
1279
1280
1281 \f
1282 /* Remove all lockfiles.  This is called by the atexit handler
1283    installed by this module but may also be called by other
1284    termination handlers.  */
1285 void
1286 dotlock_remove_lockfiles (void)
1287 {
1288   dotlock_t h, h2;
1289
1290   /* First set the lockfiles list to NULL so that for example
1291      dotlock_release is ware that this fucntion is currently
1292      running.  */
1293   LOCK_all_lockfiles ();
1294   h = all_lockfiles;
1295   all_lockfiles = NULL;
1296   UNLOCK_all_lockfiles ();
1297
1298   while ( h )
1299     {
1300       h2 = h->next;
1301       dotlock_destroy (h);
1302       h = h2;
1303     }
1304 }