replace: Fix use of mktemp
[idra/samba.git] / lib / replace / replace.c
index 8eba98acf40eab8438afee86fd118d8a6ed33a69..322bf49e91b9950fe682543fc5f275e88898daad 100644 (file)
@@ -3,6 +3,7 @@
    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
@@ -26,6 +27,7 @@
 
 #include "system/filesys.h"
 #include "system/time.h"
+#include "system/network.h"
 #include "system/passwd.h"
 #include "system/syslog.h"
 #include "system/locale.h"
@@ -410,8 +412,8 @@ int rep_mkstemp(char *template)
 {
        /* have a reasonable go at emulating it. Hope that
           the system mktemp() isn't completely hopeless */
-       char *p = mktemp(template);
-       if (!p)
+       mktemp(template);
+       if (template[0] == 0)
                return -1;
        return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
 }
@@ -502,6 +504,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)
 {
@@ -515,7 +518,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
@@ -531,7 +556,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) 
@@ -705,7 +752,7 @@ void *rep_memmem(const void *haystack, size_t haystacklen,
 #endif
 
 #ifndef HAVE_VDPRINTF
-int vdprintf(int fd, const char *format, va_list ap)
+int rep_vdprintf(int fd, const char *format, va_list ap)
 {
        char *s = NULL;
        int ret;
@@ -722,7 +769,7 @@ int vdprintf(int fd, const char *format, va_list ap)
 #endif
 
 #ifndef HAVE_DPRINTF
-int dprintf(int fd, const char *format, ...)
+int rep_dprintf(int fd, const char *format, ...)
 {
        int ret;
        va_list ap;
@@ -735,3 +782,125 @@ int dprintf(int fd, const char *format, ...)
 }
 #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 !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
+
+#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
+
+#ifndef HAVE_MEMALIGN
+void *rep_memalign( size_t align, size_t size )
+{
+#if defined(HAVE_POSIX_MEMALIGN)
+       void *p = NULL;
+       int ret = posix_memalign( &p, align, size );
+       if ( ret == 0 )
+               return p;
+
+       return NULL;
+#else
+       /* On *BSD systems memaligns doesn't exist, but memory will
+        * be aligned on allocations of > pagesize. */
+#if defined(SYSCONF_SC_PAGESIZE)
+       size_t pagesize = (size_t)sysconf(_SC_PAGESIZE);
+#elif defined(HAVE_GETPAGESIZE)
+       size_t pagesize = (size_t)getpagesize();
+#else
+       size_t pagesize = (size_t)-1;
+#endif
+       if (pagesize == (size_t)-1) {
+               errno = ENOSYS;
+               return NULL;
+       }
+       if (size < pagesize) {
+               size = pagesize;
+       }
+       return malloc(size);
+#endif
+}
+#endif
+
+#ifndef HAVE_GETPEEREID
+int rep_getpeereid(int s, uid_t *uid, gid_t *gid)
+{
+#if defined(HAVE_PEERCRED)
+       struct ucred cred;
+       socklen_t cred_len = sizeof(struct ucred);
+       int ret;
+
+#undef getsockopt
+       ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
+       if (ret != 0) {
+               return -1;
+       }
+
+       if (cred_len != sizeof(struct ucred)) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       *uid = cred.uid;
+       *gid = cred.gid;
+       return 0;
+#else
+       errno = ENOSYS;
+       return -1;
+#endif
+}
+#endif
+
+#ifndef HAVE_USLEEP
+int rep_usleep(useconds_t sec)
+{
+       struct timeval tval;
+       /*
+        * Fake it with select...
+        */
+       tval.tv_sec = 0;
+       tval.tv_usec = usecs/1000;
+       select(0,NULL,NULL,NULL,&tval);
+       return 0;
+}
+#endif /* HAVE_USLEEP */