Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

updatenews.cc File Reference

#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <iostream>
#include <vector>
#include "config.h"
#include "Debug.h"
#include "Config.h"
#include "NServer.h"
#include "Logger.h"
#include "setugid.h"

Go to the source code of this file.

Defines

#define PACKAGE   PACKAGE_UPDATENEWS
#define USAGE

Enumerations

enum  { F_PREFETCH_ACTIVE = 0x01, F_PREFETCH_GROUP = 0x02, F_PREFETCH_OVER = 0x04, F_PREFETCH_LOCKGROUP = 0x08 }

Functions

void catchsignal (int num)
void doprefetch (CServer *cs, const char *group)
int create_worker (CServer *cs, const char *group)
void readgroups (const char *fn, vector< string > &groups)
void update (void)
int main (int argc, char **argv)

Variables

Logger slog
const char * cmnd
Config Cfg
int opt_flags = 0
int opt_workers = 0
int Xsignal


Define Documentation

#define PACKAGE   PACKAGE_UPDATENEWS
 

Definition at line 44 of file updatenews.cc.

#define USAGE
 

Value:

"       -h, --help\n"\
"              Show summary of options.\n"\
"\n"\
"       -v, --version\n"\
"              Show version of program.\n"\
"\n"\
"       -c --configuration config-file\n"\
"\n"\
"       -a --active\n"\
"\n"\
"       -g --group\n"\
"              Prefetch articles.\n"\
"\n"\
"       -o --over\n"\
"              Prefetch overview database.\n"\
"\n"\
"       -l --lock-groups\n"\
"              Lock newsgroup, when prefetching.\n"\
"\n"\
"       -w --workers\n"\
"              Prefetch # newsgroups at once.\n"\

Definition at line 199 of file updatenews.cc.


Enumeration Type Documentation

anonymous enum
 

Enumeration values:
F_PREFETCH_ACTIVE 
F_PREFETCH_GROUP 
F_PREFETCH_OVER 
F_PREFETCH_LOCKGROUP 

Definition at line 52 of file updatenews.cc.

00052      {
00053         F_PREFETCH_ACTIVE = 0x01,
00054         F_PREFETCH_GROUP = 0x02,
00055         F_PREFETCH_OVER = 0x04,
00056         F_PREFETCH_LOCKGROUP = 0x08
00057 };


Function Documentation

void catchsignal int  num  ) 
 

Definition at line 66 of file updatenews.cc.

References catchsignal(), Logger::p(), slog, and Xsignal.

00067 {
00068         Xsignal = num;
00069         slog.p(Logger::Warning) << "received signal " << num << "\n";
00070 #ifdef HAVE_SIGACTION
00071         /* Reinstall the signal handler */
00072         struct sigaction action;
00073         action.sa_handler = catchsignal;
00074         sigemptyset(&action.sa_mask);
00075         action.sa_flags = 0;
00076         sigaction(num, &action, NULL);
00077 #else
00078         signal(num, catchsignal);
00079 #endif
00080 }

int create_worker CServer cs,
const char *  group
 

Definition at line 103 of file updatenews.cc.

References doprefetch(), and slog.

Referenced by update().

00104 {
00105         int c;
00106         switch (c = fork()) {
00107         case -1:
00108                 // failed
00109                 slog.
00110                     p(Logger::
00111                       Error) << "fork failed, using this process\n";
00112                 doprefetch(cs, group);
00113                 return 0;
00114         case 0:
00115                 // child
00116                 doprefetch(cs, group);
00117                 exit(0);
00118         default:
00119                 // parent
00120                 return 1;
00121                 break;
00122         }
00123 }

void doprefetch CServer cs,
const char *  group
 

Definition at line 82 of file updatenews.cc.

References F_PREFETCH_GROUP, F_PREFETCH_LOCKGROUP, F_PREFETCH_OVER, NServer::freegroup(), CServer::getgroup(), opt_flags, Logger::p(), Newsgroup::prefetchOverview(), and slog.

Referenced by create_worker(), and update().

00083 {
00084         Newsgroup *grp;
00085         try {
00086                 slog.p(Logger::Info) << "prefetching " << group << "\n";
00087                 grp = cs->getgroup(group);
00088                 if (opt_flags & F_PREFETCH_GROUP)
00089                         grp->
00090                             prefetchGroup(opt_flags &
00091                                           F_PREFETCH_LOCKGROUP);
00092                 else if (opt_flags & F_PREFETCH_OVER)
00093                         grp->prefetchOverview();
00094                 cs->freegroup(grp);
00095         }
00096         catch(...) {
00097                 slog.
00098                     p(Logger::
00099                       Error) << "prefetching " << group << " failed\n";
00100         }
00101 }

int main int  argc,
char **  argv
 

Definition at line 222 of file updatenews.cc.

