예제 #1
0
/*
 * Fetch the "mortuary" - a list of dead buddies which we keep around forever
 * so we can remove them from any client's roster that still has them listed
 */
void xmpp_store_mortuary(HashList *mortuary) {
	HashPos *HashPos;
	long len;
	void *Value;
	const char *Key;
	StrBuf *themsg;

	themsg = NewStrBuf();
	StrBufPrintf(themsg,	"Content-type: " XMPPMORTUARY "\n"
				"Content-transfer-encoding: 7bit\n"
				"\n"
	);

	HashPos = GetNewHashPos(mortuary, 0);
	while (GetNextHashPos(mortuary, HashPos, &len, &Key, &Value) != 0)
	{
		StrBufAppendPrintf(themsg, "%s\n", (char *)Value);
	}
	DeleteHashPos(&HashPos);

	/* Delete the old mortuary */
	CtdlDeleteMessages(USERCONFIGROOM, NULL, 0, XMPPMORTUARY);

	/* And save the new one to disk */
	quickie_message("Citadel", NULL, NULL, USERCONFIGROOM, ChrPtr(themsg), 4, "XMPP Mortuary");
	FreeStrBuf(&themsg);
}
예제 #2
0
파일: netconf.c 프로젝트: mingodad/citadel
void save_net_conf(HashList *Nodelist)
{
	char buf[SIZ];
	StrBuf *Buf;
	HashPos *where;
	void *vNode;
	NodeConf *Node;
	const char *Key;
	long KeyLen;

	serv_puts("CONF putsys|application/x-citadel-ignet-config");
	serv_getln(buf, sizeof buf);
	if (buf[0] == '4') {
		if ((Nodelist != NULL) && (GetCount(Nodelist) > 0)) {
			where = GetNewHashPos(Nodelist, 0);
			Buf = NewStrBuf();
			while (GetNextHashPos(Nodelist, where, &KeyLen, &Key, &vNode)) {
				Node = (NodeConf*) vNode;
				if (Node->DeleteMe==0) { 
					SerializeNode(Node, Buf);
					serv_putbuf(Buf);
				}
			}
			FreeStrBuf(&Buf);
			DeleteHashPos(&where);
		}
		serv_puts("000");
	}
}
예제 #3
0
int CountActiveQueueEntries(OneQueItem *MyQItem, int before)
{
	HashPos  *It;
	long len;
	long ActiveDeliveries;
	const char *Key;
	void *vQE;

	ActiveDeliveries = 0;
	It = GetNewHashPos(MyQItem->MailQEntries, 0);
	while (GetNextHashPos(MyQItem->MailQEntries, It, &len, &Key, &vQE))
	{
		int Active;
		MailQEntry *ThisItem = vQE;

		if (CheckQEntryActive(ThisItem))
		{
			ActiveDeliveries++;
			Active = 1;
		}
		else
			Active = 0;
		if (before)
			ThisItem->Active = Active;
		else
			ThisItem->StillActive = Active;
	}
	DeleteHashPos(&It);
	return ActiveDeliveries;
}
예제 #4
0
StrBuf *SerializeQueueItem(OneQueItem *MyQItem)
{
	StrBuf *QMessage;
	HashPos  *It;
	const char *Key;
	long len;
	void *vQE;

	QMessage = NewStrBufPlain(NULL, SIZ);
	StrBufPrintf(QMessage, "Content-type: %s\n", SPOOLMIME);
//	"attempted|%ld\n"  "retry|%ld\n",, (long)time(NULL), (long)retry );
	StrBufAppendBufPlain(QMessage, HKEY("\nmsgid|"), 0);
	StrBufAppendPrintf(QMessage, "%ld", MyQItem->MessageID);

	StrBufAppendBufPlain(QMessage, HKEY("\nsubmitted|"), 0);
	StrBufAppendPrintf(QMessage, "%ld", MyQItem->Submitted);

	if (StrLength(MyQItem->BounceTo) > 0) {
		StrBufAppendBufPlain(QMessage, HKEY("\nbounceto|"), 0);
		StrBufAppendBuf(QMessage, MyQItem->BounceTo, 0);
	}

	if (StrLength(MyQItem->EnvelopeFrom) > 0) {
		StrBufAppendBufPlain(QMessage, HKEY("\nenvelope_from|"), 0);
		StrBufAppendBuf(QMessage, MyQItem->EnvelopeFrom, 0);
	}

	if (StrLength(MyQItem->SenderRoom) > 0) {
		StrBufAppendBufPlain(QMessage, HKEY("\nsource_room|"), 0);
		StrBufAppendBuf(QMessage, MyQItem->SenderRoom, 0);
	}

	StrBufAppendBufPlain(QMessage, HKEY("\nretry|"), 0);
	StrBufAppendPrintf(QMessage, "%ld",
			   MyQItem->Retry);

	StrBufAppendBufPlain(QMessage, HKEY("\nattempted|"), 0);
	StrBufAppendPrintf(QMessage, "%ld",
			   time(NULL) /*ctdl_ev_now()*/ + MyQItem->Retry);

	It = GetNewHashPos(MyQItem->MailQEntries, 0);
	while (GetNextHashPos(MyQItem->MailQEntries, It, &len, &Key, &vQE))
	{
		MailQEntry *ThisItem = vQE;

		StrBufAppendBufPlain(QMessage, HKEY("\nremote|"), 0);
		StrBufAppendBuf(QMessage, ThisItem->Recipient, 0);
		StrBufAppendBufPlain(QMessage, HKEY("|"), 0);
		StrBufAppendPrintf(QMessage, "%d", ThisItem->Status);
		StrBufAppendBufPlain(QMessage, HKEY("|"), 0);
		if (ThisItem->AllStatusMessages != NULL)
			StrBufAppendBuf(QMessage, ThisItem->AllStatusMessages, 0);
		else
			StrBufAppendBuf(QMessage, ThisItem->StatusMessage, 0);
	}
	DeleteHashPos(&It);
	StrBufAppendBufPlain(QMessage, HKEY("\n"), 0);
	return QMessage;
}
예제 #5
0
static void DBQueueEventAddCallback(EV_P_ ev_async *w, int revents)
{
	CitContext *Ctx;
	long IOID = -1;
	long count = 0;;
	ev_tstamp Now;
	HashList *q;
	void *v;
	HashPos *It;
	long len;
	const char *Key;

	/* get the control command... */
	pthread_mutex_lock(&DBEventQueueMutex);

	if (DBInboundEventQueues[0] == DBInboundEventQueue) {
		DBInboundEventQueue = DBInboundEventQueues[1];
		q = DBInboundEventQueues[0];
	}
	else {
		DBInboundEventQueue = DBInboundEventQueues[0];
		q = DBInboundEventQueues[1];
	}
	pthread_mutex_unlock(&DBEventQueueMutex);

	Now = ev_now (event_db);
	It = GetNewHashPos(q, 0);
	while (GetNextHashPos(q, It, &len, &Key, &v))
	{
		IOAddHandler *h = v;
		eNextState rc;
		count ++;
		if (h->IO->ID == 0)
			h->IO->ID = EvIDSource++;
		IOID = h->IO->ID;
		if (h->IO->StartDB == 0.0)
			h->IO->StartDB = Now;
		h->IO->CitContext->lastcmd = h->IO->Now = Now;

		SetEVState(h->IO, eDBAttach);
		Ctx = h->IO->CitContext;
		become_session(Ctx);
		ev_cleanup_start(event_db, &h->IO->db_abort_by_shutdown);
		rc = h->EvAttch(h->IO);
		switch (rc)
		{
		case eAbort:
			ShutDownDBCLient(h->IO);
		default:
			break;
		}
	}
	DeleteHashPos(&It);
	DeleteHashContent(&q);
	EVQ_syslog(LOG_DEBUG, "%s CC[%ld] DBEVENT Q Add %ld done.", IOSTR, IOID, count);
}
예제 #6
0
eNextState POP3_FetchNetworkUsetableEntry(AsyncIO *IO)
{
	long HKLen;
	const char *HKey;
	void *vData;
	pop3aggr *RecvMsg = (pop3aggr *) IO->Data;

	SetPOP3State(IO, eUseTable);

	if((RecvMsg->Pos != NULL) &&
	   GetNextHashPos(RecvMsg->MsgNumbers,
			  RecvMsg->Pos,
			  &HKLen,
			  &HKey,
			  &vData))
	{
		if (server_shutting_down)
			return eAbort;

		if (CheckIfAlreadySeen("POP3 Item Seen",
				       RecvMsg->CurrMsg->MsgUID,
				       EvGetNow(IO),
				       EvGetNow(IO) - USETABLE_ANTIEXPIRE,
				       eCheckUpdate,
				       IO->ID, CCID)
		    != 0)
		{
			/* Item has already been seen */
			RecvMsg->CurrMsg->NeedFetch = 0;
		}
		else
		{
			EVP3CCSM_syslog(LOG_DEBUG, "NO\n");
			RecvMsg->CurrMsg->NeedFetch = 1;
		}
		return NextDBOperation(&RecvMsg->IO,
				       POP3_FetchNetworkUsetableEntry);
	}
	else
	{
		/* ok, now we know them all,
		 * continue with reading the actual messages. */
		DeleteHashPos(&RecvMsg->Pos);
		return DBQueueEventContext(IO, POP3_C_ReAttachToFetchMessages);
	}
}
예제 #7
0
int AnalyseHeaders(ParsedHttpHdrs *Hdr)
{
	OneHttpHeader *pHdr;
	void *vHdr;
	long HKLen;
	const char *HashKey;
	HashPos *at = GetNewHashPos(Hdr->HTTPHeaders, 0);
	
	while (GetNextHashPos(Hdr->HTTPHeaders, at, &HKLen, &HashKey, &vHdr) && 
	       (vHdr != NULL)) {
		pHdr = (OneHttpHeader *)vHdr;
		if (pHdr->HaveEvaluator)
			pHdr->H(pHdr->Val, Hdr);

	}
	DeleteHashPos(&at);
	return 0;
}
예제 #8
0
/*
 * Purge OpenID assocations for missing users (theoretically this will never delete anything)
 */
