1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate *
4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate * with the License.
8*7c478bd9Sstevel@tonic-gate *
9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate *
20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate */
26*7c478bd9Sstevel@tonic-gate
27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*7c478bd9Sstevel@tonic-gate
29*7c478bd9Sstevel@tonic-gate #include <netinet/in.h>
30*7c478bd9Sstevel@tonic-gate #include <limits.h>
31*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
32*7c478bd9Sstevel@tonic-gate #include <sys/socket.h>
33*7c478bd9Sstevel@tonic-gate
34*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_string.h>
35*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
36*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_lex.h>
37*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_debug.h>
38*7c478bd9Sstevel@tonic-gate #include <mdb/mdb.h>
39*7c478bd9Sstevel@tonic-gate
40*7c478bd9Sstevel@tonic-gate /*
41*7c478bd9Sstevel@tonic-gate * Convert the specified integer value to a string represented in the given
42*7c478bd9Sstevel@tonic-gate * base. The flags parameter is a bitfield of the formatting flags defined in
43*7c478bd9Sstevel@tonic-gate * mdb_string.h. A pointer to a static conversion buffer is returned.
44*7c478bd9Sstevel@tonic-gate */
45*7c478bd9Sstevel@tonic-gate const char *
numtostr(uintmax_t uvalue,int base,uint_t flags)46*7c478bd9Sstevel@tonic-gate numtostr(uintmax_t uvalue, int base, uint_t flags)
47*7c478bd9Sstevel@tonic-gate {
48*7c478bd9Sstevel@tonic-gate static const char ldigits[] = "0123456789abcdef";
49*7c478bd9Sstevel@tonic-gate static const char udigits[] = "0123456789ABCDEF";
50*7c478bd9Sstevel@tonic-gate
51*7c478bd9Sstevel@tonic-gate static char buf[68]; /* Enough for ULLONG_MAX in binary plus prefixes */
52*7c478bd9Sstevel@tonic-gate
53*7c478bd9Sstevel@tonic-gate const char *digits = (flags & NTOS_UPCASE) ? udigits : ldigits;
54*7c478bd9Sstevel@tonic-gate int i = sizeof (buf);
55*7c478bd9Sstevel@tonic-gate
56*7c478bd9Sstevel@tonic-gate intmax_t value = (intmax_t)uvalue;
57*7c478bd9Sstevel@tonic-gate int neg = (flags & NTOS_UNSIGNED) == 0 && value < 0;
58*7c478bd9Sstevel@tonic-gate uintmax_t rem = neg ? -value : value;
59*7c478bd9Sstevel@tonic-gate
60*7c478bd9Sstevel@tonic-gate buf[--i] = 0;
61*7c478bd9Sstevel@tonic-gate
62*7c478bd9Sstevel@tonic-gate do {
63*7c478bd9Sstevel@tonic-gate buf[--i] = digits[rem % base];
64*7c478bd9Sstevel@tonic-gate rem /= base;
65*7c478bd9Sstevel@tonic-gate } while (rem != 0);
66*7c478bd9Sstevel@tonic-gate
67*7c478bd9Sstevel@tonic-gate if (flags & NTOS_SHOWBASE) {
68*7c478bd9Sstevel@tonic-gate uintmax_t lim;
69*7c478bd9Sstevel@tonic-gate char c = 0;
70*7c478bd9Sstevel@tonic-gate
71*7c478bd9Sstevel@tonic-gate switch (base) {
72*7c478bd9Sstevel@tonic-gate case 2:
73*7c478bd9Sstevel@tonic-gate lim = 1;
74*7c478bd9Sstevel@tonic-gate c = 'i';
75*7c478bd9Sstevel@tonic-gate break;
76*7c478bd9Sstevel@tonic-gate case 8:
77*7c478bd9Sstevel@tonic-gate lim = 7;
78*7c478bd9Sstevel@tonic-gate c = 'o';
79*7c478bd9Sstevel@tonic-gate break;
80*7c478bd9Sstevel@tonic-gate case 10:
81*7c478bd9Sstevel@tonic-gate lim = 9;
82*7c478bd9Sstevel@tonic-gate c = 't';
83*7c478bd9Sstevel@tonic-gate break;
84*7c478bd9Sstevel@tonic-gate case 16:
85*7c478bd9Sstevel@tonic-gate lim = 9;
86*7c478bd9Sstevel@tonic-gate c = 'x';
87*7c478bd9Sstevel@tonic-gate break;
88*7c478bd9Sstevel@tonic-gate }
89*7c478bd9Sstevel@tonic-gate
90*7c478bd9Sstevel@tonic-gate if (c != 0 && uvalue > lim) {
91*7c478bd9Sstevel@tonic-gate buf[--i] = c;
92*7c478bd9Sstevel@tonic-gate buf[--i] = '0';
93*7c478bd9Sstevel@tonic-gate }
94*7c478bd9Sstevel@tonic-gate }
95*7c478bd9Sstevel@tonic-gate
96*7c478bd9Sstevel@tonic-gate if (neg)
97*7c478bd9Sstevel@tonic-gate buf[--i] = '-';
98*7c478bd9Sstevel@tonic-gate else if (flags & NTOS_SIGNPOS)
99*7c478bd9Sstevel@tonic-gate buf[--i] = '+';
100*7c478bd9Sstevel@tonic-gate
101*7c478bd9Sstevel@tonic-gate return ((const char *)(&buf[i]));
102*7c478bd9Sstevel@tonic-gate }
103*7c478bd9Sstevel@tonic-gate
104*7c478bd9Sstevel@tonic-gate #define CTOI(x) (((x) >= '0' && (x) <= '9') ? (x) - '0' : \
105*7c478bd9Sstevel@tonic-gate ((x) >= 'a' && (x) <= 'z') ? (x) + 10 - 'a' : (x) + 10 - 'A')
106*7c478bd9Sstevel@tonic-gate
107*7c478bd9Sstevel@tonic-gate /*
108*7c478bd9Sstevel@tonic-gate * Convert a string to an unsigned integer value using the specified base.
109*7c478bd9Sstevel@tonic-gate * In the event of overflow or an invalid character, we generate an
110*7c478bd9Sstevel@tonic-gate * error message and longjmp back to the main loop using yyerror().
111*7c478bd9Sstevel@tonic-gate */
112*7c478bd9Sstevel@tonic-gate uintmax_t
strtonum(const char * s,int base)113*7c478bd9Sstevel@tonic-gate strtonum(const char *s, int base)
114*7c478bd9Sstevel@tonic-gate {
115*7c478bd9Sstevel@tonic-gate uintmax_t multmax = (uintmax_t)ULLONG_MAX / (uintmax_t)(uint_t)base;
116*7c478bd9Sstevel@tonic-gate uintmax_t val = 0;
117*7c478bd9Sstevel@tonic-gate int c, i, neg = 0;
118*7c478bd9Sstevel@tonic-gate
119*7c478bd9Sstevel@tonic-gate switch (c = *s) {
120*7c478bd9Sstevel@tonic-gate case '-':
121*7c478bd9Sstevel@tonic-gate neg++;
122*7c478bd9Sstevel@tonic-gate /*FALLTHRU*/
123*7c478bd9Sstevel@tonic-gate case '+':
124*7c478bd9Sstevel@tonic-gate c = *++s;
125*7c478bd9Sstevel@tonic-gate }
126*7c478bd9Sstevel@tonic-gate
127*7c478bd9Sstevel@tonic-gate if (c == '\0')
128*7c478bd9Sstevel@tonic-gate goto done;
129*7c478bd9Sstevel@tonic-gate
130*7c478bd9Sstevel@tonic-gate if ((val = CTOI(c)) >= base)
131*7c478bd9Sstevel@tonic-gate yyerror("digit '%c' is invalid in current base\n", c);
132*7c478bd9Sstevel@tonic-gate
133*7c478bd9Sstevel@tonic-gate for (c = *++s; c != '\0'; c = *++s) {
134*7c478bd9Sstevel@tonic-gate if (val > multmax)
135*7c478bd9Sstevel@tonic-gate goto oflow;
136*7c478bd9Sstevel@tonic-gate
137*7c478bd9Sstevel@tonic-gate if ((i = CTOI(c)) >= base)
138*7c478bd9Sstevel@tonic-gate yyerror("digit '%c' is invalid in current base\n", c);
139*7c478bd9Sstevel@tonic-gate
140*7c478bd9Sstevel@tonic-gate val *= base;
141*7c478bd9Sstevel@tonic-gate
142*7c478bd9Sstevel@tonic-gate if ((uintmax_t)ULLONG_MAX - val < (uintmax_t)i)
143*7c478bd9Sstevel@tonic-gate goto oflow;
144*7c478bd9Sstevel@tonic-gate
145*7c478bd9Sstevel@tonic-gate val += i;
146*7c478bd9Sstevel@tonic-gate }
147*7c478bd9Sstevel@tonic-gate done:
148*7c478bd9Sstevel@tonic-gate return (neg ? -val : val);
149*7c478bd9Sstevel@tonic-gate oflow:
150*7c478bd9Sstevel@tonic-gate yyerror("specified value exceeds maximum immediate value\n");
151*7c478bd9Sstevel@tonic-gate return ((uintmax_t)ULLONG_MAX);
152*7c478bd9Sstevel@tonic-gate }
153*7c478bd9Sstevel@tonic-gate
154*7c478bd9Sstevel@tonic-gate /*
155*7c478bd9Sstevel@tonic-gate * Quick string to unsigned long conversion function. This function performs
156*7c478bd9Sstevel@tonic-gate * no overflow checking and is only meant for internal mdb use. It allows
157*7c478bd9Sstevel@tonic-gate * the caller to specify the length of the string in bytes and a base.
158*7c478bd9Sstevel@tonic-gate */
159*7c478bd9Sstevel@tonic-gate ulong_t
strntoul(const char * s,size_t nbytes,int base)160*7c478bd9Sstevel@tonic-gate strntoul(const char *s, size_t nbytes, int base)
161*7c478bd9Sstevel@tonic-gate {
162*7c478bd9Sstevel@tonic-gate ulong_t n;
163*7c478bd9Sstevel@tonic-gate int c;
164*7c478bd9Sstevel@tonic-gate
165*7c478bd9Sstevel@tonic-gate for (n = 0; nbytes != 0 && (c = *s) != '\0'; s++, nbytes--)
166*7c478bd9Sstevel@tonic-gate n = n * base + CTOI(c);
167*7c478bd9Sstevel@tonic-gate
168*7c478bd9Sstevel@tonic-gate return (n);
169*7c478bd9Sstevel@tonic-gate }
170*7c478bd9Sstevel@tonic-gate
171*7c478bd9Sstevel@tonic-gate /*
172*7c478bd9Sstevel@tonic-gate * Return a boolean value indicating whether or not a string consists
173*7c478bd9Sstevel@tonic-gate * solely of characters which are digits 0..9.
174*7c478bd9Sstevel@tonic-gate */
175*7c478bd9Sstevel@tonic-gate int
strisnum(const char * s)176*7c478bd9Sstevel@tonic-gate strisnum(const char *s)
177*7c478bd9Sstevel@tonic-gate {
178*7c478bd9Sstevel@tonic-gate for (; *s != '\0'; s++) {
179*7c478bd9Sstevel@tonic-gate if (*s < '0' || *s > '9')
180*7c478bd9Sstevel@tonic-gate return (0);
181*7c478bd9Sstevel@tonic-gate }
182*7c478bd9Sstevel@tonic-gate
183*7c478bd9Sstevel@tonic-gate return (1);
184*7c478bd9Sstevel@tonic-gate }
185*7c478bd9Sstevel@tonic-gate
186*7c478bd9Sstevel@tonic-gate /*
187*7c478bd9Sstevel@tonic-gate * Return a boolean value indicating whether or not a string contains a
188*7c478bd9Sstevel@tonic-gate * number. The number may be in the current radix, or it may have an
189*7c478bd9Sstevel@tonic-gate * explicit radix qualifier. The number will be validated against the
190*7c478bd9Sstevel@tonic-gate * legal characters for the given radix.
191*7c478bd9Sstevel@tonic-gate */
192*7c478bd9Sstevel@tonic-gate int
strisbasenum(const char * s)193*7c478bd9Sstevel@tonic-gate strisbasenum(const char *s)
194*7c478bd9Sstevel@tonic-gate {
195*7c478bd9Sstevel@tonic-gate char valid[] = "0123456789aAbBcCdDeEfF";
196*7c478bd9Sstevel@tonic-gate int radix = mdb.m_radix;
197*7c478bd9Sstevel@tonic-gate
198*7c478bd9Sstevel@tonic-gate if (s[0] == '0') {
199*7c478bd9Sstevel@tonic-gate switch (s[1]) {
200*7c478bd9Sstevel@tonic-gate case 'I':
201*7c478bd9Sstevel@tonic-gate case 'i':
202*7c478bd9Sstevel@tonic-gate radix = 2;
203*7c478bd9Sstevel@tonic-gate s += 2;
204*7c478bd9Sstevel@tonic-gate break;
205*7c478bd9Sstevel@tonic-gate case 'O':
206*7c478bd9Sstevel@tonic-gate case 'o':
207*7c478bd9Sstevel@tonic-gate radix = 8;
208*7c478bd9Sstevel@tonic-gate s += 2;
209*7c478bd9Sstevel@tonic-gate break;
210*7c478bd9Sstevel@tonic-gate case 'T':
211*7c478bd9Sstevel@tonic-gate case 't':
212*7c478bd9Sstevel@tonic-gate radix = 10;
213*7c478bd9Sstevel@tonic-gate s += 2;
214*7c478bd9Sstevel@tonic-gate break;
215*7c478bd9Sstevel@tonic-gate case 'x':
216*7c478bd9Sstevel@tonic-gate case 'X':
217*7c478bd9Sstevel@tonic-gate radix = 16;
218*7c478bd9Sstevel@tonic-gate s += 2;
219*7c478bd9Sstevel@tonic-gate break;
220*7c478bd9Sstevel@tonic-gate }
221*7c478bd9Sstevel@tonic-gate }
222*7c478bd9Sstevel@tonic-gate
223*7c478bd9Sstevel@tonic-gate /* limit `valid' to the digits valid for this base */
224*7c478bd9Sstevel@tonic-gate valid[radix > 10 ? 10 + (radix - 10) * 2 : radix] = '\0';
225*7c478bd9Sstevel@tonic-gate
226*7c478bd9Sstevel@tonic-gate do {
227*7c478bd9Sstevel@tonic-gate if (!strchr(valid, *s))
228*7c478bd9Sstevel@tonic-gate return (0);
229*7c478bd9Sstevel@tonic-gate } while (*++s != '\0');
230*7c478bd9Sstevel@tonic-gate
231*7c478bd9Sstevel@tonic-gate return (1);
232*7c478bd9Sstevel@tonic-gate }
233*7c478bd9Sstevel@tonic-gate
234*7c478bd9Sstevel@tonic-gate /*
235*7c478bd9Sstevel@tonic-gate * Quick string to integer (base 10) conversion function. This performs
236*7c478bd9Sstevel@tonic-gate * no overflow checking and is only meant for internal mdb use.
237*7c478bd9Sstevel@tonic-gate */
238*7c478bd9Sstevel@tonic-gate int
strtoi(const char * s)239*7c478bd9Sstevel@tonic-gate strtoi(const char *s)
240*7c478bd9Sstevel@tonic-gate {
241*7c478bd9Sstevel@tonic-gate int c, n;
242*7c478bd9Sstevel@tonic-gate
243*7c478bd9Sstevel@tonic-gate for (n = 0; (c = *s) >= '0' && c <= '9'; s++)
244*7c478bd9Sstevel@tonic-gate n = n * 10 + c - '0';
245*7c478bd9Sstevel@tonic-gate
246*7c478bd9Sstevel@tonic-gate return (n);
247*7c478bd9Sstevel@tonic-gate }
248*7c478bd9Sstevel@tonic-gate
249*7c478bd9Sstevel@tonic-gate /*
250*7c478bd9Sstevel@tonic-gate * Create a copy of string s using the mdb allocator interface.
251*7c478bd9Sstevel@tonic-gate */
252*7c478bd9Sstevel@tonic-gate char *
strdup(const char * s)253*7c478bd9Sstevel@tonic-gate strdup(const char *s)
254*7c478bd9Sstevel@tonic-gate {
255*7c478bd9Sstevel@tonic-gate char *s1 = mdb_alloc(strlen(s) + 1, UM_SLEEP);
256*7c478bd9Sstevel@tonic-gate
257*7c478bd9Sstevel@tonic-gate (void) strcpy(s1, s);
258*7c478bd9Sstevel@tonic-gate return (s1);
259*7c478bd9Sstevel@tonic-gate }
260*7c478bd9Sstevel@tonic-gate
261*7c478bd9Sstevel@tonic-gate /*
262*7c478bd9Sstevel@tonic-gate * Create a copy of string s, but only duplicate the first n bytes.
263*7c478bd9Sstevel@tonic-gate */
264*7c478bd9Sstevel@tonic-gate char *
strndup(const char * s,size_t n)265*7c478bd9Sstevel@tonic-gate strndup(const char *s, size_t n)
266*7c478bd9Sstevel@tonic-gate {
267*7c478bd9Sstevel@tonic-gate char *s2 = mdb_alloc(n + 1, UM_SLEEP);
268*7c478bd9Sstevel@tonic-gate
269*7c478bd9Sstevel@tonic-gate (void) strncpy(s2, s, n);
270*7c478bd9Sstevel@tonic-gate s2[n] = '\0';
271*7c478bd9Sstevel@tonic-gate return (s2);
272*7c478bd9Sstevel@tonic-gate }
273*7c478bd9Sstevel@tonic-gate
274*7c478bd9Sstevel@tonic-gate /*
275*7c478bd9Sstevel@tonic-gate * Convenience routine for freeing strings.
276*7c478bd9Sstevel@tonic-gate */
277*7c478bd9Sstevel@tonic-gate void
strfree(char * s)278*7c478bd9Sstevel@tonic-gate strfree(char *s)
279*7c478bd9Sstevel@tonic-gate {
280*7c478bd9Sstevel@tonic-gate mdb_free(s, strlen(s) + 1);
281*7c478bd9Sstevel@tonic-gate }
282*7c478bd9Sstevel@tonic-gate
283*7c478bd9Sstevel@tonic-gate /*
284*7c478bd9Sstevel@tonic-gate * Transform string s inline, converting each embedded C escape sequence string
285*7c478bd9Sstevel@tonic-gate * to the corresponding character. For example, the substring "\n" is replaced
286*7c478bd9Sstevel@tonic-gate * by an inline '\n' character. The length of the resulting string is returned.
287*7c478bd9Sstevel@tonic-gate */
288*7c478bd9Sstevel@tonic-gate size_t
stresc2chr(char * s)289*7c478bd9Sstevel@tonic-gate stresc2chr(char *s)
290*7c478bd9Sstevel@tonic-gate {
291*7c478bd9Sstevel@tonic-gate char *p, *q, c;
292*7c478bd9Sstevel@tonic-gate int esc = 0;
293*7c478bd9Sstevel@tonic-gate
294*7c478bd9Sstevel@tonic-gate for (p = q = s; (c = *p) != '\0'; p++) {
295*7c478bd9Sstevel@tonic-gate if (esc) {
296*7c478bd9Sstevel@tonic-gate switch (c) {
297*7c478bd9Sstevel@tonic-gate case '0':
298*7c478bd9Sstevel@tonic-gate case '1':
299*7c478bd9Sstevel@tonic-gate case '2':
300*7c478bd9Sstevel@tonic-gate case '3':
301*7c478bd9Sstevel@tonic-gate case '4':
302*7c478bd9Sstevel@tonic-gate case '5':
303*7c478bd9Sstevel@tonic-gate case '6':
304*7c478bd9Sstevel@tonic-gate case '7':
305*7c478bd9Sstevel@tonic-gate c -= '0';
306*7c478bd9Sstevel@tonic-gate p++;
307*7c478bd9Sstevel@tonic-gate
308*7c478bd9Sstevel@tonic-gate if (*p >= '0' && *p <= '7') {
309*7c478bd9Sstevel@tonic-gate c = c * 8 + *p++ - '0';
310*7c478bd9Sstevel@tonic-gate
311*7c478bd9Sstevel@tonic-gate if (*p >= '0' && *p <= '7')
312*7c478bd9Sstevel@tonic-gate c = c * 8 + *p - '0';
313*7c478bd9Sstevel@tonic-gate else
314*7c478bd9Sstevel@tonic-gate p--;
315*7c478bd9Sstevel@tonic-gate } else
316*7c478bd9Sstevel@tonic-gate p--;
317*7c478bd9Sstevel@tonic-gate
318*7c478bd9Sstevel@tonic-gate *q++ = c;
319*7c478bd9Sstevel@tonic-gate break;
320*7c478bd9Sstevel@tonic-gate
321*7c478bd9Sstevel@tonic-gate case 'a':
322*7c478bd9Sstevel@tonic-gate *q++ = '\a';
323*7c478bd9Sstevel@tonic-gate break;
324*7c478bd9Sstevel@tonic-gate case 'b':
325*7c478bd9Sstevel@tonic-gate *q++ = '\b';
326*7c478bd9Sstevel@tonic-gate break;
327*7c478bd9Sstevel@tonic-gate case 'f':
328*7c478bd9Sstevel@tonic-gate *q++ = '\f';
329*7c478bd9Sstevel@tonic-gate break;
330*7c478bd9Sstevel@tonic-gate case 'n':
331*7c478bd9Sstevel@tonic-gate *q++ = '\n';
332*7c478bd9Sstevel@tonic-gate break;
333*7c478bd9Sstevel@tonic-gate case 'r':
334*7c478bd9Sstevel@tonic-gate *q++ = '\r';
335*7c478bd9Sstevel@tonic-gate break;
336*7c478bd9Sstevel@tonic-gate case 't':
337*7c478bd9Sstevel@tonic-gate *q++ = '\t';
338*7c478bd9Sstevel@tonic-gate break;
339*7c478bd9Sstevel@tonic-gate case 'v':
340*7c478bd9Sstevel@tonic-gate *q++ = '\v';
341*7c478bd9Sstevel@tonic-gate break;
342*7c478bd9Sstevel@tonic-gate case '"':
343*7c478bd9Sstevel@tonic-gate case '\\':
344*7c478bd9Sstevel@tonic-gate *q++ = c;
345*7c478bd9Sstevel@tonic-gate break;
346*7c478bd9Sstevel@tonic-gate default:
347*7c478bd9Sstevel@tonic-gate *q++ = '\\';
348*7c478bd9Sstevel@tonic-gate *q++ = c;
349*7c478bd9Sstevel@tonic-gate }
350*7c478bd9Sstevel@tonic-gate
351*7c478bd9Sstevel@tonic-gate esc = 0;
352*7c478bd9Sstevel@tonic-gate
353*7c478bd9Sstevel@tonic-gate } else {
354*7c478bd9Sstevel@tonic-gate if ((esc = c == '\\') == 0)
355*7c478bd9Sstevel@tonic-gate *q++ = c;
356*7c478bd9Sstevel@tonic-gate }
357*7c478bd9Sstevel@tonic-gate }
358*7c478bd9Sstevel@tonic-gate
359*7c478bd9Sstevel@tonic-gate *q = '\0';
360*7c478bd9Sstevel@tonic-gate return ((size_t)(q - s));
361*7c478bd9Sstevel@tonic-gate }
362*7c478bd9Sstevel@tonic-gate
363*7c478bd9Sstevel@tonic-gate /*
364*7c478bd9Sstevel@tonic-gate * Create a copy of string s in which certain unprintable or special characters
365*7c478bd9Sstevel@tonic-gate * have been converted to the string representation of their C escape sequence.
366*7c478bd9Sstevel@tonic-gate * For example, the newline character is expanded to the string "\n".
367*7c478bd9Sstevel@tonic-gate */
368*7c478bd9Sstevel@tonic-gate char *
strchr2esc(const char * s,size_t n)369*7c478bd9Sstevel@tonic-gate strchr2esc(const char *s, size_t n)
370*7c478bd9Sstevel@tonic-gate {
371*7c478bd9Sstevel@tonic-gate const char *p;
372*7c478bd9Sstevel@tonic-gate char *q, *s2, c;
373*7c478bd9Sstevel@tonic-gate size_t addl = 0;
374*7c478bd9Sstevel@tonic-gate
375*7c478bd9Sstevel@tonic-gate for (p = s; p < s + n; p++) {
376*7c478bd9Sstevel@tonic-gate switch (c = *p) {
377*7c478bd9Sstevel@tonic-gate case '\0':
378*7c478bd9Sstevel@tonic-gate case '\a':
379*7c478bd9Sstevel@tonic-gate case '\b':
380*7c478bd9Sstevel@tonic-gate case '\f':
381*7c478bd9Sstevel@tonic-gate case '\n':
382*7c478bd9Sstevel@tonic-gate case '\r':
383*7c478bd9Sstevel@tonic-gate case '\t':
384*7c478bd9Sstevel@tonic-gate case '\v':
385*7c478bd9Sstevel@tonic-gate case '"':
386*7c478bd9Sstevel@tonic-gate case '\\':
387*7c478bd9Sstevel@tonic-gate addl++; /* 1 add'l char needed to follow \ */
388*7c478bd9Sstevel@tonic-gate break;
389*7c478bd9Sstevel@tonic-gate case ' ':
390*7c478bd9Sstevel@tonic-gate break;
391*7c478bd9Sstevel@tonic-gate default:
392*7c478bd9Sstevel@tonic-gate if (c < '!' || c > '~')
393*7c478bd9Sstevel@tonic-gate addl += 3; /* 3 add'l chars following \ */
394*7c478bd9Sstevel@tonic-gate }
395*7c478bd9Sstevel@tonic-gate }
396*7c478bd9Sstevel@tonic-gate
397*7c478bd9Sstevel@tonic-gate s2 = mdb_alloc(n + addl + 1, UM_SLEEP);
398*7c478bd9Sstevel@tonic-gate
399*7c478bd9Sstevel@tonic-gate for (p = s, q = s2; p < s + n; p++) {
400*7c478bd9Sstevel@tonic-gate switch (c = *p) {
401*7c478bd9Sstevel@tonic-gate case '\0':
402*7c478bd9Sstevel@tonic-gate *q++ = '\\';
403*7c478bd9Sstevel@tonic-gate *q++ = '0';
404*7c478bd9Sstevel@tonic-gate break;
405*7c478bd9Sstevel@tonic-gate case '\a':
406*7c478bd9Sstevel@tonic-gate *q++ = '\\';
407*7c478bd9Sstevel@tonic-gate *q++ = 'a';
408*7c478bd9Sstevel@tonic-gate break;
409*7c478bd9Sstevel@tonic-gate case '\b':
410*7c478bd9Sstevel@tonic-gate *q++ = '\\';
411*7c478bd9Sstevel@tonic-gate *q++ = 'b';
412*7c478bd9Sstevel@tonic-gate break;
413*7c478bd9Sstevel@tonic-gate case '\f':
414*7c478bd9Sstevel@tonic-gate *q++ = '\\';
415*7c478bd9Sstevel@tonic-gate *q++ = 'f';
416*7c478bd9Sstevel@tonic-gate break;
417*7c478bd9Sstevel@tonic-gate case '\n':
418*7c478bd9Sstevel@tonic-gate *q++ = '\\';
419*7c478bd9Sstevel@tonic-gate *q++ = 'n';
420*7c478bd9Sstevel@tonic-gate break;
421*7c478bd9Sstevel@tonic-gate case '\r':
422*7c478bd9Sstevel@tonic-gate *q++ = '\\';
423*7c478bd9Sstevel@tonic-gate *q++ = 'r';
424*7c478bd9Sstevel@tonic-gate break;
425*7c478bd9Sstevel@tonic-gate case '\t':
426*7c478bd9Sstevel@tonic-gate *q++ = '\\';
427*7c478bd9Sstevel@tonic-gate *q++ = 't';
428*7c478bd9Sstevel@tonic-gate break;
429*7c478bd9Sstevel@tonic-gate case '\v':
430*7c478bd9Sstevel@tonic-gate *q++ = '\\';
431*7c478bd9Sstevel@tonic-gate *q++ = 'v';
432*7c478bd9Sstevel@tonic-gate break;
433*7c478bd9Sstevel@tonic-gate case '"':
434*7c478bd9Sstevel@tonic-gate *q++ = '\\';
435*7c478bd9Sstevel@tonic-gate *q++ = '"';
436*7c478bd9Sstevel@tonic-gate break;
437*7c478bd9Sstevel@tonic-gate case '\\':
438*7c478bd9Sstevel@tonic-gate *q++ = '\\';
439*7c478bd9Sstevel@tonic-gate *q++ = '\\';
440*7c478bd9Sstevel@tonic-gate break;
441*7c478bd9Sstevel@tonic-gate case ' ':
442*7c478bd9Sstevel@tonic-gate *q++ = c;
443*7c478bd9Sstevel@tonic-gate break;
444*7c478bd9Sstevel@tonic-gate default:
445*7c478bd9Sstevel@tonic-gate if (c < '!' || c > '~') {
446*7c478bd9Sstevel@tonic-gate *q++ = '\\';
447*7c478bd9Sstevel@tonic-gate *q++ = ((c >> 6) & 3) + '0';
448*7c478bd9Sstevel@tonic-gate *q++ = ((c >> 3) & 7) + '0';
449*7c478bd9Sstevel@tonic-gate *q++ = (c & 7) + '0';
450*7c478bd9Sstevel@tonic-gate } else
451*7c478bd9Sstevel@tonic-gate *q++ = c;
452*7c478bd9Sstevel@tonic-gate }
453*7c478bd9Sstevel@tonic-gate }
454*7c478bd9Sstevel@tonic-gate
455*7c478bd9Sstevel@tonic-gate *q = '\0';
456*7c478bd9Sstevel@tonic-gate return (s2);
457*7c478bd9Sstevel@tonic-gate }
458*7c478bd9Sstevel@tonic-gate
459*7c478bd9Sstevel@tonic-gate /*
460*7c478bd9Sstevel@tonic-gate * Create a copy of string s in which certain unprintable or special characters
461*7c478bd9Sstevel@tonic-gate * have been converted to an odd representation of their escape sequence.
462*7c478bd9Sstevel@tonic-gate * This algorithm is the old adb convention for representing such sequences.
463*7c478bd9Sstevel@tonic-gate */
464*7c478bd9Sstevel@tonic-gate char *
strchr2adb(const char * s,size_t n)465*7c478bd9Sstevel@tonic-gate strchr2adb(const char *s, size_t n)
466*7c478bd9Sstevel@tonic-gate {
467*7c478bd9Sstevel@tonic-gate size_t addl = 0;
468*7c478bd9Sstevel@tonic-gate const char *p;
469*7c478bd9Sstevel@tonic-gate char *q, *s2;
470*7c478bd9Sstevel@tonic-gate
471*7c478bd9Sstevel@tonic-gate for (p = s; p < s + n; p++) {
472*7c478bd9Sstevel@tonic-gate char c = *p & CHAR_MAX;
473*7c478bd9Sstevel@tonic-gate
474*7c478bd9Sstevel@tonic-gate if (c < ' ' || c == CHAR_MAX)
475*7c478bd9Sstevel@tonic-gate addl++; /* 1 add'l char needed for "^" */
476*7c478bd9Sstevel@tonic-gate }
477*7c478bd9Sstevel@tonic-gate
478*7c478bd9Sstevel@tonic-gate s2 = mdb_alloc(n + addl + 1, UM_SLEEP);
479*7c478bd9Sstevel@tonic-gate
480*7c478bd9Sstevel@tonic-gate for (p = s, q = s2; p < s + n; p++) {
481*7c478bd9Sstevel@tonic-gate char c = *p & CHAR_MAX;
482*7c478bd9Sstevel@tonic-gate
483*7c478bd9Sstevel@tonic-gate if (c == CHAR_MAX) {
484*7c478bd9Sstevel@tonic-gate *q++ = '^';
485*7c478bd9Sstevel@tonic-gate *q++ = '?';
486*7c478bd9Sstevel@tonic-gate } else if (c < ' ') {
487*7c478bd9Sstevel@tonic-gate *q++ = '^';
488*7c478bd9Sstevel@tonic-gate *q++ = c + '@';
489*7c478bd9Sstevel@tonic-gate } else
490*7c478bd9Sstevel@tonic-gate *q++ = c;
491*7c478bd9Sstevel@tonic-gate }
492*7c478bd9Sstevel@tonic-gate
493*7c478bd9Sstevel@tonic-gate *q = '\0';
494*7c478bd9Sstevel@tonic-gate return (s2);
495*7c478bd9Sstevel@tonic-gate }
496*7c478bd9Sstevel@tonic-gate
497*7c478bd9Sstevel@tonic-gate /*
498*7c478bd9Sstevel@tonic-gate * Same as strchr, but we only search the first n characters
499*7c478bd9Sstevel@tonic-gate */
500*7c478bd9Sstevel@tonic-gate char *
strnchr(const char * s,int c,size_t n)501*7c478bd9Sstevel@tonic-gate strnchr(const char *s, int c, size_t n)
502*7c478bd9Sstevel@tonic-gate {
503*7c478bd9Sstevel@tonic-gate int i = 0;
504*7c478bd9Sstevel@tonic-gate
505*7c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) {
506*7c478bd9Sstevel@tonic-gate if (*(s + i) == (char)c)
507*7c478bd9Sstevel@tonic-gate return ((char *)(s + i));
508*7c478bd9Sstevel@tonic-gate }
509*7c478bd9Sstevel@tonic-gate
510*7c478bd9Sstevel@tonic-gate return (NULL);
511*7c478bd9Sstevel@tonic-gate }
512*7c478bd9Sstevel@tonic-gate
513*7c478bd9Sstevel@tonic-gate /*
514*7c478bd9Sstevel@tonic-gate * Split the string s at the first occurrence of character c. This character
515*7c478bd9Sstevel@tonic-gate * is replaced by \0, and a pointer to the remainder of the string is returned.
516*7c478bd9Sstevel@tonic-gate */
517*7c478bd9Sstevel@tonic-gate char *
strsplit(char * s,char c)518*7c478bd9Sstevel@tonic-gate strsplit(char *s, char c)
519*7c478bd9Sstevel@tonic-gate {
520*7c478bd9Sstevel@tonic-gate char *p;
521*7c478bd9Sstevel@tonic-gate
522*7c478bd9Sstevel@tonic-gate if ((p = strchr(s, c)) == NULL)
523*7c478bd9Sstevel@tonic-gate return (NULL);
524*7c478bd9Sstevel@tonic-gate
525*7c478bd9Sstevel@tonic-gate *p++ = '\0';
526*7c478bd9Sstevel@tonic-gate return (p);
527*7c478bd9Sstevel@tonic-gate }
528*7c478bd9Sstevel@tonic-gate
529*7c478bd9Sstevel@tonic-gate /*
530*7c478bd9Sstevel@tonic-gate * Same as strsplit, but split from the last occurrence of character c.
531*7c478bd9Sstevel@tonic-gate */
532*7c478bd9Sstevel@tonic-gate char *
strrsplit(char * s,char c)533*7c478bd9Sstevel@tonic-gate strrsplit(char *s, char c)
534*7c478bd9Sstevel@tonic-gate {
535*7c478bd9Sstevel@tonic-gate char *p;
536*7c478bd9Sstevel@tonic-gate
537*7c478bd9Sstevel@tonic-gate if ((p = strrchr(s, c)) == NULL)
538*7c478bd9Sstevel@tonic-gate return (NULL);
539*7c478bd9Sstevel@tonic-gate
540*7c478bd9Sstevel@tonic-gate *p++ = '\0';
541*7c478bd9Sstevel@tonic-gate return (p);
542*7c478bd9Sstevel@tonic-gate }
543*7c478bd9Sstevel@tonic-gate
544*7c478bd9Sstevel@tonic-gate /*
545*7c478bd9Sstevel@tonic-gate * Return the address of the first occurrence of any character from s2
546*7c478bd9Sstevel@tonic-gate * in the string s1, or NULL if none exists. This is similar to libc's
547*7c478bd9Sstevel@tonic-gate * strpbrk, but we add a third parameter to limit the search to the
548*7c478bd9Sstevel@tonic-gate * specified number of bytes in s1, or a \0 character, whichever is
549*7c478bd9Sstevel@tonic-gate * encountered first.
550*7c478bd9Sstevel@tonic-gate */
551*7c478bd9Sstevel@tonic-gate const char *
strnpbrk(const char * s1,const char * s2,size_t nbytes)552*7c478bd9Sstevel@tonic-gate strnpbrk(const char *s1, const char *s2, size_t nbytes)
553*7c478bd9Sstevel@tonic-gate {
554*7c478bd9Sstevel@tonic-gate const char *p;
555*7c478bd9Sstevel@tonic-gate
556*7c478bd9Sstevel@tonic-gate if (nbytes == 0)
557*7c478bd9Sstevel@tonic-gate return (NULL);
558*7c478bd9Sstevel@tonic-gate
559*7c478bd9Sstevel@tonic-gate do {
560*7c478bd9Sstevel@tonic-gate for (p = s2; *p != '\0' && *p != *s1; p++)
561*7c478bd9Sstevel@tonic-gate continue;
562*7c478bd9Sstevel@tonic-gate
563*7c478bd9Sstevel@tonic-gate if (*p != '\0')
564*7c478bd9Sstevel@tonic-gate return (s1);
565*7c478bd9Sstevel@tonic-gate
566*7c478bd9Sstevel@tonic-gate } while (--nbytes != 0 && *s1++ != '\0');
567*7c478bd9Sstevel@tonic-gate
568*7c478bd9Sstevel@tonic-gate return (NULL);
569*7c478bd9Sstevel@tonic-gate }
570*7c478bd9Sstevel@tonic-gate
571*7c478bd9Sstevel@tonic-gate /*
572*7c478bd9Sstevel@tonic-gate * Abbreviate a string if it meets or exceeds the specified length, including
573*7c478bd9Sstevel@tonic-gate * the terminating null character. The string is abbreviated by replacing the
574*7c478bd9Sstevel@tonic-gate * last four characters with " ...". strabbr is useful in constructs such as
575*7c478bd9Sstevel@tonic-gate * this one, where nbytes = sizeof (buf):
576*7c478bd9Sstevel@tonic-gate *
577*7c478bd9Sstevel@tonic-gate * if (mdb_snprintf(buf, nbytes, "%s %d %c", ...) >= nbytes)
578*7c478bd9Sstevel@tonic-gate * (void) strabbr(buf, nbytes);
579*7c478bd9Sstevel@tonic-gate *
580*7c478bd9Sstevel@tonic-gate * No modifications are made if nbytes is too small to hold the suffix itself.
581*7c478bd9Sstevel@tonic-gate */
582*7c478bd9Sstevel@tonic-gate char *
strabbr(char * s,size_t nbytes)583*7c478bd9Sstevel@tonic-gate strabbr(char *s, size_t nbytes)
584*7c478bd9Sstevel@tonic-gate {
585*7c478bd9Sstevel@tonic-gate static const char suffix[] = " ...";
586*7c478bd9Sstevel@tonic-gate
587*7c478bd9Sstevel@tonic-gate if (nbytes > sizeof (suffix) && strlen(s) >= nbytes - 1)
588*7c478bd9Sstevel@tonic-gate (void) strcpy(&s[nbytes - sizeof (suffix)], suffix);
589*7c478bd9Sstevel@tonic-gate
590*7c478bd9Sstevel@tonic-gate return (s);
591*7c478bd9Sstevel@tonic-gate }
592*7c478bd9Sstevel@tonic-gate
593*7c478bd9Sstevel@tonic-gate /*
594*7c478bd9Sstevel@tonic-gate * Return the basename (name after final /) of the given string. We use
595*7c478bd9Sstevel@tonic-gate * strbasename rather than basename to avoid conflicting with libgen.h's
596*7c478bd9Sstevel@tonic-gate * non-const function prototype.
597*7c478bd9Sstevel@tonic-gate */
598*7c478bd9Sstevel@tonic-gate const char *
strbasename(const char * s)599*7c478bd9Sstevel@tonic-gate strbasename(const char *s)
600*7c478bd9Sstevel@tonic-gate {
601*7c478bd9Sstevel@tonic-gate const char *p = strrchr(s, '/');
602*7c478bd9Sstevel@tonic-gate
603*7c478bd9Sstevel@tonic-gate if (p == NULL)
604*7c478bd9Sstevel@tonic-gate return (s);
605*7c478bd9Sstevel@tonic-gate
606*7c478bd9Sstevel@tonic-gate return (++p);
607*7c478bd9Sstevel@tonic-gate }
608*7c478bd9Sstevel@tonic-gate
609*7c478bd9Sstevel@tonic-gate /*
610*7c478bd9Sstevel@tonic-gate * Return the directory name (name prior to the final /) of the given string.
611*7c478bd9Sstevel@tonic-gate * The string itself is modified.
612*7c478bd9Sstevel@tonic-gate */
613*7c478bd9Sstevel@tonic-gate char *
strdirname(char * s)614*7c478bd9Sstevel@tonic-gate strdirname(char *s)
615*7c478bd9Sstevel@tonic-gate {
616*7c478bd9Sstevel@tonic-gate static char slash[] = "/";
617*7c478bd9Sstevel@tonic-gate static char dot[] = ".";
618*7c478bd9Sstevel@tonic-gate char *p;
619*7c478bd9Sstevel@tonic-gate
620*7c478bd9Sstevel@tonic-gate if (s == NULL || *s == '\0')
621*7c478bd9Sstevel@tonic-gate return (dot);
622*7c478bd9Sstevel@tonic-gate
623*7c478bd9Sstevel@tonic-gate for (p = s + strlen(s); p != s && *--p == '/'; )
624*7c478bd9Sstevel@tonic-gate continue;
625*7c478bd9Sstevel@tonic-gate
626*7c478bd9Sstevel@tonic-gate if (p == s && *p == '/')
627*7c478bd9Sstevel@tonic-gate return (slash);
628*7c478bd9Sstevel@tonic-gate
629*7c478bd9Sstevel@tonic-gate while (p != s) {
630*7c478bd9Sstevel@tonic-gate if (*--p == '/') {
631*7c478bd9Sstevel@tonic-gate while (*p == '/' && p != s)
632*7c478bd9Sstevel@tonic-gate p--;
633*7c478bd9Sstevel@tonic-gate *++p = '\0';
634*7c478bd9Sstevel@tonic-gate return (s);
635*7c478bd9Sstevel@tonic-gate }
636*7c478bd9Sstevel@tonic-gate }
637*7c478bd9Sstevel@tonic-gate
638*7c478bd9Sstevel@tonic-gate return (dot);
639*7c478bd9Sstevel@tonic-gate }
640*7c478bd9Sstevel@tonic-gate
641*7c478bd9Sstevel@tonic-gate /*
642*7c478bd9Sstevel@tonic-gate * Return a pointer to the first character in the string that makes it an
643*7c478bd9Sstevel@tonic-gate * invalid identifer (i.e. incompatible with the mdb syntax), or NULL if
644*7c478bd9Sstevel@tonic-gate * the string is a valid identifier.
645*7c478bd9Sstevel@tonic-gate */
646*7c478bd9Sstevel@tonic-gate const char *
strbadid(const char * s)647*7c478bd9Sstevel@tonic-gate strbadid(const char *s)
648*7c478bd9Sstevel@tonic-gate {
649*7c478bd9Sstevel@tonic-gate return (strpbrk(s, "#%^&*-+=,:$/\\?<>;|!`'\"[]\n\t() {}"));
650*7c478bd9Sstevel@tonic-gate }
651*7c478bd9Sstevel@tonic-gate
652*7c478bd9Sstevel@tonic-gate /*
653*7c478bd9Sstevel@tonic-gate * Return a boolean value indicating if the given string consists solely
654*7c478bd9Sstevel@tonic-gate * of printable ASCII characters terminated by \0.
655*7c478bd9Sstevel@tonic-gate */
656*7c478bd9Sstevel@tonic-gate int
strisprint(const char * s)657*7c478bd9Sstevel@tonic-gate strisprint(const char *s)
658*7c478bd9Sstevel@tonic-gate {
659*7c478bd9Sstevel@tonic-gate for (; *s != '\0'; s++) {
660*7c478bd9Sstevel@tonic-gate if (*s < ' ' || *s > '~')
661*7c478bd9Sstevel@tonic-gate return (0);
662*7c478bd9Sstevel@tonic-gate }
663*7c478bd9Sstevel@tonic-gate
664*7c478bd9Sstevel@tonic-gate return (1);
665*7c478bd9Sstevel@tonic-gate }
666*7c478bd9Sstevel@tonic-gate
667*7c478bd9Sstevel@tonic-gate /*
668*7c478bd9Sstevel@tonic-gate * This is a near direct copy of the inet_ntop() code in
669*7c478bd9Sstevel@tonic-gate * uts/common/inet/ip/ipv6.c, duplicated here for kmdb's sake.
670*7c478bd9Sstevel@tonic-gate */
671*7c478bd9Sstevel@tonic-gate static void
convert2ascii(char * buf,const in6_addr_t * addr)672*7c478bd9Sstevel@tonic-gate convert2ascii(char *buf, const in6_addr_t *addr)
673*7c478bd9Sstevel@tonic-gate {
674*7c478bd9Sstevel@tonic-gate int hexdigits;
675*7c478bd9Sstevel@tonic-gate int head_zero = 0;
676*7c478bd9Sstevel@tonic-gate int tail_zero = 0;
677*7c478bd9Sstevel@tonic-gate /* tempbuf must be big enough to hold ffff:\0 */
678*7c478bd9Sstevel@tonic-gate char tempbuf[6];
679*7c478bd9Sstevel@tonic-gate char *ptr;
680*7c478bd9Sstevel@tonic-gate uint16_t *addr_component, host_component;
681*7c478bd9Sstevel@tonic-gate size_t len;
682*7c478bd9Sstevel@tonic-gate int first = FALSE;
683*7c478bd9Sstevel@tonic-gate int med_zero = FALSE;
684*7c478bd9Sstevel@tonic-gate int end_zero = FALSE;
685*7c478bd9Sstevel@tonic-gate
686*7c478bd9Sstevel@tonic-gate addr_component = (uint16_t *)addr;
687*7c478bd9Sstevel@tonic-gate ptr = buf;
688*7c478bd9Sstevel@tonic-gate
689*7c478bd9Sstevel@tonic-gate /* First count if trailing zeroes higher in number */
690*7c478bd9Sstevel@tonic-gate for (hexdigits = 0; hexdigits < 8; hexdigits++) {
691*7c478bd9Sstevel@tonic-gate if (*addr_component == 0) {
692*7c478bd9Sstevel@tonic-gate if (hexdigits < 4)
693*7c478bd9Sstevel@tonic-gate head_zero++;
694*7c478bd9Sstevel@tonic-gate else
695*7c478bd9Sstevel@tonic-gate tail_zero++;
696*7c478bd9Sstevel@tonic-gate }
697*7c478bd9Sstevel@tonic-gate addr_component++;
698*7c478bd9Sstevel@tonic-gate }
699*7c478bd9Sstevel@tonic-gate addr_component = (uint16_t *)addr;
700*7c478bd9Sstevel@tonic-gate if (tail_zero > head_zero && (head_zero + tail_zero) != 7)
701*7c478bd9Sstevel@tonic-gate end_zero = TRUE;
702*7c478bd9Sstevel@tonic-gate
703*7c478bd9Sstevel@tonic-gate for (hexdigits = 0; hexdigits < 8; hexdigits++) {
704*7c478bd9Sstevel@tonic-gate /* if entry is a 0 */
705*7c478bd9Sstevel@tonic-gate if (*addr_component == 0) {
706*7c478bd9Sstevel@tonic-gate if (!first && *(addr_component + 1) == 0) {
707*7c478bd9Sstevel@tonic-gate if (end_zero && (hexdigits < 4)) {
708*7c478bd9Sstevel@tonic-gate *ptr++ = '0';
709*7c478bd9Sstevel@tonic-gate *ptr++ = ':';
710*7c478bd9Sstevel@tonic-gate } else {
711*7c478bd9Sstevel@tonic-gate if (hexdigits == 0)
712*7c478bd9Sstevel@tonic-gate *ptr++ = ':';
713*7c478bd9Sstevel@tonic-gate /* add another */
714*7c478bd9Sstevel@tonic-gate *ptr++ = ':';
715*7c478bd9Sstevel@tonic-gate first = TRUE;
716*7c478bd9Sstevel@tonic-gate med_zero = TRUE;
717*7c478bd9Sstevel@tonic-gate }
718*7c478bd9Sstevel@tonic-gate } else if (first && med_zero) {
719*7c478bd9Sstevel@tonic-gate if (hexdigits == 7)
720*7c478bd9Sstevel@tonic-gate *ptr++ = ':';
721*7c478bd9Sstevel@tonic-gate addr_component++;
722*7c478bd9Sstevel@tonic-gate continue;
723*7c478bd9Sstevel@tonic-gate } else {
724*7c478bd9Sstevel@tonic-gate *ptr++ = '0';
725*7c478bd9Sstevel@tonic-gate *ptr++ = ':';
726*7c478bd9Sstevel@tonic-gate }
727*7c478bd9Sstevel@tonic-gate addr_component++;
728*7c478bd9Sstevel@tonic-gate continue;
729*7c478bd9Sstevel@tonic-gate }
730*7c478bd9Sstevel@tonic-gate if (med_zero)
731*7c478bd9Sstevel@tonic-gate med_zero = FALSE;
732*7c478bd9Sstevel@tonic-gate
733*7c478bd9Sstevel@tonic-gate tempbuf[0] = '\0';
734*7c478bd9Sstevel@tonic-gate mdb_nhconvert(&host_component, addr_component,
735*7c478bd9Sstevel@tonic-gate sizeof (uint16_t));
736*7c478bd9Sstevel@tonic-gate (void) mdb_snprintf(tempbuf, sizeof (tempbuf), "%x:",
737*7c478bd9Sstevel@tonic-gate host_component & 0xffff);
738*7c478bd9Sstevel@tonic-gate len = strlen(tempbuf);
739*7c478bd9Sstevel@tonic-gate bcopy(tempbuf, ptr, len);
740*7c478bd9Sstevel@tonic-gate ptr = ptr + len;
741*7c478bd9Sstevel@tonic-gate addr_component++;
742*7c478bd9Sstevel@tonic-gate }
743*7c478bd9Sstevel@tonic-gate *--ptr = '\0';
744*7c478bd9Sstevel@tonic-gate }
745*7c478bd9Sstevel@tonic-gate
746*7c478bd9Sstevel@tonic-gate char *
mdb_inet_ntop(int af,const void * addr,char * buf,size_t buflen)747*7c478bd9Sstevel@tonic-gate mdb_inet_ntop(int af, const void *addr, char *buf, size_t buflen)
748*7c478bd9Sstevel@tonic-gate {
749*7c478bd9Sstevel@tonic-gate in6_addr_t *v6addr;
750*7c478bd9Sstevel@tonic-gate uchar_t *v4addr;
751*7c478bd9Sstevel@tonic-gate char *caddr;
752*7c478bd9Sstevel@tonic-gate
753*7c478bd9Sstevel@tonic-gate #define UC(b) (((int)b) & 0xff)
754*7c478bd9Sstevel@tonic-gate switch (af) {
755*7c478bd9Sstevel@tonic-gate case AF_INET:
756*7c478bd9Sstevel@tonic-gate ASSERT(buflen >= INET_ADDRSTRLEN);
757*7c478bd9Sstevel@tonic-gate v4addr = (uchar_t *)addr;
758*7c478bd9Sstevel@tonic-gate (void) mdb_snprintf(buf, buflen, "%d.%d.%d.%d",
759*7c478bd9Sstevel@tonic-gate UC(v4addr[0]), UC(v4addr[1]), UC(v4addr[2]), UC(v4addr[3]));
760*7c478bd9Sstevel@tonic-gate return (buf);
761*7c478bd9Sstevel@tonic-gate
762*7c478bd9Sstevel@tonic-gate case AF_INET6:
763*7c478bd9Sstevel@tonic-gate ASSERT(buflen >= INET6_ADDRSTRLEN);
764*7c478bd9Sstevel@tonic-gate v6addr = (in6_addr_t *)addr;
765*7c478bd9Sstevel@tonic-gate if (IN6_IS_ADDR_V4MAPPED(v6addr)) {
766*7c478bd9Sstevel@tonic-gate caddr = (char *)addr;
767*7c478bd9Sstevel@tonic-gate (void) mdb_snprintf(buf, buflen, "::ffff:%d.%d.%d.%d",
768*7c478bd9Sstevel@tonic-gate UC(caddr[12]), UC(caddr[13]),
769*7c478bd9Sstevel@tonic-gate UC(caddr[14]), UC(caddr[15]));
770*7c478bd9Sstevel@tonic-gate } else if (IN6_IS_ADDR_V4COMPAT(v6addr)) {
771*7c478bd9Sstevel@tonic-gate caddr = (char *)addr;
772*7c478bd9Sstevel@tonic-gate (void) mdb_snprintf(buf, buflen, "::%d.%d.%d.%d",
773*7c478bd9Sstevel@tonic-gate UC(caddr[12]), UC(caddr[13]), UC(caddr[14]),
774*7c478bd9Sstevel@tonic-gate UC(caddr[15]));
775*7c478bd9Sstevel@tonic-gate } else if (IN6_IS_ADDR_UNSPECIFIED(v6addr)) {
776*7c478bd9Sstevel@tonic-gate (void) mdb_snprintf(buf, buflen, "::");
777*7c478bd9Sstevel@tonic-gate } else {
778*7c478bd9Sstevel@tonic-gate convert2ascii(buf, v6addr);
779*7c478bd9Sstevel@tonic-gate }
780*7c478bd9Sstevel@tonic-gate return (buf);
781*7c478bd9Sstevel@tonic-gate }
782*7c478bd9Sstevel@tonic-gate #undef UC
783*7c478bd9Sstevel@tonic-gate
784*7c478bd9Sstevel@tonic-gate return (NULL);
785*7c478bd9Sstevel@tonic-gate }
786