Exemple #1
0
OneQueItem *DeserializeQueueItem(StrBuf *RawQItem, long QueMsgID)
{
	OneQueItem *Item;
	const char *pLine = NULL;
	StrBuf *Line;
	StrBuf *Token;
	void *v;

	Item = (OneQueItem*)malloc(sizeof(OneQueItem));
	memset(Item, 0, sizeof(OneQueItem));
	Item->Retry = SMTP_RETRY_INTERVAL;
	Item->MessageID = -1;
	Item->QueMsgID = QueMsgID;

	Token = NewStrBuf();
	Line = NewStrBufPlain(NULL, 128);
	while (pLine != StrBufNOTNULL) {
		const char *pItemPart = NULL;
		void *vHandler;

		StrBufExtract_NextToken(Line, RawQItem, &pLine, '\n');
		if (StrLength(Line) == 0) continue;
		StrBufExtract_NextToken(Token, Line, &pItemPart, '|');
		if (GetHash(QItemHandlers, SKEY(Token), &vHandler))
		{
			QItemHandlerStruct *HS;
			HS = (QItemHandlerStruct*) vHandler;
			HS->H(Item, Line, &pItemPart);
		}
	}
	FreeStrBuf(&Line);
	FreeStrBuf(&Token);

	if (Item->Retry >= MaxRetry)
		Item->FailNow = 1;

	pthread_mutex_lock(&ActiveQItemsLock);
	if (GetHash(ActiveQItems,
		    LKEY(Item->MessageID),
		    &v))
	{
		/* WHOOPS. somebody else is already working on this. */
		pthread_mutex_unlock(&ActiveQItemsLock);
		FreeQueItem(&Item);
		return NULL;
	}
	else {
		/* mark our claim on this. */
		Put(ActiveQItems,
		    LKEY(Item->MessageID),
		    Item,
		    HFreeQueItem);
		pthread_mutex_unlock(&ActiveQItemsLock);
	}

	return Item;
}
Exemple #2
0
eNextState POP3C_GetListOneLine(pop3aggr *RecvMsg)
{
	AsyncIO *IO = &RecvMsg->IO;
#if 0
	int rc;
#endif
	const char *pch;
	FetchItem *OneMsg = NULL;
	POP3C_DBG_READ();

	if ((StrLength(RecvMsg->IO.IOBuf) == 1) &&
	    (ChrPtr(RecvMsg->IO.IOBuf)[0] == '.'))
	{
		if (GetCount(RecvMsg->MsgNumbers) == 0)
		{
			////	RecvMsg->Sate = ReadQuitState;
		}
		else
		{
			RecvMsg->Pos = GetNewHashPos(RecvMsg->MsgNumbers, 0);
		}
		return eSendReply;

	}

	/*
	 * work around buggy pop3 servers which send
	 * empty lines in their listings.
	*/
	if ((StrLength(RecvMsg->IO.IOBuf) == 0) ||
	    !isdigit(ChrPtr(RecvMsg->IO.IOBuf)[0]))
	{
		return eReadMore;
	}

	OneMsg = (FetchItem*) malloc(sizeof(FetchItem));
	memset(OneMsg, 0, sizeof(FetchItem));
	OneMsg->MSGID = atol(ChrPtr(RecvMsg->IO.IOBuf));

	pch = strchr(ChrPtr(RecvMsg->IO.IOBuf), ' ');
	if (pch != NULL)
	{
		OneMsg->MSGSize = atol(pch + 1);
	}
#if 0
	rc = TestValidateHash(RecvMsg->MsgNumbers);
	if (rc != 0)
		EVP3CCS_syslog(LOG_DEBUG, "Hash Invalid: %d\n", rc);
#endif

	Put(RecvMsg->MsgNumbers, LKEY(OneMsg->MSGID), OneMsg, HfreeFetchItem);
#if 0
	rc = TestValidateHash(RecvMsg->MsgNumbers);
	if (rc != 0)
		EVP3CCS_syslog(LOG_DEBUG, "Hash Invalid: %d\n", rc);
#endif
	//RecvMsg->State --; /* read next Line */
	return eReadMore;
}
Exemple #3
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);
}
Exemple #4
0
/*
 * Scan a room's netconfig to determine whether it requires POP3 aggregation
 */