int PurgeStaleOpenIDassociations(void) {
	struct cdbdata *cdboi;
	struct ctdluser usbuf;
	HashList *keys = NULL;
	HashPos *HashPos;
	char *deleteme = NULL;
	long len;
	void *Value;
	const char *Key;
	int num_deleted = 0;
	long usernum = 0L;

	keys = NewHash(1, NULL);
	if (!keys) return(0);


	cdb_rewind(CDB_OPENID);
	while (cdboi = cdb_next_item(CDB_OPENID), cdboi != NULL) {
		if (cdboi->len > sizeof(long)) {
			memcpy(&usernum, cdboi->ptr, sizeof(long));
			if (CtdlGetUserByNumber(&usbuf, usernum) != 0) {
				deleteme = strdup(cdboi->ptr + sizeof(long)),
				Put(keys, deleteme, strlen(deleteme), deleteme, NULL);
			}
		}
		cdb_free(cdboi);
	}

	/* Go through the hash list, deleting keys we stored in it */

	HashPos = GetNewHashPos(keys, 0);
	while (GetNextHashPos(keys, HashPos, &len, &Key, &Value)!=0)
	{
		syslog(LOG_DEBUG, "Deleting associated OpenID <%s>",  (char*)Value);
		cdb_delete(CDB_OPENID, Value, strlen(Value));
		/* note: don't free(Value) -- deleting the hash list will handle this for us */
		++num_deleted;
	}
	DeleteHashPos(&HashPos);
	DeleteHash(&keys);
	return num_deleted;
}
예제 #9
0
void cmd_log_get(char *argbuf)
{
	long HKLen;
	const char *ch;
	HashPos *Pos;
	void *vptr;

	if (CtdlAccessCheck(ac_aide)) return;

	cprintf("%d Log modules enabled:\n", LISTING_FOLLOWS);

	Pos = GetNewHashPos(LogDebugEntryTable, 0);

	while (GetNextHashPos(LogDebugEntryTable, Pos, &HKLen, &ch, &vptr)) {
		LogDebugEntry *E = (LogDebugEntry*)vptr;
		cprintf("%s|%d\n", ch, *E->LogP);
	}
	
	DeleteHashPos(&Pos);
	cprintf("000\n");
}
예제 #10
0
eNextState POP3C_GetOneMessagID(pop3aggr *RecvMsg)
{
	AsyncIO *IO = &RecvMsg->IO;
	long HKLen;
	const char *HKey;
	void *vData;

	SetPOP3State(IO, eGetMsgID);
#if 0
	int rc;
	rc = TestValidateHash(RecvMsg->MsgNumbers);
	if (rc != 0)
		EVP3CCS_syslog(LOG_DEBUG, "Hash Invalid: %d\n", rc);
#endif
	if((RecvMsg->Pos != NULL) &&
	   GetNextHashPos(RecvMsg->MsgNumbers,
			  RecvMsg->Pos,
			  &HKLen, &HKey,
			  &vData))
	{
		RecvMsg->CurrMsg = (FetchItem*) vData;
		/* Find out the UIDL of the message,
		 * to determine whether we've already downloaded it */
		StrBufPrintf(RecvMsg->IO.SendBuf.Buf,
			     "UIDL %ld\r\n", RecvMsg->CurrMsg->MSGID);
		POP3C_DBG_SEND();
	}
	else
	{
		RecvMsg->State++;
		DeleteHashPos(&RecvMsg->Pos);
		/// done receiving uidls.. start looking them up now.
		RecvMsg->Pos = GetNewHashPos(RecvMsg->MsgNumbers, 0);
		return EventQueueDBOperation(&RecvMsg->IO,
					     POP3_FetchNetworkUsetableEntry,
					     0);
	}
	return eReadMore; /* TODO */
}
예제 #11
0
void DeletePOP3Aggregator(void *vptr)
{
	pop3aggr *ptr = vptr;
	DeleteHashPos(&ptr->Pos);
	DeleteHash(&ptr->MsgNumbers);
//	FreeStrBuf(&ptr->rooms);
	FreeStrBuf(&ptr->pop3user);
	FreeStrBuf(&ptr->pop3pass);
	FreeStrBuf(&ptr->Host);
	FreeStrBuf(&ptr->RoomName);
	FreeURL(&ptr->IO.ConnectMe);
	FreeStrBuf(&ptr->Url);
	FreeStrBuf(&ptr->IO.IOBuf);
	FreeStrBuf(&ptr->IO.SendBuf.Buf);
	FreeStrBuf(&ptr->IO.RecvBuf.Buf);
	DeleteAsyncMsg(&ptr->IO.ReadMsg);
	if (((struct CitContext*)ptr->IO.CitContext)) {
		((struct CitContext*)ptr->IO.CitContext)->state = CON_IDLE;
		((struct CitContext*)ptr->IO.CitContext)->kill_me = 1;
	}
	FreeAsyncIOContents(&ptr->IO);
	free(ptr);
}
예제 #12
0
void RemoveQItem(OneQueItem *MyQItem)
{
	long len;
	const char* Key;
	void *VData;
	HashPos  *It;

	pthread_mutex_lock(&ActiveQItemsLock);
	It = GetNewHashPos(ActiveQItems, 0);
	if (GetHashPosFromKey(ActiveQItems, LKEY(MyQItem->MessageID), It))
		DeleteEntryFromHash(ActiveQItems, It);
	else
	{
		SMTPC_syslog(LOG_WARNING,
			     "unable to find QItem with ID[%ld]",
			     MyQItem->MessageID);
		while (GetNextHashPos(ActiveQItems, It, &len, &Key, &VData))
			SMTPC_syslog(LOG_WARNING,
				     "have_: ID[%ld]",
				     ((OneQueItem *)VData)->MessageID);
	}
	pthread_mutex_unlock(&ActiveQItemsLock);
	DeleteHashPos(&It);
}
예제 #13
0
/*
 * Stupidly, XMPP does not specify a way to tell the client to flush its client-side roster
 * and prepare to receive a new one.  So instead we remember every buddy we've ever told the
 * client about, and push delete operations out at the beginning of a session.
 * 
 * We omit any users who happen to be online right now, but we still keep them in the mortuary,
 * which needs to be maintained as a list of every buddy the user has ever seen.  We don't know
 * when they're connecting from the same client and when they're connecting from a different client,
 * so we have no guarantee of what is in the client side roster at connect time.
 */
