Home | History | Annotate | Download | only in install.bin
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27 
     28 
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 #include <strings.h>
     32 #include <sys/param.h>
     33 #include <fcntl.h>
     34 #include <sys/errno.h>
     35 #include <sys/types.h>
     36 #include <sys/uio.h>
     37 #include <unistd.h>
     38 #include <sys/stat.h>
     39 #include <errno.h>
     40 #include <libgen.h>
     41 #include "stdusers.h"
     42 
     43 
     44 #define	FILE_BUFF	40960
     45 
     46 int supress = 0;
     47 
     48 
     49 void
     50 usage(void)
     51 {
     52 	(void) fprintf(stderr,
     53 	    "usage: install [-sd][-m mode][-g group][-u owner] "
     54 	    "-f dir file ...\n");
     55 }
     56 
     57 void
     58 file_copy(char *src_file, char *dest_file)
     59 {
     60 	int	src_fd;
     61 	int	dest_fd;
     62 	int	count;
     63 	static char file_buff[FILE_BUFF];
     64 
     65 	if ((src_fd = open(src_file, O_RDONLY))  == -1) {
     66 		perror(src_file);
     67 		exit(1);
     68 	}
     69 
     70 	if ((dest_fd = open(dest_file, O_CREAT|O_WRONLY|O_TRUNC, 0755)) == -1) {
     71 		perror(dest_file);
     72 		exit(1);
     73 	}
     74 
     75 	while ((count = read(src_fd, file_buff, FILE_BUFF)) > 0) {
     76 		write(dest_fd, file_buff, count);
     77 	}
     78 
     79 	if (count == -1) {
     80 		perror("file_copy(read)");
     81 		exit(1);
     82 	}
     83 
     84 	if (!supress)
     85 		(void) printf("%s installed as %s\n", src_file, dest_file);
     86 
     87 	close(src_fd);
     88 	close(dest_fd);
     89 }
     90 
     91 
     92 void
     93 chown_file(const char *file, const char *group, const char *owner)
     94 {
     95 	gid_t	grp = (gid_t)-1;
     96 	uid_t	own = (uid_t)-1;
     97 
     98 	if (group) {
     99 		grp = stdfind(group, groupnames);
    100 		if (grp < 0)
    101 			(void) fprintf(stderr, "unknown group(%s)\n", group);
    102 	}
    103 
    104 	if (owner) {
    105 		own = stdfind(owner, usernames);
    106 		if (own < 0) {
    107 			(void) fprintf(stderr, "unknown owner(%s)\n", owner);
    108 			exit(1);
    109 		}
    110 
    111 	}
    112 
    113 	if (chown(file, own, grp) == -1) {
    114 		perror("chown");
    115 		exit(1);
    116 	}
    117 }
    118 
    119 char *
    120 find_basename(const char *str)
    121 {
    122 	int	i;
    123 	int	len;
    124 
    125 	len = strlen(str);
    126 
    127 	for (i = len-1; i >= 0; i--)
    128 		if (str[i] == '/')
    129 			return ((char *)(str + i + 1));
    130 	return ((char *)str);
    131 }
    132 
    133 
    134 int
    135 main(int argc, char **argv)
    136 {
    137 	int	c;
    138 	int	errflg = 0;
    139 	int	dirflg = 0;
    140 	char	*group = NULL;
    141 	char	*owner = NULL;
    142 	char	*dirb = NULL;
    143 	char	*ins_file = NULL;
    144 	int	mode = -1;
    145 	char	dest_file[MAXPATHLEN];
    146 
    147 
    148 	while ((c = getopt(argc, argv, "f:sm:du:g:")) != EOF) {
    149 		switch (c) {
    150 		case 'f':
    151 			dirb = optarg;
    152 			break;
    153 		case 'g':
    154 			group = optarg;
    155 			break;
    156 		case 'u':
    157 			owner = optarg;
    158 			break;
    159 		case 'd':
    160 			dirflg = 1;
    161 			break;
    162 		case 'm':
    163 			mode = strtol(optarg, NULL, 8);
    164 			break;
    165 		case 's':
    166 			supress = 1;
    167 			break;
    168 		case '?':
    169 			errflg++;
    170 			break;
    171 		}
    172 	}
    173 
    174 	if (errflg) {
    175 		usage();
    176 		return (1);
    177 	}
    178 
    179 	if (argc == optind) {
    180 		usage();
    181 		return (1);
    182 	}
    183 
    184 	if (!dirflg && (dirb == NULL)) {
    185 		(void) fprintf(stderr,
    186 		    "install: no destination directory specified.\n");
    187 		return (1);
    188 	}
    189 
    190 
    191 	for (c = optind; c < argc; c++) {
    192 		ins_file = argv[c];
    193 
    194 		if (dirflg) {
    195 			struct stat buf;
    196 
    197 			if (stat(ins_file, &buf) == 0) {
    198 				if ((buf.st_mode & S_IFMT) == S_IFDIR)
    199 					continue;
    200 			} else {
    201 				if (errno != ENOENT) {
    202 					perror("install: stat");
    203 					return (1);
    204 				}
    205 			}
    206 
    207 			(void) strcpy(dest_file, ins_file);
    208 
    209 			if (mkdirp(dest_file, 0755) == -1) {
    210 				if (!supress) {
    211 					(void) printf(
    212 					    "install: mkdirp of %s failed\n",
    213 					    dest_file);
    214 				}
    215 			} else if (!supress) {
    216 				(void) printf("directory %s created\n",
    217 				    dest_file);
    218 			}
    219 		} else {
    220 			(void) strcat(strcat(strcpy(dest_file, dirb), "/"),
    221 			    find_basename(ins_file));
    222 			file_copy(ins_file, dest_file);
    223 		}
    224 
    225 		if (group || owner)
    226 			chown_file(dest_file, group, owner);
    227 
    228 		if (mode != -1) {
    229 			umask(0);
    230 			if (chmod(dest_file, mode) == -1) {
    231 				perror("chmod");
    232 				return (1);
    233 			}
    234 		}
    235 	}
    236 	return (0);
    237 }
    238