~ubuntu-branches/ubuntu/karmic/lockfile-progs/karmic

« back to all changes in this revision

Viewing changes to lockfile-progs.c

  • Committer: Bazaar Package Importer
  • Author(s): Rob Browning
  • Date: 2001-07-17 12:38:34 UTC
  • Revision ID: james.westby@ubuntu.com-20010717123834-brt4d52ox8xhx81e
Tags: 0.1.9
* Add command tool names to manpages. (closes: #88510)
* Update my email address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* lockfile-progs.c
 
2
 
 
3
   Copyright 1998 Rob Browning <rlb@defaultvalue.org>
 
4
 
 
5
   This code is covered under the terms of the Gnu Public License.
 
6
   See the accompanying COPYING file for details.
 
7
 
 
8
  To do:
 
9
 
 
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...
 
13
 
 
14
*/
 
15
 
 
16
#define _GNU_SOURCE
 
17
 
 
18
#include <lockfile.h>
 
19
#include <unistd.h>
 
20
#include <stdlib.h>
 
21
#include <stdio.h>
 
22
#include <signal.h>
 
23
#include <string.h>
 
24
#include <getopt.h>
 
25
#include <pwd.h>
 
26
#include <sys/types.h>
 
27
 
 
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;
 
32
 
 
33
/* not used yet, so not documented... */
 
34
static int lockfile_verbose = 0;
 
35
 
 
36
static int result = 0;
 
37
 
 
38
static void
 
39
usage(const char *command_name, FILE *file) {
 
40
  char *usage_str = NULL;
 
41
 
 
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";
 
54
  } else {
 
55
    fprintf(stderr, "lockfile: big problem unknown command name: %s\n",
 
56
            command_name);
 
57
    exit(1);
 
58
  }
 
59
  fprintf(file, usage_str);
 
60
}
 
61
 
 
62
static void
 
63
parse_arguments(const int argc, char *argv[]) {
 
64
 
 
65
  int opt_result;
 
66
  struct option opt_specs[] = {
 
67
    { "retry", required_argument, NULL, 'r' },
 
68
    { "oneshot", no_argument, NULL, 'o' },
 
69
    //{ "verbose", no_argument, NULL, 'v' },
 
70
    { NULL, 0, NULL, 0 }
 
71
  };
 
72
  
 
73
  char *cmd_name = rindex(argv[0], '/');
 
74
  int mail_cmd_p = 0;
 
75
  
 
76
  if(cmd_name != NULL) {
 
77
    /* Skip the '/' */
 
78
    cmd_name++;
 
79
  } else {
 
80
    cmd_name = argv[0];
 
81
  }
 
82
 
 
83
  while((opt_result = getopt_long(argc, argv, "", opt_specs, NULL)) != -1) {
 
84
    switch(opt_result) {
 
85
      case 'o':
 
86
        touchlock_oneshot = 1;
 
87
        break;
 
88
      case 'v':
 
89
        lockfile_verbose = 1;
 
90
        break;
 
91
      case 'r':
 
92
        {
 
93
          char *rest_of_string;
 
94
          long tmp_value = strtol(optarg, &rest_of_string, 10);
 
95
          
 
96
          if((tmp_value == 0) && (rest_of_string == optarg)) {
 
97
            /* Bad value */
 
98
            fprintf(stderr, "%s: bad retry-count value\n", cmd_name);
 
99
            usage(cmd_name, stderr);
 
100
            exit(1);
 
101
          } else {
 
102
            retry_count = tmp_value;
 
103
          }
 
104
        }
 
105
        break;
 
106
      default:
 
107
        fprintf(stderr, "%s: getopt returned impossible value 0%o.\n",
 
108
                cmd_name, opt_result);
 
109
        exit(1);
 
110
        break;
 
111
    }
 
112
  }
 
113
  
 
114
  if(strcmp(cmd_name, "mail-lock") == 0) {
 
115
    action = "lock";
 
116
    mail_cmd_p = 1;
 
117
  } 
 
118
  else if(strcmp(cmd_name, "mail-unlock") == 0) {
 
119
    action = "unlock";
 
120
    mail_cmd_p = 1;
 
121
  }
 
122
  else if(strcmp(cmd_name, "mail-touchlock") == 0) {
 
123
    action = "touch";
 
124
    mail_cmd_p = 1;
 
125
  }
 
126
  else if(strcmp(cmd_name, "lockfile-create") == 0) {
 
127
    action = "lock";
 
128
  } 
 
129
  else if(strcmp(cmd_name, "lockfile-remove") == 0) {
 
130
    action = "unlock";
 
131
  }
 
132
  else if(strcmp(cmd_name, "lockfile-touch") == 0) {
 
133
    action = "touch";
 
134
  } else {
 
135
    usage(cmd_name, stderr);
 
136
    exit(1);
 
137
  }
 
138
 
 
139
  if(mail_cmd_p) {
 
140
    if(optind == argc) {
 
141
      uid_t user_id = geteuid();
 
142
      struct passwd *user_info = getpwuid(user_id);
 
143
 
 
144
      if(user_info == NULL) {
 
145
        fprintf(stderr, "%s: fatal error, can't find info for user id %ud\n",
 
146
                cmd_name, user_id);
 
147
        exit(1);
 
148
      }
 
149
      
 
150
      if(asprintf(&target_file, "/var/spool/mail/%s",
 
151
                  user_info->pw_name) == -1) {
 
152
        fprintf(stderr, "asprintf failed: line %d\n", __LINE__);
 
153
        exit(1);
 
154
      }
 
155
    } else {
 
156
      usage(cmd_name, stderr);
 
157
      exit(1);
 
158
    }
 
159
  } else {
 
160
    if((argc - optind) != 1) {
 
161
      usage(cmd_name, stderr);
 
162
      exit(1);
 
163
    }
 
164
    target_file = argv[optind];
 
165
  }
 
166
}
 
167
 
 
168
static void
 
169
handle_touchdeath(int sig) {
 
170
  exit(result);
 
171
}
 
172
 
 
173
int
 
174
main(int argc, char *argv[]) {
 
175
  char * lockfilename = NULL;
 
176
 
 
177
  parse_arguments(argc, argv);
 
178
 
 
179
  if(asprintf(&lockfilename, "%s.lock", target_file) == -1) {
 
180
    fprintf(stderr, "asprintf failed: line %d\n", __LINE__);
 
181
    exit(1);
 
182
  }
 
183
  
 
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) {
 
188
      result = 0;
 
189
    } else {
 
190
      fprintf(stderr, "lockfile creation failed\n");
 
191
      result = 1;
 
192
    }
 
193
  } else if(strcmp(action, "touch") == 0) {
 
194
    signal(SIGTERM, handle_touchdeath);
 
195
 
 
196
    if(touchlock_oneshot) {
 
197
      result = lockfile_touch(lockfilename);
 
198
    } else {
 
199
      while(1 && (result == 0)) {
 
200
        result = lockfile_touch(lockfilename);
 
201
        sleep(60);
 
202
      }
 
203
    }
 
204
  }
 
205
 
 
206
  if(lockfilename) free(lockfilename);
 
207
  return(result);
 
208
}