r23795: more v2->v3 conversion
[samba.git] / source4 / lib / replace / replace.c
index c53b5a572772e980f48be277a47176bf22c8d0a9..1b4a82cb033765f284265e673c44f99b4f6a4931 100644 (file)
@@ -2,39 +2,48 @@
    Unix SMB/CIFS implementation.
    replacement routines for broken systems
    Copyright (C) Andrew Tridgell 1992-1998
+
+     ** NOTE! The following LGPL license applies to the replace
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
    
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
-#include "includes.h"
-#include "system/wait.h"
+#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) {}
+void replace_dummy(void);
+void replace_dummy(void) {}
 
 #ifndef HAVE_FTRUNCATE
  /*******************************************************************
 ftruncate for operating systems that don't have it
 ********************************************************************/
- int ftruncate(int f,off_t l)
+int rep_ftruncate(int f, off_t l)
 {
 #ifdef HAVE_CHSIZE
       return chsize(f,l);
-#else
+#elif defined(F_FREESP)
       struct  flock   fl;
 
       fl.l_whence = 0;
@@ -42,6 +51,8 @@ ftruncate for operating systems that don't have it
       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 /* HAVE_FTRUNCATE */
@@ -50,7 +61,7 @@ ftruncate for operating systems that don't have it
 #ifndef HAVE_STRLCPY
 /* like strncpy but does not 0 fill the buffer and always null 
    terminates. bufsize is the size of the destination buffer */
- size_t strlcpy(char *d, const char *s, size_t bufsize)
+size_t rep_strlcpy(char *d, const char *s, size_t bufsize)
 {
        size_t len = strlen(s);
        size_t ret = len;
@@ -66,7 +77,7 @@ ftruncate for operating systems that don't have it
 /* like strncat but does not 0 fill the buffer and always null 
    terminates. bufsize is the length of the buffer, which should
    be one more than the maximum resulting string length */
- size_t strlcat(char *d, const char *s, size_t bufsize)
+size_t rep_strlcat(char *d, const char *s, size_t bufsize)
 {
        size_t len1 = strlen(d);
        size_t len2 = strlen(s);
@@ -94,7 +105,7 @@ Corrections by richard.kettlewell@kewill.com
 #define  HOUR    60*MINUTE
 #define  DAY             24*HOUR
 #define  YEAR    365*DAY
- time_t mktime(struct tm *t)
+time_t rep_mktime(struct tm *t)
 {
   struct tm       *u;
   time_t  epoch = 0;
@@ -143,63 +154,22 @@ Corrections by richard.kettlewell@kewill.com
 #endif /* !HAVE_MKTIME */
 
 
-
-#ifndef HAVE_RENAME
-/* Rename a file. (from libiberty in GNU binutils)  */
- int rename(const char *zfrom, const char *zto)
-{
-  if (link (zfrom, zto) < 0)
-    {
-      if (errno != EEXIST)
-       return -1;
-      if (unlink (zto) < 0
-         || link (zfrom, zto) < 0)
-       return -1;
-    }
-  return unlink (zfrom);
-}
-#endif /* HAVE_RENAME */
-
-
-#ifndef HAVE_INNETGR
-#if defined(HAVE_SETNETGRENT) && defined(HAVE_GETNETGRENT) && defined(HAVE_ENDNETGRENT)
-/*
- * Search for a match in a netgroup. This replaces it on broken systems.
- */
- int innetgr(const char *group,const char *host,const char *user,const char *dom)
-{
-       char *hst, *usr, *dm;
-  
-       setnetgrent(group);
-       while (getnetgrent(&hst, &usr, &dm)) {
-               if (((host == 0) || (hst == 0) || !strcmp(host, hst)) &&
-                   ((user == 0) || (usr == 0) || !strcmp(user, usr)) &&
-                   ((dom == 0) || (dm == 0) || !strcmp(dom, dm))) {
-                       endnetgrent();
-                       return (1);
-               }
-       }
-       endnetgrent();
-       return (0);
-}
-#endif /* HAVE_SETNETGRENT HAVE_GETNETGRENT HAVE_ENDNETGRENT */
-#endif /* HAVE_INNETGR */
-
-
-
 #ifndef HAVE_INITGROUPS
 /****************************************************************************
  some systems don't have an initgroups call 
 ****************************************************************************/
- int initgroups(char *name, gid_t id)
+int rep_initgroups(char *name, gid_t id)
 {
 #ifndef HAVE_SETGROUPS
        /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
        errno = ENOSYS;
        return -1;
 #else /* HAVE_SETGROUPS */
+
+#include <grp.h>
+
        gid_t *grouplst = NULL;
-       int max_gr = groups_max();
+       int max_gr = 32;
        int ret;
        int    i,j;
        struct group *g;
@@ -240,7 +210,7 @@ Corrections by richard.kettlewell@kewill.com
 /* This is needed due to needing the nap() function but we don't want
    to include the Xenix libraries since that will break other things...
    BTW: system call # 0x0c28 is the same as calling nap() */
- long nap(long milliseconds) {
+long nap(long milliseconds) {
         return syscall(0x0c28, milliseconds);
  }
 #endif
@@ -253,7 +223,7 @@ this is only used if the machine does not have it's own memmove().
 this is not the fastest algorithm in town, but it will do for our
 needs.
 ********************************************************************/
- void *memmove(void *dest,const void *src,int size)
+void *rep_memmove(void *dest,const void *src,int size)
 {
        unsigned long d,s;
        int i;
@@ -311,7 +281,7 @@ needs.
 /****************************************************************************
 duplicate a string
 ****************************************************************************/
- char *strdup(const char *s)
+char *rep_strdup(const char *s)
 {
        size_t len;
        char *ret;
@@ -329,7 +299,7 @@ duplicate a string
 #ifndef WITH_PTHREADS
 /* REWRITE: not thread safe */
 #ifdef REPLACE_INET_NTOA
- char *rep_inet_ntoa(struct in_addr ip)
+char *rep_inet_ntoa(struct in_addr ip)
 {
        uint8_t *p = (uint8_t *)&ip.s_addr;
        static char buf[18];
@@ -341,15 +311,15 @@ duplicate a string
 #endif
 
 #ifndef HAVE_SETLINEBUF
- int setlinebuf(FILE *stream)
+void rep_setlinebuf(FILE *stream)
 {
-       return setvbuf(stream, (char *)NULL, _IOLBF, 0);
+       setvbuf(stream, (char *)NULL, _IOLBF, 0);
 }
 #endif /* HAVE_SETLINEBUF */
 
 #ifndef HAVE_VSYSLOG
 #ifdef HAVE_SYSLOG
- void vsyslog (int facility_priority, char *format, va_list arglist)
+void rep_vsyslog (int facility_priority, const char *format, va_list arglist)
 {
        char *msg = NULL;
        vasprintf(&msg, format, arglist);
@@ -361,81 +331,28 @@ duplicate a string
 #endif /* HAVE_SYSLOG */
 #endif /* HAVE_VSYSLOG */
 
-
-#ifndef HAVE_TIMEGM
-/*
-  yes, I know this looks insane, but its really needed. The function in the 
-  Linux timegm() manpage does not work on solaris.
-*/
- time_t timegm(struct tm *tm) 
-{
-       struct tm tm2, tm3;
-       time_t t;
-
-       tm2 = *tm;
-
-       t = mktime(&tm2);
-       tm3 = *localtime(&t);
-       tm2 = *tm;
-       tm2.tm_isdst = tm3.tm_isdst;
-       t = mktime(&tm2);
-       t -= get_time_zone(t);
-
-       return t;
-}
-#endif
-
-#ifndef HAVE_SETENV
- int setenv(const char *name, const char *value, int overwrite) 
-{
-       char *p = NULL;
-       int ret = -1;
-
-       asprintf(&p, "%s=%s", name, value);
-
-       if (overwrite || getenv(name)) {
-               if (p) ret = putenv(p);
-       } else {
-               ret = 0;
-       }
-
-       return ret;     
-}
-#endif
-
-
-#ifndef HAVE_STRTOULL
- unsigned long long int 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);
-#else
-# error "You need a strtoull function"
-#endif
-}
-#endif
-
-#ifndef HAVE_STRTOLL
- long long int strtoll(const char *str, char **endptr, int base)
+#ifndef HAVE_STRNLEN
+/**
+ Some platforms don't have strnlen
+**/
+ size_t rep_strnlen(const char *s, size_t max)
 {
-#ifdef HAVE_STRTOQ
-       return strtoq(str, endptr, base);
-#elif defined(HAVE___STRTOLL) 
-       return __strtoll(str, endptr, base);
-#else
-# error "You need a strtoll function"
-#endif
+        size_t len;
+  
+        for (len = 0; len < max; len++) {
+                if (s[len] == '\0') {
+                        break;
+                }
+        }
+        return len;  
 }
 #endif
-
-
+  
 #ifndef HAVE_STRNDUP
 /**
  Some platforms don't have strndup.
 **/
- char *strndup(const char *s, size_t n)
+char *rep_strndup(const char *s, size_t n)
 {
        char *ret;
        
@@ -450,28 +367,15 @@ duplicate a string
 }
 #endif
 
-#ifndef HAVE_STRNLEN
-/**
- Some platforms don't have strnlen
-**/
- size_t strnlen(const char *s, size_t n)
-{
-       int i;
-       for (i=0; s[i] && i<n; i++)
-               /* noop */ ;
-       return i;
-}
-#endif
-
 #ifndef HAVE_WAITPID
-int waitpid(pid_t pid,int *status,int options)
+int rep_waitpid(pid_t pid,int *status,int options)
 {
   return wait4(pid, status, options, NULL);
 }
 #endif
 
 #ifndef HAVE_SETEUID
- int seteuid(uid_t euid)
+int rep_seteuid(uid_t euid)
 {
 #ifdef HAVE_SETRESUID
        return setresuid(-1, euid, -1);
@@ -482,7 +386,7 @@ int waitpid(pid_t pid,int *status,int options)
 #endif
 
 #ifndef HAVE_SETEGID
- int setegid(gid_t egid)
+int rep_setegid(gid_t egid)
 {
 #ifdef HAVE_SETRESGID
        return setresgid(-1, egid, -1);
@@ -496,13 +400,8 @@ int waitpid(pid_t pid,int *status,int options)
 os/2 also doesn't have chroot
 ********************************************************************/
 #ifndef HAVE_CHROOT
-int chroot(const char *dname)
+int rep_chroot(const char *dname)
 {
-       static int done;
-       if (!done) {
-               DEBUG(1,("WARNING: no chroot!\n"));
-               done=1;
-       }
        errno = ENOSYS;
        return -1;
 }
@@ -524,8 +423,27 @@ int rep_mkstemp(char *template)
 }
 #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
+
+/*****************************************************************
+ Watch out: this is not thread safe.
+*****************************************************************/
+
 #ifndef HAVE_PREAD
-static ssize_t pread(int __fd, void *__buf, size_t __nbytes, off_t __offset)
+ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset)
 {
        if (lseek(__fd, __offset, SEEK_SET) != __offset) {
                return -1;
@@ -534,8 +452,12 @@ static ssize_t pread(int __fd, void *__buf, size_t __nbytes, off_t __offset)
 }
 #endif
 
+/*****************************************************************
+ Watch out: this is not thread safe.
+*****************************************************************/
+
 #ifndef HAVE_PWRITE
-static ssize_t pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset)
+ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset)
 {
        if (lseek(__fd, __offset, SEEK_SET) != __offset) {
                return -1;
@@ -544,4 +466,159 @@ static ssize_t pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offs
 }
 #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
+/* based on GLIBC version, copyright Free Software Foundation */
+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, count;
+
+       if (environ == NULL || getenv(name) == NULL) {
+               return 0;
+       }
+
+       for (i=0;environ[i];i++) /* noop */ ;
+
+       count=i;
+       
+       for (i=0;i<count;) {
+               if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') {
+                       /* note: we do _not_ free the old variable here. It is unsafe to 
+                          do so, as the pointer may not have come from malloc */
+                       memmove(&environ[i], &environ[i+1], (count-i)*sizeof(char *));
+                       count--;
+               } else {
+                       i++;
+               }
+       }
+
+       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