Example #1
0
time_t CheckIfAlreadySeen(const char *Facility,
			  StrBuf *guid,
			  time_t now,
			  time_t antiexpire,
			  eCheckType cType,
			  long ccid,
			  long ioid)
{
	time_t InDBTimeStamp = 0;
	struct UseTable ut;
	struct cdbdata *cdbut;

	if (cType != eWrite)
	{
		SEEN_syslog(LOG_DEBUG, "Loading [%s]", ChrPtr(guid));
		cdbut = cdb_fetch(CDB_USETABLE, SKEY(guid));
		if ((cdbut != NULL) && (cdbut->ptr != NULL)) {
			memcpy(&ut, cdbut->ptr,
			       ((cdbut->len > sizeof(struct UseTable)) ?
				sizeof(struct UseTable) : cdbut->len));
			InDBTimeStamp = now - ut.ut_timestamp;

			if (InDBTimeStamp < antiexpire)
			{
				SEEN_syslog(LOG_DEBUG, "Found - Not expired %ld < %ld", InDBTimeStamp, antiexpire);
				cdb_free(cdbut);
				return InDBTimeStamp;
			}
			else
			{
				SEEN_syslog(LOG_DEBUG, "Found - Expired. %ld >= %ld", InDBTimeStamp, antiexpire);
				cdb_free(cdbut);
			}
		}
		else
		{
			if (cdbut) cdb_free(cdbut);

			SEENM_syslog(LOG_DEBUG, "not Found");
		}

		if (cType == eCheckExist)
			return InDBTimeStamp;
	}

	memcpy(ut.ut_msgid, SKEY(guid));
	ut.ut_timestamp = now;

	SEENM_syslog(LOG_DEBUG, "Saving new Timestamp");
	/* rewrite the record anyway, to update the timestamp */
	cdb_store(CDB_USETABLE,
		  SKEY(guid),
		  &ut, sizeof(struct UseTable) );

	SEENM_syslog(LOG_DEBUG, "Done Saving");
	return InDBTimeStamp;
}
Example #2
0
//
// Utility function to fetch the current list of message numbers in a room
//
struct nntp_msglist nntp_fetch_msglist(struct ctdlroom *qrbuf) {
	struct nntp_msglist nm;
	struct cdbdata *cdbfr;

	cdbfr = cdb_fetch(CDB_MSGLISTS, &qrbuf->QRnumber, sizeof(long));
	if (cdbfr != NULL) {
		nm.msgnums = (long*)cdbfr->ptr;
		cdbfr->ptr = NULL;
		nm.num_msgs = cdbfr->len / sizeof(long);
		cdbfr->len = 0;
		cdb_free(cdbfr);
	} else {
		nm.num_msgs = 0;
		nm.msgnums = NULL;
	}
	return(nm);
}
Example #3
0
void cmd_rsen(char *argbuf) {
	char Token[SIZ];
	long TLen;
	char Time[SIZ];

	struct UseTable ut;
	struct cdbdata *cdbut;
	
	if (CtdlAccessCheck(ac_aide)) return;

	TLen = extract_token(Token, argbuf, 1, '|', sizeof Token);
	if (strncmp(argbuf, "GET", 3) == 0) {
		cdbut = cdb_fetch(CDB_USETABLE, Token, TLen);
		if (cdbut != NULL) {
			memcpy(&ut, cdbut->ptr,
			       ((cdbut->len > sizeof(struct UseTable)) ?
				sizeof(struct UseTable) : cdbut->len));
			
			cprintf("%d %ld\n", CIT_OK, ut.ut_timestamp);
		}
		else {
			cprintf("%d not found\n", ERROR + NOT_HERE);
		}

	}
	else if (strncmp(argbuf, "SET", 3) == 0) {
		memcpy(ut.ut_msgid, Token, TLen);
		extract_token(Time, argbuf, 2, '|', sizeof Time);
		ut.ut_timestamp = atol(Time);
		cdb_store(CDB_USETABLE,
			  Token, TLen,
			  &ut, sizeof(struct UseTable) );
		cprintf("%d token updated\n", CIT_OK);
	}
	else if (strncmp(argbuf, "DEL", 3) == 0) {
		if (cdb_delete(CDB_USETABLE, Token, TLen))
			cprintf("%d not found\n", ERROR + NOT_HERE);
		else
			cprintf("%d deleted.\n", CIT_OK);

	}
	else {
		cprintf("%d Usage: [GET|SET|DEL]|Token|timestamp\n", ERROR);
	}

}
Example #4
0
/*
 * Attach an OpenID to a Citadel account
 */
