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 - metrics - download
Index: T f

⟦ff7be04f5⟧ TextFile

    Length: 16550 (0x40a6)
    Types: TextFile
    Names: »fred.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« 
        └─⟦de7628f85⟧ 
            └─⟦this⟧ »isode-6.0/others/quipu/uips/fred/fred.c« 

TextFile

/* fred.c - FRont-End to Dish */

#ifndef	lint
static char *rcsid = "$Header: /f/osi/others/quipu/uips/fred/RCS/fred.c,v 7.4 90/01/16 20:43:24 mrose Exp $";
#endif

/* 
 * $Header: /f/osi/others/quipu/uips/fred/RCS/fred.c,v 7.4 90/01/16 20:43:24 mrose Exp $
 *
 *
 * $Log:	fred.c,v $
 * Revision 7.4  90/01/16  20:43:24  mrose
 * last check-out
 * 
 * Revision 7.3  90/01/11  18:36:28  mrose
 * real-sync
 * 
 * Revision 7.2  89/12/14  18:48:59  mrose
 * KIS project
 * 
 * Revision 7.1  89/12/13  20:01:46  mrose
 * errfp
 * 
 * Revision 7.0  89/11/23  22:08:56  mrose
 * Release 6.0
 * 
 */

/*
 *				  NOTICE
 *
 *    Acquisition, use, and distribution of this module and related
 *    materials are subject to the restrictions of a license agreement.
 *    Consult the Preface in the User's Manual for the full terms of
 *    this agreement.
 *
 */


#include <setjmp.h>
#include <signal.h>
#include <varargs.h>
#include "fred.h"
#include "internet.h"

/* \f

   DATA */

static char *myname = "fred";

static char **op = NULLVP;

static int alarming = 0;
static int logging = 0;
static int ontty;
static int armed;
static jmp_buf	alrmenv;
static jmp_buf	intrenv;
int	interrupted;

int	oneshot;

SFP	astat;
SFP	istat;
SFP	qstat;

SFD	alrmser ();
SFD	intrser ();

LLog    _fred_log = {
    "fred.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE,
    LLOG_NONE, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
};
LLog *fred_log = &_fred_log;


static char *from = NULL;
static char *reply_to = NULL;
static char *sender = NULL;
static char *subject = NULL;

static struct pair {
    char   *p_name;
    char  **p_value;
} pairs[] = {
    "From:", &from,
    "Reply-To:", &reply_to,
    "Sender:", &sender,
    "Subject:", &subject,
};

/* \f

   MAIN */

/* ARGSUSED  */

