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

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif not lint
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)cp.c       4.13 (Berkeley) 10/11/85";
        !            15: #endif not lint
        !            16: 
        !            17: /*
        !            18:  * cp
        !            19:  */
        !            20: #include <stdio.h>
        !            21: #include <sys/param.h>
        !            22: #include <sys/stat.h>
        !            23: #include <sys/dir.h>
        !            24: #include <sys/time.h>
        !            25: 
        !            26: int    iflag;
        !            27: int    rflag;
        !            28: int    pflag;
        !            29: char   *rindex();
        !            30: 
        !            31: main(argc, argv)
        !            32:        int argc;
        !            33:        char **argv;
        !            34: {
        !            35:        struct stat stb;
        !            36:        int rc, i;
        !            37: 
        !            38:        argc--, argv++;
        !            39:        while (argc > 0 && **argv == '-') {
        !            40:                (*argv)++;
        !            41:                while (**argv) switch (*(*argv)++) {
        !            42: 
        !            43:                case 'i':
        !            44:                        iflag++; break;
        !            45: 
        !            46:                case 'R':
        !            47:                case 'r':
        !            48:                        rflag++; break;
        !            49: 
        !            50:                case 'p':       /* preserve mtimes, atimes, and modes */
        !            51:                        pflag++;
        !            52:                        (void) umask(0);
        !            53:                        break;
        !            54: 
        !            55:                default:
        !            56:                        goto usage;
        !            57:                }
        !            58:                argc--; argv++;
        !            59:        }
        !            60:        if (argc < 2) 
        !            61:                goto usage;
        !            62:        if (argc > 2) {
        !            63:                if (stat(argv[argc-1], &stb) < 0)
        !            64:                        goto usage;
        !            65:                if ((stb.st_mode&S_IFMT) != S_IFDIR) 
        !            66:                        goto usage;
        !            67:        }
        !            68:        rc = 0;
        !            69:        for (i = 0; i < argc-1; i++)
        !            70:                rc |= copy(argv[i], argv[argc-1]);
        !            71:        exit(rc);
        !            72: usage:
        !            73:        fprintf(stderr,
        !            74:            "Usage: cp [-ip] f1 f2; or: cp [-irp] f1 ... fn d2\n");
        !            75:        exit(1);
        !            76: }
        !            77: 
        !            78: copy(from, to)
        !            79:        char *from, *to;
        !            80: {
        !            81:        int fold, fnew, n, exists;
        !            82:        char *last, destname[MAXPATHLEN + 1], buf[MAXBSIZE];
        !            83:        struct stat stfrom, stto;
        !            84: 
        !            85:        fold = open(from, 0);
        !            86:        if (fold < 0) {
        !            87:                Perror(from);
        !            88:                return (1);
        !            89:        }
        !            90:        if (fstat(fold, &stfrom) < 0) {
        !            91:                Perror(from);
        !            92:                (void) close(fold);
        !            93:                return (1);
        !            94:        }
        !            95:        if (stat(to, &stto) >= 0 &&
        !            96:           (stto.st_mode&S_IFMT) == S_IFDIR) {
        !            97:                last = rindex(from, '/');
        !            98:                if (last) last++; else last = from;
        !            99:                if (strlen(to) + strlen(last) >= sizeof destname - 1) {
        !           100:                        fprintf(stderr, "cp: %s/%s: Name too long", to, last);
        !           101:                        (void) close(fold);
        !           102:                        return(1);
        !           103:                }
        !           104:                (void) sprintf(destname, "%s/%s", to, last);
        !           105:                to = destname;
        !           106:        }
        !           107:        if (rflag && (stfrom.st_mode&S_IFMT) == S_IFDIR) {
        !           108:                int fixmode = 0;        /* cleanup mode after rcopy */
        !           109: 
        !           110:                (void) close(fold);
        !           111:                if (stat(to, &stto) < 0) {
        !           112:                        if (mkdir(to, (stfrom.st_mode & 07777) | 0700) < 0) {
        !           113:                                Perror(to);
        !           114:                                return (1);
        !           115:                        }
        !           116:                        fixmode = 1;
        !           117:                } else if ((stto.st_mode&S_IFMT) != S_IFDIR) {
        !           118:                        fprintf(stderr, "cp: %s: Not a directory.\n", to);
        !           119:                        return (1);
        !           120:                } else if (pflag)
        !           121:                        fixmode = 1;
        !           122:                n = rcopy(from, to);
        !           123:                if (fixmode)
        !           124:                        (void) chmod(to, stfrom.st_mode & 07777);
        !           125:                return (n);
        !           126:        }
        !           127: 
        !           128:        if ((stfrom.st_mode&S_IFMT) == S_IFDIR)
        !           129:                fprintf(stderr,
        !           130:                        "cp: %s: Is a directory (copying as plain file).\n",
        !           131:                                from);
        !           132: 
        !           133:        exists = stat(to, &stto) == 0;
        !           134:        if (exists) {
        !           135:                if (stfrom.st_dev == stto.st_dev &&
        !           136:                   stfrom.st_ino == stto.st_ino) {
        !           137:                        fprintf(stderr,
        !           138:                                "cp: %s and %s are identical (not copied).\n",
        !           139:                                        from, to);
        !           140:                        (void) close(fold);
        !           141:                        return (1);
        !           142:                }
        !           143:                if (iflag && isatty(fileno(stdin))) {
        !           144:                        int i, c;
        !           145: 
        !           146:                        fprintf (stderr, "overwrite %s? ", to);
        !           147:                        i = c = getchar();
        !           148:                        while (c != '\n' && c != EOF)
        !           149:                                c = getchar();
        !           150:                        if (i != 'y') {
        !           151:                                (void) close(fold);
        !           152:                                return(1);
        !           153:                        }
        !           154:                }
        !           155:        }
        !           156:        fnew = creat(to, stfrom.st_mode & 07777);
        !           157:        if (fnew < 0) {
        !           158:                Perror(to);
        !           159:                (void) close(fold); return(1);
        !           160:        }
        !           161:        if (exists && pflag)
        !           162:                (void) fchmod(fnew, stfrom.st_mode & 07777);
        !           163:                        
        !           164:        for (;;) {
        !           165:                n = read(fold, buf, sizeof buf);
        !           166:                if (n == 0)
        !           167:                        break;
        !           168:                if (n < 0) {
        !           169:                        Perror(from);
        !           170:                        (void) close(fold); (void) close(fnew); return (1);
        !           171:                }
        !           172:                if (write(fnew, buf, n) != n) {
        !           173:                        Perror(to);
        !           174:                        (void) close(fold); (void) close(fnew); return (1);
        !           175:                }
        !           176:        }
        !           177:        (void) close(fold); (void) close(fnew); 
        !           178:        if (pflag)
        !           179:                return (setimes(to, &stfrom));
        !           180:        return (0);
        !           181: }
        !           182: 
        !           183: rcopy(from, to)
        !           184:        char *from, *to;
        !           185: {
        !           186:        DIR *fold = opendir(from);
        !           187:        struct direct *dp;
        !           188:        struct stat statb;
        !           189:        int errs = 0;
        !           190:        char fromname[MAXPATHLEN + 1];
        !           191: 
        !           192:        if (fold == 0 || (pflag && fstat(fold->dd_fd, &statb) < 0)) {
        !           193:                Perror(from);
        !           194:                return (1);
        !           195:        }
        !           196:        for (;;) {
        !           197:                dp = readdir(fold);
        !           198:                if (dp == 0) {
        !           199:                        closedir(fold);
        !           200:                        if (pflag)
        !           201:                                return (setimes(to, &statb) + errs);
        !           202:                        return (errs);
        !           203:                }
        !           204:                if (dp->d_ino == 0)
        !           205:                        continue;
        !           206:                if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
        !           207:                        continue;
        !           208:                if (strlen(from)+1+strlen(dp->d_name) >= sizeof fromname - 1) {
        !           209:                        fprintf(stderr, "cp: %s/%s: Name too long.\n",
        !           210:                            from, dp->d_name);
        !           211:                        errs++;
        !           212:                        continue;
        !           213:                }
        !           214:                (void) sprintf(fromname, "%s/%s", from, dp->d_name);
        !           215:                errs += copy(fromname, to);
        !           216:        }
        !           217: }
        !           218: 
        !           219: int
        !           220: setimes(path, statp)
        !           221:        char *path;
        !           222:        struct stat *statp;
        !           223: {
        !           224:        struct timeval tv[2];
        !           225:        
        !           226:        tv[0].tv_sec = statp->st_atime;
        !           227:        tv[1].tv_sec = statp->st_mtime;
        !           228:        tv[0].tv_usec = tv[1].tv_usec = 0;
        !           229:        if (utimes(path, tv) < 0) {
        !           230:                Perror(path);
        !           231:                return (1);
        !           232:        }
        !           233:        return (0);
        !           234: }
        !           235: 
        !           236: Perror(s)
        !           237:        char *s;
        !           238: {
        !           239: 
        !           240:        fprintf(stderr, "cp: ");
        !           241:        perror(s);
        !           242: }

unix.superglobalmegacorp.com

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