int attach_openid(struct ctdluser *who, StrBuf *claimed_id)
{
	struct cdbdata *cdboi;
	long fetched_usernum;
	char *data;
	int data_len;
	char buf[2048];

	if (!who) return(1);
	if (StrLength(claimed_id)==0) return(1);

	/* Check to see if this OpenID is already in the database */

	cdboi = cdb_fetch(CDB_OPENID, ChrPtr(claimed_id), StrLength(claimed_id));
	if (cdboi != NULL) {
		memcpy(&fetched_usernum, cdboi->ptr, sizeof(long));
		cdb_free(cdboi);

		if (fetched_usernum == who->usernum) {
			syslog(LOG_INFO, "%s already associated; no action is taken", ChrPtr(claimed_id));
			return(0);
		}
		else {
			syslog(LOG_INFO, "%s already belongs to another user", ChrPtr(claimed_id));
			return(3);
		}
	}

	/* Not already in the database, so attach it now */

	data_len = sizeof(long) + StrLength(claimed_id) + 1;
	data = malloc(data_len);

	memcpy(data, &who->usernum, sizeof(long));
	memcpy(&data[sizeof(long)], ChrPtr(claimed_id), StrLength(claimed_id) + 1);

	cdb_store(CDB_OPENID, ChrPtr(claimed_id), StrLength(claimed_id), data, data_len);
	free(data);

	snprintf(buf, sizeof buf, "User <%s> (#%ld) has claimed the OpenID URL %s\n",
		 who->fullname, who->usernum, ChrPtr(claimed_id));
	CtdlAideMessage(buf, "OpenID claim");
	syslog(LOG_INFO, "%s", buf);
	return(0);
}
Example #5
0
/*
 * callback to get highest room number when rebuilding control file
 */
void control_find_highest(struct ctdlroom *qrbuf, void *data)
{
	struct ctdlroom room;
	struct cdbdata *cdbfr;
	long *msglist;
	int num_msgs=0;
	int c;
	int room_fixed = 0;
	int message_fixed = 0;
	
	if (qrbuf->QRnumber > CitControl.MMnextroom)
	{
		CitControl.MMnextroom = qrbuf->QRnumber;
		room_fixed = 1;
	}
		
	CtdlGetRoom (&room, qrbuf->QRname);
	
	/* Load the message list */
	cdbfr = cdb_fetch(CDB_MSGLISTS, &room.QRnumber, sizeof(long));
	if (cdbfr != NULL) {
		msglist = (long *) cdbfr->ptr;
		num_msgs = cdbfr->len / sizeof(long);
	} else {
		return;	/* No messages at all?  No further action. */
	}

	if (num_msgs>0)
	{
		for (c=0; c<num_msgs; c++)
		{
			if (msglist[c] > CitControl.MMhighest)
			{
				CitControl.MMhighest = msglist[c];
				message_fixed = 1;
			}
		}
	}
	cdb_free(cdbfr);
	if (room_fixed)
		syslog(LOG_INFO, "Control record checking....Fixed room counter\n");
	if (message_fixed)
		syslog(LOG_INFO, "Control record checking....Fixed message count\n");
	return;
}
Example #6
0
/*
 * Look up an Internet e-mail address in the directory.
 * On success: returns 0, and Citadel address stored in 'target'
 * On failure: returns nonzero
 */
int CtdlDirectoryLookup(char *target, char *internet_addr, size_t targbuflen) {
	struct cdbdata *cdbrec;
	char key[SIZ];

	/* Dump it in there unchanged, just for kicks */
	safestrncpy(target, internet_addr, targbuflen);

	/* Only do lookups for addresses with hostnames in them */
	if (num_tokens(internet_addr, '@') != 2) return(-1);

	/* Only do lookups for domains in the directory */
	if (IsDirectory(internet_addr, 0) == 0) return(-1);

	directory_key(key, internet_addr);
	cdbrec = cdb_fetch(CDB_DIRECTORY, key, strlen(key) );
	if (cdbrec != NULL) {
		safestrncpy(target, cdbrec->ptr, targbuflen);
		cdb_free(cdbrec);
		return(0);
	}

	return(-1);
}
Example #7
0
/*
 * If a user account exists which is associated with the Claimed ID, log it in and return zero.
 * Otherwise it returns nonzero.
 */
