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