From f8c4d4b6d5f82c1484237c3a63dfdd490ac606d4 Mon Sep 17 00:00:00 2001 From: gdr Date: Sun, 31 Mar 1996 23:38:34 +0000 Subject: [PATCH] Initial checkin of install(1) for GNO, version 1.0. --- usr.bin/install/COPYING | 33 +++ usr.bin/install/basename.c | 70 ++++++ usr.bin/install/c2gs.c | 37 +++ usr.bin/install/copyfile.c | 284 ++++++++++++++++++++++ usr.bin/install/errnoGS.c | 125 ++++++++++ usr.bin/install/expandpath.c | 53 +++++ usr.bin/install/inst.1 | 107 +++++++++ usr.bin/install/inst.c | 444 +++++++++++++++++++++++++++++++++++ usr.bin/install/inst.desc | 12 + usr.bin/install/inst.rez | 25 ++ usr.bin/install/install.h | 43 ++++ usr.bin/install/makefile.mk | 40 ++++ usr.bin/install/stringGS.c | 78 ++++++ 13 files changed, 1351 insertions(+) create mode 100644 usr.bin/install/COPYING create mode 100644 usr.bin/install/basename.c create mode 100644 usr.bin/install/c2gs.c create mode 100644 usr.bin/install/copyfile.c create mode 100644 usr.bin/install/errnoGS.c create mode 100644 usr.bin/install/expandpath.c create mode 100644 usr.bin/install/inst.1 create mode 100644 usr.bin/install/inst.c create mode 100644 usr.bin/install/inst.desc create mode 100644 usr.bin/install/inst.rez create mode 100644 usr.bin/install/install.h create mode 100644 usr.bin/install/makefile.mk create mode 100644 usr.bin/install/stringGS.c diff --git a/usr.bin/install/COPYING b/usr.bin/install/COPYING new file mode 100644 index 0000000..e761154 --- /dev/null +++ b/usr.bin/install/COPYING @@ -0,0 +1,33 @@ +Copyright 1996 Devin Reade . +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions, and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions, and the following disclaimer + in the documentation and/or other materials provided with the + distribution. If the binary form is created using Orca/C, then + the following Byteworks' copyright notice must also be included + in the same location. +3. The name of the developer may not be used to endorse or promote + products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE DEVELOPER "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +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 +permission. diff --git a/usr.bin/install/basename.c b/usr.bin/install/basename.c new file mode 100644 index 0000000..bc15b0f --- /dev/null +++ b/usr.bin/install/basename.c @@ -0,0 +1,70 @@ +/* + * Copyright 1996 Devin Reade . + * All rights reserved. + * + * For copying and distribution information, see the file "COPYING" + * accompanying this file. + * + * $Id: basename.c,v 1.1 1996/03/31 23:38:30 gdr Exp $ + */ + +#include +#include +#include "install.h" + +/* + * basename + * + * returns the filename component of . If contains colons, + * they are assumed to be the directory separators, otherwise any '/' is + * assumed to be a directory separator. + * + * If no directory separators are found, then the full path is returned. + * + * No check is done as to whether the pathname is valid on the any + * given filesystem. + */ + +char * +basename (char *path) +{ + char delim, *p; + + delim = strchr(path,':') ? ':' : '/'; + p = strrchr(path,delim); + return p ? p+1 : path; +} + +/* + * dirname + * + * Returns a pointer to an internal buffer that contains a string that + * matches the directory component + * of . If contains at least one ':', then it is assumed + * that colons are directory separators, otherwise any '/' character + * is treated as a directory separator. + * + * If contains no pathname separators, then dirname() will + * return an empty (zero-length) string. + * + * No check is done as to whether the pathname is valid on the any + * given filesystem. + */ + +char * +dirname (char *path) +{ + char delim, *p; + static char dir[FILENAME_MAX]; + + strncpy(dir,path,FILENAME_MAX-1); + dir[FILENAME_MAX-1] = '\0'; + delim = strchr(dir,':') ? ':' : '/'; + p = strchr(dir,delim); + if (p == NULL) { + *dir = '\0'; + } else { + *p = '\0'; + } + return dir; +} diff --git a/usr.bin/install/c2gs.c b/usr.bin/install/c2gs.c new file mode 100644 index 0000000..ae715ef --- /dev/null +++ b/usr.bin/install/c2gs.c @@ -0,0 +1,37 @@ +/* + * Copyright 1996 Devin Reade . + * All rights reserved. + * + * For copying and distribution information, see the file "COPYING" + * accompanying this file. + * + * $Id: c2gs.c,v 1.1 1996/03/31 23:38:31 gdr Exp $ + */ + +#include +#include +#include +#include "install.h" + +/* + * __C2GS + * + * Converts a null-terminated C string into a class 1 GS/OS string. + * Space for the GS/OS string must already be allocated, and the + * length of s must not be more than 255 chars. + * + * If the s is too long, __C2GS will return NULL, otherwise it will + * return the GS/OS string g. + */ + +GSString255Ptr +__C2GS(char *s, GSString255Ptr g) +{ + size_t len; + + len = strlen(s); + if (len > 255) return NULL; /* the string won't fit */ + g->length = len; + strncpy(g->text,s,255); + return g; +} diff --git a/usr.bin/install/copyfile.c b/usr.bin/install/copyfile.c new file mode 100644 index 0000000..596e537 --- /dev/null +++ b/usr.bin/install/copyfile.c @@ -0,0 +1,284 @@ +/* + * Copyright 1996 Devin Reade . + * All rights reserved. + * + * For copying and distribution information, see the file "COPYING" + * accompanying this file. + * + * $Id: copyfile.c,v 1.1 1996/03/31 23:38:31 gdr Exp $ + */ + +#include +#include +#include +#include +#include +#include "install.h" + +/* the chunk size in which we copy files */ +#define COPY_BUFFER_SIZE 1024 + +/* + * copyfile + * + * copy a file from the pathname to the location , which + * may be a directory. Ensure that file types and other information + * (except for the backup bit) is matched. + * + * Returns NULL and sets errno on failure. On success, returns a + * pointer to an internal buffer containing the final pathname. + * + * +++ THIS ROUTINE IS NOT REENTRANT +++ + */ + +char * +copyfile (char *from, char *to) +{ + static char buffer[COPY_BUFFER_SIZE]; + static FileInfoRecGS inforec; + static OpenRecGS openrec; + static ExpandPathRecGS expandrec; + static ResultBuf255 resultbuf; + static struct { + Word pCount; + Word refNum; + Longword dataBuffer; + Longword requestCount; + Longword transferCount; + Word cachePriority; + } iobuf; + static struct { + Word pCount; + Word refNum; + } closerec; + static GSString255 fromGS, toGS; + static char *result = NULL; /* we only use this if our path is */ + /* exactly 255 chars long */ + size_t len1, len2; + Word refNumIn, refNumOut; /* GS/OS ref numbers for I/O */ + int isDir, i, j, k, done; + char *p, *q, *r; + + /* concheck and convert filenames to GSString255 type */ + if (!from || !to || + ((len1 = strlen(from)) > 254) || + ((len2 = strlen(to)) > 254) ) + { + errno = EINVAL; + return NULL; + } + fromGS.length = len1; + toGS.length = len2; + strcpy(fromGS.text,from); + strcpy(toGS.text,to); + + /* expand the original file name */ + expandrec.pCount = 3; + expandrec.inputPath = &fromGS; + expandrec.outputPath = &resultbuf; + expandrec.flags = 0x0000; + resultbuf.bufSize = 255; + ExpandPathGS(&expandrec); + if ((i = toolerror()) != 0) { + errno = _mapErr(i); + return NULL; + } + strcpyGSString255(&fromGS,&(resultbuf.bufString)); + + /* expand the destination name */ + expandrec.pCount = 3; + expandrec.inputPath = &toGS; + expandrec.outputPath = &resultbuf; + expandrec.flags = 0x0000; + resultbuf.bufSize = 255; + ExpandPathGS(&expandrec); + if ((i = toolerror()) != 0) { + errno = _mapErr(i); + return NULL; + } + strcpyGSString255(&toGS,&(resultbuf.bufString)); + + /* find out if is a directory */ + inforec.pCount = 5; + inforec.pathname = &toGS; + GetFileInfoGS(&inforec); + i = toolerror(); + switch(i) { + case 0: + isDir = ((inforec.storageType == 0x0D) || + (inforec.storageType == 0x0F)) ? 1 : 0; + break; + case fileNotFound: + isDir = 0; + break; + default: + errno = _mapErr(i); + return NULL; + } + + /* it's a directory? tack on the file name */ + if (isDir) { + + /* expand the directory name */ + expandrec.pCount = 3; + expandrec.inputPath = &toGS; + expandrec.outputPath = &resultbuf; + expandrec.flags = 0x0000; + resultbuf.bufSize = 255; + ExpandPathGS(&expandrec); + if ((i = toolerror()) != 0) { + errno = _mapErr(i); + return NULL; + } + + /* tack on the final component */ + p = basename(from); + len1 = strlen(p); + if (len1 + toGS.length + 1 > 255) { + errno = EINVAL; + return NULL; + } + q = &(toGS.text[toGS.length]); + r = p; + *q++ = ':'; + for (i=0; i. + * All rights reserved. + * + * For copying and distribution information, see the file "COPYING" + * accompanying this file. + * + * $Id: errnoGS.c,v 1.1 1996/03/31 23:38:31 gdr Exp $ + */ + +#include +#include +#include +#include "install.h" + +#pragma lint -1 +#pragma debug 0 +#pragma optimize -1 + +#define NONE "no error" +#define UNKNOWN "unknown error" + +segment "errnoGS___"; + +typedef struct errEntry { + unsigned short num; + char *str; +} errEntry; + +static errEntry +sys_errlistGS[] = { + { badSystemCall, "bad system call number" }, + { invalidPcount, "invalid parameter count" }, + { gsosActive, "GS/OS already active" }, + { devNotFound, "device not found" }, + { invalidDevNum, "invalid device number" }, + { drvrBadReq, "bad request or command" }, + { drvrBadCode, "bad control or status code" }, + { drvrBadParm, "bad call parameter" }, + { drvrNotOpen, "character device not open" }, + { drvrPriorOpen, "character device already open" }, + { irqTableFull, "interrupt table full" }, + { drvrNoResrc, "resources not available" }, + { drvrIOError, "I/O error" }, + { drvrNoDevice, "device not connected" }, + { drvrBusy, "call aborted; driver is busy" }, + { drvrWrtProt, "device is write protected" }, + { drvrBadCount, "invalid byte count" }, + { drvrBadBlock, "invalid block address" }, + { drvrDiskSwitch, "disk has been switched" }, + { drvrOffLine, "device off line/ no media present" }, + { badPathSyntax, "invalid pathname syntax" }, + { tooManyFilesOpen, "too many files open on server volume" }, + { invalidRefNum, "invalid reference number" }, + { pathNotFound, "subdirectory does not exist" }, + { volNotFound, "volume not found" }, + { fileNotFound, "file not found" }, + { dupPathname, "create or rename with existing name" }, + { volumeFull, "volume full error" }, + { volDirFull, "volume directory full" }, + { badFileFormat, "version error (incompatible file format)" }, + { badStoreType, "unsupported (or incorrect) storage type" }, + { eofEncountered, "end-of-file encountered" }, + { outOfRange, "position out of range" }, + { invalidAccess, "access not allowed" }, + { buffTooSmall, "buffer too small" }, + { fileBusy, "file is already open" }, + { dirError, "directory error" }, + { unknownVol, "unknown volume type" }, + { paramRangeErr, "parameter out of range" }, + { outOfMem, "out of memory" }, + { dupVolume, "duplicate volume name" }, + { notBlockDev, "not a block device" }, + { invalidLevel, "specifield level outside legal range" }, + { damagedBitMap, "block number too large" }, + { badPathNames, "invalid pathnames for ChangePath" }, + { notSystemFile, "not an executable file" }, + { osUnsupported, "Operating System not supported" }, + { stackOverflow, "too many applications on stack" }, + { dataUnavail, "data unavailable" }, + { endOfDir, "end of directory has been reached" }, + { invalidClass, "invalid FST call class" }, + { resForkNotFound, "file does not contain required resource" }, + { invalidFSTID, "error - FST ID is invalid" }, + { invalidFSTop, "invalid FST operation" }, + { fstCaution, "FST handled call, but result is weird" }, + { devNameErr, "device exists with same name as replacement name" }, + { defListFull, "device list is full" }, + { supListFull, "supervisor list is full" }, + { fstError, "generic FST error" }, + { resExistsErr, "cannot expand file, resource already exists" }, + { resAddErr, "cannot add resource fork to this type file" }, + { networkError, "generic network error" }, + { 0, NONE } /* we shouldn't see this */ +}; + +unsigned short errnoGS = 0; + +char * +strerrorGS(unsigned short num) +{ + int i; + + if (num == 0) return NONE; + i = 0; + while (sys_errlistGS[i].num) { + if (sys_errlistGS[i].num == num) { + return sys_errlistGS[i].str; + } + i++; + } + return UNKNOWN; +} + +void +perrorGS(char *format, ...) +{ + va_list ap; + + va_start(ap,format); + vfprintf(stderr,format,ap); + fprintf(stderr,": %s\n",strerrorGS(errnoGS)); + va_end(ap); + return; +} diff --git a/usr.bin/install/expandpath.c b/usr.bin/install/expandpath.c new file mode 100644 index 0000000..4040955 --- /dev/null +++ b/usr.bin/install/expandpath.c @@ -0,0 +1,53 @@ +/* + * Copyright 1996 Devin Reade . + * All rights reserved. + * + * For copying and distribution information, see the file "COPYING" + * accompanying this file. + * + * $Id: expandpath.c,v 1.1 1996/03/31 23:38:32 gdr Exp $ + */ + +#include +#include +#include +#include +#include "install.h" + +/* + * expandpath + * + * Uses the GS/OS facilities to expand the pathname . On + * success, returns a pointer to the malloc'd expanded path. On + * failure it will return NULL and set errno. + * + * Note that in using this function, all directory separators will + * be converted to colons. + * + * Unfortunately, this routine uses a little over 0.5k of stack space ... + */ + +char * +expandpath (char *path) +{ + ExpandPathRecGS expand; + GSString255 inStr; + ResultBuf255 outBuf; + int i; + + if (__C2GS(path,&inStr) == NULL) { + errno = EINVAL; + return NULL; + } + expand.pCount = 3; + expand.inputPath = &inStr; + expand.outputPath = &outBuf; + expand.flags = 0x0000; + outBuf.bufSize = 255; + ExpandPathGS(&expand); + if ((i = toolerror()) != 0) { + errno = _mapErr(i); + return NULL; + } + return __GS2CMALLOC(&(outBuf.bufString)); +} diff --git a/usr.bin/install/inst.1 b/usr.bin/install/inst.1 new file mode 100644 index 0000000..d28f266 --- /dev/null +++ b/usr.bin/install/inst.1 @@ -0,0 +1,107 @@ +.\" Copyright 1996 Devin Reade +.\" +.\" $Id: inst.1,v 1.1 1996/03/31 23:38:32 gdr Exp $ +.\" +.TH INSTALL 1 "Commands and Applications" "31 Mar 96" "Version 1.0" +.SH NAME +install \- copy files and set their attributes +.SH SYNOPSIS +.BR install +[ +.I options +] [ +.BR -s +] +.I source +.I dest +.br +.BR install +[ +.I options +] [ +.BR -s +] +.I source +[ ... ] +.I directory +.br +.BR install +[ +.I options +] +[ +.BR -d +] +.I directory +[ ... ] +.SH DESCRIPTION +.BR install +copies files and sets their permission modes and, if possible, their +owner and group. It is used similarily to +.BR cp (1); +typically used in Makefiles to copy programs into their destination +directories. It can also be used to create the destination directories +and any leading directories, and to set the directories modes. +.LP +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 +with ported shell scripts and makefiles. Where options are not fully +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 +.BR install . +.IP \fB-d\fR +Create each given directory and its leading directories, if they +do not already exist. +.IP "\fB-g\fR \fIgroup\fR" +Set the group ownership of the installed file or directory to the group +ID of +.I group +(default is the processes current group). +.I group +may also be a numeric group ID. +.sp +\fBThis is currently ignored under GNO.\fR +.IP \fB-h\fR +Show usage information and exit. +.IP "\fB-m\fR \fImode\fR" +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, +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 +read, write, and (to a limited extent) execute permissions. +Furthermore, the only bits interpreted are those for the +user permissions; the +.I mode +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. +.IP "\fB-o\fR \fIowner\fR" +If run as root, set the ownership of the installed file to the user ID of +.IR owner . +.I owner +may also be numeric user ID. +.sp +\fBThis is currently ignored under GNO.\fR +.IP \fB-s\fR +Strip the symbol tables from the installed programs. +.sp +\fBThis is currently ignored under GNO.\fR +.IP \fB-v\fR +Show version number. +.SH AUTHOR +Devin Reade diff --git a/usr.bin/install/inst.c b/usr.bin/install/inst.c new file mode 100644 index 0000000..734ec97 --- /dev/null +++ b/usr.bin/install/inst.c @@ -0,0 +1,444 @@ +/* + * Copyright 1996 Devin Reade . + * All rights reserved. + * + * For copying and distribution information, see the file "COPYING" + * accompanying this file. + * + * $Id: inst.c,v 1.1 1996/03/31 23:38:33 gdr Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "install.h" + +/* actions */ +#define NOCHANGE 0 +#define ASSIGN 1 +#define REMOVE 2 +#define ADD 3 + +/* permissions */ +#define S_USER 0700 +#define S_GROUP 0070 +#define S_OTHER 0007 +#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 EMAIL "" + +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); + +/* + * usage + * + * display usage information and exit + */ + +void +usage (void) +{ + fputs("Usage: install [-cdhsv] [-o owner] [-g group] [-m mode] ",stderr); + fputs("source [...] dest\n\n",stderr); + fputs("Options:\n",stderr); + fputs("\t-c Ignored. (Backwards Unix compatibility)\n",stderr); + fputs("\t-d Create the specified directories\n",stderr); + fputs("\t-g group Specify group id (not implemented)\n",stderr); + fputs("\t-h Show usage information and exit.\n",stderr); + fputs("\t-m mode Specify (Unix) access mode\n",stderr); + fputs("\t-o owner Specify owner id (not implemented)\n",stderr); + fputs("\t-s Strip binary (not implemented)\n",stderr); + fputs("\t-v Show version number\n\n",stderr); + fprintf(stderr,versionMsg,VERSION,EMAIL); + exit(1); +} + +/* + * getmode + * + * set mode to the value corresponding to the permission bit string + * . If the first char of 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. + * + * 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. + */ + +int +getmode (char *str, unsigned long *mode, int *action) +{ + unsigned long who = 0L; + unsigned long 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); + } + + /* + * this condition should really be deduced from the umask, if it + * were supported. + */ + if (str == p) who |= S_USER; + + for (q = str; q is assumed to be an array of filenames. + * + * This routine copies all but the last specified file to the directory + * or filename specified by the last filename. If argc>2, the last element + * _must_ be a directory. + * + * Returns zero on success. On failure, returns the last non-zero errno + * and prints error conditions to stderr. + * + * 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. + */ + +static int +copyfiles (int argc, char **argv, int action, unsigned long mode) +{ + static FileInfoRecGS inforec; + static GSString255 filenameGS; + int i,j; + int result=0; + char *destination; + Word newaccess; + + if (argc < 2) { + errno = EINVAL; + perror("internal error: not enough arguments to copyfiles()"); + return errno; + } + if (argc > 2) { + + /* find out if argv[argc-1] is a directory */ + + 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. + * 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 $ + */ + +#include "Types.Rez" + +resource rVersion (0x1, purgeable3, nocrossbank) { + + { 1, 0, 0, /* version 1.0.0 */ + release, /* development|alpha|beta|final|release */ + 0 /* non-final release number */ + }, + verBritain, /* close enough */ + "install", + "Unix-style install program --\n" + " copies files and creates directories\n" + "Devin Reade \n" + "Canada" +}; diff --git a/usr.bin/install/install.h b/usr.bin/install/install.h new file mode 100644 index 0000000..9b1e9b2 --- /dev/null +++ b/usr.bin/install/install.h @@ -0,0 +1,43 @@ +/* + * Copyright 1996 Devin Reade . + * All rights reserved. + * + * For copying and distribution information, see the file "COPYING" + * accompanying this file. + * + * $Id: install.h,v 1.1 1996/03/31 23:38:33 gdr Exp $ + */ + +#ifndef __GSOS__ +#include +#endif + +/* these are from libc */ +extern GSString255Ptr __C2GSMALLOC (char *s); +extern char * __GS2CMALLOC (GSString255Ptr g); +extern char * __GS2C (char *s, GSString255Ptr g); +extern int _mapErr (int err); + +/* from basename.c */ +extern char *dirname (char *path); +extern char *basename (char *path); + +/* from c2gs.c */ +extern GSString255Ptr __C2GS(char *s, GSString255Ptr g); + +/* from copyfile.c */ +extern char *copyfile (char *from, char *to); + +/* from errnoGS.c */ +extern unsigned short errnoGS; +extern char *strerrorGS (unsigned short num); +extern void perrorGS (char *format, ...); + +/* from expandpath.c */ +extern char *expandpath (char *path); + +/* from stringGS.c */ +extern void strcpyGSString255 (GSString255Ptr to, GSString255Ptr from); +extern void strcatGSString255 (GSString255Ptr to, GSString255Ptr from); +extern int strcmpGSString255 (GSString255Ptr a, GSString255Ptr b); + diff --git a/usr.bin/install/makefile.mk b/usr.bin/install/makefile.mk new file mode 100644 index 0000000..f5278a3 --- /dev/null +++ b/usr.bin/install/makefile.mk @@ -0,0 +1,40 @@ +# +# This makefile is for use with dmake(1). +# +# $Id: makefile.mk,v 1.1 1996/03/31 23:38:34 gdr Exp $ +# + +DEFINES = -DCHECK_STACK +STACK = -s1280 +MAINFLAGS = $(DEFINES) $(STACK) -w -O +CFLAGS = $(DEFINES) $(STACK) -w -O -r +LDFLAGS = -v +LDLIBS = -l/usr/lib/stack +BINDIR = /usr/bin +MANDIR = /usr/man + +OBJS = install.o basename.o c2gs.o copyfile.o errnoGS.o \ + expandpath.o stringGS.o + +install: $(OBJS) install.r + $(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@ + copyfork install.r install -r + @echo 'type \"dmake doinstall\" to install this program' + +install.o: install.c install.h + $(CC) -c $(MAINFLAGS) install.c -o $@ + +doinstall: + ./install -m755 -obin -gsys ./install $(BINDIR) + ./install -m644 -obin -gsys ./install.1 $(MANDIR)/man1 + +clean clobber: + $(RM) $(OBJS) install.root install.r + +basename.o :: install.h +c2gs.o :: install.h +copyfile.o :: install.h +errnoGS.o :: install.h +expandpath.o :: install.h +stringGS.o :: install.h + diff --git a/usr.bin/install/stringGS.c b/usr.bin/install/stringGS.c new file mode 100644 index 0000000..3d58c20 --- /dev/null +++ b/usr.bin/install/stringGS.c @@ -0,0 +1,78 @@ +/* + * Copyright 1996 Devin Reade . + * All rights reserved. + * + * For copying and distribution information, see the file "COPYING" + * accompanying this file. + * + * $Id: stringGS.c,v 1.1 1996/03/31 23:38:34 gdr Exp $ + */ + +#include +#include "install.h" + +/* + * strcpyGSString255 + * + * copies the GSString255 pointed to by to that pointed + * to by + */ + +void +strcpyGSString255 (GSString255Ptr to, GSString255Ptr from) +{ + int i; + + char *p = from->text; + char *q = to->text; + for (i=0; ilength; i++) *q++ = *p++; + to->length = from->length; + return; +} + +/* + * strcatGSString255 + * + * concatenates the string onto , to a maximum of 255 + * chars total in . + */ + +void +strcatGSString255 (GSString255Ptr to, GSString255Ptr from) +{ + int i, count; + + char *p = from->text; + char *q = to->text; + q+= to->length; + count = from->length; + if (count > 255 - to->length) count = 255 - to->length; + for (i=0; ilength += count; + return; +} + +/* + * like strcmp(3), but for GSString255Ptr args. + */ + +int +strcmpGSString255 (GSString255Ptr a, GSString255Ptr b) +{ + int i, count; + char *p, *q; + + count = a->length - b->length; + if (count) return count; + + p = a->text; + q = b->text; + for (i=0; i *q) return 1; + else return -1; + } + return 0; +}