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