AUSAM/source/S/mv.c

Compare this file to the similar file:
Show the results in this format:

#include	<local-system>

/*
 *	mv [-d] file1 file2
 *
 *	unlink file2
 *	link file1 file2
 *	unlink file1
 */

struct sbuf
{
	int dev;
	int inum;
	int imode;
#ifdef	AUSAM
	unsigned uid;
#endif
	char nlink;
#ifndef	AUSAM
	char uid;
	char gid;
#endif
	char siz0;
	char siz1;
	int addr[8];
	int adate[2];
	int mdate[2];
};

int stbuf[42];
char strbuf[70];

main(argc,argv)
int argc;
register char **argv;
{
	char *argp1,	*argp2,	*argp3,	*argp4;
	char *p,	*p1,	*p2;
	char place[100];
	int b,	i,	status;
#ifdef	AUSAM
	unsigned u_id;
#endif	AUSAM

	/*
	 *	check for correct number of arguments
	 */
	if(argc != 3)
	{
		prints(2, "Usage: mv name1 name2\n");
		return 1;
	}
	/*
	 *	is there anything to do?
	 */
	argp3 = argv[1];
	argp4 = argv[2];
#ifndef	AUSAM
	if( stat(argv[1], stbuf) == -1)
#else
	if( newstat(argv[1], stbuf) == -1)
#endif	AUSAM
	{
		perror( argv[1] );
		return 1;
	}
	/*
	 *	yes, there is a source.
	 *	check whether file or directory
	 */
	if( (stbuf[0].imode & 060000 ) == 040000)
	{
		/*
		 *	The source is a directory, so
		 *	we do lots of checking and
		 *	messing around so as not to get
		 *	into trouble.  This patch of
		 *	code contains administrative
		 *	policies rather than system
		 *	restrictions.
		 */
#ifndef	AUSAM
		if( stat(argv[2], stbuf) != -1)
#else
		if( newstat(argv[2], stbuf) != -1)
#endif	AUSAM
		{
			prints(2, "Directory target exists.\n");
			return 1;
		}
		argp1 = argv[1];
		argp2 = argv[2];
		while(*argp1 == *argp2)
		{
			argp1++;
			if(*argp2++ == 0)
			{
				prints(2, "???\n");
				return 1;
			}
		}
		while(*argp1)if(*argp1++ == '/')
		{
			prints(2, "Directory rename only\n");
			return 1;
		}
		while(*argp2)if(*argp2++ == '/')
		{
			prints(2, "Directory rename only\n");
			return 1;
		}
		if(*--argp1 == '.')
		{
			prints(2, "Can't move . or .. !\n");
			return 1;
		}
		if( access("",2) )
		{
			perror(".");
			exit(1);
		}
	}
	else
	{
		/*
		 *	the source is a file.
		 */
#ifndef	AUSAM
		setuid(getuid());
		if( stat(argp4, &stbuf[2]) != -1 )
#else
		setuid(u_id = getreal());
		if(newstat(argp4, &stbuf[2]) != -1)
#endif	AUSAM
		{
			if( (stbuf[2].imode & 060000) == 040000 )
			{
				argp2 = strbuf;
				while(*argp2++ = *argp4++);
				argp2[-1] = '/';
				argp4 = argv[1];
				argp1 = argv[1];
				while(*argp4)
				{
					if(*argp4++ == '/')
						argp1 = argp4;
				}
				while(*argp2++ = *argp1++);
				argp4 = strbuf;
			}
#ifndef	AUSAM
			if(stat(argp4, &stbuf[2]) != -1)
#else
			if(newstat(argp4, &stbuf[2]) != -1)
#endif	AUSAM
			{
				if((stbuf[0]==stbuf[2]) && (stbuf[1]==stbuf[3]))
				{
					prints(2, "Files are identical.\n");
					return 1;
				}
				if( access(argp4,2) )
				{
					printf("%s: mode %o: (y-n) ", argp4,
						stbuf[2].imode & 07777);
					i = b = getchar();
					while(b != '\n' && b != '\0')
						b = getchar();
					if(i != 'y')
						return 0;
				}
				if(unlink(argp4) < 0)
				{
					perror(argp4);
					return 1;
				}
			}
		}
	}
	if(link(argp3, argp4) == -1)
	{
		i = fork();
		if(i == -1)
		{
			perror("try again");
			return 1;
		}
		if(i)
		{
			while(waitx(&status) != i);
		}
		else
		{
			p = place;
			p1 = p;
			while(*p++ = *argp3++);
			p2 = p;
			while(*p++ = *argp4++);
			execl("/bin/cp","cp", p1, p2, 0);
			perror("cp");
			exit(1);
		}
		if((status & 0377) != 0)
		{
			prints(2, "?\n");
			return 1;
		}
		if(status != 0)
			return 1;
	}
	if(unlink(argp3) < 0)
	{
		perror(argp3);
		return 1;
	}
}