xref: /freebsd/contrib/tcsh/tc.prompt.c (revision 2930157267fc56387bb43acf5bb441a84ff6e765)
129301572SMark Peek /* $Header: /src/pub/tcsh/tc.prompt.c,v 3.46 2002/07/12 13:16:19 christos Exp $ */
2c80476e4SDavid E. O'Brien /*
3c80476e4SDavid E. O'Brien  * tc.prompt.c: Prompt printing stuff
4c80476e4SDavid E. O'Brien  */
5c80476e4SDavid E. O'Brien /*-
6c80476e4SDavid E. O'Brien  * Copyright (c) 1980, 1991 The Regents of the University of California.
7c80476e4SDavid E. O'Brien  * All rights reserved.
8c80476e4SDavid E. O'Brien  *
9c80476e4SDavid E. O'Brien  * Redistribution and use in source and binary forms, with or without
10c80476e4SDavid E. O'Brien  * modification, are permitted provided that the following conditions
11c80476e4SDavid E. O'Brien  * are met:
12c80476e4SDavid E. O'Brien  * 1. Redistributions of source code must retain the above copyright
13c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer.
14c80476e4SDavid E. O'Brien  * 2. Redistributions in binary form must reproduce the above copyright
15c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer in the
16c80476e4SDavid E. O'Brien  *    documentation and/or other materials provided with the distribution.
1729301572SMark Peek  * 3. Neither the name of the University nor the names of its contributors
18c80476e4SDavid E. O'Brien  *    may be used to endorse or promote products derived from this software
19c80476e4SDavid E. O'Brien  *    without specific prior written permission.
20c80476e4SDavid E. O'Brien  *
21c80476e4SDavid E. O'Brien  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22c80476e4SDavid E. O'Brien  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23c80476e4SDavid E. O'Brien  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24c80476e4SDavid E. O'Brien  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25c80476e4SDavid E. O'Brien  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26c80476e4SDavid E. O'Brien  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27c80476e4SDavid E. O'Brien  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28c80476e4SDavid E. O'Brien  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29c80476e4SDavid E. O'Brien  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30c80476e4SDavid E. O'Brien  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31c80476e4SDavid E. O'Brien  * SUCH DAMAGE.
32c80476e4SDavid E. O'Brien  */
33c80476e4SDavid E. O'Brien #include "sh.h"
34c80476e4SDavid E. O'Brien 
3529301572SMark Peek RCSID("$Id: tc.prompt.c,v 3.46 2002/07/12 13:16:19 christos Exp $")
36c80476e4SDavid E. O'Brien 
37c80476e4SDavid E. O'Brien #include "ed.h"
38c80476e4SDavid E. O'Brien #include "tw.h"
39c80476e4SDavid E. O'Brien 
40c80476e4SDavid E. O'Brien /*
41c80476e4SDavid E. O'Brien  * kfk 21oct1983 -- add @ (time) and / ($cwd) in prompt.
42c80476e4SDavid E. O'Brien  * PWP 4/27/87 -- rearange for tcsh.
43c80476e4SDavid E. O'Brien  * mrdch@com.tau.edu.il 6/26/89 - added ~, T and .# - rearanged to switch()
44c80476e4SDavid E. O'Brien  *                 instead of if/elseif
45c80476e4SDavid E. O'Brien  * Luke Mewburn, <lukem@cs.rmit.edu.au>
46c80476e4SDavid E. O'Brien  *	6-Sep-91	changed date format
47c80476e4SDavid E. O'Brien  *	16-Feb-94	rewrote directory prompt code, added $ellipsis
48c80476e4SDavid E. O'Brien  *	29-Dec-96	added rprompt support
49c80476e4SDavid E. O'Brien  */
50c80476e4SDavid E. O'Brien 
51c80476e4SDavid E. O'Brien static char   *month_list[12];
52c80476e4SDavid E. O'Brien static char   *day_list[7];
53c80476e4SDavid E. O'Brien 
54c80476e4SDavid E. O'Brien void
55c80476e4SDavid E. O'Brien dateinit()
56c80476e4SDavid E. O'Brien {
57c80476e4SDavid E. O'Brien #ifdef notyet
58c80476e4SDavid E. O'Brien   int i;
59c80476e4SDavid E. O'Brien 
60c80476e4SDavid E. O'Brien   setlocale(LC_TIME, "");
61c80476e4SDavid E. O'Brien 
62c80476e4SDavid E. O'Brien   for (i = 0; i < 12; i++)
63c80476e4SDavid E. O'Brien       xfree((ptr_t) month_list[i]);
64c80476e4SDavid E. O'Brien   month_list[0] = strsave(_time_info->abbrev_month[0]);
65c80476e4SDavid E. O'Brien   month_list[1] = strsave(_time_info->abbrev_month[1]);
66c80476e4SDavid E. O'Brien   month_list[2] = strsave(_time_info->abbrev_month[2]);
67c80476e4SDavid E. O'Brien   month_list[3] = strsave(_time_info->abbrev_month[3]);
68c80476e4SDavid E. O'Brien   month_list[4] = strsave(_time_info->abbrev_month[4]);
69c80476e4SDavid E. O'Brien   month_list[5] = strsave(_time_info->abbrev_month[5]);
70c80476e4SDavid E. O'Brien   month_list[6] = strsave(_time_info->abbrev_month[6]);
71c80476e4SDavid E. O'Brien   month_list[7] = strsave(_time_info->abbrev_month[7]);
72c80476e4SDavid E. O'Brien   month_list[8] = strsave(_time_info->abbrev_month[8]);
73c80476e4SDavid E. O'Brien   month_list[9] = strsave(_time_info->abbrev_month[9]);
74c80476e4SDavid E. O'Brien   month_list[10] = strsave(_time_info->abbrev_month[10]);
75c80476e4SDavid E. O'Brien   month_list[11] = strsave(_time_info->abbrev_month[11]);
76c80476e4SDavid E. O'Brien 
77c80476e4SDavid E. O'Brien   for (i = 0; i < 7; i++)
78c80476e4SDavid E. O'Brien       xfree((ptr_t) day_list[i]);
79c80476e4SDavid E. O'Brien   day_list[0] = strsave(_time_info->abbrev_wkday[0]);
80c80476e4SDavid E. O'Brien   day_list[1] = strsave(_time_info->abbrev_wkday[1]);
81c80476e4SDavid E. O'Brien   day_list[2] = strsave(_time_info->abbrev_wkday[2]);
82c80476e4SDavid E. O'Brien   day_list[3] = strsave(_time_info->abbrev_wkday[3]);
83c80476e4SDavid E. O'Brien   day_list[4] = strsave(_time_info->abbrev_wkday[4]);
84c80476e4SDavid E. O'Brien   day_list[5] = strsave(_time_info->abbrev_wkday[5]);
85c80476e4SDavid E. O'Brien   day_list[6] = strsave(_time_info->abbrev_wkday[6]);
86c80476e4SDavid E. O'Brien #else
87c80476e4SDavid E. O'Brien   month_list[0] = "Jan";
88c80476e4SDavid E. O'Brien   month_list[1] = "Feb";
89c80476e4SDavid E. O'Brien   month_list[2] = "Mar";
90c80476e4SDavid E. O'Brien   month_list[3] = "Apr";
91c80476e4SDavid E. O'Brien   month_list[4] = "May";
92c80476e4SDavid E. O'Brien   month_list[5] = "Jun";
93c80476e4SDavid E. O'Brien   month_list[6] = "Jul";
94c80476e4SDavid E. O'Brien   month_list[7] = "Aug";
95c80476e4SDavid E. O'Brien   month_list[8] = "Sep";
96c80476e4SDavid E. O'Brien   month_list[9] = "Oct";
97c80476e4SDavid E. O'Brien   month_list[10] = "Nov";
98c80476e4SDavid E. O'Brien   month_list[11] = "Dec";
99c80476e4SDavid E. O'Brien 
100c80476e4SDavid E. O'Brien   day_list[0] = "Sun";
101c80476e4SDavid E. O'Brien   day_list[1] = "Mon";
102c80476e4SDavid E. O'Brien   day_list[2] = "Tue";
103c80476e4SDavid E. O'Brien   day_list[3] = "Wed";
104c80476e4SDavid E. O'Brien   day_list[4] = "Thu";
105c80476e4SDavid E. O'Brien   day_list[5] = "Fri";
106c80476e4SDavid E. O'Brien   day_list[6] = "Sat";
107c80476e4SDavid E. O'Brien #endif
108c80476e4SDavid E. O'Brien }
109c80476e4SDavid E. O'Brien 
110c80476e4SDavid E. O'Brien void
111c80476e4SDavid E. O'Brien printprompt(promptno, str)
112c80476e4SDavid E. O'Brien     int     promptno;
113c80476e4SDavid E. O'Brien     char   *str;
114c80476e4SDavid E. O'Brien {
115c80476e4SDavid E. O'Brien     static  Char *ocp = NULL;
116c80476e4SDavid E. O'Brien     static  char *ostr = NULL;
117c80476e4SDavid E. O'Brien     time_t  lclock = time(NULL);
118c80476e4SDavid E. O'Brien     Char   *cp;
119c80476e4SDavid E. O'Brien 
120c80476e4SDavid E. O'Brien     switch (promptno) {
121c80476e4SDavid E. O'Brien     default:
122c80476e4SDavid E. O'Brien     case 0:
123c80476e4SDavid E. O'Brien 	cp = varval(STRprompt);
124c80476e4SDavid E. O'Brien 	break;
125c80476e4SDavid E. O'Brien     case 1:
126c80476e4SDavid E. O'Brien 	cp = varval(STRprompt2);
127c80476e4SDavid E. O'Brien 	break;
128c80476e4SDavid E. O'Brien     case 2:
129c80476e4SDavid E. O'Brien 	cp = varval(STRprompt3);
130c80476e4SDavid E. O'Brien 	break;
131c80476e4SDavid E. O'Brien     case 3:
132c80476e4SDavid E. O'Brien 	if (ocp != NULL) {
133c80476e4SDavid E. O'Brien 	    cp = ocp;
134c80476e4SDavid E. O'Brien 	    str = ostr;
135c80476e4SDavid E. O'Brien 	}
136c80476e4SDavid E. O'Brien 	else
137c80476e4SDavid E. O'Brien 	    cp = varval(STRprompt);
138c80476e4SDavid E. O'Brien 	break;
139c80476e4SDavid E. O'Brien     }
140c80476e4SDavid E. O'Brien 
141c80476e4SDavid E. O'Brien     if (promptno < 2) {
142c80476e4SDavid E. O'Brien 	ocp = cp;
143c80476e4SDavid E. O'Brien 	ostr = str;
144c80476e4SDavid E. O'Brien     }
145c80476e4SDavid E. O'Brien 
146c80476e4SDavid E. O'Brien     PromptBuf[0] = '\0';
147c80476e4SDavid E. O'Brien     tprintf(FMT_PROMPT, PromptBuf, cp, 2 * INBUFSIZE - 2, str, lclock, NULL);
148c80476e4SDavid E. O'Brien 
149c80476e4SDavid E. O'Brien     if (!editing) {
150c80476e4SDavid E. O'Brien 	for (cp = PromptBuf; *cp ; )
151c80476e4SDavid E. O'Brien 	    (void) putraw(*cp++);
152c80476e4SDavid E. O'Brien 	SetAttributes(0);
153c80476e4SDavid E. O'Brien 	flush();
154c80476e4SDavid E. O'Brien     }
155c80476e4SDavid E. O'Brien 
156c80476e4SDavid E. O'Brien     RPromptBuf[0] = '\0';
157c80476e4SDavid E. O'Brien     if (promptno == 0) {	/* determine rprompt if using main prompt */
158c80476e4SDavid E. O'Brien 	cp = varval(STRrprompt);
159c80476e4SDavid E. O'Brien 	tprintf(FMT_PROMPT, RPromptBuf, cp, INBUFSIZE - 2, NULL, lclock, NULL);
160c80476e4SDavid E. O'Brien 
161c80476e4SDavid E. O'Brien 				/* if not editing, put rprompt after prompt */
162c80476e4SDavid E. O'Brien 	if (!editing && RPromptBuf[0] != '\0') {
163c80476e4SDavid E. O'Brien 	    for (cp = RPromptBuf; *cp ; )
164c80476e4SDavid E. O'Brien 		(void) putraw(*cp++);
165c80476e4SDavid E. O'Brien 	    SetAttributes(0);
166c80476e4SDavid E. O'Brien 	    putraw(' ');
167c80476e4SDavid E. O'Brien 	    flush();
168c80476e4SDavid E. O'Brien 	}
169c80476e4SDavid E. O'Brien     }
170c80476e4SDavid E. O'Brien }
171c80476e4SDavid E. O'Brien 
172c80476e4SDavid E. O'Brien void
173c80476e4SDavid E. O'Brien tprintf(what, buf, fmt, siz, str, tim, info)
174c80476e4SDavid E. O'Brien     int what;
175c80476e4SDavid E. O'Brien     Char *buf;
176c80476e4SDavid E. O'Brien     const Char *fmt;
177c80476e4SDavid E. O'Brien     size_t siz;
178c80476e4SDavid E. O'Brien     char *str;
179c80476e4SDavid E. O'Brien     time_t tim;
180c80476e4SDavid E. O'Brien     ptr_t info;
181c80476e4SDavid E. O'Brien {
182c80476e4SDavid E. O'Brien     Char   *z, *q;
183c80476e4SDavid E. O'Brien     Char    attributes = 0;
184c80476e4SDavid E. O'Brien     static int print_prompt_did_ding = 0;
185c80476e4SDavid E. O'Brien     Char    buff[BUFSIZE];
186959f4c6cSDavid E. O'Brien     /* Need to be unsigned to avoid sign extension */
187959f4c6cSDavid E. O'Brien     const unsigned char   *cz;
188959f4c6cSDavid E. O'Brien     unsigned char    cbuff[BUFSIZE];
189c80476e4SDavid E. O'Brien 
190c80476e4SDavid E. O'Brien     Char *p  = buf;
191c80476e4SDavid E. O'Brien     Char *ep = &p[siz];
192c80476e4SDavid E. O'Brien     const Char *cp = fmt;
193c80476e4SDavid E. O'Brien     Char Scp;
194c80476e4SDavid E. O'Brien     struct tm *t = localtime(&tim);
195c80476e4SDavid E. O'Brien 
196c80476e4SDavid E. O'Brien 			/* prompt stuff */
197c80476e4SDavid E. O'Brien     static Char *olddir = NULL, *olduser = NULL;
198c80476e4SDavid E. O'Brien     extern int tlength;	/* cache cleared */
19929301572SMark Peek     int updirs;
20029301572SMark Peek     size_t pdirs, sz;
201c80476e4SDavid E. O'Brien 
202c80476e4SDavid E. O'Brien     for (; *cp; cp++) {
203c80476e4SDavid E. O'Brien 	if (p >= ep)
204c80476e4SDavid E. O'Brien 	    break;
2058e66bd9eSDavid E. O'Brien #ifdef DSPMBYTE
2068e66bd9eSDavid E. O'Brien 	if (Ismbyte1(*cp) && ! (cp[1] == '\0'))
2078e66bd9eSDavid E. O'Brien 	{
2088e66bd9eSDavid E. O'Brien 	    *p++ = attributes | *cp++;	/* normal character */
2098e66bd9eSDavid E. O'Brien 	    *p++ = attributes | *cp;	/* normal character */
2108e66bd9eSDavid E. O'Brien 	}
2118e66bd9eSDavid E. O'Brien 	else
2128e66bd9eSDavid E. O'Brien #endif /* DSPMBYTE */
213c80476e4SDavid E. O'Brien 	if ((*cp == '%') && ! (cp[1] == '\0')) {
214c80476e4SDavid E. O'Brien 	    cp++;
215c80476e4SDavid E. O'Brien 	    switch (*cp) {
216c80476e4SDavid E. O'Brien 	    case 'R':
217c80476e4SDavid E. O'Brien 		if (what == FMT_HISTORY)
218959f4c6cSDavid E. O'Brien 		    fmthist('R', info, (char *) (cz = cbuff), sizeof(cbuff));
219959f4c6cSDavid E. O'Brien 		else
220959f4c6cSDavid E. O'Brien 		    cz = (unsigned char *) str;
221078e45bcSDavid E. O'Brien 		if (cz != NULL)
222959f4c6cSDavid E. O'Brien 		    for (; *cz; *p++ = attributes | *cz++)
223c80476e4SDavid E. O'Brien 			if (p >= ep) break;
224c80476e4SDavid E. O'Brien 		break;
225c80476e4SDavid E. O'Brien 	    case '#':
226c80476e4SDavid E. O'Brien 		*p++ = attributes | ((uid == 0) ? PRCHROOT : PRCH);
227c80476e4SDavid E. O'Brien 		break;
228c80476e4SDavid E. O'Brien 	    case '!':
229c80476e4SDavid E. O'Brien 	    case 'h':
230c80476e4SDavid E. O'Brien 		switch (what) {
231c80476e4SDavid E. O'Brien 		case FMT_HISTORY:
232c80476e4SDavid E. O'Brien 		    fmthist('h', info, (char *) cbuff, sizeof(cbuff));
233c80476e4SDavid E. O'Brien 		    break;
234c80476e4SDavid E. O'Brien 		case FMT_SCHED:
235959f4c6cSDavid E. O'Brien 		    (void) xsnprintf((char *) cbuff, sizeof(cbuff), "%d",
236959f4c6cSDavid E. O'Brien 			*(int *)info);
237c80476e4SDavid E. O'Brien 		    break;
238c80476e4SDavid E. O'Brien 		default:
239959f4c6cSDavid E. O'Brien 		    (void) xsnprintf((char *) cbuff, sizeof(cbuff), "%d",
240959f4c6cSDavid E. O'Brien 			eventno + 1);
241c80476e4SDavid E. O'Brien 		    break;
242c80476e4SDavid E. O'Brien 		}
243c80476e4SDavid E. O'Brien 		for (cz = cbuff; *cz; *p++ = attributes | *cz++)
244c80476e4SDavid E. O'Brien 		    if (p >= ep) break;
245c80476e4SDavid E. O'Brien 		break;
246c80476e4SDavid E. O'Brien 	    case 'T':		/* 24 hour format	 */
247c80476e4SDavid E. O'Brien 	    case '@':
248c80476e4SDavid E. O'Brien 	    case 't':		/* 12 hour am/pm format */
249c80476e4SDavid E. O'Brien 	    case 'p':		/* With seconds	*/
250c80476e4SDavid E. O'Brien 	    case 'P':
251c80476e4SDavid E. O'Brien 		{
252c80476e4SDavid E. O'Brien 		    char    ampm = 'a';
253c80476e4SDavid E. O'Brien 		    int     hr = t->tm_hour;
254c80476e4SDavid E. O'Brien 
255c80476e4SDavid E. O'Brien 		    if (p >= ep - 10) break;
256c80476e4SDavid E. O'Brien 
257c80476e4SDavid E. O'Brien 		    /* addition by Hans J. Albertsson */
258c80476e4SDavid E. O'Brien 		    /* and another adapted from Justin Bur */
259c80476e4SDavid E. O'Brien 		    if (adrof(STRampm) || (*cp != 'T' && *cp != 'P')) {
260c80476e4SDavid E. O'Brien 			if (hr >= 12) {
261c80476e4SDavid E. O'Brien 			    if (hr > 12)
262c80476e4SDavid E. O'Brien 				hr -= 12;
263c80476e4SDavid E. O'Brien 			    ampm = 'p';
264c80476e4SDavid E. O'Brien 			}
265c80476e4SDavid E. O'Brien 			else if (hr == 0)
266c80476e4SDavid E. O'Brien 			    hr = 12;
267c80476e4SDavid E. O'Brien 		    }		/* else do a 24 hour clock */
268c80476e4SDavid E. O'Brien 
269c80476e4SDavid E. O'Brien 		    /* "DING!" stuff by Hans also */
270c80476e4SDavid E. O'Brien 		    if (t->tm_min || print_prompt_did_ding ||
271c80476e4SDavid E. O'Brien 			what != FMT_PROMPT || adrof(STRnoding)) {
272c80476e4SDavid E. O'Brien 			if (t->tm_min)
273c80476e4SDavid E. O'Brien 			    print_prompt_did_ding = 0;
274c80476e4SDavid E. O'Brien 			p = Itoa(hr, p, 0, attributes);
275c80476e4SDavid E. O'Brien 			*p++ = attributes | ':';
276c80476e4SDavid E. O'Brien 			p = Itoa(t->tm_min, p, 2, attributes);
277c80476e4SDavid E. O'Brien 			if (*cp == 'p' || *cp == 'P') {
278c80476e4SDavid E. O'Brien 			    *p++ = attributes | ':';
279c80476e4SDavid E. O'Brien 			    p = Itoa(t->tm_sec, p, 2, attributes);
280c80476e4SDavid E. O'Brien 			}
281c80476e4SDavid E. O'Brien 			if (adrof(STRampm) || (*cp != 'T' && *cp != 'P')) {
282c80476e4SDavid E. O'Brien 			    *p++ = attributes | ampm;
283c80476e4SDavid E. O'Brien 			    *p++ = attributes | 'm';
284c80476e4SDavid E. O'Brien 			}
285c80476e4SDavid E. O'Brien 		    }
286c80476e4SDavid E. O'Brien 		    else {	/* we need to ding */
287c80476e4SDavid E. O'Brien 			int     i = 0;
288c80476e4SDavid E. O'Brien 
289c80476e4SDavid E. O'Brien 			(void) Strcpy(buff, STRDING);
290c80476e4SDavid E. O'Brien 			while (buff[i]) {
291c80476e4SDavid E. O'Brien 			    *p++ = attributes | buff[i++];
292c80476e4SDavid E. O'Brien 			}
293c80476e4SDavid E. O'Brien 			print_prompt_did_ding = 1;
294c80476e4SDavid E. O'Brien 		    }
295c80476e4SDavid E. O'Brien 		}
296c80476e4SDavid E. O'Brien 		break;
297c80476e4SDavid E. O'Brien 
298c80476e4SDavid E. O'Brien 	    case 'M':
299c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP
300c80476e4SDavid E. O'Brien 		if (what == FMT_WHO)
301959f4c6cSDavid E. O'Brien 		    cz = (unsigned char *) who_info(info, 'M',
302959f4c6cSDavid E. O'Brien 			(char *) cbuff, sizeof(cbuff));
303c80476e4SDavid E. O'Brien 		else
304c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */
305959f4c6cSDavid E. O'Brien 		    cz = (unsigned char *) getenv("HOST");
306c80476e4SDavid E. O'Brien 		/*
307c80476e4SDavid E. O'Brien 		 * Bug pointed out by Laurent Dami <dami@cui.unige.ch>: don't
308c80476e4SDavid E. O'Brien 		 * derefrence that NULL (if HOST is not set)...
309c80476e4SDavid E. O'Brien 		 */
310c80476e4SDavid E. O'Brien 		if (cz != NULL)
311c80476e4SDavid E. O'Brien 		    for (; *cz ; *p++ = attributes | *cz++)
312c80476e4SDavid E. O'Brien 			if (p >= ep) break;
313c80476e4SDavid E. O'Brien 		break;
314c80476e4SDavid E. O'Brien 
315c80476e4SDavid E. O'Brien 	    case 'm':
316c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP
317c80476e4SDavid E. O'Brien 		if (what == FMT_WHO)
318959f4c6cSDavid E. O'Brien 		    cz = (unsigned char *) who_info(info, 'm', (char *) cbuff,
319959f4c6cSDavid E. O'Brien 			sizeof(cbuff));
320c80476e4SDavid E. O'Brien 		else
321c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */
322959f4c6cSDavid E. O'Brien 		    cz = (unsigned char *) getenv("HOST");
323c80476e4SDavid E. O'Brien 
324c80476e4SDavid E. O'Brien 		if (cz != NULL)
325c80476e4SDavid E. O'Brien 		    for ( ; *cz && (what == FMT_WHO || *cz != '.')
326c80476e4SDavid E. O'Brien 			  ; *p++ = attributes | *cz++ )
327c80476e4SDavid E. O'Brien 			if (p >= ep) break;
328c80476e4SDavid E. O'Brien 		break;
329c80476e4SDavid E. O'Brien 
330c80476e4SDavid E. O'Brien 			/* lukem: new directory prompt code */
331c80476e4SDavid E. O'Brien 	    case '~':
332c80476e4SDavid E. O'Brien 	    case '/':
333c80476e4SDavid E. O'Brien 	    case '.':
334c80476e4SDavid E. O'Brien 	    case 'c':
335c80476e4SDavid E. O'Brien 	    case 'C':
336c80476e4SDavid E. O'Brien 		Scp = *cp;
337c80476e4SDavid E. O'Brien 		if (Scp == 'c')		/* store format type (c == .) */
338c80476e4SDavid E. O'Brien 		    Scp = '.';
339c80476e4SDavid E. O'Brien 		if ((z = varval(STRcwd)) == STRNULL)
340c80476e4SDavid E. O'Brien 		    break;		/* no cwd, so don't do anything */
341c80476e4SDavid E. O'Brien 
342c80476e4SDavid E. O'Brien 			/* show ~ whenever possible - a la dirs */
343c80476e4SDavid E. O'Brien 		if (Scp == '~' || Scp == '.' ) {
344c80476e4SDavid E. O'Brien 		    if (tlength == 0 || olddir != z) {
345c80476e4SDavid E. O'Brien 			olddir = z;		/* have we changed dir? */
346c80476e4SDavid E. O'Brien 			olduser = getusername(&olddir);
347c80476e4SDavid E. O'Brien 		    }
348c80476e4SDavid E. O'Brien 		    if (olduser)
349c80476e4SDavid E. O'Brien 			z = olddir;
350c80476e4SDavid E. O'Brien 		}
351c80476e4SDavid E. O'Brien 		updirs = pdirs = 0;
352c80476e4SDavid E. O'Brien 
353c80476e4SDavid E. O'Brien 			/* option to determine fixed # of dirs from path */
354c80476e4SDavid E. O'Brien 		if (Scp == '.' || Scp == 'C') {
355c80476e4SDavid E. O'Brien 		    int skip;
3563b6eaa7bSAndrey A. Chernov #ifdef WINNT_NATIVE
357c80476e4SDavid E. O'Brien 		    if (z[1] == ':') {
358c80476e4SDavid E. O'Brien 		    	*p++ = attributes | *z++;
359c80476e4SDavid E. O'Brien 		    	*p++ = attributes | *z++;
360c80476e4SDavid E. O'Brien 		    }
361c80476e4SDavid E. O'Brien 			if (*z == '/' && z[1] == '/') {
362c80476e4SDavid E. O'Brien 				*p++ = attributes | *z++;
363c80476e4SDavid E. O'Brien 				*p++ = attributes | *z++;
364c80476e4SDavid E. O'Brien 				do {
365c80476e4SDavid E. O'Brien 					*p++ = attributes | *z++;
366c80476e4SDavid E. O'Brien 				}while(*z != '/');
367c80476e4SDavid E. O'Brien 			}
3683b6eaa7bSAndrey A. Chernov #endif /* WINNT_NATIVE */
369c80476e4SDavid E. O'Brien 		    q = z;
370c80476e4SDavid E. O'Brien 		    while (*z)				/* calc # of /'s */
371c80476e4SDavid E. O'Brien 			if (*z++ == '/')
372c80476e4SDavid E. O'Brien 			    updirs++;
373c80476e4SDavid E. O'Brien 		    if ((Scp == 'C' && *q != '/'))
374c80476e4SDavid E. O'Brien 			updirs++;
375c80476e4SDavid E. O'Brien 
376c80476e4SDavid E. O'Brien 		    if (cp[1] == '0') {			/* print <x> or ...  */
377c80476e4SDavid E. O'Brien 			pdirs = 1;
378c80476e4SDavid E. O'Brien 			cp++;
379c80476e4SDavid E. O'Brien 		    }
380c80476e4SDavid E. O'Brien 		    if (cp[1] >= '1' && cp[1] <= '9') {	/* calc # to skip  */
381c80476e4SDavid E. O'Brien 			skip = cp[1] - '0';
382c80476e4SDavid E. O'Brien 			cp++;
383c80476e4SDavid E. O'Brien 		    }
384c80476e4SDavid E. O'Brien 		    else
385c80476e4SDavid E. O'Brien 			skip = 1;
386c80476e4SDavid E. O'Brien 
387c80476e4SDavid E. O'Brien 		    updirs -= skip;
388c80476e4SDavid E. O'Brien 		    while (skip-- > 0) {
389c80476e4SDavid E. O'Brien 			while ((z > q) && (*z != '/'))
390c80476e4SDavid E. O'Brien 			    z--;			/* back up */
391c80476e4SDavid E. O'Brien 			if (skip && z > q)
392c80476e4SDavid E. O'Brien 			    z--;
393c80476e4SDavid E. O'Brien 		    }
394c80476e4SDavid E. O'Brien 		    if (*z == '/' && z != q)
395c80476e4SDavid E. O'Brien 			z++;
396c80476e4SDavid E. O'Brien 		} /* . || C */
397c80476e4SDavid E. O'Brien 
398c80476e4SDavid E. O'Brien 							/* print ~[user] */
399c80476e4SDavid E. O'Brien 		if ((olduser) && ((Scp == '~') ||
400c80476e4SDavid E. O'Brien 		     (Scp == '.' && (pdirs || (!pdirs && updirs <= 0))) )) {
401c80476e4SDavid E. O'Brien 		    *p++ = attributes | '~';
402c80476e4SDavid E. O'Brien 		    if (p >= ep) break;
403c80476e4SDavid E. O'Brien 		    for (q = olduser; *q; *p++ = attributes | *q++)
404c80476e4SDavid E. O'Brien 			if (p >= ep) break;
405c80476e4SDavid E. O'Brien 		}
406c80476e4SDavid E. O'Brien 
407c80476e4SDavid E. O'Brien 			/* RWM - tell you how many dirs we've ignored */
408c80476e4SDavid E. O'Brien 			/*       and add '/' at front of this         */
409c80476e4SDavid E. O'Brien 		if (updirs > 0 && pdirs) {
410c80476e4SDavid E. O'Brien 		    if (p >= ep - 5) break;
411c80476e4SDavid E. O'Brien 		    if (adrof(STRellipsis)) {
412c80476e4SDavid E. O'Brien 			*p++ = attributes | '.';
413c80476e4SDavid E. O'Brien 			*p++ = attributes | '.';
414c80476e4SDavid E. O'Brien 			*p++ = attributes | '.';
415c80476e4SDavid E. O'Brien 		    } else {
416c80476e4SDavid E. O'Brien 			*p++ = attributes | '/';
417c80476e4SDavid E. O'Brien 			*p++ = attributes | '<';
418c80476e4SDavid E. O'Brien 			if (updirs > 9) {
419c80476e4SDavid E. O'Brien 			    *p++ = attributes | '9';
420c80476e4SDavid E. O'Brien 			    *p++ = attributes | '+';
421c80476e4SDavid E. O'Brien 			} else
422c80476e4SDavid E. O'Brien 			    *p++ = attributes | ('0' + updirs);
42329301572SMark Peek 			*p++ = attributes | '>';
424c80476e4SDavid E. O'Brien 		    }
425c80476e4SDavid E. O'Brien 		}
426c80476e4SDavid E. O'Brien 
427c80476e4SDavid E. O'Brien 		for (; *z ; *p++ = attributes | *z++)
428c80476e4SDavid E. O'Brien 		    if (p >= ep) break;
429c80476e4SDavid E. O'Brien 		break;
430c80476e4SDavid E. O'Brien 			/* lukem: end of new directory prompt code */
431c80476e4SDavid E. O'Brien 
432c80476e4SDavid E. O'Brien 	    case 'n':
433c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP
434c80476e4SDavid E. O'Brien 		if (what == FMT_WHO) {
435959f4c6cSDavid E. O'Brien 		    cz = (unsigned char *) who_info(info, 'n',
436959f4c6cSDavid E. O'Brien 			(char *) cbuff, sizeof(cbuff));
437c80476e4SDavid E. O'Brien 		    for (; cz && *cz ; *p++ = attributes | *cz++)
438c80476e4SDavid E. O'Brien 			if (p >= ep) break;
439c80476e4SDavid E. O'Brien 		}
440c80476e4SDavid E. O'Brien 		else
441c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */
442c80476e4SDavid E. O'Brien 		{
443c80476e4SDavid E. O'Brien 		    if ((z = varval(STRuser)) != STRNULL)
444c80476e4SDavid E. O'Brien 			for (; *z; *p++ = attributes | *z++)
445c80476e4SDavid E. O'Brien 			    if (p >= ep) break;
446c80476e4SDavid E. O'Brien 		}
447c80476e4SDavid E. O'Brien 		break;
448c80476e4SDavid E. O'Brien 	    case 'l':
449c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP
450c80476e4SDavid E. O'Brien 		if (what == FMT_WHO) {
451959f4c6cSDavid E. O'Brien 		    cz = (unsigned char *) who_info(info, 'l',
452959f4c6cSDavid E. O'Brien 			(char *) cbuff, sizeof(cbuff));
453c80476e4SDavid E. O'Brien 		    for (; cz && *cz ; *p++ = attributes | *cz++)
454c80476e4SDavid E. O'Brien 			if (p >= ep) break;
455c80476e4SDavid E. O'Brien 		}
456c80476e4SDavid E. O'Brien 		else
457c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */
458c80476e4SDavid E. O'Brien 		{
459c80476e4SDavid E. O'Brien 		    if ((z = varval(STRtty)) != STRNULL)
460c80476e4SDavid E. O'Brien 			for (; *z; *p++ = attributes | *z++)
461c80476e4SDavid E. O'Brien 			    if (p >= ep) break;
462c80476e4SDavid E. O'Brien 		}
463c80476e4SDavid E. O'Brien 		break;
464c80476e4SDavid E. O'Brien 	    case 'd':
465959f4c6cSDavid E. O'Brien 		for (cz = (unsigned char *) day_list[t->tm_wday]; *cz;
466959f4c6cSDavid E. O'Brien 		    *p++ = attributes | *cz++)
467c80476e4SDavid E. O'Brien 		    if (p >= ep) break;
468c80476e4SDavid E. O'Brien 		break;
469c80476e4SDavid E. O'Brien 	    case 'D':
470c80476e4SDavid E. O'Brien 		if (p >= ep - 3) break;
471c80476e4SDavid E. O'Brien 		p = Itoa(t->tm_mday, p, 2, attributes);
472c80476e4SDavid E. O'Brien 		break;
473c80476e4SDavid E. O'Brien 	    case 'w':
474c80476e4SDavid E. O'Brien 		if (p >= ep - 5) break;
475959f4c6cSDavid E. O'Brien 		for (cz = (unsigned char *) month_list[t->tm_mon]; *cz;
476078e45bcSDavid E. O'Brien 		    *p++ = attributes | *cz++)
477959f4c6cSDavid E. O'Brien 		    if (p >= ep) break;
478c80476e4SDavid E. O'Brien 		break;
479c80476e4SDavid E. O'Brien 	    case 'W':
480c80476e4SDavid E. O'Brien 		if (p >= ep - 3) break;
481c80476e4SDavid E. O'Brien 		p = Itoa(t->tm_mon + 1, p, 2, attributes);
482c80476e4SDavid E. O'Brien 		break;
483c80476e4SDavid E. O'Brien 	    case 'y':
484c80476e4SDavid E. O'Brien 		if (p >= ep - 3) break;
485c80476e4SDavid E. O'Brien 		p = Itoa(t->tm_year % 100, p, 2, attributes);
486c80476e4SDavid E. O'Brien 		break;
487c80476e4SDavid E. O'Brien 	    case 'Y':
488c80476e4SDavid E. O'Brien 		if (p >= ep - 5) break;
489c80476e4SDavid E. O'Brien 		p = Itoa(t->tm_year + 1900, p, 4, attributes);
490c80476e4SDavid E. O'Brien 		break;
491c80476e4SDavid E. O'Brien 	    case 'S':		/* start standout */
492c80476e4SDavid E. O'Brien 		attributes |= STANDOUT;
493c80476e4SDavid E. O'Brien 		break;
494c80476e4SDavid E. O'Brien 	    case 'B':		/* start bold */
495c80476e4SDavid E. O'Brien 		attributes |= BOLD;
496c80476e4SDavid E. O'Brien 		break;
497c80476e4SDavid E. O'Brien 	    case 'U':		/* start underline */
498c80476e4SDavid E. O'Brien 		attributes |= UNDER;
499c80476e4SDavid E. O'Brien 		break;
500c80476e4SDavid E. O'Brien 	    case 's':		/* end standout */
501c80476e4SDavid E. O'Brien 		attributes &= ~STANDOUT;
502c80476e4SDavid E. O'Brien 		break;
503c80476e4SDavid E. O'Brien 	    case 'b':		/* end bold */
504c80476e4SDavid E. O'Brien 		attributes &= ~BOLD;
505c80476e4SDavid E. O'Brien 		break;
506c80476e4SDavid E. O'Brien 	    case 'u':		/* end underline */
507c80476e4SDavid E. O'Brien 		attributes &= ~UNDER;
508c80476e4SDavid E. O'Brien 		break;
509c80476e4SDavid E. O'Brien 	    case 'L':
510c80476e4SDavid E. O'Brien 		ClearToBottom();
511c80476e4SDavid E. O'Brien 		break;
51229301572SMark Peek 
51329301572SMark Peek 	    case 'j':
51429301572SMark Peek 		{
51529301572SMark Peek 		    Char buf[128], *ebuf, *q;
51629301572SMark Peek 		    int njobs = -1;
51729301572SMark Peek 		    struct process *pp;
51829301572SMark Peek 		    for (pp = proclist.p_next; pp; pp = pp->p_next)
51929301572SMark Peek 			njobs++;
52029301572SMark Peek 		    /* make sure we have space */
52129301572SMark Peek 		    ebuf = Itoa(njobs, buf, 1, attributes);
52229301572SMark Peek 		    for (q = buf; q < ebuf; *p++ = *q++)
52329301572SMark Peek 			if (p >= ep) break;
52429301572SMark Peek 		    break;
52529301572SMark Peek 		}
526c80476e4SDavid E. O'Brien 	    case '?':
527c80476e4SDavid E. O'Brien 		if ((z = varval(STRstatus)) != STRNULL)
528c80476e4SDavid E. O'Brien 		    for (; *z; *p++ = attributes | *z++)
529c80476e4SDavid E. O'Brien 			if (p >= ep) break;
530c80476e4SDavid E. O'Brien 		break;
531c80476e4SDavid E. O'Brien 	    case '$':
53229301572SMark Peek 		sz = ep - p;
5333b6eaa7bSAndrey A. Chernov 		(void) expdollar(&p, &cp, &sz, attributes);
53429301572SMark Peek 		/* cp should point the last char of currnet % sequence */
53529301572SMark Peek 		cp--;
536c80476e4SDavid E. O'Brien 		break;
537c80476e4SDavid E. O'Brien 	    case '%':
538c80476e4SDavid E. O'Brien 		*p++ = attributes | '%';
539c80476e4SDavid E. O'Brien 		break;
540c80476e4SDavid E. O'Brien 	    case '{':		/* literal characters start */
541c80476e4SDavid E. O'Brien #if LITERAL == 0
542c80476e4SDavid E. O'Brien 		/*
543c80476e4SDavid E. O'Brien 		 * No literal capability, so skip all chars in the literal
544c80476e4SDavid E. O'Brien 		 * string
545c80476e4SDavid E. O'Brien 		 */
546c80476e4SDavid E. O'Brien 		while (*cp != '\0' && (*cp != '%' || cp[1] != '}'))
547c80476e4SDavid E. O'Brien 		    cp++;
548c80476e4SDavid E. O'Brien #endif				/* LITERAL == 0 */
549c80476e4SDavid E. O'Brien 		attributes |= LITERAL;
550c80476e4SDavid E. O'Brien 		break;
551c80476e4SDavid E. O'Brien 	    case '}':		/* literal characters end */
552c80476e4SDavid E. O'Brien 		attributes &= ~LITERAL;
553c80476e4SDavid E. O'Brien 		break;
554c80476e4SDavid E. O'Brien 	    default:
555c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP
556c80476e4SDavid E. O'Brien 		if (*cp == 'a' && what == FMT_WHO) {
557c80476e4SDavid E. O'Brien 		    cz = who_info(info, 'a', (char *) cbuff, sizeof(cbuff));
558c80476e4SDavid E. O'Brien 		    for (; cz && *cz; *p++ = attributes | *cz++)
559c80476e4SDavid E. O'Brien 			if (p >= ep) break;
560c80476e4SDavid E. O'Brien 		}
561c80476e4SDavid E. O'Brien 		else
562c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */
563c80476e4SDavid E. O'Brien 		{
564c80476e4SDavid E. O'Brien 		    if (p >= ep - 3) break;
565c80476e4SDavid E. O'Brien 		    *p++ = attributes | '%';
566c80476e4SDavid E. O'Brien 		    *p++ = attributes | *cp;
567c80476e4SDavid E. O'Brien 		}
568c80476e4SDavid E. O'Brien 		break;
569c80476e4SDavid E. O'Brien 	    }
570c80476e4SDavid E. O'Brien 	}
571c80476e4SDavid E. O'Brien 	else if (*cp == '\\' || *cp == '^')
572c80476e4SDavid E. O'Brien 	    *p++ = attributes | parseescape(&cp);
573c80476e4SDavid E. O'Brien 	else if (*cp == HIST) {	/* EGS: handle '!'s in prompts */
574c80476e4SDavid E. O'Brien 	    if (what == FMT_HISTORY)
575c80476e4SDavid E. O'Brien 		fmthist('h', info, (char *) cbuff, sizeof(cbuff));
576c80476e4SDavid E. O'Brien 	    else
577c80476e4SDavid E. O'Brien 		(void) xsnprintf((char *) cbuff, sizeof(cbuff), "%d", eventno + 1);
578c80476e4SDavid E. O'Brien 	    for (cz = cbuff; *cz; *p++ = attributes | *cz++)
579c80476e4SDavid E. O'Brien 		if (p >= ep) break;
580c80476e4SDavid E. O'Brien 	}
581c80476e4SDavid E. O'Brien 	else
582c80476e4SDavid E. O'Brien 	    *p++ = attributes | *cp;	/* normal character */
583c80476e4SDavid E. O'Brien     }
584c80476e4SDavid E. O'Brien     *p = '\0';
585c80476e4SDavid E. O'Brien }
586c80476e4SDavid E. O'Brien 
587c80476e4SDavid E. O'Brien Char *
588c80476e4SDavid E. O'Brien expdollar(dstp, srcp, spp, attr)
589c80476e4SDavid E. O'Brien     Char **dstp;
590c80476e4SDavid E. O'Brien     const Char **srcp;
591c80476e4SDavid E. O'Brien     size_t *spp;
592c80476e4SDavid E. O'Brien     int	    attr;
593c80476e4SDavid E. O'Brien {
594c80476e4SDavid E. O'Brien     struct varent *vp;
595c80476e4SDavid E. O'Brien     Char var[MAXVARLEN];
596c80476e4SDavid E. O'Brien     const Char *src = *srcp;
597c80476e4SDavid E. O'Brien     Char *val;
598c80476e4SDavid E. O'Brien     Char *dst = *dstp;
599c80476e4SDavid E. O'Brien     int i, curly = 0;
600c80476e4SDavid E. O'Brien 
601c80476e4SDavid E. O'Brien     /* found a variable, expand it */
602c80476e4SDavid E. O'Brien     for (i = 0; i < MAXVARLEN; i++) {
603c80476e4SDavid E. O'Brien 	var[i] = *++src & TRIM;
604c80476e4SDavid E. O'Brien 	if (i == 0 && var[i] == '{') {
605c80476e4SDavid E. O'Brien 	    curly = 1;
606c80476e4SDavid E. O'Brien 	    var[i] = *++src & TRIM;
607c80476e4SDavid E. O'Brien 	}
608c80476e4SDavid E. O'Brien 	if (!alnum(var[i])) {
609c80476e4SDavid E. O'Brien 
610c80476e4SDavid E. O'Brien 	    var[i] = '\0';
611c80476e4SDavid E. O'Brien 	    break;
612c80476e4SDavid E. O'Brien 	}
613c80476e4SDavid E. O'Brien     }
614c80476e4SDavid E. O'Brien     if (curly && (*src & TRIM) == '}')
615c80476e4SDavid E. O'Brien 	src++;
616c80476e4SDavid E. O'Brien 
617c80476e4SDavid E. O'Brien     vp = adrof(var);
618c80476e4SDavid E. O'Brien     val = (!vp) ? tgetenv(var) : NULL;
61929301572SMark Peek     if (vp && vp->vec) {
620c80476e4SDavid E. O'Brien 	for (i = 0; vp->vec[i] != NULL; i++) {
621c80476e4SDavid E. O'Brien 	    for (val = vp->vec[i]; *spp > 0 && *val; (*spp)--)
622c80476e4SDavid E. O'Brien 		*dst++ = *val++ | attr;
623c80476e4SDavid E. O'Brien 	    if (vp->vec[i+1] && *spp > 0) {
624c80476e4SDavid E. O'Brien 		*dst++ = ' ' | attr;
625c80476e4SDavid E. O'Brien 		(*spp)--;
626c80476e4SDavid E. O'Brien 	    }
627c80476e4SDavid E. O'Brien 	}
628c80476e4SDavid E. O'Brien     }
629c80476e4SDavid E. O'Brien     else if (val) {
630c80476e4SDavid E. O'Brien 	for (; *spp > 0 && *val; (*spp)--)
631c80476e4SDavid E. O'Brien 	    *dst++ = *val++ | attr;
632c80476e4SDavid E. O'Brien     }
633c80476e4SDavid E. O'Brien     else {
634c80476e4SDavid E. O'Brien 	**dstp = '\0';
635c80476e4SDavid E. O'Brien 	*srcp = src;
636c80476e4SDavid E. O'Brien 	return NULL;
637c80476e4SDavid E. O'Brien     }
638c80476e4SDavid E. O'Brien     *dst = '\0';
639c80476e4SDavid E. O'Brien 
640c80476e4SDavid E. O'Brien     val = *dstp;
641c80476e4SDavid E. O'Brien     *srcp = src;
642c80476e4SDavid E. O'Brien     *dstp = dst;
643c80476e4SDavid E. O'Brien 
644c80476e4SDavid E. O'Brien     return val;
645c80476e4SDavid E. O'Brien }
646