X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Frssclient%2Fserv_rssclient.c;h=530bed03fe6f689b8bb96eb6af547744f980f33c;hb=c855d497545dad80942a194624c111a54cd1fdc7;hp=c125f61748aa956a38d48a3915135e1e737db01e;hpb=fd29e13821d3aa616b03d447f92cfb2de112b31d;p=citadel.git diff --git a/citadel/modules/rssclient/serv_rssclient.c b/citadel/modules/rssclient/serv_rssclient.c index c125f6174..530bed03f 100644 --- a/citadel/modules/rssclient/serv_rssclient.c +++ b/citadel/modules/rssclient/serv_rssclient.c @@ -66,14 +66,17 @@ time_t last_run = 0L; pthread_mutex_t RSSQueueMutex; /* locks the access to the following vars: */ HashList *RSSQueueRooms = NULL; /* rss_room_counter */ -HashList *RSSFetchUrls = NULL; /* -> rss_aggregator; ->RefCount access to be locked too. */ - -eNextState RSSAggregatorTerminate(AsyncIO *IO); +HashList *RSSFetchUrls = NULL; /*->rss_aggregator;->RefCount access locked*/ +eNextState RSSAggregator_Terminate(AsyncIO *IO); +eNextState RSSAggregator_ShutdownAbort(AsyncIO *IO); struct CitContext rss_CC; struct rssnetcfg *rnclist = NULL; -void AppendLink(StrBuf *Message, StrBuf *link, StrBuf *LinkTitle, const char *Title) +void AppendLink(StrBuf *Message, + StrBuf *link, + StrBuf *LinkTitle, + const char *Title) { if (StrLength(link) > 0) { @@ -89,15 +92,6 @@ void AppendLink(StrBuf *Message, StrBuf *link, StrBuf *LinkTitle, const char *Ti StrBufAppendBufPlain(Message, HKEY("
\n"), 0); } } -typedef struct __networker_save_message { - AsyncIO IO; - struct CtdlMessage *Msg; - struct recptypes *recp; - rss_aggregator *Cfg; - StrBuf *MsgGUID; - StrBuf *Message; - struct UseTable ut; -} networker_save_message; void DeleteRoomReference(long QRnumber) @@ -110,21 +104,22 @@ void DeleteRoomReference(long QRnumber) At = GetNewHashPos(RSSQueueRooms, 0); - GetHashPosFromKey(RSSQueueRooms, LKEY(QRnumber), At); - GetHashPos(RSSQueueRooms, At, &HKLen, &HK, &vData); - if (vData != NULL) + if (GetHashPosFromKey(RSSQueueRooms, LKEY(QRnumber), At)) { - pRoomC = (rss_room_counter *) vData; - pRoomC->count --; - if (pRoomC->count == 0) - DeleteEntryFromHash(RSSQueueRooms, At); + GetHashPos(RSSQueueRooms, At, &HKLen, &HK, &vData); + if (vData != NULL) + { + pRoomC = (rss_room_counter *) vData; + pRoomC->count --; + if (pRoomC->count == 0) + DeleteEntryFromHash(RSSQueueRooms, At); + } } DeleteHashPos(&At); } void UnlinkRooms(rss_aggregator *Cfg) { - DeleteRoomReference(Cfg->QRnumber); if (Cfg->OtherQRnumbers != NULL) { @@ -134,15 +129,16 @@ void UnlinkRooms(rss_aggregator *Cfg) void *vData; At = GetNewHashPos(Cfg->OtherQRnumbers, 0); - while (GetNextHashPos(Cfg->OtherQRnumbers, At, &HKLen, &HK, &vData) && + while (! server_shutting_down && + GetNextHashPos(Cfg->OtherQRnumbers, + At, + &HKLen, &HK, + &vData) && (vData != NULL)) { long *lData = (long*) vData; DeleteRoomReference(*lData); } -/* - if (server_shutting_down) - break; / * TODO */ DeleteHashPos(&At); } @@ -155,7 +151,7 @@ void UnlinkRSSAggregator(rss_aggregator *Cfg) UnlinkRooms(Cfg); At = GetNewHashPos(RSSFetchUrls, 0); - if (GetHashPosFromKey(RSSFetchUrls, SKEY(Cfg->Url), At) == 0) + if (GetHashPosFromKey(RSSFetchUrls, SKEY(Cfg->Url), At)) { DeleteEntryFromHash(RSSFetchUrls, At); } @@ -163,29 +159,14 @@ void UnlinkRSSAggregator(rss_aggregator *Cfg) last_run = time(NULL); } -eNextState FreeNetworkSaveMessage (AsyncIO *IO) +void FreeNetworkSaveMessage (void *vMsg) { - networker_save_message *Ctx = (networker_save_message *) IO->Data; - - pthread_mutex_lock(&RSSQueueMutex); - Ctx->Cfg->RefCount --; - - if (Ctx->Cfg->RefCount == 0) - { - UnlinkRSSAggregator(Ctx->Cfg); + networker_save_message *Msg = (networker_save_message *) vMsg; - } - pthread_mutex_unlock(&RSSQueueMutex); - - CtdlFreeMessage(Ctx->Msg); - free_recipients(Ctx->recp); - FreeStrBuf(&Ctx->Message); - FreeStrBuf(&Ctx->MsgGUID); - ((struct CitContext*)IO->CitContext)->state = CON_IDLE; - ((struct CitContext*)IO->CitContext)->kill_me = 1; - free(Ctx); - last_run = time(NULL); - return eAbort; + CtdlFreeMessageContents(&Msg->Msg); + FreeStrBuf(&Msg->Message); + FreeStrBuf(&Msg->MsgGUID); + free(Msg); } eNextState AbortNetworkSaveMessage (AsyncIO *IO) @@ -195,39 +176,64 @@ eNextState AbortNetworkSaveMessage (AsyncIO *IO) eNextState RSSSaveMessage(AsyncIO *IO) { - networker_save_message *Ctx = (networker_save_message *) IO->Data; + long len; + const char *Key; + rss_aggregator *Ctx = (rss_aggregator *) IO->Data; - Ctx->Msg->cm_fields['M'] = SmashStrBuf(&Ctx->Message); + Ctx->ThisMsg->Msg.cm_fields['M'] = SmashStrBuf(&Ctx->ThisMsg->Message); - CtdlSubmitMsg(Ctx->Msg, Ctx->recp, NULL, 0); + CtdlSubmitMsg(&Ctx->ThisMsg->Msg, &Ctx->recp, NULL, 0); /* write the uidl to the use table so we don't store this item again */ - cdb_store(CDB_USETABLE, SKEY(Ctx->MsgGUID), &Ctx->ut, sizeof(struct UseTable) ); - - return eTerminateConnection; + cdb_store(CDB_USETABLE, + SKEY(Ctx->ThisMsg->MsgGUID), + &Ctx->ThisMsg->ut, + sizeof(struct UseTable) ); + + if (GetNextHashPos(Ctx->Messages, + Ctx->Pos, + &len, &Key, + (void**) &Ctx->ThisMsg)) + return NextDBOperation(IO, RSS_FetchNetworkUsetableEntry); + else + return eAbort; } eNextState RSS_FetchNetworkUsetableEntry(AsyncIO *IO) { + const char *Key; + long len; struct cdbdata *cdbut; - networker_save_message *Ctx = (networker_save_message *) IO->Data; + rss_aggregator *Ctx = (rss_aggregator *) IO->Data; /* Find out if we've already seen this item */ - strcpy(Ctx->ut.ut_msgid, ChrPtr(Ctx->MsgGUID)); /// TODO - Ctx->ut.ut_timestamp = time(NULL); + strcpy(Ctx->ThisMsg->ut.ut_msgid, + ChrPtr(Ctx->ThisMsg->MsgGUID)); /// TODO + Ctx->ThisMsg->ut.ut_timestamp = time(NULL); - cdbut = cdb_fetch(CDB_USETABLE, SKEY(Ctx->MsgGUID)); + cdbut = cdb_fetch(CDB_USETABLE, SKEY(Ctx->ThisMsg->MsgGUID)); #ifndef DEBUG_RSS if (cdbut != NULL) { /* Item has already been seen */ - syslog(LOG_DEBUG, "%s has already been seen\n", ChrPtr(Ctx->MsgGUID)); + EV_syslog(LOG_DEBUG, + "%s has already been seen\n", + ChrPtr(Ctx->ThisMsg->MsgGUID)); cdb_free(cdbut); /* rewrite the record anyway, to update the timestamp */ - cdb_store(CDB_USETABLE, - SKEY(Ctx->MsgGUID), - &Ctx->ut, sizeof(struct UseTable) ); - return eAbort; + cdb_store(CDB_USETABLE, + SKEY(Ctx->ThisMsg->MsgGUID), + &Ctx->ThisMsg->ut, sizeof(struct UseTable) ); + + if (GetNextHashPos(Ctx->Messages, + Ctx->Pos, + &len, &Key, + (void**) &Ctx->ThisMsg)) + return NextDBOperation( + IO, + RSS_FetchNetworkUsetableEntry); + else + return eAbort; } else #endif @@ -236,55 +242,26 @@ eNextState RSS_FetchNetworkUsetableEntry(AsyncIO *IO) return eSendMore; } } -void RSSQueueSaveMessage(struct CtdlMessage *Msg, struct recptypes *recp, StrBuf *MsgGUID, StrBuf *MessageBody, rss_aggregator *Cfg) -{ - networker_save_message *Ctx; - - pthread_mutex_lock(&RSSQueueMutex); - Cfg->RefCount ++; - pthread_mutex_unlock(&RSSQueueMutex); - - - Ctx = (networker_save_message *) malloc(sizeof(networker_save_message)); - memset(Ctx, 0, sizeof(networker_save_message)); - - Ctx->MsgGUID = MsgGUID; - Ctx->Message = MessageBody; - Ctx->Msg = Msg; - Ctx->Cfg = Cfg; - Ctx->recp = recp; - Ctx->IO.Data = Ctx; - Ctx->IO.CitContext = CloneContext(&rss_CC); - Ctx->IO.Terminate = FreeNetworkSaveMessage; - Ctx->IO.ShutdownAbort = AbortNetworkSaveMessage; - QueueDBOperation(&Ctx->IO, RSS_FetchNetworkUsetableEntry); -} - /* * Commit a fetched and parsed RSS item to disk */ void rss_save_item(rss_item *ri, rss_aggregator *Cfg) { - + networker_save_message *SaveMsg; struct MD5Context md5context; u_char rawdigest[MD5_DIGEST_LEN]; - struct CtdlMessage *msg; - struct recptypes *recp = NULL; int msglen = 0; StrBuf *Message; StrBuf *guid; - StrBuf *Buf; - - recp = (struct recptypes *) malloc(sizeof(struct recptypes)); - if (recp == NULL) return; - memset(recp, 0, sizeof(struct recptypes)); - Buf = NewStrBufDup(Cfg->rooms); - recp->recp_room = SmashStrBuf(&Buf); - recp->num_room = Cfg->roomlist_parts; - recp->recptypes_magic = RECPTYPES_MAGIC; - - Cfg->RefCount ++; + AsyncIO *IO = &Cfg->IO; + int n; + + + SaveMsg = (networker_save_message *) malloc( + sizeof(networker_save_message)); + memset(SaveMsg, 0, sizeof(networker_save_message)); + /* Construct a GUID to use in the S_USETABLE table. * If one is not present in the item itself, make one up. */ @@ -297,38 +274,39 @@ void rss_save_item(rss_item *ri, rss_aggregator *Cfg) else { MD5Init(&md5context); if (ri->title != NULL) { - MD5Update(&md5context, (const unsigned char*)ChrPtr(ri->title), StrLength(ri->title)); + MD5Update(&md5context, + (const unsigned char*)SKEY(ri->title)); } if (ri->link != NULL) { - MD5Update(&md5context, (const unsigned char*)ChrPtr(ri->link), StrLength(ri->link)); + MD5Update(&md5context, + (const unsigned char*)SKEY(ri->link)); } MD5Final(rawdigest, &md5context); - guid = NewStrBufPlain(NULL, MD5_DIGEST_LEN * 2 + 12 /* _rss2ctdl*/); + guid = NewStrBufPlain(NULL, + MD5_DIGEST_LEN * 2 + 12 /* _rss2ctdl*/); StrBufHexEscAppend(guid, NULL, rawdigest, MD5_DIGEST_LEN); StrBufAppendBufPlain(guid, HKEY("_rss2ctdl"), 0); } /* translate Item into message. */ - syslog(LOG_DEBUG, "RSS: translating item...\n"); + EVM_syslog(LOG_DEBUG, "RSS: translating item...\n"); if (ri->description == NULL) ri->description = NewStrBufPlain(HKEY("")); StrBufSpaceToBlank(ri->description); - msg = malloc(sizeof(struct CtdlMessage)); - memset(msg, 0, sizeof(struct CtdlMessage)); - msg->cm_magic = CTDLMESSAGE_MAGIC; - msg->cm_anon_type = MES_NORMAL; - msg->cm_format_type = FMT_RFC822; + SaveMsg->Msg.cm_magic = CTDLMESSAGE_MAGIC; + SaveMsg->Msg.cm_anon_type = MES_NORMAL; + SaveMsg->Msg.cm_format_type = FMT_RFC822; if (ri->guid != NULL) { - msg->cm_fields['E'] = strdup(ChrPtr(ri->guid)); + SaveMsg->Msg.cm_fields['E'] = strdup(ChrPtr(ri->guid)); } if (ri->author_or_creator != NULL) { char *From; StrBuf *Encoded = NULL; int FromAt; - + From = html_to_ascii(ChrPtr(ri->author_or_creator), - StrLength(ri->author_or_creator), + StrLength(ri->author_or_creator), 512, 0); StrBufPlain(ri->author_or_creator, From, -1); StrBufTrim(ri->author_or_creator); @@ -338,21 +316,27 @@ void rss_save_item(rss_item *ri, rss_aggregator *Cfg) if (!FromAt && StrLength (ri->author_email) > 0) { StrBufRFC2047encode(&Encoded, ri->author_or_creator); - msg->cm_fields['A'] = SmashStrBuf(&Encoded); - msg->cm_fields['P'] = SmashStrBuf(&ri->author_email); + SaveMsg->Msg.cm_fields['A'] = SmashStrBuf(&Encoded); + SaveMsg->Msg.cm_fields['P'] = + SmashStrBuf(&ri->author_email); } else { if (FromAt) { - msg->cm_fields['A'] = SmashStrBuf(&ri->author_or_creator); - msg->cm_fields['P'] = strdup(msg->cm_fields['A']); + SaveMsg->Msg.cm_fields['A'] = + SmashStrBuf(&ri->author_or_creator); + SaveMsg->Msg.cm_fields['P'] = + strdup(SaveMsg->Msg.cm_fields['A']); } - else + else { - StrBufRFC2047encode(&Encoded, ri->author_or_creator); - msg->cm_fields['A'] = SmashStrBuf(&Encoded); - msg->cm_fields['P'] = strdup("rss@localhost"); + StrBufRFC2047encode(&Encoded, + ri->author_or_creator); + SaveMsg->Msg.cm_fields['A'] = + SmashStrBuf(&Encoded); + SaveMsg->Msg.cm_fields['P'] = + strdup("rss@localhost"); } if (ri->pubdate <= 0) { @@ -361,10 +345,10 @@ void rss_save_item(rss_item *ri, rss_aggregator *Cfg) } } else { - msg->cm_fields['A'] = strdup("rss"); + SaveMsg->Msg.cm_fields['A'] = strdup("rss"); } - msg->cm_fields['N'] = strdup(NODENAME); + SaveMsg->Msg.cm_fields['N'] = strdup(NODENAME); if (ri->title != NULL) { long len; char *Sbj; @@ -386,21 +370,23 @@ void rss_save_item(rss_item *ri, rss_aggregator *Cfg) StrBufTrim(Encoded); StrBufRFC2047encode(&QPEncoded, Encoded); - msg->cm_fields['U'] = SmashStrBuf(&QPEncoded); + SaveMsg->Msg.cm_fields['U'] = SmashStrBuf(&QPEncoded); FreeStrBuf(&Encoded); } - msg->cm_fields['T'] = malloc(64); - snprintf(msg->cm_fields['T'], 64, "%ld", ri->pubdate); + SaveMsg->Msg.cm_fields['T'] = malloc(64); + snprintf(SaveMsg->Msg.cm_fields['T'], 64, "%ld", ri->pubdate); if (ri->channel_title != NULL) { if (StrLength(ri->channel_title) > 0) { - msg->cm_fields['O'] = strdup(ChrPtr(ri->channel_title)); + SaveMsg->Msg.cm_fields['O'] = + strdup(ChrPtr(ri->channel_title)); } } - if (ri->link == NULL) + if (ri->link == NULL) ri->link = NewStrBufPlain(HKEY("")); #if 0 /* temporarily disable shorter urls. */ - msg->cm_fields[TMP_SHORTER_URLS] = GetShorterUrls(ri->description); + SaveMsg->Msg.cm_fields[TMP_SHORTER_URLS] = + GetShorterUrls(ri->description); #endif msglen += 1024 + StrLength(ri->link) + StrLength(ri->description) ; @@ -411,7 +397,7 @@ void rss_save_item(rss_item *ri, rss_aggregator *Cfg) "Content-type: text/html; charset=\"UTF-8\"\r\n\r\n" "\n")); #if 0 /* disable shorter url for now. */ - msg->cm_fields[TMP_SHORTER_URL_OFFSET] = StrLength(Message); + SaveMsg->Msg.cm_fields[TMP_SHORTER_URL_OFFSET] = StrLength(Message); #endif StrBufAppendBuf(Message, ri->description, 0); StrBufAppendBufPlain(Message, HKEY("

\n"), 0); @@ -420,7 +406,11 @@ void rss_save_item(rss_item *ri, rss_aggregator *Cfg) AppendLink(Message, ri->reLink, ri->reLinkTitle, "Reply to this"); StrBufAppendBufPlain(Message, HKEY("\n"), 0); - RSSQueueSaveMessage(msg, recp, guid, Message, Cfg); + SaveMsg->MsgGUID = guid; + SaveMsg->Message = Message; + + n = GetCount(Cfg->Messages) + 1; + Put(Cfg->Messages, IKEY(n), SaveMsg, FreeNetworkSaveMessage); } @@ -431,40 +421,37 @@ void rss_save_item(rss_item *ri, rss_aggregator *Cfg) int rss_do_fetching(rss_aggregator *Cfg) { rss_item *ri; - time_t now; - AsyncIO *IO; - now = time(NULL); + now = time(NULL); if ((Cfg->next_poll != 0) && (now < Cfg->next_poll)) return 0; - Cfg->RefCount++; ri = (rss_item*) malloc(sizeof(rss_item)); memset(ri, 0, sizeof(rss_item)); Cfg->Item = ri; - IO = &Cfg->IO; - IO->CitContext = CloneContext(&rss_CC); - IO->Data = Cfg; - - syslog(LOG_DEBUG, "Fetching RSS feed <%s>\n", ChrPtr(Cfg->Url)); - ParseURL(&IO->ConnectMe, Cfg->Url, 80); - CurlPrepareURL(IO->ConnectMe); - - if (! evcurl_init(IO, -// Ctx, - NULL, - "Citadel RSS Client", - ParseRSSReply, - RSSAggregatorTerminate)) + if (! InitcURLIOStruct(&Cfg->IO, + Cfg, + "Citadel RSS Client", + RSSAggregator_ParseReply, + RSSAggregator_Terminate, + RSSAggregator_ShutdownAbort)) { - syslog(LOG_DEBUG, "Unable to initialize libcurl.\n"); + syslog(LOG_ALERT, "Unable to initialize libcurl.\n"); return 0; } - QueueCurlContext(IO); + safestrncpy(((CitContext*)Cfg->IO.CitContext)->cs_host, + ChrPtr(Cfg->Url), + sizeof(((CitContext*)Cfg->IO.CitContext)->cs_host)); + + syslog(LOG_DEBUG, "Fetching RSS feed <%s>\n", ChrPtr(Cfg->Url)); + ParseURL(&Cfg->IO.ConnectMe, Cfg->Url, 80); + CurlPrepareURL(Cfg->IO.ConnectMe); + + QueueCurlContext(&Cfg->IO); return 1; } @@ -472,6 +459,8 @@ int rss_do_fetching(rss_aggregator *Cfg) void DeleteRssCfg(void *vptr) { rss_aggregator *rncptr = (rss_aggregator *)vptr; + AsyncIO *IO = &rncptr->IO; + EVM_syslog(LOG_DEBUG, "RSS: destroying\n"); FreeStrBuf(&rncptr->Url); FreeStrBuf(&rncptr->rooms); @@ -481,6 +470,12 @@ void DeleteRssCfg(void *vptr) DeleteHash(&rncptr->OtherQRnumbers); FreeURL(&rncptr->IO.ConnectMe); + DeleteHashPos (&rncptr->Pos); + DeleteHash (&rncptr->Messages); + if (rncptr->recp.recp_room != NULL) + free(rncptr->recp.recp_room); + + if (rncptr->Item != NULL) { FreeStrBuf(&rncptr->Item->guid); @@ -500,33 +495,29 @@ void DeleteRssCfg(void *vptr) free(rncptr); } -eNextState RSSAggregatorTerminate(AsyncIO *IO) +eNextState RSSAggregator_Terminate(AsyncIO *IO) { rss_aggregator *rncptr = (rss_aggregator *)IO->Data; - - HashPos *At; - long HKLen; - const char *HK; - void *vData; - pthread_mutex_lock(&RSSQueueMutex); - rncptr->RefCount --; - if (rncptr->RefCount == 0) - { - UnlinkRSSAggregator(rncptr); + EVM_syslog(LOG_DEBUG, "RSS: Terminating.\n"); - } - pthread_mutex_unlock(&RSSQueueMutex); - At = GetNewHashPos(RSSFetchUrls, 0); + UnlinkRSSAggregator(rncptr); + return eAbort; +} +eNextState RSSAggregator_ShutdownAbort(AsyncIO *IO) +{ + const char *pUrl; + rss_aggregator *rncptr = (rss_aggregator *)IO->Data; - pthread_mutex_lock(&RSSQueueMutex); - GetHashPosFromKey(RSSFetchUrls, SKEY(rncptr->Url), At); - GetHashPos(RSSFetchUrls, At, &HKLen, &HK, &vData); - DeleteEntryFromHash(RSSFetchUrls, At); - pthread_mutex_unlock(&RSSQueueMutex); + pUrl = IO->ConnectMe->PlainUrl; + if (pUrl == NULL) + pUrl = ""; - DeleteHashPos(&At); + EV_syslog(LOG_DEBUG, "RSS: Aborting by shutdown: %s.\n", pUrl); + + + UnlinkRSSAggregator(rncptr); return eAbort; } @@ -552,10 +543,10 @@ void rssclient_scan_room(struct ctdlroom *qrbuf, void *data) pthread_mutex_lock(&RSSQueueMutex); if (GetHash(RSSQueueRooms, LKEY(qrbuf->QRnumber), &vptr)) { - syslog(LOG_DEBUG, - "rssclient: [%ld] %s already in progress.\n", - qrbuf->QRnumber, - qrbuf->QRname); + syslog(LOG_DEBUG, + "rssclient: [%ld] %s already in progress.\n", + qrbuf->QRnumber, + qrbuf->QRname); pthread_mutex_unlock(&RSSQueueMutex); return; } @@ -565,11 +556,13 @@ void rssclient_scan_room(struct ctdlroom *qrbuf, void *data) if (server_shutting_down) return; - + /* Only do net processing for rooms that have netconfigs */ fd = open(filename, 0); if (fd <= 0) { - //syslog(LOG_DEBUG, "rssclient: %s no config.\n", qrbuf->QRname); + /* syslog(LOG_DEBUG, + "rssclient: %s no config.\n", + qrbuf->QRname); */ return; } @@ -577,8 +570,10 @@ void rssclient_scan_room(struct ctdlroom *qrbuf, void *data) return; if (fstat(fd, &statbuf) == -1) { - syslog(LOG_DEBUG, "ERROR: could not stat configfile '%s' - %s\n", - filename, strerror(errno)); + syslog(LOG_DEBUG, + "ERROR: could not stat configfile '%s' - %s\n", + filename, + strerror(errno)); return; } @@ -597,7 +592,7 @@ void rssclient_scan_room(struct ctdlroom *qrbuf, void *data) close(fd); if (server_shutting_down) return; - + CfgPtr = NULL; CfgType = NewStrBuf(); Line = NewStrBufPlain(NULL, StrLength(CfgData)); @@ -628,29 +623,24 @@ void rssclient_scan_room(struct ctdlroom *qrbuf, void *data) use_this_rncptr = (rss_aggregator *)vptr; if (use_this_rncptr != NULL) { - /* mustn't attach to an active session */ - if (use_this_rncptr->RefCount > 0) - { - DeleteRssCfg(rncptr); - Count->count--; - } - else + long *QRnumber; + StrBufAppendBufPlain(use_this_rncptr->rooms, + qrbuf->QRname, + -1, 0); + if (use_this_rncptr->roomlist_parts == 1) { - long *QRnumber; - StrBufAppendBufPlain(use_this_rncptr->rooms, - qrbuf->QRname, - -1, 0); - if (use_this_rncptr->roomlist_parts == 1) - { - use_this_rncptr->OtherQRnumbers = NewHash(1, lFlathash); - } - QRnumber = (long*)malloc(sizeof(long)); - *QRnumber = qrbuf->QRnumber; - Put(use_this_rncptr->OtherQRnumbers, LKEY(qrbuf->QRnumber), QRnumber, NULL); - use_this_rncptr->roomlist_parts++; + use_this_rncptr->OtherQRnumbers = + NewHash(1, lFlathash); } - pthread_mutex_unlock(&RSSQueueMutex); + QRnumber = (long*)malloc(sizeof(long)); + *QRnumber = qrbuf->QRnumber; + Put(use_this_rncptr->OtherQRnumbers, + LKEY(qrbuf->QRnumber), + QRnumber, + NULL); + use_this_rncptr->roomlist_parts++; + pthread_mutex_unlock(&RSSQueueMutex); FreeStrBuf(&rncptr->Url); free(rncptr); @@ -660,7 +650,7 @@ void rssclient_scan_room(struct ctdlroom *qrbuf, void *data) pthread_mutex_unlock(&RSSQueueMutex); rncptr->ItemType = RSS_UNSET; - + rncptr->rooms = NewStrBufPlain(qrbuf->QRname, -1); pthread_mutex_lock(&RSSQueueMutex); @@ -700,14 +690,17 @@ void rssclient_scan(void) { } /* - * This is a simple concurrency check to make sure only one rssclient run - * is done at a time. We could do this with a mutex, but since we + * This is a simple concurrency check to make sure only one rssclient + * 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_rssclient) return; doing_rssclient = 1; + if ((GetCount(RSSQueueRooms) > 0) || (GetCount(RSSFetchUrls) > 0)) + return; + become_session(&rss_CC); syslog(LOG_DEBUG, "rssclient started\n"); CtdlForEachRoom(rssclient_scan_room, NULL); @@ -715,12 +708,11 @@ void rssclient_scan(void) { it = GetNewHashPos(RSSFetchUrls, 0); while (!server_shutting_down && - GetNextHashPos(RSSFetchUrls, it, &len, &Key, &vrptr) && + GetNextHashPos(RSSFetchUrls, it, &len, &Key, &vrptr) && (vrptr != NULL)) { rptr = (rss_aggregator *)vrptr; - if (rptr->RefCount == 0) - if (!rss_do_fetching(rptr)) - UnlinkRSSAggregator(rptr); + if (!rss_do_fetching(rptr)) + UnlinkRSSAggregator(rptr); } DeleteHashPos(&it); pthread_mutex_unlock(&RSSQueueMutex); @@ -748,7 +740,7 @@ CTDL_MODULE_INIT(rssclient) RSSFetchUrls = NewHash(1, NULL); syslog(LOG_INFO, "%s\n", curl_version()); CtdlRegisterSessionHook(rssclient_scan, EVT_TIMER); - CtdlRegisterCleanupHook(rss_cleanup); + CtdlRegisterCleanupHook(rss_cleanup); } return "rssclient"; }