Annotation of 43BSDTahoe/usr.bin/install.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1987 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted
        !             6:  * provided that the above copyright notice and this paragraph are
        !             7:  * duplicated in all such forms and that any documentation,
        !             8:  * advertising materials, and other materials related to such
        !             9:  * distribution and use acknowledge that the software was developed
        !            10:  * by the University of California, Berkeley.  The name of the
        !            11:  * University may not be used to endorse or promote products derived
        !            12:  * from this software without specific prior written permission.
        !            13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            16:  */
        !            17: 
        !            18: #ifndef lint
        !            19: char copyright[] =
        !            20: "@(#) Copyright (c) 1987 Regents of the University of California.\n\
        !            21:  All rights reserved.\n";
        !            22: #endif /* not lint */
        !            23: 
        !            24: #ifndef lint
        !            25: static char sccsid[] = "@(#)install.c  5.12 (Berkeley) 7/6/88";
        !            26: #endif /* not lint */
        !            27: 
        !            28: #include <sys/param.h>
        !            29: #include <sys/stat.h>
        !            30: #include <sys/file.h>
        !            31: #include <a.out.h>
        !            32: #include <grp.h>
        !            33: #include <pwd.h>
        !            34: #include <stdio.h>
        !            35: #include <ctype.h>
        !            36: 
        !            37: #define        YES     1                       /* yes/true */
        !            38: #define        NO      0                       /* no/false */
        !            39: 
        !            40: #define        PERROR(head, msg) { \
        !            41:        fputs(head, stderr); \
        !            42:        perror(msg); \
        !            43: }
        !            44: 
        !            45: static struct passwd   *pp;
        !            46: static struct group    *gp;
        !            47: static int     docopy, dostrip,
        !            48:                mode = 0755;
        !            49: static char    *group, *owner,
        !            50:                pathbuf[MAXPATHLEN];
        !            51: 
        !            52: main(argc, argv)
        !            53:        int argc;
        !            54:        char **argv;
        !            55: {
        !            56:        extern char *optarg;
        !            57:        extern int optind;
        !            58:        struct stat from_sb, to_sb;
        !            59:        int ch, no_target;
        !            60:        char *to_name;
        !            61: 
        !            62:        while ((ch = getopt(argc, argv, "cg:m:o:s")) != EOF)
        !            63:                switch((char)ch) {
        !            64:                case 'c':
        !            65:                        docopy = YES;
        !            66:                        break;
        !            67:                case 'g':
        !            68:                        group = optarg;
        !            69:                        break;
        !            70:                case 'm':
        !            71:                        mode = atoo(optarg);
        !            72:                        break;
        !            73:                case 'o':
        !            74:                        owner = optarg;
        !            75:                        break;
        !            76:                case 's':
        !            77:                        dostrip = YES;
        !            78:                        break;
        !            79:                case '?':
        !            80:                default:
        !            81:                        usage();
        !            82:                }
        !            83:        argc -= optind;
        !            84:        argv += optind;
        !            85:        if (argc < 2)
        !            86:                usage();
        !            87: 
        !            88:        /* get group and owner id's */
        !            89:        if (group && !(gp = getgrnam(group))) {
        !            90:                fprintf(stderr, "install: unknown group %s.\n", group);
        !            91:                exit(1);
        !            92:        }
        !            93:        if (owner && !(pp = getpwnam(owner))) {
        !            94:                fprintf(stderr, "install: unknown user %s.\n", owner);
        !            95:                exit(1);
        !            96:        }
        !            97: 
        !            98:        no_target = stat(to_name = argv[argc - 1], &to_sb);
        !            99:        if (!no_target && (to_sb.st_mode & S_IFMT) == S_IFDIR) {
        !           100:                for (; *argv != to_name; ++argv)
        !           101:                        install(*argv, to_name, YES);
        !           102:                exit(0);
        !           103:        }
        !           104: 
        !           105:        /* can't do file1 file2 directory/file */
        !           106:        if (argc != 2)
        !           107:                usage();
        !           108: 
        !           109:        if (!no_target) {
        !           110:                if (stat(*argv, &from_sb)) {
        !           111:                        fprintf(stderr, "install: can't find %s.\n", *argv);
        !           112:                        exit(1);
        !           113:                }
        !           114:                if ((to_sb.st_mode & S_IFMT) != S_IFREG) {
        !           115:                        fprintf(stderr, "install: %s isn't a regular file.\n", to_name);
        !           116:                        exit(1);
        !           117:                }
        !           118:                if (to_sb.st_dev == from_sb.st_dev && to_sb.st_ino == from_sb.st_ino) {
        !           119:                        fprintf(stderr, "install: %s and %s are the same file.\n", *argv, to_name);
        !           120:                        exit(1);
        !           121:                }
        !           122:                /* unlink now... avoid ETXTBSY errors later */
        !           123:                (void)unlink(to_name);
        !           124:        }
        !           125:        install(*argv, to_name, NO);
        !           126:        exit(0);
        !           127: }
        !           128: 
        !           129: /*
        !           130:  * install --
        !           131:  *     build a path name and install the file
        !           132:  */
        !           133: static
        !           134: install(from_name, to_name, isdir)
        !           135:        char *from_name, *to_name;
        !           136:        int isdir;
        !           137: {
        !           138:        struct stat from_sb;
        !           139:        int devnull, from_fd, to_fd;
        !           140:        char *C, *rindex();
        !           141: 
        !           142:        /* if try to install "/dev/null" to a directory, fails */
        !           143:        if (isdir || strcmp(from_name, "/dev/null")) {
        !           144:                if (stat(from_name, &from_sb)) {
        !           145:                        fprintf(stderr, "install: can't find %s.\n", from_name);
        !           146:                        exit(1);
        !           147:                }
        !           148:                if ((from_sb.st_mode & S_IFMT) != S_IFREG) {
        !           149:                        fprintf(stderr, "install: %s isn't a regular file.\n", from_name);
        !           150:                        exit(1);
        !           151:                }
        !           152:                /* build the target path */
        !           153:                if (isdir) {
        !           154:                        (void)sprintf(pathbuf, "%s/%s", to_name, (C = rindex(from_name, '/')) ? ++C : from_name);
        !           155:                        to_name = pathbuf;
        !           156:                }
        !           157:                devnull = NO;
        !           158:        }
        !           159:        else
        !           160:                devnull = YES;
        !           161: 
        !           162:        /* unlink now... avoid ETXTBSY errors later */
        !           163:        (void)unlink(to_name);
        !           164: 
        !           165:        /* create target */
        !           166:        if ((to_fd = open(to_name, O_CREAT|O_WRONLY|O_TRUNC, 0)) < 0) {
        !           167:                PERROR("install: ", to_name);
        !           168:                exit(1);
        !           169:        }
        !           170:        if (!devnull) {
        !           171:                if ((from_fd = open(from_name, O_RDONLY, 0)) < 0) {
        !           172:                        (void)unlink(to_name);
        !           173:                        PERROR("install: open: ", from_name);
        !           174:                        exit(1);
        !           175:                }
        !           176:                if (dostrip)
        !           177:                        strip(from_fd, from_name, to_fd, to_name);
        !           178:                else
        !           179:                        copy(from_fd, from_name, to_fd, to_name);
        !           180:                (void)close(from_fd);
        !           181:                if (!docopy)
        !           182:                        (void)unlink(from_name);
        !           183:        }
        !           184:        /* set owner, group, mode for target */
        !           185:        if (fchmod(to_fd, mode)) {
        !           186:                PERROR("install: fchmod: ", to_name);
        !           187:                bad();
        !           188:        }
        !           189:        if ((group || owner) && fchown(to_fd, owner ? pp->pw_uid : -1,
        !           190:            group ? gp->gr_gid : -1)) {
        !           191:                PERROR("install: fchown: ", to_name);
        !           192:                bad();
        !           193:        }
        !           194:        (void)close(to_fd);
        !           195: }
        !           196: 
        !           197: /*
        !           198:  * strip --
        !           199:  *     copy file, strip(1)'ing it at the same time
        !           200:  */
        !           201: static
        !           202: strip(from_fd, from_name, to_fd, to_name)
        !           203:        register int from_fd, to_fd;
        !           204:        char *from_name, *to_name;
        !           205: {
        !           206:        typedef struct exec EXEC;
        !           207:        register long size;
        !           208:        register int n;
        !           209:        EXEC head;
        !           210:        char buf[MAXBSIZE];
        !           211:        off_t lseek();
        !           212: 
        !           213:        if (read(from_fd, (char *)&head, sizeof(head)) < 0 || N_BADMAG(head)) {
        !           214:                fprintf(stderr, "install: %s not in a.out format.\n", from_name);
        !           215:                bad();
        !           216:        }
        !           217:        if (head.a_syms || head.a_trsize || head.a_drsize) {
        !           218:                size = (long)head.a_text + head.a_data;
        !           219:                head.a_syms = head.a_trsize = head.a_drsize = 0;
        !           220:                if (head.a_magic == ZMAGIC)
        !           221:                        size += getpagesize() - sizeof(EXEC);
        !           222:                if (write(to_fd, (char *)&head, sizeof(EXEC)) != sizeof(EXEC)) {
        !           223:                        PERROR("install: write: ", to_name);
        !           224:                        bad();
        !           225:                }
        !           226:                for (; size; size -= n)
        !           227:                        /* sizeof(buf) guaranteed to fit in an int */
        !           228:                        if ((n = read(from_fd, buf, (int)MIN(size, sizeof(buf)))) <= 0)
        !           229:                                break;
        !           230:                        else if (write(to_fd, buf, n) != n) {
        !           231:                                PERROR("install: write: ", to_name);
        !           232:                                bad();
        !           233:                        }
        !           234:                if (size) {
        !           235:                        fprintf(stderr, "install: read: %s: premature EOF.\n", from_name);
        !           236:                        bad();
        !           237:                }
        !           238:                if (n == -1) {
        !           239:                        PERROR("install: read: ", from_name);
        !           240:                        bad();
        !           241:                }
        !           242:        }
        !           243:        else {
        !           244:                (void)lseek(from_fd, 0L, L_SET);
        !           245:                copy(from_fd, from_name, to_fd, to_name);
        !           246:        }
        !           247: }
        !           248: 
        !           249: /*
        !           250:  * copy --
        !           251:  *     copy from one file to another
        !           252:  */
        !           253: static
        !           254: copy(from_fd, from_name, to_fd, to_name)
        !           255:        register int from_fd, to_fd;
        !           256:        char *from_name, *to_name;
        !           257: {
        !           258:        register int n;
        !           259:        char buf[MAXBSIZE];
        !           260: 
        !           261:        while ((n = read(from_fd, buf, sizeof(buf))) > 0)
        !           262:                if (write(to_fd, buf, n) != n) {
        !           263:                        PERROR("install: write: ", to_name);
        !           264:                        bad();
        !           265:                }
        !           266:        if (n == -1) {
        !           267:                PERROR("install: read: ", from_name);
        !           268:                bad();
        !           269:        }
        !           270: }
        !           271: 
        !           272: /*
        !           273:  * atoo --
        !           274:  *     octal string to int
        !           275:  */
        !           276: static
        !           277: atoo(str)
        !           278:        register char *str;
        !           279: {
        !           280:        register int val;
        !           281: 
        !           282:        for (val = 0; isdigit(*str); ++str)
        !           283:                val = val * 8 + *str - '0';
        !           284:        return(val);
        !           285: }
        !           286: 
        !           287: /*
        !           288:  * bad --
        !           289:  *     remove created target and die
        !           290:  */
        !           291: static
        !           292: bad()
        !           293: {
        !           294:        (void)unlink(pathbuf);
        !           295:        exit(1);
        !           296: }
        !           297: 
        !           298: /*
        !           299:  * usage --
        !           300:  *     print a usage message and die
        !           301:  */
        !           302: static
        !           303: usage()
        !           304: {
        !           305:        fputs("usage: install [-cs] [-g group] [-m mode] [-o owner] file1 file2;\n\tor file1 ... fileN directory\n", stderr);
        !           306:        exit(1);
        !           307: }

unix.superglobalmegacorp.com

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