rsalz@bbn.com (Rich Salz) (04/20/88)
Submitted-by: Phil Lapsley <phil@ucbvax.berkeley.edu> Posting-number: Volume 14, Issue 49 Archive-name: nntp1.5/part03 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 3 (of 9)." # Wrapped by rsalz@fig.bbn.com on Tue Apr 19 18:16:39 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f './rrnpatches/Makefile.SH.pat' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./rrnpatches/Makefile.SH.pat'\" else echo shar: Extracting \"'./rrnpatches/Makefile.SH.pat'\" \(4585 characters\) sed "s/^X//" >'./rrnpatches/Makefile.SH.pat' <<'END_OF_FILE' X*** rn/Makefile.SH Sun Mar 15 19:54:40 1987 X--- rrn/Makefile.SH Thu Feb 25 20:38:38 1988 X*************** X*** 1,5 X case $CONFIG in X! '') . config.sh ;; X esac X echo "Extracting Makefile (with variable substitutions)" X cat >Makefile <<!GROK!THIS! X X--- 1,5 ----- X case $CONFIG in X! '') . ./config.sh ;; X esac X echo "Extracting Makefile (with variable substitutions)" X cat >Makefile <<!GROK!THIS! X*************** X*** 21,26 X rnlib = $rnlib X mansrc = $mansrc X manext = $manext X CFLAGS = $iandd -O X LDFLAGS = $iandd X NDIRC = $ndirc X X--- 21,27 ----- X rnlib = $rnlib X mansrc = $mansrc X manext = $manext X+ NNTPSRC = $NNTPSRC X CFLAGS = $iandd -O X LDFLAGS = $iandd X NDIRC = $ndirc X*************** X*** 31,37 X cat >>Makefile <<'!NO!SUBS!' X X public = rn newsetup newsgroups Pnews Rnmail X! private = norm.saver mbox.saver ng.help art.help pager.help subs.help makedir filexp Pnews.header X manpages = rn.1 Pnews.1 Rnmail.1 newsetup.1 newsgroups.1 X util = Makefile makedepend newsnews X X X--- 32,38 ----- X cat >>Makefile <<'!NO!SUBS!' X X public = rn newsetup newsgroups Pnews Rnmail X! private = norm.saver mbox.saver ng.help art.help pager.help subs.help makedir filexp Pnews.header getactive X manpages = rn.1 Pnews.1 Rnmail.1 newsetup.1 newsgroups.1 X util = Makefile makedepend newsnews X X*************** X*** 45,51 X c1 = addng.c art.c artio.c artsrch.c backpage.c bits.c cheat.c X c2 = final.c head.c help.c init.c intrp.c kfile.c last.c $(NDIRC) ng.c X c3 = ngdata.c ngsrch.c ngstuff.c only.c rcln.c rcstuff.c X! c4 = respond.c rn.c search.c sw.c term.c util.c X X c = $(c1) $(c2) $(c3) $(c4) X X X--- 46,52 ----- X c1 = addng.c art.c artio.c artsrch.c backpage.c bits.c cheat.c X c2 = final.c head.c help.c init.c intrp.c kfile.c last.c $(NDIRC) ng.c X c3 = ngdata.c ngsrch.c ngstuff.c only.c rcln.c rcstuff.c X! c4 = respond.c rn.c search.c sw.c term.c util.c $(NNTPSRC)/common/clientlib.c X X c = $(c1) $(c2) $(c3) $(c4) X X*************** X*** 52,58 X obj1 = addng.o art.o artio.o artsrch.o backpage.o bits.o cheat.o X obj2 = final.o head.o help.o init.o intrp.o kfile.o last.o $(NDIRO) ng.o X obj3 = ngdata.o ngsrch.o ngstuff.o only.o rcln.o rcstuff.o X! obj4 = respond.o rn.o search.o sw.o term.o util.o X X obj = $(obj1) $(obj2) $(obj3) $(obj4) X X X--- 53,59 ----- X obj1 = addng.o art.o artio.o artsrch.o backpage.o bits.o cheat.o X obj2 = final.o head.o help.o init.o intrp.o kfile.o last.o $(NDIRO) ng.o X obj3 = ngdata.o ngsrch.o ngstuff.o only.o rcln.o rcstuff.o X! obj4 = respond.o rn.o search.o sw.o term.o util.o $(NNTPSRC)/common/clientlib.o X X obj = $(obj1) $(obj2) $(obj3) $(obj4) X X*************** X*** 78,83 X rn: $(obj) X $(CC) $(LDFLAGS) $(obj) $(libs) -o rn X X # if a .h file depends on another .h file... X $(h): X touch $@ X X--- 79,92 ----- X rn: $(obj) X $(CC) $(LDFLAGS) $(obj) $(libs) -o rn X X+ getactive: getactive.o $(NNTPSRC)/common/clientlib.o X+ $(CC) $(LDFLAGS) getactive.o $(NNTPSRC)/common/clientlib.o -o getactive X+ X+ # Eek! This is gross. X+ $(NNTPSRC)/common/clientlib.o: X+ $(CC) -c $(CFLAGS) $(NNTPSRC)/common/clientlib.c X+ mv clientlib.o $(NNTPSRC)/common/clientlib.o X+ X # if a .h file depends on another .h file... X $(h): X touch $@ X*************** X*** 86,91 X # won't work with csh X export PATH || exit 1 X - mv $(rnbin)/rn $(rnbin)/rn.old X - if test `pwd` != $(rnbin); then cp $(public) $(rnbin); fi X cd $(rnbin); chmod 755 $(public) X chmod 755 makedir X X--- 95,101 ----- X # won't work with csh X export PATH || exit 1 X - mv $(rnbin)/rn $(rnbin)/rn.old X+ - ln -s $(rnbin)/rn $(rnbin)/rrn X - if test `pwd` != $(rnbin); then cp $(public) $(rnbin); fi X cd $(rnbin); chmod 755 $(public) X chmod 755 makedir X*************** X*** 103,109 X rm -f *.o X X realclean: X! rm -f rn *.o core $(addedbyconf) X X # The following lint has practically everything turned on. Unfortunately, X # you have to wade through a lot of mumbo jumbo that can't be suppressed. X X--- 113,119 ----- X rm -f *.o X X realclean: X! rm -f rn *.o core $(addedbyconf) $(NNTPSRC)/common/clientlib.o X X # The following lint has practically everything turned on. Unfortunately, X # you have to wade through a lot of mumbo jumbo that can't be suppressed. X*************** X*** 114,120 X lint $(lintflags) $(defs) $(c) > rn.fuzz X X depend: X! makedepend X X # AUTOMATICALLY GENERATED MAKE DEPENDENCIES--PUT NOTHING BELOW THIS LINE X $(obj): X X--- 124,130 ----- X lint $(lintflags) $(defs) $(c) > rn.fuzz X X depend: X! ./makedepend X X # AUTOMATICALLY GENERATED MAKE DEPENDENCIES--PUT NOTHING BELOW THIS LINE X $(obj): END_OF_FILE if test 4585 -ne `wc -c <'./rrnpatches/Makefile.SH.pat'`; then echo shar: \"'./rrnpatches/Makefile.SH.pat'\" unpacked with wrong size! fi # end of './rrnpatches/Makefile.SH.pat' fi if test -f './rrnpatches/artio.c.pat' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./rrnpatches/artio.c.pat'\" else echo shar: Extracting \"'./rrnpatches/artio.c.pat'\" \(3894 characters\) sed "s/^X//" >'./rrnpatches/artio.c.pat' <<'END_OF_FILE' X*** rn/artio.c Sun Mar 15 19:54:46 1987 X--- rrn/artio.c Wed Aug 19 21:29:20 1987 X*************** X*** 8,13 X X #include "EXTERN.h" X #include "common.h" X #include "INTERN.h" X #include "artio.h" X X X--- 8,14 ----- X X #include "EXTERN.h" X #include "common.h" X+ #include "server.h" X #include "INTERN.h" X #include "artio.h" X X*************** X*** 23,29 X artopen(artnum) X ART_NUM artnum; X { X! char artname[8]; /* filename of current article */ X X if (artnum < 1) X return Nullfp; X X--- 24,34 ----- X artopen(artnum) X ART_NUM artnum; X { X! #ifdef SERVER X! static long our_pid; X! char ser_line[256]; X! #endif SERVER X! char artname[32]; /* filename of current article */ X X #ifdef SERVER X if (our_pid == 0) X*************** X*** 25,30 X { X char artname[8]; /* filename of current article */ X X if (artnum < 1) X return Nullfp; X if (openart == artnum) { /* this article is already open? */ X X--- 30,40 ----- X #endif SERVER X char artname[32]; /* filename of current article */ X X+ #ifdef SERVER X+ if (our_pid == 0) X+ our_pid = getpid(); X+ #endif SERVER X+ X if (artnum < 1) X return Nullfp; X if (openart == artnum) { /* this article is already open? */ X*************** X*** 33,38 X } X if (artfp != Nullfp) { /* it was somebody else? */ X fclose(artfp); /* put them out of their misery */ X openart = 0; /* and remember them no more */ X } X sprintf(artname,"%ld",(long)artnum); X X--- 43,52 ----- X } X if (artfp != Nullfp) { /* it was somebody else? */ X fclose(artfp); /* put them out of their misery */ X+ #ifdef SERVER X+ sprintf(artname, "/tmp/rrn%ld.%ld", (long) openart, our_pid); X+ UNLINK(artname); X+ #endif SERVER X openart = 0; /* and remember them no more */ X } X X*************** X*** 35,40 X fclose(artfp); /* put them out of their misery */ X openart = 0; /* and remember them no more */ X } X sprintf(artname,"%ld",(long)artnum); X /* produce the name of the article */ X if (artfp = fopen(artname,"r")) /* if we can open it */ X X--- 49,92 ----- X #endif SERVER X openart = 0; /* and remember them no more */ X } X+ X+ #ifdef SERVER X+ X+ sprintf(artname,"/tmp/rrn%ld.%ld", (long) artnum, our_pid); X+ artfp = fopen(artname, "w+"); /* create the temporary article */ X+ if (artfp == Nullfp) { X+ UNLINK(artname); X+ return Nullfp; X+ } X+ sprintf(ser_line, "ARTICLE %ld", (long)artnum); X+ put_server(ser_line); /* ask the server for the article */ X+ if (get_server(ser_line, sizeof(ser_line)) < 0) { X+ fprintf(stderr, "rrn: Unexpected close of server socket.\n"); X+ finalize(1); X+ } X+ if (*ser_line != CHAR_OK) { /* and get it's reaction */ X+ fclose(artfp); X+ artfp = Nullfp; X+ UNLINK(artname); X+ return Nullfp; X+ } X+ X+ for (;;) { X+ if (get_server(ser_line, sizeof(ser_line)) < 0) { X+ fprintf(stderr, "rrn: Unexpected close of server socket.\n"); X+ finalize(1); X+ } X+ if (ser_line[0] == '.' && ser_line[1] == '\0') X+ break; X+ fputs((ser_line[0] == '.' ? ser_line + 1 : ser_line), artfp); X+ putc('\n', artfp); X+ } X+ X+ fseek(artfp, 0L, 0); /* Then get back to the start */ X+ openart = artnum; X+ X+ #else not SERVER X+ X sprintf(artname,"%ld",(long)artnum); X /* produce the name of the article */ X if (artfp = fopen(artname,"r")) /* if we can open it */ X*************** X*** 39,44 X /* produce the name of the article */ X if (artfp = fopen(artname,"r")) /* if we can open it */ X openart = artnum; /* remember what we did here */ X #ifdef LINKART X { X char tmpbuf[256]; X X--- 91,98 ----- X /* produce the name of the article */ X if (artfp = fopen(artname,"r")) /* if we can open it */ X openart = artnum; /* remember what we did here */ X+ X+ #endif SERVER X #ifdef LINKART X { X char tmpbuf[256]; END_OF_FILE if test 3894 -ne `wc -c <'./rrnpatches/artio.c.pat'`; then echo shar: \"'./rrnpatches/artio.c.pat'\" unpacked with wrong size! fi # end of './rrnpatches/artio.c.pat' fi if test -f './rrnpatches/common.h.pat' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./rrnpatches/common.h.pat'\" else echo shar: Extracting \"'./rrnpatches/common.h.pat'\" \(4168 characters\) sed "s/^X//" >'./rrnpatches/common.h.pat' <<'END_OF_FILE' X*** rn/common.h Sun Mar 15 19:54:22 1987 X--- rrn/common.h Sun Mar 15 22:20:24 1987 X*************** X*** 567,573 X X #ifndef PIPESAVER /* % */ X # ifdef CONDSUB X! # define PIPESAVER "%(%B=^0$?<%A:tail +%Bc %A |) %b" X # else X # define PIPESAVER "tail +%Bc %A | %b" X # endif X X--- 567,577 ----- X X #ifndef PIPESAVER /* % */ X # ifdef CONDSUB X! # ifdef SERVER X! # define PIPESAVER "%(%B=^0$?<%P/rrn%a.%$:tail +%Bc %P/rrn%a.%$ |) %b" X! # else X! # define PIPESAVER "%(%B=^0$?<%A:tail +%Bc %A |) %b" X! # endif X # else X # ifdef SERVER X # define PIPESAVER "tail +%Bc %P/rrn%a.%$ | %b" X*************** X*** 569,575 X # ifdef CONDSUB X # define PIPESAVER "%(%B=^0$?<%A:tail +%Bc %A |) %b" X # else X! # define PIPESAVER "tail +%Bc %A | %b" X # endif X #endif X X X--- 573,583 ----- X # define PIPESAVER "%(%B=^0$?<%A:tail +%Bc %A |) %b" X # endif X # else X! # ifdef SERVER X! # define PIPESAVER "tail +%Bc %P/rrn%a.%$ | %b" X! # else X! # define PIPESAVER "tail +%Bc %A | %b" X! # endif X # endif X #endif X X*************** X*** 574,580 X #endif X X #ifndef NORMSAVER /* % and ~ */ X! # define NORMSAVER "%X/norm.saver %A %P %c %a %B %C \"%b\"" X #endif X X #ifndef MBOXSAVER /* % and ~ */ X X--- 582,592 ----- X #endif X X #ifndef NORMSAVER /* % and ~ */ X! # ifdef SERVER X! # define NORMSAVER "%X/norm.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\"" X! # else X! # define NORMSAVER "%X/norm.saver %A %P %c %a %B %C \"%b\"" X! # endif X #endif X X #ifndef MBOXSAVER /* % and ~ */ X*************** X*** 579,585 X X #ifndef MBOXSAVER /* % and ~ */ X # ifdef MININACT /* 2.10.2 site? */ X! # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %`date`\"" X # else X # ifdef CONDSUB X # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %(%[date]=^\\(\\w*\\), \\(\\w*\\)-\\(\\w*\\)-\\(\\w*\\) \\([^ ]*\\)?%1 %3 %(%2=..?%2: %2) %5 19%4)\"" X X--- 591,601 ----- X X #ifndef MBOXSAVER /* % and ~ */ X # ifdef MININACT /* 2.10.2 site? */ X! # ifdef SERVER X! # define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\" \"From %T %`date`\"" X! # else X! # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %`date`\"" X! # endif SERVER X # else X # ifdef CONDSUB X # ifdef SERVER X*************** X*** 582,588 X # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %`date`\"" X # else X # ifdef CONDSUB X! # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %(%[date]=^\\(\\w*\\), \\(\\w*\\)-\\(\\w*\\)-\\(\\w*\\) \\([^ ]*\\)?%1 %3 %(%2=..?%2: %2) %5 19%4)\"" X /* header munging with a vengeance */ X # else X # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %[posted]\"" X X--- 598,610 ----- X # endif SERVER X # else X # ifdef CONDSUB X! # ifdef SERVER X! # define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\ X! " \"From %T %(%[date]=^\\(\\w*\\), \\(\\w*\\)-\\(\\w*\\)-\\(\\w*\\) \\([^ ]*\\)? X! %1 %3 %(%2=..?%2: %2) %5 19%4)\"" X! # else X! # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %(%[date]=^\\(\\w*\\), \\(\\w*\\)-\\(\\w*\\)-\\(\\w*\\) \\([^ ]*\\)?%1 %3 %(%2=..?%2: %2) %5 19%4)\"" X! # endif X /* header munging with a vengeance */ X # else X # ifdef SERVER X*************** X*** 585,591 X # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %(%[date]=^\\(\\w*\\), \\(\\w*\\)-\\(\\w*\\)-\\(\\w*\\) \\([^ ]*\\)?%1 %3 %(%2=..?%2: %2) %5 19%4)\"" X /* header munging with a vengeance */ X # else X! # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %[posted]\"" X # endif X # endif X #endif X X--- 607,617 ----- X # endif X /* header munging with a vengeance */ X # else X! # ifdef SERVER X! # define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\" \"From %T %[posted]\"" X! # else X! # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %[posted]\"" X! # endif X # endif X # endif X #endif END_OF_FILE if test 4168 -ne `wc -c <'./rrnpatches/common.h.pat'`; then echo shar: \"'./rrnpatches/common.h.pat'\" unpacked with wrong size! fi # end of './rrnpatches/common.h.pat' fi if test -f './rrnpatches/head.c.pat' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./rrnpatches/head.c.pat'\" else echo shar: Extracting \"'./rrnpatches/head.c.pat'\" \(3320 characters\) sed "s/^X//" >'./rrnpatches/head.c.pat' <<'END_OF_FILE' X*** rn/head.c Sun Mar 15 19:54:37 1987 X--- rrn/head.c Mon Jun 1 10:18:35 1987 X*************** X*** 16,21 X #include "common.h" X #include "artio.h" X #include "bits.h" X #include "util.h" X #include "INTERN.h" X #include "head.h" X X--- 16,22 ----- X #include "common.h" X #include "artio.h" X #include "bits.h" X+ #include "server.h" X #include "util.h" X #include "INTERN.h" X #include "head.h" X*************** X*** 180,185 X bool copy; /* do you want it savestr()ed? */ X { X char *s = Nullch, *t; X X #ifdef CACHESUBJ X if (!subj_list) { X X--- 181,191 ----- X bool copy; /* do you want it savestr()ed? */ X { X char *s = Nullch, *t; X+ #ifdef SERVER X+ static int xhdr = 1; /* Can we use xhdr command? */ X+ int eoo; /* End of server output */ X+ char ser_line[256]; X+ #endif SERVER X X #ifdef CACHESUBJ X if (!subj_list) { X*************** X*** 208,213 X else { X s = safemalloc((MEM_SIZE)256); X *s = '\0'; X if (artopen(artnum) != Nullfp) { X do { X if (fgets(s,256,artfp) == Nullch) X X--- 214,268 ----- X else { X s = safemalloc((MEM_SIZE)256); X *s = '\0'; X+ #ifdef SERVER X+ if (xhdr) { X+ sprintf(ser_line, "XHDR subject %ld", artnum); X+ put_server(ser_line); X+ if (get_server(ser_line, sizeof (ser_line)) >= 0) { X+ if (ser_line[0] == CHAR_FATAL) { X+ xhdr = 0; X+ } else { X+ while (get_server(ser_line, sizeof (ser_line)) >= 0) { X+ if (ser_line[0] == '.') X+ break; X+ else { X+ t = index(ser_line, ' '); X+ if (t++) { X+ strcpy(s, t); X+ if (t = index(s, '\r')) X+ *t = '\0'; X+ } X+ } X+ } X+ } X+ } else { X+ fprintf(stderr, X+ "rrn: Unexpected close of server socket.\n"); X+ finalize(1); X+ } X+ } X+ X+ if (!xhdr) { X+ sprintf(ser_line, "HEAD %ld", artnum); X+ put_server(ser_line); X+ eoo = 0; X+ if (get_server(ser_line, 256) >= 0 && ser_line[0] == CHAR_OK) { X+ do { X+ if (get_server(s, 256) < 0 || (*s == '.')) { X+ strcpy(s, "Title: \n"); X+ eoo = 1; X+ } X+ } while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8)); X+ X+ if (!eoo) X+ while (get_server(ser_line, sizeof (ser_line)) >= 0 && X+ ser_line[0] != '.'); X+ t = index(s,':')+1; X+ while (*t == ' ') t++; X+ strcpy(s, t); X+ } X+ } X+ #else not SERVER X if (artopen(artnum) != Nullfp) { X do { X if (fgets(s,256,artfp) == Nullch) X*************** X*** 213,218 X if (fgets(s,256,artfp) == Nullch) X strcpy(s, "Title: \n"); X } while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8)); X s[strlen(s)-1] = '\0'; X t = index(s,':')+1; X while (*t == ' ') t++; X X--- 268,274 ----- X if (fgets(s,256,artfp) == Nullch) X strcpy(s, "Title: \n"); X } while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8)); X+ X s[strlen(s)-1] = '\0'; X t = index(s,':')+1; X while (*t == ' ') t++; X*************** X*** 218,223 X while (*t == ' ') t++; X strcpy(s, t); X } X s = saferealloc(s, (MEM_SIZE)strlen(s)+1); X #ifdef CACHESUBJ X subj_list[OFFSET(artnum)] = s; X X--- 274,280 ----- X while (*t == ' ') t++; X strcpy(s, t); X } X+ #endif X s = saferealloc(s, (MEM_SIZE)strlen(s)+1); X #ifdef CACHESUBJ X subj_list[OFFSET(artnum)] = s; END_OF_FILE if test 3320 -ne `wc -c <'./rrnpatches/head.c.pat'`; then echo shar: \"'./rrnpatches/head.c.pat'\" unpacked with wrong size! fi # end of './rrnpatches/head.c.pat' fi if test -f './server/README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/README'\" else echo shar: Extracting \"'./server/README'\" \(2963 characters\) sed "s/^X//" >'./server/README' <<'END_OF_FILE' X Caveat: Before compiling anything here, go look at README and conf.h in the "common" directory. Fix conf.h up, and then come back here. X X Back already? Ok. Now following the bouncing numbers: X X 1. Create the access file with the proper entries. X This file goes wherever you said ACCESS_FILE X was supposed to be in common/conf.h. It's format is X explained in the manual entry for nntpd.8c. X A sample access file is in ../support/access_file. X If you don't care who (ab)uses your news server, X you can have the line "default read post" in your access X file, which will allow anyone on the network to X read and post news via your server. See the manual X page for a better explanation. X Parts two and three are necessary if you're running with TCP: X X 2. Make an entry for "nntp" in /etc/services. Should X be port number 119, tcp. I.e., should look something like: X nntp 119/tcp readnews # Network News Transfer Protocol X X Sun users running yp should yppush this file to make sure all X the clients get it. X X 3. Check ../common/conf.h to make sure you're set to do what X you want to do with inetd (i.e., #define ALONE or #undef ALONE). X If you are using inetd, X X a. Add a line to /etc/inetd.conf, or whatever your X configuration file is, to reflect the presence X of the news server. On 4.3 BSD machines this should X look like: X nntp stream tcp nowait root /etc/nntpd nntpd X X while under Ultrix or 4.2 BSD machines: X nntp stream tcp nowait /etc/nntpd nntpd X X On a Sun, the file is /etc/servers; the line looks like: X nntp tcp /usr/etc/in.nntpd X X Be sure to yppush your /etc/servers file if you run X yellow pages. X X Don't forget to kill -HUP your inetd. X X If you're NOT using inetd, X X a. Edit ../common/conf.h to have the line X X #define ALONE X X to compile in code for the stand alone server. X X b. You may as well also define "FASTFORK" in X ../common/conf.h. This causes the server not to X read in the active file every time it forks, but X rather to stat it every READINTVL seconds, and if X the file has changed since the last read, to X read it in again. This makes the children run X faster, since they don't have to read the active X file every time the parent forks off a child, but X the parent server will eat more cpu, doing X stat()s every 10 minutes or so. If your server machine X is heavily loaded, you might leave this out. X X c. Change /etc/rc.local to start the server at X boot time. X Else, if you're using decnet: X X 2. && 3. Define the NNTP object with ncp: X ncp define object NNTP number 0 file /etc/nntpd ncp define object NNTP default user guest type stream X ncp set object NNTP all # just once for the running system X X 4. Compile the server by doing "make". X X 5. Cd .. and continue with the rest of the stuff; you'll X wind up doing a make install later. END_OF_FILE if test 2963 -ne `wc -c <'./server/README'`; then echo shar: \"'./server/README'\" unpacked with wrong size! fi # end of './server/README' fi if test -f './server/access.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/access.c'\" else echo shar: Extracting \"'./server/access.c'\" \(4680 characters\) sed "s/^X//" >'./server/access.c' <<'END_OF_FILE' X#ifndef lint static char *sccsid = "@(#)access.c 1.19 (Berkeley) 2/6/88"; X#endif X X#include "common.h" X#ifdef EXCELAN X#include <netinet/in.h> X#endif X#include <sys/socket.h> X X#define SNETMATCH 1 X#define NETMATCH 2 X X/* X * host_access -- determine if the client has permission to X * read, transfer, and/or post news. read->transfer. X * We switch on socket family so as to isolate network dependent code. X * X * Parameters: "canread" is a pointer to storage for X * an integer, which we set to 1 if the X * client can read news, 0 otherwise. X * X * "canpost" is a pointer to storage for X * an integer,which we set to 1 if the X * client can post news, 0 otherwise. X * X * "canxfer" is a pointer to storage for X * an integer,which we set to 1 if the X * client can transfer news, 0 otherwise. X * X * "gdlist" is a comma separated list of X * newsgroups/distributions which the client X * can access. X * X * Returns: Nothing. X * X * Side effects: None. X */ X X#ifdef EXCELAN extern struct sockaddr_in current_peer; X#endif X X#ifdef LOG char hostname[256]; X#endif X host_access(canread, canpost, canxfer, gdlist) X int *canread, *canpost, *canxfer; X char *gdlist; X{ X int sockt; X int length; X struct sockaddr sa; X int match; X int count; X char hostornet[MAXHOSTNAMELEN]; X char host_name[MAXHOSTNAMELEN]; X char net_name[MAXHOSTNAMELEN]; X char snet_name[MAXHOSTNAMELEN]; X char readperm[MAXBUFLEN]; X char postperm[MAXBUFLEN]; X char groups[MAXBUFLEN]; X char line[MAXBUFLEN]; X register char *cp; X register FILE *acs_fp; X X gdlist[0] = '\0'; X X#ifdef DEBUG X *canread = *canpost = *canxfer = 1; X return; X#endif X X *canread = *canpost = *canxfer = 0; X X sockt = fileno(stdin); X length = sizeof (sa); X X#ifdef EXCELAN X if (raddr(current_peer.sin_addr) == NULL) { X#else X if (getpeername(sockt, &sa, &length) < 0) { X#endif X if (isatty(sockt)) { X#ifdef LOG X (void) strcpy(hostname, "stdin"); X#endif X *canread = 1; X } else { X#ifdef SYSLOG X syslog(LOG_ERR, "host_access: getpeername: %m"); X#endif X#ifdef LOG X (void) strcpy(hostname, "unknown"); X#endif X } X return; X } X#ifdef EXCELAN X else bcopy(¤t_peer,&sa,length); X#endif X X switch (sa.sa_family) { X case AF_INET: X inet_netnames(sockt, &sa, net_name, snet_name, host_name); X break; X X#ifdef DECNET X case AF_DECnet: X dnet_netnames(sockt, &sa, net_name, snet_name, host_name); X break; X#endif X X default: X#ifdef SYSLOG X syslog(LOG_ERR, "unknown address family %ld", sa.sa_family); X#endif X return; X }; X X /* Normalize host name to lower case */ X X for (cp = host_name; *cp; cp++) X if (isupper(*cp)) X *cp = tolower(*cp); X X#ifdef LOG X syslog(LOG_INFO, "%s connect\n", host_name); X (void) strcpy(hostname, host_name); X#endif X X /* X * We now we have host_name, snet_name, and net_name. X * Our strategy at this point is: X * X * for each line, get the first word X * X * If it matches "host_name", we have a direct X * match; parse and return. X * X * If it matches "snet_name", we have a subnet match; X * parse and set flags. X * X * If it matches "net_name", we have a net match; X * parse and set flags. X * X * If it matches the literal "default", note we have X * a net match; parse. X */ X X acs_fp = fopen(accessfile, "r"); X if (acs_fp == NULL) { X#ifdef SYSLOG X syslog(LOG_ERR, "access: fopen %s: %m", accessfile); X#endif X return; X } X X while (fgets(line, sizeof(line), acs_fp) != NULL) { X if ((cp = index(line, '\n')) != NULL) X *cp = '\0'; X if ((cp = index(line, '#')) != NULL) X *cp = '\0'; X if (*line == '\0') X continue; X X count = sscanf(line, "%s %s %s %s", X hostornet, readperm, postperm, groups); X X if (count < 4) { X if (count < 3) X continue; X groups[0] = '\0'; /* No groups specified */ X } X X if (!strcasecmp(hostornet, host_name)) { X *canread = (readperm[0] == 'r' || readperm[0] == 'R'); X *canxfer = (*canread || readperm[0] == 'X' X || readperm[0] == 'x'); X *canpost = (postperm[0] == 'p' || postperm[0] == 'P'); X (void) strcpy(gdlist, groups); X break; X } X X if (*snet_name && !strcasecmp(hostornet, snet_name)) { X match = SNETMATCH; X *canread = (readperm[0] == 'r' || readperm[0] == 'R'); X *canxfer = (*canread || readperm[0] == 'X' X || readperm[0] == 'x'); X *canpost = (postperm[0] == 'p' || postperm[0] == 'P'); X (void) strcpy(gdlist, groups); X } X X if (match != SNETMATCH && (!strcasecmp(hostornet, net_name) || X !strcasecmp(hostornet, "default"))) { X match = NETMATCH; X *canread = (readperm[0] == 'r' || readperm[0] == 'R'); X *canxfer = (*canread || readperm[0] == 'X' X || readperm[0] == 'x'); X *canpost = (postperm[0] == 'p' || postperm[0] == 'P'); X (void) strcpy(gdlist, groups); X } X } X X (void) fclose(acs_fp); X} END_OF_FILE if test 4680 -ne `wc -c <'./server/access.c'`; then echo shar: \"'./server/access.c'\" unpacked with wrong size! fi # end of './server/access.c' fi if test -f './server/access_inet.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/access_inet.c'\" else echo shar: Extracting \"'./server/access_inet.c'\" \(3098 characters\) sed "s/^X//" >'./server/access_inet.c' <<'END_OF_FILE' X#ifndef lint static char *sccsid = "@(#)access_inet.c 1.4 (Berkeley) 1/9/88"; X#endif X X#include "common.h" X X#include <stdio.h> X#include <sys/socket.h> X#include <netinet/in.h> X#ifndef EXCELAN X#include <netdb.h> X#include <arpa/inet.h> X#endif X X/* X * inet_netnames -- return the network, subnet, and host names of X * our peer process for the Internet domain. X * X * Parameters: "sock" is our socket, which we don't need. X * "sin" is a pointer to the result of X * a getpeername() call. X * "net_name", "subnet_name", and "host_name" X * are filled in by this routine with the X * corresponding ASCII names of our peer. X * Returns: Nothing. X * Side effects: None. X */ X inet_netnames(sock, sin, net_name, subnet_name, host_name) X int sock; X struct sockaddr_in *sin; X char *net_name; X char *subnet_name; X char *host_name; X{ X#ifdef EXCELAN X excelan_netnames(sock, sin, net_name, subnet_name, host_name); X#else X static int gotsubnetconf; X u_long net_addr; X u_long subnet_addr; X struct hostent *hp; X struct netent *np; X X#ifdef SUBNET X if (!gotsubnetconf) { X if (getifconf() < 0) { X#ifdef SYSLOG X syslog(LOG_ERR, "host_access: getifconf: %m"); X#endif X return; X } X gotsubnetconf = 1; X } X#endif X X net_addr = inet_netof(sin->sin_addr); /* net_addr in host order */ X np = getnetbyaddr(net_addr, AF_INET); X if (np != NULL) X (void) strcpy(net_name, np->n_name); X else X (void) strcpy(net_name,inet_ntoa(*(struct in_addr *)&net_addr)); X X#ifdef SUBNET X subnet_addr = inet_snetof(sin->sin_addr.s_addr); X if (subnet_addr == 0) X subnet_name[0] = '\0'; X else { X np = getnetbyaddr(subnet_addr, AF_INET); X if (np != NULL) X (void) strcpy(subnet_name, np->n_name); X else X (void) strcpy(subnet_name, X inet_ntoa(*(struct in_addr *)&subnet_addr)); X } X#else X subnet_name[0] = '\0'; X#endif SUBNET X X hp = gethostbyaddr((char *) &sin->sin_addr.s_addr, X sizeof (sin->sin_addr.s_addr), AF_INET); X if (hp != NULL) X (void) strcpy(host_name, hp->h_name); X else X (void) strcpy(host_name, inet_ntoa(sin->sin_addr)); X#endif X} X X X#ifdef EXCELAN excelan_netnames(sock, sin, net_name, subnet_name, host_name) X int sock; X struct sockaddr_in *sin; X char *net_name; X char *subnet_name; X char *host_name; X{ X char *hp, *raddr(); X int octet[4]; X X /* assumes sizeof addr is long */ X octet[0] = (sin->sin_addr.s_addr>>24)&0xff; X octet[1] = (sin->sin_addr.s_addr>>16)&0xff; X octet[2] = (sin->sin_addr.s_addr>>8 )&0xff; X octet[3] = (sin->sin_addr.s_addr )&0xff; X X hp = raddr(sin->sin_addr.s_addr); X if (hp != NULL) X (void) strcpy(host_name,hp); X else X X (void) sprintf(host_name,"%d.%d.%d.%d", X octet[0],octet[1],octet[2],octet[3]); X /* No inet* routines here, so we fake it. */ X if (octet[0] < 128) /* CLASS A address */ X (void) sprintf(net_name,"%d",octet[0]); X else if(octet[0] < 192) /* CLASS B address */ X (void) sprintf(net_name,"%d.%d", X octet[0],octet[1]); X else /* CLASS C address */ X (void) sprintf(net_name,"%d.%d.%d", X octet[0],octet[1],octet[2]); X X/* hack to cover the subnet stuff */ X (void) sprintf(subnet_name,"%d.%d.%d",octet[0],octet[1],octet[2]); X} X#endif END_OF_FILE if test 3098 -ne `wc -c <'./server/access_inet.c'`; then echo shar: \"'./server/access_inet.c'\" unpacked with wrong size! fi # end of './server/access_inet.c' fi if test -f './server/active.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/active.c'\" else echo shar: Extracting \"'./server/active.c'\" \(3476 characters\) sed "s/^X//" >'./server/active.c' <<'END_OF_FILE' X#ifndef lint static char *sccsid = "@(#)active.c 1.12 (Berkeley) 1/11/88"; X#endif X X#include "common.h" X X/* X * Routines to deal with the active file X */ X int act_cmp(); X X/* X * read_groups -- read the active file into memory, sort it, X * and return the number of newsgroups read in. X * If FASTFORK is true, this can be called by interrupt, X * and may have to free up the old storage. We decide X * this by the fact that "num_groups" will be non-zero if X * we're here on an interrupt. X * X * Parameters: None. X * X * Returns: Number of newsgroups read into X * memory. X * Zero on error. X * X * Side effects: Reads newsgroups into "group_array" X * and sorts them. X */ X read_groups() X{ X register int i; X register int act_fd; X register char *actbuf, *cp, *end; X char *malloc(); X struct stat statbuf; X X /* X * If we're here on an interrupt, free up all the X * previous groups. X */ X X if (num_groups != 0) { X (void) free(group_array[0]); /* Assume [0] -> actbuf */ X (void) free(group_array); X } X X act_fd = open(activefile, O_RDONLY); X if (act_fd < 0) { X#ifdef SYSLOG X syslog(LOG_ERR, "read_groups: open %s: %m", activefile); X#endif X return (0); X } X X if (fstat(act_fd, &statbuf) < 0) { X#ifdef SYSLOG X syslog(LOG_ERR, "read_groups: fstat: %m"); X#endif X (void) close(act_fd); X return (0); X } X X actbuf = malloc(statbuf.st_size); X if (actbuf == NULL) { X#ifdef SYSLOG X syslog(LOG_ERR, "read_groups: malloc %d bytes: %m", X statbuf.st_size); X#endif X (void) close(act_fd); X return (0); X } X X if (read(act_fd, actbuf, (int)statbuf.st_size) != statbuf.st_size) { X#ifdef SYSLOG X syslog(LOG_ERR, "read_groups: read %d bytes: %m", X statbuf.st_size); X#endif X (void) close(act_fd); X return (0); X } X X (void) close(act_fd); X X for (i = 0, cp = actbuf, end = actbuf + statbuf.st_size; cp < end; cp++) X if (*cp == '\n') X i++; X X group_array = (char **) malloc(i * (sizeof (char *))); X if (group_array == NULL) { X#ifdef SYSLOG X syslog(LOG_ERR, "read_groups: malloc %d bytes: %m", X i * sizeof (char **)); X#endif X (void) close(act_fd); X return (0); X } X X cp = actbuf; X i = 0; X while (cp < end) { X group_array[i++] = cp; X cp = index(cp, '\n'); X if (cp == NULL) X break; X *cp = '\0'; X cp++; X } X X qsort((char *) group_array, i, sizeof (char *), act_cmp); X X return (i); X} X X act_cmp(ptr1, ptr2) X char **ptr1, **ptr2; X{ X return(strcmp(*ptr1, *ptr2)); X} X X X/* X * find_group -- find a given newsgroup and return X * the low and high message numbers in the group X * (space provided by user). X * X * Parameters: "group" is the name of the group X * we're searching for. X * "num_groups" is the total number X * of groups in the group array. X * "low_msg" and "high_msg" are X * pointers to where we're supposed X * to put the low and high message numbers. X * X * Returns: 0 if all goes well, X * -1 if we can't find the group. X * X * Side effects: None. X */ X find_group(group, num_groups, low_msg, high_msg) X char *group; X int num_groups; X int *low_msg, *high_msg; X{ X char kludgebuf[MAXBUFLEN]; X int cond; X register int low, high, mid; X int length; X X low = 0; X high = num_groups-1; X (void) strcpy(kludgebuf, group); X (void) strcat(kludgebuf, " "); X length = strlen(kludgebuf); X X while (low <= high) { X mid = (low + high) / 2; X if ((cond = strncmp(kludgebuf, group_array[mid], length)) < 0) X high = mid - 1; X else if (cond > 0) X low = mid + 1; X else { X (void) sscanf(group_array[mid], "%s %d %d", X kludgebuf, high_msg, low_msg); X return(0); X } X } X return(-1); X} END_OF_FILE if test 3476 -ne `wc -c <'./server/active.c'`; then echo shar: \"'./server/active.c'\" unpacked with wrong size! fi # end of './server/active.c' fi if test -f './server/strcasecmp.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/strcasecmp.c'\" else echo shar: Extracting \"'./server/strcasecmp.c'\" \(3456 characters\) sed "s/^X//" >'./server/strcasecmp.c' <<'END_OF_FILE' X/* X * Copyright (c) 1987 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms are permitted X * provided that this notice is preserved and that due credit is given X * to the University of California at Berkeley. The name of the University X * may not be used to endorse or promote products derived from this X * software without specific written prior permission. This software X * is provided ``as is'' without express or implied warranty. X */ X X#if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strcasecmp.c 5.5 (Berkeley) 11/24/87"; X#endif /* LIBC_SCCS and not lint */ X X#include <sys/types.h> X X/* X * This array is designed for mapping upper and lower case letter X * together for a case independent comparison. The mappings are X * based upon ascii character sequences. X */ static u_char charmap[] = { X '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', X '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', X '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', X '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', X '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', X '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', X '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', X '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', X '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', X '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', X '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', X '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', X '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', X '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', X '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', X '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', X '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', X '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', X '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', X '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', X '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', X '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', X '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', X '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', X '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347', X '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', X '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', X '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337', X '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', X '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', X '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', X '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', X}; X strcasecmp(s1, s2) X char *s1, *s2; X{ X register u_char *cm = charmap, X *us1 = (u_char *)s1, X *us2 = (u_char *)s2; X X while (cm[*us1] == cm[*us2++]) X if (*us1++ == '\0') X return(0); X return(cm[*us1] - cm[*--us2]); X} X strncasecmp(s1, s2, n) X char *s1, *s2; X register int n; X{ X register u_char *cm = charmap, X *us1 = (u_char *)s1, X *us2 = (u_char *)s2; X X while (--n >= 0 && cm[*us1] == cm[*us2++]) X if (*us1++ == '\0') X return(0); X return(n < 0 ? 0 : cm[*us1] - cm[*--us2]); X} END_OF_FILE if test 3456 -ne `wc -c <'./server/strcasecmp.c'`; then echo shar: \"'./server/strcasecmp.c'\" unpacked with wrong size! fi # end of './server/strcasecmp.c' fi if test -f './server/time.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/time.c'\" else echo shar: Extracting \"'./server/time.c'\" \(4156 characters\) sed "s/^X//" >'./server/time.c' <<'END_OF_FILE' X#ifndef lint static char *sccsid = "@(#)time.c 1.9 (Berkeley) 2/6/88"; X#endif X X/* X * Collection of routines for dealing with ASCII time strings. X * These may actually be useful in their own right. X */ X X#include "../common/conf.h" X X#include <stdio.h> X#include <sys/types.h> X#include <ctype.h> X#ifdef USG X#include <time.h> X#else not USG X#include <strings.h> X#include <sys/time.h> X#endif not USG X X/* X * dtol -- convert date to long integer. This is not implicitly X * local time, or any other kind of time, for that matter. If you X * pass it a date you think is GMT, you wind up with that number of X * seconds... X * X * Parameters: "date_ascii" is in the form "yymmddhhmmss". X * X * Returns: Long integer containing number X * of seconds since 000000 Jan 1, 1970, X * and "date". -1 on error. X * X * Side effects: None. X */ X X#define twodigtoi(x) (((x[0]) - '0') + (x[1] - '0')*10) X#define dysize(y) ((y % 4 ? 365 : 366)) X static int dmsize[12] = X { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; X long dtol(date_ascii) X char *date_ascii; X{ X char date[32], *date_str; X char *lhs, *rhs; X char temp; X long seconds; X int year, month, day, hour, mins, secs; X int len, i; X X len = strlen(date_ascii); X if (len != sizeof("yymmddhhmmss")-1) X return (-1); X X (void) strcpy(date, date_ascii); X date_str = date; X X#ifdef debug X printf("date_str = %s\n", date_str); X#endif X rhs = date_str + len - 1; X lhs = date_str; X X for (; lhs < rhs; ++lhs, --rhs) { X temp = *lhs; X *lhs = *rhs; X *rhs = temp; X if (!isdigit(temp) || !isdigit(*lhs)) X return (-1); X } X X lhs = date_str; X#ifdef debug X printf("date_str = %s\n", date_str); X#endif X X secs = twodigtoi(lhs); X lhs += 2; X mins = twodigtoi(lhs); X lhs += 2; X hour = twodigtoi(lhs); X lhs += 2; X day = twodigtoi(lhs); X lhs += 2; X month = twodigtoi(lhs); X lhs += 2; X year = twodigtoi(lhs); X X if (month < 1 || month > 12 || X day < 1 || day > 31 || X mins < 0 || mins > 59 || X secs < 0 || secs > 59) X return (-1); X if (hour == 24) { X hour = 0; X day++; X } X if (hour < 0 || hour > 23) X return (-1); X seconds = 0; X year += 1900; X for (i = 1970; i < year; i++) X seconds += dysize(i); X /* Leap year */ X if (dysize(year) == 366 && month >= 3) X seconds++; X while (--month) X seconds += dmsize[month-1]; X seconds += day-1; X seconds = 24 * seconds + hour; X seconds = 60 * seconds + mins; X seconds = 60 * seconds + secs; X X return (seconds); X} X X X/* X * ltod -- convert long integer to date string. X * X * Parameters: "date" is in the number of seconds X * since the epoch. X * X * Returns: Pointer to static data in the form X * yymmddhhmmss\0. X * X * Side effects: None. X */ X char * ltod(date) X long date; X{ X static char timebuf[32]; X struct tm *tp; X X tp = gmtime(&date); X X (void) sprintf(timebuf, "%02d%02d%02d%02d%02d%02d", X tp->tm_year, X tp->tm_mon + 1, /* 0 to 11??? How silly. */ X tp->tm_mday, X tp->tm_hour, X tp->tm_min, X tp->tm_sec); X X return (timebuf); X} X X X/* X * local_to_gmt -- convert a local time (in form of number of X * seconds since you-know-when) to GMT. X * X * Parameters: "date" is date we want converted, in X * seconds since 000000 1 Jan 1970. X * X * Returns: Number of seconds corrected for local X * and dst. X */ X long local_to_gmt(date) X long date; X{ X#ifdef USG X extern int timezone; X tzset(); X date += timezone; X#else not USG X struct timeval tv; X struct timezone tz; X X (void) gettimeofday(&tv, &tz); X date += (long) tz.tz_minuteswest * 60; X#endif not USG X X /* now fix up local daylight time */ X if (localtime((time_t *)&date)->tm_isdst) X date -= 60*60; X X return (date); X} X X/* X * gmt_to_local -- take a GMT time expressed in seconds since X * the epoch, and convert it to local time. X * X * Parameters: "date" is the number of seconds... X * X * Returns: Number of seconds corrected to reflect X * local time and dst. X */ X long gmt_to_local(date) X long date; X{ X#ifdef USG X extern int timezone; X tzset(); X date -= timezone; X#else not USG X struct timeval tv; X struct timezone tz; X X (void) gettimeofday(&tv, &tz); X date -= (long) tz.tz_minuteswest * 60; X#endif not USG X X /* now fix up local daylight time */ X if (localtime((time_t *)&date)->tm_isdst) X date += 60*60; X X return (date); X} END_OF_FILE if test 4156 -ne `wc -c <'./server/time.c'`; then echo shar: \"'./server/time.c'\" unpacked with wrong size! fi # end of './server/time.c' fi if test -f './server/xhdr.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/xhdr.c'\" else echo shar: Extracting \"'./server/xhdr.c'\" \(3457 characters\) sed "s/^X//" >'./server/xhdr.c' <<'END_OF_FILE' X#ifndef lint static char *sccsid = "@(#)xhdr.c 1.6 (Berkeley) 2/25/88"; X#endif X X#include "common.h" X X#ifdef XHDR X X/* X * XHDR header [<messageid>|articlerange] X * X * header is a case-insensitive header field, minus any colons. X * X * articlerange is one of: X * an article number X * an article number followed by a dash to indicate all following X * an article number followed by a dash followed by another X * article number. X * e.g., X * XHDR subject retrieve subject of current article X * XHDR subject 5589-6325 retrieve subject of arts 5589 to 6325 X * XHDR subject 5589- retrieve subject of arts 5589 and up X * XHDR subject 5589 retrieve subject of art 5589 only X * XHDR subject <123@ucbvax> retrieve subject of art <123@ucbvax> X * X * This command is an extention, and not included in RFC 977. X */ X xhdr(argc, argv) X int argc; X char *argv[]; X{ X char buf[MAXPATHLEN]; X register int artptr; X register int artnum; X register int low, high; X register FILE *fp; X register char *cp; X X if (argc < 2 || argc > 3) { X printf("%d Usage: XHDR headerfield [artrange|<message-id>]\r\n", X ERR_CMDSYN); X (void) fflush(stdout); X return; X } X X if (!canread) { X printf("%d You only have permission to transfer, sorry.\r\n", X ERR_ACCESS); X (void) fflush(stdout); X return; X } X X /* Handle message-id requests */ X X if (argc == 3 && *argv[2] == '<') { /* Message ID */ X fp = openartbyid(argv[2]); X if (fp == NULL) { X printf("%d No article by message-id %s, sorry.\r\n", X ERR_NOART, argv[2]); X (void) fflush(stdout); X return; X } X printf("%d 0 %s header of article %s.\r\n", X OK_HEAD, argv[1], argv[2]); X print_header(fp, argv[1], argv[2]); X (void) fclose(fp); X X putchar('.'); X putchar('\r'); X putchar('\n'); X (void) fflush(stdout); X return; X } X X /* X * It must be a range of articles, which means that we need X * to be in a newsgroup already. X */ X X if (!ingroup) { X printf("%d You are not currently in a newsgroup.\r\n", X ERR_NCING); X (void) fflush(stdout); X return; X } X X artptr = 0; X X if (argc == 2) { X if (art_ptr < 0 || art_ptr >= num_arts) { X printf("%d No article is currently selected.\r\n", X ERR_NOCRNT); X (void) fflush(stdout); X return; X } X high = low = art_array[art_ptr]; X artptr = art_ptr; X } else { X cp = index(argv[2], '-'); X if (cp == NULL) X low = high = atoi(argv[2]); X else { X *cp = '\0'; X low = atoi(argv[2]); X cp++; X high = atoi(cp); X if (high < low) X high = art_array[num_arts-1]; X } X } X X printf("%d %s fields follow\r\n", OK_HEAD, argv[1]); X X for (;; artptr++) { X if ((artnum = art_array[artptr]) < low) X continue; X if (artnum > high) X break; X X (void) sprintf(buf, "%d", artnum); X fp = fopen(buf, "r"); X if (fp == NULL) X continue; X print_header(fp, argv[1], buf); X (void) fclose(fp); X } X X putchar('.'); X putchar('\r'); X putchar('\n'); X (void) fflush(stdout); X} X X print_header(fp, header, artname) X register FILE *fp; X register char *header; X register char *artname; X{ X char line[NNTP_STRLEN]; X register char *cp, *cp1; X X while (fgets(line, sizeof (line), fp) != NULL) { X if (*line == '\n' || *line == '\0') { X printf("%s (none)\r\n", artname); X return; X } X if (cp = index(line, ':')) { X *cp = '\0'; X if (!strcasecmp(header, line)) { X if (cp1 = index(cp + 2, '\n')) X *cp1 = '\0'; X printf("%s %s\r\n", artname, cp + 2); X return; X } X } X } X} X X#else not XHDR X X/* Kludge to get around Greenhills C compiler */ X xhdr_greenkluydge() X{ X} X X#endif not XHDR END_OF_FILE if test 3457 -ne `wc -c <'./server/xhdr.c'`; then echo shar: \"'./server/xhdr.c'\" unpacked with wrong size! fi # end of './server/xhdr.c' fi if test -f './support/mkgrdates.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./support/mkgrdates.c'\" else echo shar: Extracting \"'./support/mkgrdates.c'\" \(3755 characters\) sed "s/^X//" >'./support/mkgrdates.c' <<'END_OF_FILE' X#ifndef lint static char *sccsid = "@(#)mkgrdates.c 1.4 (Berkeley) 2/6/88"; X#endif X X/* X * Make a list of newsgroups which are "new" in the file NGDATE_FILE. X * "New" means having an entry in the active file, and having X * a message numbered "1" in the appropriate news directory. X * Since this involves a stat of all the newsgroups, we try X * to be intelligent about things -- if the active file's size X * since we last ran -- stored in STAT_FILE -- hasn't changed X * since last time, we assume things are ok, and exit without X * doing anything. This could fail in extreme circumstances, X * but is "too painful to do right". X * X * Output in NGDATE_FILE is of the form X * X * date newsgroup X * X * where "date" is the date the newsgroup was created, expressed as X * the number of seconds since 000000 Jan 1, 1970, GMT. This file X * winds up sorted in cronological order. X * X * Phil Lapsley X * College of Engineering X * University of California, Berkeley X * (ARPA: phil@Berkeley.ARPA; UUCP: ...!ucbvax!phil) X */ X X#include <stdio.h> X#include <sys/types.h> X#include <sys/stat.h> X#include "../common/conf.h" X#ifdef USG X#include <time.h> X#else not USG X#include <sys/time.h> X#endif not USG X X#define MODE 0644 /* Better be readable by nntpd! */ X X#ifndef MAXPATHLEN X#define MAXPATHLEN 1024 X#endif X X#ifndef MAXGROUPLEN X#define MAXGROUPLEN 256 X#endif X extern int linecmp(); extern char *index(), *malloc(), *strcpy(), *strcat(); X main(argc, argv) int argc; char *argv[]; X{ X char *groups[1024]; /* XXX 1024 groups max */ X char line[MAXPATHLEN], gr_name[MAXGROUPLEN]; X char *cp; X int i, j; X long lastsize, crntsize; X long birthtime; X struct tm *tmptr; X FILE *stat_fp, *active_fp, *date_fp; X long birthof(); X X stat_fp = fopen(STAT_FILE, "r"); X X if (stat_fp != NULL) { X (void) fscanf(stat_fp, "%d", &lastsize); X (void) fclose(stat_fp); X } X X active_fp = fopen(ACTIVE_FILE, "r"); X if (active_fp == NULL) { X fprintf(stderr, "Can't read active file?\n"); X perror(ACTIVE_FILE); X exit(1); X } X X /* Check length; if it's the same as last time, quit */ X X (void) fseek(active_fp, (long) 0, 2); X crntsize = ftell(active_fp); X if (crntsize == lastsize) { X (void) fclose(active_fp); X exit(0); X } X X /* Ok, time to rebuild the date file */ X X date_fp = fopen(NGDATE_FILE, "w"); X X if (date_fp == NULL) { X perror(NGDATE_FILE); X (void) fclose(active_fp); X exit(1); X } X X rewind(active_fp); X X i = 0; X while (fgets(line, sizeof(line), active_fp) != NULL) { X if ((cp = index(line, ' ')) != NULL) X *cp = '\0'; X (void) strcpy(gr_name, line); X birthtime = birthof(line, atoi(cp + 1)); X X if (birthtime == 0) /* Skip ancient newsgroups */ X continue; X X (void) sprintf(line, "%ld %s", birthtime, gr_name); X groups[i] = malloc(strlen(line)+1); X if (groups[i] != NULL) X (void) strcpy(groups[i++], line); X else { X perror("malloc"); X exit(1); X } X } X X (void) fclose(active_fp); X X qsort((char *) groups, i, sizeof(char *), linecmp); X X for (j = 0; j < i; ++j) X fprintf(date_fp, "%s\n", groups[j]); X X (void) fclose(date_fp); X X (void) chmod(NGDATE_FILE, MODE); X X stat_fp = fopen(STAT_FILE, "w"); X if (stat_fp == NULL) { X perror(STAT_FILE); X exit(1); X } X X fprintf(stat_fp, "%d\n", crntsize); X X (void) fclose(stat_fp); X X (void) chmod(STAT_FILE, MODE); X X exit(0); X} X linecmp(line1, line2) char **line1, **line2; X{ X return(0 - strcmp(*line1, *line2)); X} X X X/* return creation time of newsgroup */ X long birthof(group, highart) char *group; int highart; X{ X char *cp, *index(); X char tst[128]; X struct stat statbuf; X X while ((cp = index(group, '.'))) X *cp = '/'; X X (void) strcpy(tst, SPOOLDIR); X (void) strcat(tst, group); X if (highart) X (void) strcat(tst, "/1"); X if (stat(tst, &statbuf) < 0) X return 0L; /* not there, assume ancient */ X else X return(statbuf.st_mtime); X} END_OF_FILE if test 3755 -ne `wc -c <'./support/mkgrdates.c'`; then echo shar: \"'./support/mkgrdates.c'\" unpacked with wrong size! fi # end of './support/mkgrdates.c' fi if test -f './xmit/sysexits.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./xmit/sysexits.h'\" else echo shar: Extracting \"'./xmit/sysexits.h'\" \(4212 characters\) sed "s/^X//" >'./xmit/sysexits.h' <<'END_OF_FILE' X/* X * Copyright (c) 1987 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms are permitted X * provided that this notice is preserved and that due credit is given X * to the University of California at Berkeley. The name of the University X * may not be used to endorse or promote products derived from this X * software without specific prior written permission. This software X * is provided ``as is'' without express or implied warranty. X * X * @(#)sysexits.h 4.3 (Berkeley) 12/15/87 X */ X X/* X** SYSEXITS.H -- Exit status codes for system programs. X** X** This include file attempts to categorize possible error X** exit statuses for system programs, notably delivermail X** and the Berkeley network. X** X** Error numbers begin at EX__BASE to reduce the possibility of X** clashing with other exit statuses that random programs may X** already return. The meaning of the codes is approximately X** as follows: X** X** EX_USAGE -- The command was used incorrectly, e.g., with X** the wrong number of arguments, a bad flag, a bad X** syntax in a parameter, or whatever. X** EX_DATAERR -- The input data was incorrect in some way. X** This should only be used for user's data & not X** system files. X** EX_NOINPUT -- An input file (not a system file) did not X** exist or was not readable. This could also include X** errors like "No message" to a mailer (if it cared X** to catch it). X** EX_NOUSER -- The user specified did not exist. This might X** be used for mail addresses or remote logins. X** EX_NOHOST -- The host specified did not exist. This is used X** in mail addresses or network requests. X** EX_UNAVAILABLE -- A service is unavailable. This can occur X** if a support program or file does not exist. This X** can also be used as a catchall message when something X** you wanted to do doesn't work, but you don't know X** why. X** EX_SOFTWARE -- An internal software error has been detected. X** This should be limited to non-operating system related X** errors as possible. X** EX_OSERR -- An operating system error has been detected. X** This is intended to be used for such things as "cannot X** fork", "cannot create pipe", or the like. It includes X** things like getuid returning a user that does not X** exist in the passwd file. X** EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp, X** etc.) does not exist, cannot be opened, or has some X** sort of error (e.g., syntax error). X** EX_CANTCREAT -- A (user specified) output file cannot be X** created. X** EX_IOERR -- An error occurred while doing I/O on some file. X** EX_TEMPFAIL -- temporary failure, indicating something that X** is not really an error. In sendmail, this means X** that a mailer (e.g.) could not create a connection, X** and the request should be reattempted later. X** EX_PROTOCOL -- the remote system returned something that X** was "not possible" during a protocol exchange. X** EX_NOPERM -- You did not have sufficient permission to X** perform the operation. This is not intended for X** file system problems, which should use NOINPUT or X** CANTCREAT, but rather for higher level permissions. X** For example, kre uses this to restrict who students X** can send mail to. X** X** Maintained by Eric Allman (eric@berkeley, ucbvax!eric) -- X** please mail changes to me. X** X** @(#)sysexits.h 4.3 12/15/87 X*/ X X# define EX_OK 0 /* successful termination */ X X# define EX__BASE 64 /* base value for error messages */ X X# define EX_USAGE 64 /* command line usage error */ X# define EX_DATAERR 65 /* data format error */ X# define EX_NOINPUT 66 /* cannot open input */ X# define EX_NOUSER 67 /* addressee unknown */ X# define EX_NOHOST 68 /* host name unknown */ X# define EX_UNAVAILABLE 69 /* service unavailable */ X# define EX_SOFTWARE 70 /* internal software error */ X# define EX_OSERR 71 /* system error (e.g., can't fork) */ X# define EX_OSFILE 72 /* critical OS file missing */ X# define EX_CANTCREAT 73 /* can't create (user) output file */ X# define EX_IOERR 74 /* input/output error */ X# define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ X# define EX_PROTOCOL 76 /* remote error in protocol */ X# define EX_NOPERM 77 /* permission denied */ END_OF_FILE if test 4212 -ne `wc -c <'./xmit/sysexits.h'`; then echo shar: \"'./xmit/sysexits.h'\" unpacked with wrong size! fi # end of './xmit/sysexits.h' fi echo shar: End of archive 3 \(of 9\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 9 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.