X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmsgbase.c;h=d000812dd0e3a2b1a824ac64809b5c796c82726a;hb=8eac29db12e027867644fcac287a6b4c34e067c7;hp=c91ead1c1bd3cdbc58c4d432759205d1148c9aff;hpb=0fb5338232a4bf51b97efd6e156be1081559b93e;p=citadel.git diff --git a/citadel/msgbase.c b/citadel/msgbase.c index c91ead1c1..d000812dd 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -504,14 +504,14 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums, * API function to perform an operation for each qualifying message in the * current room. (Returns the number of messages processed.) */ -int CtdlForEachMessage(int mode, long ref, +int CtdlForEachMessage(int mode, long ref, char *search_string, char *content_type, struct CtdlMessage *compare, void (*CallBack) (long, void *), void *userdata) { - int a; + int a, i, j; struct visit vbuf; struct cdbdata *cdbfr; long *msglist = NULL; @@ -523,6 +523,8 @@ int CtdlForEachMessage(int mode, long ref, int is_seen = 0; long lastold = 0L; int printed_lastold = 0; + int num_search_msgs = 0; + long *search_msgs = NULL; /* Learn about the user and room in question */ get_mm(); @@ -587,7 +589,45 @@ int CtdlForEachMessage(int mode, long ref, } } + /* If a search string was specified, get a message list from + * the full text index and remove messages which aren't on both + * lists. + * + * How this works: + * Since the lists are sorted and strictly ascending, and the + * output list is guaranteed to be shorter than or equal to the + * input list, we overwrite the bottom of the input list. This + * eliminates the need to memmove big chunks of the list over and + * over again. + */ + if ( (num_msgs > 0) && (mode == MSGS_SEARCH) && (search_string) ) { + ft_search(&num_search_msgs, &search_msgs, search_string); + if (num_search_msgs > 0) { + int orig_num_msgs; + + orig_num_msgs = num_msgs; + num_msgs = 0; + for (i=0; ilogged_in)) && (!(CC->internal_pgm))) { cprintf("%d not logged in\n", ERROR + NOT_LOGGED_IN); return; } + if ( (mode == MSGS_SEARCH) && (!config.c_enable_fulltext) ) { + cprintf("%d Full text index is not enabled on this server.\n", + ERROR + CMD_NOT_SUPPORTED); + return; + } + if (with_template) { unbuffer_output(); cprintf("%d Send template then receive message list\n", @@ -695,7 +746,8 @@ void cmd_msgs(char *cmdbuf) } CtdlForEachMessage(mode, - cm_ref, + ( (mode == MSGS_SEARCH) ? 0 : cm_ref ), + ( (mode == MSGS_SEARCH) ? search_string : NULL ), NULL, template, (with_headers ? headers_listing : simple_listing), @@ -3431,25 +3483,45 @@ int CtdlDoIHavePermissionToDeleteMessagesFromThisRoom(void) { /* * Delete message from current room */ -void cmd_dele(char *delstr) +void cmd_dele(char *args) { - long delnum; int num_deleted; + int i; + char msgset[SIZ]; + char msgtok[32]; + long *msgs; + int num_msgs = 0; + + extract_token(msgset, args, 0, '|', sizeof msgset); + num_msgs = num_tokens(msgset, ','); + if (num_msgs < 1) { + cprintf("%d Nothing to do.\n", CIT_OK); + return; + } if (CtdlDoIHavePermissionToDeleteMessagesFromThisRoom() == 0) { cprintf("%d Higher access required.\n", ERROR + HIGHER_ACCESS_REQUIRED); return; } - delnum = extract_long(delstr, 0); - num_deleted = CtdlDeleteMessages(CC->room.QRname, &delnum, 1, "", 1); + /* + * Build our message set to be moved/copied + */ + msgs = malloc(num_msgs * sizeof(long)); + for (i=0; iroom.QRname, msgs, num_msgs, "", 1); + free(msgs); if (num_deleted) { cprintf("%d %d message%s deleted.\n", CIT_OK, num_deleted, ((num_deleted != 1) ? "s" : "")); } else { - cprintf("%d Message %ld not found.\n", ERROR + MESSAGE_NOT_FOUND, delnum); + cprintf("%d Message not found.\n", ERROR + MESSAGE_NOT_FOUND); } } @@ -3807,7 +3879,7 @@ char *CtdlGetSysConfig(char *sysconfname) { /* We want the last (and probably only) config in this room */ begin_critical_section(S_CONFIG); config_msgnum = (-1L); - CtdlForEachMessage(MSGS_LAST, 1, sysconfname, NULL, + CtdlForEachMessage(MSGS_LAST, 1, NULL, sysconfname, NULL, CtdlGetSysConfigBackend, NULL); msgnum = config_msgnum; end_critical_section(S_CONFIG);