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 (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <strings.h>
29 #include <sys/param.h>
30 #include <fcntl.h>
31 #include <sys/errno.h>
32 #include <sys/types.h>
33 #include <sys/uio.h>
34 #include <unistd.h>
35 #include <sys/stat.h>
36 #include <errno.h>
37 #include <libgen.h>
38 #include "stdusers.h"
39
40
41 #define FILE_BUFF 40960
42
43 static int suppress = 0;
44
45 static void usage(void);
46 static void file_copy(char *src_file, char *dest_file);
47 static void chown_file(const char *file, const char *group, const char *owner);
48 static char *find_basename(const char *str);
49 static int creatdir(char *fn);
50
51
52 void
usage(void)53 usage(void)
54 {
55 (void) fprintf(stderr,
56 "usage: install [-sd][-m mode][-g group][-u owner] "
57 "-f dir file ...\n");
58 }
59
60 void
file_copy(char * src_file,char * dest_file)61 file_copy(char *src_file, char *dest_file)
62 {
63 int src_fd;
64 int dest_fd;
65 int count;
66 static char file_buff[FILE_BUFF];
67
68 if ((src_fd = open(src_file, O_RDONLY)) == -1) {
69 (void) fprintf(stderr, "install:file_copy: %s failed "
70 "(%d): %s\n", src_file, errno, strerror(errno));
71 exit(1);
72 }
73
74 if ((dest_fd = open(dest_file, O_CREAT|O_WRONLY|O_TRUNC, 0755)) == -1) {
75 (void) fprintf(stderr, "install:file_copy: %s failed "
76 "(%d): %s\n", dest_file, errno, strerror(errno));
77 exit(1);
78 }
79
80 while ((count = read(src_fd, file_buff, FILE_BUFF)) > 0) {
81 (void) write(dest_fd, file_buff, count);
82 }
83
84 if (count == -1) {
85 (void) fprintf(stderr, "install:file_copy:read failed "
86 "(%d): %s\n", errno, strerror(errno));
87 exit(1);
88 }
89
90 if (!suppress)
91 (void) printf("%s installed as %s\n", src_file, dest_file);
92
93 (void) close(src_fd);
94 (void) close(dest_fd);
95 }
96
97
98 void
chown_file(const char * file,const char * group,const char * owner)99 chown_file(const char *file, const char *group, const char *owner)
100 {
101 gid_t grp = (gid_t)-1;
102 uid_t own = (uid_t)-1;
103
104 if (group) {
105 grp = stdfind(group, groupnames);
106 if (grp < 0)
107 (void) fprintf(stderr, "unknown group(%s)\n", group);
108 }
109
110 if (owner) {
111 own = stdfind(owner, usernames);
112 if (own < 0) {
113 (void) fprintf(stderr, "unknown owner(%s)\n", owner);
114 exit(1);
115 }
116
117 }
118
119 if (chown(file, own, grp) == -1) {
120 (void) fprintf(stderr, "install:chown_file: failed "
121 "(%d): %s\n", errno, strerror(errno));
122 exit(1);
123 }
124 }
125
126
127 char *
find_basename(const char * str)128 find_basename(const char *str)
129 {
130 int i;
131 int len;
132
133 len = strlen(str);
134
135 for (i = len-1; i >= 0; i--)
136 if (str[i] == '/')
137 return ((char *)(str + i + 1));
138 return ((char *)str);
139 }
140
141 int
creatdir(char * fn)142 creatdir(char *fn) {
143
144 errno = 0;
145
146 if (mkdirp(fn, 0755) == -1) {
147 if (errno != EEXIST)
148 return (errno);
149 } else if (!suppress) {
150 (void) printf("directory %s created\n", fn);
151 }
152 return (0);
153 }
154
155
156 int
main(int argc,char ** argv)157 main(int argc, char **argv)
158 {
159 int c;
160 int errflg = 0;
161 int dirflg = 0;
162 char *group = NULL;
163 char *owner = NULL;
164 char *dirb = NULL;
165 char *ins_file = NULL;
166 int mode = -1;
167 char dest_file[MAXPATHLEN];
168 int rv = 0;
169
170 while ((c = getopt(argc, argv, "f:sm:du:g:")) != EOF) {
171 switch (c) {
172 case 'f':
173 dirb = optarg;
174 break;
175 case 'g':
176 group = optarg;
177 break;
178 case 'u':
179 owner = optarg;
180 break;
181 case 'd':
182 dirflg = 1;
183 break;
184 case 'm':
185 mode = strtol(optarg, NULL, 8);
186 break;
187 case 's':
188 suppress = 1;
189 break;
190 case '?':
191 errflg++;
192 break;
193 }
194 }
195
196 if (errflg) {
197 usage();
198 return (1);
199 }
200
201 if (argc == optind) {
202 usage();
203 return (1);
204 }
205
206 if (!dirflg && (dirb == NULL)) {
207 (void) fprintf(stderr,
208 "install: no destination directory specified.\n");
209 return (1);
210 }
211
212 for (c = optind; c < argc; c++) {
213 ins_file = argv[c];
214
215 if (dirflg) {
216 rv = creatdir(ins_file);
217 if (rv) {
218 (void) fprintf(stderr,
219 "install: creatdir %s (%d): %s\n",
220 ins_file, errno, strerror(errno));
221 return (rv);
222 }
223 (void) strlcpy(dest_file, ins_file, MAXPATHLEN);
224
225 } else {
226 (void) strcat(strcat(strcpy(dest_file, dirb), "/"),
227 find_basename(ins_file));
228 file_copy(ins_file, dest_file);
229 }
230
231 if (group || owner)
232 chown_file(dest_file, group, owner);
233
234 if (mode != -1) {
235 (void) umask(0);
236 if (chmod(dest_file, mode) == -1) {
237 (void) fprintf(stderr,
238 "install: chmod of %s to mode %o failed "
239 "(%d): %s\n",
240 dest_file, mode, errno, strerror(errno));
241 return (1);
242 }
243 }
244 }
245 return (0);
246 }
247