[CONTACT]

[ABOUT]

[POLICY]

[ADVERTISE]

Aucbarpa.net.sourcesutcsrgv!utzoo!

Found at: gopher.quux.org:70/Archives/usenet-a-news/NET.sources/82.04.04_ucbarpa.1046_net.sources.txt

Aucbarpa.1046
net.sources
utcsrgv!utzoo!decvax!ucbvax!C70:ARPAVAX:mark
Sun Apr  4 15:17:49 1982
pacman/control.c
/*
 * Control message handling code.  Deal with messages which are to be
 * acted on by netnews itself rather than by people.
 */
static char *SccsId = "@(#) control.c	2.3	3/18/82";
#include "iparams.h"
#define eq(msg) (strcmp(msg, cargv[0]) == 0)
int cargc;
char **cargv;
FILE *hfopen();
FILE *popen(), *mopen(), *mailhdr();
control(h)
struct hbuf *h;
{
	int i;
	log("Ctl Msg %s from %s: %s", h->nbuf, h->path, h->title);
	/*
	 * 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(h->title);
	
	if (eq("ihave"))
		c_ihave(cargc, cargv);
	else if (eq("sendme"))
		c_sendme(cargc, cargv);
	else if (eq("newgroup"))
		c_newgroup(cargc, cargv);
	else if (eq("rmgroup"))
		c_rmgroup(cargc, cargv);
	else if (eq("cancel"))
		c_cancel(cargc, cargv);
	else if (eq("sendsys"))
		c_sendsys(cargc, cargv);
	else if (eq("senduuname"))
		c_senduuname(cargc, cargv);
	else
		c_unknown(h);
}
/*
 * 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)
		xerror("Control message %s has no title", header.ident);
	cargc = 0;
	cargv = cavpbuf;
	cargv[0] = cavbuf;
	while (*str) {
		if (*str <=   ) SKIP /* (*STR { WHITE CARGV[CARGC]="nextfree;" OVER CARGC++; *NEXTFREE++="0;" SPACE */ WHILE> 0 && *str <=   ) * /* STR++; (*STR="=" 0) ELSE } <ARTID WHITE RETURN; ENDS *NEXTFREE++="*str++;" SPACE */ LINE IF IN IHAVE> <REMOTESYS>
 * The other system is telling you it has article <ARTID>, in case
 * you decide you want it to transmit it to you.
 */
c_ihave(argc, argv)
char **argv;
{
	char tl[256], ng[256];
	/*
	 * Check that we haven't already seen it (history)
	 * and then send back a "sendme" message if we subscribe.
	 */
	if (history(argv[1]) == 0) {
		/* Should probably check SUBFILE and NGFILE here. */
		sprintf(tl, "sendme %s %s", argv[1], SYSNAME);
		sprintf(ng, "to.%s.ctl", argv[2]);
		xmitmsg(argv[2], tl, ng);
	}
}
/*
 * sendme <ARTID> <REMOTESYS>
 * The other system wants me to send him article <ARTID>.
 */
c_sendme(argc, argv)
char **argv;
{
	struct srec srec;
	FILE *fp;
	/* Find the sys record */
	s_openr();
	while (s_read(&srec)) {
		if (strncmp(srec.s_name, argv[2], SNLN))
			continue;
		/* It's the right one.  Send it. */
		fp = hfopen(argv[1]);
		transmit(&srec, fp, 0);
		return;
	}
	sprintf(bfr, "Cannot find system %s to send article %s to.",
		argv[2], argv[1]);
	xerror(bfr);
}
/*
 * newgroup <GROUPNAME>
 * A new newsgroup has been created.
 * The body of the article, if present, is a description of the
 * purpose of the newsgroup.
 *
 * Site dependent.  Should make very sure the directory has been
 * created and properly owned.  Might want to update ngfile.
 * Might want to notify the contact person for this installation.
 * Default action is to create the newsgroup, if it doesn't already
 * exist.
 */
