1*19d2e3deSDmitry Chagin /* $Header: /p/tcsh/cvsroot/tcsh/tc.prompt.c,v 3.71 2014/08/23 09:07:57 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 35*19d2e3deSDmitry Chagin RCSID("$tcsh: tc.prompt.c,v 3.71 2014/08/23 09:07:57 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 5123338178SMark Peek static const char *month_list[12]; 5223338178SMark Peek static const char *day_list[7]; 53c80476e4SDavid E. O'Brien 54c80476e4SDavid E. O'Brien void 5545e5710bSMark Peek dateinit(void) 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 11145e5710bSMark Peek printprompt(int promptno, const char *str) 112c80476e4SDavid E. O'Brien { 11345e5710bSMark Peek static const Char *ocp = NULL; 11423338178SMark Peek static const char *ostr = NULL; 115c80476e4SDavid E. O'Brien time_t lclock = time(NULL); 11645e5710bSMark Peek const Char *cp; 117c80476e4SDavid E. O'Brien 118c80476e4SDavid E. O'Brien switch (promptno) { 119c80476e4SDavid E. O'Brien default: 120c80476e4SDavid E. O'Brien case 0: 121c80476e4SDavid E. O'Brien cp = varval(STRprompt); 122c80476e4SDavid E. O'Brien break; 123c80476e4SDavid E. O'Brien case 1: 124c80476e4SDavid E. O'Brien cp = varval(STRprompt2); 125c80476e4SDavid E. O'Brien break; 126c80476e4SDavid E. O'Brien case 2: 127c80476e4SDavid E. O'Brien cp = varval(STRprompt3); 128c80476e4SDavid E. O'Brien break; 129c80476e4SDavid E. O'Brien case 3: 130c80476e4SDavid E. O'Brien if (ocp != NULL) { 131c80476e4SDavid E. O'Brien cp = ocp; 132c80476e4SDavid E. O'Brien str = ostr; 133c80476e4SDavid E. O'Brien } 134c80476e4SDavid E. O'Brien else 135c80476e4SDavid E. O'Brien cp = varval(STRprompt); 136c80476e4SDavid E. O'Brien break; 137c80476e4SDavid E. O'Brien } 138c80476e4SDavid E. O'Brien 139c80476e4SDavid E. O'Brien if (promptno < 2) { 140c80476e4SDavid E. O'Brien ocp = cp; 141c80476e4SDavid E. O'Brien ostr = str; 142c80476e4SDavid E. O'Brien } 143c80476e4SDavid E. O'Brien 14445e5710bSMark Peek xfree(Prompt); 14545e5710bSMark Peek Prompt = NULL; 14645e5710bSMark Peek Prompt = tprintf(FMT_PROMPT, cp, str, lclock, NULL); 147c80476e4SDavid E. O'Brien if (!editing) { 14845e5710bSMark Peek for (cp = Prompt; *cp ; ) 14923338178SMark Peek (void) putwraw(*cp++); 150c80476e4SDavid E. O'Brien SetAttributes(0); 151c80476e4SDavid E. O'Brien flush(); 152c80476e4SDavid E. O'Brien } 153c80476e4SDavid E. O'Brien 15445e5710bSMark Peek xfree(RPrompt); 15545e5710bSMark Peek RPrompt = NULL; 156c80476e4SDavid E. O'Brien if (promptno == 0) { /* determine rprompt if using main prompt */ 157c80476e4SDavid E. O'Brien cp = varval(STRrprompt); 15845e5710bSMark Peek RPrompt = tprintf(FMT_PROMPT, cp, NULL, lclock, NULL); 159c80476e4SDavid E. O'Brien /* if not editing, put rprompt after prompt */ 16045e5710bSMark Peek if (!editing && RPrompt[0] != '\0') { 16145e5710bSMark Peek for (cp = RPrompt; *cp ; ) 16223338178SMark Peek (void) putwraw(*cp++); 163c80476e4SDavid E. O'Brien SetAttributes(0); 164c80476e4SDavid E. O'Brien putraw(' '); 165c80476e4SDavid E. O'Brien flush(); 166c80476e4SDavid E. O'Brien } 167c80476e4SDavid E. O'Brien } 168c80476e4SDavid E. O'Brien } 169c80476e4SDavid E. O'Brien 17045e5710bSMark Peek static void 17145e5710bSMark Peek tprintf_append_mbs(struct Strbuf *buf, const char *mbs, Char attributes) 172c80476e4SDavid E. O'Brien { 17345e5710bSMark Peek while (*mbs != 0) { 17445e5710bSMark Peek Char wc; 17545e5710bSMark Peek 17645e5710bSMark Peek mbs += one_mbtowc(&wc, mbs, MB_LEN_MAX); 17745e5710bSMark Peek Strbuf_append1(buf, wc | attributes); 17845e5710bSMark Peek } 17945e5710bSMark Peek } 18045e5710bSMark Peek 18145e5710bSMark Peek Char * 18245e5710bSMark Peek tprintf(int what, const Char *fmt, const char *str, time_t tim, ptr_t info) 18345e5710bSMark Peek { 18445e5710bSMark Peek struct Strbuf buf = Strbuf_INIT; 185c80476e4SDavid E. O'Brien Char *z, *q; 186c80476e4SDavid E. O'Brien Char attributes = 0; 187c80476e4SDavid E. O'Brien static int print_prompt_did_ding = 0; 18845e5710bSMark Peek char *cz; 189c80476e4SDavid E. O'Brien 19045e5710bSMark Peek Char *p; 191c80476e4SDavid E. O'Brien const Char *cp = fmt; 192c80476e4SDavid E. O'Brien Char Scp; 193c80476e4SDavid E. O'Brien struct tm *t = localtime(&tim); 194c80476e4SDavid E. O'Brien 195c80476e4SDavid E. O'Brien /* prompt stuff */ 19645e5710bSMark Peek static Char *olduser = NULL; 19729301572SMark Peek int updirs; 19845e5710bSMark Peek size_t pdirs; 199c80476e4SDavid E. O'Brien 20045e5710bSMark Peek cleanup_push(&buf, Strbuf_cleanup); 201c80476e4SDavid E. O'Brien for (; *cp; cp++) { 202c80476e4SDavid E. O'Brien if ((*cp == '%') && ! (cp[1] == '\0')) { 203c80476e4SDavid E. O'Brien cp++; 204c80476e4SDavid E. O'Brien switch (*cp) { 205c80476e4SDavid E. O'Brien case 'R': 20623338178SMark Peek if (what == FMT_HISTORY) { 20745e5710bSMark Peek cz = fmthist('R', info); 20845e5710bSMark Peek tprintf_append_mbs(&buf, cz, attributes); 20945e5710bSMark Peek xfree(cz); 21045e5710bSMark Peek } else { 21145e5710bSMark Peek if (str != NULL) 21245e5710bSMark Peek tprintf_append_mbs(&buf, str, attributes); 21323338178SMark Peek } 214c80476e4SDavid E. O'Brien break; 215c80476e4SDavid E. O'Brien case '#': 216*19d2e3deSDmitry Chagin #ifdef __CYGWIN__ 217*19d2e3deSDmitry Chagin /* Check for being member of the Administrators group */ 218*19d2e3deSDmitry Chagin { 219*19d2e3deSDmitry Chagin gid_t grps[NGROUPS_MAX]; 220*19d2e3deSDmitry Chagin int grp, gcnt; 221*19d2e3deSDmitry Chagin 222*19d2e3deSDmitry Chagin gcnt = getgroups(NGROUPS_MAX, grps); 223*19d2e3deSDmitry Chagin # define DOMAIN_GROUP_RID_ADMINS 544 224*19d2e3deSDmitry Chagin for (grp = 0; grp < gcnt; ++grp) 225*19d2e3deSDmitry Chagin if (grps[grp] == DOMAIN_GROUP_RID_ADMINS) 226*19d2e3deSDmitry Chagin break; 227*19d2e3deSDmitry Chagin Scp = (grp < gcnt) ? PRCHROOT : PRCH; 228*19d2e3deSDmitry Chagin } 229*19d2e3deSDmitry Chagin #else 2309ccc37e3SMark Peek Scp = (uid == 0 || euid == 0) ? PRCHROOT : PRCH; 231*19d2e3deSDmitry Chagin #endif 2329ccc37e3SMark Peek if (Scp != '\0') 2339ccc37e3SMark Peek Strbuf_append1(&buf, attributes | Scp); 234c80476e4SDavid E. O'Brien break; 235c80476e4SDavid E. O'Brien case '!': 236c80476e4SDavid E. O'Brien case 'h': 237c80476e4SDavid E. O'Brien switch (what) { 238c80476e4SDavid E. O'Brien case FMT_HISTORY: 23945e5710bSMark Peek cz = fmthist('h', info); 240c80476e4SDavid E. O'Brien break; 241c80476e4SDavid E. O'Brien case FMT_SCHED: 24245e5710bSMark Peek cz = xasprintf("%d", *(int *)info); 243c80476e4SDavid E. O'Brien break; 244c80476e4SDavid E. O'Brien default: 24545e5710bSMark Peek cz = xasprintf("%d", eventno + 1); 246c80476e4SDavid E. O'Brien break; 247c80476e4SDavid E. O'Brien } 24845e5710bSMark Peek tprintf_append_mbs(&buf, cz, attributes); 24945e5710bSMark Peek xfree(cz); 250c80476e4SDavid E. O'Brien break; 251c80476e4SDavid E. O'Brien case 'T': /* 24 hour format */ 252c80476e4SDavid E. O'Brien case '@': 253c80476e4SDavid E. O'Brien case 't': /* 12 hour am/pm format */ 254c80476e4SDavid E. O'Brien case 'p': /* With seconds */ 255c80476e4SDavid E. O'Brien case 'P': 256c80476e4SDavid E. O'Brien { 257c80476e4SDavid E. O'Brien char ampm = 'a'; 258c80476e4SDavid E. O'Brien int hr = t->tm_hour; 259c80476e4SDavid E. O'Brien 260c80476e4SDavid E. O'Brien /* addition by Hans J. Albertsson */ 261c80476e4SDavid E. O'Brien /* and another adapted from Justin Bur */ 262c80476e4SDavid E. O'Brien if (adrof(STRampm) || (*cp != 'T' && *cp != 'P')) { 263c80476e4SDavid E. O'Brien if (hr >= 12) { 264c80476e4SDavid E. O'Brien if (hr > 12) 265c80476e4SDavid E. O'Brien hr -= 12; 266c80476e4SDavid E. O'Brien ampm = 'p'; 267c80476e4SDavid E. O'Brien } 268c80476e4SDavid E. O'Brien else if (hr == 0) 269c80476e4SDavid E. O'Brien hr = 12; 270c80476e4SDavid E. O'Brien } /* else do a 24 hour clock */ 271c80476e4SDavid E. O'Brien 272c80476e4SDavid E. O'Brien /* "DING!" stuff by Hans also */ 273c80476e4SDavid E. O'Brien if (t->tm_min || print_prompt_did_ding || 274c80476e4SDavid E. O'Brien what != FMT_PROMPT || adrof(STRnoding)) { 275c80476e4SDavid E. O'Brien if (t->tm_min) 276c80476e4SDavid E. O'Brien print_prompt_did_ding = 0; 27745e5710bSMark Peek /* 27845e5710bSMark Peek * Pad hour to 2 characters if padhour is set, 27945e5710bSMark Peek * by ADAM David Alan Martin 28045e5710bSMark Peek */ 28145e5710bSMark Peek p = Itoa(hr, adrof(STRpadhour) ? 2 : 0, attributes); 28245e5710bSMark Peek Strbuf_append(&buf, p); 28345e5710bSMark Peek xfree(p); 28445e5710bSMark Peek Strbuf_append1(&buf, attributes | ':'); 28545e5710bSMark Peek p = Itoa(t->tm_min, 2, attributes); 28645e5710bSMark Peek Strbuf_append(&buf, p); 28745e5710bSMark Peek xfree(p); 288c80476e4SDavid E. O'Brien if (*cp == 'p' || *cp == 'P') { 28945e5710bSMark Peek Strbuf_append1(&buf, attributes | ':'); 29045e5710bSMark Peek p = Itoa(t->tm_sec, 2, attributes); 29145e5710bSMark Peek Strbuf_append(&buf, p); 29245e5710bSMark Peek xfree(p); 293c80476e4SDavid E. O'Brien } 294c80476e4SDavid E. O'Brien if (adrof(STRampm) || (*cp != 'T' && *cp != 'P')) { 29545e5710bSMark Peek Strbuf_append1(&buf, attributes | ampm); 29645e5710bSMark Peek Strbuf_append1(&buf, attributes | 'm'); 297c80476e4SDavid E. O'Brien } 298c80476e4SDavid E. O'Brien } 299c80476e4SDavid E. O'Brien else { /* we need to ding */ 30045e5710bSMark Peek size_t i; 301c80476e4SDavid E. O'Brien 30245e5710bSMark Peek for (i = 0; STRDING[i] != 0; i++) 30345e5710bSMark Peek Strbuf_append1(&buf, attributes | STRDING[i]); 304c80476e4SDavid E. O'Brien print_prompt_did_ding = 1; 305c80476e4SDavid E. O'Brien } 306c80476e4SDavid E. O'Brien } 307c80476e4SDavid E. O'Brien break; 308c80476e4SDavid E. O'Brien 309c80476e4SDavid E. O'Brien case 'M': 310c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP 311c80476e4SDavid E. O'Brien if (what == FMT_WHO) 31245e5710bSMark Peek cz = who_info(info, 'M'); 313c80476e4SDavid E. O'Brien else 314c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */ 31545e5710bSMark Peek cz = getenv("HOST"); 316c80476e4SDavid E. O'Brien /* 317c80476e4SDavid E. O'Brien * Bug pointed out by Laurent Dami <dami@cui.unige.ch>: don't 318c80476e4SDavid E. O'Brien * derefrence that NULL (if HOST is not set)... 319c80476e4SDavid E. O'Brien */ 320c80476e4SDavid E. O'Brien if (cz != NULL) 32145e5710bSMark Peek tprintf_append_mbs(&buf, cz, attributes); 32245e5710bSMark Peek if (what == FMT_WHO) 32345e5710bSMark Peek xfree(cz); 324c80476e4SDavid E. O'Brien break; 325c80476e4SDavid E. O'Brien 32645e5710bSMark Peek case 'm': { 32745e5710bSMark Peek char *scz = NULL; 328c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP 329c80476e4SDavid E. O'Brien if (what == FMT_WHO) 33045e5710bSMark Peek scz = cz = who_info(info, 'm'); 331c80476e4SDavid E. O'Brien else 332c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */ 33345e5710bSMark Peek cz = getenv("HOST"); 334c80476e4SDavid E. O'Brien 335c80476e4SDavid E. O'Brien if (cz != NULL) 33645e5710bSMark Peek while (*cz != 0 && (what == FMT_WHO || *cz != '.')) { 33745e5710bSMark Peek Char wc; 33845e5710bSMark Peek 33945e5710bSMark Peek cz += one_mbtowc(&wc, cz, MB_LEN_MAX); 34045e5710bSMark Peek Strbuf_append1(&buf, wc | attributes); 34123338178SMark Peek } 34245e5710bSMark Peek if (scz) 34345e5710bSMark Peek xfree(scz); 344c80476e4SDavid E. O'Brien break; 34545e5710bSMark Peek } 346c80476e4SDavid E. O'Brien 347c80476e4SDavid E. O'Brien /* lukem: new directory prompt code */ 348c80476e4SDavid E. O'Brien case '~': 349c80476e4SDavid E. O'Brien case '/': 350c80476e4SDavid E. O'Brien case '.': 351c80476e4SDavid E. O'Brien case 'c': 352c80476e4SDavid E. O'Brien case 'C': 353c80476e4SDavid E. O'Brien Scp = *cp; 354c80476e4SDavid E. O'Brien if (Scp == 'c') /* store format type (c == .) */ 355c80476e4SDavid E. O'Brien Scp = '.'; 356c80476e4SDavid E. O'Brien if ((z = varval(STRcwd)) == STRNULL) 357c80476e4SDavid E. O'Brien break; /* no cwd, so don't do anything */ 358c80476e4SDavid E. O'Brien 359c80476e4SDavid E. O'Brien /* show ~ whenever possible - a la dirs */ 360c80476e4SDavid E. O'Brien if (Scp == '~' || Scp == '.' ) { 36145e5710bSMark Peek static Char *olddir = NULL; 36245e5710bSMark Peek 363c80476e4SDavid E. O'Brien if (tlength == 0 || olddir != z) { 364c80476e4SDavid E. O'Brien olddir = z; /* have we changed dir? */ 365c80476e4SDavid E. O'Brien olduser = getusername(&olddir); 366c80476e4SDavid E. O'Brien } 367c80476e4SDavid E. O'Brien if (olduser) 368c80476e4SDavid E. O'Brien z = olddir; 369c80476e4SDavid E. O'Brien } 370c80476e4SDavid E. O'Brien updirs = pdirs = 0; 371c80476e4SDavid E. O'Brien 372c80476e4SDavid E. O'Brien /* option to determine fixed # of dirs from path */ 373c80476e4SDavid E. O'Brien if (Scp == '.' || Scp == 'C') { 374c80476e4SDavid E. O'Brien int skip; 3753b6eaa7bSAndrey A. Chernov #ifdef WINNT_NATIVE 37623338178SMark Peek Char *oldz = z; 377c80476e4SDavid E. O'Brien if (z[1] == ':') { 37845e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 37945e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 380c80476e4SDavid E. O'Brien } 381c80476e4SDavid E. O'Brien if (*z == '/' && z[1] == '/') { 38245e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 38345e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 384c80476e4SDavid E. O'Brien do { 38545e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 386c80476e4SDavid E. O'Brien } while(*z != '/'); 387c80476e4SDavid E. O'Brien } 3883b6eaa7bSAndrey A. Chernov #endif /* WINNT_NATIVE */ 389c80476e4SDavid E. O'Brien q = z; 390c80476e4SDavid E. O'Brien while (*z) /* calc # of /'s */ 391c80476e4SDavid E. O'Brien if (*z++ == '/') 392c80476e4SDavid E. O'Brien updirs++; 39323338178SMark Peek 39423338178SMark Peek #ifdef WINNT_NATIVE 39523338178SMark Peek /* 39623338178SMark Peek * for format type c, prompt will be following... 39723338178SMark Peek * c:/path => c:/path 39823338178SMark Peek * c:/path/to => c:to 39923338178SMark Peek * //machine/share => //machine/share 40023338178SMark Peek * //machine/share/folder => //machine:folder 40123338178SMark Peek */ 40223338178SMark Peek if (oldz[0] == '/' && oldz[1] == '/' && updirs > 1) 40345e5710bSMark Peek Strbuf_append1(&buf, attributes | ':'); 40423338178SMark Peek #endif /* WINNT_NATIVE */ 405c80476e4SDavid E. O'Brien if ((Scp == 'C' && *q != '/')) 406c80476e4SDavid E. O'Brien updirs++; 407c80476e4SDavid E. O'Brien 408c80476e4SDavid E. O'Brien if (cp[1] == '0') { /* print <x> or ... */ 409c80476e4SDavid E. O'Brien pdirs = 1; 410c80476e4SDavid E. O'Brien cp++; 411c80476e4SDavid E. O'Brien } 412c80476e4SDavid E. O'Brien if (cp[1] >= '1' && cp[1] <= '9') { /* calc # to skip */ 413c80476e4SDavid E. O'Brien skip = cp[1] - '0'; 414c80476e4SDavid E. O'Brien cp++; 415c80476e4SDavid E. O'Brien } 416c80476e4SDavid E. O'Brien else 417c80476e4SDavid E. O'Brien skip = 1; 418c80476e4SDavid E. O'Brien 419c80476e4SDavid E. O'Brien updirs -= skip; 420c80476e4SDavid E. O'Brien while (skip-- > 0) { 421c80476e4SDavid E. O'Brien while ((z > q) && (*z != '/')) 422c80476e4SDavid E. O'Brien z--; /* back up */ 423c80476e4SDavid E. O'Brien if (skip && z > q) 424c80476e4SDavid E. O'Brien z--; 425c80476e4SDavid E. O'Brien } 426c80476e4SDavid E. O'Brien if (*z == '/' && z != q) 427c80476e4SDavid E. O'Brien z++; 428c80476e4SDavid E. O'Brien } /* . || C */ 429c80476e4SDavid E. O'Brien 430c80476e4SDavid E. O'Brien /* print ~[user] */ 431c80476e4SDavid E. O'Brien if ((olduser) && ((Scp == '~') || 432c80476e4SDavid E. O'Brien (Scp == '.' && (pdirs || (!pdirs && updirs <= 0))) )) { 43345e5710bSMark Peek Strbuf_append1(&buf, attributes | '~'); 43445e5710bSMark Peek for (q = olduser; *q; q++) 43545e5710bSMark Peek Strbuf_append1(&buf, attributes | *q); 436c80476e4SDavid E. O'Brien } 437c80476e4SDavid E. O'Brien 438c80476e4SDavid E. O'Brien /* RWM - tell you how many dirs we've ignored */ 439c80476e4SDavid E. O'Brien /* and add '/' at front of this */ 440c80476e4SDavid E. O'Brien if (updirs > 0 && pdirs) { 441c80476e4SDavid E. O'Brien if (adrof(STRellipsis)) { 44245e5710bSMark Peek Strbuf_append1(&buf, attributes | '.'); 44345e5710bSMark Peek Strbuf_append1(&buf, attributes | '.'); 44445e5710bSMark Peek Strbuf_append1(&buf, attributes | '.'); 445c80476e4SDavid E. O'Brien } else { 44645e5710bSMark Peek Strbuf_append1(&buf, attributes | '/'); 44745e5710bSMark Peek Strbuf_append1(&buf, attributes | '<'); 448c80476e4SDavid E. O'Brien if (updirs > 9) { 44945e5710bSMark Peek Strbuf_append1(&buf, attributes | '9'); 45045e5710bSMark Peek Strbuf_append1(&buf, attributes | '+'); 451c80476e4SDavid E. O'Brien } else 45245e5710bSMark Peek Strbuf_append1(&buf, attributes | ('0' + updirs)); 45345e5710bSMark Peek Strbuf_append1(&buf, attributes | '>'); 454c80476e4SDavid E. O'Brien } 455c80476e4SDavid E. O'Brien } 456c80476e4SDavid E. O'Brien 45745e5710bSMark Peek while (*z) 45845e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 459c80476e4SDavid E. O'Brien break; 460c80476e4SDavid E. O'Brien /* lukem: end of new directory prompt code */ 461c80476e4SDavid E. O'Brien 462c80476e4SDavid E. O'Brien case 'n': 463c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP 464c80476e4SDavid E. O'Brien if (what == FMT_WHO) { 46545e5710bSMark Peek cz = who_info(info, 'n'); 46645e5710bSMark Peek tprintf_append_mbs(&buf, cz, attributes); 46745e5710bSMark Peek xfree(cz); 468c80476e4SDavid E. O'Brien } 469c80476e4SDavid E. O'Brien else 470c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */ 471c80476e4SDavid E. O'Brien { 472c80476e4SDavid E. O'Brien if ((z = varval(STRuser)) != STRNULL) 47345e5710bSMark Peek while (*z) 47445e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 475c80476e4SDavid E. O'Brien } 476c80476e4SDavid E. O'Brien break; 4779ccc37e3SMark Peek case 'N': 4789ccc37e3SMark Peek if ((z = varval(STReuser)) != STRNULL) 4799ccc37e3SMark Peek while (*z) 4809ccc37e3SMark Peek Strbuf_append1(&buf, attributes | *z++); 4819ccc37e3SMark Peek break; 482c80476e4SDavid E. O'Brien case 'l': 483c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP 484c80476e4SDavid E. O'Brien if (what == FMT_WHO) { 48545e5710bSMark Peek cz = who_info(info, 'l'); 48645e5710bSMark Peek tprintf_append_mbs(&buf, cz, attributes); 48745e5710bSMark Peek xfree(cz); 488c80476e4SDavid E. O'Brien } 489c80476e4SDavid E. O'Brien else 490c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */ 491c80476e4SDavid E. O'Brien { 492c80476e4SDavid E. O'Brien if ((z = varval(STRtty)) != STRNULL) 49345e5710bSMark Peek while (*z) 49445e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 495c80476e4SDavid E. O'Brien } 496c80476e4SDavid E. O'Brien break; 497c80476e4SDavid E. O'Brien case 'd': 49845e5710bSMark Peek tprintf_append_mbs(&buf, day_list[t->tm_wday], attributes); 499c80476e4SDavid E. O'Brien break; 500c80476e4SDavid E. O'Brien case 'D': 50145e5710bSMark Peek p = Itoa(t->tm_mday, 2, attributes); 50245e5710bSMark Peek Strbuf_append(&buf, p); 50345e5710bSMark Peek xfree(p); 504c80476e4SDavid E. O'Brien break; 505c80476e4SDavid E. O'Brien case 'w': 50645e5710bSMark Peek tprintf_append_mbs(&buf, month_list[t->tm_mon], attributes); 507c80476e4SDavid E. O'Brien break; 508c80476e4SDavid E. O'Brien case 'W': 50945e5710bSMark Peek p = Itoa(t->tm_mon + 1, 2, attributes); 51045e5710bSMark Peek Strbuf_append(&buf, p); 51145e5710bSMark Peek xfree(p); 512c80476e4SDavid E. O'Brien break; 513c80476e4SDavid E. O'Brien case 'y': 51445e5710bSMark Peek p = Itoa(t->tm_year % 100, 2, attributes); 51545e5710bSMark Peek Strbuf_append(&buf, p); 51645e5710bSMark Peek xfree(p); 517c80476e4SDavid E. O'Brien break; 518c80476e4SDavid E. O'Brien case 'Y': 51945e5710bSMark Peek p = Itoa(t->tm_year + 1900, 4, attributes); 52045e5710bSMark Peek Strbuf_append(&buf, p); 52145e5710bSMark Peek xfree(p); 522c80476e4SDavid E. O'Brien break; 523c80476e4SDavid E. O'Brien case 'S': /* start standout */ 524c80476e4SDavid E. O'Brien attributes |= STANDOUT; 525c80476e4SDavid E. O'Brien break; 526c80476e4SDavid E. O'Brien case 'B': /* start bold */ 527c80476e4SDavid E. O'Brien attributes |= BOLD; 528c80476e4SDavid E. O'Brien break; 529c80476e4SDavid E. O'Brien case 'U': /* start underline */ 530c80476e4SDavid E. O'Brien attributes |= UNDER; 531c80476e4SDavid E. O'Brien break; 532c80476e4SDavid E. O'Brien case 's': /* end standout */ 533c80476e4SDavid E. O'Brien attributes &= ~STANDOUT; 534c80476e4SDavid E. O'Brien break; 535c80476e4SDavid E. O'Brien case 'b': /* end bold */ 536c80476e4SDavid E. O'Brien attributes &= ~BOLD; 537c80476e4SDavid E. O'Brien break; 538c80476e4SDavid E. O'Brien case 'u': /* end underline */ 539c80476e4SDavid E. O'Brien attributes &= ~UNDER; 540c80476e4SDavid E. O'Brien break; 541c80476e4SDavid E. O'Brien case 'L': 542c80476e4SDavid E. O'Brien ClearToBottom(); 543c80476e4SDavid E. O'Brien break; 54429301572SMark Peek 54529301572SMark Peek case 'j': 54629301572SMark Peek { 54729301572SMark Peek int njobs = -1; 54829301572SMark Peek struct process *pp; 54945e5710bSMark Peek 55029301572SMark Peek for (pp = proclist.p_next; pp; pp = pp->p_next) 55129301572SMark Peek njobs++; 5529ccc37e3SMark Peek if (njobs == -1) 5539ccc37e3SMark Peek njobs++; 55445e5710bSMark Peek p = Itoa(njobs, 1, attributes); 55545e5710bSMark Peek Strbuf_append(&buf, p); 55645e5710bSMark Peek xfree(p); 55729301572SMark Peek break; 55829301572SMark Peek } 559c80476e4SDavid E. O'Brien case '?': 560c80476e4SDavid E. O'Brien if ((z = varval(STRstatus)) != STRNULL) 56145e5710bSMark Peek while (*z) 56245e5710bSMark Peek Strbuf_append1(&buf, attributes | *z++); 563c80476e4SDavid E. O'Brien break; 564c80476e4SDavid E. O'Brien case '$': 56545e5710bSMark Peek expdollar(&buf, &cp, attributes); 56645e5710bSMark Peek /* cp should point the last char of current % sequence */ 56729301572SMark Peek cp--; 568c80476e4SDavid E. O'Brien break; 569c80476e4SDavid E. O'Brien case '%': 57045e5710bSMark Peek Strbuf_append1(&buf, attributes | '%'); 571c80476e4SDavid E. O'Brien break; 572c80476e4SDavid E. O'Brien case '{': /* literal characters start */ 573c80476e4SDavid E. O'Brien #if LITERAL == 0 574c80476e4SDavid E. O'Brien /* 575c80476e4SDavid E. O'Brien * No literal capability, so skip all chars in the literal 576c80476e4SDavid E. O'Brien * string 577c80476e4SDavid E. O'Brien */ 57845e5710bSMark Peek while (*cp != '\0' && (cp[-1] != '%' || *cp != '}')) 579c80476e4SDavid E. O'Brien cp++; 580c80476e4SDavid E. O'Brien #endif /* LITERAL == 0 */ 581c80476e4SDavid E. O'Brien attributes |= LITERAL; 582c80476e4SDavid E. O'Brien break; 583c80476e4SDavid E. O'Brien case '}': /* literal characters end */ 584c80476e4SDavid E. O'Brien attributes &= ~LITERAL; 585c80476e4SDavid E. O'Brien break; 586c80476e4SDavid E. O'Brien default: 587c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP 588c80476e4SDavid E. O'Brien if (*cp == 'a' && what == FMT_WHO) { 58945e5710bSMark Peek cz = who_info(info, 'a'); 59045e5710bSMark Peek tprintf_append_mbs(&buf, cz, attributes); 59145e5710bSMark Peek xfree(cz); 592c80476e4SDavid E. O'Brien } 593c80476e4SDavid E. O'Brien else 594c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */ 595c80476e4SDavid E. O'Brien { 59645e5710bSMark Peek Strbuf_append1(&buf, attributes | '%'); 59745e5710bSMark Peek Strbuf_append1(&buf, attributes | *cp); 598c80476e4SDavid E. O'Brien } 599c80476e4SDavid E. O'Brien break; 600c80476e4SDavid E. O'Brien } 601c80476e4SDavid E. O'Brien } 602c80476e4SDavid E. O'Brien else if (*cp == '\\' || *cp == '^') 60345e5710bSMark Peek Strbuf_append1(&buf, attributes | parseescape(&cp)); 604c80476e4SDavid E. O'Brien else if (*cp == HIST) { /* EGS: handle '!'s in prompts */ 605c80476e4SDavid E. O'Brien if (what == FMT_HISTORY) 60645e5710bSMark Peek cz = fmthist('h', info); 607c80476e4SDavid E. O'Brien else 60845e5710bSMark Peek cz = xasprintf("%d", eventno + 1); 60945e5710bSMark Peek tprintf_append_mbs(&buf, cz, attributes); 61045e5710bSMark Peek xfree(cz); 611c80476e4SDavid E. O'Brien } 612c80476e4SDavid E. O'Brien else 61345e5710bSMark Peek Strbuf_append1(&buf, attributes | *cp); /* normal character */ 614c80476e4SDavid E. O'Brien } 61545e5710bSMark Peek cleanup_ignore(&buf); 61645e5710bSMark Peek cleanup_until(&buf); 61745e5710bSMark Peek return Strbuf_finish(&buf); 618c80476e4SDavid E. O'Brien } 619c80476e4SDavid E. O'Brien 62045e5710bSMark Peek int 62145e5710bSMark Peek expdollar(struct Strbuf *buf, const Char **srcp, Char attr) 622c80476e4SDavid E. O'Brien { 623c80476e4SDavid E. O'Brien struct varent *vp; 624c80476e4SDavid E. O'Brien const Char *src = *srcp; 62545e5710bSMark Peek Char *var, *val; 62645e5710bSMark Peek size_t i; 62745e5710bSMark Peek int curly = 0; 628c80476e4SDavid E. O'Brien 629c80476e4SDavid E. O'Brien /* found a variable, expand it */ 63045e5710bSMark Peek var = xmalloc((Strlen(src) + 1) * sizeof (*var)); 63145e5710bSMark Peek for (i = 0; ; i++) { 632c80476e4SDavid E. O'Brien var[i] = *++src & TRIM; 633c80476e4SDavid E. O'Brien if (i == 0 && var[i] == '{') { 634c80476e4SDavid E. O'Brien curly = 1; 635c80476e4SDavid E. O'Brien var[i] = *++src & TRIM; 636c80476e4SDavid E. O'Brien } 63745e5710bSMark Peek if (!alnum(var[i]) && var[i] != '_') { 638c80476e4SDavid E. O'Brien 639c80476e4SDavid E. O'Brien var[i] = '\0'; 640c80476e4SDavid E. O'Brien break; 641c80476e4SDavid E. O'Brien } 642c80476e4SDavid E. O'Brien } 643c80476e4SDavid E. O'Brien if (curly && (*src & TRIM) == '}') 644c80476e4SDavid E. O'Brien src++; 645c80476e4SDavid E. O'Brien 646c80476e4SDavid E. O'Brien vp = adrof(var); 64729301572SMark Peek if (vp && vp->vec) { 648c80476e4SDavid E. O'Brien for (i = 0; vp->vec[i] != NULL; i++) { 64945e5710bSMark Peek for (val = vp->vec[i]; *val; val++) 65045e5710bSMark Peek if (*val != '\n' && *val != '\r') 65145e5710bSMark Peek Strbuf_append1(buf, *val | attr); 65245e5710bSMark Peek if (vp->vec[i+1]) 65345e5710bSMark Peek Strbuf_append1(buf, ' ' | attr); 654c80476e4SDavid E. O'Brien } 655c80476e4SDavid E. O'Brien } 656c80476e4SDavid E. O'Brien else { 65745e5710bSMark Peek val = (!vp) ? tgetenv(var) : NULL; 65845e5710bSMark Peek if (val) { 65945e5710bSMark Peek for (; *val; val++) 66045e5710bSMark Peek if (*val != '\n' && *val != '\r') 66145e5710bSMark Peek Strbuf_append1(buf, *val | attr); 66245e5710bSMark Peek } else { 663c80476e4SDavid E. O'Brien *srcp = src; 66445e5710bSMark Peek xfree(var); 66545e5710bSMark Peek return 0; 666c80476e4SDavid E. O'Brien } 66745e5710bSMark Peek } 668c80476e4SDavid E. O'Brien 669c80476e4SDavid E. O'Brien *srcp = src; 67045e5710bSMark Peek xfree(var); 67145e5710bSMark Peek return 1; 672c80476e4SDavid E. O'Brien } 673