/*
 * John Buck -- 6/83
 * 	Set incore unix file offset (on cronlog or errfile for example) back
 *	to zero.  This because >/usr/adm/cronlog  only zeroes cronlog for
 *	the moment.  The next time cron goes to write there, it will
 *	null pad the file to its previous size THEN write the new info.
 */
#ifndef	REWRITE
#define	MODE	0
#else
#define	MODE	2
#endif
#include	"sys/types.h"
#include	"sys/sysmacros.h"
#include	"sys/param.h"
#include	"sys/stat.h"
#include	"sys/var.h"
#include	"sys/inode.h"
#include	"sys/file.h"

struct	sym	{
	char sy_name[8];
	int  sy_type;
	unsigned sy_value;
} nl[4];

struct	var v;
char	mbuf[5120];

short mem;

main(argc, argv)
char **argv;
{
	register struct file *fp;
	register struct inode *ip;
	register short i;
	char done;
	struct inode *iptr;
	long zero;
	struct stat statb;

	zero = 0L;
	done = 0;
	if(argc != 2){
		printf("Usage: %s filename\n", argv[0]);
		exit(1);
	}

	if(stat(*++argv, &statb)){
		printf("%s: Can not access %s\n", argv[-1], *argv);
		exit(2);
	}

	if((mem = open("/dev/mem", MODE)) == -1){
		printf("%s: Can not open /dev/mem\n", argv[-1]);
		exit(3);
	}

	strcpy(nl[0].sy_name, "_inode");
	strcpy(nl[1].sy_name, "_file");
	strcpy(nl[2].sy_name, "_v");
	nlist("/unix", &nl);

	if(nl[0].sy_type < 0){
		printf("%s: No namelist (/unix)\n", argv[-1]);
		exit(4);
	}

	lseek(mem, (long)(nl[2].sy_value), 0);
	read(mem, &v, sizeof (struct var));
	lseek(mem, (long)(nl[0].sy_value), 0);
	for(ip = mbuf, i = 0; i < v.v_inode; i++){
		if(read(mem, ip, sizeof (struct inode)) != sizeof (struct inode)){
			printf("%s: Inode structure read error\n", argv[-1]);
			exit(5);
		}
		if(ip->i_number != statb.st_ino || ip->i_dev != statb.st_dev){
			continue;
		}
		iptr = nl[0].sy_value + i*(sizeof (struct inode));
		printf("Inode=%d, Device=%2d,%-2d  Iptr=%o\n",
			ip->i_number, major(ip->i_dev), minor(ip->i_dev), iptr);
		goto found;
	}
	printf("%s: %s, Inode=%d, Device=%2d,%-2d not in core\n",
		argv[-1], *argv, statb.st_ino, major(statb.st_dev),
		minor(statb.st_dev));
	exit(6);

found:
	lseek(mem, (long)(nl[1].sy_value), 0);
	for(fp = mbuf, i = 0; i < v.v_file; i++){
		if(read(mem, fp, sizeof (struct file)) != sizeof (struct file)){
			printf("%s: File structure read error\n", argv[-1]);
			exit(7);
		}
		if(fp->f_count == 0 || fp->f_inode != iptr)
			continue;
		printf("Previous Offset = %D\n", fp->f_offset);
#ifdef	REWRITE
		lseek(mem, -4L, 1);
		if(write(mem, &zero, 4) != 4)
			printf("%s: Memory write error -- continuing\n",
				argv[-1]);

#endif
		done++;
	}
	if(!done)
		printf("%s: Bad news, inode not in file table\n", argv[-1]);
#ifdef	REWRITE
	else	printf("You may wish to zero the file %s...\n", *argv);
#endif
	exit(!done);
}
