/* * 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) { 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; } } 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; } 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 = 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); }