diff options
Diffstat (limited to 'ctdb/lib/replace/replace.c')
-rw-r--r-- | ctdb/lib/replace/replace.c | 275 |
1 files changed, 241 insertions, 34 deletions
diff --git a/ctdb/lib/replace/replace.c b/ctdb/lib/replace/replace.c index cec158be31..d9a96ff8ef 100644 --- a/ctdb/lib/replace/replace.c +++ b/ctdb/lib/replace/replace.c @@ -2,6 +2,8 @@ Unix SMB/CIFS implementation. replacement routines for broken systems Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Jelmer Vernooij 2005-2008 + Copyright (C) Matthieu Patou 2010 ** NOTE! The following LGPL license applies to the replace ** library. This does NOT imply that all of Samba is released @@ -27,10 +29,13 @@ #include "system/time.h" #include "system/passwd.h" #include "system/syslog.h" -#include "system/network.h" #include "system/locale.h" #include "system/wait.h" +#ifdef _WIN32 +#define mkdir(d,m) _mkdir(d) +#endif + void replace_dummy(void); void replace_dummy(void) {} @@ -83,6 +88,9 @@ size_t rep_strlcat(char *d, const char *s, size_t bufsize) size_t ret = len1 + len2; if (len1+len2 >= bufsize) { + if (bufsize < (len1+1)) { + return ret; + } len2 = bufsize - (len1+1); } if (len2 > 0) { @@ -168,7 +176,7 @@ int rep_initgroups(char *name, gid_t id) #include <grp.h> gid_t *grouplst = NULL; - int max_gr = 32; + int max_gr = NGROUPS_MAX; int ret; int i,j; struct group *g; @@ -218,7 +226,7 @@ long nap(long milliseconds) { #ifndef HAVE_MEMMOVE /******************************************************************* safely copies memory, ensuring no overlap problems. -this is only used if the machine does not have it's own memmove(). +this is only used if the machine does not have its own memmove(). this is not the fastest algorithm in town, but it will do for our needs. ********************************************************************/ @@ -295,20 +303,6 @@ char *rep_strdup(const char *s) } #endif /* HAVE_STRDUP */ -#ifndef WITH_PTHREADS -/* REWRITE: not thread safe */ -#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 /* REPLACE_INET_NTOA */ -#endif - #ifndef HAVE_SETLINEBUF void rep_setlinebuf(FILE *stream) { @@ -366,7 +360,7 @@ char *rep_strndup(const char *s, size_t n) } #endif -#ifndef HAVE_WAITPID +#if !defined(HAVE_WAITPID) && defined(HAVE_WAIT4) int rep_waitpid(pid_t pid,int *status,int options) { return wait4(pid, status, options, NULL); @@ -379,7 +373,8 @@ int rep_seteuid(uid_t euid) #ifdef HAVE_SETRESUID return setresuid(-1, euid, -1); #else -# error "You need a seteuid function" + errno = ENOSYS; + return -1; #endif } #endif @@ -390,7 +385,8 @@ int rep_setegid(gid_t egid) #ifdef HAVE_SETRESGID return setresgid(-1, egid, -1); #else -# error "You need a setegid function" + errno = ENOSYS; + return -1; #endif } #endif @@ -414,7 +410,7 @@ int rep_chroot(const char *dname) int rep_mkstemp(char *template) { /* have a reasonable go at emulating it. Hope that - the system mktemp() isn't completly hopeless */ + the system mktemp() isn't completely hopeless */ char *p = mktemp(template); if (!p) return -1; @@ -473,7 +469,7 @@ char *rep_strcasestr(const char *haystack, const char *needle) for (s=haystack;*s;s++) { if (toupper(*needle) == toupper(*s) && strncasecmp(s, needle, nlen) == 0) { - return (char *)((intptr_t)s); + return (char *)((uintptr_t)s); } } return NULL; @@ -507,6 +503,7 @@ char *rep_strtok_r(char *s, const char *delim, char **save_ptr) } #endif + #ifndef HAVE_STRTOLL long long int rep_strtoll(const char *str, char **endptr, int base) { @@ -520,7 +517,29 @@ long long int rep_strtoll(const char *str, char **endptr, int base) # error "You need a strtoll function" #endif } -#endif +#else +#ifdef HAVE_BSD_STRTOLL +#ifdef HAVE_STRTOQ +long long int rep_strtoll(const char *str, char **endptr, int base) +{ + long long int nb = strtoq(str, endptr, base); + /* In linux EINVAL is only returned if base is not ok */ + if (errno == EINVAL) { + if (base == 0 || (base >1 && base <37)) { + /* Base was ok so it's because we were not + * able to make the convertion. + * Let's reset errno. + */ + errno = 0; + } + } + return nb; +} +#else +#error "You need the strtoq function" +#endif /* HAVE_STRTOQ */ +#endif /* HAVE_BSD_STRTOLL */ +#endif /* HAVE_STRTOLL */ #ifndef HAVE_STRTOULL @@ -536,7 +555,29 @@ unsigned long long int rep_strtoull(const char *str, char **endptr, int base) # error "You need a strtoull function" #endif } -#endif +#else +#ifdef HAVE_BSD_STRTOLL +#ifdef HAVE_STRTOUQ +unsigned long long int rep_strtoull(const char *str, char **endptr, int base) +{ + unsigned long long int nb = strtouq(str, endptr, base); + /* In linux EINVAL is only returned if base is not ok */ + if (errno == EINVAL) { + if (base == 0 || (base >1 && base <37)) { + /* Base was ok so it's because we were not + * able to make the convertion. + * Let's reset errno. + */ + errno = 0; + } + } + return nb; +} +#else +#error "You need the strtouq function" +#endif /* HAVE_STRTOUQ */ +#endif /* HAVE_BSD_STRTOLL */ +#endif /* HAVE_STRTOULL */ #ifndef HAVE_SETENV int rep_setenv(const char *name, const char *value, int overwrite) @@ -600,24 +641,190 @@ int rep_unsetenv(const char *name) } #endif -#ifndef HAVE_SOCKETPAIR -int rep_socketpair(int d, int type, int protocol, int sv[2]) +#ifndef HAVE_UTIME +int rep_utime(const char *filename, const struct utimbuf *buf) { - if (d != AF_UNIX) { - errno = EAFNOSUPPORT; - return -1; + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_UTIMES +int rep_utimes(const char *filename, const struct timeval tv[2]) +{ + struct utimbuf u; + + u.actime = tv[0].tv_sec; + if (tv[0].tv_usec > 500000) { + u.actime += 1; + } + + u.modtime = tv[1].tv_sec; + if (tv[1].tv_usec > 500000) { + u.modtime += 1; + } + + return utime(filename, &u); +} +#endif + +#ifndef HAVE_DUP2 +int rep_dup2(int oldfd, int newfd) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_CHOWN +/** +chown isn't used much but OS/2 doesn't have it +**/ +int rep_chown(const char *fname, uid_t uid, gid_t gid) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_LINK +int rep_link(const char *oldpath, const char *newpath) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_READLINK +int rep_readlink(const char *path, char *buf, size_t bufsiz) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_SYMLINK +int rep_symlink(const char *oldpath, const char *newpath) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_LCHOWN +int rep_lchown(const char *fname,uid_t uid,gid_t gid) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_REALPATH +char *rep_realpath(const char *path, char *resolved_path) +{ + /* As realpath is not a system call we can't return ENOSYS. */ + errno = EINVAL; + return NULL; +} +#endif + + +#ifndef HAVE_MEMMEM +void *rep_memmem(const void *haystack, size_t haystacklen, + const void *needle, size_t needlelen) +{ + if (needlelen == 0) { + return discard_const(haystack); + } + while (haystacklen >= needlelen) { + char *p = (char *)memchr(haystack, *(const char *)needle, + haystacklen-(needlelen-1)); + if (!p) return NULL; + if (memcmp(p, needle, needlelen) == 0) { + return p; + } + haystack = p+1; + haystacklen -= (p - (const char *)haystack) + 1; } + return NULL; +} +#endif + +#ifndef HAVE_VDPRINTF +int rep_vdprintf(int fd, const char *format, va_list ap) +{ + char *s = NULL; + int ret; - if (protocol != 0) { - errno = EPROTONOSUPPORT; + vasprintf(&s, format, ap); + if (s == NULL) { + errno = ENOMEM; return -1; } + ret = write(fd, s, strlen(s)); + free(s); + return ret; +} +#endif + +#ifndef HAVE_DPRINTF +int rep_dprintf(int fd, const char *format, ...) +{ + int ret; + va_list ap; + + va_start(ap, format); + ret = vdprintf(fd, format, ap); + va_end(ap); + + return ret; +} +#endif + +#ifndef HAVE_GET_CURRENT_DIR_NAME +char *rep_get_current_dir_name(void) +{ + char buf[PATH_MAX+1]; + char *p; + p = getcwd(buf, sizeof(buf)); + if (p == NULL) { + return NULL; + } + return strdup(p); +} +#endif - if (type != SOCK_STREAM) { - errno = EOPNOTSUPP; +#if !defined(HAVE_STRERROR_R) || !defined(STRERROR_R_PROTO_COMPATIBLE) +int rep_strerror_r(int errnum, char *buf, size_t buflen) +{ + char *s = strerror(errnum); + if (strlen(s)+1 > buflen) { + errno = ERANGE; return -1; } + strncpy(buf, s, buflen); + return 0; +} +#endif - return pipe(sv); +#ifndef HAVE_CLOCK_GETTIME +int rep_clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + struct timeval tval; + switch (clk_id) { + case 0: /* CLOCK_REALTIME :*/ +#ifdef HAVE_GETTIMEOFDAY_TZ + gettimeofday(&tval,NULL); +#else + gettimeofday(&tval); +#endif + tp->tv_sec = tval.tv_sec; + tp->tv_nsec = tval.tv_usec * 1000; + break; + default: + errno = EINVAL; + return -1; + } + return 0; } #endif |