diff options
Diffstat (limited to 'src/libs/uio/uioutils.c')
-rw-r--r-- | src/libs/uio/uioutils.c | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/src/libs/uio/uioutils.c b/src/libs/uio/uioutils.c new file mode 100644 index 0000000..fbe3cd4 --- /dev/null +++ b/src/libs/uio/uioutils.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2003 Serge van den Boom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * Nota bene: later versions of the GNU General Public License do not apply + * to this program. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <sys/types.h> +#include <string.h> + +#include "uioutils.h" +#include "mem.h" +#include "paths.h" +#include "uioport.h" + +/** + * Concatenate two strings into a newly allocated buffer. + * + * @param[in] first The first (left) string, '\0' terminated. + * @param[in] second The second (right) string, '\0' terminated. + * + * @returns A newly allocated string consisting of the concatenation of + * 'first' and 'second', to be freed using uio_free(). + */ +char * +strcata(const char *first, const char *second) { + char *result, *resPtr; + size_t firstLen, secondLen; + + firstLen = strlen(first); + secondLen = strlen(second); + result = uio_malloc(firstLen + secondLen + 1); + resPtr = result; + + memcpy(resPtr, first, firstLen); + resPtr += firstLen; + + memcpy(resPtr, second, secondLen); + resPtr += secondLen; + + *resPtr = '\0'; + return result; +} + +// returns a copy of a generic array 'array' with 'element' inserted in +// position 'insertPos' +void * +insertArray(const void *array, size_t oldNumElements, int insertPos, + const void *element, size_t elementSize) { + void *newArray, *newArrayPtr; + const void *arrayPtr; + size_t preInsertSize; + + newArray = uio_malloc((oldNumElements + 1) * elementSize); + preInsertSize = insertPos * elementSize; + memcpy(newArray, array, preInsertSize); + newArrayPtr = (char *) newArray + preInsertSize; + arrayPtr = (const char *) array + preInsertSize; + memcpy(newArrayPtr, element, elementSize); + newArrayPtr = (char *) newArrayPtr + elementSize; + memcpy(newArrayPtr, arrayPtr, + (oldNumElements - insertPos) * elementSize); + return newArray; +} + +// returns a copy of a pointer array 'array' with 'element' inserted in +// position 'insertPos' +void ** +insertArrayPointer(const void **array, size_t oldNumElements, int insertPos, + const void *element) { + void **newArray, **newArrayPtr; + const void **arrayPtr; + size_t preInsertSize; + + newArray = uio_malloc((oldNumElements + 1) * sizeof (void *)); + preInsertSize = insertPos * sizeof (void *); + memcpy(newArray, array, preInsertSize); + newArrayPtr = newArray + insertPos; + arrayPtr = array + insertPos; + *newArrayPtr = unconst(element); + newArrayPtr++; + memcpy(newArrayPtr, arrayPtr, + (oldNumElements - insertPos) * sizeof (void *)); + return newArray; +} + +// returns a copy of a generic array 'array' with 'numExclude' elements, +// starting from startpos, removed. +void * +excludeArray(const void *array, size_t oldNumElements, int startPos, + int numExclude, size_t elementSize) { + void *newArray, *newArrayPtr; + const void *arrayPtr; + size_t preExcludeSize; + + newArray = uio_malloc((oldNumElements - numExclude) * elementSize); + preExcludeSize = startPos * elementSize; + memcpy(newArray, array, preExcludeSize); + newArrayPtr = (char *) newArray + preExcludeSize; + arrayPtr = (const char *) array + + (startPos + numExclude) * sizeof (elementSize); + memcpy(newArrayPtr, arrayPtr, + (oldNumElements - startPos - numExclude) * elementSize); + return newArray; +} + +// returns a copy of a pointer array 'array' with 'numExclude' elements, +// starting from startpos, removed. +void ** +excludeArrayPointer(const void **array, size_t oldNumElements, int startPos, + int numExclude) { + void **newArray; + + newArray = uio_malloc((oldNumElements - numExclude) * sizeof (void *)); + memcpy(newArray, array, startPos * sizeof (void *)); + memcpy(&newArray[startPos], &array[startPos + numExclude], + (oldNumElements - startPos - numExclude) * sizeof (void *)); + return newArray; +} + +// If the given DOS date/time is invalid, the result is unspecified, +// but the function won't crash. +time_t +dosToUnixTime(uio_uint16 date, uio_uint16 tm) { + // DOS date has the following format: + // bits 0-4 specify the number of the day in the month (1-31). + // bits 5-8 specify the number of the month in the year (1-12). + // bits 9-15 specify the year number since 1980 (0-127) + // DOS time has the fillowing format: + // bits 0-4 specify the number of seconds/2 in the minute (0-29) + // (only accurate on 2 seconds) + // bits 5-10 specify the number of minutes in the hour (0-59) + // bits 11-15 specify the number of hours since midnight (0-23) + + int year, month, day; + int hours, minutes, seconds; + long result; + + static const int daysUntilMonth[] = { + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, + 334, 334, 334, 334 }; + // The last 4 entries are there so that there's no + // invalid memory access if the date is invalid. + + year = date >> 9; + month = ((date >> 5) - 1) & 0x0f; // Number in [0..15] + day = (date - 1) & 0x1f; // Number in [0..31] + hours = tm >> 11; + minutes = (tm >> 5) & 0x3f; + seconds = (tm & 0x1f) * 2; // Even number in [0..62] + + result = year * 365 + daysUntilMonth[month] + day; + // Count the (non-leap) days in all those years + + // Add a leapday for each 4th year + if (year % 4 == 0 && month <= 2) { + // The given date is a leap-year but the leapday hasn't occured yet. + result += year / 4; + } else { + result += 1 + year / 4; + } + // result now is the number of days between 1980-01-01 and the given day. + + // Add the days between 1970-01-01 and 1980-01-01 + // (2 leapdays in this period) + result += 365 * 10 + 2; + + result = (result * 24) + hours; // days to hours + result = (result * 60) + minutes; // hours to minutes + result = (result * 60) + seconds; // minutes to seconds + + return (time_t) result; +} + +char * +dosToUnixPath(const char *path) { + const char *srcPtr; + char *result, *dstPtr; + size_t skip; + + result = uio_malloc(strlen(path) + 1); + srcPtr = path; + dstPtr = result; + + // A UNC path will look like this: "\\server\share/..."; the first two + // characters will be backslashes, and the separator between the server + // and the share too. The rest will be slashes. + // The goal is that at every forward slash, the path should be + // stat()'able. + skip = uio_skipUNCServerShare(srcPtr); + if (skip != 0) { + char *slash; + memcpy(dstPtr, srcPtr, skip); + + slash = memchr(srcPtr + 2, '/', skip - 2); + if (slash != NULL) + *slash = '\\'; + + srcPtr += skip; + dstPtr += skip; + } + + while (*srcPtr != '\0') { + if (*srcPtr == '\\') { + *dstPtr = '/'; + } else + *dstPtr = *srcPtr; + srcPtr++; + dstPtr++; + } + *dstPtr = '\0'; + return result; +} + + |