679 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			679 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* SB - Copyright 1982 by Ken Harrenstien, SRI International
 | 
						||
 *	This software is quasi-public; it may be used freely with
 | 
						||
 *	like software, but may NOT be sold or made part of licensed
 | 
						||
 *	products without permission of the author.  In all cases
 | 
						||
 *	the source code and any modifications thereto must remain
 | 
						||
 *	available to any user.
 | 
						||
 *
 | 
						||
 *	This is part of the SB library package.
 | 
						||
 *	Any software using the SB library must likewise be made
 | 
						||
 *	quasi-public, with freely available sources.
 | 
						||
 */
 | 
						||
 | 
						||
#define PRINT		/* Include printout stuff */
 | 
						||
 | 
						||
#include "sb.h"
 | 
						||
#include <stdio.h>
 | 
						||
 | 
						||
extern struct smblk *sbm_nfl;
 | 
						||
extern struct smblk *sbm_list;
 | 
						||
extern struct sdblk *sbx_nfl;
 | 
						||
 | 
						||
#ifdef PRINT
 | 
						||
#define PRF(stmt) {if(p) stmt;}
 | 
						||
#define PRFBUG(str,stmt) {if(p) stmt;else return(str);}
 | 
						||
#define PRFBAD(str,stmt) {if(p) stmt; return(str);}
 | 
						||
#else
 | 
						||
#define PRF(stmt) ;
 | 
						||
#define PRFBUG(str,stmt) return(str);
 | 
						||
#define PRFBAD(str,stmt) return(str);
 | 
						||
#endif
 | 
						||
 | 
						||
#ifndef NPTRS
 | 
						||
#define NPTRS (1000)		/* Catch loops of period less than this. */
 | 
						||
#endif
 | 
						||
 | 
						||
int sbe_dec = 0;		/* Set nonzero to use decimal printout */
 | 
						||
 | 
						||
struct ptab {
 | 
						||
	int pt_pflag;		/* Printflag value */
 | 
						||
	char *pt_err;		/* Error string return */
 | 
						||
	int pt_xerr;		/* Error index return */
 | 
						||
	int pt_hidx;		/* Highest freelist entry */
 | 
						||
	int pt_nsto;		/* # entries stored in table */
 | 
						||
	int pt_cnt;		/* # of entry store attempts */
 | 
						||
	struct smblk *pt_tab[NPTRS];
 | 
						||
};
 | 
						||
 | 
						||
_PROTOTYPE( char *sbe_sdtab, (struct ptab *pt, int p, int phys) );
 | 
						||
_PROTOTYPE( char *sbe_schk, (struct sdblk *sd, struct ptab *pt) );
 | 
						||
_PROTOTYPE( int sbe_tbent, (struct ptab *pt, struct smblk *sm) );
 | 
						||
 | 
						||
#define PTF_PRF	01	/* Do printout stuff */
 | 
						||
#define PTF_OVFERR 02	/* Complain if table overflows */
 | 
						||
#define PTF_SDPHYS 04	/* Follow SD phys links (else logical links) */
 | 
						||
 | 
						||
struct flgt {
 | 
						||
	int flg_bit;
 | 
						||
	int flg_chr;
 | 
						||
};
 | 
						||
 | 
						||
_PROTOTYPE( char *sbe_fstr, (int flags, struct flgt *fp) );
 | 
						||
 | 
						||
char *sbe_mvfy(), *sbe_mfl(), *sbe_mlst();		/* SBM */
 | 
						||
char *sbe_sbvfy(), *sbe_sbs();				/* SBBUF */
 | 
						||
char *sbe_svfy(), *sbe_sdlist(), *sbe_sdtab(), *sbe_schk();	/* SD */
 | 
						||
char *sbe_fstr();				/* Misc utility */
 | 
						||
 | 
						||
 | 
						||
/* SBE_MEM() - Print out memory usage list
 | 
						||
*/
 | 
						||
sbe_mem()
 | 
						||
{
 | 
						||
	printf("\nMemory Usage:\n");
 | 
						||
	printf("\tsbm_nfl : %6o\n",sbm_nfl);
 | 
						||
	printf("\tsbm_list: %6o\n",sbm_list);
 | 
						||
	printf("\tsmblk nodes are %o bytes long.\n",sizeof (struct smblk));
 | 
						||
 | 
						||
	sbe_mlst(1);		/* Scan mem list, printing stuff. */
 | 
						||
}
 | 
						||
 | 
						||
/* SBE_MVFY() - Verify memory allocation structures
 | 
						||
 *	Returns error message (0 if no errors found).
 | 
						||
 */
 | 
						||
char *
 | 
						||
