home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume3
/
activ
/
activ.c
next >
Wrap
C/C++ Source or Header
|
1989-02-03
|
5KB
|
357 lines
/*
** ACTIV -- keep an activioty typescript.
** whenever the user types, will prepend the time if the typein has been
** quiet for more than Interval, which defaults to 20 secs, but may be
** overridden with -i flag. If over two hours, pust the entire time and
** date out. Copies to a file.
**
** Useage:
** activ [-i interval] file
**
** History:
** 6/23/88 -- (marc) documented
**
*/
# include <stdio.h>
# include <sgtty.h>
# include <signal.h>
# include <time.h>
# include <errno.h>
# include <ctype.h>
# define MAXLINE 350
struct sgttyb Ogttyb;
char Erasec, Eofc, Killc, Wordc;
char *Outfile;
FILE *Outf;
main(argc, argv)
{
args(argc, argv);
openFile();
setty();
setend();
dialog();
}
openFile()
{
if (!Outfile)
{
fprintf(stderr, "usage: activ file\n");
exit (-1);
}
if (!(Outf = fopen(Outfile, "a+")))
{
perror(Outfile);
exit (-1);
}
setlinebuf(Outfile);
}
setty()
{
struct sgttyb ngttyb;
struct tchars tchars;
struct ltchars lchars;
/* set cbreak mode */
ioctl(0, TIOCGETP, &Ogttyb);
ngttyb = Ogttyb;
ngttyb.sg_flags |= CBREAK;
ngttyb.sg_flags &= ~ECHO;
ioctl(0, TIOCSETP, &ngttyb);
/* set editting characters */
ioctl(0, TIOCGETC, &tchars);
Eofc = tchars.t_eofc;
ioctl(0, TIOCGLTC, &lchars);
Wordc = lchars.t_werasc;
Erasec = Ogttyb.sg_erase;
Killc = Ogttyb.sg_kill;
}
setend()
{
int endIt();
/* ensure that upon SIGINT, we dump things, and close the
* file
*/
signal(SIGINT, endIt);
}
endIt()
{
/* close file, reset tty mode to original mode */
fclose(Outf);
ioctl(0, TIOCSETP, &Ogttyb);
exit (0);
}
dialog()
{
for (;;)
{
await_inp();
fill_line();
}
}
await_inp()
{
int fdt;
int err;
extern errno;
for (;;)
{
fdt = 1 << 0;
err = select(32, &fdt, NULL, NULL, NULL);
if (err != -1)
return;
if (errno != EINTR)
perror("select");
}
}
# define INTERVAL 20
char EntireLine[MAXLINE];
int LineBegin;
int OutCol;
int EdittedLine;
int ShownTill = 0;
int FirstCharOnLine = 1;
char Line[MAXLINE];
long LastTime;
long ThisTime;
int Interval = INTERVAL;
int EofIn;
fill_line()
{
gettime();
get_any(Line, sizeof Line);
if (gt_interval())
FirstCharOnLine = 1;
if (FirstCharOnLine)
{
dumpline();
newline();
}
add_to_line(Line);
line_edit(); /* edit and echo. */
if (completeline())
{
dumpline();
}
if (eof_reached())
{
endIt();
/*NOTREACHED*/
}
}
gettime()
{
ThisTime = time(NULL);
}
gt_interval()
{
long t = time(0);
return (t - LastTime > Interval);
}
dumpline()
{
int n = strlen(EntireLine);
fputs(EntireLine, Outf);
if (n != 0 && EntireLine[n-1] != '\n')
{
putc('\n', stdout);
putc('\n', Outf);
}
EntireLine[0] = 0;
EdittedLine = 0;
LineBegin = 0;
OutCol = 0;
fflush(Outf);
}
add_to_line(s)
char *s;
{
strcat(EntireLine, s);
}
newline()
{
struct tm *tm;
char data[40];
char *timestring;
char *ctime();
struct tm *localtime();
char *s;
if (ThisTime - LastTime >= 2 * 60 * 60)
{
s = ctime(&ThisTime);
s[strlen(s) - 1] = 0; /* get rid of final newline */
sprintf(data, "[%s] ", s);
}
else
{
tm = localtime(&ThisTime);
sprintf(data, "[%02d:%02d:%02d] ", tm->tm_hour, tm->tm_min,
tm->tm_sec);
s = data;
}
add_to_line(data);
LineBegin = strlen(EntireLine);
EdittedLine = LineBegin;
OutCol = 0;
LastTime = ThisTime;
fputs(data, stdout);
fflush(stdout);
}
line_edit()
{
char *i, *o;
for (i = &EntireLine[EdittedLine], o = i;
*i; i++)
{
if (*i == Killc)
{
o = &EntireLine[LineBegin];
EdittedLine = LineBegin;
erase_col(OutCol);
OutCol = 0;
}
else if (*i == Erasec)
{
--o;
if (OutCol > 0)
{
OutCol--;
EdittedLine--;
erase_col(1);
}
} else if (*i == Wordc)
{
if (OutCol <= 0)
continue;
/* skip initial spaces */
if (isspace(o[-1]))
{
while (OutCol > 0 && isspace(*--o))
{
OutCol--;
EdittedLine--;
erase_col(1);
}
if (OutCol != 0)
o++;
}
/* skip word */
while (OutCol > 0 && !isspace(*--o))
{
OutCol--;
EdittedLine--;
erase_col(1);
}
if (OutCol != 0)
o++;
}
else if (*i == Eofc)
{
EofIn++;
break;
}
else if (isgraph(*i) || isspace(*i))
{
*o++ = *i;
EdittedLine++;
OutCol++;
if (*i == '\n')
{
*i = 0;
*--o = 0;
dumpline();
/* continue till end */
line_edit();
}
else
putchar(*i);
}
else
{
/* can't map the file output because doing it in place,
* but can map the tty output, though i'll be confused
* backspaceing!
*/
EdittedLine += 1;
OutCol += 2;
putchar('^');
putchar(*i | 0100);
*o++ = *i;
}
}
*o = 0;
fflush(stdout);
LastTime = ThisTime;
FirstCharOnLine = 0;
}
completeline()
{
return (EntireLine[strlen(EntireLine) - 1] == '\n');
}
eof_reached()
{
return (EofIn);
}
erase_col(i)
{
while (--i >= 0)
fputs("\b \b", stdout);
fflush(stdout);
}
get_any(buf, size)
char *buf;
int size;
{
int n;
n = read(0, buf, size);
if (n > 0)
buf[n] = 0;
}
args(argc, argv)
int argc;
char **argv;
{
int i;
for (argv++; *argv; argv++)
{
if (**argv != '-')
Outfile = *argv;
else switch ((*argv)[1])
{
case 'i': /* set interval */
if (!argv[1])
break;
i = atoi(*++argv);
if (i > 0)
Interval = i;
break;
case '?':
fprintf(stderr, "usage: activ [-i interval] file\n");
break;
default:
fprintf(stderr, "activ: unknown flag `%s'\n",
*argv);
}
}
}