3
Copyright 1998 Rob Browning <rlb@defaultvalue.org>
5
This code is covered under the terms of the Gnu Public License.
6
See the accompanying COPYING file for details.
10
It might be useful at some point to support a --user option to
11
mail-lock that can only be used by the superuser (of course, they
12
could just use lockfile-create with an appropriate path...
26
#include <sys/types.h>
28
static const char *action = NULL;
29
static char *target_file = NULL;
30
static int retry_count = 9; /* This will be a maximum of 3 minutes */
31
static int touchlock_oneshot = 0;
33
/* not used yet, so not documented... */
34
static int lockfile_verbose = 0;
36
static int result = 0;
39
usage(const char *command_name, FILE *file) {
40
char *usage_str = NULL;
42
if(strcmp(command_name, "mail-lock") == 0) {
43
usage_str = "usage: mail-lock [ --retry retry-count ]\n";
44
} else if(strcmp(command_name, "mail-unlock") == 0) {
45
usage_str = "usage: mail-unlock\n";
46
} else if(strcmp(command_name, "mail-touchlock") == 0) {
47
usage_str = "usage: mail-touchlock [ --oneshot ]\n";
48
} else if(strcmp(command_name, "lockfile-create") == 0) {
49
usage_str = "usage: lockfile-create [ --retry retry-count ] file\n";
50
} else if(strcmp(command_name, "lockfile-remove") == 0) {
51
usage_str = "usage: lockfile-remove file\n";
52
} else if(strcmp(command_name, "lockfile-touch") == 0) {
53
usage_str = "usage: lockfile-touch [ --oneshot ] file\n";
55
fprintf(stderr, "lockfile: big problem unknown command name: %s\n",
59
fprintf(file, usage_str);
63
parse_arguments(const int argc, char *argv[]) {
66
struct option opt_specs[] = {
67
{ "retry", required_argument, NULL, 'r' },
68
{ "oneshot", no_argument, NULL, 'o' },
69
//{ "verbose", no_argument, NULL, 'v' },
73
char *cmd_name = rindex(argv[0], '/');
76
if(cmd_name != NULL) {
83
while((opt_result = getopt_long(argc, argv, "", opt_specs, NULL)) != -1) {
86
touchlock_oneshot = 1;
94
long tmp_value = strtol(optarg, &rest_of_string, 10);
96
if((tmp_value == 0) && (rest_of_string == optarg)) {
98
fprintf(stderr, "%s: bad retry-count value\n", cmd_name);
99
usage(cmd_name, stderr);
102
retry_count = tmp_value;
107
fprintf(stderr, "%s: getopt returned impossible value 0%o.\n",
108
cmd_name, opt_result);
114
if(strcmp(cmd_name, "mail-lock") == 0) {
118
else if(strcmp(cmd_name, "mail-unlock") == 0) {
122
else if(strcmp(cmd_name, "mail-touchlock") == 0) {
126
else if(strcmp(cmd_name, "lockfile-create") == 0) {
129
else if(strcmp(cmd_name, "lockfile-remove") == 0) {
132
else if(strcmp(cmd_name, "lockfile-touch") == 0) {
135
usage(cmd_name, stderr);
141
uid_t user_id = geteuid();
142
struct passwd *user_info = getpwuid(user_id);
144
if(user_info == NULL) {
145
fprintf(stderr, "%s: fatal error, can't find info for user id %ud\n",
150
if(asprintf(&target_file, "/var/spool/mail/%s",
151
user_info->pw_name) == -1) {
152
fprintf(stderr, "asprintf failed: line %d\n", __LINE__);
156
usage(cmd_name, stderr);
160
if((argc - optind) != 1) {
161
usage(cmd_name, stderr);
164
target_file = argv[optind];
169
handle_touchdeath(int sig) {
174
main(int argc, char *argv[]) {
175
char * lockfilename = NULL;
177
parse_arguments(argc, argv);
179
if(asprintf(&lockfilename, "%s.lock", target_file) == -1) {
180
fprintf(stderr, "asprintf failed: line %d\n", __LINE__);
184
if(strcmp(action, "unlock") == 0) {
185
result = lockfile_remove(lockfilename);
186
} else if(strcmp(action, "lock") == 0) {
187
if(lockfile_create(lockfilename, retry_count, 0) == L_SUCCESS) {
190
fprintf(stderr, "lockfile creation failed\n");
193
} else if(strcmp(action, "touch") == 0) {
194
signal(SIGTERM, handle_touchdeath);
196
if(touchlock_oneshot) {
197
result = lockfile_touch(lockfilename);
199
while(1 && (result == 0)) {
200
result = lockfile_touch(lockfilename);
206
if(lockfilename) free(lockfilename);