|
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