|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T f
Length: 16550 (0x40a6)
Types: TextFile
Names: »fred.c«
└─⟦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«
/* 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