|
|
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 r
Length: 6718 (0x1a3e)
Types: TextFile
Names: »rcvtty.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦3658e588a⟧ »EurOpenD3/mail/mh/mh-6.7.tar.Z«
└─⟦c75e36ecb⟧
└─⟦this⟧ »mh-6.7/uip/rcvtty.c«
/* rcvtty.c - a rcvmail program (a lot like rcvalert) handling IPC ttys */
#ifndef lint
static char ident[] = "@(#)$Id: rcvtty.c,v 1.5 90/04/05 15:02:11 sources Exp $";
#endif lint
#ifndef BSD42
#undef TTYD
#endif
#include "../h/mh.h"
#include "../h/rcvmail.h"
#include "../h/scansbr.h"
#include "../zotnet/tws.h"
#include <signal.h>
#include <sys/stat.h>
#ifndef TTYD
#include <utmp.h>
#endif not TTYD
/* \f
*/
#define SCANFMT \
"%2(hour{dtimenow}):%02(min{dtimenow}): %5(size) %<{encrypted}E%>\
%<(mymbox{from})To:%14(friendly{to})%|%17(friendly{from})%> \
%{subject}%<{body}<<%{body}>>%>"
static struct swit switches[] = {
#define HELPSW 0
"help", 4,
#define BIFFSW 1
"biff", 0,
#define FORMSW 2
"form formatfile", 0,
#define FMTSW 3
"format string", 5,
#define NLSW 4
"newline", 0,
#define NNLSW 5
"nonewline", 0,
#define BELSW 6
"bell", 0,
#define NBELSW 7
"nobell", 0,
NULL, NULL
};
/* \f
*/
static jmp_buf myctx;
long lseek ();
char *getusr ();
static int message_fd(), header_fd();
static alert();
static int bell = 1;
static int newline = 1;
static int biff = 0;
static char *form = NULL;
static char *format = NULL;
/* \f
*/
/* ARGSUSED */
main (argc, argv)
int argc;
char **argv;
{
int md,
vecp = 0;
char *cp,
*user,
buf[100],
**ap,
**argp,
*arguments[MAXARGS],
*vec[MAXARGS];
#ifndef TTYD
char tty[BUFSIZ];
struct utmp ut;
register FILE *uf;
#endif not TTYD
invo_name = r1bindex (argv[0], '/');
mts_init (invo_name);
if ((cp = m_find (invo_name)) != NULL) {
ap = brkstring (cp = getcpy (cp), " ", "\n");
ap = copyip (ap, arguments);
}
else
ap = arguments;
(void) copyip (argv + 1, ap);
argp = arguments;
/* \f
*/
while (cp = *argp++) {
if (*cp == '-')
switch (smatch (++cp, switches)) {
case AMBIGSW:
ambigsw (cp, switches);
done (1);
case UNKWNSW:
vec[vecp++] = --cp;
continue;
case HELPSW:
(void) sprintf (buf, "%s [command ...]", invo_name);
help (buf, switches);
done (1);
case BIFFSW:
biff = 1;
continue;
case FORMSW:
if (!(form = *argp++) || *form == '-')
adios (NULLCP, "missing argument to %s", argp[-2]);
format = NULL;
continue;
case FMTSW:
if (!(format = *argp++) || *format == '-')
adios (NULLCP, "missing argument to %s", argp[-2]);
form = NULL;
continue;
case NLSW:
newline = 1;
continue;
case NNLSW:
newline = 0;
continue;
case BELSW:
bell = 1;
continue;
case NBELSW:
bell = 0;
continue;
}
vec[vecp++] = cp;
}
vec[vecp] = 0;
/* \f
*/
if ((md = vecp ? message_fd (vec) : header_fd ()) == NOTOK)
exit (RCV_MBX);
user = getusr ();
#ifndef TTYD
if ((uf = fopen ("/etc/utmp", "r")) == NULL)
exit (RCV_MBX);
while (fread ((char *) &ut, sizeof ut, 1, uf) == 1)
if (ut.ut_name[0] != NULL
&& strncmp (user, ut.ut_name, sizeof ut.ut_name) == 0) {
(void) strncpy (tty, ut.ut_line, sizeof ut.ut_line);
alert (tty, md);
}
(void) fclose (uf);
#else TTYD
alert (user, md);
#endif TTYD
exit (RCV_MOK);
}
/* \f
*/
/* ARGSUSED */
static int alrmser (i)
int i;
{
longjmp (myctx, DONE);
}
static int message_fd (vec)
char *vec[];
{
int bytes,
child_id,
fd;
char tmpfil[BUFSIZ];
struct stat st;
(void) unlink (mktemp (strcpy (tmpfil, "/tmp/rcvttyXXXXX")));
if ((fd = creat (tmpfil, 0600)) == NOTOK)
return header_fd ();
(void) close (fd);
if ((fd = open (tmpfil, 2)) == NOTOK)
return header_fd ();
(void) unlink (tmpfil);
/* \f
*/
switch (child_id = vfork ()) {
case NOTOK:
(void) close (fd);
return header_fd ();
case OK:
rewind (stdin);
if (dup2 (fd, 1) == NOTOK || dup2 (fd, 2) == NOTOK)
_exit (-1);
closefds (3);
#ifdef BSD42
(void) setpgrp (0, getpid ());
#endif BSD42
execvp (vec[0], vec);
_exit (-1);
default:
switch (setjmp (myctx)) {
case OK:
(void) signal (SIGALRM, alrmser);
bytes = fstat (fileno (stdin), &st) != NOTOK
? (int) st.st_size : 100;
if (bytes <= 0)
bytes = 100;
(void) alarm ((unsigned) (bytes * 60 + 300));
(void) pidwait (child_id, OK);
(void) alarm (0);
if (fstat (fd, &st) != NOTOK && st.st_size > 0L)
return fd;
(void) close (fd);
return header_fd ();
default:
#ifndef BSD42
(void) kill (child_id, SIGKILL);
#else BSD42
(void) killpg (child_id, SIGKILL);
#endif BSD42
(void) close (fd);
return header_fd ();
}
}
}
/* \f
*/
static int header_fd () {
int fd;
char tmpfil[BUFSIZ];
(void) strcpy (tmpfil, m_tmpfil (invo_name));
if ((fd = creat (tmpfil, 0600)) == NOTOK)
return NOTOK;
(void) close (fd);
if ((fd = open (tmpfil, 2)) == NOTOK)
return NOTOK;
(void) unlink (tmpfil);
rewind (stdin);
(void) scan (stdin, 0, 0, new_fs (form, format, SCANFMT), 0, 0, 0, 0L, 0);
if ( newline )
(void) write (fd, "\n\r", 2);
(void) write (fd, scanl, strlen (scanl));
if ( bell )
(void) write (fd, "\007", 1);
return fd;
}
/* \f
*/
#ifndef TTYD
static alert (tty, md)
char *tty;
int md;
{
int i,
td;
char buffer[BUFSIZ],
ttyspec[BUFSIZ];
struct stat st;
(void) sprintf (ttyspec, "/dev/%s", tty);
if (stat (ttyspec, &st) == NOTOK ||
(st.st_mode & (biff ? S_IEXEC :
#ifdef BSD43
(S_IWRITE >> 3)
#else /* BSD43 */
02
#endif /* BSD43 */
)) == 0)
return;
switch (setjmp (myctx)) {
case OK:
(void) signal (SIGALRM, alrmser);
(void) alarm (2);
td = open (ttyspec, 1);
(void) alarm (0);
if (td == NOTOK)
return;
break;
default:
(void) alarm (0);
return;
}
(void) lseek (md, 0L, 0);
while ((i = read (md, buffer, sizeof buffer)) > 0)
if (write (td, buffer, i) != i)
break;
(void) close (td);
}
#else TTYD
/* \f
*/
static alert (user, md)
register char *user;
int md;
{
int i,
td;
char buffer[BUFSIZ];
if ((td = ttyw ("notify", NULLCP, NULLCP, user)) == NOTOK)
return;
(void) signal (SIGPIPE, SIG_IGN);
(void) lseek (md, 0L, 0);
while ((i = read (md, buffer, sizeof buffer)) > 0)
if (write (td, buffer, i) != i)
break;
(void) close (td);
}
#endif TTYD