File:  [XINU] / xinu / sys / LSI / dutil.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:39:04 2018 UTC (8 years, 3 months ago) by root
Branches: xinu, MAIN
CVS tags: xinu-19870308, HEAD
Xinu for VAX

/* dutil.c - dutil */

#include <conf.h>
#include <kernel.h>
#include <proc.h>
#include <disk.h>
#include <lfile.h>
#include <dir.h>
#include <tty.h>

#define	TERMEOF		'\004'		/* interpreted as EOF at console*/
#define	DISKID		33		/* an arbitrary disk id number	*/
#ifndef	DISK0
#define	DISK0		4
#endif

struct	dir	*dirptr;		/* pointer to the in-core dir	*/
int	diskdev;			/* disk device operated on	*/
int	dsize;				/* disk size in blocks		*/
int	niblks;				/* number of i-blocks this disk	*/
char	buf[200];			/* buffer for input line	*/
char	dbuff[DBUFSIZ];			/* one disk buffer		*/
char	msg[] =
"Choose from: dir, read, write, create, or type help\n";
#define	PROMPT	"\ncmd: "
char	arg1[150];
char	arg2[150];
Bool	verbose;

struct	cmdname	{			/* list of valid commands	*/
	char	*cname;
	int	cargs;
	char	*cexpl;
} cmds[] = {	"append",	2,	"append file1 onto file2",
		"create",	1,	"create a new (empty) file",
		"dir",		0,	"list directory",
		"exec",		1,	"execute a program from disk",
		"freeze",	1,	"freeze this program & save",
		"help",		0,	"print this page of info",
		"iblock",	1,	"print an iblock",
		"init",		1,	"initialize disk device number",
		"mkfs",		0,	"make a file system",
		"name",		2,	"rename file1 to file2",
		"quit",		0,	"quit running this program",
		"read",		1,	"read a file and display it",
		"size",		0,	"report the size of the disk",
		"trace",	1,	"trace a file's iblock list",
		"verbose",	1,	"set verbose output y or n",
		"write",	1,	"write a file from terminal",
		"zap",		1,	"remove a file from the disk",
		"?",		0,	"synonym for 'help'"};
#define	NCMDS	sizeof(cmds)/sizeof(struct cmdname)
int	ncmds;


/*------------------------------------------------------------------------
 *  dutil  --  general disk utility program.
 *------------------------------------------------------------------------
 */
dutil()
{
	int	ret;

	kprintf("\n\n*** Disk Utility Program ***\n\n");
	diskdev = DISK0;
	verbose = FALSE;
	ncmds = NCMDS;
	kprintf("Starting with disk DISK0 (device id = %d)",diskdev);
	kprintf("         type '?' for help\n");
	dirptr = dsdirec(diskdev);
	sizeup(diskdev);
	while (1) {
		switch( getcmd() ) {

		case 0:		ret = duapp(diskdev, arg1, arg2);
				break;

		case 1:		ret = ducreat(diskdev, arg1);
				break;

		case 2:		ret = dudir(diskdev);
				break;

		case 3:		ret = duexec(diskdev, arg1);
				break;

		case 4: 	ret = dufreeze(diskdev, arg1);
				break;

		case 5: 	ret = duhelp();
				break;

		case 6:		ret = duiblk(diskdev, arg1);
				break;

		case 7:		ret = duinit(arg1);
				if (ret != SYSERR)
					diskdev = ret;
				break;

		case 8:		ret = dupmkfs(diskdev);
				break;

		case 9:		ret = duname(diskdev, arg1, arg2);
				break;

		case 10:	ret = duquit();
				break;

		case 11:	ret = duread(diskdev, arg1);
				break;

		case 12:	ret = dusize(diskdev);
				break;

		case 13:	ret = dutrace(diskdev, arg1);
				break;

		case 14:	ret = duverbose(arg1);
				break;

		case 15:	ret = duwrite(diskdev, arg1);
				break;

		case 16:	ret = duzap(diskdev, arg1);
				break;

		case 17:	ret = duhelp();
				break;

		default:	ret = SYSERR;

		}
		if (verbose)
			kprintf("Command completed with code %d\n",ret);
	}
}


