17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*39e7390aSna195498 * Common Development and Distribution License (the "License"). 6*39e7390aSna195498 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21*39e7390aSna195498 22*39e7390aSna195498 /* 23*39e7390aSna195498 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*39e7390aSna195498 * Use is subject to license terms. 25*39e7390aSna195498 */ 26*39e7390aSna195498 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 30*39e7390aSna195498 #pragma ident "%Z%%M% %I% %E% SMI" 317c478bd9Sstevel@tonic-gate /* 327c478bd9Sstevel@tonic-gate * UNIX shell 337c478bd9Sstevel@tonic-gate * 347c478bd9Sstevel@tonic-gate */ 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include "defs.h" 377c478bd9Sstevel@tonic-gate #include <sys/param.h> 387c478bd9Sstevel@tonic-gate #include <locale.h> 397c478bd9Sstevel@tonic-gate #include <wctype.h> /* iswprint() */ 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate #define BUFLEN 256 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate unsigned char numbuf[21]; 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate static unsigned char buffer[BUFLEN]; 467c478bd9Sstevel@tonic-gate static unsigned char *bufp = buffer; 477c478bd9Sstevel@tonic-gate static int index = 0; 487c478bd9Sstevel@tonic-gate static int buffd = 1; 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate void prc_buff(unsigned char c); 517c478bd9Sstevel@tonic-gate void prs_buff(unsigned char *s); 527c478bd9Sstevel@tonic-gate void prn_buff(int n); 537c478bd9Sstevel@tonic-gate void prs_cntl(unsigned char *s); 547c478bd9Sstevel@tonic-gate void prs(unsigned char *as); 557c478bd9Sstevel@tonic-gate void itos(int n); 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate /* 587c478bd9Sstevel@tonic-gate * printing and io conversion 597c478bd9Sstevel@tonic-gate */ 607c478bd9Sstevel@tonic-gate void 617c478bd9Sstevel@tonic-gate prp() 627c478bd9Sstevel@tonic-gate { 637c478bd9Sstevel@tonic-gate if ((flags & prompt) == 0 && cmdadr) { 647c478bd9Sstevel@tonic-gate prs_cntl(cmdadr); 657c478bd9Sstevel@tonic-gate prs((unsigned char *)colon); 667c478bd9Sstevel@tonic-gate } 677c478bd9Sstevel@tonic-gate } 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate void 707c478bd9Sstevel@tonic-gate prs(unsigned char *as) 717c478bd9Sstevel@tonic-gate { 72*39e7390aSna195498 if (as) { 73*39e7390aSna195498 write(output, as, length(as) - 1); 747c478bd9Sstevel@tonic-gate } 757c478bd9Sstevel@tonic-gate } 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate void 787c478bd9Sstevel@tonic-gate prc(unsigned char c) 797c478bd9Sstevel@tonic-gate { 807c478bd9Sstevel@tonic-gate if (c) { 817c478bd9Sstevel@tonic-gate write(output, &c, 1); 827c478bd9Sstevel@tonic-gate } 837c478bd9Sstevel@tonic-gate } 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate void 867c478bd9Sstevel@tonic-gate prwc(wchar_t c) 877c478bd9Sstevel@tonic-gate { 887c478bd9Sstevel@tonic-gate char mb[MB_LEN_MAX + 1]; 897c478bd9Sstevel@tonic-gate int len; 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate if (c == 0) { 927c478bd9Sstevel@tonic-gate return; 937c478bd9Sstevel@tonic-gate } 947c478bd9Sstevel@tonic-gate if ((len = wctomb(mb, c)) < 0) { 957c478bd9Sstevel@tonic-gate mb[0] = (unsigned char)c; 967c478bd9Sstevel@tonic-gate len = 1; 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate write(output, mb, len); 997c478bd9Sstevel@tonic-gate } 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate void 1027c478bd9Sstevel@tonic-gate prt(long t) 1037c478bd9Sstevel@tonic-gate { 1047c478bd9Sstevel@tonic-gate int hr, min, sec; 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate t += HZ / 2; 1077c478bd9Sstevel@tonic-gate t /= HZ; 1087c478bd9Sstevel@tonic-gate sec = t % 60; 1097c478bd9Sstevel@tonic-gate t /= 60; 1107c478bd9Sstevel@tonic-gate min = t % 60; 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate if ((hr = t / 60) != 0) { 1137c478bd9Sstevel@tonic-gate prn_buff(hr); 1147c478bd9Sstevel@tonic-gate prc_buff('h'); 1157c478bd9Sstevel@tonic-gate } 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate prn_buff(min); 1187c478bd9Sstevel@tonic-gate prc_buff('m'); 1197c478bd9Sstevel@tonic-gate prn_buff(sec); 1207c478bd9Sstevel@tonic-gate prc_buff('s'); 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate void 1247c478bd9Sstevel@tonic-gate prn(int n) 1257c478bd9Sstevel@tonic-gate { 1267c478bd9Sstevel@tonic-gate itos(n); 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate prs(numbuf); 1297c478bd9Sstevel@tonic-gate } 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate void 1327c478bd9Sstevel@tonic-gate itos(int n) 1337c478bd9Sstevel@tonic-gate { 1347c478bd9Sstevel@tonic-gate unsigned char buf[21]; 1357c478bd9Sstevel@tonic-gate unsigned char *abuf = &buf[20]; 1367c478bd9Sstevel@tonic-gate int d; 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate *--abuf = (unsigned char)'\0'; 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate do { 1417c478bd9Sstevel@tonic-gate *--abuf = (unsigned char)('0' + n - 10 * (d = n / 10)); 1427c478bd9Sstevel@tonic-gate } while ((n = d) != 0); 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate strncpy(numbuf, abuf, sizeof (numbuf)); 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate int 1487c478bd9Sstevel@tonic-gate stoi(unsigned char *icp) 1497c478bd9Sstevel@tonic-gate { 1507c478bd9Sstevel@tonic-gate unsigned char *cp = icp; 1517c478bd9Sstevel@tonic-gate int r = 0; 1527c478bd9Sstevel@tonic-gate unsigned char c; 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate while ((c = *cp, digit(c)) && c && r >= 0) { 1557c478bd9Sstevel@tonic-gate r = r * 10 + c - '0'; 1567c478bd9Sstevel@tonic-gate cp++; 1577c478bd9Sstevel@tonic-gate } 1587c478bd9Sstevel@tonic-gate if (r < 0 || cp == icp) { 1597c478bd9Sstevel@tonic-gate failed(icp, badnum); 160*39e7390aSna195498 /* NOTREACHED */ 1617c478bd9Sstevel@tonic-gate } else { 1627c478bd9Sstevel@tonic-gate return (r); 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate int 1677c478bd9Sstevel@tonic-gate ltos(long n) 1687c478bd9Sstevel@tonic-gate { 1697c478bd9Sstevel@tonic-gate int i; 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate numbuf[20] = '\0'; 1727c478bd9Sstevel@tonic-gate for (i = 19; i >= 0; i--) { 1737c478bd9Sstevel@tonic-gate numbuf[i] = n % 10 + '0'; 1747c478bd9Sstevel@tonic-gate if ((n /= 10) == 0) { 1757c478bd9Sstevel@tonic-gate break; 1767c478bd9Sstevel@tonic-gate } 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate return (i); 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate 181*39e7390aSna195498 static int 1827c478bd9Sstevel@tonic-gate ulltos(u_longlong_t n) 1837c478bd9Sstevel@tonic-gate { 1847c478bd9Sstevel@tonic-gate int i; 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate /* The max unsigned long long is 20 characters (+1 for '\0') */ 1877c478bd9Sstevel@tonic-gate numbuf[20] = '\0'; 1887c478bd9Sstevel@tonic-gate for (i = 19; i >= 0; i--) { 1897c478bd9Sstevel@tonic-gate numbuf[i] = n % 10 + '0'; 1907c478bd9Sstevel@tonic-gate if ((n /= 10) == 0) { 1917c478bd9Sstevel@tonic-gate break; 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate } 1947c478bd9Sstevel@tonic-gate return (i); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate void 1987c478bd9Sstevel@tonic-gate flushb() 1997c478bd9Sstevel@tonic-gate { 2007c478bd9Sstevel@tonic-gate if (index) { 2017c478bd9Sstevel@tonic-gate bufp[index] = '\0'; 2027c478bd9Sstevel@tonic-gate write(buffd, bufp, length(bufp) - 1); 2037c478bd9Sstevel@tonic-gate index = 0; 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate void 2087c478bd9Sstevel@tonic-gate prc_buff(unsigned char c) 2097c478bd9Sstevel@tonic-gate { 2107c478bd9Sstevel@tonic-gate if (c) { 2117c478bd9Sstevel@tonic-gate if (buffd != -1 && index + 1 >= BUFLEN) { 2127c478bd9Sstevel@tonic-gate flushb(); 2137c478bd9Sstevel@tonic-gate } 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate bufp[index++] = c; 2167c478bd9Sstevel@tonic-gate } else { 2177c478bd9Sstevel@tonic-gate flushb(); 2187c478bd9Sstevel@tonic-gate write(buffd, &c, 1); 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate void 2237c478bd9Sstevel@tonic-gate prs_buff(unsigned char *s) 2247c478bd9Sstevel@tonic-gate { 225*39e7390aSna195498 int len = length(s) - 1; 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate if (buffd != -1 && index + len >= BUFLEN) { 2287c478bd9Sstevel@tonic-gate flushb(); 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate if (buffd != -1 && len >= BUFLEN) { 232*39e7390aSna195498 write(buffd, s, len); 2337c478bd9Sstevel@tonic-gate } else { 234*39e7390aSna195498 movstr(s, &bufp[index]); 2357c478bd9Sstevel@tonic-gate index += len; 2367c478bd9Sstevel@tonic-gate } 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate 239*39e7390aSna195498 static unsigned char * 2407c478bd9Sstevel@tonic-gate octal(unsigned char c, unsigned char *ptr) 2417c478bd9Sstevel@tonic-gate { 2427c478bd9Sstevel@tonic-gate *ptr++ = '\\'; 2437c478bd9Sstevel@tonic-gate *ptr++ = ((unsigned int)c >> 6) + '0'; 2447c478bd9Sstevel@tonic-gate *ptr++ = (((unsigned int)c >> 3) & 07) + '0'; 2457c478bd9Sstevel@tonic-gate *ptr++ = (c & 07) + '0'; 2467c478bd9Sstevel@tonic-gate return (ptr); 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate void 2507c478bd9Sstevel@tonic-gate prs_cntl(unsigned char *s) 2517c478bd9Sstevel@tonic-gate { 2527c478bd9Sstevel@tonic-gate int n; 2537c478bd9Sstevel@tonic-gate wchar_t wc; 2547c478bd9Sstevel@tonic-gate unsigned char *olds = s; 2557c478bd9Sstevel@tonic-gate unsigned char *ptr = bufp; 2567c478bd9Sstevel@tonic-gate wchar_t c; 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate if ((n = mbtowc(&wc, (const char *)s, MB_LEN_MAX)) <= 0) { 2597c478bd9Sstevel@tonic-gate n = 0; 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate while (n != 0) { 2627c478bd9Sstevel@tonic-gate if (n < 0) { 2637c478bd9Sstevel@tonic-gate ptr = octal(*s++, ptr); 2647c478bd9Sstevel@tonic-gate } else { 2657c478bd9Sstevel@tonic-gate c = wc; 2667c478bd9Sstevel@tonic-gate s += n; 2677c478bd9Sstevel@tonic-gate if (!iswprint(c)) { 2687c478bd9Sstevel@tonic-gate if (c < '\040' && c > 0) { 2697c478bd9Sstevel@tonic-gate /* 2707c478bd9Sstevel@tonic-gate * assumes ASCII char 2717c478bd9Sstevel@tonic-gate * translate a control character 2727c478bd9Sstevel@tonic-gate * into a printable sequence 2737c478bd9Sstevel@tonic-gate */ 2747c478bd9Sstevel@tonic-gate *ptr++ = '^'; 2757c478bd9Sstevel@tonic-gate *ptr++ = (c + 0100); 2767c478bd9Sstevel@tonic-gate } else if (c == 0177) { 2777c478bd9Sstevel@tonic-gate /* '\0177' does not work */ 2787c478bd9Sstevel@tonic-gate *ptr++ = '^'; 2797c478bd9Sstevel@tonic-gate *ptr++ = '?'; 2807c478bd9Sstevel@tonic-gate } else { 2817c478bd9Sstevel@tonic-gate /* 2827c478bd9Sstevel@tonic-gate * unprintable 8-bit byte sequence 2837c478bd9Sstevel@tonic-gate * assumes all legal multibyte 2847c478bd9Sstevel@tonic-gate * sequences are 2857c478bd9Sstevel@tonic-gate * printable 2867c478bd9Sstevel@tonic-gate */ 2877c478bd9Sstevel@tonic-gate ptr = octal(*olds, ptr); 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate } else { 2907c478bd9Sstevel@tonic-gate while (n--) { 2917c478bd9Sstevel@tonic-gate *ptr++ = *olds++; 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate } 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate if (buffd != -1 && ptr >= &bufp[BUFLEN-4]) { 2967c478bd9Sstevel@tonic-gate *ptr = '\0'; 2977c478bd9Sstevel@tonic-gate prs(bufp); 2987c478bd9Sstevel@tonic-gate ptr = bufp; 2997c478bd9Sstevel@tonic-gate } 3007c478bd9Sstevel@tonic-gate olds = s; 3017c478bd9Sstevel@tonic-gate if ((n = mbtowc(&wc, (const char *)s, MB_LEN_MAX)) <= 0) { 3027c478bd9Sstevel@tonic-gate n = 0; 3037c478bd9Sstevel@tonic-gate } 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate *ptr = '\0'; 3067c478bd9Sstevel@tonic-gate prs(bufp); 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate void 3107c478bd9Sstevel@tonic-gate prull_buff(u_longlong_t lc) 3117c478bd9Sstevel@tonic-gate { 3127c478bd9Sstevel@tonic-gate prs_buff(&numbuf[ulltos(lc)]); 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate void 3167c478bd9Sstevel@tonic-gate prn_buff(int n) 3177c478bd9Sstevel@tonic-gate { 3187c478bd9Sstevel@tonic-gate itos(n); 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate prs_buff(numbuf); 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate int 3247c478bd9Sstevel@tonic-gate setb(int fd) 3257c478bd9Sstevel@tonic-gate { 3267c478bd9Sstevel@tonic-gate int ofd; 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate if ((ofd = buffd) == -1) { 3297c478bd9Sstevel@tonic-gate if (bufp+index+1 >= brkend) { 3307c478bd9Sstevel@tonic-gate growstak(bufp+index+1); 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate if (bufp[index-1]) { 3337c478bd9Sstevel@tonic-gate bufp[index++] = 0; 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate endstak(bufp+index); 3367c478bd9Sstevel@tonic-gate } else { 3377c478bd9Sstevel@tonic-gate flushb(); 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate if ((buffd = fd) == -1) { 3407c478bd9Sstevel@tonic-gate bufp = locstak(); 3417c478bd9Sstevel@tonic-gate } else { 3427c478bd9Sstevel@tonic-gate bufp = buffer; 3437c478bd9Sstevel@tonic-gate } 3447c478bd9Sstevel@tonic-gate index = 0; 3457c478bd9Sstevel@tonic-gate return (ofd); 3467c478bd9Sstevel@tonic-gate } 347