|
|
1.1 ! root 1: #ifndef lint ! 2: static char *sccsid = "@(#)cp.c 4.8 83/07/01"; ! 3: #endif ! 4: ! 5: /* ! 6: * cp ! 7: */ ! 8: #include <stdio.h> ! 9: #include <sys/param.h> ! 10: #include <sys/stat.h> ! 11: #include <sys/dir.h> ! 12: ! 13: #define BSIZE 8192 ! 14: ! 15: int iflag; ! 16: int rflag; ! 17: char *rindex(), *sprintf(); ! 18: ! 19: main(argc, argv) ! 20: int argc; ! 21: char **argv; ! 22: { ! 23: struct stat stb; ! 24: int rc, i; ! 25: ! 26: argc--, argv++; ! 27: while (argc > 0 && **argv == '-') { ! 28: (*argv)++; ! 29: while (**argv) switch (*(*argv)++) { ! 30: ! 31: case 'i': ! 32: iflag++; break; ! 33: ! 34: case 'r': ! 35: rflag++; break; ! 36: ! 37: default: ! 38: goto usage; ! 39: } ! 40: argc--; argv++; ! 41: } ! 42: if (argc < 2) ! 43: goto usage; ! 44: if (argc > 2 || rflag) { ! 45: if (stat(argv[argc-1], &stb) < 0) ! 46: goto usage; ! 47: if ((stb.st_mode&S_IFMT) != S_IFDIR) ! 48: goto usage; ! 49: } ! 50: rc = 0; ! 51: for (i = 0; i < argc-1; i++) ! 52: rc |= copy(argv[i], argv[argc-1]); ! 53: exit(rc); ! 54: usage: ! 55: fprintf(stderr, ! 56: "Usage: cp f1 f2; or cp [ -r ] f1 ... fn d2\n"); ! 57: exit(1); ! 58: } ! 59: ! 60: copy(from, to) ! 61: char *from, *to; ! 62: { ! 63: int fold, fnew, n; ! 64: char *last, destname[BSIZE], buf[BSIZE]; ! 65: struct stat stfrom, stto; ! 66: ! 67: fold = open(from, 0); ! 68: if (fold < 0) { ! 69: Perror(from); ! 70: return (1); ! 71: } ! 72: if (fstat(fold, &stfrom) < 0) { ! 73: Perror(from); ! 74: (void) close(fold); ! 75: return (1); ! 76: } ! 77: if (stat(to, &stto) >= 0 && ! 78: (stto.st_mode&S_IFMT) == S_IFDIR) { ! 79: last = rindex(from, '/'); ! 80: if (last) last++; else last = from; ! 81: if (strlen(to) + strlen(last) >= BSIZE - 1) { ! 82: fprintf(stderr, "cp: %s/%s: Name too long", to, last); ! 83: (void) close(fold); ! 84: return(1); ! 85: } ! 86: (void) sprintf(destname, "%s/%s", to, last); ! 87: to = destname; ! 88: } ! 89: if (rflag && (stfrom.st_mode&S_IFMT) == S_IFDIR) { ! 90: (void) close(fold); ! 91: if (stat(to, &stto) < 0) { ! 92: if (mkdir(to, (int)stfrom.st_mode) < 0) { ! 93: Perror(to); ! 94: return (1); ! 95: } ! 96: } else if ((stto.st_mode&S_IFMT) != S_IFDIR) { ! 97: fprintf(stderr, "cp: %s: Not a directory.\n", to); ! 98: return (1); ! 99: } ! 100: return (rcopy(from, to)); ! 101: } ! 102: if (stat(to, &stto) >= 0) { ! 103: if (stfrom.st_dev == stto.st_dev && ! 104: stfrom.st_ino == stto.st_ino) { ! 105: fprintf(stderr, "cp: Cannot copy file to itself.\n"); ! 106: (void) close(fold); ! 107: return (1); ! 108: } ! 109: if (iflag) { ! 110: int i, c; ! 111: ! 112: fprintf (stderr, "overwrite %s? ", to); ! 113: i = c = getchar(); ! 114: while (c != '\n' && c != EOF) ! 115: c = getchar(); ! 116: if (i != 'y') { ! 117: (void) close(fold); ! 118: return(1); ! 119: } ! 120: } ! 121: } ! 122: fnew = creat(to, (int)stfrom.st_mode); ! 123: if (fnew < 0) { ! 124: Perror(to); ! 125: (void) close(fold); return(1); ! 126: } ! 127: for (;;) { ! 128: n = read(fold, buf, BSIZE); ! 129: if (n == 0) ! 130: break; ! 131: if (n < 0) { ! 132: Perror(from); ! 133: (void) close(fold); (void) close(fnew); return (1); ! 134: } ! 135: if (write(fnew, buf, n) != n) { ! 136: Perror(to); ! 137: (void) close(fold); (void) close(fnew); return (1); ! 138: } ! 139: } ! 140: (void) close(fold); (void) close(fnew); return (0); ! 141: } ! 142: ! 143: rcopy(from, to) ! 144: char *from, *to; ! 145: { ! 146: DIR *fold = opendir(from); ! 147: struct direct *dp; ! 148: int errs = 0; ! 149: char fromname[BUFSIZ]; ! 150: ! 151: if (fold == 0) { ! 152: Perror(from); ! 153: return (1); ! 154: } ! 155: for (;;) { ! 156: dp = readdir(fold); ! 157: if (dp == 0) { ! 158: closedir(fold); ! 159: return (errs); ! 160: } ! 161: if (dp->d_ino == 0) ! 162: continue; ! 163: if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) ! 164: continue; ! 165: if (strlen(from) + 1 + strlen(dp->d_name) >= BUFSIZ - 1) { ! 166: fprintf(stderr, "cp: %s/%s: Name too long.\n", ! 167: from, dp->d_name); ! 168: errs++; ! 169: continue; ! 170: } ! 171: (void) sprintf(fromname, "%s/%s", from, dp->d_name); ! 172: errs += copy(fromname, to); ! 173: } ! 174: } ! 175: ! 176: Perror(s) ! 177: char *s; ! 178: { ! 179: ! 180: fprintf(stderr, "cp: "); ! 181: perror(s); ! 182: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.