* Copyright (c) 1987 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1987 Regents of the University of California.\n\
static char sccsid
[] = "@(#)xinstall.c 5.2 (Berkeley) %G%";
#define YES 1 /* yes/true */
#define DEF_GROUP "staff" /* default group */
#define DEF_OWNER "root" /* default owner */
static int docopy
, dostrip
,
static char *group
= DEF_GROUP
,
extern char *optarg
, *sys_errlist
[];
extern int optind
, errno
;
struct stat from_sb
, to_sb
;
while ((ch
= getopt(argc
, argv
, "cg:m:o:s")) != EOF
)
/* get group and owner id's */
if (!(gp
= getgrnam(group
))) {
fprintf(stderr
, "install: unknown group %s.\n", group
);
if (!(pp
= getpwnam(owner
))) {
fprintf(stderr
, "install: unknown user %s.\n", owner
);
if (stat(argv
[0], &from_sb
)) {
fprintf(stderr
, "install: fstat: %s: %s\n", argv
[0], sys_errlist
[errno
]);
if (!(from_sb
.st_mode
& S_IFREG
)) {
fprintf(stderr
, "install: %s isn't a regular file.\n", argv
[0]);
/* build target path, find out if target is same as source */
if (!stat(path
= argv
[1], &to_sb
)) {
if (to_sb
.st_mode
& S_IFDIR
) {
(void)sprintf(path
= pbuf
, "%s/%s", argv
[1], argv
[0]);
if (to_sb
.st_mode
& S_IFDIR
) {
fprintf(stderr
, "install: %s is a directory.\n", path
);
if (to_sb
.st_dev
== from_sb
.st_dev
&& to_sb
.st_ino
== from_sb
.st_ino
) {
fprintf(stderr
, "install: %s and %s are the same file.\n", argv
[0], path
);
/* unlink now... avoid ETXTBSY errors later */
/* open target, set mode, owner, group */
if ((to_fd
= open(path
, O_CREAT
|O_WRONLY
|O_TRUNC
, 0)) < 0) {
fprintf(stderr
, "install: %s: %s\n", path
, sys_errlist
[errno
]);
if (fchmod(to_fd
, mode
)) {
fprintf(stderr
, "install: fchmod: %s: %s\n", path
, sys_errlist
[errno
]);
if (fchown(to_fd
, pp
->pw_uid
, gp
->gr_gid
)) {
fprintf(stderr
, "install: fchown: %s: %s\n", path
, sys_errlist
[errno
]);
strip(to_fd
, argv
[0], path
);
copy(argv
[0], to_fd
, path
);
else if (rename(argv
[0], path
))
copy(argv
[0], to_fd
, path
);
* copy from one file to another
copy(from_name
, to_fd
, to_name
)
char *from_name
, *to_name
;
if ((from_fd
= open(from_name
, O_RDONLY
, 0)) < 0) {
fprintf(stderr
, "install: open: %s: %s\n", from_name
, sys_errlist
[errno
]);
while ((n
= read(from_fd
, buf
, sizeof(buf
))) > 0)
if (write(to_fd
, buf
, n
) != n
) {
fprintf(stderr
, "install: write: %s: %s\n", to_name
, sys_errlist
[errno
]);
fprintf(stderr
, "install: read: %s: %s\n", from_name
, sys_errlist
[errno
]);
* copy file, strip(1)'ing it at the same time
strip(to_fd
, from_name
, to_name
)
char *from_name
, *to_name
;
typedef struct exec EXEC
;
if ((from_fd
= open(from_name
, O_RDONLY
, 0)) < 0) {
fprintf(stderr
, "install: open: %s: %s\n", from_name
, sys_errlist
[errno
]);
if (read(from_fd
, (char *)&head
, sizeof(head
)) < 0 || N_BADMAG(head
)) {
fprintf(stderr
, "install: %s not in a.out format.\n", from_name
);
if (head
.a_syms
|| head
.a_trsize
|| head
.a_drsize
) {
size
= (long)head
.a_text
+ head
.a_data
;
head
.a_syms
= head
.a_trsize
= head
.a_drsize
= 0;
if (head
.a_magic
== ZMAGIC
)
size
+= getpagesize() - sizeof(EXEC
);
if (write(to_fd
, (char *)&head
, sizeof(EXEC
)) != sizeof(EXEC
)) {
fprintf(stderr
, "install: write: %s: %s\n", to_name
, sys_errlist
[errno
]);
if ((n
= read(from_fd
, buf
, (int)MIN(size
, sizeof(buf
)))) <= 0)
else if (write(to_fd
, buf
, n
) != n
) {
fprintf(stderr
, "install: write: %s: %s\n", to_name
, sys_errlist
[errno
]);
fprintf(stderr
, "install: read: %s: premature EOF.\n", from_name
);
fprintf(stderr
, "install: read: %s: %s\n", from_name
, sys_errlist
[errno
]);
for (val
= 0; isdigit(*str
); ++str
)
val
= val
* 8 + *str
- '0';
* print a usage message and die
fputs("usage: install [-cs] [-g group] [-m mode] [-o owner] source destination\n", stderr
);
* remove created target and die