void xmpp_delete_old_buddies_who_no_longer_exist_from_the_client_roster(void)
{
	long len;
	void *Value;
	const char *Key;
	struct CitContext *cptr;
	int nContexts, i;
	int online_now = 0;
	HashList *mortuary = xmpp_fetch_mortuary();
	HashPos *HashPos = GetNewHashPos(mortuary, 0);

	/* we need to omit anyone who is currently online */
	cptr = CtdlGetContextArray(&nContexts);

	/* go through the list of users in the mortuary... */
	while (GetNextHashPos(mortuary, HashPos, &len, &Key, &Value) != 0)
	{

		online_now = 0;
		if (cptr) for (i=0; i<nContexts; i++) {
			if (xmpp_is_visible(&cptr[i], CC)) {
				if (!strcasecmp(cptr[i].cs_inet_email, (char *)Value)) {
					online_now = 1;
				}
			}
		}

		if (!online_now) {
			xmpp_destroy_buddy((char *)Value, 1);	/* aggressive presence update */
		}

	}
	DeleteHashPos(&HashPos);
	DeleteHash(&mortuary);
	free(cptr);
}
예제 #14
0
eNextState FinalizePOP3AggrRun(AsyncIO *IO)
{
	HashPos  *It;
	pop3aggr *cpptr = (pop3aggr *)IO->Data;

	EVP3C_syslog(LOG_INFO,
		     "%s@%s: fetched %ld new of %d messages in %fs. bye.",
		     ChrPtr(cpptr->pop3user),
		     ChrPtr(cpptr->Host),
		     cpptr->count,
		     GetCount(cpptr->MsgNumbers), 
		     IO->Now - cpptr->IOStart 
		);

	It = GetNewHashPos(POP3FetchUrls, 0);
	pthread_mutex_lock(&POP3QueueMutex);
	{
		if (GetHashPosFromKey(POP3FetchUrls, SKEY(cpptr->Url), It))
			DeleteEntryFromHash(POP3FetchUrls, It);
	}
	pthread_mutex_unlock(&POP3QueueMutex);
	DeleteHashPos(&It);
	return eAbort;
}
예제 #15
0
/*
 * Finalize an OpenID authentication
 */
