X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Finboxrules%2Fserv_inboxrules.c;h=676662068098619cff99e172403bc8491662b65c;hb=37f40684d11b6206a0f26fafa7a7615cdf404319;hp=0baf9320071f7a2de1df5e45eeebf74c113612e9;hpb=de0d012a56984bc9bc2db60c6909f43afbaa94ef;p=citadel.git diff --git a/citadel/modules/inboxrules/serv_inboxrules.c b/citadel/modules/inboxrules/serv_inboxrules.c index 0baf93200..676662068 100644 --- a/citadel/modules/inboxrules/serv_inboxrules.c +++ b/citadel/modules/inboxrules/serv_inboxrules.c @@ -424,7 +424,6 @@ int ctdl_getheaders(sieve2_context_t *s, void *my) { } - /* * Perform sieve processing for one message (called by sieve_do_room() for each message) */ @@ -819,112 +818,11 @@ BAIL: #endif - -/* - * A user account is identified as requring inbox processing. - * Do it. - */ -void do_inbox_processing_for_user(long usernum) { - if (CtdlGetUserByNumber(&CC->user, usernum) == 0) { - TRACE; - if (CC->user.msgnum_inboxrules <= 0) { - return; // this user has no inbox rules - } - - struct CtdlMessage *msg; - char *conf; - long conflen; - - msg = CtdlFetchMessage(CC->user.msgnum_inboxrules, 1, 1); - if (msg == NULL) { - return; // config msgnum is set but that message does not exist - } - - CM_GetAsField(msg, eMesageText, &conf, &conflen); - CM_Free(msg); - - if (conf == NULL) { - return; // config message exists but body is null - } - - - syslog(LOG_DEBUG, "RULEZ for %s", CC->user.fullname); - syslog(LOG_DEBUG, "%s", conf); - - // do something now FIXME actually write this - - free(conf); - } -} - - -/* - * Here is an array of users (by number) who have received messages in their inbox and may require processing. -*/ -long *users_requiring_inbox_processing = NULL; -int num_urip = 0; -int num_urip_alloc = 0; - - -/* - * Perform inbox processing for all rooms which require it - */ -void perform_inbox_processing(void) { - if (num_urip == 0) { - return; // no action required - } - - for (int i=0; iQRname[11], MAILROOM)) { - long usernum = atol(room->QRname); - if (usernum > 0) { - - // first check to see if this user is already on the list - if (num_urip > 0) { - for (int i=0; i<=num_urip; ++i) { - if (users_requiring_inbox_processing[i] == usernum) { // already on the list! - return(0); - } - } - } - - // make room if we need to - if (num_urip_alloc == 0) { - num_urip_alloc = 100; - users_requiring_inbox_processing = malloc(sizeof(long) * num_urip_alloc); - } - else if (num_urip >= num_urip_alloc) { - num_urip_alloc += 100; - users_requiring_inbox_processing = realloc(users_requiring_inbox_processing, (sizeof(long) * num_urip_alloc)); - } - - // now add the user to the list - users_requiring_inbox_processing[num_urip++] = usernum; - } - } - - // No errors are possible from this function. - return(0); -} - +// Fields to be compared enum { field_from, field_tocc, @@ -960,7 +858,7 @@ char *field_keys[] = { "all" }; - +// Field comparison operators enum { fcomp_contains, fcomp_notcontains, @@ -978,6 +876,7 @@ char *fcomp_keys[] = { "notmatches" }; +// Actions enum { action_keep, action_discard, @@ -995,6 +894,7 @@ char *action_keys[] = { "vacation" }; +// Size comparison operators enum { scomp_larger, scomp_smaller @@ -1004,6 +904,7 @@ char *scomp_keys[] = { "smaller" }; +// Final actions enum { final_continue, final_stop @@ -1013,6 +914,7 @@ char *final_keys[] = { "stop" }; +// This data structure represents ONE inbox rule within the configuration. struct irule { int field_compare_op; int compared_field; @@ -1026,6 +928,7 @@ struct irule { int final_action; }; +// This data structure represents the entire inbox rules configuration AND current state for a single user. struct inboxrules { long lastproc; int num_rules; @@ -1033,15 +936,14 @@ struct inboxrules { }; +// Destructor for 'struct inboxrules' void free_inbox_rules(struct inboxrules *ibr) { free(ibr->rules); free(ibr); } -/* - * Convert the serialized inbox rules message to a data type. - */ +// Constructor for 'struct inboxrules' that deserializes the configuration from text input. struct inboxrules *deserialize_inbox_rules(char *serialized_rules) { int i; @@ -1067,7 +969,7 @@ struct inboxrules *deserialize_inbox_rules(char *serialized_rules) { // For backwards compatibility, "# WEBCIT_RULE" is an alias for "rule". // Prior to version 930, WebCit converted its rules to Sieve scripts, but saved the rules as comments for later re-editing. - // Now, the rules hidden in the comments are the real rules. + // Now, the rules hidden in the comments become the real rules. if (!strncasecmp(token, "# WEBCIT_RULE|", 14)) { strcpy(token, "rule|"); strcpy(&token[5], &token[14]); @@ -1075,26 +977,20 @@ struct inboxrules *deserialize_inbox_rules(char *serialized_rules) { // Lines containing actual rules are double-serialized with Base64. It seemed like a good idea at the time :( if (!strncasecmp(token, "rule|", 5)) { - syslog(LOG_DEBUG, "rule: %s", &token[5]); remove_token(&token[5], 0, '|'); char *decoded_rule = malloc(strlen(token)); CtdlDecodeBase64(decoded_rule, &token[5], strlen(&token[5])); - TRACE; - syslog(LOG_DEBUG, "%s", decoded_rule); - ibr->num_rules++; ibr->rules = realloc(ibr->rules, (sizeof(struct irule) * ibr->num_rules)); struct irule *new_rule = &ibr->rules[ibr->num_rules - 1]; memset(new_rule, 0, sizeof(struct irule)); // We have a rule , now parse it - syslog(LOG_DEBUG, "Detokenizing: %s", decoded_rule); char rtoken[SIZ]; int nt = num_tokens(decoded_rule, '|'); for (int t=0; tcompared_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 } @@ -1177,15 +1073,118 @@ struct inboxrules *deserialize_inbox_rules(char *serialized_rules) { } free(sr); // free our copy of the source buffer that has now been trashed with null bytes... - abort(); return(ibr); // and return our complex data type to the caller. } +/* + * A user account is identified as requring inbox processing. + * Do it. + */ +void do_inbox_processing_for_user(long usernum) { + struct CtdlMessage *msg; + struct inboxrules *ii; + + if (CtdlGetUserByNumber(&CC->user, usernum) == 0) { + if (CC->user.msgnum_inboxrules <= 0) { + return; // this user has no inbox rules + } + + msg = CtdlFetchMessage(CC->user.msgnum_inboxrules, 1, 1); + if (msg == NULL) { + return; // config msgnum is set but that message does not exist + } + + ii = deserialize_inbox_rules(msg->cm_fields[eMesageText]); + CM_Free(msg); + + if (ii == NULL) { + return; // config message exists but body is null + } + + TRACE; + syslog(LOG_DEBUG, "RULEZ for %s", CC->user.fullname); + + // do something now FIXME actually write this + free_inbox_rules(ii); + } +} + + +/* + * Here is an array of users (by number) who have received messages in their inbox and may require processing. +*/ +long *users_requiring_inbox_processing = NULL; +int num_urip = 0; +int num_urip_alloc = 0; + + +/* + * Perform inbox processing for all rooms which require it + */ +void perform_inbox_processing(void) { + if (num_urip == 0) { + return; // no action required + } + + for (int i=0; iQRname[11], MAILROOM)) { + long usernum = atol(room->QRname); + if (usernum > 0) { + + // first check to see if this user is already on the list + if (num_urip > 0) { + for (int i=0; i<=num_urip; ++i) { + if (users_requiring_inbox_processing[i] == usernum) { // already on the list! + return(0); + } + } + } + + // make room if we need to + if (num_urip_alloc == 0) { + num_urip_alloc = 100; + users_requiring_inbox_processing = malloc(sizeof(long) * num_urip_alloc); + } + else if (num_urip >= num_urip_alloc) { + num_urip_alloc += 100; + users_requiring_inbox_processing = realloc(users_requiring_inbox_processing, (sizeof(long) * num_urip_alloc)); + } + + // now add the user to the list + users_requiring_inbox_processing[num_urip++] = usernum; + } + } + + // No errors are possible from this function. + return(0); +} + + + /* * Get InBox Rules * * This is a client-facing function which fetches the user's inbox rules -- it omits all lines containing anything other than a rule. + * + * hmmmmm ... should we try to rebuild this in terms of deserialize_inbox_rules() instread? */ void cmd_gibr(char *argbuf) { @@ -1196,11 +1195,6 @@ void cmd_gibr(char *argbuf) { struct CtdlMessage *msg = CtdlFetchMessage(CC->user.msgnum_inboxrules, 1, 1); if (msg != NULL) { if (!CM_IsEmpty(msg, eMesageText)) { - - - struct inboxrules *ii = deserialize_inbox_rules(msg->cm_fields[eMesageText]); - free_inbox_rules(ii); - char *token; char *rest = msg->cm_fields[eMesageText]; while ((token = strtok_r(rest, "\n", &rest))) {