1: /* 2: mv [-d] file1 file2 3: 4: unlink file2 5: link file1 file2 6: unlink file1 7: */ 8: int stbuf[42]; 9: struct sbuf { 10: int dev; 11: int inum; 12: int imode; 13: char nlink; 14: char uid; 15: char gid; 16: char siz0; 17: char siz1; 18: int addr[8]; 19: int adate[2]; 20: int mdate[2]; 21: }; 22: char strbuf[70]; 23: 24: main(argc,argv) 25: int argc; 26: char *argv[]; 27: { 28: char **argp; 29: char *argp1, *argp2, *argp3, *argp4; 30: char *p, *p1, *p2; 31: char place[100]; 32: int i; 33: int status; 34: int b; 35: argp = argv; 36: /* 37: check for correct number 38: of arguments 39: */ 40: if(argc != 3){ 41: write(1,"Usage: mv name1 name2\n",22); 42: exit(); 43: } 44: /* 45: is there anything to do? 46: */ 47: argp3 = argp[1]; 48: argp4 = argp[2]; 49: if(stat(argp[1], stbuf) < 0){ 50: write(1,"Source file non-existent\n",25); 51: exit(); 52: } 53: /* 54: yes, there is a source. 55: check whether file or directory 56: */ 57: if((stbuf[0].imode & 060000) == 040000){ 58: /* 59: The source is a directory, so 60: we do lots of checking and 61: messing around so as not to get 62: into trouble. This patch of 63: code contains administrative 64: policies rather than system 65: restrictions. 66: */ 67: if(stat(argp[2], stbuf) >= 0){ 68: write(1,"Directory target exists.\n",25); 69: exit(); 70: } 71: argp1 = argp[1]; 72: argp2 = argp[2]; 73: while(*argp1 == *argp2){ 74: argp1++; 75: if(*argp2++ == 0){ 76: write(1,"???\n",4); 77: exit(); 78: } 79: } 80: while(*argp1)if(*argp1++ == '/'){ 81: write(1,"Directory rename only\n",22); 82: exit(); 83: } 84: while(*argp2)if(*argp2++ == '/'){ 85: write(1,"Directory rename only\n",22); 86: exit(); 87: } 88: if(*--argp1 == '.'){ 89: write(1,"values of B will give rise to dom!\n",37); 90: exit(); 91: } 92: }else{ 93: /* 94: the source is a file. 95: */ 96: setuid(getuid()); 97: if(stat(argp4, &stbuf[2]) >= 0){ 98: if((stbuf[2].imode & 060000) == 040000){ 99: argp2 = strbuf; 100: while(*argp2++ = *argp4++); 101: argp2[-1] = '/'; 102: argp4 = argp[1]; 103: argp1 = argp[1]; 104: while(*argp4) 105: if(*argp4++ == '/') 106: argp1 = argp4; 107: while(*argp2++ = *argp1++); 108: argp4 = strbuf; 109: } 110: if(stat(argp4, &stbuf[2]) >= 0){ 111: if((stbuf[0]==stbuf[2]) && (stbuf[1]==stbuf[3])){ 112: write(1,"Files are identical.\n",21); 113: exit(); 114: } 115: if((getuid()&0377) == stbuf[2].uid) 116: b = 0200; else 117: if((getgid()&0377) == stbuf[2].gid) 118: b = 020; else 119: b = 02; 120: if((stbuf[2].imode & b) == 0) { 121: printf("%s: %o mode ", argp4, 122: stbuf[2].imode & 07777); 123: i = b = getchar(); 124: while(b != '\n' && b != '\0') 125: b = getchar(); 126: if(i != 'y') 127: exit(); 128: } 129: if(unlink(argp4) < 0){ 130: write(1,"Cannot remove target file.\n",27); 131: exit(); 132: } 133: } 134: } 135: } 136: if(link(argp3, argp4) < 0){ 137: i = fork(); 138: if(i == -1){ 139: write(1,"Try again.\n",11); 140: exit(); 141: } 142: if(i){ 143: while(wait(&status) != i); 144: }else{ 145: p = place; 146: p1 = p; 147: while(*p++ = *argp3++); 148: p2 = p; 149: while(*p++ = *argp4++); 150: execl("/bin/cp","cp", p1, p2, 0); 151: write(1, "no cp\n", 6); 152: exit(1); 153: } 154: if((status & 0377) != 0){ 155: write(1,"?\n", 2); 156: exit(); 157: } 158: if(status != 0) exit(); 159: } 160: if(unlink(argp3) < 0){ 161: write(1,"Cannot unlink source file.\n",27); 162: exit(); 163: } 164: } 165: 166: putchar(c) 167: { 168: write(1, &c, 1); 169: } 170: 171: getchar() 172: { 173: char c; 174: 175: if(read(0, &c, 1) != 1) return(0); 176: return(c); 177: }