401 lines
7.4 KiB
C
401 lines
7.4 KiB
C
#include "links.h"
|
|
|
|
#ifndef HAVE_SNPRINTF
|
|
|
|
#define B_SZ 65536
|
|
|
|
static char snprtintf_buffer[B_SZ];
|
|
|
|
int my_snprintf(char *str, int n, char *f, ...)
|
|
{
|
|
int i;
|
|
va_list l;
|
|
if (!n) return -1;
|
|
va_start(l, f);
|
|
#ifdef HAVE_VPRINTF
|
|
vsprintf(snprtintf_buffer, f, l);
|
|
#elif defined(HAVE_DOPRNT)
|
|
{
|
|
struct _iobuf strbuf;
|
|
strbuf._flag = _IOWRT+_IOSTRG;
|
|
strbuf._ptr = snprtintf_buffer;
|
|
strbuf._cnt = 32767;
|
|
_doprnt(f, l, &strbuf);
|
|
putc('\0', &strbuf);
|
|
}
|
|
#else
|
|
fatal_exit("No vsprintf!");
|
|
#endif
|
|
va_end(l);
|
|
i = strlen(snprtintf_buffer);
|
|
if (i >= B_SZ) {
|
|
fatal_exit("String size too large!");
|
|
}
|
|
if (i >= n) {
|
|
memcpy(str, snprtintf_buffer, n);
|
|
str[n - 1] = 0;
|
|
return -1;
|
|
}
|
|
strcpy(str, snprtintf_buffer);
|
|
return i;
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifndef HAVE_RAISE
|
|
int raise(int s)
|
|
{
|
|
#ifdef HAVE_GETPID
|
|
pid_t p;
|
|
EINTRLOOP(p, getpid());
|
|
if (p == -1) return -1;
|
|
return kill(p, s);
|
|
#else
|
|
return 0;
|
|
#endif
|
|
};
|
|
#endif
|
|
#ifndef HAVE_GETTIMEOFDAY
|
|
int gettimeofday(struct timeval *tv, struct timezone *tz)
|
|
{
|
|
time_t t;
|
|
errno = 0;
|
|
EINTRLOOPX(t, time(NULL), (time_t)-1);
|
|
if (tv) tv->tv_sec = t, tv->tv_usec = 0;
|
|
if (tz) tz->tz_minuteswest = tz->tz_dsttime = 0;
|
|
return 0;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_GETCWD
|
|
char *getcwd(char *buf, size_t size)
|
|
{
|
|
#ifndef MAXPATHLEN
|
|
#define MAXPATHLEN 1024
|
|
#endif
|
|
static char cwd[MAXPATHLEN];
|
|
if (!getwd(cwd))
|
|
return NULL;
|
|
if (strlen(cwd) >= size) {
|
|
errno = ERANGE;
|
|
return NULL;
|
|
}
|
|
strcpy(buf, cwd);
|
|
return 0;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_TEMPNAM
|
|
char *tempnam(const char *dir, const char *pfx)
|
|
{
|
|
static int counter = 0;
|
|
unsigned char *d, *s, *a;
|
|
int l;
|
|
if (!(d = cast_uchar getenv("TMPDIR"))) {
|
|
if (dir) d = cast_uchar dir;
|
|
else if (!(d = cast_uchar getenv("TMP")) && !(d = cast_uchar getenv("TEMP"))) {
|
|
#ifdef P_tmpdir
|
|
d = cast_uchar(P_tmpdir);
|
|
#else
|
|
d = cast_uchar "/tmp";
|
|
#endif
|
|
}
|
|
}
|
|
l = 0;
|
|
s = init_str();
|
|
add_to_str(&s, &l, d);
|
|
if (s[0] && s[strlen(cast_const_char s) - 1] != '/') add_chr_to_str(&s, &l, '/');
|
|
add_to_str(&s, &l, cast_uchar pfx);
|
|
add_num_to_str(&s, &l, counter++);
|
|
a = cast_uchar strdup(cast_const_char s);
|
|
mem_free(s);
|
|
return cast_char a;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRDUP
|
|
char *strdup(const char *s)
|
|
{
|
|
char *a = malloc(strlen(s) + 1);
|
|
if (!a) return NULL;
|
|
return strcpy(a, s);
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRTOL
|
|
long strtol(const char *nptr, char **endptr, int base)
|
|
{
|
|
unsigned long result;
|
|
char negative = 0;
|
|
if (*nptr == '-') {
|
|
negative = 1;
|
|
nptr++;
|
|
}
|
|
result = 0;
|
|
while (1) {
|
|
char c = *nptr;
|
|
char val;
|
|
unsigned long nr;
|
|
if (c >= '0' && c <= '9') val = c - '0';
|
|
else if (c >= 'A' && c <= 'Z') val = c - 'A' + 10;
|
|
else if (c >= 'a' && c <= 'z') val = c - 'a' + 10;
|
|
else break;
|
|
if (val >= base) break;
|
|
nr = result * base + val;
|
|
if ((long)nr < val || (nr - val) / base != result) break;
|
|
result = nr;
|
|
nptr++;
|
|
}
|
|
if (endptr) *endptr = (char *)nptr;
|
|
if (negative) return -result;
|
|
return result;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRTOUL
|
|
unsigned long strtoul(const char *nptr, char **endptr, int base)
|
|
{
|
|
if (*nptr == '-') {
|
|
if (endptr) *endptr = nptr;
|
|
return 0;
|
|
}
|
|
return (unsigned long)strtol(nptr,endptr,base);
|
|
};
|
|
#endif
|
|
#ifndef HAVE_STRTOD
|
|
double strtod(const char *nptr, char **endptr)
|
|
{
|
|
double d = 0;
|
|
char dummy;
|
|
if (endptr) *endptr = (char *)nptr;
|
|
if (sscanf(nptr, "%lf%c", &d, &dummy) == 1) {
|
|
if (endptr) *endptr = strchr(nptr, 0);
|
|
}
|
|
return d;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRLEN
|
|
size_t strlen(const char *s)
|
|
{
|
|
size_t len = 0;
|
|
while (s[len]) len++;
|
|
return len;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRNLEN
|
|
size_t strnlen(const char *s, size_t max)
|
|
{
|
|
size_t len = 0;
|
|
while (len < max && s[len]) len++;
|
|
return len;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRCPY
|
|
char *strcpy(char *dst, const char *src)
|
|
{
|
|
return memcpy(dst, src, strlen(src) + 1);
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRNCPY
|
|
char *strncpy(char *dst, const char *src, size_t len)
|
|
{
|
|
size_t sl = strlen(src);
|
|
if (sl >= len) {
|
|
memcpy(dst, src, len);
|
|
} else {
|
|
memcpy(dst, src, sl);
|
|
memset(dst + sl, 0, len - sl);
|
|
}
|
|
return dst;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRCHR
|
|
char *strchr(const char *s, int c)
|
|
{
|
|
do {
|
|
if (*s == (char)c)
|
|
return (char *)s;
|
|
} while (*s++);
|
|
return NULL;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRRCHR
|
|
char *strrchr(const char *s, int c)
|
|
{
|
|
char *ret = NULL;
|
|
do {
|
|
if (*s == (char)c)
|
|
ret = (char *)s;
|
|
} while (*s++);
|
|
return ret;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRCMP
|
|
int strcmp(const char *s1, const char *s2)
|
|
{
|
|
while (1) {
|
|
unsigned char c1 = (unsigned char)*s1;
|
|
unsigned char c2 = (unsigned char)*s2;
|
|
if (c1 != c2) {
|
|
return (int)c1 - (int)c2;
|
|
}
|
|
if (!c1) break;
|
|
s1++, s2++;
|
|
}
|
|
return 0;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRNCMP
|
|
int strncmp(const char *s1, const char *s2, size_t n)
|
|
{
|
|
while (n--) {
|
|
unsigned char c1 = (unsigned char)*s1;
|
|
unsigned char c2 = (unsigned char)*s2;
|
|
if (c1 != c2) {
|
|
return (int)c1 - (int)c2;
|
|
}
|
|
if (!c1) break;
|
|
s1++, s2++;
|
|
}
|
|
return 0;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRCSPN
|
|
size_t strcspn(const char *s, const char *reject)
|
|
{
|
|
size_t r;
|
|
for (r = 0; *s; r++, s++) {
|
|
const char *rj;
|
|
for (rj = reject; *rj; rj++) if (*s == *rj) goto brk;
|
|
}
|
|
brk:
|
|
return r;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRSPN
|
|
size_t strspn(const char *s, const char *accept)
|
|
{
|
|
size_t r;
|
|
for (r = 0; *s; r++, s++) {
|
|
const char *rj;
|
|
for (rj = accept; *rj; rj++) if (*s == *rj) goto ac;
|
|
break;
|
|
ac:;
|
|
}
|
|
return r;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRSTR
|
|
char *strstr(const char *haystack, const char *needle)
|
|
{
|
|
size_t hs = strlen(haystack);
|
|
size_t ns = strlen(needle);
|
|
if (!ns) return (char *)haystack;
|
|
while (hs >= ns) {
|
|
if (*haystack == *needle && !memcmp(haystack, needle, ns)) return (char *)haystack;
|
|
haystack++, hs--;
|
|
}
|
|
return NULL;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_MEMCHR
|
|
void *memchr(const void *s, int c, size_t length)
|
|
{
|
|
const char *sp = s;
|
|
while (length--) {
|
|
if (*sp == (char)c)
|
|
return (char *)s;
|
|
sp++;
|
|
}
|
|
return NULL;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_MEMRCHR
|
|
void *memrchr(const void *s, int c, size_t length)
|
|
{
|
|
const char *sp = s;
|
|
char *ret = NULL;
|
|
while (length--) {
|
|
if (*sp == (char)c)
|
|
ret = (char *)s;
|
|
sp++;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_MEMCMP
|
|
int memcmp(const void *src0, const void *src1, size_t length)
|
|
{
|
|
const unsigned char *s0, *s1;
|
|
#ifdef HAVE_BCMP
|
|
if (!bcmp(src0, src1, length))
|
|
return 0;
|
|
#endif
|
|
s0 = src0;
|
|
s1 = src1;
|
|
while (length--) {
|
|
int c = *s0 - *s1;
|
|
if (c) return c;
|
|
s0++, s1++;
|
|
}
|
|
return 0;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_MEMCPY
|
|
void *memcpy(void *dst0, const void *src0, size_t length)
|
|
{
|
|
return memmove(dst0, src0, length);
|
|
}
|
|
#endif
|
|
#ifndef HAVE_MEMMOVE
|
|
void *memmove(void *dst0, const void *src0, size_t length)
|
|
{
|
|
#ifdef HAVE_BCOPY
|
|
bcopy(src0, dst0, length);
|
|
return dst0;
|
|
#else
|
|
unsigned char *dst = dst0;
|
|
const unsigned char *src = src0;
|
|
|
|
if ((const unsigned char *)dst == src || !length)
|
|
return dst0;
|
|
|
|
if ((const unsigned char *)dst <= src) {
|
|
while (length--) *dst++ = *src++;
|
|
} else {
|
|
dst += length - 1;
|
|
src += length - 1;
|
|
while (length--) *dst-- = *src--;
|
|
}
|
|
return dst0;
|
|
#endif
|
|
}
|
|
#endif
|
|
#ifndef HAVE_MEMSET
|
|
void *memset(void *s, int c, size_t n)
|
|
{
|
|
char *sc = s;
|
|
#ifdef HAVE_BZERO
|
|
if (!c) bzero(s, n);
|
|
else
|
|
#endif
|
|
while (n--) *sc++ = c;
|
|
return s;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_MEMMEM
|
|
void *memmem(const void *haystack, size_t hs, const void *needle, size_t ns)
|
|
{
|
|
if (!ns) return (void *)haystack;
|
|
while (hs >= ns) {
|
|
if (*(const char *)haystack == *(const char *)needle && !memcmp(haystack, needle, ns)) return (void *)haystack;
|
|
haystack = (const void *)((const char *)haystack + 1), hs--;
|
|
}
|
|
return NULL;
|
|
}
|
|
#endif
|
|
#ifndef HAVE_STRERROR
|
|
extern char *sys_errlist[];
|
|
extern int sys_nerr;
|
|
char *strerror(int errnum)
|
|
{
|
|
if (errnum < 0 || errnum >= sys_nerr) return "Unknown error";
|
|
return sys_errlist[errnum];
|
|
};
|
|
#endif
|