int login_via_openid(StrBuf *claimed_id)
{
	struct cdbdata *cdboi;
	long usernum = 0;

	cdboi = cdb_fetch(CDB_OPENID, ChrPtr(claimed_id), StrLength(claimed_id));
	if (cdboi == NULL) {
		return(-1);
	}

	memcpy(&usernum, cdboi->ptr, sizeof(long));
	cdb_free(cdboi);

	if (!CtdlGetUserByNumber(&CC->user, usernum)) {
		/* Now become the user we just created */
		safestrncpy(CC->curr_user, CC->user.fullname, sizeof CC->curr_user);
		do_login();
		return(0);
	}
	else {
		memset(&CC->user, 0, sizeof(struct ctdluser));
		return(-1);
	}
}
Example #8
0
/*
 * First phase of message purge -- gather the locations of messages which
 * qualify for purging and write them to a temp file.
 */
void GatherPurgeMessages(struct ctdlroom *qrbuf, void *data) {
	struct ExpirePolicy epbuf;
	long delnum;
	time_t xtime, now;
	struct CtdlMessage *msg = NULL;
	int a;
	struct cdbdata *cdbfr;
	long *msglist = NULL;
	int num_msgs = 0;
	FILE *purgelist;

	purgelist = (FILE *)data;
	fprintf(purgelist, "r=%s\n", qrbuf->QRname);

	time(&now);
	GetExpirePolicy(&epbuf, qrbuf);

	/* If the room is set to never expire messages ... do nothing */
	if (epbuf.expire_mode == EXPIRE_NEXTLEVEL) return;
	if (epbuf.expire_mode == EXPIRE_MANUAL) return;

	/* Don't purge messages containing system configuration, dumbass. */
	if (!strcasecmp(qrbuf->QRname, SYSCONFIGROOM)) return;

	/* Ok, we got this far ... now let's see what's in the room */
	cdbfr = cdb_fetch(CDB_MSGLISTS, &qrbuf->QRnumber, sizeof(long));

	if (cdbfr != NULL) {
		msglist = malloc(cdbfr->len);
		memcpy(msglist, cdbfr->ptr, cdbfr->len);
		num_msgs = cdbfr->len / sizeof(long);
		cdb_free(cdbfr);
	}

	/* Nothing to do if there aren't any messages */
	if (num_msgs == 0) {
		if (msglist != NULL) free(msglist);
		return;
	}


	/* If the room is set to expire by count, do that */
	if (epbuf.expire_mode == EXPIRE_NUMMSGS) {
		if (num_msgs > epbuf.expire_value) {
			for (a=0; a<(num_msgs - epbuf.expire_value); ++a) {
				fprintf(purgelist, "m=%ld\n", msglist[a]);
				++messages_purged;
			}
		}
	}

	/* If the room is set to expire by age... */
	if (epbuf.expire_mode == EXPIRE_AGE) {
		for (a=0; a<num_msgs; ++a) {
			delnum = msglist[a];

			msg = CtdlFetchMessage(delnum, 0); /* dont need body */
			if (msg != NULL) {
				xtime = atol(msg->cm_fields[eTimestamp]);
				CM_Free(msg);
			} else {
				xtime = 0L;
			}

			if ((xtime > 0L)
			   && (now - xtime > (time_t)(epbuf.expire_value * 86400L))) {
				fprintf(purgelist, "m=%ld\n", delnum);
				++messages_purged;
			}
		}
	}

	if (msglist != NULL) free(msglist);
}
Example #9
0
/*
 * API call to perform searches.
 * (This one does the "all of these words" search.)
 * Caller is responsible for freeing the message list.
 */
