DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T f

⟦5ab110507⟧ TextFile

    Length: 13920 (0x3660)
    Types: TextFile
    Names: »funcs2.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/news/src/funcs2.c« 

TextFile

/*
 * This software is Copyright (c) 1985 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.
 *
 *
 * funcs2 - functions used by both inews and readnews.
 */

#ifdef SCCSID
static char	*SccsId = "@(#)funcs2.c	1.20	3/20/87";
#endif /* SCCSID */

#include "params.h"

#ifdef SunIII
#ifndef INTERNET
#define	INTERNET
#endif /* !INTERNET */
#endif /* SunIII */

/*LINTLIBRARY*/

/*
 * Get user name and home directory.
 */
getuser()
{
	static int flag = TRUE;
	register struct passwd *p;

	if (flag) {
		if ((p = getpwuid(uid)) == NULL)
			xerror("Cannot get user's name");
		if ( username == NULL || username[0] == 0)
			username = AllocCpy(p->pw_name);
		userhome = AllocCpy(p->pw_dir);
		flag = FALSE;
	}
	(void) strcpy(header.path, username);
}

static	FILE	*sysfile;

char *fldget();

static int sfline;

/*
 * Open SUBFILE.
 */
s_openr()
{
	sysfile = xfopen(SUBFILE, "r");
	sfline = 0;
}

/*
 * Read SUBFILE.
 */
s_read(sp)
register struct srec *sp;
{
	register char *p;
	register int  c;
	char *e;
	int chop_spaces = 0;
again:
	p = bfr;
        /*
         * Read  the  SUBFILE  (/usr/lib/news/sys)  from   the   current
	 * position  to  the  first  unescaped newline.  If a newline is
	 * escaped with a backslash (\) continue reading but throw  away
	 * the backslash and newline; read the next line skipping spaces
	 * and tabs until the first non-space/tab character, then  start
	 * looking   for   a   newline   again.   Skipping  the  leading
	 * spaces/tabs after a escaped newline  keeps  the  news  groups
	 * together.  If  a  line  begins  with a newline, just skip it.
	 */
	for (e=p+LBUFLEN; p < e && (c=getc(sysfile)) != EOF; p++) {
		*p = c;
		if (c == '\n') {
			sfline++;
			if (p == bfr || p[-1] != '\\') {
				p[1] = '\0';
				break;
			} else {
				chop_spaces++;
				p -= 2;
			}
		} else if (chop_spaces) {
			if (c == '\t' || c == ' ')
				p--;
			else
				chop_spaces = 0;
		}
	}
	if (c == EOF) {
		return FALSE;
	}
	p = bfr;
	while (*p == ' ' || *p == '\t') /* skip leading white space */
		p++;
	if (*p == '\n')
		goto again;	     /* skip newlines */
	if (!nstrip(p))
		xerror("SUBFILE (%s) line %d too long.", SUBFILE, sfline);
	if (*p == '#')
		goto again;
	sp->s_xmit[0] = '\0';
	sp->s_flags[0] = '\0';
	sp->s_nosend = (char *)0;

	p = fldget(sp->s_name, p);
	if (*p++ == '\0')
		xerror("Bad SUBFILE (%s) line %d.", SUBFILE, sfline);
	/*
	 * A sys file line reading "ME" means the name of the local system.
	 */
	if (strcmp(sp->s_name, "ME") == 0)
		(void) strcpy(sp->s_name, LOCALPATHSYSNAME);
	e = index(sp->s_name, '/');
	if (e) {
		*e++ = '\0';
		sp->s_nosend = e;
	}
	p = fldget(sp->s_nbuf, p);
	lcase(sp->s_nbuf);
	if (*p++ == '\0')
		return TRUE;

	p = fldget(sp->s_flags, p);
	if (*p++ == '\0')
		return TRUE;

	(void) fldget(sp->s_xmit, p);
	return TRUE;
}

char *
fldget(q, p)
register char *q, *p;
{
	while (*p && *p != ':') {
		if (*p == '\\' && p[1]==':')
			p++;
		*q++ = *p++;
	}
	*q = '\0';
	return p;
}

/*
 * Find the SUBFILE record for a system.
 */