void cmd_oidf(char *argbuf) {
	long len;
	char buf[2048];
	char thiskey[1024];
	char thisdata[1024];
	HashList *keys = NULL;
	const char *Key;
	void *Value;
	ctdl_openid *oiddata = (ctdl_openid *) CC->openid_data;

	if (CtdlGetConfigInt("c_disable_newu"))
	{
		cprintf("%d this system does not support openid.\n",
			ERROR + CMD_NOT_SUPPORTED);
		return;
	}
	if (oiddata == NULL) {
		cprintf("%d run OIDS first.\n", ERROR + INTERNAL_ERROR);
		return;
	}
	if (StrLength(oiddata->op_url) == 0){
		cprintf("%d No OpenID Endpoint URL has been obtained.\n", ERROR + ILLEGAL_VALUE);
		return;
	}
	keys = NewHash(1, NULL);
	if (!keys) {
		cprintf("%d NewHash() failed\n", ERROR + INTERNAL_ERROR);
		return;
	}
	cprintf("%d Transmit OpenID data now\n", START_CHAT_MODE);

	while (client_getln(buf, sizeof buf), strcmp(buf, "000")) {
		len = extract_token(thiskey, buf, 0, '|', sizeof thiskey);
		if (len < 0) {
			len = sizeof(thiskey) - 1;
		}
		extract_token(thisdata, buf, 1, '|', sizeof thisdata);
		Put(keys, thiskey, len, strdup(thisdata), NULL);
	}

	/* Check to see if this is a correct response.
	 * Start with verified=1 but then set it to 0 if anything looks wrong.
	 */
	oiddata->verified = 1;

	char *openid_ns = NULL;
	if (	(!GetHash(keys, "ns", 2, (void *) &openid_ns))
		|| (strcasecmp(openid_ns, "http://specs.openid.net/auth/2.0"))
	) {
		syslog(LOG_DEBUG, "This is not an an OpenID assertion");
		oiddata->verified = 0;
	}

	char *openid_mode = NULL;
	if (	(!GetHash(keys, "mode", 4, (void *) &openid_mode))
		|| (strcasecmp(openid_mode, "id_res"))
	) {
		oiddata->verified = 0;
	}

	char *openid_claimed_id = NULL;
	if (GetHash(keys, "claimed_id", 10, (void *) &openid_claimed_id)) {
		FreeStrBuf(&oiddata->claimed_id);
		oiddata->claimed_id = NewStrBufPlain(openid_claimed_id, -1);
		syslog(LOG_DEBUG, "Provider is asserting the Claimed ID '%s'", ChrPtr(oiddata->claimed_id));
	}

	/* Validate the assertion against the server */
	syslog(LOG_DEBUG, "Validating...");

	CURL *curl;
	CURLcode res;
	struct curl_httppost *formpost = NULL;
	struct curl_httppost *lastptr = NULL;
	char errmsg[1024] = "";
	StrBuf *ReplyBuf = NewStrBuf();

	curl_formadd(&formpost, &lastptr,
		CURLFORM_COPYNAME,	"openid.mode",
		CURLFORM_COPYCONTENTS,	"check_authentication",
		CURLFORM_END
	);

	HashPos *HashPos = GetNewHashPos(keys, 0);
	while (GetNextHashPos(keys, HashPos, &len, &Key, &Value) != 0) {
		if (strcasecmp(Key, "mode")) {
			char k_o_keyname[1024];
			snprintf(k_o_keyname, sizeof k_o_keyname, "openid.%s", (const char *)Key);
			curl_formadd(&formpost, &lastptr,
				CURLFORM_COPYNAME,	k_o_keyname,
				CURLFORM_COPYCONTENTS,	(char *)Value,
				CURLFORM_END
			);
		}
	}
	DeleteHashPos(&HashPos);

	curl = ctdl_openid_curl_easy_init(errmsg);
	curl_easy_setopt(curl, CURLOPT_URL, ChrPtr(oiddata->op_url));
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, ReplyBuf);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlFillStrBuf_callback);
	curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);

	res = curl_easy_perform(curl);
	if (res) {
		syslog(LOG_DEBUG, "cmd_oidf() libcurl error %d: %s", res, errmsg);
		oiddata->verified = 0;
	}
	curl_easy_cleanup(curl);
	curl_formfree(formpost);

	/* syslog(LOG_DEBUG, "Validation reply: \n%s", ChrPtr(ReplyBuf)); */
	if (cbmstrcasestr(ChrPtr(ReplyBuf), "is_valid:true") == NULL) {
		oiddata->verified = 0;
	}
	FreeStrBuf(&ReplyBuf);

	syslog(LOG_DEBUG, "OpenID authentication %s", (oiddata->verified ? "succeeded" : "failed") );

	/* Respond to the client */

	if (oiddata->verified) {

		/* If we were already logged in, attach the OpenID to the user's account */
		if (CC->logged_in) {
			if (attach_openid(&CC->user, oiddata->claimed_id) == 0) {
				cprintf("attach\n");
				syslog(LOG_DEBUG, "OpenID attach succeeded");
			}
			else {
				cprintf("fail\n");
				syslog(LOG_DEBUG, "OpenID attach failed");
			}
		}

		/* Otherwise, a user is attempting to log in using the verified OpenID */	
		else {
			/*
			 * Existing user who has claimed this OpenID?
			 *
			 * Note: if you think that sending the password back over the wire is insecure,
			 * check your assumptions.  If someone has successfully asserted an OpenID that
			 * is associated with the account, they already have password equivalency and can
			 * login, so they could just as easily change the password, etc.
			 */
			if (login_via_openid(oiddata->claimed_id) == 0) {
				cprintf("authenticate\n%s\n%s\n", CC->user.fullname, CC->user.password);
				logged_in_response();
				syslog(LOG_DEBUG, "Logged in using previously claimed OpenID");
			}

			/*
			 * If this system does not allow self-service new user registration, the
			 * remaining modes do not apply, so fail here and now.
			 */
			else if (CtdlGetConfigInt("c_disable_newu")) {
				cprintf("fail\n");
				syslog(LOG_DEBUG, "Creating user failed due to local policy");
			}

			/*
			 * New user whose OpenID is verified and Attribute Exchange gave us a name?
			 */
			else if (openid_create_user_via_ax(oiddata->claimed_id, keys) == 0) {
				cprintf("authenticate\n%s\n%s\n", CC->user.fullname, CC->user.password);
				logged_in_response();
				syslog(LOG_DEBUG, "Successfully auto-created new user");
			}

			/*
			 * OpenID is verified, but the desired username either was not specified or
			 * conflicts with an existing user.  Manual account creation is required.
			 */
			else {
				char *desired_name = NULL;
				cprintf("verify_only\n");
				cprintf("%s\n", ChrPtr(oiddata->claimed_id));
				if (GetHash(keys, "sreg.nickname", 13, (void *) &desired_name)) {
					cprintf("%s\n", desired_name);
				}
				else {
					cprintf("\n");
				}
				syslog(LOG_DEBUG, "The desired display name is already taken.");
			}
		}
	}
	else {
		cprintf("fail\n");
	}
	cprintf("000\n");

	if (oiddata->sreg_keys != NULL) {
		DeleteHash(&oiddata->sreg_keys);
		oiddata->sreg_keys = NULL;
	}
	oiddata->sreg_keys = keys;
}
예제 #16
0
/*
 * Attempt to auto-create a new Citadel account using the nickname from Attribute Exchange
 */
int openid_create_user_via_ax(StrBuf *claimed_id, HashList *sreg_keys)
{
	char *nickname = NULL;
	char *firstname = NULL;
	char *lastname = NULL;
	char new_password[32];
	long len;
	const char *Key;
	void *Value;

	if (CtdlGetConfigInt("c_auth_mode") != AUTHMODE_NATIVE) return(1);
	if (CtdlGetConfigInt("c_disable_newu")) return(2);
	if (CC->logged_in) return(3);

	HashPos *HashPos = GetNewHashPos(sreg_keys, 0);
	while (GetNextHashPos(sreg_keys, HashPos, &len, &Key, &Value) != 0) {
		syslog(LOG_DEBUG, "%s = %s", Key, (char *)Value);

		if (cbmstrcasestr(Key, "value.nickname") != NULL) {
			nickname = (char *)Value;
		}
		else if ( (nickname == NULL) && (cbmstrcasestr(Key, "value.nickname") != NULL)) {
			nickname = (char *)Value;
		}
		else if (cbmstrcasestr(Key, "value.firstname") != NULL) {
			firstname = (char *)Value;
		}
		else if (cbmstrcasestr(Key, "value.lastname") != NULL) {
			lastname = (char *)Value;
		}

	}
	DeleteHashPos(&HashPos);

	if (nickname == NULL) {
		if ((firstname != NULL) || (lastname != NULL)) {
			char fullname[1024] = "";
			if (firstname) strcpy(fullname, firstname);
			if (firstname && lastname) strcat(fullname, " ");
			if (lastname) strcat(fullname, lastname);
			nickname = fullname;
		}
	}

	if (nickname == NULL) {
		return(4);
	}
	syslog(LOG_DEBUG, "The desired account name is <%s>", nickname);

	len = cutuserkey(nickname);
	if (!CtdlGetUser(&CC->user, nickname)) {
		syslog(LOG_DEBUG, "<%s> is already taken by another user.", nickname);
		memset(&CC->user, 0, sizeof(struct ctdluser));
		return(5);
	}

	/* The desired account name is available.  Create the account and log it in! */
	if (create_user(nickname, len, 1)) return(6);

	/* Generate a random password.
	 * The user doesn't care what the password is since he is using OpenID.
	 */
	snprintf(new_password, sizeof new_password, "%08lx%08lx", random(), random());
	CtdlSetPassword(new_password);

	/* Now attach the verified OpenID to this account. */
	attach_openid(&CC->user, claimed_id);

	return(0);
}
예제 #17
0
/*
 * smtp_do_bounce() is caled by smtp_do_procmsg() to scan a set of delivery
 * instructions for "5" codes (permanent fatal errors) and produce/deliver
 * a "bounce" message (delivery status notification).
 */
