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