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