/*------------------------------------------------------------------------
 *  duapp  --  append one file to the end of another
 *------------------------------------------------------------------------
 */
duapp(diskdev, from, to)
int	diskdev;
char	*from, *to;
{
	int	f1, f2;
	int	ich;

	if (verbose)
		kprintf("Appending files...\n");
	if ( (f2=open(diskdev,to,"rwo")) == SYSERR) {
		kprintf("Can't open file %s\n",to);
		return(SYSERR);
	}
	if (verbose)
		kprintf("device id for file '%s' is %d\n",to,f2);
	if (strcmp(from,"-") == 0)
		f1 = CONSOLE;
	else
		if ( (f1=open(diskdev,from,"ro")) == SYSERR) {
			kprintf("Can't open input file %s\n",from);
			close(f2);
			return(SYSERR);
		}
	if (verbose)
		kprintf("device id for file '%s' is %d\n",from,f1);
	while ( (ich=getc(f2)) != EOF)
		if (ich == SYSERR)
			kprintf("Error positioning file %s\n",to);
	while ( (ich=inchar(f1)) != EOF) {
		if (ich == SYSERR) {
			kprintf("Error reading file %s\n", from);
			close(f1);
			close(f2);
			return(SYSERR);
		}
		putc(f2, ich);
	}
	close(f1);
	close(f2);
	return(OK);
}


/*------------------------------------------------------------------------
 *  ducreat  --  create an empty disk file given its name
 *------------------------------------------------------------------------
 */
ducreat(diskdev, name)
int	diskdev;
char	*name;
{
	int	f1;

	if (verbose)
		kprintf("Creating file %s\n", name);
	if ( (f1=open(diskdev,name,"nr")) == SYSERR) {
		kprintf("Can't create new file %s\n", name);
		return(SYSERR);
	}
	close(f1);
	return(OK);
}


/*------------------------------------------------------------------------
 *  duexec  --  unfreeze a program and execute from disk
 *------------------------------------------------------------------------
 */
duexec(diskdir, name)
int	diskdir;
char	*name;
{
	int	f1;

	if ( (f1=open(diskdev, name, "ro")) == SYSERR) {
		kprintf("Can't frind program %s\n", name);
		return(SYSERR);
	}
	kprintf("Command not implemented\n");
	close(f1);
	return(SYSERR);
}


/*------------------------------------------------------------------------
 *  dufreeze  --  freeze this program and save it on disk
 *------------------------------------------------------------------------
 */
dufreeze(diskdev, name)
int	diskdev;
char	*name;
{
	int	f1;

	if ( (f1 = open(diskdev,name,"wn")) == SYSERR) {
		kprintf("Can't create file %s\n", name);
		return(SYSERR);
	}
	kprintf("Command not implemented\n");
	close(f1);
	return(SYSERR);
}


/*------------------------------------------------------------------------
 *  duhelp  -- print help message
 *------------------------------------------------------------------------
 */
duhelp()
{
	int	i, len;

	kprintf("\nCommands available are:\n\n");
	kprintf("   Command      #args     Description\n");
	for (i=0 ; i<ncmds ; i++) {
		kprintf("   %s",cmds[i].cname);
		for (len=strlen(cmds[i].cname) ; len<16 ; len++)
			kprintf(" ");
		kprintf("%d    %s\n",cmds[i].cargs, cmds[i].cexpl);
	}
	kprintf("\n");
	return(OK);		
}


/*------------------------------------------------------------------------
 *  duiblk  --  print an iblock given its index
 *------------------------------------------------------------------------
 */
