[comp.os.minix] /etc/mtab support for MINIX mount, umount, and df.

ncpascal@ndsuvax.UUCP (Freeman Pascal) (11/01/87)

Hello,

     I have added support to mount.c, umount.c, and df.c to support use
of a mount table in /etc/mtab.  This allowed mount and df to display
information about mounted file systems when no command line options were
given.  I also fixed a bug in bit_count() in df.c, it would work correctly
for one pass on a filesystem, although, it would overwrite info in other
areas of memory when reading in data.  I fixed this by increasing the amount 
of buffer space it had to work in.

				- Freeman P. Pascal IV
				  ncpascal@ndsuvax 

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 1)."
# Contents:  df.c.diff mount.c.diff mtab.h umount.c.diff
# Wrapped by ncpascal@ndsuvax on Sat Oct 31 20:27:29 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f df.c.diff -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"df.c.diff\"
else
echo shar: Extracting \"df.c.diff\" \(4480 characters\)
sed "s/^X//" >df.c.diff <<'END_OF_df.c.diff'
X2a3,17
X> /*
X>  * History:
X>  *
X>  *	20 Oct 87	fpp	Added support for /etc/mnttab
X>  *	27 Oct 87	fpp	fixed bug in bit_count(), increased size
X>  *				of buf[] to 
X>  *
X>  *					BLOCKSIZE 
X>  *
X>  *				instead of 
X>  *
X>  *					BLOCKSIZE / sizeof( int )
X>  */
X> 
X> #include <stdio.h>
X8,9c23,28
X< #include "stat.h"
X< 
X---
X> #include <sys/stat.h>
X> #include <mtab.h>
X> 
X> struct	mtab	*getmntent();
X> char		*spcs();
X> FILE		*fopen();
X16,24c35,62
X<   register int i;
X< 
X<   if (argc <= 1) {
X< 	std_err("Usage: df special ...\n");
X< 	exit(1);
X<   }
X< 
X<   sync();			/* have to make sure disk is up-to-date */
X<   for (i = 1; i < argc; i++) df(argv[i]);
X---
X>   register int	i;
X>   FILE		*fd;
X>   struct mtab	*mp, mt;
X> 
X>   sync();
X>   prints( "%s%s%s%smode      i-nodes        blocks\n",
X> 	"device", spcs( MNTDEVLEN-6 ),
X> 	"file system", spcs( MNTFSYSLEN-11 ) );
X>   prints( "%sused  free     used  free\n",
X> 	spcs( MNTDEVLEN+MNTFSYSLEN+8 ) );
X>   if (argc == 1) {
X>  	if (( fd = fopen( MNTTAB, "r" )) == -1 ) {
X> 		perror( MNTTAB );
X> 		exit( 1 );
X> 	}
X> 	while(( fread( &mt, sizeof( struct mtab ), 1, fd)) != 0 ) {
X> 		df( &mt ); 
X> 	}
X> 	fclose( fd );
X>   } else
X> 	for (i = 1; i < argc; i++)
X> 		if (( mp = getmntent( argv[i] )) != NULL )
X> 			df( mp );
X> 		else {
X> 			std_err( argv[i] );
X> 			std_err( " not a valid file system.\n" );
X> 			exit( 1 );
X> 		}
X29,30c67,68
X< df(name)
X< char *name;
X---
X> df( mp )
X>   struct mtab	*mp;
X38,39c76,77
X<   if ( (fd = open(name,0)) < 0) {
X< 	perror(name);
X---
X>   if ( (fd = open( mp->mt_dev,0)) < 0) {
X> 	perror(mp->mt_dev);
X45c83
X< 	stderr2(name, ": Cannot stat\n");
X---
X> 	stderr2( mp->mt_dev, ": Cannot stat\n");
X49c87
X< 	stderr2(name, ": not a block special file\n");
X---
X> 	stderr2( mp->mt_dev, ": not a block special file\n");
X55c93
X< 	stderr2(name, ": Can't read super block\n");
X---
X> 	stderr2( mp->mt_dev, ": Can't read super block\n");
X64c102
X< 	stderr2(name, ": Not a valid file system\n");
X---
X> 	stderr2( mp->mt_dev, ": Not a valid file system\n");
X71c109
X< 	stderr2(name, ": can't find bit maps\n");
X---
X> 	stderr2( mp->mt_dev, ": can't find bit maps\n");
X75,78c113,116
X< 
X<   z_count = bit_count(sp->s_zmap_blocks, sp->s_nzones, fd);
X<   if (z_count < 0) {
X< 	stderr2(name, ": can't find bit maps\n");
X---
X>   
X>   z_count = bit_count(sp->s_zmap_blocks, sp->s_nzones, fd);
X>   if (z_count < 0) {
X> 	stderr2( mp->mt_dev, ": can't find bit maps\n");
X85,99c123,130
X<   /* Print results. */
X<   prints("%s ",name);
X<   s0 = name;
X<   while (*s0) s0++;
X<   i = 12 - (s0 - name);
X<   while (i--) prints(" ");
X<   prints("i-nodes: ");
X<   num3(i_count - 1);
X<   prints(" used  ");
X<   num3(sp->s_ninodes + 1 - i_count);
X<   prints(" free      blocks: ");
X<   num3(busyblocks);
X<   prints(" used  ");
X<   num3(totblocks - busyblocks);
X<   prints(" free\n");
X---
X>   fprintf( stdout, "%s%s%s%s %s    %5d %5d    %5d %5d\n",
X> 	mp->mt_dev, spcs( MNTDEVLEN-strlen( mp->mt_dev )),
X> 	mp->mt_filsys, spcs( MNTFSYSLEN-strlen( mp->mt_filsys )),
X> 	mp->mt_ro_flg ? "RO" : "RW",
X> 	i_count, sp->s_ninodes+1-i_count,
X> 	busyblocks, totblocks-busyblocks 
X>   );	
X> 
X108,111c139,142
X<   register int i, b;
X<   int busy, count, w;
X<   int *wptr, *wlim;
X<   int buf[BLOCK_SIZE/sizeof(int)];
X---
X>   register int	i, b;
X>   int		busy, count, w;
X>   int		*wptr, *wlim;
X>   int		buf[ BLOCK_SIZE ];
X117,118c148,149
X< 	if (read(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) return(-1);
X< 
X---
X> 	if (read(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) 
X> 		return(-1);
X136,152c167,203
X< 
X< stderr2(s1, s2)
X< char *s1, *s2;
X< {
X<   std_err(s1);
X<   std_err(s2);
X< }
X< 
X< num3(n)
X< int n;
X< {
X<   extern char *itoa();
X<   if (n < 10) prints("   %s", itoa(n));
X<   else if (n < 100) prints("  %s", itoa(n));
X<   else if (n < 1000) prints(" %s", itoa(n));
X<   else prints("%s", itoa(n));
X< }
X---
X> struct	mtab	*
X> getmntent( dev_path )
X>   char	*dev_path;
X> {
X> 	FILE			*fd;
X> 	static struct mtab	mbuf;
X> 	
X> 	if (( fd = fopen( MNTTAB, "r" )) < 0 ) {
X> 		perror( MNTTAB );
X> 		exit( 1 );
X> 	}
X> 	while ( fread( &mbuf, sizeof( struct mtab ), 1, fd) != 0 )
X> 		if (strcmp( mbuf.mt_dev, dev_path ) == 0 )
X> 			return( &mbuf );
X> 	fclose( fd );
X> 	return( NULL );
X> }
X> 
X> stderr2(s1, s2)
X> char *s1, *s2;
X> {
X>   std_err(s1);
X>   std_err(s2);
X> }
X> 
X> char	*
X> spcs( n )
X>   int	n;
X> {
X> 	static char	*sstr = "                                                                           ";
X> 	char		*sp;
X> 
X> 	sp = sstr;
X> 	while(*sp) sp++;
X> 	while(n--) sp--;
X> 	return( sp );
X> }
END_OF_df.c.diff
if test 4480 -ne `wc -c <df.c.diff`; then
    echo shar: \"df.c.diff\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mount.c.diff -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"mount.c.diff\"
else
echo shar: Extracting \"mount.c.diff\" \(3358 characters\)
sed "s/^X//" >mount.c.diff <<'END_OF_mount.c.diff'
X3c3,21
X< #include "errno.h"
X---
X> /*
X>  *  History:
X>  *
X>  *	19 Oct 87	FPP	added support for /etc/mnttab, mount table
X>  *	28 Oct 87	FPP	added support to make root file system the
X>  *				first entry in /etc/mnttab when created.
X>  */
X> 
X> #include	<stdio.h>
X> #include	<sys/types.h>
X> #include	<sys/stat.h>
X> #include	<sys/dir.h>
X> #include	<mtab.h>	
X> #include	<errno.h>
X> 
X> struct mtab	*getrootdev();
X> FILE		*fopen();
X> char		*spaces();
X> 
X11,12c29,48
X<   int ro;
X< 
X---
X>   int 		ro, n, mnttab_flg = 0;
X>   struct mtab	mt;
X>   FILE		*fd;
X> 
X>   if (argc == 1) {
X>  	if (( fd = fopen( MNTTAB, "r" )) == -1 ) {
X> 		perror( MNTTAB );
X> 		exit( 1 );
X> 	}
X> 	prints( "\nmode  %s%s%s\n\n",
X> 		"file system", spaces( MNTDEVLEN-11 ),
X> 		"mounted on" );
X> 	while(( fread( &mt, sizeof( struct mtab ), 1, fd)) != 0 ) 
X> 		prints( " %s   %s%s%s\n", 
X> 			mt.mt_ro_flg ? "RO" : "RW",
X> 			mt.mt_dev, spaces( MNTDEVLEN-strlen( mt.mt_dev )), 
X> 			mt.mt_filsys );
X> 	fclose( fd );
X> 	exit( 1 );
X>   }
X26,36c62,160
X<   std_err(argv[1]);
X<   std_err(" mounted\n");
X<   exit(0);
X< }
X< 
X< 
X< usage()
X< {
X<   std_err("Usage: mount special name [-r]\n");
X<   exit(1);
X< }
X---
X> /*
X>  *  add entry to /etc/mnttab
X>  */
X>   strcpy( mt.mt_dev, argv[1] );
X>   strcpy( mt.mt_filsys, argv[2] );
X>   mt.mt_ro_flg = ro;
X>   if (( mnttab_flg = access( MNTTAB, 0 )) == -1)	/* does /etc/mnt exist?	*/
X> 	if (creat( MNTTAB, 0644 ) == -1) {
X> 		perror( MNTTAB );
X> 		exit( 1 );
X> 	}
X>   if ((fd = fopen( MNTTAB, "a" )) == -1 ) {
X> 	std_err( "\nmount:  cannot open " );
X> 	std_err( MNTTAB );
X> 	std_err( "\n" );
X> 	exit( 1 );
X>   }
X> 
X>   /* 
X>    * if /etc/mtab is newly created we must add root file system entry
X>    */
X>   if (mnttab_flg) 
X> 	fwrite( getrootdev( NULL ), sizeof( struct mtab ), 1, fd );
X>   fwrite( &mt, sizeof( struct mtab ), 1, fd );	/* append new entry	*/
X>   fclose( fd );
X> 
X>   std_err(argv[1]);
X>   std_err(" mounted\n");
X>   exit(0);
X> }
X> 
X> #define	ROOT		"/"
X> #define DEV_PATH	"/dev/"
X> 
X> struct mtab *
X> getrootdev( mntp )
X>   struct mtab	*mntp;
X> {
X> 	static struct mtab	*mp, mbuf;
X> 	struct stat		rstat, sbuf;
X> 	struct direct		dir;
X> 	char			buf[64];
X> 	int			fd;
X> 
X> 
X> 	if ( stat( ROOT, &rstat ) < 0 ) 
X> 		return( NULL );	/* cannot get status of root */
X> 
X> 	if (( fd = open( DEV_PATH, 0 )) < 0 ) {
X> 		perror( DEV_PATH );
X> 		return( NULL );
X> 	}
X> 	while( read( fd, &dir, sizeof( dir ))) {
X> 		if (dir.d_ino == NO_ENTRY)
X> 			continue;		/* nothing here	*/
X> 		strcpy( buf, DEV_PATH );
X> 		strcat( buf, dir.d_name );
X> 		if ( stat( buf, &sbuf ) < 0 ){
X> 			perror( buf );
X> 			continue;
X> 		}
X> 		if (( sbuf.st_mode & S_IFMT ) != S_IFBLK )
X> 			continue;	/* if block special file	*/
X> 		if ( sbuf.st_rdev == rstat.st_dev ) 
X> 			break;
X> 	}
X> 	close( fd );
X> 	if ( sbuf.st_rdev == rstat.st_dev ) {
X> 		mp = ( mntp == NULL ) ? &mbuf : mntp;
X> 		strcpy( mp->mt_dev, buf );
X> 		strcpy( mp->mt_filsys, ROOT );
X> 		/* check if we have write permission */
X> 		mp->mt_ro_flg = access( ROOT, 02 ); 
X> 		return( mp );
X> 	} else
X> 		return( NULL );
X> }
X> 
X> 
X> char	*
X> spaces( n )
X>   int	n;
X> {
X>   char	*rs, *sp;
X> 
X>   if (( rs = (char *) malloc( n )) == NULL )
X> 	return( NULL );
X>   sp = rs;
X>   while( n-- )
X> 	*sp++ = ' ';
X>   *sp = NULL;
X>   return( rs );
X> }
X> 
X> usage()
X> {
X>   std_err("Usage: mount special name [-r]\n");
X>   exit(1);
X> }
END_OF_mount.c.diff
if test 3358 -ne `wc -c <mount.c.diff`; then
    echo shar: \"mount.c.diff\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mtab.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"mtab.h\"
else
echo shar: Extracting \"mtab.h\" \(215 characters\)
sed "s/^X//" >mtab.h <<'END_OF_mtab.h'
X/*
X *	mtab.h
X *
X *	mount table structures
X *
X */
X
X#define	MNTTAB		"/etc/mtab"
X#define	MNTDEVLEN	16
X#define	MNTFSYSLEN	16
X
Xstruct	mtab {
X	char	mt_dev[ MNTDEVLEN ];
X	char	mt_filsys[ MNTFSYSLEN ];
X	short	mt_ro_flg;
X};
END_OF_mtab.h
if test 215 -ne `wc -c <mtab.h`; then
    echo shar: \"mtab.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f umount.c.diff -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"umount.c.diff\"
else
echo shar: Extracting \"umount.c.diff\" \(2124 characters\)
sed "s/^X//" >umount.c.diff <<'END_OF_umount.c.diff'
X3c3,10
X< #include "errno.h"
X---
X> /*
X>  * History:
X>  *	27 Oct 87	FPP	added support for /etc/mtab
X>  */
X> 
X> #include <stdio.h>
X> #include <errno.h>
X> #include <mtab.h>
X6a14,16
X> struct mtab	*getmntent();
X> FILE		*fopen();
X> 
X11,21c21,36
X< 
X<   if (argc != 2) usage();
X<   if (umount(argv[1]) < 0) {
X< 	if (errno == EINVAL) 
X< 		std_err("Device not mounted\n");
X< 	else
X< 		perror("umount");
X< 	exit(1);
X<   }
X<   std_err(argv[1]);
X<   std_err(" unmounted\n");
X---
X>   struct mtab	*mt;
X> 
X>   if (argc != 2) usage();
X> 
X>   for( i = 1; i++ < argc; ) {  
X> 	if (umount(argv[1]) < 0) {
X> 		if ((errno == EINVAL) || (mt == NULL))
X> 			std_err("Device not mounted, but listed in /etc/mtab.\n");
X> 		else
X> 			perror("umount");
X> 		exit(1);
X> 	}
X> 	update_mtab( argv[1] );	
X> 	std_err(argv[1]);
X> 	std_err(" unmounted\n");
X>   }
X25,29c40,93
X< usage()
X< {
X<   std_err("Usage: umount special\n");
X<   exit(1);
X< }
X---
X> update_mtab( dev )
X>   char	*dev;
X> {
X>   struct mtab	mt;
X>   FILE		*fin, *fout;
X>   char		*ftmp = "/tmp/mtab\0           ";
X> 
X>   if (( fin = fopen( MNTTAB, "r" )) < 0 ) {
X> 	perror( MNTTAB );
X> 	exit( 1 );
X>   }
X>   if (( fout = fopen( strcat( ftmp, itoa( getpid())), "w" )) < 0 ) {
X> 	perror( ftmp );
X> 	exit( 1 );
X>   }
X>   while(( fread( &mt, sizeof( struct mtab ), 1, fin)) != 0 ) {
X> 	if (strcmp( mt.mt_dev, dev ) != 0 )
X> 		fwrite( &mt, sizeof( struct mtab ), 1, fout );
X>   }
X>   fclose( fin );
X>   fclose( fout );
X>   unlink( MNTTAB );			/* delete /etc/mtab		*/
X>   if ( link( ftmp, MNTTAB ) == -1 ) {	/* link tmp file to /etc/mtab	*/
X> 	perror( ftmp );
X> 	exit( 1 );
X>   }
X>   unlink( ftmp );			/* delete tmp file link		*/
X> }
X> 
X> struct	mtab	*
X> getmntent( dev_path )
X>   char	*dev_path;
X> {
X> 	FILE			*fd;
X> 	static struct mtab	mbuf;
X> 	
X> 	if (( fd = fopen( MNTTAB, "r" )) < 0 ) {
X> 		perror( MNTTAB );
X> 		exit( 1 );
X> 	}
X> 	while ( fread( &mbuf, sizeof( struct mtab ), 1, fd) != 0 )
X> 		if (strcmp( mbuf.mt_dev, dev_path ) == 0 ) {
X> 			fclose( fd );
X> 			return( &mbuf );
X> 		}
X> 	fclose( fd );
X> 	return( NULL );
X> }
X> 
X> usage()
X> {
X>   std_err("Usage: umount special\n");
X>   exit(1);
X> }
END_OF_umount.c.diff
if test 2124 -ne `wc -c <umount.c.diff`; then
    echo shar: \"umount.c.diff\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 1 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0