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