main (argc, argv, envp)
int	argc;
char  **argv,
      **envp;
{
    int	    eof,
	    status,
	    vecp;
    register char   *cp;
    char    address[BUFSIZ],
	    buffer[BUFSIZ],
	   *vec[NVEC + 1];
    struct sockaddr_in in_socket,
		      *isock = &in_socket;

    arginit (argv);

    rcinit ();

    rcfile (isodefile ("fredrc", 0), 0, 1);

    status = 0;

    if (mail) {
	register int   c;
	register char *ep;
	register struct pair *p;
	FILE   *fp;

	for (;;) {
	    ep = (cp = buffer) + sizeof buffer - 1;

	    while ((c = getc (stdin)) != EOF)
		if (c == '\n') {
		    if ((c = getc (stdin)) == ' ' || c == '\t') {
			*cp++ = ' ';
			while ((c = getc (stdin)) == ' ' || c == '\t')
			    continue;
			if (c != EOF)
			    (void) ungetc (c, stdin);
			else {
			    c = NULL;
			    break;
			}
		    }
		    else {
			if (c == EOF)
			    c = NULL;
			else
			    (void) ungetc (c, stdin);
			break;
		    }
		}
		else
		    if (cp < ep)
			*cp++ = c != '\t' ? c & 0xff : ' ';

	    if (cp == buffer)
		break;
	    *cp = NULL;

	    for (p = pairs; p -> p_name; p++)
		if (lexnequ (buffer, p -> p_name, c = strlen (p -> p_name))
		        == 0) {
		    if (*p -> p_value == NULL) {
			for (cp = buffer + c; *cp == ' ' || *cp == '\t'; cp++)
			    continue;
			if (*cp) {
			    ep = cp + strlen (cp) - 1;
			    while (*ep == ' ')
				ep--;
			    *++ep = NULL;
			    *p -> p_value = strdup (cp);
			}
		    }
		    break;
		}

	}

	if (!from && !reply_to && !sender)
	    adios (NULLCP, "unable to determine return address");

	(void) sprintf (buffer, "/bin/mail \"%s\"",
			ep = reply_to ? reply_to : from ? from : sender);
	if (watch) {
	    fprintf (stderr, "%s\n", buffer);
	    (void) fflush (stderr);
	}

	(void) signal (SIGPIPE, SIG_IGN);
	if ((fp = popen (buffer, "w")) == NULL)
	    adios ("failed", "popen");

	stdfp = errfp = fp;

	fprintf (stdfp, "To: %s\nSubject: Re: %s\n\n",
		 ep, subject ? subject : "white pages query");
	(void) fflush (stdfp);

	if (f_bind (NULLVP) == NOTOK)
	    adios (NULLCP, "unable to open the white pages");

	if (subject) {
	    (void) strcpy (buffer, subject);
	    (void) ll_log (fred_log, LLOG_NOTICE, NULLCP, "%s asks: %s",
			   ep, buffer);

	    bzero ((char *) vec, sizeof vec);
	    if (str2vec (buffer, vec) < 1)
		(void) f_help (NULLVP);
	    else
		if (fredloop (vec, NOTOK) != OK)
		    status = 1;
	}
	else {
	    int	    didone = 0;

	    while ((c = getc (stdin)) != EOF)
		if (c != ' ' || c != '\t' || c != '\n')
		    break;

	    if (c != EOF)
		while (fgets (buffer, sizeof buffer, stdin)) {
		    if (cp = index (buffer, '\n'))
			*cp = NULL;
		    if (buffer[0] == NULL)
			break;

		    (void) ll_log (fred_log, LLOG_NOTICE, NULLCP,
				   "%s asks: %s", ep, buffer);

		    fprintf (stdfp, "%s>>> %s\n", didone ? "\n\n" : "", buffer);

		    bzero ((char *) vec, sizeof vec);
		    if (str2vec (buffer, vec) < 1)
			break;

		    if (fredloop (vec, NOTOK) != OK) {
			status = 1;
			break;
		    }
		    didone = 1;
		}

	    if (!didone)
		(void) f_help (NULLVP);
	}

	(void) fclose (fp);

	stdfp = stdout;

	goto were_out_of_here;
    }

    if (network) {
	int    len;

	if (getpeername (fileno (stdin), (struct sockaddr *) isock,
			 (len = sizeof *isock, &len)) != NOTOK) {
	    (void) sprintf (address, "%s/%d",
			    inet_ntoa (isock -> sin_addr),
			    ntohs (isock -> sin_port));

	    rcmap (isock);
	}
	else {
	    (void) ll_log (fred_log, LLOG_EXCEPTIONS, "failed", "getpeername");
	    (void) strcpy (address, "peer");
	}
    }
    else
	{
	    register struct hostent *hp;

	    (void) strcpy (address, getlocalhost ());

	    if (hp = gethostbystring (address)) {
		bzero ((char *) isock, sizeof *isock);
		isock -> sin_family = hp -> h_addrtype;
		inaddr_copy (hp, isock);
		rcmap (isock);
	    }
	    else
		advise (NULLCP, "%s: unknown host", address);

	}

    if (!fflag) {
	(void) sprintf (buffer, "%s/.fredrc", myhome);
	rcfile (buffer, op ? 1 : 0, 0);
    }

    if (f_bind (NULLVP) == NOTOK)
	adios (NULLCP, "unable to open the white pages");

    if (network) {
	errfp = stdout;

	switch (fetchline (buffer, sizeof buffer, stdin)) {
	    case NOTOK:
	        adios (NULLCP, "error reading query from %s", address);
		/* NOTREACHED */

	    case DONE:
	        buffer[0] = NULL;
		/* and fall... */

	    case OK:
	    default:
	        break;
	}
	if (cp = index (buffer, '\r'))
	    *cp = NULL;
	if (cp = index (buffer, '\n'))
	    *cp = NULL;

	(void) ll_log (fred_log, LLOG_NOTICE, NULLCP, "%s asks: %s",
		       address, buffer);

	bzero ((char *) vec, sizeof vec);
	if (str2vec (buffer, vec) < 1)
	    (void) f_help (NULLVP);
	else
	    if (fredloop (vec, NOTOK) != OK)
		status = 1;

	goto were_out_of_here;
    }

    if (op) {
	vecp = 0;
	if (strcmp (myname, "whois") == 0)
	    vec[vecp++] = myname;
	while (*op)
	    vec[vecp++] = *op++;
	vec[vecp] = NULL;

	if (fredloop (vec, NOTOK) != NOTOK)
	    status = 1;

	goto were_out_of_here;
    }

    istat = signal (SIGINT, intrser);

    eof = 0;
    for (interrupted = 0;; interrupted = 0) {
	if (alarming) {
	    astat = signal (SIGALRM, alrmser);

	    switch (setjmp (alrmenv)) {
		case OK:
		    (void) alarm ((unsigned) 300);
		    break;

		default:
		    adios (NULLCP, "timed out due to inactivity");
	    }
	}

	if ((usetty ? getline ("%s> ", buffer) : readline (buffer)) == NOTOK) {
	    if (eof)
		break;

	    eof = 1;
	    continue;
	}
	eof = 0;

	if (alarming)
	    (void) alarm ((unsigned) 0);

	if (logging)
	    (void) ll_log (fred_log, LLOG_NOTICE, NULLCP, "command: %s",
			   buffer);

	bzero ((char *) vec, sizeof vec);
	if ((vecp = str2vec (buffer, vec)) < 1)
	    continue;

	switch (fredloop (vec, OK)) {
	    case NOTOK:
	        status = 1;
		break;

	    case OK:
	    default:
		continue;

	    case DONE:
		status = 0;
		break;
	}
	break;
    }

    (void) signal (SIGINT, istat);

were_out_of_here: ;
    (void) f_quit (NULLVP);

    exit (mail ? 0 : status);		/* NOTREACHED */
}

