]> err.no Git - sash/commitdiff
Imported Debian patch 3.7-10 debian/3.7-10
authorTollef Fog Heen <tfheen@debian.org>
Sun, 4 Apr 2010 08:25:57 +0000 (10:25 +0200)
committerTollef Fog Heen <tfheen@err.no>
Sun, 20 Apr 2014 06:13:10 +0000 (08:13 +0200)
19 files changed:
Makefile
cmd_chattr.c
cmds.c
debian/changelog
debian/control
debian/patches/__inactive__exit_with_command_status [new file with mode: 0644]
debian/patches/buildsystem [new file with mode: 0644]
debian/patches/debian-changes-3.7-10 [new file with mode: 0644]
debian/patches/e2fslibs_chattr_include [new file with mode: 0644]
debian/patches/exit_with_argument [new file with mode: 0644]
debian/patches/exit_with_command_status [new file with mode: 0644]
debian/patches/fix_exec [new file with mode: 0644]
debian/patches/freebsd_build [new file with mode: 0644]
debian/patches/interactive_flag [new file with mode: 0644]
debian/patches/series [new file with mode: 0644]
debian/patches/touch_error_handling [new file with mode: 0644]
debian/source/format [new file with mode: 0644]
debian/stamp-makefile-build [new file with mode: 0644]
sash.c

index f7e2e3c89410eb36c97ccfa719c537148fcbafd8..bd8358e534c1f52cfd5fb54397a3f7b31e7df4b9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -13,12 +13,13 @@ HAVE_LINUX_MOUNT    = 1
 HAVE_BSD_MOUNT         = 0
 MOUNT_TYPE             = '"ext3"'
 
-DEFS = -DHAVE_GZIP=$(HAVE_GZIP) \
+
+CFLAGS = -O3 -Wall -Wmissing-prototypes \
+       -DHAVE_GZIP=$(HAVE_GZIP) \
        -DHAVE_LINUX_ATTR=$(HAVE_LINUX_ATTR) \
        -DHAVE_LINUX_MOUNT=$(HAVE_LINUX_MOUNT) \
        -DHAVE_BSD_MOUNT=$(HAVE_BSD_MOUNT) \
        -DMOUNT_TYPE=$(MOUNT_TYPE)
-CFLAGS = -O3 -Wall -Wmissing-prototypes -g $(DEFS)
 
 LDFLAGS = -static -s
 LIBS = -lz
@@ -42,7 +43,4 @@ install: sash
        cp sash $(BINDIR)/sash
        cp sash.1 $(MANDIR)/sash.1
 
-%.o: %.c
-       $(CC) $(CFLAGS) $(DEFS) -c $<
-
 $(OBJS):       sash.h
index 9f697ea436b83c996bfbaf9f42dae5d9db7df986..5fc43c250f9ddebb602772db74166f964f303bf5 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <sys/ioctl.h>
 #include <sys/types.h>
-#include <ext2fs/ext2_fs.h>
+#include <linux/ext2_fs.h>
 
 #include "sash.h"
 
diff --git a/cmds.c b/cmds.c
index a576269ecc83ddb01126e103199f87ed3e87caca..ec85539e22006508f97d07dba5165981720cc0a8 100644 (file)
--- a/cmds.c
+++ b/cmds.c
@@ -337,9 +337,12 @@ do_touch(int argc, const char ** argv)
                if (fd >= 0)
                {
                        close(fd);
-               } else {
-                       perror(name);
+
+                       continue;
                }
+
+               if (utime(name, &now) < 0)
+                       perror(name);
        }
 }
 
@@ -990,18 +993,14 @@ do_sum(int argc, const char ** argv)
 void
 do_exit(int argc, const char ** argv)
 {
-       int r = 0;
        if (getpid() == 1)
        {
                fprintf(stderr, "You are the INIT process!\n");
 
                return;
        }
-       if (argc == 2)
-       {
-               r = atoi(argv[1]);
-       }
-       exit(r);
+
+       exit(0);
 }
 
 
index 8df708bc0d649108bf77e4dfc90de32f91c3d452..0d3ddae712b2dd012eb4a6fab97cf4d705ab5597 100644 (file)
@@ -1,3 +1,15 @@
+sash (3.7-10) unstable; urgency=low
+
+  * Switch to 3.0 (quilt) as the source format and convert patches.
+  * Fix up debian/patches/touch_error_handling to actually update the
+    timestamp of the file, something that has been broken for more than
+    ten years.
+  * Add kFreeBSD build fixes from Axel Beckert. Closes: #565539
+  * When exiting the shell, use the exit status of the last command as our
+    exit status.  Closes: #281728
+
+ -- Tollef Fog Heen <tfheen@debian.org>  Sun, 04 Apr 2010 10:25:57 +0200
+
 sash (3.7-9) unstable; urgency=low
 
   * Drop dependency on lockfile-progs, no longer needed.
index e5be88e609c1e914b8598a4de9829e08cb3f89ea..0efef3a302f27a451274460d157c2ef6c55ce6d0 100644 (file)
@@ -3,7 +3,9 @@ Section: shells
 Priority: optional
 Maintainer: Tollef Fog Heen <tfheen@debian.org>
 Standards-Version: 3.8.0
-Build-Depends: zlib1g-dev (>= 1:1.2.2-7), debhelper (>= 7), e2fslibs-dev
+Build-Depends: zlib1g-dev (>= 1:1.2.2-7), debhelper (>= 7),
+ e2fslibs-dev [!kfreebsd-amd64 !kfreebsd-i386],
+ kfreebsd-kernel-headers [kfreebsd-amd64 kfreebsd-i386]
 
 Package: sash
 Architecture: any
