Date: Sun, 09 May 2004 16:18:53 +0200 From: Oliver Eikemeier <eik@FreeBSD.org> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/66420: [PATCH] tcsh: history mangles command lines containing the hash character Message-ID: <409E3DCD.4000408@FreeBSD.org> Resent-Message-ID: <200405091420.i49EKOsO033443@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 66420 >Category: bin >Synopsis: [PATCH] tcsh: history mangles command lines containing the hash character >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun May 09 07:20:24 PDT 2004 >Closed-Date: >Last-Modified: >Originator: Oliver Eikemeier >Release: FreeBSD 4.10-STABLE i386 >Organization: Fillmore Labs - http://www.fillmore-labs.com >Environment: System: FreeBSD nuuk.fillmore-labs.com 4.10-STABLE >Description: tcsh uses source -h to read the .history file on logon. This parses the .history file with normal shell script syntax, interpreting the hash character as the start of an comment. This cuts of all commands at `#', which is annoying. Moreover, history time specifications are parsed in the middle of the line. This patch lets source -h do some special parsing, so that comments are only recognized when they start a line. While this is not perfect, it should be reasonably backwards compatible and fixes all real world cases I can think of. Upstream developers (tcsh-bugs@mx.gw.com) notified. >How-To-Repeat: add set savehist = (100 merge) to ~/.cshrc do find /usr/src -name .#\* echo abc #+1131458139 def vi #irclog log out, log in, do history | tail especially the `echo' is hard to get rid of >Fix: The following patch should apply to -CURRENT and -STABLE. It makes enterhist (= `-h' flag) global and changes parsing in lex accordingly. Index: tcsh/sh.c =================================================================== RCS file: /home/ncvs/src/contrib/tcsh/sh.c,v retrieving revision 1.1.1.2.2.5 diff -u -r1.1.1.2.2.5 sh.c --- tcsh/sh.c 10 Aug 2002 18:14:44 -0000 1.1.1.2.2.5 +++ tcsh/sh.c 9 May 2004 13:14:32 -0000 @@ -114,7 +114,7 @@ static bool batch = 0; static bool mflag = 0; static bool prompt = 1; -static int enterhist = 0; +int enterhist = 0; bool tellwhat = 0; time_t t_period; Char *ffile = NULL; Index: tcsh/sh.lex.c =================================================================== RCS file: /home/ncvs/src/contrib/tcsh/sh.lex.c,v retrieving revision 1.1.1.2.2.3 diff -u -r1.1.1.2.2.3 sh.lex.c --- tcsh/sh.lex.c 10 Aug 2002 18:14:45 -0000 1.1.1.2.2.3 +++ tcsh/sh.lex.c 9 May 2004 13:38:29 -0000 @@ -47,7 +47,7 @@ * There is some involved processing here, because of the complications * of input buffering, and especially because of history substitution. */ -static Char *word __P((void)); +static Char *word __P((int)); static int getC1 __P((int)); static void getdol __P((void)); static void getexcl __P((int)); @@ -137,6 +137,11 @@ static time_t a2time_t __P((Char *)); /* + * special parsing rules apply for source -h + */ +extern int enterhist; + +/* * for history event processing * in the command 'echo !?foo?:1 !$' we want the !$ to expand from the line * 'foo' was found instead of the last command @@ -149,6 +154,7 @@ { struct wordent *wdp; int c; + int parsehtime = enterhist; uselastevent = 1; @@ -183,7 +189,8 @@ wdp->next = new; hp->prev = new; wdp = new; - wdp->word = word(); + wdp->word = word(parsehtime); + parsehtime = 0; } while (wdp->word[0] != '\n'); if (histlinep < histline + BUFSIZE) { *histlinep = '\0'; @@ -282,7 +289,8 @@ } static Char * -word() +word(parsehtime) + int parsehtime; { Char c, c1; Char *wp; @@ -315,18 +323,20 @@ goto ret; case '#': - if (intty) + if (intty || (enterhist && !parsehtime)) break; c = 0; h = 0; do { c1 = c; c = getC(0); - if (h < 12) + if (h < 11 && parsehtime) hbuf[h++] = c; } while (c != '\n'); - hbuf[11] = '\0'; - Htime = a2time_t(hbuf); + if (parsehtime) { + hbuf[11] = '\0'; + Htime = a2time_t(hbuf); + } if (c1 == '\\') goto loop; /*FALLTHROUGH*/ @@ -416,7 +426,7 @@ c1 = c; dolflg = c == '"' ? DOALL : DOEXCL; } - else if (c != '#' || !intty) { + else if (c != '#' || (!intty && !enterhist)) { ungetC(c); break; } >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?409E3DCD.4000408>
