PWB1/sys/source/s2/mv.c
/*
* mv file1 file2
*/
struct
{
int dev;
int inum;
int imode;
char nlink;
char uid;
char gid;
char siz0;
char siz1;
int addr[8];
int adate[2];
int mdate[2];
} sbuf1, sbuf2;
char strbuf[100];
main(argc, argv)
char *argv[];
{
char **argp;
char *p1, *p2, *source, *target;
int i;
int b;
argp = argv;
if(argc != 3) {
printf("mv: Usage: mv name1 name2\n");
return(1);
}
source = argp[1];
target = argp[2];
if(stat(source, &sbuf1) < 0) {
printf("mv: %s non-existent\n", source);
return(1);
}
if((sbuf1.imode & 060000) == 040000)
goto mvdir;
setuid(getuid());
if(stat(target, &sbuf2) >= 0) {
if((sbuf2.imode & 060000) == 040000) {
p2 = strbuf;
while(*p2++ = *target++)
;
p2[-1] = '/';
target = argp[1];
p1 = argp[1];
while(*target)
if(*target++ == '/')
p1 = target;
while(*p2++ = *p1++)
;
target = strbuf;
}
if(stat(target, &sbuf2) >= 0) {
if(sbuf1.dev == sbuf2.dev && sbuf1.inum == sbuf2.inum) {
printf("mv: %s and %s are identical\n", source, target);
return(1);
}
if(access(target, 2)<0 && ttyn(0)!='x') {
printf("mv: %s: %o mode ", target,
sbuf2.imode & 07777);
i = b = getchar();
while(b != '\n' && b > 0)
b = getchar();
if(i != 'y')
return(1);
}
if(unlink(target) < 0) {
printf("mv: Cannot unlink %s\n", target);
return(1);
}
}
}
if(link(source, target) < 0) {
i = fork();
if(i == -1) {
printf("mv: Try again\n");
return(1);
}
if(i == 0) {
execl("/bin/cp", "cp", source, target, 0);
printf("mv: No cp\n");
return(1);
}
while(wait(&b) != i)
;
if(b != 0)
return(1);
}
if(unlink(source) < 0) {
printf("mv: Cannot unlink %s\n", source);
return(1);
}
return(0);
mvdir:
if(stat(target, &sbuf2) >= 0) {
printf("mv: Directory %s exists\n", target);
return(1);
}
p1 = source;
p2 = target;
while(*p1 == *p2) {
p1++;
if(*p2++ == 0) {
printf("mv: ?? source == target, source exists and target doesnt\n");
return(1);
}
}
while(*p1)
if(*p1++ == '/') {
printf("mv: Directory rename only\n");
return(1);
}
while(*p2)
if(*p2++ == '/') {
printf("mv: Directory rename only\n");
return(1);
}
if (*--p1=='.' && p1==source
|| *--p1=='.' && p1==source) {
printf("mv: Cannot rename %s\n", source);
return(1);
}
b = 0;
p1 = source;
while(*p1)
if(*p1++ == '/') {
p2 = p1;
b++;
}
p1 = source;
if(b == 0) {
p1 = ".";
p2 = p1+2;
}
*--p2 = '\0';
if(access(p1, 2) < 0) {
printf("mv: No write access to %s\n", p1);
return(1);
}
*p2 = '/';
if(link(source, target) < 0) {
printf("mv: ?? directory link failed\n");
return(1);
}
if(unlink(source) < 0) {
printf("mv: ?? directory unlink failed\n");
return(1);
}
return(0);
}
getchar()
{
int c;
c = 0;
read(0, &c, 1);
return(c);
}