/* rmi.c
 *
 * Remove file in the current directory by inode number.
 *
 * If links we remove only one of them.
 * All links IN THE CURRENT DIRECTORY are removed with the -a option.
 *
 */

#define NO_PROTOTYPE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/dir.h>


extern void perror();

char _sccsid[] = { " rmi.c 1.3 12/25/96 " };
int onlyfirst;

main( argc, argv )
int argc;
char **argv;
{
	extern char *getcwd();

	int rmfbyi();

	char dirname[ LPNMAX ];
	/* Note: ino_t is a typedef in <sys/types> that is unsigned short */
	ino_t inode;
	int lnks;

	if( argc < 2 || argc > 3 )    {
		fprintf( stderr, "Usage: %s [-a] inode\n", argv[ 0 ] );
		exit( 1 );
	}
	if( argc == 2 )    {
		onlyfirst = 1;
		sscanf( argv[ 1 ], "%u", &inode );
	}
	else if( argc == 3 )    {
		if( strcmp( argv[ 1 ], "-a" ) == 0 )    {
			onlyfirst = 0;
			sscanf( argv[ 2 ], "%u", &inode );
		}
		else    {
			fprintf( stderr, "Bad option: %s\n", argv[ 0 ], argv[ 1 ] );
			fprintf( stderr, "Usage: %s [-a] inode\n", argv[ 0 ] );
			exit( 1 );
		}
	}

	getcwd( dirname, LPNMAX + 2 );

	switch( lnks = rmfbyi( dirname, inode ) )    {
		case -1:
			fprintf( stderr, "%s cannot read current directory\n", argv[ 0 ] );
			perror( argv[ 0 ] );
			exit( 1 );
		case -2:
			/* Unlink has failed */
			perror( argv[ 0 ] );
			exit( 1 );
		case 0:
			fprintf( stderr, "%s cannot find inode %u in current directory\n", argv[ 0 ], inode );
			exit( 1 );
		case 1:
			/* Successful removal of single inode entry */
			break;
		default:
			/* Successful removal of linked inode entries */
			printf( "%s: all links (%d) removed\n", argv[ 0 ], lnks );
			break;
	}

	exit( 0 );
	return( 0 );
}

int rmfbyi( dirname, inode )
char *dirname;
ino_t inode;
{
	struct direct dirbuf;
	char filname[ LPNMAX ];
	int cnt;
	int fd;

	if( ( fd = open( dirname, O_RDONLY ) ) == -1 )
		return( -1 );

	cnt = 0;
	while( read( fd, (char *)&dirbuf, sizeof( dirbuf ) ) > 0 )    {
		/* NEVER alter current or parent directory */
		if( strcmp( dirbuf.d_name, "." ) == 0
		 || strcmp( dirbuf.d_name, ".." ) == 0 )
			continue;

		if( dirbuf.d_ino == inode )    {
			/* A matching directory entry found */
			sprintf( filname, "%s/%s", dirname, dirbuf.d_name );
			if( unlink( filname ) == -1 )    {
				/* unlink failure */
				close( fd );
				return( -2 );
			}
			++cnt;
		}
		if( onlyfirst && cnt == 1 )
			break;

		/* Otherwise we unlink all entries with the same inode number.
		 * (-a option has been used).
		 */
	}

	close( fd );

	return( cnt );
}


Return to Home Page
Return to Metayoga Page
Return to C Language Page


The URL for this document is:
http://graham.main.nc.us/~bhammel/graham/CPROGS/rmi.html
Created: 1997
Last Updated: May 28, 2000 Email me, Bill Hammel at
bhammel@graham.main.nc.us
READ WARNING BEFORE SENDING E-MAIL