|
|
researchv10 Norman
/*
* Suck up system messages
* dmesg
* print current buffer
* dmesg -
* print and update incremental history
*/
#include <stdio.h>
#include <libc.h>
#include <sys/param.h>
#include <nlist.h>
#include <signal.h>
#include <sys/msgbuf.h>
long msgptr;
struct msgbuf msgbuf;
char *msgbufp;
int sflg;
int wflg;
struct msgbuf omesg;
struct nlist nl[2] = {
{ "_msgbuf" },
{ 0 }
};
#define BUFFER "/usr/adm/msgbuf"
main(argc, argv)
char **argv;
{
int mem;
int timeout();
signal(SIGALRM, timeout);
alarm(60);
if (argc>1 && argv[1][0] == '-') {
sflg++;
switch (argv[1][1]) {
default: /* ugh */
wflg++;
break;
case 'i':
break;
}
argc--;
argv++;
}
if (sflg)
openbuf();
sflg = 0;
timeout("can't read namelist\n");
nlist(argc>2? argv[2]:"/unix", nl);
if (nl[0].n_type==0)
done("No namelist\n");
if ((mem = open((argc>1? argv[1]: "/dev/kmem"), 0)) < 0)
done("No /dev/kmem\n");
lseek(mem, (long)nl[0].n_value, 0);
read(mem, &msgptr, sizeof(msgptr));
lseek(mem, msgptr, 0);
read(mem, &msgbuf, sizeof (msgbuf));
if (msgbuf.msg_magic != MSG_MAGIC)
done("Magic number wrong (namelist mismatch?)\n");
if (bufdiff(&omesg, &msgbuf) == 0)
exit(0);
prdiff(&omesg, &msgbuf);
done((char *)NULL);
}
bufdiff(om, nm)
register struct msgbuf *om, *nm;
{
if (om->msg_bufx != nm->msg_bufx)
return (1);
return (memcmp(om->msg_bufc, nm->msg_bufc, MSG_BSIZE));
}
prdiff(om, nm)
register struct msgbuf *om, *nm;
{
register int ox, nx;
register int c;
if ((ox = om->msg_bufx) < 0 || ox >= MSG_BSIZE)
ox = 0;
if ((nx = nm->msg_bufx) < 0 || nx >= MSG_BSIZE)
nx = 0;
pdate();
/*
* did we lose something?
*/
if (ox < nx) {
if (memcmp(&om->msg_bufc[0], &nm->msg_bufc[0], ox)
|| memcmp(&om->msg_bufc[nx], &nm->msg_bufc[nx], MSG_BSIZE - nx)) {
ox = nx;
printf("...\n");
}
} else if (ox > nx) {
if (memcmp(&om->msg_bufc[ox], &nm->msg_bufc[ox], nx - ox)) {
ox = nx;
printf("...\n");
}
}
/*
* else ox == nx; something might be lost, but assume not
* now print the new part: from ox to nx-1
*/
do {
c = nm->msg_bufc[ox++];
if ((c & 0200) == 0 && c != 0) /* sanity */
putchar(c);
if (ox >= MSG_BSIZE)
ox = 0;
} while (ox != nx);
}
done(s)
char *s;
{
if (s && s!=(char *)omesg.msg_magic && sflg==0) {
pdate();
printf(s);
}
if (wflg) {
wflg = 0;
writebuf();
}
exit(s!=NULL);
}
openbuf()
{
int f;
timeout("can't read buffer file\n");
if ((f = open(BUFFER, 0)) < 0)
return;
if (read(f, (char *)&omesg, sizeof(omesg)) != sizeof(omesg)
|| omesg.msg_magic != MSG_MAGIC)
memset((char *)&omesg, sizeof(omesg), 0);
close(f);
}
writebuf()
{
int f;
timeout("can't write buffer file\n");
if ((f = open(BUFFER, 1)) < 0)
done("can't open buffer\n");
if (write(f, (char *)&msgbuf, sizeof(msgbuf)) != sizeof(msgbuf))
done("error writing buffer\n");
close(f);
}
pdate()
{
extern char *ctime();
static firstime;
time_t tbuf;
if (firstime==0) {
firstime++;
time(&tbuf);
printf("\n%.12s\n", ctime(&tbuf)+4);
}
}
char *terr;
timeout(s)
char *s;
{
extern ttrap();
terr = s;
signal(SIGALRM, ttrap);
alarm(60);
}
ttrap()
{
char buf[100];
sprintf(buf, "timeout: %s", terr);
done(buf);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.