コード例 #1
0
ファイル: imap_search.c プロジェクト: henri14/citadel
/*
 * imap_search() calls imap_do_search() to do its actual work, once it's
 * validated and boiled down the request a bit.
 */
void imap_do_search(int num_items, ConstStr *itemlist, int is_uid) {
	citimap *Imap = IMAP;
	int i, j, k;
	int fts_num_msgs = 0;
	long *fts_msgs = NULL;
	int is_in_list = 0;
	int num_results = 0;

	/* Strip parentheses.  We realize that this method will not work
	 * in all cases, but it seems to work with all currently available
	 * client software.  Revisit later...
	 */
	for (i=0; i<num_items; ++i) {
		if (itemlist[i].Key[0] == '(') {
			
			TokenCutLeft(&Imap->Cmd, 
				     &itemlist[i], 
				     1);
		}
		if (itemlist[i].Key[itemlist[i].len-1] == ')') {
			TokenCutRight(&Imap->Cmd, 
				      &itemlist[i], 
				      1);
		}
	}

	/* If there is a BODY search criterion in the query, use our full
	 * text index to disqualify messages that don't have any chance of
	 * matching.  (Only do this if the index is enabled!!)
	 */
	if (config.c_enable_fulltext) for (i=0; i<(num_items-1); ++i) {
		if (!strcasecmp(itemlist[i].Key, "BODY")) {
			CtdlModuleDoSearch(&fts_num_msgs, &fts_msgs, itemlist[i+1].Key, "fulltext");
			if (fts_num_msgs > 0) {
				for (j=0; j < Imap->num_msgs; ++j) {
					if (Imap->flags[j] & IMAP_SELECTED) {
						is_in_list = 0;
						for (k=0; k<fts_num_msgs; ++k) {
							if (Imap->msgids[j] == fts_msgs[k]) {
								++is_in_list;
							}
						}
					}
					if (!is_in_list) {
						Imap->flags[j] = Imap->flags[j] & ~IMAP_SELECTED;
					}
				}
			}
			else {		/* no hits on the index; disqualify every message */
				for (j=0; j < Imap->num_msgs; ++j) {
					Imap->flags[j] = Imap->flags[j] & ~IMAP_SELECTED;
				}
			}
			if (fts_msgs) {
				free(fts_msgs);
			}
		}
	}

	/* Now go through the messages and apply all search criteria. */
	buffer_output();
	IAPuts("* SEARCH ");
	if (Imap->num_msgs > 0)
	 for (i = 0; i < Imap->num_msgs; ++i)
	  if (Imap->flags[i] & IMAP_SELECTED) {
		if (imap_do_search_msg(i+1, NULL, num_items, itemlist, is_uid)) {
			if (num_results != 0) {
				IAPuts(" ");
			}
			if (is_uid) {
				IAPrintf("%ld", Imap->msgids[i]);
			}
			else {
				IAPrintf("%d", i+1);
			}
			++num_results;
		}
	}
	IAPuts("\r\n");
	unbuffer_output();
}
コード例 #2
0
ファイル: imap_acl.c プロジェクト: mingodad/citadel
/*
 * Implements the GETACL command.
 */
void imap_getacl(int num_parms, ConstStr *Params) {
	char roomname[ROOMNAMELEN];
	char savedroom[ROOMNAMELEN];
	int msgs, new;
	int ret;
	struct ctdluser temp;
	struct cdbdata *cdbus;
	int ra;
	StrBuf *rights;

	if (num_parms != 3) {
		IReply("BAD usage error");
		return;
	}

	/*
	 * Search for the specified room or folder
	 */
	ret = imap_grabroom(roomname, Params[2].Key, 1);
	if (ret != 0) {
		IReply("NO Invalid mailbox name or access denied");
		return;
	}

	/*
	 * CtdlUserGoto() formally takes us to the desired room.  (If another
	 * folder is selected, save its name so we can return there!!!!!)
	 */
	if (IMAP->selected) {
		strcpy(savedroom, CC->room.QRname);
	}
	CtdlUserGoto(roomname, 0, 0, &msgs, &new, NULL, NULL);

	IAPuts("* ACL ");
	IPutCParamStr(2);

	/*
	 * Traverse the userlist
	 */
	rights = NewStrBuf();
	cdb_rewind(CDB_USERS);
	while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) 
	{
		memset(&temp, 0, sizeof temp);
		memcpy(&temp, cdbus->ptr, sizeof temp);
		cdb_free(cdbus);

		CtdlRoomAccess(&CC->room, &temp, &ra, NULL);
		if (!IsEmptyStr(temp.fullname)) {
			imap_acl_flags(rights, ra);
			if (StrLength(rights) > 0) {
				IAPuts(" ");
				IPutStr(temp.fullname, strlen(temp.fullname));
				IAPuts(" ");
				iaputs(SKEY( rights));
			}
		}
	}
	FreeStrBuf(&rights);
	IAPuts("\r\n");

	/*
	 * If another folder is selected, go back to that room so we can resume
	 * our happy day without violent explosions.
	 */
	if (IMAP->selected) {
		CtdlUserGoto(savedroom, 0, 0, &msgs, &new, NULL, NULL);
	}