#define	CATADDR	154				/* -> catalog page map	*/
#define	FREEADR	152				/* Free page map	*/
#define	FMAX	116				/* # files in dist.	*/
#define	DSKSIZ	4800				/* #blocks/RK05		*/
#define	CATFIL	9				/* # of catalog file	*/

struct	file					/* Control for each file*/
	{
		int	nextblk;		/* -> next block #	*/
		int	length;			/* # blocks in file	*/
		int	blocks[255];		/* list of block #'s	*/
	}
		cat, cfile;			/* used for catalog &   */
						/* current file		*/

	int	schn;				/* Channel for SOLO disk*/
	int	fchn;				/* Channel for filenames*/
	int	findex;				/* RT-11 file index	*/
	int	ichn;				/* Channel for RT file	*/
	int	u_block[DSKSIZ];		/* Block allocation 	*/
						/* Matrix		*/

main()
{
	int	ior;				/* I/O result		*/
	char	rtname[20];			/* RT-11 file name	*/
	char	solonm[20];			/* Solo file name	*/
	extern	fout;				/* printf output	*/
	int	ii;				/* Temp			*/

	fout = 2;				/* init printf		*/

	for (ii=0; ii < CATADDR; ii++)		/* Init static blocks	*/
		u_block[ii] = -2;		/* Mark as system blocks */
	for (ii=CATADDR; ii < DSKSIZ; ii++)	/* For dynamic region	*/
		u_block[ii] = 0;		/* Mark as free		*/

	if((schn=open("SOL:")) < 0)		/* Device present?	*/
	{
		printf("Please assign device SOL:\n"); /* no, error	*/
		flush();
		exit();
	}

	if((fchn=open("DK:SOLO.FIL")) < 0)	/* Try to open directory */
	{
		printf("Cant find DK:SOLO.FIL\n"); /* Error		*/
		flush();
		exit();
	}

	findex = 2;				/* Start at F2.PAS	*/
while(findex <= FMAX)				/* For all files	*/
{
	printf(-1,rtname,"RT:F%d.PAS",findex);	/* Compute RT-11 name	*/

	if((ichn=open(rtname)) < 0)		/* File present?	*/
	{
		printf("Cant find %s\n",rtname);/* No, error		*/
		flush();
		exit();
	}

	ior = read(fchn,solonm,14);		/* Read next file name	*/
	if (ior != 14)				/* Wrong!!		*/
	{
		printf("Error in directory read\n"); /* Print message	*/
		flush();
		exit();
	}

	solonm[12]='\0';			/* Set terminator	*/

	findfil(solonm);			/* See if in directory	*/

	if(cfile.nextblk < 0)			/* then it isn't	*/
	{
		printf("File %s not in SOLO directory\n",solonm);
		flush();
		exit();
	}

	checkfile(solonm);			/* See if RT-11 file 	*/
						/* Matches SOLO file	*/

	findex++;				/* Then go to next file	*/
	if(findex == 9)				/* Skip CATALOG		*/
		findex++;
	close(ichn);				/* Close RT-11 File	*/
}
}
/*
 *	Findfil (name);
 *
 *		This function finds a file "name" in the SOLO directory,
 *		and sets up the cfile structure accordingly.
 *
 */

findfil(name)
	char	name[14];			/* Solo file name	*/
{
	int	i,j;				/* char subscripts	*/
	char	catbuff[512];			/* Catalog buffer	*/
	int	block;				/* Temp for block #	*/

	i =_read(schn,&cat.length,512,CATADDR);	/* Read catalog header	*/
	if(i < 0)				/* Error in read	*/
	{
		printf("Error in cat read\n");	/* Print message	*/
		flush();			/* 			*/
		exit();				/*			*/
	}


	cat.nextblk = 0;			/* Set next block pointer */

while (cat.length > 0)
{
	_read(schn,catbuff,512,cat.blocks[cat.nextblk]); /* read next block */
	j = 0;

	while (j < 512)
	{
		for (i=0; i < 12; i++)
		{
			if (catbuff[j+i] != name[i])
				goto quit;		/* get next one	*/
			if (i == 11)			/* then match	*/
			{
				block=(catbuff[j+14]&0377)|(catbuff[j+15]<<8);
				cfile.nextblk = 0;	/* indicate found */
				_read(schn,&cfile.length,512,block);
				chkblk(block,findex);	/* Mark blk in use */
				return;			/* done!	*/
			}
		}

quit:
		j =+ 32;				/* j --> next	*/
	}

	cat.nextblk++;					/* try next block */
	cat.length--;					/* Count down	  */
}

/*
 *	Failed to find file "name" in solo catalog ...
 *
 */

	cfile.nextblk = -1;			/* indicate failure	*/
	return;					/* quit			*/
}
/*
 *
 *	checkfile(name)
 *
 *		This function checks the solo file against the RT-11 file.
 *
 */

checkfile(name)

	char	*name;
{
	int	buffer1[256];			/* RT-11 buffer		*/
	int	buffer2[256];			/* SOLO buffer		*/
	int	i,j,k,l;			/* Temporaries		*/

	i=0;
	k=0;
	l=0;

while (cfile.length > 0)			/* Check all of file	*/
{
	_read(ichn,buffer1,512,i);		/* Read RT-11 file	*/
	_read(schn,buffer2,512,cfile.blocks[cfile.nextblk]); /* read solo */

	chkblk(cfile.blocks[cfile.nextblk],findex); /* Mark block in use */
	for (j=0; j < 256; j++)			/* for 256 words	*/
	{
		if(buffer1[j] != buffer2[j])	/* Difference		*/
		{
			k++;			/* Count differences	*/
		}
	}
	if (k != 0)
	{
		_write(schn,buffer1,512,cfile.blocks[cfile.nextblk]);
		printf("File %s block %o (%o) different\n",name,i,
			cfile.blocks[cfile.nextblk]);
		l =+ k;
		k = 0;
	}
	cfile.length--;				/* Count down		*/
	i++;					/* Increment block #	*/
	cfile.nextblk++;			/* Bump block count	*/
}

	printf("File %s -- %d differences\n",name,l);
	flush();
	return;
}
/*
 *
 *	Chkblk (block,id);
 *
 *		This function keeps track of all the blocks used on the disk
 *		If a block appears in two or more files, an error message
 *		will be printed.
 *
 */

chkblk(blkno,id)
{
	if(u_block[blkno] != 0)
	{
		printf("Block %o allocated twice F%d and F%d\n",
			blkno,u_block[blkno],id);	/* Error message  */
		flush();
	}
	else
		u_block[blkno] = id;
	return;
}
                                                                                                            