4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 1996 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
40 #pragma ident "%Z%%M% %I% %E% SMI"
42 #include <sys/param.h>
43 #include <sys/types.h>
54 #define DEF_GROUP "staff" /* default group */
55 #define DEF_OWNER "root" /* default owner */
56 #define DEF_MODE 0755 /* default mode */
58 char *group
= DEF_GROUP
;
59 char *owner
= DEF_OWNER
;
69 main(int argc
, char **argv
)
83 (void) setlocale(LC_ALL
, "");
85 #if !defined(TEXT_DOMAIN)
86 #define TEXT_DOMAIN "SYS_TEST"
88 (void) textdomain(TEXT_DOMAIN
);
90 while ((ch
= getopt(argc
, argv
, "dcg:o:m:s")) != EOF
)
93 break; /* always do "copy" */
119 /* get group and owner id's */
120 if (!(gp
= getgrnam(group
))) {
121 fprintf(stderr
, gettext("install: unknown group %s.\n"), group
);
124 if (!(pp
= getpwnam(owner
))) {
125 fprintf(stderr
, gettext("install: unknown user %s.\n"), owner
);
129 if (dflag
) { /* install a directory */
135 if (mkdirp(dirname
, 0777) < 0) {
136 exists
= errno
== EEXIST
;
138 fprintf(stderr
, gettext("install: mkdir: %s: %s\n"), dirname
, strerror(errno
));
142 if (stat(dirname
, &stb
) < 0) {
143 fprintf(stderr
, gettext("install: stat: %s: %s\n"), dirname
, strerror(errno
));
146 if ((stb
.st_mode
&S_IFMT
) != S_IFDIR
) {
147 fprintf(stderr
, gettext("install: %s is not a directory\n"), dirname
);
149 /* make sure directory setgid bit is inherited */
150 mode
= (mode
& ~S_ISGID
) | (stb
.st_mode
& S_ISGID
);
151 if (mflag
&& chmod(dirname
, mode
)) {
152 fprintf(stderr
, gettext("install: chmod: %s: %s\n"), dirname
, strerror(errno
));
154 (void) unlink(dirname
);
157 if (oflag
&& chown(dirname
, pp
->pw_uid
, -1) && errno
!= EPERM
) {
158 fprintf(stderr
, gettext("install: chown: %s: %s\n"), dirname
, strerror(errno
));
160 (void) unlink(dirname
);
163 if (gflag
&& chown(dirname
, -1, gp
->gr_gid
) && errno
!= EPERM
) {
164 fprintf(stderr
, gettext("install: chgrp: %s: %s\n"), dirname
, strerror(errno
));
166 (void) unlink(dirname
);
175 if (argc
> 2) { /* last arg must be a directory */
176 if (stat(argv
[argc
-1], &stb
) < 0)
178 if ((stb
.st_mode
&S_IFMT
) != S_IFDIR
)
182 for (i
= 0; i
< argc
-1; i
++)
183 rc
|= install(argv
[i
], argv
[argc
-1]);
195 struct stat from_sb
, to_sb
;
196 static char pbuf
[MAXPATHLEN
];
197 char buf
[MAXPATHLEN
+ 10];
200 if (stat(from
, &from_sb
)) {
201 fprintf(stderr
, gettext("install: %s: %s\n"), from
, strerror(errno
));
204 /* special case for removing files */
205 devnull
= !strcmp(from
, "/dev/null");
206 if (!devnull
&& !((from_sb
.st_mode
&S_IFMT
) == S_IFREG
)) {
207 fprintf(stderr
, gettext("install: %s isn't a regular file.\n"), from
);
211 /* build target path, find out if target is same as source */
212 if (!stat(path
= to
, &to_sb
)) {
213 if ((to_sb
.st_mode
&S_IFMT
) == S_IFDIR
) {
216 (void) sprintf(path
= pbuf
, "%s/%s", to
, (C
= strrchr(from
, '/')) ? ++C
: from
);
217 if (stat(path
, &to_sb
))
220 if ((to_sb
.st_mode
&S_IFMT
) != S_IFREG
) {
221 fprintf(stderr
, gettext("install: %s isn't a regular file.\n"), path
);
224 if (to_sb
.st_dev
== from_sb
.st_dev
&& to_sb
.st_ino
== from_sb
.st_ino
) {
225 fprintf(stderr
, gettext("install: %s and %s are the same file.\n"), from
, path
);
228 /* unlink now... avoid ETXTBSY errors later */
233 /* open target, set mode, owner, group */
234 if ((to_fd
= open(path
, O_CREAT
|O_WRONLY
|O_TRUNC
, 0)) < 0) {
235 fprintf(stderr
, gettext("install: %s: %s\n"), path
, strerror(errno
));
238 if (fchmod(to_fd
, mode
)) {
239 fprintf(stderr
, gettext("install: chmod: %s: %s\n"), path
, strerror(errno
));
245 status
= copy(from
, to_fd
, path
); /* copy */
249 sprintf(buf
, "strip %s", path
);
252 if (chown(path
, pp
->pw_uid
, gp
->gr_gid
) && errno
!= EPERM
) {
253 fprintf(stderr
, gettext("install: chown: %s: %s\n"), path
, strerror(errno
));
265 * copy from one file to another
268 copy(from_name
, to_fd
, to_name
)
270 char *from_name
, *to_name
;
276 if ((from_fd
= open(from_name
, O_RDONLY
, 0)) < 0) {
277 fprintf(stderr
, gettext("install: open: %s: %s\n"), from_name
, strerror(errno
));
280 while ((n
= read(from_fd
, buf
, sizeof(buf
))) > 0)
281 if (write(to_fd
, buf
, n
) != n
) {
282 fprintf(stderr
, gettext("install: write: %s: %s\n"), to_name
, strerror(errno
));
287 fprintf(stderr
, gettext("install: read: %s: %s\n"), from_name
, strerror(errno
));
293 (void) close(from_fd
);
299 * octal string to int
307 for (val
= 0; isdigit(*str
); ++str
)
308 val
= val
* 8 + *str
- '0';
315 * print a usage message and die
320 fputs(gettext("usage: install [-cs] [-g group] [-m mode] [-o owner] file ... destination\n"), stderr
);
321 fputs(gettext(" install -d [-g group] [-m mode] [-o owner] dir\n"), stderr
);
327 * make a directory and parents if needed
339 if (mkdir(dir
, mode
) == 0)
343 slash
= strrchr(dir
, '/');
347 err
= mkdirp(dir
, 0777);
351 return mkdir(dir
, mode
);