Annotation of 43BSDReno/pgrm/xinstall/xinstall.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 provided
        !             6:  * that: (1) source distributions retain this entire copyright notice and
        !             7:  * comment, and (2) distributions including binaries display the following
        !             8:  * acknowledgement:  ``This product includes software developed by the
        !             9:  * University of California, Berkeley and its contributors'' in the
        !            10:  * documentation or other materials provided with the distribution and in
        !            11:  * all advertising materials mentioning features or use of this software.
        !            12:  * Neither the name of the University nor the names of its contributors may
        !            13:  * be used to endorse or promote products derived from this software without
        !            14:  * specific prior written permission.
        !            15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            18:  */
        !            19: 
        !            20: #ifndef lint
        !            21: char copyright[] =
        !            22: "@(#) Copyright (c) 1987 Regents of the University of California.\n\
        !            23:  All rights reserved.\n";
        !            24: #endif /* not lint */
        !            25: 
        !            26: #ifndef lint
        !            27: static char sccsid[] = "@(#)xinstall.c 5.24 (Berkeley) 7/1/90";
        !            28: #endif /* not lint */
        !            29: 
        !            30: #include <sys/param.h>
        !            31: #include <sys/stat.h>
        !            32: #include <sys/file.h>
        !            33: #include <grp.h>
        !            34: #include <pwd.h>
        !            35: #include <stdio.h>
        !            36: #include <ctype.h>
        !            37: #include <paths.h>
        !            38: #include "pathnames.h"
        !            39: 
        !            40: static struct passwd *pp;
        !            41: static struct group *gp;
        !            42: static int docopy, dostrip, mode = 0755;
        !            43: static char *group, *owner, pathbuf[MAXPATHLEN];
        !            44: 
        !            45: main(argc, argv)
        !            46:        int argc;
        !            47:        char **argv;
        !            48: {
        !            49:        extern char *optarg;
        !            50:        extern int optind;
        !            51:        struct stat from_sb, to_sb;
        !            52:        mode_t *set, *setmode();
        !            53:        int ch, no_target;
        !            54:        char *to_name;
        !            55: 
        !            56:        while ((ch = getopt(argc, argv, "cg:m:o:s")) != EOF)
        !            57:                switch((char)ch) {
        !            58:                case 'c':
        !            59:                        docopy = 1;
        !            60:                        break;
        !            61:                case 'g':
        !            62:                        group = optarg;
        !            63:                        break;
        !            64:                case 'm':
        !            65:                        if (!(set = setmode(optarg))) {
        !            66:                                (void)fprintf(stderr,
        !            67:                                    "install: invalid file mode.\n");
        !            68:                                exit(1);
        !            69:                        }
        !            70:                        mode = getmode(set, 0);
        !            71:                        break;
        !            72:                case 'o':
        !            73:                        owner = optarg;
        !            74:                        break;
        !            75:                case 's':
        !            76:                        dostrip = 1;
        !            77:                        break;
        !            78:                case '?':
        !            79:                default:
        !            80:                        usage();
        !            81:                }
        !            82:        argc -= optind;
        !            83:        argv += optind;
        !            84:        if (argc < 2)
        !            85:                usage();
        !            86: 
        !            87:        /* get group and owner id's */
        !            88:        if (group && !(gp = getgrnam(group))) {
        !            89:                fprintf(stderr, "install: unknown group %s.\n", group);
        !            90:                exit(1);
        !            91:        }
        !            92:        if (owner && !(pp = getpwnam(owner))) {
        !            93:                fprintf(stderr, "install: unknown user %s.\n", owner);
        !            94:                exit(1);
        !            95:        }
        !            96: 
        !            97:        no_target = stat(to_name = argv[argc - 1], &to_sb);
        !            98:        if (!no_target && (to_sb.st_mode & S_IFMT) == S_IFDIR) {
        !            99:                for (; *argv != to_name; ++argv)
        !           100:                        install(*argv, to_name, 1);
        !           101:                exit(0);
        !           102:        }
        !           103: 
        !           104:        /* can't do file1 file2 directory/file */
        !           105:        if (argc != 2)
        !           106:                usage();
        !           107: 
        !           108:        if (!no_target) {
        !           109:                if (stat(*argv, &from_sb)) {
        !           110:                        fprintf(stderr, "install: can't find %s.\n", *argv);
        !           111:                        exit(1);
        !           112:                }
        !           113:                if ((to_sb.st_mode & S_IFMT) != S_IFREG) {
        !           114:                        fprintf(stderr, "install: %s isn't a regular file.\n", to_name);
        !           115:                        exit(1);
        !           116:                }
        !           117:                if (to_sb.st_dev == from_sb.st_dev && to_sb.st_ino == from_sb.st_ino) {
        !           118:                        fprintf(stderr, "install: %s and %s are the same file.\n", *argv, to_name);
        !           119:                        exit(1);
        !           120:                }
        !           121:                /* unlink now... avoid ETXTBSY errors later */
        !           122:                (void)unlink(to_name);
        !           123:        }
        !           124:        install(*argv, to_name, 0);
        !           125:        exit(0);
        !           126: }
        !           127: 
        !           128: /*
        !           129:  * install --
        !           130:  *     build a path name and install the file
        !           131:  */
        !           132: install(from_name, to_name, isdir)
        !           133:        char *from_name, *to_name;
        !           134:        int isdir;
        !           135: {
        !           136:        struct stat from_sb;
        !           137:        int devnull, from_fd, to_fd;
        !           138:        char *C, *rindex();
        !           139: 
        !           140:        /* if try to install NULL file to a directory, fails */
        !           141:        if (isdir || strcmp(from_name, _PATH_DEVNULL)) {
        !           142:                if (stat(from_name, &from_sb)) {
        !           143:                        fprintf(stderr, "install: can't find %s.\n", from_name);
        !           144:                        exit(1);
        !           145:                }
        !           146:                if ((from_sb.st_mode & S_IFMT) != S_IFREG) {
        !           147:                        fprintf(stderr, "install: %s isn't a regular file.\n", from_name);
        !           148:                        exit(1);
        !           149:                }
        !           150:                /* build the target path */
        !           151:                if (isdir) {
        !           152:                        (void)sprintf(pathbuf, "%s/%s", to_name, (C = rindex(from_name, '/')) ? ++C : from_name);
        !           153:                        to_name = pathbuf;
        !           154:                }
        !           155:                devnull = 0;
        !           156:        } else
        !           157:                devnull = 1;
        !           158: 
        !           159:        /* unlink now... avoid ETXTBSY errors later */
        !           160:        (void)unlink(to_name);
        !           161: 
        !           162:        /* create target */
        !           163:        if ((to_fd = open(to_name, O_CREAT|O_WRONLY|O_TRUNC, 0600)) < 0) {
        !           164:                error(to_name);
        !           165:                exit(1);
        !           166:        }
        !           167:        if (!devnull) {
        !           168:                if ((from_fd = open(from_name, O_RDONLY, 0)) < 0) {
        !           169:                        (void)unlink(to_name);
        !           170:                        error(from_name);
        !           171:                        exit(1);
        !           172:                }
        !           173:                copy(from_fd, from_name, to_fd, to_name);
        !           174:                (void)close(from_fd);
        !           175:        }
        !           176:        if (dostrip)
        !           177:                strip(to_name);
        !           178:        /*
        !           179:         * set owner, group, mode for target; do the chown first,
        !           180:         * chown may lose the setuid bits.
        !           181:         */
        !           182:        if ((group || owner) &&
        !           183:            fchown(to_fd, owner ? pp->pw_uid : -1, group ? gp->gr_gid : -1) ||
        !           184:            fchmod(to_fd, mode)) {
        !           185:                error(to_name);
        !           186:                bad(to_name);
        !           187:        }
        !           188:        (void)close(to_fd);
        !           189:        if (!docopy && !devnull && unlink(from_name)) {
        !           190:                error(from_name);
        !           191:                exit(1);
        !           192:        }
        !           193: }
        !           194: 
        !           195: /*
        !           196:  * copy --
        !           197:  *     copy from one file to another
        !           198:  */
        !           199: copy(from_fd, from_name, to_fd, to_name)
        !           200:        register int from_fd, to_fd;
        !           201:        char *from_name, *to_name;
        !           202: {
        !           203:        register int n;
        !           204:        char buf[MAXBSIZE];
        !           205: 
        !           206:        while ((n = read(from_fd, buf, sizeof(buf))) > 0)
        !           207:                if (write(to_fd, buf, n) != n) {
        !           208:                        error(to_name);
        !           209:                        bad(to_name);
        !           210:                }
        !           211:        if (n == -1) {
        !           212:                error(from_name);
        !           213:                bad(to_name);
        !           214:        }
        !           215: }
        !           216: 
        !           217: /*
        !           218:  * strip --
        !           219:  *     use strip(1) to strip the target file
        !           220:  */
        !           221: strip(to_name)
        !           222:        char *to_name;
        !           223: {
        !           224:        int status;
        !           225: 
        !           226:        switch (vfork()) {
        !           227:        case -1:
        !           228:                error("fork");
        !           229:                bad(to_name);
        !           230:        case 0:
        !           231:                execl(_PATH_STRIP, "strip", to_name, (char *)NULL);
        !           232:                error(_PATH_STRIP);
        !           233:                _exit(1);
        !           234:        default:
        !           235:                if (wait(&status) == -1 || status)
        !           236:                        bad(to_name);
        !           237:        }
        !           238: }
        !           239: 
        !           240: /*
        !           241:  * error --
        !           242:  *     print out an error message
        !           243:  */
        !           244: error(s)
        !           245:        char *s;
        !           246: {
        !           247:        extern int errno;
        !           248:        char *strerror();
        !           249: 
        !           250:        (void)fprintf(stderr, "install: %s: %s\n", s, strerror(errno));
        !           251: }
        !           252: 
        !           253: /*
        !           254:  * bad --
        !           255:  *     remove created target and die
        !           256:  */
        !           257: bad(fname)
        !           258:        char *fname;
        !           259: {
        !           260:        (void)unlink(fname);
        !           261:        exit(1);
        !           262: }
        !           263: 
        !           264: /*
        !           265:  * usage --
        !           266:  *     print a usage message and die
        !           267:  */
        !           268: usage()
        !           269: {
        !           270:        (void)fprintf(stderr,
        !           271: "usage: install [-cs] [-g group] [-m mode] [-o owner] file1 file2;\n\tor file1 ... fileN directory\n");
        !           272:        exit(1);
        !           273: }

unix.superglobalmegacorp.com

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