7 /* lock mail folder and execute command
10 /* \fBpostlock\fR [\fB-c \fIconfig_dir\fB] [\fB-l \fIlock_style\fB]
11 /* [\fB-v\fR] \fIfile command...\fR
13 /* The \fBpostlock\fR(1) command locks \fIfile\fR for exclusive
14 /* access, and executes \fIcommand\fR. The locking method is
15 /* compatible with the Postfix UNIX-style local delivery agent.
18 /* .IP "\fB-c \fIconfig_dir\fR"
19 /* Read the \fBmain.cf\fR configuration file in the named directory
20 /* instead of the default configuration directory.
21 /* .IP "\fB-l \fIlock_style\fR"
22 /* Override the locking method specified via the
23 /* \fBmailbox_delivery_lock\fR configuration parameter (see below).
25 /* Enable verbose logging for debugging purposes. Multiple \fB-v\fR
26 /* options make the software increasingly verbose.
30 /* A mailbox file. The user should have read/write permission.
31 /* .IP \fIcommand...\fR
32 /* The command to execute while \fIfile\fR is locked for exclusive
33 /* access. The command is executed directly, i.e. without
34 /* interpretation by a shell command interpreter.
36 /* The result status is 75 (EX_TEMPFAIL) when \fBpostlock\fR(1)
37 /* could not perform the requested operation. Otherwise, the
38 /* exit status is the exit status from the command.
40 /* With remote file systems, the ability to acquire a lock does not
41 /* necessarily eliminate access conflicts. Avoid file access by
42 /* processes running on different machines.
46 /* .IP \fBMAIL_CONFIG\fR
47 /* Directory with Postfix configuration files.
48 /* .IP \fBMAIL_VERBOSE\fR
49 /* Enable verbose logging for debugging purposes.
50 /* CONFIGURATION PARAMETERS
53 /* The following \fBmain.cf\fR parameters are especially relevant to
55 /* The text below provides only a parameter summary. See
56 /* \fBpostconf\fR(5) for more details including examples.
60 /* .IP "\fBdeliver_lock_attempts (20)\fR"
61 /* The maximal number of attempts to acquire an exclusive lock on a
62 /* mailbox file or \fBbounce\fR(8) logfile.
63 /* .IP "\fBdeliver_lock_delay (1s)\fR"
64 /* The time between attempts to acquire an exclusive lock on a mailbox
65 /* file or \fBbounce\fR(8) logfile.
66 /* .IP "\fBstale_lock_time (500s)\fR"
67 /* The time after which a stale exclusive mailbox lockfile is removed.
68 /* .IP "\fBmailbox_delivery_lock (see 'postconf -d' output)\fR"
69 /* How to lock a UNIX-style \fBlocal\fR(8) mailbox before attempting delivery.
70 /* RESOURCE AND RATE CONTROLS
73 /* .IP "\fBfork_attempts (5)\fR"
74 /* The maximal number of attempts to fork() a child process.
75 /* .IP "\fBfork_delay (1s)\fR"
76 /* The delay between attempts to fork() a child process.
77 /* MISCELLANEOUS CONTROLS
80 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
81 /* The default location of the Postfix main.cf and master.cf
82 /* configuration files.
84 /* postconf(5), configuration parameters
88 /* The Secure Mailer license must be distributed with this software.
91 /* IBM T.J. Watson Research
93 /* Yorktown Heights, NY 10598, USA
100 #include <sys/wait.h>
106 /* Utility library. */
111 #include <msg_vstream.h>
114 /* Global library. */
116 #include <mail_params.h>
117 #include <mail_version.h>
118 #include <dot_lockfile.h>
119 #include <deliver_flock.h>
120 #include <mail_conf.h>
121 #include <sys_exits.h>
122 #include <mbox_conf.h>
123 #include <mbox_open.h>
124 #include <dsn_util.h>
126 /* Application-specific. */
128 /* usage - explain */
130 static NORETURN
usage(char *myname
)
132 msg_fatal("usage: %s [-c config_dir] [-l lock_style] [-v] folder command...", myname
);
135 /* fatal_exit - all failures are deemed recoverable */
137 static void fatal_exit(void)
142 MAIL_VERSION_STAMP_DECLARE
;
144 /* main - go for it */
146 int main(int argc
, char **argv
)
155 WAIT_STATUS_T status
;
158 char *lock_style
= 0;
162 * Fingerprint executables and core dumps.
164 MAIL_VERSION_STAMP_ALLOCATE
;
167 * Be consistent with file permissions.
172 * To minimize confusion, make sure that the standard file descriptors
173 * are open before opening anything else. XXX Work around for 44BSD where
174 * fstat can return EBADF on an open file descriptor.
176 for (fd
= 0; fd
< 3; fd
++)
177 if (fstat(fd
, &st
) == -1
178 && (close(fd
), open("/dev/null", O_RDWR
, 0)) != fd
)
179 msg_fatal("open /dev/null: %m");
182 * Process environment options as early as we can. We are not set-uid,
183 * and we are supposed to be running in a controlled environment.
185 if (getenv(CONF_ENV_VERB
))
189 * Set up logging and error handling. Intercept fatal exits so we can
190 * return a distinguished exit status.
192 msg_vstream_init(argv
[0], VSTREAM_ERR
);
193 msg_cleanup(fatal_exit
);
198 while ((ch
= GETOPT(argc
, argv
, "c:l:v")) > 0) {
204 if (setenv(CONF_ENV_PATH
, optarg
, 1) < 0)
205 msg_fatal("out of memory");
215 if (optind
+ 2 > argc
)
217 folder
= argv
[optind
];
218 command
= argv
+ optind
+ 1;
221 * Read the config file. The command line lock style can override the
222 * configured lock style.
225 lock_mask
= mbox_lock_mask(lock_style
? lock_style
:
226 get_mail_conf_str(VAR_MAILBOX_LOCK
, DEF_MAILBOX_LOCK
, 1, 0));
229 * Lock the folder for exclusive access. Lose the lock upon exit. The
230 * command is not supposed to disappear into the background.
233 if ((mp
= mbox_open(folder
, O_APPEND
| O_WRONLY
| O_CREAT
,
234 S_IRUSR
| S_IWUSR
, (struct stat
*) 0,
235 -1, -1, lock_mask
, "5.2.0", why
)) == 0)
236 msg_fatal("open file %s: %s", folder
, vstring_str(why
->reason
));
240 * Run the command. Remove the lock after completion.
242 for (count
= 1; (pid
= fork()) == -1; count
++) {
243 msg_warn("fork %s: %m", command
[0]);
244 if (count
>= var_fork_tries
) {
248 sleep(var_fork_delay
);
252 (void) msg_cleanup((MSG_CLEANUP_FN
) 0);
253 execvp(command
[0], command
);
254 msg_fatal("execvp %s: %m", command
[0]);
256 if (waitpid(pid
, &status
, 0) < 0)
257 msg_fatal("waitpid: %m");
258 vstream_fclose(mp
->fp
);
260 exit(WIFEXITED(status
) ? WEXITSTATUS(status
) : 1);