garvey@cmic.UUCP (Joe Garvey) (02/17/90)
I would like to hold all incoming news until late at night (even though it may be received at all times during the day), before unpacking it (using rnews). However, I'm unwilling to just stall the whole uucp system that long. Mail that comes in should be immediately unpacked. I'm using a HDB based uucp on an HP 9000/370 running HP-UX 6.5. Any suggestions? Any one out there doing this already? -- Joe Garvey UUCP: {apple,backbone}!versatc!mips!cmic!garvey California Microwave Internet: garvey%cmic@mips.com 990 Almanor Ave HP Desk: garvey (cmic@mips.com) /hp1900/ux Sunnyvale, Ca, 94086 800-831-3104 (outside CA) 408-720-6439 (let it ring) 800-824-7814 (inside CA)
jbayer@ispi.UUCP (Jonathan Bayer) (02/17/90)
garvey@cmic.UUCP (Joe Garvey) writes: >I would like to hold all incoming news until late at night (even though >it may be received at all times during the day), before unpacking it (using >rnews). >However, I'm unwilling to just stall the whole uucp system that long. Mail >that comes in should be immediately unpacked. I'm using a HDB based uucp >on an HP 9000/370 running HP-UX 6.5. What you will want to do is the following: 1. Rename rnews to be rnews.x 2. Replace rnews with a small program that will simply do a "mv" to move the news files to a holding directory. Also, it should create a command file which will hold all the commands necessary to unpack each file. 3. Create a cron entry which will execute the command file at the time you want. JB -- Jonathan Bayer Intelligent Software Products, Inc. (201) 245-5922 500 Oakwood Ave. jbayer@ispi.COM Roselle Park, NJ 07204
tneff@bfmny0.UU.NET (Tom Neff) (02/18/90)
In article <239@cmic.UUCP> garvey@cmic.UUCP (Joe Garvey) writes: >I would like to hold all incoming news until late at night (even though >it may be received at all times during the day), before unpacking it (using >rnews). > >However, I'm unwilling to just stall the whole uucp system that long. Mail >that comes in should be immediately unpacked. I'm using a HDB based uucp >on an HP 9000/370 running HP-UX 6.5. Jonathan Bayer points out one way, which is to front end 'rnews' with a program of your own that waits till evening before letting the real unbatcher do its thing. The only reason I don't like this is that it lets the batches sit around in your spool directory all day, and also makes you pay for downloading them in daytime when you don't really want the contents till later. Another, perhaps simpler approach is to fine tune the *grade* of UUCP traffic you collect during the day. Many feed sites queue news batches with a lower grade than mail; if you're not sure whether your feed sites do this, ask their news admins. Mine does, so I can say this in my HDB 'Systems' file: uunet Any/C,Any1900-0700 ACU 2400 5551212 "" \d\r Host UUNET ... This lets me transfer grade C or better (including mail and filecopy) around the clock, but anything else only from 7pm-7am. For more info about this stuff, peruse the Nutshell handbook on Managing UUCP and Usenet. Wotta tome :-)
icsu6000@caesar (Jaye Mathisen) (02/19/90)
In article <1309@ispi.UUCP> jbayer@ispi.UUCP (Jonathan Bayer) writes: >garvey@cmic.UUCP (Joe Garvey) writes: > >>I would like to hold all incoming news until late at night (even though >>it may be received at all times during the day), before unpacking it (using >>rnews). > >>However, I'm unwilling to just stall the whole uucp system that long. Mail >>that comes in should be immediately unpacked. I'm using a HDB based uucp >>on an HP 9000/370 running HP-UX 6.5. >What you will want to do is the following: Why not just rebuild your news software with the SPOOLNEWS options (assuming you have B news) defined, and then run rnews -U from cron late at night? I assume this is doable inside C news, although I have no experience using it. Hope this helps. -- +-----------------------------------------------------------------------------+ | Jaye Mathisen,systems manager Internet: icsu6000@caesar.cs.montana.edu| | 410 Roberts Hall BITNET: icsu6000@mtsunix1.bitnet | | Dept. of Computer Science |
dce@smsc.sony.com (David Elliott) (02/20/90)
In article <3273@caesar.cs.montana.edu> icsu6000@caesar.cs.montana.edu (Jaye Mathisen) writes: >>garvey@cmic.UUCP (Joe Garvey) writes: >>>I would like to hold all incoming news until late at night (even though >>>it may be received at all times during the day), before unpacking it (using >>>rnews). >I assume this is doable inside C news, although I have no experience >using it. It's not only doable, it's trivial. C news leaves the incoming batches in /usr/spool/news/in.coming. You set up a cron job that unbatches the news. I currently unbatch news at 20 minutes past each hour, but I could easily change this to only unbatch once a day. Note that you will probably want to unbatch *after* you expire. -- David Elliott dce@smsc.sony.com | ...!{uunet,mips}!sonyusa!dce (408)944-4073
henry@utzoo.uucp (Henry Spencer) (02/20/90)
In article <3273@caesar.cs.montana.edu> icsu6000@caesar.cs.montana.edu (Jaye Mathisen) writes: >>>I would like to hold all incoming news until late at night (even though >>>it may be received at all times during the day), before unpacking it... > >I assume this is doable inside C news, although I have no experience >using it. It's standard with C News. If you want to pay the extra costs of doing an unpacking immediately (it does cost a little extra, it turns out), you have to work at it. -- "The N in NFS stands for Not, | Henry Spencer at U of Toronto Zoology or Need, or perhaps Nightmare"| uunet!attcan!utzoo!henry henry@zoo.toronto.edu
zeeff@b-tech.ann-arbor.mi.us (Jon Zeeff) (02/20/90)
>>>>I would like to hold all incoming news until late at night (even though >>>>it may be received at all times during the day), before unpacking it... > >It's standard with C News. If you want to pay the extra costs of doing >an unpacking immediately (it does cost a little extra, it turns out), >you have to work at it. I agree, if you use the standard C News method. I used to do it, but now have something more efficient and less of a hassle (it does some disk space management). It seems to run about 40% faster by avoiding a copy and puting all the front end code into one process. It also has enough "niceness" features that you may not notice it running during the day. Copies of rnews.c are available on request. -- Jon Zeeff zeeff@b-tech.ann-arbor.mi.us or b-tech!zeeff
henry@utzoo.uucp (Henry Spencer) (02/21/90)
In article <FKT#$T&@b-tech.uucp> zeeff@b-tech.ann-arbor.mi.us (Jon Zeeff) writes: >>... standard with C News. If you want to pay the extra costs of doing >>an unpacking immediately (it does cost a little extra, it turns out), >>you have to work at it. > >I agree, if you use the standard C News method... Jon, it costs a little extra no matter how you do it; amortizing startup and shutdown overhead over multiple batches is a win even when those overheads are small. Of course, it may not be enough of a win to be worth bothering with. -- "The N in NFS stands for Not, | Henry Spencer at U of Toronto Zoology or Need, or perhaps Nightmare"| uunet!attcan!utzoo!henry henry@zoo.toronto.edu
zeeff@b-tech.ann-arbor.mi.us (Jon Zeeff) (02/21/90)
>>>... standard with C News. If you want to pay the extra costs of doing >>>an unpacking immediately (it does cost a little extra, it turns out), >>>you have to work at it. >> >>I agree, if you use the standard C News method... > >Jon, it costs a little extra no matter how you do it; amortizing startup >and shutdown overhead over multiple batches is a win even when those >overheads are small. I'm not sure I agree. A process (rnews) is already running and if you are going to delay processing and do it in a batch, you have to copy the news off somewhere (which adds disk i/o overhead) and then start up another process to handle it later. It's also suprising how little processing doesn't get repeated for every batch - looking at newsrun, all I see if a few lines of minor code (like a lock creation and a hostname determination) that aren't in the main loop. Plus, my rnews is faster than either of the C News methods, meaning that while in theory you might be able to gain something (what?) by doing it in batches, in practice you can't (with currently available code). -- Jon Zeeff zeeff@b-tech.ann-arbor.mi.us or b-tech!zeeff
allan@cs.strath.ac.uk (Allan Black) (02/24/90)
In article <239@cmic.UUCP> garvey@cmic.UUCP (Joe Garvey) writes: >I would like to hold all incoming news until late at night (even though >it may be received at all times during the day), before unpacking it (using >rnews). Try this - I've been using it for a couple of years and it seems to work OK. It checks time of day, load average and number of free inodes in /usr/spool. [If you're on a SYS5 machine you probably won't get load average & you may have to tweak some of the code - sorry] # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #-----cut here-----cut here-----cut here-----cut here----- #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # README # Makefile # qnews.8 # unqnews.8 # config.h # qnews.h # ctl.c # loadav.c # qerror.c # qnews.c # unqnews.c # This archive created: Fri Feb 23 16:59:22 1990 echo shar: extracting README '(3803 characters)' sed 's/^XX//' << \SHAR_EOF > README XXqnews/unqnews 8/4/88 XX XX Qnews and unqnews provide a simple queuing mechanism for incoming news XXbatches. Qnews, invoked by the appropriate listener, places each news XXbatch in a spool file. Unqnews picks up these spool files in chronological XXorder and invokes inews(1) to process them. XX XXCONFIGURATION XX There are several options to be configured before building qnews and XXunqnews. These are defined in config.h: XX XXBATCHDIR The directory to be used for the news spool files. The XX names of the spool files are all of the form XX "${BATCHDIR}/rnews.XXXXXX" where "XXXXXX" is a serial XX number used to ensure chronological processing of XX incoming news articles. This is almost always XX "/usr/spool/news/<subdir>" where <subdir> is something XX like "inbatch" or "incoming". XX XXCOPYDIR This is the directory where the TRANSPORT SERVICE XX software has spooled the file containing the news batch. XX Normally, the niftp listener will pass the file name to XX qnews as an absolute pathname, so COPYDIR will not be XX used. In any strange case where qnews is given a relative XX pathname, it will look for the spool file in XX "${COPYDIR}/<pathname>". Typical values of COPYDIR are XX "/usr/spool/niftp/news" or "/usr/spool/hhcp". XX XXERRLOG The absolute pathname of a file to be used for error XX logging by either qnews or unqnews. The file should be XX writable by the UID specified by NEWSUID or the group XX specified by NEWSGID (see below). Typically, ERRLOG XX will be "/usr/lib/news/qnews.errlog". XX XXNEWSUID The UID of the news administrator, usually "news". XXNEWSGID The GID of the news administrator, also usually "news". XX XXMAXLOAD The maximum load average at which news processing will XX be done. If this is undefined, no account will be taken XX of the load average and news will be processed no matter XX how crippling this could turn out to be to your poor XX machine. If defined, the load average is examined before XX starting the processing of each batch by inews. The load XX average used is the one averaged over five minutes (the XX middle of the three as printed by uptime etc.). XX XXPEAKTIME If PEAKTIME is defined, no news processing will be done XX during peak hours (8 a.m. to 6 p.m.). Unqnews will exit XX whether it is started by qnews or cron. XX XXDAEMON If daemon is defined, qnews will NOT start up unqnews XX upon receiving a news batch. Unqnews can then be started XX by cron at the appropriate time (usually sometime during XX the night). XX XXRWHO If rwho is defined, unqnews will use the rwho daemon XX to find out the load average. If undefined, it will XX dig around in /dev/kmem looking at kernel variables. XX Only meaningful when MAXLOAD is defined. XX XXIFREE Most transport systems check to make sure sufficient XX disk space is available before accepting incoming news. XX They don't, however, check sufficient inodes are available XX to unpack the news into separate files. IFREE defines XX the minimum number of free inodes required before unqnews XX will start unbatching. Should be about 10% of total inodes - XX "df -i" will tell you what you need to know. XX XXSPOOLDEV The cooked device where news is spooled (for the IFREE XX option). E.g. "/dev/zd5e". XX XXINSTALLATION XX Usually the binaries for qnews and unqnews will reside in the news XXhome directory, "/usr/lib/news". If this is not the case, edit Makefile XXand change NEWSDIR to be the directory you want to put them in. XX Type "make" and, if all goes according to plan, "make install". XX XXINVOCATION XX Qnews is invoked either with a single argument giving the ABSOLUTE XXPATHNAME of the batch file, or with the batch file open on the standard XXinput: XX/usr/lib/news/qnews <filename> XX XX[For the UK NIFTP system] XXThis is typically achieved by putting the following line in your XXniftptailor file: XXNEWSPROC "/usr/lib/news/qnews %s" XX XXAllan Black <allan@uk.ac.strath.cs> XX SHAR_EOF if test 3803 -ne "`wc -c README`" then echo shar: error transmitting README '(should have been 3803 characters)' fi echo shar: extracting Makefile '(1545 characters)' sed 's/^XX//' << \SHAR_EOF > Makefile XX# Makefile for qnews/unqnews XX XXCFLAGS= -O XX XXNEWSDIR= /usr/lib/news XX XXSRC= qnews.c unqnews.c ctl.c qerror.c loadav.c XXHEADER= config.h qnews.h XX XXall: qnews unqnews XX XXqnews: qnews.o ctl.o qerror.o XX cc -o qnews qnews.o ctl.o qerror.o XX XXunqnews: unqnews.o ctl.o qerror.o loadav.o XX cc -o unqnews unqnews.o ctl.o qerror.o loadav.o XX XXinstall: all XX install -m 500 -o news -g news -s qnews ${NEWSDIR} XX install -m 2500 -o news -g operator -s unqnews ${NEWSDIR} XX XXdepend: XX for i in ${SRC}; do \ XX ( /bin/grep '^#[ ]*include[ ]*"' $$i | sed -n \ XX -e 's/[^"]*"\([^"]*\)".*/\1/' \ XX -e H -e '$$g' -e '$$s/\n/ /g' \ XX -e '$$s/.*/'$$i': &/' -e '$$s/\.c:/.o:/p' \ XX >> makedep); done XX for i in ${HEADER}; do \ XX echo '$$s/.*/'$$i': &\' >eddep; \ XX echo ' touch '$$i'/p' >>eddep; \ XX ( /bin/grep '^#[ ]*include[ ]*"' $$i | sed -n \ XX -e 's/[^"]*"\([^"]*\)".*/\1/' \ XX -e H -e '$$g' -e '$$s/\n/ /g' \ XX -f eddep \ XX >> makedep); done XX @echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep XX @echo '$$r makedep' >>eddep XX @echo 'w' >>eddep XX @cp Makefile Makefile.bak XX ed - Makefile < eddep XX @rm -f eddep makedep XX @echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile XX @echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile XX @echo '# see make depend above' >> Makefile XX - diff Makefile Makefile.bak XX @rm -f Makefile.bak XX XX# DO NOT DELETE THIS LINE XX XXqnews.o: qnews.h XXunqnews.o: qnews.h XXctl.o: qnews.h XXqerror.o: qnews.h XXqnews.h: config.h XX touch qnews.h XX# DEPENDENCIES MUST END AT END OF FILE XX# IF YOU PUT STUFF HERE IT WILL GO AWAY XX# see make depend above SHAR_EOF if test 1545 -ne "`wc -c Makefile`" then echo shar: error transmitting Makefile '(should have been 1545 characters)' fi echo shar: extracting qnews.8 '(1018 characters)' sed 's/^XX//' << \SHAR_EOF > qnews.8 XX.lg 0 XX.TH QNEWS 8 "8 April 1988" XX.UC 4 XX.SH NAME XXqnews \- Queue incoming news batches for processing by inews(1). XX.SH SYNOPSIS XX.B /usr/lib/news/qnews XX[ batchfile ] XX.SH DESCRIPTION XX.I Qnews XXtakes a news batch and queues it for processing by inews(1) at some later time. XXThe single argument should be the absolute pathname of a file containing XXthe news batch. XXIf a relative pathname is given, XXa default directory will be prepended. XXIf XX.I qnews XXis invoked without any argument the standard input will be used. XXThe batches are given serially numbered filenames of the form "rnews.XXXXXX", XXwhere "XXXXXX" is a six-digit integer. XXThese files are later picked up by XX.I unqnews(1) XXin chronological order and given to XX.I inews. XX.SH FILES XX/usr/lib/news/qnews.errlog error logging file XX/usr/spool/news/inbatch/.qnews serial number seqence XX/usr/spool/news/inbatch/rnews.XXXXXX news batches XX/usr/spool/news/inbatch/rnews.qnews temporary XX.SH SEE ALSO XXinews(1), unqnews(8) XX.SH AUTHORS XXAllan R. Black XX.SH DIAGNOSTICS XXSelf-explanatory. SHAR_EOF if test 1018 -ne "`wc -c qnews.8`" then echo shar: error transmitting qnews.8 '(should have been 1018 characters)' fi echo shar: extracting unqnews.8 '(708 characters)' sed 's/^XX//' << \SHAR_EOF > unqnews.8 XX.lg 0 XX.TH UNQNEWS 8 "11 April 1988" XX.UC 4 XX.SH NAME XXunqnews \- Give queued news batches to inews(1). XX.SH SYNOPSIS XX.B /usr/lib/news/unqnews XX.SH DESCRIPTION XX.I Unqnews XXtakes the news batches queued by qnews(8) in chronological order XXand gives them to inews(1). XXThe batches have serially numbered filenames of the form "rnews.XXXXXX" XXwhere "XXXXXX" is a six-digit integer. XX.SH FILES XX/usr/lib/news/qnews.errlog error logging file XX/usr/spool/news/inbatch/.qnews serial number seqence XX/usr/spool/news/inbatch/.unqnews lock file XX/usr/spool/news/inbatch/rnews.XXXXXX news batches XX/usr/spool/news/inbatch/rnews.tmp temporary XX.SH SEE ALSO XXinews(1), qnews(8) XX.SH AUTHORS XXAllan R. Black XX.SH DIAGNOSTICS XXSelf-explanatory. SHAR_EOF if test 708 -ne "`wc -c unqnews.8`" then echo shar: error transmitting unqnews.8 '(should have been 708 characters)' fi echo shar: extracting config.h '(1858 characters)' sed 's/^XX//' << \SHAR_EOF > config.h XX/* config.h University of Strathclyde 24/3/86 XX * XX * Configuration options for news batch spooler XX * XX */ XX XX /* Configurable directories/files: XX * BATCHDIR - Spool directory for temporary storage of news batches XX * until they have been given to rnews XX * COPYDIR - The directory used by the transport system to spool XX * temporary files. This is only needed in case qnews XX * is presented with a relative path name by the XX * transport system's Q process. XX * ERRLOG - File for various error messages XX */ XX#define BATCHDIR "/usr/spool/news/inbatch" XX#define COPYDIR "/usr/spool/niftp/news" XX#define ERRLOG "/usr/lib/news/qnews.errlog" XX XX /* User ID and group ID to run rnews under */ XX#define NEWSUID 7 XX#define NEWSGID 6 XX XX /* Define MAXLOAD to be the maximum load average (over 5 minutes) XX * at which news processing will be done. Undefine it if you want XX * unconditional news processing. Define PEAKTIME if you want to XX * prevent news processing during the hours 8 a.m. to 6 p.m. XX */ XX#define MAXLOAD 6.0 XX#undef PEAKTIME XX XX /* Define daemon if you want news processing to be kicked off by XX * cron and ONLY by cron. If you want unqnews started by qnews XX * when a news batch appears, (and perhaps also by cron, if the XX * load average/time of day have resulted in news lying around XX * for a few hours) undefine DAEMON. XX */ XX#undef DAEMON XX XX /* Define RWHO if you want to take the load average from the rwho XX * daemon. Otherwise, loadav() will dig around in /dev/kmem to XX * find the load average in kernel variables. RWHO is only meaningful XX * if MAXLOAD is defined. XX */ XX#define RWHO XX XX /* Define IFREE to be the minimum number of inodes free on the spool XX * spool partition before news unbatching will be done. SPOOLDEV XX * should be set to the (cooked) device where the spool partition is. XX */ XX#define IFREE 3000 XX#define SPOOLDEV "/dev/zd5e" XX SHAR_EOF if test 1858 -ne "`wc -c config.h`" then echo shar: error transmitting config.h '(should have been 1858 characters)' fi echo shar: extracting qnews.h '(280 characters)' sed 's/^XX//' << \SHAR_EOF > qnews.h XX/* qnews.h University of Strathclyde 24/3/86 XX * XX * Batch spooler for incoming news XX * XX */ XX XX#include "config.h" XX XX#define RNTEMPLATE "rnews.XXXXXX" XX XXstruct control { XX int c_next; XX int c_last; XX int c_bad; XX}; XX XXstruct control ctl; XX XXchar *func; XX XX#ifdef MAXLOAD XXfloat loadav(); XX#endif XX SHAR_EOF if test 280 -ne "`wc -c qnews.h`" then echo shar: error transmitting qnews.h '(should have been 280 characters)' fi echo shar: extracting ctl.c '(1700 characters)' sed 's/^XX//' << \SHAR_EOF > ctl.c XX/* ctl.c University of Strathclyde 24/3/86 XX * XX * Control file handler for incoming news processors XX * XX */ XX XX#include "qnews.h" XX#include <errno.h> XX#include <sys/file.h> XX XX#define CTLSIZE 22 /* Three six-digit integers plus XX * a newline each = 21 characters. XX */ XX XXchar cfile[] = ".qnews"; XX XXint cfd; XX XXchar ctlbuf[CTLSIZE]; XX XXopen_ctl(c) XX int c; XX /* Open the control file. "c" gives us permission to create it if it XX * doesn't exist. Otherwise, we wait for someone else to do it. XX * Notice that 'qnews' runs as super-user, so it gives ownership XX * of the file to news, enabling the unbatchers to do a setuid(news). XX */ XX{ XX while((cfd = open(cfile,2)) < 0) { XX if(c) { XX if((cfd = creat(cfile,0644)) >= 0) { XX close(cfd); XX chown(cfile,NEWSUID,NEWSGID); XX continue; XX } XX qerror(cfile); XX } XX sleep(300); XX } XX} XX XXget_ctl() XX /* Get the info in the control file, plus an exclusive lock */ XX{ XX if(flock(cfd,LOCK_EX) < 0) qerror(cfile); XX if(lseek(cfd,0L,0) < 0) qerror(cfile); XX if(read(cfd,ctlbuf,CTLSIZE) < 0) qerror(cfile); XX sscanf(ctlbuf,"%6d\n%6d\n%6d\n",&ctl.c_next,&ctl.c_last,&ctl.c_bad); XX} XX XXput_ctl() XX /* Put info back to the control file and release the lock */ XX{ XX if(lseek(cfd,0L,0) < 0) qerror(cfile); XX sprintf(ctlbuf,"%06d\n%06d\n%06d\n",ctl.c_next,ctl.c_last,ctl.c_bad); XX if(write(cfd,ctlbuf,strlen(ctlbuf)) < 0) qerror(cfile); XX flock(cfd,LOCK_UN); XX} XX XXrel_ctl() XX /* Release the control file */ XX{ XX flock(cfd,LOCK_UN); XX} XX XXexists(file) XX char *file; XX /* Test for persence of file. If the file exists, We simulate a XX * "File exists" error, to facilitate qerror's job. XX */ XX{ XX extern int errno; XX if(access(file,F_OK) < 0) { XX return 0; XX } else { XX errno = EEXIST; XX return 1; XX } XX} XX SHAR_EOF if test 1700 -ne "`wc -c ctl.c`" then echo shar: error transmitting ctl.c '(should have been 1700 characters)' fi echo shar: extracting loadav.c '(3645 characters)' sed 's/^XX//' << \SHAR_EOF > loadav.c XX/* loadav.c XX * XX * This code is all 4.[23] BSD specific. Who cares about System V? XX * We 'fail-safe' by returning values that'll prevent unbatching XX * if something unexpected occurs, like a system call failing. XX */ XX XX#include "config.h" XX XX/* XX * NB - On 'vanilla' 4.2 BSD systems, the kernel stores the load XX * averages as floats and the values there should not be divided XX * by 100. If you plan to read /dev/kmem on such a system, the XX * definition of avenrun[] and the value of MAXLOADAVG will have XX * to be changed accordingly. #define VANILLA should do this OK. XX */ XX XX#undef VANILLA XX XX#ifdef MAXLOAD XX#ifdef RWHO XX/* XX * Find out the load average by looking at the files created by XX * the rwho daemon in /usr/spool/rwho. This won't work if the XX * daemon isn't running. XX */ XX XX/* XX * rwho protocol packet format. XX * - lifted from /usr/src/etc/rwhod/rwho.h XX */ XXstruct whod { XX char wd_vers; /* protocol version # */ XX char wd_type; /* packet type, see below */ XX char wd_pad[2]; XX int wd_sendtime; /* time stamp by sender */ XX int wd_recvtime; /* time stamp applied by receiver */ XX char wd_hostname[32]; /* hosts's name */ XX int wd_loadav[3]; /* load average as in uptime */ XX int wd_boottime; /* time system booted */ XX /* who cares about the login crud from utmp ? */ XX} whod; XX XXchar whodfile[100]; XXchar hostname[32]; XX XX#define SPOOLPATH "/usr/spool/rwho/whod." XX XXfloat loadav() XX/* XX * Return the load average over the last 5 minutes XX */ XX{ XX int fd; XX if(gethostname(hostname,sizeof(hostname)) != 0) return 0; XX sprintf(whodfile, "%s%s", SPOOLPATH, hostname); XX if((fd = open(whodfile,0)) < 0) return (float)0; XX if(read(fd,&whod,sizeof(struct whod)) < 0) { XX close(fd); XX return (float)0; XX } XX return (float)(whod.wd_loadav[1]/100); XX} XX XX#else RWHO XX XX#include <nlist.h> XX XXstruct nlist nl[] = { XX { "_avenrun" }, XX#define X_AVENRUN 0 XX { "" }, XX}; XX XXfloat loadav() XX/* XX * Poke around in /dev/kmem and the kernel symbol table XX * and fish out the load average ourselves (Yuk)! This XX * won't be allowed on systems that keep /dev/*mem* away XX * from prying eyes. XX * XX */ XX{ XX int kmem, kloadav; XX#ifdef VANILLA XX float avenrun[3]; XX#else XX long avenrun[3]; XX#endif XX XX if((kmem = open("/dev/kmem",0)) < 0) return 0; XX nlist("/vmunix", nl); XX if(nl[0].n_type == 0) return 0; XX if(lseek(kmem,(long)nl[X_AVENRUN].n_value,0) < 0) { XX close(kmem); XX return 0; XX } XX if(read(kmem,avenrun,sizeof(avenrun)) != sizeof(avenrun)) { XX close(kmem); XX return 0; XX } XX close(kmem); XX#ifdef VANILLA XX return avenrun[1]; XX#else XX return (float)(avenrun[1]/100) XX#endif XX} XX XX#endif RWHO XX#endif MAXLOAD XX XX#ifdef PEAKTIME XX XX#include <sys/time.h> XX XX#define SECSPERDAY (24*60*60) XX#define EIGHT_AM (8*60*60) XX#define SIX_PM (18*60*60) XX XXint peaktime() XX/* XX * Return non-zero if we're in peak time - between 8 am and 6 pm. XX * This'll stop us processing news during the daytime when there XX * are 1,000 users logged in all running emacs and compiling Ada XX * programs....... XX */ XX{ XX struct timeval tv; XX struct timezone tz; XX int now; XX XX if (gettimeofday(&tv,&tz) < 0) return 0; XX now = tv.tv_sec % SECSPERDAY; XX return now >= EIGHT_AM && now <= SIX_PM; XX} XX XX#endif PEAKTIME XX XX#ifdef IFREE XX XX/* Examine number of free inodes on /usr/spool partition */ XX XX#include <sys/param.h> XX#include <sys/fs.h> XX XXunion { XX struct fs sb_fs; XX char sb_pad[SBSIZE]; XX} sb; XX#define sblock sb.sb_fs XX XXifree() XX{ XX int dev; XX if((dev = open(SPOOLDEV, 0)) < 0) { XX qerror(SPOOLDEV); XX return IFREE; XX } XX if(lseek(dev, (long) (SBLOCK*DEV_BSIZE), 0) < 0) { XX qerror("lseek"); XX close(dev); XX return IFREE; XX } XX if(read(dev, (char *) &sblock, SBSIZE) != SBSIZE) { XX qerror("read"); XX close(dev); XX return IFREE; XX } XX close(dev); XX return sblock.fs_cstotal.cs_nifree; XX} XX XX#endif IFREE XX SHAR_EOF if test 3645 -ne "`wc -c loadav.c`" then echo shar: error transmitting loadav.c '(should have been 3645 characters)' fi echo shar: extracting qerror.c '(620 characters)' sed 's/^XX//' << \SHAR_EOF > qerror.c XX/* qerror.c University of Strathclyde 24/3/86 XX * XX * Error messages XX * XX */ XX XX#include "qnews.h" XX#include <stdio.h> XX#include <sys/file.h> XX XXqerror(str) XX char *str; XX /* Open the error log file and simulate a perror() */ XX{ XX extern int errno; XX extern char *sys_errlist[]; XX qlog("%s: %s: %s\n",func,str,sys_errlist[errno]); XX} XX XXqlog(fmt,args) XX char *fmt; XX int args; XX{ XX register FILE *errlog; XX if((errlog = fopen(ERRLOG,"a")) == NULL) return; XX flock(fileno(errlog),LOCK_EX); XX _doprnt(fmt,&args,errlog); XX flock(fileno(errlog),LOCK_UN); XX fclose(errlog); XX} XX XXpanic(str) XX char *str; XX /* I give up ..... */ XX{ XX qerror(str); XX exit(1); XX} XX SHAR_EOF if test 620 -ne "`wc -c qerror.c`" then echo shar: error transmitting qerror.c '(should have been 620 characters)' fi echo shar: extracting qnews.c '(3229 characters)' sed 's/^XX//' << \SHAR_EOF > qnews.c XX/* qnews.c University of Strathclyde 24/3/86 XX * XX * Batch spooler for incoming news XX * XX */ XX XX/* Called as "qnews filename"; filename being the name of the spool XX * file which hhcp/uucp etc. has just finished receiving. XX * Renames, or copies if rename fails, the file into the news XX * batch directory for processing by unqnews. XX * With no arg, copies standard input to news batch directory. XX * This a) lets the comms link close as soon as possible XX * b) allows a certain amount of control over processing XX * N.B. MUST be called as "qnews <absolute pathname>", since it does XX * a but of cd'ing. XX */ XX XX#include <signal.h> XX#include <sys/ioctl.h> XX#include "qnews.h" XX XX#define BUFSIZE 1024 XX XXchar batchdir[] = BATCHDIR; XXchar rnfile[] = RNTEMPLATE; XXchar unqnews[] = "/usr/lib/news/unqnews"; XXchar xfile[] = "rnews.qnews"; XX XXchar copyfile[100]; XX XXchar buf[BUFSIZE]; XX XXmain(argc,argv,envp) XX int argc; XX char **argv; XX char **envp; XX{ XX register int rfd, wfd; XX register char *sfile; XX register int n; XX XX *envp = 0; XX XX func = argv[0]; XX for(n = 0; n < NSIG; n++) signal(n,SIG_IGN); XX rfd = open("/dev/tty",2); XX ioctl(rfd,TIOCNOTTY); XX close(rfd); XX XX if(chdir(batchdir) < 0) { XX /* Surely not.... */ XX panic(batchdir); XX } XX XX open_ctl(1); XX get_ctl(); XX XX if(argc > 1) { XX /* Just take the file.... */ XX sfile = argv[1]; XX if(*sfile != '/') { XX /* Make it an absolute pathname in the XX * hh/uu/ftp etc. spool directory [COPYDIR] XX */ XX strcpy(copyfile,COPYDIR); XX strcat(copyfile,"/"); XX strcat(copyfile,sfile); XX sfile = copyfile; XX } XX } else { XX /* Copy stdin to tmp file */ XX if((wfd = creat(xfile,0644)) < 0) panic(xfile); XX while((n = read(0,buf,BUFSIZE)) > 0) { XX if(write(wfd,buf,n) < 0) { XX qerror(xfile); XX unlink(xfile); XX exit(1); XX } XX } XX close(wfd); XX sfile = xfile; XX } XX XX mkrnfile(rnfile,ctl.c_last); XX while(rename(sfile,rnfile) < 0) { XX if(sfile != xfile) { XX /* We can't rename the hhcp/ftp/uucp[etc.] spool file XX * into the news spool directory, so try to copy it. XX */ XX if((rfd = open(sfile,0)) < 0) { XX qerror(sfile); XX goto junk; XX } XX if((wfd = creat(xfile,0644)) < 0) { XX qerror(xfile); XX goto junk; XX } XX while((n = read(rfd,buf,BUFSIZE)) > 0) { XX if(write(wfd,buf,n) < 0) { XX qerror(xfile); XX goto junk; XX } XX } XX close(rfd); XX close(wfd); XX if(unlink(sfile) < 0) qerror(sfile); XX sfile = xfile; XX continue; XX } XX /* If we can't rename a file within the same directory, XX * there's something seriously wrong..... XX */ XX qerror(sfile); XX qerror(rnfile); XX junk: XX unlink(xfile); /* May or may not exist */ XX rel_ctl(); /* Locks on files, not fd's... */ XX exit(1); XX } XX XX /* Done successfully. Chown and chmod the file */ XX chown(rnfile,NEWSUID,NEWSGID); XX chmod(rnfile,0644); XX ctl.c_last++; XX put_ctl(); XX XX#ifndef DAEMON XX /* unqnews will fork and exit immediately.... */ XX execl(unqnews,unqnews,0); XX qerror(unqnews); XX /* Even if we can't unqueue it, the news is still ok, XX * so we can exit(0) XX */ XX#endif XX XX exit(0); XX} XX XXmkrnfile(fname,num) XX char *fname; XX register int num; XX /* Transform the "rnews.XXXXXX" template into "rnews.nnnnnn" XX * where 'nnnnnn' is the serial number 'num'. XX */ XX{ XX register char *f; XX for(f = fname; *f; f++); XX while(*--f == 'X') { XX *f = num%10+'0'; XX num /= 10; XX } XX} XX SHAR_EOF if test 3229 -ne "`wc -c qnews.c`" then echo shar: error transmitting qnews.c '(should have been 3229 characters)' fi echo shar: extracting unqnews.c '(6189 characters)' sed 's/^XX//' << \SHAR_EOF > unqnews.c XX/* unqnews.c University of Strathclyde 24/3/86 XX * XX * Batch processor for incoming news XX * XX */ XX XX/* Give the news batches in "/usr/spool/news/batched/rnews.nnnnnn" to XX * rnews. Invoked in /etc/rc.local will restart processing. XX */ XX XX#include "qnews.h" XX#include <stdio.h> XX#include <signal.h> XX#include <sys/ioctl.h> XX#include <sys/file.h> XX XX#define MAXENV 50 XX XXchar batchdir[] = BATCHDIR; XXchar rnfile[] = RNTEMPLATE; XX XXchar newsdir[] = "/usr/lib/news"; XXchar tmpfile[] = "rnews.tmp"; XXchar rnews[] = "rnews"; XXchar rnewspath[] = "/usr/lib/news/rnews"; XXchar null[] = "/dev/null"; XXchar unqlfile[] = ".unqnews"; XXchar badfile[] = "badbatch.XXXXXX"; XXchar newpath[100] = "PATH=/bin:/usr/bin:/usr/ucb:"; XX XXchar *newenv[MAXENV+1]; XX XXint unqlfd; XX XXint terminate(); XX XXint (*sigfunc[NSIG+1])() = { XX 0, /* 0: UNUSED */ XX terminate, /* 1 SIGHUP */ XX SIG_IGN, /* 2 SIGINT */ XX SIG_IGN, /* 3 SIGQUIT */ XX SIG_IGN, /* 4 SIGILL */ XX SIG_IGN, /* 5 SIGTRAP */ XX SIG_IGN, /* 6 SIGIOT */ XX SIG_IGN, /* 7 SIGEMT */ XX SIG_IGN, /* 8 SIGFPE */ XX SIG_DFL, /* 9 SIGKILL */ XX SIG_DFL, /* 10 SIGBUS */ XX SIG_DFL, /* 11 SIGSEGV */ XX SIG_DFL, /* 12 SIGSYS */ XX SIG_DFL, /* 13 SIGPIPE */ XX SIG_IGN, /* 14 SIGALRM */ XX terminate, /* 15 SIGTERM */ XX SIG_DFL, /* 16 SIGURG */ XX SIG_DFL, /* 17 SIGSTOP */ XX SIG_IGN, /* 18 SIGTSTP */ XX SIG_IGN, /* 19 SIGCONT */ XX SIG_DFL, /* 20 SIGCHLD */ XX SIG_DFL, /* 21 SIGTTIN */ XX SIG_DFL, /* 22 SIGTTOU */ XX SIG_DFL, /* 23 SIGIO */ XX SIG_IGN, /* 24 SIGXCPU */ XX SIG_IGN, /* 25 SIGXFSZ */ XX SIG_IGN, /* 26 SIGVTALRM */ XX SIG_IGN, /* 27 SIGPROF */ XX SIG_IGN, /* 28 SIGWINCH */ XX SIG_DFL, /* 29 (UNUSED) */ XX SIG_DFL, /* 30 (UNUSED) */ XX SIG_DFL, /* 31 (UNUSED) */ XX SIG_DFL, /* 32 (UNUSED) */ XX}; XX XXextern char tmpfile[]; XX XXchar *mkfile(); XX XXmain(argc,argv,envp) XX int argc; XX char **argv; XX char **envp; XX{ XX register int i; XX register char *file; XX register char **ep; XX XX func = argv[0]; XX XX#ifdef PEAKTIME XX if(peaktime()) exit(0); XX#endif XX XX#ifdef MAXLOAD XX if(loadav() > MAXLOAD) exit(0); XX#endif XX XX#ifdef IFREE XX if(ifree() < IFREE) exit(0); XX#endif IFREE XX XX if(fork()) exit(0); XX XX for(i = 1; i <= NSIG; i++) signal(i,sigfunc[i]); XX XX i = open("/dev/tty",2); XX ioctl(i,TIOCNOTTY); XX close(i); XX XX strcat(newpath, newsdir); XX for(ep = newenv; ep < &newenv[MAXENV-1] && *envp; envp++) XX if(!strncmp(*envp, newpath, 5)) *ep++ = *envp; XX *ep++ = newpath; XX *ep = 0; XX XX setuid(NEWSUID); XX XX if(chdir(batchdir) < 0) { XX /* If we can't get to the batch directory .... */ XX panic(batchdir); XX } XX XX open_ctl(0); XX get_ctl(); XX unqlock(); XX rel_ctl(); XX XX /* Now we are sure we have control. Make sure there isn't an old XX * batch which hasn't been completely processed yet. XX */ XX if(exists(tmpfile)) do_rnews(); XX XX for(;;) { XX XX#ifdef PEAKTIME XX if(peaktime()) unqexit(0); XX#endif XX#ifdef MAXLOAD XX if(loadav() > MAXLOAD) unqexit(0); XX#endif XX#ifdef IFREE XX if(ifree() < IFREE) unqexit(0); XX#endif IFREE XX XX get_ctl(); XX if(ctl.c_next < ctl.c_last) { XX /* Something claims to be there. Try to process XX * the batch. XX */ XX file = mkfile(rnfile,ctl.c_next); XX if(++ctl.c_next >= ctl.c_last) { XX /* Last one - go back to zero */ XX ctl.c_next = ctl.c_last = 0; XX } XX if(!exists(file)) { XX /* If the file doesn't exist, too bad */ XX qerror(file); XX put_ctl(); XX continue; XX } XX if(rename(file,tmpfile) < 0) { XX /* If we can't rename it, something's XX * seriously wrong. Give up. XX */ XX qerror(tmpfile); XX rel_ctl(); XX unqexit(1); XX } XX } else { XX /* Nothing to process */ XX rel_ctl(); XX unqexit(0); XX } XX put_ctl(); XX do_rnews(); XX } XX} XX XXterminate(n) XX int n; XX{ XX qlog("%s: terminated by signal %d\n",func,n); XX unqexit(1); XX} XX XXchar *mkfile(fname,num) XX char *fname; XX register int num; XX /* Return a file name constructed from the 'fname' template, by XX * printing 'num' into the 'X's XX * 'fname' usually = "rnews.XXXXXX" XX */ XX{ XX register char *f; XX static char buf[100]; XX for(f = buf; *f = *fname++; f++); XX while(*--f == 'X') { XX *f = num%10+'0'; XX num /= 10; XX } XX return(buf); XX} XX XXdo_rnews() XX /* Call rnews [at last!] giving it 'tmpfile' as standard input. XX * If ANYTHING AT ALL goes wrong, we abort and kill the parent XX * process. XX * We can't afford to ignore errors here - I had a nasty experience XX * with rnews once where /dev/null wasn't opened on channels 1 & 2. XX * [The history.pag database ended up being opened on stderr by rnews XX * and "inews: Article too old, moved to junk" didn't go down too XX * well with the database functions] XX * If the child process terminates abnormally, we assume we have a XX * bad batch and save it for the news administrator to salvage what XX * he can from it. XX */ XX{ XX register int n, pid; XX int st; XX register char *file; XX extern int errno; XX pid = getpid(); XX if((n = fork()) == 0) { XX for(n = 1; n <= NSIG; n++) signal(n,SIG_DFL); XX for(n = 0; n < _NFILE; n++) close(n); XX if(open(tmpfile,0) != 0) { XX qerror(tmpfile); XX kill(pid,1); XX unqexit(1); XX } XX if(open(null,1) != 1) { XX qerror(null); XX kill(pid,1); XX unqexit(1); XX } XX if(open(null,1) != 2) { XX qerror(null); XX kill(pid,1); XX unqexit(1); XX } XX if(chdir(newsdir) < 0) { XX qerror(newsdir); XX kill(pid,1); XX unqexit(1); XX } XX execle(rnewspath,rnews,0,newenv); XX qerror(rnews); XX kill(pid,1); XX unqexit(1); XX } XX while(wait(&st) != n); XX if(st) { XX get_ctl(); XX file = mkfile(badfile,ctl.c_bad); XX ++ctl.c_bad; XX if(rename(tmpfile,file) < 0) { XX rel_ctl(); XX panic(file); XX } XX put_ctl(); XX } else { XX unlink(tmpfile); XX } XX} XX XXunqlock() XX /* Lock on the .unqnews file. This ensures only one copy of XX * unqnews runs at a time. It also makes it safe to start XX * unqnews by hand, or restart from /etc/rc.local. Thus, XX * if we don't get the lock, we just exit(0). THE LOCK ON XX * THE CONTROL FILE MUST BE MADE BEFORE ATTEMPTING TO CALL XX * THIS! XX */ XX{ XX unsigned int x; XX if(!exists(unqlfile)) { XX if((unqlfd = creat(unqlfile,0644)) < 0) panic(unqlfile); XX close(unqlfile); XX } XX if((unqlfd = open(unqlfile,2)) < 0) panic(unqlfile); XX if(flock(unqlfd,LOCK_EX|LOCK_NB) < 0) exit(0); XX x = getpid(); XX write(unqlfd,&x,sizeof(int)); XX} XX XXunqexit(st) XX int st; XX /* Don't forget to release the lock on unqueueing before XX * exiting! Some versions of BSD [at least older systems] XX * don't always release locks automatically. XX */ XX{ XX flock(unqlfd,LOCK_UN); XX exit(st); XX} XX SHAR_EOF if test 6189 -ne "`wc -c unqnews.c`" then echo shar: error transmitting unqnews.c '(should have been 6189 characters)' fi # End of shell archive exit 0