Commit de82eae6 de82eae68b917d574ad60a0046f5a2810d4352e6 by Sam Roberts

Now supports a ~/.sieverc file. Mine looks like:

  # ~/.sieverc
  #   Just moves my mail into my local spool.
  -dTt --ticket=~/.tickets
  -f pop://pop.uniserve.com
  ~/.filter.sv
1 parent 99885cb9
......@@ -10,18 +10,23 @@ sieve script interpreter.
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <argcv.h>
#include <argp.h>
#include "sieve.h"
#include <mailutils/registrar.h>
#include <mailutils/mailbox.h>
#include <mailutils/mutil.h>
#include <mailutils/registrar.h>
void mutil_register_all_mbox_formats(void);
......@@ -39,6 +44,8 @@ static char doc[] =
" q - sieve message queries (SV_DEBUG_MSG_QUERY)\n"
;
#define D_DEFAULT "TPt"
static struct argp_option options[] = {
{"no-actions", 'n', 0, 0,
"No actions executed, just print what would be done", 0},
......@@ -59,7 +66,7 @@ static struct argp_option options[] = {
"Mailer URL (defaults to \"sendmail:\")", 0},
{"debug", 'd', "FLAGS", OPTION_ARG_OPTIONAL,
"Debug flags (defaults to \"TPt\")", 0},
"Debug flags (defaults to \"" D_DEFAULT "\")", 0},
{0}
};
......@@ -74,6 +81,8 @@ struct options
int debug_level;
char *mailer;
char *script;
int final; /* final arg pass */
};
static error_t
......@@ -84,8 +93,12 @@ parser (int key, char *arg, struct argp_state *state)
switch (key)
{
case ARGP_KEY_INIT:
opts->mailer = "sendmail:";
opts->debug_level = MU_DEBUG_ERROR;
if (!opts->tickets)
opts->tickets = mu_tilde_expansion ("~/.tickets", "/", NULL);
if (!opts->mailer)
opts->mailer = strdup ("sendmail:");
if(!opts->debug_level)
opts->debug_level = MU_DEBUG_ERROR;
break;
case 'n':
opts->no_actions = SV_FLAG_NO_ACTIONS;
......@@ -97,12 +110,21 @@ parser (int key, char *arg, struct argp_state *state)
opts->compile_only = 1;
break;
case 'f':
opts->mbox = arg;
if(opts->mbox)
argp_error (state, "only one MBOX can be specified");
opts->mbox = strdup(arg);
break;
case 't':
opts->tickets = arg;
free (opts->tickets);
opts->tickets = mu_tilde_expansion (arg, "/", NULL);
break;
case 'm':
free (opts->mailer);
opts->mailer = strdup(arg);
break;
case 'd':
if(!arg)
arg = D_DEFAULT;
for (; *arg; arg++)
{
switch (*arg)
......@@ -132,12 +154,12 @@ parser (int key, char *arg, struct argp_state *state)
case ARGP_KEY_ARG:
if (opts->script)
argp_error (state, "only one SCRIPT can be specified");
opts->script = arg;
opts->script = mu_tilde_expansion (arg, "/", NULL);
break;
case ARGP_KEY_NO_ARGS:
argp_error (state, "SCRIPT must be specified");
break;
if (opts->final && !opts->script)
argp_error (state, "SCRIPT must be specified");
default:
return ARGP_ERR_UNKNOWN;
......@@ -197,6 +219,72 @@ debug_print (mu_debug_t debug, size_t level, const char *fmt, va_list ap)
return 0;
}
static int
dot_parse (int argc, char *argv[], struct options *opts)
{
int err = 0;
char *rcfile = mu_tilde_expansion ("~/.sieverc", "/", NULL);
struct stat s;
char *cmd = 0;
int fd = -1;
int ac = 0;
char **av = 0;
if (!rcfile)
return ENOMEM;
/* Chomp argv[0] down to the last path component. */
{
char* n = argv[0] + strlen(argv[0]);
while(n > argv[0] && *n != '/')
n--;
if(*n == '/')
n++;
argv[0] = n;
}
fd = open (rcfile, O_RDONLY, 0);
free (rcfile);
rcfile = 0;
if (fd != -1)
{
if ((err = fstat (fd, &s)) == -1)
return errno;
if ((cmd = malloc (s.st_size + 1 + strlen (argv[0]) + 1)) == NULL)
return ENOMEM;
strcpy (cmd, argv[0]);
strcat (cmd, " ");
err = read (fd, &cmd[strlen (argv[0]) + 1], s.st_size);
close (fd);
if (err == -1)
{
free (cmd);
return errno;
}
cmd[strlen (argv[0]) + 1 + err] = '\0';
argcv_get (cmd, "", "#", &ac, &av);
argp_parse (&argp, ac, av, ARGP_IN_ORDER, NULL, opts);
argcv_free (ac, av);
free (cmd);
}
opts->final = 1;
argp_parse (&argp, argc, argv, ARGP_IN_ORDER, NULL, opts);
return 0;
}
int
main (int argc, char *argv[])
{
......@@ -215,7 +303,12 @@ main (int argc, char *argv[])
int rc = 0;
argp_parse (&argp, argc, argv, ARGP_IN_ORDER, NULL, &opts);
rc = dot_parse(argc, argv, &opts);
if(rc) {
fprintf (stderr, "arg parsing failed: %s\n", sv_strerror (rc));
return 1;
}
mutil_register_all_mbox_formats ();
......