mirror of
https://github.com/GnoConsortium/gno.git
synced 2025-02-24 07:28:58 +00:00
updated for inclusion in GNO base build
This commit is contained in:
parent
14a1927519
commit
c6e102e916
@ -1,4 +1,4 @@
|
||||
Copyright 1996 Devin Reade <gdr@myrias.com>.
|
||||
Copyright 1996-1997 Devin Reade <gdr@myrias.com>.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -29,5 +29,5 @@ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE.
|
||||
|
||||
The binary distribution of this program contains material from the Orca/C
|
||||
Run-Time Libraries, copyright 1987-1996 by Byte Works, Inc. Used with
|
||||
Run-Time Libraries, copyright 1987-1997 by Byte Works, Inc. Used with
|
||||
permission.
|
||||
|
46
usr.bin/install/Makefile
Normal file
46
usr.bin/install/Makefile
Normal file
@ -0,0 +1,46 @@
|
||||
#
|
||||
# $Id: Makefile,v 1.1 1997/10/30 04:14:21 gdr Exp $
|
||||
#
|
||||
|
||||
# Don't name this "install"; we change the name later.
|
||||
PROG = inst
|
||||
|
||||
.INCLUDE: /src/gno/paths.mk
|
||||
.INCLUDE: /src/gno/binconst.mk
|
||||
|
||||
BINDIR = /usr/bin
|
||||
MANDIR = /usr/man
|
||||
OBJS = $(SRCS:s/.c/.o/:f)
|
||||
OPTIMIZE = 78
|
||||
STACK = 1024
|
||||
|
||||
# Add -D__STACK_CHECK__ to DEFINES to show stack usage.
|
||||
DEFINES +=
|
||||
CFLAGS += -I/src/gno/lib/libcontrib
|
||||
CFLAGS += -r -O$(OPTIMIZE) $(DEFINES) -s$(STACK)
|
||||
LDLIBS += -l/src/gno/lib/libcontrib/libcontrib
|
||||
|
||||
RELBIN = $(RELEASE_DIR)$(BINDIR)
|
||||
RELMAN = $(RELEASE_DIR)$(MANDIR)
|
||||
|
||||
INST = ./$(PROG)
|
||||
|
||||
.INCLUDE: /src/gno/binrules.mk
|
||||
|
||||
# Place files where they will subsequently be archived in a binary
|
||||
# distribution.
|
||||
#
|
||||
# This is slightly different from the standard 'release' target because
|
||||
# the binary is renamed when it is installed.
|
||||
#
|
||||
release: $(PROG) $(PROG).1 $(DESC)
|
||||
$(INST) -d $(RELBIN) $(RELMAN)/man1 $(DESC_DIR)
|
||||
$(INST) $(PROG) $(RELBIN)/install
|
||||
$(INST) $(PROG).1 $(RELMAN)/man1/install.1
|
||||
$(DESCU) -o $(DESC_SRC) $(DESC_SRC) $(DESC)
|
||||
|
||||
install: $(PROG) $(PROG).1 $(DESC)
|
||||
$(INST) -d $(BINDIR) $(MANDIR)/man1 $(DESC_DIR)
|
||||
$(INST) $(PROG) $(BINDIR)/install
|
||||
$(INST) $(PROG).1 $(MANDIR)/man1/install.1
|
||||
$(DESCU) -o $(DESC_SRC) $(DESC_SRC) $(DESC)
|
@ -1,4 +1,4 @@
|
||||
$Id: README,v 1.1 1996/09/03 03:54:55 gdr Exp $
|
||||
$Id: README,v 1.2 1997/10/30 04:14:21 gdr Exp $
|
||||
|
||||
As the describe file says, install(1) is a utility similar to cp(1),
|
||||
except that it does a few more things and is intended for use in
|
||||
@ -14,3 +14,17 @@ encounter problems or bugs.
|
||||
|
||||
Devin Reade
|
||||
March 1996
|
||||
|
||||
|
||||
CHANGE LOG
|
||||
==========
|
||||
|
||||
v1.1 August 1997
|
||||
- Incorporated install(1) into base GNO v2.0.6 distribution
|
||||
- Use the GNO v2.0.6 libcontrib library
|
||||
- Symbolic mode arguments now use mode 0000 as a starting point,
|
||||
rather than the original file mode. This corresponds to the
|
||||
usual UNIX usage.
|
||||
|
||||
v1.0 March 1996
|
||||
Initial Version
|
||||
|
@ -1,8 +1,8 @@
|
||||
.\" Copyright 1996 Devin Reade <gdr@myrias.com>
|
||||
.\" Copyright 1996-1997 Devin Reade <gdr@myrias.com>
|
||||
.\"
|
||||
.\" $Id: inst.1,v 1.1 1996/03/31 23:38:32 gdr Exp $
|
||||
.\" $Id: inst.1,v 1.2 1997/10/30 04:14:21 gdr Exp $
|
||||
.\"
|
||||
.TH INSTALL 1 "Commands and Applications" "31 Mar 96" "Version 1.0"
|
||||
.TH INSTALL 1 "16 October 1997" GNO "Commands and Applications"
|
||||
.SH NAME
|
||||
install \- copy files and set their attributes
|
||||
.SH SYNOPSIS
|
||||
@ -46,13 +46,13 @@ and any leading directories, and to set the directories modes.
|
||||
Some of the options listed below are not implemented or are implemented
|
||||
in a restricted sense. Such options are recognised to maximize
|
||||
.BR install 's
|
||||
compatibility with other Unix versions, in order to minimize problems
|
||||
compatibility with other UNIX versions, in order to minimize problems
|
||||
with ported shell scripts and makefiles. Where options are not fully
|
||||
implemented, it is usually due to differences between Unix and GS/OS.
|
||||
implemented, it is usually due to differences between UNIX and GS/OS.
|
||||
.SH OPTIONS
|
||||
.IP \fB-c\fR
|
||||
Ignored. This option is included for backwards compatibility
|
||||
with old Unix versions of
|
||||
with old UNIX versions of
|
||||
.BR install .
|
||||
.IP \fB-d\fR
|
||||
Create each given directory and its leading directories, if they
|
||||
@ -61,7 +61,7 @@ do not already exist.
|
||||
Set the group ownership of the installed file or directory to the group
|
||||
ID of
|
||||
.I group
|
||||
(default is the processes current group).
|
||||
(default is the processes' current group).
|
||||
.I group
|
||||
may also be a numeric group ID.
|
||||
.sp
|
||||
@ -72,12 +72,12 @@ Show usage information and exit.
|
||||
Set the permission mode for the installed file or directory to
|
||||
.IR mode ,
|
||||
which can be either an octal number, or a symbolic mode as in the
|
||||
Unix chmod command,
|
||||
UNIX chmod command,
|
||||
with 0 as the point of departure. The default mode is 0755.
|
||||
.sp
|
||||
Note that currently under GNO, the
|
||||
.I mode
|
||||
is interpreted in the traditional Unix sense in that it only affects
|
||||
is interpreted in the traditional UNIX sense in that it only affects
|
||||
read, write, and (to a limited extent) execute permissions.
|
||||
Furthermore, the only bits interpreted are those for the
|
||||
user permissions; the
|
||||
@ -85,11 +85,9 @@ user permissions; the
|
||||
is effectively bitwise `anded' with the constant 0700.
|
||||
.sp
|
||||
An execute modification is only permitted when the original file
|
||||
is of type TXT or SRC. If the `execute bit' is enabled, then
|
||||
the file type will be changed to SRC and the auxilliary type to EXEC.
|
||||
This is equivalent to making the file an executable shell script.
|
||||
If the `execute bit' is disabled, then the file type will be changed
|
||||
to TXT and the auxilliary type to 0x0000.
|
||||
is of type TXT or SRC, in which case the file becomes a shell script
|
||||
(type SRC, auxtype 0x0006). See also
|
||||
.BR chmod (2).
|
||||
.IP "\fB-o\fR \fIowner\fR"
|
||||
If run as root, set the ownership of the installed file to the user ID of
|
||||
.IR owner .
|
||||
@ -103,5 +101,12 @@ Strip the symbol tables from the installed programs.
|
||||
\fBThis is currently ignored under GNO.\fR
|
||||
.IP \fB-v\fR
|
||||
Show version number.
|
||||
.SH VERSION
|
||||
This manual page documents
|
||||
.BR install
|
||||
version 1.1.
|
||||
.SH AUTHOR
|
||||
Devin Reade <gdr@eddore.myrias.com>
|
||||
.SH "SEE ALSO"
|
||||
.BR cp (1)
|
||||
.BR chmod (2).
|
||||
|
@ -1,60 +1,63 @@
|
||||
/*
|
||||
* Copyright 1996 Devin Reade <gdr@myrias.com>.
|
||||
* Copyright 1996-1997 Devin Reade <gdr@myrias.com>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* For copying and distribution information, see the file "COPYING"
|
||||
* accompanying this file.
|
||||
*
|
||||
* $Id: inst.c,v 1.2 1996/09/03 03:54:58 gdr Exp $
|
||||
* $Id: inst.c,v 1.3 1997/10/30 04:14:21 gdr Exp $
|
||||
*/
|
||||
|
||||
#define __USE_DYNAMIC_GSSTRING__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <gno/gno.h>
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <orca.h>
|
||||
#include <gsos.h>
|
||||
|
||||
extern int _mapErr(int);
|
||||
#include <err.h>
|
||||
|
||||
#include "contrib.h"
|
||||
|
||||
/* actions */
|
||||
#define NOCHANGE 0
|
||||
#define ASSIGN 1
|
||||
#define REMOVE 2
|
||||
#define ADD 3
|
||||
#define ACTION_CHANGE_MODE 0x0001
|
||||
#define ACTION_CHANGE_OWNER 0x0002
|
||||
#define ACTION_CHANGE_GROUP 0x0004
|
||||
|
||||
/* permissions */
|
||||
#define S_USER 0700
|
||||
#define S_GROUP 0070
|
||||
#define S_OTHER 0007
|
||||
#define S_ALL 0777
|
||||
#define S_ALL 0777
|
||||
#define S_READ 0444
|
||||
#define S_WRITE 0222
|
||||
#define S_EXECUTE 0111
|
||||
|
||||
#define TYPE_TXT 0x04
|
||||
#define TYPE_SRC 0xB0
|
||||
#define TYPE_EXEC 0x00000006
|
||||
#define TYPE_NONE 0x00000000
|
||||
|
||||
#define VERSION "1.0"
|
||||
#define VERSION "1.1"
|
||||
#define EMAIL "<gdr@myrias.com>"
|
||||
|
||||
char *versionMsg = "Version %s by Devin Reade %s\n";
|
||||
int dFlag;
|
||||
|
||||
extern int mkdir(const char *);
|
||||
extern int needsgno(void);
|
||||
extern void begin_stack_check(void);
|
||||
extern int end_stack_check(void);
|
||||
#ifdef __STACK_CHECK__
|
||||
/*
|
||||
* printStack
|
||||
*
|
||||
* prints stack usage (debugging only)
|
||||
*/
|
||||
static void
|
||||
printStack (void) {
|
||||
fprintf(stderr, "stack usage: %d bytes\n", _endStackCheck());
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* usage
|
||||
@ -81,84 +84,85 @@ usage(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* getmode
|
||||
* translateMode
|
||||
*
|
||||
* set mode to the value corresponding to the permission bit string
|
||||
* <str>. If the first char of <str> is a digit, then it is assumed
|
||||
* to be an octal number. Otherwise it is assumed to be a string of
|
||||
* the form "ug+rx" (in the usual chmod(1) format). Also sets action
|
||||
* to be the type of action to take, whether we're removing, adding,
|
||||
* or assigning the permission bits.
|
||||
* the form "ug+rx" (in the usual chmod(1) format).
|
||||
*
|
||||
* If these assumptions don't hold, then return non-zero. Returns
|
||||
* zero and sets mode on success.
|
||||
*
|
||||
* Since the IIgs currently doesn't have the concept of "group" and
|
||||
* "other" permissions, we take everything from the user permissions.
|
||||
* zero and sets mode on success. mode may be modified, even on
|
||||
* failure.
|
||||
*/
|
||||
|
||||
int
|
||||
getmode(char *str, unsigned long *mode, int *action)
|
||||
static int
|
||||
translateMode(char *str, mode_t *mode)
|
||||
{
|
||||
unsigned long who = 0L;
|
||||
unsigned long perm = 0L;
|
||||
char *p, *q;
|
||||
mode_t who = 0L;
|
||||
mode_t perm = 0L;
|
||||
char *p, *q;
|
||||
|
||||
/* octal number? */
|
||||
if (isdigit(*str)) {
|
||||
*action = ASSIGN;
|
||||
errno = 0;
|
||||
*mode = strtoul(str, NULL, 8);
|
||||
return errno;
|
||||
}
|
||||
/* it's not an absolute octal; treat as a string */
|
||||
if (((p = strchr(str, '+')) == NULL) &&
|
||||
((p = strchr(str, '-')) == NULL) &&
|
||||
((p = strchr(str, '=')) == NULL)) {
|
||||
errno = EINVAL;
|
||||
return errno;
|
||||
}
|
||||
switch (*p) {
|
||||
case '+': *action = ADD; break;
|
||||
case '-': *action = REMOVE; break;
|
||||
case '=': *action = ASSIGN; break;
|
||||
default: assert(0);
|
||||
}
|
||||
/* octal number? */
|
||||
if (isdigit(*str)) {
|
||||
errno = 0;
|
||||
*mode = strtoul(str, NULL, 8);
|
||||
return errno;
|
||||
}
|
||||
|
||||
/*
|
||||
* this condition should really be deduced from the umask, if it
|
||||
* were supported.
|
||||
*/
|
||||
if (str == p) {
|
||||
who |= S_USER;
|
||||
}
|
||||
/* it's not an absolute octal; treat as a string */
|
||||
if (((p = strchr(str, '=')) == NULL) &&
|
||||
((p = strchr(str, '+')) == NULL) &&
|
||||
((p = strchr(str, '-')) == NULL)) {
|
||||
errno = EINVAL;
|
||||
return errno;
|
||||
}
|
||||
|
||||
for (q = str; q < p; q++) {
|
||||
switch (*q) {
|
||||
case 'u': who |= S_USER; break;
|
||||
case 'g': who |= S_GROUP; break;
|
||||
case 'o': who |= S_OTHER; break;
|
||||
case 'a': who |= S_ALL; break;
|
||||
default: errno = EINVAL; return errno;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Since we use mode 0000 as our starting point, using '-' in the
|
||||
* symbolic mode is equivalent to setting the mode to 0000 (absolute).
|
||||
* Similarly, using '+' and '=' are equivalent.
|
||||
*
|
||||
* If '-' was specified, ignore the "ugo" and "rwx" parts of the string.
|
||||
*/
|
||||
if (*p == '-') {
|
||||
*mode = 0000;
|
||||
return 0;
|
||||
}
|
||||
*p++ = '\0';
|
||||
|
||||
for (q = p + 1; *q; q++) {
|
||||
switch (*q) {
|
||||
case 'r': perm |= S_READ; break;
|
||||
case 'w': perm |= S_WRITE; break;
|
||||
case 'x': perm |= S_EXECUTE; break;
|
||||
case 's': /* ignored */ break;
|
||||
default: errno = EINVAL; return errno;
|
||||
}
|
||||
}
|
||||
if (*str == '\0') {
|
||||
/* this should probably be derived from the umask */
|
||||
who |= S_ALL;
|
||||
} else {
|
||||
for (q = str; *q; q++) {
|
||||
switch (*q) {
|
||||
case 'u': who |= S_USER; break;
|
||||
case 'g': who |= S_GROUP; break;
|
||||
case 'o': who |= S_OTHER; break;
|
||||
case 'a': who |= S_ALL; break;
|
||||
default: errno = EINVAL; return errno;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* currently: ignore all but user permissions */
|
||||
if (!(who & S_USER)) {
|
||||
*action = NOCHANGE;
|
||||
}
|
||||
*mode = who & perm;
|
||||
return 0;
|
||||
if (*p == '\0') {
|
||||
/* this should probaby be taken from the umask */
|
||||
perm |= S_READ | S_WRITE | S_EXECUTE;
|
||||
} else {
|
||||
for (; *p; p++) {
|
||||
switch (*p) {
|
||||
case 'r': perm |= S_READ; break;
|
||||
case 'w': perm |= S_WRITE; break;
|
||||
case 'x': perm |= S_EXECUTE; break;
|
||||
case 's': perm |= S_EXECUTE; break;
|
||||
default: errno = EINVAL; return errno;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*mode = who & perm;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -179,17 +183,17 @@ mkdirs(int argc, char **argv)
|
||||
char *path, *p;
|
||||
size_t pathlen;
|
||||
int result = 0;
|
||||
int makeit; /* do we try a mkdir()? */
|
||||
int abortpath; /* we saw an error; don't both with rest of path */
|
||||
int makeit; /* do we try a mkdir()? */
|
||||
int abortpath; /* we saw an error; don't both with rest of path */
|
||||
int i, j;
|
||||
int coloncount;
|
||||
int coloncount, isVolume;
|
||||
|
||||
/* loop over each of the pathnames in the array */
|
||||
for (i = 0; i < argc; i++) {
|
||||
|
||||
/* expand to a full pathname */
|
||||
if ((path = expandpath(argv[i])) == NULL) {
|
||||
perror(argv[i]);
|
||||
if ((path = LC_ExpandPath(argv[i])) == NULL) {
|
||||
warn("couldn't expand the pathname of %s (ignored)", argv[i]);
|
||||
continue;
|
||||
}
|
||||
pathlen = strlen(path);
|
||||
@ -206,20 +210,25 @@ mkdirs(int argc, char **argv)
|
||||
}
|
||||
p++;
|
||||
}
|
||||
p = path + 1;
|
||||
|
||||
/* skip the volume name */
|
||||
if ((p = strchr(p, ':')) == NULL) {
|
||||
/* only the volume name was given; skip it */
|
||||
free(path);
|
||||
continue;
|
||||
}
|
||||
p++;
|
||||
--coloncount;
|
||||
/* skip the first part if it's a volume or device name */
|
||||
abortpath = 0;
|
||||
if ((*path == ':') || (*path == '.')) {
|
||||
j = 1;
|
||||
p = path + 1;
|
||||
if ((p = strchr(p, ':')) == NULL) {
|
||||
p = path + pathlen;
|
||||
abortpath = 1;
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
} else {
|
||||
j = 0;
|
||||
p = path;
|
||||
}
|
||||
|
||||
/* create each component in path */
|
||||
abortpath = 0;
|
||||
for (j = 0; !abortpath && j < coloncount; j++) {
|
||||
for (; !abortpath && j < coloncount; j++) {
|
||||
if ((p = strchr(p, ':')) == NULL) {
|
||||
p = path + pathlen;
|
||||
}
|
||||
@ -229,7 +238,7 @@ mkdirs(int argc, char **argv)
|
||||
if (errno == ENOENT) {
|
||||
makeit = 1;
|
||||
} else {
|
||||
perror(path);
|
||||
warn("couldn't stat %s", path);
|
||||
makeit = 0;
|
||||
abortpath = 1;
|
||||
result = 1;
|
||||
@ -237,7 +246,7 @@ mkdirs(int argc, char **argv)
|
||||
} else {
|
||||
makeit = 0;
|
||||
if (statbuf.st_mode & S_IFDIR == 0) {
|
||||
fprintf(stderr, "%s exists and is not a directory\n", path);
|
||||
warnx("%s exists and is not a directory\n", path);
|
||||
abortpath = 1;
|
||||
result = 1;
|
||||
} /* else it exists and is a directory */
|
||||
@ -245,7 +254,7 @@ mkdirs(int argc, char **argv)
|
||||
|
||||
/* go ahead and create the directory */
|
||||
if (makeit && mkdir(path)) {
|
||||
perror(path);
|
||||
warn("couldn't create directory %s", path);
|
||||
abortpath = 1;
|
||||
result = 1;
|
||||
}
|
||||
@ -254,7 +263,6 @@ mkdirs(int argc, char **argv)
|
||||
*p++ = ':';
|
||||
}
|
||||
}
|
||||
free(path);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -269,125 +277,80 @@ mkdirs(int argc, char **argv)
|
||||
* _must_ be a directory.
|
||||
*
|
||||
* Returns zero on success. On failure, returns the last non-zero errno
|
||||
* and prints error conditions to stderr.
|
||||
* and prints error conditions to stderr via the warn(3) routines.
|
||||
*
|
||||
* If action is not NOCHANGE, this routine will also set file permissions
|
||||
* as specified in the install(1) man page. This may involve changing
|
||||
* the file type.
|
||||
* If the ACTION_CHANGE_MODE bit is set in <action>, chmod(2) is invoked
|
||||
* on the resulting file. ACTION_CHANGE_USER and ACTION_CHANGE_GROUP
|
||||
* are currently ignored.
|
||||
*/
|
||||
|
||||
static int
|
||||
copyfiles(int argc, char **argv, int action, unsigned long mode)
|
||||
copyfiles(int argc, char **argv, int action, mode_t mode)
|
||||
{
|
||||
static FileInfoRecGS inforec;
|
||||
static GSString255 filenameGS;
|
||||
int i, j;
|
||||
int result = 0;
|
||||
char *destination;
|
||||
Word newaccess;
|
||||
static FileInfoRecGS inforec;
|
||||
GSStringPtr src, dest, newname;
|
||||
int total, i, result;
|
||||
unsigned short flags;
|
||||
|
||||
if (argc < 2) {
|
||||
errno = EINVAL;
|
||||
perror("internal error: not enough arguments to copyfiles()");
|
||||
return errno;
|
||||
}
|
||||
if (argc > 2) {
|
||||
static const char *nodup = "couldn't duplicate %s file name \"%s\"";
|
||||
|
||||
/* find out if argv[argc-1] is a directory */
|
||||
assert(argc > 1);
|
||||
|
||||
if (__C2GS(argv[argc - 1], &filenameGS) == NULL) {
|
||||
errno = EINVAL;
|
||||
perror("destination path too long");
|
||||
return errno;
|
||||
}
|
||||
inforec.pCount = 5;
|
||||
inforec.pathname = &filenameGS;
|
||||
GetFileInfoGS(&inforec);
|
||||
if ((errnoGS = toolerror()) != 0) {
|
||||
perrorGS("%s", argv[argc - 1]);
|
||||
errno = _mapErr(errnoGS);
|
||||
return -1;
|
||||
}
|
||||
if ((inforec.storageType != 0x0D) && (inforec.storageType != 0x0F)) {
|
||||
errno = ENOTDIR;
|
||||
perror(argv[argc - 1]);
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
--argc;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if ((destination = copyfile(argv[i], argv[argc])) == NULL) {
|
||||
errnoGS = toolerror();
|
||||
perrorGS("install of %s to %s", argv[i], argv[argc]);
|
||||
result = errno = _mapErr(errnoGS);
|
||||
}
|
||||
if (action == NOCHANGE) {
|
||||
continue;
|
||||
}
|
||||
/* initialization */
|
||||
result = 0;
|
||||
total = argc - 1;
|
||||
flags = LC_COPY_DATA | LC_COPY_REZ | LC_COPY_KEEPBUF;
|
||||
|
||||
/* get the file info for the source file */
|
||||
if (__C2GS(argv[i], &filenameGS) == NULL) {
|
||||
assert(0);
|
||||
}
|
||||
inforec.pCount = 7;
|
||||
inforec.pathname = &filenameGS;
|
||||
GetFileInfoGS(&inforec);
|
||||
if ((errnoGS = toolerror()) != 0) {
|
||||
perrorGS("GetFileInfo for %s failed", argv[i]);
|
||||
result = errno = _mapErr(errnoGS);
|
||||
}
|
||||
/* modify the permissions as necessary */
|
||||
switch (action) {
|
||||
case ASSIGN:
|
||||
newaccess = 0xFFFF;
|
||||
if (!(mode & S_READ)) newaccess &= ~readEnable;
|
||||
if (!(mode & S_WRITE)) newaccess &= ~writeEnable;
|
||||
inforec.access &= newaccess;
|
||||
/* duplicate the destination name */
|
||||
if ((dest = __C2GSMALLOC(argv[argc - 1])) == NULL) {
|
||||
err(1, nodup, "destination", argv[argc - 1]);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
if ((mode & S_EXECUTE) &&
|
||||
(inforec.fileType == TYPE_TXT) || (inforec.fileType == TYPE_SRC)) {
|
||||
inforec.fileType = TYPE_SRC;
|
||||
inforec.auxType = TYPE_EXEC;
|
||||
}
|
||||
break;
|
||||
/*
|
||||
* If we're copying more than one file, make sure the last
|
||||
* is a directory.
|
||||
*/
|
||||
if (argc > 2) {
|
||||
inforec.pCount = 5;
|
||||
inforec.pathname = dest;
|
||||
GetFileInfoGS(&inforec);
|
||||
if (_toolErr != 0) {
|
||||
errno = _mapErr(_toolErr);
|
||||
err(1, "couldn't stat %s", dest->text);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if ((inforec.storageType != 0x0D) &&
|
||||
(inforec.storageType != 0x0F)) {
|
||||
errno = ENOTDIR;
|
||||
errx(1, "%s is not a directory", dest->text);
|
||||
}
|
||||
}
|
||||
|
||||
case ADD:
|
||||
if (mode & S_READ) inforec.access |= readEnable;
|
||||
if (mode & S_WRITE) inforec.access |= writeEnable;
|
||||
|
||||
if ((mode & S_EXECUTE) &&
|
||||
(inforec.fileType == TYPE_TXT) || (inforec.fileType == TYPE_SRC)) {
|
||||
inforec.fileType = TYPE_SRC;
|
||||
inforec.auxType = TYPE_EXEC;
|
||||
}
|
||||
break;
|
||||
|
||||
case REMOVE:
|
||||
if (mode & S_READ) inforec.access &= ~readEnable;
|
||||
if (mode & S_WRITE) inforec.access &= ~writeEnable;
|
||||
|
||||
if ((mode & S_EXECUTE) &&
|
||||
(inforec.fileType == TYPE_TXT) || (inforec.fileType == TYPE_SRC)) {
|
||||
inforec.fileType = TYPE_TXT;
|
||||
inforec.auxType = TYPE_NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* set the modified file info for the destination file */
|
||||
if (__C2GS(destination, &filenameGS) == NULL) {
|
||||
assert(0);
|
||||
}
|
||||
SetFileInfoGS(&inforec);
|
||||
if ((errnoGS = toolerror()) != 0) {
|
||||
perrorGS("SetFileInfo for %s failed", destination);
|
||||
result = errno = _mapErr(errnoGS);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
/* copy each file */
|
||||
for (i=0; i<total; i++) {
|
||||
if ((src = __C2GSMALLOC(argv[i])) == NULL) {
|
||||
err(1, nodup, "source", argv[i]);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
newname = LC_CopyFileGS(src, dest, flags);
|
||||
if (newname == NULL) {
|
||||
result = errno;
|
||||
warn("install of %s to %s failed", argv[i],
|
||||
argv[argc-1]);
|
||||
} else {
|
||||
if (action & ACTION_CHANGE_MODE) {
|
||||
if (chmod(newname->text, mode) < 0) {
|
||||
result = errno;
|
||||
warn("couldn't change %s to mode %o",
|
||||
newname->text, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
GIfree(src);
|
||||
}
|
||||
GIfree(dest);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -397,32 +360,34 @@ copyfiles(int argc, char **argv, int action, unsigned long mode)
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
unsigned long mode;
|
||||
mode_t newmode;
|
||||
int c, nfiles;
|
||||
int action = NOCHANGE;
|
||||
int action = 0;
|
||||
|
||||
#ifdef CHECK_STACK
|
||||
begin_stack_check();
|
||||
#ifdef __STACK_CHECK__
|
||||
_beginStackCheck();
|
||||
atexit(printStack);
|
||||
#endif
|
||||
|
||||
if (needsgno() == 0) {
|
||||
fprintf(stderr, "Requires GNO/ME\n");
|
||||
exit(1);
|
||||
errx(1, "requires GNO");
|
||||
}
|
||||
|
||||
/* initialize */
|
||||
dFlag = 0;
|
||||
mode = 0L;
|
||||
newmode = 0L;
|
||||
|
||||
/* parse command line */
|
||||
while ((c = getopt(argc, argv, "cdg:hm:o:sv")) != EOF) {
|
||||
switch (c) {
|
||||
case 'v':
|
||||
fprintf(stderr, versionMsg, VERSION, EMAIL);
|
||||
exit(1);
|
||||
errx(1, versionMsg, VERSION, EMAIL);
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (getmode(optarg, &mode, &action)) {
|
||||
action |= ACTION_CHANGE_MODE;
|
||||
if (translateMode(optarg, &newmode)) {
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
@ -450,12 +415,10 @@ main(int argc, char **argv)
|
||||
if (nfiles < 2) {
|
||||
usage();
|
||||
}
|
||||
c = copyfiles(nfiles, &argv[optind], action, mode);
|
||||
/* ignore new user and group for now */
|
||||
c = copyfiles(nfiles, &argv[optind], action, newmode);
|
||||
}
|
||||
|
||||
#ifdef CHECK_STACK
|
||||
fprintf(stderr, "stack usage: %d bytes\n", end_stack_check());
|
||||
#endif
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
Name: install
|
||||
Version: 1.0 (31 Mar 96)
|
||||
Shell: GNO/ME
|
||||
Version: 1.1 (16 Oct 97)
|
||||
Shell: GNO
|
||||
Author: Devin Reade
|
||||
Contact: gdr@myrias.com
|
||||
Contact: gdr@eddore.myrias.com
|
||||
Where: /usr/bin
|
||||
FTP: apple2.caltech.edu, ground.isca.uiowa.edu
|
||||
FTP: apple2.caltech.edu, ground.isca.uiowa.edu, trenco.myrias.com
|
||||
|
||||
Install is similar to cp(1) in that it copies files. It will
|
||||
also create directory hierarchies, and modify some access bits.
|
||||
It is intended for use with Makefiles or other scripts to install
|
||||
files into their destination directories.
|
||||
Install is similar to cp(1) in that it copies files. It will also create
|
||||
directory hierarchies, modify certain access bits, and convert TXT or SRC
|
||||
files into shell shell scripts (by changing the file and aux types). It
|
||||
is intended for use with Makefiles or other scripts to install files into
|
||||
their destination directories.
|
||||
|
@ -1,25 +1,25 @@
|
||||
/*
|
||||
* Copyright 1996 Devin Reade <gdr@myrias.com>.
|
||||
* Copyright 1996-1997 Devin Reade <gdr@myrias.com>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* For copying and distribution information, see the file "COPYING"
|
||||
* accompanying this file.
|
||||
*
|
||||
* $Id: inst.rez,v 1.1 1996/03/31 23:38:34 gdr Exp $
|
||||
* $Id: inst.rez,v 1.2 1997/10/30 04:14:21 gdr Exp $
|
||||
*/
|
||||
|
||||
#include "Types.Rez"
|
||||
|
||||
resource rVersion (0x1, purgeable3, nocrossbank) {
|
||||
|
||||
{ 1, 0, 0, /* version 1.0.0 */
|
||||
{ 1, 1, 0, /* version 1.1.0 */
|
||||
release, /* development|alpha|beta|final|release */
|
||||
0 /* non-final release number */
|
||||
},
|
||||
verBritain, /* close enough */
|
||||
verUS,
|
||||
"install",
|
||||
"Unix-style install program --\n"
|
||||
" copies files and creates directories\n"
|
||||
"Devin Reade <gdr@myrias.com>\n"
|
||||
"Devin Reade <gdr@eddore.myrias.com>\n"
|
||||
"Canada"
|
||||
};
|
||||
|
@ -1,31 +0,0 @@
|
||||
#
|
||||
# This makefile is for use with dmake(1).
|
||||
#
|
||||
# $Id: makefile.mk,v 1.2 1996/09/03 03:54:59 gdr Exp $
|
||||
#
|
||||
|
||||
DEFINES = -D__GNO__ # -DCHECK_STACK
|
||||
INCLUDES = -I ../contrib/src
|
||||
STACK = -s1280
|
||||
CFLAGS = $(DEFINES) $(INCLUDES) $(STACK) -w -O -v
|
||||
LDFLAGS = -v
|
||||
LDLIBS = -l ../contrib/src/lcontrib \
|
||||
-l ../contrib/src/libc2 \
|
||||
# -l/usr/lib/stack
|
||||
BINDIR = /usr/bin
|
||||
MANDIR = /usr/man
|
||||
|
||||
OBJS = install.o
|
||||
|
||||
install: $(OBJS) install.r
|
||||
$(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@
|
||||
copyfork install.r install -r
|
||||
@echo 'type \"dmake doinstall\" to install this program'
|
||||
|
||||
doinstall:
|
||||
./install -d $(BINDIR) $(MANDIR)/man1
|
||||
./install -m755 -obin -gsys ./install $(BINDIR)
|
||||
./install -m644 -obin -gsys ./install.1 $(MANDIR)/man1
|
||||
|
||||
clean clobber:
|
||||
$(RM) $(OBJS) install.root install.r
|
Loading…
x
Reference in New Issue
Block a user