Репозитории ALT
S: | 3.4-alt2.qa2 |
5.1: | 3.4-alt2 |
4.1: | 3.4-alt1 |
4.0: | 3.4-ipl11mdk.1 |
3.0: | 3.4-ipl11mdk.1 |
Группа :: Интерпретаторы команд
Пакет: sash
Главная Изменения Спек Патчи Sources Загрузить Gear Bugs and FR Repocop
Патч: sash-3.4-alt.patch
Скачать
Скачать
--- sash/Makefile
+++ sash/Makefile
@@ -3,29 +3,36 @@
#
# The HAVE_GZIP definition adds the -gzip and -gunzip commands.
# The HAVE_EXT2 definition adds the -chattr and -lsattr comamnds.
+# The WITH_READLINE definition adds readline support.
#
-CFLAGS = -O3 -Wall -Wmissing-prototypes -DHAVE_GZIP -DHAVE_EXT2
-LDFLAGS = -static -s
-LIBS = -lz
+MKDIR = mkdir -p
+INSTALL = install -p
+CFLAGS = $(RPM_OPT_FLAGS) -D_GNU_SOURCE -DHAVE_GZIP -DHAVE_EXT2 -DWITH_READLINE
+LDFLAGS = -static
+LIBS = -lz -lreadline -ltinfo
-BINDIR = /bin
-MANDIR = /usr/man/man1
+sbindir = /sbin
+mandir = /usr/share/man
+mansubdir = man1
+OBJS = sash.o message.o getline.o utils.o \
+ cmds.o cmd_dd.o cmd_ed.o cmd_grep.o cmd_ls.o cmd_tar.o \
+ cmd_gzip.o cmd_find.o cmd_file.o cmd_chattr.o cmd_ar.o
-OBJS = sash.o cmds.o cmd_dd.o cmd_ed.o cmd_grep.o cmd_ls.o cmd_tar.o \
- cmd_gzip.o cmd_find.o cmd_file.o cmd_chattr.o cmd_ar.o utils.o
+TARGET = sash
+$(TARGET): $(OBJS)
+ $(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
-sash: $(OBJS)
- $(CC) $(LDFLAGS) -o sash $(OBJS) $(LIBS)
+install: $(TARGET)
+ $(MKDIR) $(sbindir)
+ $(INSTALL) sash $(sbindir)/sash
+ $(MKDIR) $(mandir)/$(mansubdir)
+ $(INSTALL) -m644 sash.1 $(mandir)/$(mansubdir)/sash.1
clean:
- rm -f $(OBJS) sash
-
-install: sash
- cp sash $(BINDIR)/sash
- cp sash.1 $(MANDIR)/sash.1
+ rm -f $(OBJS) $(TARGET)
$(OBJS): sash.h
--- sash/cmd_ar.c
+++ sash/cmd_ar.c
@@ -16,14 +16,9 @@
#include <ar.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
#include <limits.h>
+#include "message.h"
#include "sash.h"
@@ -70,14 +65,14 @@ static int shortNameMatches44BSD(const char * name);
static int shortNameMatchesSysV(const char * name);
static BOOL wantMember(const Archive * arch, int n_names,
- const char ** names);
+ const char *const *names);
static BOOL getNumber(const char * s, unsigned base, int max_digits,
unsigned long * ul);
void
-do_ar(int argc, const char ** argv)
+do_ar(int argc, const char *const *argv)
{
const char * options;
const char * archiveName;
@@ -94,8 +89,7 @@ do_ar(int argc, const char ** argv)
if (argc < 3)
{
- fprintf(stderr, "Too few arguments for ar\n");
-
+ errmsg( "ar: too few arguments." );
return;
}
@@ -135,22 +129,18 @@ do_ar(int argc, const char ** argv)
break;
case 'd': case 'm': case 'q': case 'r':
- fprintf(stderr, "Writing ar files is not supported\n");
-
+ errmsg( "writing ar files is not supported." );
return;
default:
- fprintf(stderr, "Unknown ar flag: %c\n", *options);
-
+ errmsg( "ar: unknown flag: %c", *options );
return;
}
}
if (doExtract + doTable + doPrint != 1)
{
- fprintf(stderr,
- "Exactly one of 'x', 'p' or 't' must be specified\n");
-
+ errmsg( "ar: exactly one of 'x', 'p' or 't' must be specified." );
return;
}
@@ -230,9 +220,7 @@ do_ar(int argc, const char ** argv)
if (close(outfd) == -1)
{
- fprintf(stderr, "Can't close %s: %s\n",
- arch.name, strerror(errno));
-
+ errmsg( "ar: failed to close %s: %s", arch.name, strerror(errno) );
break;
}
@@ -241,7 +229,7 @@ do_ar(int argc, const char ** argv)
}
else
{
- fprintf(stderr, "Oops -- I don't know what to do\n");
+ errmsg( "ar: Oops -- I don't know what to do..." );
break;
}
}
@@ -264,9 +252,7 @@ createFile(const Archive * arch)
if (fd == -1)
{
- fprintf(stderr, "Can't create \"%s\": %s\n",
- arch->name, strerror(errno));
-
+ errmsg( "ar: cannot create \"%s\": %s", arch->name, strerror(errno) );
return -1;
}
@@ -288,7 +274,7 @@ createFile(const Archive * arch)
* file names, or else that the specified list of file names is empty.
*/
static BOOL
-wantMember(const Archive * arch, int n_names, const char ** name)
+wantMember(const Archive * arch, int n_names, const char *const *name)
{
int i;
@@ -395,9 +381,7 @@ openArchive(const char * name, Archive * arch)
if (arch->fd == -1)
{
- fprintf(stderr, "Can't open archive file %s: %s\n",
- name, strerror(errno));
-
+ errmsg( "ar: cannot open archive file %s: %s", name, strerror(errno) );
return FALSE;
}
@@ -405,23 +389,19 @@ openArchive(const char * name, Archive * arch)
if (cc == -1)
{
- fprintf(stderr, "Error reading archive header: %s\n",
- strerror(errno));
-
+ errmsg( "ar: %s: error reading archive header: %s", name, strerror(errno) );
goto close_and_out;
}
if (cc != SARMAG)
{
- fprintf(stderr, "Short read of archive header\n");
-
+ errmsg( "ar: %s: archive header too short", name );
goto close_and_out;
}
if (memcmp(buf, ARMAG, SARMAG))
{
- fprintf(stderr, "Invalid archive header\n");
-
+ errmsg( "ar: %s: invalid archive header", name );
goto close_and_out;
}
@@ -472,9 +452,7 @@ readMember(Archive * arch, struct ar_hdr * hdr)
if (cc < 0)
{
- fprintf(stderr, "Error reading member header: %s\n",
- strerror(errno));
-
+ errmsg( "ar: error reading member header: %s", strerror(errno) );
return FALSE;
}
@@ -487,15 +465,13 @@ readMember(Archive * arch, struct ar_hdr * hdr)
if (cc != sizeof(*hdr))
{
- fprintf(stderr, "Short read of member header\n");
-
+ errmsg( "ar: member header too short" );
return FALSE;
}
if (memcmp(hdr->ar_fmag, ARFMAG, sizeof(hdr->ar_fmag)))
{
- fprintf(stderr, "Invalid member header\n");
-
+ errmsg( "ar: invalid member header" );
return FALSE;
}
@@ -585,7 +561,7 @@ shortNameMatchesSysV(const char * name)
arch->name = malloc(n); \
if (!arch->name) \
{ \
- fprintf(stderr, "Out of memory\n"); \
+ errmsg( "malloc: %s", strerror(errno) ); \
return FALSE; \
} \
} while (0);
@@ -631,16 +607,13 @@ canonicalize(Archive * arch, const struct ar_hdr * hdr)
if (cc == -1)
{
- fprintf(stderr, "Error reading longname: %s\n",
- strerror(errno));
-
+ errmsg( "ar: error reading longname: %s", strerror(errno) );
goto free_and_out;
}
if (cc != n)
{
- fprintf(stderr, "Unexpected end of file in longname\n");
-
+ errmsg( "ar: unexpected end of file in longname" );
goto free_and_out;
}
@@ -663,8 +636,7 @@ canonicalize(Archive * arch, const struct ar_hdr * hdr)
if (n >= strlen(arch->nameTable))
{
- fprintf(stderr, "Longname index too large\n");
-
+ errmsg( "ar: longname index too large" );
return FALSE;
}
@@ -674,15 +646,13 @@ canonicalize(Archive * arch, const struct ar_hdr * hdr)
if (!p)
{
- fprintf(stderr, "Bad longname index\n");
-
+ errmsg( "ar: invalid longname index" );
return FALSE;
}
if (p[1] != '\n')
{
- fprintf(stderr, "Malformed longname table\n");
-
+ errmsg( "ar: malformed longname table" );
return FALSE;
}
@@ -724,7 +694,7 @@ canonicalize(Archive * arch, const struct ar_hdr * hdr)
#define FIELD(AFIELD, MFIELD, base) \
if (!getNumber(hdr->AFIELD, base, sizeof(hdr->AFIELD), &ul)) \
{ \
- fprintf(stderr, "Malformed archive member header\n"); \
+ errmsg( "ar: malformed archive member header" ); \
goto free_and_out; \
} \
arch->MFIELD = ul;
@@ -790,9 +760,7 @@ skipPadding(int fd, int pad)
{
if (lseek(fd, 1, SEEK_CUR) == -1)
{
- fprintf(stderr, "Can't skip pad byte: %s\n",
- strerror(errno));
-
+ errmsg( "ar: cannot skip pad byte: %s", strerror(errno) );
return FALSE;
}
}
@@ -842,8 +810,7 @@ readSpecialMember(Archive * arch)
if (!getNumber(hdr.ar_size, 10, sizeof(hdr.ar_size), &len))
{
- fprintf(stderr, "Invalid name-table size\n");
-
+ errmsg( "ar: invalid nameTable size" );
return FALSE;
}
@@ -851,8 +818,7 @@ readSpecialMember(Archive * arch)
if (!arch->nameTable)
{
- fprintf(stderr, "Out of memory\n");
-
+ errmsg( "ar: nameTable: %s", strerror(errno) );
return FALSE;
}
@@ -860,17 +826,13 @@ readSpecialMember(Archive * arch)
if (cc == -1)
{
- fprintf(stderr, "Error reading name-table: %s\n",
- strerror(errno));
-
+ errmsg( "ar: error reading nameTable: %s", strerror(errno) );
return FALSE;
}
if (cc != (ssize_t) len)
{
- fprintf(stderr,
- "Unexpected end of file in name-table\n");
-
+ errmsg( "ar: unexpected end of file in nameTable" );
return FALSE;
}
@@ -932,9 +894,7 @@ skipMember(const Archive * arch)
{
if (lseek(arch->fd, arch->size, SEEK_CUR) == -1)
{
- fprintf(stderr, "Can't skip past archive member: %s\n",
- strerror(errno));
-
+ errmsg( "ar: cannot skip past archive member: %s", strerror(errno) );
return FALSE;
}
@@ -962,23 +922,19 @@ writeFile(const Archive * arch, int outfd)
if (cc == -1)
{
- fprintf(stderr, "Error reading archive member: %s\n",
- strerror(errno));
-
+ errmsg( "ar: error reading archive member: %s", strerror(errno) );
return FALSE;
}
if (cc == 0)
{
- fprintf(stderr, "Unexpected end of file\n");
-
+ errmsg( "ar: unexpected end of file" );
return FALSE;
}
if (fullWrite(outfd, buf, cc) < 0)
{
- fprintf(stderr, "Write error: %s\n", strerror(errno));
-
+ errmsg( "ar: write failure: %s", strerror(errno) );
return FALSE;
}
--- sash/cmd_chattr.c
+++ sash/cmd_chattr.c
@@ -12,8 +12,9 @@
#include <sys/ioctl.h>
#include <sys/types.h>
-#include <linux/ext2_fs.h>
+#include <ext2fs/ext2_fs.h>
+#include "message.h"
#include "sash.h"
@@ -22,7 +23,7 @@
* This can turn on or off the immutable and append-only ext2 flags.
*/
void
-do_chattr(int argc, const char ** argv)
+do_chattr(int argc, const char *const *argv)
{
const char * fileName;
const char * options;
@@ -71,9 +72,7 @@ do_chattr(int argc, const char ** argv)
break;
default:
- fprintf(stderr, "Unknown flag '%c'\n",
- options[-1]);
-
+ errmsg( "chattr: unknown flag: %c", options[-1] );
return;
}
}
@@ -84,15 +83,13 @@ do_chattr(int argc, const char ** argv)
*/
if ((onFlags == 0) && (offFlags == 0))
{
- fprintf(stderr, "No attributes specified\n");
-
+ errmsg( "chattr: no attributes specified" );
return;
}
if ((onFlags & offFlags) != 0)
{
- fprintf(stderr, "Inconsistent attributes specified\n");
-
+ errmsg( "chattr: inconsistent attributes specified" );
return;
}
@@ -101,8 +98,7 @@ do_chattr(int argc, const char ** argv)
*/
if (argc <= 0)
{
- fprintf(stderr, "No files specified for setting attributes\n");
-
+ errmsg( "chattr: no files specified for setting attributes" );
return;
}
@@ -120,8 +116,7 @@ do_chattr(int argc, const char ** argv)
if (fd < 0)
{
- perror(fileName);
-
+ errmsg( "chattr: %s: %s", fileName, strerror(errno) );
continue;
}
@@ -130,10 +125,8 @@ do_chattr(int argc, const char ** argv)
*/
if (ioctl(fd, EXT2_IOC_GETFLAGS, &oldFlags) < 0)
{
- perror(fileName);
-
- (void) close(fd);
-
+ errmsg( "chattr: %s: %s", fileName, strerror(errno) );
+ close(fd);
continue;
}
@@ -160,10 +153,8 @@ do_chattr(int argc, const char ** argv)
*/
if (ioctl(fd, EXT2_IOC_SETFLAGS, &newFlags) < 0)
{
- perror(fileName);
-
+ errmsg( "chattr: %s: %s", fileName, strerror(errno) );
(void) close(fd);
-
continue;
}
@@ -180,7 +171,7 @@ do_chattr(int argc, const char ** argv)
* This lists the immutable and append-only ext2 flags.
*/
void
-do_lsattr(int argc, const char ** argv)
+do_lsattr(int argc, const char *const *argv)
{
const char * fileName;
int fd;
@@ -205,8 +196,7 @@ do_lsattr(int argc, const char ** argv)
if (fd < 0)
{
- perror(fileName);
-
+ errmsg( "lsattr: %s: %s", fileName, strerror(errno) );
continue;
}
@@ -222,8 +212,7 @@ do_lsattr(int argc, const char ** argv)
if (status < 0)
{
- perror(fileName);
-
+ errmsg( "lsattr: %s: %s", fileName, strerror(errno) );
continue;
}
--- sash/cmd_dd.c
+++ sash/cmd_dd.c
@@ -6,6 +6,7 @@
* The "dd" built-in command.
*/
+#include "message.h"
#include "sash.h"
@@ -41,7 +42,7 @@ static long getNum(const char * cp);
void
-do_dd(int argc, const char ** argv)
+do_dd(int argc, const char *const *argv)
{
const char * str;
const PARAM * par;
@@ -73,10 +74,9 @@ do_dd(int argc, const char ** argv)
str = *++argv;
cp = strchr(str, '=');
- if (cp == NULL)
+ if ( !cp )
{
- fprintf(stderr, "Bad dd argument\n");
-
+ errmsg( "dd: invalid argument" );
return;
}
@@ -93,8 +93,7 @@ do_dd(int argc, const char ** argv)
case PAR_IF:
if (inFile)
{
- fprintf(stderr, "Multiple input files illegal\n");
-
+ errmsg( "dd: multiple input files illegal" );
return;
}
@@ -104,8 +103,7 @@ do_dd(int argc, const char ** argv)
case PAR_OF:
if (outFile)
{
- fprintf(stderr, "Multiple output files illegal\n");
-
+ errmsg( "dd: multiple output files illegal" );
return;
}
@@ -117,8 +115,7 @@ do_dd(int argc, const char ** argv)
if (blockSize <= 0)
{
- fprintf(stderr, "Bad block size value\n");
-
+ errmsg( "dd: bad block size value" );
return;
}
@@ -129,8 +126,7 @@ do_dd(int argc, const char ** argv)
if (count < 0)
{
- fprintf(stderr, "Bad count value\n");
-
+ errmsg( "dd: bad count value" );
return;
}
@@ -141,8 +137,7 @@ do_dd(int argc, const char ** argv)
if (seekVal < 0)
{
- fprintf(stderr, "Bad seek value\n");
-
+ errmsg( "dd: bad seek value" );
return;
}
@@ -153,31 +148,27 @@ do_dd(int argc, const char ** argv)
if (skipVal < 0)
{
- fprintf(stderr, "Bad skip value\n");
-
+ errmsg( "dd: bad skip value" );
return;
}
break;
default:
- fprintf(stderr, "Unknown dd parameter\n");
-
+ errmsg( "dd: unknown parameter" );
return;
}
}
- if (inFile == NULL)
+ if ( !inFile )
{
- fprintf(stderr, "No input file specified\n");
-
+ errmsg( "dd: no input file specified" );
return;
}
- if (outFile == NULL)
+ if ( !outFile )
{
- fprintf(stderr, "No output file specified\n");
-
+ errmsg( "dd: no output file specified" );
return;
}
@@ -185,12 +176,11 @@ do_dd(int argc, const char ** argv)
if (blockSize > sizeof(localBuf))
{
- buf = malloc(blockSize);
+ buf = alloca(blockSize);
- if (buf == NULL)
+ if ( !buf )
{
- fprintf(stderr, "Cannot allocate buffer\n");
-
+ errmsg( "dd: buffer allocation failure: %s", strerror(errno) );
return;
}
}
@@ -202,11 +192,7 @@ do_dd(int argc, const char ** argv)
if (inFd < 0)
{
- perror(inFile);
-
- if (buf != localBuf)
- free(buf);
-
+ errmsg( "dd: error opening %s: %s", inFile, strerror(errno) );
return;
}
@@ -214,12 +200,9 @@ do_dd(int argc, const char ** argv)
if (outFd < 0)
{
- perror(outFile);
+ errmsg( "dd: error opening %s: %s", outFile, strerror(errno) );
close(inFd);
- if (buf != localBuf)
- free(buf);
-
return;
}
@@ -233,13 +216,13 @@ do_dd(int argc, const char ** argv)
if (inCc < 0)
{
- perror(inFile);
+ errmsg( "dd: error reading %s while skipping: %s", inFile, strerror(errno) );
goto cleanup;
}
if (inCc == 0)
{
- fprintf(stderr, "End of file while skipping\n");
+ errmsg( "dd: %s: unexpected end of file while skipping", inFile );
goto cleanup;
}
}
@@ -250,8 +233,7 @@ do_dd(int argc, const char ** argv)
{
if (lseek(outFd, seekVal * blockSize, 0) < 0)
{
- perror(outFile);
-
+ errmsg( "dd: error seeking %s: %s", outFile, strerror(errno) );
goto cleanup;
}
}
@@ -263,7 +245,7 @@ do_dd(int argc, const char ** argv)
if (intFlag)
{
- fprintf(stderr, "Interrupted\n");
+ errmsg( "dd: interrupted" );
goto cleanup;
}
@@ -273,7 +255,7 @@ do_dd(int argc, const char ** argv)
if (outCc < 0)
{
- perror(outFile);
+ errmsg( "dd: error writing %s: %s", outFile, strerror(errno) );
goto cleanup;
}
@@ -284,22 +266,23 @@ do_dd(int argc, const char ** argv)
}
if (inCc < 0)
- perror(inFile);
+ errmsg( "dd: error reading %s: %s", inFile, strerror(errno) );
cleanup:
- close(inFd);
+ if ( close(inFd) < 0 )
+ errmsg( "dd: error closing %s: %s", inFile, strerror(errno) );
if (close(outFd) < 0)
- perror(outFile);
-
- if (buf != localBuf)
- free(buf);
+ errmsg( "dd: error closing %s: %s", outFile, strerror(errno) );
- printf("%ld+%d records in\n", intotal / blockSize,
- (intotal % blockSize) != 0);
+ if ( intotal || outTotal )
+ {
+ printf("%ld+%d records in\n", intotal / blockSize,
+ (intotal % blockSize) != 0);
- printf("%ld+%d records out\n", outTotal / blockSize,
- (outTotal % blockSize) != 0);
+ printf("%ld+%d records out\n", outTotal / blockSize,
+ (outTotal % blockSize) != 0);
+ }
}
--- sash/cmd_ed.c
+++ sash/cmd_ed.c
@@ -6,6 +6,7 @@
* The "ed" built-in command (much simplified)
*/
+#include "message.h"
#include "sash.h"
#define USERSIZE 1024 /* max line length typed in by user */
@@ -43,7 +44,7 @@ static LEN bufSize;
static void doCommands(void);
static void subCommand(const char * cmd, NUM num1, NUM num2);
-static BOOL getNum(const char ** retcp, BOOL * retHaveNum, NUM * retNum);
+static BOOL getNum(const char **retcp, BOOL * retHaveNum, NUM * retNum);
static BOOL setCurNum(NUM num);
static BOOL initEdit(void);
static void termEdit(void);
@@ -61,7 +62,7 @@ static LEN findString
void
-do_ed(int argc, const char ** argv)
+do_ed(int argc, const char *const *argv)
{
if (!initEdit())
return;
@@ -70,18 +71,16 @@ do_ed(int argc, const char ** argv)
{
fileName = strdup(argv[1]);
- if (fileName == NULL)
+ if ( !fileName )
{
- fprintf(stderr, "No memory\n");
+ errmsg( "ed: %s", strerror(errno) );
termEdit();
-
return;
}
if (!readLines(fileName, 1))
{
termEdit();
-
return;
}
@@ -119,7 +118,7 @@ doCommands(void)
printf(": ");
fflush(stdout);
- if (fgets(buf, sizeof(buf), stdin) == NULL)
+ if ( !fgets(buf, sizeof(buf), stdin) )
return;
len = strlen(buf);
@@ -131,7 +130,7 @@ doCommands(void)
if (*endbuf != '\n')
{
- fprintf(stderr, "Command line too long\n");
+ errmsg( "ed: command line too long" );
do
{
@@ -208,7 +207,7 @@ doCommands(void)
case 'f':
if (*cp && !isBlank(*cp))
{
- fprintf(stderr, "Bad file command\n");
+ errmsg( "ed: bad file command" );
break;
}
@@ -227,9 +226,9 @@ doCommands(void)
newname = strdup(cp);
- if (newname == NULL)
+ if ( !newname )
{
- fprintf(stderr, "No memory for file name\n");
+ errmsg( "ed: file name allocation failure: %s", strerror(errno) );
break;
}
@@ -249,7 +248,7 @@ doCommands(void)
if ((*cp < 'a') || (*cp > 'a') || cp[1])
{
- fprintf(stderr, "Bad mark name\n");
+ errmsg( "ed: bad mark name" );
break;
}
@@ -270,7 +269,7 @@ doCommands(void)
if (have1 || *cp)
{
- fprintf(stderr, "Bad quit command\n");
+ errmsg( "ed: bad quit command" );
break;
}
@@ -295,16 +294,16 @@ doCommands(void)
case 'r':
if (*cp && !isBlank(*cp))
{
- fprintf(stderr, "Bad read command\n");
+ errmsg( "ed: bad read command" );
break;
}
while (isBlank(*cp))
cp++;
- if (*cp == '\0')
+ if ( !*cp )
{
- fprintf(stderr, "No file name\n");
+ errmsg( "ed: no file name specified" );
break;
}
@@ -314,7 +313,7 @@ doCommands(void)
if (readLines(cp, num1 + 1))
break;
- if (fileName == NULL)
+ if ( !fileName )
fileName = strdup(cp);
break;
@@ -326,7 +325,7 @@ doCommands(void)
case 'w':
if (*cp && !isBlank(*cp))
{
- fprintf(stderr, "Bad write command\n");
+ errmsg( "ed: bad write command" );
break;
}
@@ -341,9 +340,9 @@ doCommands(void)
if (*cp == '\0')
cp = fileName;
- if (cp == NULL)
+ if ( !cp )
{
- fprintf(stderr, "No file name specified\n");
+ errmsg( "ed: no file name specified");
break;
}
@@ -368,7 +367,7 @@ doCommands(void)
case '.':
if (have1)
{
- fprintf(stderr, "No arguments allowed\n");
+ errmsg( "ed: no arguments allowed" );
break;
}
@@ -398,7 +397,7 @@ doCommands(void)
break;
default:
- fprintf(stderr, "Unimplemented command\n");
+ errmsg( "ed: command not implemented" );
break;
}
}
@@ -430,8 +429,7 @@ subCommand(const char * cmd, NUM num1, NUM num2)
if ((num1 < 1) || (num2 > lastNum) || (num1 > num2))
{
- fprintf(stderr, "Bad line range for substitute\n");
-
+ errmsg( "ed: bad line range for substitution" );
return;
}
@@ -448,8 +446,7 @@ subCommand(const char * cmd, NUM num1, NUM num2)
if (isBlank(*cp) || (*cp == '\0'))
{
- fprintf(stderr, "Bad delimiter for substitute\n");
-
+ errmsg( "ed: bad delimiter for substitution" );
return;
}
@@ -458,10 +455,9 @@ subCommand(const char * cmd, NUM num1, NUM num2)
cp = strchr(cp, delim);
- if (cp == NULL)
+ if ( !cp )
{
- fprintf(stderr, "Missing 2nd delimiter for substitute\n");
-
+ errmsg( "ed: missing 2nd delimiter for substitution" );
return;
}
@@ -486,8 +482,7 @@ subCommand(const char * cmd, NUM num1, NUM num2)
break;
default:
- fprintf(stderr, "Unknown option for substitute\n");
-
+ errmsg( "ed: unknown option for substitution" );
return;
}
@@ -495,7 +490,7 @@ subCommand(const char * cmd, NUM num1, NUM num2)
{
if (searchString[0] == '\0')
{
- fprintf(stderr, "No previous search string\n");
+ errmsg( "ed: no previous search string" );
return;
}
@@ -508,7 +503,7 @@ subCommand(const char * cmd, NUM num1, NUM num2)
lp = findLine(num1);
- if (lp == NULL)
+ if ( !lp )
return;
oldLen = strlen(oldStr);
@@ -581,10 +576,9 @@ subCommand(const char * cmd, NUM num1, NUM num2)
*/
nlp = (LINE *) malloc(sizeof(LINE) + lp->len + deltaLen);
- if (nlp == NULL)
+ if ( !nlp )
{
- fprintf(stderr, "Cannot get memory for line\n");
-
+ errmsg( "ed: cannot allocate line: %s", strerror(errno) );
return;
}
@@ -625,7 +619,7 @@ subCommand(const char * cmd, NUM num1, NUM num2)
}
if (!didSub)
- fprintf(stderr, "No substitutions found for \"%s\"\n", oldStr);
+ errmsg( "ed: no substitutions found for \"%s\"", oldStr );
}
@@ -647,7 +641,7 @@ findString( const LINE * lp, const char * str, LEN len, LEN offset)
{
ncp = memchr(cp, *str, left);
- if (ncp == NULL)
+ if ( !ncp )
return -1;
left -= (ncp - cp);
@@ -692,7 +686,7 @@ addLines(NUM num)
if (buf[len - 1] != '\n')
{
- fprintf(stderr, "Line too long\n");
+ errmsg( "ed: line too long" );
do
{
@@ -718,7 +712,7 @@ addLines(NUM num)
* The character pointer which stopped the scan is also returned.
*/
static BOOL
-getNum(const char ** retcp, BOOL * retHaveNum, NUM * retNum)
+getNum(const char **retcp, BOOL * retHaveNum, NUM * retNum)
{
const char * cp;
char * endStr;
@@ -757,7 +751,7 @@ getNum(const char ** retcp, BOOL * retHaveNum, NUM * retNum)
if ((*cp < 'a') || (*cp > 'z'))
{
- fprintf(stderr, "Bad mark name\n");
+ errmsg( "ed: bad mark name" );
return FALSE;
}
@@ -844,10 +838,9 @@ initEdit(void)
bufSize = INITBUF_SIZE;
bufBase = malloc(bufSize);
- if (bufBase == NULL)
+ if ( !bufBase )
{
- fprintf(stderr, "No memory for buffer\n");
-
+ errmsg( "ed: buffer allocation failure: %s", strerror(errno) );
return FALSE;
}
@@ -917,8 +910,7 @@ readLines(const char * file, NUM num)
if ((num < 1) || (num > lastNum + 1))
{
- fprintf(stderr, "Bad line for read\n");
-
+ errmsg( "ed: bad line for read" );
return FALSE;
}
@@ -926,8 +918,7 @@ readLines(const char * file, NUM num)
if (fd < 0)
{
- perror(file);
-
+ errmsg( "ed: error opening %s: %s", file, strerror(errno) );
return FALSE;
}
@@ -982,11 +973,10 @@ readLines(const char * file, NUM num)
len = (bufSize * 3) / 2;
cp = realloc(bufBase, len);
- if (cp == NULL)
+ if ( !cp )
{
- fprintf(stderr, "No memory for buffer\n");
+ errmsg( "ed: buffer allocation failure: %s", strerror(errno) );
close(fd);
-
return FALSE;
}
@@ -1004,9 +994,8 @@ readLines(const char * file, NUM num)
if (cc < 0)
{
- perror(file);
+ errmsg( "ed: error reading %s: %s", file, strerror(errno) );
close(fd);
-
return FALSE;
}
@@ -1046,7 +1035,7 @@ writeLines(const char * file, NUM num1, NUM num2)
if ((num1 < 1) || (num2 > lastNum) || (num1 > num2))
{
- fprintf(stderr, "Bad line range for write\n");
+ errmsg( "ed: bad line range for write" );
return FALSE;
}
@@ -1057,8 +1046,7 @@ writeLines(const char * file, NUM num1, NUM num2)
fd = creat(file, 0666);
if (fd < 0) {
- perror(file);
-
+ errmsg( "ed: error creating %s: %s", file, strerror(errno) );
return FALSE;
}
@@ -1067,10 +1055,9 @@ writeLines(const char * file, NUM num1, NUM num2)
lp = findLine(num1);
- if (lp == NULL)
+ if ( !lp )
{
close(fd);
-
return FALSE;
}
@@ -1078,9 +1065,8 @@ writeLines(const char * file, NUM num1, NUM num2)
{
if (write(fd, lp->data, lp->len) != lp->len)
{
- perror(file);
+ errmsg( "ed: error writing %s: %s", file, strerror(errno) );
close(fd);
-
return FALSE;
}
@@ -1091,8 +1077,7 @@ writeLines(const char * file, NUM num1, NUM num2)
if (close(fd) < 0)
{
- perror(file);
-
+ errmsg( "ed: error closing %s: %s", file, strerror(errno) );
return FALSE;
}
@@ -1118,14 +1103,13 @@ printLines(NUM num1, NUM num2, BOOL expandFlag)
if ((num1 < 1) || (num2 > lastNum) || (num1 > num2))
{
- fprintf(stderr, "Bad line range for print\n");
-
+ errmsg( "ed: bad line range for print" );
return FALSE;
}
lp = findLine(num1);
- if (lp == NULL)
+ if ( !lp )
return FALSE;
while (!intFlag && (num1 <= num2))
@@ -1199,17 +1183,15 @@ insertLine(NUM num, const char * data, LEN len)
if ((num < 1) || (num > lastNum + 1))
{
- fprintf(stderr, "Inserting at bad line number\n");
-
+ errmsg( "ed: inserting at bad line number" );
return FALSE;
}
newLp = (LINE *) malloc(sizeof(LINE) + len - 1);
- if (newLp == NULL)
+ if ( !newLp )
{
- fprintf(stderr, "Failed to allocate memory for line\n");
-
+ errmsg( "ed: line allocation failure: %s", strerror(errno) );
return FALSE;
}
@@ -1222,7 +1204,7 @@ insertLine(NUM num, const char * data, LEN len)
{
lp = findLine(num);
- if (lp == NULL)
+ if ( !lp )
{
free((char *) newLp);
@@ -1255,14 +1237,13 @@ deleteLines(NUM num1, NUM num2)
if ((num1 < 1) || (num2 > lastNum) || (num1 > num2))
{
- fprintf(stderr, "Bad line numbers for delete\n");
-
+ errmsg( "ed: bad line numbers for delete" );
return FALSE;
}
lp = findLine(num1);
- if (lp == NULL)
+ if ( !lp )
return FALSE;
if ((curNum >= num1) && (curNum <= num2))
@@ -1316,7 +1297,7 @@ searchLines(const char * str, NUM num1, NUM num2)
if ((num1 < 1) || (num2 > lastNum) || (num1 > num2))
{
- fprintf(stderr, "Bad line numbers for search\n");
+ errmsg( "ed: bad line numbers for search" );
return 0;
}
@@ -1325,7 +1306,7 @@ searchLines(const char * str, NUM num1, NUM num2)
{
if (searchString[0] == '\0')
{
- fprintf(stderr, "No previous search string\n");
+ errmsg( "ed: no previous search string" );
return 0;
}
@@ -1340,7 +1321,7 @@ searchLines(const char * str, NUM num1, NUM num2)
lp = findLine(num1);
- if (lp == NULL)
+ if ( !lp )
return 0;
while (num1 <= num2)
@@ -1352,8 +1333,7 @@ searchLines(const char * str, NUM num1, NUM num2)
lp = lp->next;
}
- fprintf(stderr, "Cannot find string \"%s\"\n", str);
-
+ errmsg( "ed: cannot find string \"%s\"", str );
return 0;
}
@@ -1369,8 +1349,7 @@ findLine(NUM num)
if ((num < 1) || (num > lastNum))
{
- fprintf(stderr, "Line number %d does not exist\n", num);
-
+ errmsg( "ed: line number %d does not exist", num );
return NULL;
}
@@ -1424,7 +1403,7 @@ setCurNum(NUM num)
lp = findLine(num);
- if (lp == NULL)
+ if ( !lp )
return FALSE;
curNum = num;
--- sash/cmd_file.c
+++ sash/cmd_file.c
@@ -6,11 +6,10 @@
* The "file" built-in command.
*/
-#include <ctype.h>
-#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include "message.h"
#include "sash.h"
@@ -18,7 +17,7 @@ static const char * checkFile(const char * name);
void
-do_file(int argc, const char ** argv)
+do_file(int argc, const char *const *argv)
{
const char * name;
const char * info;
--- sash/cmd_find.c
+++ sash/cmd_find.c
@@ -9,18 +9,11 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
-#include <errno.h>
+#include "message.h"
#include "sash.h"
-#ifdef S_ISLNK
-#define LSTAT lstat
-#else
-#define LSTAT stat
-#endif
-
-
#define MAX_NAME_SIZE (1024 * 10)
@@ -47,7 +40,7 @@ static BOOL testFile(const char * fullName, const struct stat * statBuf);
* This is limited to just printing their file names.
*/
void
-do_find(int argc, const char ** argv)
+do_find(int argc, const char *const *argv)
{
const char * cp;
const char * path;
@@ -63,8 +56,7 @@ do_find(int argc, const char ** argv)
if ((argc <= 0) || (**argv == '-'))
{
- fprintf(stderr, "No path specified\n");
-
+ errmsg( "find: no path specified" );
return;
}
@@ -82,7 +74,7 @@ do_find(int argc, const char ** argv)
{
if ((argc <= 0) || (**argv == '-'))
{
- fprintf(stderr, "Missing type string\n");
+ errmsg( "find: missing type string" );
return;
}
@@ -94,7 +86,7 @@ do_find(int argc, const char ** argv)
{
if ((argc <= 0) || (**argv == '-'))
{
- fprintf(stderr, "Missing file name\n");
+ errmsg( "find: missing file name" );
return;
}
@@ -106,7 +98,7 @@ do_find(int argc, const char ** argv)
{
if ((argc <= 0) || (**argv == '-'))
{
- fprintf(stderr, "Missing file size\n");
+ errmsg( "find: missing file size" );
return;
}
@@ -121,7 +113,7 @@ do_find(int argc, const char ** argv)
if (*cp || (fileSize < 0))
{
- fprintf(stderr, "Bad file size specified\n");
+ errmsg( "find: bad file size specified" );
return;
}
@@ -129,9 +121,9 @@ do_find(int argc, const char ** argv)
else
{
if (*cp != '-')
- fprintf(stderr, "Missing dash in option\n");
+ errmsg( "find: missing dash in option" );
else
- fprintf(stderr, "Unknown option\n");
+ errmsg( "find: unknown option" );
return;
}
@@ -143,16 +135,13 @@ do_find(int argc, const char ** argv)
*/
if (stat(path, &statBuf) < 0)
{
- fprintf(stderr, "Cannot stat \"%s\": %s\n", path,
- strerror(errno));
-
+ errmsg( "find: cannot stat \"%s\": %s", path, strerror(errno) );
return;
}
if (!S_ISDIR(statBuf.st_mode))
{
- fprintf(stderr, "Path \"%s\" is not a directory\n", path);
-
+ errmsg( "find: path \"%s\" is not a directory", path );
return;
}
@@ -191,11 +180,9 @@ examineDirectory(const char * path)
*/
dir = opendir(path);
- if (dir == NULL)
+ if ( !dir )
{
- fprintf(stderr, "Cannot read directory \"%s\": %s\n",
- path, strerror(errno));
-
+ errmsg( "find: cannot read directory \"%s\": %s", path, strerror(errno) );
return;
}
@@ -229,11 +216,9 @@ examineDirectory(const char * path)
/*
* Find out about this file.
*/
- if (LSTAT(fullName, &statBuf) < 0)
+ if (lstat(fullName, &statBuf) < 0)
{
- fprintf(stderr, "Cannot stat \"%s\": %s\n",
- fullName, strerror(errno));
-
+ errmsg( "find: cannot stat \"%s\": %s", fullName, strerror(errno) );
continue;
}
--- sash/cmd_grep.c
+++ sash/cmd_grep.c
@@ -6,8 +6,7 @@
* The "grep" built-in command.
*/
-#include <ctype.h>
-
+#include "message.h"
#include "sash.h"
@@ -16,7 +15,7 @@ static BOOL search
void
-do_grep(int argc, const char ** argv)
+do_grep(int argc, const char *const *argv)
{
FILE * fp;
const char * word;
@@ -50,8 +49,7 @@ do_grep(int argc, const char ** argv)
break;
default:
- fprintf(stderr, "Unknown option\n");
-
+ errmsg( "grep: unknown option: -%c", *cp );
return;
}
}
@@ -67,10 +65,9 @@ do_grep(int argc, const char ** argv)
fp = fopen(name, "r");
- if (fp == NULL)
+ if ( !fp )
{
- perror(name);
-
+ errmsg( "grep: error opening %s: %s", name, strerror(errno) );
continue;
}
@@ -81,7 +78,6 @@ do_grep(int argc, const char ** argv)
if (intFlag)
{
fclose(fp);
-
return;
}
@@ -90,7 +86,7 @@ do_grep(int argc, const char ** argv)
cp = &buf[strlen(buf) - 1];
if (*cp != '\n')
- fprintf(stderr, "%s: Line too long\n", name);
+ errmsg( "grep: %s: line too long", name );
if (search(buf, word, ignoreCase))
{
@@ -105,7 +101,7 @@ do_grep(int argc, const char ** argv)
}
if (ferror(fp))
- perror(name);
+ errmsg( "grep: error reading %s: %s", name, strerror(errno) );
fclose(fp);
}
--- sash/cmd_gzip.c
+++ sash/cmd_gzip.c
@@ -16,6 +16,7 @@
#include <sys/stat.h>
#include <zlib.h>
+#include "message.h"
#include "sash.h"
@@ -63,7 +64,7 @@ static const char * convertName
void
-do_gzip(int argc, const char ** argv)
+do_gzip(int argc, const char *const *argv)
{
const char * outPath;
const char * inFile;
@@ -94,10 +95,10 @@ do_gzip(int argc, const char ** argv)
{
if (argv[i][0] == '-')
{
- if (strcmp(argv[i], "-o") == 0)
- fprintf(stderr, "Illegal use of -o\n");
+ if ( !strcmp(argv[i], "-o") )
+ errmsg( "gzip: illegal use of -o" );
else
- fprintf(stderr, "Illegal option\n");
+ errmsg( "gzip: illegal option" );
return;
}
@@ -108,7 +109,7 @@ do_gzip(int argc, const char ** argv)
* the input files in place using their full paths. The input
* file names are then deleted.
*/
- if (outPath == NULL)
+ if ( !outPath )
{
while (!intFlag && (argc-- > 0))
{
@@ -128,8 +129,7 @@ do_gzip(int argc, const char ** argv)
*/
if (unlink(inFile) < 0)
{
- fprintf(stderr, "%s: %s\n", inFile,
- "Compressed ok but unlink failed");
+ errmsg( "gzip: %s: %s", inFile, "compressed ok but unlink failed" );
}
}
@@ -147,7 +147,7 @@ do_gzip(int argc, const char ** argv)
if (argc == 1)
(void) gzip(*argv, outPath);
else
- fprintf(stderr, "Exactly one input file is required\n");
+ errmsg( "gzip: exactly one input file is required" );
return;
}
@@ -193,7 +193,7 @@ do_gzip(int argc, const char ** argv)
void
-do_gunzip(int argc, const char ** argv)
+do_gunzip(int argc, const char *const *argv)
{
const char * outPath;
const char * inFile;
@@ -225,9 +225,9 @@ do_gunzip(int argc, const char ** argv)
if (argv[i][0] == '-')
{
if (strcmp(argv[i], "-o") == 0)
- fprintf(stderr, "Illegal use of -o\n");
+ errmsg( "gunzip: illegal use of -o" );
else
- fprintf(stderr, "Illegal option\n");
+ errmsg( "gunzip: illegal option" );
return;
}
@@ -249,9 +249,7 @@ do_gunzip(int argc, const char ** argv)
if (inFile == outFile)
{
- fprintf(stderr, "%s: %s\n", inFile,
- "missing compression extension");
-
+ errmsg( "gunzip: %s: %s", inFile, "missing compression suffix" );
continue;
}
@@ -267,8 +265,7 @@ do_gunzip(int argc, const char ** argv)
*/
if (unlink(inFile) < 0)
{
- fprintf(stderr, "%s: %s\n", inFile,
- "Uncompressed ok but unlink failed");
+ errmsg( "gunzip: %s: %s", inFile, "uncompressed ok but unlink failed" );
}
}
@@ -298,7 +295,7 @@ do_gunzip(int argc, const char ** argv)
if (argc == 1)
(void) gunzip(*argv, outPath);
else
- fprintf(stderr, "Exactly one input file is required\n");
+ errmsg( "gunzip: exactly one input file is required" );
return;
}
@@ -367,8 +364,7 @@ gzip(const char * inputFileName, const char * outputFileName)
*/
if (stat(inputFileName, &statBuf1) < 0)
{
- perror(inputFileName);
-
+ errmsg( "gzip: %s: %s", inputFileName, strerror(errno) );
return FALSE;
}
@@ -381,10 +377,7 @@ gzip(const char * inputFileName, const char * outputFileName)
if ((statBuf1.st_dev == statBuf2.st_dev) &&
(statBuf1.st_ino == statBuf2.st_ino))
{
- fprintf(stderr,
- "Cannot compress file \"%s\" on top of itself\n",
- inputFileName);
-
+ errmsg( "gzip: cannot compress file \"%s\" on top of itself", inputFileName );
return FALSE;
}
@@ -395,8 +388,7 @@ gzip(const char * inputFileName, const char * outputFileName)
if (inFD < 0)
{
- perror(inputFileName);
-
+ errmsg( "gzip: error opening %s: %s", inputFileName, strerror(errno) );
goto failed;
}
@@ -407,8 +399,7 @@ gzip(const char * inputFileName, const char * outputFileName)
if (outGZ == NULL)
{
- fprintf(stderr, "%s: gzopen failed\n", outputFileName);
-
+ errmsg( "gzip: %s: gzopen failure: %s", outputFileName, strerror(errno) );
goto failed;
}
@@ -420,9 +411,7 @@ gzip(const char * inputFileName, const char * outputFileName)
{
if (gzwrite(outGZ, buf, len) != len)
{
- fprintf(stderr, "%s: %s\n", inputFileName,
- gzerror(outGZ, &err));
-
+ errmsg( "gzip: error writing %s: %s", outputFileName, gzerror(outGZ, &err) );
goto failed;
}
@@ -432,8 +421,7 @@ gzip(const char * inputFileName, const char * outputFileName)
if (len < 0)
{
- perror(inputFileName);
-
+ errmsg( "gzip: error reading %s: %s", inputFileName, strerror(errno) );
goto failed;
}
@@ -442,8 +430,7 @@ gzip(const char * inputFileName, const char * outputFileName)
*/
if (close(inFD))
{
- perror(inputFileName);
-
+ errmsg( "gzip: error closing %s: %s", inputFileName, strerror(errno) );
goto failed;
}
@@ -451,8 +438,7 @@ gzip(const char * inputFileName, const char * outputFileName)
if (gzclose(outGZ) != Z_OK)
{
- fprintf(stderr, "%s: gzclose failed\n", outputFileName);
-
+ errmsg( "gzip: %s: gzclose failure: %s", outputFileName, gzerror(outGZ, &err) );
goto failed;
}
@@ -502,8 +488,7 @@ gunzip(const char * inputFileName, const char * outputFileName)
*/
if (stat(inputFileName, &statBuf1) < 0)
{
- perror(inputFileName);
-
+ errmsg( "gunzip: %s: %s", inputFileName, strerror(errno) );
return FALSE;
}
@@ -516,10 +501,7 @@ gunzip(const char * inputFileName, const char * outputFileName)
if ((statBuf1.st_dev == statBuf2.st_dev) &&
(statBuf1.st_ino == statBuf2.st_ino))
{
- fprintf(stderr,
- "Cannot uncompress file \"%s\" on top of itself\n",
- inputFileName);
-
+ errmsg( "gunzip: cannot uncompress file \"%s\" on top of itself", inputFileName );
return FALSE;
}
@@ -528,10 +510,9 @@ gunzip(const char * inputFileName, const char * outputFileName)
*/
inGZ = gzopen(inputFileName, "rb");
- if (inGZ == NULL)
+ if ( !inGZ )
{
- fprintf(stderr, "%s: gzopen failed\n", inputFileName);
-
+ errmsg( "gunzip: %s: gzopen failure: %s", inputFileName, strerror(errno) );
return FALSE;
}
@@ -545,8 +526,7 @@ gunzip(const char * inputFileName, const char * outputFileName)
if (outFD < 0)
{
- perror(outputFileName);
-
+ errmsg( "gunzip: error opening %s: %s", outputFileName, strerror(errno) );
goto failed;
}
@@ -558,8 +538,7 @@ gunzip(const char * inputFileName, const char * outputFileName)
{
if (fullWrite(outFD, buf, len) < 0)
{
- perror(outputFileName);
-
+ errmsg( "gunzip: error writing %s: %s", outputFileName, strerror(errno) );
goto failed;
}
@@ -569,9 +548,7 @@ gunzip(const char * inputFileName, const char * outputFileName)
if (len < 0)
{
- fprintf(stderr, "%s: %s\n", inputFileName,
- gzerror(inGZ, &err));
-
+ errmsg( "gunzip: error reading %s: %s", inputFileName, gzerror(inGZ, &err) );
goto failed;
}
@@ -580,8 +557,7 @@ gunzip(const char * inputFileName, const char * outputFileName)
*/
if (close(outFD))
{
- perror(outputFileName);
-
+ errmsg( "gunzip: error closing %s: %s", outputFileName, strerror(errno) );
goto failed;
}
@@ -589,8 +565,7 @@ gunzip(const char * inputFileName, const char * outputFileName)
if (gzclose(inGZ) != Z_OK)
{
- fprintf(stderr, "%s: gzclose failed\n", inputFileName);
-
+ errmsg( "gunzip: %s: gzclose failure: %s", inputFileName, gzerror(inGZ, &err) );
goto failed;
}
--- sash/cmd_ls.c
+++ sash/cmd_ls.c
@@ -6,23 +6,17 @@
* The "ls" built-in command.
*/
-#include "sash.h"
-
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <pwd.h>
#include <grp.h>
-
-#define LISTSIZE 8192
+#include "message.h"
+#include "sash.h"
-#ifdef S_ISLNK
-#define LSTAT lstat
-#else
-#define LSTAT stat
-#endif
+#define LISTSIZE 8192
/*
@@ -60,7 +54,7 @@ static void clearListNames(void);
void
-do_ls(int argc, const char ** argv)
+do_ls(int argc, const char *const *argv)
{
const char * cp;
const char * name;
@@ -73,7 +67,7 @@ do_ls(int argc, const char ** argv)
char fullName[PATH_LEN];
struct stat statBuf;
- static const char * def[] = {"."};
+ static const char *const def[] = {"."};
/*
* Reset for a new listing run.
@@ -103,7 +97,7 @@ do_ls(int argc, const char ** argv)
case 'C': flags |= LSF_COLUMN; break;
default:
- fprintf(stderr, "Unknown option -%c\n", cp[-1]);
+ errmsg( "ls: unknown option -%c", cp[-1] );
return;
}
@@ -177,10 +171,9 @@ do_ls(int argc, const char ** argv)
name = *argv++;
endSlash = (*name && (name[strlen(name) - 1] == '/'));
- if (LSTAT(name, &statBuf) < 0)
+ if ( lstat(name, &statBuf) < 0 )
{
- perror(name);
-
+ errmsg( "ls: %s: %s", name, strerror(errno) );
continue;
}
@@ -197,8 +190,7 @@ do_ls(int argc, const char ** argv)
if (dirp == NULL)
{
- perror(name);
-
+ errmsg( "ls: %s: %s", name, strerror(errno) );
continue;
}
@@ -300,10 +292,9 @@ listAllFiles(int flags, int displayWidth)
{
name = list[i];
- if (LSTAT(name, &statBuf) < 0)
+ if ( lstat(name, &statBuf) < 0 )
{
- perror(name);
-
+ errmsg( "ls: %s: %s", name, strerror(errno) );
continue;
}
@@ -529,10 +520,9 @@ addListName(const char * fileName)
newList = realloc(list,
((sizeof(char **)) * (listSize + LISTSIZE)));
- if (newList == NULL)
+ if ( !newList )
{
- fprintf(stderr, "No memory for file name buffer\n");
-
+ errmsg( "ls: file list allocation failure: %s", strerror(errno) );
return FALSE;
}
@@ -545,10 +535,9 @@ addListName(const char * fileName)
*/
list[listUsed] = strdup(fileName);
- if (list[listUsed] == NULL)
+ if ( !list[listUsed] )
{
- fprintf(stderr, "No memory for file name\n");
-
+ errmsg( "ls: file name allocation failure: %s", strerror(errno) );
return FALSE;
}
--- sash/cmd_tar.c
+++ sash/cmd_tar.c
@@ -7,12 +7,12 @@
* This allows creation, extraction, and listing of tar files.
*/
-#include "sash.h"
-
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
-#include <errno.h>
+
+#include "message.h"
+#include "sash.h"
/*
@@ -87,13 +87,13 @@ static ino_t tarInode;
/*
* Local procedures to restore files from a tar file.
*/
-static void readTarFile(int fileCount, const char ** fileTable);
+static void readTarFile(int fileCount, const char *const *fileTable);
static void readData(const char * cp, int count);
static void createPath(const char * name, int mode);
static long getOctal(const char * cp, int len);
static void readHeader(const TarHeader * hp,
- int fileCount, const char ** fileTable);
+ int fileCount, const char *const *fileTable);
/*
@@ -108,19 +108,19 @@ static void saveDirectory(const char * fileName,
const struct stat * statbuf);
static BOOL wantFileName(const char * fileName,
- int fileCount, const char ** fileTable);
+ int fileCount, const char *const *fileTable);
static void writeHeader(const char * fileName,
const struct stat * statbuf);
-static void writeTarFile(int fileCount, const char ** fileTable);
+static void writeTarFile(int fileCount, const char *const *fileTable);
static void writeTarBlock(const char * buf, int len);
static BOOL putOctal(char * cp, int len, long value);
void
-do_tar(int argc, const char ** argv)
+do_tar(int argc, const char *const *argv)
{
const char * options;
@@ -129,8 +129,7 @@ do_tar(int argc, const char ** argv)
if (argc < 2)
{
- fprintf(stderr, "Too few arguments for tar\n");
-
+ errmsg( "tar: too few arguments for tar" );
return;
}
@@ -154,10 +153,9 @@ do_tar(int argc, const char ** argv)
switch (*options)
{
case 'f':
- if (tarName != NULL)
+ if ( !tarName )
{
- fprintf(stderr, "Only one 'f' option allowed\n");
-
+ errmsg( "tar: only one 'f' option allowed" );
return;
}
@@ -183,8 +181,7 @@ do_tar(int argc, const char ** argv)
break;
default:
- fprintf(stderr, "Unknown tar flag '%c'\n", *options);
-
+ errmsg( "tar: unknown flag: %c", *options );
return;
}
}
@@ -194,15 +191,13 @@ do_tar(int argc, const char ** argv)
*/
if (extractFlag + listFlag + createFlag != 1)
{
- fprintf(stderr, "Exactly one of 'c', 'x' or 't' must be specified\n");
-
+ errmsg( "tar: exactly one of 'c', 'x' or 't' must be specified" );
return;
}
- if (tarName == NULL)
+ if ( !tarName )
{
- fprintf(stderr, "The 'f' flag must be specified\n");
-
+ errmsg( "tar: the 'f' flag must be specified" );
return;
}
@@ -222,7 +217,7 @@ do_tar(int argc, const char ** argv)
* If the list is empty than all files are extracted or listed.
*/
static void
-readTarFile(int fileCount, const char ** fileTable)
+readTarFile(int fileCount, const char *const *fileTable)
{
const char * cp;
int cc;
@@ -248,8 +243,7 @@ readTarFile(int fileCount, const char ** fileTable)
if (tarFd < 0)
{
- perror(tarName);
-
+ errmsg( "tar: error opening %s: %s", tarName, strerror(errno) );
return;
}
@@ -271,17 +265,13 @@ readTarFile(int fileCount, const char ** fileTable)
if (inCc < 0)
{
- perror(tarName);
-
+ errmsg( "tar: error reading %s: %s", tarName, strerror(errno) );
goto done;
}
- if (inCc == 0)
+ if ( !inCc )
{
- fprintf(stderr,
- "Unexpected end of file from \"%s\"",
- tarName);
-
+ errmsg( "tar: %s: unexpected end of file", tarName );
goto done;
}
}
@@ -327,7 +317,7 @@ readTarFile(int fileCount, const char ** fileTable)
* Check for an interrupt.
*/
if (intFlag)
- fprintf(stderr, "Interrupted - aborting\n");
+ errmsg( "tar: interrupted" );
done:
@@ -335,7 +325,7 @@ done:
* Close the tar file if needed.
*/
if ((tarFd >= 0) && (close(tarFd) < 0))
- perror(tarName);
+ errmsg( "tar: error closing %s: %s", tarName, strerror(errno) );
/*
* Close the output file if needed.
@@ -353,7 +343,7 @@ done:
* the end of the tar file.
*/
static void
-readHeader(const TarHeader * hp, int fileCount, const char ** fileTable)
+readHeader(const TarHeader * hp, int fileCount, const char *const *fileTable)
{
int mode;
int uid;
@@ -399,7 +389,7 @@ readHeader(const TarHeader * hp, int fileCount, const char ** fileTable)
if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0))
{
if (!badHeader)
- fprintf(stderr, "Bad tar header, skipping\n");
+ errmsg( "tar: bad header, skipping" );
badHeader = TRUE;
@@ -436,10 +426,7 @@ readHeader(const TarHeader * hp, int fileCount, const char ** fileTable)
name++;
if (!warnedRoot)
- {
- fprintf(stderr,
- "Absolute path detected, removing leading slashes\n");
- }
+ errmsg( "tar: absolute path detected, removing leading slashes" );
warnedRoot = TRUE;
}
@@ -499,19 +486,14 @@ readHeader(const TarHeader * hp, int fileCount, const char ** fileTable)
if (hardLink)
{
if (link(hp->linkName, name) < 0)
- perror(name);
-
+ errmsg( "tar: error hardlinking '%s' -> '%s': %s", name, hp->linkName, strerror(errno) );
return;
}
if (softLink)
{
-#ifdef S_ISLNK
if (symlink(hp->linkName, name) < 0)
- perror(name);
-#else
- fprintf(stderr, "Cannot create symbolic links\n");
-#endif
+ errmsg( "tar: error symlinking '%s' -> '%s': %s", name, hp->linkName, strerror(errno) );
return;
}
@@ -541,9 +523,8 @@ readHeader(const TarHeader * hp, int fileCount, const char ** fileTable)
if (outFd < 0)
{
- perror(name);
+ errmsg( "tar: error creating %s: %s", name, strerror(errno) );
skipFileFlag = TRUE;
-
return;
}
@@ -586,7 +567,7 @@ readData(const char * cp, int count)
*/
if (fullWrite(outFd, cp, count) < 0)
{
- perror(outName);
+ errmsg( "tar: error writing %s: %s", outName, strerror(errno) );
(void) close(outFd);
outFd = -1;
skipFileFlag = TRUE;
@@ -601,7 +582,7 @@ readData(const char * cp, int count)
if (dataCc <= 0)
{
if (close(outFd))
- perror(outName);
+ errmsg( "tar: error closing %s: %s", outName, strerror(errno) );
outFd = -1;
}
@@ -612,7 +593,7 @@ readData(const char * cp, int count)
* Write a tar file containing the specified files.
*/
static void
-writeTarFile(int fileCount, const char ** fileTable)
+writeTarFile(int fileCount, const char *const *fileTable)
{
struct stat statbuf;
@@ -623,8 +604,7 @@ writeTarFile(int fileCount, const char ** fileTable)
*/
if (fileCount <= 0)
{
- fprintf(stderr, "No files specified to be saved\n");
-
+ errmsg( "tar: no files specified to be saved" );
return;
}
@@ -635,8 +615,7 @@ writeTarFile(int fileCount, const char ** fileTable)
if (tarFd < 0)
{
- perror(tarName);
-
+ errmsg( "tar: error creating %s: %s", tarName, strerror(errno) );
return;
}
@@ -645,8 +624,7 @@ writeTarFile(int fileCount, const char ** fileTable)
*/
if (fstat(tarFd, &statbuf) < 0)
{
- perror(tarName);
-
+ errmsg( "tar: %s: %s", tarName, strerror(errno) );
goto done;
}
@@ -663,7 +641,7 @@ writeTarFile(int fileCount, const char ** fileTable)
}
if (intFlag)
- fprintf(stderr, "Interrupted - aborting archiving\n");
+ errmsg( "tar: interrupted - archiving aborted");
/*
* Now write an empty block of zeroes to end the archive.
@@ -676,7 +654,7 @@ done:
* Close the tar file and check for errors if it was opened.
*/
if ((tarFd >= 0) && (close(tarFd) < 0))
- perror(tarName);
+ errmsg( "tar: error closing %s: %s", tarName, strerror(errno) );
}
@@ -702,8 +680,7 @@ saveFile(const char * fileName, BOOL seeLinks)
*/
if (strlen(fileName) >= TAR_NAME_SIZE)
{
- fprintf(stderr, "%s: File name is too long\n", fileName);
-
+ errmsg( "tar: %s: file name is too long", fileName );
return;
}
@@ -719,8 +696,7 @@ saveFile(const char * fileName, BOOL seeLinks)
if (status < 0)
{
- perror(fileName);
-
+ errmsg( "tar: %s: %s", fileName, strerror(errno) );
return;
}
@@ -729,7 +705,7 @@ saveFile(const char * fileName, BOOL seeLinks)
*/
if ((statbuf.st_dev == tarDev) && (statbuf.st_ino == tarInode))
{
- fprintf(stderr, "Skipping saving of archive file itself\n");
+ errmsg( "tar: skipped saving of archive file itself" );
return;
}
@@ -756,7 +732,7 @@ saveFile(const char * fileName, BOOL seeLinks)
/*
* The file is a strange type of file, ignore it.
*/
- fprintf(stderr, "%s: not a directory or regular file\n", fileName);
+ errmsg( "tar: %s: not a directory or regular file", fileName );
}
@@ -780,8 +756,7 @@ saveRegularFile(const char * fileName, const struct stat * statbuf)
if (fileFd < 0)
{
- perror(fileName);
-
+ errmsg( "tar: error opening %s: %s", fileName, strerror(errno) );
return;
}
@@ -823,7 +798,7 @@ saveRegularFile(const char * fileName, const struct stat * statbuf)
if (cc < 0)
{
- perror(fileName);
+ errmsg( "tar: error reading %s: %s", fileName, strerror(errno) );
(void) close(fileFd);
errorFlag = TRUE;
@@ -837,10 +812,7 @@ saveRegularFile(const char * fileName, const struct stat * statbuf)
*/
if (cc < dataCount)
{
- fprintf(stderr,
- "%s: Short read - zero filling",
- fileName);
-
+ errmsg( "tar: %s: unexpected end of file - zero filling", fileName );
sawEof = TRUE;
}
}
@@ -863,7 +835,7 @@ saveRegularFile(const char * fileName, const struct stat * statbuf)
* Close the file.
*/
if (close(fileFd) < 0)
- fprintf(stderr, "%s: close: %s\n", fileName, strerror(errno));
+ errmsg( "tar: error closing %s: %s", fileName, strerror(errno) );
}
@@ -895,11 +867,9 @@ saveDirectory(const char * dirName, const struct stat * statbuf)
*/
dir = opendir(dirName);
- if (dir == NULL)
+ if ( !dir )
{
- fprintf(stderr, "Cannot read directory \"%s\": %s\n",
- dirName, strerror(errno));
-
+ errmsg( "tar: cannot read directory \"%s\": %s\n", dirName, strerror(errno) );
return;
}
@@ -1029,10 +999,8 @@ writeTarBlock(const char * buf, int len)
*/
if ((completeLength > 0) && !fullWrite(tarFd, buf, completeLength))
{
- perror(tarName);
-
+ errmsg( "tar: error writing %s: %s", tarName, strerror(errno) );
errorFlag = TRUE;
-
return;
}
@@ -1054,8 +1022,7 @@ writeTarBlock(const char * buf, int len)
*/
if (!fullWrite(tarFd, fullBlock, TAR_BLOCK_SIZE))
{
- perror(tarName);
-
+ errmsg( "tar: error writing %s: %s", tarName, strerror(errno) );
errorFlag = TRUE;
}
}
@@ -1191,7 +1158,7 @@ putOctal(char * cp, int len, long value)
* Returns TRUE if the file is selected.
*/
static BOOL
-wantFileName(const char * fileName, int fileCount, const char ** fileTable)
+wantFileName(const char * fileName, int fileCount, const char *const *fileTable)
{
const char * pathName;
int fileLength;
--- sash/cmds.c
+++ sash/cmds.c
@@ -6,6 +6,7 @@
* Most simple built-in commands are here.
*/
+#include "message.h"
#include "sash.h"
#include <sys/types.h>
@@ -15,12 +16,14 @@
#include <pwd.h>
#include <grp.h>
#include <utime.h>
-#include <errno.h>
-#include <linux/fs.h>
+#ifndef dev_t
+#define dev_t dev_t
+#endif
+#include <linux/loop.h>
void
-do_echo(int argc, const char ** argv)
+do_echo(int argc, const char *const *argv)
{
BOOL first;
@@ -40,14 +43,13 @@ do_echo(int argc, const char ** argv)
void
-do_pwd(int argc, const char ** argv)
+do_pwd(int argc, const char *const *argv)
{
char buf[PATH_LEN];
- if (getcwd(buf, PATH_LEN) == NULL)
+ if ( !getcwd(buf, PATH_LEN) )
{
- fprintf(stderr, "Cannot get current directory\n");
-
+ errmsg( "pwd: cannot get current directory" );
return;
}
@@ -56,7 +58,7 @@ do_pwd(int argc, const char ** argv)
void
-do_cd(int argc, const char ** argv)
+do_cd(int argc, const char *const *argv)
{
const char * path;
@@ -66,41 +68,36 @@ do_cd(int argc, const char ** argv)
{
path = getenv("HOME");
- if (path == NULL)
+ if ( !path )
{
- fprintf(stderr, "No HOME environment variable\n");
-
+ errmsg( "cd: HOME not set" );
return;
}
}
if (chdir(path) < 0)
- perror(path);
+ errmsg( "cd: chdir: %s: %s", path, strerror(errno) );
}
void
-do_mkdir(int argc, const char ** argv)
+do_mkdir(int argc, const char *const *argv)
{
while (argc-- > 1)
{
if (mkdir(argv[1], 0777) < 0)
- perror(argv[1]);
+ errmsg( "mkdir: %s: %s", argv[1], strerror(errno) );
- argv++;
+ ++argv;
}
}
void
-do_mknod(int argc, const char ** argv)
+do_mknod(int argc, const char *const *argv)
{
- const char * cp;
- int mode;
- int major;
- int minor;
-
- mode = 0666;
+ int mode = 0666, major = 0, minor = 0;
+ const char *cp = argv[3];
if (strcmp(argv[2], "b") == 0)
mode |= S_IFBLK;
@@ -108,25 +105,19 @@ do_mknod(int argc, const char ** argv)
mode |= S_IFCHR;
else
{
- fprintf(stderr, "Bad device type\n");
-
+ errmsg( "mknod: bad device type: %s", argv[2] );
return;
}
- major = 0;
- cp = argv[3];
-
while (isDecimal(*cp))
major = major * 10 + *cp++ - '0';
if (*cp || (major < 0) || (major > 255))
{
- fprintf(stderr, "Bad major number\n");
-
+ errmsg( "mknod: bad major number: %d", major );
return;
}
- minor = 0;
cp = argv[4];
while (isDecimal(*cp))
@@ -134,51 +125,50 @@ do_mknod(int argc, const char ** argv)
if (*cp || (minor < 0) || (minor > 255))
{
- fprintf(stderr, "Bad minor number\n");
-
+ errmsg( "mknod: bad minor number: %d", minor );
return;
}
if (mknod(argv[1], mode, major * 256 + minor) < 0)
- perror(argv[1]);
+ errmsg( "mknod: %s: %s", argv[1], strerror(errno) );
}
void
-do_rmdir(int argc, const char ** argv)
+do_rmdir(int argc, const char *const *argv)
{
while (argc-- > 1)
{
if (rmdir(argv[1]) < 0)
- perror(argv[1]);
+ errmsg( "rmdir: %s: %s", argv[1], strerror(errno) );
- argv++;
+ ++argv;
}
}
void
-do_sync(int argc, const char ** argv)
+do_sync(int argc, const char *const *argv)
{
sync();
}
void
-do_rm(int argc, const char ** argv)
+do_rm(int argc, const char *const *argv)
{
while (argc-- > 1)
{
if (unlink(argv[1]) < 0)
- perror(argv[1]);
+ errmsg( "rm: %s: %s", argv[1], strerror(errno) );
- argv++;
+ ++argv;
}
}
void
-do_chmod(int argc, const char ** argv)
+do_chmod(int argc, const char *const *argv)
{
const char * cp;
int mode;
@@ -191,26 +181,25 @@ do_chmod(int argc, const char ** argv)
if (*cp)
{
- fprintf(stderr, "Mode must be octal\n");
-
+ errmsg( "chmod: mode must be octal" );
return;
}
- argc--;
- argv++;
+ --argc;
+ ++argv;
while (argc-- > 1)
{
if (chmod(argv[1], mode) < 0)
- perror(argv[1]);
+ errmsg( "chmod: %s: %s", argv[1], strerror(errno) );
- argv++;
+ ++argv;
}
}
void
-do_chown(int argc, const char ** argv)
+do_chown(int argc, const char *const *argv)
{
const char * cp;
int uid;
@@ -228,41 +217,39 @@ do_chown(int argc, const char ** argv)
if (*cp)
{
- fprintf(stderr, "Bad uid value\n");
-
+ errmsg( "chown: bad uid value: %s", argv[1] );
return;
}
} else {
pwd = getpwnam(cp);
- if (pwd == NULL)
+ if ( !pwd )
{
- fprintf(stderr, "Unknown user name\n");
-
+ errmsg( "chown: unknown user name: %s", cp );
return;
}
uid = pwd->pw_uid;
}
- argc--;
- argv++;
+ --argc;
+ ++argv;
while (argc-- > 1)
{
- argv++;
+ ++argv;
if ((stat(*argv, &statBuf) < 0) ||
(chown(*argv, uid, statBuf.st_gid) < 0))
{
- perror(*argv);
+ errmsg( "chown: %s: %s", *argv, strerror(errno) );
}
}
}
void
-do_chgrp(int argc, const char ** argv)
+do_chgrp(int argc, const char *const *argv)
{
const char * cp;
int gid;
@@ -280,8 +267,7 @@ do_chgrp(int argc, const char ** argv)
if (*cp)
{
- fprintf(stderr, "Bad gid value\n");
-
+ errmsg( "chgrp: bad gid value: %s", argv[1] );
return;
}
}
@@ -289,34 +275,33 @@ do_chgrp(int argc, const char ** argv)
{
grp = getgrnam(cp);
- if (grp == NULL)
+ if ( !grp )
{
- fprintf(stderr, "Unknown group name\n");
-
+ errmsg( "chgrp: unknown group name: %s", cp );
return;
}
gid = grp->gr_gid;
}
- argc--;
- argv++;
+ --argc;
+ ++argv;
while (argc-- > 1)
{
- argv++;
+ ++argv;
if ((stat(*argv, &statBuf) < 0) ||
(chown(*argv, statBuf.st_uid, gid) < 0))
{
- perror(*argv);
+ errmsg( "chgrp: %s: %s", *argv, strerror(errno) );
}
}
}
void
-do_touch(int argc, const char ** argv)
+do_touch(int argc, const char *const *argv)
{
const char * name;
int fd;
@@ -334,32 +319,26 @@ do_touch(int argc, const char ** argv)
if (fd >= 0)
{
close(fd);
-
continue;
}
if (utime(name, &now) < 0)
- perror(name);
+ errmsg( "touch: %s: %s", name, strerror(errno) );
}
}
void
-do_mv(int argc, const char ** argv)
+do_mv(int argc, const char *const *argv)
{
- const char * srcName;
- const char * destName;
- const char * lastArg;
- BOOL dirFlag;
-
- lastArg = argv[argc - 1];
-
- dirFlag = isDirectory(lastArg);
+ const char *srcName;
+ const char *destName;
+ const char *lastArg = argv[argc - 1];
+ BOOL dirFlag = isDirectory(lastArg);
if ((argc > 3) && !dirFlag)
{
- fprintf(stderr, "%s: not a directory\n", lastArg);
-
+ errmsg( "mv: %s: when moving multiple files, last argument must be a directory", lastArg );
return;
}
@@ -369,8 +348,7 @@ do_mv(int argc, const char ** argv)
if (access(srcName, 0) < 0)
{
- perror(srcName);
-
+ errmsg( "mv: %s: %s", srcName, strerror(errno) );
continue;
}
@@ -384,8 +362,7 @@ do_mv(int argc, const char ** argv)
if (errno != EXDEV)
{
- perror(destName);
-
+ errmsg( "mv: %s: %s", destName, strerror(errno) );
continue;
}
@@ -393,65 +370,45 @@ do_mv(int argc, const char ** argv)
continue;
if (unlink(srcName) < 0)
- perror(srcName);
+ errmsg( "mv: error unlinking %s: %s", srcName, strerror(errno) );
}
}
void
-do_ln(int argc, const char ** argv)
+do_ln(int argc, const char *const *argv)
{
- const char * srcName;
- const char * destName;
- const char * lastArg;
- BOOL dirFlag;
+ const char * srcName;
+ const char * destName;
+ const char * lastArg = argv[argc - 1];
+ BOOL dirFlag = isDirectory(lastArg), sym = FALSE;
if (argv[1][0] == '-')
{
if (strcmp(argv[1], "-s"))
{
- fprintf(stderr, "Unknown option\n");
-
- return;
- }
-
- if (argc != 4)
- {
- fprintf(stderr, "Wrong number of arguments for symbolic link\n");
-
+ errmsg( "ln: unknown option: %s", argv[1] );
return;
}
-#ifdef S_ISLNK
- if (symlink(argv[2], argv[3]) < 0)
- perror(argv[3]);
-#else
- fprintf(stderr, "Symbolic links are not allowed\n");
-#endif
- return;
+ sym = TRUE;
+ --argc;
+ ++argv;
}
- /*
- * Here for normal hard links.
- */
- lastArg = argv[argc - 1];
- dirFlag = isDirectory(lastArg);
-
if ((argc > 3) && !dirFlag)
{
- fprintf(stderr, "%s: not a directory\n", lastArg);
-
+ errmsg( "ln: %s: when making multiple links, last argument must be a directory", lastArg );
return;
}
- while (argc-- > 2)
+ while (--argc > 1)
{
srcName = *(++argv);
- if (access(srcName, 0) < 0)
+ if ( !sym && access(srcName, 0) < 0)
{
- perror(srcName);
-
+ errmsg( "ln: %s: %s", srcName, strerror(errno) );
continue;
}
@@ -460,18 +417,15 @@ do_ln(int argc, const char ** argv)
if (dirFlag)
destName = buildName(destName, srcName);
- if (link(srcName, destName) < 0)
- {
- perror(destName);
-
- continue;
- }
+ if ( (sym ? symlink(srcName, destName) : link(srcName, destName)) < 0 )
+ errmsg( "%s: %s -> %s: %s", (sym ? "symlink" : "ln"),
+ srcName, destName, strerror(errno) );
}
}
void
-do_cp(int argc, const char ** argv)
+do_cp(int argc, const char *const *argv)
{
const char * srcName;
const char * destName;
@@ -484,8 +438,7 @@ do_cp(int argc, const char ** argv)
if ((argc > 3) && !dirFlag)
{
- fprintf(stderr, "%s: not a directory\n", lastArg);
-
+ errmsg( "cp: %s: when copying multiple files, last argument must be a directory", lastArg );
return;
}
@@ -503,20 +456,20 @@ do_cp(int argc, const char ** argv)
void
-do_mount(int argc, const char ** argv)
+do_mount(int argc, const char *const *argv)
{
const char * str;
const char * type;
int flags;
- argc--;
- argv++;
+ --argc;
+ ++argv;
type = "ext2";
flags = MS_MGC_VAL;
while ((argc > 0) && (**argv == '-'))
{
- argc--;
+ --argc;
str = *argv++;
while (*++str) switch (*str)
@@ -524,13 +477,12 @@ do_mount(int argc, const char ** argv)
case 't':
if ((argc <= 0) || (**argv == '-'))
{
- fprintf(stderr, "Missing file system type\n");
-
+ errmsg( "mount: missing file system type" );
return;
}
type = *argv++;
- argc--;
+ --argc;
break;
case 'r':
@@ -542,34 +494,33 @@ do_mount(int argc, const char ** argv)
break;
default:
- fprintf(stderr, "Unknown option\n");
-
+ errmsg( "mount: unknown option: %s", str );
return;
}
}
if (argc != 2)
{
- fprintf(stderr, "Wrong number of arguments for mount\n");
+ errmsg( "mount: wrong number of arguments for mount" );
return;
}
if (mount(argv[0], argv[1], type, flags, 0) < 0)
- perror("mount failed");
+ errmsg( "mount: %s", strerror(errno) );
}
void
-do_umount(int argc, const char ** argv)
+do_umount(int argc, const char *const *argv)
{
if (umount(argv[1]) < 0)
- perror(argv[1]);
+ errmsg( "umount: %s: %s", argv[1], strerror(errno) );
}
void
-do_cmp(int argc, const char ** argv)
+do_cmp(int argc, const char *const *argv)
{
int fd1;
int fd2;
@@ -585,30 +536,26 @@ do_cmp(int argc, const char ** argv)
if (stat(argv[1], &statBuf1) < 0)
{
- perror(argv[1]);
-
+ errmsg( "cmp: %s: %s", argv[1], strerror(errno) );
return;
}
if (stat(argv[2], &statBuf2) < 0)
{
- perror(argv[2]);
-
+ errmsg( "cmp: %s: %s", argv[2], strerror(errno) );
return;
}
if ((statBuf1.st_dev == statBuf2.st_dev) &&
(statBuf1.st_ino == statBuf2.st_ino))
{
- printf("Files are links to each other\n");
-
+ puts( "Files are links to each other" );
return;
}
if (statBuf1.st_size != statBuf2.st_size)
{
- printf("Files are different sizes\n");
-
+ puts( "Files are different sizes" );
return;
}
@@ -616,8 +563,7 @@ do_cmp(int argc, const char ** argv)
if (fd1 < 0)
{
- perror(argv[1]);
-
+ errmsg( "cmp: error opening %s: %s", argv[1], strerror(errno) );
return;
}
@@ -625,15 +571,14 @@ do_cmp(int argc, const char ** argv)
if (fd2 < 0)
{
- perror(argv[2]);
+ errmsg( "cmp: error opening %s: %s", argv[2], strerror(errno) );
close(fd1);
-
return;
}
pos = 0;
- while (TRUE)
+ for(;;)
{
if (intFlag)
goto closefiles;
@@ -642,7 +587,7 @@ do_cmp(int argc, const char ** argv)
if (cc1 < 0)
{
- perror(argv[1]);
+ errmsg( "cmp: error reading %s: %s", argv[1], strerror(errno) );
goto closefiles;
}
@@ -650,25 +595,25 @@ do_cmp(int argc, const char ** argv)
if (cc2 < 0)
{
- perror(argv[2]);
+ errmsg( "cmp: error reading %s: %s", argv[2], strerror(errno) );
goto closefiles;
}
- if ((cc1 == 0) && (cc2 == 0))
+ if ( !cc1 && !cc2 )
{
- printf("Files are identical\n");
+ puts( "Files are identical" );
goto closefiles;
}
if (cc1 < cc2)
{
- printf("First file is shorter than second\n");
+ puts( "First file is shorter than second" );
goto closefiles;
}
if (cc1 > cc2)
{
- printf("Second file is shorter than first\n");
+ puts( "Second file is shorter than first" );
goto closefiles;
}
@@ -685,7 +630,7 @@ do_cmp(int argc, const char ** argv)
while (*bp1++ == *bp2++)
pos++;
- printf("Files differ at byte position %ld\n", pos);
+ printf( "Files differ at byte position %ld\n", pos );
goto closefiles;
}
@@ -697,7 +642,7 @@ closefiles:
void
-do_more(int argc, const char ** argv)
+do_more(int argc, const char *const *argv)
{
FILE * fp;
const char * name;
@@ -739,11 +684,9 @@ do_more(int argc, const char ** argv)
name = *(++argv);
fp = fopen(name, "r");
-
- if (fp == NULL)
+ if ( !fp )
{
- perror(name);
-
+ errmsg( "more: error opening %s: %s", name, strerror(errno) );
return;
}
@@ -833,7 +776,7 @@ do_more(int argc, const char ** argv)
void
-do_sum(int argc, const char ** argv)
+do_sum(int argc, const char *const *argv)
{
const char * name;
int fd;
@@ -843,8 +786,8 @@ do_sum(int argc, const char ** argv)
unsigned long checksum;
char buf[BUF_SIZE];
- argc--;
- argv++;
+ --argc;
+ ++argv;
while (argc-- > 0)
{
@@ -854,8 +797,7 @@ do_sum(int argc, const char ** argv)
if (fd < 0)
{
- perror(name);
-
+ errmsg( "sum: error opening %s: %s", name, strerror(errno) );
continue;
}
@@ -878,8 +820,7 @@ do_sum(int argc, const char ** argv)
if (cc < 0)
{
- perror(name);
-
+ errmsg( "sum: error reading %s: %s", name, strerror(errno) );
(void) close(fd);
continue;
@@ -893,58 +834,34 @@ do_sum(int argc, const char ** argv)
void
-do_exit(int argc, const char ** argv)
+do_exit(int argc, const char *const *argv)
{
- if (getpid() == 1)
+ if ( getpid() == 1 )
{
- fprintf(stderr, "You are the INIT process!\n");
-
+ errmsg( "exit: you are the INIT process!" );
return;
}
- exit(0);
+ exit( argc ? atoi( argv[1] ) : 0 );
}
void
-do_setenv(int argc, const char ** argv)
+do_setenv(int argc, const char *const *argv)
{
- const char * name;
- const char * value;
- char * str;
-
- name = argv[1];
- value = argv[2];
-
- /*
- * The value given to putenv must remain around, so we must malloc it.
- * Note: memory is not reclaimed if the same variable is redefined.
- */
- str = malloc(strlen(name) + strlen(value) + 2);
-
- if (str == NULL)
- {
- fprintf(stderr, "Cannot allocate memory\n");
-
- return;
- }
-
- strcpy(str, name);
- strcat(str, "=");
- strcat(str, value);
-
- putenv(str);
+ if ( setenv( argv[1], argv[2], 1 ) < 0 )
+ errmsg( "setenv: %s", strerror(errno) );
}
void
-do_printenv(int argc, const char ** argv)
+do_printenv(int argc, const char *const *argv)
{
- const char ** env;
+ const char *const * env;
extern char ** environ;
int len;
- env = (const char **) environ;
+ env = (const char *const *) environ;
if (argc == 1)
{
@@ -971,7 +888,7 @@ do_printenv(int argc, const char ** argv)
void
-do_umask(int argc, const char ** argv)
+do_umask(int argc, const char *const *argv)
{
const char * cp;
int mask;
@@ -993,63 +910,88 @@ do_umask(int argc, const char ** argv)
if (*cp || (mask & ~0777))
{
- fprintf(stderr, "Bad umask value\n");
-
+ errmsg( "umask: bad value: %o", mask );
return;
}
umask(mask);
}
+typedef struct
+{
+ int no;
+ const char *name;
+} sig_desc_t;
+
+static sig_desc_t sig_desc[] = {
+ { SIGHUP, "HUP" },
+ { SIGINT, "INT" },
+ { SIGQUIT, "QUIT" },
+ { SIGILL, "ILL" },
+ { SIGTRAP, "TRAP" },
+ { SIGABRT, "ABRT" },
+ { SIGIOT, "IOT" },
+ { SIGBUS, "BUS" },
+ { SIGFPE, "FPE" },
+ { SIGKILL, "KILL" },
+ { SIGUSR1, "USR1" },
+ { SIGSEGV, "SEGV" },
+ { SIGUSR2, "USR2" },
+ { SIGPIPE, "PIPE" },
+ { SIGALRM, "ALRM" },
+ { SIGTERM, "TERM" },
+ { SIGSTKFLT, "STKFLT" },
+ { SIGCHLD, "CHLD" },
+ { SIGCONT, "CONT" },
+ { SIGSTOP, "STOP" },
+ { SIGTSTP, "TSTP" },
+ { SIGTTIN, "TTIN" },
+ { SIGTTOU, "TTOU" },
+ { SIGURG, "URG" },
+ { SIGXCPU, "XCPU" },
+ { SIGXFSZ, "XFSZ" },
+ { SIGVTALRM, "VTALRM" },
+ { SIGPROF, "PROF" },
+ { SIGWINCH, "WINCH" },
+ { SIGIO, "IO" },
+ { SIGPOLL, "POLL" },
+ { SIGPWR, "PWR" }
+};
void
-do_kill(int argc, const char ** argv)
+do_kill(int argc, const char *const *argv)
{
const char * cp;
- int sig;
- int pid;
+ int sig = SIGTERM, pid;
- sig = SIGTERM;
-
- if (argv[1][0] == '-')
+ if ( *argv[1] == '-' )
{
+ unsigned i = 0;
+ sig = 0;
cp = &argv[1][1];
-
- if (strcmp(cp, "HUP") == 0)
- sig = SIGHUP;
- else if (strcmp(cp, "INT") == 0)
- sig = SIGINT;
- else if (strcmp(cp, "QUIT") == 0)
- sig = SIGQUIT;
- else if (strcmp(cp, "KILL") == 0)
- sig = SIGKILL;
- else if (strcmp(cp, "STOP") == 0)
- sig = SIGSTOP;
- else if (strcmp(cp, "CONT") == 0)
- sig = SIGCONT;
- else if (strcmp(cp, "USR1") == 0)
- sig = SIGUSR1;
- else if (strcmp(cp, "USR2") == 0)
- sig = SIGUSR2;
- else if (strcmp(cp, "TERM") == 0)
- sig = SIGTERM;
- else
+ for ( ; i < sizeof(sig_desc) / sizeof(*sig_desc); ++i )
{
- sig = 0;
+ if ( !strcmp( cp, sig_desc[i].name ) )
+ {
+ sig = sig_desc[i].no;
+ break;
+ }
+ }
+ if ( !sig )
+ {
while (isDecimal(*cp))
sig = sig * 10 + *cp++ - '0';
- if (*cp)
+ if ( sig <= 0 || sig >= SIGUNUSED || *cp )
{
- fprintf(stderr, "Unknown signal\n");
-
+ errmsg( "kill: unknown signal: %s", &argv[1][1] );
return;
}
}
- argc--;
- argv++;
+ --argc;
+ ++argv;
}
while (argc-- > 1)
@@ -1062,19 +1004,18 @@ do_kill(int argc, const char ** argv)
if (*cp)
{
- fprintf(stderr, "Non-numeric pid\n");
-
+ errmsg( "kill: non-numeric pid: %s", *argv );
return;
}
if (kill(pid, sig) < 0)
- perror(*argv);
+ errmsg( "kill: %d: %s", pid, strerror(errno) );
}
}
void
-do_where(int argc, const char ** argv)
+do_where(int argc, const char *const *argv)
{
const char * program;
const char * dirName;
@@ -1086,10 +1027,9 @@ do_where(int argc, const char ** argv)
found = FALSE;
program = argv[1];
- if (strchr(program, '/') != NULL)
+ if ( strchr(program, '/') )
{
- fprintf(stderr, "Program name cannot include a path\n");
-
+ errmsg( "where: program name cannot include a path" );
return;
}
@@ -1098,10 +1038,9 @@ do_where(int argc, const char ** argv)
fullPath = getChunk(strlen(path) + strlen(program) + 2);
path = chunkstrdup(path);
- if ((path == NULL) || (fullPath == NULL))
+ if ( !path || !fullPath )
{
- fprintf(stderr, "Memory allocation failed\n");
-
+ errmsg( "where: memory allocation failure: %s", strerror(errno) );
return;
}
@@ -1155,4 +1094,64 @@ do_where(int argc, const char ** argv)
printf("Program \"%s\" not found in PATH\n", program);
}
+void do_losetup(int argc, const char *const *argv)
+{
+ int loopfd, targfd;
+ struct loop_info loopInfo;
+
+ if ( !strcmp( argv[1], "-d" ) )
+ {
+ loopfd = open( argv[2], O_RDONLY );
+ if ( loopfd < 0 )
+ {
+ errmsg( "losetup: error opening %s: %s", argv[2], strerror(errno) );
+ return;
+ }
+
+ if ( ioctl(loopfd, LOOP_CLR_FD, 0) < 0 )
+ {
+ errmsg( "losetup: error unassociating device: %s", strerror(errno) );
+ close( loopfd );
+ return;
+ }
+
+ close( loopfd );
+ return;
+ }
+
+ loopfd = open( argv[1], O_RDONLY );
+ if ( loopfd < 0 )
+ {
+ errmsg( "losetup: error opening %s: %s", argv[1], strerror(errno) );
+ return;
+ }
+
+ targfd = open( argv[2], O_RDONLY );
+ if ( targfd < 0 )
+ {
+ errmsg( "losetup: error opening %s: %s", argv[2], strerror(errno) );
+ close( loopfd );
+ return;
+ }
+
+ if ( ioctl(loopfd, LOOP_SET_FD, targfd) < 0 )
+ {
+ errmsg( "losetup: error setting up loopback device: %s", strerror(errno) );
+ close( loopfd );
+ close( targfd );
+ return;
+ }
+
+ memset(&loopInfo, 0, sizeof(loopInfo));
+ strcpy(loopInfo.lo_name, argv[2]);
+
+ if ( ioctl(loopfd, LOOP_SET_STATUS, &loopInfo) < 0 )
+ errmsg( "losetup: error setting up loopback device: %s", strerror(errno) );
+
+ close( loopfd );
+ close( targfd );
+
+ return;
+}
+
/* END CODE */
--- /dev/null
+++ sash/getline.c
@@ -0,0 +1,75 @@
+#include <errno.h>
+#include "getline.h"
+#include "sash.h"
+
+int rl_disable;
+
+static void showPrompt( void )
+{
+ const char *cp = prompt ?: "$ ";
+ write( STDOUT_FILENO, cp, strlen(cp) );
+}
+
+static char *get_line_norl( FILE *fp )
+{
+ static char buf[CMD_LEN];
+ int is_tty = isatty(fileno(fp));
+ char *p;
+
+ if ( is_tty )
+ showPrompt();
+
+ for(;;)
+ {
+ if ( fgets( buf, CMD_LEN - 1, fp ) )
+ break;
+
+ if ( ferror(fp) && (EINTR == errno) )
+ {
+ clearerr( fp );
+ continue;
+ }
+
+ return 0;
+ }
+
+ for ( p = buf + strlen(buf) - 1; p >= buf; --p )
+ if ( !isspace( *p ) )
+ break;
+
+ p[1] = '\0';
+
+ return buf;
+}
+
+#ifdef WITH_READLINE
+#include <readline/readline.h>
+#include <readline/history.h>
+
+static char *get_line_rl( FILE *fp )
+{
+ static char *input;
+
+ if ( input )
+ free( input );
+
+ intCrlf = FALSE;
+ input = readline( prompt ?: "$ " );
+ intCrlf = TRUE;
+
+ if ( input && *input )
+ add_history( input );
+
+ return input;
+}
+#endif /* WITH_READLINE */
+
+char *get_line( FILE *fp )
+{
+#ifdef WITH_READLINE
+ if ( !rl_disable && isatty(fileno(fp)) )
+ return get_line_rl( fp );
+ else
+#endif /* WITH_READLINE */
+ return get_line_norl( fp );
+}
--- /dev/null
+++ sash/getline.h
@@ -0,0 +1,12 @@
+#ifndef __GETLINE_H__
+#define __GETLINE_H__
+
+#include <stdio.h>
+
+extern int intCrlf;
+extern int rl_disable;
+extern char *prompt;
+
+extern char *get_line( FILE *fp );
+
+#endif /* __GETLINE_H__ */
--- /dev/null
+++ sash/message.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "message.h"
+
+extern const char *__progname;
+
+static void print_message( const char *fmt, va_list args )
+{
+ fprintf( stderr, "%s: ", __progname );
+ vfprintf( stderr, fmt, args );
+ fputs( "\r\n", stderr );
+ fflush( stderr );
+}
+
+void errmsg( const char *fmt, ... )
+{
+ va_list args;
+
+ va_start( args, fmt );
+ print_message( fmt, args );
+ va_end( args );
+}
+
+void fatal( const char *fmt, ... )
+{
+ va_list args;
+
+ va_start( args, fmt );
+ print_message( fmt, args );
+ va_end( args );
+ exit( 1 );
+}
--- /dev/null
+++ sash/message.h
@@ -0,0 +1,7 @@
+#ifndef __MESSAGE_H__
+#define __MESSAGE_H__
+
+void errmsg( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2)));
+void fatal( const char *fmt, ... ) __attribute__ ((noreturn)) __attribute__ ((format (printf, 1, 2)));
+
+#endif /* __MESSAGE_H__ */
--- sash/sash.1
+++ sash/sash.1
@@ -2,7 +2,7 @@
.SH NAME
sash \- stand-alone shell with built-in commands
.SH SYNOPSYS
-.B sash [-c command] [-p prompt] [-q] [-a]
+.B sash [-c command] [-p prompt] [-q] [-a] [script]
.SH DESCRIPTION
The
.B sash
@@ -24,9 +24,9 @@ These built-in commands are:
.nf
-ar, -chattr, -chgrp, -chmod, -chown, -cmp, -cp,
-dd, -echo, -ed, -grep, -file, -find, -gunzip,
- -gzip, -kill, -ln, -ls, -lsattr, -mkdir, -mknod,
- -more, -mount, -mv, -printenv, -pwd, -rm, -rmdir,
- -sum, -sync, -tar, -touch, -umount, -where
+ -gzip, -kill, -losetup, -ln, -ls, -lsattr, -mkdir,
+ -mknod, -more, -mount, -mv, -printenv, -pwd, -rm,
+ -rmdir, -sum, -sync, -tar, -touch, -umount, -where
.fi
.PP
These commands are generally similar to the standard programs with similar
@@ -303,6 +303,12 @@ is a numeric value, or one of the special values HUP, INT,
QUIT, KILL, TERM, STOP, CONT, USR1 or USR2.
If no signal is specified then SIGTERM is used.
.TP
+.B -losetup [-d] loopDev [file]
+Associates loopback devices with files on the system. If -d is not given,
+the loopback device \fBloopDev\fR is associated with \fBfile\fR. If -d is
+given, \fBloopDev\fR is unassociated with the file it's currently configured
+for.
+.TP
.B -ln [-s] srcName ... destName
Links one or more files from the
.I srcName
@@ -455,20 +461,36 @@ then the reason is also printed.
.SH OPTIONS
There are several command line options to
.BR sash .
-The -c option executes the next argument as a command (including embedded
+.TP
+.B -c
+Executes the next argument as a command (including embedded
spaces to separate the arguments of the command), and then exits.
-.PP
-The -p option takes the next argument as the prompt string to be used
+.TP
+.B -p
+Takes the next argument as the prompt string to be used
when prompting for commands.
-.PP
-The -q option makes
+.TP
+.B -q
+Makes
.B sash
quiet, which simply means that it doesn't print its introduction line
when it starts.
-.PP
-The -a option creates aliases for the built-in commands so
+.TP
+.B -a
+Creates aliases for the built-in commands so
that they replace the corresponding standard commands.
This is the same result as if the 'aliasall' command was used.
+.TP
+.B -e
+Disables command editing and history support, if it was compiled into the
+.B sash
+executable. Otherwise, does nothing.
+.PP
+A file name may be provided as the last argument to sash, in which case
+sash's standard input is read from that file. This allows #! scripts
+to use sash as their script interpretor. Be aware that sash does not provide
+most normal bourne-shell programming features, however.
+
.SH SYSTEM RECOVERY
This section contains some useful information about using
.B sash
--- sash/sash.c
+++ sash/sash.c
@@ -10,8 +10,9 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
-#include <errno.h>
+#include "getline.h"
+#include "message.h"
#include "sash.h"
@@ -31,7 +32,7 @@ static const char * const version = "3.4";
typedef struct
{
const char * name;
- void (*func)(int argc, const char ** argv);
+ void (*func)(int argc, const char *const *argv);
int minArgs;
int maxArgs;
const char * description;
@@ -132,9 +133,9 @@ static const CommandEntry commandEntryTable[] =
},
{
- "exit", do_exit, 1, 1,
+ "exit", do_exit, 1, 2,
"Exit from sash",
- ""
+ "[exitcode]"
},
{
@@ -182,6 +183,12 @@ static const CommandEntry commandEntryTable[] =
},
{
+ "-losetup", do_losetup, 3, 3,
+ "Associate a loopback device with a file",
+ "[-d] device\n -losetup device filename"
+ },
+
+ {
"-ln", do_ln, 3, INFINITE_ARGS,
"Link one fileName to another",
"[-s] srcName ... destName"
@@ -351,25 +358,21 @@ typedef struct
static Alias * aliasTable;
static int aliasCount;
-static FILE * sourcefiles[MAX_SOURCE];
-static int sourceCount;
-
-static BOOL intCrlf = TRUE;
-static char * prompt;
+int intCrlf = TRUE;
+char *prompt;
/*
* Local procedures.
*/
-static void catchInt(int);
-static void catchQuit(int);
-static void readFile(const char * name);
+static void catchInterrupt(int);
+static int readFile(const char * name);
static void command(const char * cmd);
static BOOL tryBuiltIn(const char * cmd);
static void runCmd(const char * cmd);
-static void childProcess(const char * cmd);
-static void showPrompt(void);
-static void usage(void);
+static void childProcess(const char * cmd) __attribute__ ((noreturn));
+static void print_version( FILE *fp );
+static void usage(void) __attribute__ ((noreturn));
static Alias * findAlias(const char * name);
@@ -378,143 +381,128 @@ static Alias * findAlias(const char * name);
*/
BOOL intFlag;
-
-int
-main(int argc, const char ** argv)
+int main( int argc, char *const argv[] )
{
- const char * cp;
- const char * singleCommand;
- BOOL quietFlag;
- BOOL aliasFlag;
- char buf[PATH_LEN];
-
- singleCommand = NULL;
- quietFlag = FALSE;
- aliasFlag = FALSE;
-
- /*
- * Look for options.
- */
- argv++;
- argc--;
+ const char *singleCommand = NULL;
+ BOOL aliasFlag = FALSE, quietFlag = FALSE;
+ int ch;
+ char *cp;
- while ((argc > 0) && (**argv == '-'))
+ while ( (ch = getopt( argc, argv, "aeqh?c:p:" )) >= 0 )
{
- cp = *argv++ + 1;
- argc--;
-
- while (*cp) switch (*cp++)
+ switch ( ch )
{
- case 'c':
- /*
- * Execute specified command.
- */
- if ((argc != 1) || singleCommand)
- usage();
-
- singleCommand = *argv++;
- argc--;
-
+ case 'a':
+ aliasFlag = TRUE;
break;
-
- case 'p':
- /*
- * Set the prompt string.
- */
- if ((argc <= 0) || (**argv == '-'))
- usage();
-
- if (prompt)
- free(prompt);
-
- prompt = strdup(*argv++);
- argc--;
-
+ case 'e':
+ rl_disable = TRUE;
break;
-
case 'q':
quietFlag = TRUE;
break;
-
- case 'a':
- aliasFlag = TRUE;
+ case 'c':
+ if ( singleCommand )
+ usage();
+ singleCommand = strdup( optarg );
+ if ( !singleCommand )
+ fatal( "error during initialization: %s", strerror(errno) );
+ break;
+ case 'p':
+ if ( prompt )
+ free( prompt );
+
+ prompt = strdup( optarg );
+ if ( !prompt )
+ fatal( "error during initialization: %s", strerror(errno) );
break;
-
case 'h':
case '?':
usage();
- break;
-
default:
- fprintf(stderr, "Unknown option -%c\n", cp[-1]);
-
- return 1;
+ fatal( "unrecognized option: -%c", ch );
}
}
/*
- * No more arguments are allowed.
+ * No arguments are allowed for single command.
*/
- if (argc > 0)
+ if ( (singleCommand && optind < argc) || (optind + 1 < argc) )
usage();
/*
* Default our path if it is not set.
*/
- if (getenv("PATH") == NULL)
- putenv("PATH=/bin:/usr/bin:/sbin:/usr/sbin:/etc");
+ if ( !getenv("PATH") )
+ putenv( "PATH=/bin:/usr/bin:/sbin:/usr/sbin:/etc" );
/*
* If the alias flag is set then define all aliases.
*/
- if (aliasFlag)
- do_aliasall(0, NULL);
+ if ( aliasFlag )
+ do_aliasall( 0, NULL );
/*
* If we are to execute a single command, then do so and exit.
*/
- if (singleCommand)
+ if ( singleCommand )
{
- command(singleCommand);
-
+ command( singleCommand );
return 0;
}
+ if ( optind < argc )
+ {
+ int fd = open( argv[optind], O_RDONLY );
+ if ( fd < 0 )
+ fatal( "error opening %s: %s", argv[optind], strerror(errno) );
+
+ if ( dup2(fd, STDIN_FILENO) < 0 )
+ fatal( "dup2: %s", strerror(errno) );
+
+ if ( fcntl( STDIN_FILENO, F_SETFD, FD_CLOEXEC ) < 0 )
+ fatal( "fcntl: %s", strerror(errno) );
+
+ if ( close(fd) < 0 )
+ fatal( "close: %s", strerror(errno) );
+ }
+
/*
* Print a hello message unless we are told to be silent.
*/
- if (!quietFlag && isatty(STDIN))
+ if ( !quietFlag && isatty(STDIN_FILENO) )
{
- printf("Stand-alone shell (version %s)\n", version);
+ print_version( stdout );
if (aliasFlag)
printf("Built-in commands are aliased to standard commands\n");
}
- signal(SIGINT, catchInt);
- signal(SIGQUIT, catchQuit);
+ signal(SIGINT, catchInterrupt);
+ signal(SIGQUIT, catchInterrupt);
/*
* Execute the user's alias file if present.
*/
cp = getenv("HOME");
- if (cp)
+ if ( cp )
{
- strcpy(buf, cp);
- strcat(buf, "/");
- strcat(buf, ".aliasrc");
+ const char aliasrc[] = "/.aliasrc";
+ unsigned len = strlen( cp );
+ char fname[len + sizeof(aliasrc)];
+
+ memcpy( fname, cp, len );
+ memcpy( fname + len, aliasrc, sizeof(aliasrc) );
- if ((access(buf, 0) == 0) || (errno != ENOENT))
- readFile(buf);
+ if ( !access(fname, R_OK ) )
+ readFile( fname );
}
/*
* Read commands from stdin.
*/
- readFile(NULL);
-
- return 0;
+ return readFile( 0 );
}
@@ -522,80 +510,55 @@ main(int argc, const char ** argv)
* Read commands from the specified file.
* A null name pointer indicates to read from stdin.
*/
-static void
+static int
readFile(const char * name)
{
- FILE * fp;
- int cc;
- BOOL ttyFlag;
- char buf[CMD_LEN];
-
- if (sourceCount >= MAX_SOURCE)
- {
- fprintf(stderr, "Too many source files\n");
-
- return;
- }
-
- fp = stdin;
+ FILE *fp = stdin;
- if (name)
+ if ( name )
{
- fp = fopen(name, "r");
-
- if (fp == NULL)
+ fp = fopen( name, "r" );
+ if ( !fp )
{
- perror(name);
+ errmsg( "%s: %s", name, strerror(errno) );
+ return 1;
+ }
- return;
+ if ( fcntl( fileno(fp), F_SETFD, FD_CLOEXEC ) < 0 )
+ {
+ errmsg( "fcntl: %s: %s", name, strerror(errno) );
+ return 1;
}
}
- sourcefiles[sourceCount++] = fp;
-
- ttyFlag = isatty(fileno(fp));
-
- while (TRUE)
+ for(;;)
{
- if (ttyFlag)
- showPrompt();
+ const char *input;
- if (intFlag && !ttyFlag && (fp != stdin))
+ if ( intFlag && !isatty(fileno(fp)) )
{
- fclose(fp);
- sourceCount--;
+ if (fp != stdin)
+ fclose(fp);
- return;
+ return 128;
}
-
- if (fgets(buf, CMD_LEN - 1, fp) == NULL)
- {
- if (ferror(fp) && (errno == EINTR))
- {
- clearerr(fp);
- continue;
- }
+ input = get_line( fp );
- break;
+ if ( !input )
+ {
+ if ( getpid() == 1 )
+ continue;
+ else
+ break;
}
- cc = strlen(buf);
-
- if (buf[cc - 1] == '\n')
- cc--;
-
- while ((cc > 0) && isBlank(buf[cc - 1]))
- cc--;
-
- buf[cc] = '\0';
-
- command(buf);
+ command( input );
}
- if (ferror(fp))
+ if ( ferror(fp) )
{
- perror("Reading command line");
+ errmsg( "error reading command input: %s", strerror(errno) );
if (fp == stdin)
exit(1);
@@ -606,7 +569,7 @@ readFile(const char * name)
if (fp != stdin)
fclose(fp);
- sourceCount--;
+ return 0;
}
@@ -695,45 +658,43 @@ command(const char * cmd)
static BOOL
tryBuiltIn(const char * cmd)
{
- const char * endCmd;
- const CommandEntry * entry;
- int argc;
- const char ** argv;
- char cmdName[CMD_LEN];
+ char *cmdName;
+ const char *endCmd = cmd;
+ const CommandEntry *entry;
+ int argc;
+ const char *const *argv;
/*
* Look for the end of the command name and then copy the
* command name to a buffer so we can null terminate it.
*/
- endCmd = cmd;
-
- while (*endCmd && !isBlank(*endCmd))
- endCmd++;
+ while ( *endCmd && !isBlank(*endCmd) )
+ ++endCmd;
+ cmdName = alloca( endCmd - cmd + 1 );
memcpy(cmdName, cmd, endCmd - cmd);
-
cmdName[endCmd - cmd] = '\0';
/*
* Search the command table looking for the command name.
*/
- for (entry = commandEntryTable; entry->name != NULL; entry++)
+ for ( entry = commandEntryTable; entry->name; ++entry )
{
- if (strcmp(entry->name, cmdName) == 0)
+ if ( !strcmp(entry->name, cmdName) )
break;
}
/*
* If the command is not a built-in, return indicating that.
*/
- if (entry->name == NULL)
+ if ( !entry->name )
return FALSE;
/*
* The command is a built-in.
* Break the command up into arguments and expand wildcards.
*/
- if (!makeArgs(cmd, &argc, &argv))
+ if ( !makeArgs(cmd, &argc, &argv) )
return TRUE;
/*
@@ -742,7 +703,7 @@ tryBuiltIn(const char * cmd)
*/
if ((argc < entry->minArgs) || (argc > entry->maxArgs))
{
- fprintf(stderr, "usage: %s %s\n", entry->name, entry->usage);
+ errmsg( "usage: %s %s", entry->name, entry->usage);
return TRUE;
}
@@ -818,7 +779,7 @@ runCmd(const char * cmd)
if (pid < 0)
{
- perror("fork failed");
+ errmsg( "fork failed: %s", strerror(errno) );
return;
}
@@ -841,18 +802,15 @@ runCmd(const char * cmd)
intCrlf = TRUE;
- if (pid < 0)
+ if ( pid < 0 )
{
- fprintf(stderr, "Error from waitpid: %s", strerror(errno));
-
+ errmsg( "waitpid: %s", strerror(errno) );
return;
}
- if (WIFSIGNALED(status))
- {
- fprintf(stderr, "pid %ld: killed by signal %d\n",
- (long) pid, WTERMSIG(status));
- }
+ if ( WIFSIGNALED(status) )
+ errmsg( "%s: %s%s\n", cmd, strsignal(WTERMSIG(status)),
+ WCOREDUMP(status) ? " (core dumped)" : "" );
}
@@ -864,53 +822,37 @@ runCmd(const char * cmd)
static void
childProcess(const char * cmd)
{
- const char ** argv;
+ char *const *argv;
int argc;
/*
- * Close any extra file descriptors we have opened.
- */
- while (--sourceCount >= 0)
- {
- if (sourcefiles[sourceCount] != stdin)
- fclose(sourcefiles[sourceCount]);
- }
-
- /*
* Break the command line up into individual arguments.
* If this fails, then run the shell to execute the command.
*/
- if (!makeArgs(cmd, &argc, &argv))
- {
- system(cmd);
- exit(0);
- }
+ if ( !makeArgs(cmd, &argc, (const char *const **)&argv) )
+ exit( system( cmd ) );
/*
* Try to execute the program directly.
*/
- execvp(argv[0], (char **) argv);
+ execvp( argv[0], argv );
/*
* The exec failed, so try to run the command using the shell
* in case it is a shell script.
*/
- if (errno == ENOEXEC)
- {
- system(cmd);
- exit(0);
- }
+ if ( errno == ENOEXEC )
+ exit( system( cmd ) );
/*
* There was something else wrong, complain and exit.
*/
- perror(argv[0]);
- exit(1);
+ fatal( "exec: %s: %s", argv[0], strerror(errno) );
}
void
-do_help(int argc, const char ** argv)
+do_help(int argc, const char *const *argv)
{
const CommandEntry * entry;
const char * str;
@@ -955,7 +897,7 @@ do_help(int argc, const char ** argv)
void
-do_alias(int argc, const char ** argv)
+do_alias(int argc, const char *const *argv)
{
const char * name;
char * value;
@@ -982,14 +924,14 @@ do_alias(int argc, const char ** argv)
if (alias)
printf("%s\n", alias->value);
else
- fprintf(stderr, "Alias \"%s\" is not defined\n", name);
+ errmsg( "alias \"%s\" is not defined", name );
return;
}
- if (strcmp(name, "alias") == 0)
+ if ( !strcmp(name, "alias") )
{
- fprintf(stderr, "Cannot alias \"alias\"\n");
+ errmsg( "cannot alias \"alias\"");
return;
}
@@ -997,17 +939,14 @@ do_alias(int argc, const char ** argv)
if (!makeString(argc - 2, argv + 2, buf, CMD_LEN))
return;
- value = malloc(strlen(buf) + 1);
+ value = strdup( buf );
- if (value == NULL)
+ if ( !value )
{
- fprintf(stderr, "No memory for alias value\n");
-
+ errmsg( "failed to alias \"%s\": %s", name, strerror( errno ) );
return;
}
- strcpy(value, buf);
-
alias = findAlias(name);
if (alias)
@@ -1018,7 +957,7 @@ do_alias(int argc, const char ** argv)
return;
}
- if ((aliasCount % ALIAS_ALLOC) == 0)
+ if ( !(aliasCount % ALIAS_ALLOC) )
{
count = aliasCount + ALIAS_ALLOC;
@@ -1030,11 +969,10 @@ do_alias(int argc, const char ** argv)
else
alias = (Alias *) malloc(sizeof(Alias) * count);
- if (alias == NULL)
+ if ( !alias )
{
- free(value);
- fprintf(stderr, "No memory for alias table\n");
-
+ free( value );
+ errmsg( "failed to alias \"%s\": %s", name, strerror( errno ) );
return;
}
@@ -1043,19 +981,17 @@ do_alias(int argc, const char ** argv)
alias = &aliasTable[aliasCount];
- alias->name = malloc(strlen(name) + 1);
+ alias->name = strdup( name );
- if (alias->name == NULL)
+ if ( !alias->name )
{
- free(value);
- fprintf(stderr, "No memory for alias name\n");
-
+ free( value );
+ errmsg( "failed to alias \"%s\": %s", name, strerror( errno ) );
return;
}
- strcpy(alias->name, name);
alias->value = value;
- aliasCount++;
+ ++aliasCount;
}
@@ -1064,25 +1000,22 @@ do_alias(int argc, const char ** argv)
* using the names without the dash.
*/
void
-do_aliasall(int argc, const char **argv)
+do_aliasall(int argc, const char *const *argv)
{
- const CommandEntry * entry;
- const char * name;
- const char * newArgv[4];
+ const CommandEntry *entry;
- for (entry = commandEntryTable; entry->name; entry++)
+ for ( entry = commandEntryTable; entry->name; ++entry )
{
- name = entry->name;
+ const char *name = entry->name;
if (*name != '-')
continue;
+ else
+ {
+ const char *const newArgv[] = { "alias", name + 1, name, NULL };
- newArgv[0] = "alias";
- newArgv[1] = name + 1;
- newArgv[2] = name;
- newArgv[3] = NULL;
-
- do_alias(3, newArgv);
+ do_alias(3, newArgv);
+ }
}
}
@@ -1110,60 +1043,40 @@ findAlias(const char * name)
void
-do_source(int argc, const char ** argv)
+do_source(int argc, const char *const *argv)
{
readFile(argv[1]);
}
void
-do_exec(int argc, const char ** argv)
+do_exec(int argc, const char *const *argv)
{
- const char * name;
-
- name = argv[1];
-
- if (access(name, 4))
- {
- perror(name);
-
- return;
- }
-
- while (--sourceCount >= 0)
- {
- if (sourcefiles[sourceCount] != stdin)
- fclose(sourcefiles[sourceCount]);
- }
-
- argv[argc] = NULL;
-
- execvp(name, (char **) argv + 1);
- exit(1);
+ char *const *av = (char *const *)argv;
+ const char *const name = av[1];
+ execvp( name, av + 1);
+ errmsg( "exec: %s: %s", name, strerror(errno) );
}
void
-do_prompt(int argc, const char ** argv)
+do_prompt(int argc, const char *const *argv)
{
char * cp;
- char buf[CMD_LEN];
+ char buf[1+CMD_LEN];
- if (!makeString(argc - 1, argv + 1, buf, CMD_LEN))
+ if (!makeString(argc - 1, argv + 1, buf, sizeof(buf)))
return;
- cp = malloc(strlen(buf) + 2);
+ strcat( buf, " " );
+ cp = strdup( buf );
- if (cp == NULL)
+ if ( !cp )
{
- fprintf(stderr, "No memory for prompt\n");
-
+ errmsg( "failed to set prompt: %s", strerror(errno) );
return;
}
- strcpy(cp, buf);
- strcat(cp, " ");
-
if (prompt)
free(prompt);
@@ -1172,7 +1085,7 @@ do_prompt(int argc, const char ** argv)
void
-do_unalias(int argc, const char ** argv)
+do_unalias(int argc, const char *const *argv)
{
Alias * alias;
@@ -1192,56 +1105,28 @@ do_unalias(int argc, const char ** argv)
}
-/*
- * Display the prompt string.
- */
-static void
-showPrompt(void)
+static void catchInterrupt( int no )
{
- const char * cp;
-
- cp = "> ";
-
- if (prompt)
- cp = prompt;
-
- write(STDOUT, cp, strlen(cp));
-}
-
-
-static void
-catchInt(int val)
-{
- signal(SIGINT, catchInt);
-
intFlag = TRUE;
- if (intCrlf)
- write(STDOUT, "\n", 1);
+ if ( intCrlf )
+ write( STDOUT_FILENO, "\r\n", 2 );
}
-static void
-catchQuit(int val)
+static void print_version( FILE *fp )
{
- signal(SIGQUIT, catchQuit);
-
- intFlag = TRUE;
-
- if (intCrlf)
- write(STDOUT, "\n", 1);
+ fprintf( fp, "Stand-alone shell (version %s)\n", version );
}
-
/*
* Print the usage information and quit.
*/
-static void
-usage(void)
+static void usage( void )
{
- fprintf(stderr, "Stand-alone shell (version %s)\n", version);
- fprintf(stderr, "\n");
- fprintf(stderr, "Usage: sash [-a] [-q] [-c command] [-p prompt]\n");
+ extern const char *__progname;
+ print_version( stderr );
+ fprintf( stderr, "Usage: %s [-a] [-q] [-e] [-c command] [-p prompt] [script]\n", __progname );
exit(1);
}
--- sash/sash.h
+++ sash/sash.h
@@ -19,7 +19,7 @@
#include <malloc.h>
#include <time.h>
#include <ctype.h>
-
+#include <errno.h>
#define PATH_LEN 1024
#define CMD_LEN 10240
@@ -52,56 +52,57 @@ typedef int BOOL;
/*
* Built-in command functions.
*/
-extern void do_alias(int argc, const char ** argv);
-extern void do_aliasall(int argc, const char ** argv);
-extern void do_cd(int argc, const char ** argv);
-extern void do_exec(int argc, const char ** argv);
-extern void do_exit(int argc, const char ** argv);
-extern void do_prompt(int argc, const char ** argv);
-extern void do_source(int argc, const char ** argv);
-extern void do_umask(int argc, const char ** argv);
-extern void do_unalias(int argc, const char ** argv);
-extern void do_help(int argc, const char ** argv);
-extern void do_ln(int argc, const char ** argv);
-extern void do_cp(int argc, const char ** argv);
-extern void do_mv(int argc, const char ** argv);
-extern void do_rm(int argc, const char ** argv);
-extern void do_chmod(int argc, const char ** argv);
-extern void do_mkdir(int argc, const char ** argv);
-extern void do_rmdir(int argc, const char ** argv);
-extern void do_mknod(int argc, const char ** argv);
-extern void do_chown(int argc, const char ** argv);
-extern void do_chgrp(int argc, const char ** argv);
-extern void do_sum(int argc, const char ** argv);
-extern void do_sync(int argc, const char ** argv);
-extern void do_printenv(int argc, const char ** argv);
-extern void do_more(int argc, const char ** argv);
-extern void do_cmp(int argc, const char ** argv);
-extern void do_touch(int argc, const char ** argv);
-extern void do_ls(int argc, const char ** argv);
-extern void do_dd(int argc, const char ** argv);
-extern void do_tar(int argc, const char ** argv);
-extern void do_ar(int argc, const char ** argv);
-extern void do_mount(int argc, const char ** argv);
-extern void do_umount(int argc, const char ** argv);
-extern void do_setenv(int argc, const char ** argv);
-extern void do_pwd(int argc, const char ** argv);
-extern void do_echo(int argc, const char ** argv);
-extern void do_kill(int argc, const char ** argv);
-extern void do_grep(int argc, const char ** argv);
-extern void do_file(int argc, const char ** argv);
-extern void do_find(int argc, const char ** argv);
-extern void do_ed(int argc, const char ** argv);
-extern void do_where(int argc, const char ** argv);
+extern void do_alias(int argc, const char *const *argv);
+extern void do_aliasall(int argc, const char *const *argv);
+extern void do_cd(int argc, const char *const *argv);
+extern void do_exec(int argc, const char *const *argv);
+extern void do_exit(int argc, const char *const *argv);
+extern void do_prompt(int argc, const char *const *argv);
+extern void do_source(int argc, const char *const *argv);
+extern void do_umask(int argc, const char *const *argv);
+extern void do_unalias(int argc, const char *const *argv);
+extern void do_help(int argc, const char *const *argv);
+extern void do_ln(int argc, const char *const *argv);
+extern void do_cp(int argc, const char *const *argv);
+extern void do_mv(int argc, const char *const *argv);
+extern void do_rm(int argc, const char *const *argv);
+extern void do_chmod(int argc, const char *const *argv);
+extern void do_mkdir(int argc, const char *const *argv);
+extern void do_rmdir(int argc, const char *const *argv);
+extern void do_mknod(int argc, const char *const *argv);
+extern void do_chown(int argc, const char *const *argv);
+extern void do_chgrp(int argc, const char *const *argv);
+extern void do_sum(int argc, const char *const *argv);
+extern void do_sync(int argc, const char *const *argv);
+extern void do_printenv(int argc, const char *const *argv);
+extern void do_more(int argc, const char *const *argv);
+extern void do_cmp(int argc, const char *const *argv);
+extern void do_touch(int argc, const char *const *argv);
+extern void do_ls(int argc, const char *const *argv);
+extern void do_dd(int argc, const char *const *argv);
+extern void do_tar(int argc, const char *const *argv);
+extern void do_ar(int argc, const char *const *argv);
+extern void do_mount(int argc, const char *const *argv);
+extern void do_umount(int argc, const char *const *argv);
+extern void do_setenv(int argc, const char *const *argv);
+extern void do_pwd(int argc, const char *const *argv);
+extern void do_echo(int argc, const char *const *argv);
+extern void do_kill(int argc, const char *const *argv);
+extern void do_grep(int argc, const char *const *argv);
+extern void do_file(int argc, const char *const *argv);
+extern void do_find(int argc, const char *const *argv);
+extern void do_ed(int argc, const char *const *argv);
+extern void do_where(int argc, const char *const *argv);
+extern void do_losetup(int argc, const char *const *argv);
#ifdef HAVE_GZIP
-extern void do_gzip(int argc, const char ** argv);
-extern void do_gunzip(int argc, const char ** argv);
+extern void do_gzip(int argc, const char *const *argv);
+extern void do_gunzip(int argc, const char *const *argv);
#endif
#ifdef HAVE_EXT2
-extern void do_lsattr(int argc, const char ** argv);
-extern void do_chattr(int argc, const char ** argv);
+extern void do_lsattr(int argc, const char *const *argv);
+extern void do_chattr(int argc, const char *const *argv);
#endif
@@ -124,13 +125,13 @@ extern const char * buildName
(const char * dirName, const char * fileName);
extern BOOL makeArgs
- (const char * cmd, int * argcPtr, const char *** argvPtr);
+ (const char * cmd, int * argcPtr, const char *const ** argvPtr);
extern BOOL copyFile
(const char * srcName, const char * destName, BOOL setModes);
extern BOOL makeString
- (int argc, const char ** argv, char * buf, int bufLen);
+ (int argc, const char *const *argv, char * buf, int bufLen);
extern int expandWildCards
(const char * fileNamePattern, const char *** retFileTable);
--- sash/utils.c
+++ sash/utils.c
@@ -520,7 +520,7 @@ expandWildCards(const char * fileNamePattern, const char *** retFileTable)
/*
* Return the file list and count.
*/
- *retFileTable = (const char **) fileTable;
+ *retFileTable = (const char **)fileTable;
return fileCount;
}
@@ -532,11 +532,11 @@ expandWildCards(const char * fileNamePattern, const char *** retFileTable)
int
nameSort(const void * p1, const void * p2)
{
- const char ** s1;
- const char ** s2;
+ const char *const * s1;
+ const char *const * s2;
- s1 = (const char **) p1;
- s2 = (const char **) p2;
+ s1 = (const char *const *) p1;
+ s2 = (const char *const *) p2;
return strcmp(*s1, *s2);
}
@@ -646,14 +646,14 @@ match(const char * text, const char * pattern)
* already output.
*/
BOOL
-makeArgs(const char * cmd, int * retArgc, const char *** retArgv)
+makeArgs(const char * cmd, int * retArgc, const char *const ** retArgv)
{
const char * argument;
char * cp;
char * cpOut;
char * newStrings;
- const char ** fileTable;
- const char ** newArgTable;
+ const char **fileTable;
+ const char **newArgTable;
int newArgTableSize;
int fileCount;
int len;
@@ -900,7 +900,7 @@ makeArgs(const char * cmd, int * retArgc, const char *** retArgv)
* Copy the new arguments to the end of the old ones.
*/
memcpy((void *) &argTable[argCount], (const void *) fileTable,
- (sizeof(const char **) * fileCount));
+ (sizeof(const char *const *) * fileCount));
/*
* Add to the argument count.
@@ -914,7 +914,7 @@ makeArgs(const char * cmd, int * retArgc, const char *** retArgv)
argTable[argCount] = NULL;
*retArgc = argCount;
- *retArgv = argTable;
+ *retArgv = (const char *const *)argTable;
return TRUE;
}
@@ -929,7 +929,7 @@ makeArgs(const char * cmd, int * retArgc, const char *** retArgv)
BOOL
makeString(
int argc,
- const char ** argv,
+ const char *const * argv,
char * buf,
int bufLen
)