[comp.sources.misc] v03i062: program for keeping timed transcript for activity logs

marc@uunet.uu.net@tss.UUCP (Marc Meyer) (06/25/88)

comp.sources.misc: Volume 3, Issue 62
Submitted-By: "Marc Meyer" <marc@uunet.uu.net@tss.UUCP>
Archive-Name: activ

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README activ.c
# Wrapped by marc@alcatraz on Fri Jun 24 14:13:08 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(449 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X/*
X**  ACTIV -- keep an activity typescript.
X**	whenever the user types, will prepend the time if the typein has been
X**	quiet for more than Interval, which defaults to 20 secs, but may be 
X**	overridden with -i flag.  If over two hours, pust the entire time and 
X**	date out.  Copies to a file.
X**
X**	Useage:
X**		activ [-i interval] file
X**
X**	Compilation:
X**		make activ -- no Makefile needed
X**
X**	History:
X**		6/23/88 -- (marc) documented
X**
X*/
END_OF_FILE
if test 449 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'activ.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'activ.c'\"
else
echo shar: Extracting \"'activ.c'\" \(5423 characters\)
sed "s/^X//" >'activ.c' <<'END_OF_FILE'
X
X/*
X**  ACTIV -- keep an activioty typescript.
X**	whenever the user types, will prepend the time if the typein has been
X**	quiet for more than Interval, which defaults to 20 secs, but may be 
X**	overridden with -i flag.  If over two hours, pust the entire time and 
X**	date out.  Copies to a file.
X**
X**	Useage:
X**		activ [-i interval] file
X**
X**	History:
X**		6/23/88 -- (marc) documented
X**
X*/
X
X# include	<stdio.h>
X# include	<sgtty.h>
X# include	<signal.h>
X# include	<time.h>
X# include	<errno.h>
X# include	<ctype.h>
X
X# define	MAXLINE	 	350
X
Xstruct sgttyb	Ogttyb;
Xchar		Erasec, Eofc, Killc, Wordc;
Xchar		*Outfile;
XFILE		*Outf;
X
Xmain(argc, argv)
X{
X	args(argc, argv);
X	openFile();
X	setty();
X	setend();
X	dialog();
X}
X
XopenFile()
X{
X	if (!Outfile)
X	{
X		fprintf(stderr, "usage: activ file\n");
X		exit (-1);
X	}
X	if (!(Outf = fopen(Outfile, "a+")))
X	{
X		perror(Outfile);
X		exit (-1);
X	}
X	setlinebuf(Outfile);
X}
Xsetty()
X{
X	struct sgttyb	ngttyb;
X	struct tchars	tchars;
X	struct ltchars	lchars;
X
X	/* set cbreak mode */
X	ioctl(0, TIOCGETP, &Ogttyb);
X	ngttyb = Ogttyb;
X	ngttyb.sg_flags |= CBREAK;
X	ngttyb.sg_flags &= ~ECHO;
X
X	ioctl(0, TIOCSETP, &ngttyb);
X	/* set editting characters */
X	ioctl(0, TIOCGETC, &tchars);
X	Eofc = tchars.t_eofc;
X	ioctl(0, TIOCGLTC, &lchars);
X	Wordc = lchars.t_werasc;
X
X	Erasec = Ogttyb.sg_erase;
X	Killc = Ogttyb.sg_kill;
X}
Xsetend()
X{
X	int	endIt();
X
X	/* ensure that upon SIGINT, we dump things, and close the
X	 * file 
X	 */
X	signal(SIGINT, endIt);
X}
XendIt()
X{
X	/* close file, reset tty mode to original mode */
X	fclose(Outf);
X	ioctl(0, TIOCSETP, &Ogttyb);
X	exit (0);
X}
Xdialog()
X{
X	for (;;)
X	{
X		await_inp();
X		fill_line();
X	}
X}
Xawait_inp()
X{
X	int	fdt;
X	int	err;
X	extern	errno;
X
X	for (;;)
X	{
X		fdt = 1 << 0;
X		err = select(32, &fdt, NULL, NULL, NULL);
X		if (err != -1)
X			return;
X		if (errno != EINTR)
X			perror("select");
X	}
X}
X
X# define	INTERVAL	20
X
Xchar	EntireLine[MAXLINE];
Xint	LineBegin;
Xint	OutCol;
Xint	EdittedLine;
Xint	ShownTill = 0;
Xint	FirstCharOnLine = 1;
Xchar	Line[MAXLINE];
Xlong	LastTime;
Xlong	ThisTime;
Xint	Interval = INTERVAL;
Xint	EofIn;
X
Xfill_line()
X{
X	gettime();
X	get_any(Line, sizeof Line);
X	if (gt_interval())
X		FirstCharOnLine = 1;
X	if (FirstCharOnLine)
X	{
X		dumpline();
X		newline();
X	}
X	add_to_line(Line);
X	line_edit();		/* edit and echo. */
X	if (completeline())
X	{
X		dumpline();
X	}
X	if (eof_reached())
X	{
X		endIt();
X		/*NOTREACHED*/
X	}
X}
Xgettime()
X{
X	ThisTime = time(NULL);
X}
Xgt_interval()
X{
X	long	t = time(0);
X
X	return (t - LastTime > Interval);
X}
Xdumpline()
X{
X	int	n = strlen(EntireLine);
X
X	fputs(EntireLine, Outf);
X	if (n != 0 && EntireLine[n-1] != '\n')
X	{
X		putc('\n', stdout);
X		putc('\n', Outf);
X	}
X	EntireLine[0] = 0;
X	EdittedLine = 0;
X	LineBegin = 0;
X	OutCol = 0;
X	fflush(Outf);
X}
Xadd_to_line(s)
Xchar	*s;
X{
X	strcat(EntireLine, s);
X}
Xnewline()
X{
X	struct tm	*tm;
X	char		data[40];
X	char		*timestring;
X	char		*ctime();
X	struct tm	*localtime();
X	char		*s;
X
X	if (ThisTime - LastTime >= 2 * 60 * 60)
X	{
X		s = ctime(&ThisTime);
X		s[strlen(s) - 1] = 0;	/* get rid of final newline */
X		sprintf(data, "[%s] ", s);
X	}
X	else
X	{
X		tm = localtime(&ThisTime);
X		sprintf(data, "[%02d:%02d:%02d] ", tm->tm_hour, tm->tm_min,
X			tm->tm_sec);
X		s = data;
X	}
X	add_to_line(data);
X	LineBegin = strlen(EntireLine);
X	EdittedLine = LineBegin;
X	OutCol = 0;
X	LastTime = ThisTime;
X	fputs(data, stdout);
X	fflush(stdout);
X}
Xline_edit()
X{
X	char	*i, *o;
X
X	for (i = &EntireLine[EdittedLine], o = i;
X		*i; i++)
X	{
X		if (*i == Killc)
X		{
X			o = &EntireLine[LineBegin];
X			EdittedLine = LineBegin;
X			erase_col(OutCol);
X			OutCol = 0;
X		}
X		else if (*i == Erasec)
X		{
X			--o; 
X			if (OutCol > 0)
X			{
X				OutCol--;
X				EdittedLine--;
X				erase_col(1);
X			}
X		} else if (*i == Wordc)
X		{
X			if (OutCol <= 0)
X				continue;
X			/* skip initial spaces */
X			if (isspace(o[-1]))
X			{
X				while (OutCol > 0 && isspace(*--o))
X				{
X					OutCol--;
X					EdittedLine--;
X					erase_col(1);
X				}
X				if (OutCol != 0)
X					o++;
X			}
X			/* skip word */
X			while (OutCol > 0 && !isspace(*--o))
X			{
X				OutCol--;
X				EdittedLine--;
X				erase_col(1);
X			}
X			if (OutCol != 0)
X				o++;
X		}
X		else if (*i == Eofc)
X		{
X			EofIn++;
X			break;
X		}
X		else if (isgraph(*i) || isspace(*i))
X		{
X			*o++ = *i;
X			EdittedLine++;
X			OutCol++;
X			if (*i == '\n')
X			{
X				*i = 0;
X				*--o = 0;
X				dumpline();
X				/* continue till end */
X				line_edit();
X			}
X			else
X				putchar(*i);
X		}
X		else
X		{
X			/* can't map the file output because doing it in place,
X			 * but can map the tty output, though i'll be confused
X			 * backspaceing!
X			 */
X			EdittedLine += 1;
X			OutCol += 2;
X			putchar('^');
X			putchar(*i | 0100);
X			*o++ = *i;
X		}
X	}
X	*o = 0;
X	fflush(stdout);
X	LastTime = ThisTime;
X	FirstCharOnLine = 0;
X}
Xcompleteline()
X{
X	return (EntireLine[strlen(EntireLine) - 1] == '\n');
X}
Xeof_reached()
X{
X	return (EofIn);
X}
Xerase_col(i)
X{
X	while (--i >= 0)
X		fputs("\b \b", stdout);
X	fflush(stdout);
X}
Xget_any(buf, size)
Xchar	*buf;
Xint	size;
X{
X	int	n;
X
X	n = read(0, buf, size);
X	if (n > 0)
X		buf[n] = 0;
X}
Xargs(argc, argv)
Xint	argc;
Xchar	**argv;
X{
X	int	i;
X
X	for (argv++; *argv; argv++)
X	{
X		if (**argv != '-')
X			Outfile = *argv;
X		else switch ((*argv)[1])
X		{
X		  case 'i':	/* set interval */
X			if (!argv[1])
X				break;
X			i = atoi(*++argv);
X			if (i > 0)
X				Interval = i;
X			break;
X
X		  case '?':
X			fprintf(stderr, "usage: activ [-i interval] file\n");
X			break;
X		
X		  default:
X			fprintf(stderr, "activ: unknown flag `%s'\n",
X				*argv);
X		}
X	}
X}
END_OF_FILE
if test 5423 -ne `wc -c <'activ.c'`; then
    echo shar: \"'activ.c'\" unpacked with wrong size!
fi
# end of 'activ.c'
fi
echo shar: End of shell archive.
exit 0