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
prp()60 prp()
61 {
62 if ((flags & prompt) == 0 && cmdadr) {
63 prs_cntl(cmdadr);
64 prs((unsigned char *)colon);
65 }
66 }
67
68 void
prs(unsigned char * as)69 prs(unsigned char *as)
70 {
71 if (as) {
72 write(output, as, length(as) - 1);
73 }
74 }
75
76 void
prc(unsigned char c)77 prc(unsigned char c)
78 {
79 if (c) {
80 write(output, &c, 1);
81 }
82 }
83
84 void
prwc(wchar_t c)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
prt(long t)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
prn(int n)123 prn(int n)
124 {
125 itos(n);
126
127 prs(numbuf);
128 }
129
130 void
itos(int n)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
stoi(unsigned char * icp)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
ltos(long n)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
ulltos(u_longlong_t n)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
flushb()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
prc_buff(unsigned char c)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
prs_buff(unsigned char * s)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 *
octal(unsigned char c,unsigned char * ptr)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
prs_cntl(unsigned char * s)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
prull_buff(u_longlong_t lc)309 prull_buff(u_longlong_t lc)
310 {
311 prs_buff(&numbuf[ulltos(lc)]);
312 }
313
314 void
prn_buff(int n)315 prn_buff(int n)
316 {
317 itos(n);
318
319 prs_buff(numbuf);
320 }
321
322 int
setb(int fd)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