/* \f

   ARGINIT */

static	arginit (vec)
char  **vec;
{
    register char  *ap,
		   *pp;

    if (myname = rindex (*vec, '/'))
	myname++;
    if (myname == NULL || *myname == NULL)
	myname = *vec;

    if (strcmp (myname, "in.whitepages") == 0)
	network++, fflag++;

    isodetailor (myname, 1);
    ll_hdinit (fred_log, myname);

    if (ontty = isatty (fileno (stdin)))
	verbose++;
    oneshot = 0;

    for (vec++; ap = *vec; vec++) {
	if (*ap == '-') {
	    while (*++ap)
		switch (*ap) {
		    case 'a':
			alarming++;
			break;

		    case 'd':
		        debug++;
			break;

		    case 'm':
		        mail++;
			/* and fall... */

		    case 'n':
		        network++;
			/* and fall... */

		    case 'f':
		        fflag++;
			break;

		    case 'k':
		        kflag++;
			break;

		    case 'l':
			logging++;
			break;

		    case 'r':
			readonly++;
			pager = "internal";
			break;

		    case 'v':
		        verbose++;
			break;

		    case 'w':
		        watch++;
			break;

		    case 'q':
			if ((pp = *++vec) == NULL
				|| sscanf (pp, "%d %d", &ifd, &ofd) != 2)
			    adios (NULLCP, "usage: %s -q fd-pair", myname);
			usetty = 0;
			break;
			
		    default:
			adios (NULLCP, "unknown switch -%c", *ap);
		}
	    continue;
	}
	if (op == NULL) {
	    op = vec;
	    oneshot = 1;
	    break;
	}
    }

    if (debug)
	ll_dbinit (fred_log, myname);
    if (logging)
	log_utmp ();
}

/* \f

   INTERACTIVE */

int	getline (prompt, buffer)
char   *prompt,
       *buffer;
{
    register int    i;
    register char  *cp,
                   *ep;
    static int  sticky = 0;

    if (interrupted) {
	interrupted = 0;
	return NOTOK;
    }

    if (sticky) {
	sticky = 0;
	return NOTOK;
    }

    switch (setjmp (intrenv)) {
	case OK:
	    armed++;
	    break;

	case NOTOK:
	    if (ontty)
		printf ("\n");	/* and fall */
	default:
	    armed = 0;
	    return NOTOK;
    }
	
    if (ontty) {
	printf (prompt, myname);
	(void) fflush (stdout);
    }

    for (ep = (cp = buffer) + BUFSIZ - 1; (i = getchar ()) != '\n';) {
	if (i == EOF) {
	    if (ontty)
		printf ("\n");
	    clearerr (stdin);
	    if (cp == buffer)
		longjmp (intrenv, DONE);

	    sticky++;
	    break;
	}

	if (cp < ep)
	    *cp++ = i;
    }
    *cp = NULL;

    armed = 0;
    
    return OK;
}

