#include "config.h"#include <crypt.h>#include <ctype.h>#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/socket.h>#include <sys/types.h>#include <sys/wait.h>#include <time.h>#include <limits.h>#include <socket++/sockstream.h>#include <pwd.h>#include <iostream>#include <algorithm>#include <map>#include "NServer.h"#include "Newsgroup.h"#include "util.h"#include "setugid.h"#include "Config.h"#include "Logger.h"Go to the source code of this file.
Classes | |
| struct | nnrp_command_t |
| class | NNRPCommandMap |
| class | ClientData |
| class | print_list_active |
| class | print_list_active_times |
| class | active_filter_group |
| class | active_filter_group_time |
| class | active_filter_time |
Defines | |
| #define | CONF_MultiClient |
| #define | SOCKLEN_TYPE size_t |
| #define | REJECT_SEQUENCE "502" |
| #define | PASS_NEEDED_SEQUENCE "381" |
| #define | OK_SEQUENCE "281" |
| #define | INCORRECT_ORDER_SEQUENCE "482" |
| #define | DD2INT(x) ((x)[0]-'0')*10+((x)[1]-'0') |
| #define | USAGE |
Typedefs | |
| typedef nnrp_command_t | nnrp_command_t |
Enumerations | |
| enum | { AUTH_REQUIRED, AUTH_OK, AUTH_FAILED, AUTH_NOT_REQUIRED } |
Functions | |
| int | ns_authinfo (ClientData *clt, int argc, char *argv[]) |
| int | ns_article (ClientData *clt, int argc, char *argv[]) |
| int | ns_stat (ClientData *clt, int argc, char *argv[]) |
| int | ns_date (ClientData *clt, int argc, char *argv[]) |
| int | ns_group (ClientData *clt, int argc, char *argv[]) |
| int | ns_help (ClientData *clt, int argc, char *argv[]) |
| int | ns_lastnext (ClientData *clt, int argc, char *argv[]) |
| int | ns_list (ClientData *clt, int argc, char *argv[]) |
| int | ns_listgroup (ClientData *clt, int argc, char *argv[]) |
| int | ns_mode (ClientData *clt, int argc, char *argv[]) |
| int | ns_newgroups (ClientData *clt, int argc, char *argv[]) |
| int | ns_post (ClientData *clt, int argc, char *argv[]) |
| int | ns_quit (ClientData *clt, int argc, char *argv[]) |
| int | ns_xmotd (ClientData *clt, int argc, char *argv[]) |
| int | ns_xover (ClientData *clt, int argc, char *argv[]) |
| int | ns_xdebug (ClientData *clt, int argc, char *argv[]) |
| void | set_client_command_table (ClientData &clt) |
| char ** | seekfile (const char *filename, const char *username) |
| int | auto_cryptcheck (const char *key, const char *pass) |
| int | check_auth_unix (ClientData *clt) |
| int | check_auth_file (ClientData *clt) |
| int | check_authentication (ClientData *clt) |
| int | fillHostStruct (struct sockaddr_in *addr, char *pHost) |
| GroupInfo * | selectgroup (ClientData *clt, const char *group) |
| void | nsh_particle (ClientData *clt, char *cmnd, int nbr, Article *a) |
| void | nnrpd (int fd) |
| void | nntpd () |
| void | sigchld (int num) |
| void | catchsigalarm (int num) |
| void | catchsighup (int num) |
| void | catchsignal (int num) |
| int | main (int argc, char **argv) |
Variables | |
| char * | ConfigurationOptions [] |
| int | clientTimeoutReached = 0 |
| Logger | slog |
| const char * | cmnd |
| char | config_file [MAXPATHLEN] |
| Config | Cfg |
| int | Xsignal |
| int | nntp_connections |
|
|
Definition at line 130 of file NewsCache.cc. |
|
|
Definition at line 1527 of file NewsCache.cc. Referenced by ns_newgroups(). |
|
|
Definition at line 900 of file NewsCache.cc. Referenced by ns_authinfo(). |
|
|
Definition at line 899 of file NewsCache.cc. Referenced by ns_authinfo(). |
|
|
Definition at line 898 of file NewsCache.cc. Referenced by ns_authinfo(). |
|
|
Definition at line 897 of file NewsCache.cc. Referenced by ns_authinfo(). |
|
|
Definition at line 138 of file NewsCache.cc. Referenced by nntpd(). |
|
|
Value: " -h, --help\n"\ " Show summary of options.\n"\ "\n"\ " -v, --version\n"\ " Show version of program.\n"\ "\n"\ " -f --fqdn\n"\ " Print what newscache thinks is the fully qualified domain name.\n"\ "\n"\ " -c --configuration config-file\n"\ "\n"\ " -i --inetd\n"\ " newscache is used with inetd and read from stdin.\n"\ "\n"\ " -d --debug\n"\ " Do not detach.\n"\ "\n"\ " -p --print-parameter\n"\ " Print current parameter settings.\n"\ "\n"\ " -o --configurtion-options\n"\ " Print all options specified in the configure phase.\n" Definition at line 2493 of file NewsCache.cc. Referenced by main(). |
|
|
|
|
|
Definition at line 304 of file NewsCache.cc.
00304 {
00305 AUTH_REQUIRED,
00306 AUTH_OK,
00307 AUTH_FAILED,
00308 AUTH_NOT_REQUIRED
00309 };
|
|
||||||||||||
|
Definition at line 443 of file NewsCache.cc. References md5crypt(). Referenced by check_auth_file(), and check_auth_unix().
00444 {
00445 #ifdef MD5_AUTO
00446 if (strlen(pass) == 24 && pass[23] == '=' && pass[22] == '=') {
00447 // looks like an MD5 hash
00448 #endif
00449 #ifdef MD5_CRYPT
00450 return strcmp(pass, (const char *) md5crypt(key));
00451 #endif
00452 #ifdef MD5_AUTO
00453 } else {
00454 #endif
00455 return strcmp(pass, (const char *) crypt(key, pass));
00456 #ifdef MD5_AUTO
00457 }
00458 #endif /*MD5_AUTO */
00459 return 0;
00460 }
|
|
|
Definition at line 2444 of file NewsCache.cc. References catchsigalarm(), clientTimeoutReached, Logger::p(), and slog. Referenced by catchsigalarm(), and main().
02445 {
02446 slog.p(Logger::Debug) << "receiving signal SIGALRM: " << num << "\n";
02447 clientTimeoutReached=1;
02448 #ifdef HAVE_SIGACTION
02449 /* Reinstall the signal handler */
02450 struct sigaction action;
02451 action.sa_handler = catchsigalarm;
02452 sigemptyset(&action.sa_mask);
02453 action.sa_flags = 0;
02454 sigaction(num, &action, NULL);
02455 #else
02456 signal(num, catchsigalarm);
02457 #endif
02458 }
|
|
|
Definition at line 2460 of file NewsCache.cc. References catchsighup(), Cfg, config_file, Config::init(), Logger::p(), Config::read(), and slog. Referenced by catchsighup(), and main().
02461 {
02462 slog.p(Logger::Debug) << "receiving signal SIGHUP: " << num << "\n";
02463 Cfg.init();
02464 Cfg.read(config_file);
02465 #ifdef HAVE_SIGACTION
02466 /* Reinstall the signal handler */
02467 struct sigaction action;
02468 action.sa_handler = catchsighup;
02469 sigemptyset(&action.sa_mask);
02470 action.sa_flags = 0;
02471 sigaction(num, &action, NULL);
02472 #else
02473 signal(num, catchsighup);
02474 #endif
02475 }
|
|
|
Definition at line 2477 of file NewsCache.cc. References catchsignal(), Logger::p(), slog, and Xsignal. Referenced by catchsignal(), and main().
02478 {
02479 slog.p(Logger::Debug) << "receiving signal: " << num << "\n";
02480 Xsignal = num;
02481 #ifdef HAVE_SIGACTION
02482 /* Reinstall the signal handler */
02483 struct sigaction action;
02484 action.sa_handler = catchsignal;
02485 sigemptyset(&action.sa_mask);
02486 action.sa_flags = 0;
02487 sigaction(num, &action, NULL);
02488 #else
02489 signal(num, catchsignal);
02490 #endif
02491 }
|
|
|
Definition at line 508 of file NewsCache.cc. References ClientData::access_entry, Authentication::appendField(), ClientData::auth_pass, ClientData::auth_user, AccessEntry::authentication, auto_cryptcheck(), Authentication::getField(), NewsgroupFilter::getRulelist(), AccessEntry::list, AccessEntry::modifyAccessFlags(), Logger::p(), AccessEntry::postTo, AccessEntry::read, seekfile(), Authentication::set(), slog, and Authentication::typeEqual(). Referenced by check_authentication().
00509 {
00510 AccessEntry *access_entry = clt->access_entry;
00511 string type("file:");
00512
00513 if (access_entry->authentication.typeEqual (type))
00514 return -1;
00515
00516 string authfile = access_entry->authentication.getField(1);
00517 char **authv = seekfile(authfile.c_str(), clt->auth_user);
00518 int authc = 0;
00519 int passf=-1;
00520
00521 if (!authv)
00522 return -1;
00523
00524 while (authv[authc])
00525 authc++;
00526 if (authc < 3)
00527 return -1;
00528
00529
00530 #ifdef PLAIN_TEXT_PASSWORDS
00531 passf=strcmp(clt->auth_pass, authv[1]);
00532 #endif
00533 if (passf)
00534 passf=auto_cryptcheck(clt->auth_pass, authv[1]);
00535 if (passf)
00536 return -1;
00537
00538 // Now we build a authentication string like the
00539 // unix:::: authentication string and set authentication
00540 // Herbert Straub
00541 access_entry->authentication.set (type+authfile);
00542 for (authc=2; authv[authc]; authc++) {
00543 access_entry->authentication.appendField(authv[authc]);
00544 }
00545 access_entry->list |= NewsgroupFilter(
00546 (access_entry->authentication.getField(2))
00547 .c_str());
00548 access_entry->read |= NewsgroupFilter(
00549 (access_entry->authentication.getField(3))
00550 .c_str());
00551 access_entry->postTo |= NewsgroupFilter(
00552 (access_entry->authentication.getField(4)).
00553 c_str());
00554 access_entry->modifyAccessFlags (access_entry->authentication.
00555 getField(5));
00556 slog.p(Logger::Debug) << "check_auth_file::NewsgroupFilter set to: "
00557 << access_entry->list.getRulelist() << ":"
00558 << access_entry->read.getRulelist() << ":"
00559 << access_entry->postTo.getRulelist() << "\n";
00560
00561 return 0;
00562 }
|
|
|
Definition at line 462 of file NewsCache.cc. References ClientData::access_entry, ClientData::auth_pass, ClientData::auth_user, AccessEntry::authentication, auto_cryptcheck(), Authentication::getField(), NewsgroupFilter::getRulelist(), AccessEntry::list, AccessEntry::modifyAccessFlags(), Logger::p(), AccessEntry::postTo, AccessEntry::read, slog, and Authentication::typeEqual(). Referenced by check_authentication().
00463 {
00464 AccessEntry *access_entry = clt->access_entry;
00465 string type("unix:");
00466
00467 if (access_entry->authentication.typeEqual (type))
00468 return -1;
00469
00470 const char *pass;
00471 struct passwd *pw = NULL;
00472 pw = getpwnam(clt->auth_user);
00473 if (!pw || !(pw->pw_name) || !(pw->pw_passwd)
00474 || !(pw->pw_passwd[0]))
00475 return -1;
00476 pass = pw->pw_passwd;
00477 #ifdef SHADOW_PASSWORD
00478 if ((pass[0] == 'x') && (pass[1] == '\0')) {
00479 struct spwd *spw = NULL;
00480 spw = getspnam(pw->pw_name);
00481 if (!(spw) || !(spw->sp_namp) || !(spw->sp_pwdp))
00482 return -1;
00483 pass = spw->sp_pwdp;
00484 }
00485 #endif
00486 if (auto_cryptcheck(clt->auth_pass, pass))
00487 return -1;
00488
00489 access_entry->list |= NewsgroupFilter(
00490 (access_entry->authentication.getField(1))
00491 .c_str());
00492 access_entry->read |= NewsgroupFilter(
00493 (access_entry->authentication.getField(2))
00494 .c_str());
00495 access_entry->postTo |= NewsgroupFilter(
00496 (access_entry->authentication.getField(3)).
00497 c_str());
00498 access_entry->modifyAccessFlags (access_entry->authentication.
00499 getField(4));
00500 slog.p(Logger::Debug) << "check_auth_unix::NewsgroupFilter set to: "
00501 << access_entry->list.getRulelist() << ":"
00502 << access_entry->read.getRulelist() << ":"
00503 << access_entry->postTo.getRulelist() << "\n";
00504
00505 return 0;
00506 }
|
|
|
Definition at line 722 of file NewsCache.cc. References ClientData::access_entry, AccessEntry::authentication, check_auth_file(), check_auth_unix(), and Authentication::getType(). Referenced by ns_authinfo().
00723 {
00724 AccessEntry *access_entry = clt->access_entry;
00725
00726 if (access_entry->authentication.getType() == "none") {
00727 return -1;
00728 }
00729
00730 if (!strncmp((access_entry->authentication.getType()).c_str()
00731 , "unix", 4)) {
00732 return check_auth_unix (clt);
00733 } else
00734 if (!strncmp((access_entry->authentication.getType()).c_str(),
00735 "file", 4))
00736 {
00737 return check_auth_file (clt);
00738 }
00739 #ifdef PAM_AUTH
00740 else if (!strncmp
00741 ((access_entry->authentication.getType()).c_str(),
00742 "pam+file", 8)) {
00743 return check_auth_pam_file (clt);
00744 }
00745 else if (!strncmp
00746 ((access_entry->authentication.getType()).c_str(),
00747 "pam", 3)) {
00748 return check_auth_pam (clt);
00749 }
00750 #endif /* #ifndef PAM_AUTH */
00751 // auth_{deny,none} is handled in nnrpd()
00752 return -1;
00753 }
|
|
||||||||||||
|
Definition at line 757 of file NewsCache.cc. References Logger::Error, Logger::p(), and slog. Referenced by nntpd().
00758 {
00759 char fname[] = "getHost";
00760 char *p;
00761 struct servent *cport;
00762 struct hostent *host;
00763 int portFlg = 0;
00764
00765 addr->sin_family = AF_INET;
00766
00767 if ((p = strchr(pHost, ':')) != NULL) {
00768 portFlg = 1;
00769 *p = '\0';
00770 }
00771
00772 if (strcmp(pHost, "DEFAULT") == 0) {
00773 addr->sin_addr.s_addr = INADDR_ANY;
00774 } else if ((addr->sin_addr.s_addr = inet_addr(pHost)) ==
00775 INADDR_NONE) {
00776 if ((host =
00777 gethostbyname(pHost)) == NULL | host->h_addrtype !=
00778 AF_INET) {
00779 if (portFlg)
00780 *p = ':';
00781 slog.
00782 p(Logger::
00783 Error) << fname << ": gethostbyname (" <<
00784 pHost << ") error: " << strerror(errno) <<
00785 "\n";
00786 return -1;
00787 } else {
00788 if (host->h_addr_list[0]) {
00789 memcpy(&addr->sin_addr.s_addr,
00790 host->h_addr_list[0],
00791 host->h_length);
00792 } else {
00793 if (portFlg)
00794 *p = ':';
00795 slog.
00796 p(Logger::
00797 Error) << fname <<
00798 ":host->h_addr_list[0] of " << pHost <<
00799 "not valid\n";
00800 return -1;
00801 }
00802 }
00803 }
00804 if (portFlg)
00805 *p = ':';
00806
00807 if (portFlg && isdigit(*(p + 1))) {
00808 addr->sin_port = htons(atoi(p + 1));
00809 } else
00810 if ((cport =
00811 getservbyname((portFlg) ? (p + 1) : ("nntp"),
00812 "tcp")) == NULL) {
00813
00814 slog.p(Logger::Error) << fname << ": getservbyname ("
00815 << ((portFlg) ? ((const char *) (p + 1))
00816 : ((const char *) "nntp")) << "/tcp error \n";
00817 return -1;
00818 } else {
00819 addr->sin_port = cport->s_port;
00820 }
00821
00822 return 1;
00823 }
|
|
||||||||||||
|
Definition at line 2517 of file NewsCache.cc. References catchsigalarm(), catchsighup(), catchsignal(), Cfg, cmnd, config_file, ConfigurationOptions, Logger::Error, getfqdn(), Config::Groupname, Config::Hostname, Config::LogDirectory, nnrpd(), nntp_hostname, nntpd(), Logger::open(), Logger::p(), PACKAGE, Config::printParameters(), Config::read(), Config::ServerType, setugid(), sigchld(), slog, USAGE, Config::Username, and Xsignal.
02518 {
02519 #ifndef WITH_SYSLOG
02520 char logfile[MAXPATHLEN];
02521 time_t t;
02522 pid_t p;
02523 #endif
02524 int opt_config = 0, opt_inetd = 0, opt_debug = 0, opt_print_para = 0;
02525 int opt_config_options = 0;
02526 int aerr = 0, c;
02527
02528 sprintf(config_file, "%s/newscache.conf", SYSCONFDIR);
02529
02530 cmnd = argv[0];
02531 while (1) {
02532 int option_index = 0;
02533 static struct option long_options[] = {
02534 {"version", 0, 0, 'v'},
02535 {"fqdn", 0, 0, 'f'},
02536 {"help", 0, 0, 'h'},
02537 {"configuration", 1, 0, 'c'},
02538 {"inetd", 0, 0, 'i'},
02539 {"debug", 0, 0, 'd'},
02540 {"print-parameter", 0, 0, 'p'},
02541 {"configuration-options", 0, 0, 'o'},
02542 {0, 0, 0, 0}
02543 };
02544
02545 c = getopt_long (argc, argv, "vfhc:idpo", long_options,
02546 &option_index);
02547 if (c == -1)
02548 break;
02549
02550 switch (c) {
02551 case 'v':
02552 cout << PACKAGE << " " VERSION << endl;
02553 exit (0);
02554 break;
02555
02556 case 'f':
02557 cout << getfqdn () << endl;
02558 exit (0);
02559 break;
02560
02561 case 'h':
02562 cout << "Usage: " << cmnd << " [options]\n"
02563 << USAGE;
02564 exit (0);
02565 break;
02566
02567 case 'c':
02568 strcpy (config_file, optarg);
02569 ++opt_config;
02570 break;
02571
02572 case 'i':
02573 ++opt_inetd;
02574 break;
02575
02576 case 'd':
02577 ++opt_debug;
02578 break;
02579 case 'p':
02580 ++opt_print_para;
02581 break;
02582 case 'o':
02583 ++opt_config_options;
02584 break;
02585 default:
02586 aerr = 1;
02587 break;
02588 }
02589 }
02590
02591 if (aerr || optind != argc) {
02592 cerr << "Usage: " << cmnd << " [options]\n" << USAGE;
02593 exit(1);
02594 }
02595
02596 try {
02597 Cfg.read(config_file);
02598 strcpy(nntp_hostname, Cfg.Hostname);
02599 }
02600 catch(IOError & io) {
02601 cerr << "unexpected EOF in " << config_file << "\n";
02602 exit(2);
02603 }
02604 catch(SyntaxError & se) {
02605 cerr << se._errtext << "\n";
02606 exit(2);
02607 }
02608
02609 if (opt_print_para) {
02610 cout << "# This output is generated with newscache -p" << endl;
02611 Cfg.printParameters (&cout);
02612 exit (0);
02613 }
02614
02615 if (opt_config_options) {
02616 for (int i=0; ConfigurationOptions[i] != NULL; i++) {
02617 cout << ConfigurationOptions[i] << " ";
02618 }
02619 cout << endl;
02620 exit (0);
02621 }
02622
02623 #ifdef WITH_SYSLOG
02624 slog.open(PACKAGE, LOG_NDELAY | LOG_PID, LOG_NEWS);
02625 #else
02626 sprintf (logfile, "%s/newscache.log", Cfg.LogDirectory);
02627 slog.open (logfile);
02628 #endif
02629
02630 // signal handling
02631 Xsignal = -1;
02632
02633 #ifdef HAVE_SIGACTION
02634 struct sigaction action;
02635
02636 // alarm - client timeout signal
02637 action.sa_handler = catchsigalarm;
02638 sigemptyset(&action.sa_mask);
02639 action.sa_flags = 0;
02640 sigaction(SIGALRM, &action, NULL);
02641
02642 // reread config file
02643 action.sa_handler = catchsighup;
02644 sigemptyset(&action.sa_mask);
02645 action.sa_flags = 0;
02646 sigaction(SIGHUP, &action, NULL);
02647
02648 // signals indicating to terminate NewsCache
02649 action.sa_handler = catchsignal;
02650 sigaction(SIGINT, &action, NULL);
02651 sigaction(SIGPIPE, &action, NULL);
02652 sigaction(SIGTERM, &action, NULL);
02653
02654 // ignored signals
02655 action.sa_handler = SIG_IGN;
02656 sigaction(SIGUSR1, &action, NULL);
02657 sigaction(SIGUSR2, &action, NULL);
02658
02659 // clean zombies
02660 action.sa_handler = sigchld;
02661 sigaction(SIGCHLD, &action, NULL);
02662 #else
02663 signal(SIGALRM, catchsigalarm);
02664 signal(SIGHUP, catchsighup);
02665 signal(SIGINT, catchsignal);
02666 signal(SIGPIPE, catchsignal);
02667 signal(SIGTERM, catchsignal);
02668
02669 signal(SIGUSR1, SIG_IGN);
02670 signal(SIGUSR2, SIG_IGN);
02671
02672 signal(SIGCHLD, sigchld);
02673 #endif
02674
02675 if (Cfg.ServerType == Config::inetd)
02676 opt_inetd = 1;
02677
02678 if (opt_inetd) {
02679 if (getuid() == CONF_UIDROOT)
02680 setugid(Cfg.Username, Cfg.Groupname);
02681 nnrpd(-1);
02682 } else {
02683 if (opt_debug == 0) {
02684 switch (fork()) {
02685 case -1:
02686 cerr << "cannot fork\n";
02687 slog.p(Logger::Error) << "cannot fork\n";
02688 break;
02689 case 0:
02690 if (setsid() == -1) {
02691 cerr << "setsid failed\n";
02692 slog.
02693 p(Logger::
02694 Error) << "setsid failed\n";
02695 exit(1);
02696 }
02697 close(STDIN_FILENO);
02698 close(STDOUT_FILENO);
02699 close(STDERR_FILENO);
02700 break;
02701 default:
02702 return 0;
02703 }
02704 }
02705 nntpd();
02706 }
02707
02708 return 0;
02709 }
|
|
|
Definition at line 1869 of file NewsCache.cc. References ClientData::access_entry, AccessEntry::access_flags, ClientData::auth_failures, ClientData::auth_max_failures, AUTH_NOT_REQUIRED, AUTH_REQUIRED, ClientData::auth_state, ClientData::auth_user, AccessEntry::authentication, Cfg, ClientData::ci, AccessList::client(), ClientData::client_command_map, ClientData::client_logname, ClientData::client_name, Config::ClientTimeout, clientTimeoutReached, Config::clnts, ClientData::co, Authentication::getNrOfFields(), Authentication::getType(), ClientData::groupname, AccessEntry::hostname, Config::LogStyle, Config::NiceServer, nntp_posting_host, Logger::p(), PACKAGE, Logger::print(), set_client_command_table(), CServer::setttl(), slog, ClientData::sock, ClientData::socklen, Config::SpoolDirectory, ClientData::srvr, Config::srvrs, ClientData::stat_articles, ClientData::stat_artingrp, ClientData::stat_groups, Config::ttl_desc, Config::ttl_list, and Xsignal. Referenced by main(), and nntpd().
01870 {
01871 struct hostent *he;
01872 ClientData clt;
01873 char req[1024], oreq[1024], *rp;
01874 char *argv[256];
01875 int argc;
01876 const char *cmd;
01877 map < string, nnrp_command_t * >::iterator cmdp, end =
01878 nnrp_commands.end();
01879 int errc = 0;
01880 sockbuf *psock_buff = NULL;
01881 iosockstream *psock_stream = NULL;
01882 int nice;
01883
01884 /* set nice value for master server */
01885 #ifdef HAVE_SETPRIORITY
01886 errno = 0;
01887 nice = Cfg.NiceServer;
01888 nice += getpriority(PRIO_PROCESS, 0);
01889 if (nice == -1 && errno != 0) {
01890 slog.
01891 p(Logger::
01892 Error) << "getpriority failed: " << strerror(errno)
01893 << "\n";
01894 } else {
01895 if (setpriority(PRIO_PROCESS, 0, nice) == -1)
01896 slog.
01897 p(Logger::
01898 Error) << "setpriority failed: " <<
01899 strerror(errno) << "\n";
01900 }
01901 #endif
01902
01903 if (fd >= 0) {
01904 // FIXME: check NULL Pointer and throw exception
01905 psock_buff = new sockbuf(fd);
01906 psock_buff->setname ("nntp client socket");
01907 psock_stream = new iosockstream(psock_buff);
01908 psock_buff->recvtimeout(-1);
01909 psock_buff->sendtimeout(-1);
01910 psock_stream->unsetf(ios::skipws);
01911 clt.co = psock_stream;
01912 clt.ci = psock_stream;
01913
01914 // get network address and name of client
01915 clt.socklen = sizeof(clt.sock);
01916 if (getpeername
01917 (fd, (struct sockaddr *) &clt.sock,
01918 &clt.socklen) < 0) {
01919 // Cannot get socket --- connection from stdin?
01920 sprintf(clt.client_name, "fd#%d", fd);
01921 clt.client_logname = clt.client_name;
01922 } else {
01923 // get the name of the client and store it in clt.client_name.
01924 // if the client does not have a name, use the ip-address instead
01925 // store it in nntp_posting_host as used by libnserver
01926 he = gethostbyaddr((const char *)
01927 &(clt.sock.sin_addr),
01928 sizeof(clt.sock.sin_addr),
01929 AF_INET);
01930 if (he) {
01931 strncpy(clt.client_name, he->h_name,
01932 sizeof(clt.client_name));
01933 clt.client_name[sizeof(clt.client_name) -
01934 1] = '\0';
01935 } else {
01936 strncpy(clt.client_name,
01937 inet_ntoa(clt.sock.sin_addr),
01938 sizeof(clt.client_name));
01939 clt.client_name[sizeof(clt.client_name) -
01940 1] = '\0';
01941 }
01942 strcpy(nntp_posting_host, clt.client_name);
01943
01944 // add the client's name to its logging name (clt.client_logname),
01945 // if names should be logged
01946 if (Cfg.LogStyle & Config::LogName) {
01947 clt.client_logname = clt.client_name;
01948 }
01949
01950 if (Cfg.LogStyle & Config::LogAddr) {
01951 if (clt.client_logname.length() > 0)
01952 clt.client_logname += " [";
01953 else
01954 clt.client_logname += '[';
01955 clt.client_logname +=
01956 inet_ntoa(clt.sock.sin_addr);
01957 clt.client_logname += ']';
01958 }
01959 // check whether the client is allowed access according to
01960 // libwrap
01961 #ifdef HAVE_LIBWRAP
01962 // Check the hosts_access configuration; emulate INN error message
01963 if (!hosts_ctl(PACKAGE,
01964 clt.client_name,
01965 inet_ntoa(clt.sock.sin_addr),
01966 STRING_UNKNOWN)) {
01967 slog.p(Logger::Notice) << clt.
01968 client_logname << " denied - hosts.allow\n";
01969 (*clt.
01970 co) <<
01971 "502 You have no permission to talk. Goodbye.\n";
01972 clt.co->flush ();
01973 return;
01974 }
01975 #endif
01976 }
01977 } else {
01978 cin.unsetf(ios::skipws);
01979 clt.ci = &cin;
01980 clt.co = &cout;
01981 strcpy(clt.client_name, "stdin");
01982 clt.client_logname = clt.client_name;
01983 fd = 0;
01984 }
01985
01986 #ifdef NO_STREAM_BUFFERING
01987 {
01988 streambuf *b;
01989 b = clt.ci->rdbuf();
01990 if (b)
01991 b->setbuf(0, 0);
01992 b = clt.co->rdbuf();
01993 if (b)
01994 b->setbuf(0, 0);
01995 }
01996 #endif
01997
01998 // check whether the client is allowed access according to
01999 // our own access configuration
02000 clt.access_entry =
02001 Cfg.clnts.client(clt.client_name, clt.sock.sin_addr);
02002 if (!clt.access_entry || !clt.access_entry->access_flags) {
02003 // nnrpd_deny:
02004 slog.p(Logger::Notice) << clt.
02005 client_logname << " denied\n";
02006 (*clt.
02007 co) << "502 You have no permission to talk. Goodbye.\n";
02008 clt.co->flush();
02009 return;
02010 } else {
02011 slog.p(Logger::Debug) << "nnrpd: access_entry name matched: "
02012 << clt.access_entry->hostname << "\n";
02013 }
02014
02015 slog.p(Logger::Notice) << clt.client_logname << " connect\n";
02016
02017 if (clt.access_entry->authentication.getType() != "none") {
02018 clt.auth_state = AUTH_REQUIRED;
02019 }
02020 if (clt.access_entry->authentication.getType() == "unix" &&
02021 clt.access_entry->authentication.getNrOfFields() > 1) {
02022 // authentication optional, not required
02023 clt.auth_state = AUTH_NOT_REQUIRED;
02024 }
02025 if (clt.access_entry->authentication.getType() == "file") {
02026 // authentication optional, not required
02027 clt.auth_state = AUTH_NOT_REQUIRED;
02028 }
02029 if (clt.access_entry->authentication.getType() == "pam") {
02030 // authentication optional, not required
02031 clt.auth_state = AUTH_NOT_REQUIRED;
02032 }
02033 if (clt.access_entry->authentication.getType() == "pam+file") {
02034 // authentication optional, not required
02035 clt.auth_state = AUTH_NOT_REQUIRED;
02036 }
02037
02038 // Set client command table, can be changed after successfully
02039 // authentication!
02040 set_client_command_table (clt);
02041
02042 try {
02043 clt.srvr = new CServer(Cfg.SpoolDirectory, &(Cfg.srvrs));
02044 clt.srvr->setttl(Cfg.ttl_list, Cfg.ttl_desc);
02045 }
02046 catch(SystemError & se) {
02047 slog.
02048 p(Logger::
02049 Alert) << "CServer failed, check permissions\n";
02050 se.print();
02051 (*clt.
02052 co) << "400 " PACKAGE " " VERSION
02053 ", service not available\r\n";
02054 exit(1);
02055 }
02056
02057 (*clt.
02058 co) << "200 " PACKAGE " " VERSION ", accepting NNRP commands\r\n";
02059 do {
02060 flush(*clt.co);
02061
02062 alarm (Cfg.ClientTimeout);
02063 clt.ci->getline(req, sizeof(req), '\n');
02064 alarm (0);
02065 if (clientTimeoutReached) {
02066 (*clt.co) << "400 " PACKAGE " " VERSION ", service timed out!\r\n";
02067 slog.p(Logger::Notice) << clt.client_logname << " ClientTimeout reached\n";
02068 goto client_exit;
02069 }
02070 if (Xsignal >= 0) {
02071 (*clt.co) << "400 " PACKAGE " " VERSION ", service discontinued\r\n";
02072 slog.p(Logger::Notice) << clt.client_logname << " discontinued due to Signal\n";
02073 goto client_exit;
02074 }
02075 if (clt.ci->eof()) {
02076 slog.p(Logger::Debug) << "NewsCache.cc input stream eof!\n";
02077 break;
02078 }
02079 if (!clt.ci->good()) {
02080 slog.p(Logger::Debug) << "NewsCache.cc input stream not good!\n";
02081 break;
02082 }
02083 rp = req + strlen(req);
02084 while (rp > req) {
02085 rp--;
02086 if (!isspace(*rp))
02087 break;
02088 else
02089 *rp = '\0';
02090 }
02091 strcpy(oreq, req);
02092 // FIXME: better solution?
02093 if (strncasecmp(oreq, "authinfo", 8))
02094 slog.p(Logger::Info) << clt.
02095 client_logname << " " << oreq << "\n";
02096 else
02097 slog.p(Logger::Info) << clt.
02098 client_logname << " authinfo\n";
02099
02100 // Split command into arguments
02101 for (rp = req, argc = 0; *rp && argc < 256; rp++) {
02102 if (isspace(*rp)) {
02103 *rp = '\0';
02104 } else {
02105 if (rp == req || *(rp - 1) == '\0')
02106 argv[argc++] = rp;
02107 if (argc == 1)
02108 *rp = tolower(*rp);
02109 }
02110 }
02111 if (!argc)
02112 continue;
02113 if (argc == 256) {
02114 (*clt.co) << "500 Line too long\r\n";
02115 continue;
02116 }
02117 // Call function for command
02118 cmd = argv[0];
02119 if (clt.auth_state == AUTH_REQUIRED &&
02120 strcasecmp(cmd, "authinfo") != 0 &&
02121 strcasecmp(cmd, "quit") != 0 &&
02122 strcasecmp(cmd, "help") != 0) {
02123 (*clt.
02124 co) << "480 Authentication required (" << cmd <<
02125 ")\r\n";
02126 continue;
02127 }
02128
02129 cmdp = clt.client_command_map.find(argv[0]);
02130 if (cmdp == clt.client_command_map.end() || !cmdp->second->func) {
02131 slog.p(Logger::Notice) << clt.client_logname
02132 << " unrecognized " << oreq << "\n";
02133 (*clt.co) << "500 What?\r\n";
02134 continue;
02135 }
02136
02137 errc = cmdp->second->func(&clt, argc, argv);
02138 if (!(Cfg.LogStyle & Config::LogINN)) {
02139 if (errc < 0) {
02140 if (strncasecmp(oreq, "authinfo", 8))
02141 slog.p(Logger::Notice) << clt.
02142 client_logname << " failed " << oreq <<
02143 "\n";
02144 else
02145 slog.p(Logger::Notice) << clt.
02146 client_logname << " failed authinfo for user " <<
02147 clt.auth_user << "\n";
02148 }
02149 if (clt.auth_failures >= clt.auth_max_failures) {
02150
02151 (*clt. co) << "400 " PACKAGE " " VERSION
02152 ", service discontinued (max passwords retries)\r\n";
02153 goto client_exit;
02154 }
02155 }
02156 } while (errc == 0 || errc == -1);
02157
02158 client_exit:
02159 if (clt.stat_artingrp) {
02160 slog.p(Logger::Notice) << clt.client_logname
02161 << " group " << clt.groupname
02162 << " " << clt.stat_artingrp << "\n";
02163 clt.stat_artingrp = 0;
02164 }
02165 slog.p(Logger::Notice) << clt.client_logname
02166 << " exit articles " << clt.stat_articles
02167 << " groups " << clt.stat_groups << "\n";
02168 clt.co->flush();
02169 delete clt.srvr;
02170 }
|
|
|
Definition at line 2172 of file NewsCache.cc. References Config::CachePort, Cfg, cmnd, Logger::Error, fillHostStruct(), Config::Groupname, Config::ListenTo, Config::MaxConnections, Config::NiceServer, nnrpd(), nntp_connections, Logger::p(), Config::PidFile, Logger::print(), setugid(), slog, SOCKLEN_TYPE, Config::Username, and Xsignal. Referenced by main().
02173 {
02174 int sock;
02175 struct sockaddr_in nproxy;
02176 struct servent *cport;
02177
02178 struct sockaddr_in clt_sa;
02179 SOCKLEN_TYPE clt_salen;
02180
02181 int clt_fd;
02182 int clt_pid = 0;
02183 int nice;
02184
02185 slog.p(Logger::Notice) << "NewsCache Server Start\n";
02186
02187 /* set nice value for master server */
02188 #ifdef HAVE_SETPRIORITY
02189 errno = 0;
02190 nice = Cfg.NiceServer;
02191 nice += getpriority(PRIO_PROCESS, 0);
02192 if (nice == -1 && errno != 0) {
02193 slog.
02194 p(Logger::
02195 Error) << "getpriority failed: " << strerror(errno)
02196 << "\n";
02197 } else {
02198 if (setpriority(PRIO_PROCESS, 0, nice) == -1)
02199 slog.
02200 p(Logger::
02201 Error) << "setpriority failed: " <<
02202 strerror(errno) << "\n";
02203 }
02204 #endif
02205
02206 /* nobody is connecting to NewsCache currently */
02207 nntp_connections = 0;
02208
02209 { /* create socket and set some socket options */
02210 int one = 1;
02211 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
02212 slog.
02213 p(Logger::
02214 Error) << "socket failed: " <<
02215 strerror(errno) << "\n";
02216 exit(1);
02217 }
02218
02219 if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
02220 (char *) &one, sizeof(int)) < 0) {
02221 slog.
02222 p(Logger::
02223 Error) << "setsockopt failed: " <<
02224 strerror(errno) << "\n";
02225 }
02226
02227 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
02228 (char *) &one, sizeof(int)) < 0) {
02229 slog.
02230 p(Logger::
02231 Error) << "setsockopt failed: " <<
02232 strerror(errno) << "\n";
02233 }
02234
02235 /* fill the sockaddr with the port we should listen too */
02236 if (Cfg.CachePort[0] != '\0') {
02237 // old variant
02238 const char *cp = Cfg.CachePort;
02239 nproxy.sin_family = AF_INET;
02240 nproxy.sin_addr.s_addr = INADDR_ANY;
02241 if (cp[0] != '#') {
02242 if ((cport =
02243 getservbyname(cp, "tcp")) == NULL) {
02244 slog.
02245 p(Logger::
02246 Error) << cmnd <<
02247 ": Can't resolve service " <<
02248 cp << "/tcp\n";
02249 exit(1);
02250 }
02251 nproxy.sin_port = cport->s_port;
02252 } else {
02253 nproxy.sin_port = htons(atoi(cp + 1));
02254 }
02255 } else if (fillHostStruct(&nproxy, Cfg.ListenTo) == -1) {
02256 slog.
02257 p(Logger::
02258 Error) << cmnd <<
02259 ": Can't resolve parameter ListenTo: " << Cfg.
02260 ListenTo << "\n";
02261 exit(1);
02262 }
02263 } /* end create socket and set some socket options */
02264
02265 if (bind(sock, (struct sockaddr *) &nproxy, sizeof(nproxy)) < 0) {
02266 slog.
02267 p(Logger::
02268 Error) << "can't bind socket: " << strerror(errno) <<
02269 "\n";
02270 exit(1);
02271 }
02272
02273 { /* store pid in Cfg.PidFile */
02274 ofstream pid(Cfg.PidFile);
02275 pid << getpid() << endl;
02276 if (!pid.good()) {
02277 slog.
02278 p(Logger::Warning) << "cannot open pid file\n";
02279 }
02280 }
02281
02282 setugid(Cfg.Username, Cfg.Groupname);
02283 listen(sock, 4);
02284 for (;;) {
02285 /* Accept connection */
02286 clt_salen = sizeof(clt_sa);
02287 do {
02288 errno = 0;
02289 clt_fd =
02290 accept(sock, (struct sockaddr *) &clt_sa,
02291 &clt_salen);
02292 if (Xsignal >= 0) {
02293 close(sock);
02294 exit(0);
02295 }
02296 } while (errno == EINTR);
02297 if (clt_fd < 0) {
02298 slog.
02299 p(Logger::
02300 Warning) << "accept failed: " <<
02301 strerror(errno) << "\n";
02302 continue;
02303 }
02304 #ifdef CONF_MultiClient
02305 if (nntp_connections >= Cfg.MaxConnections
02306 || (clt_pid = fork()) < 0) {
02307 if (clt_pid < 0) {
02308 slog.
02309 p(Logger::
02310 Error) << "fork failed: " <<
02311 strerror(errno) << "\n";
02312 }
02313 write(clt_fd, "400 too many users\r\n", 21);
02314 close(clt_fd);
02315 } else {
02316 // success
02317 if (clt_pid == 0) {
02318 // child
02319 int one = 1;
02320 close(sock);
02321 if (setsockopt
02322 (clt_fd, SOL_SOCKET, SO_KEEPALIVE,
02323 (char *) &one, sizeof(int)) < 0) {
02324 slog.
02325 p(Logger::
02326 Error) <<
02327 "client setsockopt failed: " <<
02328 strerror(errno) << "\n";
02329 }
02330 try {
02331 nnrpd(clt_fd);
02332 } catch (sockerr e) {
02333 slog.p(Logger::Error) << "nnrpd caught "
02334 << "sockbuf " << e.operation ()
02335 << e.serrno ()
02336 << " " << e.errstr () << "\n";
02337 } catch (UsageError e) {
02338 slog.p(Logger::Error) << "nnrpd caught "
02339 << "UsageError ";
02340 e.print();
02341 } catch (NotAllowedError e) {
02342 slog.p(Logger::Error) << "nnrpd caught "
02343 << "NotAllowdError ";
02344 e.print();
02345 } catch (NoSuchArticleError e) {
02346 slog.p(Logger::Error) << "nnrpd caught "
02347 << "NoSuchArticleError ";
02348 e.print();
02349 } catch (DuplicateArticleError e) {
02350 slog.p(Logger::Error) << "nnrpd caught "
02351 << "DuplicateArticleError ";
02352 e.print();
02353 } catch (NoSuchGroupError e) {
02354 slog.p(Logger::Error) << "nnrpd caught "
02355 << "NoSuchGroupError ";
02356 e.print();
02357 } catch (NoNewsServerError e) {
02358 slog.p(Logger::Error) << "nnrpd caught "
02359 << "NoNewsServerError ";
02360 e.print();
02361 } catch (NoSuchFieldError e) {
02362 slog.p(Logger::Error) << "nnrpd caught "
02363 << "NoSuchFieldError ";
02364 e.print();
02365 } catch (NSError e) {
02366 slog.p(Logger::Error) << "nnrpd caught "
02367 << "NSError ";
02368 e.print();
02369 } catch (AssertionError e) {
02370 slog.p(Logger::Error) << "nnrpd caught "
02371 << "AssertionError ";
02372 e.print();
02373 } catch (IOError e) {
02374 slog.p(Logger::Error) << "nnrpd caught "
02375 << "IOError ";
02376 e.print();
02377 } catch (SystemError e) {
02378 slog.p(Logger::Error) << "nnrpd caught "
02379 << "SystemError ";
02380 e.print();
02381 } catch (Error e) {
02382 slog.p(Logger::Error) << "nnrpd caught "
02383 << "Error ";
02384 e.print();
02385 } catch ( ... ) {
02386 slog.p(Logger::Error) << "nnrpd caught "
02387 << "unknown!!" << "\n";
02388 }
02389 close(clt_fd);
02390 exit(0);
02391 }
02392 //Parent
02393 close(clt_fd);
02394 nntp_connections++;
02395 }
02396 #else
02397 nnrpd(clt_fd);
02398 close(clt_fd);
02399 #endif
02400 }
02401
02402 close(sock);
02403 }
|
|
||||||||||||||||
|
Definition at line 961 of file NewsCache.cc. References CServer::article(), ASSERT2, ClientData::co, Newsgroup::freearticle(), Newsgroup::getarticle(), CServer::getgroup(), ClientData::groupname, ClientData::grp, ClientData::nbr, nsh_particle(), Logger::print(), slog, ClientData::srvr, ClientData::stat_articles, and ClientData::stat_artingrp.
00962 {
00963 if (argc > 2)
00964 goto ns_article_error;
00965
00966 // retrieve article|body|head by number?
00967 if (argc == 1 || isdigit(argv[1][0])) {
00968 if (clt->groupname[0] == '\0') {
00969 (*clt->
00970 co) << "412 no newsgroup has been selected\r\n";
00971 return -1;
00972 }
00973 try {
00974 if (!clt->grp)
00975 clt->grp =
00976 clt->srvr->getgroup(clt->groupname);
00977 }
00978 catch(NoSuchGroupError & nsge) {
00979 (*clt->co) << "411 no such newsgroup\r\n";
00980 return -1;
00981 }
00982 catch(Error & e) {
00983 (*clt->co) << "412 operation failed\r\n";
00984 return -1;
00985 }
00986
00987 if (argc == 1 && clt->nbr < 0) {
00988 (*clt->
00989 co) <<
00990 "420 no current article has been selected\r\n";
00991 return -1;
00992 }
00993
00994 int nbr = (argc == 2) ? atoi(argv[1]) : clt->nbr;
00995
00996 ASSERT2(clt->grp->testdb());
00997 Article *a;
00998
00999 if ((a = clt->grp->getarticle(nbr)) == NULL) {
01000 (*clt->
01001 co) <<
01002 "423 no such article number in this group\r\n";
01003 return -1;
01004 }
01005 nsh_particle(clt, argv[0], nbr, a);
01006 clt->grp->freearticle(a);
01007 clt->nbr = nbr;
01008 clt->stat_artingrp++;
01009 clt->stat_articles++;
01010 return 0;
01011 }
01012 // retrieve article|body|head by id?
01013 if (argv[1][0] == '<') {
01014 try {
01015 Article a;
01016 clt->srvr->article(argv[1], &a);
01017 nsh_particle(clt, argv[0], 0, &a);
01018 }
01019 catch(NoSuchArticleError nsae) {
01020 (*clt->co) << "430 no such article id found\r\n";
01021 return -1;
01022 }
01023 catch(ResponseError e) {
01024 // error
01025 (*clt->co) << e._got << "\r\n";
01026 return -1;
01027 }
01028 catch(Error e) {
01029 // error
01030 (*clt->co) << "520 ???\r\n";
01031 slog.
01032 p(Logger::
01033 Error) <<
01034 "Internal Error? Please report to h.straub@aon.at\r\n";
01035 e.print();
01036 return -1;
01037 }
01038 clt->stat_artingrp++;
01039 clt->stat_articles++;
01040 return 0;
01041 }
01042 // error
01043 ns_article_error:
01044 switch (argv[0][0]) {
01045 case 'a':
01046 (*clt->co) << "501 Syntax: article [nbr|<id>]\r\n";
01047 return -1;
01048 case 'h':
01049 (*clt->co) << "501 Syntax: head [nbr|<id>]\r\n";
01050 return -1;
01051 case 'b':
01052 (*clt->co) << "501 Syntax: body [nbr|<id>]\r\n";
01053 return -1;
01054 }
01055 return -1;
01056 }
|
|
||||||||||||||||
|
Definition at line 903 of file NewsCache.cc. References ClientData::auth_failure_sleep_time, ClientData::auth_failures, AUTH_OK, ClientData::auth_pass, ClientData::auth_state, ClientData::auth_user, check_authentication(), ClientData::co, INCORRECT_ORDER_SEQUENCE, OK_SEQUENCE, PASS_NEEDED_SEQUENCE, REJECT_SEQUENCE, and set_client_command_table().
00904 {
00905 // check arguments
00906 if (argc != 3)
00907 goto ns_authinfo_error;
00908 if (strlen(argv[2]) > sizeof(clt->auth_user) - 1) {
00909 (*clt->co) << REJECT_SEQUENCE " argument too long\r\n";
00910 return -1;
00911 }
00912
00913 if (!strcasecmp(argv[1], "user")) {
00914 strcpy(clt->auth_user, argv[2]);
00915 (*clt->co) << PASS_NEEDED_SEQUENCE " password please\r\n";
00916 return 0;
00917 }
00918
00919 if (!strcasecmp(argv[1], "pass")) {
00920 if (clt->auth_user[0] == '\0') {
00921 (*clt->
00922 co) << INCORRECT_ORDER_SEQUENCE
00923 " issue authinfo user first\r\n";
00924 return -1;
00925 }
00926 strcpy(clt->auth_pass, argv[2]);
00927
00928 if (check_authentication(clt) < 0) {
00929 sleep (clt->auth_failure_sleep_time*
00930 (++clt->auth_failures));
00931 (*clt->
00932 co) << REJECT_SEQUENCE << " Bad authinfo.\r\n";
00933 return -1;
00934 }
00935
00936 (*clt->co) << OK_SEQUENCE << " OK.\r\n";
00937 clt->auth_state = AUTH_OK;
00938 set_client_command_table(*clt);
00939
00940 return 0;
00941 }
00942 // error
00943 ns_authinfo_error:
00944 if (argc > 1) {
00945 switch (tolower(argv[1][0])) {
00946 case 'u':
00947 (*clt->
00948 co) << "501 Syntax: authinfo user username\r\n";
00949 return -1;
00950 case 'p':
00951 (*clt->
00952 co) << "501 Syntax: authinfo pass password\r\n";
00953 return -1;
00954 }
00955 }
00956 (*clt->
00957 co) << "501 Syntax: authinfo [user username|pass password]\r\n";
00958 return -1;
00959 }
|
|
||||||||||||||||
|
Definition at line 1152 of file NewsCache.cc. References ClientData::co, Logger::Error, Logger::p(), and slog.
01153 {
01154 struct tm *ltm;
01155 time_t conv;
01156 char buf[256];
01157
01158 if (argc != 1) {
01159 (*clt->co) << "501 Syntax: group Newsgroup\r\n";
01160 return -1;
01161 }
01162 time(&conv);
01163 if ((ltm = gmtime(&conv)) == NULL) {
01164 (*clt->co) << "500 gmtime failed\r\n";
01165 slog.p(Logger::Error) << "ns_date() gmtime failed\n";
01166 return -1;
01167 }
01168 sprintf(buf, "111 %04d%02d%02d%02d%02d%02d\r\n",
01169 1900 + ltm->tm_year, ltm->tm_mon + 1, ltm->tm_mday,
01170 ltm->tm_hour, ltm->tm_min, ltm->tm_sec);
01171 (*clt->co) << buf;
01172
01173 return 0;
01174 }
|
|
||||||||||||||||
|
Definition at line 1181 of file NewsCache.cc. References ClientData::access_entry, ClientData::co, GroupInfo::first(), GroupInfo::last(), NewsgroupFilter::matches(), GroupInfo::n(), GroupInfo::name(), Logger::p(), AccessEntry::read, selectgroup(), and slog.
01182 {
01183 if (argc != 2) {
01184 (*clt->co) << "501 Syntax: group Newsgroup\r\n";
01185 return -1;
01186 }
01187
01188 if (clt->access_entry->read.matches(argv[1]) <= 0) {
01189 (*clt->co) << "480 authentication required\r\n";
01190 return 0;
01191 }
01192
01193 GroupInfo *gi;
01194 if ((gi = selectgroup(clt, argv[1])) == NULL) {
01195 (*clt->co) << "411 no such news group\r\n";
01196 return -1;
01197 }
01198
01199 (*clt->co) << "211 "
01200 << gi->n() << " "
01201 << gi->first() << " "
01202 << gi->last() << " " << gi->name() << " group selected\r\n";
01203
01204 slog.p(Logger::Info) << "groupsize [" << gi->first() << ","
01205 << gi->last() << "]\n";
01206
01207 return 0;
01208 }
|
|
||||||||||||||||
|
Definition at line 1214 of file NewsCache.cc. References Config::Admin, Cfg, ClientData::client_command_map, ClientData::co, Logger::p(), slog, and VERB.
01215 {
01216 map < string, nnrp_command_t * >::iterator begin =
01217 clt->client_command_map.begin(), end = clt->client_command_map.end();
01218
01219 VERB(slog.p(Logger::Debug) << "NewsCache::ns_help:\n");
01220 (*clt->co) << "100 Legal commands\r\n";
01221 while (begin != end) {
01222 if (begin->second->func) {
01223 (*clt->co) << " " << begin->
01224 first << " " << begin->second->desc << "\r\n";
01225 }
01226 ++begin;
01227 }
01228 (*clt->co) << "Report problems to " << Cfg.Admin << "\r\n.\r\n";
01229 return 0;
01230 }
|
|
||||||||||||||||
|
Definition at line 1233 of file NewsCache.cc. References ClientData::co, OverviewFmt::getfield(), CServer::getgroup(), Newsgroup::getover(), Newsgroup::getsize(), ClientData::groupname, ClientData::grp, ClientData::nbr, CServer::overviewfmt(), and ClientData::srvr.
01234 {
01235 if (argc != 1) {
01236 switch (argv[0][0]) {
01237 case 'l':
01238 (*clt->co) << "501 Syntax: last\r\n";
01239 return -1;
01240 case 'n':
01241 (*clt->co) << "501 Syntax: next\r\n";
01242 return -1;
01243 }
01244 }
01245 if (clt->groupname[0] == '\0') {
01246 (*clt->co) << "412 No newsgroup currently selected\r\n";
01247 return -1;
01248 }
01249 if (clt->nbr < 0) {
01250 (*clt->
01251 co) << "420 no current article has been selected\r\n";
01252 return -1;
01253 }
01254 try {
01255 if (!clt->grp)
01256 clt->grp = clt->srvr->getgroup(clt->groupname);
01257 }
01258 catch(NoSuchGroupError & nsge) {
01259 (*clt->co) << "411 no such news group\r\n";
01260 return -1;
01261 }
01262 catch(Error & e) {
01263 (*clt->co) << "412 operation failed\r\n";
01264 return -1;
01265 }
01266
01267 unsigned int f, i = clt->nbr, l;
01268 const char *o;
01269 string aid;
01270 OverviewFmt *ofmt = clt->srvr->overviewfmt();
01271 clt->grp->getsize(&f, &l);
01272 switch (argv[0][0]) {
01273 case 'l':
01274 for (;;) {
01275 i--;
01276 if (i < f) {
01277 (*clt->
01278 co) << "422 No previous to retrieve\r\n";
01279 return -1;
01280 }
01281 o = clt->grp->getover(i);
01282 if (o[0]) {
01283 aid = ofmt->getfield(o, "Message-ID:", 0);
01284 break;
01285 }
01286 }
01287 break;
01288 case 'n':
01289 for (;;) {
01290 ++i;
01291 if (i > l) {
01292 (*clt->
01293 co) << "421 No next to retrieve\r\n";
01294 return -1;
01295 }
01296 o = clt->grp->getover(i);
01297 if (o[0]) {
01298 aid = ofmt->getfield(o, "Message-ID:", 0);
01299 break;
01300 }
01301 }
01302 }
01303 clt->nbr = i;
01304
01305 (*clt->co) << "223 " << clt->nbr << " " << aid
01306 << " article retrieved - request text separately\r\n";
01307 return 0;
01308 }
|
|
||||||||||||||||
|
Definition at line 1379 of file NewsCache.cc. References ClientData::access_entry, CServer::active(), ActiveDB::begin(), Cfg, ClientData::co, ActiveDB::end(), nlreadline(), CServer::overviewfmt(), NewsgroupFilter::setWildmat(), Config::SpoolDirectory, and ClientData::srvr.
01380 {
01381 if (argc <= 3) {
01382 if (argc == 1 || strcasecmp(argv[1], "active") == 0) {
01383 ActiveDB *active;
01384 active = clt->srvr->active();
01385 (*clt->
01386 co) <<
01387 "215 List of newsgroups (Group High Low Flags) follows\r\n";
01388 try {
01389 NewsgroupFilter filter(clt->access_entry->
01390 list);
01391 if (argc == 3)
01392 filter.setWildmat(argv[2]);
01393 for_each(active->begin(),
01394 active->end(),
01395 active_filter_group <
01396 print_list_active > (*clt->co,
01397 filter));
01398 }
01399 catch(SystemError & se) {
01400 return -2;
01401 }
01402 (*clt->co) << ".\r\n";
01403 return 0;
01404 } else if (strcasecmp(argv[1], "active.times") == 0) {
01405 ActiveDB *active;
01406 active = clt->srvr->active();
01407 (*clt->co) << "215 information follows\r\n";
01408 try {
01409 NewsgroupFilter filter(clt->access_entry->
01410 list);
01411 if (argc == 3)
01412 filter &= NewsgroupFilter(argv[2]);
01413
01414 for_each(active->begin(),
01415 active->end(),
01416 active_filter_group <
01417 print_list_active_times >
01418 (*clt->co, filter));
01419 }
01420 catch(SystemError & se) {
01421 return -2;
01422 }
01423 (*clt->co) << ".\r\n";
01424 return 0;
01425 } else if (argc == 2) {
01426 if (strcasecmp(argv[1], "extensions") == 0) {
01427 (*clt->
01428 co) << "202 extensions supported\r\n";
01429 (*clt->co) << " over\r\n";
01430 (*clt->co) << " authinfo user\r\n";
01431 (*clt->co) << ".\r\n";
01432 return 0;
01433 } else if (strcasecmp(argv[1], "newsgroups") == 0) {
01434 char buf[MAXPATHLEN];
01435 string strg;
01436 sprintf(buf, "%s/.newsgroups",
01437 Cfg.SpoolDirectory);
01438 ifstream ifs(buf);
01439 (*clt->
01440 co) << "215 Description follows\r\n";
01441 for (;;) {
01442 nlreadline(ifs, strg);
01443 if (!ifs.good())
01444 break;
01445 (*clt->co) << strg;
01446 }
01447 (*clt->co) << ".\r\n";
01448 return 0;
01449 } else if (strcasecmp(argv[1], "overview.fmt") ==
01450 0) {
01451 (*clt->
01452 co) <<
01453 "215 Order of fields in overview database\r\n"
01454 << *(clt->srvr->overviewfmt()) << ".\r\n";
01455 return 0;
01456 }
01457 }
01458 }
01459
01460 (*clt->
01461 co) <<
01462 "501 Syntax: list [active [wildmat]|active.times [time]|extensions|newsgroups|overview.fmt]\r\n";
01463 return -1;
01464 }
|
|
||||||||||||||||
|
Definition at line 1470 of file NewsCache.cc. References ClientData::access_entry, ClientData::co, CServer::getgroup(), ClientData::groupname, ClientData::grp, NewsgroupFilter::matches(), Newsgroup::printlistgroup(), AccessEntry::read, selectgroup(), and ClientData::srvr.
01471 {
01472 if (argc > 2) {
01473 (*clt->co) << "501 Syntax: listgroup [Newsgroup]\r\n";
01474 return -1;
01475 }
01476 if (argc == 1 && clt->groupname[0] == '\0') {
01477 (*clt->co) << "412 Not currently in a newsgroup\r\n";
01478 return -1;
01479 }
01480 if (argc == 2) {
01481 if (selectgroup(clt, argv[1]) == NULL) {
01482 (*clt->co) << "411 no such news group\r\n";
01483 return -1;
01484 }
01485 if (clt->access_entry->read.matches(argv[1]) <= 0) {
01486 (*clt->co) << "480 authentication required\r\n";
01487 return 0;
01488 }
01489 }
01490
01491 try {
01492 if (!clt->grp)
01493 clt->grp = clt->srvr->getgroup(clt->groupname);
01494 }
01495 catch(NoSuchGroupError & nsge) {
01496 (*clt->co) << "411 no such news group\r\n";
01497 return -1;
01498 }
01499 catch(Error & e) {
01500 (*clt->co) << "412 operation failed\r\n";
01501 e.print();
01502 return -1;
01503 }
01504
01505 (*clt->co) << "211 list of article numbers follow\r\n";
01506 clt->grp->printlistgroup(*clt->co);
01507 (*clt->co) << ".\r\n";
01508 return 0;
01509 }
|
|
||||||||||||||||
|
Definition at line 1511 of file NewsCache.cc. References ClientData::co, and PACKAGE.
01512 {
01513 if (argc != 2 ||
01514 (strcasecmp(argv[1], "reader") != 0 &&
01515 strcasecmp(argv[1], "query") != 0)) {
01516 (*clt->co) << "501 Syntax: mode (reader|query)\r\n";
01517 return -1;
01518 }
01519 (*clt->
01520 co) << "200 " PACKAGE " " VERSION ", accepting NNRP commands\r\n";
01521 return 0;
01522 }
|
|
||||||||||||||||
|
Definition at line 1528 of file NewsCache.cc. References ClientData::access_entry, CServer::active(), ActiveDB::begin(), ClientData::co, DD2INT, ActiveDB::end(), and ClientData::srvr.
01529 {
01530 if (argc < 3 || argc > 5) {
01531 ns_newgroups_error:
01532 (*clt->
01533 co) <<
01534 "501 Syntax: NEWGROUPS date time [GMT] [<wildmat>]\r\n";
01535 return -1;
01536 }
01537
01538 int i, y4, is_gmt = 0;
01539 struct tm ltm;
01540 time_t lt;
01541 char *p;
01542
01543 // check first two arguments, y4 indicates whether year has 4 digits
01544 for (i = 0; isdigit(argv[2][i]); i++);
01545 if (i != 6 || argv[2][i])
01546 goto ns_newgroups_error;
01547 for (y4 = 0; isdigit(argv[1][y4]); y4++);
01548 if ((y4 != 8 && y4 != 6) || argv[1][y4])
01549 goto ns_newgroups_error;
01550 y4 -= 4;
01551
01552 // check whether time/date is specified in GMT
01553 if (argc >= 4) {
01554 if (strcasecmp(argv[3], "gmt") != 0 &&
01555 strcasecmp(argv[3], "utc") != 0) {
01556 goto ns_newgroups_error;
01557 }
01558 is_gmt = 1;
01559 }
01560 // fill in ltm with supplied values
01561 p = argv[1];
01562 if (y4 > 2) {
01563 i = DD2INT(p);
01564 p += 2;
01565 ltm.tm_year = i * 100 + DD2INT(p) - 1900;
01566 p += 2;
01567 } else {
01568 struct tm *now;
01569 int yr;
01570
01571 // draft-ietf-nntpext-base-04.txt:
01572 // If the first two digits of the year are not specified,
01573 // the year is to be taken from the current century if YY
01574 // is smaller than or equal to the current year,
01575 // otherwise the year is from the previous century.
01576 time(<);
01577 now = is_gmt ? gmtime(<) : localtime(<);
01578 yr = now->tm_year % 100;
01579
01580 ltm.tm_year = DD2INT(p);
01581 p += 2;
01582 if (ltm.tm_year > yr)
01583 ltm.tm_year += now->tm_year - yr - 100;
01584 else
01585 ltm.tm_year += now->tm_year - yr;
01586 }
01587 ltm.tm_mon = DD2INT(p) - 1;
01588 p += 2; // tm_mon has a range of 0(Jan)--11(Dec)!!!
01589 ltm.tm_mday = DD2INT(p);
01590
01591 p = argv[2];
01592 ltm.tm_hour = DD2INT(p);
01593 p += 2;
01594 ltm.tm_min = DD2INT(p);
01595 p += 2;
01596 ltm.tm_sec = DD2INT(p);
01597
01598 #ifdef HAVE_TZNAME
01599 ltm.tm_isdst = daylight;
01600
01601 lt = mktime(<m);
01602 if (lt == -1)
01603 goto ns_newgroups_error;
01604
01605 // correct timezone if time/date is given in GMT
01606 if (is_gmt) {
01607 lt -= timezone;
01608 }
01609 #else
01610 struct tm *plt;
01611
01612 time(<);
01613 plt = localtime(<);
01614
01615 ltm.tm_isdst = plt->tm_isdst;
01616 ltm.tm_gmtoff = plt->tm_gmtoff;
01617
01618 lt = mktime(<m);
01619 if (lt == -1)
01620 goto ns_newgroups_error;
01621 #endif
01622
01623 ActiveDB *active;
01624 try {
01625 active = clt->srvr->active();
01626 }
01627 catch(Error & e) {
01628 (*clt->co) << "410 operation failed\r\n";
01629 return -1;
01630 }
01631 (*clt->co) << "231 list of new groups follows " << lt << "\r\n";
01632 try {
01633 NewsgroupFilter filter();
01634
01635 for_each(active->begin(),
01636 active->end(),
01637 active_filter_group_time <
01638 print_list_active_times > (*clt->co,
01639 clt->access_entry->
01640 list, lt));
01641 }
01642 catch(SystemError & se) {
01643 return -2;
01644 }
01645 (*clt->co) << ".\r\n";
01646 return 0;
01647 }
|
|
||||||||||||||||
|
Definition at line 1651 of file NewsCache.cc. References ClientData::access_entry, ClientData::ci, ClientData::co, Article::getfield(), newsgroups, Logger::p(), CServer::post(), AccessEntry::postTo, Article::read(), slog, ClientData::srvr, and VERB.
01652 {
01653 VERB(slog.p(Logger::Debug) << "NewsCache::ns_post\n");
01654 if (argc != 1) {
01655 (*clt->co) << "501 Syntax: post\r\n";
01656 return -1;
01657 }
01658
01659 Article art;
01660
01661 try {
01662 // request article to be posted
01663 (*clt->co) << "340 send article to be posted.\r\n";
01664 clt->co->flush();
01665 art.read(*clt->ci);
01666
01667 // check whether client is authorized to post this article.
01668 string newsgroups = art.getfield("newsgroups:");
01669 unsigned int i1 = 0, i2 = newsgroups.find(",");
01670 for (;;) {
01671 string group = newsgroups.substr(i1, i2);
01672 if (clt->access_entry->postTo.
01673 matches(group.c_str()) <= 0) {
01674 (*clt->
01675 co) << "480 authentication required\r\n";
01676 return 0;
01677 }
01678 if (i2 == string::npos)
01679 break;
01680 i1 = i2 + 1;
01681 i2 = newsgroups.find(",", i1);
01682 }
01683 }
01684 catch(InvalidArticleError & iae) {
01685 (*clt->co) << "441 invalid article\r\n";
01686 return -1;
01687 }
01688 catch(NoSuchFieldError & nsfe) {
01689 (*clt->co) << "441 invalid article\r\n";
01690 return -1;
01691 }
01692
01693 try {
01694 // client is authorized to post the article
01695 clt->srvr->post(&art);
01696 (*clt->co) << "240 Article posted\r\n";
01697 return 0;
01698 }
01699 catch(InvalidArticleError & iae) {
01700 (*clt->co) << "441 invalid article\r\n";
01701 return -1;
01702 }
01703 catch(NotAllowedError & nae) {
01704 (*clt->co) << "440 posting not allowed\r\n";
01705 return -1;
01706 }
01707 catch(Error & e) {
01708 (*clt->co) << "449 operation failed\r\n";
01709 return -1;
01710 }
01711 }
|
|
||||||||||||||||
|
Definition at line 1713 of file NewsCache.cc. References ClientData::co.
01714 {
01715 (*clt->co) << "205 Good bye\r\n";
01716 return 1;
01717 }
|
|
||||||||||||||||
|
Definition at line 1058 of file NewsCache.cc. References CServer::article(), ASSERT2, ClientData::co, Article::getfield(), OverviewFmt::getfield(), CServer::getgroup(), Newsgroup::getover(), ClientData::groupname, ClientData::grp, ClientData::nbr, CServer::overviewfmt(), Logger::print(), slog, and ClientData::srvr.
01059 {
01060 /* Offene Punkte:
01061 ** stat auf nummer die nicht vorhanden ist, ergibt:
01062 ** 223 351 status
01063 ** das ist falsch, sollte sein:
01064 ** 423 No Such Article In Group
01065 **
01066 */
01067 if (argc > 2)
01068 goto ns_stat_error;
01069
01070 // stat by number?
01071 if (argc == 1 || isdigit(argv[1][0])) {
01072 // fetch article by number
01073 if (clt->groupname[0] == '\0') {
01074 (*clt->
01075 co) << "412 no newsgroup has been selected\r\n";
01076 return -1;
01077 }
01078 try {
01079 if (!clt->grp)
01080 clt->grp =
01081 clt->srvr->getgroup(clt->groupname);
01082 }
01083 catch(NoSuchGroupError & nsge) {
01084 (*clt->co) << "411 no such newsgroup\r\n";
01085 return -1;
01086 }
01087 catch(Error & e) {
01088 (*clt->co) << "412 operation failed\r\n";
01089 return -1;
01090 }
01091
01092 if (argc == 1 && clt->nbr < 0) {
01093 (*clt->
01094 co) <<
01095 "420 no current article has been selected\r\n";
01096 return -1;
01097 }
01098
01099 int nbr = (argc == 2) ? atoi(argv[1]) : clt->nbr;
01100
01101 ASSERT2(clt->grp->testdb());
01102 OverviewFmt *of = clt->srvr->overviewfmt();
01103 const char *o = clt->grp->getover(nbr);
01104 (*clt->co) << "223 " << nbr << " " << of->getfield(o,
01105 "Message-ID:",
01106 0)
01107 << " status \r\n";
01108 return 0;
01109 }
01110 // stat by id?
01111 if (argv[1][0] == '<') {
01112 //(*clt->co) << "223 0 " << argv[1] << " status\r\n";
01113 Article a;
01114 try {
01115 clt->srvr->article(argv[1], &a);
01116 //nsh_particle(clt, argv[0], 0, &a);
01117 }
01118 catch(NoSuchArticleError nsae) {
01119 (*clt->co) << "430 no such article id found\r\n";
01120 return -1;
01121 }
01122 catch(ResponseError e) {
01123 // error
01124 (*clt->co) << e._got << "\r\n";
01125 return -1;
01126 }
01127 catch(Error e) {
01128 // error
01129 (*clt->co) << "520 ???\r\n";
01130 slog.
01131 p(Logger::
01132 Error) <<
01133 "Internal Error? Please report to h.straub@aon.at\r\n";
01134 e.print();
01135 return -1;
01136 }
01137 string mid = a.getfield("Message-ID:");
01138 (*clt->co) << "223 0 " << mid << " status\r\n";
01139 return 0;
01140 }
01141 // error
01142 ns_stat_error:
01143 (*clt->co) << "501 Syntax: stat [nbr|<id>]\r\n";
01144 return -1;
01145 }
|
|
||||||||||||||||
|
Definition at line 1797 of file NewsCache.cc. References ClientData::access_entry, Cfg, ClientData::co, and Config::printParameters().
01798 {
01799 if (argc == 3) {
01800 if (strcmp(argv[1], "dump") == 0) {
01801 if (strcmp(argv[2], "authorization") == 0) {
01802 (*clt->
01803 co) <<
01804 "xxx authorization data follows\r\n";
01805 (*clt->co) << *clt->access_entry << "\r\n";
01806 (*clt->co) << ".\r\n";
01807 }
01808 if (strcmp(argv[2], "configuration") == 0) {
01809 (*clt->
01810 co) <<
01811 "xxx configuration data follows\r\n";
01812 Cfg.printParameters (clt->co);
01813 (*clt->co) << ".\r\n";
01814 }
01815 }
01816 return 0;
01817 }
01818
01819 if (argc == 2) {
01820 if (strcmp(argv[1], "help") == 0) {
01821 (*clt->co) << "Valid commands:\r\n";
01822 (*clt->co) << "xdebug dump authorization:\r\n";
01823 (*clt->co) << "xdebug dump configuration:\r\n";
01824 (*clt->co) << ".\r\n";
01825 return 0;
01826 }
01827 }
01828
01829 (*clt->co) << "501 Syntax: xdebug help\r\n";
01830 return -1;
01831 }
|
|
||||||||||||||||
|
Definition at line 1719 of file NewsCache.cc. References ClientData::co.
01720 {
01721 (*clt->co) << "500 not yet supported\r\n";
01722 return -1;
01723 }
|
|
||||||||||||||||
|
Definition at line 1733 of file NewsCache.cc. References ASSERT2, ClientData::co, CServer::getgroup(), ClientData::groupname, ClientData::grp, ClientData::nbr, Newsgroup::printheaderdb(), Newsgroup::printoverdb(), and ClientData::srvr.
01734 {
01735 int i = 1, fst, lst;
01736 char *p;
01737
01738 if (clt->groupname[0] == '\0') {
01739 (*clt->co) << "412 No newsgroup currently selected\r\n";
01740 return -1;
01741 }
01742 if (strcmp(argv[0], "xhdr") == 0) {
01743 i = 2;
01744 }
01745 switch (argc - i) {
01746 case 0:
01747 fst = lst = clt->nbr;
01748 break;
01749 case 1:
01750 p = argv[i];
01751 if (isdigit(*p))
01752 fst = lst = strtol(argv[i], &p, 10);
01753 if ((*p) == '\0')
01754 break;
01755 if ((*p) == '-') {
01756 lst = UINT_MAX;
01757 p++;
01758 if (isdigit(*p))
01759 lst = strtol(p, &p, 10);
01760 if ((*p) == '\0')
01761 break;
01762 }
01763 default:
01764 (*clt->co) << "501 Syntax: xover [range]\r\n";
01765 return -1;
01766 }
01767 try {
01768 if (!clt->grp)
01769 clt->grp = clt->srvr->getgroup(clt->groupname);
01770 }
01771 catch(NoSuchGroupError & nsge) {
01772 (*clt->co) << "411 no such news group\r\n";
01773 return -1;
01774 }
01775 catch(Error & e) {
01776 e.print();
01777 (*clt->co) << "412 operation failed\r\n";
01778 return -1;
01779 }
01780
01781 ASSERT2(clt->grp->testdb());
01782 switch (i) {
01783 case 1:
01784 (*clt->co) << "224 Overview information follows\r\n";
01785 clt->grp->printoverdb(*clt->co, fst, lst);
01786 break;
01787 case 2:
01788 (*clt->
01789 co) << "221 " << p << "[" << fst << "-" << lst << "]\r\n";
01790 clt->grp->printheaderdb(*clt->co, argv[1], fst, lst);
01791 break;
01792 }
01793 (*clt->co) << ".\r\n";
01794 return 0;
01795 }
|
|
||||||||||||||||||||
|
Definition at line 867 of file NewsCache.cc. References cmnd, ClientData::co, Article::getfield(), Article::length(), Logger::p(), slog, and Article::write(). Referenced by ns_article().
00868 {
00869 string aid = a->getfield("Message-ID:");
00870
00871 switch (cmnd[0]) {
00872 case 'a':
00873 (*clt->co) << "220 " << nbr << " " << aid
00874 << " article retrieved - head and body follow\r\n";
00875 (*clt->co) << *a << ".\r\n";
00876 slog.p(Logger::Info) << "articlesize " << clt->
00877 groupname << ":" << nbr << " " << a->length() << "\n";
00878 break;
00879 case 'h':
00880 (*clt->co) << "221 " << nbr << " " << aid
00881 << " article retrieved - head follows\r\n";
00882 a->write(*clt->co, Article::Head);
00883 (*clt->co) << ".\r\n";
00884 break;
00885 case 'b':
00886 (*clt->co) << "222 " << nbr << " " << aid
00887 << " article retrieved - body follows\r\n";
00888 a->write(*clt->co, Article::Body);
00889 (*clt->co) << ".\r\n";
00890 slog.p(Logger::Info) << "articlesize " << clt->
00891 groupname << ":" << nbr << " " << a->length() << "\n";
00892 break;
00893 }
00894 }
|
|
||||||||||||
|
Definition at line 398 of file NewsCache.cc. References slog. Referenced by check_auth_file().
00399 {
00400 FILE *F;
00401 static char buf[1024];
00402 char *p;
00403 int i;
00404
00405 static char *fields[8];
00406 int fields_n = sizeof(fields) / sizeof(fields[0]);
00407
00408 if ((F = fopen(filename, "r")) == NULL) {
00409 slog.
00410 p(Logger::
00411 Error) << "cannot fopen " << filename << "\n";
00412 return NULL;
00413 }
00414
00415 while (fgets(buf, sizeof(buf), F) != NULL) {
00416 p = buf + strlen(buf) - 1;
00417 while (p > buf && isspace(*p))
00418 *p-- = '\0';
00419 p = buf;
00420 while (isspace(*p))
00421 p++;
00422 if (*p == '#' || *p == '\0')
00423 continue;
00424
00425 fields[0] = p;
00426 for (i = 1; *p && i < fields_n - 1; p++) {
00427 if (*p == ':') {
00428 *p = '\0';
00429 fields[i++] = p + 1;
00430 }
00431 }
00432 fields[i] = NULL;
00433
00434 if (strcmp(username, fields[0]) == 0) {
00435 (void) fclose(F);
00436 return fields;
00437 }
00438 }
00439 (void) fclose(F);
00440 return NULL;
00441 }
|
|
||||||||||||
|
Definition at line 826 of file NewsCache.cc. References GroupInfo::first(), NServer::freegroup(), CServer::groupinfo(), ClientData::groupname, ClientData::grp, GroupInfo::last(), ClientData::nbr, Logger::p(), Newsgroup::setsize(), slog, ClientData::srvr, ClientData::stat_artingrp, ClientData::stat_groups, and VERB. Referenced by ns_group(), and ns_listgroup().
00827 {
00828 GroupInfo *gi;
00829 VERB(slog.
00830 p(Logger::
00831 Debug) << "NewsCache selectgroup (" << group << ")\n");
00832
00833 try {
00834 gi = clt->srvr->groupinfo(group);
00835 } catch(NSError & nse) {
00836 return NULL;
00837 }
00838 catch(...) {
00839 return NULL;
00840 }
00841 // Reset Article Pointer
00842 if (gi->first() <= gi->last())
00843 clt->nbr = gi->first();
00844 else
00845 clt->nbr = -1;
00846 if (strcmp(clt->groupname, group) != 0) {
00847 if (clt->grp)
00848 clt->srvr->freegroup(clt->grp);
00849 clt->grp = NULL;
00850 clt->stat_groups++;
00851 if (clt->stat_artingrp) {
00852 slog.p(Logger::Notice) << clt->
00853 client_logname << " group " << clt->
00854 groupname << " " << clt->stat_artingrp << "\n";
00855 clt->stat_artingrp = 0;
00856 }
00857 strcpy(clt->groupname, group);
00858 } else {
00859 //FIXME! NServer has to maintain a list of all the allocated
00860 //FIXME! newsgroups and should call this function itself!!!
00861 if (clt->grp)
00862 clt->grp->setsize(gi->first(), gi->last());
00863 }
00864 return gi;
00865 }
|
|
|
Definition at line 1851 of file NewsCache.cc. References ClientData::access_entry, AccessEntry::access_flags, ClientData::client_command_map, NNRPCommandMap::disableDebug(), NNRPCommandMap::disablePost(), NNRPCommandMap::disableRead(), and NNRPCommandMap::enableAll(). Referenced by nnrpd(), and ns_authinfo().
01852 {
01853 clt.client_command_map.enableAll();
01854 if (!(clt.access_entry->access_flags & AccessEntry::af_read)) {
01855 clt.client_command_map.disableRead();
01856 }
01857
01858 if (!(clt.access_entry->access_flags & AccessEntry::af_post)) {
01859 clt.client_command_map.disablePost ();
01860 }
01861
01862 if (!(clt.access_entry->access_flags & AccessEntry::af_debug)) {
01863 clt.client_command_map.disableDebug ();
01864 }
01865 }
|
|
|
Definition at line 2405 of file NewsCache.cc. References nntp_connections, Logger::p(), sigchld(), and slog. Referenced by main(), and sigchld().
02406 {
02407 int pid;
02408 int st;
02409
02410 slog.p(Logger::Debug) << "receiving signal SIGCHLD: " << num << "\n";
02411 /* Reinstall the signal handler */
02412 #ifdef HAVE_SIGACTION
02413 struct sigaction action;
02414 action.sa_handler = sigchld;
02415 sigemptyset(&action.sa_mask);
02416 action.sa_flags = 0;
02417 sigaction(num, &action, NULL);
02418 #else
02419 signal(num, sigchld);
02420 #endif
02421
02422 while ((pid = waitpid(0, &st, WNOHANG)) > 0) {
02423 if (WIFEXITED(st) || WIFSIGNALED(st)) {
02424 // child terminated
02425 nntp_connections--;
02426 if (st) {
02427 if (WIFEXITED(st)) {
02428 slog.
02429 p(Logger::
02430 Error) << pid << " returned "
02431 << WEXITSTATUS(st) << "\n";
02432 } else if (WIFSIGNALED(st)) {
02433 slog.
02434 p(Logger::
02435 Error) << pid <<
02436 " caught signal " <<
02437 WTERMSIG(st) << "\n";
02438 }
02439 }
02440 }
02441 }
02442 }
|
|
|
Definition at line 299 of file NewsCache.cc. Referenced by catchsighup(), clean(), main(), nnrpd(), nntpd(), ns_help(), ns_list(), ns_xdebug(), readgroups(), and update(). |
|
|
Definition at line 141 of file NewsCache.cc. Referenced by catchsigalarm(), and nnrpd(). |
|
|
Definition at line 143 of file NewsCache.cc. Referenced by main(), nntpd(), nsh_particle(), and nvflock(). |
|
|
Definition at line 298 of file NewsCache.cc. Referenced by catchsighup(), and main(). |
|
|
Definition at line 52 of file NewsCache.cc. Referenced by main(). |
|
|
Definition at line 302 of file NewsCache.cc. |
|
|
Definition at line 142 of file NewsCache.cc. |
|
|
Definition at line 301 of file NewsCache.cc. Referenced by catchsignal(), main(), nnrpd(), nntpd(), readgroups(), and update(). |
1.3.6-20040222