[comp.unix.questions] is a PD implementation of statfs

afc@shibaya.lonestar.org (Augustine Cano) (10/02/90)

While trying to compile Chip Rosenthal's enhanced du, recently posted, I
realized that the Unix PC doesn't have the statfs() system call and
associated .h file.  The quick way out, hardwiring the values for a
specific file system, is not the most elegant and portable solution.
So, does anyone know of PD statfs()?

-- 
Augustine Cano		INTERNET: afc@shibaya.lonestar.org
			UUCP:     ...!{ernest,tsci,egsner}!shibaya!afc

dave@galaxia.Newport.RI.US (David H. Brierley) (10/06/90)

>So, does anyone know of PD statfs()?

I have started to work on a PD statfs call but I ran into a slight problem in
that I was not sure exactly what the call was supposed to do.  In general I
know that it returns info about a mounted file system but I'm not sure what
info it is supposed to return.  I looked through the "du" program that was
posted and determined what fields from the structure it was examining and
put togethor an include file and a library function that would fill in those
fields.  If anyone can send me a copy of the description of the statfs routine
then I can finish writing the routine and post it.

Of course, if someone already has a PD version of statfs that they are
willing to post I would gladly use that instead.  One drawback to the statfs
routine that I have started to write is that all the information you need to
know is contained in the file systems superblock.  This means that you either
have to be writing kernel level code so that you can access the incore copy
of the superblock or you have to have read access to the raw file system or
you have to figure out how to poke through the kernel memory and find the
incore copy of the superblock.

Anyway, when I finish my statfs routine I will post it and in the meantime I
have a *very crude* version which will work on the 3B1 (theoritically it should
work on any systemV) and will supply the fields required by the du program.
If you want a copy of this preliminary version, let me know and I will send
you a copy.
-- 
David H. Brierley
Home: dave@galaxia.Newport.RI.US    Work: dhb@quahog.ssd.ray.com
Be excellent to each other.

kimcm@diku.dk (Kim Christian Madsen) (10/07/90)

dave@galaxia.Newport.RI.US (David H. Brierley) writes:

>>So, does anyone know of PD statfs()?

>I have started to work on a PD statfs call but I ran into a slight problem in
>that I was not sure exactly what the call was supposed to do.  In general I
>know that it returns info about a mounted file system but I'm not sure what
>info it is supposed to return.  I looked through the "du" program that was
>posted and determined what fields from the structure it was examining and
>put togethor an include file and a library function that would fill in those
>fields.  If anyone can send me a copy of the description of the statfs routine
>then I can finish writing the routine and post it.

>Of course, if someone already has a PD version of statfs that they are
>willing to post I would gladly use that instead.  One drawback to the statfs
>routine that I have started to write is that all the information you need to
>know is contained in the file systems superblock.  This means that you either
>have to be writing kernel level code so that you can access the incore copy
>of the superblock or you have to have read access to the raw file system or
>you have to figure out how to poke through the kernel memory and find the
>incore copy of the superblock.

OK, once I've written a statfs() simulation routine for the AIX system,
running on an IBM PC-RT6150. If you can use it feel free to do it, but
remember you might have to hack it to please your particular superblock.

If you however use SYSV R3.0 or later you should have statfs(2) as
an integral part of your system call routines.

				Kim Chr. Madsen

/*-------------------------CUT HERE-------------------------*/
#ifdef HAS_STATFS
#include <sys/statfs.h>
#else
#include <sys/param.h>
#include <sys/filsys.h>
#include <sys/ino.h>
#endif

#define	MNTTAB	"/etc/mnttab"
#define	MNTSIZ	sizeof(struct mnttab)

struct mnttab mt;

#ifndef	HAS_STATFS
struct statfs {
	short	f_fstyp;	/* File system type */
	short	f_bsize;	/* Block Size */
	short	f_frsize;	/* Fragment Size */
	long	f_blocks;	/* Total number of blocks */
	long	f_bfree;	/* Count of free blocks */
	long	f_files;	/* Total number of file nodes */
	long	f_ffree;	/* Count of free file nodes */
	char	f_fname[6];	/* Volume name */
	char	f_fpack[6];	/* Pack Name */
};
#endif /* HAS_STATFS */


#ifndef	HAS_STATFS

#define	HD_BLOCKSIZE	2048
#define	FD_BLOCKSIZE	 512

int statfs(path,buf,len,fstyp)
char		*path;
struct statfs	*buf;
int		len, fstyp;
{
	int		fd;
	int		mntfd;
	struct mnttab	tab;
	filsys_t	fs;
	register int	i;
	char		devicename[256];
	void		sync();		/* Update superblock(s) */

	if (fstyp) return(-1);
	if ((mntfd=open(MNTTAB,O_RDONLY)) < 0) return(-1);
	devicename[0] = 0;
	while (read(mntfd,(char *)&tab,MNTSIZ) == MNTSIZ) {
		if (strcmp(path,tab.mt_filsys) == 0) {
			sprintf(devicename,"/dev/%s",tab.mt_dev);
			break;
		}
	}
	if (devicename[0] == 0) return(-1);
	sync();
	if ((fd=open(devicename,O_RDONLY)) < 0) return(-1);
	lseek(fd,HD_BLOCKSIZE,0);
	if (read(fd,(char *)&fs,FSfixsz) != FSfixsz)  return(-1);
	if (strncmp(fs.s_magic,FSmagic,4)) return(-1);
	buf->f_fstyp = (short) fs.s_type;
	switch (fs.s_type) {
	case Fs1b: buf->f_bsize = 512; break;
	case Fs2b: buf->f_bsize = 1024; break;
	case Fs4b: buf->f_bsize = 2048; break;
	case Fs8b: buf->f_bsize = 4096; break;
	}
	buf->f_frsize = 0;	/* Unknown Value in superblock */
	buf->f_blocks = (long) fs.s_fsize;
	buf->f_bfree  = (long) fs.s_tfree;
	buf->f_files  = (long) (fs.s_isize*buf->f_bsize)/sizeof(struct dinode);
	buf->f_ffree  = (long) fs.s_tinode;
	for (i=0; i<6; i++) {
		buf->f_fname[i] = fs.s_fname[i];
		buf->f_fpack[i] = fs.s_fpack[i];
	}
	close(mntfd);
	close(fd);
	return(0);
}

#endif /* HAS_STATFS */