/* \f

 */

static	readline (buffer)
char   *buffer;
{
    register int    i;
    register char  *bp,
		   *cp,
		   *ep;

    (void) signal (SIGINT, istat);
    (void) signal (SIGQUIT, qstat);

    ep = (bp = buffer) + BUFSIZ - 1;

    (void) strcpy (bp, "whois ");
    bp += strlen (bp);
    while ((i = read (ifd, bp, ep - bp)) > 0) {
	for (cp = bp + i; bp < cp; bp++)
	    if (*bp == '\n')
		break;
	if (bp < cp)
	    break;
    }
    if (i == NOTOK)
	adios ("failed", "read from pipe");
    if (i == 0)
	exit (0);
    *bp = NULL;

    if (watch) {
	fprintf (stderr, "<--- %s\n", buffer);
	(void) fflush (stderr);
    }

    usetty = 1;

    return OK;
}

/* \f

 */

#ifndef	IAC
#define	IAC	255
#endif


static int  fetchline (s, n, iop)
register char  *s;
register int	n;
register FILE  *iop;
{
    register int    c;
    register char  *p;

    p = s;
    while (--n > 0 && (c = getc (iop)) != EOF) {
	while (c == IAC) {
	    (void) getc (iop);
	    c = getc (iop);
	}
	if ((*p++ = c) == '\n')
	    break;
    }
    if (ferror (iop))
	return NOTOK;
    if (c == EOF && p == s)
	return DONE;
    *p++ = NULL;

    return OK;
}

/* \f

 */

/* ARGSUSED */

static	SFD alrmser (sig)
int	sig;
{
#ifndef	BSDSIGS
    (void) signal (SIGALRM, alrmser);
#endif

    longjmp (alrmenv, NOTOK);
}

/* \f

 */

/* ARGSUSED */

static	SFD intrser (sig)
int	sig;
{
#ifndef	BSDSIGS
    (void) signal (SIGINT, intrser);
#endif

    if (armed)
	longjmp (intrenv, NOTOK);

    interrupted++;
}

/* \f

 */

#ifndef	lint
int	ask (va_alist)
va_dcl
{
    int     x,
            y,
            result;
    char    buffer[BUFSIZ];
    va_list ap;

    if (interrupted) {
	interrupted = 0;
	return NOTOK;
    }

    if (!ontty)
	return OK;

    switch (setjmp (intrenv)) {
	case OK: 
	    armed++;
	    break;

	case NOTOK: 
	default: 
	    printf ("\n");
	    armed = 0;
	    return DONE;
    }

    va_start (ap);

    _asprintf (buffer, NULLCP, ap);

    va_end (ap);
    
again: ;
    printf ("%s? (y)es, (n)o: ", buffer);

    x = y = getchar ();
    while (y != '\n' && y != EOF)
	y = getchar ();

    switch (x) {
	case 'y': 
	case '\n':
	    result = OK;
	    break;

	case 'n': 
	    result = NOTOK;
	    break;

	case EOF: 
	    result = DONE;
	    break;

	default: 
	    goto again;
    }

    armed = 0;

    return result;
}
#else
/* VARARGS */

int	ask (fmt)
char   *fmt;
{
    return ask (fmt);
}
#endif

/* \f

   MAPPING */

/* reads fred's IP-address to DN mapping file.

   for environments like Rutgers where IP-addresses can be more or less
   trusted, this allows an easy mechanism for mapping local Rutgers users into
   some DN other than the NULL user

   Syntax:

   	<addrmask>	<netaddr>	<dn>	<password>

	Each token is seperated by LWSP, though double-quotes may be used to
	prevent separation.

 */

static	rcmap (isock)
struct sockaddr_in *isock;
{
    u_long	hostaddr,
		netmask,
		netaddr;
    register char *cp;
    char    buffer[BUFSIZ + 1],
	   *vec[NVEC + 1];
    FILE   *fp;

    if ((fp = fopen (isodefile ("fredmap", 0), "r")) == NULL)
	goto done;

    hostaddr = isock -> sin_addr.s_addr;

