1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 /* 32 * UNIX shell 33 * 34 */ 35 36 #include "defs.h" 37 #include <sys/param.h> 38 #include <locale.h> 39 #include <wctype.h> /* iswprint() */ 40 41 #define BUFLEN 256 42 43 unsigned char numbuf[21]; 44 45 static unsigned char buffer[BUFLEN]; 46 static unsigned char *bufp = buffer; 47 static int index = 0; 48 static int buffd = 1; 49 50 void prc_buff(unsigned char c); 51 void prs_buff(unsigned char *s); 52 void prn_buff(int n); 53 void prs_cntl(unsigned char *s); 54 void prs(unsigned char *as); 55 void itos(int n); 56 57 /* 58 * printing and io conversion 59 */ 60 void 61 prp() 62 { 63 if ((flags & prompt) == 0 && cmdadr) { 64 prs_cntl(cmdadr); 65 prs((unsigned char *)colon); 66 } 67 } 68 69 void 70 prs(unsigned char *as) 71 { 72 if (as) { 73 write(output, as, length(as) - 1); 74 } 75 } 76 77 void 78 prc(unsigned char c) 79 { 80 if (c) { 81 write(output, &c, 1); 82 } 83 } 84 85 void 86 prwc(wchar_t c) 87 { 88 char mb[MB_LEN_MAX + 1]; 89 int len; 90 91 if (c == 0) { 92 return; 93 } 94 if ((len = wctomb(mb, c)) < 0) { 95 mb[0] = (unsigned char)c; 96 len = 1; 97 } 98 write(output, mb, len); 99 } 100 101 void 102 prt(long t) 103 { 104 int hr, min, sec; 105 106 t += HZ / 2; 107 t /= HZ; 108 sec = t % 60; 109 t /= 60; 110 min = t % 60; 111 112 if ((hr = t / 60) != 0) { 113 prn_buff(hr); 114 prc_buff('h'); 115 } 116 117 prn_buff(min); 118 prc_buff('m'); 119 prn_buff(sec); 120 prc_buff('s'); 121 } 122 123 void 124 prn(int n) 125 { 126 itos(n); 127 128 prs(numbuf); 129 } 130 131 void 132 itos(int n) 133 { 134 unsigned char buf[21]; 135 unsigned char *abuf = &buf[20]; 136 int d; 137 138 *--abuf = (unsigned char)'\0'; 139 140 do { 141 *--abuf = (unsigned char)('0' + n - 10 * (d = n / 10)); 142 } while ((n = d) != 0); 143 144 strncpy(numbuf, abuf, sizeof (numbuf)); 145 } 146 147 int 148 stoi(unsigned char *icp) 149 { 150 unsigned char *cp = icp; 151 int r = 0; 152 unsigned char c; 153 154 while ((c = *cp, digit(c)) && c && r >= 0) { 155 r = r * 10 + c - '0'; 156 cp++; 157 } 158 if (r < 0 || cp == icp) { 159 failed(icp, badnum); 160 /* NOTREACHED */ 161 } else { 162 return (r); 163 } 164 } 165 166 int 167 ltos(long n) 168 { 169 int i; 170 171 numbuf[20] = '\0'; 172 for (i = 19; i >= 0; i--) { 173 numbuf[i] = n % 10 + '0'; 174 if ((n /= 10) == 0) { 175 break; 176 } 177 } 178 return (i); 179 } 180 181 static int 182 ulltos(u_longlong_t n) 183 { 184 int i; 185 186 /* The max unsigned long long is 20 characters (+1 for '\0') */ 187 numbuf[20] = '\0'; 188 for (i = 19; i >= 0; i--) { 189 numbuf[i] = n % 10 + '0'; 190 if ((n /= 10) == 0) { 191 break; 192 } 193 } 194 return (i); 195 } 196 197 void 198 flushb() 199 { 200 if (index) { 201 bufp[index] = '\0'; 202 write(buffd, bufp, length(bufp) - 1); 203 index = 0; 204 } 205 } 206 207 void 208 prc_buff(unsigned char c) 209 { 210 if (c) { 211 if (buffd != -1 && index + 1 >= BUFLEN) { 212 flushb(); 213 } 214 215 bufp[index++] = c; 216 } else { 217 flushb(); 218 write(buffd, &c, 1); 219 } 220 } 221 222 void 223 prs_buff(unsigned char *s) 224 { 225 int len = length(s) - 1; 226 227 if (buffd != -1 && index + len >= BUFLEN) { 228 flushb(); 229 } 230 231 if (buffd != -1 && len >= BUFLEN) { 232 write(buffd, s, len); 233 } else { 234 movstr(s, &bufp[index]); 235 index += len; 236 } 237 } 238 239 static unsigned char * 240 octal(unsigned char c, unsigned char *ptr) 241 { 242 *ptr++ = '\\'; 243 *ptr++ = ((unsigned int)c >> 6) + '0'; 244 *ptr++ = (((unsigned int)c >> 3) & 07) + '0'; 245 *ptr++ = (c & 07) + '0'; 246 return (ptr); 247 } 248 249 void 250 prs_cntl(unsigned char *s) 251 { 252 int n; 253 wchar_t wc; 254 unsigned char *olds = s; 255 unsigned char *ptr = bufp; 256 wchar_t c; 257 258 if ((n = mbtowc(&wc, (const char *)s, MB_LEN_MAX)) <= 0) { 259 n = 0; 260 } 261 while (n != 0) { 262 if (n < 0) { 263 ptr = octal(*s++, ptr); 264 } else { 265 c = wc; 266 s += n; 267 if (!iswprint(c)) { 268 if (c < '\040' && c > 0) { 269 /* 270 * assumes ASCII char 271 * translate a control character 272 * into a printable sequence 273 */ 274 *ptr++ = '^'; 275 *ptr++ = (c + 0100); 276 } else if (c == 0177) { 277 /* '\0177' does not work */ 278 *ptr++ = '^'; 279 *ptr++ = '?'; 280 } else { 281 /* 282 * unprintable 8-bit byte sequence 283 * assumes all legal multibyte 284 * sequences are 285 * printable 286 */ 287 ptr = octal(*olds, ptr); 288 } 289 } else { 290 while (n--) { 291 *ptr++ = *olds++; 292 } 293 } 294 } 295 if (buffd != -1 && ptr >= &bufp[BUFLEN-4]) { 296 *ptr = '\0'; 297 prs(bufp); 298 ptr = bufp; 299 } 300 olds = s; 301 if ((n = mbtowc(&wc, (const char *)s, MB_LEN_MAX)) <= 0) { 302 n = 0; 303 } 304 } 305 *ptr = '\0'; 306 prs(bufp); 307 } 308 309 void 310 prull_buff(u_longlong_t lc) 311 { 312 prs_buff(&numbuf[ulltos(lc)]); 313 } 314 315 void 316 prn_buff(int n) 317 { 318 itos(n); 319 320 prs_buff(numbuf); 321 } 322 323 int 324 setb(int fd) 325 { 326 int ofd; 327 328 if ((ofd = buffd) == -1) { 329 if (bufp+index+1 >= brkend) { 330 growstak(bufp+index+1); 331 } 332 if (bufp[index-1]) { 333 bufp[index++] = 0; 334 } 335 endstak(bufp+index); 336 } else { 337 flushb(); 338 } 339 if ((buffd = fd) == -1) { 340 bufp = locstak(); 341 } else { 342 bufp = buffer; 343 } 344 index = 0; 345 return (ofd); 346 } 347