/* * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #include #include #include "stuff/bool.h" #include "stuff/allocate.h" #include "stuff/errors.h" /* * get_version_number() converts an ascii version number string of the form: * X[.Y[.Z]] * to a uint32_t with the value (X << 16) | (Y << 8) | Z and does * all the needed range checks. The value is indirectly returned through value * and flag and argument are used for error messages. It TRUE if there were * no errors FALSE otherwise. */ __private_extern__ enum bool get_version_number( char *flag, char *argument, uint32_t *value) { char *p, *x, *y, *z, *dot, *endp; uint32_t X, Y, Z; *value = 0; p = allocate(strlen(argument) + 1); strcpy(p, argument); y = NULL; z = NULL; x = p; dot = strchr(x, '.'); if(dot != NULL && dot[1] != '\0'){ *dot = '\0'; y = dot + 1; dot = strchr(y, '.'); if(dot != NULL && dot[1] != '\0'){ *dot = '\0'; z = dot + 1; dot = strchr(z, '.'); if(dot != NULL){ *dot = '\0'; } } } Y = 0; Z = 0; X = strtoul(x, &endp, 10); if(*endp != '\0'){ error("first field (%s) in argument for: %s %s not a proper " "unsigned number", x, flag, argument); goto fail; } if(X > 0xffff){ error("first field (%s) in argument for: %s %s too large (maximum " "%d)", x, flag, argument, 0xffff); goto fail; } if(y != NULL){ Y = strtoul(y, &endp, 10); if(*endp != '\0'){ error("second field (%s) in argument for: %s %s not a proper " "unsigned number", y, flag, argument); goto fail; } if(Y > 0xff){ error("second field (%s) in argument for: %s %s too large " "(maximum %d)", y, flag, argument, 0xff); goto fail; } if(z != NULL){ Z = strtoul(z, &endp, 10); if(*endp != '\0'){ error("third field (%s) in argument for: %s %s not a " "proper unsigned number", z, flag, argument); goto fail; } if(Z > 0xff){ error("third field (%s) in argument for: %s %s too large " "(maximum %d)", z, flag, argument, 0xff); goto fail; } } } *value = (X << 16) | (Y << 8) | Z; free(p); return((enum bool)TRUE); fail: free(p); return((enum bool)FALSE); }