Annotation of 43BSDTahoe/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.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.