s_find(sp, system)
register struct srec *sp;
char *system;
{
	s_openr();
	while (s_read(sp))
		if (strncmp(system, sp->s_name, SNLN) == 0) {
			s_close();
			return TRUE;
		}
	s_close();
	return FALSE;
}

/*
 * Close sysfile.
 */
s_close()
{
	(void) fclose(sysfile);
}

extern struct timeb Now;

time_t
cgtdate(datestr)
char *datestr;
{
	char	junk[40],month[40],day[30],tod[60],year[50];
	static time_t lasttime;
	static char lastdatestr[BUFLEN] = "";

	if ( lastdatestr[0] && strcmp(datestr, lastdatestr) == 0)
		return lasttime;
	lasttime = getdate(datestr, &Now);
	if (lasttime < 0 &&
	  sscanf(datestr, "%s %s %s %s %s", junk, month, day, tod, year) == 5) {
		(void) sprintf(bfr, "%s %s, %s %s", month, day, year, tod);
		lasttime = getdate(bfr, &Now);
	}
	strncpy(lastdatestr, datestr, BUFLEN);
	return lasttime;
}

lcase(s)
register char *s;
{
	register char *ptr;

	for (ptr = s; *ptr; ptr++)
		if (isupper(*ptr))
			*ptr = tolower(*ptr);
}

/*
 * Return a compact representation of the person who posted the given
 * message.  A sender or internet name will be used, otherwise
 * the last part of the path is used preceded by an optional ".."
 */
char *
tailpath(hp)
struct hbuf *hp;
{
	char *p, *r;
	static char resultbuf[BUFLEN];
	char pathbuf[PATHLEN];
	char *malloc();

	/*
	 * This only happens for articles posted by old news software
	 * in non-internet format.
	 */
	resultbuf[0] = '\0';
	(void) strncpy(pathbuf, hp->path, PATHLEN);
	p = index(pathbuf, ' ');
	if (p)
		*p = '\0';	/* Chop off trailing " (name)" */
	r = rindex(pathbuf, '!');
	if (r == 0) {
		r = pathbuf;
	} else {
		while (r > pathbuf && *--r != '!')
			;
		if (r > pathbuf) {
			r++;
			(void) strcpy(resultbuf, "..!");
		}
	}
	(void) strcat(resultbuf, r);
	return resultbuf;
}

/*
 * arpadate is like ctime(3) except that the time is returned in
 * an acceptable ARPANET time format instead of ctime format.
 */
char *
arpadate(longtime)
time_t *longtime;
{
	register char *p, *q, *ud;
	register int i;
	static char b[40];
	extern struct tm *gmtime();
	extern char *asctime();

	/*  Get current time. This will be used resolve the timezone. */
	ud = asctime(gmtime(longtime));

	/*  Crack the UNIX date line in a singularly unoriginal way. */
	q = b;

#ifdef notdef
/* until every site installs the fix to getdate.y, the day
   of the week can cause time warps */
	p = &ud[0];		/* Mon */
	*q++ = *p++;
	*q++ = *p++;
	*q++ = *p++;
	*q++ = ','; *q++ = ' ';
#endif

	p = &ud[8];		/* 16 */
	if (*p == ' ')
		p++;
	else
		*q++ = *p++;
	*q++ = *p++; *q++ = ' ';

	p = &ud[4];		/* Sep */
	*q++ = *p++; *q++ = *p++; *q++ = *p++; *q++ = ' ';

	p = &ud[22];		/* 1979 */
	*q++ = *p++; *q++ = *p++; *q++ = ' ';

	p = &ud[11];		/* 01:03:52 */
	for (i = 8; i > 0; i--)
		*q++ = *p++;

	*q++ = ' ';
	*q++ = 'G';		/* GMT */
	*q++ = 'M';
	*q++ = 'T';
	*q = '\0';

	return b;
}

char *
replyname(hptr)
struct hbuf *hptr;
{
	register char *ptr;
	static char tbuf[PATHLEN];

