Annotation of 42BSD/bin/cp.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.