|
|
1.1 ! root 1: /* ! 2: * cp oldfile newfile ! 3: */ ! 4: ! 5: #include <stdio.h> ! 6: #include <sys/types.h> ! 7: #include <sys/stat.h> ! 8: #define BLOCKSIZE BUFSIZE ! 9: struct stat stbuf1, stbuf2; ! 10: char iobuf[BLOCKSIZE]; ! 11: char zero[BLOCKSIZE]; /* keep as zero */ ! 12: int zflag = 0; ! 13: #define wrcp() write(2, "cp: ", 4) ! 14: ! 15: main(argc, argv) ! 16: char *argv[]; ! 17: { ! 18: register i, r; ! 19: ! 20: if (argc < 3) ! 21: goto usage; ! 22: i = 1; ! 23: if(strcmp(argv[i], "-z") == 0) ! 24: zflag = 1, i++; ! 25: if ((argc-i) > 2) { ! 26: if (stat(argv[argc-1], &stbuf2) < 0) ! 27: goto usage; ! 28: if ((stbuf2.st_mode&S_IFMT) != S_IFDIR) ! 29: goto usage; ! 30: } ! 31: r = 0; ! 32: for(; i<argc-1;i++) ! 33: r |= copy(argv[i], argv[argc-1]); ! 34: exit(r); ! 35: usage: ! 36: fprintf(stderr, "Usage: cp: [-z] f1 f2; or cp [-z] f1 ... fn d2\n"); ! 37: exit(1); ! 38: } ! 39: ! 40: copy(from, to) ! 41: char *from, *to; ! 42: { ! 43: int fold, fnew, n; ! 44: register char *p1, *p2, *bp; ! 45: int mode; ! 46: int bsize, zsize; ! 47: long lseek(); ! 48: ! 49: if ((fold = open(from, 0)) < 0) { ! 50: wrcp(); ! 51: perror(from); ! 52: return(1); ! 53: } ! 54: fstat(fold, &stbuf1); ! 55: mode = stbuf1.st_mode; ! 56: /* is source a directory? */ ! 57: if ((mode&S_IFMT) == S_IFDIR) { ! 58: fprintf(stderr, "cp: %s is a directory\n", from); ! 59: close(fold); ! 60: return(1); ! 61: } ! 62: /* is target a directory? */ ! 63: if (stat(to, &stbuf2) >=0 && ! 64: (stbuf2.st_mode&S_IFMT) == S_IFDIR) { ! 65: p1 = from; ! 66: p2 = to; ! 67: bp = iobuf; ! 68: while(*bp++ = *p2++) ! 69: ; ! 70: bp[-1] = '/'; ! 71: p2 = bp; ! 72: while(*bp = *p1++) ! 73: if (*bp++ == '/') ! 74: bp = p2; ! 75: to = iobuf; ! 76: } ! 77: if (stat(to, &stbuf2) >= 0) { ! 78: if (stbuf1.st_dev == stbuf2.st_dev && ! 79: stbuf1.st_ino == stbuf2.st_ino) { ! 80: fprintf(stderr, "cp: cannot copy file to itself\n"); ! 81: close(fold); ! 82: return(1); ! 83: } ! 84: } ! 85: bsize = BSIZE(stbuf2.st_dev); ! 86: if (bsize > BLOCKSIZE) { ! 87: fprintf(stderr, "cp: BSIZE(%s) > %d\n", to, BLOCKSIZE); ! 88: return 1; ! 89: } ! 90: if ((fnew = creat(to, mode)) < 0) { ! 91: wrcp(); ! 92: perror(to); ! 93: close(fold); ! 94: return(1); ! 95: } ! 96: zsize = 0; ! 97: while(n = read(fold, iobuf, bsize)) { ! 98: if (n < 0) { ! 99: wrcp(); ! 100: perror(from); ! 101: close(fold); ! 102: close(fnew); ! 103: return(1); ! 104: } else ! 105: if(zflag && (n == bsize) && (memcmp(iobuf, zero, bsize) == 0)){ ! 106: if (lseek(fnew, (long)bsize, 1) < 0) { ! 107: wrcp(); ! 108: perror(to); ! 109: close(fold); ! 110: close(fnew); ! 111: return(1); ! 112: } ! 113: zsize = bsize; ! 114: } else { ! 115: if (write(fnew, iobuf, n) != n) { ! 116: wrcp(); ! 117: perror(to); ! 118: close(fold); ! 119: close(fnew); ! 120: return(1); ! 121: } ! 122: zsize = 0; ! 123: } ! 124: } ! 125: ! 126: if (zsize) { ! 127: if (lseek(fnew, (long)-zsize, 1) < 0 ! 128: || write(fnew,zero,zsize) != zsize) { ! 129: wrcp(); ! 130: perror(to); ! 131: close(fold); ! 132: close(fnew); ! 133: return(1); ! 134: } ! 135: } ! 136: ! 137: close(fold); ! 138: close(fnew); ! 139: return(0); ! 140: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.