	ptr = hptr->path;
	if (prefix(ptr, PATHSYSNAME) &&
		index(NETCHRS, ptr[strlen(PATHSYSNAME)]))
		ptr = index(ptr, '!') + 1;
#ifdef INTERNET
	if (hptr->from[0])
		ptr = hptr->from;
	if (hptr->replyto[0])
		ptr = hptr->replyto;
#endif
	(void) strcpy(tbuf, ptr);
	ptr = index(tbuf, '(');
	if (ptr) {
		while (ptr[-1] == ' ')
			ptr--;
		*ptr = 0;
	}
#ifdef	SunIII
	if (ptr = rindex(tbuf, '.')) {
		if (prefix(++ptr, "OZ")) {
			/* some people only allow it in lower case ... */
			strcpy(ptr, "oz");
			return tbuf;
		}
		if (prefix(ptr, "UUCP") || prefix(ptr, "ARPA") ||
		    prefix(ptr, "DEC") || prefix(ptr, "CSNET")) {
			strcat(tbuf, "@munnari.oz");	/* via sun to munnari */
			return tbuf;
		}
	}
	/*
	 * must(?) have come from a uucp site, lets look see if path passes
	 * through munnari, and if so delete the fake uucp path after that.
	 */
	for (ptr = tbuf ;; ptr++) {
		if (prefix(ptr, "munnari!")) {
			strcpy(tbuf, ptr+8);
			break;
		}
		ptr = index(ptr, '!');
		if (ptr == (char *)0)
			break;
	}
	/*
	 * now, just send the address we have left to munnari, and
	 * hope that something sensible will be done with it there.
	 * (This works in more cases than you'd think ...)
	 */
	strcat(tbuf, "@munnari.oz");
#else /* !SunIII */
#ifndef INTERNET
	/*
	 * Play games stripping off multiple berknet
	 * addresses (a!b!c:d:e => a!b!d:e) here.
	 */
	for (ptr=tbuf; *ptr; ptr++) {
		register char *ptr2;

		if (index(NETCHRS, *ptr) && *ptr == ':' &&
		    (ptr2=index(ptr+1, ':')))
			(void) strcpy(ptr, ptr2);
	}
#else	/* INTERNET */
	{
	char mbuf[BUFLEN], modadd[BUFLEN];
	FILE *mfd;
	/* Let's find a path to the backbone */
	sprintf(mbuf, "%s/mailpaths", LIB);
	mfd = xfopen(mbuf, "r");
	do {
		if (fgets(mbuf, sizeof mbuf, mfd) == NULL)
			xerror("Can't find internet in %s/mailpaths",
				LIB);
	} while (!prefix(mbuf, "internet"));
	if (sscanf(mbuf, "%*s %s", modadd) != 1)
		xerror("backbone address corrupted");
	(void) fclose(mfd);
	(void)strcpy(mbuf, tbuf);
	/* If we are lucky, there is no ! or @ in the forward address */
	if (strpbrk(modadd, "!@") == NULL) {
		sprintf(tbuf, modadd, mbuf);
	} else {
		char *cp = index(mbuf, '@');
		if (index(modadd, '@') == NULL && cp) {
			/* we have to rearrange the address so no @ are in it */
			char atbuf[BUFLEN];
			*cp++ = '\0';
			sprintf(atbuf, "%s!%s", cp, mbuf);
			sprintf(tbuf, modadd, atbuf);
		} else if (cp) {
			/* some days you don't get lucky. presume the % hack */
			*cp = '%';
			sprintf(tbuf, modadd, mbuf);
		}
	}
	}
#endif /* INTERNET */
#endif /* !SunIII */
	return tbuf;
}

#ifdef DBM
typedef struct {
	char *dptr;
	int dsize;
} datum;
#endif /* DBM */

/*
 * 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];
	char oidbuf[BUFSIZ];
	FILE *hfp;
	register char *p;
#ifdef DBM
	datum lhs, rhs;
	datum fetch();
	long fpos; /* We have to use an explicit variable to insure alignment */
#else /* !DBM */
	char *histfile();
#endif /* !DBM */

	/* Try to understand old artid's as well.  Assume .UUCP domain. */
	if (artid[0] != '<') {
		p = index(artid, '.');
		if (p)
			*p++ = '\0';
		(void) sprintf(oidbuf, "<%s@%s.UUCP>", p, artid);
		if (p)
			*--p = '.';
	} else
		(void) strcpy(oidbuf, artid);
	lcase(oidbuf);
#ifdef DBM
	initdbm(ARTFILE);
	lhs.dptr = oidbuf;
	lhs.dsize = strlen(lhs.dptr) + 1;
	rhs = fetch(lhs);
	if (rhs.dptr == NULL)
		return NULL;
	hfp = xfopen(ARTFILE, "r");
	/* The bcopy is NECESSARY to insure alignment on some machines */
	bcopy(rhs.dptr, (char *)&fpos, sizeof (long));
	fseek(hfp, fpos, 0);
