/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to plugin-runner.c

  • Committer: Teddy Hogeborn
  • Date: 2008-08-15 21:09:25 UTC
  • mfrom: (24.1.52 mandos)
  • Revision ID: teddy@fukt.bsnet.se-20080815210925-32718zu3nrlotix5
Merge.

* plugin-runner.c (ARGFILE): Renamed to "plugin-runner.conf".

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 * Contact the authors at <mandos@fukt.bsnet.se>.
22
22
 */
23
23
 
24
 
#define _GNU_SOURCE             /* TEMP_FAILURE_RETRY() */
 
24
#define _GNU_SOURCE             /* TEMP_FAILURE_RETRY(), getline() */
25
25
 
26
26
#include <stddef.h>             /* size_t, NULL */
27
27
#include <stdlib.h>             /* malloc(), exit(), EXIT_FAILURE,
65
65
#include <errno.h>              /* errno, EBADF */
66
66
 
67
67
#define BUFFER_SIZE 256
 
68
#define ARGFILE "/conf/conf.d/mandos/plugin-runner.conf"
68
69
 
69
70
const char *argp_program_version = "plugin-runner 1.0";
70
71
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
185
186
  return true;
186
187
}
187
188
 
 
189
char ** addcustomargument(char **argv, int *argc, char *arg){
 
190
 
 
191
  if (argv == NULL){
 
192
    *argc = 1;
 
193
    argv = malloc(sizeof(char*) * 2);
 
194
    if(argv == NULL){
 
195
      return NULL;
 
196
    }
 
197
    argv[0] = NULL;     /* Will be set to argv[0] in main before parsing */
 
198
    argv[1] = NULL;
 
199
  }
 
200
  *argc += 1;
 
201
  argv = realloc(argv, sizeof(char *)
 
202
                  * ((unsigned int) *argc + 1));
 
203
  if(argv == NULL){
 
204
    return NULL;
 
205
  }
 
206
  argv[*argc-1] = arg;
 
207
  argv[*argc] = NULL;   
 
208
  return argv;
 
209
}
 
210
 
