diff --git a/src/lib/libc/stdlib/a64l.3 b/src/lib/libc/stdlib/a64l.3 new file mode 100644 index 00000000..5093edb5 --- /dev/null +++ b/src/lib/libc/stdlib/a64l.3 @@ -0,0 +1,125 @@ +.\" +.\" Copyright (c) 1997 Todd C. Miller +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by Todd C. Miller. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $OpenBSD: a64l.3,v 1.1 1997/08/17 22:58:33 millert Exp $ +.\" +.Dd August 17, 1997 +.Dt A64L 3 +.Os +.Sh NAME +.Nm a64l , +.Nm l64a +.Nd convert between 32-bit integer and radix-64 ASCII string +.Sh SYNOPSIS +.Fd #include +.Ft long +.Fn a64l "const char *s" +.Ft char * +.Fn l64a "long l" +.Sh DESCRIPTION +The +.Fn a64l +and +.Fn l64a +functions are used to maintain numbers stored in radix-64 +ASCII characters. This is a notation by which 32-bit integers +can be represented by up to six characters; each character +represents a "digit" in a radix-64 notation. +.Pp +The characters used to represent "digits" are '.' for 0, '/' for 1, +'0' through '9' for 2-11, 'A' through 'Z' for 12-37, and 'a' through +'z' for 38-63. +.Pp +The +.Fn a64l +function takes a pointer to a null-terminated radix-64 representation +and returns a corresponding 32-bit value. If the string pointed to by +.Ar s +contains more than six characters, +.Fn a64l +will use the first six. +.Fn A64l +scans the character string from left to right, decoding +each character as a 6-bit radix-64 number. If a long integer is +larger than 32 bits, the return value will be sign-extended. +.Pp +.Fn l64a +takes a long integer argument +.Ar l +and returns a pointer to the corresponding radix-64 representation. +.Sh RETURN VALUES +On success, +.Fn a64l +returns a 32-bit representation of +.Ar s . +If +.Ar s +is a NULL pointer or if it contains "digits" other than those described above, +.Fn a64l +returns -1L and sets the global variable errno to +.Va EINVAL . +.Pp +On success, +.Fn l64a +returns a pointer to a string containing the radix-64 representation of +.Ar l . +If +.Ar l +is 0, +.Fn l64a +returns a pointer to the empty string. +If +.Ar l +is negative, +.Fn l64a +returns a NULL pointer and sets the global variable errno to +.Va EINVAL . +.Sh WARNINGS +The value returned by +.Fn l64a +is a pointer into a static buffer, the contents of which +will be overwritten by subsequent calls. +.Pp +The value returned by +.Fn a64l +may be incorrect if the value is too large; for that reason, only strings +that resulted from a call to +.Fn l64a +should be used to call +.Fn a64l . +.Pp +If a long integer is larger than 32 bits, only the low-order +32 bits are used. +.Sh STANDARDS +The +.Fn a64l +and +.Fn l64a +functions conform to +.St -xpg4.2 . diff --git a/src/lib/libc/stdlib/a64l.c b/src/lib/libc/stdlib/a64l.c index 975e26eb..a68f0a6d 100644 --- a/src/lib/libc/stdlib/a64l.c +++ b/src/lib/libc/stdlib/a64l.c @@ -4,9 +4,12 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: a64l.c,v 1.2 1996/08/19 08:33:19 tholo Exp $"; +static char *rcsid = "$OpenBSD: a64l.c,v 1.3 1997/08/17 22:58:34 millert Exp $"; #endif /* LIBC_SCCS and not lint */ +#include +#include + long a64l(s) const char *s; @@ -14,21 +17,30 @@ a64l(s) long value, digit, shift; int i; + if (s == NULL) { + errno = EINVAL; + return(-1L); + } + value = 0; shift = 0; for (i = 0; *s && i < 6; i++, s++) { - if (*s <= '/') + if (*s >= '.' && *s <= '/') digit = *s - '.'; - else if (*s <= '9') + else if (*s >= '0' && *s <= '9') digit = *s - '0' + 2; - else if (*s <= 'Z') + else if (*s >= 'A' && *s <= 'Z') digit = *s - 'A' + 12; - else - digit = *s - 'a' + 38; + else if (*s >= 'a' && *s <= 'z') + digit = *s - 'a' + 38; + else { + errno = EINVAL; + return(-1L); + } value |= digit << shift; shift += 6; } - return (long) value; + return(value); } diff --git a/src/lib/libc/stdlib/l64a.c b/src/lib/libc/stdlib/l64a.c index 630f9e33..4e993912 100644 --- a/src/lib/libc/stdlib/l64a.c +++ b/src/lib/libc/stdlib/l64a.c @@ -4,13 +4,14 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: l64a.c,v 1.2 1996/08/19 08:33:33 tholo Exp $"; +static char *rcsid = "$OpenBSD: l64a.c,v 1.3 1997/08/17 22:58:34 millert Exp $"; #endif /* LIBC_SCCS and not lint */ +#include #include char * -l64a (value) +l64a(value) long value; { static char buf[8]; @@ -18,8 +19,10 @@ l64a (value) int digit; int i; - if (!value) - return NULL; + if (value < 0) { + errno = EINVAL; + return(NULL); + } for (i = 0; value != 0 && i < 6; i++) { digit = value & 0x3f; @@ -39,5 +42,5 @@ l64a (value) *s = '\0'; - return buf; + return(buf); }