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 }