[mod.sources] v07i053: 2.11 News Source, Part04/09

sources-request@mirror.UUCP (11/06/86)

Submitted by: seismo!rick (Rick Adams)
Mod.sources: Volume 7, Issue 53
Archive-name: 2.11news/Part14

# To extract, sh this file
#
#	news 2.11 source part 4 of 9
#
if test ! -d src
then
	mkdir src
fi
echo x - src/postnews.c 1>&2
sed 's/.//' >src/postnews.c <<'*-*-END-of-src/postnews.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.
- *
- * Postnews: post a news message to Usenet.  This C version replaces a shell
- * script, and does more intelligent prompting and filtering than possible
- * in a shell script.
- */
-
-#ifdef SCCSID
-static char	*SccsId = "@(#)postnews.c	1.28	10/23/86";
-#endif /* SCCSID */
-
-#include "params.h"
-
-#define APPEND 1
-#define REPLACE 2
-
-extern char *MAILPARSER;
-
-char tempfname[50];		/* file name used for making article */
-char original[BUFLEN];		/* file name of original, used in followup */
-char homedir[BUFLEN];		/* HOME environment setting */
-char user[SBUFLEN];		/* user name */
-char ccname[BUFLEN];		/* file name for article copy */
-
-/* article header information */
-char subject[BUFLEN];
-char distribution[BUFLEN];
-char references[BUFLEN];
-char newsgroups[BUFLEN];
-char isfrom[BUFLEN];
-char msgid[BUFLEN];
-char keywords[BUFLEN];
-char summary[BUFLEN];
-
-char ngsep[] = { NGDELIM, '\0' };	/* == "," */
-
-char *Progname = "postnews";		/* for xerror */
-
-time_t fmodtime;
-char buf[BUFLEN];
-
-#define MAXDISTR	16
-struct distr {
-	char abbr[24];
-	char descr[128];
-} distr[MAXDISTR];
-
-FILE *xfopen();
-
-main(argc, argv)
-char *argv[];
-{
-	register int c;
-
-	init();
-
-	if (argc == 2) {
-		if (!prefix(argv[1], SPOOL))
-			xerror("Can only followup to articles in %s", SPOOL);
-		followup(argv[1]);
-		(void) strcpy(original, argv[1]);
-	} else
-	if (askyes("Is this message in response to some other message? ","no")) {
-		char ng[BUFLEN], num[BUFLEN];
-		long i, j, lastnum;
-		register char *p;
-		int fd, dir;
-		char canpost;
-
-		getpr("In what newsgroup was the article posted? ",ng);
-		if (!valid_ng(ng, &i, &j, &canpost))
-			if (canpost == 'i' )
-				byebye("There is no such newsgroup.");
-			else if (canpost == 'n')
-				byebye("You are not allowed to post to that group.");
-
-		printf("Valid article numbers are from %ld to %ld\n", j, i);
-		lastnum = i + 1;
-		dir = -1;
-
-		for(;;) {
-			getpr("\nWhat was the article number? ", num);
-			switch(num[0]) {
-			case '+':
-				dir = 1;
-				sprintf(num, "%ld", lastnum + 1);
-				break;
-			case '-':
-				dir = -1;
-				/* no break */
-			case '\0':
-				sprintf(num, "%ld", lastnum + dir);
-				break;
-			}
-			(void) sprintf(original, "%s/%s", SPOOL, ng);
-			for (p=original+strlen(SPOOL)+1; *p ;++p)
-				if (*p == '.')
-					*p = '/';
-			(void) strcat(original, "/");
-			(void) strcat(original, num);
-
-			if ((fd=open(original,0)) >= 0) {
-				(void) close(fd);
-				printf("\narticle %s\n", original);
-				if (article_line(original, "From: ", buf))
-					printf("%s\n", buf);
-				if (article_line(original, "Subject: ", buf))
-					printf("%s\n", buf);
-				if (askyes("Is this the one you want? ", "n"))
-					break;
-			} else
-				printf("I can't find that article.\n");
-			lastnum = atol(num);
-		}
-
-		followup(original);
-	} else {
-		do {
-			getpr("Subject: ", subject);
-			if (*subject == '?') {
-printf("People read the subject line to learn what your article is about.\n");
-printf("You want it to do the same job as a newspaper headline.\n");
-printf("So type in something both brief and descriptive.\n");
-				*subject = '\0';
-			}
-		} while (*subject == '\0');
-		getpr("Keywords: ", keywords);
-
-		while (!get_newsgroup())
-			;
-		get_distribution((char *)0);
-	}
-
-	if (pre_checks())
-		exit(1);
-
-	prep_article();
-	c = 'e';
-	for (;;) {
-		if (c == 'e') {
-			edit_article();
-			post_checks();
-		}
-		do {
-			do {
-				getpr("\nWhat now?  [send, edit, list, quit, write] ", buf);
-				c = buf[0];
-			} while (c == '\0');
-			if (isupper(c))
-				c = tolower(c);
-			if (c == 'q') {
-				(void) UNLINK(tempfname);
-				exit(1);
-			}
-			if (c == 'l') {
-				char *pager = getenv("PAGER");
-				char lbuf[BUFLEN];
-				if (pager == NULL || *pager == '\0') {
-#ifdef PAGE
-# ifdef IHCC
-					(void) sprintf(lbuf,"%s/bin/%s", logdir(HOME), PAGE);
-# else /* !IHCC */
-					(void) strcpy(lbuf, PAGE);
-# endif /* !IHCC */
-					pager = lbuf;
-#else /* !PAGE */
-					pager = "cat";
-#endif /* !PAGE */
-				}
-				sprintf(buf, "exec %s %s", pager, tempfname);
-				(void)  system(buf);
-			}
-			if (c == 'w') {
-				register int ifd, ofd, nbytes;
-				char iobuf[BUFSIZ];
-				char fname[BUFLEN];
-				getpr("Filename? ", fname);
-				if (fname[0] == '\0')
-					continue;
-				ofd = creat(fname, 0666);
-				if (ofd < 0)
-					perror(fname);
-				else {
-					ifd = open(tempfname, 0);
-					if (ifd < 0)
-						xerror("Can't reopen %s\n", tempfname);
-					while ((nbytes = read(ifd, iobuf, BUFSIZ)) > 0 )
-						write(ofd, iobuf, nbytes);
-					close(ofd);
-					close(ifd);
-				}
-			}
-		} while (!index("eps", c));
-		if (c != 'e')
-			post_article(); /* will exit if posted successfully */
-	};
-}
-
-/*
- * Find out the topic of interest.
- */
-get_newsgroup()
-{
-	int n;
-	long i;
-	char canpost;
-	static int first = 1;
-
-	printf("Newsgroups (enter one at a time, end with a blank line):\n");
-	if (first) {
-		printf("\nThe most relevant newsgroup should be the first, you should\n");
-		printf("add others only if your article really MUST be read by people\n");
-		printf("who choose not to read the appropriate group for your article.\n");
-		printf("But DO use multiple newsgroups rather than posting many times.\n\n");
-		first = 0;
-	}
-	printf("For a list of newsgroups, type ?\n");
-	n = 0;
-	newsgroups[0] = '\0';
-
-	for(;;) {
-		getpr("> ", buf);
-		if (buf[0] == '\0')
-			if (n == 0)
-				return FALSE;
-			else
-				return TRUE;
-		if (buf[0] == '?'){
-			char *pager = getenv("PAGER");
-			char lbuf[BUFLEN];
-			if (pager == NULL) {
-#ifdef PAGE
-# ifdef IHCC
-				(void) sprintf(lbuf,"%s/bin/%s", logdir(HOME), PAGE);
-# else /* !IHCC */
-				(void) strcpy(lbuf, PAGE);
-# endif /* !IHCC */
-				pager = lbuf;
-#else /* !PAGE */
-				pager = "cat";
-#endif /* !PAGE */
-			}
-			printf("These are the currently active groups:\n");
-			sprintf(buf, "exec %s %s/newsgroups", pager, LIB);
-			(void) system(buf);
-			continue;
-		}
-		if (valid_ng(buf, &i, &i, &canpost)) {
-			if (n++ != 0)
-				(void) strcat(newsgroups, ngsep);
-			(void) strcat(newsgroups, buf);
-		} else {
-			if (canpost == 'n')
-				printf("You are not allowed to post to %s\n",
-					buf);
-			else if (canpost == 'i')
-				printf("%s is not a valid newsgroup.\n", buf);
-		}
-	}
-}
-
-/*
- * Find out how widely the author wants the message distributed.
- */
-get_distribution(deflt)
-	char *deflt;
-{
-	register int i;
-	register char *r;
-	char def[BUFLEN];
-	char *lastgroup;
-
-	lastgroup = newsgroups;
-	(void) strcpy(def, newsgroups);
-	r = index(def, NGDELIM);
-	if (r)
-		*r = '\0';
-	r = index(def, '.');
-	if (r) {
-		*r = '\0';
-		if (strcmp(def, "net") == 0)
-			(void) strcpy(def, "world");
-	} else {
-		distribution[0] = '\0';
-		return;
-	}
-
-	if (strcmp(def, "to") == 0) {
-		/*
-		 * This only works if "to.xx" is the first (or only)
-		 * newsgroup, but it usually is ..
-		 * Perhaps we should make the distribution be "to.xxx" ??
-		 */
-		distribution[0] = '\0';
-		return;		/* He's probably testing something */
-	}
-	if (deflt != (char *)0)
-		(void) strcpy(def, deflt);
-	if (ngmatch("net.test", newsgroups))
-		(void) strcpy(def, "local");
-	for(;;) {
-		do {
-			(void) sprintf(buf, "Distribution (default='%s', '?' for help) : ", def);
-			getpr(buf, distribution);
-			if (distribution[0] == '\0') {
-				if (strcmp(def, "*None*") == 0)
-					printf("You must enter a distribution, '?' for help.\n");
-				(void) strcpy(distribution, def);
-			}
-		} while (strcmp(distribution, "*None*") == 0);
-
-		/* Did the user ask for help? */
-		if (distribution[0] == '?') {
-			printf("How widely should your article be distributed?\n\n");
-			for (i=0; distr[i].abbr[0]; i++)
-				printf("%s\t%s\n", distr[i].abbr, distr[i].descr);
-			printf("\nEnter the word that specifies the distribution that you require.\n");
-			continue;
-		}
-
-		/* Check that it's a proper distribution */
-		for (i=0; distr[i].abbr[0]; i++) {
-			if (strncmp(distr[i].abbr, distribution, sizeof(distr[0].abbr)) == 0) {
-				register int n;
-				/* Found a match. Do any special rewriting. */
-				r = newsgroups;
-				n = strlen(distribution);
-				/*
-				 * A distribution of foo is useless
-				 * if all the newsgroups are in foo.all
-				 */
-				for (;;) {
-					if (strncmp(r, distribution, n))
-						return;
-					if ((r = index(r, NGDELIM)) == NULL)
-						break;
-					++r;
-				}
-				distribution[0] = '\0';
-				return;
-			}
-		}
-		if (strcmp(distribution, def) != 0)
-			printf("Type ? for help.\n");
-		else {
-			int once = TRUE;
-
-			do {
-				r = lastgroup;
-				while (r = index(r, NGDELIM))
-					if (!prefix(++r, def))
-						break;
-				if (r == NULL) {
-					/*
-					 * no newsgroups are distribution
-					 * names, and user simply will
-					 * not type a valid distribution,
-					 * assume that the default is OK.
-					 */
-					distribution[0] = '\0';
-					return;
-				}
-				lastgroup = r;
-				if (once)
-					printf("Sorry, '%s' is an unknown distribution.  Type ? for help.\n", def);
-				once = FALSE;
-				strcpy(def, r);
-				r = index(def, NGDELIM);
-				if (r)
-					*r = '\0';
-				r = index(def, '.');
-			} while (r == NULL);
-			*r = '\0';
-			if (strcmp(def, "net") == 0)
-				strcpy(def, "world");
-		}
-	}
-}
-
-/*
- * Do sanity checks before the author types in the message.
- */
-pre_checks()
-{
-	if (recording(newsgroups))
-		return 1;
-	return 0;
-}
-
-/*
- * Set up the temp file with headers.
- */
-prep_article()
-{
-	FILE *tf, *of;
-	struct stat stbuf;
-
-	(void) strcpy(tempfname, "/tmp/postXXXXXX");
-	(void) mktemp(tempfname);
-
-	/* insert a header */
-	tf = xfopen(tempfname, "w");
-	fprintf(tf, "Subject: %s\n", subject);
-	fprintf(tf, "Newsgroups: %s\n", newsgroups);
-	if (distribution[0] != '\0' && strcmp(distribution, "world"))
-		fprintf(tf, "Distribution: %s\n", distribution);
-
-	if (keywords[0] != '\0')
-		fprintf(tf, "Keywords: %s\n", keywords);
-	if (summary[0] != '\0')
-		fprintf(tf, "Summary: %s\n", summary);
-
-	if (references[0] != '\0') {
-		fprintf(tf, "References: %s\n\n", references);
-
-		if (askyes("Do you want to include a copy of the article? ", "no")){
-			of = xfopen(original, "r");
-			while (fgets(buf, BUFSIZ, of) != NULL)
-				if (buf[0] == '\n')	/* skip headers */
-					break;
-			fprintf(tf, "In article %s, %s writes:\n", msgid, isfrom);
-			while (fgets(buf, BUFSIZ, of) != NULL)
-				fprintf(tf, "> %s", buf);
-			(void) fclose(of);
-			printf("OK, but please edit it to suppress unnecessary verbiage, signatures, etc.\n");
-		}
-	}
-
-	fprintf(tf, "\n\n");
-	(void) fflush(tf);
-	(void) fstat(fileno(tf), &stbuf);
-	fmodtime = stbuf.st_mtime;
-	(void) fclose(tf);
-}
-
-edit_article()
-{
-	register char *p;
-	char *editor;
-	char *endflag = "";
-	char *getenv();
-
-	/* edit the file */
-	editor = getenv("EDITOR");
-	if (editor == NULL)
-		editor = DFTEDITOR;
-
-	p = editor + strlen(editor) - 2;
-	if (strcmp(p, "vi") == 0)
-		endflag = "+";
-
-	(void) sprintf(buf, "A=%s;export A;exec %s %s %s",
-		original, editor, endflag, tempfname);
-
-	(void) system(buf);
-}
-
-/*
- * Do sanity checks after the author has typed in the message.
- */
-post_checks()
-{
-	char group[BUFLEN];
-	register char *c, *p;
-	struct stat stbuf;
-
-	if (stat(tempfname, &stbuf) < 0) {
-		printf("File deleted - no message posted.\n");
-		(void) UNLINK(tempfname);
-		exit(1);
-	}
-	if (stbuf.st_size < 5) {
-		printf("File too small (<5 characters) - no message posted.\n");
-		(void) UNLINK(tempfname);
-		exit(1);
-	}
-
-	if (stbuf.st_mtime == fmodtime) {
-		printf("File not modified - no message posted.\n");
-		(void) UNLINK(tempfname);
-		exit(1);
-	}
-
-	/*
-	 * Is this the right number?  Most of the headers are yet to be added
-	 */
-	if (stbuf.st_size > 64000) {
-		printf("\nYour message will probably be truncated when it\n");
-		printf("passes through a notesfile site, since it is\n");
-		printf("greater than 64000 characters.\n\n");
-		if (!askyes("Do you still want to post it? ","")) {
-			sprintf(ccname, "%s/dead.article", homedir);
-			save_article();
-			(void) UNLINK(tempfname);
-			exit(1);
-		}
-	}
-
-	/*
-	 * get the newsgroups from the edited article, in
-	 * case they were altered in the editor
-	 */
-	if (!article_line(tempfname, "Newsgroups: ", group)) {
-  nogroups:
-		printf("Not sending to any newsgroups - no message posted\n");
-		(void) UNLINK(tempfname);
-		exit(1);
-	}
-	c = &group[11];
-	while (*c == ' ' || *c == '\t')
-		c++;
-	if (*c == '\0')
-		goto nogroups;
-	for (p = newsgroups; *c; c++)	/* copy to newsgroups, w/o blanks */
-		if (*c != ' ' && *c != '\t')
-			*p++ = *c;
-	*p = '\0';
-
-	/* Sanity checks for certain newsgroups */
-	if (ngmatch(newsgroups, "all.wanted") && ngmatch(distribution,"net,na,usa,att,btl,eunet,aus")) {
-		printf("Is your message something that might go in your local\n");
-		printf("newspaper, for example a used car ad, or an apartment\n");
-		printf("for rent? ");
-		if (askyes("","")) {
-			printf("It's pointless to distribute your article widely, since\n");
-			printf("people more than a hundred miles away won't be interested.\n");
-			printf("Please use a more restricted distribution.\n");
-			get_distribution("*None*");
-			modify_article(tempfname, "Distribution: ", distribution,REPLACE);
-		}
-	}
-
-	if (ngmatch(newsgroups, "all.jokes")) {
-		if (askyes("Could this be offensive to anyone? ","")) {
-			getpr("Whom might it offend? ", group);
-			(void) sprintf(buf," - offensive to %s (rot 13)",group);
-			modify_article(tempfname, "Subject: ", buf, APPEND);
-			encode(tempfname);
-		}
-	}
-
-	if (ngmatch(newsgroups, "net.general")) {
-		if (index(newsgroups, NGDELIM)) {
-			printf("Everybody in the world reads net.general, so it doesn't make\n");
-			printf("sense to post to newsgroups in addition to net.general.  If your\n");
-			printf("article belongs in one of these other newsgroups, then you\n");
-			printf("should not post to net.general.	If it is important enough\n");
-			printf("for net.general, then you shouldn't post it in other places\n");
-			printf("as well.	Please reenter the newsgroups.\n");
-			while (!get_newsgroup())
-				;
-			modify_article(tempfname, "Newsgroups: ", newsgroups,REPLACE);
-		}
-		if (ngmatch(newsgroups, "net.general")) {
-			printf("net.general is for important announcements.\n");
-			printf("It is not for items for which you couldn't think\n");
-			printf("of a better place - those belong in net.misc.\n");
-			if (!askyes("Are you sure your message belongs in net.general? ","")) {
-				while (!get_newsgroup())
-					;
-				modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
-			}
-		}
-	}
-
-	if (ngmatch(newsgroups, "net.sources,!net.sources.all")) {
-		if (!article_line(tempfname, "Subject: ", group)) {
-  nosubj:
-			printf("There seems to be no subject for this article.\n");
-			getpr("Subject: ", subject);
-			modify_article(tempfname, "Subject: ", subject, REPLACE);
-		} else {
-			c = &group[8];
-			while (*c == ' ' || *c == '\t')
-				c++;
-			if (*c == '\0')
-				goto nosubj;
-			strcpy(subject, c);
-		}
-		if (ngmatch(newsgroups, "all.wanted") || iswanted(subject)) {
-			printf("Requests for sources should not be posted to any of\n");
-			printf("the net.sources newsgroups, please post such requests\n");
-			printf("to net.wanted.sources only.     Please reenter the newsgroups.\n\n");
-			while (!get_newsgroup())
-				;
-			modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
-		}
-		if (ngmatch(newsgroups, "net.sources")) {
-			if (!ngmatch(newsgroups, "net.sources.all") &&
-			    stbuf.st_size < (4*1024)) {
-				printf("Your article seems rather small to be a source distribution.\n");
-				if (!askyes("Are you certain that this is really source? ", "")) {
-
-					while (!get_newsgroup())
-						;
-					modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
-				}
-			}
-			if (index(newsgroups, NGDELIM)) {
-				printf("Sources should be posted to one newsgroup only.\n");
-				printf("Please pick the most appropriate group for your article.\n\n");
-				while (!get_newsgroup())
-					;
-				modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
-			}
-		}
-	}
-}
-
-iswanted(str)
-register char *str;
-{
-	while (*str == ' ')
-		str++;
-
-	if (prefix(str, "Re:"))
-		return (FALSE);
-
-	if (isin(str, " wanted ") || isin(str, " can any") ||
-	    isin(str, " need ") || isin(str, " please ") || isin(str, " help ")
-	    || isin(str, " looking ") || index(str, '?'))
-		return (TRUE);
-
-	return (FALSE);
-}
-
-isin(str, words)
-register char *str, *words;
-{
-	register char *p;
-	register sc, wc;
-
-	p = words;
-	while (sc = *str++) {
-		if ((wc = *p++) == '\0')
-			return (TRUE);
-		if (wc == ' ') {
-			if (index(".,!?-; \t\n", sc))
-				continue;
-		} else {
-			if (isupper(wc))
-				wc = tolower(wc);
-			if (isupper(sc))
-				sc = tolower(sc);
-			if (wc == sc)
-				continue;
-		}
-		str -= p - words - 1;
-		p = words;
-	}
-	if (*p == '\0')
-		return (TRUE);
-	return (FALSE);
-}
-
-/*
- * Save a copy of the article in the users NEWSARCHIVE directory.
- */
-save_article()
-{
-	FILE *in, *out;
-	int c;
-	time_t timenow, time();
-	char *today, *ctime();
-	struct stat stbuf;
-	char filename[BUFLEN];
-
-	if (stat(ccname, &stbuf) == 0 && (stbuf.st_mode&S_IFMT) == S_IFDIR) {
-		/*
-		 * It would be much nicer here to write articles
-		 * in MH format (numbered files, in rfc822 format)
-		 *
-		 * one day ..
-		 */
-		(void) sprintf(filename, "%s/author_copy", ccname);
-		(void) strcpy(ccname, filename);
-	}
-	in = xfopen(tempfname, "r");
-	out = xfopen(ccname, "a");
-	timenow = time((time_t)0);
-	today = ctime(&timenow);
-	fprintf(out,"From postnews %s",today);
-	while ((c=getc(in)) != EOF)
-		putc(c, out);
-	putc('\n', out);
-	(void) fclose(in);
-	(void) fclose(out);
-}
-
-/*
- * Post the article to the net.
- */
-post_article()
-{
-	int status;
-
-	printf("Posting article...\n");
-	fflush(stdout);
-	(void) sprintf(buf, "exec %s/%s -h < %s", LIB, "inews", tempfname);
-	status = system(buf);
-
-	if (status) {
-		printf("Article not posted - exit status %d\n", status);
-		return;
-	} else
-		printf("Article posted successfully.\n");
-
-	if (ccname[0]) {
-		printf("A copy has been saved in %s\n", ccname);
-		save_article();
-	}
-
-	(void) UNLINK(tempfname);
-	exit(0);
-}
-
-/*
- * Initialization.
- */
-init()
-{
-	FILE *fd;
-	register char *p;
-	int i;
-	char *getenv();
-	struct passwd *pw;
-
-	references[0] = '\0';
-	distribution[0] = '\0';
-
-	uid = getuid();
-	pw = getpwuid(uid);
-	if (pw == NULL) {
-		fprintf(stderr,"You're not in /etc/passwd\n");
-		exit(1);
-	}
-	p = getenv("HOME");
-	if (p == NULL) {
-		p = getenv("LOGDIR");
-		if (p == NULL) 
-			p = pw->pw_dir;
-	}
-	(void) strncpy(user, pw->pw_name, SBUFLEN);
-	(void) strcpy(homedir, p);
-
-	p = getenv("NEWSARCHIVE");
-	if (p != NULL) {
-		if (*p == '\0')
-			sprintf(ccname, "%s/author_copy", homedir);
-		else
-			strcpy(ccname, p);
-	}
-
-	pathinit();
-	(void) sprintf(buf, "%s/%s", LIB, "distributions");
-	fd = xfopen(buf, "r");
-	for (i=0; i < MAXDISTR; i++) {
-		if (fscanf(fd, "%s %[^\n]", distr[i].abbr, distr[i].descr)
-			!= 2)
-			break;
-	}
-	(void) fclose(fd);
-}
-
-/*
- * Get a yes or no answer to a question.	A default may be used.
- */
-askyes(msg, def)
-char *msg, *def;
-{
-	for(;;) {
-		printf("%s", msg);
-		buf[0] = 0;
-		(void) gets(buf);
-		switch(buf[0]) {
-		case 'y':
-		case 'Y':
-			return TRUE;
-		case 'n':
-		case 'N':
-			return FALSE;
-		case '\0':
-			switch(*def) {
-			case 'y':
-			case 'Y':
-				return TRUE;
-			case 'n':
-			case 'N':
-				return FALSE;
-			}
-		default:
-			printf("Please answer yes or no.\n");
-		}
-	}
-}
-
-/*
- * Get a character string into buf, using prompt msg.
- */
-getpr(msg, bptr)
-char *msg, *bptr;
-{
-	static int numeof = 0;
-	printf("%s", msg);
-	(void) gets(bptr);
-	(void) nstrip(bptr);
-	if (feof(stdin)) {
-		if (numeof++ > 3) {
-			fprintf(stderr,"Too many EOFs\n");
-			exit(1);
-		}
-		clearerr(stdin);
-	}
-}
-
-byebye(mesg)
-char *mesg;
-{
-	printf("%s\n", mesg);
-	exit(1);
-}
-
-/*
- * make a modification to the header of an article
- *
- *	 fname -- name of article
- *	 field -- header field to modify
- *	 line	-- modification line
- *	 how	 -- APPEND or REPLACE
- *
- * example:
- *	 modify_article("/tmp/article" , "Subject:" , "new subject" , REPLACE);
- *
- *
- */
-modify_article(fname, field, line, how)
-char *fname, *field, *line;
-{
-	FILE *fpart, *fptmp;
-	char *temp2fname = "/tmp/postXXXXXX";
-	char lbfr[BUFLEN];
-	register found = FALSE;
-
-	mktemp(temp2fname);
-
-	fptmp = xfopen(temp2fname, "w");
-	fpart = xfopen(fname, "r");
-
-	while (fgets(lbfr, BUFLEN, fpart) != NULL) {
-		if (prefix(lbfr, field)) {
-			found = TRUE;
-			(void) nstrip(lbfr);
-			if (how == APPEND) {
-				/* append to current field */
-				(void) strcat(lbfr, line);
-				(void) strcat(lbfr, "\n");
-			} else
-				/* replace current field */
-				(void) sprintf(lbfr, "%s%s\n", field, line);
-		}
-		(void) fputs(lbfr, fptmp);
-	}
-
-	fclose(fpart);
-	fclose(fptmp);
-
-	fptmp = xfopen(temp2fname, "r");
-	fpart = xfopen(fname, "w");
-
-	if (!found)
-		fprintf(fpart, "%s%s\n", field, line);
-	while (fgets(buf,BUFLEN,fptmp) != NULL)
-		(void) fputs(buf, fpart);
-
-	(void) fclose(fpart);
-	(void) fclose(fptmp);
-	(void) UNLINK(temp2fname);
-}
-
-
-/* verify that newsgroup exists, and get number of entries */
-valid_ng(ng, maxart, minart, canpost)
-char *ng;
-long *maxart, *minart;
-char *canpost;
-{
-	char ng_check[BUFLEN], ng_read[BUFLEN];
-	FILE *fp;
-
-	fp = xfopen(ACTIVE, "r");
-	while (fgets(ng_read, BUFLEN, fp) != NULL) {
-		switch (sscanf(ng_read, "%s %ld %ld %c", ng_check, maxart, minart, canpost)) {
-		case 2:
-			*minart = 1;
-			/* fall through */
-		case 3:
-			*canpost = 'y';
-			/* fall through */
-		case 4:
-			break;
-
-		default:
-			printf("Active file (%s) corrupted. ", ACTIVE);
-			byebye("Seek help!");
-		}
-			
-		if (strcmp(ng_check, ng) == 0) {
-			(void) fclose(fp);
-			if (*canpost != 'n') {
-#ifdef FASCIST
-				if (uid && uid != ROOTID && fascist(user, ng)) {
-					*canpost = 'n';
-					return FALSE;
-				}
-#endif FASCIST
-				return TRUE;
-			} else
-				return FALSE;
-		}
-	}
-	*canpost = 'i';
-	*maxart = 0;
-	*minart = 0;
-	(void) fclose(fp);
-	return FALSE;
-}
-
-/* get the line specified by field from an article */
-article_line(article, field, line)
-char *article, *field, *line;
-{
-	FILE *fp;
-	char *c;
-
-	fp = xfopen(article,"r");
-	while ((c=fgets(line,BUFLEN,fp)) != NULL && !prefix(line, field))
-		if (line[0] == '\n') {
-			c = NULL;
-			break;
-		}
-	(void) fclose(fp);
-	if (c != NULL) {
-		(void) nstrip(line);
-		return TRUE;
-	} else {
-		line[0] = '\0';
-		return FALSE;
-	}
-}
-
-/* get the header information for a followup article */
-followup(baseart)
-register char *baseart;
-{
-	register char *p;
-
-	/* subject */
-	if (article_line(baseart, "Subject: ", buf)) {
-		p = buf+9;
-		for ( ; ; ) {
-			while (*p == ' ' || *p == '\t')
-				++p;
-			if ((*p != 'r' && *p != 'R') ||
-				(p[1] != 'e' && p[1] != 'E') ||
-				(p[2] != ':' && p[2] != ' '))
-					break;
-			p += 3;
-		}
-		(void) sprintf(subject, "Re: %s", p);
-	} else {
-		if (article_line(baseart, "From: ", buf))
-			(void) sprintf(subject, "Re: orphan response from %s", buf);
-		else
-			(void) strcpy(subject, "Re: orphan response");
-	}
-
-	/* newsgroup */
-	if (article_line(baseart, "Newsgroups: ", buf))
-		(void) strcpy(newsgroups, buf+12);
-	if (ngmatch(newsgroups, "net.general"))
-		(void) strcpy(newsgroups,"net.followup");
-	if (ngmatch(newsgroups, "net.sources,!net.sources.all"))
-		(void) strcpy(newsgroups,"net.sources.d");
-	if (ngmatch(newsgroups, "net.jobs")) {
-		printf("net.jobs is for the direct posting of job announcements and requests.\n");
-		printf("it is not for discussion. You followup has been directed to net.misc\n");
-		(void) strcpy(newsgroups,"net.misc");
-	}
-
-	/* distribution */
-	if (article_line(baseart, "Distribution: ", buf))
-		(void) strcpy(distribution, buf+14);
-
-	/* references */
-	if (article_line(baseart, "References: ", buf)) {
-		register char *rcp;
-		(void) strcpy(references, buf+12);
-		(void) strcat(references, " ");
-		/* keep the number of references to a reasonable number */
-		rcp = rindex(references, ' '); /* Can not fail */
-		while ((int)(rcp - references) > 70) {
-			while (*--rcp != ' ')
-				;
-			rcp[1] = '\0';
-		}
-	}
-	if (article_line(baseart, "Message-ID: ", buf)) {
-		(void) strcat(references, buf+12);
-		(void) strcpy(msgid, buf+12);
-	}
-
-	if (article_line(baseart, "From: ", buf))
-		(void) strcpy(isfrom, buf+6);
-
-	if (article_line(baseart, "Keywords: ", buf))
-		(void) strcpy(keywords, buf+10);
-
-	if (article_line(baseart, "Followup-To: ", buf)) {
-		(void) strcpy(newsgroups, buf+13);
-		if (strcmp(newsgroups, "poster") == 0)
-			byebye("Mail followups directly to poster.");
-	}
-
-	get_summary();
-}
-
-get_summary()
-{
-	register char *p;
-	register i;
-
-	printf("Please enter a short summary of your contribution to the discussion\n");
-	printf("Just one or two lines ...   (end with a blank line)\n");
-	p = summary;
-	for (i = 0; i < 3; i++) {	/* 3 * 80 < 256, should be safe .. */
-		getpr(">\t", p);
-		if (*p == '\0')
-			break;
-		p = index(p, '\0');
-		(void) strcpy(p, "\n\t ");
-		p += 3;
-	}
-	if (p > summary)
-		p[-3] = '\0';
-}
-
-encode(article)
-char *article;
-{
-	FILE *fpart, *fphead, *fpcoded;
-	char *headerfile = "/tmp/pheadXXXXXX";
-	char *codedfile = "/tmp/pcodeXXXXXX";
-
-	(void) mktemp(headerfile);
-	(void) mktemp(codedfile);
-
-	fpart = xfopen(article, "r");
-
-	/* place article header in "headerfile" file */
-	fphead = xfopen(headerfile, "w");
-	while (fgets(buf, BUFLEN, fpart) != NULL) {
-		(void) fputs(buf, fphead);
-		if (buf[0] == '\n')
-			break;
-	}
-	(void) fclose(fphead);
-
-	/* place article body in "codedfile" file */
-	fpcoded = xfopen(codedfile, "w");
-	while (fgets(buf, BUFLEN, fpart) != NULL)
-		(void) fputs(buf, fpcoded);
-	(void) fclose(fpcoded);
-	(void) fclose(fpart);
-
-	/* encode body and put back together with header */
-	(void) rename(headerfile, article);
-
-	(void) sprintf(buf,"exec %s/%s 13 < %s >> %s\n", LIB, "caesar", codedfile, article);
-	printf("Encoding article -- please stand by\n");
-	if (system(buf)) {
-		printf("encoding failed");
-		exit(2);
-	}
-	(void) UNLINK(codedfile);
-}
-
-
-/*
- * Print a recorded message warning the poor luser what he is doing
- * and demand that he understands it before proceeding.  Only do
- * this for newsgroups listed in LIBDIR/recording.
- */
-recording(ngrps)
-char *ngrps;
-{
-	char recbuf[BUFLEN];
-	FILE *fd;
-	char nglist[BUFLEN], fname[BUFLEN];
-	int  c, n, yes, retval = 0;
-
-	(void) sprintf(recbuf, "%s/%s", LIB, "recording");
-	fd = fopen(recbuf, "r");
-	if (fd == NULL)
-		return 0;
-	while ((fgets(recbuf, sizeof recbuf, fd)) != NULL) {
-		(void) sscanf(recbuf, "%s %s", nglist, fname);
-		if (ngmatch(ngrps, nglist)) {
-			(void) fclose(fd);
-			if (fname[0] == '/')
-				(void) strcpy(recbuf, fname);
-			else
-				(void) sprintf(recbuf, "%s/%s", LIB, fname);
-			fd = fopen(recbuf, "r");
-			if (fd == NULL)
-				return 0;
-			while ((c = getc(fd)) != EOF)
-				putc(c, stderr);
-			fprintf(stderr, "Do you understand this?  Hit <return> to proceed, <BREAK> to abort: ");
-			n = read(2, recbuf, 100);
-			c = recbuf[0];
-			yes = (c=='y' || c=='Y' || c=='\n' || c=='\n' || c==0);
-			if (n <= 0 || !yes)
-				retval = -1;
-		}
-	}
-	return retval;
-}
-
-xxit(i)
-{
-	exit(i);
-}
-
-#if !defined(BSD4_2) && !defined(BSD4_1C)
-rename(from,to)
-register char *from, *to;
-{
-	(void) unlink(to);
-	if (link(from, to) < 0)
-		return -1;
-
-	(void) unlink(from);
-	return 0;
-}
-#endif /* !BSD4_2 && ! BSD4_1C */
*-*-END-of-src/postnews.c-*-*
echo x - src/control.c 1>&2
sed 's/.//' >src/control.c <<'*-*-END-of-src/control.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.
- *
- * Control message handling code.  Deal with messages which are to be
- * acted on by netnews itself rather than by people.
- *
- * See defs.h "news_version" for the real version of netnews.
- */
-
-#ifdef SCCSID
-static char	*SccsId = "@(#)control.c	2.48	10/30/86";
-#endif /* SCCSID */
-
-#include "iparams.h"
-
-#define eq(msg) (strcmp(msg, cargv[0]) == 0)
-
-int cargc;
-char **cargv;
-
-FILE *hfopen();
-FILE *popen(), *mhopen(), *mailhdr();
-
-char *senderof();
-#ifdef u370
-static struct hbuf htmp;
-#endif /* u370 */
-
-/*
- * The global structure is initialized to NOTIFY as the default (if defined)
- * uid to send mail to for every state.  The following conditions are
- * dealt with (assumes NOTIFY defined):
- *
- * 1) LIB/notify exists and is empty (or contains no recognizable control
- *    message types).
- *    	Action: force TELLME = "";
- * 2) LIB/notify contains the control message name "all" and no associated
- *    address.
- *	Action: force TELLME = "";
- * 3) LIB/notify contains the control message name "all" and has an address.
- *	Action: set TELLME = AlloCpy(address);
- * 4) LIB/notify contains only some of the known control message types.
- *	Action: initialize all addresses to "" and set declared addresses
- *		to listed address.
- */
-
-control(h)
-struct hbuf *h;
-{
-	register char *ctlmsgtext;
-	register struct msgtype *mp;
-
-	if (strncmp(h->title, "cmsg ", 5) == 0) {
-		register char *cp1, *cp2;
-		cp1 = h->title;
-		cp2 = h->title + 5;
-		while (*cp1++ = *cp2++)
-			;
-	}
-
-	if (*h->ctlmsg)
-		ctlmsgtext = h->ctlmsg;
-	else
-		ctlmsgtext = h->title;
-	log("Ctl Msg %s from %s: %s", h->nbuf, h->path, ctlmsgtext);
-	/*
-	 * Control messages have the standard format
-	 *	command [args]
-	 * much like shell commands.  Each site has the option
-	 * of customizing this code to deal with control messages
-	 * as they see fit, but we would like to buy back the
-	 * code, ifdeffed or otherwise parameterized, to simplify
-	 * the maintenence issues.
-	 */
-	argparse(ctlmsgtext);
-	
-	/*
-	 * We look for a match of the control message name and then
-	 * set TELLME to the value parsed from the LIB/notify file
-	 * (if any).
-	 */
-	for(mp=msgtype; mp->m_name; mp++) {
-		if(eq(mp->m_name) ) {		/* hit */
-#ifdef NOTIFY
-			TELLME = mp->m_who_to;	/* reset whom to tell */
-#endif /* NOTIFY */
-			if(strcmp(mp->m_name, "cancel") == 0) /* special case */
-				return (*mp->m_func)(cargc, cargv);
-			(*mp->m_func)(cargc, cargv); /* do the function */
-			break;
-		}
-	}
-	if( !mp->m_name ) {
-#ifdef NOTIFY
-		TELLME = NOTIFY;
-#endif /* NOTIFY */
-		c_unknown(h, ctlmsgtext);
-	}
-	return 0;
-}
-
-/*
- * Parse the string str into separate words in cargc and cargv
- * as per the usual UNIX convention.  Nothing fancy here, just
- * blanks and tabs separating words.
- */
-argparse(str)
-char *str;
-{
-	static char *cavpbuf[20];
-	static char cavbuf[256];
-	char *nextfree = cavbuf;
-
-	if (str == '\0')
-		error("Control message %s has no title", header.ident);
-	cargc = (*str != '\0');
-	cargv = cavpbuf;
-	cargv[0] = cavbuf;
-
-	while (*str) {
-		if (*str <= ' ') {
-			*nextfree++ = 0;
-			cargv[cargc] = nextfree;
-			cargc++;
-			/* skip over white space */
-			while (*str != '\0' && *str <= ' ')
-				str++;
-			if (*str == '\0')	/* line ends in white space */
-				return;
-		} else
-			*nextfree++ = *str++;
-	}
-}
-
-/*
- * ihave <artid> ... <remotesys>
- *	or
- * ihave <remotesys>
- *	with <artid>s in message body.
- *
- * The other system is telling you it has article <artid>, in case
- * you decide you want it to transmit it to you.
- * The assumption is that the other system only tells you about articles
- * in newsgroups you subscribe to.
- *
- * We turn the incoming ihave into an outgoing sendme on the fly.
- * It then gets saved in the SPOOL directory and transmitted to the
- * remote system.  (This way the sendme messages can be batched.)
- */
-c_ihave(argc, argv)
-register char **	argv;
-{
-	register int	i;
-	char		list[sizeof header.title];
-	extern char *	findhist();
-
-	if (argc < 2)
-		error("ihave: Too few arguments.");
-	if (strncmp(FULLSYSNAME, argv[argc - 1], SNLN) == 0)
-		return;
-	list[0] = '\0';
-	if (argc > 2) {
-		for (i = 1; i < (argc - 1); ++i)
-			if (findhist(argv[i]) == NULL) {
-				(void) strcat(list, " ");
-				(void) strcat(list, argv[i]);
-			}
-		if (list[0] == '\0')
-			return;
-	} else {
-		register FILE *	outfp;
-		register long	outpos, inpos;
-		char		myid[256];
-
-		outfp = xfopen(INFILE, "a");
-		outpos = ftell(outfp);
-		inpos = ftell(infp);
-		while (ftell(infp) < outpos) {
-			if (fgets(myid, sizeof myid, infp) != myid)
-				error("iline: Can't rerear article");
-			myid[strlen(myid) - 1] = '\0';
-			if (findhist(myid) == NULL)
-				(void) fprintf(outfp, "%s\n", myid);
-		}
-		if (outpos == ftell(outfp)) {	/* if nothing is wanted */
-			(void) fclose(outfp);
-			(void) fseek(infp, inpos, 0);
-			return;
-		}
-		(void) fclose(outfp);
-		/*
-		** The close and open may just be paranoia.
-		*/
-		(void) fclose(infp);
-		infp = xfopen(INFILE, "r");
-		(void) fseek(infp, outpos, 0);
-	}
-	/*
-	** Turn the ihave into a sendme.
-	*/
-	(void) sprintf(header.nbuf, "to.%s.ctl", argv[argc - 1]);
-	(void) sprintf(header.title, "sendme%s %s", list, FULLSYSNAME);
-	(void) strcpy(header.ctlmsg, header.title);
-	getident(&header);
-	(void) sprintf(header.from, "%s@%s%s", "usenet", FULLSYSNAME, MYDOMAIN);
-	(void) strcpy(header.path, NEWSUSR);
-	header.subdate[0] = header.expdate[0] = '\0';
-	dates(&header);
-	/*
-	** What else of this kind should be done?
-	*/
-	header.organization[0] = header.distribution[0] = '\0';
-	for (i = 0; i < NUNREC && header.unrec[i] != NULL; ++i) {
-		free(header.unrec[i]);
-		header.unrec[i] = NULL;
-	}
-	/*
-	** Note that we do *not* change the history line
-	** so that if the "ihave" message comes in again it gets rejected.
-	*/
-}
-
-/*
- * sendme <artid> ... <remotesys>
- *	or
- * sendme <remotesys>
- *	with <artid>s in message body.
- * The other system wants me to send out article <artid>.
- * Give it to them with no fuss.
- */
-c_sendme(argc, argv)
-register char **	argv;
-{
-	struct srec	srec;
-
-	if (argc < 2)
-		error("sendme: Too few arguments.");
-	if (strncmp(FULLSYSNAME, argv[argc - 1], SNLN) == 0)
-		return;
-	if (s_find(&srec, argv[argc - 1]) != TRUE)
-		error("sendme: Can't find sys record for %s", argv[argc - 1]);
-	/* Send the articles. */
-	if (argc == 2) {
-		register FILE *	fp;
-		char		buf[256];
-
-		fp = xfopen(INFILE, "r");
-		while (fgets(buf, sizeof buf, fp) == buf) {
-			buf[strlen(buf) - 1] = '\0';	/* zap trailing '\n' */
-			sendmefunc(buf, &srec);
-		}
-		(void) fclose(fp);
-	} else { 	/* argc > 2 */
-		register int	i;
-
-		for (i = 1; i < (argc - 1); ++i)
-			sendmefunc(argv[i], &srec);
-	}
-}
-
-static
-sendmefunc(id, sp)
-register char *		id;
-register struct srec *	sp;
-{
-	register FILE *	fp;
-	register char *	cp;
-	char		savedbufname[256];
-	extern char	firstbufname[];
-	extern char *	dirname();
-	extern char *	findfname();
-
-	cp = findfname(id);
-	if (cp == NULL) {
-		logerr("System %s wants unavailable article %s.",
-			sp->s_name, id);
-		return;
-	}
-	cp = dirname(cp);
-	fp = fopen(cp, "r");
-	if (fp == NULL) {
-		logerr("Article %s unopenable as %s.", id, cp);
-		return;
-	}
-	(void) strcpy(savedbufname, firstbufname);
-	(void) strcpy(firstbufname, cp);
-	transmit(sp, fp, FALSE, (char **) NULL, FALSE);
-	/* transmit closes fp */
-	(void) strcpy(firstbufname, savedbufname);
-}
-
-/*
- * newgroup <groupname>
- * A new newsgroup has been created.
- * The body of the article, if present, is a description of the
- * purpose of the newsgroup.
- *
- */
-c_newgroup(argc, argv)
-char **argv;
-{
-	FILE *fd;
-	char abuf[BUFLEN], subjline[BUFLEN];
-	int didcreate = 0;
-	register char *p, *q;
-# ifdef NONEWGROUPS
-#  ifdef ORGDISTRIB
-	/* local or ORGDISTRIB */
-	int can_change = (strcmp(header.distribution, "local") == 0) ||
-				(strcmp(header.distribution, ORGDISTRIB) == 0);
-#  else /* ! ORGDISTRIB */
-	/* local only */
-	int can_change = strcmp(header.distribution, "local") == 0;
-#  endif /* ORGDISTRIB */
-# else /* ! NONEWGROUPS */
-	int can_change = 1;	/* allow changes for all distributions */
-# endif /* NONEWGROUPS */
-
-	if (argc < 2)
-		error("newgroup: Too few arguments.");
-
-	if (header.approved[0] == '\0')
-		error("newgroup: %s not approved", argv[1]);
-
-	/* see if it already exists */
-	(void) rewind(actfp); clearerr(actfp);
-	while(fgets(abuf, BUFLEN, actfp) != NULL) {
-		p = abuf;
-		q = argv[1];
-		while (*p++ == *q++)
-			;
-		if (*--q == '\0' && *--p == ' ') {
-			int modified = 0;
-			/* Now check if it's correctly moderated/unmoderated */
-			while (*p++)
-				;
-			p -= 3;
-			if (argc > 2 && strcmp(argv[2], "moderated") == 0) {
-				if (*p == 'm')
-					return;
-# ifdef NONEWGROUPS
-				if(can_change) {
-					*p = 'm';
-					modified = 1;
-				}
-# else /* ! NONEWGROUPS */
-				*p = 'm';
-				modified = 1;
-#endif /* NONEWGROUPS */
-			} else {
-				if (*p != 'm')
-					return;
-# ifdef NONEWGROUPS
-				if(can_change)  {
-					*p = 'y';
-					modified = 1;
-				}
-# else /* ! NONEWGROUPS */
-				*p = 'y';
-				modified = 1;
-# endif /* NONEWGROUPS */
-			}
-# ifdef NOTIFY
-			(void) sprintf(subjline,
-			"Newsgroup %s change from %smoderated to %smoderated",
-				argv[1], *p=='y' ? "" : "un",
-				*p=='y' ? "un" : "");
-			fd = mailhdr((struct hbuf *)NULL, subjline);
-			if (fd != NULL) {
-				if(modified)
-					fprintf(fd,
-"%s has been changed from %smoderated to %smoderated as requested by\n%s\n",
-						argv[1], *p=='y' ? "" : "un", 
-						*p=='y' ? "un":"", header.path);
-				else {
-					fprintf(fd,
-"%s\nhas requested that %s be changed from %smoderated to %smoderated\n",
-						header.path, argv[1], 
-						*p=='y' ? "un" : "",
-						*p=='y' ? "" : "un");
-#ifdef ORGDISTRIB
-					fprintf(fd,
-"You can accomplish this by re-creating the newsgroup with a distribution\n");
-					fprintf(fd,
-"of '%s' by executing the command:\n", ORGDISTRIB);
-					fprintf(fd,
-				"%s/inews -d %s -C %s moderated\n",
-						LIB, ORGDISTRIB, argv[1]);
-#else /* !ORGDISTRIB */
-					fprintf(fd,
-"You can accomplish this by re-creating the newsgroup by executing the command:\n");
-					fprintf(fd, "%s/inews -C %s moderated\n",
-						LIB, argv[1]);
-#endif /* !ORGDISTRIB */
-				}
-				(void) mclose(fd);
-			}
-# endif /* NOTIFY */
-# ifdef NONEWGROUPS
-			/*
-			 * No permission to change
-			 */
-			if(!can_change)
-				return;
-# endif /* NONEWGROUPS */
-			/* The active file was wrong about the state of the
-			 * group. Rewrite the active file
-			 */
-			(void) fseek(actfp, -2L, 1); /* back up 2 characters */
-#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 hack works
-			 * on all "real" USG Unix 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 didn't
-			 */
-			actfp->_flag |= _IOWRT;
-#endif /* USG */
-			putc(*p, actfp);
-			fflush(actfp);
-			if (*p != 'm')
-				logerr("Newsgroup %s changed from moderated to unmoderated",
-				argv[1]);
-			else
-				logerr("Newsgroup %s changed from unmoderated to moderated",
-				argv[1]);
-			return;
-		}
-	}
-
-	/* It doesn't already exist, we must create it */
-
-	if(can_change) {
-		didcreate++;
-		(void) fseek(actfp, 0L, 2); clearerr(actfp);
-		fprintf(actfp, "%s 00000 00001 %c\n", argv[1],
-			(argc > 2 && strcmp(argv[2], "moderated") == 0) 
-				? 'm' : 'y');
-		fflush(actfp);
-	}
-
-# ifdef NOTIFY
-	(void) sprintf(subjline, "Newsgroup %s created", argv[1]);
-	fd = mailhdr((struct hbuf *)NULL, subjline);
-	if (fd != NULL) {
-		if (didcreate) 
-			fprintf(fd, 
-		"A new newsgroup called '%s' has been created by %s.\n",
-							argv[1], header.path);
-		else {
-			fprintf(fd, 
-		"%s requested that a new newsgroup called '%s' be created.\n",
-			header.path, argv[1]);
-			fprintf(fd,"It was approved by %s\n\n",header.approved);
-			fprintf(fd, 
-		"You can accomplish this by creating the newgroup yourself\n");
-#  ifdef ORGDISTRIB
-			fprintf(fd,"with a distribution of '%s'.\n",
-				ORGDISTRIB);
-			fprintf(fd,
-				"In other words, by executing the command:\n");
-			fprintf(fd, "%s/inews -d %s -C %s\n", LIB, 
-							ORGDISTRIB, argv[1]);
-#  else /* !ORGDISTRIB */
-			fprintf(fd, "In other words, by executing the command:\n");
-			fprintf(fd, "%s/inews -C %s\n", LIB, argv[1]);
-#  endif /* !ORGDISTRIB */
-		}
-		(void) mclose(fd);
-	}
-# endif /* NOTIFY */
-}
-
-/*
- * rmgroup <groupname>
- * An old newsgroup is being cancelled on a network wide basis.
- */
-c_rmgroup(argc, argv)
-char **argv;
-{
-	FILE *fd;
-	int shouldremove = 0;
-#ifdef NOTIFY
-	char subjline[BUFLEN];
-#endif	/* NOTIFY */
-
-	if (argc < 2)
-		error("rmgroup: Too few arguments.");
-	if (!validng(argv[1]))
-		return;
-	if (header.approved[0] == '\0')
-		error("rmgroup: %s not approved", argv[1]);
-
-#ifndef MANUALLY
-#ifdef ORGDISTRIB
-	/*
-	 * Allow local as well as organizational removals
-	 */
-	if (!strcmp(ORGDISTRIB, header.distribution)
-	   || !strcmp("local", header.distribution))
-#else	/* !ORGDISTRIB */		
-	if (!strcmp("local", header.distribution))
-#endif	/* !ORGDISTRIB */		
-		shouldremove++;
-#endif /* !MANUALLY */
-#ifdef NOTIFY
-	sprintf(subjline, "Recevied rmgroup for %s", argv[1]);
-	fd = mailhdr((struct hbuf *)NULL, subjline);
-	if (fd != NULL) {
-		if (shouldremove) {
-		    fprintf(fd, "Newsgroup '%s' has been removed by %s.\n\n",
-				argv[1], header.path);
-#  ifdef USG
-		    fprintf(fd, "You may need to remove the directory %s by hand\n",
-				dirname(argv[1]));
-#  endif
-		} else {
-		    fprintf(fd, "%s requested that newsgroup %s be removed.\n",
-				header.path, argv[1]);
-		    fprintf(fd, "You should remove it by hand\n");
-		    fprintf(fd, "To do this, execute the command\n");
-		    fprintf(fd, "\t%s/rmgroup %s\n", LIB, argv[1]);
-		}
-		(void) mclose(fd);
-	}
-#endif /* NOTIFY */
-
-	if (shouldremove) {
-		int rc;
-		/* We let the shell do all the work.
-		 * See the rmgrp shell script. */
-		(void) setuid(geteuid()); /* otherwise it won't rmdir the dir */
-		(void) sprintf(bfr, "exec %s/rmgroup %s", LIB, argv[1]);
-		rc = system(bfr);
-		log("system(%s) status %d", bfr, rc);
-	}
-}
-
-/*
- * cancel <artid>
- * Cancel the named article
- */
-c_cancel(argc, argv)
-char **argv;
-{
-	char *line, *p, *q, *r, *poster;
-	char *findhist();
-	register FILE *fp;
-	char whatsisname[BUFLEN], nfilename[BUFLEN];
-	time_t t;
-	int su = 0;
-#ifndef u370
-	struct hbuf htmp;
-#endif /* !u370 */
-
-	if (argc < 2)
-		error("cancel: Too few arguments.");
-	(void) strcpy(whatsisname, senderof(&header));
-	line = findhist(argv[1]);
-	if (line == NULL) {
-		struct tm *tm;
-		log("Can't cancel %s:  non-existent", argv[1]);
-		(void) time(&t);
-		tm = localtime(&t);
-#ifdef USG
-		sprintf(bfr,"%s\t%2.2d/%2.2d/%d %2.2d:%2.2d\tcancelled",
-#else /* !USG */
-		sprintf(bfr,"%s\t%02d/%02d/%d %02d:%02d\tcancelled",
-#endif /* !USG */
-		   argv[1], tm->tm_mon+1, tm->tm_mday, tm->tm_year, tm->tm_hour,
-		   tm->tm_min);
-		savehist(bfr);
-		return 1;
-	}
-
-	q = index(line, '\t');
-	p = index(q+1, '\t');
-	if (p == NULL || *++p == '\0' || *p == '\n') {
-		*q = '\0';
-		log("Expired article %s", line);
-		return 1;
-	}
-	if (strcmp(p, "cancelled") == 0) {
-		*q = '\0';
-		log("Already Cancelled %s", line);
-		return 1;
-	} else
-		log("Cancelling %s", line);
-	if ((uid == ROOTID||uid == 0) && strcmp(header.distribution, "local") == 0)
-		su = 1;
-	while (*p) {
-		q = index(p, ' ');
-		if (q)
-			*q = '\0';
-		(void) strcpy(nfilename, dirname(p));
-		fp = fopen(nfilename, "r");
-		if (fp == NULL) {
-			log("Already Cancelled %s", line);
-			return 1;
-		}
-		htmp.unrec[0] = NULL;
-		if (hread(&htmp, fp, TRUE) == NULL) {
-			if (bfr[0] == '/') {
-				fp = fopen(bfr, "r");
-				if (fp == NULL
-					|| hread(&htmp, fp, TRUE) == NULL)
-					error("Article is garbled.");
-			} else 
-				error("Article is garbled.");
-		}
-		(void) fclose(fp);
-		poster = senderof(&htmp);
-		/* only compare up to '.' or ' ' */
-		r = index(poster,'.');
-		if (r == NULL)
-			r = index(poster,' ');
-		if (r != NULL)
-			*r = '\0';
-		if (!su && strncmp(whatsisname, poster,strlen(poster))) {
-			error("Not contributor: posted by %s, and you are %s", poster, whatsisname);
-		}
-
-		(void) unlink(nfilename);
-		p = q+1;
-	}
-	return 0;
-}
-
-/*
- * sendsys	(no arguments)
- *
- * Mail the sys file to the person submitting the article.
- * POLICY: the contents of your sys file are public information
- * and as such, you should not change this code.  You may feel
- * free to arrange for it to manually notify you, in the event
- * that you want to do something to clean it up before it goes out.
- * Secret sites on the net are expressly frowned on.
- * 
- * The purpose of this command is for making a network map.  The
- * details of your link and which newsgroups are forwarded are not
- * important, in case you want to sanitize them.  Since the definition
- * of USENET is those sites getting net.announce, you can disable this
- * on sites not getting net articles, but if you take out the list of
- * forwarded newsgroups, and you have sites that only get local newsgroups,
- * you should make this clear, or remove those sites from what you send out.
- */
-/* ARGSUSED */
-c_sendsys(argc, argv)
-char **argv;
-{
-	register FILE *f, *u;
-	int c;
-
-#ifdef NOTIFY
-	f = mailhdr((struct hbuf *)NULL, "sendsys control message");
-	if (f != NULL) {
-		fprintf(f, "%s requested your %s/sys file.\n", header.path, LIB);
-		fprintf(f, "It has been sent.\n");
-		(void) mclose(f);
-	}
-#endif /* NOTIFY */
-	f = mailhdr(&header, "response to your sendsys request");
-	u = fopen(SUBFILE, "r");
-	if (f != NULL && u != NULL) {
-		while ((c=getc(u)) != EOF)
-			putc(c, f);
-		(void) fclose(u);
-		(void) mclose(f);
-	}
-}
-
-/*
- * senduuname	(no arguments)
- *
- * Run the "uuname" command and send it back to the person who submitted
- * the article.  The purpose of this control message is for attempting to
- * make a uucp net map.
- *
- * POLICY: If you view this information as not public (because you have
- * a connection you consider secret, or know a site that considers itself
- * secret) you can feel free to change this code in whatever way is
- * appropriate, so long as it sends some response back to the sender.  If
- * you don't run uucp, this code does not make sense, and so an error
- * message (or garbage, such as "research") will be mailed back.
- *
- * If you wish to add or remove sites from the output of uuname, you
- * may wish to use the euuname.sh shell script here.
- */
-/* ARGSUSED */
-c_senduuname(argc, argv)
-char **argv;
-{
-	char buf[256];
-	FILE *fd, *u;
-	int c;
-
-#ifdef NOTIFY
-	fd = mailhdr((struct hbuf *)NULL, "uuname control message");
-	fprintf(fd, "%s requested your uuname output\n", header.path);
-	(void) mclose(fd);
-#endif /* NOTIFY */
-	fd = mailhdr(&header, "response to your senduuname request");
-#ifdef UUPROG
-	if (UUPROG[0] == '/')
-		(void) strcpy(buf, UUPROG);
-	else
-		(void) sprintf(buf, "%s/%s", LIB, UUPROG);
-#else
-	(void) strcpy(buf, "uuname");
-#endif
-	u = popen(buf, "r");
-	if (fd != NULL && u != NULL) {
-		while ((c=getc(u)) != EOF)
-			putc(c, fd);
-		(void) pclose(u);
-		(void) mclose(fd);
-	}
-}
-
-/*
- * Send the version number to the right person.
- */
-/* ARGSUSED */
-c_version(argc, argv)
-char **argv;
-{
-	register FILE *f;
-
-	f = mailhdr(&header, "Our news version");
-	if (f == NULL)
-		error("Cannot send back error message");
-	fprintf(f, "Currently running news version %s.\n\n", news_version);
-	fprintf(f, "The header of your message follows:\n\n");
-	(void) hwrite(&header, f);
-	(void) mclose(f);
-}
-
-/*
- * Check the active file for old or missing newsgroups
- * Body of article is list of valid groups
- */
-/* ARGSUSED */
-c_checkgroups(argc, argv)
-char **argv;
-{
-	int rc;
-
-	(void) setuid(geteuid());
-	/* dont change the cat %s| to < %s, it breaks some "unix" systems */
-	(void) sprintf(bfr, "cat %s | %s/checkgroups %s", INFILE, LIB,
-#ifdef NOTIFY
-		(TELLME && *TELLME) ? TELLME : NEWSUSR );
-#else /* !NOTIFY */
-		NEWSUSR);
-#endif /* !NOTIFY */
-	rc = system(bfr);
-	log("system(%s) status %d", bfr, rc);
-}
-
-/*
- * An unknown control message has been received.
- */
-c_unknown(h, ctlmsgtext)
-struct hbuf *h;
-char *ctlmsgtext;
-{
-	register FILE *f;
-
-	log("UNKNOWN Ctl Msg %s from %s", ctlmsgtext, h->path);
-#ifdef NOTIFY
-	f = mailhdr((struct hbuf *)NULL, "Unrecognized Control Message");
-	if (f != NULL) {
-		fprintf(f, "Currently running news version %s.\n\n", news_version);
-		fprintf(f, "The header of the message follows:\n\n");
-		(void) hwrite(h, f);
-		(void) mclose(f);
-	}
-#endif /* NOTIFY */
-}
-
-/* ARGSUSED */
-c_unimp(argc, argv)
-char **argv;
-{
-	register FILE *f;
-
-#ifdef NOTIFY
-	f = mailhdr((struct hbuf*)NULL, "Unimplemented Control Message");
-	if (f != NULL) {
-		fprintf(f, "Currently running news version B %s.\n\n", news_version);
-		fprintf(f, "The header of the message follows:\n\n");
-		(void) hwrite(&header, f);
-		(void) mclose(f);
-	}
-#endif /* NOTIFY */
-}
-
-/*
- * This is a modified version of popen, made more secure.  Rather than
- * forking off a shell, you get a bare process.  You must have exactly
- * one argument, and the command must be mail (or sendmail if you have it).
- */
-#define	RDR	0
-#define	WTR	1
-static	int	mopen_pid[20];
-char *replyname();
-
-FILE *
-mhopen(hptr)
-struct hbuf *hptr;
-{
-	int p[2];
-	register myside, hisside, pid;
-	char *sendto = "usenet";
-
-	if (hptr)
-		sendto = replyname(hptr);
-	else {
-#ifdef NOTIFY
-		if (TELLME)
-			sendto = TELLME;
-#endif /* NOTIFY */
-		if (sendto == NULL || *sendto == NULL)
-			return NULL;
-	}
-	verifyname(sendto);
-	if(pipe(p) < 0)
-		return NULL;
-	myside = p[WTR];
-	hisside = p[RDR];
-	if((pid = vfork()) == 0) {
-		/* myside and hisside reverse roles in child */
-		(void) close(myside);
-		(void) close(0);
-		(void) dup(hisside);
-		(void) close(hisside);
-		(void) setgid(gid);
-		(void) setuid(uid);
-#ifdef SENDMAIL
-		execl(SENDMAIL, "sendmail", "-oi", "-oeq", sendto, (char *)NULL);
-#endif /* SENDMAIL */
-#ifdef MMDF
-		execl(MMDF, "inews-mail", "-smuxto,cc*", (char *)NULL);
-#endif /* MMDF */
-		execl("/bin/mail", "mail", sendto, (char *)NULL);
-		execl("/usr/bin/mail", "mail", sendto, (char *)NULL);
-		execl("/usr/ucb/mail", "mail", sendto, (char *)NULL);
-		_exit(1);
-	}
-	if(pid == -1)
-		return NULL;
-	mopen_pid[myside] = pid;
-	(void) close(hisside);
-	return(fdopen(myside, "w"));
-}
-
-mclose(ptr)
-FILE *ptr;
-{
-	register f, r, (*hstat)(), (*istat)(), (*qstat)();
-	int status;
-
-	f = fileno(ptr);
-	(void) fclose(ptr);
-	istat = signal(SIGINT, SIG_IGN);
-	qstat = signal(SIGQUIT, SIG_IGN);
-	hstat = signal(SIGHUP, SIG_IGN);
-	while((r = wait(&status)) != mopen_pid[f] && r != -1)
-		;
-	if(r == -1)
-		status = -1;
-	signal(SIGINT, istat);
-	signal(SIGQUIT, qstat);
-	signal(SIGHUP, hstat);
-	return status;
-}
-
-/*
- * mhopen a pipe to mail, write out a std header, and return the file ptr.
- *
- * We don't include a From: field because this is probably uucp, i.e.
- * explicitly routed.  Leave it up to the recipient's mailer.
- * Always include the To: field because if we ge back failed mail, we
- * might be able to deliver it by hand if we know to wom it was addressed.
- * By convention, hptr==NULL means to send the message to the local contact person.
- */
-FILE *
-mailhdr(hptr, subject)
-struct hbuf *hptr;
-char  *subject;
-{
-	FILE *fp;
-	time_t now;
-	char *to = "usenet";
-
-#ifdef NOTIFY
-	if (TELLME && *TELLME)
-		to = TELLME;
-#endif /* NOTIFY */
-	if (hptr)
-		to = replyname(hptr);
-
-	if ((fp = mhopen(hptr)) != NULL) {
-		(void) time(&now);
-		fprintf(fp, "Date: %s\n", arpadate(&now));
-#ifdef MMDF
-		fprintf(fp, "From: The News System <usenet@%s%s>\n",
-				FULLSYSNAME, MYDOMAIN);
-#endif /* MMDF */
-		fprintf(fp, "To: %s\n", to);
-		fprintf(fp, "Subject: %s\n", subject);
-#ifdef HIDDENNET
-		if (strcmp(LOCALSYSNAME, FULLSYSNAME))
-			fprintf(fp, "Responding-System: %s.%s%s\n\n",
-				LOCALSYSNAME, FULLSYSNAME, MYDOMAIN);
-		else
-#endif /* !HIDDENNET */
-			fprintf(fp, "Responding-System: %s%s\n\n",
-				FULLSYSNAME, MYDOMAIN);
-	}
-	return fp;
-}
-
-/*
- * verify that the name mail is being sent to does not contain any
- * nasty hooks to invoke funny functions from the shell or the like.
- */
-verifyname(sendto)
-char *sendto;
-{
-	/* Be sure we DO allow alphabetics, !, :, ., -, @. *. */
-	char *nasty = "\"'\\`^|;& <>/~";
-	register char *p;
-
-	if (sendto[0] <= ' ') {
-		log("nasty mail name %s from %s", sendto, header.path);
-		xxit(1);
-	}
-	for (p=sendto; *p; p++) {
-		if (*p == ' ') {
-			*p = 0;
-			break;
-		}
-	}
-	if (strpbrk(sendto, nasty) != NULL)
-		error("nasty mail name %s from %s", sendto, header.path);
-
-	for (nasty = sendto; (nasty = index(nasty, '.')) != NULL; ) {
-		if (*++nasty == '.')	/* check for .. */
-			error("nasty mail name %s from %s", sendto, header.path);
-	}
-}
-
-/*
- * Checks to make sure the control message is OK to post.
- */
-ctlcheck()
-{
-	char msg[BUFLEN];
-	char *p;
-
-	if (!is_ctl)
-		return;
-
-	if (header.ctlmsg[0])
-		(void) strcpy(msg, header.ctlmsg);
-	else
-		(void) strcpy(msg, header.title);
-
-	p = index(msg, ' ');
-	if (p)
-		*p = 0;
-	
-	if (strcmp(msg, "ihave") == 0 || strcmp(msg, "sendbad") == 0 ||
-		strcmp(msg, "sendme") == 0) {
-		return;	/* no restrictions */
-	} else if (strcmp(msg, "newgroup") == 0) {
-		suser();
-	} else if (strcmp(msg, "rmgroup") == 0) {
-		suser();
-	} else if (strcmp(msg, "sendsys") == 0) {
-		suser();
-	} else if (strcmp(msg, "senduuname") == 0) {
-		suser();
-	} else if (strcmp(msg, "checkgroups") == 0) {
-		suser();
-	} else if (strcmp(msg, "version") == 0) {
-		return;	/* no restrictions */
-	} else if (strcmp(msg, "cancel") == 0) {
-		return;	/* no restrictions at this level */
-	} else if (strcmp(msg, "delsub") == 0) {
-		if (!prefix(header.nbuf, "to.")) {
-			printf("Must be in a 'to.system' newsgroup.");
-			xxit(0);
-		}
-		return;
-	} else {
-		printf("Unrecognized control message - %s\n", msg);
-		xxit(0);
-	}
-}
-
-/* Make sure this guy is special. */
-suser()
-{
-	if (uid == 0 || uid == ROOTID)
-		return;
-	/*
-	 * We assume that since our real uid is the same as NEWSUSR
-	 * (the euid) we were run by rootid and it did a setuid.
-	 * Too bad we can't set just the effective uid like suid does.
-	 */
-	if (uid == geteuid())
-		return;
-#ifdef IHCC
-	printf("Please use the command:\n\ttoolnews providers\n");
-	printf("then call one of the news people.\n");
-#else
-	printf("Get your local netnews contact to do it for you.\n");
-#endif
-	xxit(0);
-}
*-*-END-of-src/control.c-*-*
echo x - src/unbatch.c 1>&2
sed 's/.//' >src/unbatch.c <<'*-*-END-of-src/unbatch.c-*-*'
-/*
- * unbatchnews: extract news in batched format and process it one article
- * at a time.  The format looks like
- *	#! rnews 1234
- *	article containing 1234 characters
- *	#! rnews 4321
- *	article containing 4321 characters
- *
- *	or
- *
- *	#! command [args]
- *	calls LIBDIR/command [args] to process the news
- */
-
-#ifdef SCCSID
-static char	*SccsId = "@(#)unbatch.c	1.22	10/23/86";
-#endif /* SCCSID */
-
-#define	MAXARGS		20
-
-#include "defs.h"
-#include <stdio.h>
-#include <ctype.h>
-#if defined(USG) || defined(BSD4_2) || defined(BSD4_1C)
-#include <fcntl.h>
-#endif /* USG */
-
-char buf[BUFSIZ];
-char sibuf[BUFSIZ];
-
-main()
-{
-	register int c;
-	register FILE *pfn;
-	register long size;
-	char *filename;
-	int pid, wpid, exstat;
-	char *mktemp(), *gets();
-	long atol();
-
-	filename = mktemp("/tmp/unbnewsXXXXXX");
-	setbuf(stdin, (char *)NULL);	/* only for the first line */
-	if (gets(buf) == NULL) {
-		(void) unlink(filename);
-		exit(0);
-	}
-	if (strncmp(buf, "#! rnews ", 9) != 0) {
-		docmd(buf);
-		/* should not return */
-		logerr("unbatch: docmd returned!");
-		exit(1);
-	}
-
-	setbuf(stdin, sibuf);	/* buffer the rest of the file */
-
-	do {
-		while (strncmp(buf, "#! rnews ", 9) 
-		    && strncmp(buf, "! rnews ", 8)) { /* kludge for bug */
-			register char *cp;
-			for (cp = buf; *cp != '\0'; ++cp)
-				if (!isascii(*cp) ||
-					(!isprint(*cp) && !isspace(*cp)))
-						*cp = '?';
-			logerr("out of sync, skipping %s", buf);
-			if (gets(buf) == NULL)
-				exit(0);
-		}
-		size = atol(buf + (buf[0] == '#' ? 9 : 8));
-		if(size <= 0) {
-			logerr("nonsense size %ld", size);
-			continue;
-		}
-#ifdef VMS
-/* The loop is to delete all versions. */
-		while (unlink(filename) == 0)
-			;
-#endif /* VMS */
-		pfn = fopen(filename, "w");
-		while(--size >= 0 && (c = getc(stdin)) != EOF)
-			putc(c, pfn);
-		if (ferror(pfn) || fclose(pfn)) {	/* disk full? */
-			logerr("error writing temporary file");
-			break;
-		}
-
-		/*
-		 * If we got a truncated batch, don't process the
-		 * last article; it will probably be received again.
-		 */
-		if (size > 0) {
-			logerr("truncated batch");
-			break;
-		}
-
-		/*
-		 * rnews < filename
-		 */
-		while ((pid = vfork()) == -1) {
-			logerr("fork failed, waiting...\n");
-			sleep(60);
-		}
-		if (pid == 0) {
-			(void) close(0);
-			(void) open(filename, 0);
-#ifdef IHCC
-			(void) sprintf(buf, "%s/%s/rnews", logdir(HOME), LIBDIR);
-#else
-			(void) sprintf(buf, "%s/rnews", BINDIR);
-#endif
-#ifdef SPOOLNEWS
-			execlp(buf, "rnews", "-S", (char *)0);
-#else /* !SPOOLNEWS */
-			execlp(buf, "rnews", (char *)0);
-#endif /* !SPOOLNEWS */
-			perror("rnews");
-			exit(1);
-		}
-		while ((wpid = wait(&exstat)) >= 0 && wpid != pid)
-			;
-	} while (gets(buf) != NULL);
-	(void) unlink(filename);
-	exit(0);
-}
-
-docmd(p)
-register char *p;
-{
-	char *args[MAXARGS];
-	register char **ap = args;
-	char path[BUFSIZ];
-	char *rindex(), *cp;
-
-	while (*p && !isspace(*p))		/* skip leading #! crud */
-		p++;
-
-	while (isspace(*p))
-		p++;
-
-	while (*p != '\0') {
-		*ap++ = p;
-		if (ap >= &args[MAXARGS]) {
-			logerr("unbatch: Too many args to %s", args[0]);
-			exit(2);
-		}
-		while (*p && !isspace(*p))
-			p++;
-		if (*p)
-			*p++ = '\0';
-		while (isspace(*p))
-			p++;
-	}
-	*ap = (char *)0;
-
-	if (ap == args) {
-		logerr("unbatch: no command to execute");
-		exit(2);
-	}
-
-	/* strip off any leading pathname in case someone gets tricky */
-	cp = rindex(args[0], '/');
-	if (cp++ == NULL)
-		cp = args[0];
-
-	sprintf(path, "%s/%s", LIBDIR, cp);
-
-	/*
-	 * "path" is absolute, no searching is needed,  we use
-	 * 'execvp' solely so that sh scripts will be handled
-	 */
-	(void) execvp(path, args);
-	perror(path);
-	exit(2);
-}
-
-/*
- * Log the given message, with printf strings and parameters allowed,
- * on the log file, if it can be written.
- */
-/* VARARGS1 */
-logerr(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
-char *fmt;
-{
-	FILE *logfile;
-	char lfname[BUFSIZ];		/* the log file */
-	char bfr[BUFSIZ];
-	char *logtime, *ctime(); 
-	long t;
-
-	(void) time(&t);
-	logtime = ctime(&t);
-	logtime[16] = 0;
-	logtime += 4;
-
-#ifdef IHCC
-	(void) sprintf(lfname, "%s/%s/errlog", logdir(HOME), LIBDIR);
-#else
-	(void) sprintf(lfname, "%s/errlog", LIBDIR);
-#endif
-
-	(void) sprintf(bfr, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
-	(void) fprintf(stderr, "%s\n", bfr);
-	if (access(lfname, 0) == 0 && (logfile = fopen(lfname, "a")) != NULL) {
-#if defined(USG) || defined(BSD4_2) || defined(BSD4_1C)
-		int flags;
-		flags = fcntl(fileno(logfile), F_GETFL, 0);
-		(void) fcntl(fileno(logfile), F_SETFL, flags|O_APPEND);
-#else /* v7 */
-		(void) lseek(fileno(logfile), 0L, 2);
-#endif /* v7 */
-		fprintf(logfile, "%s\tbatch\t%s\n", logtime, bfr);
-		(void) fclose(logfile);
-	}
-}
*-*-END-of-src/unbatch.c-*-*
echo x - src/euninstal.com 1>&2
sed 's/.//' >src/euninstal.com <<'*-*-END-of-src/euninstal.com-*-*'
-$ ! @(#)euninstal.com	1.2	10/28/86
-$ ! This DCL script installs inews and rnews with the necessary
-$ ! privileges in a Eunice system.
-$ SET PROCESS/PRIV=CMKRNL
-$ RUN SYS$SYSTEM:INSTALL
-EUN_USR:[USR.BIN]RNEWS. /OPEN/SHARED/PRIV=SYSPRV
-EUN_USR:[USR.LIB.NEWS]INEWS. /OPEN/SHARED/PRIV=SYSPRV
-$ EXIT
*-*-END-of-src/euninstal.com-*-*
exit