References catchsignal(), Cfg, cmnd, CONF_UIDROOT, MPList::entries, F_PREFETCH_ACTIVE, F_PREFETCH_GROUP, F_PREFETCH_LOCKGROUP, F_PREFETCH_OVER, Config::Groupname, Config::Hostname, Config::LogDirectory, nntp_hostname, Logger::open(), opt_flags, PACKAGE, Config::read(), setugid(), slog, Config::srvrs, SYSCONFDIR, update(), USAGE, Config::Username, VERSION, and Xsignal.

00223 {
00224 #ifndef WITH_SYSLOG
00225         char logfile[MAXPATHLEN];
00226         time_t t;
00227         pid_t p;
00228 #endif
00229         char conffile[MAXPATHLEN];
00230         int opt_config = 0, opt_flagsset = 0;
00231         int c, aerr = 0;
00232 
00233         sprintf(conffile, "%s/newscache.conf", SYSCONFDIR);
00234 
00235         cmnd = argv[0];
00236         while (1) {
00237                 int option_index = 0;
00238                 static struct option long_options[] = {
00239                         {"version", 0, 0, 'v'},
00240                         {"help", 0, 0, 'h'},
00241                         {"active", 0, 0, 'a'},
00242                         {"group", 0, 0, 'g'},
00243                         {"over", 0, 0, 'o'},
00244                         {"lock-group", 0, 0, 'l'},
00245                         {"workers", 1, 0, 'w'},
00246                         {"configuration", 1, 0, 'c'},
00247                         {0, 0, 0, 0}
00248                 };
00249 
00250                 c = getopt_long (argc, argv, "vhc:agolw:", long_options,
00251                                 &option_index);
00252 
00253                 if (c == -1)
00254                         break;
00255 
00256                 switch (c) {
00257                         case 'v':
00258                                 cout << PACKAGE << " " << VERSION << endl;
00259                                 exit (0);
00260                                 break;
00261 
00262                         case 'h':
00263                                 cout << "Usage: " << cmnd << endl;
00264                                 cout << USAGE << endl;
00265                                 exit (0);
00266                                 break;
00267 
00268                         case 'a':
00269                                 opt_flags |= F_PREFETCH_ACTIVE;
00270                                 opt_flagsset = 1;
00271                                 break;
00272 
00273                         case 'g':
00274                                 opt_flags |= F_PREFETCH_GROUP;
00275                                 opt_flagsset = 1;
00276                                 break;
00277 
00278                         case 'o':
00279                                 opt_flags |= F_PREFETCH_OVER;
00280                                 opt_flagsset = 1;
00281                                 break;
00282 
00283                         case 'l':
00284                                 opt_flags |= F_PREFETCH_LOCKGROUP;
00285                                 opt_flagsset = 1;
00286                                 break;
00287 
00288                         case 'c':
00289                                 strcpy (conffile, optarg);
00290                                 ++opt_config;
00291                                 break;
00292 
00293                         default:
00294                                 aerr = 1;
00295                                 break;
00296                 }
00297 
00298         }
00299         if (!opt_flagsset)
00300                 opt_flags = F_PREFETCH_GROUP;
00301 
00302         if (aerr || optind != argc) {
00303                 cerr << "Usage: " << cmnd << " [options]\n" << USAGE;
00304                 exit(1);
00305         }
00306 
00307         try {
00308                 Cfg.read(conffile);
00309                 strcpy(nntp_hostname, Cfg.Hostname);
00310         }
00311         catch(IOError & io) {
00312                 cerr << "unexpected EOF in " << conffile << "\n";
00313                 exit(2);
00314         }
00315         catch(SyntaxError & se) {
00316                 cerr << se._errtext << "\n";
00317                 exit(2);
00318         }
00319 
00320         for (unsigned int i = 0; i < Cfg.srvrs.entries.size(); i++) {
00321                 // Switch off offline mode
00322                 Cfg.srvrs.entries[i].flags &=
00323                     ~(MPListEntry::F_OFFLINE | MPListEntry::F_SEMIOFFLINE);
00324                 // Set timeout to 0
00325                 Cfg.srvrs.entries[i].groupTimeout = 0;
00326         }
00327 
00328         // signal
00329         Xsignal = -1;
00330 #ifdef HAVE_SIGACTION
00331         struct sigaction action;
00332         // signals indicating to terminate NewsCache
00333         action.sa_handler = catchsignal;
00334         sigemptyset(&action.sa_mask);
00335         action.sa_flags = 0;
00336         sigaction(SIGHUP, &action, NULL);
00337         sigaction(SIGINT, &action, NULL);
00338         sigaction(SIGPIPE, &action, NULL);
00339         sigaction(SIGTERM, &action, NULL);
00340 
00341         sigaction(SIGALRM, &action, NULL);
00342         sigaction(SIGUSR1, &action, NULL);
00343         sigaction(SIGUSR2, &action, NULL);
00344 #else
00345         signal(SIGHUP, catchsignal);
00346         signal(SIGPIPE, catchsignal);
00347         signal(SIGINT, catchsignal);
00348         signal(SIGPIPE, catchsignal);
00349         signal(SIGTERM, catchsignal);
00350         signal(SIGALRM, catchsignal);
00351         signal(SIGUSR1, catchsignal);
00352         signal(SIGUSR2, catchsignal);
00353 #endif
00354 
00355 #ifdef WITH_SYSLOG
00356         slog.open(PACKAGE, LOG_NDELAY | LOG_PID, LOG_NEWS);
00357 #else
00358         sprintf (logfile, "%s/newscache_updatenews.log", Cfg.LogDirectory);
00359         slog.open (logfile);
00360 #endif
00361 
00362         // Check the queue in each server-directory and send it off to the 
00363         // news server
00364         if (getuid() == CONF_UIDROOT)
00365                 setugid(Cfg.Username, Cfg.Groupname);
00366         update();
00367         return 0;
00368 }

