Annotation of 43BSD/bin/cp.c, revision 1.1.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.