Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37400456
en ru br
Репозитории ALT

Группа :: Интерпретаторы команд
Пакет: bash3

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: bash-3.2.57-alt4.patch
Скачать


 array.c               |   2 +-
 bashhist.c            |   2 +-
 bashline.c            |  17 +++---
 braces.c              |   2 +-
 builtins.h            |   1 +
 builtins/bind.def     |   2 +-
 builtins/cd.def       |   4 +-
 builtins/declare.def  |   2 +-
 builtins/echo.def     |   2 +-
 builtins/enable.def   |   7 ++-
 builtins/evalstring.c |   2 +-
 builtins/fc.def       |   8 +--
 builtins/fg_bg.def    |   1 +
 builtins/getopt.c     |   2 +-
 builtins/getopts.def  |   1 +
 builtins/help.def     |   2 +-
 builtins/history.def  |   1 +
 builtins/mkbuiltins.c |  28 ++++++++-
 builtins/printf.def   |   2 +-
 builtins/psize.sh     |  24 +-------
 builtins/read.def     |   2 +-
 builtins/set.def      |   5 +-
 builtins/setattr.def  |   5 +-
 builtins/test.def     |   6 ++
 builtins/type.def     |   2 +-
 builtins/ulimit.def   |   4 ++
 config-top.h          |   8 +--
 config.h.in           |   8 ++-
 configure.in          |   7 ++-
 doc/Makefile.in       |  10 ++--
 doc/bash.1            |  36 ++++++++++-
 doc/bashbug.1         |   3 +-
 doc/bashref.texi      |  17 ++++++
 doc/builtins.1        |   4 +-
 doc/rbash.1           |   4 +-
 error.c               |   5 +-
 eval.c                |   5 +-
 execute_cmd.c         |  22 +++++--
 execute_cmd.h         |   2 +
 expr.c                |   7 +--
 externs.h             |   5 +-
 findcmd.c             |  24 ++++++--
 general.c             |   2 +-
 hashlib.c             |   2 +-
 jobs.c                |  10 ++--
 jobs.h                |   4 ++
 lib/glob/glob.c       |   3 +-
 lib/glob/sm_loop.c    |  12 ++--
 lib/glob/smatch.c     |   2 +-
 lib/glob/strmatch.c   |   2 +-
 lib/malloc/stats.c    |   2 +-
 lib/malloc/trace.c    |   2 +-
 lib/readline/rldefs.h |   2 +-
 lib/sh/eaccess.c      |   6 +-
 lib/sh/makepath.c     |   2 +-
 lib/sh/netopen.c      |   6 +-
 lib/sh/pathcanon.c    |   2 +-
 lib/sh/spell.c        |   2 +-
 lib/sh/strtrans.c     |   2 +-
 lib/sh/tmpfile.c      | 162 +++++++++-----------------------------------------
 lib/sh/winsize.c      |   2 +
 lib/tilde/tilde.c     |   2 +-
 mailcheck.c           |   4 +-
 make_cmd.c            |  85 +++++++++++++++++++++++++-
 parse.y               |  29 +++++----
 pathexp.c             |   4 +-
 pcomplete.c           |   2 +
 print_cmd.c           |   2 +-
 redir.c               |  10 +++-
 shell.c               |  14 ++++-
 sig.c                 |   3 +-
 subst.c               |  94 +++++++++++++++++++++--------
 support/bashbug.sh    |  45 ++++----------
 support/fixlinks      |  35 ++++-------
 support/man2html.c    |   2 +-
 support/mkclone       |  39 ++++--------
 support/rlvers.sh     |  24 +++-----
 trap.c                |  11 ----
 unwind_prot.c         |   4 +-
 variables.c           |  59 ++++++++++++------
 y.tab.c               |   2 +
 81 files changed, 570 insertions(+), 430 deletions(-)
diff --git a/array.c b/array.c
index cee9c1f..61e4fd2 100644
--- a/array.c
+++ b/array.c
@@ -137,7 +137,7 @@ ARRAY_ELEMENT	*s, *e;
 	a = array_create ();
 	a->type = array->type;
 
