bin/89410: [PATCH] sh missing \u interpolation and bug/fix in \W

Dr Balwinder Singh Dheeman < bsd at rubyforge.org
Tue Nov 22 09:20:21 GMT 2005


>Number:         89410
>Category:       bin
>Synopsis:       [PATCH] sh missing \u interpolation and bug/fix in \W
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Nov 22 09:20:19 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Dr Balwinder Singh Dheeman
>Release:        FreeBSD 6.0-RELEASE
>Organization:
Anu's Linux at HOME
>Environment:
FreeBSD cto.sebs.org.in 6.0-RELEASE FreeBSD 6.0-RELEASE #0: Thu Nov  3 09:36:13 UTC 2005     root at x64.samsco.home:/usr/obj/usr/src/sys/GENERIC  i386

Applicable to all base os and, or rescue box.
>Description:
        The code for interpolating \u in $PS1 (prompt sting) is from
        /usr/src/bin/sh/parser.c, which is part of sh binary.

        And interpolation for \W is also buggy and, or incomplete.

>How-To-Repeat:
        At any CLI/shell prompt exec the following:

        /bin/sh -i
        PS1='[\u@\h \W]\$ '

        See whether your /bin/sh is iterpolating \u and \W properly?
        No, I think NOT. Try:

        cd /

        You will see a missing ']$ ' or ']# ' the later if you are
        logged in as root

        Now try:

        cd

        Yor are back in your $HOME, which /bin/sh should interploate as
        a "~" for brivity; but is not in the current parser.c code which
        is linked with binary sh.

        NOTE: The /usr/share/skel/dot.shrc is needed to be patched.

>Fix:
        Apply the following patch to /usr/src/bin/sh/parser.c for /bin/sh:

        --- parser.c.orig       Mon Feb 28 18:30:00 2005
        +++ parser.c    Tue Nov 22 10:43:12 2005
        @@ -36,6 +36,9 @@
         #endif
         #endif /* not lint */
         #include <sys/cdefs.h>
        +#include <sys/types.h>
        +#include <pwd.h>
        +
         __FBSDID("$FreeBSD: src/bin/sh/parser.c,v 1.52 2005/03/01 03:35:58 obrien Exp $");

         #include <stdlib.h>
        @@ -1564,8 +1567,11 @@
         getprompt(void *unused __unused)
         {
                static char ps[PROMPTLEN];
        +       static char hd[PROMPTLEN];
                char *fmt;
                int i, j, trim;
        +       struct passwd *pw;
        +       pw = getpwuid(geteuid());

                /*
                 * Select prompt format.
        @@ -1608,6 +1614,17 @@
                                        break;

                                        /*
        +                                * username.
        +                                *
        +                                * \u specifies the username.
        +                                */
        +                       case 'u':
        +                               ps[i] == '\0';
        +                               strcpy(&ps[i], pw->pw_name);
        +                               i += strlen(pw->pw_name) - 1;
        +                               break;
        +
        +                               /*
                                         * Working directory.
                                         *
                                         * \W specifies just the final component,
        @@ -1617,14 +1634,19 @@
                                case 'w':
                                        ps[i] == '\0';
                                        getcwd(&ps[i], PROMPTLEN - i);
        -                               if (*fmt == 'W') {
        -                                       /* Final path component only. */
        -                                       trim = 1;
        -                                       for (j = i; ps[j] != '\0'; j++)
        -                                         if (ps[j] == '/')
        -                                               trim = j + 1;
        -                                       memmove(&ps[i], &ps[trim],
        -                                           j - trim + 1);
        +                               chdir(pw->pw_dir);
        +                               getcwd(hd, PROMPTLEN - i);
        +                               if (strcmp(&ps[i], hd) == NULL)
        +                                   strcpy(&ps[i], "~");
        +                               else
        +                                   chdir(&ps[i]);
        +                               if (*fmt == 'W' && ps[i + 1] != '\0') {
        +                                   /* Final path component only. */
        +                                   trim = 1;
        +                                   for (j = i; ps[j] != '\0'; j++)
        +                                       if (ps[j] == '/')
        +                                           trim = j + 1;
        +                                   memmove(&ps[i], &ps[trim], j - trim + 1);
                                        }
                                        /* Skip to end of path. */
                                        while (ps[i + 1] != '\0')
        @@ -1637,7 +1659,7 @@
                                         * '$' for normal users, '#' for root.
                                         */
                                case '$':
        -                               ps[i] = (geteuid() != 0) ? '$' : '#';
        +                               ps[i] = (pw->pw_uid != 0) ? '$' : '#';
                                        break;

                                        /*

        The following may also be applied to /usr/share/skel/dot.shrc
        though is not that very critical.

        --- dot.shrc.orig       Thu Nov  3 08:11:13 2005
        +++ dot.shrc    Tue Nov 22 08:23:38 2005
        @@ -36,12 +36,8 @@
         # alias rm='rm -i'


        -# # set prompt: ``username at hostname$ ''
        -# PS1="`whoami`@`hostname | sed 's/\..*//'`"
        -# case `id -u` in
        -#      0) PS1="${PS1}# ";;
        -#      *) PS1="${PS1}$ ";;
        -# esac
        +# # set prompt: '[username at hostname cwdtail]$|# '
        +#PS1="[\u@\h \W]\$ "

         # search path for cd(1)
         # CDPATH=.:$HOME

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list