154359Sroberto/*
254359Sroberto * hextolfp - convert an ascii hex string to an l_fp number
354359Sroberto */
4290000Sglebius#include <config.h>
554359Sroberto#include <stdio.h>
654359Sroberto#include <ctype.h>
754359Sroberto
854359Sroberto#include "ntp_fp.h"
954359Sroberto#include "ntp_string.h"
1054359Sroberto#include "ntp_stdlib.h"
1154359Sroberto
1254359Srobertoint
1354359Srobertohextolfp(
1454359Sroberto	const char *str,
1554359Sroberto	l_fp *lfp
1654359Sroberto	)
1754359Sroberto{
1854359Sroberto	register const char *cp;
1954359Sroberto	register const char *cpstart;
2054359Sroberto	register u_long dec_i;
2154359Sroberto	register u_long dec_f;
2254359Sroberto	char *ind = NULL;
2354359Sroberto	static const char *digits = "0123456789abcdefABCDEF";
2454359Sroberto
2554359Sroberto	dec_i = dec_f = 0;
2654359Sroberto	cp = str;
2754359Sroberto
2854359Sroberto	/*
2954359Sroberto	 * We understand numbers of the form:
3054359Sroberto	 *
3154359Sroberto	 * [spaces]8_hex_digits[.]8_hex_digits[spaces|\n|\0]
3254359Sroberto	 */
33290000Sglebius	while (isspace((unsigned char)*cp))
3454359Sroberto	    cp++;
3554359Sroberto
3654359Sroberto	cpstart = cp;
3754359Sroberto	while (*cp != '\0' && (cp - cpstart) < 8 &&
3854359Sroberto	       (ind = strchr(digits, *cp)) != NULL) {
3954359Sroberto		dec_i = dec_i << 4;	/* multiply by 16 */
40293894Sglebius		dec_i += ((ind - digits) > 15)
41293894Sglebius			? (u_long)(ind - digits - 6)
42293894Sglebius			: (u_long)(ind - digits);
4354359Sroberto		cp++;
4454359Sroberto	}
4554359Sroberto
4654359Sroberto	if ((cp - cpstart) < 8 || ind == NULL)
4754359Sroberto	    return 0;
4854359Sroberto	if (*cp == '.')
4954359Sroberto	    cp++;
5054359Sroberto
5154359Sroberto	cpstart = cp;
5254359Sroberto	while (*cp != '\0' && (cp - cpstart) < 8 &&
5354359Sroberto	       (ind = strchr(digits, *cp)) != NULL) {
5454359Sroberto		dec_f = dec_f << 4;	/* multiply by 16 */
55293894Sglebius		dec_f += ((ind - digits) > 15)
56293894Sglebius			? (u_long)(ind - digits - 6)
57293894Sglebius			: (u_long)(ind - digits);
5854359Sroberto		cp++;
5954359Sroberto	}
6054359Sroberto
6154359Sroberto	if ((cp - cpstart) < 8 || ind == NULL)
6254359Sroberto	    return 0;
6354359Sroberto
64290000Sglebius	if (*cp != '\0' && !isspace((unsigned char)*cp))
6554359Sroberto	    return 0;
6654359Sroberto
6754359Sroberto	lfp->l_ui = dec_i;
6854359Sroberto	lfp->l_uf = dec_f;
6954359Sroberto	return 1;
7054359Sroberto}
71