7600 zfs rollback should pass target snapshot to kernel
[unleashed.git] / usr / src / cmd / bnu / stoa.c
blobd26f86f967d3ec36ce76ec971bd0f3d118979d08
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
26 #ident "%Z%%M% %I% %E% SMI" /* from SVR4 bnu:stoa.c 1.4 */
28 #include "uucp.h"
30 #ifdef TLI
32 #include <stdio.h>
33 #include <string.h>
34 #include <memory.h>
35 #include <malloc.h>
36 #include <sys/tiuser.h>
37 #include <ctype.h>
38 #define OCT 0
39 #define HEX 1
40 /* #include <nsaddr.h>
42 #define toupper(c) (islower(c) ? _toupper(c) : (c))
43 #define todigit(c) ((int)((c) - '0')) /* char to digit */
44 #define toxdigit(c) ((isdigit(c))?todigit(c):(toupper(c)-(int)'A'+10))
45 #define isodigit(c) (isdigit(c) && ((c) != '9') && ((c) != '8'))
46 #define itoac(i) (((i) > 9) ? ((char)((i)-10) + 'A'):((char)(i) + '0'))
47 #define MASK(n) ((1 << (n)) - 1)
49 #define SBUFSIZE 128
51 /* #define TRUE 1;
52 * #define FALSE 0;
55 GLOBAL char sbuf[SBUFSIZE];
57 /* local static functions */
58 static int dobase();
59 static void memcp();
60 static char *xfer();
63 stoa - convert string to address
65 If a string begins in \o or \O, the following address is octal
66 " " " " " \x or \X, the following address is hex
68 If ok, return pointer to netbuf structure.
69 A NULL is returned on any error(s).
72 GLOBAL struct netbuf *
73 stoa(str, addr) /* Return netbuf ptr if success */
74 char *str; /* Return NULL if error */
75 struct netbuf *addr;
77 int myadr; /* was netbuf struct allocated here ? */
79 myadr = FALSE;
81 if (!str)
82 return NULL;
83 while (*str && isspace(*str)) /* leading whites are OK */
84 ++str;
86 if (!str || !*str) return NULL; /* Nothing to convert */
88 if (!addr) {
89 if ((addr = (struct netbuf *)malloc(sizeof(struct netbuf))) == NULL)
90 return NULL;
91 myadr = TRUE;
92 addr->buf = NULL;
93 addr->maxlen = 0;
94 addr->len = 0;
97 /* Now process the address */
98 if (*str == '\\') {
99 ++str;
100 switch (*str) {
102 case 'X': /* hex */
103 case 'x':
104 addr->len = dobase(++str, sbuf, HEX);
105 break;
107 case 'o': /* octal */
108 case 'O':
109 addr->len = dobase(++str, sbuf, OCT);
110 break;
112 default: /* error */
113 addr->len = 0;
114 break;
118 if (addr->len == 0) { /* Error in conversion */
119 if (myadr)
120 free(addr);
121 return NULL;
123 if ((addr->buf = xfer(addr->buf, sbuf, addr->len, addr->maxlen)) == NULL)
124 return NULL;
125 else
126 return addr;
130 dobase : converts a hex or octal ASCII string
131 to a binary address. Only HEX or OCT may be used
132 for type.
133 return length of binary string (in bytes), 0 if error.
134 The binary result is placed at buf.
137 static int
138 dobase(s, buf, type) /* read in an address */
139 char *s, *buf; /* source ASCII, result binary string */
140 int type;
142 int bp = SBUFSIZE - 1;
143 int shift = 0;
144 char *end;
146 for (end = s; *end && ((type == OCT) ? isodigit(*end) :
147 isxdigit(*end)); ++end) ;
149 /* any non-white, non-digits cause address to be rejected,
150 other fields are ignored */
152 if ((*s == 0) || (end == s) || (!isspace(*end) && *end)) {
153 fprintf(stderr, "dobase: Illegal trailer on address string\n");
154 buf[0] = '\0';
155 return 0;
157 --end;
159 buf[bp] = '\0';
161 while (bp > 0 && end >= s) {
162 buf[bp] |= toxdigit(*end) << shift;
163 if (type == OCT) {
164 if (shift > 5) {
165 buf[--bp] = (todigit(*end) >> (8 - shift))
166 & MASK(shift-5);
168 if ((shift = (shift + 3) % 8) == 0)
169 buf[--bp] = 0;
171 else /* hex */
172 if ((shift = (shift) ? 0 : 4) == 0)
173 buf[--bp] = 0;;
174 --end;
176 if (bp == 0) {
177 fprintf(stderr, "stoa: dobase: number to long\n");
178 return 0;
181 /* need to catch end case to avoid extra 0's in front */
182 if (!shift)
183 bp++;
184 memcp(buf, &buf[bp], (SBUFSIZE - bp));
185 return (SBUFSIZE - bp);
188 static void
189 memcp(d, s, n) /* safe memcpy for overlapping regions */
190 char *d, *s;
191 int n;
193 while (n--)
194 *d++ = *s++;
195 return;
198 /* transfer block to a given destination or allocate one of the
199 right size
200 if max = 0 : ignore max
203 static char *
204 xfer(dest, src, len, max)
205 char *dest, *src;
206 unsigned len, max;
208 if (max && dest && max < len) { /* No room */
209 fprintf(stderr, "xfer: destination not long enough\n");
210 return NULL;
212 if (!dest)
213 if ((dest = malloc(len)) == NULL) {
214 fprintf(stderr, "xfer: malloc failed\n");
215 return NULL;
218 memcpy(dest, src, (int)len);
219 return dest;
222 #endif /* TLI */