X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Finboxrules%2Fserv_inboxrules.c;h=a3e0420307a65929d87f918d7bd31768128f9e6a;hb=f338fe3df988f4c9384e817237526325a31b6971;hp=fa9cca82acd06320d5d0c7aafafccc061b9b6e1c;hpb=7f9d699a7f73ac27bcbde2075a8758744036fb98;p=citadel.git diff --git a/citadel/modules/inboxrules/serv_inboxrules.c b/citadel/modules/inboxrules/serv_inboxrules.c index fa9cca82a..a3e042030 100644 --- a/citadel/modules/inboxrules/serv_inboxrules.c +++ b/citadel/modules/inboxrules/serv_inboxrules.c @@ -834,8 +834,8 @@ char *final_keys[] = { // This data structure represents ONE inbox rule within the configuration. struct irule { - int field_compare_op; int compared_field; + int field_compare_op; char compared_value[128]; int size_compare_op; long compared_size; @@ -967,18 +967,18 @@ struct inboxrules *deserialize_inbox_rules(char *serialized_rules) { free(decoded_rule); // if we re-serialized this now, what would it look like? - //syslog(LOG_DEBUG, "test reserialize: 0|%s|%s|%s|%s|%ld|%s|%s|%s|%s|%s", - //field_keys[new_rule->compared_field], - //fcomp_keys[new_rule->field_compare_op], - //new_rule->compared_value, - //scomp_keys[new_rule->size_compare_op], - //new_rule->compared_size, - //action_keys[new_rule->action], - //new_rule->file_into, - //new_rule->redirect_to, - //new_rule->autoreply_message, - //final_keys[new_rule->final_action] - //); + syslog(LOG_DEBUG, "test reserialize: 0|%s|%s|%s|%s|%ld|%s|%s|%s|%s|%s", + field_keys[new_rule->compared_field], + fcomp_keys[new_rule->field_compare_op], + new_rule->compared_value, + scomp_keys[new_rule->size_compare_op], + new_rule->compared_size, + action_keys[new_rule->action], + new_rule->file_into, + new_rule->redirect_to, + new_rule->autoreply_message, + final_keys[new_rule->final_action] + ); // delete the above after moving it to a reserialize function } @@ -1000,13 +1000,212 @@ struct inboxrules *deserialize_inbox_rules(char *serialized_rules) { */ void inbox_do_msg(long msgnum, void *userdata) { struct inboxrules *ii = (struct inboxrules *) userdata; - struct CtdlMessage *msg; + struct CtdlMessage *msg = NULL; + int headers_loaded = 0; + int body_loaded = 0; + int metadata_loaded = 0; + int rule_activated = 0; // On each rule, this is set if the compare succeeds and the rule activates. + char compare_me[SIZ]; // On each rule, we will store the field to be compared here. + int i; + syslog(LOG_DEBUG, "inboxrules: processing message #%ld which is higher than %ld, we are in %s", msgnum, ii->lastproc, CC->room.QRname); - // FIXME you are here + if (ii->num_rules <= 0) { + syslog(LOG_DEBUG, "inboxrules: rule set is empty"); + return; + } + + for (i=0; inum_rules; ++i) { + syslog(LOG_DEBUG, "inboxrules: processing rule %d is %s", i, field_keys[ ii->rules[i].compared_field ]); + rule_activated = 0; + + // Before doing a field compare, check to see if we have the correct parts of the message in memory. + + switch(ii->rules[i].compared_field) { + // These fields require loading only the top-level headers + case field_from: // From: + case field_tocc: // To: or Cc: + case field_subject: // Subject: + case field_replyto: // Reply-to: + case field_listid: // List-ID: + case field_envto: // Envelope-to: + case field_envfrom: // Return-path: + if (!headers_loaded) { + syslog(LOG_DEBUG, "inboxrules: loading headers for message %ld", msgnum); + msg = CtdlFetchMessage(msgnum, 0); + if (!msg) { + return; + } + headers_loaded = 1; + } + break; + // These fields are not stored as Citadel headers, and therefore require a full message load. + case field_sender: + case field_resentfrom: + case field_resentto: + case field_xmailer: + case field_xspamflag: + case field_xspamstatus: + if (!body_loaded) { + syslog(LOG_DEBUG, "inboxrules: loading all of message %ld", msgnum); + if (msg != NULL) { + CM_Free(msg); + } + msg = CtdlFetchMessage(msgnum, 1); + if (!msg) { + return; + } + headers_loaded = 1; + body_loaded = 1; + } + break; + case field_size: + if (!metadata_loaded) { + syslog(LOG_DEBUG, "inboxrules: loading metadata for message %ld", msgnum); + // FIXME do this + metadata_loaded = 1; + } + break; + case field_all: + syslog(LOG_DEBUG, "this is an always-on rule"); + break; + default: + syslog(LOG_DEBUG, "inboxrules: unknown rule key"); + } + + // If the rule involves a field comparison, load the field to be compared. + compare_me[0] = 0; + switch(ii->rules[i].compared_field) { + + case field_from: // From: + + // FIXME we actually need the rfc822 address + syslog(LOG_DEBUG, "eAuthor is <%s>", msg->cm_fields[eAuthor]); + safestrncpy(compare_me, msg->cm_fields[eAuthor], sizeof compare_me); + break; + case field_tocc: // To: or Cc: + if (!IsEmptyStr(msg->cm_fields[eRecipient])) { + safestrncpy(compare_me, msg->cm_fields[eRecipient], sizeof compare_me); + } + if (!IsEmptyStr(msg->cm_fields[eCarbonCopY])) { + if (!IsEmptyStr(compare_me)) { + strcat(compare_me, ","); + } + safestrncpy(&compare_me[strlen(compare_me)], msg->cm_fields[eCarbonCopY], (sizeof compare_me - strlen(compare_me))); + } + break; + case field_subject: // Subject: + safestrncpy(compare_me, msg->cm_fields[eMsgSubject], sizeof compare_me); + break; + case field_replyto: // Reply-to: + safestrncpy(compare_me, msg->cm_fields[eReplyTo], sizeof compare_me); + break; + case field_listid: // List-ID: + safestrncpy(compare_me, msg->cm_fields[eListID], sizeof compare_me); + break; + case field_envto: // Envelope-to: + safestrncpy(compare_me, msg->cm_fields[eenVelopeTo], sizeof compare_me); + break; + case field_envfrom: // Return-path: + safestrncpy(compare_me, msg->cm_fields[eMessagePath], sizeof compare_me); + break; + + case field_sender: + case field_resentfrom: + case field_resentto: + case field_xmailer: + case field_xspamflag: + case field_xspamstatus: + + default: + break; + } + + // Message data to compare is loaded, now do something. + switch(ii->rules[i].compared_field) { + case field_from: // From: + case field_tocc: // To: or Cc: + case field_subject: // Subject: + case field_replyto: // Reply-to: + case field_listid: // List-ID: + case field_envto: // Envelope-to: + case field_envfrom: // Return-path: + case field_sender: + case field_resentfrom: + case field_resentto: + case field_xmailer: + case field_xspamflag: + case field_xspamstatus: + + // For all of the above fields, we can compare the field we've loaded into the buffer. + // FIXME you are here YOU ARE HERE + syslog(LOG_DEBUG, "Value of field to compare is: <%s>", compare_me); + switch(ii->rules[i].field_compare_op) { + case fcomp_contains: + case fcomp_matches: + rule_activated = (bmstrcasestr(compare_me, ii->rules[i].compared_value) ? 1 : 0); + break; + case fcomp_notcontains: + case fcomp_notmatches: + rule_activated = (bmstrcasestr(compare_me, ii->rules[i].compared_value) ? 0 : 1); + break; + case fcomp_is: + rule_activated = (strcasecmp(compare_me, ii->rules[i].compared_value) ? 0 : 1); + break; + case fcomp_isnot: + rule_activated = (strcasecmp(compare_me, ii->rules[i].compared_value) ? 1 : 0); + break; + } + + case field_size: + rule_activated = 0; // FIXME + break; + case field_all: // This rule always triggers + rule_activated = 1; + break; + default: + TRACE; + break; + } + + if (rule_activated) { + syslog(LOG_DEBUG, "rule activated"); + } + else { + syslog(LOG_DEBUG, "rule NOT activated"); + } + + + } + + TRACE; + if (msg != NULL) { + CM_Free(msg); + } - //msg = CtdlFetchMessage(msgnum, +//struct irule { + //int field_compare_op; + //int compared_field; + //char compared_value[128]; + //int size_compare_op; + //long compared_size; + //int action; + //char file_into[ROOMNAMELEN]; + //char redirect_to[1024]; + //char autoreply_message[SIZ]; + //int final_action; +//}; + +//struct inboxrules { + //long lastproc; + //int num_rules; + //struct irule *rules; + + + // Fetch the message, including the body, we need all of it to run our rules. + //msg = CtdlFetchMessage(msgnum, 0); + //CM_Free(msg); }