v07i053: 2.11 News Source, Part03/09
sources-request at mirror.UUCP
sources-request at mirror.UUCP
Fri Nov 7 02:59:16 AEST 1986
Submitted by: seismo!rick (Rick Adams)
Mod.sources: Volume 7, Issue 53
Archive-name: 2.11news/Part13
# To extract, sh this file
#
# news 2.11 source part 3 of 9
#
if test ! -d src
then
mkdir src
fi
echo x - src/inews.c 1>&2
sed 's/.//' >src/inews.c <<'*-*-END-of-src/inews.c-*-*'
-/*
- * This software is Copyright (c) 1986 by Rick Adams.
- *
- * Permission is hereby granted to copy, reproduce, redistribute or
- * otherwise use this software as long as: there is no monetary
- * profit gained specifically from the use or reproduction or this
- * software, it is not sold, rented, traded or otherwise marketed, and
- * this copyright notice is included prominently in any copy
- * made.
- *
- * The author make no claims as to the fitness or correctness of
- * this software for any use whatsoever, and it is provided as is.
- * Any use of this software is at the user's own risk.
- *
- * inews - insert, receive, and transmit news articles.
- *
- */
-
-#ifdef SCCSID
-static char *SccsId = "@(#)inews.c 2.69 10/30/86";
-#endif /* SCCSID */
-
-#include "iparams.h"
-#include <errno.h>
-
-#ifdef BSD4_2
-# include <sys/dir.h>
-# include <sys/file.h>
-#else /* !BSD4_2 */
-# include "ndir.h"
-# ifdef USG
-# include <fcntl.h>
-# endif /* USG */
-# ifdef LOCKF
-# include <unistd.h>
-# endif /* LOCKF */
-#endif /* !BSD4_2 */
-/* local defines for inews */
-
-#define OPTION 0 /* pick up an option string */
-#define STRING 1 /* pick up a string of arguments */
-
-#define UNKNOWN 0001 /* possible modes for news program */
-#define UNPROC 0002 /* Unprocessed input */
-#define PROC 0004 /* Processed input */
-#define CONTROL 0010 /* Control Message */
-#define CREATENG 0020 /* Create a new newsgroup */
-
-char forgedname[NAMELEN]; /* A user specified -f option. */
-int spool_news = FALSE;
-extern char histline[];
-/* Fake sys line in case they forget their own system */
-struct srec dummy_srec = { "MEMEME", "", "all", "", "" };
-
-char *Progname = "inews"; /* used by xerror to identify failing program */
-
-struct { /* options table. */
- char optlet; /* option character. */
- char filchar; /* if to pickup string, fill character. */
- int flag; /* TRUE if have seen this opt. */
- int oldmode; /* OR of legal input modes. */
- int newmode; /* output mode. */
- char *buf; /* string buffer */
-} *optpt, options[] = { /*
-optlet filchar flag oldmode newmode buf */
-'t', ' ', FALSE, UNPROC, UNKNOWN, header.title,
-'n', NGDELIM, FALSE, UNPROC, UNKNOWN, header.nbuf,
-'d', '\0', FALSE, UNPROC, UNKNOWN, header.distribution,
-'e', ' ', FALSE, UNPROC, UNKNOWN, header.expdate,
-'p', '\0', FALSE, UNKNOWN|PROC, PROC, filename,
-'f', '\0', FALSE, UNPROC, UNKNOWN, forgedname,
-'F', ' ', FALSE, UNPROC, UNKNOWN, header.followid,
-'c', ' ', FALSE, UNKNOWN,UNKNOWN, header.ctlmsg,
-'C', ' ', FALSE, UNKNOWN,CREATENG, header.ctlmsg,
-#define hflag options[9].flag
-'h', '\0', FALSE, UNPROC, UNKNOWN, filename,
-#define oflag options[10].flag
-'o', '\0', FALSE, UNPROC, UNKNOWN, header.organization,
-#define Mflag options[11].flag
-'M', '\0', FALSE, UNPROC, UNKNOWN, filename,
-'a', '\0', FALSE, UNPROC, UNKNOWN, header.approved,
-'U', '\0', FALSE, PROC, PROC, filename,
-'S', '\0', FALSE, UNKNOWN|PROC, UNPROC, filename,
-'x', '\0', FALSE, UNPROC, UNKNOWN, not_here,
-'r', '\0', FALSE, UNPROC, UNKNOWN, header.replyto,
-'\0', '\0', 0, 0, 0, (char *)NULL
-};
-
-FILE *mailhdr();
-extern int errno;
-
-struct timeb Now;
-
-/*
- * Authors:
- * Matt Glickman glickman at ucbarpa.Berkeley.ARPA
- * Mark Horton mark at cbosgd.UUCP
- * Stephen Daniels swd at mcnc.UUCP
- * Tom Truscott trt at duke.UUCP
- * Rick Adams rick at seismo.CSS.GOV
- * IHCC version adapted by:
- * Larry Marek larry at ihuxf.UUCP
- */
-main(argc, argv)
-int argc;
-register char **argv;
-{
- int state; /* which type of argument to pick up */
- int tlen, len; /* temps for string processing routine */
- register char *ptr; /* pointer to rest of buffer */
- int filchar; /* fill character (state = STRING) */
- char *user = NULL, *home = NULL; /* environment temps */
- struct passwd *pw; /* struct for pw lookup */
- struct group *gp; /* struct for group lookup */
- register int i;
- FILE *mfd; /* mail file file-descriptor */
- char cbuf[BUFLEN]; /* command buffer */
-
- /* uuxqt doesn't close all it's files */
- for (i = 3; !close(i); i++)
- ;
- /* set up defaults and initialize. */
- mode = UNKNOWN;
- infp = stdin;
- pathinit();
- ptr = rindex(*argv, '/');
- if (!ptr)
- ptr = *argv - 1;
- actfp = xfopen(ACTIVE, "r+");
-#ifdef BSD4_2
- if (flock(fileno(actfp), LOCK_SH|LOCK_NB) < 0 && errno == EWOULDBLOCK)
-#else /* !BSD4_2 */
-#ifdef LOCKF
- if (lockf(fileno(actfp), F_TLOCK, 0) < 0 && errno == EAGAIN)
-#else /* !LOCKF */
- sprintf(bfr, "%s.lock", ACTIVE);
- if (LINK(ACTIVE,bfr) < 0 && errno == EEXIST)
-#endif /* V7 */
-#endif /* !BSD4_2 */
- spool_news = TRUE;
- else {
-#ifdef SPOOLNEWS
- if (argc > 1 && !strcmp(*(argv+1), "-S")) {
- argc--;
- argv++;
- } else
- spool_news = TRUE;
-
-#endif /* SPOOLNEWS */
-#if !defined(BSD4_2) && !defined(LOCKF)
- (void) UNLINK(bfr);
-#endif /* !BSD4_2 && !LOCKF */
- }
- if (argc > 1 && !strcmp(*(argv+1), "-U")) {
- dounspool();
- /* NOT REACHED */
- }
-
- if (!strncmp(ptr+1, "rnews", 5)) {
- mode = PROC;
- if (spool_news) {
- dospool((char *)NULL, FALSE);
- /* NOT REACHED */
- }
-#ifdef NICENESS
- nice(NICENESS);
-#endif /* NICENESS */
- } else
- if (argc < 2)
- goto usage;
-
- state = OPTION;
- header.title[0] = header.nbuf[0] = filename[0] = '\0';
-
- /* check for existence of special files */
- if (!rwaccess(ARTFILE)) {
- mfd = mailhdr((struct hbuf *)NULL, exists(ARTFILE) ? "Unwritable files!" : "Missing files!");
- if (mfd != NULL) {
-#ifdef HIDDENNET
- fprintf(mfd,"System: %s.%s\n\nThere was a problem with %s!!\n", LOCALSYSNAME, FULLSYSNAME, ARTFILE);
-#else /* !HIDDENNET */
- fprintf(mfd,"System: %s\n\nThere was a problem with %s!!\n", FULLSYSNAME, ARTFILE);
-#endif /* !HIDDENNET */
- (void) sprintf(cbuf, "touch %s;chmod 666 %s", ARTFILE, ARTFILE);
- (void) system(cbuf);
- if (rwaccess(ARTFILE))
- fprintf(mfd, "The problem has been taken care of.\n");
- else
- fprintf(mfd, "Corrective action failed - check suid bits.\n");
- (void) mclose(mfd);
- }
- }
- if (!rwaccess(ACTIVE)) {
- mfd = mailhdr((struct hbuf *)NULL, exists(ACTIVE) ? "Unwritable files!" : "Missing files!");
- if (mfd != NULL) {
-#ifdef HIDDENNET
- fprintf(mfd,"System: %s.%s\n\nThere was a problem with %s!!\n", LOCALSYSNAME, FULLSYSNAME, ARTFILE);
-#else /* !HIDDENNET */
- fprintf(mfd, "System: %s\n\nThere was a problem with %s!!\n", FULLSYSNAME, ACTIVE);
-#endif /* !HIDDENNET */
- (void) sprintf(cbuf, "touch %s;chmod 666 %s", ACTIVE, ACTIVE);
- (void) system(cbuf);
- if (rwaccess(ACTIVE))
- fprintf(mfd, "The problem has been taken care of.\n");
- else
- fprintf(mfd, "Corrective action failed - check suid bits.\n");
- (void) mclose(mfd);
- }
- }
- SigTrap = FALSE; /* true if a signal has been caught */
- if (mode != PROC) {
- (void) signal(SIGHUP, onsig);
- (void) signal(SIGINT, onsig);
- }
- savmask = umask(N_UMASK); /* set up mask */
- uid = getuid();
- gid = getgid();
- duid = geteuid();
- dgid = getegid();
- (void) ftime(&Now);
- if (uid == 0 && duid == 0) {
- /*
- * Must go through with this kludge since
- * some systems do not honor the setuid bit
- * when root invokes a setuid program.
- */
- if ((pw = getpwnam(NEWSUSR)) == NULL)
- xerror("Cannot get NEWSU pw entry");
-
- duid = pw->pw_uid;
- if ((gp = getgrnam(NEWSGRP)) == NULL)
- xerror("Cannot get NEWSG gr entry");
- dgid = gp->gr_gid;
- (void) setgid(dgid);
- (void) setuid(duid);
- }
-
-#ifndef IHCC
- /*
- * We force the use of 'getuser()' to prevent forgery of articles
- * by just changing $LOGNAME
- */
- if (isatty(fileno(stderr))) {
- if ((user = getenv("USER")) == NULL)
- user = getenv("LOGNAME");
- if ((home = getenv("HOME")) == NULL)
- home = getenv("LOGDIR");
- }
-#endif
- if (user == NULL || home == NULL)
- getuser();
- else {
- if (username == NULL || username[0] == 0) {
- username = AllocCpy(user);
- }
- userhome = AllocCpy(home);
- }
- getuser();
-
- /* loop once per arg. */
-
- ++argv; /* skip first arg, which is prog name. */
-
- while (--argc) {
- if (state == OPTION) {
- if (**argv != '-') {
- xerror("Bad option string \"%s\"", *argv);
- }
- while (*++*argv != '\0') {
- for (optpt = options; optpt->optlet != '\0'; ++optpt) {
- if (optpt->optlet == **argv)
- goto found;
- }
- /* unknown option letter */
-usage:
- fprintf(stderr, "usage: inews -t title");
- fprintf(stderr, " [ -n newsgroups ]");
- fprintf(stderr, " [ -e expiration date ]\n");
- fprintf(stderr, "\t[ -f sender]\n\n");
- xxit(1);
-
- found:;
- if (optpt->flag == TRUE || (mode != UNKNOWN &&
- (mode&optpt->oldmode) == 0)) {
- xerror("Bad %c option", **argv);
- }
- if (mode == UNKNOWN)
- mode = optpt->newmode;
- filchar = optpt->filchar;
- optpt->flag = TRUE;
- state = STRING;
- ptr = optpt->buf;
- len = BUFLEN;
- }
-
- argv++; /* done with this option arg. */
-
- } else {
-
- /*
- * Pick up a piece of a string and put it into
- * the appropriate buffer.
- */
- if (**argv == '-') {
- state = OPTION;
- argc++; /* uncount this arg. */
- continue;
- }
-
- if ((tlen = strlen(*argv)) >= len)
- xerror("Argument string too long");
- (void) strcpy(ptr, *argv++);
- ptr += tlen;
- if (*(ptr-1) != filchar)
- *ptr++ = filchar;
- len -= tlen + 1;
- *ptr = '\0';
- }
- }
-
- /*
- * ALL of the command line has now been processed. (!)
- */
-
- if (*filename) {
- (void) fclose(stdin);
- infp = freopen(filename, "r", stdin);
- if (infp == NULL)
- xerror("freopen(%s): %s", filename, errmsg(errno));
- } else
- infp = stdin;
-
- tty = isatty(fileno(infp));
-
- if (mode == CREATENG)
- createng();
-
- if (header.ctlmsg[0] != '\0' && header.title[0] == '\0')
- (void) strcpy(header.title, header.ctlmsg);
-
- if (*header.nbuf) {
- lcase(header.nbuf);
- ptr = index(header.nbuf, '\0');
- if (ptr[-1] == NGDELIM)
- *--ptr = '\0';
- }
- (void) nstrip(header.title);
- (void) nstrip(header.expdate);
- (void) nstrip(header.followid);
- if (mode != PROC) {
- if (hflag) {
- header.path[0] = '\0';
- (void) hread(&header, infp, FALSE);
- /* there are certain fields we won't let him specify. */
- if (header.from[0])
- (void) strcpy(forgedname, header.from);
- if (!header.approved[0])
- Mflag = FALSE;
- header.from[0] = '\0';
- header.sender[0] = '\0';
- if (header.subdate[0] && cgtdate(header.subdate) < 0)
- header.subdate[0] = '\0';
- }
-
- if (header.ident[0] == '\0')
- getident(&header);
-
- if (forgedname[0]) {
- register char *p1;
- if (Mflag)
- sprintf(header.path, "%s!%s",
- FULLSYSNAME, username);
- else if (!header.path[0]) {
- (void) strcpy(header.path, forgedname);
-
- if ((p1 = strpbrk(header.path, "@ (<")) != NULL)
- *p1 = '\0';
- }
- if (!Mflag && !strpbrk(forgedname, "@ (<"))
- (void) sprintf(header.from,"%s@%s%s",
- forgedname, FULLSYSNAME, MYDOMAIN);
- else
- (void) strncpy(header.from, forgedname, BUFLEN);
-
- (void) sprintf(header.sender, "%s@%s%s",
- username, FULLSYSNAME, MYDOMAIN);
- } else {
- gensender(&header, username);
- }
-#ifdef MYORG
- if (header.organization[0] == '\0' && !Mflag &&
- header.sender[0] == '\0') {
- strncpy(header.organization, MYORG, BUFLEN);
- if (strncmp(header.organization, "Frobozz", 7) == 0)
- header.organization[0] = '\0';
- if (ptr = getenv("ORGANIZATION"))
- strncpy(header.organization, ptr, BUFLEN);
- /*
- * Note that the organization can also be turned off by
- * setting it to the null string, either in MYORG or
- * $ORGANIZATION in the environment.
- */
- if (header.organization[0] == '/') {
- mfd = fopen(header.organization, "r");
- if (mfd) {
- (void) fgets(header.organization, sizeof header.organization, mfd);
- (void) fclose(mfd);
- } else {
- header.organization[0] = '\0';
- logerr("Couldn't open %s",
- header.organization);
- }
- ptr = index(header.organization, '\n');
- if (ptr)
- *ptr = '\0';
- }
- }
-#endif /* MYORG */
- }
-
- /* Authorize newsgroups. */
- if (mode == PROC) {
-#ifdef BATCH
- checkbatch();
-#endif /* BATCH */
- (void) signal(SIGHUP, SIG_IGN);
- (void) signal(SIGINT, SIG_IGN);
- (void) signal(SIGQUIT, SIG_IGN);
- header.ident[0] = '\0';
- if (hread(&header, infp, TRUE) == NULL)
- error("Inbound news is garbled");
- input();
- }
- /* always check history */
-
- if (history(&header)) {
- log("Duplicate article %s rejected. Path: %s",
- header.ident, header.path);
- xxit(0);
- }
-
- /* Easy way to make control messages, since all.all.ctl is unblessed */
- if (mode != PROC && prefix(header.title, "cmsg ") && header.ctlmsg[0] == 0)
- (void) strcpy(header.ctlmsg, &header.title[5]);
- is_ctl = mode != CREATENG &&
- (ngmatch(header.nbuf, "all.all.ctl,") || header.ctlmsg[0]);
-#ifdef DEBUG
- fprintf(stderr,"is_ctl set to %d\n", is_ctl);
-#endif
-
- if (mode != CREATENG) {
- if (!*header.title)
- error("No title, ng %s from %s", header.nbuf,
- header.from);
- if (!*header.nbuf)
- (void) strcpy(header.nbuf, DFLTNG);
- }
-
- if (mode <= UNPROC) {
-#ifdef FASCIST
- if (uid && uid != ROOTID && fascist(user, header.nbuf))
- xerror("User %s is not authorized to post to newsgroup %s",
- user, header.nbuf);
-#endif /* FASCIST */
- ctlcheck();
- }
-
- if (mode == CREATENG)
- createng();
-
- /* Determine input. */
- if (mode != PROC)
- input();
- if (header.intnumlines == 0 && !is_ctl)
- error("%s rejected: no text lines", header.ident);
-
- dates(&header);
-
- /* Do the actual insertion. */
- insert();
-}
-
-dospool(batchcmd, dolhwrite)
-char *batchcmd;
-int dolhwrite;
-{
- register int c;
- register FILE *sp;
- register struct tm *tp;
- time_t t;
- char buf[BUFLEN];
- extern struct tm *gmtime();
-
- (void) time(&t);
- tp = gmtime(&t);
- /* This file name "has to" be unique (right?) */
-#ifdef USG
- (void) sprintf(buf, "%s/.rnews/%2.2d%2.2d%2.2d%2.2d%2.2d%x",
-#else
-#ifdef VMS
- /* Eunice doesn't like dots in directory names */
- (void) sprintf(buf, "%s/+rnews/%02d%02d%02d%02d%02d%x",
-#else /* V7 */
- (void) sprintf(buf, "%s/.rnews/%02d%02d%02d%02d%02d%x",
-#endif /* V7 */
-#endif /* VMS */
- SPOOLDIR,
- tp->tm_year, tp->tm_mon+1, tp->tm_mday,
- tp->tm_hour, tp->tm_min, getpid());
- sp = xfopen(buf, "w");
- if (batchcmd != NULL)
- fprintf(sp, "%s\n", batchcmd);
- if (dolhwrite)
- lhwrite(&header, sp);
- while ((c = getc(infp)) != EOF)
- putc(c, sp);
- fclose(sp);
- xxit(0);
- /* NOTREACHED */
-}
-
-/*
- * Create a newsgroup
- */
-createng()
-{
- register char *cp;
-
- /*
- * Only certain users are allowed to create newsgroups
- */
- if (uid != ROOTID && uid != duid && uid) {
- fprintf(stderr, "Please contact one of the local netnews people\n\tto create this group for you");
- xxit(1);
- }
- if (header.distribution[0] == '\0')
-#ifdef ORGDISTRIB
- strcpy(header.distribution, ORGDISTRIB);
-#else /* !ORGDISTRIB */
- strcpy(header.distribution, "local");
-#endif /* !ORGDISTRIB */
-
- (void) strcpy(header.nbuf, header.ctlmsg);
- if ((cp=index(header.nbuf, ' ')) != NULL)
- *cp = '\0';
-
- if (header.approved[0] == '\0')
- (void) sprintf(header.approved, "%s@%s%s",
- username, FULLSYSNAME, MYDOMAIN);
- (void) sprintf(bfr, "%s/inews -n %s.ctl -c newgroup %s -d %s -a \"%s\"",
- LIB, header.nbuf, header.ctlmsg, header.distribution,
- header.approved);
- if (tty) {
- printf("Please type in a paragraph describing the new newsgroup.\n");
- printf("End with control D as usual.\n");
- }
- printf("%s\n", bfr);
- (void) fflush(stdout);
- (void) system(bfr);
- exit(0);
- /*NOTREACHED*/
-}
-
-char firstbufname[BUFLEN];
-/*
- * Link ARTICLE into dir for ngname and update active file.
- */
-long
-localize(ngname)
-char *ngname;
-{
- char afline[BUFLEN];
- long ngsize;
- long fpos;
- int e;
- char *cp;
-
- lock();
- (void) rewind(actfp); clearerr(actfp);
-
- for(;;) {
- fpos = ftell(actfp);
- if (fgets(afline, sizeof afline, actfp) == NULL) {
- unlock();
- logerr("Can't find \"%s\" in active file", ngname);
- return FALSE; /* No such newsgroup locally */
- }
- if (prefix(afline, ngname)) {
- (void) sscanf(afline, "%s %ld", bfr, &ngsize);
- if (strcmp(bfr, ngname) == 0) {
- if (ngsize < 0 || ngsize > 99998) {
- logerr("found bad ngsize %ld ng %s, setting to 1", ngsize, bfr);
- ngsize = 1;
- }
- break;
- }
- }
- }
- for (;;) {
- cp = dirname(ngname);
-
- (void) sprintf(bfr, "%s/%ld", cp, ngsize+1);
-#ifdef VMS
- /*
- * The effect of this code is to store the article in the first
- * newsgroup's directory and to put symbolic links elsewhere.
- * If this is the first group, firstbufname is not yet filled
- * in. It should be portable to other link-less systems.
- * epimass!jbuck
- */
- if (firstbufname[0]) {
- if (vmslink(firstbufname, bfr) == 0)
- break;
- } else if (rename(ARTICLE, bfr) == 0)
- break;
-#else /* !VMS */
- if (link(ARTICLE, bfr) == 0)
- break;
-#endif /* !VMS */
- if (!exists(cp))
- mknewsg(cp, ngname);
-#ifdef VMS
- if (firstbufname[0]) {
- if (vmslink(firstbufname, bfr) == 0)
- break;
- } else if (rename(ARTICLE, bfr) == 0)
- break;
-#else /* !VMS */
- if (link(ARTICLE, bfr) == 0)
- break;
-#endif /* !VMS */
- e = errno; /* keep log from clobbering it */
- log("Cannot install article as %s: %s", bfr, errmsg(errno));
- if (e != EEXIST) {
- logerr("Link into %s failed (%s); check dir permissions.",
- bfr, errmsg(e));
- unlock();
- return FALSE;
- }
- ngsize++;
- }
-
- /*
- * This works around a bug in the 4.1bsd stdio
- * on fseeks to non even offsets in r+w files
- */
- if (fpos&1)
- (void) rewind(actfp);
-
- (void) fseek(actfp, fpos, 0);
-#ifdef USG
- /*
- * U G L Y K L U D G E
- * This utter piece of tripe is the only way I know of to get
- * around the fact that ATT BROKE standard IO in System 5.2.
- * Basically, you can't open a file for "r+" and then try and
- * write to it. This works on all "real" USGUnix systems, It will
- * probably break on some obscure look alike that doesnt use the
- * real ATT stdio.h
- * Don't blame me, blame ATT. stdio should have already done the
- * following line for us, but it doesn't
- */
- actfp->_flag |= _IOWRT;
-#endif /* USG */
- /* Has to be same size as old because of %05d.
- * This will overflow with 99999 articles.
- */
- fprintf(actfp, "%s %05ld", ngname, ngsize+1);
- (void) fflush(actfp);
- if (ferror(actfp))
- xerror("Active file write failed");
- unlock();
- if (firstbufname[0] == '\0')
- (void) strcpy(firstbufname, bfr);
- (void) sprintf(bfr, "%s/%ld ", ngname, ngsize+1);
- addhist(bfr);
- return ngsize+1;
-}
-
-/*
- * Localize for each newsgroup and broadcast.
- */
-insert()
-{
- register char *ptr;
- register FILE *tfp;
- register int c;
- struct srec srec; /* struct for sys file lookup */
- struct tm *tm, *gmtime();
- int is_invalid = FALSE;
- int exitcode = 0;
- long now;
-#ifdef DOXREFS
- register char *nextref = header.xref;
-#endif /* DOXREFS */
-
- /* Clean up Newsgroups: line */
- if (!is_ctl && mode != CREATENG)
- is_invalid = ngfcheck(mode == PROC);
-
- (void) time(&now);
- tm = gmtime(&now);
- if (header.expdate[0])
- addhist(" ");
-#ifdef USG
- sprintf(bfr,"%2.2d/%2.2d/%d %2.2d:%2.2d\t",
-#else /* !USG */
- sprintf(bfr,"%02d/%02d/%d %02d:%02d\t",
-#endif /* !USG */
- tm->tm_mon+1, tm->tm_mday, tm->tm_year,tm->tm_hour, tm->tm_min);
- addhist(bfr);
- log("%s %s ng %s subj '%s' from %s",
- spool_news ? "queued" : (mode==PROC ? "received" : "posted"),
- header.ident, header.nbuf, header.title, header.from);
-
- /* Write article to temp file. */
- tfp = xfopen(mktemp(ARTICLE), "w");
-
- if (is_invalid) {
- logerr("No valid newsgroups found, moved to junk");
- if (localize("junk"))
- savehist(histline);
- exitcode = 1;
- goto writeout;
- }
-
-#ifdef ZAPNOTES
- if (strcmp(header.title, "Re: Orphaned Response") == 0) {
- logerr("Orphaned Response, moved to junk");
- if (localize("junk"))
- savehist(histline);
- exitcode = 1;
- goto writeout;
- }
-#endif /* ZAPNOTES */
-
- if (time((time_t *)0) > (cgtdate(header.subdate) + HISTEXP) ){
- logerr("Article too old, moved to junk");
- if (localize("junk"))
- savehist(histline);
- exitcode = 1;
- goto writeout;
- }
-
- if (is_mod[0] != '\0' /* one of the groups is moderated */
- && header.approved[0] == '\0') { /* and unapproved */
- struct hbuf mhdr;
- FILE *mfd;
- register char *p;
- char modadd[BUFLEN];
-#ifdef DONTFOWARD
- if(mode == PROC) {
- logerr("Unapproved article in moderated group %s",
- is_mod);
- if (localize("junk"))
- savehist(histline);
- goto writeout;
- }
-#endif /* DONTFORWARD */
- fprintf(stderr,"%s is moderated and may not be posted to",
- is_mod);
- fprintf(stderr," directly.\nYour article is being mailed to");
- fprintf(stderr," the moderator who will post it for you.\n");
- /* Let's find a path to the backbone */
- sprintf(bfr, "%s/mailpaths", LIBDIR);
- mfd = xfopen(bfr, "r");
- do {
- if (fgets(bfr, sizeof bfr, mfd) == NULL)
- xerror("Can't find backbone in %s/mailpaths",
- LIBDIR);
- } while (!prefix(bfr, "backbone"));
- if (sscanf(bfr, "%*s %s", modadd) != 1)
- xerror("backbone address corrupted");
- /* fake a header for mailhdr */
- mhdr.from[0] = '\0';
- mhdr.replyto[0] = '\0';
- p = is_mod;
- while (*++p)
- if (*p == '.')
- *p = '-';
- sprintf(bfr, "Submission for %s", is_mod);
- sprintf(mhdr.path, modadd, is_mod);
- mfd = mailhdr(&mhdr, bfr);
- if (mfd == NULL)
- xerror("Can't send mail to %s", mhdr.path);
- lhwrite(&header, mfd);
- while ((c = getc(infp)) != EOF)
- putc(c, mfd);
- mclose(mfd);
- log("Article mailed to %s", mhdr.path);
- xxit(0);
- }
-
- if (spool_news && mode != PROC) {
- fprintf(stderr,"Your article has been spooled for later processing.\n");
- dospool((char *)NULL, TRUE);
- /* NOT REACHED */
- }
-
- if (is_ctl) {
- exitcode = control(&header);
- if (localize("control") && exitcode != 0)
- savehist(histline);
- } else {
- if (s_find(&srec, FULLSYSNAME) == FALSE) {
- logerr("Cannot find my name '%s' in %s", FULLSYSNAME, SUBFILE);
- srec = dummy_srec;
- }
-#ifdef DOXREFS
- (void) strncpy(nextref, FULLSYSNAME, BUFLEN);
-#endif /* DOXREFS */
- for (ptr = nbuf; *ptr;) {
- if (ngmatch(ptr,srec.s_nbuf) || index(ptr,'.') == NULL){
-#ifdef DOXREFS
- while (*nextref++)
- ;
- (void) sprintf(--nextref, " %s:%ld", ptr, localize(ptr));
-#else /* !DOXREFS */
- (void) localize(ptr);
-#endif /* !DOXREFS */
- }
- while (*ptr++)
- ;
- }
- if (firstbufname[0] == '\0') {
- logerr("Newsgroups in active, but not sys");
- (void) localize("junk");
- }
- }
-#ifdef DOXREFS
- if (index(header.nbuf, NGDELIM) == NULL)
- header.xref[0] = '\0';
-#endif /* DOXREFS */
-
-writeout:
- /* Part 1 of kludge to get around article truncation problem */
- if ( (c=getc(infp)) != EOF) {
- ungetc(c, infp);
- if (c == ' ' || c == '\t') {
- header.intnumlines++;
- (void) sprintf(header.numlines, "%d",
- header.intnumlines);
- }
- }
- /* End of part 1 */
- if (header.expdate[0] != '\0' && mode != PROC) {
- /* Make sure it's fully qualified */
- long t = cgtdate(header.expdate);
- strcpy(header.expdate, arpadate(&t));
- }
-
- lhwrite(&header, tfp);
- if ((c = getc(infp)) != EOF) {
- /* Part 2 of kludge to get around article truncation problem */
- if (c == ' ' || c == '\t' )
- putc('\n', tfp);
- /* End of part 2 */
- ungetc(c, infp);
- while (fgets(bfr, BUFLEN, infp) != NULL)
- fputs(bfr, tfp);
- if (bfr[strlen(bfr)-1] != '\n')
- putc('\n',tfp);
- }
- if (ferror(tfp))
- xerror("Write failed for temp file");
- (void) fclose(tfp);
- (void) fclose(infp);
- if(exitcode == 0) {
- int pid;
- /* article has passed all the checks, so work in background */
- if (mode != PROC)
- if ((pid=vfork()) < 0)
- xerror("Can't fork");
- else if (pid > 0)
- exit(0);
-#ifdef SIGTTOU
- signal(SIGTTOU, SIG_IGN);
-#endif /* SIGTTOU */
- savehist(histline);
- broadcast();
- }
- xxit(mode == PROC ? 0 : exitcode);
-}
-
-input()
-{
- register char *cp;
- register int c;
- register int empty = TRUE;
- FILE *tmpfp;
- int consec_newlines = 0;
- int linecount = 0;
- int linserted = 0;
-
- tmpfp = xfopen(mktemp(INFILE), "w");
- while (!SigTrap && fgets(bfr, BUFLEN, infp) != NULL) {
- if (mode == PROC) { /* zap trailing empty lines */
-#ifdef ZAPNOTES
- if (empty && bfr[0] == '#' && bfr[2] == ':'
- && header.nf_id[0] == '\0'
- && header.nf_from[0] == '\0' ) {
- (void) strcpy(header.nf_id, bfr);
- (void) nstrip(header.nf_id);
- (void) fgets(bfr, BUFLEN, infp);
- (void) strcpy(header.nf_from, bfr);
- (void) nstrip(header.nf_from);
- (void) fgets(bfr, BUFLEN, infp);
-
- if (header.numlines[0]) {
- header.intnumlines -= 2;
- (void) sprintf(header.numlines, "%d", header.intnumlines);
- }
-
- /* Strip trailing " - (nf)" */
- if ((cp = rindex(header.title, '-')) != NULL
- && !strcmp(--cp, " - (nf)"))
- *cp = '\0';
- log("Stripped notes header on %s", header.ident);
- continue;
- }
-#endif /* ZAPNOTES */
- if (bfr[0] == '\n' ||
- /* Bandage for older versions of inews */
- bfr[1] == '\n' && !isascii(bfr[0])) {
- consec_newlines++; /* count it, in case */
- continue; /* but don't write it*/
- }
- /* foo! a non-empty line. write out all saved lines. */
- while (consec_newlines > 0) {
- putc('\n', tmpfp);
- consec_newlines--;
- linecount++;
- }
- }
- if (mode != PROC && tty && strcmp(bfr, ".\n") == 0)
- break;
- for (cp = bfr; c = toascii(*cp); cp++) {
- if (isprint(c) || isspace(c) || c == '\b')
- putc(c, tmpfp);
- if (c == '\n')
- linecount++;
- }
- if (bfr[0] == '>')
- linserted++;
- empty = FALSE;
- }
- if (*filename)
- (void) fclose(infp);
- if (mode != PROC && linserted > (linecount-linserted))
- error("Article rejected: %s included more text than new text",
- username);
-
- if (mode != PROC && !is_ctl && header.sender[0] == '\0') {
- int siglines = 0;
- char sbuf[BUFLEN];
- (void) sprintf(bfr, "%s/%s", userhome, ".signature");
- if (access(bfr, 4) == 0) {
- if ((infp = fopen(bfr, "r")) == NULL) {
- (void) fprintf(stderr,
- "inews: \"%s\" left off (must be readable by \"inews\" owner)\n", bfr);
- goto finish;
- }
-
- while (fgets(sbuf, sizeof sbuf, infp) != NULL)
- if (++siglines > 4)
- break;
- if (siglines > 4)
- fprintf(stderr,".signature not included (> 4 lines)\n");
- else {
- rewind(infp);
- fprintf(tmpfp, "-- \n"); /* To separate */
- linecount++;
- while ((c = getc(infp)) != EOF) {
- putc(c, tmpfp);
- if (c == '\n')
- linecount++;
- }
- }
- (void) fclose(infp);
- }
- }
-
-finish:
- if (ferror(tmpfp))
- xerror("write failed to temp file");
- (void) fclose(tmpfp);
- if (SigTrap) {
- if (tty)
- fprintf(stderr, "Interrupt\n");
- if (tty && !empty)
- fwait(fsubr(newssave, (char *) NULL, (char *) NULL));
- if (!tty)
- log("Blown away by an interrupt %d", SigTrap);
- xxit(1);
- }
- if (tty)
- fprintf(stderr, "EOT\n");
- fflush(stdout);
- infp = fopen(INFILE, "r");
- if (header.numlines[0]) {
- /*
- * Check line count if there's already one attached to
- * the article. Could make this a fatal error -
- * throwing it away if it got chopped, in hopes that
- * another copy will come in later with a correct
- * line count. But that seems a bit much for now.
- */
- if (linecount != header.intnumlines) {
- if (linecount == 0)
- error("%s rejected. linecount expected %d, got 0", header.ident, header.intnumlines);
- if (linecount > header.intnumlines ||
- linecount+consec_newlines < header.intnumlines)
- log("linecount expected %d, got %d", header.intnumlines, linecount+consec_newlines);
- }
- /* adjust count for blank lines we stripped off */
- if (consec_newlines) {
- header.intnumlines -= consec_newlines;
- if (header.intnumlines < 0 )
- header.intnumlines = 0; /* paranoia */
- (void) sprintf(header.numlines, "%d", header.intnumlines);
- }
-
- } else {
- /* Attach a line count to the article. */
- header.intnumlines = linecount;
- (void) sprintf(header.numlines, "%d", linecount);
- }
-}
-
-/*
- * Make the directory for a new newsgroup. ngname should be the
- * full pathname of the directory. Do the other stuff too.
- * The various games with setuid and chown are to try to make sure
- * the directory is owned by NEWSUSR and NEWSGRP, which is tough to
- * do if you aren't root. This will work on a UCB system (which allows
- * setuid(geteuid()) or a USG system (which allows you to give away files
- * you own with chown), otherwise you have to change your kernel to allow
- * one of these things or run with your dirs 777 so that it doesn't matter
- * who owns them.
- */
-mknewsg(fulldir, ngname)
-char *fulldir;
-char *ngname;
-{
-#ifdef USG
- register char *p;
- char parent[200];
- char sysbuf[200];
- struct stat sbuf;
-#endif /* USG */
-
- if (ngname == NULL || !isalpha(ngname[0]))
- xerror("Tried to make illegal newsgroup %s", ngname);
-
-#ifdef USG
- /*
- * If the parent is 755 the setuid(getuid)
- * will fail, and since mkdir is suid, and our real uid is random,
- * the mkdir will fail. So we have to temporarily chmod it to 777.
- */
- (void) strcpy(parent, fulldir);
- while (p = rindex(parent, '/')) {
- *p = '\0';
- if (stat(parent, &sbuf) == 0) {
- (void) chmod(parent, 0777);
- break;
- }
- }
-#endif /* USG */
-
- /* Create the directory */
- mkparents(fulldir);
- if (mkdir(fulldir, 0777) < 0)
- xerror("Cannot mkdir %s: %s", fulldir, errmsg(errno));
-
-#ifdef USG
- (void) chmod(parent, (int)sbuf.st_mode); /* put it back */
- /*
- * Give away the directories we just created which were assigned
- * our real uid.
- */
- (void) setuid(uid);
- (void) chown(fulldir, duid, dgid);
- (void) strcpy(sysbuf, fulldir);
- while (p = rindex(sysbuf, '/')) {
- *p = '\0';
- /* stop when get to last known good parent */
- if (strcmp(sysbuf, parent) == 0)
- break;
- (void) chown(sysbuf, duid, dgid);
- }
- (void) setuid(duid);
-#endif /* USG */
-
- log("make newsgroup %s in dir %s", ngname, fulldir);
-}
-
-/*
- * If any parent directories of this dir don't exist, create them.
- */
-mkparents(dname)
-char *dname;
-{
- char buf[200];
- register char *p;
-
- (void) strcpy(buf, dname);
- p = rindex(buf, '/');
- if (p)
- *p = '\0';
- if (exists(buf))
- return;
- mkparents(buf);
- if (mkdir(buf, 0777) < 0)
- xerror("Can not mkdir %s: %s", buf, errmsg(errno));
-}
-
-cancel()
-{
- register FILE *fp;
-
- log("cancel article %s", filename);
- fp = fopen(filename, "r");
- if (fp == NULL) {
- log("article %s not found", filename);
- return;
- }
- if (hread(&header, fp, TRUE) == NULL)
- error("Article is garbled.");
- (void) fclose(fp);
- (void) unlink(filename);
-}
-
-dounspool()
-{
- register DIR *dirp;
- register struct direct *dir;
- register int foundsome;
-#ifdef VMS
- sprintf(bfr, "%s/+rnews", SPOOLDIR);
-#else /* !VMS */
- sprintf(bfr, "%s/.rnews", SPOOLDIR);
-#endif /* !VMS */
-
- if (chdir(bfr) < 0)
- xerror("chdir(%s):%s", bfr, errmsg(errno));
-
- do {
- foundsome = 0;
- dirp = opendir(".");
- if (dirp == NULL) /* Boy are things screwed up */
- xerror("opendir can't open .:%s", errmsg(errno));
-
- while ((dir=readdir(dirp)) != NULL) {
- if (dir->d_name[0] == '.')
- continue;
- sprintf(bfr,"%s -S -p %s", RNEWS, dir->d_name);
- system(bfr);
- (void) unlink(dir->d_name);
- foundsome++;
- }
- closedir(dirp);
- } while (foundsome); /* keep rereading the directory until it's empty */
-
- xxit(0);
-}
*-*-END-of-src/inews.c-*-*
echo x - src/ifuncs.c 1>&2
sed 's/.//' >src/ifuncs.c <<'*-*-END-of-src/ifuncs.c-*-*'
-/*
- * This software is Copyright (c) 1986 by Rick Adams.
- *
- * Permission is hereby granted to copy, reproduce, redistribute or
- * otherwise use this software as long as: there is no monetary
- * profit gained specifically from the use or reproduction or this
- * software, it is not sold, rented, traded or otherwise marketed, and
- * this copyright notice is included prominently in any copy
- * made.
- *
- * The author make no claims as to the fitness or correctness of
- * this software for any use whatsoever, and it is provided as is.
- * Any use of this software is at the user's own risk.
- *
- * ifuncs - functions used by inews.
- */
-
-#ifdef SCCSID
-static char *SccsId = "@(#)ifuncs.c 2.57 10/29/86";
-#endif /* SCCSID */
-
-#include "iparams.h"
-#include <errno.h>
-
-/*LINTLIBRARY*/
-
-#define AFSIZ 4000 /* size of text in the active file for initial malloc */
-
-/*
- * Transmit this article to all interested systems.
- */
-
-#ifdef u370
-static struct srec srec;
-#endif /* u370 */
-
-static struct hbuf h, hh;
-
-#ifdef MULTICAST
-#define MAXMCAST 20
-#define MAXMCS 10
-
-struct multicast {
- char mc_name[SBUFLEN]; /* "multi-cast" name */
- short mc_syscnt;
- char mc_tosys[MAXMCAST][SBUFLEN];
-} mcast[MAXMCS];
-
-static int mccount;
-#endif /* MULTICAST */
-
-#ifndef DBM
-char *histfile();
-#endif /* !DBM */
-
-#ifdef VMS
-/*
- * For VMS/Eunice there are no links: article was moved to firstbufname
- * before broadcast is reached. So we read it from there.
- */
-extern char firstbufname[];
-#endif
-
-broadcast()
-{
- register char *hptr;
- register char *sptr;
- register FILE *fp;
-#ifndef u370
- struct srec srec;
-#endif
- char sentbuf[LBUFLEN];
- int nsent = 0;
- char *sentsys;
-
- /* h is a local copy of the header we can scribble on */
-#ifdef VMS
- fp = xfopen (firstbufname, "r");
-#else
- fp = xfopen(ARTICLE, "r");
-#endif
- if (hread(&h, fp, TRUE) == NULL)
- xerror("Cannot reread article");
- (void) fclose(fp);
-
- (void) strcpy(sentbuf, h.ident);
- (void) strcat(sentbuf, " sent to ");
- sentsys = index(sentbuf, 0);
- nsent = 0;
- /* break path into list of systems. */
- sptr = hptr = h.path;
- while ((hptr=strpbrk(hptr, NETCHRS)) != NULL) {
- *hptr++ = '\0';
- sptr = hptr;
- }
- *sptr = '\0';
-
-#ifdef MULTICAST
- mccount = 0;
-#endif /* MULTICAST */
-
- /* loop once per system. */
- s_openr();
- while (s_read(&srec)) {
- char *dist = h.distribution;
-#ifdef HIDDENNET
- if (strncmp(srec.s_name, LOCALSYSNAME, SNLN) == 0)
- continue;
-#endif /* HIDDENNET */
- if (strncmp(srec.s_name, FULLSYSNAME, SNLN) == 0)
- continue;
- if (sptr = srec.s_nosend) {
- while (*sptr) {
- while (*sptr && *sptr != ',')
- sptr++;
- if (*sptr == ',')
- *sptr++ = '\0';
- }
- *++sptr = '\0';
- }
- hptr = h.path;
- while (*hptr != '\0') {
- if (strncmp(srec.s_name, hptr, SNLN) == 0)
- goto contin;
- if (sptr = srec.s_nosend) {
- while (*sptr != '\0') {
- if (strncmp(sptr, hptr, SNLN) == 0)
- goto contin;
- while (*sptr++)
- ;
- }
- }
- while (*hptr++ != '\0')
- ;
- }
- if (!ngmatch(h.nbuf, srec.s_nbuf))
- continue;
- if (*dist == '\0')
- dist = "world";
- if (!ngmatch(dist, srec.s_nbuf) && !ngmatch(srec.s_nbuf, dist))
- continue;
-
- if (nsent) {
- hptr = sentsys;
- while ((sptr = index(hptr, ',')) != NULL) {
- *sptr = '\0';
- if (strcmp(hptr, srec.s_name) == 0) {
- *sptr = ',';
- goto contin;
- }
- *sptr++ = ',';
- for (hptr = sptr; isspace(*hptr); hptr++)
- ;
- }
- if (strcmp(hptr, srec.s_name) == 0)
- continue;
- }
- /* now we've found a system to send this article to */
-#ifdef MULTICAST
- if (index(srec.s_flags, 'M')) {
- /* do a "multi-cast" transmit */
- register struct multicast *m;
-
- if (strlen(srec.s_name) >= SBUFLEN ||
- strlen(srec.s_xmit) >= SBUFLEN)
- xerror("system name too long for multicast");
- for (m = mcast; m < &mcast[mccount]; m++)
- if (strcmp(srec.s_xmit, m->mc_name) == 0)
- break;
- if (m >= &mcast[MAXMCS])
- xerror("Too many multicasts");
- if (m == &mcast[mccount]) {
- mccount++;
- m->mc_syscnt = 0;
- strcpy(m->mc_name, srec.s_xmit);
- }
- if (m->mc_syscnt >= MAXMCAST)
- xerror("Too many systems for multicast");
- strcpy(m->mc_tosys[m->mc_syscnt++], srec.s_name);
- } else {
- register struct multicast *m;
- register char **yptr;
- char *sysptrs[MAXMCAST];
- int mc;
-
- mc = 0;
- for (m = mcast; m < &mcast[mccount]; m++)
- if (strcmp(m->mc_name, srec.s_name) == 0) {
- yptr = sysptrs;
- while (mc < m->mc_syscnt)
- *yptr++ = m->mc_tosys[mc++];
- break;
- }
-#ifdef VMS
- if (!transmit(&srec, xfopen(firstbufname,"r"), 1,
- sysptrs, mc))
-#else /* !VMS */
- if (!transmit(&srec, xfopen(ARTICLE,"r"), 1, sysptrs,
- mc))
-#endif /* !VMS */
- continue;
- }
-#else /* !MULTICAST */
-#ifdef VMS
- if (!transmit(&srec, xfopen(firstbufname, "r"),
-#else /* !VMS */
- if (!transmit(&srec, xfopen(ARTICLE, "r"),
-#endif /* !VMS */
- (strncmp(h.nbuf, "to.", 3) != 0),
- (char **) NULL, FALSE))
- continue;
-#endif /* !MULTICAST */
- if (nsent)
- (void) strcat(sentbuf, ", ");
- (void) strcat(sentbuf, srec.s_name);
- nsent++;
- contin:;
- }
- if (nsent)
- log(sentbuf);
- s_close();
-}
-
-/*
- * Transmit file to system.
- */
-#define PROC 0004
-#ifndef MULTICAST
-/* ARGSUSED */
-#endif /* !MULTICAST */
-transmit(sp, ifp, maynotify, sysnames, mc)
-register struct srec *sp;
-register FILE *ifp;
-int maynotify;
-char **sysnames;
-int mc;
-{
- register FILE *ofp;
- register int c;
- register char *ptr;
- char TRANS[BUFLEN];
- char *argv[20];
- register int pid;
- extern char firstbufname[];
-
-/* A: afmt: the other machine runs an A news, so we xmit in A format */
- int afmt = (index(sp->s_flags, 'A') != NULL);
-/* B: use B format (this is the default - don't use this letter elsewise). */
-/* F: append name to file */
- int appfile = (index(sp->s_flags, 'F') != NULL);
-/* L: local: don't send the article unless it was generated locally */
- int local = ((ptr = index(sp->s_flags, 'L')) != NULL);
-/* H: interpolate history line into command, use existing file */
- int history = (index(sp->s_flags, 'H') != NULL);
-/* m: moderated: only send if group is moderated */
- int sendifmoderated = (index(sp->s_flags, 'm') != NULL);
-/* u: unmoderated: only send if group is unmoderated */
- int sendifunmoderated = (index(sp->s_flags, 'u') != NULL);
-/* M: multi-cast: this is taken care of above, but don't reuse flag */
-#ifdef MULTICAST
-/* O: multi-cast only, don't send article if not multicast hosts */
- int multisend = (index(sp->s_flags, 'O') != NULL);
-#endif /* MULTICAST */
-/* N: notify: don't send the article, just tell him we have it */
- int notify = maynotify && (index(sp->s_flags, 'N') != NULL);
-/* S: noshell: don't fork a shell to execute the xmit command */
- int noshell = (index(sp->s_flags, 'S') != NULL);
-/* U: useexist: use the -c option to uux to use the existing copy */
- int useexist = (index(sp->s_flags, 'U') != NULL);
-/* I: append messageid to file. implies F flag */
- int appmsgid = maynotify && (index(sp->s_flags, 'I') != NULL);
-
- if (notify)
- appfile = appmsgid = FALSE;
-
- if (!appfile)
- appfile = appmsgid;
-
- if (local && mode == PROC) {
- local = 0;
- while (isdigit(*++ptr))
- local = local * 10 + *ptr - '0';
- for (ptr = h.path; *ptr != '\0' && local >= 0; local--)
- while (*ptr++ != '\0')
- ;
- if (local < 0) {
- (void) fclose(ifp);
- return FALSE;
- }
- }
-
- /*
- ** Do not transmit to system specified in -x flag.
- */
- if (not_here[0] && strcmp(not_here, sp->s_name) == 0) {
- (void) fclose(ifp);
- return FALSE;
- }
-
-#ifdef DEBUG
- printf("Transmitting to '%s'\n", sp->s_name);
-#endif /* DEBUG */
-
-#ifdef MULTICAST
- if (multisend && mc == 0) {
- (void) fclose(ifp);
- return FALSE;
- }
-#endif /* MULTICAST */
-
- if ((sendifmoderated && is_mod[0] == '\0') ||
- (sendifunmoderated && is_mod[0] != '\0')) {
- fclose(ifp);
- return FALSE;
- }
-
- if (appmsgid || (!appfile && !useexist && !history)) {
- if (!hread(&hh, ifp, TRUE)) {
- logerr("Bad header, not transmitting %s re %s to %s",
- hh.ident, hh.title, sp->s_name);
- (void) fclose(ifp);
- return FALSE;
- }
- if (hh.nbuf[0] == '\0') {
- fprintf(stderr, "Article not subscribed to by %s\n", sp->s_name);
- (void) fclose(ifp);
- return FALSE;
- }
- (void) sprintf(TRANS, "%s/trXXXXXX", SPOOL);
- }
-
- if (notify) {
- char oldid[50];
- (void) sprintf(hh.title, "ihave %s %s", hh.ident, FULLSYSNAME);
- (void) strcpy(hh.ctlmsg, hh.title);
- (void) strcpy(hh.numlines, "0");
- (void) sprintf(hh.nbuf, "to.%s.ctl", sp->s_name);
- (void) strcpy(oldid, hh.ident);
- getident(&hh);
- log("tell %s about %s, notif. id %s",
- sp->s_name, oldid, hh.ident);
- }
-
- if (appfile) {
- if (firstbufname[0] == '\0') {
- extern char histline[];
- localize("junk");
- savehist(histline);
- xerror("No file name to xmit from");
- }
- if (sp->s_xmit[0] == '\0')
- sprintf(sp->s_xmit, "%s/%s%s", BATCHDIR, sp->s_name,
- appmsgid ? ".ihave" : "");
-#ifdef IHCC
- (void) sprintf(TRANS, "%s/%s/%s", logdir(HOME), BATCHDIR, sp->s_xmit);
- ofp = fopen(TRANS, "a");
-#else /* !IHCC */
- ofp = fopen(sp->s_xmit, "a");
-#endif /* !IHCC */
- if (ofp == NULL)
- xerror("Cannot append to %s", sp->s_xmit);
- fprintf(ofp, "%s", appmsgid ? hh.ident : firstbufname);
-#ifdef MULTICAST
- while (--mc >= 0)
- fprintf(ofp, " %s", *sysnames++);
-#endif /* !MULTICAST */
- putc('\n', ofp);
- (void) fclose(ofp);
- (void) fclose(ifp);
- return TRUE;
- }
- else if (useexist) {
- if (firstbufname[0] == '\0')
- xerror("No file name to xmit from");
- if (*sp->s_xmit == '\0')
-#ifdef UXMIT
- (void) sprintf(bfr, UXMIT, sp->s_name, firstbufname);
-#else
- xerror("UXMIT not defined for U flag");
-#endif
- else
-#ifdef MULTICAST
- makeargs(bfr, sp->s_xmit, firstbufname, sysnames, mc);
-#else
- (void) sprintf(bfr, sp->s_xmit, firstbufname);
-#endif
- (void) fclose(ifp);
- } else if (history) {
- extern char histline[];
-
- if (*sp->s_xmit == '\0')
- xerror("no xmit command with H flag");
-#ifdef MULTICAST
- makeargs(bfr, sp->s_xmit, histline, sysnames, mc);
-#else
- (void) sprintf(bfr, sp->s_xmit, histline);
-#endif
- } else {
- ofp = xfopen(mktemp(TRANS), "w");
- if (afmt) {
-#ifdef OLD
- fprintf(ofp, "A%s\n%s\n%s!%s\n%s\n%s\n", oident(hh.ident), hh.nbuf, FULLSYSNAME,
- hh.path, hh.subdate, hh.title);
-#else /* !OLD */
- logerr("Must have OLD defined to use A flag for xmit");
- return FALSE;
-#endif /* !OLD */
- } else
- hwrite(&hh, ofp);
- if (!notify)
- while ((c = getc(ifp)) != EOF)
- putc(c, ofp);
- if (ferror(ofp))
- xerror("write failed on transmit");
- (void) fclose(ifp);
- (void) fclose(ofp);
- if (*sp->s_xmit == '\0')
- (void) sprintf(bfr, DFTXMIT, sp->s_name, TRANS);
- else
-#ifdef MULTICAST
- makeargs(bfr, sp->s_xmit, TRANS, sysnames, mc);
-#else /* !MULTICAST */
- (void) sprintf(bfr, sp->s_xmit, TRANS);
-#endif /* !MULTICAST */
- }
-
- /* At this point, the command to be executed is in bfr. */
- if (noshell) {
- if (pid = vfork())
- fwait(pid);
- else {
- (void) close(0);
- (void) open(TRANS, 0);
- ptr = bfr;
- for (pid = 0; pid < 19; pid++) {
- while (isspace(*ptr))
- *ptr++ = 0;
- argv[pid] = ptr;
- while (!isspace(*++ptr) && *ptr)
- ;
- if (!*ptr)
- break;
- }
- argv[++pid] = 0;
- (void) setgid(gid);
- (void) setuid(uid);
- execv(argv[0], argv);
- xerror("Can't execv %s", argv[0]);
- }
- } else {
- if (!history && sp->s_xmit[0] && !index(bfr, '<')) {
- char newcmd[LBUFLEN];
-
- (void) sprintf(newcmd, "(%s) <%s", bfr,
- useexist ? firstbufname : TRANS);
- system(newcmd);
- } else
- system(bfr);
- }
- if (!appfile && !useexist && !history)
- (void) unlink(TRANS);
- (void) fclose(ifp);
- return TRUE;
-}
-
-#ifdef MULTICAST
-makeargs(buf, cmd, arg2, sysargs, sac)
-char *buf;
-char *cmd;
-char *arg2;
-register char **sysargs;
-int sac;
-{
- register char *p = cmd;
- register char *q;
- register ac = 0;
- register char *b = buf;
-
- q = p;
- do {
- if (q = index(q, ' '))
- *q = '\0';
- if (index(p, '%')) {
- switch (++ac) {
- case 1:
- while (--sac >= 0) {
- sprintf(b, p, *sysargs++);
- b = index(b, '\0');
- }
- break;
- case 2:
- sprintf(b, p, arg2);
- b = index(b, '\0');
- break;
- default:
- if (q)
- *q = ' ';
- xerror("badly formed command: %s", cmd);
- }
- } else {
- strcpy(b, p);
- b = index(b, '\0');
- }
- if (q) {
- *q = ' ';
- p = q;
- while (isspace(*q))
- q++;
- }
- } while (q != NULL);
-}
-#endif /* MULTICAST */
-
-typedef struct {
- char *dptr;
- int dsize;
-} datum;
-
-/*
- * Return TRUE if we have seen this file before, else FALSE.
- */
-history(hp)
-struct hbuf *hp;
-{
-#ifdef DBM
- datum lhs, rhs;
- datum fetch();
-#else /* !DBM */
- register FILE *hfp;
- register char *p;
-#endif /* !DBM */
- char lcident[BUFLEN];
- extern char histline[];
-
-#ifdef DEBUG
- fprintf(stderr,"history(%s)\n", hp->ident);
-#endif /* DEBUG */
- /*
- * Make the article ID case insensitive.
- */
- (void) strcpy(lcident, hp->ident);
- lcase(lcident);
-
- idlock(lcident);
-#ifdef DBM
- initdbm(ARTFILE);
- lhs.dptr = lcident;
- lhs.dsize = strlen(lhs.dptr) + 1;
- rhs = fetch(lhs);
- if (rhs.dptr)
- return(TRUE);
-#else /* !DBM */
- hfp = xfopen(histfile(lcident), "r");
- while (fgets(bfr, BUFLEN, hfp) != NULL) {
- p = index(bfr, '\t');
- if (p == NULL)
- p = index(bfr, '\n');
- if (p != NULL) /* can happen if nulls in file */
- *p = 0;
- lcase(bfr);
-
- if (strcmp(bfr, lcident) == 0) {
- (void) fclose(hfp);
- idunlock();
-#ifdef DEBUG
- fprintf(stderr,"history returns true\n");
-#endif /* DEBUG */
- return TRUE;
- }
- }
- (void) fclose(hfp);
-#endif /* !DBM */
- histline[0] = '\0';
- addhist(hp->ident);
- addhist("\t");
-#ifdef DEBUG
- fprintf(stderr,"history returns false\n");
-#endif
- return FALSE;
-}
-
-char histline[PATHLEN];
-
-addhist(msg)
-char *msg;
-{
- (void) strcat(histline, msg);
-}
-
-savehist(hline)
-char *hline;
-{
- register FILE *hfp;
- datum lhs, rhs;
- long fpos;
- register char *p;
-
- hfp = xfopen(ARTFILE, "a");
- (void) fseek(hfp, 0L, 2); /* Unisoft 5.1 doesn't seek to EOF on 'a' */
- fpos = ftell(hfp);
- fprintf(hfp, "%s\n", hline);
- (void) fclose(hfp);
-#ifdef DBM
- /* We assume that history has already been called, calling dbminit. */
- p = index(hline, '\t');
- if (p)
- *p = 0;
- lcase(hline);
- lhs.dptr = hline;
- lhs.dsize = strlen(lhs.dptr) + 1;
- rhs.dptr = (char *)&fpos;
- rhs.dsize = sizeof fpos;
- store(lhs, rhs);
-#else /* !DBM */
- /* also append to proper history subfile */
- hfp = xfopen(histfile(hline), "a");
- fprintf(hfp, "%s\n", hline);
- (void) fclose(hfp);
-#endif /* !DBM */
- idunlock();
-}
-
-/*
- * Save partial news.
- */
-/* ARGSUSED */
-newssave(fd, dummy)
-FILE *fd;
-char *dummy;
-{
- register FILE *tofd, *fromfd;
- char sfname[BUFLEN];
- register int c;
- time_t tim;
-
- if (fd == NULL)
- fromfd = xfopen(INFILE, "r");
- else
- fromfd = fd;
- (void) umask(savmask);
- (void) setgid(gid);
- (void) setuid(uid);
-
- (void) sprintf(sfname, "%s/%s", userhome, PARTIAL);
- if ((tofd = fopen(sfname, "a")) == NULL)
- xerror("Cannot save partial news in %s", sfname);
- (void) time(&tim);
- fprintf(tofd, "----- News saved at %s\n", arpadate(&tim));
- while ((c = getc(fromfd)) != EOF)
- putc(c, tofd);
- (void) fclose(fromfd);
- (void) fclose(tofd);
- printf("News saved in %s\n", sfname);
- xxit(1);
-}
-
-/*
- * Handle dates in header.
- */
-
-dates(hp)
-struct hbuf *hp;
-{
- time_t edt;
-
- if (*hp->subdate) {
- if (cgtdate(hp->subdate) < 0) {
- error("Cannot parse submittal date '%s'", hp->subdate);
- }
- } else {
- (void) time(&edt);
- (void) strcpy(hp->subdate, arpadate(&edt));
- }
-}
-
-#define LOCKSIZE 128
-char lockname[LOCKSIZE];
-
-idlock(str)
-char *str;
-{
- register int i;
- register char *cp, *scp;
- char tempname[LOCKSIZE];
- time_t now;
- struct stat sbuf;
- extern int errno;
-#ifdef VMS
- int fd;
-
- (void) sprintf(lockname, "/tmp/%s.l.1", str);
- while ((fd = creat(lockname, 0444)) < 0) {
-#else /* !VMS */
- (void) strcpy(tempname, "/tmp/LTMP.XXXXXX");
- (void) mktemp(tempname);
- (void) strcpy(lockname, "/tmp/L");
- i = strlen(lockname);
- cp = &lockname[i];
- scp = str - 1;
- while (i++ < LOCKSIZE && *++scp != '\0')
- if (*scp == '/') /* slash screws up the open */
- *cp++ = '.';
- else
- *cp++ = *scp;
- *cp = '\0';
-#ifdef FOURTEENMAX
- lockname[5 /* /tmp/ */ + 14] = '\0';
-#endif
- i = creat(tempname, 0666);
- if (i < 0)
- xerror("Cannot creat %s: errno %d", tempname, errno);
- (void) close(i);
- while (link(tempname, lockname)) {
-#endif /* !VMS */
- (void) time(&now);
- if (stat(lockname, &sbuf) < 0)
- xerror("Directory permission problem in /tmp");
-
- if (sbuf.st_mtime + 10*60 < now) {
- (void) unlink(lockname);
- logerr("Article %s locked up", str);
- break;
- }
- log("waiting on lock for %s", lockname);
- sleep((unsigned)60);
- }
-#ifdef VMS
- (void) close(fd);
-#endif
- (void) unlink(tempname);
-}
-
-idunlock()
-{
- (void) unlink(lockname);
-}
-
-/*
- * Put a unique name into header.ident.
- */
-getident(hp)
-struct hbuf *hp;
-{
- long seqn;
- register FILE *fp;
-
- lock();
- fp = xfopen(SEQFILE, "r");
- (void) fgets(bfr, BUFLEN, fp);
- (void) fclose(fp);
- seqn = atol(bfr) + 1;
-/*
- * For Eunice, this breaks if SEQFILE is not in Unix format.
- */
- fp = xfopen(SEQFILE, "r+w");
- fprintf(fp, "%ld\n", seqn);
- (void) fclose(fp);
- unlock();
-#ifdef HIDDENNET
- if (strcmp(LOCALSYSNAME, FULLSYSNAME))
- (void) sprintf(hp->ident, "<%ld@%s.%s%s>", seqn, LOCALSYSNAME, FULLSYSNAME,
- MYDOMAIN);
- else
-#endif /* !HIDDENNET */
- (void) sprintf(hp->ident, "<%ld@%s%s>", seqn, FULLSYSNAME, MYDOMAIN);
-}
-
-/*
- * Check that header.nbuf contains only valid newsgroup names;
- * exit with error if not valid.
- */
-ngfcheck(isproc)
-{
- register FILE * f;
- register char * cp;
- register int i, j;
- register int ngcount, okcount, havealiased;
- register int pass;
- char * ngs[sizeof header.nbuf / 2];
- char uses[sizeof header.nbuf / 2];
- char tbuf[sizeof header.nbuf];
- char abuf[BUFLEN];
-
- havealiased = ngcount = 0;
- is_mod[0] = '\0';
- /*
- ** Split header.nbuf into constituent newsgroups.
- ** Zap "local" newsgroups of articles from remote sites.
- */
- cp = tbuf;
- (void) strcpy(cp, header.nbuf);
- for ( ; ; ) {
- while (*cp == NGDELIM || *cp == ' ')
- ++cp;
- if (*cp == '\0')
- break;
- ngs[ngcount] = cp;
- do {
- ++cp;
- } while (*cp != '\0' && *cp != NGDELIM && *cp != ' ');
- if (*cp != '\0')
- *cp++ = '\0';
- /*
- ** Check for local only distribution on incoming
- ** newsgroups. This might occur if someone posted to
- ** general,net.unix
- */
- if (isproc && index(ngs[ngcount], '.') == NULL &&
- index(header.nbuf, '.') != NULL) {
- logerr("Local group '%s' removed",
- ngs[ngcount]);
- continue;
- }
- uses[ngcount] = 1; /* it should go in "Newsgroups" line */
- ++ngcount;
- }
- /*
- ** Check groups against active file.
- */
-recheck:
- okcount = 0;
- rewind(actfp); clearerr(actfp);
- while (okcount < ngcount && fgets(bfr, BUFLEN, actfp) == bfr) {
- if ((cp = index(bfr, ' ')) == NULL)
- continue; /* strange line in input! */
- /* newsgroup 12345 12345 X */
- /* cp + 01234567890123 */
- if (!isproc && cp[13] == 'n')
- continue; /* can't post to this group! */
- *cp = '\0';
- for (i = 0; i < ngcount; ++i)
- if (uses[i] >= 1 && strcmp(bfr, ngs[i]) == 0) {
- uses[i] = 2; /* it should be localized too */
- if (cp[13] == 'm')
- strcpy(is_mod, bfr);
- ++okcount;
- }
- }
-#ifdef ALWAYSALIAS
- okcount = 0;
-#endif /* ALWAYSALIAS */
- /*
- ** Handle groups absent from active file.
- */
- if (havealiased == 0 && okcount < ngcount) {
- /*
- ** See if remaining groups are in our alias list.
- */
- f = xfopen(ALIASES, "r");
- while (okcount < ngcount && fscanf(f, "%s %s", abuf, bfr) == 2)
- for (i = 0; i < ngcount; ++i) {
-#ifndef ALWAYSALIAS
- if (uses[i] == 2)
- continue;
-#endif /* ALWAYSALIAS */
- if (strcmp(ngs[i], abuf) != 0)
- continue;
- if (isproc)
- cp = "Aliased newsgroup %s to %s";
- else
- cp = "Please change %s to %s";
- logerr(cp, abuf, bfr);
- ngs[i] = AllocCpy(bfr);
- uses[i] = 2;
- ++havealiased;
- ++okcount;
- }
- (void) fclose(f);
- for (i = 0; i < ngcount; ++i) {
- if (uses[i] == 2)
- continue;
- if (isproc)
- cp = "Unknown newsgroup '%s' not localized";
- else
- cp = "Unknown newsgroup '%s'";
- logerr(cp, ngs[i]);
-#ifdef ALWAYSALIAS
- ++okcount; /* so we know to exit below */
- }
- if (!isproc && okcount > 0)
-#else /* !ALWAYSALIAS */
- }
- if (!isproc)
-#endif /* !ALWAYSALIAS */
- newssave(infp, (char *) NULL);
- /*
- * Unfortunately, if you alias an unmoderated group to a
- * moderated group, you must recheck the active file to see
- * if the new group is moderated. Rude but necessary.
- */
- if (havealiased)
- goto recheck;
- }
- /*
- ** Zap duplicates.
- */
- for (i = 0; i < ngcount - 1; ++i) {
- if (uses[i] == 0)
- continue;
- for (j = i + 1; j < ngcount; ++j) {
- if (uses[j] == 0)
- continue;
- if (strcmp(ngs[i], ngs[j]) != 0)
- continue;
- logerr("Duplicate '%s' removed", ngs[j]);
- if (uses[i] < uses[j])
- uses[i] = uses[j];
- uses[j] = 0;
- }
- }
- for (pass = 1; pass <= 2; ++pass) {
- register int avail;
-
- if (pass == 1) {
- /*
- ** Rewrite header.nbuf.
- */
- cp = header.nbuf;
- avail = sizeof header.nbuf;
- } else {
- /*
- ** Fill in nbuf.
- */
- cp = nbuf;
- avail = sizeof nbuf;
- }
- for (i = 0; i < ngcount; ++i) {
- if (uses[i] < pass)
- continue;
- j = strlen(ngs[i]);
- if (j + 2 > avail) {
- logerr("Redone Newsgroups too long");
- break;
- }
- (void) strcpy(cp, ngs[i]);
- cp += j;
- *cp++ = (pass == 1) ? NGDELIM : '\0';
- avail -= (j + 1);
- }
- if (pass == 1) {
- if (cp == header.nbuf)
- *cp = '\0';
- else *(cp - 1) = '\0';
- } else *cp = '\0';
- }
- /*
- ** Free aliases.
- */
- for (i = 0; i < ngcount; ++i)
- if (ngs[i] < tbuf || ngs[i] > &tbuf[sizeof tbuf - 1])
- free(ngs[i]);
- return nbuf[0] == '\0';
-}
-
-/*
- * Figure out who posted the article (which is locally entered).
- * The results are placed in the header structure hp.
- */
-gensender(hp, logname)
-struct hbuf *hp;
-char *logname;
-{
- register char *fn, *p;
- char buf[BUFLEN];
- char *fullname(), *getenv();
- int fd, n;
-
- if ((fn = getenv("NAME")) == NULL) {
- (void) sprintf(buf, "%s/%s", userhome, ".name");
- if ((fd = open(buf, 0)) >= 0) {
- n = read(fd, buf, sizeof buf);
- (void) close(fd);
- if (n > 0 && buf[0] >= 'A') {
- for (p = fn = buf; *p; p++)
- if (*p < ' ')
- *p = '\0';
- }
- }
- }
-
- if (fn == NULL)
- fn = fullname(logname);
-
- (void) sprintf(hp->path, "%s", logname);
- (void) sprintf(hp->from, "%s@%s%s (%s)", logname, FULLSYSNAME, MYDOMAIN, fn);
-}
-
-/*
- * Trap interrupts.
- */
-onsig(n)
-int n;
-{
- static int numsigs = 0;
- /*
- * Most UNIX systems reset caught signals to SIG_DFL.
- * This bad design requires that the trap be set again here.
- * Unfortunately, if the signal recurs before the trap is set,
- * the program will die, possibly leaving the lock in place.
- */
- if (++numsigs > 100) {
- logerr("inews ran away looping on signal %d", n);
- xxit(1);
- }
- (void) signal(n, onsig);
- SigTrap = n;
-}
-
-#ifdef BATCH
-/*
- * If the stdin begins with "#", we assume we have been fed a batched
- * shell script which looks like this:
- * #! rnews 1234
- * article with 1234 chars
- * #! rnews 4321
- * article with 4321 chars
- *
- * In this case we just exec the unbatcher and let it unpack and call us back.
- *
- * Note that there is a potential security hole here. If the batcher is
- * /bin/sh, someone could ship you arbitrary stuff to run as shell commands.
- * The main protection you have is that the effective uid will be news, not
- * uucp and not the super user. (That, plus the fact that BATCH is set to
- * "unbatch" as the system is distributed.) If you want to run a batched link
- * and you are security conscious, do not use /bin/sh as the unbatcher.
- * the thing to do is to change BATCH in your localize.sh file from /bin/sh
- * to some restricted shell which can only run rnews.
- */
-checkbatch()
-{
- int c;
-
- c = getc(infp);
- if (c != EOF)
- (void) ungetc(c, infp);
- clearerr(infp);
- if (c == '#') {
- char cmd[BUFLEN], unbatcher[BUFLEN], arg1[BUFLEN], arg2[BUFLEN];
- register char *cp;
- int n;
-
- reset_infp();
- /*
- * For efficiency, try and recognize the most common
- * forms of batching and exec them directly
- */
- n = read(0, cmd, BUFLEN-1);
- if (n <= 0) /* Can't happen */
- xerror("can't read stdin to unbatch");
- cmd[n] = '\0';
- cp = index(cmd, '\n');
- if (cp)
- *cp = '\0';
- /* now put stdin at the "right" place for the exec */
- (void) lseek(0,1L+(long)(cp - cmd), 0);
- if( strncmp(cmd, "#! cunbatch", 11) == 0) {
- (void) strcpy(unbatcher, "/bin/sh");
- (void) strcpy(arg1, "-c");
- (void) sprintf(arg2, "%s/compress -d | %s/%s",
- LIB, LIB, BATCH);
- } else if (strncmp(cmd, "#! c7unbatch", 12) == 0) {
- (void) strcpy(unbatcher, "/bin/sh");
- (void) strcpy(arg1, "-c");
- (void) sprintf(arg2,
- "%s/decode | %s/compress -d | %s/%s",
- LIB, LIB, LIB, BATCH);
- } else {
- (void) lseek(0, 0L, 0);
- (void) sprintf(unbatcher, "%s/%s", LIB, BATCH);
- arg1[0] = '\0';
- arg2[0] = '\0';
- }
- execl(unbatcher, "news-unpack", arg1, arg2, (char *)0);
- xerror("Unable to exec %s to unpack news.", unbatcher);
- }
-}
-
-/*
- * We've already done a read on stdin, and we want to seek back to the
- * beginning. We want the real file descriptor (beyond buffers) to
- * reflect the true beginning. Do whatever is necessary.
- */
-reset_infp()
-{
- register FILE *ofd;
- register int c;
- char *ofdname;
- long lseek();
-
- /* First try to seek back - if so, it's a cheap way back. */
- if (lseek(0, 0L, 0) == 0L)
- return;
-
- /* Can't seek, so have to copy input to a file and use that. */
- ofdname = "/tmp/inewsXXXXXX";
- (void) mktemp(ofdname);
- ofd = fopen(ofdname, "w");
- while ((c=getc(infp)) != EOF)
- putc(c, ofd);
- if (ferror(ofd))
- xerror("write failed on temp file %s", ofdname);
- (void) fclose(ofd);
- (void) fclose(infp);
-
- /* Now for a few lower level hacks to reopen stdin and make
- * absolutely sure that the right fd's are done for the exec.
- */
- (void) close(0); /* make sure stdin is really closed. */
- (void) open(ofdname, 0);
- (void) unlink(ofdname); /* to avoid cleaning it up later. */
-}
-#endif /* BATCH */
-
-/*
- * Exit and cleanup.
- */
-xxit(status)
-int status;
-{
- (void) unlink(INFILE);
- (void) unlink(ARTICLE);
- while (lockcount > 0)
- unlock();
- idunlock();
- exit(status);
-}
-
-rwaccess(fname)
-char *fname;
-{
- int fd;
-
- fd = open(fname, 2);
- if (fd < 0)
- return 0;
- (void) close(fd);
- return 1;
-}
-
-exists(fname)
-char *fname;
-{
- int fd;
-
- fd = open(fname, 0);
- if (fd < 0)
- return 0;
- (void) close(fd);
- return 1;
-}
-
-int lockcount = 0; /* no. of times we've called lock */
-
-#ifdef VMS
-
-#define SUBLOCK "/tmp/netnews.lck.1"
-
-/*
- * Newsystem locking.
- * These routines are different for VMS because we can not
- * effectively simulate links, and VMS supports multiple
- * version numbers of files
- */
-lock()
-{
- register int i;
- register int fd;
-
- if (lockcount++ == 0) {
- i = DEADTIME;
- while ((fd = creat(SUBLOCK, 0444)) < 0) {
- if (--i < 0) {
- (void) unlink(SUBLOCK);
- logerr("News system locked up");
- }
- if (i < -3)
- xerror("Unable to unlock news system");
- sleep((unsigned)1);
- }
- (void) close(fd);
- }
-}
-
-unlock()
-{
- if (--lockcount == 0)
- (void) unlink(SUBLOCK);
-}
-
-#else /* !VMS */
-
-/*
- * Newsystem locking.
- */
-
-#if defined(BSD4_2) || defined(LOCKF)
-#ifdef LOCKF
-#include <unistd.h>
-#else /* !LOCKF */
-#include <sys/file.h>
-#endif /* !LOCKF */
-static int LockFd = -1;
-lock()
-{
- LockFd = open(SUBFILE,0);
- /* This will sleep until the other program releases the lock */
- /* We may need to alarm out of this, but I don't think so */
-#ifdef LOCKF
- (void) lockf(LockFd, F_LOCK, 0);
-#else
- (void) flock(LockFd, LOCK_EX);
-#endif
-}
-
-unlock()
-{
- (void) close(LockFd);
-}
-#else /* !BSD4_2 */
-lock()
-{
- register int i;
- extern int errno;
-
- if (lockcount++ == 0) {
- i = DEADTIME;
- while (link(SUBFILE, LOCKFILE)) {
- if (errno != EEXIST)
- break;
- if (--i < 0)
- xerror("News system locked up");
- sleep((unsigned)1);
- }
- }
-}
-
-unlock()
-{
- if (--lockcount == 0)
- (void) unlink(LOCKFILE);
-}
-#endif /* !BSD4_2 */
-#endif /* !VMS */
-
-/*
- * Generate the name of the person responsible for posting this article,
- * in order to check that two articles were posted by the same person.
- */
-char *
-senderof(hp)
-struct hbuf *hp;
-{
- register char *r, *q, *tp;
- char *tailpath();
-
- if (hp->sender[0])
- tp = hp->sender;
- else if (hp->from[0])
- tp = hp->from;
- else
- tp = tailpath(hp);
-
- /* Remove full name */
- q = index(tp, ' ');
- if (q)
- *q = '\0';
-
- r = AllocCpy(tp);
- if (q != NULL)
- *q = ' ';
- return r;
-}
-
-/* VARARGS1 */
-error(message, arg1, arg2, arg3)
-char *message;
-long arg1, arg2, arg3;
-{
- char buffer[LBUFLEN];
-
- fflush(stdout);
- (void) sprintf(buffer, message, arg1, arg2, arg3);
- logerr(buffer);
- xxit(mode == PROC ? 0 : 1);
-}
*-*-END-of-src/ifuncs.c-*-*
echo x - src/patchlevel.h 1>&2
sed 's/.//' >src/patchlevel.h <<'*-*-END-of-src/patchlevel.h-*-*'
-0
*-*-END-of-src/patchlevel.h-*-*
echo x - src/localize.sh 1>&2
sed 's/.//' >src/localize.sh <<'*-*-END-of-src/localize.sh-*-*'
*-*-END-of-src/localize.sh-*-*
exit
More information about the Mod.sources
mailing list