/* From http://www.ietf.org/internet-drafts/draft-ietf-sieve-notify-07.txt Usage: notify [":from" string] [":importance" <"1" / "2" / "3">] [":options" string-list] [":message" string] <method: string> */ int sort_notify(sieve2_context_t *s, void *my) { struct sort_context *m = (struct sort_context *)my; const char *message, *fromaddr, *method; const char *rc_to, *rc_from; int importance; char * const * options; fromaddr = sieve2_getvalue_string(s, "fromaddr"); method = sieve2_getvalue_string(s, "method"); message = sieve2_getvalue_string(s, "message"); importance = sieve2_getvalue_int(s, "importance"); options = sieve2_getvalue_stringlist(s, "options"); // FIXME: should be validated as a user might try // to forge an address from their script. rc_from = fromaddr; if (!rc_from) rc_from = dbmail_message_get_header(m->message, "Delivered-To"); if (!rc_from) rc_from = m->message->envelope_recipient->str; rc_to = dbmail_message_get_header(m->message, "Reply-To"); if (!rc_to) rc_to = dbmail_message_get_header(m->message, "Return-Path"); // send_notification(m->message, rc_to, rc_from, method, message); TRACE(TRACE_INFO, "Notification from [%s] to [%s] was not sent as notify is not supported in this release.", rc_from, rc_to); return SIEVE2_OK; }
int my_notify(sieve2_context_t *s, void *my) { struct my_context *m = (struct my_context *)my; char ** options; int i; printf( "Action is NOTIFY: \n" ); printf( " ID \"%s\" is %s\n", sieve2_getvalue_string(s, "id"), sieve2_getvalue_string(s, "active")); printf( " Method is %s\n", sieve2_getvalue_string(s, "method")); printf( " Priority is %s\n", sieve2_getvalue_string(s, "priority")); printf( " Message is %s\n", sieve2_getvalue_string(s, "message")); options = sieve2_getvalue_stringlist(s, "options"); if (!options) return SIEVE2_ERROR_BADARGS; for (i = 0; options[i] != NULL; i++) { printf( " Options are %s\n", options[i] ); } m->actiontaken = 1; return SIEVE2_OK; }
int my_vacation(sieve2_context_t *s, void *my) { struct my_context *m = (struct my_context *)my; int yn; /* Ask for the message hash, the days parameters, etc. */ fprintf(stderr, "Have I already responded to '%s' in the past %d days?\n", sieve2_getvalue_string(s, "hash"), sieve2_getvalue_int(s, "days") ); yn = getchar(); /* Check in our 'database' to see if there's a match. */ if (yn == 'y' || yn == 'Y') { printf( "Ok, not sending a vacation response.\n" ); } /* If so, do nothing. If not, send a vacation and log it. */ printf("echo '%s' | mail -s '%s' '%s' for message '%s'\n", sieve2_getvalue_string(s, "message"), sieve2_getvalue_string(s, "subject"), sieve2_getvalue_string(s, "address"), sieve2_getvalue_string(s, "name") ); m->actiontaken = 1; return SIEVE2_OK; }
/* From http://www.ietf.org/internet-drafts/draft-ietf-sieve-vacation-06.txt Usage: vacation [":days" number] [":subject" string] [":from" string] [":addresses" string-list] [":mime"] [":handle" string] <reason: string> The parameters that an implementation needs to know about are: days, subject, from, mime, handle, reason. Addresses is used internally by libSieve implementation to comply with RFCs. We need to make sure to respect the implementation requirements. */ int sort_vacation(sieve2_context_t *s, void *my) { struct sort_context *m = (struct sort_context *)my; const char *message, *subject, *fromaddr, *handle; const char *rc_to, *rc_from, *rc_handle; char *md5_handle = NULL; int days, mime; days = sieve2_getvalue_int(s, "days"); mime = sieve2_getvalue_int(s, "mime"); // mime: 1 if message is mime coded. FIXME. message = sieve2_getvalue_string(s, "message"); subject = sieve2_getvalue_string(s, "subject"); fromaddr = sieve2_getvalue_string(s, "fromaddr"); // From: specified by the script. handle = sieve2_getvalue_string(s, "hash"); /* Default to a week, upper limit of a month. * This is our only loop prevention mechanism! The value must be * greater than 0, else the replycache code will always indicate * that we haven't seen anything since 0 days ago... */ if (days == 0) days = 7; if (days < 1) days = 1; if (days > 30) days = 30; if (handle) { rc_handle = handle; } else { char *tmp; tmp = g_strconcat(subject, message, NULL); rc_handle = md5_handle = dm_md5((char * const) tmp); g_free(tmp); } // FIXME: should be validated as a user might try // to forge an address from their script. rc_from = fromaddr; if (!rc_from) rc_from = dbmail_message_get_header(m->message, "Delivered-To"); if (!rc_from) rc_from = m->message->envelope_recipient->str; rc_to = dbmail_message_get_header(m->message, "Reply-To"); if (!rc_to) rc_to = dbmail_message_get_header(m->message, "Return-Path"); if (db_replycache_validate(rc_to, rc_from, rc_handle, days) == DM_SUCCESS) { if (send_vacation(m->message, rc_to, rc_from, subject, message, rc_handle) == 0) db_replycache_register(rc_to, rc_from, rc_handle); TRACE(TRACE_INFO, "Sending vacation to [%s] from [%s] handle [%s] repeat days [%d]", rc_to, rc_from, rc_handle, days); } else { TRACE(TRACE_INFO, "Vacation suppressed to [%s] from [%s] handle [%s] repeat days [%d]", rc_to, rc_from, rc_handle, days); } m->result->cancelkeep = 0; return SIEVE2_OK; }
int my_debug(sieve2_context_t *s, void *my) { if (debug) { printf("Debug: level [%d] module [%s] file [%s] function [%s] message [%s]\n", sieve2_getvalue_int(s, "level"), sieve2_getvalue_string(s, "module"), sieve2_getvalue_string(s, "file"), sieve2_getvalue_string(s, "function"), sieve2_getvalue_string(s, "message")); } return SIEVE2_OK; }
int sort_redirect(sieve2_context_t *s, void *my) { struct sort_context *m = (struct sort_context *)my; const char *to; const char *from; to = sieve2_getvalue_string(s, "address"); TRACE(TRACE_INFO, "Action is REDIRECT: REDIRECT destination is [%s].", to); /* According to a clarification from the ietf-mta-filter mailing list, * the redirect is supposed to be absolutely transparent: the envelope * sender is the original envelope sender, with only the envelope * recipient changed. As a fallback, we'll use the redirecting user. */ from = dbmail_message_get_header(m->message, "Return-Path"); if (!from) from = m->message->envelope_recipient->str; if (send_redirect(m->message, to, from) != 0) { return SIEVE2_ERROR_FAIL; } m->result->cancelkeep = 1; return SIEVE2_OK; }
int my_errexec(sieve2_context_t *s, void *my) { struct my_context *m = (struct my_context *)my; printf( "Error is EXEC: " ); printf( " Message is %s\n", sieve2_getvalue_string(s, "message")); m->error_runtime = 1; return SIEVE2_OK; }
int my_erraddress(sieve2_context_t *s, void *my) { // struct my_context *m = (struct my_context *)my; printf( "Error is ADDRESS PARSE: " ); printf( " Message is %s\n", sieve2_getvalue_string(s, "message")); // m->error_parse = 1; return SIEVE2_OK; }
int my_reject(sieve2_context_t *s, void *my) { struct my_context *m = (struct my_context *)my; printf( "Action is REJECT: \n" ); printf( " Message is [%s]\n", sieve2_getvalue_string(s, "message")); m->actiontaken = 1; return SIEVE2_OK; }
int my_redirect(sieve2_context_t *s, void *my) { struct my_context *m = (struct my_context *)my; printf( "Action is REDIRECT: \n" ); printf( " Destination is [%s]\n", sieve2_getvalue_string(s, "address")); m->actiontaken = 1; return SIEVE2_OK; }
int my_getheader(sieve2_context_t *s, void *my) { // struct my_context *m = (struct my_context *)my; printf( "Requested header [%s], returning NULL\n", sieve2_getvalue_string(s, "header") ); char * null[] = { NULL, NULL }; sieve2_setvalue_stringlist(s, "body", null); return SIEVE2_OK; }
int my_errheader(sieve2_context_t *s, void *my) { struct my_context *m = (struct my_context *)my; printf( "Error is HEADER PARSE: " ); printf( " Line is %d\n", sieve2_getvalue_int(s, "lineno")); printf( " Message is %s\n", sieve2_getvalue_string(s, "message")); m->error_parse = 1; return SIEVE2_OK; }
int my_getscript(sieve2_context_t *s, void *my) { struct my_context *m = (struct my_context *)my; const char * path, * name; int res; /* Path could be :general, :personal, or empty. */ path = sieve2_getvalue_string(s, "path"); /* If no file is named, we're looking for the main file. */ name = sieve2_getvalue_string(s, "name"); if (path == NULL || name == NULL) return SIEVE2_ERROR_BADARGS; if (strlen(path) && strlen(name)) { printf("Include requested from '%s' named '%s'\n", path, name); } else if (!strlen(path) && !strlen(name)) { /* If we're being called again, free what was here before. */ if (m->s_buf) free(m->s_buf); /* Read the script file given as an argument. */ printf("Reading script: %s\n", m->scriptfile); res = read_file(m->scriptfile, &m->s_buf, end_of_nothing); if (res != SIEVE2_OK) { printf("my_getscript: read_file() returns %d\n", res); return SIEVE2_ERROR_FAIL; } sieve2_setvalue_string(s, "script", m->s_buf); } else { return SIEVE2_ERROR_BADARGS; } return SIEVE2_OK; }
// Calculate the address according to the mail system's specs. int my_getsubaddress(sieve2_context_t *s, void *my) { struct my_context *m = (struct my_context *)my; const char *address; char *user = NULL, *detail = NULL, *localpart = NULL, *domain = NULL; address = sieve2_getvalue_string(s, "address"); // In a real system, you have to watch this memory; // the client app owns it, not libSieve! You may // not permute the address parameter, either! localpart = strdup(address); domain = strchr(localpart, '@'); if (domain) { *domain = '\0'; domain++; } else { // Malformed address. } user = strdup(localpart); detail = strchr(user, '+'); if (detail) { *detail = '\0'; detail++; } else { // No detail present. } sieve2_setvalue_string(s, "user", user); sieve2_setvalue_string(s, "detail", detail); sieve2_setvalue_string(s, "localpart", localpart); sieve2_setvalue_string(s, "domain", domain); struct freelist *tmp = malloc(sizeof(struct freelist)); tmp->next = m->freelist; tmp->free = user; m->freelist = tmp; tmp = malloc(sizeof(struct freelist)); tmp->next = m->freelist; tmp->free = localpart; m->freelist = tmp; return SIEVE2_OK; }
int sort_reject(sieve2_context_t *s, void *my) { struct sort_context *m = (struct sort_context *)my; const char *message; message = sieve2_getvalue_string(s, "message"); TRACE(TRACE_INFO, "Action is REJECT: REJECT message is [%s].", message); m->result->rejectmsg = g_string_new(message); /* Reject also discards. */ m->result->cancelkeep = 1; m->result->reject = 1; return SIEVE2_OK; }
int my_fileinto(sieve2_context_t *s, void *my) { struct my_context *m = (struct my_context *)my; char ** flags; int i; printf( "Action is KEEP or FILEINTO: \n" ); printf( " Destination is %s\n", sieve2_getvalue_string(s, "mailbox")); flags = sieve2_getvalue_stringlist(s, "flags"); if (flags) { printf( " Flags are:"); for (i = 0; flags[i]; i++) printf( " %s", flags[i]); printf( ".\n"); } else { printf( " No flags specified.\n"); } m->actiontaken = 1; return SIEVE2_OK; }