void ft_search(int *fts_num_msgs, long **fts_msgs, const char *search_string) {
	int num_tokens = 0;
	int *tokens = NULL;
	int i, j;
	struct cdbdata *cdb_bucket;
	int num_all_msgs = 0;
	long *all_msgs = NULL;
	int num_ret_msgs = 0;
	int num_ret_alloc = 0;
	long *ret_msgs = NULL;
	int tok;

	wordbreaker(search_string, &num_tokens, &tokens);
	if (num_tokens > 0) {
		for (i=0; i<num_tokens; ++i) {

			/* search for tokens[i] */
			tok = tokens[i];

			/* fetch the bucket, Liza */
			if (ftc_msgs[tok] == NULL) {
				cdb_bucket = cdb_fetch(CDB_FULLTEXT, &tok, sizeof(int));
				if (cdb_bucket != NULL) {
					ftc_num_msgs[tok] = cdb_bucket->len / sizeof(long);
					ftc_msgs[tok] = (long *)cdb_bucket->ptr;
					cdb_bucket->ptr = NULL;
					cdb_free(cdb_bucket);
				}
				else {
					ftc_num_msgs[tok] = 0;
					ftc_msgs[tok] = malloc(sizeof(long));
				}
			}

			num_all_msgs += ftc_num_msgs[tok];
			if (num_all_msgs > 0) {
				all_msgs = realloc(all_msgs, num_all_msgs*sizeof(long) );
				memcpy(&all_msgs[num_all_msgs-ftc_num_msgs[tok]],
					ftc_msgs[tok], ftc_num_msgs[tok]*sizeof(long) );
			}

		}
		free(tokens);
		if (all_msgs != NULL) {
			qsort(all_msgs, num_all_msgs, sizeof(long), longcmp);

			/*
			 * At this point, if a message appears num_tokens times in the
			 * list, then it contains all of the search tokens.
			 */
			if (num_all_msgs >= num_tokens)
				for (j=0; j<(num_all_msgs-num_tokens+1); ++j) {
					if (all_msgs[j] == all_msgs[j+num_tokens-1]) {
						
						++num_ret_msgs;
						if (num_ret_msgs > num_ret_alloc) {
							num_ret_alloc += 64;
							ret_msgs = realloc(ret_msgs,
									   (num_ret_alloc*sizeof(long)) );
						}
						ret_msgs[num_ret_msgs - 1] = all_msgs[j];
						
					}
				}
			free(all_msgs);
		}
	}

	*fts_num_msgs = num_ret_msgs;
	*fts_msgs = ret_msgs;
}
Example #10
0
/*
 * Index or de-index a message.  (op == 1 to index, 0 to de-index)
 */
void ft_index_message(long msgnum, int op) {
	int num_tokens = 0;
	int *tokens = NULL;
	int i, j;
	struct cdbdata *cdb_bucket;
	StrBuf *msgtext;
	char *txt;
	int tok;
	struct CtdlMessage *msg = NULL;

	msg = CtdlFetchMessage(msgnum, 1, 1);
	if (msg == NULL) {
		syslog(LOG_ERR, "ft_index_message() could not load msg %ld", msgnum);
		return;
	}

	if (!CM_IsEmpty(msg, eSuppressIdx)) {
		syslog(LOG_DEBUG, "ft_index_message() excluded msg %ld", msgnum);
		CM_Free(msg);
		return;
	}

	syslog(LOG_DEBUG, "ft_index_message() %s msg %ld", (op ? "adding" : "removing") , msgnum);

	/* Output the message as text before indexing it, so we don't end up
	 * indexing a bunch of encoded base64, etc.
	 */
	CC->redirect_buffer = NewStrBufPlain(NULL, SIZ);
	CtdlOutputPreLoadedMsg(msg, MT_CITADEL, HEADERS_ALL, 0, 1, 0);
	CM_Free(msg);
	msgtext = CC->redirect_buffer;
	CC->redirect_buffer = NULL;
	if (msgtext != NULL) {
		syslog(LOG_DEBUG, "Wordbreaking message %ld (%d bytes)", msgnum, StrLength(msgtext));
	}
	txt = SmashStrBuf(&msgtext);
	wordbreaker(txt, &num_tokens, &tokens);
	free(txt);

	syslog(LOG_DEBUG, "Indexing message %ld [%d tokens]", msgnum, num_tokens);
	if (num_tokens > 0) {
		for (i=0; i<num_tokens; ++i) {

			/* Add the message to the relevant token bucket */

			/* search for tokens[i] */
			tok = tokens[i];

			if ( (tok >= 0) && (tok <= 65535) ) {
				/* fetch the bucket, Liza */
				if (ftc_msgs[tok] == NULL) {
					cdb_bucket = cdb_fetch(CDB_FULLTEXT, &tok, sizeof(int));
					if (cdb_bucket != NULL) {
						ftc_num_msgs[tok] = cdb_bucket->len / sizeof(long);
						ftc_msgs[tok] = (long *)cdb_bucket->ptr;
						cdb_bucket->ptr = NULL;
						cdb_free(cdb_bucket);
					}
					else {
						ftc_num_msgs[tok] = 0;
						ftc_msgs[tok] = malloc(sizeof(long));
					}
				}
	
	
				if (op == 1) {	/* add to index */
					++ftc_num_msgs[tok];
					ftc_msgs[tok] = realloc(ftc_msgs[tok],
								ftc_num_msgs[tok]*sizeof(long));
					ftc_msgs[tok][ftc_num_msgs[tok] - 1] = msgnum;
				}
	
				if (op == 0) {	/* remove from index */
					if (ftc_num_msgs[tok] >= 1) {
						for (j=0; j<ftc_num_msgs[tok]; ++j) {
							if (ftc_msgs[tok][j] == msgnum) {
								memmove(&ftc_msgs[tok][j], &ftc_msgs[tok][j+1], ((ftc_num_msgs[tok] - j - 1)*sizeof(long)));
								--ftc_num_msgs[tok];
								--j;
							}
						}
					}
				}
			}
			else {
				syslog(LOG_ALERT, "Invalid token %d !!", tok);
			}
		}

		free(tokens);
	}
}
Example #11
0
/*
 * Attempt to autocomplete an address based on a partial...
 */
