This was discussed in a smaller circle and has been in snaps for two
days, but I'd like to show this to a wider audience.

Theo asked me to make sure that all our shells print a prompt including
the hostname by default. The reasoning is roughly as follows:

With tmux, ssh and vmd, we tend to open shells on many different hosts
simultaneously and the default prompts '$ ' and '# ' for {,k}sh as well
as  '% ' and '# ' for csh become dangerous: it's very easy to issue a
command on the wrong host.

This can easily be avoided by displaying the hostname in the prompt.
Everything beyond "hostname{$,#,%} " is going to be a matter of taste,
so we left it at that. If you use an FQDN, only the first part (the
output of 'hostname -s') will be printed.

Since not everybody makes use of the config files in /etc/skel or runs
only login shells, it is not really possible to handle this with config
files. Thus, we decided to hardcode it in the shells. We are aware that
POSIX says that PS1 defaults to '$ ' or '# ' for sh(1).

The simplest case is ksh: rely on the already existing shell escapes.
For sh we can easily fall back to these (the diff to ksh/lex.c).  For
csh, I decided to implement the "%m" prompt escape which is standard in
c-type shells, so I don't expect this to cause surprises.

In single user mode and the early installer, gethostname() returns the
empty string, so the familiar prompts will be displayed there.

Index: bin/csh/const.c
===================================================================
RCS file: /var/cvs/src/bin/csh/const.c,v
retrieving revision 1.8
diff -u -p -r1.8 const.c
--- bin/csh/const.c     26 Oct 2015 16:27:04 -0000      1.8
+++ bin/csh/const.c     8 Dec 2017 12:15:26 -0000
@@ -114,6 +114,8 @@ Char STRprintexitvalue[] = { 'p', 'r', '
                            'a', 'l', 'u', 'e', '\0' };
 Char STRprompt[]       = { 'p', 'r', 'o', 'm', 'p', 't', '\0' };
 Char STRprompt2[]      = { 'p', 'r', 'o', 'm', 'p', 't', '2', '\0' };
+Char STRpromptroot[]   = { '%', 'm', '#', ' ', '\0' };
+Char STRpromptuser[]   = { '%', 'm', '%', ' ', '\0' };
 Char STRpushdsilent[]  = { 'p', 'u', 's', 'h', 'd', 's', 'i', 'l', 'e', 'n',
                            't', '\0' };
 Char STRret[]          = { '\n', '\0' };
@@ -138,8 +140,6 @@ Char STRspor2sp[]   = { ' ', '|', '|', ' '
 Char STRsporsp[]       = { ' ', '|', ' ', '\0' };
 Char STRstar[]         = { '*', '\0' };
 Char STRstatus[]       = { 's', 't', 'a', 't', 'u', 's', '\0' };
-Char STRsymcent[]      = { '%', ' ', '\0' };
-Char STRsymhash[]      = { '#', ' ', '\0' };
 Char STRterm[]         = { 't', 'e', 'r', 'm', '\0' };
 Char STRthen[]         = { 't', 'h', 'e', 'n', '\0' };
 Char STRtilde[]                = { '~', '\0' };
Index: bin/csh/csh.c
===================================================================
RCS file: /var/cvs/src/bin/csh/csh.c,v
retrieving revision 1.41
diff -u -p -r1.41 csh.c
--- bin/csh/csh.c       30 Aug 2017 06:42:21 -0000      1.41
+++ bin/csh/csh.c       8 Dec 2017 12:16:00 -0000
@@ -401,7 +401,7 @@ main(int argc, char *argv[])
      * Set up the prompt.
      */
     if (prompt) {
-       set(STRprompt, Strsave(uid == 0 ? STRsymhash : STRsymcent));
+       set(STRprompt, Strsave(uid == 0 ? STRpromptroot : STRpromptuser));
        /* that's a meta-questionmark */
        set(STRprompt2, Strsave(STRmquestion));
     }
@@ -1283,7 +1283,16 @@ printprompt(void)
        for (cp = value(STRprompt); *cp; cp++)
            if (*cp == HIST)
                (void) fprintf(cshout, "%d", eventno + 1);
-           else {
+           else if (*cp == '%' && *(cp + 1) == 'm') {
+               char hostname[HOST_NAME_MAX + 1];
+               char *p;
+
+               gethostname(hostname, sizeof hostname);
+               if ((p = strchr(hostname, '.')) != NULL)
+                   *p = '\0';
+               fprintf(cshout, "%s", hostname);
+               cp++;
+           } else {
                if (*cp == '\\' && cp[1] == HIST)
                    cp++;
                (void) vis_fputc(*cp | QUOTE, cshout);
Index: bin/ksh/lex.c
===================================================================
RCS file: /var/cvs/src/bin/ksh/lex.c,v
retrieving revision 1.72
diff -u -p -r1.72 lex.c
--- bin/ksh/lex.c       7 Dec 2017 01:54:33 -0000       1.72
+++ bin/ksh/lex.c       8 Dec 2017 11:02:10 -0000
@@ -1246,7 +1246,8 @@ dopprompt(const char *sp, int ntruncate,
                        cp++;
                        if (!*cp)
                                break;
-                       if (Flag(FSH))
+                       /* Expand \h and \$ for both, sh(1) and ksh(1) */
+                       if (Flag(FSH) && !(*cp == 'h' || *cp == 'p'))
                                snprintf(strbuf, sizeof strbuf, "\\%c", *cp);
                        else switch (*cp) {
                        case 'a':       /* '\' 'a' bell */
Index: bin/ksh/main.c
===================================================================
RCS file: /var/cvs/src/bin/ksh/main.c,v
retrieving revision 1.84
diff -u -p -r1.84 main.c
--- bin/ksh/main.c      7 Dec 2017 01:54:33 -0000       1.84
+++ bin/ksh/main.c      8 Dec 2017 10:26:35 -0000
@@ -316,7 +316,7 @@ main(int argc, char *argv[])
                /* Set PS1 if it isn't set */
                if (!(vp->flag & ISSET)) {
                        /* setstr can't fail here */
-                       setstr(vp, safe_prompt, KSH_RETURN_ERROR);
+                       setstr(vp, "\\h\\$ ", KSH_RETURN_ERROR);
                }
        }
 

Reply via email to