188
211
int main(int argc, char *argv[]){
189
212
  const char *plugindir = "/lib/mandos/plugins.d";
 
213
  const char *argfile = ARGFILE;
 
214
  FILE *conffp;
190
215
  size_t d_name_len;
191
216
  DIR *dir = NULL;
192
217
  struct dirent *dirst;
200
225
  struct sigaction old_sigchld_action;
201
226
  struct sigaction sigchld_action = { .sa_handler = handle_sigchld,
202
227
                                      .sa_flags = SA_NOCLDSTOP };
203
 
  char *plus_options = NULL;
204
 
  char **plus_argv = NULL;
205
 
 
 
228
  char **custom_argv = NULL;
 
229
  int custom_argc = 0;
 
230
  
206
231
  /* Establish a signal handler */
207
232
  sigemptyset(&sigchld_action.sa_mask);
208
233
  ret = sigaddset(&sigchld_action.sa_mask, SIGCHLD);
250
275
      if (arg != NULL){
251
276
        char *p;
252
277
        while((p = strsep(&arg, ",")) != NULL){
253
 
          if(strcmp(p, "") == 0){
 
278
          if(p[0] == '\0'){
254
279
            continue;
255
280
          }
256
281
          addargument(getplugin(NULL, plugins), p);
260
285
    case 'o':
261
286
      if (arg != NULL){
262
287
        char *name = strsep(&arg, ":");
263
 
        if(strcmp(name, "") == 0){
 
288
        if(name[0] == '\0'){
264
289
          break;
265
290
        }
266
291
        char *opt = strsep(&arg, ":");
267
 
        if(strcmp(opt, "") == 0){
 
292
        if(opt[0] == '\0'){
268
293
          break;
269
294
        }
270
295
        if(opt != NULL){
271
296
          char *p;
272
297
          while((p = strsep(&opt, ",")) != NULL){
273
 
            if(strcmp(p, "") == 0){
 
298
            if(p[0] == '\0'){
274
299
              continue;
275
300
            }
276
301
            addargument(getplugin(name, plugins), p);
296
321
      debug = true;
297
322
      break;
298
323
    case ARGP_KEY_ARG:
299
 
      if(plus_options != NULL or arg == NULL or arg[0] != '+'){
300
 
        argp_usage (state);
301
 
      }
302
 
      plus_options = arg;
 
324
      fprintf(stderr, "Ignoring unknown argument \"%s\"\n", arg); 
303
325
      break;
304
326
    case ARGP_KEY_END:
305
327
      break;
321
343
    exitstatus = EXIT_FAILURE;
322
344
    goto end;
323
345
  }
324
 
  
325
 
  if(plus_options){
326
 
    /* This is a mangled argument in the form of
327
 
     "+--option+--other-option=parameter+--yet-another-option", etc */
328
 
    /* Make new argc and argv vars, and call argp_parse() again. */
329
 
    plus_options++;             /* skip the first '+' character */
330
 
    const char delims[] = "+";
331
 
    char *arg;
332
 
    int new_argc = 1;
333
 
    plus_argv = malloc(sizeof(char*) * 2);
334
 
    if(plus_argv == NULL){
335
 
      perror("malloc");
 
346
 
 
347
  conffp = fopen(argfile, "r");
 
348
  if(conffp != NULL){
 
349
    char *org_line = NULL;
 
350
    size_t size = 0;
 
351
    ssize_t sret;
 
352
    char *p, *arg, *new_arg, *line;
 
353
    const char whitespace_delims[] = " \r\t\f\v\n";
 
354
    const char comment_delim[] = "#";
 
355
 
 
356
    while(true){
 
357
      sret = getline(&org_line, &size, conffp);
 
358
      if(sret == -1){
 
359
        break;
 
360
      }
 
361
 
 
362
      line = org_line;
 
363
      arg = strsep(&line, comment_delim);
 
364
      while((p = strsep(&arg, whitespace_delims)) != NULL){
 
365
        if(p[0] == '\0'){
 
366
          continue;
 
367
        }
 
368
        new_arg = strdup(p);
 
369
        custom_argv = addcustomargument(custom_argv, &custom_argc, new_arg);
 
370
        if (custom_argv == NULL){
 
371
          perror("addcustomargument");
 
372
          exitstatus = EXIT_FAILURE;
 
373
          goto end;
 
374
        }
 
375
      }
 
376
    }
 
377
    free(org_line);
 
378
  } else{
 
379
    /* Check for harmful errors and go to fallback. Other errors might
 
380
       not affect opening plugins */
 
381
    if (errno == EMFILE or errno == ENFILE or errno == ENOMEM){
 
382
      perror("fopen");
336
383
      exitstatus = EXIT_FAILURE;
337
384
      goto end;
338
385
    }
339
 
    plus_argv[0] = argv[0];
340
 
    plus_argv[1] = NULL;
 
386
  }
341
387
 
342
 
    while((arg = strsep(&plus_options, delims)) != NULL){
343
 
      new_argc++;
344
 
      plus_argv = realloc(plus_argv, sizeof(char *)
345
 
                         * ((unsigned int) new_argc + 1));
346
 
      if(plus_argv == NULL){
347
 
        perror("realloc");
348
 
        exitstatus = EXIT_FAILURE;
349
 
        goto end;
350
 
      }
351
 
      plus_argv[new_argc-1] = arg;
352
 
      plus_argv[new_argc] = NULL;
353
 
    }
354
 
    
355
 
    ret = argp_parse (&argp, new_argc, plus_argv, 0, 0, &plugin_list);
 
388
  if(custom_argv != NULL){
 
389
    custom_argv[0] = argv[0];
 
390
    ret = argp_parse (&argp, custom_argc, custom_argv, 0, 0, &plugin_list);
356
391
    if (ret == ARGP_ERR_UNKNOWN){
357
392
      fprintf(stderr, "Unknown error while parsing arguments\n");
358
393
      exitstatus = EXIT_FAILURE;
742
777
  /* Restore old signal handler */
743
778
  sigaction(SIGCHLD, &old_sigchld_action, NULL);
744
779
  
745
 
  free(plus_argv);
 
780
  free(custom_argv);
746
781
  
747
782
  /* Free the plugin list */
748
783
  for(plugin *next; plugin_list != NULL; plugin_list = next){