Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!shadooby!samsung!munnari.oz.au!basser!ultima!nick From: nick@ultima.cs.uts.oz (Nick Andrew) Newsgroups: comp.os.minix Subject: News for Minix (part 7 of 12) Keywords: news Message-ID: <16749@ultima.cs.uts.oz> Date: 7 Dec 89 11:53:31 GMT Organization: Comp Sci, NSWIT, Australia Lines: 2255 #! /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 'makeactive.sh' <<'END_OF_FILE' X: "Create active file and newsgroup hierarchy for new machine" X: "Usage: sh makeactive.sh LIBDIR SPOOLDIR NEWSUSR NEWSGRP" X: '@(#)makeactive 1.23 12/16/86' XLIBDIR=$1 XSPOOLDIR=$2 XNEWSUSR=$3 XNEWSGRP=$4 Xcat <<"E_O_F" > /tmp/$$groups Xgeneral Articles that should be read by everyone on your local system Xnet.sources For the posting of software packages & documentation. Xnet.sources.bugs For bug fixes and features discussion Xnet.sources.games Postings of recreational software Xnet.sources.mac Software for the Apple Macintosh Xmod.announce General announcements of interest to all. (Moderated) Xmod.announce.newusers Explanatory postings for new users. (Moderated) Xmod.ai Discussions about Artificial Intelligence (Moderated) Xmod.amiga Commodore Amiga micros -- info, uses, but no programs. (Moderated) Xmod.amiga.binaries Encoded public domain programs in binary form. (Moderated) Xmod.amiga.sources Public domain software in source code format. (Moderated) Xmod.compilers Discussion about compiler construction, theory, etc. (Moderated) Xmod.computers Discussion about various computers and related. (Moderated) Xmod.computers.68k 68000-based systems. (Moderated) Xmod.computers.apollo Apollo computer systems. (Moderated) Xmod.computers.masscomp The Masscomp line of computers. (Moderated) Xmod.computers.ibm-pc The IBM PC, PC-XT, and PC-AT. (Moderated) Xmod.computers.laser-printers Laser printers, hardware and software. (Moderated) Xmod.computers.pyramid Pyramid 90x computers. (Moderated) Xmod.computers.ridge Ridge 32 computers and ROS. (Moderated) Xmod.computers.sequent Sequent systems, (esp. Balance 8000). (Moderated) Xmod.computers.sun Sun "workstation" computers (Moderated) Xmod.computers.vax DEC's VAX* line of computers & VMS. (Moderated) Xmod.computers.workstations Various workstation-type computers. (Moderated) Xmod.conferences Calls for papers and conference announcements. (Moderated) Xmod.comp-soc Discussion on the impact of technology on society. (Moderated) Xmod.graphics Graphics software, hardware, theory, etc. (Moderated) Xmod.human-nets Computer aided communications digest. (Moderated) Xmod.mac Apple Macintosh micros -- info, uses, but no programs. (Moderated) Xmod.mac.binaries Encoded public domain programs in binary form. (Moderated) Xmod.mac.sources Public domain software in source code format. (Moderated) Xmod.mag.otherrealms Edited science fiction and fantasy "magazine". (Moderated) Xmod.map Various maps, including UUCP maps (Moderated) Xmod.music Reviews and discussion of things musical (Moderated) Xmod.music.gaffa Progressive music discussions (e.g., Kate Bush). (Moderated) Xmod.newprod Announcements of new products of interest to readers (Moderated) Xmod.newslists Postings of news-related statistics and lists (Moderated) Xmod.os Disussions about operating systems and related areas. (Moderated) Xmod.os.os9 Discussions about the os9 operating system. (Moderated) Xmod.os.unix Discussion of UNIX* features and bugs. (Moderated) Xmod.philosophy Discussion of philosphical issues and concepts. (Moderated) Xmod.philosophy.tech Technical philosophy: math, science, logic, etc (Moderated) Xmod.politics Discussions on political problems, systems, solutions. (Moderated) Xmod.politics.arms-d Arms discussion digest. (Moderated) Xmod.protocols Various forms and types of FTP protocol discussions. (Moderated) Xmod.protocols.appletalk Applebus hardware & software discussion. (Moderated) Xmod.protocols.kermit Information about the Kermit package. (Moderated) Xmod.protocols.tcp-ip TCP and IP network protocols. (Moderated) Xmod.psi Discussion of paranormal abilities and experiences. (Moderated) Xmod.rec Discussions on pastimes (not currently active) (Moderated) Xmod.rec.guns Discussions about firearms (Moderated) Xmod.recipes A "distributed cookbook" of screened recipes. (Moderated) Xmod.religion Top-level group with no moderator (as of yet). (Moderated) Xmod.religion.christian Discussions on Christianity and related topics. (Moderated) Xmod.risks Risks to the public from computers & users. (Moderated) Xmod.sources postings of public-domain sources. (Moderated) Xmod.sources.doc Archived public-domain documentation. (Moderated) Xmod.sources.games Postings of public-domain game sources (Moderated) Xmod.std Discussion about various standards (Moderated) Xmod.std.c Discussion about C language standards (Moderated) Xmod.std.mumps Discussion for the X11.1 committee on Mumps (Moderated) Xmod.std.unix Discussion for the P1003 committee on UNIX (Moderated) Xmod.techreports Announcements and lists of technical reports. (Moderated) Xmod.telecom Telecommunications digest. (Moderated) Xcomp.ai Artificial intelligence discussions. Xcomp.arch Computer architecture. Xcomp.bugs.2bsd Reports of UNIX* version 2BSD related bugs. Xcomp.bugs.4bsd Reports of UNIX version 4BSD related bugs. Xcomp.bugs.misc General bug reports and fixes (includes V7 & uucp). Xcomp.bugs.sys5 Reports of USG (System III, V, etc.) bugs. Xcomp.cog-eng Cognitive engineering. Xcomp.databases Database and data management issues and theory. Xcomp.dcom.lans Local area network hardware and software. Xcomp.dcom.modems Data communications hardware and software. Xcomp.edu Computer science education. Xcomp.emacs EMACS editors of different flavors. Xcomp.graphics Computer graphics, art, animation, image processing, Xcomp.lang.ada Discussion about Ada*. Xcomp.lang.apl Discussion about APL. Xcomp.lang.c Discussion about C. Xcomp.lang.c++ The object-oriented C++ language. Xcomp.lang.forth Discussion about Forth. Xcomp.lang.fortran Discussion about FORTRAN. Xcomp.lang.lisp Discussion about LISP. Xcomp.lang.misc Different computer languages not specifically listed. Xcomp.lang.modula2 Discussion about Modula-2. Xcomp.lang.pascal Discussion about Pascal. Xcomp.lang.prolog Discussion about PROLOG. Xcomp.lang.smalltalk Discussion about Smalltalk 80. Xcomp.lsi Large scale integrated circuits. Xcomp.mail.headers Gatewayed from the ARPA header-people list. Xcomp.mail.misc General discussions about computer mail. Xcomp.mail.uucp Mail in the uucp network environment. Xcomp.misc General topics about computers not covered elsewhere. Xcomp.org.decus DEC* Users' Society newsgroup. Xcomp.org.usenix USENIX Association events and announcements. Xcomp.os.cpm Discussion about the CP/M operating system. Xcomp.os.eunice The SRI Eunice system. Xcomp.os.misc General OS-oriented discussion not carried elsewhere. Xcomp.periphs Peripheral devices. Xcomp.sources.d For any discussion of source postings. Xcomp.sources.wanted Requests for software and fixes. Xcomp.std.internat Discussion about international standards Xcomp.sys.amiga Discussion about the Amiga micro. Xcomp.sys.apple Discussion about Apple micros. Xcomp.sys.atari.8bit Discussion about 8 bit Atari micros. Xcomp.sys.atari.st Discussion about 16 bit Atari micros. Xcomp.sys.att Discussions about AT&T microcomputers Xcomp.sys.cbm Discussion about Commodore micros. Xcomp.sys.dec Discussions about DEC computer systems. Xcomp.sys.hp Discussion about Hewlett/Packard's. Xcomp.sys.ibm.pc Discussion about IBM personal computers. Xcomp.sys.intel Disucussions about Intel systems and parts. Xcomp.sys.m6809 Discussion about 6809's. Xcomp.sys.m68k Discussion about 68k's. Xcomp.sys.mac Discussions about the Apple Macintosh & Lisa. Xcomp.sys.misc Micro computers of all kinds. Xcomp.sys.nsc.32k National Semiconductor 32000 series chips Xcomp.sys.tandy Discussion about TRS-80's. Xcomp.sys.ti Discussion about Texas Instruments. Xcomp.terminals All sorts of terminals. Xcomp.text Text processing. Xcomp.unix.questions UNIX neophytes group. Xcomp.unix.wizards Discussions, bug reports, and fixes on and for UNIX. Xcomp.unix.xenix Discussion about the Xenix OS. Xmisc.consumers Consumer interests, product reviews, etc. Xmisc.consumers.house Discussion about owning and maintaining a house. Xmisc.forsale Short, tasteful postings about items for sale. Xmisc.headlines Current interest: drug testing, terrorism, etc. Xmisc.invest Investments and the handling of money. Xmisc.jobs Job announcements, requests, etc. Xmisc.kids Children, their behavior and activities. Xmisc.legal Legalities and the ethics of law. Xmisc.misc Various discussions not fitting in any other group. Xmisc.taxes Tax laws and advice. Xmisc.test For testing of network software. Very boring. Xmisc.wanted Requests for things that are needed (NOT software). Xnews.admin Comments directed to news administrators. Xnews.config Postings of system down times and interruptions. Xnews.groups Discussions and lists of newsgroups Xnews.lists News-related statistics and lists (Moderated) Xnews.misc Discussions of USENET itself. Xnews.newsites Postings of new site announcements. Xnews.software.b Discussion about B news software. Xnews.software.notes Notesfile software from the Univ. of Illinois. Xnews.stargate Discussion about satellite transmission of news. Xnews.sysadmin Comments directed to system administrators. Xrec.arts.books Books of all genres, shapes, and sizes. Xrec.arts.comics The funnies, old and new. Xrec.arts.drwho Discussion about Dr. Who. Xrec.arts.movies Reviews and discussions of movies. Xrec.arts.poems For the posting of poems. Xrec.arts.sf-lovers Science fiction lovers' newsgroup. Xrec.arts.startrek Star Trek, the TV show and the movies. Xrec.arts.tv The boob tube, its history, and past and current shows. Xrec.arts.tv.soaps Postings about soap operas. Xrec.arts.wobegon "A Prairie Home Companion" radio show discussion. Xrec.audio High fidelity audio. Xrec.autos Automobiles, automotive products and laws. Xrec.autos.tech Technical aspects of automobiles, et. al. Xrec.aviation Aviation rules, means, and methods. Xrec.bicycles Bicycles, related products and laws. Xrec.birds Hobbyists interested in bird watching. Xrec.boats Hobbyists interested in boating. Xrec.food.cooking Food, cooking, cookbooks, and recipes. Xrec.food.drink Wines and spirits. Xrec.food.veg Vegetarians. Xrec.games.board Discussion and hints on board games. Xrec.games.bridge Hobbyists interested in bridge. Xrec.games.chess Chess & computer chess. Xrec.games.empire Discussion and hints about Empire. Xrec.games.frp Discussion about Fantasy Role Playing games. Xrec.games.go Discussion about Go. Xrec.games.hack Discussion, hints, etc. about the Hack game. Xrec.games.misc Games and computer games. Xrec.games.pbm Discussion about Play by Mail games. Xrec.games.rogue Discussion and hints about Rogue. Xrec.games.trivia Discussion about trivia. Xrec.games.video Discussion about video games. Xrec.gardens Gardening, methods and results. Xrec.ham-radio Amateur Radio practices, contests, events, rules, etc. Xrec.ham-radio.packet Discussion about packet radio setups. Xrec.humor Jokes and the like. May be somewhat offensive. Xrec.humor.d Discussions on the content of rec.humor articles Xrec.mag Magazine summaries, tables of contents, etc. Xrec.misc General topics about recreational/participant sports. Xrec.motorcycles Motorcycles and related products and laws. Xrec.music.classical Discussion about classical music. Xrec.music.folk Folks discussing folk music of various sorts Xrec.music.gdead A group for (Grateful) Dead-heads Xrec.music.makers For performers and their discussions. Xrec.music.misc Music lovers' group. Xrec.music.synth Synthesizers and computer music Xrec.nude Hobbyists interested in naturist/nudist activities. Xrec.pets Pets, pet care, and household animals in general. Xrec.photo Hobbyists interested in photography. Xrec.puzzles Puzzles, problems, and quizzes. Xrec.railroad Real and model train fans' newsgroup. Xrec.scuba Hobbyists interested in SCUBA diving. Xrec.skiing Hobbyists interested in skiing. Xrec.skydiving Hobbyists interested in skydiving. Xrec.sport.baseball Discussion about baseball. Xrec.sport.basketball Discussion about basketball. Xrec.sport.football Discussion about football. Xrec.sport.hockey Discussion about hockey. Xrec.sport.misc Spectator sports. Xrec.travel Traveling all over the world. Xrec.video Video and video components. Xrec.woodworking Hobbyists interested in woodworking. Xsci.astro Astronomy discussions and information. Xsci.bio Biology and related sciences. Xsci.crypt Different methods of data en/decryption. Xsci.electronics Circuits, theory, electrons and discussions. Xsci.lang Natural languages, communication, etc. Xsci.math Mathematical discussions and pursuits Xsci.math.stat Statistics discussion. Xsci.math.symbolic Symbolic algebra discussion. Xsci.med Medicine and its related products and regulations. Xsci.misc Short-lived discussions on subjects in the sciences. Xsci.physics Physical laws, properties, etc. Xsci.research Research methods, funding, ethics, and whatever. Xsci.space Space, space programs, space related research, etc. Xsci.space.shuttle The space shuttle and the STS program. Xsoc.college College, college activities, campus life, etc. Xsoc.culture.african Discussions about Africa & things African Xsoc.culture.celtic Group about Celtics (*not* basketball!) Xsoc.culture.greek Group about Greeks. Xsoc.culture.indian Group for discussion about India & things Indian Xsoc.culture.jewish Group for discussion about Jewish culture & religion Xsoc.culture.misc Group for discussion about other cultures Xsoc.misc Socially-oriented topics not in other groups. Xsoc.motss Issues pertaining to homosexuality. Xsoc.roots Genealogical matters. Xsoc.singles Newsgroup for single people, their activities, etc. Xsoc.net-people Announcements, requests, etc. about people on the net. Xsoc.women Women's rights, discrimination, etc. Xtalk.abortion All sorts of discussions and arguments on abortion. Xtalk.bizarre The unusual, bizarre, curious, and often stupid. Xtalk.origins Evolution versus creationism (sometimes hot!). Xtalk.philosophy.misc Philosophical musings on all topics. Xtalk.politics.misc Political discussions and ravings of all kinds. Xtalk.politics.theory Theory of politics and political systems. Xtalk.religion.misc Religious, ethical, & moral implications. Xtalk.rumors For the posting of rumors. XE_O_F X: if active file is empty, create it Xif test ! -s $LIBDIR/active Xthen X sed 's/[ ].*/ 00000 00001/' /tmp/$$groups > $LIBDIR/active X cat <<'E_O_F' >>$LIBDIR/active Xcontrol 00000 00001 Xjunk 00000 00001 XE_O_F X set - group 0 1 Xelse X: make sure it is in the new format X set - `sed 1q $LIBDIR/active` X case $# in X 4) ed - $LIBDIR/active << 'EOF' Xg/^mod\./s/y$/m/ Xw Xq XEOF X ;; X 3) ;; X 2) ed - $LIBDIR/active << 'EOF' X1,$s/$/ 00001/ Xw Xq XEOF X echo X echo Active file updated to new format. X echo You must run expire immediately after this install X echo is done to properly update the tables.;; X *) echo Active file is in unrecognized format. Not upgraded.;; X esac Xfi Xif test $# -eq 3 -o $# -eq 2 Xthen X (sed '/^!net/!d Xs/^!// Xs!^!/! Xs!$! /s/$/ n/! X' $LIBDIR/ngfile X echo '/ n$/!s/$/ y/') >/tmp/$$sed X mv $LIBDIR/active $LIBDIR/oactive X sed -f /tmp/$$sed $LIBDIR/oactive >$LIBDIR/active X chown $NEWSUSR $LIBDIR/active X chgrp $NEWSGRP $LIBDIR/active X chmod 644 $LIBDIR/active Xfi Xsort /tmp/$$groups | $LIBDIR/checkgroups | tee /tmp/checkgroups.out Xecho the output of checkgroups has been copied into /tmp/checkgroups.out Xrm -f /tmp/$$* END_OF_FILE if test 15147 -ne `wc -c <'makeactive.sh'`; then echo shar: \"'makeactive.sh'\" unpacked with wrong size! fi # end of 'makeactive.sh' fi if test -f 'funcs2.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'funcs2.c'\" else echo shar: Extracting \"'funcs2.c'\" \(14115 characters\) sed "s/^X//" >'funcs2.c' <<'END_OF_FILE' X/* X * This software is Copyright (c) 1985 by Rick Adams. X * X * Permission is hereby granted to copy, reproduce, redistribute or X * otherwise use this software as long as: there is no monetary X * profit gained specifically from the use or reproduction or this X * software, it is not sold, rented, traded or otherwise marketed, and X * this copyright notice is included prominently in any copy X * made. X * X * The author make no claims as to the fitness or correctness of X * this software for any use whatsoever, and it is provided as is. X * Any use of this software is at the user's own risk. X * X * X * funcs2 - functions used by both inews and readnews. X */ X X#ifdef SCCSID Xstatic char *SccsId = "@(#)funcs2.c 1.20 3/20/87"; X#endif /* SCCSID */ X X#include "params.h" X X#ifdef SunIII X#ifndef INTERNET X#define INTERNET X#endif /* !INTERNET */ X#endif /* SunIII */ X X/*LINTLIBRARY*/ X X/* X * Get user name and home directory. X */ Xgetuser() X{ X static int flag = TRUE; X register struct passwd *p; X X if (flag) { X if ((p = getpwuid(uid)) == NULL) X xerror("Cannot get user's name"); X if ( username == NULL || username[0] == 0) X username = AllocCpy(p->pw_name); X userhome = AllocCpy(p->pw_dir); X flag = FALSE; X } X (void) strcpy(header.path, username); X} X Xstatic FILE *sysfile; X Xchar *fldget(); X Xstatic int sfline; X X/* X * Open SUBFILE. X */ Xs_openr() X{ X fprintf(stderr,"Opening subfile, %s\n",SUBFILE); X sysfile = xfopen(SUBFILE, "r"); X sfline = 0; X} X X/* X * Read SUBFILE. X */ Xs_read(sp) Xregister struct srec *sp; X{ X register char *p; X register int c; X char *e; X int chop_spaces = 0; Xagain: X p = bfr; X /* X * Read the SUBFILE (/usr/lib/news/sys) from the current X * position to the first unescaped newline. If a newline is X * escaped with a backslash (\) continue reading but throw away X * the backslash and newline; read the next line skipping spaces X * and tabs until the first non-space/tab character, then start X * looking for a newline again. Skipping the leading X * spaces/tabs after a escaped newline keeps the news groups X * together. If a line begins with a newline, just skip it. X */ X for (e=p+LBUFLEN; p < e && (c=getc(sysfile)) != EOF; p++) { X *p = c; X if (c == '\n') { X sfline++; X if (p == bfr || p[-1] != '\\') { X p[1] = '\0'; X break; X } else { X chop_spaces++; X p -= 2; X } X } else if (chop_spaces) { X if (c == '\t' || c == ' ') X p--; X else X chop_spaces = 0; X } X } X if (c == EOF) { X return FALSE; X } X p = bfr; X while (*p == ' ' || *p == '\t') /* skip leading white space */ X p++; X if (*p == '\n') X goto again; /* skip newlines */ X if (!nstrip(p)) X xerror("SUBFILE (%s) line %d too long.", SUBFILE, sfline); X if (*p == '#') X goto again; X sp->s_xmit[0] = '\0'; X sp->s_flags[0] = '\0'; X sp->s_nosend = (char *)0; X X p = fldget(sp->s_name, p); X if (*p++ == '\0') X xerror("Bad SUBFILE (%s) line %d.", SUBFILE, sfline); X /* X * A sys file line reading "ME" means the name of the local system. X */ X if (strcmp(sp->s_name, "ME") == 0) X (void) strcpy(sp->s_name, LOCALPATHSYSNAME); X e = index(sp->s_name, '/'); X if (e) { X *e++ = '\0'; X sp->s_nosend = e; X } X p = fldget(sp->s_nbuf, p); X lcase(sp->s_nbuf); X if (*p++ == '\0') X return TRUE; X X p = fldget(sp->s_flags, p); X if (*p++ == '\0') X return TRUE; X X (void) fldget(sp->s_xmit, p); X return TRUE; X} X Xchar * Xfldget(q, p) Xregister char *q, *p; X{ X while (*p && *p != ':') { X if (*p == '\\' && p[1]==':') X p++; X *q++ = *p++; X } X *q = '\0'; X return p; X} X X/* X * Find the SUBFILE record for a system. X */ Xs_find(sp, system) Xregister struct srec *sp; Xchar *system; X{ X s_openr(); X while (s_read(sp)) X if (strncmp(system, sp->s_name, SNLN) == 0) { X s_close(); X return TRUE; X } X s_close(); X return FALSE; X} X X/* X * Close sysfile. X */ Xs_close() X{ X (void) fclose(sysfile); X} X Xextern struct timeb Now; X Xtime_t Xcgtdate(datestr) Xchar *datestr; X{ X char junk[40],month[40],day[30],tod[60],year[50]; X static time_t lasttime; X static char lastdatestr[BUFLEN] = ""; X X if ( lastdatestr[0] && strcmp(datestr, lastdatestr) == 0) X return lasttime; X lasttime = getdate(datestr, &Now); X if (lasttime < 0 && X sscanf(datestr, "%s %s %s %s %s", junk, month, day, tod, year) == 5) { X (void) sprintf(bfr, "%s %s, %s %s", month, day, year, tod); X lasttime = getdate(bfr, &Now); X } X strncpy(lastdatestr, datestr, BUFLEN); X return lasttime; X} X Xlcase(s) Xregister char *s; X{ X register char *ptr; X X for (ptr = s; *ptr; ptr++) X if (isupper(*ptr)) X *ptr = tolower(*ptr); X} X X/* X * Return a compact representation of the person who posted the given X * message. A sender or internet name will be used, otherwise X * the last part of the path is used preceded by an optional ".." X */ Xchar * Xtailpath(hp) Xstruct hbuf *hp; X{ X char *p, *r; X static char resultbuf[BUFLEN]; X char pathbuf[PATHLEN]; X char *malloc(); X X /* X * This only happens for articles posted by old news software X * in non-internet format. X */ X resultbuf[0] = '\0'; X (void) strncpy(pathbuf, hp->path, PATHLEN); X p = index(pathbuf, ' '); X if (p) X *p = '\0'; /* Chop off trailing " (name)" */ X r = rindex(pathbuf, '!'); X if (r == 0) { X r = pathbuf; X } else { X while (r > pathbuf && *--r != '!') X ; X if (r > pathbuf) { X r++; X (void) strcpy(resultbuf, "..!"); X } X } X (void) strcat(resultbuf, r); X return resultbuf; X} X X/* X * arpadate is like ctime(3) except that the time is returned in X * an acceptable ARPANET time format instead of ctime format. X */ Xchar * Xarpadate(longtime) Xtime_t *longtime; X{ X register char *p, *q, *ud; X register int i; X static char b[40]; X extern struct tm *gmtime(); X X#ifndef MINIX X extern char *asctime(); X X /* Get current time. This will be used resolve the timezone. */ X ud = asctime(gmtime(longtime)); X#else X /* Get current time. This will be used resolve the timezone. */ X ud = ctime(longtime); X#endif X X /* Crack the UNIX date line in a singularly unoriginal way. */ X q = b; X X#ifdef notdef X/* until every site installs the fix to getdate.y, the day X of the week can cause time warps */ X p = &ud[0]; /* Mon */ X *q++ = *p++; X *q++ = *p++; X *q++ = *p++; X *q++ = ','; *q++ = ' '; X#endif X X p = &ud[8]; /* 16 */ X if (*p == ' ') X p++; X else X *q++ = *p++; X *q++ = *p++; *q++ = ' '; X X p = &ud[4]; /* Sep */ X *q++ = *p++; *q++ = *p++; *q++ = *p++; *q++ = ' '; X X p = &ud[22]; /* 1979 */ X *q++ = *p++; *q++ = *p++; *q++ = ' '; X X p = &ud[11]; /* 01:03:52 */ X for (i = 8; i > 0; i--) X *q++ = *p++; X X *q++ = ' '; X *q++ = 'G'; /* GMT */ X *q++ = 'M'; X *q++ = 'T'; X *q = '\0'; X X fprintf(stderr,"arpadate 2 asctime: %s\n",b); X return b; X} X Xchar * Xreplyname(hptr) Xstruct hbuf *hptr; X{ X register char *ptr; X static char tbuf[PATHLEN]; X X ptr = hptr->path; X if (prefix(ptr, PATHSYSNAME) && X index(NETCHRS, ptr[strlen(PATHSYSNAME)])) X ptr = index(ptr, '!') + 1; X#ifdef INTERNET X if (hptr->from[0]) X ptr = hptr->from; X if (hptr->replyto[0]) X ptr = hptr->replyto; X#endif X (void) strcpy(tbuf, ptr); X ptr = index(tbuf, '('); X if (ptr) { X while (ptr[-1] == ' ') X ptr--; X *ptr = 0; X } X#ifdef SunIII X if (ptr = rindex(tbuf, '.')) { X if (prefix(++ptr, "OZ")) { X /* some people only allow it in lower case ... */ X strcpy(ptr, "oz"); X return tbuf; X } X if (prefix(ptr, "UUCP") || prefix(ptr, "ARPA") || X prefix(ptr, "DEC") || prefix(ptr, "CSNET")) { X strcat(tbuf, "@munnari.oz"); /* via sun to munnari */ X return tbuf; X } X } X /* X * must(?) have come from a uucp site, lets look see if path passes X * through munnari, and if so delete the fake uucp path after that. X */ X for (ptr = tbuf ;; ptr++) { X if (prefix(ptr, "munnari!")) { X strcpy(tbuf, ptr+8); X break; X } X ptr = index(ptr, '!'); X if (ptr == (char *)0) X break; X } X /* X * now, just send the address we have left to munnari, and X * hope that something sensible will be done with it there. X * (This works in more cases than you'd think ...) X */ X strcat(tbuf, "@munnari.oz"); X#else /* !SunIII */ X#ifndef INTERNET X /* X * Play games stripping off multiple berknet X * addresses (a!b!c:d:e => a!b!d:e) here. X */ X for (ptr=tbuf; *ptr; ptr++) { X register char *ptr2; X X if (index(NETCHRS, *ptr) && *ptr == ':' && X (ptr2=index(ptr+1, ':'))) X (void) strcpy(ptr, ptr2); X } X#else /* INTERNET */ X { X char mbuf[BUFLEN], modadd[BUFLEN]; X FILE *mfd; X /* Let's find a path to the backbone */ X sprintf(mbuf, "%s/mailpaths", LIB); X mfd = xfopen(mbuf, "r"); X do { X if (fgets(mbuf, sizeof mbuf, mfd) == NULL) X xerror("Can't find internet in %s/mailpaths", X LIB); X } while (!prefix(mbuf, "internet")); X if (sscanf(mbuf, "%*s %s", modadd) != 1) X xerror("backbone address corrupted"); X (void) fclose(mfd); X (void)strcpy(mbuf, tbuf); X /* If we are lucky, there is no ! or @ in the forward address */ X if (strpbrk(modadd, "!@") == NULL) { X sprintf(tbuf, modadd, mbuf); X } else { X char *cp = index(mbuf, '@'); X if (index(modadd, '@') == NULL && cp) { X /* we have to rearrange the address so no @ are in it */ X char atbuf[BUFLEN]; X *cp++ = '\0'; X sprintf(atbuf, "%s!%s", cp, mbuf); X sprintf(tbuf, modadd, atbuf); X } else if (cp) { X /* some days you don't get lucky. presume the % hack */ X *cp = '%'; X sprintf(tbuf, modadd, mbuf); X } X } X } X#endif /* INTERNET */ X#endif /* !SunIII */ X return tbuf; X} X X#ifdef DBM Xtypedef struct { X char *dptr; X int dsize; X} datum; X#endif /* DBM */ X X/* X * Given an article ID, find the line in the history file that mentions it. X * Return the text of the line, or NULL if not found. A pointer to a X * static area is returned. X */ Xchar * Xfindhist(artid) Xchar *artid; X{ X static char lbuf[256]; X char oidbuf[BUFSIZ]; X FILE *hfp; X register char *p; X#ifdef DBM X datum lhs, rhs; X datum fetch(); X long fpos; /* We have to use an explicit variable to insure alignment */ X#else /* !DBM */ X char *histfile(); X#endif /* !DBM */ X X /* Try to understand old artid's as well. Assume .UUCP domain. */ X if (artid[0] != '<') { X p = index(artid, '.'); X if (p) X *p++ = '\0'; X (void) sprintf(oidbuf, "<%s@%s.UUCP>", p, artid); X if (p) X *--p = '.'; X } else X (void) strcpy(oidbuf, artid); X lcase(oidbuf); X#ifdef DBM X initdbm(ARTFILE); X lhs.dptr = oidbuf; X lhs.dsize = strlen(lhs.dptr) + 1; X rhs = fetch(lhs); X if (rhs.dptr == NULL) X return NULL; X hfp = xfopen(ARTFILE, "r"); X /* The bcopy is NECESSARY to insure alignment on some machines */ X xbcopy(rhs.dptr, (char *)&fpos, sizeof (long)); X fseek(hfp, fpos, 0); X#else /* !DBM */ X hfp = xfopen(histfile(oidbuf), "r"); X#endif /* !DBM */ X while (fgets(lbuf, BUFLEN, hfp) != NULL) { X p = index(lbuf, '\t'); X if (p == NULL) X p = index(lbuf, '\n'); X *p = 0; X if (strcmp(lbuf, artid) == 0 || strcmp(lbuf, oidbuf) == 0) { X (void) fclose(hfp); X *p = '\t'; X *(lbuf + strlen(lbuf) - 1) = 0; /* zap the \n */ X return lbuf; X } X#ifdef DBM X break; X#endif /* DBM */ X } X (void) fclose(hfp); X return NULL; X} X X/* X * Hunt up the article "artid", and return the newsgroup/artnum X * where it can be found. X */ Xchar * Xfindfname(artid) Xchar *artid; X{ X char *line, *p, *q; X char *findhist(); X static char fname[BUFLEN]; X X line = findhist(artid); X if (line) { X /* Look for it stored as an article, where it should be */ X p = index(line, '\t'); X p = index(p+1, '\t'); X p++; X if (*p) { X q = index(p, ' '); X if (q) X *q = 0; X (void) strcpy(fname, p); X return fname; X } X } X return NULL; X} X X/* X * Hunt up the article "artid", fopen it for read, and return a X * file descriptor to it. We look everywhere we can think of. X */ XFILE * Xhfopen(artid) Xchar *artid; X{ X char *p; X char *findhist(); X FILE *rv = NULL; X char fname[BUFLEN]; X X p = findfname(artid); X if (p) { X (void) strcpy(fname, dirname(p)); X rv = fopen(fname, "r"); /* NOT xfopen! */ X if (rv == NULL) X xerror("Cannot hfopen article %s", artid); X } X return rv; X} X X#ifdef DBM X/* X** Avoid problems of multiple dbminit calls. X*/ Xinitdbm(name) Xchar *name; X{ X static int called = 0; X X if (called != 0) X return; X called = 1; X (void) dbminit(name); X} X#endif X X/* X * move n bytes from a to b X */ Xxbcopy(a, b, n) Xregister char *a, *b; Xregister n; X{ X while (--n >= 0) X *b++ = *a++; X} X X#if !defined(BSD4_2) && !defined(BSD4_1C) Xrename(from,to) Xregister char *from, *to; X{ X (void) unlink(to); X if (link(from, to) < 0) X return -1; X X (void) unlink(from); X return 0; X} X#endif /* !BSD4_2 && ! BSD4_1C */ X X#ifndef DBM X/* X** Generate the appropriate history subfile name X*/ Xchar * Xhistfile(hline) Xchar *hline; X{ X char chr; /* least significant digit of article number */ X static char subfile[BUFLEN]; X X chr = findhfdigit(hline); X sprintf(subfile, "%s.d/%c", ARTFILE, chr); X return subfile; X} X Xfindhfdigit(fn) Xchar *fn; X{ X register char *p; X register int chr; X X p = index(fn, '@'); X if (p != NULL && p > fn) X chr = *(p - 1); X else X chr = '0'; X if (!isdigit(chr)) X chr = '0'; X return chr; X} X#endif /* !DBM */ X X#ifdef VMS X/* X * These functions open an article with one level of indirection, X * to support symbolic links. xart_open exits if the open fails. X */ XFILE * Xxart_open (filename,mode) Xchar *filename,*mode; X{ X FILE *fp = art_open (filename, mode); X extern int errno; X if (fp == NULL) X xerror("Cannot open article %s (%s): %s\n", X filename, mode, errmsg(errno)); X return fp; X} X XFILE * Xart_open (filename,mode) Xchar *filename,*mode; X{ X char linkfile[BUFSIZ]; X FILE *fp; X X if ((fp = fopen (filename, mode)) == NULL) X return NULL; X if (fgets (linkfile, BUFSIZ, fp) == NULL || linkfile[0] != '/') { X rewind (fp); X return fp; X } X/* Chase the symbolic link. */ X (void) fclose (fp); X if ((fp = fopen (linkfile, mode)) == NULL) X/* Clean up dangling link, if we have the power. Ignore error if we don't. */ X (void) unlink (filename); X return fp; X} X#endif /* VMS */ X X/* X * Generate the name of the person responsible for posting this article, X * in order to check that two articles were posted by the same person. X */ Xchar * Xsenderof(hp) Xstruct hbuf *hp; X{ X register char *r, *q, *tp; X char *tailpath(); X static char senderbuf[BUFLEN]; X X if (hp->sender[0]) X tp = hp->sender; X else if (hp->from[0]) X tp = hp->from; X else X tp = tailpath(hp); X X (void) strncpy(senderbuf, tp, BUFLEN); X /* Remove full name */ X q = index(senderbuf, ' '); X if (q) X *q = '\0'; X X return senderbuf; X} END_OF_FILE if test 14115 -ne `wc -c <'funcs2.c'`; then echo shar: \"'funcs2.c'\" unpacked with wrong size! fi # end of 'funcs2.c' fi if test -f 'getdate.y' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'getdate.y'\" else echo shar: Extracting \"'getdate.y'\" \(12591 characters\) sed "s/^X//" >'getdate.y' <<'END_OF_FILE' X%token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO X%{ X /* Originally from: Steven M. Bellovin (unc!smb) */ X /* Dept. of Computer Science */ X /* University of North Carolina at Chapel Hill */ X /* @(#)getdate.y 2.15 12/16/86 */ X X#include X#ifdef USG Xstruct timeb X{ X time_t time; X unsigned short millitm; X short timezone; X short dstflag; X}; X#else X#include X#endif X#include X X#include "defs.h" X#if defined(BSD4_2) || defined (BSD4_1C) X#include X#else /* sane */ X#include X#endif /* sane */ X X#define NULL 0 X#define daysec (24L*60L*60L) X static int timeflag, zoneflag, dateflag, dayflag, relflag; X static time_t relsec, relmonth; X static int hh, mm, ss, merid, daylight; X static int dayord, dayreq; X static int month, day, year; X static int ourzone; X#define AM 1 X#define PM 2 X#define DAYLIGHT 1 X#define STANDARD 2 X#define MAYBE 3 X%} X X%% Xtimedate: /* empty */ X | timedate item; X Xitem: tspec = X {timeflag++;} X | zone = X {zoneflag++;} X | dtspec = X {dateflag++;} X | dyspec = X {dayflag++;} X | rspec = X {relflag++;} X | nspec; X Xnspec: NUMBER = X {if (timeflag && dateflag && !relflag) year = $1; X else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}}; X Xtspec: NUMBER MERIDIAN = X {hh = $1; mm = 0; ss = 0; merid = $2;} X | NUMBER ':' NUMBER = X {hh = $1; mm = $3; merid = 24;} X | NUMBER ':' NUMBER MERIDIAN = X {hh = $1; mm = $3; merid = $4;} X | NUMBER ':' NUMBER NUMBER = X {hh = $1; mm = $3; merid = 24; X daylight = STANDARD; ourzone = -($4%100 + 60*($4/100));} X | NUMBER ':' NUMBER ':' NUMBER = X {hh = $1; mm = $3; ss = $5; merid = 24;} X | NUMBER ':' NUMBER ':' NUMBER MERIDIAN = X {hh = $1; mm = $3; ss = $5; merid = $6;} X | NUMBER ':' NUMBER ':' NUMBER NUMBER = X {hh = $1; mm = $3; ss = $5; merid = 24; X daylight = STANDARD; ourzone = -($6%100 + 60*($6/100));}; X Xzone: ZONE = X {ourzone = $1; daylight = STANDARD;} X | DAYZONE = X {ourzone = $1; daylight = DAYLIGHT;}; X Xdyspec: DAY = X {dayord = 1; dayreq = $1;} X | DAY ',' = X {dayord = 1; dayreq = $1;} X | NUMBER DAY = X {dayord = $1; dayreq = $2;}; X Xdtspec: NUMBER '/' NUMBER = X {month = $1; day = $3;} X | NUMBER '/' NUMBER '/' NUMBER = X {month = $1; day = $3; year = $5;} X | MONTH NUMBER = X {month = $1; day = $2;} X | MONTH NUMBER ',' NUMBER = X {month = $1; day = $2; year = $4;} X | NUMBER MONTH = X {month = $2; day = $1;} X | NUMBER MONTH NUMBER = X {month = $2; day = $1; year = $3;}; X X Xrspec: NUMBER UNIT = X {relsec += 60L * $1 * $2;} X | NUMBER MUNIT = X {relmonth += $1 * $2;} X | NUMBER SUNIT = X {relsec += $1;} X | UNIT = X {relsec += 60L * $1;} X | MUNIT = X {relmonth += $1;} X | SUNIT = X {relsec++;} X | rspec AGO = X {relsec = -relsec; relmonth = -relmonth;}; X%% X Xstatic int mdays[12] = X {31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; X#define epoch 1970 X Xextern struct tm *localtime(); X Xtime_t Xdateconv(mm, dd, yy, h, m, s, mer, zone, dayflag) Xint mm, dd, yy, h, m, s, mer, zone, dayflag; X{ X time_t tod, jdate; X register int i; X time_t timeconv(); X X if (yy < 0) yy = -yy; X if (yy < 100) yy += 1900; X mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0)); X if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 || X dd < 1 || dd > mdays[--mm]) return (-1); X jdate = dd-1; X for (i=0; itm_isdst)) X jdate += -1*60*60; X return (jdate); X} X Xtime_t Xdayconv(ord, day, now) Xint ord, day; time_t now; X{ X register struct tm *loctime; X time_t tod; X time_t daylcorr(); X X tod = now; X loctime = localtime(&tod); X tod += daysec * ((day - loctime->tm_wday + 7) % 7); X tod += 7*daysec*(ord<=0?ord:ord-1); X return daylcorr(tod, now); X} X Xtime_t Xtimeconv(hh, mm, ss, mer) Xregister int hh, mm, ss, mer; X{ X if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1); X switch (mer) { X case AM: if (hh < 1 || hh > 12) return(-1); X return (60L * ((hh%12)*60L + mm)+ss); X case PM: if (hh < 1 || hh > 12) return(-1); X return (60L * ((hh%12 +12)*60L + mm)+ss); X case 24: if (hh < 0 || hh > 23) return (-1); X return (60L * (hh*60L + mm)+ss); X default: return (-1); X } X} Xtime_t Xmonthadd(sdate, relmonth) Xtime_t sdate, relmonth; X{ X struct tm *ltime; X time_t dateconv(); X time_t daylcorr(); X int mm, yy; X X if (relmonth == 0) return 0; X ltime = localtime(&sdate); X mm = 12*ltime->tm_year + ltime->tm_mon + relmonth; X yy = mm/12; X mm = mm%12 + 1; X return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour, X ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate); X} X Xtime_t Xdaylcorr(future, now) Xtime_t future, now; X{ X int fdayl, nowdayl; X X nowdayl = (localtime(&now)->tm_hour+1) % 24; X fdayl = (localtime(&future)->tm_hour+1) % 24; X return (future-now) + 60L*60L*(nowdayl-fdayl); X} X Xstatic char *lptr; X Xyylex() X{ X extern int yylval; X int sign; X register char c; X register char *p; X char idbuf[20]; X int pcnt; X X for (;;) { X while (isspace(*lptr)) X lptr++; X X if (isdigit(c = *lptr) || c == '-' || c == '+') { X if (c== '-' || c == '+') { X if (c=='-') sign = -1; X else sign = 1; X if (!isdigit(*++lptr)) { X /* yylval = sign; return (NUMBER); */ X return yylex(); /* skip the '-' sign */ X } X } else sign = 1; X yylval = 0; X while (isdigit(c = *lptr++)) X yylval = 10*yylval + c - '0'; X yylval *= sign; X lptr--; X return (NUMBER); X X } else if (isalpha(c)) { X p = idbuf; X while (isalpha(c = *lptr++) || c=='.') X *p++ = c; X *p = '\0'; X lptr--; X return (lookup(idbuf)); X } X X else if (c == '(') { X pcnt = 0; X do { X c = *lptr++; X if (c == '\0') return(c); X else if (c == '(') pcnt++; X else if (c == ')') pcnt--; X } while (pcnt > 0); X } X X else return (*lptr++); X } X} X Xstruct table { X char *name; X int type, value; X}; X Xstruct table mdtab[] = { X {"january", MONTH, 1}, X {"february", MONTH, 2}, X {"march", MONTH, 3}, X {"april", MONTH, 4}, X {"may", MONTH, 5}, X {"june", MONTH, 6}, X {"july", MONTH, 7}, X {"august", MONTH, 8}, X {"september", MONTH, 9}, X {"sept", MONTH, 9}, X {"october", MONTH, 10}, X {"november", MONTH, 11}, X {"december", MONTH, 12}, X X {"sunday", DAY, 0}, X {"monday", DAY, 1}, X {"tuesday", DAY, 2}, X {"tues", DAY, 2}, X {"wednesday", DAY, 3}, X {"wednes", DAY, 3}, X {"thursday", DAY, 4}, X {"thur", DAY, 4}, X {"thurs", DAY, 4}, X {"friday", DAY, 5}, X {"saturday", DAY, 6}, X {0, 0, 0}}; X X#define HRS *60 X#define HALFHR 30 Xstruct table mztab[] = { X {"a.m.", MERIDIAN, AM}, X {"am", MERIDIAN, AM}, X {"p.m.", MERIDIAN, PM}, X {"pm", MERIDIAN, PM}, X {"nst", ZONE, 3 HRS + HALFHR}, /* Newfoundland */ X {"n.s.t.", ZONE, 3 HRS + HALFHR}, X {"ast", ZONE, 4 HRS}, /* Atlantic */ X {"a.s.t.", ZONE, 4 HRS}, X {"adt", DAYZONE, 4 HRS}, X {"a.d.t.", DAYZONE, 4 HRS}, X {"est", ZONE, 5 HRS}, /* Eastern */ X {"e.s.t.", ZONE, 5 HRS}, X {"edt", DAYZONE, 5 HRS}, X {"e.d.t.", DAYZONE, 5 HRS}, X {"cst", ZONE, 6 HRS}, /* Central */ X {"c.s.t.", ZONE, 6 HRS}, X {"cdt", DAYZONE, 6 HRS}, X {"c.d.t.", DAYZONE, 6 HRS}, X {"mst", ZONE, 7 HRS}, /* Mountain */ X {"m.s.t.", ZONE, 7 HRS}, X {"mdt", DAYZONE, 7 HRS}, X {"m.d.t.", DAYZONE, 7 HRS}, X {"pst", ZONE, 8 HRS}, /* Pacific */ X {"p.s.t.", ZONE, 8 HRS}, X {"pdt", DAYZONE, 8 HRS}, X {"p.d.t.", DAYZONE, 8 HRS}, X {"yst", ZONE, 9 HRS}, /* Yukon */ X {"y.s.t.", ZONE, 9 HRS}, X {"ydt", DAYZONE, 9 HRS}, X {"y.d.t.", DAYZONE, 9 HRS}, X {"hst", ZONE, 10 HRS}, /* Hawaii */ X {"h.s.t.", ZONE, 10 HRS}, X {"hdt", DAYZONE, 10 HRS}, X {"h.d.t.", DAYZONE, 10 HRS}, X X {"gmt", ZONE, 0 HRS}, X {"g.m.t.", ZONE, 0 HRS}, X {"bst", DAYZONE, 0 HRS}, /* British Summer Time */ X {"b.s.t.", DAYZONE, 0 HRS}, X {"eet", ZONE, 0 HRS}, /* European Eastern Time */ X {"e.e.t.", ZONE, 0 HRS}, X {"eest", DAYZONE, 0 HRS}, /* European Eastern Summer Time */ X {"e.e.s.t.", DAYZONE, 0 HRS}, X {"met", ZONE, -1 HRS}, /* Middle European Time */ X {"m.e.t.", ZONE, -1 HRS}, X {"mest", DAYZONE, -1 HRS}, /* Middle European Summer Time */ X {"m.e.s.t.", DAYZONE, -1 HRS}, X {"wet", ZONE, -2 HRS }, /* Western European Time */ X {"w.e.t.", ZONE, -2 HRS }, X {"west", DAYZONE, -2 HRS}, /* Western European Summer Time */ X {"w.e.s.t.", DAYZONE, -2 HRS}, X X {"jst", ZONE, -9 HRS}, /* Japan Standard Time */ X {"j.s.t.", ZONE, -9 HRS}, /* Japan Standard Time */ X /* No daylight savings time */ X X {"aest", ZONE, -10 HRS}, /* Australian Eastern Time */ X {"a.e.s.t.", ZONE, -10 HRS}, X {"aesst", DAYZONE, -10 HRS}, /* Australian Eastern Summer Time */ X {"a.e.s.s.t.", DAYZONE, -10 HRS}, X {"acst", ZONE, -(9 HRS + HALFHR)}, /* Australian Central Time */ X {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)}, X {"acsst", DAYZONE, -(9 HRS + HALFHR)}, /* Australian Central Summer */ X {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)}, X {"awst", ZONE, -8 HRS}, /* Australian Western Time */ X {"a.w.s.t.", ZONE, -8 HRS}, /* (no daylight time there, I'm told */ X {0, 0, 0}}; X Xstruct table unittb[] = { X {"year", MUNIT, 12}, X {"month", MUNIT, 1}, X {"fortnight", UNIT, 14*24*60}, X {"week", UNIT, 7*24*60}, X {"day", UNIT, 1*24*60}, X {"hour", UNIT, 60}, X {"minute", UNIT, 1}, X {"min", UNIT, 1}, X {"second", SUNIT, 1}, X {"sec", SUNIT, 1}, X {0, 0, 0}}; X Xstruct table othertb[] = { X {"tomorrow", UNIT, 1*24*60}, X {"yesterday", UNIT, -1*24*60}, X {"today", UNIT, 0}, X {"now", UNIT, 0}, X {"last", NUMBER, -1}, X {"this", UNIT, 0}, X {"next", NUMBER, 2}, X {"first", NUMBER, 1}, X /* {"second", NUMBER, 2}, */ X {"third", NUMBER, 3}, X {"fourth", NUMBER, 4}, X {"fifth", NUMBER, 5}, X {"sixth", NUMBER, 6}, X {"seventh", NUMBER, 7}, X {"eigth", NUMBER, 8}, X {"ninth", NUMBER, 9}, X {"tenth", NUMBER, 10}, X {"eleventh", NUMBER, 11}, X {"twelfth", NUMBER, 12}, X {"ago", AGO, 1}, X {0, 0, 0}}; X Xstruct table milzone[] = { X {"a", ZONE, 1 HRS}, X {"b", ZONE, 2 HRS}, X {"c", ZONE, 3 HRS}, X {"d", ZONE, 4 HRS}, X {"e", ZONE, 5 HRS}, X {"f", ZONE, 6 HRS}, X {"g", ZONE, 7 HRS}, X {"h", ZONE, 8 HRS}, X {"i", ZONE, 9 HRS}, X {"k", ZONE, 10 HRS}, X {"l", ZONE, 11 HRS}, X {"m", ZONE, 12 HRS}, X {"n", ZONE, -1 HRS}, X {"o", ZONE, -2 HRS}, X {"p", ZONE, -3 HRS}, X {"q", ZONE, -4 HRS}, X {"r", ZONE, -5 HRS}, X {"s", ZONE, -6 HRS}, X {"t", ZONE, -7 HRS}, X {"u", ZONE, -8 HRS}, X {"v", ZONE, -9 HRS}, X {"w", ZONE, -10 HRS}, X {"x", ZONE, -11 HRS}, X {"y", ZONE, -12 HRS}, X {"z", ZONE, 0 HRS}, X {0, 0, 0}}; X Xlookup(id) Xchar *id; X{ X#define gotit (yylval=i->value, i->type) X X char idvar[128]; X register char *j, *k; X register struct table *i; X int abbrev; X X (void) strcpy(idvar, id); X j = idvar; X k = id - 1; X while (*++k) X *j++ = isupper(*k) ? tolower(*k) : *k; X *j = '\0'; X X if (strlen(idvar) == 3) X abbrev = 1; X else X if (strlen(idvar) == 4 && idvar[3] == '.') { X abbrev = 1; X idvar[3] = '\0'; X } X else X abbrev = 0; X X for (i = mdtab; i->name; i++) { X k = idvar; X for (j = i->name; *j++ == *k++;) { X if (abbrev && j == i->name+3) X return gotit; X if (j[-1] == 0) X return gotit; X } X } X X for (i = mztab; i->name; i++) X if (strcmp(i->name, idvar) == 0) X return gotit; X X for (i=mztab; i->name; i++) X if (strcmp(i->name, idvar) == 0) X return gotit; X X for (i=unittb; i->name; i++) X if (strcmp(i->name, idvar) == 0) X return gotit; X X if (idvar[strlen(idvar)-1] == 's') X idvar[strlen(idvar)-1] = '\0'; X X for (i=unittb; i->name; i++) X if (strcmp(i->name, idvar) == 0) X return gotit; X X for (i = othertb; i->name; i++) X if (strcmp(i->name, idvar) == 0) X return gotit; X X if (strlen(idvar) == 1 && isalpha(*idvar)) { X for (i = milzone; i->name; i++) X if (strcmp(i->name, idvar) == 0) X return gotit; X } X X return ID; X} X Xtime_t Xgetdate(p, now) Xchar *p; Xstruct timeb *now; X{ X#define mcheck(f) if (f>1) err++ X time_t monthadd(); X int err; X struct tm *lt; X struct timeb ftz; X X time_t sdate, tod; X X lptr = p; X if (now == ((struct timeb *) NULL)) { X now = &ftz; X ftime(&ftz); X } X lt = localtime(&now->time); X year = lt->tm_year; X month = lt->tm_mon+1; X day = lt->tm_mday; X relsec = 0; relmonth = 0; X timeflag=zoneflag=dateflag=dayflag=relflag=0; X ourzone = now->timezone; X daylight = MAYBE; X hh = mm = ss = 0; X merid = 24; X X if (err = yyparse()) return (-1); X X mcheck(timeflag); X mcheck(zoneflag); X mcheck(dateflag); X mcheck(dayflag); X X if (err) return (-1); X if (dateflag || timeflag || dayflag) { X sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylight); X if (sdate < 0) return -1; X } X else { X sdate = now->time; X if (relflag == 0) X sdate -= (lt->tm_sec + lt->tm_min*60 + X lt->tm_hour*(60L*60L)); X } X X sdate += relsec; X sdate += monthadd(sdate, relmonth); X X if (dayflag && !dateflag) { X tod = dayconv(dayord, dayreq, sdate); X sdate += tod; X } X X return sdate; X} X Xyyerror(s) char *s; X{} END_OF_FILE if test 12591 -ne `wc -c <'getdate.y'`; then echo shar: \"'getdate.y'\" unpacked with wrong size! fi # end of 'getdate.y' fi if test -f 'funcs.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'funcs.c'\" else echo shar: Extracting \"'funcs.c'\" \(12952 characters\) sed "s/^X//" >'funcs.c' <<'END_OF_FILE' X/* X * This software is Copyright (c) 1986 by Rick Adams. X * X * Permission is hereby granted to copy, reproduce, redistribute or X * otherwise use this software as long as: there is no monetary X * profit gained specifically from the use or reproduction or this X * software, it is not sold, rented, traded or otherwise marketed, and X * this copyright notice is included prominently in any copy X * made. X * X * The author make no claims as to the fitness or correctness of X * this software for any use whatsoever, and it is provided as is. X * Any use of this software is at the user's own risk. X * X * funcs - functions used by many programs X */ X X#ifdef SCCSID Xstatic char *SccsId = "@(#)funcs.c 2.35 12/16/86"; X#endif /* SCCSID */ X X/*LINTLIBRARY*/ X X#include "params.h" X#include X#if defined(USG) || defined(BSD4_2) || defined(BSD4_1C) X#include X#endif /* !v7 */ X Xextern char *Progname; X X/* X * News group matching. X * X * nglist is a list of newsgroups. X * sublist is a list of subscriptions. X * sublist may have "meta newsgroups" in it. X * All fields are NGDELIM separated, X * and there is an NGDELIM at the end of each argument. X * X * Currently implemented glitches: X * sublist uses 'all' like shell uses '*', and '.' like shell '/'. X * If subscription X matches Y, it also matches Y.anything. X */ Xngmatch(nglist, sublist) Xregister char *nglist, *sublist; X{ X register char *n, *s; X register int rc; X X rc = FALSE; X for (n = nglist; *n != '\0' && rc == FALSE;) { X for (s = sublist; *s != '\0';) { X if (*s != NEGCHAR) X rc = rc || ptrncmp(s, n); X else X rc = rc && !ptrncmp(s+1, n); X while (*s++ != NGDELIM && *s != '\0') X ; X } X while (*n++ != NGDELIM && *n != '\0') X ; X } X return rc; X} X X/* X * Compare two newsgroups for equality. X * The first one may be a "meta" newsgroup. X */ Xptrncmp(ng1, ng2) Xregister char *ng1, *ng2; X{ X while (*ng1 != NGDELIM && *ng1 != '\0') { X if (ng1[0]=='a' && ng1[1]=='l' && ng1[2]=='l') { X ng1 += 3; X while (*ng2 != NGDELIM && *ng2 != '.' && *ng2 != '\0') X if (ptrncmp(ng1, ng2++)) X return(TRUE); X return ptrncmp(ng1, ng2); X } else if (*ng1++ != *ng2++) X return FALSE; X } X return *ng2 == '.' || *ng2 == NGDELIM || *ng2 == '\0'; X} X X/* X * Exec the shell. X * This version resets uid, gid, and umask. X * Called with fsubr(ushell, s, NULL) X */ X/* ARGSUSED */ Xushell(s, dummy) Xchar *s, *dummy; X{ X (void) umask(savmask); X (void) setgid(gid); X (void) setuid(uid); X xshell(s); X} X X/* X * Exec the shell. X */ X X#ifdef lint Xchar **environ; X#else /* !lint */ Xextern char **environ; X#endif /* !lint */ X Xxshell(s) Xchar *s; X{ X char *env[100], **envp; X char a[BUFLEN + 2]; X extern char filename[]; X /* set $A */ X (void) sprintf(a, "A=%s", filename); X env[0] = a; X for (envp = env + 1 ; *environ != NULL && envp < env + 98 ; environ++) X if ((*environ)[0] != 'A' || (*environ)[1] != '=') X *envp++ = *environ; X *envp = NULL; X X execle(SHELL, SHELL, "-c", s, (char *)0, env); X xerror("No shell!"); X} X X/* X * Fork and call a subroutine with two args. X * Return pid without waiting. X */ Xfsubr(f, s1, s2) Xint (*f)(); Xchar *s1, *s2; X{ X register int pid; X X /* this may NOT be a vfork */ X while ((pid = fork()) == -1) X sleep((unsigned)1); X if (pid == 0) { X (*f)(s1, s2); X exit(0); X } X return pid; X} X X/* X * Wait on a child process. X */ Xfwait(pid) Xregister int pid; X{ X register int w; X int status; X int (*onhup)(), (*onint)(); X X onint = signal(SIGINT, SIG_IGN); X onhup = signal(SIGHUP, SIG_IGN); X while ((w = wait(&status)) != pid && w != -1) X ; X if (w == -1) X status = -1; X (void) signal(SIGINT, onint); X (void) signal(SIGHUP, onhup); X return status; X} X X/* X * Strip trailing newlines, blanks, and tabs from 's'. X * Return TRUE if newline was found, else FALSE. X */ Xnstrip(s) Xregister char *s; X{ X register char *p; X register int rc; X X rc = FALSE; X p = s; X while (*p) X if (*p++ == '\n') X rc = TRUE; X while (--p >= s && (*p == '\n' || *p == ' ' || *p == '\t')); X *++p = '\0'; X return rc; X} X X/* X * Local open routine. X */ XFILE * Xxfopen(name, fmode) Xregister char *name, *fmode; X{ X register FILE *fp; X char *fname; X extern int errno; X X if (!strcmp(fmode,"")) { X fprintf(stderr,"Opening %s, mode %s\n",name,fmode); X fmode="r"; X } X X if ((fp = fopen(name, fmode)) == NULL) { X#ifdef IHCC X /* X * IHCC users only see the "filename" that was in trouble, X * not the whole path. (for security!) X */ X fname = rindex(name, '/') + 1; X#else X fname = name; X#endif X xerror("Cannot open %s (%s): %s", fname, fmode, errmsg(errno)); X } X /* kludge for setuid not being honored for root */ X if ((uid == 0) && (duid != 0) && ((*fmode == 'a') || (*fmode == 'w'))) X (void) chown(name, duid, dgid); X return fp; X} X Xchar * Xerrmsg(code) Xint code; X{ X extern int sys_nerr; X extern char *sys_errlist[]; X static char ebuf[6+5+1]; X X if (code > sys_nerr) { X (void) sprintf(ebuf, "Error %d", code); X return ebuf; X } else X return sys_errlist[code]; X} X Xprefix(full, pref) Xregister char *full, *pref; X{ X register char fc, pc; X X while ((pc = *pref++) != '\0') { X fc = *full++; X if (isupper(fc)) X fc = tolower(fc); X if (isupper(pc)) X pc = tolower(pc); X if (fc != pc) X return FALSE; X } X return TRUE; X} X Xchar * Xdirname(ngname) Xchar *ngname; X{ X static char rbuf[BUFLEN]; X register char *p; X X (void) sprintf(rbuf, "%s/%s", SPOOL, ngname); X X for (p=rbuf+strlen(SPOOL); *p; p++) X if (*p == '.') X *p = '/'; X return rbuf; X} X X/* X * Return TRUE iff ngname is a valid newsgroup name X */ Xvalidng(ngname) Xchar *ngname; X{ X register FILE *fp; X register char *p, *q; X char abuf[BUFLEN]; X X fp = xfopen(ACTIVE, "r"); X while(fgets(abuf, BUFLEN, fp) != NULL) { X p = abuf; X q = ngname; X while (*p++ == *q++) X ; X if (*--q == '\0' && *--p == ' ') { X (void) fclose(fp); X return TRUE; X } X } X (void) fclose(fp); X return FALSE; X} X X/* VARARGS1 */ Xxerror(message, arg1, arg2, arg3) Xchar *message; Xlong arg1, arg2, arg3; X{ X char buffer[LBUFLEN]; X X fflush(stdout); X (void) sprintf(buffer, message, arg1, arg2, arg3); X logerr(buffer); X xxit(1); X} X X/* VARARGS1 */ Xlog(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) Xchar *fmt; Xlong a1, a2, a3, a4, a5, a6, a7, a8, a9; X{ X _dolog(0, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); X} X X/* VARARGS1 */ Xlogerr(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) Xchar *fmt; Xlong a1, a2, a3, a4, a5, a6, a7, a8, a9; X{ X _dolog(1, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); X} X Xchar *lfsuffix[] = { X "log", X "errlog", X NULL, X}; X X/* X * Log the given message, with printf strings and parameters allowed, X * on the log file, if it can be written. The date and an attempt at X * figuring out the remote system name are also logged. X */ X/* VARARGS1 */ X_dolog(which, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) Xchar *fmt; Xlong a1, a2, a3, a4, a5, a6, a7, a8, a9; X{ X FILE *logfile; X register char *p, *logtime; X int i; X char logfname[BUFLEN]; /* the log file */ X char rmtsys[BUFLEN]; X char msg[LBUFLEN]; X time_t t; X X (void) strcpy(rmtsys, header.path); X p = index(rmtsys, '!'); X if (p == NULL) X p = index(rmtsys, ':'); X if (p) X *p = 0; X else { X p = rindex(rmtsys, '@'); X if (p) X (void) strcpy(rmtsys, p+1); X else X (void) strcpy(rmtsys, "local"); X } X X (void) time(&t); X logtime = ctime(&t); X logtime[16] = 0; X logtime += 4; X X X (void) sprintf(msg, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); X X if (which) X fprintf(stderr,"%s: %s\n", Progname, msg); X X for (i=0; i<=which;i++) { X (void) sprintf(logfname, "%s/%s", LIB, lfsuffix[i]); X X if (access(logfname, 0) == 0 && (logfile = fopen(logfname, "a")) != NULL) { X#if defined(USG) || defined(BSD4_2) || defined(BSD4_1C) X int flags; X flags = fcntl(fileno(logfile), F_GETFL, 0); X (void) fcntl(fileno(logfile), F_SETFL, flags|O_APPEND); X#else /* v7 */ X (void) lseek(fileno(logfile), 0L, 2); X#endif /* v7 */ X if (i) X fprintf(logfile, "%s\t%s\t%s: %s\n", logtime, X header.ident[0] ? header.ident : username, Progname, msg); X else X fprintf(logfile, "%s\t%s\t%s\n", logtime, X rmtsys, msg); X (void) fclose(logfile); X } X } X} X#ifdef VMS X X/* X * vmslink allows simulation of file linking under VMS. X */ Xvmslink(infile,outfile) Xchar *infile, *outfile; X{ X FILE *fp; X X if (access(outfile,0) == 0) { X errno = EEXIST; X return -1; X } X X fp = fopen(outfile, "w"); X if (fp == NULL) { X errno = EACCES; X return -1; X } X X (void) fprintf(fp, "%s", infile); X (void) fclose(fp); X X return 0; X} X X/* X * vmsdelete deletes all revisions of a file. It attempts to X * appear as unlink(2) under conventional Unix in other respects. X */ Xvmsdelete(file) Xchar *file; X{ X int i; X X i = unlink(file); X if (i != 0) X return i; X X i = errno; X while (unlink(file) == 0) X ; X errno = i; X X return 0; X} X X/* X * Convert a Unix file to a VMS fixed record format file by X * executing the 'unixtovms' command. X */ Xunixtovms(file) Xchar *file; X{ X char buf[BUFLEN]; X sprintf(buf, "exec /etc/unixtovms %s", file); X return system(buf); X} X X/* X * Convert a VMS fixed record format file to a Unix file by X * executing the 'vmstounix' command. X */ Xvmstounix(file) Xchar *file; X{ X char buf[BUFLEN]; X sprintf(buf,"exec /etc/vmstounix %s", file); X return system(buf); X} X#endif /* VMS */ X X#if !defined(BSD4_2) && !defined(BSD4_1C) X/* X * make a directory. Also make sure that the directory is owned X * by the right userid X */ Xmkdir(path, perm) Xchar *path; Xint perm; X{ X int pid, status; X#ifdef USG X char parent[200]; X char *p; X struct stat sbuf; X X /* X * Make parent directory writable, because we will X * be creating a directory owned by the real user, X * rather than by news. X */ X (void) strcpy(parent, path); X if (p = rindex(parent, '/')) { X *p = '\0'; X if (stat(parent, &sbuf) == 0) X (void) chmod(parent, 0777); X else X return -1; X } else X return -1; X#endif X X if (pid=vfork()) { X status = fwait(pid); X#if defined(USG) && !defined(CHEAP) X if (pid=vfork()) X (void) fwait(pid); X else { X setgid(gid); X setuid(uid); X if (chown(path, duid, dgid) == 0) X (void) chmod(path, perm&(~N_UMASK)); X _exit(0); X } X#endif /* USG && !CHEAP */ X } else { X (void) setgid(dgid); X if (setuid(duid) < 0) X (void) umask(0); X else X (void) umask(perm&N_UMASK); X (void) execlp("mkdir", "mkdir", path, (char *)NULL); X perror(path); X _exit(1); X } X#ifdef USG X (void) chmod(parent, sbuf.st_mode); /* Restore mode of parent */ X#endif X return status; X} X#endif /* !BSD4_2 && ! BSD4_1C */ X#ifndef USG Xchar * Xstrpbrk(str, chars) Xregister char *str, *chars; X{ X register char *cp; X X do { X cp = chars - 1; X while (*++cp) { X if (*str == *cp) X return str; X } X } while (*str++); X return NULL; X} X#endif /* !USG */ X X#ifdef FASCIST X/* X * This routine checks to see if the posting user is allowed to X * post to the given newsgroup. If the username is not in the file X * $LIBDIR/authorized then the default in the symbol FASCIST is used. X * X * Format of the call: X * fascist(user, newgroups) X * X * Returns: X * FALSE, if authorized X * TRUE, if not X * X * Format of the file "authorized" is: X * user:allowed groups X * X * Example: X * root:net.all,mod.all X * naughty_person:junk,net.politics X * operator:!net.all,general,test,mod.unix X * X * An open environment could have FASCIST set to "all" X * and then individual entries could be made in the authorized file X * to prevent certain individuals from posting to such a wide X * area. X * X * Note that a distribution of "all" does NOT mean to allow postings X * only to local groups -- "all" includes "all.all". X * Use "all,!all.all" to get this behavior X * X * Eugene Spafford spaf@gatech May 22, 1985 X */ X Xfascist(user, newsgroups) Xregister char *user, *newsgroups; X{ X FILE *facfd; X char facuser[BUFLEN], facgroups[BUFLEN], factemp[BUFLEN]; X register char *facptr; X X /* First, open the necessary file...$LIBDIR/authorized and see if there X * is an entry for this user X */ X X (void) strncpy(facgroups, FASCIST, BUFLEN); X sprintf(factemp, "%s/%s", LIB, "authorized"); X facfd = fopen(factemp, "r"); X X if (facfd != NULL) { /* If no such file, we go with the global default */ X while (fscanf(facfd, "%[^:]:%s\n", facuser, factemp) != EOF) X if (strncmp(facuser, user, BUFLEN) == 0) { X (void) strcat(facgroups, ","); X (void) strcat(facgroups, factemp); X break; X } X fclose (facfd); X } X#ifdef DEBUG X fprintf(stderr, "facgroups = %s\n", facgroups); X fprintf(stderr, "newsgroups = %s\n", newsgroups); X#endif /* DEBUG */ X X /* We step through the newsgroups being posted to and check each against X * the restriction list. *ALL* posted groups must match the restriction X * list or we don't allow the posting. X */ X X while (*newsgroups != '\0') { X facptr = factemp; X while (*newsgroups != '\0' && *newsgroups != NGDELIM) X *facptr++ = *newsgroups++; X *facptr = '\0'; X if (*newsgroups == NGDELIM) X newsgroups++; X X#ifdef DEBUG X fprintf(stderr, "Checking newsgroup '%s'\n", factemp); X#endif X X if (ngmatch(factemp, facgroups) == FALSE) X return TRUE; X } X X /* must be okay -- return */ X#ifdef DEBUG X fprintf (stderr, "Newsgroups approved for this poster.\n"); X#endif /* DEBUG */ X return FALSE; X} X#endif /* FASCIST */ END_OF_FILE if test 12952 -ne `wc -c <'funcs.c'`; then echo shar: \"'funcs.c'\" unpacked with wrong size! fi # end of 'funcs.c' fi echo shar: End of shell archive. exit 0 -- "Zeta Microcomputer Software" ACSnet: nick@ultima.cs.uts.oz UUCP: ...!uunet!munnari!ultima.cs.uts.oz!nick Fidonet: Nick Andrew on 3:713/602 (Zeta)