sbe_mvfy()
 | 
						||
{	register char *res;
 | 
						||
 | 
						||
	if((res = sbe_mfl(0))
 | 
						||
	  || (res = sbe_mlst(0)))
 | 
						||
		return(res);
 | 
						||
	return(0);
 | 
						||
}
 | 
						||
 | 
						||
/* SBM Debugging Routines */
 | 
						||
 | 
						||
struct flgt smflgtab[] = {
 | 
						||
	SM_USE,	'U',
 | 
						||
	SM_NXM, 'N',
 | 
						||
	SM_EXT, 'E',
 | 
						||
	SM_MNODS,'M',
 | 
						||
	SM_DNODS,'D',
 | 
						||
	0,0
 | 
						||
};
 | 
						||
 | 
						||
static char smfhelp[] = "U-Used, N-NXM, E-External, M-SMnodes, D-SDnodes";
 | 
						||
static char smhdline[] = "\
 | 
						||
      SM: back   smaddr   smlen  smuse  smflags";
 | 
						||
 | 
						||
/* SBE_MFL(printflag) - Verify/Print memory freelist
 | 
						||
 *	Returns error message (0 if no errors found).
 | 
						||
 */
 | 
						||
char *
 | 
						||
sbe_mfl(p)
 | 
						||
int p;
 | 
						||
{	register struct smblk *sm;
 | 
						||
	register int i;
 | 
						||
	struct ptab smtab;		/* For loop detection */
 | 
						||
 | 
						||
	PRF(printf("Tracing SM node freelist --\n"))
 | 
						||
	PRF(printf("    Maximum loop detection size is %d.", NPTRS))
 | 
						||
	if((sm = sbm_nfl) == 0)
 | 
						||
	  {	PRF(printf("\n\tNo list.\n"))
 | 
						||
		return(0);			/* Null freelist is ok */
 | 
						||
	  }
 | 
						||
	smtab.pt_pflag = p ? PTF_PRF : 0;
 | 
						||
	smtab.pt_nsto = smtab.pt_cnt = 0;
 | 
						||
	i = 0;				/* Print 8 addrs/line */
 | 
						||
	for(; sm; sm = sm->smforw)
 | 
						||
	  {
 | 
						||
		PRF(printf("%s%7o->", (i==0 ? "\n    " : ""), sm))
 | 
						||
		if(++i >= 8) i = 0;
 | 
						||
		if(sbe_tbent(&smtab, sm) < 0)	/* If hit loop, stop */
 | 
						||
			PRFBAD("SM freelist loop",
 | 
						||
			  printf("\nLOOP - %o seen as node %d!!\n",
 | 
						||
				sm, smtab.pt_xerr))
 | 
						||
		if(sm->smflags)
 | 
						||
		  {	PRF((i = 0, printf("\nFreelist node has flags:\n")))
 | 
						||
			PRFBUG("Free SM flagged", sbe_smp(sm, 0))
 | 
						||
		  }
 | 
						||
	  }
 | 
						||
	PRF(printf("\nEnd - %d nodes on SM freelist.\n", smtab.pt_cnt))
 | 
						||
	return(0);
 | 
						||
}
 | 
						||
 | 
						||
/* SBE_MLST(printflag) - Verify/Print allocated memory list.
 | 
						||
 *	Returns error message (0 if no errors found).
 | 
						||
 */
 | 
						||
char *
 | 
						||
sbe_mlst(p)
 | 
						||
