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