Example #1
0
/* Syntax: addheader [:last] <field-name: string> <value: string>
 */
int
sieve_addheader (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
{
  mu_sieve_value_t *val;
  const char *field_name;
  const char *field_value;
  mu_message_t msg;
  mu_header_t hdr;
  int rc;
  
  val = mu_sieve_value_get (args, 0);
  if (!val)
    {
      mu_sieve_error (mach, "%lu: %s",
		      (unsigned long) mu_sieve_get_message_num (mach),
		      _("cannot get field name"));
      mu_sieve_abort (mach);
    }
  field_name = val->v.string;

  val = mu_sieve_value_get (args, 1);
  if (!val)
    {
      mu_sieve_error (mach, "%lu: %s",
		      (unsigned long) mu_sieve_get_message_num (mach),
		      _("cannot get field value"));
      mu_sieve_abort (mach);
    }
  field_value = val->v.string;

  mu_sieve_log_action (mach, "ADDHEADER", "%s: %s", field_name, field_value);

  if (mu_sieve_is_dry_run (mach))
    return 0;

  msg = mu_sieve_get_message (mach);
  rc = mu_message_get_header (msg, &hdr);
  if (rc)
    {
      mu_sieve_error (mach, "%lu: %s: %s",
		      (unsigned long) mu_sieve_get_message_num (mach),
		      _("cannot get message header"),
		      mu_strerror (rc));
      mu_sieve_abort (mach);
    }

  rc = (mu_sieve_tag_lookup (tags, "last", NULL) ?
	mu_header_append : mu_header_prepend) (hdr, field_name, field_value);
  if (rc)
    {
      mu_sieve_error (mach, "%lu: %s: %s",
		      (unsigned long) mu_sieve_get_message_num (mach),
		      _("cannot append message header"),
		      mu_strerror (rc));
      mu_sieve_abort (mach);
    }
  return 0;
}
Example #2
0
/* Produce diagnostic output. */
static int
diag (mu_sieve_machine_t mach)
{
  if (mu_sieve_get_debug_level (mach) & MU_SIEVE_DEBUG_TRACE)
    {
      mu_sieve_debug (mach, "VACATION");
    }

  mu_sieve_log_action (mach, "VACATION", NULL);
  return mu_sieve_is_dry_run (mach);
}
Example #3
0
int
sieve_run (mu_sieve_machine_t mach)
{
  if (setjmp (mach->errbuf))
    return 1;

  mach->action_count = 0;
  
  for (mach->pc = 1; mach->prog[mach->pc].handler; )
    (*mach->prog[mach->pc++].instr) (mach);

  if (mach->action_count == 0)
    mu_sieve_log_action (mach, "IMPLICIT KEEP", NULL);
  
  if (INSTR_DEBUG (mach))
    mu_sieve_debug (mach, "%4lu: STOP\n", (unsigned long) mach->pc);
  
  return 0;
}
Example #4
0
static int
moderator_action (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
{
  mu_message_t msg, orig;
  int rc;
  size_t nparts = 0;
  int discard = 0;
  int ismime;
  
  if (mu_sieve_get_debug_level (mach) & MU_SIEVE_DEBUG_TRACE)
    {
      mu_sieve_debug (mach, "moderator_test %lu",
		      (unsigned long) mu_sieve_get_message_num (mach));
    }

  msg = mu_sieve_get_message (mach);
  mu_message_is_multipart (msg, &ismime);

  if (!ismime)
    {
      mu_sieve_error (mach, _("message is not multipart"));
      mu_sieve_abort (mach);
    }

  mu_message_get_num_parts (msg, &nparts);

  if (nparts != 3) /* Mailman moderation requests have three parts */
    {
      mu_sieve_error (mach, _("expected 3 parts, but found %lu"),
		      (unsigned long) nparts);
      mu_sieve_abort (mach);
    }

  if ((rc = moderator_message_get_part (mach, msg, 2, &orig)))
    mu_sieve_abort (mach);

  rc = moderator_filter_message (mach, tags, orig, &discard);
  mu_message_unref (orig);
  if (rc)
    mu_sieve_abort (mach);

  if (discard && !mu_sieve_is_dry_run (mach))
    {
      mu_message_t request;
      char *from = NULL;
      mu_sieve_value_t *arg;
      
      if ((rc = moderator_message_get_part (mach, msg, 3, &request)))
	{
	  mu_sieve_error (mach, _("cannot get message part #3: %s"),
			  mu_strerror (rc));
	  mu_sieve_abort (mach);
	}

      if (mu_sieve_tag_lookup (tags, "address", &arg))
	from = arg->v.string;
      
      if (moderator_discard_message (mach, request, from))
	discard = 0;
      else
	{
	  if (!mu_sieve_tag_lookup (tags, "keep", NULL))
	    {
	      mu_attribute_t attr = 0;

	      if (mu_message_get_attribute (msg, &attr) == 0)
		mu_attribute_set_deleted (attr);
	    }
	  else
	    discard = 0;
	}
      mu_message_unref (request);
    }

  mu_sieve_log_action (mach, "MODERATOR", 
		       discard ? _("discarding message") :
		       _("keeping message"));
  return 0;
}
Example #5
0
/* Syntax: deleteheader [:index <fieldno: number> [:last]]
                        [COMPARATOR] [MATCH-TYPE]
                        <field-name: string>
                        [<value-patterns: string-list>]
 */
int
sieve_deleteheader (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
{
  mu_sieve_value_t *val;
  const char *field_name;
  const char *field_pattern;
  mu_message_t msg;
  mu_header_t hdr;
  int rc;
  mu_sieve_comparator_t comp;
  mu_iterator_t itr;
  unsigned long i, idx = 0;
  
  val = mu_sieve_value_get (args, 0);
  if (!val)
    {
      mu_sieve_error (mach, "%lu: %s",
		      (unsigned long) mu_sieve_get_message_num (mach),
		      _("cannot get field name"));
      mu_sieve_abort (mach);
    }
  field_name = val->v.string;

  val = mu_sieve_value_get (args, 1);
  if (!val)
    {
      field_pattern = NULL;
      mu_sieve_log_action (mach, "DELETEHEADER", "%s", field_name);
    }
  else
    {
      switch (val->type)
	{
	case SVT_STRING_LIST:
	  if (mu_list_get (val->v.list, 0, (void**)&field_pattern))
	    {
	      mu_sieve_error (mach, "%lu: %s",
			      (unsigned long) mu_sieve_get_message_num (mach),
			      _("cannot get list item"));
	      mu_sieve_abort (mach);
	    }
	  mu_sieve_log_action (mach, "DELETEHEADER", "%s: (regexp)",
			       field_name);
	  break;
	  
	case SVT_STRING:
	  field_pattern = val->v.string;
	  mu_sieve_log_action (mach, "DELETEHEADER", "%s: %s", field_name,
			       field_pattern);
	  break;

	default:
	  mu_sieve_error (mach, "%lu: %s: %d",
			  (unsigned long) mu_sieve_get_message_num (mach),
			  _("unexpected value type"), val->type);
	  mu_sieve_abort (mach);
	  
	}
    }
  
  if (mu_sieve_is_dry_run (mach))
    return 0;

  msg = mu_sieve_get_message (mach);
  rc = mu_message_get_header (msg, &hdr);
  if (rc)
    {
      mu_sieve_error (mach, "%lu: %s: %s",
		      (unsigned long) mu_sieve_get_message_num (mach),
		      _("cannot get message header"),
		      mu_strerror (rc));
      mu_sieve_abort (mach);
    }

  mu_header_get_iterator (hdr, &itr);
  if (mu_sieve_tag_lookup (tags, "last", NULL))
    {
      int backwards = 1;
      mu_iterator_ctl (itr, mu_itrctl_set_direction, &backwards);
    }
  comp = mu_sieve_get_comparator (mach, tags);

  if (mu_sieve_tag_lookup (tags, "index", &val))
    idx = val->v.number;
  
  for (i = 0, mu_iterator_first (itr); !mu_iterator_is_done (itr);
       mu_iterator_next (itr))
    {
      const char *fn, *fv;

      mu_iterator_current_kv (itr, (const void **)&fn, (void **)&fv);
      if (strcmp (field_name, fn))
	continue;
      if (idx && ++i < idx)
	continue;
	  
      if (field_pattern)
	{
	  if (comp (field_pattern, fv))
	    mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
	}
      else
	mu_iterator_ctl (itr, mu_itrctl_delete, NULL);

      if (idx)
	break;
    }
  mu_iterator_destroy (&itr);
  return 0;
}