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