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; }
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); }
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); }
/* * 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 } }