void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt, ParsedURL *Relay)
{
	static int seq = 0;
	
	struct CtdlMessage *bmsg = NULL;
	StrBuf *boundary;
	StrBuf *Msg = NULL;
	StrBuf *BounceMB;
	recptypes *valid;
	time_t now;

	HashPos *It;
	void *vQE;
	long len;
	const char *Key;

	int first_attempt = 0;
	int successful_bounce = 0;
	int num_bounces = 0;
	int give_up = 0;

	SMTPCM_syslog(LOG_DEBUG, "smtp_do_bounce() called\n");

	if (MyQItem->SendBounceMail == 0)
		return;

	now = time (NULL); //ev_time();

	if ( (now - MyQItem->Submitted) > SMTP_GIVE_UP ) {
		give_up = 1;
	}

	if (MyQItem->Retry == SMTP_RETRY_INTERVAL) {
		first_attempt = 1;
	}

	/*
	 * Now go through the instructions checking for stuff.
	 */
	Msg = NewStrBufPlain(NULL, 1024);
	It = GetNewHashPos(MyQItem->MailQEntries, 0);
	while (GetNextHashPos(MyQItem->MailQEntries, It, &len, &Key, &vQE))
	{
		MailQEntry *ThisItem = vQE;
		if ((ThisItem->Active && (ThisItem->Status == 5)) || /* failed now? */
		    ((give_up == 1) && (ThisItem->Status != 2)) ||
		    ((first_attempt == 1) && (ThisItem->Status != 2)))
			/* giving up after failed attempts... */
		{
			++num_bounces;

			StrBufAppendBufPlain(Msg, HKEY(" "), 0);
			StrBufAppendBuf(Msg, ThisItem->Recipient, 0);
			StrBufAppendBufPlain(Msg, HKEY(": "), 0);
			if (ThisItem->AllStatusMessages != NULL)
				StrBufAppendBuf(Msg, ThisItem->AllStatusMessages, 0);
			else
				StrBufAppendBuf(Msg, ThisItem->StatusMessage, 0);
			StrBufAppendBufPlain(Msg, HKEY("\r\n"), 0);
		}
	}
	DeleteHashPos(&It);

	/* Deliver the bounce if there's anything worth mentioning */
	SMTPC_syslog(LOG_DEBUG, "num_bounces = %d\n", num_bounces);

	if (num_bounces == 0) {
		FreeStrBuf(&Msg);
		return;
	}

	if ((StrLength(MyQItem->SenderRoom) == 0) && MyQItem->HaveRelay) {
		const char *RelayUrlStr = "[not found]";
		/* one message that relaying is broken is enough; no extra room error message. */
		StrBuf *RelayDetails = NewStrBuf();

		if (Relay != NULL)
			RelayUrlStr = ChrPtr(Relay->URL);

		StrBufPrintf(RelayDetails,
			     "Relaying via %s failed permanently. \n Reason:\n%s\n Revalidate your relay configuration.",
			     RelayUrlStr,
			     ChrPtr(Msg));
                CtdlAideMessage(ChrPtr(RelayDetails), "Relaying Failed");
		FreeStrBuf(&RelayDetails);
	}

	boundary = NewStrBufPlain(HKEY("=_Citadel_Multipart_"));
	StrBufAppendPrintf(boundary,
			   "%s_%04x%04x",
			   CtdlGetConfigStr("c_fqdn"),
			   getpid(),
			   ++seq);

	/* Start building our bounce message; go shopping for memory first. */
	BounceMB = NewStrBufPlain(
		NULL,
		1024 + /* mime stuff.... */
		StrLength(Msg) +  /* the bounce information... */
		StrLength(OMsgTxt)); /* the original message */
	if (BounceMB == NULL) {
		FreeStrBuf(&boundary);
		SMTPCM_syslog(LOG_ERR, "Failed to alloc() bounce message.\n");

		return;
	}

	bmsg = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage));
	if (bmsg == NULL) {
		FreeStrBuf(&boundary);
		FreeStrBuf(&BounceMB);
		SMTPCM_syslog(LOG_ERR, "Failed to alloc() bounce message.\n");

		return;
	}
	memset(bmsg, 0, sizeof(struct CtdlMessage));


	StrBufAppendBufPlain(BounceMB, HKEY("Content-type: multipart/mixed; boundary=\""), 0);
	StrBufAppendBuf(BounceMB, boundary, 0);
	StrBufAppendBufPlain(BounceMB, HKEY("\"\r\n"), 0);
	StrBufAppendBufPlain(BounceMB, HKEY("MIME-Version: 1.0\r\n"), 0);
	StrBufAppendBufPlain(BounceMB, HKEY("X-Mailer: " CITADEL "\r\n"), 0);
	StrBufAppendBufPlain(BounceMB, HKEY("\r\nThis is a multipart message in MIME format.\r\n\r\n"), 0);
	StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
	StrBufAppendBuf(BounceMB, boundary, 0);
	StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
	StrBufAppendBufPlain(BounceMB, HKEY("Content-type: text/plain\r\n\r\n"), 0);

	if (give_up)
		StrBufAppendBufPlain(
			BounceMB,
			HKEY(
				"A message you sent could not be delivered "
				"to some or all of its recipients\n"
				"due to prolonged unavailability "
				"of its destination(s).\n"
				"Giving up on the following addresses:\n\n"
				), 0);
	else
		StrBufAppendBufPlain(
			BounceMB,
			HKEY(
				"A message you sent could not be delivered "
				"to some or all of its recipients.\n"
				"The following addresses "
				"were undeliverable:\n\n"
				), 0);

	StrBufAppendBuf(BounceMB, Msg, 0);
	FreeStrBuf(&Msg);

	if (StrLength(MyQItem->SenderRoom) > 0)
	{
		StrBufAppendBufPlain(
			BounceMB,
			HKEY("The message was originaly posted in: "), 0);
		StrBufAppendBuf(BounceMB, MyQItem->SenderRoom, 0);
		StrBufAppendBufPlain(
			BounceMB,
			HKEY("\n"), 0);
	}

	/* Attach the original message */
	StrBufAppendBufPlain(BounceMB, HKEY("\r\n--"), 0);
	StrBufAppendBuf(BounceMB, boundary, 0);
	StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
	StrBufAppendBufPlain(BounceMB,
			     HKEY("Content-type: message/rfc822\r\n"), 0);
	StrBufAppendBufPlain(BounceMB,
			     HKEY("Content-Transfer-Encoding: 7bit\r\n"), 0);
	StrBufAppendBufPlain(BounceMB,
			     HKEY("Content-Disposition: inline\r\n"), 0);
	StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
	StrBufAppendBuf(BounceMB, OMsgTxt, 0);

	/* Close the multipart MIME scope */
	StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
	StrBufAppendBuf(BounceMB, boundary, 0);
	StrBufAppendBufPlain(BounceMB, HKEY("--\r\n"), 0);

	bmsg->cm_magic = CTDLMESSAGE_MAGIC;
	bmsg->cm_anon_type = MES_NORMAL;
	bmsg->cm_format_type = FMT_RFC822;

	CM_SetField(bmsg, eOriginalRoom, HKEY(MAILROOM));
	CM_SetField(bmsg, eAuthor, HKEY("Citadel"));
	CM_SetField(bmsg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
	CM_SetField(bmsg, eMsgSubject, HKEY("Delivery Status Notification (Failure)"));
	CM_SetAsFieldSB(bmsg, eMesageText, &BounceMB);

	/* First try the user who sent the message */
	if (StrLength(MyQItem->BounceTo) == 0) {
		SMTPCM_syslog(LOG_ERR, "No bounce address specified\n");
	}
	else {
		SMTPC_syslog(LOG_DEBUG, "bounce to user? <%s>\n",
		       ChrPtr(MyQItem->BounceTo));
	}

	/* Can we deliver the bounce to the original sender? */
	valid = validate_recipients(ChrPtr(MyQItem->BounceTo), NULL, 0);
	if ((valid != NULL) && (valid->num_error == 0)) {
		CtdlSubmitMsg(bmsg, valid, "", QP_EADDR);
		successful_bounce = 1;
	}

	/* If not, post it in the Aide> room */
	if (successful_bounce == 0) {
		CtdlSubmitMsg(bmsg, NULL, CtdlGetConfigStr("c_aideroom"), QP_EADDR);
	}

	/* Free up the memory we used */
	free_recipients(valid);
	FreeStrBuf(&boundary);
	CM_Free(bmsg);
	SMTPCM_syslog(LOG_DEBUG, "Done processing bounces\n");
}
예제 #18
0
파일: control.c 프로젝트: henri14/citadel
void cmd_gvdn(char *argbuf)
{
	const ConfType *pCfg;
	char *confptr;
	long min = atol(argbuf);
	const char *Pos = NULL;
	const char *PPos = NULL;
	const char *HKey;
	long HKLen;
	StrBuf *Line;
	StrBuf *Config;
	StrBuf *Cfg;
	StrBuf *CfgToken;
	HashList *List;
	HashPos *It;
	void *vptr;
	
	List = NewHash(1, NULL);
	Cfg = NewStrBufPlain(config.c_fqdn, -1);
	Put(List, SKEY(Cfg), Cfg, HFreeStrBuf);
	Cfg = NULL;

	confptr = CtdlGetSysConfig(INTERNETCFG);
	Config = NewStrBufPlain(confptr, -1);
	free(confptr);

	Line = NewStrBufPlain(NULL, StrLength(Config));
	CfgToken = NewStrBufPlain(NULL, StrLength(Config));
	while (StrBufSipLine(Line, Config, &Pos))
	{
		if (Cfg == NULL)
			Cfg = NewStrBufPlain(NULL, StrLength(Line));
		PPos = NULL;
		StrBufExtract_NextToken(Cfg, Line, &PPos, '|');
		StrBufExtract_NextToken(CfgToken, Line, &PPos, '|');
		if (GetHash(CfgNameHash, SKEY(CfgToken), &vptr) &&
		    (vptr != NULL))
		{
			pCfg = (ConfType *) vptr;
			if (pCfg->Type <= min)
			{
				Put(List, SKEY(Cfg), Cfg, HFreeStrBuf);
				Cfg = NULL;
			}
		}
	}

	cprintf("%d Valid Domains\n", LISTING_FOLLOWS);
	It = GetNewHashPos(List, 1);
	while (GetNextHashPos(List, It, &HKLen, &HKey, &vptr))
	{
		cputbuf(vptr);
		cprintf("\n");
	}
	cprintf("000\n");

	DeleteHashPos(&It);
	DeleteHash(&List);
	FreeStrBuf(&Cfg);
	FreeStrBuf(&Line);
	FreeStrBuf(&CfgToken);
	FreeStrBuf(&Config);
}
예제 #19
0
/*
 * smtp_do_procmsg()
 *
 * Called by smtp_do_queue() to handle an individual message.
 */