-	for (p = s, i = 0; p != e; p = element_forw(p), i++) {
+	for (p = s, i = 0, mi = 0; p != e; p = element_forw(p), i++) {
 		n = array_create_element (element_index(p), element_value(p));
 		ADD_BEFORE(a->head, n);
 		mi = element_index(n);
diff --git a/bashhist.c b/bashhist.c
index 3b85416..124d7dd 100644
--- a/bashhist.c
+++ b/bashhist.c
@@ -574,7 +574,7 @@ hc_erasedups (line)
   int r;
 
   using_history ();
-  while (temp = previous_history ())
+  while ((temp = previous_history ()))
     {
       if (STREQ (temp->line, line))
 	{
diff --git a/bashline.c b/bashline.c
index fa4055e..e7de666 100644
--- a/bashline.c
+++ b/bashline.c
@@ -637,7 +637,7 @@ snarf_hosts_from_file (filename)
   if (file == 0)
     return;
 
-  while (temp = fgets (buffer, 255, file))
+  while ((temp = fgets (buffer, 255, file)))
     {
       /* Skip to first character. */
       for (i = 0; buffer[i] && cr_whitespace (buffer[i]); i++)
@@ -803,7 +803,7 @@ operate_and_get_next (count, c)
    command being entered (if no explicit argument is given), otherwise on
    a command from the history file. */
 
-#define VI_EDIT_COMMAND		"fc -e \"${VISUAL:-${EDITOR:-vi}}\""
+#define VI_EDIT_COMMAND		"fc -e \"${VISUAL:-${EDITOR:-vitmp}}\""
 #define EMACS_EDIT_COMMAND	"fc -e \"${VISUAL:-${EDITOR:-emacs}}\""
 #define POSIX_VI_EDIT_COMMAND	"fc -e vi"
 
@@ -1756,7 +1756,7 @@ bash_servicename_completion_function (text, state)
       setservent (0);
     }
 
-  while (srvent = getservent ())
+  while ((srvent = getservent ()))
     {
       afound = 0;
       if (snamelen == 0 || (STREQN (sname, srvent->s_name, snamelen)))
@@ -1812,7 +1812,7 @@ bash_groupname_completion_function (text, state)
       setgrent ();
     }
 
-  while (grent = getgrent ())
+  while ((grent = getgrent ()))
     {
       if (gnamelen == 0 || (STREQN (gname, grent->gr_name, gnamelen)))
         break;
@@ -2147,11 +2147,8 @@ _ignore_completion_names (names, name_func)
     ;
   newnames = strvec_create (nidx + 1);
 
-  if (force_fignore == 0)
-    {
-      oldnames = strvec_create (nidx - 1);
-      oidx = 0;
-    }
+  oldnames = (force_fignore == 0) ? strvec_create (nidx - 1) : 0;
+  oidx = 0;
 
   newnames[0] = names[0];
   for (idx = nidx = 1; names[idx]; idx++)
@@ -3087,7 +3084,7 @@ isolate_sequence (string, ind, need_dquote, startp)
   if (startp)
     *startp = delim ? ++i : i;
 
-  for (passc = 0; c = string[i]; i++)
+  for (passc = 0; (c = string[i]); i++)
     {
       if (passc)
 	{
diff --git a/braces.c b/braces.c
index 2537397..2eac919 100644
--- a/braces.c
+++ b/braces.c
@@ -440,7 +440,7 @@ brace_gobbler (text, tlen, indx, satisfy)
 #endif
 
   i = *indx;
-  while (c = text[i])
+  while ((c = text[i]))
     {
       if (pass_next)
 	{
diff --git a/builtins.h b/builtins.h
index f75e503..3610c3e 100644
--- a/builtins.h
+++ b/builtins.h
@@ -40,6 +40,7 @@
 #define STATIC_BUILTIN  0x4	/* This builtin is not dynamically loaded. */
 #define SPECIAL_BUILTIN 0x8	/* This is a Posix `special' builtin. */
 #define ASSIGNMENT_BUILTIN 0x10	/* This builtin takes assignment statements. */
+#define REQUIRES_BUILTIN 0x20	/* This builtin requires other files. */
 
 #define BASE_INDENT	4
 
diff --git a/builtins/bind.def b/builtins/bind.def
index 4711031..3de3726 100644
--- a/builtins/bind.def
+++ b/builtins/bind.def
@@ -114,7 +114,7 @@ bind_builtin (list)
 
   kmap = saved_keymap = (Keymap) NULL;
   flags = 0;
-  initfile = map_name = fun_name = unbind_name = remove_seq = (char *)NULL;
+  initfile = map_name = fun_name = unbind_name = remove_seq = cmd_seq = (char *)NULL;
   return_code = EXECUTION_SUCCESS;
 
   if (!bash_readline_initialized)
diff --git a/builtins/cd.def b/builtins/cd.def
index 54e328e..10d1b58 100644
--- a/builtins/cd.def
+++ b/builtins/cd.def
@@ -224,13 +224,13 @@ cd_builtin (list)
     }
   else if (absolute_pathname (list->word->word))
     dirname = list->word->word;
-  else if (cdpath = get_string_value ("CDPATH"))
+  else if ((cdpath = get_string_value ("CDPATH")))
     {
       dirname = list->word->word;
 
       /* Find directory in $CDPATH. */
       path_index = 0;
-      while (path = extract_colon_unit (cdpath, &path_index))
+      while ((path = extract_colon_unit (cdpath, &path_index)))
 	{
 	  /* OPT is 1 if the path element is non-empty */
 	  opt = path[0] != '\0';
diff --git a/builtins/declare.def b/builtins/declare.def
index 4d94fac..d8dd43f 100644
--- a/builtins/declare.def
+++ b/builtins/declare.def
@@ -248,7 +248,7 @@ declare_internal (list, local_var)
 #if defined (ARRAY_VARS)
       compound_array_assign = simple_array_assign = 0;
       subscript_start = (char *)NULL;
-      if (t = strchr (name, '['))	/* ] */
+      if ((t = strchr (name, '[')))	/* ] */
 	{
 	  subscript_start = t;
 	  *t = '\0';
diff --git a/builtins/echo.def b/builtins/echo.def
index 923c43a..0399dfc 100644
--- a/builtins/echo.def
+++ b/builtins/echo.def
@@ -118,7 +118,7 @@ echo_builtin (list)
 
       /* All of the options in TEMP are valid options to ECHO.
 	 Handle them. */
-      while (i = *temp++)
+      while ((i = *temp++))
 	{
 	  switch (i)
 	    {
diff --git a/builtins/enable.def b/builtins/enable.def
index 823c38f..94f47e0 100644
--- a/builtins/enable.def
+++ b/builtins/enable.def
@@ -101,6 +101,9 @@ enable_builtin (list)
 
   result = EXECUTION_SUCCESS;
   flags = 0;
+#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
+  filename = NULL;
+#endif
 
   reset_internal_getopt ();
   while ((opt = internal_getopt (list, "adnpsf:")) != -1)
@@ -295,7 +298,7 @@ dyn_load_builtin (list, flags, filename)
 #if defined (_AIX)
   handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL);
 #else
-  handle = dlopen (filename, RTLD_LAZY);
+  handle = dlopen (filename, RTLD_NOW);
 #endif /* !_AIX */
 
   if (handle == 0)
@@ -336,7 +339,7 @@ dyn_load_builtin (list, flags, filename)
 	b->flags |= SPECIAL_BUILTIN;
       b->handle = handle;
 
-      if (old_builtin = builtin_address_internal (name, 1))
+      if ((old_builtin = builtin_address_internal (name, 1)))
 	{
 	  replaced++;
 	  FASTCOPY ((char *)b, (char *)old_builtin, sizeof (struct builtin));
diff --git a/builtins/evalstring.c b/builtins/evalstring.c
index fb03c8a..c77cbaa 100644
--- a/builtins/evalstring.c
+++ b/builtins/evalstring.c
@@ -231,7 +231,7 @@ parse_and_execute (string, from_file, flags)
 	      dispose_command (global_command);
 	      global_command = (COMMAND *)NULL;
 	    }
-	  else if (command = global_command)
+	  else if ((command = global_command))
 	    {
 	      struct fd_bitmap *bitmap;
 
diff --git a/builtins/fc.def b/builtins/fc.def
index 101eb00..b359c72 100644
--- a/builtins/fc.def
+++ b/builtins/fc.def
@@ -31,7 +31,7 @@ string, which means the most recent command beginning with that
 string.
 
    -e ENAME selects which editor to use.  Default is FCEDIT, then EDITOR,
-      then vi.
+      then vitmp.
 
    -l means list lines instead of editing.
    -n means no line numbers listed.
@@ -107,7 +107,7 @@ extern int delete_last_history __P((void));
 
    -e ENAME selects which editor to use.  Default is FCEDIT, then EDITOR,
       then the editor which corresponds to the current readline editing
-      mode, then vi.
+      mode, then vitmp.
 
    -l means list lines instead of editing.
    -n means no line numbers listed.
@@ -155,7 +155,7 @@ static void fc_addhist __P((char *));
 #endif
 
 /* String to execute on a file that we want to edit. */
-#define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vi}}"
+#define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vitmp}}"
 #if defined (STRICT_POSIX)
 #  define POSIX_FC_EDIT_COMMAND "${FCEDIT:-ed}"
 #else
@@ -343,7 +343,7 @@ fc_builtin (list)
   else
     {
       numbering = 0;
-      stream = sh_mktmpfp ("bash-fc", MT_USERANDOM|MT_USETMPDIR, &fn);
+      stream = sh_mktmpfp ("bash-fc", MT_USETMPDIR, &fn);
       if (stream == 0)
 	{
 	  builtin_error (_("%s: cannot open temp file: %s"), fn ? fn : "", strerror (errno));
diff --git a/builtins/fg_bg.def b/builtins/fg_bg.def
index c14381b..fe1eec0 100644
--- a/builtins/fg_bg.def
+++ b/builtins/fg_bg.def
@@ -150,6 +150,7 @@ fg_bg (list, foreground)
       goto failure;
     }
 
+  old_async_pid = 0;
   if (foreground == 0)
     {
       old_async_pid = last_asynchronous_pid;
diff --git a/builtins/getopt.c b/builtins/getopt.c
index b223a76..0ec120f 100644
--- a/builtins/getopt.c
+++ b/builtins/getopt.c
@@ -178,7 +178,7 @@ sh_getopt (argc, argv, optstring)
       nextchar = (char *)NULL;
     }
 
-  if (sh_badopt = (temp == NULL || c == ':'))
+  if ((sh_badopt = (temp == NULL || c == ':')))
     {
       if (sh_opterr)
 	BADOPT (c);
diff --git a/builtins/getopts.def b/builtins/getopts.def
index a9aad62..dd87dd4 100644
--- a/builtins/getopts.def
+++ b/builtins/getopts.def
@@ -162,6 +162,7 @@ dogetopts (argc, argv)
   argc -= 2;
   argv += 2;
 
+  old_opterr = 0;
   special_error = optstr[0] == ':';
 
   if (special_error)
diff --git a/builtins/help.def b/builtins/help.def
index 35a6de9..44e7e5d 100644
--- a/builtins/help.def
+++ b/builtins/help.def
@@ -117,7 +117,7 @@ help_builtin (list)
       pattern = list->word->word;
       plen = strlen (pattern);
 
-      for (i = 0; name = shell_builtins[i].name; i++)
+      for (i = 0; (name = shell_builtins[i].name); i++)
 	{
 	  QUIT;
 	  if ((strncmp (pattern, name, plen) == 0) ||
diff --git a/builtins/history.def b/builtins/history.def
index efee005..3253710 100644
--- a/builtins/history.def
+++ b/builtins/history.def
@@ -105,6 +105,7 @@ history_builtin (list)
   intmax_t delete_offset;
 
   flags = 0;
+  delete_arg = NULL;
   reset_internal_getopt ();
   while ((opt = internal_getopt (list, "acd:npsrw")) != -1)
     {
diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c
index ff0bdc0..e2de810 100644
--- a/builtins/mkbuiltins.c
+++ b/builtins/mkbuiltins.c
@@ -69,8 +69,13 @@ extern char *strcpy ();
 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
 
 /* Flag values that builtins can have. */
+/*  These flags are for the C code generator,
+    the C which is produced (./builtin.c)
+    includes the flags definitions found
+    in ../builtins.h */
 #define BUILTIN_FLAG_SPECIAL	0x01
 #define BUILTIN_FLAG_ASSIGNMENT 0x02
+#define BUILTIN_FLAG_REQUIRES	0x04
 
 #define BASE_INDENT	4
 
@@ -154,9 +159,20 @@ char *assignment_builtins[] =
   (char *)NULL
 };
 
+/* The builtin commands that cause requirements on other files. */
+static char *requires_builtins[] =
+{
+  ".", "command", "exec", "source",
+#if defined (apollo)
+  "inlib",
+#endif
+  (char *)NULL
+};
+
 /* Forward declarations. */
 static int is_special_builtin ();
 static int is_assignment_builtin ();
+static int is_requires_builtin ();
 
 #if !defined (HAVE_RENAME)
 static int rename ();
@@ -800,6 +816,8 @@ builtin_handler (self, defs, arg)
     new->flags |= BUILTIN_FLAG_SPECIAL;
   if (is_assignment_builtin (name))
     new->flags |= BUILTIN_FLAG_ASSIGNMENT;
+  if (is_requires_builtin (name))
+    new->flags |= BUILTIN_FLAG_REQUIRES;
 
   array_add ((char *)new, defs->builtins);
   building_builtin = 1;
@@ -1217,10 +1235,11 @@ write_builtins (defs, structfile, externfile)
 		  else
 		    fprintf (structfile, "(sh_builtin_func_t *)0x0, ");
 
-		  fprintf (structfile, "%s%s%s, %s_doc,\n",
+		  fprintf (structfile, "%s%s%s%s, %s_doc,\n",
 		    "BUILTIN_ENABLED | STATIC_BUILTIN",
 		    (builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
 		    (builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
+		    (builtin->flags & BUILTIN_FLAG_REQUIRES) ? " | REQUIRES_BUILTIN" : "",
 		    document_name (builtin));
 
 		  fprintf
@@ -1561,6 +1580,13 @@ is_assignment_builtin (name)
   return (_find_in_table (name, assignment_builtins));
 }
 
+static int
+is_requires_builtin (name)
+     char *name;
+{
+  return (_find_in_table (name, requires_builtins));
+}
+
 #if !defined (HAVE_RENAME)
 static int
 rename (from, to)
diff --git a/builtins/printf.def b/builtins/printf.def
index 5a63167..c844e01 100644
--- a/builtins/printf.def
+++ b/builtins/printf.def
@@ -577,7 +577,7 @@ printstr (fmt, string, len, fieldwidth, precision)
 #else
   if (string == 0 || len == 0)
 #endif
-    return;
+    return 0;
 
 #if 0
   s = fmt;
diff --git a/builtins/psize.sh b/builtins/psize.sh
index c4d73e1..56de799 100644
--- a/builtins/psize.sh
+++ b/builtins/psize.sh
@@ -3,19 +3,10 @@
 # psize.sh -- determine this system's pipe size, and write a define to
 #             pipesize.h so ulimit.c can use it.
 
-: ${TMPDIR:=/tmp}
-# try to use mktemp(1) if the system supports it
-{ TMPFILE="`mktemp $TMPDIR/pipsize.XXXXXX 2>/dev/null`"; } 2>/dev/null
-used_mktemp=true
+TMPFILE="`mktemp -t pipsize.XXXXXXXXXX`" || exit 1
 
-if [ -z "$TMPFILE" ]; then
-	TMPNAME=pipsize.$$
-	TMPFILE=$TMPDIR/$TMPNAME
-	used_mktemp=false
-fi
-
-trap 'rm -f "$TMPFILE" ; exit 1' 1 2 3 6 15
-trap 'rm -f "$TMPFILE"' 0
+trap 'rm -f -- "$TMPFILE"; exit 1' HUP INT QUIT TERM
+trap 'rm -f -- "$TMPFILE"' EXIT
 
 echo "/*"
 echo " * pipesize.h"
@@ -25,15 +16,6 @@ echo " * Do not edit!"
 echo " */"
 echo ""
 
-#
-# Try to avoid tempfile races.  We can't really check for the file's
-# existance before we run psize.aux, because `test -e' is not portable,
-# `test -h' (test for symlinks) is not portable, and `test -f' only
-# checks for regular files.  If we used mktemp(1), we're ahead of the
-# game.
-#
-$used_mktemp || rm -f "$TMPFILE"
-
 ./psize.aux 2>"$TMPFILE" | sleep 3
 
 if [ -s "$TMPFILE" ]; then
diff --git a/builtins/read.def b/builtins/read.def
index 1c18c8d..b7a2156 100644
--- a/builtins/read.def
+++ b/builtins/read.def
@@ -128,7 +128,7 @@ read_builtin (list)
 {
   register char *varname;
   int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
-  int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
+  int input_is_tty, input_is_pipe, unbuffered_read;
   int raw, edit, nchars, silent, have_timeout, fd;
   unsigned int tmout;
   intmax_t intval;
diff --git a/builtins/set.def b/builtins/set.def
index 9d86319..01c43bb 100644
--- a/builtins/set.def
+++ b/builtins/set.def
@@ -529,7 +529,7 @@ parse_shellopts (value)
   int vptr;
 
   vptr = 0;
-  while (vname = extract_colon_unit (value, &vptr))
+  while ((vname = extract_colon_unit (value, &vptr)))
     {
       set_minus_o_option (FLAG_ON, vname);
       free (vname);
@@ -637,7 +637,7 @@ set_builtin (list)
 
       if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+'))
 	{
-	  while (flag_name = *++arg)
+	  while ((flag_name = *++arg))
 	    {
 	      if (flag_name == '?')
 		{
@@ -761,6 +761,7 @@ unset_builtin (list)
 
 #if defined (ARRAY_VARS)
       unset_array = 0;
+      t = NULL;
       if (!unset_function && valid_array_reference (name))
 	{
 	  t = strchr (name, '[');
diff --git a/builtins/setattr.def b/builtins/setattr.def
index 28102bc..9189aaf 100644
--- a/builtins/setattr.def
+++ b/builtins/setattr.def
@@ -261,7 +261,7 @@ set_or_show_attributes (list, attribute, nodefs)
 
       if (variable_list)
 	{
-	  for (i = 0; var = variable_list[i]; i++)
+	  for (i = 0; (var = variable_list[i]); i++)
 	    {
 #if defined (ARRAY_VARS)
 	      if (arrays_only && array_p (var) == 0)
@@ -438,4 +438,7 @@ set_var_attribute (name, attribute, undo)
 
   if (var && (exported_p (var) || (attribute & att_exported)))
     array_needs_making++;	/* XXX */
+
+  if (var)
+    stupidly_hack_special_variables (name);
 }
diff --git a/builtins/test.def b/builtins/test.def
index e51d00b..44f48a4 100644
--- a/builtins/test.def
+++ b/builtins/test.def
@@ -60,6 +60,9 @@ File operators:
 
   FILE1 -ef FILE2  True if file1 is a hard link to file2.
 
+All file operators except -h and -L are acting on the target of a symbolic
+link, not on the symlink itself, if FILE is a symbolic link.
+
 String operators:
 
     -z STRING      True if string is empty.
@@ -89,6 +92,9 @@ Other operators:
 Arithmetic binary operators return true if ARG1 is equal, not-equal,
 less-than, less-than-or-equal, greater-than, or greater-than-or-equal
 than ARG2.
+
+See the bash manual page bash(1) for the handling of parameters (i.e.
+missing parameters).
 $END
 
 $BUILTIN [
diff --git a/builtins/type.def b/builtins/type.def
index d03ccb2..4182d37 100644
--- a/builtins/type.def
+++ b/builtins/type.def
@@ -331,7 +331,7 @@ describe_command (command, dflags)
      whether the file is present in our hash table. */
   if (all == 0 || (dflags & CDESC_FORCE_PATH))
     {
-      if (full_path = phash_search (command))
+      if ((full_path = phash_search (command)))
 	{
 	  if (dflags & CDESC_TYPE)
 	    puts ("file");
diff --git a/builtins/ulimit.def b/builtins/ulimit.def
index 2d2e7b2..c1d1863 100644
--- a/builtins/ulimit.def
+++ b/builtins/ulimit.def
@@ -182,7 +182,9 @@ static int set_limit __P((int, RLIMTYPE, int));
 static void printone __P((int, RLIMTYPE, int));
 static void print_all_limits __P((int));
 
+#ifdef NOTYET
 static int set_all_limits __P((int, RLIMTYPE));
+#endif
 
 static int filesize __P((RLIMTYPE *));
 static int pipesize __P((RLIMTYPE *));
@@ -707,6 +709,7 @@ printone (limind, curlim, pdesc)
     print_rlimtype ((curlim / limits[limind].block_factor), 1);
 }
 
+#ifdef NOTYET
 /* Set all limits to NEWLIM.  NEWLIM currently must be RLIM_INFINITY, which
    causes all limits to be set as high as possible depending on mode (like
    csh `unlimit').  Returns -1 if NEWLIM is invalid, 0 if all limits
@@ -746,5 +749,6 @@ set_all_limits (mode, newlim)
       }
   return retval;
 }
+#endif
 
 #endif /* !_MINIX */
diff --git a/config-top.h b/config-top.h
index 7a90b16..e3fbec3 100644
--- a/config-top.h
+++ b/config-top.h
@@ -52,14 +52,14 @@
 /* The default value of the PATH variable. */
 #ifndef DEFAULT_PATH_VALUE
 #define DEFAULT_PATH_VALUE \
-  "/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:."
+  "/bin:/usr/bin:/usr/local/bin"
 #endif
 
 /* The value for PATH when invoking `command -p'.  This is only used when
    the Posix.2 confstr () function, or CS_PATH define are not present. */
 #ifndef STANDARD_UTILS_PATH
 #define STANDARD_UTILS_PATH \
-  "/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc"
+  "/bin:/usr/bin:/sbin:/usr/sbin"
 #endif
 
 /* Default primary and secondary prompt strings. */
@@ -80,8 +80,8 @@
 
 /* Define this to make non-interactive shells begun with argv[0][0] == '-'
    run the startup files when not in posix mode. */
-/* #define NON_INTERACTIVE_LOGIN_SHELLS */
+#define NON_INTERACTIVE_LOGIN_SHELLS
 
 /* Define this if you want bash to try to check whether it's being run by
    sshd and source the .bashrc if so (like the rshd behavior). */
-/* #define SSH_SOURCE_BASHRC */
+#define SSH_SOURCE_BASHRC
diff --git a/config.h.in b/config.h.in
index 3699374..d76e59b 100644
--- a/config.h.in
+++ b/config.h.in
@@ -201,7 +201,7 @@
 
 /* System paths */
 
-#define DEFAULT_MAIL_DIRECTORY "/usr/spool/mail"
+#define DEFAULT_MAIL_DIRECTORY "/var/mail"
 
 /* Characteristics of the system's header files and libraries that affect
    the compilation environment. */
@@ -654,6 +654,9 @@
 /* Define if you have the raise function. */
 #undef HAVE_RAISE
 
+/* Define if you have the random function.  */
+#undef HAVE_RANDOM
+
 /* Define if you have the readlink function. */
 #undef HAVE_READLINK
 
@@ -703,6 +706,9 @@
 /* Define if you have the snprintf function.  */
 #undef HAVE_SNPRINTF
 
+/* Define if you have the srandom function.  */
+#undef HAVE_SRANDOM
+
 /* Define if you have the strcasecmp function.  */
 #undef HAVE_STRCASECMP
 
diff --git a/configure.in b/configure.in
index a688b2d..ca88819 100644
--- a/configure.in
+++ b/configure.in
@@ -27,7 +27,7 @@ AC_REVISION([for Bash 3.2, version 3.190])dnl
 define(bashvers, 3.2)
 define(relstatus, release)
 
-AC_INIT([bash], bashvers-relstatus, [bug-bash@gnu.org])
+AC_INIT([bash3], bashvers-relstatus, [bug-bash@gnu.org])
 
 dnl make sure we are using a recent autoconf version
 AC_PREREQ(2.50)
@@ -325,7 +325,7 @@ fi
 HELPDIR= HELPDIRDEFINE= HELPINSTALL=
 if test "$opt_separate_help" != no; then
 	if test "$opt_separate_help" = "yes" ; then
-		HELPDIR='${datadir}/bash'
+		HELPDIR='${datadir}/AC_PACKAGE_NAME'
 	else
 		HELPDIR=$opt_separate_help
 	fi
@@ -748,6 +748,9 @@ BASH_CHECK_DECL(strtoumax)
 
 AC_FUNC_MKTIME
 
+dnl checks for random functions
+AC_CHECK_FUNCS(random srandom)
+
 dnl
 dnl Checks for lib/intl and related code (uses some of the output from
 dnl AM_GNU_GETTEXT)
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 270ddfd..2c9c60c 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -69,7 +69,6 @@ TEXI2DVI    = ${SUPPORT_SRCDIR}/texi2dvi
 TEXI2HTML   = ${SUPPORT_SRCDIR}/texi2html
 MAN2HTML    = ${BUILD_DIR}/support/man2html
 HTMLPOST    = ${srcdir}/htmlpost.sh
-INFOPOST    = ${srcdir}/infopost.sh
 QUIETPS	    = #set this to -q to shut up dvips
 PAPERSIZE   = letter	# change to a4 for A4-size paper
 PSDPI       = 600	# could be 300 if you like
@@ -146,7 +145,7 @@ nodvi: ps info text html
 
 PSFILES = bash.ps bashbug.ps article.ps builtins.ps rbash.ps 
 DVIFILES = bashref.dvi bashref.ps
-INFOFILES = bashref.info
+INFOFILES = bashref.info bash.info
 MAN0FILES = bash.0 bashbug.0 builtins.0 rbash.0
 HTMLFILES = bashref.html bash.html
 PDFFILES = bash.pdf bashref.pdf article.pdf rose94.pdf
@@ -167,8 +166,8 @@ bashref.info: $(BASHREF_FILES) $(HSUSER) $(RLUSER)
 bashref.html: $(BASHREF_FILES) $(HSUSER) $(RLUSER)
 	$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/bashref.texi
 
-bash.info: bashref.info
-	${SHELL} ${INFOPOST} < $(srcdir)/bashref.info > $@ ; \
+bash.info: $(BASHREF_FILES) $(HSUSER) $(RLUSER)
+	$(MAKEINFO) --no-split -I$(TEXINPUTDIR) $(srcdir)/bashref.texi -o $@
 
 bash.txt: bash.1
 bash.ps: bash.1
@@ -222,9 +221,10 @@ installdirs:
 	
 install: info installdirs bash.info
 	-$(INSTALL_DATA) $(srcdir)/bash.1 $(DESTDIR)$(man1dir)/bash${man1ext}
+	-$(INSTALL_DATA) $(srcdir)/rbash.1 $(DESTDIR)$(man1dir)/rbash${man1ext}
 	-$(INSTALL_DATA) $(srcdir)/bashbug.1 $(DESTDIR)$(man1dir)/bashbug${man1ext}
 # uncomment the next line to install the builtins man page
-#	-$(INSTALL_DATA) $(srcdir)/builtins.1 $(DESTDIR)$(man1dir)/bash_builtins${man1ext}
+	-$(INSTALL_DATA) $(srcdir)/builtins.1 $(DESTDIR)$(man1dir)/builtins${man1ext}
 	-$(INSTALL_DATA) $(srcdir)/bash.info $(DESTDIR)$(infodir)/bash.info
 # run install-info if it is present to update the info directory
 	if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
diff --git a/doc/bash.1 b/doc/bash.1
index 4d977f9..8c336c1 100644
--- a/doc/bash.1
+++ b/doc/bash.1
@@ -116,6 +116,12 @@ processing, then commands are read from the standard input.
 This option allows the positional parameters to be set
 when invoking an interactive shell.
 .TP
+.B \-v
+Print shell input lines as they are read.
+.TP
+.B \-x
+Print commands and their arguments as they are executed.
+.TP
 .B \-D
 A list of all double-quoted strings preceded by \fB$\fP
 is printed on the standard output.
@@ -232,6 +238,13 @@ The shell becomes restricted (see
 .B "RESTRICTED SHELL"
 below).
 .TP
+.B \-\-rpm-requires
+Produce the list of files that are required for the
+shell script to run.  This implies '-n' and is subject
+to the same limitations as compile time error checking checking;
+Backticks, [] tests,  and evals are not parsed so some
+dependencies may be missed.
+.TP
 .B \-\-verbose
 Equivalent to  \fB\-v\fP.
 .TP
@@ -1647,7 +1660,9 @@ A filename whose suffix matches one of the entries in
 is excluded from the list of matched filenames.
 A sample value is
 .if t \f(CW".o:~"\fP.
-.if n ".o:~".
+.if n ".o:~"
+(Quoting is needed when assigning a value to this variable,
+which contains tildes).
 .TP
 .B GLOBIGNORE
 A colon-separated list of patterns defining the set of filenames to
@@ -2420,6 +2435,9 @@ below).
 \fIlength\fP must evaluate to a number greater than or equal to zero.
 If \fIoffset\fP evaluates to a number less than zero, the value
 is used as an offset from the end of the value of \fIparameter\fP.
+Arithmetic expressions starting with a - must be separated by whitespace
+from the preceding : to be
+distinguished from the \fBUse Default Values\fP expansion.
 If \fIparameter\fP is \fB@\fP, the result is \fIlength\fP positional
 parameters beginning at \fIoffset\fP.
 If \fIparameter\fP is an array name indexed by @ or *,
@@ -2611,6 +2629,9 @@ and the substitution of the result.  The format for arithmetic expansion is:
 \fB$((\fP\fIexpression\fP\fB))\fP
 .RE
 .PP
+The old format \fB$[\fP\fIexpression\fP\fB]\fP is deprecated and will
+be removed in upcoming versions of bash.
+.PP
 The
 .I expression
 is treated as if it were within double quotes, but a double quote
@@ -2748,6 +2769,10 @@ If the shell option
 .B nocaseglob
 is enabled, the match is performed without regard to the case
 of alphabetic characters.
+Note that when using range expressions like
+[a-z] (see below), letters of the other case may be included,
+depending on the setting of
+.B LC_COLLATE.
 When a pattern is used for pathname expansion,
 the character
 .B ``.''
@@ -3014,6 +3039,9 @@ a UDP connection to the corresponding socket.
 .PD
 .RE
 .PP
+\fBNOTE:\fP This Bash build does \fBnot\fP support using
+the \fB/dev/tcp\fP and \fB/dev/udp\fP files.
+.PP
 A failure to open or create a file causes the redirection to fail.
 .PP
 Redirections using file descriptors greater than 9 should be used with
@@ -3543,6 +3571,10 @@ descriptor 0, 1, or 2, respectively, is checked.
 .PP
 Unless otherwise specified, primaries that operate on files follow symbolic
 links and operate on the target of the link, rather than the link itself.
+.PP
+See the description of the \fItest\fP builtin command (section SHELL
+BUILTIN COMMANDS below) for the handling of parameters (i.e.
+missing parameters).
 .sp 1
 .PD 0
 .TP
@@ -6839,7 +6871,7 @@ if
 .SM
 .B FCEDIT
 is not set.  If neither variable is set,
-.FN vi
+.FN vitmp
 is used.  When editing is complete, the edited commands are
 echoed and executed.
 .sp 1
diff --git a/doc/bashbug.1 b/doc/bashbug.1
index 971e4c4..fefe156 100644
--- a/doc/bashbug.1
+++ b/doc/bashbug.1
@@ -35,7 +35,8 @@ Specifies the preferred editor. If
 is not set,
 .B bashbug
 defaults to
-.BR emacs .
+an instance of
+.BR vi .
 .TP
 .B HOME
 Directory in which the failed bug report is saved if the mail fails.
diff --git a/doc/bashref.texi b/doc/bashref.texi
index c2892d6..4f618b4 100644
--- a/doc/bashref.texi
+++ b/doc/bashref.texi
@@ -1589,6 +1589,9 @@ This is referred to as Substring Expansion.
 @var{length} must evaluate to a number greater than or equal to zero.
 If @var{offset} evaluates to a number less than zero, the value
 is used as an offset from the end of the value of @var{parameter}.
+Arithmetic expressions starting with a - must be separated by whitespace
+from the preceding : to be
+distinguished from the $@{@var{parameter}:@minus{}@var{word}@} expansion.
 If @var{parameter} is @samp{@@}, the result is @var{length} positional
 parameters beginning at @var{offset}.
 If @var{parameter} is an array name indexed by @samp{@@} or @samp{*},
@@ -2025,6 +2028,9 @@ If @var{host} is a valid hostname or Internet address, and @var{port}
 is an integer port number or service name, Bash attempts to open a UDP
 connection to the corresponding socket.
 
+NOTE: This @code{Bash} build does not support using the
+@file{/dev/tcp} and @file{/dev/udp} files.
+
 @end table
 
 A failure to open or create a file causes the redirection to fail.
@@ -4906,6 +4912,13 @@ standard.  @xref{Bash POSIX Mode}, for a description of the Bash
 @item --restricted
 Make the shell a restricted shell (@pxref{The Restricted Shell}).
 
+@item --rpm-requires
+Produce the list of files that are required for the
+shell script to run.  This implies '-n' and is subject
+to the same limitations as compile time error checking checking;
+Backticks, [] tests,  and evals are not parsed so some
+dependencies may be missed.
+
 @item --verbose
 Equivalent to @option{-v}.  Print shell input lines as they're read.
 
@@ -5285,6 +5298,10 @@ descriptor 0, 1, or 2, respectively, is checked.
 Unless otherwise specified, primaries that operate on files follow symbolic
 links and operate on the target of the link, rather than the link itself.
 
+See the description of the @code{test} builtin command (section
+@pxref{Bash Builtins} below) for the handling of parameters
+(i.e. missing parameters).
+
 @table @code
 @item -a @var{file}
 True if @var{file} exists.
diff --git a/doc/builtins.1 b/doc/builtins.1
index 6a0b248..0e25b2d 100644
--- a/doc/builtins.1
+++ b/doc/builtins.1
@@ -7,8 +7,8 @@ continue, declare, dirs, disown, echo, enable, eval, exec, exit,
 export, fc, fg, getopts, hash, help, history, jobs, kill,
 let, local, logout, popd, printf, pushd, pwd, read, readonly, return, set,
 shift, shopt, source, suspend, test, times, trap, type, typeset,
-ulimit, umask, unalias, unset, wait \- bash built-in commands, see \fBbash\fR(1)
-.SH BASH BUILTIN COMMANDS
+ulimit, umask, unalias, unset, wait \- bash built-in commands
+.SH "BASH BUILTIN COMMANDS"
 .nr zZ 1
 .so bash.1
 .SH SEE ALSO
diff --git a/doc/rbash.1 b/doc/rbash.1
index c148abf..e4bb507 100644
--- a/doc/rbash.1
+++ b/doc/rbash.1
@@ -1,7 +1,7 @@
 .TH RBASH 1 "2004 Apr 20" "GNU Bash-3.0"
 .SH NAME
-rbash \- restricted bash, see \fBbash\fR(1)
-.SH RESTRICTED SHELL
+rbash \- restricted bash
+.SH "RESTRICTED SHELL"
 .nr zY 1
 .so bash.1
 .SH SEE ALSO
diff --git a/error.c b/error.c
index 83f6a7a..0cf1176 100644
--- a/error.c
+++ b/error.c
@@ -144,7 +144,9 @@ programming_error (format, va_alist)
 #endif
 {
   va_list args;
+#if defined (HISTORY)
   char *h;
+#endif
 
 #if defined (JOB_CONTROL)
   give_terminal_to (shell_pgrp, 0);
@@ -358,6 +360,7 @@ itrace (format, va_alist)
 
 /* A trace function for silent debugging -- doesn't require a control
    terminal. */
+/* Unused. */
 void
 #if defined (PREFER_STDARG)
 trace (const char *format, ...)
@@ -371,7 +374,7 @@ trace (format, va_alist)
   static FILE *tracefp = (FILE *)NULL;
 
   if (tracefp == NULL)
-    tracefp = fopen("/tmp/bash-trace.log", "a+");
+    tracefp = fopen("/var/run/bash-trace.log", "a+");
 
   if (tracefp == NULL)
     tracefp = stderr;
diff --git a/eval.c b/eval.c
index bae6c5b..c7271ad 100644
--- a/eval.c
+++ b/eval.c
@@ -53,6 +53,7 @@ extern int last_command_exit_value, stdin_redir;
 extern int need_here_doc;
 extern int current_command_number, current_command_line_count, line_number;
 extern int expand_aliases;
+extern int rpm_requires;
 
 static void send_pwd_to_eterm __P((void));
 static sighandler alrm_catcher __P((int));
@@ -131,13 +132,13 @@ reader_loop ()
 
       if (read_command () == 0)
 	{
-	  if (interactive_shell == 0 && read_but_dont_execute)
+	  if (interactive_shell == 0 && (read_but_dont_execute && !rpm_requires))
 	    {
 	      last_command_exit_value = EXECUTION_SUCCESS;
 	      dispose_command (global_command);
 	      global_command = (COMMAND *)NULL;
 	    }
-	  else if (current_command = global_command)
+	  else if ((current_command = global_command))
 	    {
 	      global_command = (COMMAND *)NULL;
 	      current_command_number++;
diff --git a/execute_cmd.c b/execute_cmd.c
index 81de1dc..943cafc 100644
--- a/execute_cmd.c
+++ b/execute_cmd.c
@@ -476,6 +476,8 @@ async_redirect_stdin ()
 
 #define DESCRIBE_PID(pid) do { if (interactive) describe_pid (pid); } while (0)
 
+extern int rpm_requires;
+
 /* Execute the command passed in COMMAND, perhaps doing it asynchrounously.
    COMMAND is exactly what read_command () places into GLOBAL_COMMAND.
    ASYNCHROUNOUS, if non-zero, says to do this command in the background.
@@ -507,7 +509,15 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
 #else
   if (breaking || continuing)
     return (last_command_exit_value);
-  if (command == 0 || read_but_dont_execute)
+  if (command == 0 || (read_but_dont_execute && !rpm_requires))
+    return (EXECUTION_SUCCESS);
+
+  if (rpm_requires && command->type == cm_function_def)
+    return last_command_exit_value =
+      execute_intern_function (command->value.Function_def->name,
+			       command->value.Function_def->command);
+
+  if (read_but_dont_execute)
     return (EXECUTION_SUCCESS);
 #endif
 
@@ -891,6 +901,8 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
 #  endif
       set_pipestatus_from_exit (exec_result);
       break;
+    default:
+      break;
     }
 #endif
 
@@ -2542,8 +2554,8 @@ execute_cond_node (cond)
   else if (cond->type == COND_BINARY)
     {
       rmatch = 0;
-      patmatch = ((cond->op->word[1] == '=') && (cond->op->word[2] == '\0') &&
-		  (cond->op->word[0] == '!' || cond->op->word[0] == '=') ||
+      patmatch = (((cond->op->word[1] == '=') && (cond->op->word[2] == '\0') &&
+		  (cond->op->word[0] == '!' || cond->op->word[0] == '=')) ||
 		  (cond->op->word[0] == '=' && cond->op->word[1] == '\0'));
 #if defined (COND_REGEXP)
       rmatch = (cond->op->word[0] == '=' && cond->op->word[1] == '~' &&
@@ -3739,7 +3751,9 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
     }
   else
     {
+#if defined (RESTRICTED_SHELL)
 parent_return:
+#endif /* RESTRICTED_SHELL */
       /* Make sure that the pipes are closed in the parent. */
       close_pipes (pipe_in, pipe_out);
 #if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
@@ -4073,7 +4087,7 @@ execute_intern_function (name, function)
 
   if (check_identifier (name, posixly_correct) == 0)
     {
-      if (posixly_correct && interactive_shell == 0)
+      if (posixly_correct && interactive_shell == 0 && rpm_requires == 0)
 	{
 	  last_command_exit_value = EX_USAGE;
 	  jump_to_top_level (ERREXIT);
diff --git a/execute_cmd.h b/execute_cmd.h
index 6de86be..2b34715 100644
--- a/execute_cmd.h
+++ b/execute_cmd.h
@@ -22,6 +22,8 @@
 #define _EXECUTE_CMD_H_
 
 #include "stdc.h"
+#include "variables.h"
+#include "command.h"
 
 extern struct fd_bitmap *new_fd_bitmap __P((int));
 extern void dispose_fd_bitmap __P((struct fd_bitmap *));
diff --git a/expr.c b/expr.c
index a5cb038..2c04138 100644
--- a/expr.c
+++ b/expr.c
@@ -418,11 +418,8 @@ expassign ()
       if (lasttok != STR)
 	evalerror (_("attempted assignment to non-variable"));
 
-      if (special)
-	{
-	  op = assigntok;		/* a OP= b */
-	  lvalue = value;
-	}
+      op = assigntok;		/* a OP= b */
+      lvalue = value;
 
       lhs = savestring (tokstr);
       readtok ();
diff --git a/externs.h b/externs.h
index bc28eda..a5f8d66 100644
--- a/externs.h
+++ b/externs.h
@@ -367,9 +367,10 @@ extern void print_timeval ();
 /* declarations for functions defined in lib/sh/tmpfile.c */
 #define MT_USETMPDIR		0x0001
 #define MT_READWRITE		0x0002
-#define MT_USERANDOM		0x0004
 
-extern char *sh_mktmpname __P((char *, int));
+#if !defined(HAVE_DEV_FD)
+extern char *sh_mktmpname_unsafe __P((char *, int));
+#endif
 extern int sh_mktmpfd __P((char *, int, char **));
 /* extern FILE *sh_mktmpfp __P((char *, int, char **)); */
 
diff --git a/findcmd.c b/findcmd.c
index 27720f8..0cb070f 100644
--- a/findcmd.c
+++ b/findcmd.c
@@ -94,7 +94,22 @@ file_status (name)
 
   r = FS_EXISTS;
 
-#if defined (AFS)
+#if defined (HAVE_EACCESS)	/* FreeBSD, GLIBC_2.4+ */
+
+  /* For support of ACL's use eaccess(3) if found e.g. glibc 2.4 and up:
+   * Like  access(2), euidaccess(3) checks permissions and existence of the
+   * file identified by its argument pathname.  However, whereas access(2),
+   * performs checks using the real user and group identifiers of the pro-
+   * cess, euidaccess(3) uses the effective identifiers.
+   * eaccess(3) is a synonym for euidaccess(3), provided for compatibility
+   * with some other systems. */
+  if (eaccess (name, X_OK) == 0)
+      r |= FS_EXECABLE;
+  if (eaccess (name, R_OK) == 0)
+      r |= FS_READABLE;
+
+#elif defined (AFS)
+
   /* We have to use access(2) to determine access because AFS does not
      support Unix file system semantics.  This may produce wrong
      answers for non-AFS files when ruid != euid.  I hate AFS. */
@@ -103,8 +118,7 @@ file_status (name)
   if (access (name, R_OK) == 0)
     r |= FS_READABLE;
 
-  return r;
-#else /* !AFS */
+#else /* !AFS && !HAVE_EACCESS */
 
   /* Find out if the file is actually executable.  By definition, the
      only other criteria is that the file has an execute bit set that
@@ -147,8 +161,8 @@ file_status (name)
 	r |= FS_READABLE;
     }
 
+#endif /* !AFS && !HAVE_EACCESS */
   return r;
-#endif /* !AFS */
 }
 
 /* Return non-zero if FILE exists and is executable.
@@ -216,7 +230,7 @@ _find_user_command_internal (name, flags)
 
   /* Search for the value of PATH in both the temporary environments and
      in the regular list of variables. */
-  if (var = find_variable_internal ("PATH", 1))	/* XXX could be array? */
+  if ((var = find_variable_internal ("PATH", 1)))	/* XXX could be array? */
     path_list = value_cell (var);
   else
     path_list = (char *)NULL;
diff --git a/general.c b/general.c
index 4ac4de0..a3538ff 100644
--- a/general.c
+++ b/general.c
@@ -274,7 +274,7 @@ assignment (string, flags)
 #endif
     return (0);
 
-  while (c = string[indx])
+  while ((c = string[indx]))
     {
       /* The following is safe.  Note that '=' at the start of a word
 	 is not an assignment statement. */
diff --git a/hashlib.c b/hashlib.c
index 456272a..5e97c64 100644
--- a/hashlib.c
+++ b/hashlib.c
@@ -81,7 +81,7 @@ copy_bucket_array (ba, cpdata)
   if (ba == 0)
     return ((BUCKET_CONTENTS *)0);
 
-  for (n = (BUCKET_CONTENTS *)0, e = ba; e; e = e->next)
+  for (new_bucket = n = (BUCKET_CONTENTS *)0, e = ba; e; e = e->next)
     {
       if (n == 0)
         {
diff --git a/jobs.c b/jobs.c
index d183394..6f34338 100644
--- a/jobs.c
+++ b/jobs.c
@@ -213,7 +213,7 @@ int already_making_children = 0;
 
 /* If this is non-zero, $LINES and $COLUMNS are reset after every process
    exits from get_tty_state(). */
-int check_window_size;
+int check_window_size = 1;
 
 /* Functions local to this file. */
 
@@ -1050,7 +1050,7 @@ nohup_job (job_index)
   if (js.j_jobslots == 0)
     return;
 
-  if (temp = jobs[job_index])
+  if ((temp = jobs[job_index]))
     temp->flags |= J_NOHUP;
 }
 
@@ -2311,7 +2311,6 @@ wait_for (pid)
   WAIT s;
   register PROCESS *child;
   sigset_t set, oset;
-  register PROCESS *p;
 
   /* In the case that this code is interrupted, and we longjmp () out of it,
      we are relying on the code in throw_to_top_level () to restore the
@@ -3596,8 +3595,7 @@ initialize_job_control (force)
 
   change_flag ('m', job_control ? '-' : '+');
 
-  if (interactive)
-    get_tty_state ();
+  get_tty_state ();
 
   if (js.c_childmax < 0)
     js.c_childmax = getmaxchild ();
@@ -4100,11 +4098,13 @@ pipe_close (pp)
   pp[0] = pp[1] = -1;
 }
 
+#if defined (JOB_CONTROL)
 /* Functional interface closes our local-to-job-control pipes. */
 void
 close_pgrp_pipe ()
 {
   pipe_close (pgrp_pipe);
 }
+#endif /* JOB_CONTROL */
 
 #endif /* PGRP_PIPE */
diff --git a/jobs.h b/jobs.h
index 93a42fb..c56f655 100644
--- a/jobs.h
+++ b/jobs.h
@@ -229,6 +229,10 @@ extern void default_tty_job_signals __P((void));
 
 extern void init_job_stats __P((void));
 
+#if defined (JOB_CONTROL) && defined (PGRP_PIPE)
+extern void close_pgrp_pipe __P((void));
+#endif
+
 #if defined (JOB_CONTROL)
 extern int job_control;
 #endif
diff --git a/lib/glob/glob.c b/lib/glob/glob.c
index 08a7da8..3a4eec4 100644
--- a/lib/glob/glob.c
+++ b/lib/glob/glob.c
@@ -46,6 +46,7 @@
 #include "stdc.h"
 #include "memalloc.h"
 #include "quit.h"
+#include "sig.h"
 
 #include "glob.h"
 #include "strmatch.h"
@@ -357,7 +358,7 @@ glob_vector (pat, dir, flags)
   struct globval *firstmalloc, *tmplink;
 
   lastlink = 0;
-  count = lose = skip = 0;
+  count = lose = skip = nalloca = 0;
 
   firstmalloc = 0;
   nalloca = 0;
diff --git a/lib/glob/sm_loop.c b/lib/glob/sm_loop.c
index 41b0759..cb2982f 100644
--- a/lib/glob/sm_loop.c
+++ b/lib/glob/sm_loop.c
@@ -301,7 +301,7 @@ BRACKMATCH (p, test, flags)
      circumflex (`^') in its role in a `nonmatching list'.  A bracket
      expression starting with an unquoted circumflex character produces
      unspecified results.  This implementation treats the two identically. */
-  if (not = (*p == L('!') || *p == L('^')))
+  if ((not = (*p == L('!') || *p == L('^'))))
     ++p;
 
   c = *p++;
@@ -529,7 +529,7 @@ PATSCAN (string, end, delim)
   cchar = 0;
   bfirst = NULL;
 
-  for (s = string; c = *s; s++)
+  for (s = string; (c = *s); s++)
     {
       if (s >= end)
 	return (s);
@@ -610,7 +610,7 @@ STRCOMPARE (p, pe, s, se)
   c2 = *se;
 
   *pe = *se = '\0';
-#if HAVE_MULTIBYTE || defined (HAVE_STRCOLL)
+#if HANDLE_MULTIBYTE || defined (HAVE_STRCOLL)
   ret = STRCOLL ((XCHAR *)p, (XCHAR *)s);
 #else
   ret = STRCMP ((XCHAR *)p, (XCHAR *)s);
@@ -682,9 +682,9 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
 		  xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags;
 		  m2 = (GMATCH (srest, se, prest, pe, xflags) == 0) ||
 			(s != srest && GMATCH (srest, se, p - 1, pe, xflags) == 0);
+		  if (m2)
+		    return (0);
 		}
-	      if (m1 && m2)
-		return (0);
 	    }
 	  if (pnext == prest)
 	    break;
@@ -727,7 +727,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
 	    {
 	      pnext = PATSCAN (psub, pe, L('|'));
 	      /* If one of the patterns matches, just bail immediately. */
-	      if (m1 = (GMATCH (s, srest, psub, pnext - 1, flags) == 0))
+	      if ((m1 = (GMATCH (s, srest, psub, pnext - 1, flags) == 0)))
 		break;
 	      if (pnext == prest)
 		break;
diff --git a/lib/glob/smatch.c b/lib/glob/smatch.c
index be4f927..0b08e99 100644
--- a/lib/glob/smatch.c
+++ b/lib/glob/smatch.c
@@ -353,7 +353,7 @@ is_wcclass (wc, name)
 #define IS_CCLASS(C, S)		is_wcclass((C), (S))
 #include "sm_loop.c"
 
-#endif /* HAVE_MULTIBYTE */
+#endif /* HANDLE_MULTIBYTE */
 
 int
 xstrmatch (pattern, string, flags)
diff --git a/lib/glob/strmatch.c b/lib/glob/strmatch.c
index 4d9c68d..ff3b5a1 100644
--- a/lib/glob/strmatch.c
+++ b/lib/glob/strmatch.c
@@ -25,7 +25,7 @@
 #include "strmatch.h"
 
 extern int xstrmatch __P((char *, char *, int));
-#if defined (HAVE_MULTIBYTE)
+#if defined (HANDLE_MULTIBYTE)
 extern int internal_wstrmatch __P((wchar_t *, wchar_t *, int));
 #endif
 
diff --git a/lib/malloc/stats.c b/lib/malloc/stats.c
index 0d119fa..593260e 100644
--- a/lib/malloc/stats.c
+++ b/lib/malloc/stats.c
@@ -132,7 +132,7 @@ fprint_malloc_stats (s, fp)
   _print_malloc_stats (s, fp);
 }
 
-#define TRACEROOT "/var/tmp/maltrace/stats."
+#define TRACEROOT "/var/run/maltrace/stats."
 
 void
 trace_malloc_stats (s, fn)
diff --git a/lib/malloc/trace.c b/lib/malloc/trace.c
index 79f4668..37e0e11 100644
--- a/lib/malloc/trace.c
+++ b/lib/malloc/trace.c
@@ -107,7 +107,7 @@ malloc_trace_bin (n)
 #endif
 }
 
-#define TRACEROOT "/var/tmp/maltrace/trace."
+#define TRACEROOT "/var/run/maltrace/trace."
 
 void
 malloc_set_tracefn (s, fn)
diff --git a/lib/readline/rldefs.h b/lib/readline/rldefs.h
index 0f6c874..609c4a6 100644
--- a/lib/readline/rldefs.h
+++ b/lib/readline/rldefs.h
@@ -81,7 +81,7 @@ extern int _rl_stricmp PARAMS((char *, char *));
 extern int _rl_strnicmp PARAMS((char *, char *, int));
 #endif
 
-#if defined (HAVE_STRPBRK) && !defined (HAVE_MULTIBYTE)
+#if defined (HAVE_STRPBRK) && !defined (HANDLE_MULTIBYTE)
 #  define _rl_strpbrk(a,b)	strpbrk((a),(b))
 #else
 extern char *_rl_strpbrk PARAMS((const char *, const char *));
diff --git a/lib/sh/eaccess.c b/lib/sh/eaccess.c
index 1cff692..0c6e2bf 100644
--- a/lib/sh/eaccess.c
+++ b/lib/sh/eaccess.c
@@ -54,7 +54,7 @@ extern int errno;
 
 static int path_is_devfd __P((const char *));
 static int sh_stataccess __P((char *, int));
-#if HAVE_DECL_SETREGID
+#if HAVE_DECL_SETREGID && !defined (HAVE_EACCESS) && !defined (EFF_ONLY_OK)
 static int sh_euidaccess __P((char *, int));
 #endif
 
@@ -165,7 +165,7 @@ sh_stataccess (path, mode)
   return (-1);
 }
 
-#if HAVE_DECL_SETREGID
+#if HAVE_DECL_SETREGID && !defined (HAVE_EACCESS) && !defined (EFF_ONLY_OK)
 /* Version to call when uid != euid or gid != egid.  We temporarily swap
    the effective and real uid and gid as appropriate. */
 static int
@@ -201,7 +201,7 @@ sh_eaccess (path, mode)
   if (path_is_devfd (path))
     return (sh_stataccess (path, mode));
 
-#if defined (HAVE_EACCESS)		/* FreeBSD */
+#if defined (HAVE_EACCESS)		/* FreeBSD, GLIBC_2.4+ */
   return (eaccess (path, mode));
 #elif defined (EFF_ONLY_OK)		/* SVR4(?), SVR4.2 */
   return access (path, mode|EFF_ONLY_OK);
diff --git a/lib/sh/makepath.c b/lib/sh/makepath.c
index c496154..3628822 100644
--- a/lib/sh/makepath.c
+++ b/lib/sh/makepath.c
@@ -110,7 +110,7 @@ sh_makepath (path, dir, flags)
   if (s[-1] != '/')
     *r++ = '/';      
   s = xdir;
-  while (*r++ = *s++)
+  while ((*r++ = *s++))
     ;
   if (xpath != path)
     free (xpath);
diff --git a/lib/sh/netopen.c b/lib/sh/netopen.c
index d8eec75..71d699c 100644
--- a/lib/sh/netopen.c
+++ b/lib/sh/netopen.c
@@ -25,6 +25,8 @@
 
 #include <config.h>
 
+#if defined (NETWORK_REDIRECTIONS)
+
 #if defined (HAVE_NETWORK)
 
 #if defined (HAVE_UNISTD_H)
@@ -237,7 +239,7 @@ _netopen6 (host, serv, typ)
       return -1;
     }
 
-  for (res = res0; res; res = res->ai_next)
+  for (res = res0, s = -1; res; res = res->ai_next)
     {
       if ((s = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
 	{
@@ -348,3 +350,5 @@ netopen (path)
 }
 
 #endif /* !HAVE_NETWORK */
+
+#endif /* !NETWORK_REDIRECTIONS */
diff --git a/lib/sh/pathcanon.c b/lib/sh/pathcanon.c
index 3b427a8..8f48c03 100644
--- a/lib/sh/pathcanon.c
+++ b/lib/sh/pathcanon.c
@@ -114,7 +114,7 @@ sh_canonpath (path, flags)
 
   /* POSIX.2 says to leave a leading `//' alone.  On cygwin, we skip over any
      leading `x:' (dos drive name). */
-  if (rooted = ROOTEDPATH(path))
+  if ((rooted = ROOTEDPATH(path)))
     {
       stub_char = DIRSEP;
 #if defined (__CYGWIN__)
diff --git a/lib/sh/spell.c b/lib/sh/spell.c
index cff20b2..20fc8bb 100644
--- a/lib/sh/spell.c
+++ b/lib/sh/spell.c
@@ -95,7 +95,7 @@ spname(oldname, newname)
       /*
        *  Add to end of newname
        */
-      for (p = best; *np = *p++; np++)
+      for (p = best; (*np = *p++); np++)
 	;
     }
 }
diff --git a/lib/sh/strtrans.c b/lib/sh/strtrans.c
index 1f0290e..f4d7cdb 100644
--- a/lib/sh/strtrans.c
+++ b/lib/sh/strtrans.c
@@ -247,7 +247,7 @@ ansic_shouldquote (string)
   if (string == 0)
     return 0;
 
-  for (s = string; c = *s; s++)
+  for (s = string; (c = *s); s++)
     if (ISPRINT (c) == 0)
       return 1;
 
diff --git a/lib/sh/tmpfile.c b/lib/sh/tmpfile.c
index 5f2279d..e895ff4 100644
--- a/lib/sh/tmpfile.c
+++ b/lib/sh/tmpfile.c
@@ -22,132 +22,49 @@
 
 #include <config.h>
 
-#include <bashtypes.h>
-#include <posixstat.h>
-#include <posixtime.h>
-#include <filecntl.h>
 
 #if defined (HAVE_UNISTD_H)
 #  include <unistd.h>
 #endif
 
 #include <stdio.h>
-#include <errno.h>
+#include <stdlib.h>
 
 #include <shell.h>
 
-#ifndef errno
-extern int errno;
-#endif
-
-#define BASEOPENFLAGS	(O_CREAT | O_TRUNC | O_EXCL)
-
-#define DEFAULT_TMPDIR		"."	/* bogus default, should be changed */
-#define DEFAULT_NAMEROOT	"shtmp"
-
-extern pid_t dollar_dollar_pid;
-
-static char *get_sys_tmpdir __P((void));
-static char *get_tmpdir __P((int));
-
-static char *sys_tmpdir = (char *)NULL;
-static int ntmpfiles;
-static int tmpnamelen = -1;
-static unsigned long filenum = 1L;
-
-static char *
-get_sys_tmpdir ()
-{
-  if (sys_tmpdir)
-    return sys_tmpdir;
-
-#ifdef P_tmpdir
-  sys_tmpdir = P_tmpdir;
-  if (file_iswdir (sys_tmpdir))
-    return sys_tmpdir;
-#endif
-
-  sys_tmpdir = "/tmp";
-  if (file_iswdir (sys_tmpdir))
-    return sys_tmpdir;
-
-  sys_tmpdir = "/var/tmp";
-  if (file_iswdir (sys_tmpdir))
-    return sys_tmpdir;
-
-  sys_tmpdir = "/usr/tmp";
-  if (file_iswdir (sys_tmpdir))
-    return sys_tmpdir;
-
-  sys_tmpdir = DEFAULT_TMPDIR;
-
-  return sys_tmpdir;
-}
+#define DEFAULT_TMPDIR			P_tmpdir
+#define DEFAULT_NAMEROOT		"bash"
 
 static char *
 get_tmpdir (flags)
      int flags;
 {
-  char *tdir;
-
-  tdir = (flags & MT_USETMPDIR) ? get_string_value ("TMPDIR") : (char *)NULL;
-  if (tdir == 0)
-    tdir = get_sys_tmpdir ();
-
-#if defined (HAVE_PATHCONF) && defined (_PC_NAME_MAX)
-  if (tmpnamelen == -1)
-    tmpnamelen = pathconf (tdir, _PC_NAME_MAX);
-#else
-  tmpnamelen = 0;
-#endif
-
-  return tdir;
+  if (flags & MT_USETMPDIR)
+    return get_string_value ("TMPDIR") ?: DEFAULT_TMPDIR;
+  return DEFAULT_TMPDIR;
 }
 
+#if !defined(HAVE_DEV_FD)
+/* This is renamed to *_unsafe to trap and review possible additional
+ * references when applying the patch to future versions of bash. */
 char *
-sh_mktmpname (nameroot, flags)
+sh_mktmpname_unsafe (nameroot, flags)
      char *nameroot;
      int flags;
 {
-  char *filename, *tdir, *lroot;
-  struct stat sb;
-  int r, tdlen;
-
-  filename = (char *)xmalloc (PATH_MAX + 1);
-  tdir = get_tmpdir (flags);
-  tdlen = strlen (tdir);
-
-  lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
+  char *filename;
 
-#ifdef USE_MKTEMP
-  sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
-  if (mktemp (filename) == 0)
+  if (asprintf (&filename, "%s/%s.XXXXXX", get_tmpdir (flags),
+		nameroot ?: DEFAULT_NAMEROOT) < 0)
+    return NULL;
+  if (!mktemp (filename) || !*filename)
     {
       free (filename);
       filename = NULL;
     }
-#else  /* !USE_MKTEMP */
-  while (1)
-    {
-      filenum = (filenum << 1) ^
-		(unsigned long) time ((time_t *)0) ^
-		(unsigned long) dollar_dollar_pid ^
-		(unsigned long) ((flags & MT_USERANDOM) ? get_random_number () : ntmpfiles++);
-      sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum);
-      if (tmpnamelen > 0 && tmpnamelen < 32)
-	filename[tdlen + 1 + tmpnamelen] = '\0';
-#  ifdef HAVE_LSTAT
-      r = lstat (filename, &sb);
-#  else
-      r = stat (filename, &sb);
-#  endif
-      if (r < 0 && errno == ENOENT)
-	break;
-    }
-#endif /* !USE_MKTEMP */
-
   return filename;
 }
+#endif /* !defined(HAVE_DEV_FD) */
 
 int
 sh_mktmpfd (nameroot, flags, namep)
@@ -155,47 +72,25 @@ sh_mktmpfd (nameroot, flags, namep)
      int flags;
      char **namep;
 {
-  char *filename, *tdir, *lroot;
-  int fd, tdlen;
-
-  filename = (char *)xmalloc (PATH_MAX + 1);
-  tdir = get_tmpdir (flags);
-  tdlen = strlen (tdir);
+  char *filename;
+  int fd = -1;
 
-  lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
-
-#ifdef USE_MKSTEMP
-  sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
-  fd = mkstemp (filename);
-  if (fd < 0 || namep == 0)
+  if (namep)
+    *namep = NULL;
+  if (asprintf (&filename, "%s/%s.XXXXXX", get_tmpdir (flags),
+		nameroot ?: DEFAULT_NAMEROOT) < 0)
+    return -1;
+  if ((fd = mkstemp (filename)) < 0)
     {
       free (filename);
       filename = NULL;
     }
   if (namep)
     *namep = filename;
-  return fd;
-#else /* !USE_MKSTEMP */
-  do
-    {
-      filenum = (filenum << 1) ^
-		(unsigned long) time ((time_t *)0) ^
-		(unsigned long) dollar_dollar_pid ^
-		(unsigned long) ((flags & MT_USERANDOM) ? get_random_number () : ntmpfiles++);
-      sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum);
-      if (tmpnamelen > 0 && tmpnamelen < 32)
-	filename[tdlen + 1 + tmpnamelen] = '\0';
-      fd = open (filename, BASEOPENFLAGS | ((flags & MT_READWRITE) ? O_RDWR : O_WRONLY), 0600);
-    }
-  while (fd < 0 && errno == EEXIST);
-
-  if (namep)
-    *namep = filename;
-  else
-    free (filename);
+  else if (filename)
+    free(filename);
 
   return fd;
-#endif /* !USE_MKSTEMP */
 }
 
 FILE *
@@ -207,9 +102,8 @@ sh_mktmpfp (nameroot, flags, namep)
   int fd;
   FILE *fp;
 
-  fd = sh_mktmpfd (nameroot, flags, namep);
-  if (fd < 0)
-    return ((FILE *)NULL);
+  if ((fd = sh_mktmpfd (nameroot, flags, namep)) < 0)
+    return NULL;
   fp = fdopen (fd, (flags & MT_READWRITE) ? "w+" : "w");
   if (fp == 0)
     close (fd);
diff --git a/lib/sh/winsize.c b/lib/sh/winsize.c
index f4696de..9ec2959 100644
--- a/lib/sh/winsize.c
+++ b/lib/sh/winsize.c
@@ -23,6 +23,8 @@
 #include <stdc.h>
 
 #include "bashtypes.h"
+#include "shell.h"
+#include "variables.h"
 
 #if defined (HAVE_UNISTD_H)
 #  include <unistd.h>
diff --git a/lib/tilde/tilde.c b/lib/tilde/tilde.c
index 1b76c9f..b59b502 100644
--- a/lib/tilde/tilde.c
+++ b/lib/tilde/tilde.c
@@ -196,7 +196,7 @@ tilde_expand (string)
   int result_size, result_index;
 
   result_index = result_size = 0;
-  if (result = strchr (string, '~'))
+  if ((result = strchr (string, '~')))
     result = (char *)xmalloc (result_size = (strlen (string) + 16));
   else
     result = (char *)xmalloc (result_size = (strlen (string) + 1));
diff --git a/mailcheck.c b/mailcheck.c
index 4b7e207..44290cf 100644
--- a/mailcheck.c
+++ b/mailcheck.c
@@ -338,7 +338,7 @@ remember_mail_dates ()
       return;
     }
 
-  while (mailfile = extract_colon_unit (mailpaths, &i))
+  while ((mailfile = extract_colon_unit (mailpaths, &i)))
     {
       mp = parse_mailpath_spec (mailfile);
       if (mp && *mp)
@@ -412,7 +412,7 @@ check_mail ()
 #undef atime
 #undef mtime
 
-	  if (temp = expand_string_to_string (message, Q_DOUBLE_QUOTES))
+	  if ((temp = expand_string_to_string (message, Q_DOUBLE_QUOTES)))
 	    {
 	      puts (temp);
 	      free (temp);
diff --git a/make_cmd.c b/make_cmd.c
index a8448d5..c819b27 100644
--- a/make_cmd.c
+++ b/make_cmd.c
@@ -41,11 +41,15 @@ Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
 #include "flags.h"
 #include "make_cmd.h"
 #include "dispose_cmd.h"
+#include "execute_cmd.h"
 #include "variables.h"
 #include "subst.h"
 #include "input.h"
 #include "ocache.h"
 #include "externs.h"
+#include "builtins.h"
+
+#include "builtins/common.h"
 
 #if defined (JOB_CONTROL)
 #include "jobs.h"
@@ -55,6 +59,10 @@ Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
 
 extern int line_number, current_command_line_count;
 extern int last_command_exit_value;
+extern int rpm_requires;
+
+static char *alphabet_set = "abcdefghijklmnopqrstuvwxyz"
+                     "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
 /* Object caching */
 sh_obj_cache_t wdcache = {0, 0, 0};
@@ -602,7 +610,7 @@ make_here_document (temp)
      be read verbatim from the input.  If it was not quoted, we
      need to perform backslash-quoted newline removal. */
   delim_unquoted = (temp->redirectee.filename->flags & W_QUOTED) == 0;
-  while (full_line = read_secondary_line (delim_unquoted))
+  while ((full_line = read_secondary_line (delim_unquoted)))
     {
       register char *line;
       int len;
@@ -746,6 +754,27 @@ make_redirection (source, instruction, dest_and_filename)
   return (temp);
 }
 
+static void
+output_requirement (deptype, filename)
+const char *deptype;
+char *filename;
+{
+  if (strchr(filename, '$') || (filename[0] != '/' && strchr(filename, '/')))
+    return;
+
+  /*
+      if the executable is called via variable substitution we can
+      not dermine what it is at compile time.
+
+      if the executable consists only of characters not in the
+      alphabet we do not consider it a dependency just an artifact
+      of shell parsing (ex "exec < ${infile}").
+  */
+
+  if (strpbrk(filename, alphabet_set))
+    printf ("%s(%s)\n", deptype, filename);
+}
+
 COMMAND *
 make_function_def (name, command, lineno, lstart)
      WORD_DESC *name;
@@ -774,6 +803,23 @@ make_function_def (name, command, lineno, lstart)
 #endif
   bind_function_def (name->word, temp);
 
+  if (rpm_requires)
+    /* Each function is possibly required, which is, er, provided.
+     * I need to know function names in order to implement strong
+     * self-requires elimination in /usr/lib/rpm/shell.req.  Just about
+     * the only way to achieve this without breaking "--rpm-requires"
+     * compatibility is to spit them here as they go.
+     *
+     * Also note that another "function" output in clean_simple_command()
+     * is not much useful since it only means that a function is defined
+     * in the very same file before being used (shell have seen it while
+     * parsing the script).  My point is that it makes no sense to resolve
+     * function requirements -- functions are simply "provided" by its nature.
+     *
+     *    -- at@altlinux
+     */
+    output_requirement ("function", name->word);
+
   temp->source_file = 0;
   return (make_command (cm_function_def, (SIMPLE_COM *)temp));
 }
@@ -807,6 +853,43 @@ clean_simple_command (command)
 	REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
     }
 
+  if (rpm_requires && command->value.Simple->words)
+    {
+      WORD_LIST *words = command->value.Simple->words;
+      const char *cmd = words->word->word;
+
+      /* skip LC_* assignments */
+      while (words->next && assignment (cmd, 0))
+	{
+	  if (strncmp (cmd, "LC_", 3) != 0)
+	    break;
+	  words = words->next;
+	  cmd = words->word->word;
+	}
+
+      if (!assignment (cmd, 0))
+	{
+	  struct builtin *b = builtin_address_internal (cmd, 0);
+	  if (b)
+	    {
+	      /* exec-like builtin with an argument */
+	      if ((b->flags & REQUIRES_BUILTIN) && words->next)
+		{
+		  words = words->next;
+		  cmd = words->word->word;
+		  output_requirement ("executable", cmd);
+		}
+	    }
+	  else
+	    {
+	      if (find_function (cmd) || find_function_def (cmd))
+		output_requirement ("function", cmd);
+	      else
+		output_requirement ("executable", cmd);
+	    }
+	}
+    } /* rpm_requires */
+
   return (command);
 }
 
diff --git a/parse.y b/parse.y
index f1967ab..004df4a 100644
--- a/parse.y
+++ b/parse.y
@@ -194,7 +194,9 @@ static int token_is_assignment __P((char *, int));
 static int token_is_ident __P((char *, int));
 #endif
 static int read_token_word __P((int));
+#ifdef INCLUDE_UNUSED
 static void discard_parser_constructs __P((int));
+#endif
 
 static char *error_token_from_token __P((int));
 static char *error_token_from_text __P((void));
@@ -2778,6 +2780,7 @@ parse_matched_pair (qc, open, close, lenp, flags)
   rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
 
   ret = (char *)xmalloc (retsize = 64);
+  nestret = NULL;
   retind = 0;
 
   start_lineno = line_number;
@@ -3103,7 +3106,7 @@ cond_error ()
     parser_error (cond_lineno, _("unexpected EOF while looking for `]]'"));
   else if (cond_token != COND_ERROR)
     {
-      if (etext = error_token_from_token (cond_token))
+      if ((etext = error_token_from_token (cond_token)))
 	{
 	  parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext);
 	  free (etext);
@@ -3185,7 +3188,7 @@ cond_term ()
 	{
 	  if (term)
 	    dispose_cond_node (term);		/* ( */
-	  if (etext = error_token_from_token (cond_token))
+	  if ((etext = error_token_from_token (cond_token)))
 	    {
 	      parser_error (lineno, _("unexpected token `%s', expected `)'"), etext);
 	      free (etext);
@@ -3217,7 +3220,7 @@ cond_term ()
       else
 	{
 	  dispose_word (op);
-	  if (etext = error_token_from_token (tok))
+	  if ((etext = error_token_from_token (tok)))
 	    {
 	      parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext);
 	      free (etext);
@@ -3261,7 +3264,7 @@ cond_term ()
 	}
       else
 	{
-	  if (etext = error_token_from_token (tok))
+	  if ((etext = error_token_from_token (tok)))
 	    {
 	      parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext);
 	      free (etext);
@@ -3282,7 +3285,7 @@ cond_term ()
 	}
       else
 	{
-	  if (etext = error_token_from_token (tok))
+	  if ((etext = error_token_from_token (tok)))
 	    {
 	      parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext);
 	      free (etext);
@@ -3300,7 +3303,7 @@ cond_term ()
     {
       if (tok < 256)
 	parser_error (line_number, _("unexpected token `%c' in conditional command"), tok);
-      else if (etext = error_token_from_token (tok))
+      else if ((etext = error_token_from_token (tok)))
 	{
 	  parser_error (line_number, _("unexpected token `%s' in conditional command"), etext);
 	  free (etext);
@@ -4061,7 +4064,10 @@ decode_prompt_string (string)
   int last_exit_value;
 #if defined (PROMPT_STRING_DECODE)
   int result_size, result_index;
-  int c, n, i;
+  int c, n;
+#if defined (READLINE)
+  int i;
+#endif /* READLINE */
   char *temp, octal_string[4];
   struct tm *tm;  
   time_t the_time;
@@ -4071,8 +4077,9 @@ decode_prompt_string (string)
   result = (char *)xmalloc (result_size = PROMPT_GROWTH);
   result[result_index = 0] = 0;
   temp = (char *)NULL;
+  n = 0;
 
-  while (c = *string++)
+  while ((c = *string++))
     {
       if (posixly_correct && c == '!')
 	{
@@ -4439,10 +4446,10 @@ error_token_from_token (tok)
 {
   char *t;
 
-  if (t = find_token_in_alist (tok, word_token_alist, 0))
+  if ((t = find_token_in_alist (tok, word_token_alist, 0)))
     return t;
 
-  if (t = find_token_in_alist (tok, other_token_alist, 0))
+  if ((t = find_token_in_alist (tok, other_token_alist, 0)))
     return t;
 
   t = (char *)NULL;
@@ -4594,6 +4601,7 @@ report_syntax_error (message)
   last_command_exit_value = EX_USAGE;
 }
 
+#ifdef INCLUDE_UNUSED
 /* ??? Needed function. ??? We have to be able to discard the constructs
    created during parsing.  In the case of error, we want to return
    allocated objects to the memory pool.  In the case of no error, we want
@@ -4604,6 +4612,7 @@ discard_parser_constructs (error_p)
      int error_p;
 {
 }
+#endif
 
 /************************************************
  *						*
diff --git a/pathexp.c b/pathexp.c
index 69966ac..9052d41 100644
--- a/pathexp.c
+++ b/pathexp.c
@@ -67,7 +67,7 @@ unquoted_glob_pattern_p (string)
   open = 0;
   send = string + strlen (string);
 
-  while (c = *string++)
+  while ((c = *string++))
     {
       switch (c)
 	{
@@ -448,7 +448,7 @@ setup_ignore_patterns (ivp)
 
   numitems = maxitems = ptr = 0;
 
-  while (colon_bit = extract_colon_unit (this_ignoreval, &ptr))
+  while ((colon_bit = extract_colon_unit (this_ignoreval, &ptr)))
     {
       if (numitems + 1 >= maxitems)
 	{
diff --git a/pcomplete.c b/pcomplete.c
index 471fb54..04b348a 100644
--- a/pcomplete.c
+++ b/pcomplete.c
@@ -520,6 +520,8 @@ it_init_joblist (itp, jstate)
     ws = JRUNNING;
   else if (jstate == 1)
     ws = JSTOPPED;
+  else
+    ws = -1;
 
   sl = strlist_create (js.j_jobslots);
   for (i = js.j_jobslots - 1; i >= 0; i--)
diff --git a/print_cmd.c b/print_cmd.c
index d1dfd1a..956db53 100644
--- a/print_cmd.c
+++ b/print_cmd.c
@@ -1149,7 +1149,7 @@ indent (amount)
   for (i = 0; amount > 0; amount--)
     indentation_string[i++] = ' ';
   indentation_string[i] = '\0';
-  cprintf (indentation_string);
+  cprintf ("%s", indentation_string);
 }
 
 static void
diff --git a/redir.c b/redir.c
index 0bd2d5f..de847f7 100644
--- a/redir.c
+++ b/redir.c
@@ -93,6 +93,7 @@ redirection_error (temp, error)
   int oflags;
 
   allocname = 0;
+  oflags = 0;
   if (temp->redirector < 0)
     /* This can happen when read_token_word encounters overflow, like in
        exec 4294967297>x */
@@ -375,7 +376,7 @@ here_document_to_fd (redirectee, ri)
   char *filename;
   int r, fd, fd2;
 
-  fd = sh_mktmpfd ("sh-thd", MT_USERANDOM, &filename);
+  fd = sh_mktmpfd ("sh-thd", MT_USETMPDIR, &filename);
 
   /* If we failed for some reason other than the file existing, abort */
   if (fd < 0)
@@ -629,6 +630,7 @@ do_redirection_internal (redirect, flags)
   redir_fd = redirect->redirectee.dest;
   redirector = redirect->redirector;
   ri = redirect->instruction;
+  oflags = 0;
 
   if (redirect->flags & RX_INTERNAL)
     flags |= RX_INTERNAL;
@@ -638,6 +640,7 @@ do_redirection_internal (redirect, flags)
       /* We have [N]>&WORD[-] or [N]<&WORD[-].  Expand WORD, then translate
 	 the redirection into a new one and continue. */
       redirectee_word = redirection_expand (redirectee);
+      new_redirect = NULL;
 
       /* XXX - what to do with [N]<&$w- where w is unset or null?  ksh93
 	       closes N. */
@@ -668,6 +671,8 @@ do_redirection_internal (redirect, flags)
 	    case r_move_output_word:
 	      new_redirect = make_redirection (redirector, r_move_output, rd);
 	      break;
+	    default:
+	      break;
 	    }
 	}
       else if (ri == r_duplicating_output_word && redirector == 1)
@@ -938,6 +943,7 @@ do_redirection_internal (redirect, flags)
 
     case r_duplicating_input_word:
     case r_duplicating_output_word:
+    default:
       break;
     }
   return (0);
@@ -1066,9 +1072,9 @@ stdin_redirection (ri, redirector)
     case r_err_and_out:
     case r_output_force:
     case r_duplicating_output_word:
+    default:
       return (0);
     }
-  return (0);
 }
 
 /* Return non-zero if any of the redirections in REDIRS alter the standard
diff --git a/shell.c b/shell.c
index 6693f85..04643fb 100644
--- a/shell.c
+++ b/shell.c
@@ -175,6 +175,9 @@ int running_under_emacs;
 /* The name of the .(shell)rc file. */
 static char *bashrc_file = "~/.bashrc";
 
+/* Non-zero if we are finding the scripts requirements. */
+int rpm_requires;
+
 /* Non-zero means to act more like the Bourne shell on startup. */
 static int act_like_sh;
 
@@ -233,6 +236,7 @@ struct {
   { "posix", Int, &posixly_correct, (char **)0x0 },
   { "protected", Int, &protected_mode, (char **)0x0 },
   { "rcfile", Charp, (int *)0x0, &bashrc_file },
+  { "rpm-requires", Int, &rpm_requires, (char **)0x0 },
 #if defined (RESTRICTED_SHELL)
   { "restricted", Int, &restricted, (char **)0x0 },
 #endif
@@ -460,6 +464,12 @@ main (argc, argv, env)
   if (dump_translatable_strings)
     read_but_dont_execute = 1;
 
+  if (rpm_requires)
+    {
+      read_but_dont_execute = 1;
+      initialize_shell_builtins ();
+    }
+
   if (running_setuid && privileged_mode == 0)
     disable_priv_mode ();
 
@@ -797,7 +807,7 @@ parse_shell_options (argv, arg_start, arg_end)
 
       i = 1;
       on_or_off = arg_string[0];
-      while (arg_character = arg_string[i++])
+      while ((arg_character = arg_string[i++]))
 	{
 	  switch (arg_character)
 	    {
@@ -1541,7 +1551,7 @@ set_shell_name (argv0)
       login_shell++;
     }
 
-  if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0')
+  if (shell_name[0] == 's' && shell_name[1] == 'h' && (shell_name[2] == '\0' || (shell_name[2] == '3' && shell_name[3] == '\0')))
     act_like_sh++;
   if (shell_name[0] == 's' && shell_name[1] == 'u' && shell_name[2] == '\0')
     su_shell++;
diff --git a/sig.c b/sig.c
index c479a4a..ea66f94 100644
--- a/sig.c
+++ b/sig.c
@@ -308,8 +308,9 @@ initialize_shell_signals ()
     {
       set_signal_handler (SIGINT, sigint_sighandler);
       set_signal_handler (SIGTERM, SIG_IGN);
-      set_sigwinch_handler ();
     }
+
+  set_sigwinch_handler ();
 }
 
 void
diff --git a/subst.c b/subst.c
index 089457f..c530c79 100644
--- a/subst.c
+++ b/subst.c
@@ -50,6 +50,8 @@
 
 #include "shmbutil.h"
 
+#include "sig.h"
+
 #include "builtins/getopt.h"
 #include "builtins/common.h"
 
@@ -190,8 +192,10 @@ WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL;
    without any leading variable assignments. */
 static WORD_LIST *garglist = (WORD_LIST *)NULL;
 
+#ifdef INCLUDE_UNUSED
 static char *quoted_substring __P((char *, int, int));
 static int quoted_strlen __P((char *));
+#endif
 static char *quoted_strchr __P((char *, int, int));
 
 static char *expand_string_if_necessary __P((char *, int, EXPFUNC *));
@@ -208,8 +212,10 @@ static WORD_LIST *quote_list __P((WORD_LIST *));
 static char *remove_quoted_escapes __P((char *));
 static char *remove_quoted_nulls __P((char *));
 
+#ifdef INCLUDE_UNUSED
 static int unquoted_substring __P((char *, char *));
 static int unquoted_member __P((int, char *));
+#endif
 
 #if defined (ARRAY_VARS)
 static SHELL_VAR *do_compound_assignment __P((char *, char *, int));
@@ -227,7 +233,9 @@ static char *extract_dollar_brace_string __P((char *, int *, int, int));
 
 static char *pos_params __P((char *, int, int, int));
 
+#ifdef INCLUDE_UNUSED
 static unsigned char *mb_getcharlens __P((char *, int));
+#endif
 
 static char *remove_upattern __P((char *, char *, int));
 #if defined (HANDLE_MULTIBYTE) 
@@ -244,7 +252,9 @@ static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char
 static int match_pattern __P((char *, char *, int, char **, char **));
 static int getpatspec __P((int, char *));
 static char *getpattern __P((char *, int, int));
+#ifdef INCLUDE_UNUSED
 static char *variable_remove_pattern __P((char *, char *, int, int));
+#endif
 static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int));
 static char *parameter_list_remove_pattern __P((int, char *, int, int));
 #ifdef ARRAY_VARS
@@ -289,7 +299,7 @@ static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *)
 
 static WORD_LIST *word_list_split __P((WORD_LIST *));
 
-static void exp_jump_to_top_level __P((int));
+static void exp_jump_to_top_level __P((int)) __attribute__((__noreturn__));
 
 static WORD_LIST *separate_out_assignments __P((WORD_LIST *));
 static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int));
@@ -399,6 +409,7 @@ quoted_strchr (s, c, flags)
   return ((char *)NULL);
 }
 
+#ifdef INCLUDE_UNUSED
 /* Return 1 if CHARACTER appears in an unquoted portion of
    STRING.  Return 0 otherwise.  CHARACTER must be a single-byte character. */
 static int
@@ -412,7 +423,7 @@ unquoted_member (character, string)
 
   slen = strlen (string);
   sindex = 0;
-  while (c = string[sindex])
+  while ((c = string[sindex]))
     {
       if (c == character)
 	return (1);
@@ -440,7 +451,9 @@ unquoted_member (character, string)
     }
   return (0);
 }
+#endif
 
+#ifdef INCLUDE_UNUSED
 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
 static int
 unquoted_substring (substr, string)
@@ -455,7 +468,7 @@ unquoted_substring (substr, string)
 
   slen = strlen (string);
   sublen = strlen (substr);
-  for (sindex = 0; c = string[sindex]; )
+  for (sindex = 0; (c = string[sindex]); )
     {
       if (STREQN (string + sindex, substr, sublen))
 	return (1);
@@ -484,6 +497,7 @@ unquoted_substring (substr, string)
     }
   return (0);
 }
+#endif
 
 /* Most of the substitutions must be done in parallel.  In order
    to avoid using tons of unclear goto's, I have some functions
@@ -565,7 +579,7 @@ string_extract (string, sindex, charlist, flags)
   slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
   i = *sindex;
   found = 0;
-  while (c = string[i])
+  while ((c = string[i]))
     {
       if (c == '\\')
 	{
@@ -636,7 +650,7 @@ string_extract_double_quoted (string, sindex, stripdq)
 
   j = 0;
   i = *sindex;
-  while (c = string[i])
+  while ((c = string[i]))
     {
       /* Process a character that was quoted by a backslash. */
       if (pass_next)
@@ -783,7 +797,7 @@ skip_double_quoted (string, slen, sind)
 
   pass_next = backquote = 0;
   i = sind;
-  while (c = string[i])
+  while ((c = string[i]))
     {
       if (pass_next)
 	{
@@ -918,7 +932,7 @@ string_extract_verbatim (string, slen, sindex, charlist)
   clen = strlen (charlist);
   wcharlist = 0;
 #endif
-  while (c = string[i])
+  while ((c = string[i]))
     {
 #if defined (HANDLE_MULTIBYTE)
       size_t mblength;
@@ -1206,7 +1220,7 @@ extract_dollar_brace_string (string, sindex, quoted, flags)
   slen = strlen (string + *sindex) + *sindex;
 
   i = *sindex;
-  while (c = string[i])
+  while ((c = string[i]))
     {
       if (pass_character)
 	{
@@ -1475,7 +1489,7 @@ skip_to_delim (string, start, delims)
   no_longjmp_on_fatal_error = 1;
   i = start;
   pass_next = backq = 0;
-  while (c = string[i])
+  while ((c = string[i]))
     {
       if (pass_next)
 	{
@@ -1956,6 +1970,7 @@ list_string (string, separators, quoted)
 				 separators[3] == '\0';
 
   slen = 0;
+  s = NULL;
   /* Remove sequences of whitespace at the beginning of STRING, as
      long as those characters appear in IFS.  Do not do this if
      STRING is quoted or if there are no separator characters. */
@@ -2327,7 +2342,7 @@ do_assignment_internal (word, expand)
     aflags |= ASS_APPEND;
 
 #if defined (ARRAY_VARS)
-  if (t = xstrchr (name, '['))	/*]*/
+  if ((t = xstrchr (name, '[')))	/*]*/
     {
       if (assign_list)
 	{
@@ -4158,13 +4173,24 @@ static char *
 make_named_pipe ()
 {
   char *tname;
+  int retries;
 
-  tname = sh_mktmpname ("sh-np", MT_USERANDOM);
-  if (mkfifo (tname, 0600) < 0)
+  retries = 0x1000;
+  do
     {
-      free (tname);
-      return ((char *)NULL);
-    }
+      tname = sh_mktmpname_unsafe ("sh-np", MT_USETMPDIR);
+      if (!tname)
+        {
+	  free (tname);
+	  return ((char *)NULL);
+	}
+      if (mkfifo (tname, 0600) == 0) break;
+      if (errno != EEXIST || !--retries)
+        {
+          free (tname);
+          return ((char *)NULL);
+        }
+    } while(1);
 
   add_fifo_list (tname);
   return (tname);
@@ -4463,6 +4489,7 @@ read_comsub (fd, quoted)
 
   istring = (char *)NULL;
   istring_index = istring_size = bufn = 0;
+  bufp = NULL;
 
 #ifdef __CYGWIN__
   setmode (fd, O_TEXT);		/* we don't want CR/LF, we want Unix-style */
@@ -4950,7 +4977,7 @@ parameter_brace_expand_word (name, var_is_special, quoted)
 	rflags |= W_HASQUOTEDNULL;
     }
 #endif
-  else if (var = find_variable (name))
+  else if ((var = find_variable (name)))
     {
       if (var_isset (var) && invisible_p (var) == 0)
 	{
@@ -5188,6 +5215,7 @@ parameter_brace_expand_length (name)
     number = number_of_args ();
   else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0')
     {
+      t = NULL;
       /* Take the lengths of some of the shell's special parameters. */
       switch (name[1])
 	{
@@ -5345,6 +5373,7 @@ verify_substring_values (value, substr, vtype, e1p, e2p)
     return (0);
 
   len = -1;	/* paranoia */
+  a = NULL;
   switch (vtype)
     {
     case VT_VARIABLE:
@@ -5782,10 +5811,8 @@ parameter_brace_patsub (varname, value, patsub, quoted)
 
   /* If the pattern starts with a `/', make sure we skip over it when looking
      for the replacement delimiter. */
-  if (rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL))
+  if ((rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL)))
     *rep++ = '\0';
-  else
-    rep = (char *)NULL;
 
   if (rep && *rep == '\0')
     rep = (char *)NULL;
@@ -5833,6 +5860,7 @@ parameter_brace_patsub (varname, value, patsub, quoted)
      other cases if QUOTED == 0, since the posparams and arrays
      indexed by * or @ do special things when QUOTED != 0. */
 
+  temp = NULL;
   switch (vtype)
     {
     case VT_VARIABLE:
@@ -5997,7 +6025,7 @@ parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_doll
 
   /* Find out what character ended the variable name.  Then
      do the appropriate thing. */
-  if (c = string[sindex])
+  if ((c = string[sindex]))
     sindex++;
 
   /* If c is followed by one of the valid parameter expansion
@@ -6007,7 +6035,7 @@ parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_doll
   if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex]))
     {
       check_nullness++;
-      if (c = string[sindex])
+      if ((c = string[sindex]))
 	sindex++;
     }
   else if (c == ':' && string[sindex] != RBRACE)
@@ -6200,6 +6228,15 @@ parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_doll
   *indexp = sindex;
 
   /* If this is a substring spec, process it and add the result. */
+  if ((want_substring || want_patsub) && var_is_set == 0 && unbound_vars_is_error)
+    {
+      err_unboundvar (name);
+      FREE (value);
+      FREE (temp);
+      free (name);
+      last_command_exit_value = EXECUTION_FAILURE;
+      return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
+    }
   if (want_substring)
     {
       temp1 = parameter_brace_substring (name, temp, value, quoted);
@@ -6261,6 +6298,15 @@ parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_doll
 
     case '#':	/* ${param#[#]pattern} */
     case '%':	/* ${param%[%]pattern} */
+      if (var_is_set == 0 && unbound_vars_is_error)
+	{
+	  err_unboundvar (name);
+	  FREE (value);
+	  FREE (temp);
+	  free (name);
+	  last_command_exit_value = EXECUTION_FAILURE;
+	  return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
+	}
       if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
 	{
 	  FREE (value);
@@ -7461,7 +7507,7 @@ string_quote_removal (string, quoted)
 
   r = result_string = (char *)xmalloc (slen + 1);
 
-  for (dquote = sindex = 0; c = string[sindex];)
+  for (dquote = sindex = 0; (c = string[sindex]);)
     {
       switch (c)
 	{
@@ -7642,7 +7688,7 @@ word_list_split (list)
 {
   WORD_LIST *result, *t, *tresult, *e;
 
-  for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
+  for (t = list, result = e = (WORD_LIST *)NULL; t; t = t->next)
     {
       tresult = word_split (t->word, ifs_value);
       if (result == 0)
@@ -7957,7 +8003,7 @@ brace_expand_word_list (tlist, eflags)
 	{
 	  expansions = brace_expand (tlist->word->word);
 
-	  for (eindex = 0; temp_string = expansions[eindex]; eindex++)
+	  for (eindex = 0; (temp_string = expansions[eindex]); eindex++)
 	    {
 	      w = make_word (temp_string);
 	      /* If brace expansion didn't change the word, preserve
diff --git a/support/bashbug.sh b/support/bashbug.sh
index 8c4e1ec..f365074 100644
--- a/support/bashbug.sh
+++ b/support/bashbug.sh
@@ -1,4 +1,4 @@
-#!/bin/sh -
+#!/bin/sh3 -
 #
 # bashbug - create a bug report and mail it to the bug address
 #
@@ -39,18 +39,14 @@ MACHTYPE="!MACHTYPE!"
 PATH=/bin:/usr/bin:/usr/local/bin:$PATH
 export PATH
 
-# Check if TMPDIR is set, default to /tmp
-: ${TMPDIR:=/tmp}
-
-#Securely create a temporary directory for the temporary files
-TEMPDIR=$TMPDIR/bbug.$$
-(umask 077 && mkdir $TEMPDIR) || {
-	echo "$0: could not create temporary directory" >&2
+TEMPFILE1="`mktemp -t bashbug.XXXXXXXXXX`" || exit 1
+TEMPFILE2="`mktemp -t bashbug.XXXXXXXXXX`" || {
+	rm -f "$TEMPFILE1"
 	exit 1
 }
 
-TEMPFILE1=$TEMPDIR/bbug1
-TEMPFILE2=$TEMPDIR/bbug2
+trap 'rm -f "$TEMPFILE1" "$TEMPFILE2"; exit 1' HUP INT PIPE TERM
+trap 'rm -f "$TEMPFILE1" "$TEMPFILE2"' EXIT
         
 USAGE="Usage: $0 [--help] [--version] [bug-report-email-address]"
 VERSTR="GNU bashbug, version ${RELEASE}.${PATCHLEVEL}-${RELSTATUS}"
@@ -121,24 +117,8 @@ esac
 BUGADDR="${1-$BUGBASH}"
 
 if [ -z "$DEFEDITOR" ] && [ -z "$EDITOR" ]; then
-	if [ -x /usr/bin/editor ]; then
-		DEFEDITOR=editor
-	elif [ -x /usr/local/bin/ce ]; then
-		DEFEDITOR=ce
-	elif [ -x /usr/local/bin/emacs ]; then
-		DEFEDITOR=emacs
-	elif [ -x /usr/contrib/bin/emacs ]; then
-		DEFEDITOR=emacs
-	elif [ -x /usr/bin/emacs ]; then
-		DEFEDITOR=emacs
-	elif [ -x /usr/bin/xemacs ]; then
-		DEFEDITOR=xemacs
-	elif [ -x /usr/contrib/bin/jove ]; then
-		DEFEDITOR=jove
-	elif [ -x /usr/local/bin/jove ]; then
-		DEFEDITOR=jove
-	elif [ -x /usr/bin/vi ]; then
-		DEFEDITOR=vi
+	if [ -x /bin/vitmp ]; then
+		DEFEDITOR=vitmp
 	else
 		echo "$0: No default editor found: attempting to use vi" >&2
 		DEFEDITOR=vi
@@ -150,9 +130,6 @@ fi
 
 : ${USER=${LOGNAME-`whoami`}}
 
-trap 'rm -rf "$TEMPDIR"; exit 1' 1 2 3 13 15
-trap 'rm -rf "$TEMPDIR"' 0
-
 UN=
 if (uname) >/dev/null 2>&1; then
 	UN=`uname -a`
@@ -203,7 +180,8 @@ EOF
 cp "$TEMPFILE1" "$TEMPFILE2"
 chmod u+w "$TEMPFILE1"
 
-trap '' 2		# ignore interrupts while in editor
+# ignore interrupts while in editor
+trap '' INT
 
 edstat=1
 while [ $edstat -ne 0 ]; do
@@ -250,7 +228,8 @@ while [ $edstat -ne 0 ]; do
 
 done
 
-trap 'rm -rf "$TEMPDIR"; exit 1' 2	# restore trap on SIGINT
+# restore trap on SIGINT
+trap 'rm -f "$TEMPFILE1" "$TEMPFILE2"; exit 1' INT
 
 if cmp -s "$TEMPFILE1" "$TEMPFILE2"
 then
diff --git a/support/fixlinks b/support/fixlinks
index 13a86c8..a40be68 100755
--- a/support/fixlinks
+++ b/support/fixlinks
@@ -22,7 +22,7 @@
 SRCDIR=.
 while [ $# -gt 0 ]; do
 	case "$1" in
-	-s)	shift; SRCDIR=$1 ;;
+	-s)	shift; SRCDIR="$1" ;;
 	-u)	unfix=yes ;;
 	-h)	hardlinks=yes ;;
 	-*)	echo "$0: $1: bad option" 1>&2
@@ -33,15 +33,15 @@ while [ $# -gt 0 ]; do
 	shift
 done
 
-if [ ! -d $SRCDIR/builtins ]; then
+if [ ! -d "$SRCDIR/builtins" ]; then
 	echo "$0: must be run with valid -s argument or from source directory" 1>&2
 	exit 1
 fi
 
 if [ $# -eq 0 ]; then
-	linkfile=$SRCDIR/support/SYMLINKS
+	linkfile="$SRCDIR/support/SYMLINKS"
 else
-	linkfile=$1	
+	linkfile="$1"
 fi
 
 if [ ! -f "$linkfile" ]; then
@@ -49,25 +49,12 @@ if [ ! -f "$linkfile" ]; then
 	exit 1
 fi
 
-rm_ltmp=false
-LINKTEMP=`mktemp -t linktmp.XXXXXXXX 2>/dev/null`
-if [ -z "$LINKTEMP" ]; then
-	: ${TMPDIR:=/tmp}
-	LINKTEMP=${TMPDIR}/linktmp.$$
-	rm_ltmp=true
-fi
-
-$rm_ltmp && rm -f ${LINKTEMP}
-# if the user specified hard links, then do that.  otherwise, try to use
-# symlinks if they're present
+# if the user specified hard links, then do that.  otherwise, use symlinks.
 if [ -n "$hardlinks" ]; then
 	LN=ln
-elif (ln -s /dev/null ${LINKTEMP}) >/dev/null 2>&1; then
-	LN="ln -s"
 else
-	LN=ln
+	LN="ln -s"
 fi
-rm -f ${LINKTEMP}
 
 while read name target
 do
@@ -75,15 +62,15 @@ do
 	\#*)	continue;;
 	esac
 
-	rm -f $name
+	rm -f "$name"
 	case "$unfix" in
 	yes)	dirname=`expr "$name" ':' '^\(.*\)/[^/]*'`
 		[ -z "$dirname" ] && dirname=.
-		cp $dirname/$target $name
-		echo $target copied to $name ;;
-	*)	$LN $target $name ; echo "$name -> $target" ;;
+		cp "$dirname/$target" "$name"
+		echo "$target copied to $name" ;;
+	*)	$LN "$target" "$name" ; echo "$name -> $target" ;;
 	esac
 
-done < $linkfile
+done < "$linkfile"
 
 exit 0
diff --git a/support/man2html.c b/support/man2html.c
index 2432c13..fafb266 100644
--- a/support/man2html.c
+++ b/support/man2html.c
@@ -279,7 +279,7 @@ struct INTDEF {
 static char NEWLINE[2] = "\n";
 static char idxlabel[6] = "ixAAA";
 
-#define INDEXFILE "/tmp/manindex.list"
+#define INDEXFILE "manindex.list"
 
 static char *fname;
 static FILE *idxfile;
diff --git a/support/mkclone b/support/mkclone
index 10b08c0..5ed059b 100755
--- a/support/mkclone
+++ b/support/mkclone
@@ -28,12 +28,12 @@ USAGE="usage: $prog [-m manifest] [-s srcdir] [-v] [-d] [-h] target"
 while getopts dhm:s:v opt
 do
 	case "$opt" in
-	m)	MANIFEST=$OPTARG ;;
-	s)	SRCDIR=$OPTARG ;;
+	m)	MANIFEST="$OPTARG" ;;
+	s)	SRCDIR="$OPTARG" ;;
 	v)	verbose=y ;;
 	d)	ECHO=echo debug=y ;;
 	h)	hardlinks=y ;;
-	?)	echo $USAGE >&2
+	?)	echo "$USAGE" >&2
 		exit 2;;
 	esac
 done
@@ -45,37 +45,24 @@ done
 shift $(( $OPTIND - 1 ))
 
 if [ $# -lt 1 ]; then
-	echo $USAGE >&2
+	echo "$USAGE" >&2
         exit 2
 fi
 
-if [ ! -f $MANIFEST ]; then
+if [ ! -f "$MANIFEST" ]; then
 	echo "$prog: $MANIFEST: no such file or directory" >&2
 	echo "$prog: must be run with valid -s argument or from source directory" >&2
 	exit 1
 fi
 
-rm_ltmp=false
-LINKTEMP=`mktemp -t linktmp.XXXXXXXX 2>/dev/null`
-if [ -z "$LINKTEMP" ]; then
-	: ${TMPDIR:=/tmp}
-	LINKTEMP=${TMPDIR}/linktmp.$$
-	rm_ltmp=true
-fi
-
-$rm_ltmp && rm -f ${LINKTEMP}
-# if the user specified hard links, then do that.  otherwise, try to use
-# symlinks if they're present
+# if the user specified hard links, then do that.  otherwise, use symlinks.
 if [ -n "$hardlinks" ]; then
 	LN=ln
-elif (ln -s /dev/null ${LINKTEMP}) >/dev/null 2>&1; then
-	LN="ln -s"
 else
-	LN=ln
+	LN="ln -s"
 fi
-rm -f ${LINKTEMP}
 
-TARGET=$1
+TARGET="$1"
 
 if [ ! -d "$TARGET" ]; then
 	mkdir "$TARGET"
@@ -95,7 +82,7 @@ do
 
 	case "$type" in
 	d)	[ -n "$verbose" ] && echo mkdir $fname
-		$ECHO mkdir $fname ;;		# already in $TARGET
+		$ECHO mkdir "$fname" ;;		# already in $TARGET
 	f)	fn=${fname##*/}
 		case "$fname" in
 		*/*)	dn=${fname%/*} ;;
@@ -104,11 +91,11 @@ do
 		if [ -n "$verbose" ] || [ -n "$debug" ]; then
 			echo "( cd $dn && $LN $SRCDIR/$fname $fn )"
 		fi
-		[ -z "$debug" ] && ( cd $dn && $LN $SRCDIR/$fname $fn )
+		[ -z "$debug" ] && ( cd "$dn" && $LN "$SRCDIR/$fname" "$fn" )
 		;;
 	*)	echo "${prog}: ${fname}: unknown file type $type" 1>&2 ;;
 	esac
-done < $MANIFEST
+done < "$MANIFEST"
 
 # special
 SPECIAL="parser-built y.tab.c y.tab.h"
@@ -116,8 +103,8 @@ SPECIAL="parser-built y.tab.c y.tab.h"
 rm -f $SPECIAL
 for sf in $SPECIAL
 do
-	[ -n "$verbose" ] && echo cp -p $SRCDIR/$sf $TARGET
-	$ECHO cp -p $SRCDIR/$sf $TARGET
+	[ -n "$verbose" ] && echo cp -p "$SRCDIR/$sf" "$TARGET"
+	$ECHO "cp -p $SRCDIR/$sf $TARGET"
 done
 
 exit 0
diff --git a/support/rlvers.sh b/support/rlvers.sh
index b3de8fe..0468498 100755
--- a/support/rlvers.sh
+++ b/support/rlvers.sh
@@ -22,9 +22,6 @@
 
 PROGNAME=`basename $0`
 
-: ${TMPDIR:=/tmp}
-TDIR=$TMPDIR/rlvers
-
 # defaults
 CC=cc
 RL_LIBDIR=/usr/local/lib
@@ -47,11 +44,11 @@ done
 
 # if someone happened to install examples/rlversion, use it (it's not
 # installed by default)
-if test -f ${RL_LIBDIR}/rlversion ; then
+if test -f "${RL_LIBDIR}/rlversion" ; then
 	if [ -n "$verbose" ]; then
 		echo "${PROGNAME}: using installed rlversion from ${RL_LIBDIR}/rlversion"
 	fi
-	v=`${RL_LIBDIR}/rlversion 2>/dev/null`
+	v="`${RL_LIBDIR}/rlversion 2>/dev/null`"
 	case "$v" in
 	unknown | "")	echo 0 ;;
 	*)		echo "$v" ;;
@@ -64,17 +61,14 @@ if [ -n "$verbose" ]; then
 	echo "${PROGNAME}: attempting program compilation"
 fi
 
-# make $TDIR mode 0700
-mkdir $TDIR || {
-	echo "${PROGNAME}: ${TDIR}: file exists" >&2
+TDIR="mktemp -td rlvers.XXXXXXXXXX" || {
 	echo 0
 	exit 1
 }
-chmod 700 $TDIR
 
-trap 'rm -f $TDIR/rlvers $TDIR/rlvers.? ; rmdir $TDIR' 0 1 2 3 6 15
+trap 'rm -f "$TDIR"/rlvers "$TDIR"/rlvers.? ; rmdir "$TDIR'" EXIT HUP INT TERM
 
-cat > $TDIR/rlvers.c << EOF
+cat > "$TDIR"/rlvers.c << EOF
 #include <stdio.h>
 extern char *rl_library_version;
 
@@ -87,15 +81,15 @@ EOF
 
 opwd=`pwd`
 
-cd $TDIR || {
+cd "$TDIR" || {
 	echo "${PROGNAME}: cannot cd to $TDIR" >&2
 	echo 0
 	exit 1
 }
 	
-if eval ${CC} -L${RL_LIBDIR} -I${RL_INCDIR} -o $TDIR/rlvers $TDIR/rlvers.c -lreadline ${TERMCAP_LIB};
+if eval ${CC} -L${RL_LIBDIR} -I${RL_INCDIR} -o "$TDIR"/rlvers "$TDIR"/rlvers.c -lreadline ${TERMCAP_LIB};
 then
-	v=`$TDIR/rlvers`
+	v=`"$TDIR"/rlvers`
 else
 	if [ -n "$verbose" ] ; then
 		echo "${PROGNAME}: compilation failed: status $?"
@@ -109,5 +103,5 @@ unknown | "")	echo 0 ;;
 *)		echo "$v" ;;
 esac
 
-cd $opwd
+cd "$opwd"
 exit 0
diff --git a/trap.c b/trap.c
index 2d5934f..518c92d 100644
--- a/trap.c
+++ b/trap.c
@@ -67,8 +67,6 @@ static int sigmodes[BASH_NSIG];
 static void free_trap_command __P((int));
 static void change_signal __P((int, char *));
 
-static void get_original_signal __P((int));
-
 static int _run_trap_internal __P((int, char *));
 
 static void reset_signal __P((int));
@@ -543,15 +541,6 @@ change_signal (sig, value)
     sigmodes[sig] |= SIG_CHANGED;
 }
 
-static void
-get_original_signal (sig)
-     int sig;
-{
-  /* If we aren't sure the of the original value, then get it. */
-  if (original_signals[sig] == (SigHandler *)IMPOSSIBLE_TRAP_HANDLER)
-    GETORIGSIG (sig);
-}
-
 /* Restore the default action for SIG; i.e., the action the shell
    would have taken before you used the trap command.  This is called
    from trap_builtin (), which takes care to restore the handlers for
diff --git a/unwind_prot.c b/unwind_prot.c
index 4fd194e..60d4b77 100644
--- a/unwind_prot.c
+++ b/unwind_prot.c
@@ -233,7 +233,7 @@ unwind_frame_discard_internal (tag, ignore)
 {
   UNWIND_ELT *elt;
 
-  while (elt = unwind_protect_list)
+  while ((elt = unwind_protect_list))
     {
       unwind_protect_list = unwind_protect_list->head.next;
       if (elt->head.cleanup == 0 && (STREQ (elt->arg.v, tag)))
@@ -262,7 +262,7 @@ unwind_frame_run_internal (tag, ignore)
 {
   UNWIND_ELT *elt;
 
-  while (elt = unwind_protect_list)
+  while ((elt = unwind_protect_list))
     {
       unwind_protect_list = elt->head.next;
 
diff --git a/variables.c b/variables.c
index 76501cf..488e4cf 100644
--- a/variables.c
+++ b/variables.c
@@ -149,8 +149,10 @@ static int export_env_size;
 
 #if defined (READLINE)
 static int winsize_assignment;		/* currently assigning to LINES or COLUMNS */
+#if defined (STRICT_POSIX)
 static int winsize_assigned;		/* assigned to LINES or COLUMNS */
 #endif
+#endif
 
 /* Non-zero means that we have to remake EXPORT_ENV. */
 int array_needs_making = 1;
@@ -172,9 +174,10 @@ static void uidset __P((void));
 static void make_vers_array __P((void));
 #endif
 
-static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t));
 #if defined (ARRAY_VARS)
 static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t));
+#else
+static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t));
 #endif
 static SHELL_VAR *get_self __P((SHELL_VAR *));
 
@@ -293,7 +296,7 @@ initialize_shell_variables (env, privmode)
 
   create_variable_tables ();
 
-  for (string_index = 0; string = env[string_index++]; )
+  for (string_index = 0; (string = env[string_index++]); )
     {
       char_index = 0;
       name = string;
@@ -339,7 +342,7 @@ initialize_shell_variables (env, privmode)
 	  if (absolute_program (tname) == 0 && (posixly_correct == 0 || legal_identifier (tname)))
 	    parse_and_execute (temp_string, tname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
 
-	  if (temp_var = find_function (tname))
+	  if ((temp_var = find_function (tname)))
 	    {
 	      VSETATTR (temp_var, (att_exported|att_imported));
 	      array_needs_making = 1;
@@ -426,7 +429,11 @@ initialize_shell_variables (env, privmode)
 #endif
       set_if_not ("PS2", secondary_prompt);
     }
-  set_if_not ("PS4", "+ ");
+
+  if (current_user.euid == 0)
+    bind_variable ("PS4", "+ ", 0);
+  else
+    set_if_not ("PS4", "+ ");
 
   /* Don't allow IFS to be imported from the environment. */
   temp_var = bind_variable ("IFS", " \t\n", 0);
@@ -1054,21 +1061,21 @@ print_var_function (var)
     } \
   while (0)
 
+#if defined (ARRAY_VARS)
 static SHELL_VAR *
-null_assign (self, value, unused)
+null_array_assign (self, value, ind)
      SHELL_VAR *self;
      char *value;
-     arrayind_t unused;
+     arrayind_t ind;
 {
   return (self);
 }
-
-#if defined (ARRAY_VARS)
+#else
 static SHELL_VAR *
-null_array_assign (self, value, ind)
+null_assign (self, value, unused)
      SHELL_VAR *self;
      char *value;
-     arrayind_t ind;
+     arrayind_t unused;
 {
   return (self);
 }
@@ -1160,16 +1167,22 @@ static unsigned long rseed = 1;
 static int last_random_value;
 static int seeded_subshell = 0;
 
-/* A linear congruential random number generator based on the example
-   one in the ANSI C standard.  This one isn't very good, but a more
-   complicated one is overkill. */
+/* Use the random number genrator provided by the standard C library,
+   else use a linear congruential random number generator based on the
+   ANSI C standard.  This one isn't very good (the values are alternately
+   odd and even, for example), but a more complicated one is overkill. */
 
 /* Returns a pseudo-random number between 0 and 32767. */
 static int
 brand ()
 {
+#if defined(HAVE_RANDOM)
+  rseed = (unsigned int) (labs(random()) & 32767);
+  return rseed;
+#else
   rseed = rseed * 1103515245 + 12345;
   return ((unsigned int)((rseed >> 16) & 32767));	/* was % 32768 */
+#endif
 }
 
 /* Set the random number generator seed to SEED. */
@@ -1177,8 +1190,12 @@ static void
 sbrand (seed)
      unsigned long seed;
 {
+#if defined(HAVE_SRANDOM)
+  srandom(seed);
+#else
   rseed = seed;
   last_random_value = 0;
+#endif
 }
 
 static SHELL_VAR *
@@ -1523,7 +1540,7 @@ var_lookup (name, vcontext)
 
   v = (SHELL_VAR *)NULL;
   for (vc = vcontext; vc; vc = vc->down)
-    if (v = hash_lookup (name, vc->table))
+    if ((v = hash_lookup (name, vc->table)))
       break;
 
   return v;
@@ -1662,6 +1679,7 @@ make_local_variable (name)
   int was_tmpvar;
   char *tmp_value;
 
+  tmp_value = NULL;
   /* local foo; local foo;  is a no-op. */
   old_var = find_variable (name);
   if (old_var && local_p (old_var) && old_var->context == variable_context)
@@ -1829,6 +1847,7 @@ make_variable_value (var, value, flags)
      evaluation done. */
   if (integer_p (var))
     {
+      lval = 0;
       if (flags & ASS_APPEND)
 	{
 	  oval = value_cell (var);
@@ -2394,7 +2413,7 @@ makunbound (name, vc)
   char *t;
 
   for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down)
-    if (elt = hash_remove (name, v->table, 0))
+    if ((elt = hash_remove (name, v->table, 0)))
       break;
 
   if (elt == 0)
@@ -3016,6 +3035,10 @@ merge_temporary_env ()
 /*								    */
 /* **************************************************************** */
 
+/* Returns the string NAME=VALUE if !FUNCTIONP or if VALUE == NULL (in
+   which case it is treated as empty).  Otherwise, decorate NAME with
+   FUNCDEF_PREFIX and FUNCDEF_SUFFIX, and return a string of the form
+   FUNCDEF_PREFIX NAME FUNCDEF_SUFFIX = VALUE (without spaces).  */
 static inline char *
 mk_env_string (name, value, isfunc)
      const char *name, *value;
@@ -3101,7 +3124,7 @@ make_env_array_from_var_list (vars)
 
 #define USE_EXPORTSTR (value == var->exportstr)
 
-  for (i = 0, list_index = 0; var = vars[i]; i++)
+  for (i = 0, list_index = 0; (var = vars[i]); i++)
     {
 #if defined (__CYGWIN__)
       /* We don't use the exportstr stuff on Cygwin at all. */
@@ -3515,7 +3538,7 @@ pop_var_context ()
       return;
     }
 
-  if (ret = vcxt->down)
+  if ((ret = vcxt->down))
     {
       ret->up = (VAR_CONTEXT *)NULL;
       shell_variables = ret;
@@ -4094,7 +4117,7 @@ sv_history_control (name)
     return;
 
   tptr = 0;
-  while (val = extract_colon_unit (temp, &tptr))
+  while ((val = extract_colon_unit (temp, &tptr)))
     {
       if (STREQ (val, "ignorespace"))
 	history_control |= HC_IGNSPACE;
diff --git a/y.tab.c b/y.tab.c
index f8db50d..c821124 100644
--- a/y.tab.c
+++ b/y.tab.c
@@ -3832,6 +3832,8 @@ reset_parser ()
   FREE (word_desc_to_read);
   word_desc_to_read = (WORD_DESC *)NULL;
 
+  eol_ungetc_lookahead = 0;
+
   last_read_token = '\n';
   token_to_read = '\n';
 }
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin