Annotation of 43BSDTahoe/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.14 (Berkeley) 12/2/86";
        !            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:                        /* I/O buffer; guarantee long-word alignment */
        !            79: static char    buf[MAXBSIZE];
        !            80: 
        !            81: copy(from, to)
        !            82:        char *from, *to;
        !            83: {
        !            84:        int fold, fnew, n, exists;
        !            85:        char *last, destname[MAXPATHLEN + 1];
        !            86:        struct stat stfrom, stto;
        !            87: 
        !            88:        fold = open(from, 0);
        !            89:        if (fold < 0) {
        !            90:                Perror(from);
        !            91:                return (1);
        !            92:        }
        !            93:        if (fstat(fold, &stfrom) < 0) {
        !            94:                Perror(from);
        !            95:                (void) close(fold);
        !            96:                return (1);
        !            97:        }
        !            98:        if (stat(to, &stto) >= 0 &&
        !            99:           (stto.st_mode&S_IFMT) == S_IFDIR) {
        !           100:                last = rindex(from, '/');
        !           101:                if (last) last++; else last = from;
        !           102:                if (strlen(to) + strlen(last) >= sizeof destname - 1) {
        !           103:                        fprintf(stderr, "cp: %s/%s: Name too long", to, last);
        !           104:                        (void) close(fold);
        !           105:                        return(1);
        !           106:                }
        !           107:                (void) sprintf(destname, "%s/%s", to, last);
        !           108:                to = destname;
        !           109:        }
        !           110:        if (rflag && (stfrom.st_mode&S_IFMT) == S_IFDIR) {
        !           111:                int fixmode = 0;        /* cleanup mode after rcopy */
        !           112: 
        !           113:                (void) close(fold);
        !           114:                if (stat(to, &stto) < 0) {
        !           115:                        if (mkdir(to, (stfrom.st_mode & 07777) | 0700) < 0) {
        !           116:                                Perror(to);
        !           117:                                return (1);
        !           118:                        }
        !           119:                        fixmode = 1;
        !           120:                } else if ((stto.st_mode&S_IFMT) != S_IFDIR) {
        !           121:                        fprintf(stderr, "cp: %s: Not a directory.\n", to);
        !           122:                        return (1);
        !           123:                } else if (pflag)
        !           124:                        fixmode = 1;
        !           125:                n = rcopy(from, to);
        !           126:                if (fixmode)
        !           127:                        (void) chmod(to, stfrom.st_mode & 07777);
        !           128:                return (n);
        !           129:        }
        !           130: 
        !           131:        if ((stfrom.st_mode&S_IFMT) == S_IFDIR)
        !           132:                fprintf(stderr,
        !           133:                        "cp: %s: Is a directory (copying as plain file).\n",
        !           134:                                from);
        !           135: 
        !           136:        exists = stat(to, &stto) == 0;
        !           137:        if (exists) {
        !           138:                if (stfrom.st_dev == stto.st_dev &&
        !           139:                   stfrom.st_ino == stto.st_ino) {
        !           140:                        fprintf(stderr,
        !           141:                                "cp: %s and %s are identical (not copied).\n",
        !           142:                                        from, to);
        !           143:                        (void) close(fold);
        !           144:                        return (1);
        !           145:                }
        !           146:                if (iflag && isatty(fileno(stdin))) {
        !           147:                        int i, c;
        !           148: 
        !           149:                        fprintf (stderr, "overwrite %s? ", to);
        !           150:                        i = c = getchar();
        !           151:                        while (c != '\n' && c != EOF)
        !           152:                                c = getchar();
        !           153:                        if (i != 'y') {
        !           154:                                (void) close(fold);
        !           155:                                return(1);
        !           156:                        }
        !           157:                }
        !           158:        }
        !           159:        fnew = creat(to, stfrom.st_mode & 07777);
        !           160:        if (fnew < 0) {
        !           161:                Perror(to);
        !           162:                (void) close(fold); return(1);
        !           163:        }
        !           164:        if (exists && pflag)
        !           165:                (void) fchmod(fnew, stfrom.st_mode & 07777);
        !           166:                        
        !           167:        for (;;) {
        !           168:                n = read(fold, buf, sizeof buf);
        !           169:                if (n == 0)
        !           170:                        break;
        !           171:                if (n < 0) {
        !           172:                        Perror(from);
        !           173:                        (void) close(fold); (void) close(fnew); return (1);
        !           174:                }
        !           175:                if (write(fnew, buf, n) != n) {
        !           176:                        Perror(to);
        !           177:                        (void) close(fold); (void) close(fnew); return (1);
        !           178:                }
        !           179:        }
        !           180:        (void) close(fold); (void) close(fnew); 
        !           181:        if (pflag)
        !           182:                return (setimes(to, &stfrom));
        !           183:        return (0);
        !           184: }
        !           185: 
        !           186: rcopy(from, to)
        !           187:        char *from, *to;
        !           188: {
        !           189:        DIR *fold = opendir(from);
        !           190:        struct direct *dp;
        !           191:        struct stat statb;
        !           192:        int errs = 0;
        !           193:        char fromname[MAXPATHLEN + 1];
        !           194: 
        !           195:        if (fold == 0 || (pflag && fstat(fold->dd_fd, &statb) < 0)) {
        !           196:                Perror(from);
        !           197:                return (1);
        !           198:        }
        !           199:        for (;;) {
        !           200:                dp = readdir(fold);
        !           201:                if (dp == 0) {
        !           202:                        closedir(fold);
        !           203:                        if (pflag)
        !           204:                                return (setimes(to, &statb) + errs);
        !           205:                        return (errs);
        !           206:                }
        !           207:                if (dp->d_ino == 0)
        !           208:                        continue;
        !           209:                if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
        !           210:                        continue;
        !           211:                if (strlen(from)+1+strlen(dp->d_name) >= sizeof fromname - 1) {
        !           212:                        fprintf(stderr, "cp: %s/%s: Name too long.\n",
        !           213:                            from, dp->d_name);
        !           214:                        errs++;
        !           215:                        continue;
        !           216:                }
        !           217:                (void) sprintf(fromname, "%s/%s", from, dp->d_name);
        !           218:                errs += copy(fromname, to);
        !           219:        }
        !           220: }
        !           221: 
        !           222: int
        !           223: setimes(path, statp)
        !           224:        char *path;
        !           225:        struct stat *statp;
        !           226: {
        !           227:        struct timeval tv[2];
        !           228:        
        !           229:        tv[0].tv_sec = statp->st_atime;
        !           230:        tv[1].tv_sec = statp->st_mtime;
        !           231:        tv[0].tv_usec = tv[1].tv_usec = 0;
        !           232:        if (utimes(path, tv) < 0) {
        !           233:                Perror(path);
        !           234:                return (1);
        !           235:        }
        !           236:        return (0);
        !           237: }
        !           238: 
        !           239: Perror(s)
        !           240:        char *s;
        !           241: {
        !           242: 
        !           243:        fprintf(stderr, "cp: ");
        !           244:        perror(s);
        !           245: }

unix.superglobalmegacorp.com

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