#else /* !DBM */
	hfp = xfopen(histfile(oidbuf), "r");
#endif /* !DBM */
	while (fgets(lbuf, BUFLEN, hfp) != NULL) {
		p = index(lbuf, '\t');
		if (p == NULL)
			p = index(lbuf, '\n');
		*p = 0;
		if (strcmp(lbuf, artid) == 0 || strcmp(lbuf, oidbuf) == 0) {
			(void) fclose(hfp);
			*p = '\t';
			*(lbuf + strlen(lbuf) - 1) = 0;	/* zap the \n */
			return lbuf;
		}
#ifdef DBM
		break;
#endif /* DBM */
	}
	(void) fclose(hfp);
	return NULL;
}

/*
 * Hunt up the article "artid", and return the newsgroup/artnum
 * where it can be found.
 */
char *
findfname(artid)
char *artid;
{
	char *line, *p, *q;
	char *findhist();
	static char fname[BUFLEN];

	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++;
		if (*p) {
			q = index(p, ' ');
			if (q)
				*q = 0;
			(void) strcpy(fname, p);
			return fname;
		}
	}
	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 *p;
	char *findhist();
	FILE *rv = NULL;
	char fname[BUFLEN];

	p = findfname(artid);
	if (p) {
		(void) strcpy(fname, dirname(p));
		rv = fopen(fname, "r");	/* NOT xfopen! */
		if (rv == NULL)
			xerror("Cannot hfopen article %s", artid);
	}
	return rv;
}

#ifdef DBM
/*
** Avoid problems of multiple dbminit calls.
*/
initdbm(name)
char *name;
{
	static int called = 0;

	if (called != 0)
		return;
	called = 1;
	(void) dbminit(name);
}
#endif

#ifndef BSD4_2
/*
 * move n bytes from a to b
 */
bcopy(a, b, n)
register char *a, *b;
register n;
{
	while (--n >= 0)
		*b++ = *a++;
}
#endif

#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 */

#ifndef DBM
/*
** Generate the appropriate history subfile name
*/
char *
histfile(hline)
char *hline;
{
	char chr;	/* least significant digit of article number */
	static char subfile[BUFLEN];

	chr = findhfdigit(hline);
	sprintf(subfile, "%s.d/%c", ARTFILE, chr);
	return subfile;
}

findhfdigit(fn)
char *fn;
{
	register char *p;
	register int chr;

	p = index(fn, '@');
	if (p != NULL && p > fn)
		chr = *(p - 1);
	else
		chr = '0';
	if (!isdigit(chr))
		chr = '0';
	return chr;
}
#endif /* !DBM */

#ifdef VMS
/*
 * These functions open an article with one level of indirection,
 * to support symbolic links. xart_open exits if the open fails.
 */
FILE *
xart_open (filename,mode)
char *filename,*mode;
{
	FILE *fp = art_open (filename, mode);
	extern int errno;
	if (fp == NULL)
		xerror("Cannot open article %s (%s): %s\n",
			 filename, mode, errmsg(errno));
	return fp;
}

FILE *
art_open (filename,mode)
char *filename,*mode;
{
	char linkfile[BUFSIZ];
	FILE *fp;

	if ((fp = fopen (filename, mode)) == NULL)
		return NULL;
	if (fgets (linkfile, BUFSIZ, fp) == NULL || linkfile[0] != '/') {
		rewind (fp);
		return fp;
	}
/* Chase the symbolic link. */
	(void) fclose (fp);
	if ((fp = fopen (linkfile, mode)) == NULL)
/* Clean up dangling link, if we have the power. Ignore error if we don't. */
		(void) unlink (filename);
	return fp;
}
#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();
	static char senderbuf[BUFLEN];

	if (hp->sender[0])
		tp = hp->sender;
	else if (hp->from[0])
		tp = hp->from;
	else
		tp = tailpath(hp);

	(void) strncpy(senderbuf, tp, BUFLEN);
	/* Remove full name */
	q = index(senderbuf, ' ');
	if (q)
		*q = '\0';

	return senderbuf;
}