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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 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. 13 * 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] 19 * 20 * CDDL HEADER END 21 */ 22 #ident "%Z%%M% %I% %E% SMI" 23 24 /* 25 * Copyright (c) 1996, by Sun Microsystems, Inc. 26 * All rights reserved. 27 */ 28 29 #include <stdio.h> 30 #include <ctype.h> 31 #include <sys/types.h> 32 33 /* 34 * More generic than get_u_long. Supports byte, short, long, longlong. 35 * Returns 0 for success, -1 for failure. 36 */ 37 int 38 get_number(char **src, void *dest, int len) 39 { 40 register unsigned base; 41 register char c; 42 43 if (len != 1 && (len % 2) != 0 || len > 8) 44 return (-1); /* not valid */ 45 /* 46 * Collect number up to first illegal character. Values are specified 47 * as for C: 0x=hex, 0=octal, other=decimal. 48 */ 49 base = 10; 50 if (**src == '0') { 51 base = 8; 52 (*src)++; 53 } 54 if (**src == 'x' || **src == 'X') { 55 base = 16, 56 (*src)++; 57 } 58 59 while (c = **src) { 60 if (isdigit(c)) { 61 switch (len) { 62 case 1: 63 *(u_char *) dest = 64 (*(u_char *) dest) * base + (c - '0'); 65 break; 66 case 2: 67 *(u_short *) dest = (*(u_short *) dest) * 68 base + (c - '0'); 69 break; 70 case 4: 71 *(u_long *) dest = (*(u_long *) dest) * 72 base + (c - '0'); 73 break; 74 case 8: 75 *(u_longlong_t *) dest = 76 (*(u_longlong_t *) dest) * base + 77 (c - '0'); 78 break; 79 } 80 (*src)++; 81 continue; 82 } 83 if (base == 16 && isxdigit(c)) { 84 switch (len) { 85 case 1: 86 *(u_char *) dest = 87 ((*(u_char *) dest) << 4) + ((c & ~32) + 88 10 - 'A'); 89 break; 90 case 2: 91 *(u_short *) dest = 92 ((*(u_short *) dest) << 4) + ((c & ~32) + 93 10 - 'A'); 94 break; 95 case 4: 96 *(u_long *) dest = 97 ((*(u_long *) dest) << 4) + ((c & ~32) + 98 10 - 'A'); 99 break; 100 case 8: 101 *(u_longlong_t *) dest = 102 ((*(u_longlong_t *) dest) << 4) + 103 ((c & ~32) + 10 - 'A'); 104 break; 105 } 106 (*src)++; 107 continue; 108 } 109 break; 110 } 111 return (0); 112 } 113 main() 114 { 115 char *src; 116 u_char one; 117 u_short two; 118 u_long four; 119 u_longlong_t eight; 120 121 /* 122 * Try single octet (dec) 123 */ 124 src = "a56"; 125 one = 0; 126 if (get_number(&src, (void *) &one, 1) != 0) 127 printf("byte failed.\n"); 128 else 129 printf("byte: %d\n", one); 130 131 src = "65535"; 132 two = 0; 133 if (get_number(&src, (void *) &two, 2) != 0) 134 printf("short failed.\n"); 135 else 136 printf("short: %d\n", two); 137 138 src = "4294967296"; 139 four = 0; 140 if (get_number(&src, (void *) &four, 4) != 0) 141 printf("long failed.\n"); 142 else 143 printf("long: %d\n", four); 144 145 src = "4289672944289672944"; 146 eight = 0; 147 if (get_number(&src, (void *) &eight, 8) != 0) 148 printf("longlong failed.\n"); 149 else 150 printf("longlong: %d\n", eight); 151 152 153 154 /* 155 * Try single octet (hex) 156 */ 157 src = "0xff"; 158 one = 0; 159 if (get_number(&src, (void *) &one, 1) != 0) 160 printf("byte failed.\n"); 161 else 162 printf("byte: 0x%x\n", one); 163 164 src = "0xffff"; 165 two = 0; 166 if (get_number(&src, (void *) &two, 2) != 0) 167 printf("short failed.\n"); 168 else 169 printf("short: 0x%x\n", two); 170 171 src = "0xffffffff"; 172 four = 0; 173 if (get_number(&src, (void *) &four, 4) != 0) 174 printf("long failed.\n"); 175 else 176 printf("long: 0x%x\n", four); 177 178 src = "0xffffffffffffffff"; 179 eight = 0; 180 if (get_number(&src, (void *) &eight, 8) != 0) 181 printf("longlong failed.\n"); 182 else 183 printf("longlong: 0x%x\n", eight); 184 185 /* 186 * Try single octet (Oct) 187 */ 188 src = "0376"; 189 one = 0; 190 if (get_number(&src, (void *) &one, 1) != 0) 191 printf("byte failed.\n"); 192 else 193 printf("byte: 0x%x\n", one); 194 195 src = "0177776"; 196 two = 0; 197 if (get_number(&src, (void *) &two, 2) != 0) 198 printf("short failed.\n"); 199 else 200 printf("short: 0x%x\n", two); 201 202 src = "037777777776"; 203 four = 0; 204 if (get_number(&src, (void *) &four, 4) != 0) 205 printf("long failed.\n"); 206 else 207 printf("long: 0x%x\n", four); 208 209 src = "01777777777777777777776"; 210 eight = 0; 211 if (get_number(&src, (void *) &eight, 8) != 0) 212 printf("longlong failed.\n"); 213 else 214 printf("longlong: 0x%x\n", eight); 215 return (0); 216 }