    while (fgets (buffer, sizeof buffer, fp)) {
	if (*buffer == '#')
	    continue;
	if (cp = index (buffer, '\n'))
	    *cp = NULL;
	bzero ((char *) vec, sizeof vec);
	if (str2vec (buffer, vec) != 4)
	    continue;
	if ((netmask = inet_network (vec[0])) == NOTOK)
	    continue;
	if ((netaddr = inet_network (vec[1])) == NOTOK)
	    continue;
	if ((hostaddr & netmask) != netaddr)
	    continue;

	vec[1] = "thisis";

	runcom = 1, rcmode = 0400;
	if (f_thisis (vec + 1) == NOTOK)
	    adios (NULLCP, "unable to bind as %s for %s",
		   vec[2], inet_ntoa (isock -> sin_addr));

	runcom = 0;
	break;
    }

    (void) fclose (fp);

done: ;
    (void) setgid (getgid ());
    (void) setuid (getuid ());
}

/* \f

   ERRORS */

#ifndef	lint
void	_advise ();


void	adios (va_alist)
va_dcl
{
    va_list ap;

    va_start (ap);

    if (network)
	(void) _ll_log (fred_log, LLOG_FATAL, ap);

    _advise (ap);

    va_end (ap);

    (void) f_quit (NULLVP);

    _exit (1);
}
#else
/* VARARGS */

void	adios (what, fmt)
char   *what,
       *fmt;
{
    adios (what, fmt);
}
#endif


#ifndef	lint
void	advise (va_alist)
va_dcl
{
    va_list ap;

    va_start (ap);

    _advise (ap);

    va_end (ap);
}


static void  _advise (ap)
va_list	ap;
{
    char    buffer[BUFSIZ];
    FILE   *fp = network ? stdfp : stderr;

    asprintf (buffer, ap);

    (void) fflush (stdfp);

    fprintf (fp, "%s: ", myname);
    (void) fputs (buffer, fp);
    (void) fputs (EOLN, fp);

    (void) fflush (fp);
}
#else
/* VARARGS */

void	advise (what, fmt)
char   *what,
       *fmt;
{
    advise (what, fmt);
}
#endif

/* \f

   MISCELLANY */

#ifndef	lint
char   *strdup (s)
char   *s;
{
    char    *p;

    if ((p = malloc((unsigned) (strlen (s) + 1))) == NULL)
	adios (NULLCP, "out of memory");

    (void) strcpy (p, s);

    return p;
}
#endif

/* \f

 */

#include <utmp.h>

#ifdef	sun
#define	BSD42
#undef	SYS5
#endif

#ifdef	bsd43_ut_host
#undef	BSD42
#define	SYS5
#endif

#ifdef	BSD42
#define	HMAX	(sizeof (ut -> ut_host))
#endif
#define	LMAX	(sizeof (ut -> ut_line))
#define	NMAX	(sizeof (ut -> ut_name))

#define SCPYN(a, b)	strncpy(a, b, sizeof (a))
#define SCMPN(a, b)	strncmp(a, b, sizeof (a))


#ifdef	SYS5
struct utmp *getutent ();
#endif

char *ttyname ();


static	log_utmp () {
#ifndef	SYS5
    int	    ud;
#endif
    char   *line;
    struct utmp uts;
    register struct utmp *ut = &uts;

    if ((line = ttyname (fileno (stdin))) == NULL)
	return;
    if (strncmp (line, "/dev/", sizeof "/dev/" - 1) == 0)
	line += sizeof "/dev/" - 1;
#ifndef	SYS5
    if ((ud = open ("/etc/utmp", 0)) == NOTOK)
	return;
    while (read (ud, (char *) ut, sizeof *ut) == sizeof *ut) {
	if (ut -> ut_name[0] == NULL || SCMPN (ut -> ut_line, line))
	    continue;
#ifndef	BSD42
	(void) ll_log (fred_log, LLOG_NOTICE, NULLCP, "%.*s on %.*s",
		       NMAX, ut -> ut_name, LMAX, ut -> ut_line);
#else
	(void) ll_log (fred_log, LLOG_NOTICE, NULLCP,
		       "%.*s on %.*s (%.*s)",
		       NMAX, ut -> ut_name, LMAX, ut -> ut_line,
		       HMAX, ut -> ut_host);
#endif
	break;
    }
    (void) close (ud);
#else
    setutent ();
    while (ut = getutent ()) {
	if (ut -> ut_type != USER_PROCESS || SCMPN (ut -> ut_line, line))
	    continue;
	
	(void) ll_log (fred_log, LLOG_NOTICE, NULLCP, "%.*s on %.*s",
		       NMAX, ut -> ut_name, LMAX, ut -> ut_line);
	break;
    }
    endutent ();
#endif
}


#ifdef	bsd43_ut_host
#define	BSD42
#undef	SYS5
#endif