/*
 * $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred."
 *
 */
/*	Copyright (c) 1984 AT&T	*/
/*	  All Rights Reserved  	*/

/*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*/
/*	The copyright notice above does not evidence any   	*/
/*	actual or intended publication of such source code.	*/

#ident	"$Header: 4.2fstyp.c 1.2 89/10/10 $@(#)fstyp:4.2fstyp.c	1.0"
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/ufsfilsys.h>

#define  SUCCESS	 0
#define  FAILURE	-1
#define  cmd		4.2fstyp

void	exit();
long	lseek();

main(argc,argv)
int	argc;
char	*argv[];
{

	int	fd;
	long	bsize = 0;
	char	*dev;
	char	*usage = "fstyp special";
	struct	stat	buf;
	struct	fs	*sblock;


	if (argc != 2) {
		fprintf(stderr,"Usage: %s\n",usage);
		exit(1);
	}

	dev = argv[1];
	if (stat(dev, &buf) < 0) {
		fprintf(stderr, "cmd: cannot stat <%s>\n",dev);
		exit(1);
	}

	if (((buf.st_mode & S_IFMT) != S_IFBLK) 
		&& ((buf.st_mode & S_IFMT) != S_IFCHR)) {
		fprintf(stderr,"cmd: <%s> is not a block, or a character device\n",dev);
		exit(1);
	}

	/*
	 *	Read the super block associated with the device. 
	 */

	if ((fd = open(dev, O_RDONLY)) < 0) {
		fprintf(stderr,"cmd: cannot open <%s>\n",dev);
		exit(1);
	}
	
	if ((sblock = (struct fs *)valloc(SBSIZE)) == NULL) {
		fprintf(stderr,"cmd: cannot read superblock\n");
		close(fd);
		exit(1);
	}
	if (lseek(fd, (long)dbtob(SBLOCK), 0) < 0
		|| read(fd, sblock, SBSIZE) != SBSIZE) {
		fprintf(stderr,"cmd: cannot read superblock\n");
		close(fd);
		exit(1);
	}
	close(fd);
	
	/*
	 *	Determine if it is a System V file system and set the
	 *	block size.
 	 */
	
#ifdef i386
	if (sblock->fs_magic != FS_MAGIC) {
		fprintf(stderr,"cmd: <%s> is not a 4.2 file system\n",dev);
		exit(1);
	}
#else
	if (sblock.s_magic == FsMAGIC) {
		switch (sblock.s_type) {
			case Fs1b:
				bsize = BSIZE;
				break;
			case Fs2b:
#ifdef u3b15
				bsize = 4 * BSIZE;
#else
				bsize = 2 * BSIZE;
#endif
				break;
			default:
				fprintf(stderr,"cmd: <%s> is not a System V file system\n",dev);
				exit(1);
		}
	} else {
		fprintf(stderr,"cmd: <%s> is not a System V file system\n",dev);
		exit(1);
	}

	if (sanity_check(sblock,bsize) == FAILURE) {
		fprintf(stderr,"cmd: 4.2 file system sanity check failed\n");
		exit(1);
	}
#endif /* i386 */
	fprintf(stdout,"4.2\n");
	exit(0);
}

#ifndef i386
sanity_check(sblock,bsize)
struct	fs	*sblock;
long	bsize;
{


	sblock->s_isize -= 2;
	if (sblock->s_fsize <= sblock->s_isize
		|| sblock->s_fsize < sblock->s_tfree
		|| sblock->s_isize < sblock->s_tinode*sizeof(struct dinode)/bsize
		|| (long)sblock->s_isize*bsize/sizeof(struct dinode) > 0x10000L) {
		return(FAILURE);
	}
	return(SUCCESS);
}
#endif /* ! i386 */