int p;
 | 
						||
{	register struct smblk *sm, *smf, *smb;
 | 
						||
	char *nextaddr = NULL;
 | 
						||
	int i;
 | 
						||
	struct ptab smtab;		/* For loop detection */
 | 
						||
 | 
						||
	PRF(printf("Tracing mem list -- \n"))
 | 
						||
	if((sm = sbm_list) == 0)
 | 
						||
	  {	PRF(printf("\tNo list?!\n"))
 | 
						||
		if(sbm_nfl)		/* Ensure rest are 0 too */
 | 
						||
			return("No mem list?!!");
 | 
						||
		return(0);
 | 
						||
	  }
 | 
						||
 | 
						||
	smtab.pt_pflag = p;
 | 
						||
	smtab.pt_cnt = smtab.pt_nsto = 0;
 | 
						||
	smb = 0;
 | 
						||
	PRF(printf("   Flags: %s\n%s\n", smfhelp, smhdline))
 | 
						||
	for(; sm; sm = smf)
 | 
						||
	  {	PRF(printf("  %6o: ",sm))
 | 
						||
		if(sbe_tbent(&smtab, sm) < 0)
 | 
						||
			PRFBAD("Loop in mem list!!",
 | 
						||
			  printf("LOOP - seen as node %d!!\n", smtab.pt_xerr))
 | 
						||
 | 
						||
		if(sm->smback == smb)
 | 
						||
			PRF(printf("^ "))	/* Back ptr OK */
 | 
						||
 | 
						||
		else PRFBUG("Bad back ptr!",
 | 
						||
			printf("%6o BAD Backptr!!\n\t    ",sm->smback))
 | 
						||
 | 
						||
		if((sm->smflags&0377)!= SM_NID)
 | 
						||
			PRFBUG("SM: bad node ID",
 | 
						||
				printf("BAD - no node ID!\n\t    "))
 | 
						||
		PRF(printf((sm->smflags&SM_USE) ? "     " : "FREE "))
 | 
						||
		if(sm->smlen == 0)
 | 
						||
			PRFBUG("SM: len 0",
 | 
						||
				printf("Zero-length area!"))
 | 
						||
		if((sm->smflags&SM_USE)==0
 | 
						||
		  && rndrem(sm->smaddr - sbm_lowaddr))
 | 
						||
			PRFBUG("Bad free-mem block",
 | 
						||
				printf("Bad free-mem block"))
 | 
						||
		PRF(sbe_smp(sm, 1))		/* Print out rest of info */
 | 
						||
 | 
						||
		if(nextaddr != sm->smaddr
 | 
						||
		  && smtab.pt_cnt != 1)		/* 1st time needs init */
 | 
						||
		  {	PRFBUG("Alignment error!",
 | 
						||
				printf("\t  BAD!! %6o expected; ",nextaddr))
 | 
						||
#if !(MINIX)
 | 
						||
			PRF((i = sm->smaddr - nextaddr) > 0
 | 
						||
				? printf("%d skipped.\n",i)
 | 
						||
				: printf("%d overlapped.\n",-i))
 | 
						||
#endif
 | 
						||
		  }
 | 
						||
		nextaddr = sm->smaddr + sm->smlen;
 | 
						||
		smf = sm->smforw;
 | 
						||
		smb = sm;			/* Save ptr to back */
 | 
						||
	  }
 | 
						||
	PRF(printf("End = %6o\n",nextaddr))
 | 
						||
	return(0);
 | 
						||
}
 | 
						||
 | 
						||
#ifdef PRINT
 | 
						||
sbe_smp(sm,type)
 | 
						||
register struct smblk *sm;
 | 
						||
int type;
 | 
						||
{
 | 
						||
	if(type==0)
 | 
						||
		printf("  %6o:  %s  ", sm,
 | 
						||
			((sm->smflags&SM_USE) ? "    " : "FREE"));
 | 
						||
	printf("%6o: ", sm->smaddr);
 | 
						||
	printf((sbe_dec ? "%5d. %5d." : "%6o %6o"), sm->smlen, sm->smuse);
 | 
						||
	printf("  %7o = %s\n", sm->smflags, sbe_fstr(sm->smflags, smflgtab));
 | 
						||
}
 | 
						||
#endif /*PRINT*/
 | 
						||
 | 
						||
/* SD (SBSTR) debugging routines */
 | 
						||
 | 
						||
struct flgt sdflgtab[] = {
 | 
						||
	SD_LOCK, 'L',
 | 
						||
	SD_LCK2, 'T',
 | 
						||
	SD_MOD,	 '*',
 | 
						||
	0,0
 | 
						||
};
 | 
						||
 | 
						||
static char sdfhelp[] = "\
 | 
						||
<f> flags: *-MOD (disk outofdate), L-LOCK, T-LCK2 (temp)";
 | 
						||
static char sdhdline[] = "\
 | 
						||
<f>      SD: slforw slback sdflgs sdforw sdback  sdmem sdfile  sdaddr sdlen";
 | 
						||
 | 
						||
 | 
						||
/* SBE_SFL(printflag) - Verify/Print SD freelist
 | 
						||
 *	Returns error message (0 if no errors found).
 | 
						||
 */
 | 
						||
char *
 | 
						||
sbe_sfl(p)
 | 
						||