c_newgroup(argc, argv)
char **argv;
{
	FILE *fd;
	sprintf(bfr, "%s/%s", SPOOL, argv[1]);
	/*
	 * This check will cause us to exit if we already have the newsgroup.
	 * Since propagation happens later, this means we won't forward it,
	 * either.  We assume that what happened is some new site had to
	 * do inews -C to submit to a newsgroup that already exists but that
	 * they don't have yet.  So we don't want to propagate in this case.
	 */
	if (access(bfr, 0) == 0)
		xerror("newgroup already exists");
	mknewsg(bfr);
#ifdef UPDATENGFILE
	/* Sample code to update ngfile */
	fd = fopen(NGFILE, "a");
	fprintf(fd, "%s\n", argv[1]);
	fclose(NGFILE);
#endif
#ifdef NOTIFY
	/*
	 * Sample code to notify the contact person.
	 * Probably should dig up the text of the article
	 * and enclose that, too.  It can be found in the
	 * file ARTICLE.  Also, there needs to be
	 * an automatic provision to help you add the newsgroup.
	 *
	 * Note that even if you take out the above call to mknewsg,
	 * the newsgroup will still be created by the first article
	 * that comes in on it by a different call to mknewsg in inews.c
	 */
	fd = mailhdr(NOTIFY, "request for new newsgroup");
	fprintf(fd, "\nA new newsgroup called '%s' has been created by %s.\n\n",
		argv[1], header.path);
	mclose(fd);
#endif
}
/*
 * rmgroup <GROUPNAME>
 * An old newsgroup is being cancelled on a network wide basis.
 */
c_rmgroup(argc, argv)
char **argv;
{
	FILE *fd;
	char *groupname;
	char groupdir[128];
	int rc;
#ifdef NOTIFY
	fd = mailhdr(NOTIFY, "rmgroup control message");
	fprintf(fd, "\nA newsgroup called '%s' has been removed by %s.\n\n",
		argv[1], header.path);
#ifdef USG
	fprintf(fd, "You may need to remove the directory %s/%s by hand\n",
		SPOOL, argv[1]);
#endif
	mclose(fd);
#endif
	groupname = argv[1];
	verifyname(groupname);
	if (groupname[0] == '.')
		xerror("Illegal group name in rmgroup");
	sprintf(groupdir, "%s/%s", SPOOL, groupname);
	if (access(groupdir, 0)) {
		/*
		 * If the group already is gone, it's a nonfatal error - we
		 * want to propagate the message anyway, since what probably
		 * happened is somebody locally already removed it.
		 */
		log("Cannot remove newsgroup '%s'", groupname);
		return;
	}
#ifndef MANUALLY
	/* We let the shell do all the work.  See the rmgrp shell script. */
	setuid(geteuid());	/* otherwise it won't rmdir the dir */
	sprintf(bfr, "rm -rf %s", groupdir);
	rc = system(bfr); log("system(%s) status %d", bfr, rc);
	sprintf(bfr, "cp %s/active /tmp/$$ ; sed '/^%s$/d' </TMP/$$> %s/active ; rm /tmp/$$",
		LIB, groupname, LIB);
	rc = system(bfr); log("system(%s) status %d", bfr, rc);
#endif
}
/*
 * cancel <ARTID>
 * Cancel the named article
 */
c_cancel(argc, argv)
char **argv;
{
	char *line, *p, *q, *r, *s;
	char *findhist();
	register FILE *fp;
	char whatsisname[150];
	char msgbuf[256];
	char msgng[64];
	int su = 0;
	strcpy(whatsisname, header.path);
	strcpy(msgng, header.nbuf);
	line = findhist(argv[1]);
	if (line)
		log("Cancelling %s", line);
	else
		log("Can't cancel %s:  non-existent", argv[1]);
	p = index(line, '\t');
	p = index(p+1, '\t');
	p++;
	while (*p) {
		q = index(p, ' ');
		if (q)
			*q = 0;
		sprintf(filename, "%s/%s", SPOOL, p);
		fp = xfopen(filename, "r");
		if (hread(&header, fp) == NULL)
			xerror("Article is garbled.\n");
		fclose(fp);
printf("uid %d, ROOTID %d, msgng %s\n", uid, ROOTID, msgng);
		if((uid==ROOTID||uid==0) && strncmp(msgng,"to.",3) == 0)
			su = 1;
		r = rindex(header.path, '!');
		if (r == 0) {
			r = header.path;
		}
		else {
			while (r > header.path && *--r != '!')
				;
			if (r > header.path)
				r++;
		}
printf("header.path '%s', r %x, su %d\n", header.path, r, su);
		s = rindex(whatsisname, '!');
		if (s == 0)
			s = whatsisname;
		else {
			while (s > whatsisname && *--s != '!')
				;
			if (s > whatsisname)
				s++;
		}
		if (!su && strcmp(r, s)) {
			sprintf(msgbuf, "Not contributor: %s and %s", header.path, whatsisname);
			xerror(msgbuf);
		}
		cancel();
		p = q+1;
	}
}
/*
 * 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.general, 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.
 */
