Annotation of coherent/d/bin/cp.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * /usr/src/cmd/cp.c
        !             3:  * Usage: cp [ -d ] file1 file2
        !             4:  *       cp [ -d ] file ... directory
        !             5:  * Copy one file to another or
        !             6:  * copy several files into a directory.
        !             7:  * define SLOW for 'block at a time copying' .... (not recommended)
        !             8:  */
        !             9: 
        !            10: #include <stdio.h>
        !            11: #include <sys/stat.h>
        !            12: #include <sys/types.h>
        !            13: #include <errno.h>
        !            14: 
        !            15: #define        MAX(a, b)       ((a) < (b) ? (b) : (a))
        !            16: #define        or              ||
        !            17: #define        and             &&
        !            18: #define        not             !
        !            19: #define        TRUE            (0==0)
        !            20: #define        FALSE           (not TRUE)
        !            21: 
        !            22: extern int     errno;
        !            23: struct stat    sb;
        !            24: 
        !            25: #ifndef                SLOW
        !            26: char   buf[50*BUFSIZ];
        !            27: #else
        !            28: char   buf[BUFSIZ];
        !            29: #endif
        !            30: int    dflag;
        !            31: char   *namebuf;
        !            32: char   *suffix;
        !            33: char   *target;
        !            34: 
        !            35: main(argc, argv)
        !            36: int argc;
        !            37: char *argv[];
        !            38: {
        !            39:        register int i;
        !            40:        register int n;
        !            41:        register int status = 0;
        !            42: 
        !            43:        if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'd' && argv[1][2] == '\0') {
        !            44:                ++dflag;
        !            45:                --argc;
        !            46:                ++argv;
        !            47:        }
        !            48:        n = init(argc, argv);
        !            49:        if (namebuf == NULL)
        !            50:                return (cp(argv[1], target) ? 0 : 1);
        !            51:        for (i = 1; i <= n; ++i)
        !            52:                status |= cpdir(argv[i]);
        !            53:        return (status ? 0 : 1);
        !            54: }
        !            55: 
        !            56: /*
        !            57:  * Copy inf to outf.
        !            58:  */
        !            59: cp(inf, outf)
        !            60: char *inf, *outf;
        !            61: {
        !            62: #ifndef SLOW
        !            63:        register char   *ip;
        !            64: #endif
        !            65:        register int    n;
        !            66:        register int    i;
        !            67:        register short  infd;
        !            68:        register short  outfd;
        !            69:        register short  mode;
        !            70:        register ino_t  ino;
        !            71:        register dev_t  dev;
        !            72:        register fsize_t size;
        !            73:        time_t          times[2];
        !            74: #ifndef SLOW
        !            75:        register char   *wp;
        !            76:        register int    wflag;
        !            77: #endif
        !            78: 
        !            79:        if (stat(inf, &sb) < 0) {
        !            80:                cperr("%s: cannot find", inf);
        !            81:                return (FALSE);
        !            82:        }
        !            83:        if ((sb.st_mode & S_IFMT) == S_IFDIR) {
        !            84:                cperr("%s: directory", inf);
        !            85:                return (FALSE);
        !            86:        }
        !            87:        mode = sb.st_mode;
        !            88:        size = sb.st_size;
        !            89:        ino = sb.st_ino;
        !            90:        dev = sb.st_dev;
        !            91:        if (dflag)
        !            92:                times[1] = sb.st_mtime;
        !            93: 
        !            94:        if (stat(outf, &sb) >= 0)
        !            95:                if (sb.st_ino==ino && sb.st_dev==dev) {
        !            96:                        cperr("%s: cannot copy file to itself", inf);
        !            97:                        return (FALSE);
        !            98:                }
        !            99:        if ((infd = open(inf, 0)) < 0) {
        !           100:                cperr("%s: cannot open", inf);
        !           101:                return (FALSE);
        !           102:        }
        !           103:        if ((outfd = creat(outf, mode & 06777)) < 0) {
        !           104:           if (errno == ETXTBSY)
        !           105:              cperr("%s: cannot copy over busy shared text file", outf);
        !           106:           else
        !           107:              cperr("%s: cannot create", outf);
        !           108:           close(infd);
        !           109:           return (FALSE);
        !           110:        }
        !           111: 
        !           112: #ifndef SLOW
        !           113:        while ((n = read(infd, buf, sizeof(buf))) > 0) {
        !           114: #else
        !           115:        while ((n = read(infd, buf, BUFSIZ)) > 0) {
        !           116: #endif
        !           117:                /*
        !           118:                 * Check for blocks of zeroes (holes in a sparse file).
        !           119:                 * However, a block of zeroes at the end of a file must be
        !           120:                 * written so the file has correct length.
        !           121:                 */
        !           122: #ifndef                SLOW
        !           123:                wp = ip = buf;
        !           124:                size -= n;
        !           125:                while ((n-BUFSIZ) > 0 || ((n-BUFSIZ) == 0 && size != 0)) {
        !           126:                        n -= BUFSIZ;
        !           127:                        wflag = FALSE;
        !           128:                        ip = wp;
        !           129:                        for (i = 0; i < BUFSIZ; ++i)
        !           130:                                if (*ip++ != '\0') {
        !           131:                                        wflag = TRUE;
        !           132:                                        break;
        !           133:                                }
        !           134:                        if (wflag) {
        !           135:                                if (write(outfd, wp, BUFSIZ) < BUFSIZ) {
        !           136:                                        cperr("%s: write error", outf);
        !           137:                                        close(infd);
        !           138:                                        close(outfd);
        !           139:                                        return (FALSE);
        !           140:                                }
        !           141:                        } else {
        !           142:                                lseek(outfd, (long)BUFSIZ, 1);
        !           143:                        }
        !           144:                        wp += BUFSIZ;
        !           145:                }
        !           146:                if (write(outfd, wp, n) < n) {
        !           147:                        cperr("%s: write error", outf);
        !           148:                        close(infd);
        !           149:                        close(outfd);
        !           150:                        return (FALSE);
        !           151:                }
        !           152: #else
        !           153:                if ((size -= n) == (fsize_t)0)
        !           154:                        goto WRITE;
        !           155:                for (i = 0; i < n; ++i)
        !           156:                        if (buf[i] != '\0')
        !           157:                                goto WRITE;
        !           158:                lseek(outfd, (long)BUFSIZ, 1);
        !           159:                continue;
        !           160: 
        !           161:                WRITE:
        !           162:                if (write(outfd, buf, n) < n) {
        !           163:                        cperr("%s: write error", outf);
        !           164:                        close(infd);
        !           165:                        close(outfd);
        !           166:                        return (FALSE);
        !           167:                }
        !           168: #endif
        !           169:        }
        !           170: 
        !           171:        close(infd);
        !           172:        if (dflag && fstat(outfd, &sb) != -1) {
        !           173:                times[0] = sb.st_atime;
        !           174:                if (utime(outf, times) == -1)
        !           175:                        cperr("%s: cannot preserve mtime", outf);
        !           176:        }
        !           177:        close(outfd);
        !           178:        if (n < 0) {
        !           179:                cperr("%s: read error", inf);
        !           180:                return (FALSE);
        !           181:        }
        !           182:        return (TRUE);
        !           183: }
        !           184: 
        !           185: /*
        !           186:  * The second form of cp, copy a file into a directory. This builds the name
        !           187:  * of the target file in namebuf and then just calls `cp'.
        !           188:  */
        !           189: cpdir(file)
        !           190: char *file;
        !           191: {
        !           192:        register char *a, *b;
        !           193: 
        !           194:        for (a = b = file; *b != '\0'; )
        !           195:                if (*b++ == '/')
        !           196:                        a = b;
        !           197:        strcpy(suffix, a);
        !           198:        return (cp(file, namebuf));
        !           199: }
        !           200: 
        !           201: usage()
        !           202: {
        !           203:        fprintf(stderr,
        !           204:                "Usage:\tcp [ -d ] file1 file2\n"
        !           205:                      "\tcp [ -d ] file ... directory\n"
        !           206:                );
        !           207:        exit (2);
        !           208: }
        !           209: 
        !           210: cperr(arg0)
        !           211: {
        !           212:        fprintf(stderr, "cp: %r\n", &arg0);
        !           213: }
        !           214: 
        !           215: /*
        !           216:  * Check whether target is a directory, regular file, non-extant or in error.
        !           217:  * If a directory, malloc namebuf big enough for all names.
        !           218:  * Also, set flags used by cperr.
        !           219:  */
        !           220: init(ac, av)
        !           221: register int ac;
        !           222: register char *av[];
        !           223: {
        !           224:        register int n;
        !           225: 
        !           226:        if (ac < 3)
        !           227:                usage();
        !           228:        target = av[ac-1];
        !           229:        if (stat(target, &sb) == 0  and  (sb.st_mode & S_IFMT) == S_IFDIR) {
        !           230:                av[ac-1] = NULL;
        !           231:                n = 0;
        !           232:                while (*++av != NULL)
        !           233:                        if (n < strlen(*av))
        !           234:                                n = strlen(*av);
        !           235:                namebuf = malloc(n + strlen(target) + 2);
        !           236:                if (namebuf == NULL) {
        !           237:                        cperr("out of memory");
        !           238:                        exit(1);
        !           239:                } 
        !           240:                strcpy(namebuf, target);
        !           241:                suffix = namebuf + strlen(target);
        !           242:                *suffix++ = '/';
        !           243:                return (ac - 2);
        !           244:        }
        !           245:        if (ac != 3)
        !           246:                usage();
        !           247:        return (1);
        !           248: }
        !           249: 
        !           250: /* end of cp.c */

unix.superglobalmegacorp.com

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