#include <NServer.h>
Inheritance diagram for CServer:

Public Member Functions | |
| CServer (const char *spooldir, MPList *serverlist) | |
| ~CServer () | |
| void | setttl (time_t ttl_list, time_t ttl_desc) |
| virtual OverviewFmt * | overviewfmt () |
| virtual ActiveDB * | active () |
| void | invalidateActiveDB (void) |
| virtual GroupInfo * | groupinfo (const char *name) |
| virtual Newsgroup * | getgroup (const char *name) |
| virtual int | post (Article *article) |
| virtual void | spoolarticle (Article *article) |
| virtual void | postspooled (void) |
| virtual void | listgroup (const char *gname, char *lstgrp, unsigned int f, unsigned int l) |
| virtual void | overviewdb (Newsgroup *ng, unsigned int fst, unsigned int lst) |
| virtual void | article (const char *gname, unsigned int nbr, Article *art) |
| virtual void | article (const char *id, Article *art) |
Protected Member Functions | |
| int | active_valid () |
| int | desc_valid () |
| int | group_valid () |
Protected Attributes | |
| NVActiveDB * | _NVActiveDB |
| nvtime_t | _TTLActive |
| nvtime_t | _TTLDesc |
Definition at line 487 of file NServer.h.
|
||||||||||||
|
Definition at line 1143 of file NServer.cc. References _NVActiveDB, _TTLActive, _TTLDesc, ASSERT, RServer::init(), LServer::init(), slog, and VERB.
01144 {
01145 VERB(slog.
01146 p(Logger::
01147 Debug) << "CServer::CServer(" << spooldir <<
01148 ",*serverlist)\n");
01149 char buf[MAXPATHLEN];
01150
01151 ASSERT(if (!serverlist) {
01152 slog.
01153 p(Logger::
01154 Notice) <<
01155 "CServer::CServer: serverlist is a null-pointer\n";}
01156 );
01157 if (!_OverviewFormat) {
01158 _OverviewFormat = new OverviewFmt;
01159 }
01160 if (!_ActiveDB) {
01161 sprintf(buf, "%s/.active", spooldir);
01162 _ActiveDB = _NVActiveDB = new NVActiveDB(buf);
01163 }
01164
01165 ASSERT(if (!serverlist) {
01166 slog.
01167 p(Logger::
01168 Notice) <<
01169 "CServer::CServer: serverlist is a null-pointer\n";}
01170 );
01171 // other constructors
01172 LServer::init(spooldir);
01173 RServer::init(serverlist);
01174
01175 ASSERT(if (!_ServerList) {
01176 slog.
01177 p(Logger::
01178 Notice) <<
01179 "CServer::CServer: serverlist is a null-pointer\n";
01180 exit(9);}
01181 );
01182 _TTLActive = 300;
01183 _TTLDesc = 500;
01184 }
|
|
|
Definition at line 1186 of file NServer.cc. References _NVActiveDB, Logger::p(), slog, and VERB.
01187 {
01188 VERB(slog.p(Logger::Debug) << "CServer::~CServer()\n");
01189 if (_OverviewFormat) {
01190 delete _OverviewFormat;
01191 _OverviewFormat = NULL;
01192 }
01193 if (_NVActiveDB) {
01194 delete _NVActiveDB;
01195 _NVActiveDB = NULL;
01196 _ActiveDB = NULL;
01197 }
01198 }
|
|
|
Retrieves the active database (list of newsgroup and the number of their first and last article) from the news servers, if the local copy is older than _TTLActive seconds.
Reimplemented from LServer. Definition at line 1200 of file NServer.cc. References _NVActiveDB, RServer::active(), active_valid(), NVActiveDB::lock(), Logger::p(), Logger::print(), and slog. Referenced by ns_list(), ns_newgroups(), and update().
01201 {
01202 // The validity of the active database has to be tested twice,
01203 // because it is possible that several processes can reach
01204 // this point and in this case all these processes would
01205 // transfer the active database
01206 // Locking the database before the first active_valid call
01207 // is no good idea, since this requires to set a lock
01208 // even in cases where this is not necessary at all
01209
01210 if (!active_valid()) {
01211 slog.p(Logger::Info) << "CServer::active: active database timed out\n";
01212 _NVActiveDB->lock(NVcontainer::ExclLock);
01213 try {
01214 if (!active_valid()) {
01215 RServer::active();
01216 }
01217 }
01218 catch(Error & e) {
01219 slog.p(Logger::Alert)
01220 <<
01221 "CServer::active: UNEXPECTED EXCEPTION CAUGHT, WHILE IN CRITICAL REGION!\n"
01222 <<
01223 "CServer::active: PLEASE REPORT TO h.straub@aon.at\n";
01224 e.print();
01225 }
01226 catch(...) {
01227 slog.p(Logger::Alert)
01228 <<
01229 "CServer::active: UNEXPECTED EXCEPTION CAUGHT, WHILE IN CRITICAL REGION!\n"
01230 <<
01231 "CServer::active: PLEASE REPORT TO h.straub@aon.at\n";
01232 }
01233 _NVActiveDB->lock(NVcontainer::UnLock);
01234 }
01235 return _NVActiveDB;
01236 }
|
|
|
Definition at line 493 of file NServer.h. References _NVActiveDB, _TTLActive, NVActiveDB::getmtime(), and nvtime(). Referenced by active().
00493 {
00494 unsigned long tm;
00495 _NVActiveDB->getmtime(&tm);
00496 return (tm + _TTLActive) > nvtime(NULL);
00497 } int desc_valid() {
|
|
||||||||||||
|
Return the article for a given article id.
Reimplemented from RServer. Definition at line 1483 of file NServer.cc. References RServer::connect(), MPList::entries, ERROR_LOCATION, MPListEntry::flags, RServer::issue(), Logger::p(), Article::read(), Article::setnbr(), RServer::setserver(), slog, and VERB.
01484 {
01485 VERB(slog.p(Logger::Debug) << "CServer::article(" << id << ")\n");
01486 char buf[1024];
01487 const char *p;
01488 string resp;
01489
01490 sprintf(buf, "article %s\r\n", id);
01491 if (_CurrentServer
01492 && !(_CurrentServer->flags & MPListEntry::F_OFFLINE)) {
01493 resp = issue(buf, NULL);
01494 p = resp.c_str();
01495 if (strncmp(p, "220", 3) == 0) {
01496 art->read(*_pServerStream);
01497 art->setnbr(-1);
01498 return;
01499 }
01500 // 412 cannot happen since we specified the article id
01501 // 420 -"- since we specified the article id
01502 // 423 -"- since we specified the article id, not the art nbr
01503 if (strncmp(p, "430", 3) != 0) {
01504 slog.p(Logger::Notice)
01505 <<
01506 "illegal response code to <artcile <id>> request\n"
01507 << p;
01508 }
01509 }
01510 // check whether the article can be found at one of the other
01511 // news servers
01512 MPListEntry *cs = _CurrentServer;
01513 for (unsigned int i = 0; i < _ServerList->entries.size(); i++) {
01514 if (cs == &(_ServerList->entries[i]) ||
01515 !_ServerList->entries[i].hostname[0] ||
01516 _ServerList->entries[i].flags & MPListEntry::F_OFFLINE)
01517 continue;
01518 setserver(&(_ServerList->entries[i]));
01519 connect();
01520 resp = issue(buf, NULL);
01521 p = resp.c_str();
01522 if (strncmp(p, "220", 3) == 0) {
01523 art->read(*_pServerStream);
01524 art->setnbr(-1);
01525 return;
01526 }
01527 if (strncmp(p, "430", 3) != 0) {
01528 slog.p(Logger::Notice)
01529 <<
01530 "illegal response code to <artcile <id>> request\n"
01531 << p;
01532 }
01533 }
01534 throw NoSuchArticleError(resp, ERROR_LOCATION);
01535 }
|
|
||||||||||||||||
|
Return a given article of a given newsgroup.
Reimplemented from RServer. Definition at line 1470 of file NServer.cc. References RServer::article(), ERROR_LOCATION, MPListEntry::flags, Logger::p(), MPList::server(), slog, and VERB. Referenced by ns_article(), and ns_stat().
01471 {
01472 VERB(slog.p(Logger::Debug) << "CServer::article(" << nbr << ")\n");
01473 MPListEntry *mpe;
01474
01475 mpe = _ServerList->server(gname);
01476 if (mpe->flags & MPListEntry::F_OFFLINE)
01477 throw NSError("cannot retrieve articles in offline mode",
01478 ERROR_LOCATION);
01479
01480 RServer::article(gname, nbr, art);
01481 }
|
|
|
Definition at line 497 of file NServer.h.
00497 {
00498 return 1;
00499 }
|
|
|
Return the newsgroup with name >name<. If the newsgroup does not exist, NULL will be returned.
Reimplemented from LServer. Definition at line 1283 of file NServer.cc. References _NVActiveDB, ERROR_LOCATION, GroupInfo::first(), MPListEntry::flags, NVActiveDB::get(), groupinfo(), MPListEntry::groupTimeout, GroupInfo::last(), MPList::server(), CNewsgroup::setsize(), RNewsgroup::setsize(), NVNewsgroup::setsize(), CNewsgroup::setttl(), slog, and VERB. Referenced by doprefetch(), ns_article(), ns_lastnext(), ns_listgroup(), ns_stat(), and ns_xover().
01284 {
01285 VERB(slog.
01286 p(Logger::Debug) << "CServer::getgroup(" << name << ")\n");
01287 CNewsgroup *grp;
01288 MPListEntry *mpe;
01289
01290 if ((mpe = _ServerList->server(name)) == NULL) {
01291 throw NoSuchGroupError("no such group", ERROR_LOCATION);
01292 }
01293
01294 if (mpe->flags & MPListEntry::F_OFFLINE) {
01295 // offline => use NVNewsgroup
01296 GroupInfo grpinfo;
01297 if (_NVActiveDB->get(name, &grpinfo) < 0)
01298 throw NoSuchGroupError("no such group",
01299 ERROR_LOCATION);
01300 NVNewsgroup *grp =
01301 new NVNewsgroup(_OverviewFormat, _SpoolDirectory,
01302 name);
01303 grp->setsize(grpinfo.first(), grpinfo.last());
01304 return grp;
01305 }
01306
01307 if (!(mpe->flags & MPListEntry::F_CACHED)) {
01308 // not-cached => use RNewsgroup
01309 GroupInfo *grpinfo = groupinfo(name);
01310 if (_NVActiveDB->get(name, grpinfo) < 0)
01311 throw NoSuchGroupError("no such group",
01312 ERROR_LOCATION);
01313 RNewsgroup *grp =
01314 new RNewsgroup(this, _OverviewFormat, name);
01315 grp->setsize(grpinfo->first(), grpinfo->last());
01316 return grp;
01317 }
01318
01319 GroupInfo *grpinfo = groupinfo(name);
01320 grp = new CNewsgroup(this, _OverviewFormat, _SpoolDirectory, name);
01321 grp->setsize(grpinfo->first(), grpinfo->last());
01322 grp->setttl(mpe->groupTimeout);
01323 return grp;
01324 }
|
|
|
|
|
|
Returns information onto the newsgroup >name< from the active database. If the last information obtained for the newsgroup is older than groupTimeout (GroupTimeout in newscache.conf), a group request is issued to the news server with RServer::selectgroup(). If the Flag offline is specified, then the LServer::groupinfo is returned.
Reimplemented from LServer. Definition at line 1238 of file NServer.cc. References _NVActiveDB, ASSERT, ERROR_LOCATION, MPListEntry::flags, NVActiveDB::get(), LServer::groupinfo(), MPListEntry::groupTimeout, GroupInfo::mtime(), nvtime(), Logger::p(), RServer::selectgroup(), MPList::server(), slog, and VERB. Referenced by getgroup(), and selectgroup().
01239 {
01240 VERB(slog.
01241 p(Logger::Debug) << "CServer::groupinfo(" << name << ")\n");
01242 ASSERT(if (strlen(name) > 512) {
01243 throw
01244 AssertionError
01245 ("CServer::groupinfo: Name of newsgroup too long\n",
01246 ERROR_LOCATION);}
01247 );
01248
01249 static GroupInfo agroup;
01250 int errc;
01251 MPListEntry *mpe;
01252
01253 if ((mpe = _ServerList->server(name)) == NULL) {
01254 throw NoSuchGroupError("no such group", ERROR_LOCATION);
01255 }
01256 if (mpe->flags & MPListEntry::F_OFFLINE)
01257 return LServer::groupinfo(name);
01258
01259 if ((errc = _NVActiveDB->get(name, &agroup)) < 0 ||
01260 agroup.mtime() + mpe->groupTimeout < nvtime(NULL)) {
01261 VERB(slog.p(Logger::Debug) << "CServer::groupinfo "
01262 << "groupinfo timed out\n");
01263 try {
01264 RServer::selectgroup(name, 1);
01265 agroup = _CurrentGroup;
01266 }
01267 catch(ResponseError & re) {
01268 // in case of a response error, use cached values
01269 if (errc < 0)
01270 throw NoSuchGroupError("no such group",
01271 ERROR_LOCATION);
01272 }
01273 catch(SystemError & sr) {
01274 // in case of a system error, use cached values
01275 if (errc < 0)
01276 throw NoSuchGroupError("no such group",
01277 ERROR_LOCATION);
01278 }
01279 }
01280 return &agroup;
01281 }
|
|
|
Invalidate the Active DB. This is done by reseting the datebase timestamp value. This is usefull, if we change the configuration and add one Server, otherwise the new server activeDB is available after the active-db Timeout (see configurations file Timeouts active-db group-description. The next call of active() retrieve the data.
Definition at line 680 of file NServer.h. References _NVActiveDB, and NVActiveDB::setmtime(). Referenced by update().
00681 {
00682 _NVActiveDB->setmtime (0,1); // force flag 1 !!
00683 }
|
|
||||||||||||||||||||
|
Return a list of article available in a newsgroup
Reimplemented from RServer. Definition at line 1416 of file NServer.cc. References ASSERT, ERROR_LOCATION, MPListEntry::flags, RServer::listgroup(), MPList::server(), slog, and VERB.
01418 {
01419 VERB(slog.
01420 p(Logger::
01421 Debug) << "CServer::listgroup(" << gname << ",...)\n");
01422 ASSERT(if (!gname) {
01423 throw
01424 AssertionError
01425 ("CServer::listgroup: gname parameter is a null-pointer",
01426 ERROR_LOCATION);}
01427 if (!lstgrp) {
01428 throw
01429 AssertionError
01430 ("CServer::listgroup: lstgrp parameter is a null-pointer",
01431 ERROR_LOCATION);}
01432 );
01433 MPListEntry *mpe;
01434
01435 mpe = _ServerList->server(gname);
01436 if (mpe->flags & MPListEntry::F_OFFLINE)
01437 throw NSError("cannot listgroup in offline mode",
01438 ERROR_LOCATION);
01439
01440 RServer::listgroup(gname, lstgrp, f, l);
01441 }
|
|
||||||||||||||||
|
Return the overviewdatabase of the newsgroup >ng<. This function should not be called by the user. Instead it should be called via a Newsgroup object.
Reimplemented from RServer. Definition at line 1443 of file NServer.cc. References MPListEntry::flags, Newsgroup::name(), RServer::overviewdb(), Logger::p(), MPList::server(), slog, and VERB.
01445 {
01446 VERB(slog.p(Logger::Debug) << "CServer::overviewdb(*ng,"
01447 << fst << "-" << lst << ")\n");
01448 MPListEntry *mpe;
01449
01450 mpe = _ServerList->server(ng->name());
01451 if (!(mpe->flags & MPListEntry::F_OFFLINE))
01452 RServer::overviewdb(ng, fst, lst);
01453 }
|
|
|
Reimplemented from NServer. Definition at line 522 of file NServer.h. Referenced by ns_lastnext(), ns_list(), and ns_stat().
00522 {
00523 return _OverviewFormat;
00524 }
|
|
|
Post an article to the primary news server. The primary news server is the news server being listed first in the MPList. If the article cannot be submitted immediately, it is kept for later transmission.
Reimplemented from LServer. Definition at line 1326 of file NServer.cc. References Logger::p(), RServer::post(), slog, spoolarticle(), VERB, and Article::write(). Referenced by ns_post().
01327 {
01328 VERB(slog.p(Logger::Debug) << "CServer::post(Article*)\n");
01329 int r;
01330
01331 if ((r = RServer::post(article)) < 0) {
01332 spoolarticle(article);
01333 return 1;
01334 }
01335 #ifdef ENABLE_HEADERLOG
01336 char fn[MAXPATHLEN];
01337 fstream fs;
01338 struct timeval tv;
01339
01340 gettimeofday(&tv, NULL);
01341
01342 sprintf(fn, "%s/.headerlog", _SpoolDirectory);
01343 fs.open(fn, ios::app);
01344 fs << getpid() << " " << tv.tv_sec << endl;
01345 article->write(fs, Article::Head);
01346 fs.close();
01347 #endif
01348 return 0;
01349 }
|
|
|
Definition at line 1369 of file NServer.cc. References Logger::Error, Article::getfield(), ArtSpooler::getSpooledArt(), Logger::p(), RServer::post(), slog, ArtSpooler::storeBadArt(), and VERB. Referenced by update().
01370 {
01371 VERB(slog.p(Logger::Debug) << "CServer::postspooled()\n");
01372
01373 Article *pA;
01374 int s;
01375
01376 try {
01377 for (pA = pSpool->getSpooledArt(); pA != NULL;
01378 pA = pSpool->getSpooledArt()) {
01379 try {
01380 s = RServer::post(pA);
01381 if (s == -1) {
01382 slog.p(Logger::Debug)
01383 << "CServer::postspooled():\
01384 RServer::post returns Spooling\
01385 necessary; ID:" << pA->getfield("message-id") << "\n";
01386 pSpool->storeBadArt(*pA);
01387 } else if (s == -2) {
01388 slog.p(Logger::Error)
01389 << "CServer::postspooled():\
01390 RServer::post returns -2; ID:" << pA->getfield("message-id") << "\n";
01391 pSpool->storeBadArt(*pA);
01392 }
01393 }
01394 catch(InvalidArticleError iae) {
01395 slog.p(Logger::Error)
01396 << "CServer::postspooled(): RServer::post\
01397 throw InvalidArticleError; ID: "
01398 << pA->getfield("message-id") << "\n";
01399 pSpool->storeBadArt(*pA);
01400 }
01401 delete pA;
01402 }
01403 }
01404 catch(SystemError se) {
01405 slog.p(Logger::Error) << "CServer::postspooled():\
01406 Error posting articles from spool\n";
01407 throw se;
01408 }
01409 catch(...) {
01410 slog.p(Logger::Error) << "CServer::postspooled();\
01411 Unknown error while posting articles\n";
01412 throw;
01413 }
01414 }
|
|
||||||||||||
|
Definition at line 516 of file NServer.h. References _TTLActive, and _TTLDesc. Referenced by nnrpd(), and update().
00516 {
00517 _TTLActive = ttl_list;
00518 _TTLDesc = ttl_desc;
00519 }
|
|
|
Spool a news article for later transmission
Definition at line 1351 of file NServer.cc. References Logger::Error, Logger::p(), slog, ArtSpooler::spoolArt(), and VERB. Referenced by post().
01352 {
01353 VERB(slog.p(Logger::Debug) << "CServer::spoolarticle\n");
01354
01355 try {
01356 pSpool->spoolArt(*article);
01357 } catch(SystemError se) {
01358 slog.p(Logger::Error) << "CServer::spoolarticle: catched\
01359 SystemError while spooling article\n";
01360 throw se;
01361 }
01362 catch(...) {
01363 slog.p(Logger::Error) << "CServer::spoolarticle: catched\
01364 unknown error while spooling article";
01365 throw;
01366 }
01367 }
|
|
|
Definition at line 489 of file NServer.h. Referenced by active(), active_valid(), CServer(), getgroup(), groupinfo(), invalidateActiveDB(), and ~CServer(). |
|
|
Definition at line 491 of file NServer.h. Referenced by active_valid(), CServer(), and setttl(). |
|
|
|
1.3.6-20040222