duiblk(diskdev, arg)
int	diskdev;
char	*arg;
{
	struct	iblk	iblock;
	int	k, j;
	char	ch;
	IBADDR	ibnum;

	for (ibnum=0 ; (ch = *arg)!='\000' ; arg++) {
		if (ch<'0' || ch>'9')
			return(SYSERR);
		ibnum = 10*ibnum + (ch - '0');
	}
	if (ibnum < 0)
		return(SYSERR);
	ibget(diskdev, ibnum, &iblock);
	kprintf("iblock %d: offset=%U  next=%d\n\n   ",
		ibnum, iblock.ib_byte, iblock.ib_next);
	for (j=IBLEN-1 ; j>=0&&iblock.ib_dba[j]==DBNULL ; j--)
		;
	if (j < 0)
		kprintf("empty\n");
	else {
		for (k=0 ; k<=j ; k++)
			kprintf("%u ", iblock.ib_dba[k]);
		kprintf("\n");
	}
	return(OK);
}


/*------------------------------------------------------------------------
 *  duinit  --  initialize disk drive number and size
 *------------------------------------------------------------------------
 */
duinit(drive)
char	*drive;
{
	int	i,n;
	char	ch;

	n = 0;
	for (i=0 ; i<20 ; i++) {
		if ( (ch = *drive++) == '\000' || ch=='\n') {
			sizeup(n);
			return(n);
		} else {
			if (ch<'0' || ch>'9') {
				kprintf("Digit expected; got '%c'\n",ch);
				return(SYSERR);
			}
			n = 10*n + (ch - '0');
		}
	}
	kprintf("Argument too long.\n");
	return(SYSERR);
}


/*------------------------------------------------------------------------
 *  dupmkfs  -- make a file system from scratch
 *------------------------------------------------------------------------
 */
dupmkfs(diskdev)
int	diskdev;
{
	int	ret;

	if (verbose)
		kprintf("Making a file system...\n");
	ret = dumkfs(diskdev, niblks, dsize, DISKID, verbose);
	return(ret);
}

/*------------------------------------------------------------------------
 *  duname  -- rename one file into another
 *------------------------------------------------------------------------
 */
duname(diskdev, fname, tname)
int	diskdev;
char	*fname;
char	*tname;
{
	struct	fdes	*fdptr, *fdptr2;
	struct	dir	*dirptr;
	int	i, pos;
	int	sem;

	if (verbose)
		kprintf("Renaming file '%s' to '%s'\n", fname, tname);
	dirptr = dsdirec(diskdev);
	sem = ( (struct dsblk *)devtab[diskdev].dvioblk)->ddirsem;
	wait(sem);
	for (pos= -1,i=0 ; i<dirptr->d_nfiles ; i++) {
		fdptr = &dirptr->d_files[i];
		if (strcmp(fname, fdptr->fdname) == 0) {
			pos = i;
		} else if (strcmp(tname, fdptr->fdname) == 0) {
			kprintf("File '%s' already exists\n",tname);
			signal(sem);
			return(SYSERR);
		}
	}
	if (pos >= 0) {
		strcpy(dirptr->d_files[pos].fdname, tname);
		write(diskdev, dskbcpy(dirptr), DIRBLK);
		signal(sem);
		return(OK);
	}
	kprintf("File '%s' not found in directory\n", fname);
	signal(sem);
	return(SYSERR);
}


/*------------------------------------------------------------------------
 *  duquit  --  stop executing
 *------------------------------------------------------------------------
 */
duquit()
{
	int	i;

	if (verbose)
		kprintf("Exiting utility program...\n");
	for (i=1 ; i<NPROC ; i++)
		if (i != currpid)
			kill(i);
	kill(currpid);
}


/*------------------------------------------------------------------------
 *  duread  -- read a file and display on the terminal
 *------------------------------------------------------------------------
 */
duread(diskdev, fname)
int	diskdev;
char	*fname;
{
	int	f, ich;

	if (verbose)
		kprintf("Read file %s\n", fname);
	if ( (f=open(diskdev, fname, "ro")) == SYSERR) {
		kprintf("Can't open file %s\n", fname);
		return(SYSERR);
	}
	while( (ich=getc(f)) != EOF )
		if (ich == SYSERR) {
			kprintf("***ERROR ON READ***\n");
			return(SYSERR);
		} else
			kprintf("%c", ich);
	close(f);
	return(OK);
}