void smtp_do_procmsg(long msgnum, void *userdata) {
	time_t now;
	int mynumsessions = num_sessions;
	struct CtdlMessage *msg = NULL;
	char *Author = NULL;
	char *Address = NULL;
	char *instr = NULL;
	StrBuf *PlainQItem;
	OneQueItem *MyQItem;
	char *pch;
	HashPos  *It;
	void *vQE;
	long len;
	const char *Key;
	int HaveBuffers = 0;
	StrBuf *Msg =NULL;

	if (mynumsessions > max_sessions_for_outbound_smtp) {
		SMTPC_syslog(LOG_INFO,
			     "skipping because of num jobs %d > %d max_sessions_for_outbound_smtp",
			     mynumsessions,
			     max_sessions_for_outbound_smtp);
	}

	SMTPC_syslog(LOG_DEBUG, "smtp_do_procmsg(%ld)\n", msgnum);
	///strcpy(envelope_from, "");

	msg = CtdlFetchMessage(msgnum, 1, 1);
	if (msg == NULL) {
		SMTPC_syslog(LOG_ERR, "tried %ld but no such message!\n",
		       msgnum);
		return;
	}

	pch = instr = msg->cm_fields[eMesageText];

	/* Strip out the headers (no not amd any other non-instruction) line */
	while (pch != NULL) {
		pch = strchr(pch, '\n');
		if ((pch != NULL) &&
		    ((*(pch + 1) == '\n') ||
		     (*(pch + 1) == '\r')))
		{
			instr = pch + 2;
			pch = NULL;
		}
	}
	PlainQItem = NewStrBufPlain(instr, -1);
	CM_Free(msg);
	MyQItem = DeserializeQueueItem(PlainQItem, msgnum);
	FreeStrBuf(&PlainQItem);

	if (MyQItem == NULL) {
		SMTPC_syslog(LOG_ERR,
			     "Msg No %ld: already in progress!\n",
			     msgnum);
		return; /* s.b. else is already processing... */
	}

	/*
	 * Postpone delivery if we've already tried recently.
	 */
	now = time(NULL);
	if ((MyQItem->ReattemptWhen != 0) && 
	    (now < MyQItem->ReattemptWhen) &&
	    (run_queue_now == 0))
	{
		SMTPC_syslog(LOG_DEBUG, 
			     "Retry time not yet reached. %ld seconds left.",
			     MyQItem->ReattemptWhen - now);

		It = GetNewHashPos(MyQItem->MailQEntries, 0);
		pthread_mutex_lock(&ActiveQItemsLock);
		{
			if (GetHashPosFromKey(ActiveQItems,
					      LKEY(MyQItem->MessageID),
					      It))
			{
				DeleteEntryFromHash(ActiveQItems, It);
			}
		}
		pthread_mutex_unlock(&ActiveQItemsLock);
		////FreeQueItem(&MyQItem); TODO: DeleteEntryFromHash frees this?
		DeleteHashPos(&It);
		return;
	}

	/*
	 * Bail out if there's no actual message associated with this
	 */
	if (MyQItem->MessageID < 0L) {
		SMTPCM_syslog(LOG_ERR, "no 'msgid' directive found!\n");
		It = GetNewHashPos(MyQItem->MailQEntries, 0);
		pthread_mutex_lock(&ActiveQItemsLock);
		{
			if (GetHashPosFromKey(ActiveQItems,
					      LKEY(MyQItem->MessageID),
					      It))
			{
				DeleteEntryFromHash(ActiveQItems, It);
			}
		}
		pthread_mutex_unlock(&ActiveQItemsLock);
		DeleteHashPos(&It);
		////FreeQueItem(&MyQItem); TODO: DeleteEntryFromHash frees this?
		return;
	}


	It = GetNewHashPos(MyQItem->MailQEntries, 0);
	while (GetNextHashPos(MyQItem->MailQEntries, It, &len, &Key, &vQE))
	{
		MailQEntry *ThisItem = vQE;
		SMTPC_syslog(LOG_DEBUG, "SMTP Queue: Task: <%s> %d\n",
			     ChrPtr(ThisItem->Recipient),
			     ThisItem->Active);
	}
	DeleteHashPos(&It);

	MyQItem->NotYetShutdownDeliveries = 
		MyQItem->ActiveDeliveries = CountActiveQueueEntries(MyQItem, 1);

	/* failsafe against overload: 
	 * will we exceed the limit set? 
	 */
	if ((MyQItem->ActiveDeliveries + mynumsessions > max_sessions_for_outbound_smtp) && 
	    /* if yes, did we reach more than half of the quota? */
	    ((mynumsessions * 2) > max_sessions_for_outbound_smtp) && 
	    /* if... would we ever fit into half of the quota?? */
	    (((MyQItem->ActiveDeliveries * 2)  < max_sessions_for_outbound_smtp)))
	{
		/* abort delivery for another time. */
		SMTPC_syslog(LOG_INFO,
			     "SMTP Queue: skipping because of num jobs %d + %ld > %d max_sessions_for_outbound_smtp",
			     mynumsessions,
			     MyQItem->ActiveDeliveries,
			     max_sessions_for_outbound_smtp);

		It = GetNewHashPos(MyQItem->MailQEntries, 0);
		pthread_mutex_lock(&ActiveQItemsLock);
		{
			if (GetHashPosFromKey(ActiveQItems,
					      LKEY(MyQItem->MessageID),
					      It))
			{
				DeleteEntryFromHash(ActiveQItems, It);
			}
		}
		pthread_mutex_unlock(&ActiveQItemsLock);

		return;
	}


	if (MyQItem->ActiveDeliveries > 0)
	{
		ParsedURL *RelayUrls = NULL;
		int nActivated = 0;
		int n = MsgCount++;
		int m = MyQItem->ActiveDeliveries;
		int i = 1;

		It = GetNewHashPos(MyQItem->MailQEntries, 0);

		Msg = smtp_load_msg(MyQItem, n, &Author, &Address);
		RelayUrls = LoadRelayUrls(MyQItem, Author, Address);
		if ((RelayUrls == NULL) && MyQItem->HaveRelay) {

			while ((i <= m) &&
			       (GetNextHashPos(MyQItem->MailQEntries,
					       It, &len, &Key, &vQE)))
			{
				int KeepBuffers = (i == m);
				MailQEntry *ThisItem = vQE;
				StrBufPrintf(ThisItem->StatusMessage,
					     "No relay configured matching %s / %s", 
					     (Author != NULL)? Author : "",
					     (Address != NULL)? Address : "");
				ThisItem->Status = 5;

				nActivated++;

				if (i > 1) n = MsgCount++;
				SMTPC_syslog(LOG_INFO,
					     "SMTPC: giving up on <%ld> <%s> %d / %d \n",
					     MyQItem->MessageID,
					     ChrPtr(ThisItem->Recipient),
					     i,
					     m);
				(*((int*) userdata)) ++;
				smtp_try_one_queue_entry(MyQItem,
							 ThisItem,
							 Msg,
							 KeepBuffers,
							 n,
							 RelayUrls);

				if (KeepBuffers) HaveBuffers++;

				i++;
			}
			if (Author != NULL) free (Author);
			if (Address != NULL) free (Address);
			DeleteHashPos(&It);

			return;
		}
		if (Author != NULL) free (Author);
		if (Address != NULL) free (Address);

		while ((i <= m) &&
		       (GetNextHashPos(MyQItem->MailQEntries,
				       It, &len, &Key, &vQE)))
		{
			MailQEntry *ThisItem = vQE;

			if (ThisItem->Active == 1)
			{
				int KeepBuffers = (i == m);

				nActivated++;
				if (nActivated % ndelay_count == 0)
					usleep(delay_msec);

				if (i > 1) n = MsgCount++;
				SMTPC_syslog(LOG_DEBUG,
					     "SMTPC: Trying <%ld> <%s> %d / %d \n",
					     MyQItem->MessageID,
					     ChrPtr(ThisItem->Recipient),
					     i,
					     m);
				(*((int*) userdata)) ++;
				smtp_try_one_queue_entry(MyQItem,
							 ThisItem,
							 Msg,
							 KeepBuffers,
							 n,
							 RelayUrls);

				if (KeepBuffers) HaveBuffers++;

				i++;
			}
		}
		DeleteHashPos(&It);
	}
	else
	{
		It = GetNewHashPos(MyQItem->MailQEntries, 0);
		pthread_mutex_lock(&ActiveQItemsLock);
		{
			if (GetHashPosFromKey(ActiveQItems,
					      LKEY(MyQItem->MessageID),
					      It))
			{
				DeleteEntryFromHash(ActiveQItems, It);
			}
			else
			{
				long len;
				const char* Key;
				void *VData;

				SMTPC_syslog(LOG_WARNING,
					     "unable to find QItem with ID[%ld]",
					     MyQItem->MessageID);
				while (GetNextHashPos(ActiveQItems,
						      It,
						      &len,
						      &Key,
						      &VData))
				{
					SMTPC_syslog(LOG_WARNING,
						     "have: ID[%ld]",
						     ((OneQueItem *)VData)->MessageID);
				}
			}

		}
		pthread_mutex_unlock(&ActiveQItemsLock);
		DeleteHashPos(&It);
		////FreeQueItem(&MyQItem); TODO: DeleteEntryFromHash frees this?

// TODO: bounce & delete?

	}
	if (!HaveBuffers) {
		FreeStrBuf (&Msg);
// TODO : free RelayUrls
	}
}
예제 #20
0
파일: nttlist.c 프로젝트: mingodad/citadel
int CtdlNetworkTalkingTo(const char *nodename, long len, int operation)
{

	int retval = 0;
	HashPos *Pos = NULL;
	void *vdata;

	begin_critical_section(S_NTTLIST);

	switch(operation) {

		case NTT_ADD:
			if (nttlist == NULL) 
				nttlist = NewHash(1, NULL);
			Put(nttlist, nodename, len, NewStrBufPlain(nodename, len), HFreeStrBuf);
			if (NTTDebugEnabled) syslog(LOG_DEBUG, "nttlist: added <%s>\n", nodename);
			break;
		case NTT_REMOVE:
			if ((nttlist == NULL) ||
			    (GetCount(nttlist) == 0))
				break;
			Pos = GetNewHashPos(nttlist, 1);
			if (GetHashPosFromKey (nttlist, nodename, len, Pos))
				DeleteEntryFromHash(nttlist, Pos);
			DeleteHashPos(&Pos);
			if (NTTDebugEnabled) syslog(LOG_DEBUG, "nttlist: removed <%s>\n", nodename);

			break;

		case NTT_CHECK:
			if ((nttlist == NULL) ||
			    (GetCount(nttlist) == 0))
				break;
			if (GetHash(nttlist, nodename, len, &vdata))
				retval ++;
			if (NTTDebugEnabled) syslog(LOG_DEBUG, "nttlist: have [%d] <%s>\n", retval, nodename);
			break;
	}

	if (NTTDumpEnabled)
	{
		HashPos *It;
		StrBuf *NTTDump;
		long len;
		const char *Key;
		void *v;
		NTTDump = NewStrBuf ();

		It = GetNewHashPos(nttlist, 0);
		while (GetNextHashPos(nttlist, It, &len, &Key, &v))
		{
			if (StrLength(NTTDump) > 0)
				StrBufAppendBufPlain(NTTDump, HKEY("|"), 0);
			StrBufAppendBuf(NTTDump, (StrBuf*) v, 0);
		}
		DeleteHashPos(&It);

		syslog(LOG_DEBUG, "nttlist: Dump: [%d] <%s>\n", 
		       GetCount(nttlist),
		       ChrPtr(NTTDump));
		FreeStrBuf(&NTTDump);
	}
	end_critical_section(S_NTTLIST);
	return(retval);
}
예제 #21
0
static void QueueEventAddCallback(EV_P_ ev_async *w, int revents)
{
	CitContext *Ctx;
	long IOID = -1;
	long count = 0;
	ev_tstamp Now;
	HashList *q;
	void *v;
	HashPos*It;
	long len;
	const char *Key;

	/* get the control command... */
	pthread_mutex_lock(&EventQueueMutex);

	if (InboundEventQueues[0] == InboundEventQueue) {
		InboundEventQueue = InboundEventQueues[1];
		q = InboundEventQueues[0];
	}
	else {
		InboundEventQueue = InboundEventQueues[0];
		q = InboundEventQueues[1];
	}
	pthread_mutex_unlock(&EventQueueMutex);
	Now = ev_now (event_base);
	It = GetNewHashPos(q, 0);
	while (GetNextHashPos(q, It, &len, &Key, &v))
	{
		IOAddHandler *h = v;
		count ++;
		if (h->IO->ID == 0) {
			h->IO->ID = EvIDSource++;
		}
		IOID = h->IO->ID;
		if (h->IO->StartIO == 0.0)
			h->IO->StartIO = Now;

		SetEVState(h->IO, eIOAttach);

		Ctx = h->IO->CitContext;
		become_session(Ctx);

		h->IO->CitContext->lastcmd = h->IO->Now = Now;
		switch (h->EvAttch(h->IO))
		{
		case eReadMore:
		case eReadMessage:
		case eReadFile:
		case eSendReply:
		case eSendMore:
		case eReadPayload:
		case eSendFile:
		case eDBQuery:
		case eSendDNSQuery:
		case eReadDNSReply:
		case eConnect:
			break;
		case eTerminateConnection:
		case eAbort:
			ShutDownCLient(h->IO);
		break;
		}
	}
	DeleteHashPos(&It);
	DeleteHashContent(&q);
	EVQ_syslog(LOG_DEBUG, "%s CC[%ld] EVENT Q Add %ld  done.", IOSTR, IOID, count);
}
예제 #22
0
void pop3client_scan(void) {
	static time_t last_run = 0L;
	time_t fastest_scan;
	HashPos *it;
	long len;
	const char *Key;
	void *vrptr;
	pop3aggr *cptr;

	become_session(&pop3_client_CC);

	if (config.c_pop3_fastest < config.c_pop3_fetch)
		fastest_scan = config.c_pop3_fastest;
	else
		fastest_scan = config.c_pop3_fetch;

	/*
	 * Run POP3 aggregation no more frequently than once every n seconds
	 */
	if ( (time(NULL) - last_run) < fastest_scan ) {
		return;
	}

	/*
	 * This is a simple concurrency check to make sure only one pop3client
	 * run is done at a time.  We could do this with a mutex, but since we
	 * don't really require extremely fine granularity here, we'll do it
	 * with a static variable instead.
	 */
	if (doing_pop3client) return;
	doing_pop3client = 1;

	EVP3CQM_syslog(LOG_DEBUG, "pop3client started");
	CtdlForEachNetCfgRoom(pop3client_scan_room, NULL, pop3client);

	pthread_mutex_lock(&POP3QueueMutex);
	it = GetNewHashPos(POP3FetchUrls, 0);
	while (!server_shutting_down &&
	       GetNextHashPos(POP3FetchUrls, it, &len, &Key, &vrptr) &&
	       (vrptr != NULL)) {
		cptr = (pop3aggr *)vrptr;
		if (cptr->RefCount == 0)
			if (!pop3_do_fetching(cptr))
				DeletePOP3Aggregator(cptr);////TODO

/*
	if ((palist->interval && time(NULL) > (last_run + palist->interval))
			|| (time(NULL) > last_run + config.c_pop3_fetch))
			pop3_do_fetching(palist->roomname, palist->pop3host,
			palist->pop3user, palist->pop3pass, palist->keep);
		pptr = palist;
		palist = palist->next;
		free(pptr);
*/
	}
	DeleteHashPos(&it);
	pthread_mutex_unlock(&POP3QueueMutex);

	EVP3CQM_syslog(LOG_DEBUG, "pop3client ended");
	last_run = time(NULL);
	doing_pop3client = 0;
}