xref: /illumos-gate/usr/src/tools/install.bin/install.bin.c (revision a38ddfee9c8c6b6c5a2947ff52fd2338362a4444)
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