void cmd_auto(char *argbuf) {
	char hold_rm[ROOMNAMELEN];
	char search_string[256];
	long *msglist = NULL;
	int num_msgs = 0;
	long *fts_msgs = NULL;
	int fts_num_msgs = 0;
	struct cdbdata *cdbfr;
	int r = 0;
	int i = 0;
	int j = 0;
	int search_match = 0;
	char *rooms_to_try[] = { USERCONTACTSROOM, ADDRESS_BOOK_ROOM };
		
	if (CtdlAccessCheck(ac_logged_in)) return;
	extract_token(search_string, argbuf, 0, '|', sizeof search_string);
	if (IsEmptyStr(search_string)) {
		cprintf("%d You supplied an empty partial.\n",
			ERROR + ILLEGAL_VALUE);
		return;
	}

	strcpy(hold_rm, CC->room.QRname);       /* save current room */
	cprintf("%d try these:\n", LISTING_FOLLOWS);

	/*
	 * Gather up message pointers in rooms containing vCards
	 */
	for (r=0; r < (sizeof(rooms_to_try) / sizeof(char *)); ++r) {
		if (CtdlGetRoom(&CC->room, rooms_to_try[r]) == 0) {
			cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long));
			if (cdbfr != NULL) {
				msglist = realloc(msglist, (num_msgs * sizeof(long)) + cdbfr->len + 1);
				memcpy(&msglist[num_msgs], cdbfr->ptr, cdbfr->len);
				num_msgs += (cdbfr->len / sizeof(long));
				cdb_free(cdbfr);
			}
		}
	}

	/*
	 * Search-reduce the results if we have the full text index available
	 */
	if (config.c_enable_fulltext) {
		CtdlModuleDoSearch(&fts_num_msgs, &fts_msgs, search_string, "fulltext");
		if (fts_msgs) {
			for (i=0; i<num_msgs; ++i) {
				search_match = 0;
				for (j=0; j<fts_num_msgs; ++j) {
					if (msglist[i] == fts_msgs[j]) {
						search_match = 1;
						j = fts_num_msgs + 1;	/* end the search */
					}
				}
				if (!search_match) {
					msglist[i] = 0;		/* invalidate this result */
				}
			}
			free(fts_msgs);
		}
		else {
			/* If no results, invalidate the whole list */
			free(msglist);
			msglist = NULL;
			num_msgs = 0;
		}
	}

	/*
	 * Now output the ones that look interesting
	 */
	if (num_msgs > 0) for (i=0; i<num_msgs; ++i) {
		if (msglist[i] != 0) {
			hunt_for_autocomplete(msglist[i], search_string);
		}
	}
	
	cprintf("000\n");
	if (strcmp(CC->room.QRname, hold_rm)) {
		CtdlGetRoom(&CC->room, hold_rm);    /* return to saved room */
	}

	if (msglist) {
		free(msglist);
	}
	
}