int send_alert(uint64_t user_idnr, char *subject, char *body) { DbmailMessage *new_message; Field_T postmaster; char *from; int msgflags[IMAP_NFLAGS]; // Only send each unique alert once a day. char *tmp = g_strconcat(subject, body, NULL); char *userchar = g_strdup_printf("%" PRIu64 "", user_idnr); char handle[FIELDSIZE]; memset(handle, 0, sizeof(handle)); dm_md5(tmp, handle); if (db_replycache_validate(userchar, "send_alert", handle, 1) != DM_SUCCESS) { TRACE(TRACE_INFO, "Already sent alert [%s] to user [%" PRIu64 "] today", subject, user_idnr); g_free(userchar); g_free(tmp); return 0; } else { TRACE(TRACE_INFO, "Sending alert [%s] to user [%" PRIu64 "]", subject, user_idnr); db_replycache_register(userchar, "send_alert", handle); g_free(userchar); g_free(tmp); } // From the Postmaster. if (config_get_value("POSTMASTER", "DBMAIL", postmaster) < 0) { TRACE(TRACE_NOTICE, "no config value for POSTMASTER"); } if (strlen(postmaster)) from = postmaster; else from = DEFAULT_POSTMASTER; // Set the \Flagged flag. memset(msgflags, 0, sizeof(msgflags)); msgflags[IMAP_FLAG_FLAGGED] = 1; // Get the user's login name. char *to = auth_get_userid(user_idnr); new_message = dbmail_message_new(NULL); new_message = dbmail_message_construct(new_message, to, from, subject, body); // Pre-insert the message and get a new_message->id dbmail_message_store(new_message); uint64_t tmpid = new_message->id; if (sort_deliver_to_mailbox(new_message, user_idnr, "INBOX", BOX_BRUTEFORCE, msgflags, NULL) != DSN_CLASS_OK) { TRACE(TRACE_ERR, "Unable to deliver alert [%s] to user [%" PRIu64 "]", subject, user_idnr); } g_free(to); db_delete_message(tmpid); dbmail_message_free(new_message); return 0; }
/* 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; }