Files
2026-08-07 17:38:18 +09:00

585 lines
10 KiB
C

/*
* Copyright (C) 1998 Nikos Mavroyanopoulos
* Copyright (C) 1999,2000 Sascha Schumman, Nikos Mavroyanopoulos
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
$Id: stdfns.c,v 1.2 2006/01/10 03:47:18 imipak Exp $
*/
#include "libdefs.h"
/**
* Some of these are wrappers. The idea is to eventually produce an extremely
* lightweight set of robust, portable functions that are guaranteed to produce
* a "safe" result, even with bogus inputs. We can't trust native C libraries
* to validate inputs.
*/
WIN32DLL_DEFINE
int mutils_mlock(__const void *addr, __const mutils_word32 len)
{
int ret;
if ((addr == NULL) || (len == 0))
{
ret = -1;
errno = EINVAL;
}
#if defined(HAVE_MLOCK)
ret = mlock(addr, len);
#endif
return(ret);
}
WIN32DLL_DEFINE
int mutils_munlock(__const void *addr, __const mutils_word32 len)
{
int ret;
if ((addr == NULL) || (len == 0))
{
ret = -1;
errno = EINVAL;
}
#if defined(HAVE_MLOCK)
ret = munlock(addr, len);
#endif
return(ret);
}
/*
* NOTE: In order for memory locking to be useful, we need our own malloc
* implementation, as we cannot guarantee that the system-supplied one will
* let us know how much memory has been malloc()'ed. For much the same reason,
* neither free() nor realloc() can zero safely. This allows the potential
* leakage of information.
*/
WIN32DLL_DEFINE
void *
mutils_malloc(__const mutils_word32 n)
{
void *ptr;
if (n == 0)
{
return(NULL);
}
ptr = malloc(n);
if (ptr != NULL)
{
mutils_bzero(ptr, n);
}
return(ptr);
}
WIN32DLL_DEFINE
void *
mutils_realloc(__const void *ptr, __const mutils_word32 n)
{
void *ptrOut;
if ((ptr == NULL) && (n > 0))
{
ptrOut = mutils_malloc(n);
}
else
{
if ((ptr != NULL) && (n == 0))
{
mutils_free(ptr);
ptrOut = NULL;
}
else
{
ptrOut = realloc((void *) ptr, n);
}
}
return(ptrOut);
}
WIN32DLL_DEFINE
void
mutils_free(__const void *ptr)
{
if (ptr == NULL)
{
return;
}
free((void *) ptr);
return;
}
WIN32DLL_DEFINE
void
mutils_bzero(void *s, __const mutils_word32 n)
{
mutils_word8 *stmp = (mutils_word8 *) s;
mutils_word32 i;
if ((s == NULL) || (n == 0))
{
return;
}
for (i = 0; i < n; i++, stmp++)
{
*stmp = '\0';
}
}
WIN32DLL_DEFINE
void
mutils_memset(void *s, __const mutils_word8 c, __const mutils_word32 n)
{
#if defined(sparc)
/* Sparc needs 8-bit alignment - just use standard memset */
memset(s, (int) c, (size_t) n);
#else
mutils_word8 *stmp;
mutils_word32 *ltmp = (mutils_word32 *) s;
mutils_word32 lump;
mutils_word32 i;
mutils_word32 words;
mutils_word32 remainder;
if ((s == NULL) || (n == 0))
{
return;
}
lump = (c << 24) + (c << 16) + (c << 8) + c;
words = n >> 2;
remainder = n - (words << 2);
for (i = 0; i < words; i++, ltmp++)
{
*ltmp = lump;
}
stmp = (mutils_word8 *) ltmp;
for (i = 0; i < remainder; i++, stmp++)
{
*stmp = c;
}
#endif
}
static void
mutils_memcpy8(mutils_word8 *p_dest, __const mutils_word8 *p_src,
__const mutils_word32 n)
{
mutils_word32 i;
for (i = 0; i < n; i++)
{
*p_dest++ = *p_src++;
}
}
WIN32DLL_DEFINE
void
mutils_memcpy(void *dest, __const void *src, __const mutils_word32 n)
{
mutils_word8 *ptr1;
mutils_word8 *ptr2;
mutils_word32 *bigptr1;
mutils_word32 *bigptr2;
mutils_word32 i;
mutils_word32 words;
mutils_word32 remainder;
if ((dest == NULL) || (src == NULL) || (n == 0))
{
return;
}
ptr1 = (mutils_word8 *)src;
ptr2 = dest;
/* copy byte-by-byte for small and/or unaligned copies */
if ((n < 16) || ((mutils_word32)ptr1 & 0x3) || ((mutils_word32)ptr2
& 0x3))
{
mutils_memcpy8(ptr2, ptr1, n);
return;
}
words = n >> 2;
remainder = n - (words << 2);
bigptr1 = (mutils_word32 *) dest;
bigptr2 = (mutils_word32 *) src;
for (i = 0; i < words; i ++, bigptr1++, bigptr2++)
{
*bigptr1 = *bigptr2;
}
ptr1 = (mutils_word8 *) bigptr1;
ptr2 = (mutils_word8 *) bigptr2;
for (i = 0; i < remainder; i++, ptr1++, ptr2++)
{
*ptr1 = *ptr2;
}
}
/*
* If the system ordering is big-endian, convert to little-endian format.
* In both cases, the data is held in a temporary workspace that will be
* overwritten the next time this function is called. This function is
* deprecated and should NOT be called in new code. The ordering macros
* should be used instead, for all single-word conversions.
*/
WIN32DLL_DEFINE
mutils_word32
mutils_word32swap(mutils_word32 x)
{
static mutils_word32 value;
value = mutils_lend32(x);
return(value);
}
/*
* Byte swap a series of 32-bit integers. If destructive is set to false, the
* output will be placed in a freshly malloc()'ed buffer and the original
* data will remain intact.
*/
WIN32DLL_DEFINE
mutils_word32 *
mutils_word32nswap(mutils_word32 *x, mutils_word32 n, mutils_boolean destructive)
{
mutils_word32 loop;
mutils_word32 *buffer;
mutils_word32 *ptrIn;
mutils_word32 *ptrOut;
mutils_word32 count = n * 4;
if (destructive == MUTILS_FALSE)
{
buffer = mutils_malloc(count);
if (buffer == NULL)
{
return(NULL);
}
}
else
{
buffer = x;
}
/*
* This loop is totally useless for destructive processing of little-endian
* data on a little-endian machine.
*/
for (loop = 0, ptrIn = x, ptrOut = buffer; loop < n; loop++, ptrOut++, ptrIn++)
{
*ptrOut = mutils_lend32(*ptrIn);
}
return(buffer);
}
WIN32DLL_DEFINE
void
mutils_memmove(void *dest, __const void *src, const mutils_word32 n)
{
mutils_word8 *ptr1;
mutils_word8 *ptr2;
mutils_word32 i;
mutils_word32 *bigptr1;
mutils_word32 *bigptr2;
mutils_word32 words;
mutils_word32 remainder;
if ((dest == NULL) || (src == NULL) || (n == 0))
{
return;
}
bigptr1 = (mutils_word32 *) dest;
bigptr2 = (mutils_word32 *) src;
words = n >> 2;
remainder = n - (words << 2);
for (i = 0; i < words; i++, bigptr1++, bigptr2++)
{
*bigptr1 = *bigptr2;
}
ptr1 = (mutils_word8 *) bigptr1;
ptr2 = (mutils_word8 *) bigptr2;
for (i = 0; i < remainder; i++, ptr1++, ptr2++)
{
*ptr1 = *ptr2;
}
}
WIN32DLL_DEFINE
int
mutils_memcmp(__const void *s1, const void *s2, const mutils_word32 n)
{
if (n == 0)
{
return(0);
}
if (s1 == NULL)
{
if (s2 == NULL)
{
return(0);
}
return(-MAXINT);
}
if (s2 == NULL)
{
return(MAXINT);
}
return(memcmp(s1, s2, n));
}
/* Ugh. This could do nasty things, if a string isn't correctly terminated,
* particularly as memory can be larger than can be stored in a 32-bit word.
* If it is possible to produce an incorrect result, or segfault, then it
* is not a robust solution.
*/
WIN32DLL_DEFINE
mutils_word32
mutils_strlen(__const mutils_word8 *str)
{
mutils_word32 ret;
mutils_word8 *endStr = (mutils_word8 *) str;
if (str == NULL)
{
return(0);
}
while (*endStr != 0)
{
endStr++;
}
ret = endStr - str;
return(ret);
}
WIN32DLL_DEFINE
mutils_word8 *
mutils_strdup(__const mutils_word8 *str)
{
mutils_word8 *ret = NULL;
mutils_word8 *ptr1;
mutils_word8 *ptr2;
mutils_word32 len;
if (str == NULL)
{
return(NULL);
}
len = mutils_strlen(str) + 1;
ret = (mutils_word8 *) mutils_malloc(len);
if (ret != NULL)
{
ptr1 = (mutils_word8 *) str;
ptr2 = ret;
for (len = mutils_strlen(str); len > 0; len--, ptr1++, ptr2++)
{
*ptr2 = *ptr1;
}
}
return(ret);
}
WIN32DLL_DEFINE
mutils_word8 *
mutils_strcat(mutils_word8 *dest, __const mutils_word8 *src)
{
mutils_word8 *ptrIn = (mutils_word8 *) src;
mutils_word8 *ptrOut = dest + mutils_strlen(dest);
if (dest == NULL)
{
return(NULL);
}
if (src == NULL)
{
return(dest);
}
while (*src != 0)
{
*ptrOut = *ptrIn;
ptrOut++;
ptrIn++;
}
*ptrOut = '\0';
return((mutils_word8 *) dest);
}
WIN32DLL_DEFINE
mutils_word8 *
mutils_strcpy(mutils_word8 *dest, __const mutils_word8 *src)
{
if (dest == NULL)
{
return(NULL);
}
return((mutils_word8 *) strcpy((char *) dest, (char *) src));
}
WIN32DLL_DEFINE
mutils_word8 *
mutils_strncpy(mutils_word8 *dest, __const mutils_word8 *src, const mutils_word32 n)
{
if (dest == NULL)
{
return(NULL);
}
if (n == 0)
{
return(NULL);
}
return((mutils_word8 *) strncpy((char *) dest, (char *) src, n));
}
WIN32DLL_DEFINE
int
mutils_strcmp(__const mutils_word8 *src1, const mutils_word8 *src2)
{
if (src1 == NULL)
{
if (src2 == NULL)
{
return(0);
}
return(-MAXINT);
}
if (src2 == NULL)
{
return(MAXINT);
}
return(strcmp((char *) src1, (char *) src2));
}
WIN32DLL_DEFINE
int
mutils_strncmp(__const mutils_word8 *src1, const mutils_word8 *src2, const mutils_word32 n)
{
if (n == 0)
{
return(0);
}
if (src1 == NULL)
{
if (src2 == NULL)
{
return(0);
}
return(-MAXINT);
}
if (src2 == NULL)
{
return(MAXINT);
}
return(strncmp((char *) src1, (char *) src2, n));
}
WIN32DLL_DEFINE
long
mutils_strtol(__const mutils_word8 *nptr, mutils_word8 **endptr, const mutils_word8 base)
{
return(strtol((char *) nptr, (char **) endptr, (int) base));
}
WIN32DLL_DEFINE
mutils_word8
mutils_val2char(mutils_word8 x)
{
mutils_word8 out;
static mutils_word8 *table = (mutils_word8 *) "0123456789abcdef";
out = *(table + x);
return(out);
}
WIN32DLL_DEFINE
mutils_word8 *
mutils_asciify(mutils_word8 *in, __const mutils_word32 len)
{
mutils_word8 *ptrIn = in;
mutils_word8 *buffer = mutils_malloc((2 * len) + 1);
mutils_word8 *ptrOut = buffer;
mutils_word32 loop;
for (loop = 0; loop < len; loop++, ptrIn++)
{
*ptrOut++ = mutils_val2char((*ptrIn & 0xf0) >> 4);
*ptrOut++ = mutils_val2char((*ptrIn & 0x0f));
}
return(buffer);
}
WIN32DLL_DEFINE
mutils_boolean
mutils_thequals(mutils_word8 *text, mutils_word8 *hash, __const mutils_word32 len)
{
mutils_word8 *ptrText = text;
mutils_word8 *ptrHash = hash;
mutils_word32 loop;
for (loop = 0; loop < len; loop++, ptrHash++)
{
if (mutils_val2char((*ptrHash & 0xf0) >> 4) != *ptrText++)
{
return(MUTILS_FALSE);
}
if (mutils_val2char((*ptrHash & 0x0f)) != *ptrText++)
{
return(MUTILS_FALSE);
}
}
return(MUTILS_TRUE);
}