Annotation of 43BSDTahoe/bin/mv.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 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) 1980 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif /* not lint */
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)mv.c       5.7 (Berkeley) 4/21/88";
        !            15: #endif /* not lint */
        !            16: 
        !            17: /*
        !            18:  * mv file1 file2
        !            19:  */
        !            20: #include <sys/param.h>
        !            21: #include <sys/stat.h>
        !            22: #include <sys/time.h>
        !            23: #include <sys/file.h>
        !            24: #include <stdio.h>
        !            25: #include <errno.h>
        !            26: 
        !            27: #define        DELIM   '/'
        !            28: #define MODEBITS 07777
        !            29: 
        !            30: #define        ISDIR(st)       (((st).st_mode&S_IFMT) == S_IFDIR)
        !            31: #define        ISLNK(st)       (((st).st_mode&S_IFMT) == S_IFLNK)
        !            32: #define        ISREG(st)       (((st).st_mode&S_IFMT) == S_IFREG)
        !            33: #define        ISDEV(st) \
        !            34:        (((st).st_mode&S_IFMT) == S_IFCHR || ((st).st_mode&S_IFMT) == S_IFBLK)
        !            35: 
        !            36: char   *dname();
        !            37: int    iflag = 0;      /* interactive mode */
        !            38: int    fflag = 0;      /* force overwriting */
        !            39: extern unsigned errno;
        !            40: 
        !            41: main(argc, argv)
        !            42:        register int argc;
        !            43:        register char **argv;
        !            44: {
        !            45:        extern int optind;
        !            46:        struct stat st;
        !            47:        int ch, r;
        !            48:        char *dest;
        !            49: 
        !            50:        while ((ch = getopt(argc, argv, "-fi")) != EOF)
        !            51:                switch((char)ch) {
        !            52:                case '-':
        !            53:                        goto endarg;
        !            54:                case 'f':
        !            55:                        fflag++;
        !            56:                        break;
        !            57:                case 'i':
        !            58:                        iflag++;
        !            59:                        break;
        !            60:                case '?':
        !            61:                default:
        !            62:                        usage();
        !            63:                }
        !            64: endarg:        argv += optind;
        !            65:        argc -= optind;
        !            66: 
        !            67:        if (argc < 2)
        !            68:                usage();
        !            69:        dest = argv[argc - 1];
        !            70:        if (stat(dest, &st) >= 0 && ISDIR(st)) {
        !            71:                for (r = 0; --argc; ++argv)
        !            72:                        r |= movewithshortname(*argv, dest);
        !            73:                exit(r);
        !            74:        }
        !            75:        if (argc != 2)
        !            76:                usage();
        !            77:        r = move(argv[0], argv[1]);
        !            78:        exit(r);
        !            79: }
        !            80: 
        !            81: movewithshortname(src, dest)
        !            82:        char *src, *dest;
        !            83: {
        !            84:        register char *shortname;
        !            85:        char target[MAXPATHLEN + 1];
        !            86: 
        !            87:        shortname = dname(src);
        !            88:        if (strlen(dest) + strlen(shortname) > MAXPATHLEN - 1) {
        !            89:                error("%s/%s: pathname too long", dest,
        !            90:                        shortname);
        !            91:                return (1);
        !            92:        }
        !            93:        (void)sprintf(target, "%s/%s", dest, shortname);
        !            94:        return (move(src, target));
        !            95: }
        !            96: 
        !            97: move(source, target)
        !            98:        char *source, *target;
        !            99: {
        !           100:        int targetexists;
        !           101:        struct stat s1, s2;
        !           102: 
        !           103:        if (lstat(source, &s1) < 0) {
        !           104:                Perror2(source, "Cannot access");
        !           105:                return (1);
        !           106:        }
        !           107:        /*
        !           108:         * First, try to rename source to destination.
        !           109:         * The only reason we continue on failure is if
        !           110:         * the move is on a nondirectory and not across
        !           111:         * file systems.
        !           112:         */
        !           113:        targetexists = lstat(target, &s2) >= 0;
        !           114:        if (targetexists) {
        !           115:                if (s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino) {
        !           116:                        error("%s and %s are identical", source, target);
        !           117:                        return (1);
        !           118:                }
        !           119:                if (!fflag && isatty(fileno(stdin)))
        !           120:                        if (iflag) {
        !           121:                                if (!query("remove %s? ", target))
        !           122:                                        return (1);
        !           123:                        }
        !           124:                        else if (access(target, W_OK) < 0 &&
        !           125:                            !query("override protection %o for %s? ",
        !           126:                            s2.st_mode & MODEBITS, target))
        !           127:                                return (1);
        !           128:        }
        !           129:        if (rename(source, target) >= 0)
        !           130:                return (0);
        !           131:        if (errno != EXDEV) {
        !           132:                Perror2(errno == ENOENT && targetexists == 0 ? target : source,
        !           133:                    "rename");
        !           134:                return (1);
        !           135:        }
        !           136:        if (ISDIR(s1)) {
        !           137:                error("can't mv directories across file systems");
        !           138:                return (1);
        !           139:        }
        !           140:        if (targetexists && unlink(target) < 0) {
        !           141:                Perror2(target, "Cannot unlink");
        !           142:                return (1);
        !           143:        }
        !           144:        /*
        !           145:         * File can't be renamed, try to recreate the symbolic
        !           146:         * link or special device, or copy the file wholesale
        !           147:         * between file systems.
        !           148:         */
        !           149:        if (ISLNK(s1)) {
        !           150:                register m;
        !           151:                char symln[MAXPATHLEN + 1];
        !           152: 
        !           153:                m = readlink(source, symln, sizeof (symln) - 1);
        !           154:                if (m < 0) {
        !           155:                        Perror(source);
        !           156:                        return (1);
        !           157:                }
        !           158:                symln[m] = '\0';
        !           159: 
        !           160:                (void) umask(~(s1.st_mode & MODEBITS));
        !           161:                if (symlink(symln, target) < 0) {
        !           162:                        Perror(target);
        !           163:                        return (1);
        !           164:                }
        !           165:                goto cleanup;
        !           166:        }
        !           167:        (void) umask(0);
        !           168:        if (ISDEV(s1)) {
        !           169:                struct timeval tv[2];
        !           170: 
        !           171:                if (mknod(target, s1.st_mode, s1.st_rdev) < 0) {
        !           172:                        Perror(target);
        !           173:                        return (1);
        !           174:                }
        !           175: 
        !           176:                tv[0].tv_sec = s1.st_atime;
        !           177:                tv[0].tv_usec = 0;
        !           178:                tv[1].tv_sec = s1.st_mtime;
        !           179:                tv[1].tv_usec = 0;
        !           180:                (void) utimes(target, tv);
        !           181:                goto cleanup;
        !           182:        }
        !           183:        if (ISREG(s1)) {
        !           184:                register int fi, fo, n;
        !           185:                struct timeval tv[2];
        !           186:                char buf[MAXBSIZE];
        !           187: 
        !           188:                fi = open(source, 0);
        !           189:                if (fi < 0) {
        !           190:                        Perror(source);
        !           191:                        return (1);
        !           192:                }
        !           193: 
        !           194:                fo = creat(target, s1.st_mode & MODEBITS);
        !           195:                if (fo < 0) {
        !           196:                        Perror(target);
        !           197:                        close(fi);
        !           198:                        return (1);
        !           199:                }
        !           200: 
        !           201:                for (;;) {
        !           202:                        n = read(fi, buf, sizeof buf);
        !           203:                        if (n == 0) {
        !           204:                                break;
        !           205:                        } else if (n < 0) {
        !           206:                                Perror2(source, "read");
        !           207:                                close(fi);
        !           208:                                close(fo);
        !           209:                                return (1);
        !           210:                        } else if (write(fo, buf, n) != n) {
        !           211:                                Perror2(target, "write");
        !           212:                                close(fi);
        !           213:                                close(fo);
        !           214:                                return (1);
        !           215:                        }
        !           216:                }
        !           217: 
        !           218:                close(fi);
        !           219:                close(fo);
        !           220: 
        !           221:                tv[0].tv_sec = s1.st_atime;
        !           222:                tv[0].tv_usec = 0;
        !           223:                tv[1].tv_sec = s1.st_mtime;
        !           224:                tv[1].tv_usec = 0;
        !           225:                (void) utimes(target, tv);
        !           226:                goto cleanup;
        !           227:        }
        !           228:        error("%s: unknown file type %o", source, s1.st_mode);
        !           229:        return (1);
        !           230: 
        !           231: cleanup:
        !           232:        if (unlink(source) < 0) {
        !           233:                Perror2(source, "Cannot unlink");
        !           234:                return (1);
        !           235:        }
        !           236:        return (0);
        !           237: }
        !           238: 
        !           239: /*VARARGS*/
        !           240: query(prompt, a1, a2)
        !           241:        char *a1;
        !           242: {
        !           243:        register int i, c;
        !           244: 
        !           245:        fprintf(stderr, prompt, a1, a2);
        !           246:        i = c = getchar();
        !           247:        while (c != '\n' && c != EOF)
        !           248:                c = getchar();
        !           249:        return (i == 'y');
        !           250: }
        !           251: 
        !           252: char *
        !           253: dname(name)
        !           254:        register char *name;
        !           255: {
        !           256:        register char *p;
        !           257: 
        !           258:        p = name;
        !           259:        while (*p)
        !           260:                if (*p++ == DELIM && *p)
        !           261:                        name = p;
        !           262:        return name;
        !           263: }
        !           264: 
        !           265: /*VARARGS*/
        !           266: error(fmt, a1, a2)
        !           267:        char *fmt;
        !           268: {
        !           269: 
        !           270:        fprintf(stderr, "mv: ");
        !           271:        fprintf(stderr, fmt, a1, a2);
        !           272:        fprintf(stderr, "\n");
        !           273: }
        !           274: 
        !           275: Perror(s)
        !           276:        char *s;
        !           277: {
        !           278:        char buf[MAXPATHLEN + 10];
        !           279: 
        !           280:        (void)sprintf(buf, "mv: %s", s);
        !           281:        perror(buf);
        !           282: }
        !           283: 
        !           284: Perror2(s1, s2)
        !           285:        char *s1, *s2;
        !           286: {
        !           287:        char buf[MAXPATHLEN + 20];
        !           288: 
        !           289:        (void)sprintf(buf, "mv: %s: %s", s1, s2);
        !           290:        perror(buf);
        !           291: }
        !           292: 
        !           293: usage()
        !           294: {
        !           295:        fputs("usage: mv [-if] file1 file2 or mv [-if] file/directory ... directory\n", stderr);
        !           296:        exit(1);
        !           297: }

unix.superglobalmegacorp.com

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