Exemple #1
0
int sieve_execute_bytecode(sieve_execute_t *exe, sieve_interp_t *interp,
			   void *script_context, void *message_context) 
{
    action_list_t *actions = NULL;
    notify_list_t *notify_list = NULL;
    /*   notify_action_t *notify_action;*/
    action_t lastaction = -1;
    int ret;
    char actions_string[ACTIONS_STRING_LEN] = "";
    const char *errmsg = NULL;
    strarray_t imapflags = STRARRAY_INITIALIZER;
    
    if (!interp) return SIEVE_FAIL;

    if (interp->notify) {
	notify_list = new_notify_list();
	if (notify_list == NULL) {
	    return do_sieve_error(SIEVE_NOMEM, interp,
				  script_context, message_context, &imapflags,
				  actions, notify_list, lastaction, 0,
				  actions_string, errmsg);
	}
    }

    actions = new_action_list();
    if (actions == NULL) {
	ret = do_sieve_error(SIEVE_NOMEM, interp,
			     script_context, message_context, &imapflags,
			     actions, notify_list, lastaction, 0,
			     actions_string, errmsg);
    }
    else {
	ret = sieve_eval_bc(exe, 0, interp,
			    script_context, message_context,
			    &imapflags, actions, notify_list, &errmsg);

	if (ret < 0) {
	    ret = do_sieve_error(SIEVE_RUN_ERROR, interp,
				 script_context, message_context, &imapflags,
				 actions, notify_list, lastaction, 0,
				 actions_string, errmsg);
	}
	else {
	    ret = do_action_list(interp,
				 script_context, message_context, 
				 &imapflags, actions, notify_list,
				 actions_string, errmsg);
	}
    }

    strarray_fini(&imapflags);

    return ret;
}
Exemple #2
0
static int do_action_list(sieve_interp_t *interp,
                          void *script_context,
                          void *message_context,
                          strarray_t *imapflags,
                          action_list_t *actions,
                          notify_list_t *notify_list,
                          /* notify_action_t *notify_action,*/
                          char *actions_string,
                          const char *errmsg)
{
    action_list_t *a;
    action_t lastaction = -1;
    int ret = 0;
    int implicit_keep = 1;

    strcpy(actions_string,"Action(s) taken:\n");

    /* now perform actions attached to m */
    a = actions;
    while (a != NULL) {
        lastaction = a->a;
        errmsg = NULL;
        implicit_keep = implicit_keep && !a->cancel_keep;
        switch (a->a) {
        case ACTION_REJECT:
            if (!interp->reject)
                return SIEVE_INTERNAL_ERROR;
            ret = interp->reject(&a->u.rej,
                                 interp->interp_context,
                                 script_context,
                                 message_context,
                                 &errmsg);
            free(interp->lastitem);
            interp->lastitem = xstrdup(a->u.rej.msg);

            if (ret == SIEVE_OK)
                snprintf(actions_string+strlen(actions_string),
                         ACTIONS_STRING_LEN-strlen(actions_string),
                         "Rejected with: %s\n", a->u.rej.msg);

            break;
        case ACTION_FILEINTO:
            if (!interp->fileinto)
                return SIEVE_INTERNAL_ERROR;
            ret = interp->fileinto(&a->u.fil,
                                   interp->interp_context,
                                   script_context,
                                   message_context,
                                   &errmsg);
            free(interp->lastitem);
            interp->lastitem = xstrdup(a->u.fil.mailbox);

            if (ret == SIEVE_OK)
                snprintf(actions_string+strlen(actions_string),
                         ACTIONS_STRING_LEN-strlen(actions_string),
                         "Filed into: %s\n",a->u.fil.mailbox);
            break;
        case ACTION_KEEP:
            if (!interp->keep)
                return SIEVE_INTERNAL_ERROR;
            ret = interp->keep(&a->u.keep,
                               interp->interp_context,
                               script_context,
                               message_context,
                               &errmsg);
            free(interp->lastitem);
            interp->lastitem = NULL;
            if (ret == SIEVE_OK)
                snprintf(actions_string+strlen(actions_string),
                         ACTIONS_STRING_LEN-strlen(actions_string),
                         "Kept\n");
            break;
        case ACTION_REDIRECT:
            if (!interp->redirect)
                return SIEVE_INTERNAL_ERROR;
            ret = interp->redirect(&a->u.red,
                                   interp->interp_context,
                                   script_context,
                                   message_context,
                                   &errmsg);
            free(interp->lastitem);
            interp->lastitem = xstrdup(a->u.red.addr);
            if (ret == SIEVE_OK)
                snprintf(actions_string+strlen(actions_string),
                         ACTIONS_STRING_LEN-strlen(actions_string),
                         "Redirected to %s\n", a->u.red.addr);
            break;
        case ACTION_DISCARD:
            if (interp->discard) /* discard is optional */
                ret = interp->discard(NULL, interp->interp_context,
                                      script_context,
                                      message_context,
                                      &errmsg);
            free(interp->lastitem);
            interp->lastitem = NULL;
            if (ret == SIEVE_OK)
                snprintf(actions_string+strlen(actions_string),
                         ACTIONS_STRING_LEN-strlen(actions_string),
                         "Discarded\n");
            break;

        case ACTION_VACATION:
            {
                if (!interp->vacation)
                    return SIEVE_INTERNAL_ERROR;

                /* first, let's figure out if we should respond to this */
                ret = interp->vacation->autorespond(&a->u.vac.autoresp,
                                                    interp->interp_context,
                                                    script_context,
                                                    message_context,
                                                    &errmsg);
                free(interp->lastitem);
                interp->lastitem = NULL;

                if (ret == SIEVE_OK) {
                    /* send the response */
                    ret = interp->vacation->send_response(&a->u.vac.send,
                                                          interp->interp_context,
                                                          script_context,
                                                          message_context,
                                                          &errmsg);

                    if (ret == SIEVE_OK)
                        snprintf(actions_string+strlen(actions_string),
                                 ACTIONS_STRING_LEN-strlen(actions_string),
                                 "Sent vacation reply\n");

                } else if (ret == SIEVE_DONE) {
                    snprintf(actions_string+strlen(actions_string),
                             ACTIONS_STRING_LEN-strlen(actions_string),
                             "Vacation reply suppressed\n");

                    ret = SIEVE_OK;
                }

                break;
            }


        case ACTION_SETFLAG:
            strarray_fini(imapflags);
            break;
        case ACTION_ADDFLAG:
            strarray_add_case(imapflags, a->u.fla.flag);
            free(interp->lastitem);
            interp->lastitem = xstrdup(a->u.fla.flag);
            break;
        case ACTION_REMOVEFLAG:
            strarray_remove_all_case(imapflags, a->u.fla.flag);
            free(interp->lastitem);
            interp->lastitem = xstrdup(a->u.fla.flag);
            break;
        case ACTION_MARK:
            {
                int n = interp->markflags->count;

                ret = SIEVE_OK;
                while (n) {
                    strarray_add_case(imapflags,
                                        interp->markflags->data[--n]);
                }
                free(interp->lastitem);
                interp->lastitem = NULL;
                break;
            }
        case ACTION_UNMARK:
          {

                int n = interp->markflags->count;
                ret = SIEVE_OK;
                while (n) {
                    strarray_remove_all_case(imapflags,
                                           interp->markflags->data[--n]);
                }
                free(interp->lastitem);
                interp->lastitem = NULL;
                break;
            }

        case ACTION_NONE:
            break;

        default:
            ret = SIEVE_INTERNAL_ERROR;
            break;
        }
        a = a->next;

        if (ret != SIEVE_OK) {
            /* uh oh! better bail! */
            break;
        }
    }

    return do_sieve_error(ret, interp,
                          script_context, message_context,
                          imapflags, actions, notify_list, lastaction,
                          implicit_keep, actions_string, errmsg);
}
Exemple #3
0
static int do_sieve_error(int ret,
                          sieve_interp_t *interp,
                          void *script_context,
                          void *message_context,
                          strarray_t *imapflags,
                          action_list_t *actions,
                          notify_list_t *notify_list,
                          /* notify_action_t *notify_action,*/
                          int lastaction,
                          int implicit_keep,
                          char *actions_string,
                          const char *errmsg
                          )
{
   if (ret != SIEVE_OK) {
        if (lastaction == -1) /* we never executed an action */
            snprintf(actions_string+strlen(actions_string),
                     ACTIONS_STRING_LEN-strlen(actions_string),
                     "script execution failed: %s\n",
                     errmsg ? errmsg : sieve_errstr(ret));
        else
            snprintf(actions_string+strlen(actions_string),
                     ACTIONS_STRING_LEN-strlen(actions_string),
                     "%s action failed: %s\n",
                     action_to_string(lastaction),
                     errmsg ? errmsg : sieve_errstr(ret));
    }


    /* Process notify actions */
    if (interp->notify && notify_list)
      {
        notify_list_t *n = notify_list;
        int notify_ret = SIEVE_OK;

        while (n != NULL)
          {
            if (n->isactive)
              {
              lastaction = ACTION_NOTIFY;
               notify_ret = send_notify_callback(interp,
                                                 message_context,
                                                 script_context,n,
                                                 actions_string, &errmsg);
              ret |= notify_ret;
              }
            n = n->next;
          }

        if (notify_list) free_notify_list(notify_list);
        notify_list = NULL;     /* don't try any notifications again */


        if (notify_ret != SIEVE_OK)
          return do_sieve_error(ret, interp,
                                script_context, message_context,
                                imapflags, actions, notify_list, lastaction,
                                implicit_keep, actions_string, errmsg);

      }

    if ((ret != SIEVE_OK) && interp->execute_err) {
        char buf[ERR_BUF_SIZE];
        if (lastaction == -1) /* we never executed an action */
            snprintf(buf, ERR_BUF_SIZE,
                     "%s", errmsg ? errmsg : sieve_errstr(ret));
        else {
            if (interp->lastitem) {
                snprintf(buf, ERR_BUF_SIZE, "%s (%s): %s",
                         action_to_string(lastaction), interp->lastitem,
                         errmsg ? errmsg : sieve_errstr(ret));
            }
            else {
                snprintf(buf, ERR_BUF_SIZE, "%s: %s",
                         action_to_string(lastaction),
                         errmsg ? errmsg : sieve_errstr(ret));
            }
        }

        ret |= interp->execute_err(buf, interp->interp_context,
                                   script_context, message_context);
    }

    if (implicit_keep) {
        sieve_keep_context_t keep_context;
        int keep_ret;
        keep_context.imapflags = imapflags;

        lastaction = ACTION_KEEP;
        keep_ret = interp->keep(&keep_context, interp->interp_context,
                                script_context, message_context, &errmsg);
        ret |= keep_ret;
        if (keep_ret == SIEVE_OK)
            snprintf(actions_string+strlen(actions_string),
                     ACTIONS_STRING_LEN-strlen(actions_string),
                     "Kept\n");
        else {
            implicit_keep = 0;  /* don't try an implicit keep again */
            return do_sieve_error(ret, interp,
                                  script_context, message_context,
                                  imapflags, actions, notify_list, lastaction,
                                  implicit_keep, actions_string, errmsg);
        }
    }

    if (actions)
        free_action_list(actions);

    return ret;
}