Annotation of 43BSDTahoe/usr.bin/install.c, revision 1.1.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.