--- /dev/null
+These are the major changes from version 3.6 to version 3.7:
+
+A few bugs in the dd command have been fixed.
+
+
+These are the major changes from version 3.5 to version 3.6:
+
+The -mount and -umount commands have been modified to work for both
+Linux and BSD systems. Thanks to Wilbern Cobb for the patches.
+
+The -e and -s options for the -mount command have been added.
+
+The -f option was added to the command line so that script files
+using sash can be executed.
# Makefile for sash
#
# The HAVE_GZIP definition adds the -gzip and -gunzip commands.
-# The HAVE_EXT2 definition adds the -chattr and -lsattr comamnds.
+# The HAVE_LINUX_ATTR definition adds the -chattr and -lsattr commands.
+# The HAVE_LINUX_MOUNT definition makes -mount and -umount work on Linux.
+# The HAVE_BSD_MOUNT definition makes -mount and -umount work on BSD.
+# The MOUNT_TYPE definition sets the default file system type for -mount.
#
+HAVE_GZIP = 1
+HAVE_LINUX_ATTR = 1
+HAVE_LINUX_MOUNT = 1
+HAVE_BSD_MOUNT = 0
+MOUNT_TYPE = '"ext3"'
+
+
+CFLAGS = -O3 -Wall -Wmissing-prototypes \
+ -DHAVE_GZIP=$(HAVE_GZIP) \
+ -DHAVE_LINUX_ATTR=$(HAVE_LINUX_ATTR) \
+ -DHAVE_LINUX_MOUNT=$(HAVE_LINUX_MOUNT) \
+ -DHAVE_BSD_MOUNT=$(HAVE_BSD_MOUNT) \
+ -DMOUNT_TYPE=$(MOUNT_TYPE)
-CFLAGS = -O3 -Wall -Wmissing-prototypes -DHAVE_GZIP -DHAVE_EXT2
LDFLAGS = -static -s
LIBS = -lz
-This is release 3.4 of sash, my stand-alone shell for Linux.
+This is release 3.7 of sash, my stand-alone shell for Linux or other systems.
The purpose of this program is to make system recovery possible in
many cases where there are missing shared libraries or executables.
including versions of many of the standard utilities within itself.
Read the sash.1 documentation for more details.
-This version has the "-ar" built-in command for extracting files
-from archive files. This is used for unpacking Debian packages.
-Thanks to Aaron R. Crane for donating the code for this command
-(highly modified by me).
-
Type "make install" to build and install the program and man page.
-Some warning messages may appear when compiling cmds.c under Linux from
-the mount.h and fs.h include files. These warnings can be ignored.
+Several options in the Makefile can be changed to build sash for
+other UNIX-like systems. In particular, dependencies on Linux file
+systems can be removed and the mount command can be configured.
David I. Bell
dbell@canb.auug.org.au
-2 October 1999
+12 January 2004
* provided that this copyright notice remains intact.
*
* Modified:
- * Copyright (c) 1999 by David I. Bell
+ * Copyright (c) 2002 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
/*
- * Copyright (c) 1999 by David I. Bell
+ * Copyright (c) 2002 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
* They manipulate the important ext2 file system file attribute flags.
*/
-#ifdef HAVE_EXT2
+#if HAVE_LINUX_ATTR
#include <sys/ioctl.h>
#include <sys/types.h>
/*
- * Copyright (c) 1999 by David I. Bell
+ * Copyright (c) 2004 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
long count;
long seekVal;
long skipVal;
- long intotal;
- long outTotal;
+ long inFull;
+ long inPartial;
+ long outFull;
+ long outPartial;
char * buf;
char localBuf[BUF_SIZE];
seekVal = 0;
skipVal = 0;
blockSize = 512;
- count = 0x7fffffff;
+ count = -1;
while (--argc > 0)
{
}
}
- intotal = 0;
- outTotal = 0;
+ inFull = 0;
+ inPartial = 0;
+ outFull = 0;
+ outPartial = 0;
inFd = open(inFile, 0);
}
}
- while ((inCc = read(inFd, buf, blockSize)) > 0)
+ inCc = 0;
+
+ while (((count < 0) || (inFull + inPartial < count)) &&
+ (inCc = read(inFd, buf, blockSize)) > 0)
{
- intotal += inCc;
+ if (inCc < blockSize)
+ inPartial++;
+ else
+ inFull++;
cp = buf;
if (intFlag)
goto cleanup;
}
- outTotal += outCc;
+ if (outCc < blockSize)
+ outPartial++;
+ else
+ outFull++;
cp += outCc;
inCc -= outCc;
}
if (buf != localBuf)
free(buf);
- printf("%ld+%d records in\n", intotal / blockSize,
- (intotal % blockSize) != 0);
+ printf("%ld+%ld records in\n", inFull, inPartial);
- printf("%ld+%d records out\n", outTotal / blockSize,
- (outTotal % blockSize) != 0);
+ printf("%ld+%ld records out\n", outFull, outPartial);
}
/*
- * Copyright (c) 1999 by David I. Bell
+ * Copyright (c) 2002 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
/*
- * Copyright (c) 1999 by David I. Bell
+ * Copyright (c) 2002 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
/*
- * Copyright (c) 1999 by David I. Bell
+ * Copyright (c) 2002 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
/*
- * Copyright (c) 1999 by David I. Bell
+ * Copyright (c) 2002 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
/*
- * Copyright (c) 1999 by David I. Bell
+ * Copyright (c) 2002 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
* uncompress the files.
*/
-#ifdef HAVE_GZIP
+#if HAVE_GZIP
#include <sys/types.h>
/*
- * Copyright (c) 1999 by David I. Bell
+ * Copyright (c) 2002 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
/*
- * Copyright (c) 1999 by David I. Bell
+ * Copyright (c) 2002 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
/*
- * Copyright (c) 1999 by David I. Bell
+ * Copyright (c) 2002 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
#include <grp.h>
#include <utime.h>
#include <errno.h>
+
+#if HAVE_LINUX_MOUNT
#include <linux/fs.h>
+#endif
void
argc--;
argv++;
- type = "ext2";
+
+ type = MOUNT_TYPE;
+
+#if HAVE_LINUX_MOUNT
flags = MS_MGC_VAL;
+#else
+ flags = 0;
+#endif
while ((argc > 0) && (**argv == '-'))
{
argc--;
break;
+#if HAVE_LINUX_MOUNT
case 'r':
flags |= MS_RDONLY;
break;
flags |= MS_REMOUNT;
break;
+ case 's':
+ flags |= MS_NOSUID;
+ break;
+
+ case 'e':
+ flags |= MS_NOEXEC;
+ break;
+
+#elif HAVE_BSD_MOUNT
+ case 'r':
+ flags |= MNT_RDONLY;
+ break;
+
+ case 's':
+ flags |= MNT_NOSUID;
+ break;
+
+ case 'e':
+ flags |= MNT_NOEXEC;
+ break;
+#endif
default:
fprintf(stderr, "Unknown option\n");
return;
}
- if (mount(argv[0], argv[1], type, flags, 0) < 0)
- perror("mount failed");
+#if HAVE_LINUX_MOUNT
+
+ if (mount(argv[0], argv[1], type, flags, 0) < 0)
+ perror("mount failed");
+
+#elif HAVE_BSD_MOUNT
+ {
+ struct ufs_args ufs;
+ struct adosfs_args adosfs;
+ struct iso_args iso;
+ struct mfs_args mfs;
+ struct msdosfs_args msdosfs;
+ void * args;
+
+ if(!strcmp(type, "ffs") || !strcmp(type, "ufs")) {
+ ufs.fspec = (char*) argv[0];
+ args = &ufs;
+ } else if(!strcmp(type, "adosfs")) {
+ adosfs.fspec = (char*) argv[0];
+ adosfs.uid = 0;
+ adosfs.gid = 0;
+ args = &adosfs;
+ } else if(!strcmp(type, "cd9660")) {
+ iso.fspec = (char*) argv[0];
+ args = &iso;
+ } else if(!strcmp(type, "mfs")) {
+ mfs.fspec = (char*) argv[0];
+ args = &mfs;
+ } else if(!strcmp(type, "msdos")) {
+ msdosfs.fspec = (char*) argv[0];
+ msdosfs.uid = 0;
+ msdosfs.gid = 0;
+ args = &msdosfs;
+ } else {
+ fprintf(stderr, "Unknown filesystem type: %s", type);
+ fprintf(stderr,
+ "Supported: ffs ufs adosfs cd9660 mfs msdos\n");
+ return;
+ }
+
+ if (mount(type, argv[1], flags, args) < 0)
+ perror(argv[0]);
+ }
+#endif
}
void
do_umount(int argc, const char ** argv)
{
+#if HAVE_LINUX_MOUNT
if (umount(argv[1]) < 0)
perror(argv[1]);
+#elif HAVE_BSD_MOUNT
+ {
+ const char * str;
+ int flags = 0;
+
+ for (argc--, argv++;
+ (argc > 0) && (**argv == '-');) {
+ argc--;
+ str = *argv++;
+
+ while (*++str) {
+ switch (*str)
+ {
+ case 'f':
+ flags = MNT_FORCE;
+ break;
+ }
+ }
+ }
+
+ if (unmount(argv[0], flags) < 0)
+ perror(argv[0]);
+ }
+#endif
}
.SH NAME
sash \- stand-alone shell with built-in commands
.SH SYNOPSYS
-.B sash [-c command] [-p prompt] [-q] [-a]
+.B sash [-c command] [-f fileName ] [-p prompt] [-q] [-a]
.SH DESCRIPTION
The
.B sash
to the user's home directory (value of the $HOME environment variable).
.TP
.B -chattr [+i] [-i] [+a] [-a] fileName ...
-Change the attributes of the specified files on the ext2 file system.
+Change the attributes of the specified files on an ext2 or ext3 file system.
Using a plus sign adds the specified attribute for the files.
Using a minus sign removes the specified attributes for the files.
The 'i' attribute makes a file immutable so that it cannot be changed.
The 'a' attribute makes a file append-only.
+This command is only available on Linux.
.TP
.B -chgrp gid fileName ...
Change the group id for the specified list of files. The
path exactly as specified.
If the output path is a block or character device, then the uncompressed
versions of the input files are concatenated to the device.
+.sp
+This command is only available if
+.B sash
+was compiled to use the gzip library.
.TP
.B -gzip inputFileName ... [-o outputPath]
Compresses one or more files using the
If the output path is not a directory, then only one input file is allowed,
and the compressed version of that input file is created as the output
path exactly as specified.
+.sp
+This command is only available if
+.B sash
+was compiled to use the gzip library.
.TP
.B help [word]
Displays a list of built-in commands along with their usage strings.
The width of the output is calculated using the COLS environment variable.
.TP
.B -lsattr fileName ...
-Display attributes for the specified files on the ext2 file system.
+Display attributes for the specified files on an ext2 or ext3 file system.
The letter 'i' indicates that the file is immutable and cannot change.
The letter 'a' indicates that the file is append-only.
Dashes are shown where the attributes are not set.
+This command is only available on Linux.
.TP
.B -mkdir dirName ...
Creates the specified directories. They are created with the
or just a return to go to the next page. The environment variables
LINES and COLS can be used to set the page size.
.TP
-.B -mount [-t type] [-r] [-m] devName dirName
-Mount a filesystem on a directory name. The -t option specifies the
-type of filesystem being mounted, and defaults to "ext2".
+.B -mount [-t type] [-r] [-s] [-e] [-m] devName dirName
+Mount a filesystem on a directory name.
+The -t option specifies the type of filesystem being mounted,
+and defaults to "ext3" for Linux and "ffs" for BSD.
The -r option indicates to mount the filesystem read-only.
+The -s option indicates to mount the filesystem no-suid.
+The -e option indicates to mount the filesystem no-exec.
The -m option indicates to remount an already mounted filesystem.
+The -m option is only available on Linux.
.TP
.B -mv srcName ... destName
Moves one or more files from the
is not given, then the
current umask value is printed. The mask is an octal value.
.TP
-.B -umount fileName
+.B -umount [-f] fileName
Unmounts a file system. The file name can either be the device name
which is mounted, or else the directory name which the file system
is mounted onto.
+The -f option unmounts the filesystem even if it is being used.
+The -f option is only available on BSD.
.TP
.B unalias name
Remove the definition for the specified alias.
.SH OPTIONS
There are several command line options to
.BR sash .
+.PP
The -c option executes the next argument as a command (including embedded
spaces to separate the arguments of the command), and then exits.
.PP
+The -f option executes the commands contained in the file name specified
+by the next argument, and then exits.
+This feature can be used to create executable scripts for
+.B sash
+by starting the script file with a line similar to:
+.nf
+ #! /bin/sash -f
+.fi
+.PP
The -p option takes the next argument as the prompt string to be used
when prompting for commands.
.PP
.B sash
quiet, which simply means that it doesn't print its introduction line
when it starts.
+This option is also implied if the -c or -f options are used.
.PP
The -a option creates aliases for the built-in commands so
that they replace the corresponding standard commands.
with
.B lilo
to perform system recovery in some situations.
+Similar concepts should exist for other boot loaders and operating systems.
.PP
When important shared libraries are being upgraded,
it might be a good idea to have
.nf
David I. Bell
dbell@canb.auug.org.au
-2 October 1999
+12 January 2004
.fi
/*
- * Copyright (c) 1999 by David I. Bell
+ * Copyright (c) 2004 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
#include "sash.h"
-static const char * const version = "3.4";
+static const char * const version = "3.7";
/*
"[dirName]"
},
-#ifdef HAVE_EXT2
+#if HAVE_LINUX_ATTR
{
"-chattr", do_chattr, 3, INFINITE_ARGS,
"Change ext2 file attributes",
"[-in] word fileName ..."
},
-#ifdef HAVE_GZIP
+#if HAVE_GZIP
{
"-gunzip", do_gunzip, 2, INFINITE_ARGS,
"Uncompress files which were saved in GZIP or compress format",
"[-lidFC] fileName ..."
},
-#ifdef HAVE_EXT2
+#if HAVE_LINUX_ATTR
{
"-lsattr", do_lsattr, 2, INFINITE_ARGS,
"List ext2 file attributes",
{
"-mount", do_mount, 3, INFINITE_ARGS,
"Mount or remount a filesystem on a directory",
- "[-t type] [-r] [-m] devName dirName"
+#if HAVE_LINUX_MOUNT
+ "[-t type] [-r] [-s] [-e] [-m] devName dirName"
+#elif HAVE_BSD_MOUNT
+ "[-t type] [-r] [-s] [-e] devName dirName"
+#else
+ "[-t type] devName dirName"
+#endif
},
{
},
{
+#if HAVE_BSD_MOUNT
+ "-umount", do_umount, 2, 3,
+ "Unmount a filesystem",
+ "[-f] fileName"
+#else
"-umount", do_umount, 2, 2,
"Unmount a filesystem",
"fileName"
+#endif
},
{
{
const char * cp;
const char * singleCommand;
+ const char * commandFile;
BOOL quietFlag;
BOOL aliasFlag;
char buf[PATH_LEN];
singleCommand = NULL;
+ commandFile = NULL;
quietFlag = FALSE;
aliasFlag = FALSE;
break;
+ case 'f':
+ /*
+ * Execute commands from file.
+ * This is used for sash script files.
+ * The quiet flag is also set.
+ */
+ if ((argc != 1) || commandFile)
+ usage();
+
+ quietFlag = TRUE;
+ commandFile = *argv++;
+ argc--;
+
+ break;
+
case 'p':
/*
* Set the prompt string.
}
/*
- * Read commands from stdin.
+ * Read commands from stdin or from a command file.
*/
- readFile(NULL);
+ readFile(commandFile);
return 0;
}
{
fprintf(stderr, "Stand-alone shell (version %s)\n", version);
fprintf(stderr, "\n");
- fprintf(stderr, "Usage: sash [-a] [-q] [-c command] [-p prompt]\n");
+ fprintf(stderr, "Usage: sash [-a] [-q] [-f fileName] [-c command] [-p prompt]\n");
exit(1);
}
/*
- * Copyright (c) 1999 by David I. Bell
+ * Copyright (c) 2002 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
#ifndef SASH_H
#define SASH_H
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <memory.h>
-#include <malloc.h>
#include <time.h>
#include <ctype.h>
+#if __OpenBSD__
+#include <sys/param.h>
+#endif
+
+#if __Linux__
+#include <malloc.h>
+#endif
+
#define PATH_LEN 1024
#define CMD_LEN 10240
extern void do_ed(int argc, const char ** argv);
extern void do_where(int argc, const char ** argv);
-#ifdef HAVE_GZIP
+#if HAVE_GZIP
extern void do_gzip(int argc, const char ** argv);
extern void do_gunzip(int argc, const char ** argv);
#endif
-#ifdef HAVE_EXT2
+#if HAVE_LINUX_ATTR
extern void do_lsattr(int argc, const char ** argv);
extern void do_chattr(int argc, const char ** argv);
#endif
/*
- * Copyright (c) 1999 by David I. Bell
+ * Copyright (c) 2002 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*