int p;
 | 
						||
{	register struct sdblk *sd;
 | 
						||
	register int i;
 | 
						||
	struct ptab sdtab;		/* For loop detection */
 | 
						||
 | 
						||
	PRF(printf("Tracing SDBLK node freelist --\n"))
 | 
						||
	PRF(printf("    Maximum loop detection size is %d.", NPTRS))
 | 
						||
	if((sd = sbx_nfl) == 0)
 | 
						||
	  {	PRF(printf("\n\tNo list.\n"))
 | 
						||
		return(0);			/* Null freelist is ok */
 | 
						||
	  }
 | 
						||
	sdtab.pt_pflag = p ? PTF_PRF : 0;
 | 
						||
	sdtab.pt_nsto = sdtab.pt_cnt = 0;
 | 
						||
	i = 0;				/* Print 8 addrs/line */
 | 
						||
	for(; sd; sd = sd->slforw)
 | 
						||
	  {
 | 
						||
		PRF(printf("%s%7o->", (i==0 ? "\n    " : ""), sd))
 | 
						||
		if(++i >= 8) i = 0;
 | 
						||
		if(sbe_tbent(&sdtab, sd) < 0)	/* If hit loop, stop */
 | 
						||
			PRFBAD("SD freelist loop",
 | 
						||
			  printf("\nLOOP - %o seen as node %d!!",
 | 
						||
				sd, sdtab.pt_xerr))
 | 
						||
		if(sd->sdflags)
 | 
						||
		  {	PRF((i = 0, printf("\nFreelist node has flags:\n")))
 | 
						||
			PRFBUG("Free SD flagged", sbe_psd(sd))
 | 
						||
		  }
 | 
						||
	  }
 | 
						||
	PRF(printf("\nEnd - %d nodes on SD freelist.\n", sdtab.pt_cnt))
 | 
						||
	return(0);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
/* SBE_SDS() - Print out all sdblk data stuff
 | 
						||
 */
 | 
						||
sbe_sds()
 | 
						||
{	int sbe_psd();
 | 
						||
 | 
						||
	printf("Printout of all in-use SDBLKs:\n");
 | 
						||
	printf("  %s\n", sdfhelp);
 | 
						||
	printf("%s\n", sdhdline);
 | 
						||
	sbm_nfor(SM_DNODS,sizeof(struct sdblk),sbe_psd,0);
 | 
						||
	printf("\n");
 | 
						||
}
 | 
						||
 | 
						||
/* SBE_PSD - Auxiliary for invocation by SBE_SDS above. */
 | 
						||
sbe_psd(sd)
 | 
						||
register struct sdblk *sd;
 | 
						||
{	register int flags;
 | 
						||
 | 
						||
	flags = sd->sdflags;
 | 
						||
	printf("%c%c%c",
 | 
						||
		((flags&SD_MOD)  ? '*' : ' '),
 | 
						||
		((flags&SD_LOCK) ? 'L' : ' '),
 | 
						||
		((flags&SD_LCK2) ? 'T' : ' '));
 | 
						||
 | 
						||
	printf(" %7o: %6o %6o %6o %6o %6o %6o %6o %7lo %5ld.\n", sd,
 | 
						||
		sd->slforw, sd->slback, sd->sdflags,
 | 
						||
		sd->sdforw, sd->sdback, sd->sdmem,
 | 
						||
		sd->sdfile, sd->sdaddr, sd->sdlen);
 | 
						||
	return(0);
 | 
						||
}
 | 
						||
 | 
						||
/* SBE_SVFY() - Verify all SD blocks
 | 
						||
 *	Returns error message (0 if no errors found).
 | 
						||
 */
 | 
						||
char *
 | 
						||
sbe_svfy()
 | 
						||
{	register char *res;
 | 
						||
	return((res = sbe_sdlist(0,0)) ? res : sbe_sdlist(0,1));
 | 
						||
}
 | 
						||
 | 
						||
/* SBE_SDLIST(printflag, physflag) - Verify/Print all SD blocks.
 | 
						||
 *	Show logical lists if physflag 0
 | 
						||
 *	Show physical lists otherwise
 | 
						||
 *	Returns error message (0 if no errors found).
 | 
						||
 */
 | 
						||
char *
 | 
						||
sbe_sdlist(p,phys)
 | 
						||
int p, phys;
 | 
						||
{	register char *res;
 | 
						||
	struct ptab sdtab;	/* The SDLIST table to use */
 | 
						||
 | 
						||
	/* First put freelist in table, then scan for all
 | 
						||
	 * SD nodes.  Each active node (not in table) gets
 | 
						||
	 * its entire list traced forward/backward and added to table.
 | 
						||
	 */
 | 
						||
	if(res = sbe_sdtab(&sdtab, p, phys))	/* Set up freelist table */
 | 
						||
		return(res);
 | 
						||
 | 
						||
	/* Freelist entered in table, now scan all SD's */
 | 
						||
	res = (char *)sbm_nfor(SM_DNODS,sizeof(struct sdblk),
 | 
						||
			sbe_schk, &sdtab);
 | 
						||
 | 
						||
	PRF(printf("\n"))
 | 
						||
	return(res);
 | 
						||
}
 | 
						||
 | 
						||
/* SBE_SDTAB(tableptr, printflag, physflag) - Auxiliary for SBE_SDLIST.
 | 
						||
 *	Stuffs all freelist SDBLK addresses in table for dup detection.
 | 
						||
 *	Returns error message (0 if no errors found).
 | 
						||
 */
 | 
						||
char *
 | 
						||
sbe_sdtab(pt, p, phys)
 | 
						||
register struct ptab *pt;
 | 
						||
int p, phys;
 | 
						||
{	register struct sdblk *sd;
 | 
						||
 | 
						||
	pt->pt_pflag = (p ? PTF_PRF : 0) | (phys ? PTF_SDPHYS : 0)
 | 
						||
			| PTF_OVFERR;
 | 
						||
	pt->pt_cnt = pt->pt_nsto = 0;	/* Initialize */
 | 
						||
 | 
						||
	/* Stick freelist in table */
 | 
						||
	for(sd = sbx_nfl; sd; sd = sd->slforw)
 | 
						||
	  {	if(sbe_tbent(pt, sd) < 0)
 | 
						||
		  {	if(pt->pt_xerr < 0)
 | 
						||
				PRFBAD("SD freelist too long",
 | 
						||
					printf("SD freelist too long (%d)\n",
 | 
						||
						NPTRS))
 | 
						||
			PRFBAD("SD freelist loop",
 | 
						||
			  printf("SD freelist loop at %o\n", pt->pt_xerr))
 | 
						||
		  }
 | 
						||
 | 
						||
		if(sd->sdflags)
 | 
						||
		  {
 | 
						||
			PRF(printf("Bad free SD, non-zero flag:\n"))
 | 
						||
			PRFBUG("Free SD flagged", sbe_psd(sd))
 | 
						||
		  }
 | 
						||
	  }
 | 
						||
	pt->pt_hidx = pt->pt_nsto;	/* Set idx of 1st non-FL entry */
 | 
						||
	return(0);
 | 
						||
}
 | 
						||
 | 
						||
/* SBE_SCHK(SDptr, tableptr) - Auxiliary for SBE_SDLIST.
 | 
						||
 *	If SD not already in table, verifies or prints
 | 
						||
 *	the complete physical or logical list it's on, and enters all
 | 
						||
 *	of its SDs into table (to prevent doing it again).
 | 
						||
 *	Returns 0 if no errors, else error string.
 | 
						||
** There is a problem when the table overflows.  The tbent routine
 | 
						||
** wants to add it (wrapping around at bottom) in that case, because
 | 
						||
** that still helps detect loops.  But this routine wants to reset
 | 
						||
** the table back (after scanning to head of list) and once it starts
 | 
						||
** scanning forward again it will fail, because some of the SDs are
 | 
						||
** still in the table due to the wraparound!  Thus PTF_OVFERR is always
 | 
						||
** set, in order to at least give the right error message.
 | 
						||
*/
 | 
						||
char *
 | 
						||
sbe_schk(sd, pt)
 | 
						||
register struct sdblk *sd;
 | 
						||
struct ptab *pt;
 | 
						||
{	register struct sdblk *sdx;
 | 
						||
	register struct smblk *sm;
 | 
						||
	struct sbfile *savfile;
 | 
						||
	chroff lastaddr;
 | 
						||
	int p, savidx, phys;
 | 
						||
 | 
						||
	phys = pt->pt_pflag&PTF_SDPHYS;	/* Set up physflag */
 | 
						||
	if(phys && (sd->sdfile == 0))	/* Ignore non-phys stuff if phys */
 | 
						||
		return(0);
 | 
						||
	p = pt->pt_pflag&PTF_PRF;	/* Set up printflag */
 | 
						||
	savidx = pt->pt_nsto;		/* Remember initial extent of table */
 | 
						||
 | 
						||
	if(sbe_tbent(pt, sd) < 0)
 | 
						||
	  {	if(pt->pt_xerr >= 0)	/* OK if already in table */
 | 
						||
			return(0);
 | 
						||
		PRFBAD("Too many SDs",
 | 
						||
			printf("Too many SDs for table (%d)\n",	NPTRS))
 | 
						||
	  }
 | 
						||
 | 
						||
	/* Now search backward for start of list */
 | 
						||
	while(sdx = (phys ? sd->sdback : sd->slback))
 | 
						||
		if(sbe_tbent(pt,sdx) >= 0)
 | 
						||
			sd = sdx;
 | 
						||
		else break;
 | 
						||
	if(sdx)
 | 
						||
	  {	if(pt->pt_xerr < 0)	/* Table error? */
 | 
						||
			PRFBAD("Too many SDs",
 | 
						||
				printf("Too many SDs for table (%d)\n",NPTRS))
 | 
						||
		PRF(printf("Backlist loop!! Dup'd node:%s\n",
 | 
						||
				(pt->pt_xerr < pt->pt_hidx) ?
 | 
						||
					"(on freelist!)" : "" ))
 | 
						||
		PRFBUG((phys ? "Phys SD loop" : "SD loop"), sbe_psd(sdx))
 | 
						||
	  }
 | 
						||
	/* Reset table to flush nodes backed over */
 | 
						||
	pt->pt_cnt = pt->pt_nsto = savidx;
 | 
						||
 | 
						||
	/* SD now points to start of list.  Begin stepping thru list... */
 | 
						||
	PRF(printf("---- %sList started: ", (phys ? "Phys " : "")))
 | 
						||
	if(phys)
 | 
						||
	  {	savfile = sd->sdfile;
 | 
						||
		PRF(printf(" SF: %o, fd= %d, ln= %ld\n",
 | 
						||
			savfile,savfile->sffd,savfile->sflen))
 | 
						||
		if(savfile->sfptr1 != sd)
 | 
						||
			PRFBUG("SFPTR1 bad",
 | 
						||
			  printf("  BAD!! Sfptr1 %o doesn't match SD %o!!\n",
 | 
						||
				savfile->sfptr1, sd))
 | 
						||
		lastaddr = 0;
 | 
						||
	  }
 | 
						||
	else PRF(printf("\n"))
 | 
						||
 | 
						||
	PRF(printf("%s\n", sdhdline))
 | 
						||
	for(sdx = 0; sd; (sdx = sd, sd = (phys ? sd->sdforw : sd->slforw)))
 | 
						||
	  {
 | 
						||
		PRF(sbe_psd(sd))	/* Print it out */
 | 
						||
		if(sdx != (phys ? sd->sdback : sd->slback))
 | 
						||
		  {	if(phys)
 | 
						||
			  PRFBUG("PSD bad sdback",printf("\tBad phys backptr\n"))
 | 
						||
			else
 | 
						||
			  PRFBUG("SD bad slback",printf("\tBad backptr\n"))
 | 
						||
		  }
 | 
						||
 | 
						||
		if((sd->sdflags&0377) != SD_NID)
 | 
						||
			PRFBUG("Bad SD node ID", printf("\tBad node ID!\n"))
 | 
						||
 | 
						||
 | 
						||
		if(sd->sdfile && (sd->sdlen < 0 || sd->sdaddr < 0))
 | 
						||
			PRFBUG("SD: neg len/addr",
 | 
						||
				printf("\tNeg disk len/addr\n"))
 | 
						||
		if(phys) goto dophys;
 | 
						||
 | 
						||
		/* Do special stuff for logical list */
 | 
						||
		if(sm = sd->sdmem)
 | 
						||
		  {	if((sm->smflags&0377) != SM_NID)
 | 
						||
				PRFBUG("SD: bad SM",
 | 
						||
					printf("\nBad SMBLK ptr\n"))
 | 
						||
			if((sd->sdflags&SD_MOD)==0
 | 
						||
			  && sd->sdlen != sm->smuse)
 | 
						||
				PRFBUG("SD != SM",
 | 
						||
					printf("\tBad SMBLK? Len conflict\n"))
 | 
						||
			if(sm->smlen < sm->smuse)
 | 
						||
				PRFBUG("SD: SM len < use",
 | 
						||
					printf("\tBad SMBLK, len < use\n"))
 | 
						||
		  }
 | 
						||
		goto doboth;	/* Skip phys stuff */
 | 
						||
 | 
						||
		/* Do special stuff for phys list */
 | 
						||
	dophys:	if(sd->sdfile != savfile)
 | 
						||
			PRFBUG("SD: bad sdfile",
 | 
						||
				printf("\tBad sdfile ptr! Shd be %o\n",
 | 
						||
					savfile))
 | 
						||
		if(sd->sdaddr < lastaddr)
 | 
						||
			PRFBUG("SD addr out of order",
 | 
						||
				printf("\tBad disk addr, not in order!\n"))
 | 
						||
		lastaddr = sd->sdaddr;
 | 
						||
		/* Done with special phys stuff */
 | 
						||
 | 
						||
	doboth:	if(sbe_tbent(pt, sd) < 0)
 | 
						||
		  {	if(pt->pt_xerr < 0)
 | 
						||
				PRFBAD("Too many SDs",
 | 
						||
					printf("Too many SDs for table (%d)\n",NPTRS))
 | 
						||
 | 
						||
			PRFBUG("SD loop",
 | 
						||
				printf("\tLOOP!! This SD already seen%s.\n",
 | 
						||
					(pt->pt_xerr < pt->pt_hidx) ?
 | 
						||
					" (on freelist!)" : "" ))
 | 
						||
			break;
 | 
						||
		  }
 | 
						||
	  }
 | 
						||
	PRF(printf("-----------\n"))
 | 
						||
	return(0);
 | 
						||
}
 | 
						||
 | 
						||
/* SBE_DSK(SFptr) - Print out disk usage list for specific file
 | 
						||
 */
 | 
						||
 | 
						||
sbe_dsk(sfp)
 | 
						||
SBFILE *sfp;
 | 
						||
{
 | 
						||
	printf("SBFILE printout not coded: %o\n",sfp);
 | 
						||
}
 | 
						||
 | 
						||
/* SBBUF structure debugging routines */
 | 
						||
 | 
						||
struct flgt sbflgtab[] = {
 | 
						||
	SB_OVW, 'O',
 | 
						||
	SB_WRIT,'W',
 | 
						||
	0,0
 | 
						||
};
 | 
						||
static char sbfhelp[] = "O-Overwrite, W-Write";
 | 
						||
 | 
						||
/* SBE_SBVFY(SBptr) - Verify a SB-string.
 | 
						||
 *	Returns error message (0 if no errors found).
 | 
						||
 */
 | 
						||
char *
 | 
						||
sbe_sbvfy(sbp)
 | 
						||
SBBUF *sbp;
 | 
						||
{	return(sbe_sbs(sbp,0));
 | 
						||
}
 | 
						||
 | 
						||
/* SBE_SBS(SBptr, printflag) - Verify/Print SBSTR data stuff
 | 
						||
 *	Returns error message (0 if no errors found).
 | 
						||
 */
 | 
						||
char *
 | 
						||
sbe_sbs(sbp,p)
 | 
						||
SBBUF *sbp;
 | 
						||
int p;
 | 
						||
{	register SBBUF *sb;
 | 
						||
	register struct smblk *sm;
 | 
						||
	register struct sdblk *sd;
 | 
						||
 | 
						||
	sb = sbp;
 | 
						||
	PRF(printf("SBSTR %o: ",sb))
 | 
						||
	if(sb == 0)
 | 
						||
		PRFBUG(0,printf("Zero pointer???\n"))
 | 
						||
 | 
						||
	/* First print out cryptic summary in case pointers bomb
 | 
						||
	 * out farther on. */
 | 
						||
	PRF(printf(" (io,cur,r,w,f,.,+ = %o,%o,%d,%d,%o,%lo,%lo)\n",
 | 
						||
		sb->sbiop, sb->sbcur, sb->sbrleft, sb->sbwleft,
 | 
						||
		sb->sbflags, sb->sbdot, sb->sboff))
 | 
						||
 | 
						||
	PRF(printf("  sbflags %5o = %s (%s)\n",
 | 
						||
			sb->sbflags, sbe_fstr(sb->sbflags,sbflgtab),
 | 
						||
			sbfhelp))
 | 
						||
 | 
						||
	if(sd = sb->sbcur)	/* Okay, now try getting pointers */
 | 
						||
		sm = sd->sdmem;
 | 
						||
	else sm = 0;
 | 
						||
 | 
						||
	PRF(printf("  sbcur %6o",sd))
 | 
						||
	if(sd)
 | 
						||
	  {
 | 
						||
		PRF(printf("\n   %s\n   ", sdhdline))
 | 
						||
		PRF(sbe_psd(sd))
 | 
						||
 | 
						||
		if((sd->sdflags&0377) != SD_NID)
 | 
						||
			PRFBUG("SBCUR not SD?",printf("   BAD SDBLK ID!! \n"))
 | 
						||
		if(sm)
 | 
						||
		  {
 | 
						||
			PRF(printf("   %s\n   ", smhdline))
 | 
						||
			PRF(sbe_smp(sm,0))
 | 
						||
			if((sm->smflags&0377) != SM_NID)
 | 
						||
				PRFBUG("SBCUR has bad SM",
 | 
						||
					printf("   BAD SMBLK ID!!\n"))
 | 
						||
		  }
 | 
						||
	  }
 | 
						||
 | 
						||
 | 
						||
	PRF(printf("  sbiop  %6o",sb->sbiop))
 | 
						||
	if(sb->sbiop)
 | 
						||
	  {	if(!sm || sb->sbiop < sm->smaddr
 | 
						||
		  || sb->sbiop > (sm->smaddr + sm->smlen))
 | 
						||
			PRFBUG("Bad SBIOP", printf("  BAD"))
 | 
						||
	  }
 | 
						||
	else if(sb->sbrleft > 0 || sb->sbwleft > 0)
 | 
						||
		PRFBUG("Bad SBIOP/cnts", printf("  BAD"))
 | 
						||
	PRF(printf("\n"))
 | 
						||
 | 
						||
	PRF(printf("  sbrleft %5o = %5d.",sb->sbrleft, sb->sbrleft))
 | 
						||
	if(sb->sbrleft
 | 
						||
	  && (	!sm
 | 
						||
	    ||	sb->sbwleft
 | 
						||
	    ||	(sb->sbflags&SB_WRIT)
 | 
						||
	    ||	(sb->sbrleft != (sm->smuse - (sb->sbiop - sm->smaddr)))
 | 
						||
	    ))
 | 
						||
		PRFBUG("Bad sbrleft", printf("  BAD"))
 | 
						||
	PRF(printf("\n"))
 | 
						||
 | 
						||
	PRF(printf("  sbwleft %5o = %5d.", sb->sbwleft, sb->sbwleft))
 | 
						||
	if(sb->sbwleft
 | 
						||
	  && (	!sm
 | 
						||
	    ||	(sb->sbflags&SB_WRIT) == 0
 | 
						||
	    ||	(sb->sbwleft > (sm->smlen - (sb->sbiop - sm->smaddr)))
 | 
						||
	    ))
 | 
						||
		PRFBUG("Bad sbwleft", printf("  BAD"))
 | 
						||
	PRF(printf("\n"))
 | 
						||
 | 
						||
	PRF(printf("  sbdot %7lo = %7ld.", sb->sbdot, sb->sbdot))
 | 
						||
	if(sb->sbdot < 0)
 | 
						||
		PRFBUG("Bad sbdot", printf("  BAD"))
 | 
						||
 | 
						||
	PRF(printf("\n  sboff %7lo = %7ld.\n", sb->sboff, sb->sboff))
 | 
						||
	PRF(printf("  I/O ptr loc: %ld.\n\n", sb_tell(sb)))
 | 
						||
 | 
						||
	return(0);
 | 
						||
}
 | 
						||
 | 
						||
/* SBE_TBENT() - Auxiliary to add and check entries to a pointer table.
 | 
						||
 *	Note we assume here that smblk ptrs are used, although sdblks
 | 
						||
 *	can also be hacked.  This wins as long as the two kinds of ptrs
 | 
						||
 *	are basically identical (saves horrible casting problems).
 | 
						||
 *	Returns index # if successful (between 0 and NPTRS-1 inclusive).
 | 
						||
 *	Otherwise an error (-1), with relevant info in pt_xerr:
 | 
						||
 *		-1 if out of room and flag set making it an error
 | 
						||
 *		0-n if entry already existed.
 | 
						||
 */
 | 
						||
sbe_tbent(pt, sm)
 | 
						||
register struct ptab *pt;
 | 
						||
struct smblk *sm;
 | 
						||
{	register struct smblk **smt;
 | 
						||
	register int i;
 | 
						||
	int p;
 | 
						||
 | 
						||
	p = pt->pt_pflag&PTF_PRF;	/* Set up print flag */
 | 
						||
	smt = &(pt->pt_tab[0]);
 | 
						||
	if(i = pt->pt_nsto)
 | 
						||
	  {	do {
 | 
						||
			if(sm == *smt++)
 | 
						||
			  {	pt->pt_xerr = pt->pt_nsto - i;
 | 
						||
				return(-1);
 | 
						||
			  }
 | 
						||
		  } while(--i);
 | 
						||
		--smt;
 | 
						||
	  }
 | 
						||
 | 
						||
	i = pt->pt_cnt++;
 | 
						||
	if(++(pt->pt_nsto) > NPTRS)
 | 
						||
	  {	if(pt->pt_pflag&PTF_OVFERR)
 | 
						||
		  {	pt->pt_err = "Ptrtab overflow";
 | 
						||
			pt->pt_xerr = -1;
 | 
						||
			return(-1);
 | 
						||
		  }
 | 
						||
		pt->pt_nsto = NPTRS;
 | 
						||
		i %= NPTRS;
 | 
						||
	  }
 | 
						||
	pt->pt_tab[i] = sm;
 | 
						||
	return(i);
 | 
						||
}
 | 
						||
 | 
						||
/* SBE_FSTR(flags, flagtab) - Auxiliary to convert flag word to a string
 | 
						||
 *	and return pointer to it.  Handy for printfs.
 | 
						||
 */
 | 
						||
char *
 | 
						||
sbe_fstr(flags, fp)
 | 
						||
register int flags;
 | 
						||
register struct flgt *fp;
 | 
						||
{	static char retstr[17];	/* Max of 16 flags */
 | 
						||
	register char *cp;
 | 
						||
	cp = retstr;
 | 
						||
	for(; fp->flg_bit; ++fp)
 | 
						||
		*cp++ = (fp->flg_bit&flags) ? fp->flg_chr : ' ';
 | 
						||
	*cp = 0;
 | 
						||
	return(retstr);
 | 
						||
}
 |