From ddebf8f5b3ce9c6b768c7aae49a200949945b5a2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Fri, 12 Mar 2010 20:26:08 +0000 Subject: [PATCH] * casting int to char* doesn't work out on 64 bit architectures * pass in a structure instead of casting stuf around all over the place --- citadel/imap_tools.h | 2 +- citadel/modules/imap/imap_list.c | 136 +++++++++++++++++------------- citadel/modules/imap/imap_tools.c | 2 +- 3 files changed, 78 insertions(+), 62 deletions(-) diff --git a/citadel/imap_tools.h b/citadel/imap_tools.h index 1db052be1..78e2f5afd 100644 --- a/citadel/imap_tools.h +++ b/citadel/imap_tools.h @@ -50,7 +50,7 @@ void imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf); void imap_ial_out(struct internet_address_list *ialist); int imap_roomname(char *buf, int bufsize, const char *foldername); int imap_is_message_set(const char *); -int imap_mailbox_matches_pattern(char *pattern, char *mailboxname); +int imap_mailbox_matches_pattern(const char *pattern, char *mailboxname); int imap_datecmp(const char *datestr, time_t msgtime); /* diff --git a/citadel/modules/imap/imap_list.c b/citadel/modules/imap/imap_list.c index 235acfdf4..4151981be 100644 --- a/citadel/modules/imap/imap_list.c +++ b/citadel/modules/imap/imap_list.c @@ -68,10 +68,21 @@ #include "ctdl_module.h" +typedef struct __ImapRoomListFilter { + char verb[16]; + int subscribed_rooms_only; + int return_subscribed; + int return_children; + + int num_patterns; + int num_patterns_avail; + StrBuf **patterns; +}ImapRoomListFilter; + /* * Used by LIST and LSUB to show the floors in the listing */ -void imap_list_floors(char *verb, int num_patterns, char **patterns) +void imap_list_floors(char *verb, int num_patterns, StrBuf **patterns) { int i; struct floor *fl; @@ -83,7 +94,7 @@ void imap_list_floors(char *verb, int num_patterns, char **patterns) if (fl->f_flags & F_INUSE) { match = 0; for (j=0; jf_name)) { + if (imap_mailbox_matches_pattern (ChrPtr(patterns[j]), fl->f_name)) { match = 1; } } @@ -111,32 +122,19 @@ void imap_listroom(struct ctdlroom *qrbuf, void *data) char return_options[256]; int ra; int yes_output_this_room; - - char **data_for_callback; - char *verb; - int subscribed_rooms_only; - int num_patterns; - char **patterns; - int return_subscribed = 0; - int return_children = 0; + ImapRoomListFilter *ImapFilter; int i = 0; int match = 0; /* Here's how we break down the array of pointers passed to us */ - data_for_callback = data; - verb = data_for_callback[0]; - subscribed_rooms_only = (int) data_for_callback[1]; - num_patterns = (int) data_for_callback[2]; - patterns = (char **) data_for_callback[3]; - return_subscribed = (int) data_for_callback[4]; - return_children = (int) data_for_callback[5]; + ImapFilter = (ImapRoomListFilter*)data; /* Only list rooms to which the user has access!! */ yes_output_this_room = 0; strcpy(return_options, ""); CtdlRoomAccess(qrbuf, &CC->user, &ra, NULL); - if (return_subscribed) { + if (ImapFilter->return_subscribed) { if (ra & UA_KNOWN) { strcat(return_options, "\\Subscribed"); } @@ -148,14 +146,14 @@ void imap_listroom(struct ctdlroom *qrbuf, void *data) * the \HasChildren attribute for every room. * We'll fix this later when we have time. */ - if (return_children) { + if (ImapFilter->return_children) { if (!IsEmptyStr(return_options)) { strcat(return_options, " "); } strcat(return_options, "\\HasChildren"); } - if (subscribed_rooms_only) { + if (ImapFilter->subscribed_rooms_only) { if (ra & UA_KNOWN) { yes_output_this_room = 1; } @@ -169,13 +167,13 @@ void imap_listroom(struct ctdlroom *qrbuf, void *data) if (yes_output_this_room) { imap_mailboxname(buf, sizeof buf, qrbuf); match = 0; - for (i=0; inum_patterns; ++i) { + if (imap_mailbox_matches_pattern(ChrPtr(ImapFilter->patterns[i]), buf)) { match = 1; } } if (match) { - cprintf("* %s (%s) \"/\" ", verb, return_options); + cprintf("* %s (%s) \"/\" ", ImapFilter->verb, return_options); plain_imap_strout(buf); cprintf("\r\n"); } @@ -189,11 +187,8 @@ void imap_listroom(struct ctdlroom *qrbuf, void *data) void imap_list(int num_parms, ConstStr *Params) { int subscribed_rooms_only = 0; - char verb[16]; int i, j, paren_nest; - char *data_for_callback[6]; - int num_patterns = 1; - char *patterns[MAX_PATTERNS]; + ImapRoomListFilter ImapFilter; int selection_left = (-1); int selection_right = (-1); int return_left = (-1); @@ -202,24 +197,27 @@ void imap_list(int num_parms, ConstStr *Params) int patterns_left = 3; int patterns_right = 3; int extended_list_in_use = 0; - int return_subscribed = 0; - int return_children = 0; if (num_parms < 4) { cprintf("%s BAD arguments invalid\r\n", Params[0].Key); return; } + ImapFilter.num_patterns = 1; + ImapFilter.return_subscribed = 0; + ImapFilter.return_children = 0; + + /* parms[1] is the IMAP verb being used (e.g. LIST or LSUB) * This tells us how to behave, and what verb to return back to the caller */ - safestrncpy(verb, Params[1].Key, sizeof verb); + safestrncpy(ImapFilter.verb, Params[1].Key, sizeof ImapFilter.verb); j = Params[1].len; for (i=0; i 1) + StrBufAppendBufPlain(ImapFilter.patterns[i], + 1 + CKEY(Params[root_pos]) - 1, 0); } - if (i == num_patterns-1) { - patterns[i][strlen(patterns[i])-1] = 0; + else + StrBufAppendBufPlain(ImapFilter.patterns[i], + CKEY(Params[root_pos]), 0); + + if (i == ImapFilter.num_patterns-1) { + if (Params[patterns_left+i].len > 1) + StrBufAppendBufPlain(ImapFilter.patterns[i], + CKEY(Params[patterns_left+i]) - 1, 0); } + else StrBufAppendBufPlain(ImapFilter.patterns[i], + CKEY(Params[patterns_left+i]), 0); + } + } } else { - num_patterns = 1; - patterns[0] = malloc(512); - snprintf(patterns[0], 512, "%s%s", - Params[root_pos].Key, - Params[patterns_left].Key); + ImapFilter.num_patterns = 1; + ImapFilter.patterns[0] = NewStrBufPlain(NULL, + Params[root_pos].len + + Params[patterns_left].len); + StrBufAppendBufPlain(ImapFilter.patterns[0], + CKEY(Params[root_pos]), 0); + StrBufAppendBufPlain(ImapFilter.patterns[0], + CKEY(Params[patterns_left]), 0); } /* If the word "RETURN" appears after the folder pattern list, then the client @@ -358,11 +376,11 @@ void imap_list(int num_parms, ConstStr *Params) CtdlLogPrintf(9, "evaluating <%s>\n", Params[i].Key); if (!strcasecmp(Params[i].Key, "SUBSCRIBED")) { - return_subscribed = 1; + ImapFilter.return_subscribed = 1; } else if (!strcasecmp(Params[i].Key, "CHILDREN")) { - return_children = 1; + ImapFilter.return_children = 1; } if (paren_nest == 0) { @@ -374,36 +392,34 @@ void imap_list(int num_parms, ConstStr *Params) /* Now start setting up the data we're going to send to the CtdlForEachRoom() callback. */ - data_for_callback[0] = (char *) verb; - data_for_callback[1] = (char *) subscribed_rooms_only; - data_for_callback[2] = (char *) num_patterns; - data_for_callback[3] = (char *) patterns; - data_for_callback[4] = (char *) return_subscribed; - data_for_callback[5] = (char *) return_children; - + /* The non-extended LIST command is required to treat an empty * ("" string) mailbox name argument as a special request to return the * hierarchy delimiter and the root name of the name given in the * reference parameter. */ - if ( (IsEmptyStr(patterns[0])) && (extended_list_in_use == 0) ) { - cprintf("* %s (\\Noselect) \"/\" \"\"\r\n", verb); + if ( (StrLength(ImapFilter.patterns[0]) == 0) && (extended_list_in_use == 0) ) { + cprintf("* %s (\\Noselect) \"/\" \"\"\r\n", ImapFilter.verb); } /* Non-empty mailbox names, and any form of the extended LIST command, * is handled by this loop. */ else { - imap_list_floors(verb, num_patterns, patterns); - CtdlForEachRoom(imap_listroom, data_for_callback); + imap_list_floors(ImapFilter.verb, + ImapFilter.num_patterns, + ImapFilter.patterns); + CtdlForEachRoom(imap_listroom, (char**)&ImapFilter); } /* * Free the pattern buffers we allocated above. */ - for (i=0; i