c_sendsys(argc, argv)
char **argv;
{
	char buf[256];
	FILE *f, *u;
	int c;
#ifdef NOTIFY
	f = mailhdr(NOTIFY, "sendsys control message");
	fprintf(f, "\n%s requested your sys file.\n", header.path);
	mclose(f);
#endif
	f = mopen(header.path);
	fprintf(f, "Subject: response to your sendsys request\n\n");
	u = fopen(SUBFILE, "r");
	while ((c=getc(u)) != EOF)
		putc(c, f);
	fclose(u);
	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.
 */
c_senduuname(argc, argv)
char **argv;
{
	char buf[256];
	FILE *fd, *u;
	int c;
#ifdef NOTIFY
	fd = mailhdr(NOTIFY, "uuname control message");
	fprintf(fd, "\n%s requested your uuname output\n", header.path);
	mclose(fd);
#endif
	fd = mailhdr(header.path, "response to your senduuname request");
#ifdef UUNAME
	if (UUNAME[0] == '/')
		strcpy(buf, UUNAME);
	else
		sprintf(buf, "%s/%s", LIB, UUNAME);
#else
	strcpy(buf, "uuname");
#endif
	u = popen(buf, "r");
	while ((c=getc(u)) != EOF)
		putc(c, fd);
	pclose(u);
	mclose(fd);
}
/*
 * An unknown control message has been received.
 */
c_unknown(h)
struct hbuf *h;
{
	FILE *f;
	log("UNKNOWN Ctl Msg %s from %s", h->title, h->path);
	f = mailhdr(h->path, "Unrecognized Control Message");
	if (f == NULL)
		xerror("Cannot send back error message");
	fprintf(f, "Sent-by: USENET Site %s\n\n", SYSNAME);
	fprintf(f, "Currently running news B version %s.\n\n", SccsId);
	fprintf(f, "The header of the message follows:\n");
	hwrite(h, f);
	mclose(f);
}
c_unimp(msg)
char *msg;
{
	FILE *f;
	char buf[256];
	f = mailhdr(header.path, "Unimplemented Control Message");
	if (f == NULL)
		xerror("Cannot send back error message");
	fprintf(f, "Sent-by: USENET Site %s\n\n", SYSNAME);
	fprintf(f, "Currently running news B version %s.\n\n", SccsId);
	fprintf(f, "The header of the message follows:\n");
	hwrite(&header, f);
	mclose(f);
}
xmitmsg(tosys, title, ng)
char *tosys, *title, *ng;
{
	struct hbuf h;
	struct srec srec;
	FILE *tfp;
	char *fname;
	/* Make an article called ARTICLE */
	strcpy(h.path, NEWSU);
	strcpy(h.nbuf, ng);
	strcpy(h.title, title);
	strcpy(h.subdate, "");
	strcpy(h.recdate, "");
	strcpy(h.expdate, "");
	getident(&h);
	dates(&h);
	tfp = xfopen(fname = mktemp("/tmp/xmsgXXXXXX"), "w");
	hwrite(&h, tfp);
	fclose(tfp);
	/* Find the sys record */
	s_openr();
	while (s_read(&srec)) {
		if (strncmp(srec.s_name, tosys, SNLN))
			continue;
		tfp = xfopen(fname, "r");
		transmit(&srec, tfp, 0);
		unlink(fname);
		return;
	}
	log("Can't find sys record for %s", tosys);
	xerror("Cannot find sys record");
}
/*
 * Given an article ID, find the line in the history file that mentions it.
 * Return the text of the line, or NULL if not found.  A pointer to a
 * static area is returned.
 */
char *
findhist(artid)
char *artid;
{
	static char lbuf[256];
	FILE *hfp;
	char *p;
	hfp = xfopen(ARTFILE, "r");
	while (fgets(lbuf, BUFLEN, hfp) != NULL) {
		p = index(lbuf, '\t');
		if (p == NULL)
			p = index(lbuf, '\n');
		*p = 0;
		if (strcmp(lbuf, artid) == 0) {
			fclose(hfp);
			*p = '\t';
			*(lbuf + strlen(lbuf) - 1) = 0;	/* zap the \n */
			return(lbuf);
		}
	}
	fclose(hfp);
	return(NULL);
}
/*
 * Hunt up the article "artid", fopen it for read, and return a
 * file descriptor to it.  We look everywhere we can think of.
 */
FILE *
hfopen(artid)
char *artid;
{
	char *line, *p, *q;
	char *findhist();
	FILE *rv;
	char fname[256];
	line = findhist(artid);
	if (line) {
		/* Look for it stored as an article, where it should be */
		p = index(line, '\t');
		p = index(p+1, '\t');
		p++;
		while (*p) {
			q = index(p, ' ');
			*q = 0;
			sprintf(fname, "%s/%s", SPOOL, p);
			rv = fopen(fname, "r");	/* NOT xfopen! */
			if (rv != NULL)
				return rv;
			p = q+1;
		}
	}
	/*
	 * Last ditch effort - see if we have it archived in with the
	 * cancelled articles.
	 */
	sprintf(fname, "%s/%s", CAND, artid);
	rv = fopen(fname, "r");
	if (rv == NULL)
		xerror("Cannot hfopen article %s", artid);
	return rv;
}
/*
 * 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.
 */
/* @(#)popen.c	4.1 (Berkeley) 12/21/80 */
#include <STDIO.H>
#include <SIGNAL.H>
#define	RDR	0
#define	WTR	1
static	int	mopen_pid[20];
FILE *
mopen(sendto)
char	*sendto;
{
	int p[2];
	register myside, hisside, pid;
	verifyname(sendto);
	if(pipe(p) /~";
	while (*nasty) {
		if (index(sendto, *nasty++)) {
			log("nasty mail name %s from %s", sendto, header.path);
			xxit(1);
		}
	}
	for (nasty = sendto; (nasty = index(nasty, '.')) != NULL; ) {
		if (*++nasty == '.') {	/* check for .. */
			log("nasty mail name %s from %s", sendto, header.path);
			xxit(1);
		}
	}
}
/*
 * Checks to make sure the control message is OK to post.
 */
ctlcheck()
{
	char msg[150];
	char *p;
	if (!is_ctl)
		return;
	strcpy(msg, header.title);
	p = index(msg, ' ');
	if (p)
		*p = 0;
	
	if (strcmp(msg, "ihave") == 0) {
	} else if (strcmp(msg, "sendme") == 0) {
		return;	/* no restrictions */
	} else if (strcmp(msg, "newgroup") == 0) {
		return;	/* no restrictions */
	} else if (strcmp(msg, "rmgroup") == 0) {
		suser();
		checkpass("mTnyckAVEMXWk");
	} else if (strcmp(msg, "sendsys") == 0) {
		suser();
	} else if (strcmp(msg, "senduuname") == 0) {
		suser();
	} else if (strcmp(msg, "cancel") == 0) {
		return;	/* no restrictions at this level */
	} else {
		printf("Unrecognized control message - %s\n", msg);
		xxit(0);
	}
}
/* Make sure this guy is special. */
suser()
{
	if (uid == 0)
		return;
	if (uid == ROOTID)
		return;
	printf("Get a guru to do it for you.\n");
	xxit(0);
}
/*
 * Demand a password from the user.
 */
checkpass(encpw)
{
	if (strcmp(encpw, crypt(getpass("Password:"), "mT"))) {
		printf("Sorry\n");
		xxit(0);
	}
}
-----------------------------------------------------------------
 gopher://quux.org/ conversion by John Goerzen <jgoerzen@complete.org>
 of http://communication.ucsd.edu/A-News/
This Usenet Oldnews Archive
article may be copied and distributed freely, provided:
1. There is no money collected for the text(s) of the articles.
2. The following notice remains appended to each copy:
The Usenet Oldnews Archive: Compilation Copyright (C) 1981, 1996 
 Bruce Jones, Henry Spencer, David Wiseman.


AD:

NEW PAGES:

[ODDNUGGET]

[GOPHER]