void readgroups const char *  fn,
vector< string > &  groups
 

Definition at line 125 of file updatenews.cc.

References Cfg, Logger::Error, nlreadline(), slog, and Xsignal.

Referenced by update().

00126 {
00127         ifstream ifs(fn);
00128         string group;
00129 
00130         if (!ifs.good()) {
00131                 return;
00132         }
00133 
00134         for (; Xsignal < 0;) {
00135                 nlreadline(ifs, group, 0);
00136                 if (ifs.eof())
00137                         break;
00138                 if (group[0] == '!')
00139                         continue;
00140                 if (ifs.bad()) {
00141                         slog.
00142                             p(Logger::Error) << "cannot read from " << Cfg.
00143                             PrefetchFile;
00144                         break;
00145                 }
00146                 groups.push_back(group);
00147         }
00148         ifs.close();
00149 }

void update void   ) 
 

Definition at line 151 of file updatenews.cc.

References CServer::active(), Cfg, create_worker(), doprefetch(), F_PREFETCH_ACTIVE, F_PREFETCH_GROUP, F_PREFETCH_OVER, CServer::invalidateActiveDB(), opt_flags, opt_workers, Logger::p(), CServer::postspooled(), Config::PrefetchFile, readgroups(), CServer::setttl(), slog, Config::SpoolDirectory, Config::srvrs, Config::ttl_desc, Config::ttl_list, and Xsignal.

Referenced by main().

00152 {
00153         CServer cs(Cfg.SpoolDirectory, &(Cfg.srvrs));
00154         int wi = opt_workers ? 0 : -1;
00155 
00156         cs.setttl(Cfg.ttl_list, Cfg.ttl_desc);
00157 
00158         slog.p(Logger::Info) << "posting spooled articles\n";
00159         cs.postspooled();
00160         if (opt_flags & F_PREFETCH_ACTIVE) {
00161                 slog.p(Logger::Debug) << "invalidate the ActiveDB (force update)\n";
00162                 cs.invalidateActiveDB ();
00163         };
00164         slog.p(Logger::Info) << "prefetching active database\n";
00165         cs.active();
00166 
00167         if (!(opt_flags & (F_PREFETCH_GROUP | F_PREFETCH_OVER)))
00168                 return;
00169 
00170         // read groups to prefetch
00171         vector < string > groups;
00172         vector < string >::iterator begin, end;
00173         readgroups(Cfg.PrefetchFile, groups);
00174 
00175         for (begin = groups.begin(), end = groups.end();
00176              begin != end && Xsignal < 0; ++begin) {
00177                 while (wi == opt_workers) {
00178                         // maximum workers spawned, wait until a worker exits
00179                         int cstat;
00180                         int cid;
00181                         cid = wait(&cstat);
00182                         if (WIFSIGNALED(cstat)) {
00183                                 slog.
00184                                     p(Logger::
00185                                       Error) <<
00186                                     "worker terminated unexpectedly\n";
00187                                 --wi;
00188                         } else if (WIFEXITED(cstat)) {
00189                                 --wi;
00190                         }
00191                 }
00192                 if (opt_workers == 0)
00193                         doprefetch(&cs, begin->c_str());
00194                 else
00195                         wi += create_worker(&cs, begin->c_str());
00196         }
00197 }


Variable Documentation

Config Cfg
 

Definition at line 61 of file updatenews.cc.

const char* cmnd
 

Definition at line 60 of file updatenews.cc.

int opt_flags = 0
 

Definition at line 62 of file updatenews.cc.

Referenced by doprefetch(), main(), and update().

int opt_workers = 0
 

Definition at line 63 of file updatenews.cc.

Referenced by update().

Logger slog
 

Definition at line 59 of file updatenews.cc.

int Xsignal
 

Definition at line 64 of file updatenews.cc.


Generated on Sun Oct 24 21:08:21 2004 for NewsCache by doxygen 1.3.6-20040222