1/* 2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23#include <stdlib.h> 24#include <string.h> 25 26#include "stuff/bool.h" 27#include "stuff/allocate.h" 28#include "stuff/errors.h" 29 30/* 31 * get_version_number() converts an ascii version number string of the form: 32 * X[.Y[.Z]] 33 * to a uint32_t with the value (X << 16) | (Y << 8) | Z and does 34 * all the needed range checks. The value is indirectly returned through value 35 * and flag and argument are used for error messages. It TRUE if there were 36 * no errors FALSE otherwise. 37 */ 38__private_extern__ 39enum bool 40get_version_number( 41char *flag, 42char *argument, 43uint32_t *value) 44{ 45 char *p, *x, *y, *z, *dot, *endp; 46 uint32_t X, Y, Z; 47 48 *value = 0; 49 p = allocate(strlen(argument) + 1); 50 strcpy(p, argument); 51 52 y = NULL; 53 z = NULL; 54 55 x = p; 56 dot = strchr(x, '.'); 57 if(dot != NULL && dot[1] != '\0'){ 58 *dot = '\0'; 59 y = dot + 1; 60 dot = strchr(y, '.'); 61 if(dot != NULL && dot[1] != '\0'){ 62 *dot = '\0'; 63 z = dot + 1; 64 dot = strchr(z, '.'); 65 if(dot != NULL){ 66 *dot = '\0'; 67 } 68 } 69 } 70 71 Y = 0; 72 Z = 0; 73 74 X = strtoul(x, &endp, 10); 75 if(*endp != '\0'){ 76 error("first field (%s) in argument for: %s %s not a proper " 77 "unsigned number", x, flag, argument); 78 goto fail; 79 } 80 if(X > 0xffff){ 81 error("first field (%s) in argument for: %s %s too large (maximum " 82 "%d)", x, flag, argument, 0xffff); 83 goto fail; 84 } 85 if(y != NULL){ 86 Y = strtoul(y, &endp, 10); 87 if(*endp != '\0'){ 88 error("second field (%s) in argument for: %s %s not a proper " 89 "unsigned number", y, flag, argument); 90 goto fail; 91 } 92 if(Y > 0xff){ 93 error("second field (%s) in argument for: %s %s too large " 94 "(maximum %d)", y, flag, argument, 0xff); 95 goto fail; 96 } 97 if(z != NULL){ 98 Z = strtoul(z, &endp, 10); 99 if(*endp != '\0'){ 100 error("third field (%s) in argument for: %s %s not a " 101 "proper unsigned number", z, flag, argument); 102 goto fail; 103 } 104 if(Z > 0xff){ 105 error("third field (%s) in argument for: %s %s too large " 106 "(maximum %d)", z, flag, argument, 0xff); 107 goto fail; 108 } 109 } 110 } 111 *value = (X << 16) | (Y << 8) | Z; 112 free(p); 113 return((enum bool)TRUE); 114 115fail: 116 free(p); 117 return((enum bool)FALSE); 118} 119