#include "replace.h"
#include "system/filesys.h"
#include "system/time.h"
#include "system/passwd.h"
#include "system/syslog.h"
#include "system/network.h"
#include "system/locale.h"
#include "system/wait.h"
void replace_dummy(void);
void replace_dummy(void) {}
#ifndef HAVE_FTRUNCATE
int rep_ftruncate(int f, off_t l)
{
#ifdef HAVE_CHSIZE
return chsize(f,l);
#elif defined(F_FREESP)
struct flock fl;
fl.l_whence = 0;
fl.l_len = 0;
fl.l_start = l;
fl.l_type = F_WRLCK;
return fcntl(f, F_FREESP, &fl);
#else
#error "you must have a ftruncate function"
#endif
}
#endif
#ifndef HAVE_STRLCPY
size_t rep_strlcpy(char *d, const char *s, size_t bufsize)
{
size_t len = strlen(s);
size_t ret = len;
if (bufsize <= 0) return 0;
if (len >= bufsize) len = bufsize-1;
memcpy(d, s, len);
d[len] = 0;
return ret;
}
#endif
#ifndef HAVE_STRLCAT
size_t rep_strlcat(char *d, const char *s, size_t bufsize)
{
size_t len1 = strlen(d);
size_t len2 = strlen(s);
size_t ret = len1 + len2;
if (len1+len2 >= bufsize) {
len2 = bufsize - (len1+1);
}
if (len2 > 0) {
memcpy(d+len1, s, len2);
d[len1+len2] = 0;
}
return ret;
}
#endif
#ifndef HAVE_MKTIME
#define MINUTE 60
#define HOUR 60*MINUTE
#define DAY 24*HOUR
#define YEAR 365*DAY
time_t rep_mktime(struct tm *t)
{
struct tm *u;
time_t epoch = 0;
int n;
int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
y, m, i;
if(t->tm_year < 70)
return((time_t)-1);
n = t->tm_year + 1900 - 1;
epoch = (t->tm_year - 70) * YEAR +
((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY;
y = t->tm_year + 1900;
m = 0;
for(i = 0; i < t->tm_mon; i++) {
epoch += mon [m] * DAY;
if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
epoch += DAY;
if(++m > 11) {
m = 0;
y++;
}
}
epoch += (t->tm_mday - 1) * DAY;
epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
if((u = localtime(&epoch)) != NULL) {
t->tm_sec = u->tm_sec;
t->tm_min = u->tm_min;
t->tm_hour = u->tm_hour;
t->tm_mday = u->tm_mday;
t->tm_mon = u->tm_mon;
t->tm_year = u->tm_year;
t->tm_wday = u->tm_wday;
t->tm_yday = u->tm_yday;
t->tm_isdst = u->tm_isdst;
}
return(epoch);
}
#endif
#ifndef HAVE_INITGROUPS
int rep_initgroups(char *name, gid_t id)
{
#ifndef HAVE_SETGROUPS
errno = ENOSYS;
return -1;
#else
#include <grp.h>
gid_t *grouplst = NULL;
int max_gr = 32;
int ret;
int i,j;
struct group *g;
char *gr;
if((grouplst = malloc(sizeof(gid_t) * max_gr)) == NULL) {
errno = ENOMEM;
return -1;
}
grouplst[0] = id;
i = 1;
while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group *)NULL)) {
if (g->gr_gid == id)
continue;
j = 0;
gr = g->gr_mem[0];
while (gr && (*gr != (char)NULL)) {
if (strcmp(name,gr) == 0) {
grouplst[i] = g->gr_gid;
i++;
gr = (char *)NULL;
break;
}
gr = g->gr_mem[++j];
}
}
endgrent();
ret = setgroups(i, grouplst);
free(grouplst);
return ret;
#endif
}
#endif
#if (defined(SecureWare) && defined(SCO))
long nap(long milliseconds) {
return syscall(0x0c28, milliseconds);
}
#endif
#ifndef HAVE_MEMMOVE
void *rep_memmove(void *dest,const void *src,int size)
{
unsigned long d,s;
int i;
if (dest==src || !size) return(dest);
d = (unsigned long)dest;
s = (unsigned long)src;
if ((d >= (s+size)) || (s >= (d+size))) {
memcpy(dest,src,size);
return(dest);
}
if (d < s) {
if (s-d >= sizeof(int) &&
!(s%sizeof(int)) &&
!(d%sizeof(int)) &&
!(size%sizeof(int))) {
int *idest = (int *)dest;
int *isrc = (int *)src;
size /= sizeof(int);
for (i=0;i<size;i++) idest[i] = isrc[i];
} else {
char *cdest = (char *)dest;
char *csrc = (char *)src;
for (i=0;i<size;i++) cdest[i] = csrc[i];
}
} else {
if (d-s >= sizeof(int) &&
!(s%sizeof(int)) &&
!(d%sizeof(int)) &&
!(size%sizeof(int))) {
int *idest = (int *)dest;
int *isrc = (int *)src;
size /= sizeof(int);
for (i=size-1;i>=0;i--) idest[i] = isrc[i];
} else {
char *cdest = (char *)dest;
char *csrc = (char *)src;
for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
}
}
return(dest);
}
#endif
#ifndef HAVE_STRDUP
char *rep_strdup(const char *s)
{
size_t len;
char *ret;
if (!s) return(NULL);
len = strlen(s)+1;
ret = (char *)malloc(len);
if (!ret) return(NULL);
memcpy(ret,s,len);
return(ret);
}
#endif
#ifndef WITH_PTHREADS
#ifdef REPLACE_INET_NTOA
char *rep_inet_ntoa(struct in_addr ip)
{
uint8_t *p = (uint8_t *)&ip.s_addr;
static char buf[18];
slprintf(buf, 17, "%d.%d.%d.%d",
(int)p[0], (int)p[1], (int)p[2], (int)p[3]);
return buf;
}
#endif
#endif
#ifndef HAVE_SETLINEBUF
void rep_setlinebuf(FILE *stream)
{
setvbuf(stream, (char *)NULL, _IOLBF, 0);
}
#endif
#ifndef HAVE_VSYSLOG
#ifdef HAVE_SYSLOG
void rep_vsyslog (int facility_priority, const char *format, va_list arglist)
{
char *msg = NULL;
vasprintf(&msg, format, arglist);
if (!msg)
return;
syslog(facility_priority, "%s", msg);
free(msg);
}
#endif
#endif
#ifndef HAVE_STRNLEN
size_t rep_strnlen(const char *s, size_t max)
{
size_t len;
for (len = 0; len < max; len++) {
if (s[len] == '\0') {
break;
}
}
return len;
}
#endif
#ifndef HAVE_STRNDUP
char *rep_strndup(const char *s, size_t n)
{
char *ret;
n = strnlen(s, n);
ret = malloc(n+1);
if (!ret)
return NULL;
memcpy(ret, s, n);
ret[n] = 0;
return ret;
}
#endif
#ifndef HAVE_WAITPID
int rep_waitpid(pid_t pid,int *status,int options)
{
return wait4(pid, status, options, NULL);
}
#endif
#ifndef HAVE_SETEUID
int rep_seteuid(uid_t euid)
{
#ifdef HAVE_SETRESUID
return setresuid(-1, euid, -1);
#else
# error "You need a seteuid function"
#endif
}
#endif
#ifndef HAVE_SETEGID
int rep_setegid(gid_t egid)
{
#ifdef HAVE_SETRESGID
return setresgid(-1, egid, -1);
#else
# error "You need a setegid function"
#endif
}
#endif
#ifndef HAVE_CHROOT
int rep_chroot(const char *dname)
{
errno = ENOSYS;
return -1;
}
#endif
#ifndef HAVE_SECURE_MKSTEMP
int rep_mkstemp(char *template)
{
char *p = mktemp(template);
if (!p)
return -1;
return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
}
#endif
#ifndef HAVE_MKDTEMP
char *rep_mkdtemp(char *template)
{
char *dname;
if ((dname = mktemp(template))) {
if (mkdir(dname, 0700) >= 0) {
return dname;
}
}
return NULL;
}
#endif
#ifndef HAVE_PREAD
ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset)
{
if (lseek(__fd, __offset, SEEK_SET) != __offset) {
return -1;
}
return read(__fd, __buf, __nbytes);
}
#endif
#ifndef HAVE_PWRITE
ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset)
{
if (lseek(__fd, __offset, SEEK_SET) != __offset) {
return -1;
}
return write(__fd, __buf, __nbytes);
}
#endif
#ifndef HAVE_STRCASESTR
char *rep_strcasestr(const char *haystack, const char *needle)
{
const char *s;
size_t nlen = strlen(needle);
for (s=haystack;*s;s++) {
if (toupper(*needle) == toupper(*s) &&
strncasecmp(s, needle, nlen) == 0) {
return (char *)((intptr_t)s);
}
}
return NULL;
}
#endif
#ifndef HAVE_STRTOK_R
char *rep_strtok_r(char *s, const char *delim, char **save_ptr)
{
char *token;
if (s == NULL) s = *save_ptr;
s += strspn(s, delim);
if (*s == '\0') {
*save_ptr = s;
return NULL;
}
token = s;
s = strpbrk(token, delim);
if (s == NULL) {
*save_ptr = token + strlen(token);
} else {
*s = '\0';
*save_ptr = s + 1;
}
return token;
}
#endif
#ifndef HAVE_STRTOLL
long long int rep_strtoll(const char *str, char **endptr, int base)
{
#ifdef HAVE_STRTOQ
return strtoq(str, endptr, base);
#elif defined(HAVE___STRTOLL)
return __strtoll(str, endptr, base);
#elif SIZEOF_LONG == SIZEOF_LONG_LONG
return (long long int) strtol(str, endptr, base);
#else
# error "You need a strtoll function"
#endif
}
#endif
#ifndef HAVE_STRTOULL
unsigned long long int rep_strtoull(const char *str, char **endptr, int base)
{
#ifdef HAVE_STRTOUQ
return strtouq(str, endptr, base);
#elif defined(HAVE___STRTOULL)
return __strtoull(str, endptr, base);
#elif SIZEOF_LONG == SIZEOF_LONG_LONG
return (unsigned long long int) strtoul(str, endptr, base);
#else
# error "You need a strtoull function"
#endif
}
#endif
#ifndef HAVE_SETENV
int rep_setenv(const char *name, const char *value, int overwrite)
{
char *p;
size_t l1, l2;
int ret;
if (!overwrite && getenv(name)) {
return 0;
}
l1 = strlen(name);
l2 = strlen(value);
p = malloc(l1+l2+2);
if (p == NULL) {
return -1;
}
memcpy(p, name, l1);
p[l1] = '=';
memcpy(p+l1+1, value, l2);
p[l1+l2+1] = 0;
ret = putenv(p);
if (ret != 0) {
free(p);
}
return ret;
}
#endif
#ifndef HAVE_UNSETENV
int rep_unsetenv(const char *name)
{
extern char **environ;
size_t len = strlen(name);
size_t i;
int found = 0;
for (i=0; (environ && environ[i]); i++) {
if (found) {
environ[i-1] = environ[i];
continue;
}
if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') {
free(environ[i]);
environ[i] = NULL;
found = 1;
continue;
}
}
return 0;
}
#endif
#ifndef HAVE_SOCKETPAIR
int rep_socketpair(int d, int type, int protocol, int sv[2])
{
if (d != AF_UNIX) {
errno = EAFNOSUPPORT;
return -1;
}
if (protocol != 0) {
errno = EPROTONOSUPPORT;
return -1;
}
if (type != SOCK_STREAM) {
errno = EOPNOTSUPP;
return -1;
}
return pipe(sv);
}
#endif