diff --git a/debian/patches/__inactive__exit_with_command_status b/debian/patches/__inactive__exit_with_command_status
new file mode 100644 (file)
index 0000000..8190b99
--- /dev/null
@@ -0,0 +1,1976 @@
+Index: sash-3.7/cmds.c
+===================================================================
+--- sash-3.7.orig/cmds.c       2010-04-04 11:45:33.864951850 +0200
++++ sash-3.7/cmds.c    2010-04-04 12:29:17.184954241 +0200
+@@ -26,7 +26,7 @@
+ #endif
+-void
++int
+ do_echo(int argc, const char ** argv)
+ {
+       BOOL    first;
+@@ -43,10 +43,11 @@
+       }
+       fputc('\n', stdout);
++      return 0;
+ }
+-void
++int
+ do_pwd(int argc, const char ** argv)
+ {
+       char    buf[PATH_LEN];
+@@ -55,14 +56,15 @@
+       {
+               fprintf(stderr, "Cannot get current directory\n");
+-              return;
++              return 1;
+       }
+       printf("%s\n", buf);
++      return 0;
+ }
+-void
++int
+ do_cd(int argc, const char ** argv)
+ {
+       const char *    path;
+@@ -77,29 +79,38 @@
+               {
+                       fprintf(stderr, "No HOME environment variable\n");
+-                      return;
++                      return 1;
+               }
+       }
+       if (chdir(path) < 0)
++      {
+               perror(path);
++              return 1;
++      }
++      return 0;
+ }
+-void
++int
+ do_mkdir(int argc, const char ** argv)
+ {
++      int r = 0;
+       while (argc-- > 1)
+       {
+               if (mkdir(argv[1], 0777) < 0)
++              {
+                       perror(argv[1]);
++                      r = 1;
++              }
+               argv++;
+       }
++      return r;
+ }
+-void
++int
+ do_mknod(int argc, const char ** argv)
+ {
+       const char *    cp;
+@@ -117,7 +128,7 @@
+       {
+               fprintf(stderr, "Bad device type\n");
+-              return;
++              return 1;
+       }
+       major = 0;
+@@ -130,7 +141,7 @@
+       {
+               fprintf(stderr, "Bad major number\n");
+-              return;
++              return 1;
+       }
+       minor = 0;
+@@ -143,53 +154,70 @@
+       {
+               fprintf(stderr, "Bad minor number\n");
+-              return;
++              return 1;
+       }
+       if (mknod(argv[1], mode, major * 256 + minor) < 0)
++      {
+               perror(argv[1]);
++              return 1;
++      }
++      return 0;
+ }
+-void
++int
+ do_rmdir(int argc, const char ** argv)
+ {
++      int r = 0;
+       while (argc-- > 1)
+       {
+               if (rmdir(argv[1]) < 0)
++              {
+                       perror(argv[1]);
++                      r = 1;
++              }
+               argv++;
+       }
++      return r;
+ }
+-void
++int
+ do_sync(int argc, const char ** argv)
+ {
+       sync();
++      return 0;
+ }
+-void
++int
+ do_rm(int argc, const char ** argv)
+ {
++      int r = 0;
+       while (argc-- > 1)
+       {
+               if (unlink(argv[1]) < 0)
++              {
+                       perror(argv[1]);
++                      r = 1;
++              }
+               argv++;
+       }
++      return r;
+ }
+-void
++int
+ do_chmod(int argc, const char ** argv)
+ {
+       const char *    cp;
+       int             mode;
++      int             r;
++      r = 0;
+       mode = 0;
+       cp = argv[1];
+@@ -200,7 +228,7 @@
+       {
+               fprintf(stderr, "Mode must be octal\n");
+-              return;
++              return 1;
+       }
+       argc--;
+@@ -209,21 +237,27 @@
+       while (argc-- > 1)
+       {
+               if (chmod(argv[1], mode) < 0)
++              {
+                       perror(argv[1]);
++                      r = 1;
++              }
+               argv++;
+       }
++      return r;
+ }
+-void
++int
+ do_chown(int argc, const char ** argv)
+ {
+       const char *    cp;
+       int             uid;
+       struct passwd * pwd;
+       struct stat     statBuf;
++      int             r;
++      r = 0;
+       cp = argv[1];
+       if (isDecimal(*cp))
+@@ -237,7 +271,7 @@
+               {
+                       fprintf(stderr, "Bad uid value\n");
+-                      return;
++                      return 1;
+               }
+       } else {
+               pwd = getpwnam(cp);
+@@ -246,7 +280,7 @@
+               {
+                       fprintf(stderr, "Unknown user name\n");
+-                      return;
++                      return 1;
+               }
+               uid = pwd->pw_uid;
+@@ -263,19 +297,23 @@
+                       (chown(*argv, uid, statBuf.st_gid) < 0))
+               {
+                       perror(*argv);
++                      r = 1;
+               }
+       }
++      return r;
+ }
+-void
++int
+ do_chgrp(int argc, const char ** argv)
+ {
+       const char *    cp;
+       int             gid;
+       struct group *  grp;
+       struct stat     statBuf;
++      int             r;
++      r = 0;
+       cp = argv[1];
+       if (isDecimal(*cp))
+@@ -289,7 +327,7 @@
+               {
+                       fprintf(stderr, "Bad gid value\n");
+-                      return;
++                      return 1;
+               }
+       }
+       else
+@@ -300,7 +338,7 @@
+               {
+                       fprintf(stderr, "Unknown group name\n");
+-                      return;
++                      return 1;
+               }
+               gid = grp->gr_gid;
+@@ -317,18 +355,22 @@
+                       (chown(*argv, statBuf.st_uid, gid) < 0))
+               {
+                       perror(*argv);
++                      r = 1;
+               }
+       }
++      return r;
+ }
+-void
++int
+ do_touch(int argc, const char ** argv)
+ {
+       const char *    name;
+       int             fd;
+       struct utimbuf  now;
++      int             r;
++      r = 0;
+       time(&now.actime);
+       now.modtime = now.actime;
+@@ -347,23 +389,30 @@
+               if (errno != EEXIST) {
+                       perror(name);
++                      r = 1;
+                       continue;
+               }
+               if (utime(name, &now) < 0)
++              {
+                       perror(name);
++                      r = 1;
++              }
+       }
++      return r;
+ }
+-void
++int
+ do_mv(int argc, const char ** argv)
+ {
+       const char *    srcName;
+       const char *    destName;
+       const char *    lastArg;
+       BOOL            dirFlag;
++      int             r;
++      r = 0;
+       lastArg = argv[argc - 1];
+       dirFlag = isDirectory(lastArg);
+@@ -372,7 +421,7 @@
+       {
+               fprintf(stderr, "%s: not a directory\n", lastArg);
+-              return;
++              return 1;
+       }
+       while (!intFlag && (argc-- > 2))
+@@ -382,6 +431,7 @@
+               if (access(srcName, 0) < 0)
+               {
+                       perror(srcName);
++                      r = 1;
+                       continue;
+               }
+@@ -397,6 +447,7 @@
+               if (errno != EXDEV)
+               {
+                       perror(destName);
++                      r = 1;
+                       continue;
+               }
+@@ -405,18 +456,25 @@
+                       continue;
+               if (unlink(srcName) < 0)
++              {
+                       perror(srcName);
++                      r = 1;
++              }
+       }
++      return r;
+ }
+-void
++int
+ do_ln(int argc, const char ** argv)
+ {
+       const char *    srcName;
+       const char *    destName;
+       const char *    lastArg;
+       BOOL            dirFlag;
++      int             r;
++
++      r = 0;
+       if (argv[1][0] == '-')
+       {
+@@ -424,23 +482,27 @@
+               {
+                       fprintf(stderr, "Unknown option\n");
+-                      return;
++                      return 1;
+               }
+               if (argc != 4)
+               {
+                       fprintf(stderr, "Wrong number of arguments for symbolic link\n");
+-                      return;
++                      return 1;
+               }
+ #ifdef        S_ISLNK
+               if (symlink(argv[2], argv[3]) < 0)
++              {
+                       perror(argv[3]);
++                      return 1;
++              }
++              return 0;
+ #else
+               fprintf(stderr, "Symbolic links are not allowed\n");
++              return 1;
+ #endif
+-              return;
+       }
+       /*
+@@ -453,7 +515,7 @@
+       {
+               fprintf(stderr, "%s: not a directory\n", lastArg);
+-              return;
++              return 1;
+       }
+       while (argc-- > 2)
+@@ -463,6 +525,7 @@
+               if (access(srcName, 0) < 0)
+               {
+                       perror(srcName);
++                      r = 1;
+                       continue;
+               }
+@@ -475,21 +538,25 @@
+               if (link(srcName, destName) < 0)
+               {
+                       perror(destName);
++                      r = 1;
+                       continue;
+               }
+       }
++      return r;
+ }
+-void
++int
+ do_cp(int argc, const char ** argv)
+ {
+       const char *    srcName;
+       const char *    destName;
+       const char *    lastArg;
+       BOOL            dirFlag;
++      int             r;
++      r = 0;
+       lastArg = argv[argc - 1];
+       dirFlag = isDirectory(lastArg);
+@@ -498,7 +565,7 @@
+       {
+               fprintf(stderr, "%s: not a directory\n", lastArg);
+-              return;
++              return 1;
+       }
+       while (!intFlag && (argc-- > 2))
+@@ -509,12 +576,14 @@
+               if (dirFlag)
+                       destName = buildName(destName, srcName);
+-              (void) copyFile(srcName, destName, FALSE);
++              if (!copyFile(srcName, destName, FALSE))
++                      r = 1;
+       }
++      return r;
+ }
+-void
++int
+ do_mount(int argc, const char ** argv)
+ {
+       const char *    str;
+@@ -544,7 +613,7 @@
+                               {
+                                       fprintf(stderr, "Missing file system type\n");
+-                                      return;
++                                      return 1;
+                               }
+                               type = *argv++;
+@@ -584,7 +653,7 @@
+                       default:
+                               fprintf(stderr, "Unknown option\n");
+-                              return;
++                              return 1;
+               }
+       }
+@@ -592,14 +661,16 @@
+       {
+               fprintf(stderr, "Wrong number of arguments for mount\n");
+-              return;
++              return 1;
+       }
+ #if   HAVE_LINUX_MOUNT
+-      if (mount(argv[0], argv[1], type, flags, 0) < 0)
+-              perror("mount failed");
+-
++      if (mount(argv[0], argv[1], type, flags, 0) < 0)
++      {
++              perror("mount failed");
++              return 1;
++      }
+ #elif HAVE_BSD_MOUNT
+       {
+               struct      ufs_args ufs;
+@@ -622,22 +693,29 @@
+                       fprintf(stderr, "Unknown filesystem type: %s", type);
+                       fprintf(stderr,
+                           "Supported: ffs ufs adosfs cd9660 mfs msdos\n");
+-                      return;
++                      return 1;
+               }
+               if (mount(type, argv[1], flags, args) < 0)
+-                      perror(argv[0]);
++              {
++                      perror(argv[0]);
++                      return 1;
++              }
+       }
+ #endif
++      return 0;
+ }
+-void
++int
+ do_umount(int argc, const char ** argv)
+ {
+ #if   HAVE_LINUX_MOUNT
+       if (umount(argv[1]) < 0)
++      {
+               perror(argv[1]);
++              return 1;
++      }
+ #elif HAVE_BSD_MOUNT
+       {
+               const char *    str;
+@@ -659,13 +737,17 @@
+               }
+               if (unmount(argv[0], flags) < 0)
++              {
+                       perror(argv[0]);
++                      return 1;
++              }
+       }
+ #endif
++      return 0;
+ }
+-void
++int
+ do_cmp(int argc, const char ** argv)
+ {
+       int             fd1;
+@@ -679,19 +761,22 @@
+       char            buf2[BUF_SIZE];
+       struct  stat    statBuf1;
+       struct  stat    statBuf2;
++      int             r;
++
++      r = 0;
+       if (stat(argv[1], &statBuf1) < 0)
+       {
+               perror(argv[1]);
+-              return;
++              return 1;
+       }
+       if (stat(argv[2], &statBuf2) < 0)
+       {
+               perror(argv[2]);
+-              return;
++              return 1;
+       }
+       if ((statBuf1.st_dev == statBuf2.st_dev) &&
+@@ -699,14 +784,14 @@
+       {
+               printf("Files are links to each other\n");
+-              return;
++              return 0;
+       }
+       if (statBuf1.st_size != statBuf2.st_size)
+       {
+               printf("Files are different sizes\n");
+-              return;
++              return 1;
+       }
+       fd1 = open(argv[1], O_RDONLY);
+@@ -715,7 +800,7 @@
+       {
+               perror(argv[1]);
+-              return;
++              return 1;
+       }
+       fd2 = open(argv[2], O_RDONLY);
+@@ -725,7 +810,7 @@
+               perror(argv[2]);
+               close(fd1);
+-              return;
++              return 1;
+       }
+       pos = 0;
+@@ -740,6 +825,7 @@
+               if (cc1 < 0)
+               {
+                       perror(argv[1]);
++                      r = 1;
+                       goto closefiles;
+               }
+@@ -748,24 +834,28 @@
+               if (cc2 < 0)
+               {
+                       perror(argv[2]);
++                      r = 1;
+                       goto closefiles;
+               }
+               if ((cc1 == 0) && (cc2 == 0))
+               {
+                       printf("Files are identical\n");
++                      r = 0;
+                       goto closefiles;
+               }
+               if (cc1 < cc2)
+               {
+                       printf("First file is shorter than second\n");
++                      r = 1;
+                       goto closefiles;
+               }
+               if (cc1 > cc2)
+               {
+                       printf("Second file is shorter than first\n");
++                      r = 1;
+                       goto closefiles;
+               }
+@@ -783,6 +873,7 @@
+                       pos++;
+               printf("Files differ at byte position %ld\n", pos);
++              r = 1;
+               goto closefiles;
+       }
+@@ -790,10 +881,11 @@
+ closefiles:
+       close(fd1);
+       close(fd2);
++      return r;
+ }
+-void
++int
+ do_more(int argc, const char ** argv)
+ {
+       FILE *          fp;
+@@ -841,7 +933,7 @@
+               {
+                       perror(name);
+-                      return;
++                      return 1;
+               }
+               printf("<< %s >>\n", name);
+@@ -896,7 +988,7 @@
+                               if (fp)
+                                       fclose(fp);
+-                              return;
++                              return 0;
+                       }
+                       ch = buf[0];
+@@ -916,7 +1008,7 @@
+                               case 'q':
+                                       fclose(fp);
+-                                      return;
++                                      return 0;
+                       }
+                       col = 0;
+@@ -926,10 +1018,11 @@
+               if (fp)
+                       fclose(fp);
+       }
++      return 0;
+ }
+-void
++int
+ do_sum(int argc, const char ** argv)
+ {
+       const char *    name;
+@@ -939,9 +1032,11 @@
+       int             i;
+       unsigned long   checksum;
+       char            buf[BUF_SIZE];
++      int             r;
+       argc--;
+       argv++;
++      r = 0;
+       while (argc-- > 0)
+       {
+@@ -952,6 +1047,7 @@
+               if (fd < 0)
+               {
+                       perror(name);
++                      r = 1;
+                       continue;
+               }
+@@ -976,6 +1072,7 @@
+               if (cc < 0)
+               {
+                       perror(name);
++                      r = 1;
+                       (void) close(fd);
+@@ -986,10 +1083,11 @@
+               printf("%05lu %s\n", checksum, name);
+       }
++      return r;
+ }
+-void
++int
+ do_exit(int argc, const char ** argv)
+ {
+       int r = 0;
+@@ -997,17 +1095,18 @@
+       {
+               fprintf(stderr, "You are the INIT process!\n");
+-              return;
++              return 1;
+       }
+       if (argc == 2)
+       {
+               r = atoi(argv[1]);
+       }
+       exit(r);
++      return r;
+ }
+-void
++int
+ do_setenv(int argc, const char ** argv)
+ {
+       const char *    name;
+@@ -1027,7 +1126,7 @@
+       {
+               fprintf(stderr, "Cannot allocate memory\n");
+-              return;
++              return 1;
+       }
+       strcpy(str, name);
+@@ -1035,10 +1134,11 @@
+       strcat(str, value);
+       putenv(str);
++      return 0;
+ }
+-void
++int
+ do_printenv(int argc, const char ** argv)
+ {
+       const char **   env;
+@@ -1052,7 +1152,7 @@
+               while (*env)
+                       printf("%s\n", *env++);
+-              return;
++              return 0;
+       }
+       len = strlen(argv[1]);
+@@ -1064,14 +1164,15 @@
+               {
+                       printf("%s\n", &env[0][len+1]);
+-                      return;
++                      return 0;
+               }
+               env++;
+       }
++      return 0;
+ }
+-void
++int
+ do_umask(int argc, const char ** argv)
+ {
+       const char *    cp;
+@@ -1083,7 +1184,7 @@
+               umask(mask);
+               printf("%03o\n", mask);
+-              return;
++              return 0;
+       }
+       mask = 0;
+@@ -1096,20 +1197,24 @@
+       {
+               fprintf(stderr, "Bad umask value\n");
+-              return;
++              return 1;
+       }
+       umask(mask);
++      return 0;
++
+ }
+-void
++int
+ do_kill(int argc, const char ** argv)
+ {
+       const char *    cp;
+       int             sig;
+       int             pid;
++      int             r;
++      r = 0;
+       sig = SIGTERM;
+       if (argv[1][0] == '-')
+@@ -1145,7 +1250,7 @@
+                       {
+                               fprintf(stderr, "Unknown signal\n");
+-                              return;
++                              return 1;
+                       }
+               }
+@@ -1165,16 +1270,20 @@
+               {
+                       fprintf(stderr, "Non-numeric pid\n");
+-                      return;
++                      return 1;
+               }
+               if (kill(pid, sig) < 0)
++              {
+                       perror(*argv);
++                      r = 1;
++              }
+       }
++      return r;
+ }
+-void
++int
+ do_where(int argc, const char ** argv)
+ {
+       const char *    program;
+@@ -1183,6 +1292,7 @@
+       char *          endPath;
+       char *          fullPath;
+       BOOL            found;
++      int             r;
+       found = FALSE;
+       program = argv[1];
+@@ -1191,7 +1301,7 @@
+       {
+               fprintf(stderr, "Program name cannot include a path\n");
+-              return;
++              return 1;
+       }
+       path = getenv("PATH");
+@@ -1203,7 +1313,7 @@
+       {
+               fprintf(stderr, "Memory allocation failed\n");
+-              return;
++              return 1;
+       }
+       /*
+@@ -1243,7 +1353,10 @@
+               if (access(fullPath, X_OK) < 0)
+               {
+                       if (errno != ENOENT)
+-                              printf("%s: %s\n", fullPath, strerror(errno));
++                      {
++                              perror(fullPath);
++                              r = 1;
++                      }
+                       continue;
+               }
+@@ -1253,7 +1366,11 @@
+       }
+       if (!found)
++      {
+               printf("Program \"%s\" not found in PATH\n", program);
++              r = 1;
++      }
++      return r;
+ }
+ /* END CODE */
+Index: sash-3.7/sash.h
+===================================================================
+--- sash-3.7.orig/sash.h       2010-04-04 11:45:33.888951646 +0200
++++ sash-3.7/sash.h    2010-04-04 11:46:22.112949938 +0200
+@@ -58,56 +58,56 @@
+ /*
+  * 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        int     do_alias(int argc, const char ** argv);
++extern        int     do_aliasall(int argc, const char ** argv);
++extern        int     do_cd(int argc, const char ** argv);
++extern        int     do_exec(int argc, const char ** argv);
++extern        int     do_exit(int argc, const char ** argv);
++extern        int     do_prompt(int argc, const char ** argv);
++extern        int     do_source(int argc, const char ** argv);
++extern        int     do_umask(int argc, const char ** argv);
++extern        int     do_unalias(int argc, const char ** argv);
++extern        int     do_help(int argc, const char ** argv);
++extern        int     do_ln(int argc, const char ** argv);
++extern        int     do_cp(int argc, const char ** argv);
++extern        int     do_mv(int argc, const char ** argv);
++extern        int     do_rm(int argc, const char ** argv);
++extern        int     do_chmod(int argc, const char ** argv);
++extern        int     do_mkdir(int argc, const char ** argv);
++extern        int     do_rmdir(int argc, const char ** argv);
++extern        int     do_mknod(int argc, const char ** argv);
++extern        int     do_chown(int argc, const char ** argv);
++extern        int     do_chgrp(int argc, const char ** argv);
++extern        int     do_sum(int argc, const char ** argv);
++extern        int     do_sync(int argc, const char ** argv);
++extern        int     do_printenv(int argc, const char ** argv);
++extern        int     do_more(int argc, const char ** argv);
++extern        int     do_cmp(int argc, const char ** argv);
++extern        int     do_touch(int argc, const char ** argv);
++extern        int     do_ls(int argc, const char ** argv);
++extern        int     do_dd(int argc, const char ** argv);
++extern        int     do_tar(int argc, const char ** argv);
++extern        int     do_ar(int argc, const char ** argv);
++extern        int     do_mount(int argc, const char ** argv);
++extern        int     do_umount(int argc, const char ** argv);
++extern        int     do_setenv(int argc, const char ** argv);
++extern        int     do_pwd(int argc, const char ** argv);
++extern        int     do_echo(int argc, const char ** argv);
++extern        int     do_kill(int argc, const char ** argv);
++extern        int     do_grep(int argc, const char ** argv);
++extern        int     do_file(int argc, const char ** argv);
++extern        int     do_find(int argc, const char ** argv);
++extern        int     do_ed(int argc, const char ** argv);
++extern        int     do_where(int argc, const char ** argv);
+ #if   HAVE_GZIP
+-extern        void    do_gzip(int argc, const char ** argv);
+-extern        void    do_gunzip(int argc, const char ** argv);
++extern        int     do_gzip(int argc, const char ** argv);
++extern        int     do_gunzip(int argc, const char ** argv);
+ #endif
+ #if   HAVE_LINUX_ATTR
+-extern        void    do_lsattr(int argc, const char ** argv);
+-extern        void    do_chattr(int argc, const char ** argv);
++extern        int     do_lsattr(int argc, const char ** argv);
++extern        int     do_chattr(int argc, const char ** argv);
+ #endif
+Index: sash-3.7/sash.c
+===================================================================
+--- sash-3.7.orig/sash.c       2010-04-04 11:45:33.876960339 +0200
++++ sash-3.7/sash.c    2010-04-04 11:46:22.116952745 +0200
+@@ -31,7 +31,7 @@
+ typedef struct
+ {
+       const char *    name;
+-      void            (*func)(int argc, const char ** argv);
++      int             (*func)(int argc, const char ** argv);
+       int             minArgs;
+       int             maxArgs;
+       const char *    description;
+@@ -375,10 +375,10 @@
+  */
+ static        void    catchInt(int);
+ static        void    catchQuit(int);
+-static        void    readFile(const char * name);
+-static        void    command(const char * cmd);
+-static        BOOL    tryBuiltIn(const char * cmd);
+-static        void    runCmd(const char * cmd);
++static        int     readFile(const char * name);
++static        int     command(const char * cmd);
++static        int     tryBuiltIn(const char * cmd);
++static        int     runCmd(const char * cmd);
+ static        void    childProcess(const char * cmd);
+ static        void    showPrompt(void);
+ static        void    usage(void);
+@@ -571,19 +571,20 @@
+  * 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];
++      int     r = 0;
+       if (sourceCount >= MAX_SOURCE)
+       {
+               fprintf(stderr, "Too many source files\n");
+-              return;
++              return 1;
+       }
+       fp = stdin;
+@@ -596,7 +597,7 @@
+               {
+                       perror(name);
+-                      return;
++                      return 1;
+               }
+       }
+@@ -614,7 +615,7 @@
+                       fclose(fp);
+                       sourceCount--;
+-                      return;
++                      return 1;
+               }
+       
+               if (fgets(buf, CMD_LEN - 1, fp) == NULL)
+@@ -639,7 +640,7 @@
+               buf[cc] = '\0';
+-              command(buf);
++              r = command(buf);
+       }
+       if (ferror(fp))
+@@ -656,6 +657,7 @@
+               fclose(fp);
+       sourceCount--;
++      return r;
+ }
+@@ -664,13 +666,14 @@
+  * This breaks the command line up into words, checks to see if the
+  * command is an alias, and expands wildcards.
+  */
+-static void
++static int
+ command(const char * cmd)
+ {
+       const char *    endCmd;
+       const Alias *   alias;
+       char            newCommand[CMD_LEN];
+       char            cmdName[CMD_LEN];
++      int             r = -1;
+       /*
+        * Rest the interrupt flag and free any memory chunks that
+@@ -690,7 +693,7 @@
+        * If the command is empty or is a comment then ignore it.
+        */
+       if ((*cmd == '\0') || (*cmd == '#'))
+-              return;
++              return 0;
+       /*
+        * Look for the end of the command name and then copy the
+@@ -725,14 +728,15 @@
+        * Now look for the command in the builtin table, and execute
+        * the command if found.
+        */
+-      if (tryBuiltIn(cmd))
+-              return;
++      r = tryBuiltIn(cmd);
++      if (r >= 0)
++              return r;
+       /*
+        * The command is not a built-in, so run the program along
+        * the PATH list.
+        */
+-      runCmd(cmd);
++      return runCmd(cmd);
+ }
+@@ -741,7 +745,7 @@
+  * Returns TRUE if the command is a built in, whether or not the
+  * command succeeds.  Returns FALSE if this is not a built-in command.
+  */
+-static BOOL
++static int
+ tryBuiltIn(const char * cmd)
+ {
+       const char *            endCmd;
+@@ -776,14 +780,14 @@
+        * If the command is not a built-in, return indicating that.
+        */
+       if (entry->name == NULL)
+-              return FALSE;
++              return -1;
+       /*
+        * The command is a built-in.
+        * Break the command up into arguments and expand wildcards.
+        */
+       if (!makeArgs(cmd, &argc, &argv))
+-              return TRUE;
++              return 0;
+       /*
+        * Give a usage string if the number of arguments is too large
+@@ -793,15 +797,13 @@
+       {
+               fprintf(stderr, "usage: %s %s\n", entry->name, entry->usage);
+-              return TRUE;
++              return 0;
+       }
+       /*
+        * Call the built-in function with the argument list.
+        */
+-      entry->func(argc, argv);
+-
+-      return TRUE;
++      return entry->func(argc, argv);
+ }
+@@ -809,7 +811,7 @@
+  * Execute the specified command either by forking and executing
+  * the program ourself, or else by using the shell.
+  */
+-static void
++static int
+ runCmd(const char * cmd)
+ {
+       const char *    cp;
+@@ -854,9 +856,7 @@
+        */
+       if (magic)
+       {
+-              system(cmd);
+-
+-              return;
++              return system(cmd);
+       }
+       /*
+@@ -869,7 +869,7 @@
+       {
+               perror("fork failed");
+-              return;
++              return -1;
+       }
+       /*
+@@ -894,7 +894,7 @@
+       {
+               fprintf(stderr, "Error from waitpid: %s", strerror(errno));
+-              return;
++              return -1;
+       }
+       if (WIFSIGNALED(status))
+@@ -902,6 +902,7 @@
+               fprintf(stderr, "pid %ld: killed by signal %d\n",
+                       (long) pid, WTERMSIG(status));
+       }
++      return WEXITSTATUS(status);
+ }
+@@ -958,7 +959,7 @@
+ }
+-void
++int
+ do_help(int argc, const char ** argv)
+ {
+       const CommandEntry *    entry;
+@@ -983,7 +984,7 @@
+                               printf("usage: %s %s\n", entry->name,
+                                       entry->usage);
+-                              return;
++                              return 0;
+                       }
+               }
+       }
+@@ -1000,10 +1001,11 @@
+                       printf("%-10s %s\n", entry->name, entry->usage);
+               }
+       }
++      return 0;
+ }
+-void
++int
+ do_alias(int argc, const char ** argv)
+ {
+       const char *    name;
+@@ -1019,7 +1021,7 @@
+               for (alias = aliasTable; count-- > 0; alias++)
+                       printf("%s\t%s\n", alias->name, alias->value);
+-              return;
++              return 0;
+       }
+       name = argv[1];
+@@ -1029,22 +1031,26 @@
+               alias = findAlias(name);
+               if (alias)
++              {
+                       printf("%s\n", alias->value);
++                      return 0;
++              }
+               else
++              {
+                       fprintf(stderr, "Alias \"%s\" is not defined\n", name);
+-
+-              return; 
++                      return 1;
++              }
+       }
+       if (strcmp(name, "alias") == 0)
+       {
+               fprintf(stderr, "Cannot alias \"alias\"\n");
+-              return;
++              return 1;
+       }
+       if (!makeString(argc - 2, argv + 2, buf, CMD_LEN))
+-              return;
++              return -1;
+       value = malloc(strlen(buf) + 1);
+@@ -1052,7 +1058,7 @@
+       {
+               fprintf(stderr, "No memory for alias value\n");
+-              return;
++              return 1;
+       }
+       strcpy(value, buf);
+@@ -1064,7 +1070,7 @@
+               free(alias->value);
+               alias->value = value;
+-              return;
++              return 0;
+       }
+       if ((aliasCount % ALIAS_ALLOC) == 0)
+@@ -1084,7 +1090,7 @@
+                       free(value);
+                       fprintf(stderr, "No memory for alias table\n");
+-                      return;
++                      return 1;
+               }
+               aliasTable = alias;
+@@ -1099,12 +1105,13 @@
+               free(value);
+               fprintf(stderr, "No memory for alias name\n");
+-              return;
++              return 1;
+       }
+       strcpy(alias->name, name);
+       alias->value = value;
+       aliasCount++;
++      return 0;
+ }
+@@ -1112,12 +1119,13 @@
+  * Build aliases for all of the built-in commands which start with a dash,
+  * using the names without the dash.
+  */
+-void
++int
+ do_aliasall(int argc, const char **argv)
+ {
+       const CommandEntry *    entry;
+       const char *            name;
+       const char *            newArgv[4];
++      int                     r;
+       for (entry = commandEntryTable; entry->name; entry++)
+       {
+@@ -1131,8 +1139,13 @@
+               newArgv[2] = name;
+               newArgv[3] = NULL;
+-              do_alias(3, newArgv);
++              r = do_alias(3, newArgv);
++              if (r != 0)
++              {
++                      return r;
++              }
+       }
++      return 0;
+ }
+@@ -1158,14 +1171,14 @@
+ }
+-void
++int
+ do_source(int argc, const char ** argv)
+ {
+-      readFile(argv[1]);
++      return readFile(argv[1]);
+ }
+-void
++int
+ do_exec(int argc, const char ** argv)
+ {
+       const char *    name;
+@@ -1182,17 +1195,18 @@
+       execvp(name, (char **) argv + 1);
+       perror(name);
++      return 127;
+ }
+-void
++int
+ do_prompt(int argc, const char ** argv)
+ {
+       char *  cp;
+       char    buf[CMD_LEN];
+       if (!makeString(argc - 1, argv + 1, buf, CMD_LEN))
+-              return;
++              return 1;
+       cp = malloc(strlen(buf) + 2);
+@@ -1200,7 +1214,7 @@
+       {
+               fprintf(stderr, "No memory for prompt\n");
+-              return;
++              return 1;
+       }
+       strcpy(cp, buf);
+@@ -1210,10 +1224,11 @@
+               free(prompt);
+       prompt = cp;
++      return 0;
+ }
+-void
++int
+ do_unalias(int argc, const char ** argv)
+ {
+       Alias * alias;
+@@ -1231,6 +1246,7 @@
+               alias->name = aliasTable[aliasCount].name;
+               alias->value = aliasTable[aliasCount].value;    
+       }
++      return 0;
+ }
+Index: sash-3.7/cmd_dd.c
+===================================================================
+--- sash-3.7.orig/cmd_dd.c     2010-04-04 12:29:35.236953933 +0200
++++ sash-3.7/cmd_dd.c  2010-04-04 12:32:57.081955729 +0200
+@@ -40,7 +40,7 @@
+ static        long    getNum(const char * cp);
+-void
++int
+ do_dd(int argc, const char ** argv)
+ {
+       const char *    str;
+@@ -62,6 +62,7 @@
+       long            outPartial;
+       char *          buf;
+       char            localBuf[BUF_SIZE];
++      int             r;
+       inFile = NULL;
+       outFile = NULL;
+@@ -69,6 +70,7 @@
+       skipVal = 0;
+       blockSize = 512;
+       count = -1;
++      r = 0;
+       while (--argc > 0)
+       {
+@@ -79,7 +81,7 @@
+               {
+                       fprintf(stderr, "Bad dd argument\n");
+-                      return;
++                      return 1;
+               }
+               *cp++ = '\0';
+@@ -97,7 +99,7 @@
+                               {
+                                       fprintf(stderr, "Multiple input files illegal\n");
+-                                      return;
++                                      return 1;
+                               }
+       
+                               inFile = cp;
+@@ -108,7 +110,7 @@
+                               {
+                                       fprintf(stderr, "Multiple output files illegal\n");
+-                                      return;
++                                      return 1;
+                               }
+                               outFile = cp;
+@@ -121,7 +123,7 @@
+                               {
+                                       fprintf(stderr, "Bad block size value\n");
+-                                      return;
++                                      return 1;
+                               }
+                               break;
+@@ -133,7 +135,7 @@
+                               {
+                                       fprintf(stderr, "Bad count value\n");
+-                                      return;
++                                      return 1;
+                               }
+                               break;
+@@ -145,7 +147,7 @@
+                               {
+                                       fprintf(stderr, "Bad seek value\n");
+-                                      return;
++                                      return 1;
+                               }
+                               break;
+@@ -157,7 +159,7 @@
+                               {
+                                       fprintf(stderr, "Bad skip value\n");
+-                                      return;
++                                      return 1;
+                               }
+                               break;
+@@ -165,7 +167,7 @@
+                       default:
+                               fprintf(stderr, "Unknown dd parameter\n");
+-                              return;
++                              return 1;
+               }
+       }
+@@ -173,14 +175,14 @@
+       {
+               fprintf(stderr, "No input file specified\n");
+-              return;
++              return 1;
+       }
+       if (outFile == NULL)
+       {
+               fprintf(stderr, "No output file specified\n");
+-              return;
++              return 1;
+       }
+       buf = localBuf;
+@@ -193,7 +195,7 @@
+               {
+                       fprintf(stderr, "Cannot allocate buffer\n");
+-                      return;
++                      return 1;
+               }
+       }
+@@ -211,7 +213,7 @@
+               if (buf != localBuf)
+                       free(buf);
+-              return;
++              return 1;
+       }
+       outFd = creat(outFile, 0666);
+@@ -224,7 +226,7 @@
+               if (buf != localBuf)
+                       free(buf);
+-              return;
++              return 1;
+       }
+       if (skipVal)
+@@ -238,12 +240,14 @@
+                               if (inCc < 0)
+                               {
+                                       perror(inFile);
++                                      r = 1;
+                                       goto cleanup;
+                               }
+                               if (inCc == 0)
+                               {
+                                       fprintf(stderr, "End of file while skipping\n");
++                                      r = 1;
+                                       goto cleanup;
+                               }
+                       }
+@@ -255,7 +259,7 @@
+               if (lseek(outFd, seekVal * blockSize, 0) < 0)
+               {
+                       perror(outFile);
+-
++                      r = 1;
+                       goto cleanup;
+               }
+       }
+@@ -274,6 +278,7 @@
+               if (intFlag)
+               {
+                       fprintf(stderr, "Interrupted\n");
++                      r = 1;
+                       goto cleanup;
+               }
+@@ -284,6 +289,7 @@
+                       if (outCc < 0)
+                       {
+                               perror(outFile);
++                              r = 1;
+                               goto cleanup;
+                       }
+@@ -303,7 +309,10 @@
+       close(inFd);
+       if (close(outFd) < 0)
++      {
+               perror(outFile);
++              r = 1;
++      }
+       if (buf != localBuf)
+               free(buf);
+@@ -311,6 +320,7 @@
+       printf("%ld+%ld records in\n", inFull, inPartial);
+       printf("%ld+%ld records out\n", outFull, outPartial);
++      return r;
+ }
+Index: sash-3.7/cmd_ed.c
+===================================================================
+--- sash-3.7.orig/cmd_ed.c     2010-04-04 12:33:11.076954419 +0200
++++ sash-3.7/cmd_ed.c  2010-04-04 12:34:01.244953056 +0200
+@@ -60,11 +60,11 @@
+       (const LINE * lp, const char * str, LEN len, LEN offset);
+-void
++int
+ do_ed(int argc, const char ** argv)
+ {
+       if (!initEdit())
+-              return;
++              return 1;
+       if (argc > 1)
+       {
+@@ -75,14 +75,14 @@
+                       fprintf(stderr, "No memory\n");
+                       termEdit();
+-                      return;
++                      return 1;
+               }
+               if (!readLines(fileName, 1))
+               {
+                       termEdit();
+-                      return;
++                      return 1;
+               }
+               if (lastNum)
+@@ -94,6 +94,7 @@
+       doCommands();
+       termEdit();
++      return 0;
+ }
+Index: sash-3.7/cmd_grep.c
+===================================================================
+--- sash-3.7.orig/cmd_grep.c   2010-04-04 12:34:30.320951181 +0200
++++ sash-3.7/cmd_grep.c        2010-04-04 12:38:36.524986801 +0200
+@@ -15,7 +15,7 @@
+       (const char * string, const char * word, BOOL ignoreCase);
+-void
++int
+ do_grep(int argc, const char ** argv)
+ {
+       FILE *          fp;
+@@ -27,7 +27,9 @@
+       BOOL            tellLine;
+       long            line;
+       char            buf[BUF_SIZE];
++      int             r;
++      r = 1;
+       ignoreCase = FALSE;
+       tellLine = FALSE;
+@@ -52,7 +54,7 @@
+                       default:
+                               fprintf(stderr, "Unknown option\n");
+-                              return;
++                              return 1;
+               }
+       }
+@@ -70,6 +72,7 @@
+               if (fp == NULL)
+               {
+                       perror(name);
++                      r = 1;
+                       continue;
+               }
+@@ -82,7 +85,7 @@
+                       {
+                               fclose(fp);
+-                              return;
++                              return 1;
+                       }
+                       line++;
+@@ -94,6 +97,7 @@
+                       if (search(buf, word, ignoreCase))
+                       {
++                              r = 0;
+                               if (tellName)
+                                       printf("%s: ", name);
+@@ -109,6 +113,7 @@
+               fclose(fp);
+       }
++      return r;
+ }
+Index: sash-3.7/cmd_ls.c
+===================================================================
+--- sash-3.7.orig/cmd_ls.c     2010-04-04 12:38:46.364975686 +0200
++++ sash-3.7/cmd_ls.c  2010-04-04 12:40:32.424951492 +0200
+@@ -59,7 +59,7 @@
+ static        void    clearListNames(void);
+-void
++int
+ do_ls(int argc, const char ** argv)
+ {
+       const char *    cp;
+@@ -72,6 +72,7 @@
+       struct dirent * dp;
+       char            fullName[PATH_LEN];
+       struct  stat    statBuf;
++      int             r;
+       static const char *     def[] = {"."};
+@@ -105,7 +106,7 @@
+                       default:
+                               fprintf(stderr, "Unknown option -%c\n", cp[-1]);
+-                              return;
++                              return 1;
+               }
+       }
+@@ -153,7 +154,7 @@
+               if ((flags & LSF_DIR) || !isDirectory(argv[i]))
+               {
+                       if (!addListName(argv[i]))
+-                              return;
++                              return 1;
+               }
+       }
+@@ -167,7 +168,7 @@
+        * If directories were being listed as themselves, then we are done.
+        */
+       if (flags & LSF_DIR)
+-              return;
++              return r;
+       /*
+        * Now iterate over the file names processing the directories.
+@@ -180,6 +181,7 @@
+               if (LSTAT(name, &statBuf) < 0)
+               {
+                       perror(name);
++                      r = 1;
+                       continue;
+               }
+@@ -226,7 +228,7 @@
+                       {
+                               closedir(dirp);
+-                              return;
++                              return 1;
+                       }
+               }
+@@ -239,6 +241,7 @@
+               listAllFiles(flags, displayWidth);
+               clearListNames();
+       }
++      return r;
+ }
+Index: sash-3.7/cmd_tar.c
+===================================================================
+--- sash-3.7.orig/cmd_tar.c    2010-04-04 12:40:41.588964080 +0200
++++ sash-3.7/cmd_tar.c 2010-04-04 12:41:56.960954363 +0200
+@@ -119,7 +119,7 @@
+-void
++int
+ do_tar(int argc, const char ** argv)
+ {
+       const char *    options;
+@@ -131,7 +131,7 @@
+       {
+               fprintf(stderr, "Too few arguments for tar\n");
+-              return;
++              return 1;
+       }
+       extractFlag = FALSE;
+@@ -158,7 +158,7 @@
+                               {
+                                       fprintf(stderr, "Only one 'f' option allowed\n");
+-                                      return;
++                                      return 1;
+                               }
+                               tarName = *argv++;
+@@ -185,7 +185,7 @@
+                       default:
+                               fprintf(stderr, "Unknown tar flag '%c'\n", *options);
+-                              return;
++                              return 1;
+               }
+       }
+@@ -196,14 +196,14 @@
+       {
+               fprintf(stderr, "Exactly one of 'c', 'x' or 't' must be specified\n");
+-              return;
++              return 1;
+       }
+       if (tarName == NULL)
+       {
+               fprintf(stderr, "The 'f' flag must be specified\n");
+-              return;
++              return 1;
+       }
+       /*
+@@ -211,9 +211,9 @@
+        * command line arguments as the list of files to process.
+        */
+       if (createFlag)
+-              writeTarFile(argc, argv);
++              return writeTarFile(argc, argv);
+       else
+-              readTarFile(argc, argv);
++              return readTarFile(argc, argv);
+ }
+@@ -221,7 +221,7 @@
+  * Read a tar file and extract or list the specified files within it.
+  * If the list is empty than all files are extracted or listed.
+  */
+-static void
++static int
+ readTarFile(int fileCount, const char ** fileTable)
+ {
+       const char *    cp;
+@@ -250,7 +250,7 @@
+       {
+               perror(tarName);
+-              return;
++              return 1;
+       }
+       /*
diff --git a/debian/patches/buildsystem b/debian/patches/buildsystem
new file mode 100644 (file)
index 0000000..ee0ed89
--- /dev/null
@@ -0,0 +1,28 @@
+Index: sash-3.7/Makefile
+===================================================================
+--- sash-3.7.orig/Makefile     2010-04-04 10:13:55.176949485 +0200
++++ sash-3.7/Makefile  2010-04-04 10:14:03.300968030 +0200
+@@ -13,13 +13,12 @@
+ HAVE_BSD_MOUNT                = 0
+ MOUNT_TYPE            = '"ext3"'
+-
+-CFLAGS = -O3 -Wall -Wmissing-prototypes \
+-      -DHAVE_GZIP=$(HAVE_GZIP) \
++DEFS = -DHAVE_GZIP=$(HAVE_GZIP) \
+       -DHAVE_LINUX_ATTR=$(HAVE_LINUX_ATTR) \
+       -DHAVE_LINUX_MOUNT=$(HAVE_LINUX_MOUNT) \
+       -DHAVE_BSD_MOUNT=$(HAVE_BSD_MOUNT) \
+       -DMOUNT_TYPE=$(MOUNT_TYPE)
++CFLAGS = -O3 -Wall -Wmissing-prototypes -g $(DEFS)
+ LDFLAGS = -static -s
+ LIBS = -lz
+@@ -43,4 +42,7 @@
+       cp sash $(BINDIR)/sash
+       cp sash.1 $(MANDIR)/sash.1
++%.o: %.c
++      $(CC) $(CFLAGS) $(DEFS) -c $<
++
+ $(OBJS):      sash.h
diff --git a/debian/patches/debian-changes-3.7-10 b/debian/patches/debian-changes-3.7-10
new file mode 100644 (file)
index 0000000..9474294
--- /dev/null
@@ -0,0 +1,1324 @@
+Description: Upstream changes introduced in version 3.7-10
+ This patch has been created by dpkg-source during the package build.
+ Here's the last changelog entry, hopefully it gives details on why
+ those changes were made:
+ .
+ sash (3.7-10) unstable; urgency=low
+ .
+   * Switch to 3.0 (quilt) as the source format and convert patches.
+   * Fix up debian/patches/touch_error_handling to actually update the
+     timestamp of the file, something that has been broken for more than
+     ten years.
+   * Add kFreeBSD build fixes from Axel Beckert. Closes: #565539
+   * When exiting the shell, use the exit status of the last command as our
+     exit status.  Closes: #281728
+ .
+ The person named in the Author field signed this changelog entry.
+Author: Tollef Fog Heen <tfheen@debian.org>
+Bug-Debian: http://bugs.debian.org/281728
+Bug-Debian: http://bugs.debian.org/565539
+
+---
+The information above should follow the Patch Tagging Guidelines, please
+checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
+are templates for supplementary fields that you might want to add:
+
+Origin: <vendor|upstream|other>, <url of original patch>
+Bug: <url in upstream bugtracker>
+Bug-Debian: http://bugs.debian.org/<bugnumber>
+Forwarded: <no|not-needed|url proving that it has been forwarded>
+Reviewed-By: <name and email of someone who approved the patch>
+Last-Update: <YYYY-MM-DD>
+
+--- /dev/null
++++ sash-3.7/sash.c.old
+@@ -0,0 +1,1289 @@
++/*
++ * Copyright (c) 2004 by David I. Bell
++ * Permission is granted to use, distribute, or modify this source,
++ * provided that this copyright notice remains intact.
++ *
++ * Stand-alone shell for system maintainance for Linux.
++ * This program should NOT be built using shared libraries.
++ */
++
++#include <sys/types.h>
++#include <sys/wait.h>
++#include <signal.h>
++#include <errno.h>
++
++#include "sash.h"
++
++
++static const char * const     version = "3.7";
++
++
++/*
++ * The special maximum argument value which means that there is
++ * no limit to the number of arguments on the command line.
++ */
++#define       INFINITE_ARGS   0x7fffffff
++
++
++/*
++ * One entry of the command table.
++ */
++typedef struct
++{
++      const char *    name;
++      void            (*func)(int argc, const char ** argv);
++      int             minArgs;
++      int             maxArgs;
++      const char *    description;
++      const char *    usage;
++} CommandEntry;
++
++
++/*
++ * The table of built-in commands.
++ * This is terminated wih an entry containing NULL values.
++ */
++static const CommandEntry     commandEntryTable[] =
++{
++      {
++              "alias",        do_alias,       1,      INFINITE_ARGS,
++              "Define a command alias",
++              "[name [command]]"
++      },
++
++      {
++              "aliasall",     do_aliasall,    1,      1,
++              "Define aliases for all of the build-in commands",
++              ""
++      },
++
++      {
++              "-ar",          do_ar,          3,      INFINITE_ARGS,
++              "Extract or list files from an AR file",
++              "[txp]v arFileName fileName ..."
++      },
++
++      {
++              "cd",           do_cd,          1,      2,
++              "Change current directory",
++              "[dirName]"
++      },
++
++#if   HAVE_LINUX_ATTR
++      {
++              "-chattr",      do_chattr,      3,      INFINITE_ARGS,
++              "Change ext2 file attributes",
++              "[+i] [-i] [+a] [-a] fileName ..."
++      },
++#endif
++
++      {
++              "-chgrp",       do_chgrp,       3,      INFINITE_ARGS,
++              "Change the group id of some files",
++              "gid fileName ..."
++      },
++
++      {
++              "-chmod",       do_chmod,       3,      INFINITE_ARGS,
++              "Change the protection of some files",
++              "mode fileName ..."
++      },
++
++      {
++              "-chown",       do_chown,       3,      INFINITE_ARGS,
++              "Change the owner id of some files",
++              "uid fileName ..."
++      },
++
++      {
++              "-cmp",         do_cmp,         3,      3,
++              "Compare two files for equality",
++              "fileName1 fileName2"
++      },
++
++      {
++              "-cp",          do_cp,          3,      INFINITE_ARGS,
++              "Copy files",
++              "srcName ... destName"
++      },
++
++      {
++              "-dd",          do_dd,          3,      INFINITE_ARGS,
++              "Copy data between two files",
++              "if=name of=name [bs=n] [count=n] [skip=n] [seek=n]"
++      },
++
++      {
++              "-echo",        do_echo,        1,      INFINITE_ARGS,
++              "Echo the arguments",
++              "[args] ..."
++      },
++
++      {
++              "-ed",          do_ed,          1,      2,
++              "Edit a fileName using simple line mode commands",
++              "[fileName]"
++      },
++
++      {
++              "exec",         do_exec,        2,      INFINITE_ARGS,
++              "Execute another program in place of this sash process",
++              "fileName [args]"
++      },
++
++      {
++              "exit",         do_exit,        1,      2,
++              "Exit from sash",
++              "[exit value]"
++      },
++
++      {
++              "-file",        do_file,        1,      INFINITE_ARGS,
++              "Describe information about files",
++              "fileName ..."
++      },
++
++      {
++              "-find",        do_find,        2,      INFINITE_ARGS,
++              "Find files in a directory tree meeting some conditions",
++              "dirName [-xdev] [-type chars] [-name pattern] [-size minSize]"
++      },
++
++      {
++              "-grep",        do_grep,        3,      INFINITE_ARGS,
++              "Look for lines containing a word in some files",
++              "[-in] word fileName ..."
++      },
++
++#if   HAVE_GZIP
++      {
++              "-gunzip",      do_gunzip,      2,      INFINITE_ARGS,
++              "Uncompress files which were saved in GZIP or compress format",
++              "fileName ... [-o outputPath]"
++      },
++
++      {
++              "-gzip",        do_gzip,        2,      INFINITE_ARGS,
++              "Compress files into GZIP format",
++              "fileName ... [-o outputPath]"
++      },
++#endif
++
++      {
++              "help",         do_help,        1,      2,
++              "Print help about a command",
++              "[word]"
++      },
++
++      {
++              "-kill",        do_kill,        2,      INFINITE_ARGS,
++              "Send a signal to the specified process",
++              "[-sig] pid ..."
++      },
++
++      {
++              "-ln",          do_ln,          3,      INFINITE_ARGS,
++              "Link one fileName to another",
++              "[-s] srcName ... destName"
++      },
++
++      {
++              "-ls",          do_ls,          1,      INFINITE_ARGS,
++              "List information about files or directories",
++              "[-lidFC] fileName ..."
++      },
++
++#if   HAVE_LINUX_ATTR
++      {
++              "-lsattr",      do_lsattr,      2,      INFINITE_ARGS,
++              "List ext2 file attributes",
++              "fileName ..."
++      },
++#endif
++
++      {
++              "-mkdir",       do_mkdir,       2,      INFINITE_ARGS,
++              "Create a directory",
++              "dirName ..."
++      },
++
++      {
++              "-mknod",       do_mknod,       5,      5,
++              "Create a special type of file",
++              "fileName type major minor"
++      },
++
++      {
++              "-more",        do_more,        2,      INFINITE_ARGS,
++              "Type file contents page by page",
++              "fileName ..."
++      },
++
++      {
++              "-mount",       do_mount,       3,      INFINITE_ARGS,
++              "Mount or remount a filesystem on a directory",
++#if   HAVE_LINUX_MOUNT
++              "[-t type] [-r] [-s] [-e] [-m] devName dirName"
++#elif HAVE_BSD_MOUNT
++              "[-t type] [-r] [-s] [-e] devName dirName"
++#else
++              "[-t type] devName dirName"
++#endif
++      },
++
++      {
++              "-mv",          do_mv,          3,      INFINITE_ARGS,
++              "Move or rename files",
++              "srcName ... destName"
++      },
++
++      {
++              "-printenv",    do_printenv,    1,      2,
++              "Print environment variables",
++              "[name]"
++      },
++
++      {
++              "prompt",       do_prompt,      2,      INFINITE_ARGS,
++              "Set the prompt string for sash",
++              "string"
++      },
++
++      {
++              "-pwd",         do_pwd,         1,      1,
++              "Print the current working directory",
++              ""
++      },
++
++      {
++              "quit",         do_exit,        1,      1,
++              "Exit from sash",
++              ""
++      },
++
++      {
++              "-rm",          do_rm,          2,      INFINITE_ARGS,
++              "Remove the specified files",
++              "fileName ..."
++      },
++
++      {
++              "-rmdir",       do_rmdir,       2,      INFINITE_ARGS,
++              "Remove the specified empty directories",
++              "dirName ..."
++      },
++
++      {
++              "setenv",       do_setenv,      3,      3,
++              "Set an environment variable value",
++              "name value"
++      },
++
++      {
++              "source",       do_source,      2,      2,
++              "Read commands from the specified file",
++              "fileName"
++      },
++
++      {
++              "-sum",         do_sum,         2,      INFINITE_ARGS,
++              "Calculate checksums of the specified files",
++              "fileName ..."
++      },
++
++      {
++              "-sync",        do_sync,        1,      1,
++              "Sync the disks to force cached data to them",
++              ""
++      },
++
++      {
++              "-tar",         do_tar,         2,      INFINITE_ARGS,
++              "Create, extract, or list files from a TAR file",
++              "[cxtv]f tarFileName fileName ..."
++      },
++
++      {
++              "-touch",       do_touch,       2,      INFINITE_ARGS,
++              "Update times or create the specified files",
++              "fileName ..."
++      },
++
++      {
++              "umask",        do_umask,       1,      2,
++              "Set the umask value for file protections",
++              "[mask]"
++      },
++
++      {
++#if   HAVE_BSD_MOUNT
++              "-umount",      do_umount,      2,      3,
++              "Unmount a filesystem",
++              "[-f] fileName"
++#else
++              "-umount",      do_umount,      2,      2,
++              "Unmount a filesystem",
++              "fileName"
++#endif
++      },
++
++      {
++              "unalias",      do_unalias,     2,      2,
++              "Remove a command alias",
++              "name"
++      },
++
++      {
++              "-where",       do_where,       2,      2,
++              "Type the location of a program",
++              "program"
++      },
++
++      {
++              NULL,           0,              0,      0,
++              NULL,
++              NULL
++      }
++};
++
++
++/*
++ * The definition of an command alias.
++ */
++typedef struct
++{
++      char *  name;
++      char *  value;
++} Alias;
++
++
++/*
++ * Local data.
++ */
++static        Alias * aliasTable;
++static        int     aliasCount;
++
++static        FILE *  sourcefiles[MAX_SOURCE];
++static        int     sourceCount;
++
++static        BOOL    intCrlf = TRUE;
++static        char *  prompt;
++
++
++/*
++ * Local procedures.
++ */
++static        void    catchInt(int);
++static        void    catchQuit(int);
++static        int     readFile(const char * name);
++static        int     command(const char * cmd);
++static        BOOL    tryBuiltIn(const char * cmd);
++static        int     runCmd(const char * cmd);
++static        void    childProcess(const char * cmd);
++static        void    showPrompt(void);
++static        void    usage(void);
++static        Alias * findAlias(const char * name);
++
++
++/*
++ * Global interrupt flag.
++ */
++BOOL  intFlag;
++
++
++int
++main(int argc, const char ** argv)
++{
++      const char *    cp;
++      const char *    singleCommand;
++      const char *    commandFile;
++      BOOL            quietFlag;
++      BOOL            aliasFlag;
++        BOOL          interactiveFlag;
++      char            buf[PATH_LEN];
++
++      singleCommand = NULL;
++      commandFile = NULL;
++      quietFlag = FALSE;
++      aliasFlag = FALSE;
++        interactiveFlag = FALSE;
++
++      /*
++       * Look for options.
++       */
++      argv++;
++      argc--;
++
++      while ((argc > 0) && (**argv == '-'))
++      {
++              cp = *argv++ + 1;
++              argc--;
++
++              while (*cp) switch (*cp++)
++              {
++                        case '-':
++                                /*
++                                 * Ignore.  This is so that we can be
++                                 * run from login.
++                                 */
++                                break;
++                      case 'c':
++                              /*
++                               * Execute specified command.
++                               */
++                              if ((argc != 1) || singleCommand || interactiveFlag)
++                                      usage();
++
++                              singleCommand = *argv++;
++                              argc--;
++
++                              break;
++
++                      case 'f':
++                              /*
++                               * Execute commands from file.
++                               * This is used for sash script files.
++                               * The quiet flag is also set.
++                               */
++                              if ((argc != 1) || commandFile)
++                                      usage();
++
++                              quietFlag = TRUE;
++                              commandFile = *argv++;
++                              argc--;
++
++                              break;
++
++                      case 'i':
++                              /*
++                               * Be an interactive shell
++                               * ..is a no-op, but some contexts require this
++                               * ..interactiveFlag is to avoid -ic as a legacy
++                               */
++                               if (singleCommand)
++                                      usage();
++                               
++                               interactiveFlag = TRUE;
++                               break;
++                               
++                      case 'p':
++                              /*
++                               * Set the prompt string.
++                               */
++                              if ((argc <= 0) || (**argv == '-'))
++                                      usage();
++
++                              if (prompt)
++                                      free(prompt);
++
++                              prompt = strdup(*argv++);
++                              argc--;
++
++                              break;
++
++                      case 'q':
++                              quietFlag = TRUE;
++                              break;
++
++                      case 'a':
++                              aliasFlag = TRUE;
++                              break;
++
++                      case 'h':
++                      case '?':
++                              usage();
++                              break;
++
++                      default:
++                              fprintf(stderr, "Unknown option -%c\n", cp[-1]);
++
++                              return 1;
++              }
++      }
++
++      /*
++       * No more arguments are allowed.
++       */
++      if (argc > 0)
++              usage();
++
++      /*
++       * Default our path if it is not set.
++       */
++      if (getenv("PATH") == NULL)
++              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 we are to execute a single command, then do so and exit.
++       */
++      if (singleCommand)
++      {
++              return command(singleCommand);
++      }
++
++      /*
++       * Print a hello message unless we are told to be silent.
++       */
++      if (!quietFlag && isatty(STDIN))
++      {
++              printf("Stand-alone shell (version %s)\n", version);
++
++              if (aliasFlag)
++                      printf("Built-in commands are aliased to standard commands\n");
++      }
++
++      signal(SIGINT, catchInt);
++      signal(SIGQUIT, catchQuit);
++
++      /*
++       * Execute the user's alias file if present.
++       */
++      cp = getenv("HOME");
++
++      if (cp)
++      {
++              strcpy(buf, cp);
++              strcat(buf, "/");
++              strcat(buf, ".aliasrc");
++
++              if ((access(buf, 0) == 0) || (errno != ENOENT))
++                      readFile(buf);
++      }
++
++      /*
++       * Read commands from stdin or from a command file.
++       */
++      return readFile(commandFile);
++
++}
++
++
++/*
++ * Read commands from the specified file.
++ * A null name pointer indicates to read from stdin.
++ */
++static int
++readFile(const char * name)
++{
++      FILE *  fp;
++      int     cc;
++      BOOL    ttyFlag;
++      char    buf[CMD_LEN];
++      int     r = 0;
++
++      if (sourceCount >= MAX_SOURCE)
++      {
++              fprintf(stderr, "Too many source files\n");
++
++              return 1;
++      }
++
++      fp = stdin;
++
++      if (name)
++      {
++              fp = fopen(name, "r");
++
++              if (fp == NULL)
++              {
++                      perror(name);
++
++                      return 1;
++              }
++      }
++
++      sourcefiles[sourceCount++] = fp;
++
++      ttyFlag = isatty(fileno(fp));
++
++      while (TRUE)
++      {
++              if (ttyFlag)
++                      showPrompt();
++
++              if (intFlag && !ttyFlag && (fp != stdin))
++              {
++                      fclose(fp);
++                      sourceCount--;
++
++                      return 1;
++              }
++      
++              if (fgets(buf, CMD_LEN - 1, fp) == NULL)
++              {
++                      if (ferror(fp) && (errno == EINTR))
++                      {
++                              clearerr(fp);
++
++                              continue;
++                      }
++
++                      break;
++              }
++
++              cc = strlen(buf);
++
++              if (buf[cc - 1] == '\n')
++                      cc--;
++
++              while ((cc > 0) && isBlank(buf[cc - 1]))
++                      cc--;
++
++              buf[cc] = '\0';
++
++              r = command(buf);
++      }
++
++      if (ferror(fp))
++      {
++              perror("Reading command line");
++
++              if (fp == stdin)
++                      exit(1);
++      }
++
++      clearerr(fp);
++
++      if (fp != stdin)
++              fclose(fp);
++
++      sourceCount--;
++      return r;
++}
++
++
++/*
++ * Parse and execute one null-terminated command line string.
++ * This breaks the command line up into words, checks to see if the
++ * command is an alias, and expands wildcards.
++ */
++static int
++command(const char * cmd)
++{
++      const char *    endCmd;
++      const Alias *   alias;
++      char            newCommand[CMD_LEN];
++      char            cmdName[CMD_LEN];
++
++      /*
++       * Rest the interrupt flag and free any memory chunks that
++       * were allocated by the previous command.
++       */
++      intFlag = FALSE;
++
++      freeChunks();
++
++      /*
++       * Skip leading blanks.
++       */
++      while (isBlank(*cmd))
++              cmd++;
++
++      /*
++       * If the command is empty or is a comment then ignore it.
++       */
++      if ((*cmd == '\0') || (*cmd == '#'))
++              return 0;
++
++      /*
++       * 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++;
++
++      memcpy(cmdName, cmd, endCmd - cmd);
++
++      cmdName[endCmd - cmd] = '\0';
++
++      /*
++       * Search for the command name in the alias table.
++       * If it is found, then replace the command name with
++       * the alias value, and append the current command
++       * line arguments to that.
++       */
++      alias = findAlias(cmdName);
++
++      if (alias)
++      {
++              strcpy(newCommand, alias->value);
++              strcat(newCommand, endCmd);
++
++              cmd = newCommand;
++      }
++
++      /*
++       * Now look for the command in the builtin table, and execute
++       * the command if found.
++       */
++      if (tryBuiltIn(cmd))
++              return 0; /* This is a blatant lie */
++
++      /*
++       * The command is not a built-in, so run the program along
++       * the PATH list.
++       */
++      return runCmd(cmd);
++}
++
++
++/*
++ * Try to execute a built-in command.
++ * Returns TRUE if the command is a built in, whether or not the
++ * command succeeds.  Returns FALSE if this is not a built-in command.
++ */
++static BOOL
++tryBuiltIn(const char * cmd)
++{
++      const char *            endCmd;
++      const CommandEntry *    entry;
++      int                     argc;
++      const char **           argv;
++      char                    cmdName[CMD_LEN];
++
++      /*
++       * 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++;
++
++      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++)
++      {
++              if (strcmp(entry->name, cmdName) == 0)
++                      break;
++      }
++
++      /*
++       * If the command is not a built-in, return indicating that.
++       */
++      if (entry->name == NULL)
++              return FALSE;
++
++      /*
++       * The command is a built-in.
++       * Break the command up into arguments and expand wildcards.
++       */
++      if (!makeArgs(cmd, &argc, &argv))
++              return TRUE;
++
++      /*
++       * Give a usage string if the number of arguments is too large
++       * or too small.
++       */
++      if ((argc < entry->minArgs) || (argc > entry->maxArgs))
++      {
++              fprintf(stderr, "usage: %s %s\n", entry->name, entry->usage);
++
++              return TRUE;
++      }
++
++      /*
++       * Call the built-in function with the argument list.
++       */
++      entry->func(argc, argv);
++
++      return TRUE;
++}
++
++
++/*
++ * Execute the specified command either by forking and executing
++ * the program ourself, or else by using the shell.
++ */
++static int
++runCmd(const char * cmd)
++{
++      const char *    cp;
++      BOOL            magic;
++      pid_t           pid;
++      int             status;
++
++      /*
++       * Check the command for any magic shell characters
++       * except for quoting.
++       */
++      magic = FALSE;
++
++      for (cp = cmd; *cp; cp++)
++      {
++              if ((*cp >= 'a') && (*cp <= 'z'))
++                      continue;
++
++              if ((*cp >= 'A') && (*cp <= 'Z'))
++                      continue;
++
++              if (isDecimal(*cp))
++                      continue;
++
++              if (isBlank(*cp))
++                      continue;
++
++              if ((*cp == '.') || (*cp == '/') || (*cp == '-') ||
++                      (*cp == '+') || (*cp == '=') || (*cp == '_') ||
++                      (*cp == ':') || (*cp == ',') || (*cp == '\'') ||
++                      (*cp == '"'))
++              {
++                      continue;
++              }
++
++              magic = TRUE;
++      }
++
++      /*
++       * If there were any magic characters used then run the
++       * command using the shell.
++       */
++      if (magic)
++      {
++              return system(cmd);
++      }
++
++      /*
++       * No magic characters were in the command, so we can do the fork
++       * and exec ourself.
++       */
++      pid = fork();
++
++      if (pid < 0)
++      {
++              perror("fork failed");
++
++              return -1;
++      }
++
++      /*
++       * If we are the child process, then go execute the program.
++       */
++      if (pid == 0)
++              childProcess(cmd);
++
++      /*
++       * We are the parent process.
++       * Wait for the child to complete.
++       */
++      status = 0;
++      intCrlf = FALSE;
++
++      while (((pid = waitpid(pid, &status, 0)) < 0) && (errno == EINTR))
++              ;
++
++      intCrlf = TRUE;
++
++      if (pid < 0)
++      {
++              fprintf(stderr, "Error from waitpid: %s", strerror(errno));
++
++              return -1;
++      }
++
++      if (WIFSIGNALED(status))
++      {
++              fprintf(stderr, "pid %ld: killed by signal %d\n",
++                      (long) pid, WTERMSIG(status));
++      }
++      return WEXITSTATUS(status);
++}
++
++
++/*
++ * Here as the child process to try to execute the command.
++ * This is only called if there are no meta-characters in the command.
++ * This procedure never returns.
++ */
++static void
++childProcess(const char * cmd)
++{
++      const char **   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);
++      }
++
++      /*
++       * Try to execute the program directly.
++       */
++      execvp(argv[0], (char **) 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);
++      }
++
++      /*
++       * There was something else wrong, complain and exit.
++       */
++      perror(argv[0]);
++      exit(1);
++}
++
++
++void
++do_help(int argc, const char ** argv)
++{
++      const CommandEntry *    entry;
++      const char *            str;
++
++      str = NULL;
++
++      if (argc == 2)
++              str = argv[1];
++
++      /*
++       * Check for an exact match, in which case describe the program.
++       */
++      if (str)
++      {
++              for (entry = commandEntryTable; entry->name; entry++)
++              {
++                      if (strcmp(str, entry->name) == 0)
++                      {
++                              printf("%s\n", entry->description);
++
++                              printf("usage: %s %s\n", entry->name,
++                                      entry->usage);
++
++                              return;
++                      }
++              }
++      }
++
++      /*
++       * Print short information about commands which contain the
++       * specified word.
++       */
++      for (entry = commandEntryTable; entry->name; entry++)
++      {
++              if ((str == NULL) || (strstr(entry->name, str) != NULL) ||
++                      (strstr(entry->usage, str) != NULL))
++              {
++                      printf("%-10s %s\n", entry->name, entry->usage);
++              }
++      }
++}
++
++
++void
++do_alias(int argc, const char ** argv)
++{
++      const char *    name;
++      char *          value;
++      Alias *         alias;
++      int             count;
++      char            buf[CMD_LEN];
++
++      if (argc < 2)
++      {
++              count = aliasCount;
++
++              for (alias = aliasTable; count-- > 0; alias++)
++                      printf("%s\t%s\n", alias->name, alias->value);
++
++              return;
++      }
++
++      name = argv[1];
++
++      if (argc == 2)
++      {
++              alias = findAlias(name);
++
++              if (alias)
++                      printf("%s\n", alias->value);
++              else
++                      fprintf(stderr, "Alias \"%s\" is not defined\n", name);
++
++              return; 
++      }
++
++      if (strcmp(name, "alias") == 0)
++      {
++              fprintf(stderr, "Cannot alias \"alias\"\n");
++
++              return;
++      }
++
++      if (!makeString(argc - 2, argv + 2, buf, CMD_LEN))
++              return;
++
++      value = malloc(strlen(buf) + 1);
++
++      if (value == NULL)
++      {
++              fprintf(stderr, "No memory for alias value\n");
++
++              return;
++      }
++
++      strcpy(value, buf);
++
++      alias = findAlias(name);
++
++      if (alias)
++      {
++              free(alias->value);
++              alias->value = value;
++
++              return;
++      }
++
++      if ((aliasCount % ALIAS_ALLOC) == 0)
++      {
++              count = aliasCount + ALIAS_ALLOC;
++
++              if (aliasTable)
++              {
++                      alias = (Alias *) realloc(aliasTable,
++                              sizeof(Alias) * count);
++              }
++              else
++                      alias = (Alias *) malloc(sizeof(Alias) * count);
++
++              if (alias == NULL)
++              {
++                      free(value);
++                      fprintf(stderr, "No memory for alias table\n");
++
++                      return;
++              }
++
++              aliasTable = alias;
++      }
++
++      alias = &aliasTable[aliasCount];
++
++      alias->name = malloc(strlen(name) + 1);
++
++      if (alias->name == NULL)
++      {
++              free(value);
++              fprintf(stderr, "No memory for alias name\n");
++
++              return;
++      }
++
++      strcpy(alias->name, name);
++      alias->value = value;
++      aliasCount++;
++}
++
++
++/*
++ * Build aliases for all of the built-in commands which start with a dash,
++ * using the names without the dash.
++ */
++void
++do_aliasall(int argc, const char **argv)
++{
++      const CommandEntry *    entry;
++      const char *            name;
++      const char *            newArgv[4];
++
++      for (entry = commandEntryTable; entry->name; entry++)
++      {
++              name = entry->name;
++
++              if (*name != '-')
++                      continue;
++
++              newArgv[0] = "alias";
++              newArgv[1] = name + 1;
++              newArgv[2] = name;
++              newArgv[3] = NULL;
++
++              do_alias(3, newArgv);
++      }
++}
++
++
++/*
++ * Look up an alias name, and return a pointer to it.
++ * Returns NULL if the name does not exist.
++ */
++static Alias *
++findAlias(const char * name)
++{
++      Alias * alias;
++      int     count;
++
++      count = aliasCount;
++
++      for (alias = aliasTable; count-- > 0; alias++)
++      {
++              if (strcmp(name, alias->name) == 0)
++                      return alias;
++      }
++
++      return NULL;
++}
++
++
++void
++do_source(int argc, const char ** argv)
++{
++      readFile(argv[1]);
++}
++
++
++void
++do_exec(int argc, const char ** argv)
++{
++      const char *    name;
++
++      name = argv[1];
++
++      while (--sourceCount >= 0)
++      {
++              if (sourcefiles[sourceCount] != stdin)
++                      fclose(sourcefiles[sourceCount]);
++      }
++
++      argv[argc] = NULL;
++
++      execvp(name, (char **) argv + 1);
++      perror(name);
++}
++
++
++void
++do_prompt(int argc, const char ** argv)
++{
++      char *  cp;
++      char    buf[CMD_LEN];
++
++      if (!makeString(argc - 1, argv + 1, buf, CMD_LEN))
++              return;
++
++      cp = malloc(strlen(buf) + 2);
++
++      if (cp == NULL)
++      {
++              fprintf(stderr, "No memory for prompt\n");
++
++              return;
++      }
++
++      strcpy(cp, buf);
++      strcat(cp, " ");
++
++      if (prompt)
++              free(prompt);
++
++      prompt = cp;
++}
++
++
++void
++do_unalias(int argc, const char ** argv)
++{
++      Alias * alias;
++
++      while (--argc > 0)
++      {
++              alias = findAlias(*++argv);
++
++              if (alias == NULL)
++                      continue;
++
++              free(alias->name);
++              free(alias->value);
++              aliasCount--;
++              alias->name = aliasTable[aliasCount].name;
++              alias->value = aliasTable[aliasCount].value;    
++      }
++}
++
++
++/*
++ * Display the prompt string.
++ */
++static void
++showPrompt(void)
++{
++      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);
++}
++
++
++static void
++catchQuit(int val)
++{
++      signal(SIGQUIT, catchQuit);
++
++      intFlag = TRUE;
++
++      if (intCrlf)
++              write(STDOUT, "\n", 1);
++}
++
++
++/*
++ * Print the usage information and quit.
++ */
++static void
++usage(void)
++{
++      fprintf(stderr, "Stand-alone shell (version %s)\n", version);
++      fprintf(stderr, "\n");
++      fprintf(stderr, "Usage: sash [-a] [-q] [-f fileName] [-c command] [-p prompt] [-i]\n");
++
++      exit(1);
++}
++
++/* END CODE */
diff --git a/debian/patches/e2fslibs_chattr_include b/debian/patches/e2fslibs_chattr_include
new file mode 100644 (file)
index 0000000..add1ffc
--- /dev/null
@@ -0,0 +1,17 @@
+Subject: Use includes from e2fslibs rather than the kernel
+From: Tollef Fog Heen <tfheen@debian.org>
+Bug-Debian: #223203
+Last-updated: 2010-04-04
+Index: sash-3.7/cmd_chattr.c
+===================================================================
+--- sash-3.7.orig/cmd_chattr.c 2010-04-04 10:40:52.644957438 +0200
++++ sash-3.7/cmd_chattr.c      2010-04-04 10:41:11.084974379 +0200
+@@ -12,7 +12,7 @@
+ #include <sys/ioctl.h>
+ #include <sys/types.h>
+-#include <linux/ext2_fs.h>
++#include <ext2fs/ext2_fs.h>
+ #include "sash.h"
diff --git a/debian/patches/exit_with_argument b/debian/patches/exit_with_argument
new file mode 100644 (file)
index 0000000..86e520e
--- /dev/null
@@ -0,0 +1,44 @@
+Subject: Let exit have an optional argument
+From: Tollef Fog Heen <tfheen@debian.org>
+Last-updated: 2010-04-04
+Index: sash-3.7/cmds.c
+===================================================================
+--- sash-3.7.orig/cmds.c       2002-07-22 00:28:19.000000000 +0200
++++ sash-3.7/cmds.c    2010-04-04 10:58:51.604971262 +0200
+@@ -993,14 +993,18 @@
+ void
+ do_exit(int argc, const char ** argv)
+ {
++      int r = 0;
+       if (getpid() == 1)
+       {
+               fprintf(stderr, "You are the INIT process!\n");
+               return;
+       }
+-
+-      exit(0);
++      if (argc == 2)
++      {
++              r = atoi(argv[1]);
++      }
++      exit(r);
+ }
+Index: sash-3.7/sash.c
+===================================================================
+--- sash-3.7.orig/sash.c       2004-01-14 06:08:03.000000000 +0100
++++ sash-3.7/sash.c    2010-04-04 10:58:51.604971262 +0200
+@@ -132,9 +132,9 @@
+       },
+       {
+-              "exit",         do_exit,        1,      1,
++              "exit",         do_exit,        1,      2,
+               "Exit from sash",
+-              ""
++              "[exit value]"
+       },
+       {
diff --git a/debian/patches/exit_with_command_status b/debian/patches/exit_with_command_status
new file mode 100644 (file)
index 0000000..89454cc
--- /dev/null
@@ -0,0 +1,178 @@
+Index: sash-3.7/sash.c
+===================================================================
+--- sash-3.7.orig/sash.c       2010-04-04 14:56:47.964954627 +0200
++++ sash-3.7/sash.c    2010-04-04 14:57:03.932954934 +0200
+@@ -375,10 +375,10 @@
+  */
+ static        void    catchInt(int);
+ static        void    catchQuit(int);
+-static        void    readFile(const char * name);
+-static        void    command(const char * cmd);
++static        int     readFile(const char * name);
++static        int     command(const char * cmd);
+ static        BOOL    tryBuiltIn(const char * cmd);
+-static        void    runCmd(const char * cmd);
++static        int     runCmd(const char * cmd);
+ static        void    childProcess(const char * cmd);
+ static        void    showPrompt(void);
+ static        void    usage(void);
+@@ -524,9 +524,7 @@
+        */
+       if (singleCommand)
+       {
+-              command(singleCommand);
+-
+-              return 0;
++              return command(singleCommand);
+       }
+       /*
+@@ -561,9 +559,8 @@
+       /*
+        * Read commands from stdin or from a command file.
+        */
+-      readFile(commandFile);
++      return readFile(commandFile);
+-      return 0;
+ }
+@@ -571,19 +568,20 @@
+  * 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];
++      int     r = 0;
+       if (sourceCount >= MAX_SOURCE)
+       {
+               fprintf(stderr, "Too many source files\n");
+-              return;
++              return 1;
+       }
+       fp = stdin;
+@@ -596,7 +594,7 @@
+               {
+                       perror(name);
+-                      return;
++                      return 1;
+               }
+       }
+@@ -614,7 +612,7 @@
+                       fclose(fp);
+                       sourceCount--;
+-                      return;
++                      return 1;
+               }
+       
+               if (fgets(buf, CMD_LEN - 1, fp) == NULL)
+@@ -639,7 +637,7 @@
+               buf[cc] = '\0';
+-              command(buf);
++              r = command(buf);
+       }
+       if (ferror(fp))
+@@ -656,6 +654,7 @@
+               fclose(fp);
+       sourceCount--;
++      return r;
+ }
+@@ -664,7 +663,7 @@
+  * This breaks the command line up into words, checks to see if the
+  * command is an alias, and expands wildcards.
+  */
+-static void
++static int
+ command(const char * cmd)
+ {
+       const char *    endCmd;
+@@ -690,7 +689,7 @@
+        * If the command is empty or is a comment then ignore it.
+        */
+       if ((*cmd == '\0') || (*cmd == '#'))
+-              return;
++              return 0;
+       /*
+        * Look for the end of the command name and then copy the
+@@ -726,13 +725,13 @@
+        * the command if found.
+        */
+       if (tryBuiltIn(cmd))
+-              return;
++              return 0; /* This is a blatant lie */
+       /*
+        * The command is not a built-in, so run the program along
+        * the PATH list.
+        */
+-      runCmd(cmd);
++      return runCmd(cmd);
+ }
+@@ -809,7 +808,7 @@
+  * Execute the specified command either by forking and executing
+  * the program ourself, or else by using the shell.
+  */
+-static void
++static int
+ runCmd(const char * cmd)
+ {
+       const char *    cp;
+@@ -854,9 +853,7 @@
+        */
+       if (magic)
+       {
+-              system(cmd);
+-
+-              return;
++              return system(cmd);
+       }
+       /*
+@@ -869,7 +866,7 @@
+       {
+               perror("fork failed");
+-              return;
++              return -1;
+       }
+       /*
+@@ -894,7 +891,7 @@
+       {
+               fprintf(stderr, "Error from waitpid: %s", strerror(errno));
+-              return;
++              return -1;
+       }
+       if (WIFSIGNALED(status))
+@@ -902,6 +899,7 @@
+               fprintf(stderr, "pid %ld: killed by signal %d\n",
+                       (long) pid, WTERMSIG(status));
+       }
++      return WEXITSTATUS(status);
+ }
diff --git a/debian/patches/fix_exec b/debian/patches/fix_exec
new file mode 100644 (file)
index 0000000..4cec306
--- /dev/null
@@ -0,0 +1,30 @@
+Subject: Don't check permissions before trying to execute a command
+From: Unknown
+Last-updated: 2010-04-04
+Index: sash-3.7/sash.c
+===================================================================
+--- sash-3.7.orig/sash.c       2010-04-04 10:12:57.228978742 +0200
++++ sash-3.7/sash.c    2010-04-04 10:13:04.008985124 +0200
+@@ -1172,13 +1172,6 @@
+       name = argv[1];
+-      if (access(name, 4))
+-      {
+-              perror(name);
+-
+-              return;
+-      }
+-
+       while (--sourceCount >= 0)
+       {
+               if (sourcefiles[sourceCount] != stdin)
+@@ -1188,7 +1181,7 @@
+       argv[argc] = NULL;
+       execvp(name, (char **) argv + 1);
+-      exit(1);
++      perror(name);
+ }
diff --git a/debian/patches/freebsd_build b/debian/patches/freebsd_build
new file mode 100644 (file)
index 0000000..b614c10
--- /dev/null
@@ -0,0 +1,67 @@
+Subject: Build fixes for Debian GNU/kFreeBSD
+From: Axel Beckert <abe@debian.org>
+Bug-Debian: #565539
+Last-updated: 2010-04-04
+Index: sash-3.7/Makefile
+===================================================================
+--- sash-3.7.orig/Makefile     2010-04-04 11:13:36.005953632 +0200
++++ sash-3.7/Makefile  2010-04-04 11:38:19.300955689 +0200
+@@ -9,9 +9,16 @@
+ #
+ HAVE_GZIP             = 1
+ HAVE_LINUX_ATTR               = 1
++ifeq (Linux,$(shell uname -s))
+ HAVE_LINUX_MOUNT      = 1
+ HAVE_BSD_MOUNT                = 0
+ MOUNT_TYPE            = '"ext3"'
++endif
++ifeq (kFreeBSD,$(shell uname -s))
++HAVE_LINUX_MOUNT      = 0
++HAVE_BSD_MOUNT                = 1
++MOUNT_TYPE            = '"ufs"'
++endif
+ DEFS = -DHAVE_GZIP=$(HAVE_GZIP) \
+       -DHAVE_LINUX_ATTR=$(HAVE_LINUX_ATTR) \
+Index: sash-3.7/cmds.c
+===================================================================
+--- sash-3.7.orig/cmds.c       2010-04-04 11:13:36.025952857 +0200
++++ sash-3.7/cmds.c    2010-04-04 11:37:59.160966064 +0200
+@@ -19,6 +19,10 @@
+ #if   HAVE_LINUX_MOUNT
+ #include <linux/fs.h>
++#elif HAVE_BSD_MOUNT
++#include <ufs/ufs/ufsmount.h>
++#include <fs/cd9660/cd9660_mount.h>
++#include <fs/msdosfs/msdosfsmount.h>
+ #endif
+@@ -599,26 +603,16 @@
+ #elif HAVE_BSD_MOUNT
+       {
+               struct      ufs_args ufs;
+-              struct      adosfs_args adosfs;
+               struct      iso_args iso;
+-              struct      mfs_args mfs;
+               struct      msdosfs_args msdosfs;
+               void *      args;
+               if(!strcmp(type, "ffs") || !strcmp(type, "ufs")) {
+                       ufs.fspec = (char*) argv[0];
+                       args = &ufs;
+-              } else if(!strcmp(type, "adosfs")) {
+-                      adosfs.fspec = (char*) argv[0];
+-                      adosfs.uid = 0;
+-                      adosfs.gid = 0;
+-                      args = &adosfs;
+               } else if(!strcmp(type, "cd9660")) {
+                       iso.fspec = (char*) argv[0];
+                       args = &iso;
+-              } else if(!strcmp(type, "mfs")) {
+-                      mfs.fspec = (char*) argv[0];
+-                      args = &mfs;
+               } else if(!strcmp(type, "msdos")) {
+                       msdosfs.fspec = (char*) argv[0];
+                       msdosfs.uid = 0;
diff --git a/debian/patches/interactive_flag b/debian/patches/interactive_flag
new file mode 100644 (file)
index 0000000..83d034f
--- /dev/null
@@ -0,0 +1,70 @@
+Subject: Add -i option
+From: Michael Meskes <meskes@debian.org>
+Bug-Debian: #19656
+Last-updated: 2010-04-04
+Index: sash-3.7/sash.c
+===================================================================
+--- sash-3.7.orig/sash.c       2010-04-04 10:35:51.268950839 +0200
++++ sash-3.7/sash.c    2010-04-04 10:36:42.572973204 +0200
+@@ -399,12 +399,14 @@
+       const char *    commandFile;
+       BOOL            quietFlag;
+       BOOL            aliasFlag;
++        BOOL          interactiveFlag;
+       char            buf[PATH_LEN];
+       singleCommand = NULL;
+       commandFile = NULL;
+       quietFlag = FALSE;
+       aliasFlag = FALSE;
++        interactiveFlag = FALSE;
+       /*
+        * Look for options.
+@@ -419,11 +421,17 @@
+               while (*cp) switch (*cp++)
+               {
++                        case '-':
++                                /*
++                                 * Ignore.  This is so that we can be
++                                 * run from login.
++                                 */
++                                break;
+                       case 'c':
+                               /*
+                                * Execute specified command.
+                                */
+-                              if ((argc != 1) || singleCommand)
++                              if ((argc != 1) || singleCommand || interactiveFlag)
+                                       usage();
+                               singleCommand = *argv++;
+@@ -446,6 +454,18 @@
+                               break;
++                      case 'i':
++                              /*
++                               * Be an interactive shell
++                               * ..is a no-op, but some contexts require this
++                               * ..interactiveFlag is to avoid -ic as a legacy
++                               */
++                               if (singleCommand)
++                                      usage();
++                               
++                               interactiveFlag = TRUE;
++                               break;
++                               
+                       case 'p':
+                               /*
+                                * Set the prompt string.
+@@ -1263,7 +1290,7 @@
+ {
+       fprintf(stderr, "Stand-alone shell (version %s)\n", version);
+       fprintf(stderr, "\n");
+-      fprintf(stderr, "Usage: sash [-a] [-q] [-f fileName] [-c command] [-p prompt]\n");
++      fprintf(stderr, "Usage: sash [-a] [-q] [-f fileName] [-c command] [-p prompt] [-i]\n");
+       exit(1);
+ }
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644 (file)
index 0000000..ab43127
--- /dev/null
@@ -0,0 +1,9 @@
+exit_with_argument
+e2fslibs_chattr_include
+touch_error_handling
+interactive_flag
+fix_exec
+buildsystem
+freebsd_build
+exit_with_command_status
+debian-changes-3.7-10
diff --git a/debian/patches/touch_error_handling b/debian/patches/touch_error_handling
new file mode 100644 (file)
index 0000000..d567c2a
--- /dev/null
@@ -0,0 +1,20 @@
+Subject: Correct error message when touching non-existent file in non-writeable directory
+From: Tollef Fog Heen <tfheen@debian.org>, Raul Miller <moth@debian.org>
+Bug-Debian: #43428
+Last-updated: 2010-04-04
+Index: sash-3.7/cmds.c
+===================================================================
+--- sash-3.7.orig/cmds.c       2010-04-04 10:58:51.000000000 +0200
++++ sash-3.7/cmds.c    2010-04-04 11:04:55.185955708 +0200
+@@ -341,6 +341,11 @@
+                       continue;
+               }
++              if (errno != EEXIST) {
++                      perror(name);
++                      continue;
++              }
++
+               if (utime(name, &now) < 0)
+                       perror(name);
+       }
diff --git a/debian/source/format b/debian/source/format
new file mode 100644 (file)
index 0000000..163aaf8
--- /dev/null
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debian/stamp-makefile-build b/debian/stamp-makefile-build
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sash.c b/sash.c
index 6041bed65d07399fdda334e82f1a751b3aa29e84..ee444a64bde402d82a47773088f33e9705e844e5 100644 (file)
--- a/sash.c
+++ b/sash.c
@@ -132,9 +132,9 @@ static const CommandEntry   commandEntryTable[] =
        },
 
        {
-               "exit",         do_exit,        1,      2,
+               "exit",         do_exit,        1,      1,
                "Exit from sash",
-               "[exit value]"
+               ""
        },
 
        {
@@ -399,14 +399,12 @@ main(int argc, const char ** argv)
        const char *    commandFile;
        BOOL            quietFlag;
        BOOL            aliasFlag;
-        BOOL           interactiveFlag;
        char            buf[PATH_LEN];
 
        singleCommand = NULL;
        commandFile = NULL;
        quietFlag = FALSE;
        aliasFlag = FALSE;
-        interactiveFlag = FALSE;
 
        /*
         * Look for options.
@@ -421,17 +419,11 @@ main(int argc, const char ** argv)
 
                while (*cp) switch (*cp++)
                {
-                        case '-':
-                                /*
-                                 * Ignore.  This is so that we can be
-                                 * run from login.
-                                 */
-                                break;
                        case 'c':
                                /*
                                 * Execute specified command.
                                 */
-                               if ((argc != 1) || singleCommand || interactiveFlag)
+                               if ((argc != 1) || singleCommand)
                                        usage();
 
                                singleCommand = *argv++;
@@ -454,18 +446,6 @@ main(int argc, const char ** argv)
 
                                break;
 
-                       case 'i':
-                               /*
-                                * Be an interactive shell
-                                * ..is a no-op, but some contexts require this
-                                * ..interactiveFlag is to avoid -ic as a legacy
-                                */
-                                if (singleCommand)
-                                       usage();
-                                
-                                interactiveFlag = TRUE;
-                                break;
-                                
                        case 'p':
                                /*
                                 * Set the prompt string.
@@ -1172,6 +1152,13 @@ do_exec(int argc, const char ** argv)
 
        name = argv[1];
 
+       if (access(name, 4))
+       {
+               perror(name);
+
+               return;
+       }
+
        while (--sourceCount >= 0)
        {
                if (sourcefiles[sourceCount] != stdin)
@@ -1181,7 +1168,7 @@ do_exec(int argc, const char ** argv)
        argv[argc] = NULL;
 
        execvp(name, (char **) argv + 1);
-       perror(name);
+       exit(1);
 }
 
 
@@ -1283,7 +1270,7 @@ usage(void)
 {
        fprintf(stderr, "Stand-alone shell (version %s)\n", version);
        fprintf(stderr, "\n");
-       fprintf(stderr, "Usage: sash [-a] [-q] [-f fileName] [-c command] [-p prompt] [-i]\n");
+       fprintf(stderr, "Usage: sash [-a] [-q] [-f fileName] [-c command] [-p prompt]\n");
 
        exit(1);
 }