void pop3client_scan_room(struct ctdlroom *qrbuf, void *data, OneRoomNetCfg *OneRNCFG)
{
	const RoomNetCfgLine *pLine;
	void *vptr;

	pthread_mutex_lock(&POP3QueueMutex);
	if (GetHash(POP3QueueRooms, LKEY(qrbuf->QRnumber), &vptr))
	{
		pthread_mutex_unlock(&POP3QueueMutex);
		EVP3CQ_syslog(LOG_DEBUG,
			      "pop3client: [%ld] %s already in progress.",
			      qrbuf->QRnumber,
			      qrbuf->QRname);
		return;
	}
	pthread_mutex_unlock(&POP3QueueMutex);

	if (server_shutting_down) return;

	pLine = OneRNCFG->NetConfigs[pop3client];

	while (pLine != NULL)
	{
		pop3aggr *cptr;

		cptr = (pop3aggr *) malloc(sizeof(pop3aggr));
		memset(cptr, 0, sizeof(pop3aggr));
		///TODO do we need this? cptr->roomlist_parts=1;
		cptr->RoomName = NewStrBufPlain(qrbuf->QRname, -1);
		cptr->pop3user = NewStrBufDup(pLine->Value[1]);
		cptr->pop3pass = NewStrBufDup(pLine->Value[2]);
		cptr->Url = NewStrBuf();
		cptr->Host = NewStrBufDup(pLine->Value[0]);

		cptr->keep = atol(ChrPtr(pLine->Value[3]));
		cptr->interval = atol(ChrPtr(pLine->Value[4]));

		StrBufAppendBufPlain(cptr->Url, HKEY("pop3://"), 0);
		StrBufUrlescUPAppend(cptr->Url, cptr->pop3user, NULL);
		StrBufAppendBufPlain(cptr->Url, HKEY(":"), 0);
		StrBufUrlescUPAppend(cptr->Url, cptr->pop3pass, NULL);
		StrBufAppendBufPlain(cptr->Url, HKEY("@"), 0);
		StrBufAppendBuf(cptr->Url, cptr->Host, 0);
		StrBufAppendBufPlain(cptr->Url, HKEY("/"), 0);
		StrBufUrlescAppend(cptr->Url, cptr->RoomName, NULL);

		ParseURL(&cptr->IO.ConnectMe, cptr->Url, 110);


#if 0
/* todo: we need to reunite the url to be shure. */

		pthread_mutex_lock(&POP3ueueMutex);
		GetHash(POP3FetchUrls, SKEY(ptr->Url), &vptr);
		use_this_cptr = (pop3aggr *)vptr;

		if (use_this_rncptr != NULL)
		{
			/* mustn't attach to an active session */
			if (use_this_cptr->RefCount > 0)
			{
				DeletePOP3Cfg(cptr);
///						Count->count--;
			}
			else
			{
				long *QRnumber;
				StrBufAppendBufPlain(
					use_this_cptr->rooms,
					qrbuf->QRname,
					-1, 0);
				if (use_this_cptr->roomlist_parts == 1)
				{
					use_this_cptr->OtherQRnumbers
						= NewHash(1, lFlathash);
				}
				QRnumber = (long*)malloc(sizeof(long));
				*QRnumber = qrbuf->QRnumber;
				Put(use_this_cptr->OtherQRnumbers,
				    LKEY(qrbuf->QRnumber),
				    QRnumber,
				    NULL);

				use_this_cptr->roomlist_parts++;
			}
			pthread_mutex_unlock(&POP3QueueMutex);
			continue;
		}
		pthread_mutex_unlock(&RSSQueueMutex);
#endif
		cptr->n = Pop3ClientID++;
		pthread_mutex_lock(&POP3QueueMutex);
		Put(POP3FetchUrls,
		    SKEY(cptr->Url),
		    cptr,
		    DeletePOP3Aggregator);

		pthread_mutex_unlock(&POP3QueueMutex);
		pLine = pLine->next;

	}
}
Exemple #5
0
	snew_key(31, '~', "SCROLL_FORWARD");
	snew_key(32, '~', "SCROLL_START");
	snew_key(33, '~', "SCROLL_END");
}

#define LKEY(x, y) \
{									\
	char *l = get_term_capability(#x, 0, 1);			\
	if (l)								\
		snew_key_from_str(l, #y);				\
}

void	init_keys2 (void)
{
	/* keys bound from terminfo/termcap */
	LKEY(key_up, BACKWARD_HISTORY)
	LKEY(key_down, FORWARD_HISTORY)
	LKEY(key_left, BACKWARD_CHARACTER)
	LKEY(key_right, FORWARD_CHARACTER)
	LKEY(key_ppage, SCROLL_BACKWARD)
	LKEY(key_npage, SCROLL_FORWARD)
	LKEY(key_home, SCROLL_START)
	LKEY(key_end, SCROLL_END)
	LKEY(key_ic, TOGGLE_INSERT_MODE)
	/*LKEY(key_dc, DELETE_CHARACTER)*/
	LKEY(key_f1, CHELP)
	LKEY(key_f2, CHANNEL_CHOPS)
	LKEY(key_f3, CHANNEL_NONOPS)
#ifdef WANT_CDCC
	LKEY(key_f4, CDCC_PLIST)
#endif
Exemple #6
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
	}
}