/*------------------------------------------------------------------------
 *  dusize  --  size the disk and print out the number of blocks
 *------------------------------------------------------------------------
 */
dusize()
{
	kprintf("Disk has %u blocks on it\n", dsize);
}


/*------------------------------------------------------------------------
 *  dutrace  --  trace the iblock list for a given file
 *------------------------------------------------------------------------
 */
dutrace(diskdev, fname)
int	diskdev;
char	*fname;
{
	int	f;
	int	inum, i, j,k;
	struct	iblk	iblock;
	struct	flblk	*flptr;

	if (verbose)
		kprintf("Tracing iblocks for file %s\n", fname);
	if ( (f=open(diskdev, fname, "ro")) == SYSERR) {
		kprintf("Can't open file %s\n", fname);
		return(SYSERR);
	}
	flptr = (struct flblk *)devtab[f].dvioblk;
	inum = flptr->fl_iba;
	for (i=0 ; inum!=IBNULL && i<10 ; i++) {
		kprintf("iblock %d: ",inum);
		ibget(diskdev, inum, &iblock);
		for (j=IBLEN-1 ; j>=0&&iblock.ib_dba[j]==DBNULL ; j--)
			;
		if (j < 0)
			kprintf("empty\n");
		else {
			for (k=0 ; k<=j ; k++)
				kprintf("%u ", iblock.ib_dba[k]);
			kprintf("\n");
		}
		inum = iblock.ib_next;
	}
	close(f);
	return(OK);
}

/*------------------------------------------------------------------------
 *  duverbose  --  turn on/off verbose output switch
 *------------------------------------------------------------------------
 */
duverbose(arg)
char	*arg;
{
	int	len;

	if (verbose)
		kprintf("Setting verbose option.\n");
	len = strlen(arg);
	if (len<=3 && strncmp(arg,"yes",len) == 0) {
		verbose = TRUE;
		return(OK);
	} else if (len<=2 && strncmp(arg,"no",len) == 0) {
		verbose = FALSE;
		return(OK);
	}
	kprintf("Argument must be 'yes' or 'no', not '%s'\n", arg);
	return(SYSERR);
}


/*------------------------------------------------------------------------
 *  duwrite  --  overwrite a file taking input from terminal
 *------------------------------------------------------------------------
 */
duwrite(diskdev, fname)
{
	int	f, ich;

	if (verbose)
		kprintf("Writing file %s\n", fname);
	if ( (f=open(diskdev,fname,"wo")) == SYSERR) {
		kprintf("Error opening file %s -- will attempt to create\n",
			fname);
		if ( (f=open(diskdev,fname,"wn")) == SYSERR) {
			kprintf("Can't create file %s\n", fname);
			return(SYSERR);
		}
	}
	kprintf("Enter text; terminate with CNTL-d\n\n");
	while( (ich=inchar(CONSOLE)) != EOF )
		putc(f, ich);
	close(f);
	return(OK);
}


/*------------------------------------------------------------------------
 *  dupzap  --  zap a file from the directory
 *------------------------------------------------------------------------
 */
duzap(diskdev, fname)
int	diskdev;
char	*fname;
{
	struct	fdes	*fdptr, *fdptr2;
	struct	dir	*dirptr;
	int	i, j, sem;
	IBADDR	ilist;

	if (verbose)
		kprintf("Removing file %s from directory\n", fname);
	dirptr = dsdirec(diskdev);
	sem = ((struct dsblk *)devtab[diskdev].dvioblk)->ddirsem;
	wait(sem);
	for (i=0 ; i<dirptr->d_nfiles ; i++) {
		fdptr = &dirptr->d_files[i];
		if (strcmp(fname, fdptr->fdname) == 0) {
			ilist = fdptr->fdiba;
			dirptr->d_nfiles--;
			fdptr2 = &dirptr->d_files[i+1];
			for (j=i ; j<dirptr->d_nfiles ; j++)
				*fdptr++ = *fdptr2++;
			write(diskdev, dskbcpy(dirptr), DIRBLK);
			signal(sem);
			iblfree(diskdev, ilist);
			return(OK);
		}
	}
	kprintf("File %s not found in directory\n", fname);
	signal(sem);
	return(SYSERR);
}


