1/*++
2/* NAME
3/*	deliver_flock 3
4/* SUMMARY
5/*	lock open file for mail delivery
6/* SYNOPSIS
7/*	#include <deliver_flock.h>
8/*
9/*	int	deliver_flock(fd, lock_style, why)
10/*	int	fd;
11/*	int	lock_style;
12/*	VSTRING	*why;
13/* DESCRIPTION
14/*	deliver_flock() sets one exclusive kernel lock on an open file,
15/*	for example in order to deliver mail.
16/*	It performs several non-blocking attempts to acquire an exclusive
17/*	lock before giving up.
18/*
19/*	Arguments:
20/* .IP fd
21/*	A file descriptor that is associated with an open file.
22/* .IP lock_style
23/*	A locking style defined in myflock(3).
24/* .IP why
25/*	A null pointer, or storage for diagnostics.
26/* DIAGNOSTICS
27/*	deliver_flock() returns -1 in case of problems, 0 in case
28/*	of success. The reason for failure is returned via the \fIwhy\fR
29/*	parameter.
30/* CONFIGURATION PARAMETERS
31/*	deliver_lock_attempts, number of locking attempts
32/*	deliver_lock_delay, time in seconds between attempts
33/*	sun_mailtool_compatibility, disable kernel locking
34/* LICENSE
35/* .ad
36/* .fi
37/*	The Secure Mailer license must be distributed with this software.
38/* AUTHOR(S)
39/*	Wietse Venema
40/*	IBM T.J. Watson Research
41/*	P.O. Box 704
42/*	Yorktown Heights, NY 10598, USA
43/*--*/
44
45/* System library. */
46
47#include "sys_defs.h"
48#include <unistd.h>
49
50/* Utility library. */
51
52#include <vstring.h>
53#include <myflock.h>
54#include <iostuff.h>
55
56/* Global library. */
57
58#include "mail_params.h"
59#include "deliver_flock.h"
60
61/* Application-specific. */
62
63#define MILLION	1000000
64
65/* deliver_flock - lock open file for mail delivery */
66
67int     deliver_flock(int fd, int lock_style, VSTRING *why)
68{
69    int     i;
70
71    for (i = 1; /* void */ ; i++) {
72	if (myflock(fd, lock_style,
73		    MYFLOCK_OP_EXCLUSIVE | MYFLOCK_OP_NOWAIT) == 0)
74	    return (0);
75	if (i >= var_flock_tries)
76	    break;
77	rand_sleep(var_flock_delay * MILLION, var_flock_delay * MILLION / 2);
78    }
79    if (why)
80	vstring_sprintf(why, "unable to lock for exclusive access: %m");
81    return (-1);
82}
83