spy.c
/*
Marcus Ranum 1985
usage: spy &
the program will exit cleanly when you log out.
*/
#include
#include
#include
#include
#include
#include
#include
/*
* Defines to work around System V
* lameness. sysvreallydoessux.
*/
#define bcopy(s1, s2, len) memcpy(s2, s1, len)
#define index(s, c) strchr(s, c)
#define rindex(s, c) strrchr(s, c)
#define bzero(s, len) memset(s, 0, len)
#define bcmp(s1, s2, len) (memcmp(s1, s2, len)!=0)
#define WAITIME 5
#define USIZ (sizeof(struct utmp))
extern char *malloc();
extern char *realloc();
extern off_t lseek();
static void
szprint(s,max)
char *s;
int max;
{
/* catch the bastard even if they put esc. codes in ! */
while(max-- && *s != '\0')
if(isprint(*s))
(void)fprintf(stderr,"%c",*s++);
else
(void)fprintf(stderr,"(0x%X)",*s++);
}
static void
notify(old,new)
struct utmp *old;
struct utmp *new;
{
char *op;
struct utmp *u;
u=new;
op="in";
if(new->ut_name[0] == '\0') {
u = old;
op = "out";
}
szprint(u->ut_name,sizeof(u->ut_name));
if(u->ut_line[0] != '\0') {
(void)fprintf(stderr,"@");
szprint(u->ut_line,sizeof(u->ut_line));
}
(void)fprintf(stderr," (");
szprint(u->ut_line,sizeof(u->ut_line));
(void)fprintf(stderr,") logged %s\n",op);
}
main()
{
time_t m_time;
int utfd;
struct utmp *up;
struct utmp ubuf;
int upsiz;
struct stat sbuf;
if(stat(UTMP_FILE,&sbuf) != 0 || (utfd = open(UTMP_FILE,O_RDONLY)) < 0) {
perror(UTMP_FILE);
exit(1);
}
m_time = sbuf.st_mtime;
if((up = (struct utmp *)malloc((unsigned)sbuf.st_size)) == NULL) {
perror("malloc utmp buffer");
exit(1);
}
upsiz = sbuf.st_size;
if(read(utfd,(char *)up,(int)sbuf.st_size) != sbuf.st_size) {
(void)fprintf(stderr,"read %ld bytes from ",sbuf.st_size);
perror(UTMP_FILE);
exit(1);
}
while(1) {
if(getppid() == 1)
exit(0);
(void)sleep(WAITIME);
if(stat(UTMP_FILE,&sbuf) < 0) {
perror(UTMP_FILE);
exit(1);
}
if(upsiz < sbuf.st_size) {
up = (struct utmp *)realloc((char *)up,(unsigned)sbuf.st_size);
if(up == NULL) {
perror("realloc utmp buffer");
exit(1);
}
upsiz = sbuf.st_size;
}
if(sbuf.st_mtime != m_time) {
int i;
if(lseek(utfd,0L,0) != 0L)
continue;
for(i = 0; i < sbuf.st_size / USIZ; i++) {
if(read(utfd,(char *)&ubuf,USIZ) != USIZ)
continue;
if(bcmp((char *)&up[i],(char *)&ubuf,USIZ)) {
notify(&up[i],&ubuf);
(void)bcopy((char *)&ubuf,(char *)&up[i],USIZ);
}
}
m_time = sbuf.st_mtime;
}
}
}
Go BACK!