/*------------------------------------------------------------------------
 *  sizeup  --  size up the disk and place number of blocks in dsize
 *------------------------------------------------------------------------
 */
LOCAL	sizeup(diskdev)
int	diskdev;
{
	DBADDR	low, high, mid;

	low = 0;
	high = 31000;
	while (low < high-1) {
		mid = (DBADDR)(low + high)/(DBADDR)2;
		if (read(diskdev,dbuff,mid) == SYSERR)
			high = mid;
		else
			low = mid;
	}
	dsize = low+1;
	niblks = dsize/20;
}


/*------------------------------------------------------------------------
 *  inchar  --  get next input character
 *------------------------------------------------------------------------
 */
LOCAL	inchar(dev)
{
	int	ich;

	if (dev!=CONSOLE)
		return(getc(dev));
	if ( (ich=getc(CONSOLE)) == TERMEOF) {
		while( getc(CONSOLE) != NEWLINE)
			;
		return(EOF);
	} else
		return(ich);
}


/*------------------------------------------------------------------------
 *  getcmd  -- get next command and appropriate number of args.
 *------------------------------------------------------------------------
 */
getcmd()
{
	int	i;

	while (1) {
		kprintf("%s", PROMPT);
		i = duparse();
		sleep10(1);
		if (i != SYSERR)
			return(i);
		else 			
			kprintf("%s\n", msg);
	}
}


/*------------------------------------------------------------------------
 *  duparse  -- parse one command line and return command index
 *------------------------------------------------------------------------
 */
LOCAL	duparse()
{
	int	len, i, nargs, cindex;
	char	ch;

	while( (ch=getc(CONSOLE)) == ' ')
		;
	for (len=0 ; ch!='\n' && ch!=' ' ; ch=getc(CONSOLE))
		buf[len++] = ch;
	if (len == 0)
		return(SYSERR);
	buf[len] = '\000';
	if ( (cindex=lookup(len)) == SYSERR) {
		read(CONSOLE, buf, 0);
		return(SYSERR);
	}
	if ( (nargs=cmds[cindex].cargs) == 0) {
		while (ch != '\n')
			ch = getc(CONSOLE);
		return(cindex);
	}
	while (ch == ' ')
		 ch=getc(CONSOLE);
	if (ch == '\n') {
		kprintf("\nToo few arguments for '%s'\n",
			cmds[cindex].cname);
		return(SYSERR);
	}
	for (len=0 ; ch!='\n' && ch!=' ' ; ch=getc(CONSOLE))
		arg1[len++] = ch;
	arg1[len] = '\000';
	if ( (nargs=cmds[cindex].cargs) <= 1) {
		while (ch != '\n')
			ch = getc(CONSOLE);
		return(cindex);
	}
	while (ch == ' ')
		 ch=getc(CONSOLE);
	if (ch == '\n') {
		kprintf("\nToo few arguments for '%s'\n",
			cmds[cindex].cname);
		return(SYSERR);
	}
	for (len=0 ; ch!='\n' && ch!=' ' ; ch=getc(CONSOLE))
		arg2[len++] = ch;
	arg2[len] = '\000';
	while (ch != '\n')
		ch = getc(CONSOLE);
	return(cindex);
}


/*------------------------------------------------------------------------
 *  lookup  -- lookup a command name in the table, returning its index
 *------------------------------------------------------------------------
 */
LOCAL	lookup(len)
int	len;
{
	int	i;

	for (i=0 ; i<ncmds ; i++)
		if (len <= strlen(cmds[i].cname) &&
		    strncmp(cmds[i].cname, buf, len) == 0)
			return(i);
	return(SYSERR);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.