summaryrefslogtreecommitdiff
path: root/source4/lib/replace
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/replace')
-rw-r--r--source4/lib/replace/README54
-rw-r--r--source4/lib/replace/SConscript2
-rw-r--r--source4/lib/replace/config.m484
-rw-r--r--source4/lib/replace/config.mk4
-rw-r--r--source4/lib/replace/dlfcn.c71
-rw-r--r--source4/lib/replace/replace.c73
-rw-r--r--source4/lib/replace/replace.h22
7 files changed, 269 insertions, 41 deletions
diff --git a/source4/lib/replace/README b/source4/lib/replace/README
new file mode 100644
index 0000000000..74b5397949
--- /dev/null
+++ b/source4/lib/replace/README
@@ -0,0 +1,54 @@
+This subsystem ensures that we can always use a certain core set of
+functions and types, that are either provided by the OS or by replacement
+functions / definitions in this subsystem. The aim is to try to stick
+to POSIX functions in here as much as possible. Convenience functions
+that are available on no platform at all belong in different subsystems
+(such as LIBUTIL).
+
+The following functions are guarenteed:
+
+ftruncate
+strlcpy
+strlcat
+mktime
+rename
+innetgr
+initgroups
+memmove
+strdup
+inet_ntoa
+setlinebuf
+vsyslog
+timegm
+setenv
+strtoull
+strtoll
+strndup
+strnlen
+waitpid
+seteuid
+setegid
+asprintf
+snprintf
+vasprintf
+vsnprintf
+opendir
+readdir
+telldir
+seekdir
+closedir
+dlopen
+dlclose
+dlsym
+dlerror
+chroot
+bzero
+strerror
+errno
+mkstemp (a secure one!)
+
+Prerequisites:
+memset (for bzero)
+syslog (for vsyslog)
+setnetgrent, getnetgrent, endnetgrent (for innetgr)
+mktemp (for mkstemp)
diff --git a/source4/lib/replace/SConscript b/source4/lib/replace/SConscript
index 84088db162..982120e1bf 100644
--- a/source4/lib/replace/SConscript
+++ b/source4/lib/replace/SConscript
@@ -9,4 +9,4 @@ if hostenv['configure']:
conf.Finish()
hostenv.StaticLibrary('repdir', ['repdir/repdir.c'])
-hostenv.StaticLibrary('replace', ['replace.c', 'snprintf.c'])
+hostenv.StaticLibrary('replace', ['replace.c', 'snprintf.c','dlfcn.c'])
diff --git a/source4/lib/replace/config.m4 b/source4/lib/replace/config.m4
index 4dfeb5647a..88e3be5e94 100644
--- a/source4/lib/replace/config.m4
+++ b/source4/lib/replace/config.m4
@@ -15,5 +15,87 @@ if test x"$samba_cv_REPLACE_INET_NTOA" = x"yes"; then
AC_DEFINE(REPLACE_INET_NTOA,1,[Whether inet_ntoa should be replaced])
fi
+dnl Provided by replace.c:
+AC_CHECK_HEADERS(sys/syslog.h syslog.h)
AC_CHECK_FUNCS(strtoull __strtoull strtouq strtoll __strtoll strtoq)
-AC_CHECK_FUNCS(seteuid setresuid setegid setresgid)
+AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror)
+AC_CHECK_FUNCS(timegm setenv vsyslog setlinebuf mktime ftruncate chsize rename)
+AC_CHECK_FUNCS(waitpid strnlen strlcpy strlcat innetgr initgroups memmove strdup)
+AC_HAVE_DECL(setresuid, [#include <unistd.h>])
+AC_HAVE_DECL(setresgid, [#include <unistd.h>])
+AC_HAVE_DECL(errno, [#include <errno.h>])
+
+AC_CACHE_CHECK([for secure mkstemp],samba_cv_HAVE_SECURE_MKSTEMP,[
+AC_TRY_RUN([#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+main() {
+ struct stat st;
+ char tpl[20]="/tmp/test.XXXXXX";
+ int fd = mkstemp(tpl);
+ if (fd == -1) exit(1);
+ unlink(tpl);
+ if (fstat(fd, &st) != 0) exit(1);
+ if ((st.st_mode & 0777) != 0600) exit(1);
+ exit(0);
+}],
+samba_cv_HAVE_SECURE_MKSTEMP=yes,
+samba_cv_HAVE_SECURE_MKSTEMP=no,
+samba_cv_HAVE_SECURE_MKSTEMP=cross)])
+if test x"$samba_cv_HAVE_SECURE_MKSTEMP" = x"yes"; then
+ AC_DEFINE(HAVE_SECURE_MKSTEMP,1,[Whether mkstemp is secure])
+fi
+
+dnl Provided by snprintf.c:
+AC_HAVE_DECL(asprintf, [#include <stdio.h>])
+AC_HAVE_DECL(vasprintf, [#include <stdio.h>])
+AC_HAVE_DECL(vsnprintf, [#include <stdio.h>])
+AC_HAVE_DECL(snprintf, [#include <stdio.h>])
+AC_CHECK_FUNCS(snprintf vsnprintf asprintf vasprintf)
+
+AC_CACHE_CHECK([for C99 vsnprintf],samba_cv_HAVE_C99_VSNPRINTF,[
+AC_TRY_RUN([
+#include <sys/types.h>
+#include <stdarg.h>
+void foo(const char *format, ...) {
+ va_list ap;
+ int len;
+ char buf[20];
+ long long l = 1234567890;
+ l *= 100;
+
+ va_start(ap, format);
+ len = vsnprintf(buf, 0, format, ap);
+ va_end(ap);
+ if (len != 5) exit(1);
+
+ va_start(ap, format);
+ len = vsnprintf(0, 0, format, ap);
+ va_end(ap);
+ if (len != 5) exit(1);
+
+ if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(1);
+
+ if (snprintf(buf, 20, "%lld", l) != 12 || strcmp(buf, "123456789000") != 0) exit(1);
+
+ exit(0);
+}
+main() { foo("hello"); }
+],
+samba_cv_HAVE_C99_VSNPRINTF=yes,samba_cv_HAVE_C99_VSNPRINTF=no,samba_cv_HAVE_C99_VSNPRINTF=cross)])
+if test x"$samba_cv_HAVE_C99_VSNPRINTF" = x"yes"; then
+ AC_DEFINE(HAVE_C99_VSNPRINTF,1,[Whether there is a C99 compliant vsnprintf])
+fi
+
+dnl Provided by dlfcn.c:
+AC_SEARCH_LIBS_EXT(dlopen, [dl], DL_LIBS)
+SMB_EXT_LIB(DL,[${DL_LIBS}],[${DL_CFLAGS}],[${DL_CPPFLAGS}],[${DL_LDFLAGS}])
+SAVE_LIBS="$LIBS"
+LIBS="$LIBS $DL_LIBS"
+AC_CHECK_HEADERS(dlfcn.h)
+AC_CHECK_FUNCS(dlopen dlsym dlerror dlclose)
+LIBS="$SAVE_LIBS"
+
+AC_CHECK_FUNCS([syslog memset setnetgrent getnetgrent endnetgrent],,
+ [AC_MSG_ERROR([Need syslog and memset])])
diff --git a/source4/lib/replace/config.mk b/source4/lib/replace/config.mk
index 16952ea32d..2658f0e96a 100644
--- a/source4/lib/replace/config.mk
+++ b/source4/lib/replace/config.mk
@@ -13,7 +13,9 @@ NOPROTO = YES
[SUBSYSTEM::LIBREPLACE]
INIT_OBJ_FILES = lib/replace/replace.o
ADD_OBJ_FILES = \
- lib/replace/snprintf.o
+ lib/replace/snprintf.o \
+ lib/replace/dlfcn.o
+NOPROTO = YES
REQUIRED_SUBSYSTEMS = REPLACE_READDIR
# End SUBSYSTEM LIBREPLACE
##############################
diff --git a/source4/lib/replace/dlfcn.c b/source4/lib/replace/dlfcn.c
new file mode 100644
index 0000000000..7a9e7230de
--- /dev/null
+++ b/source4/lib/replace/dlfcn.c
@@ -0,0 +1,71 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba system utilities
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 1998-2002
+
+ 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,
+ 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.
+*/
+
+/*
+ Unix SMB/CIFS implementation.
+ Samba system utilities
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 1998-2002
+
+ 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,
+ 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.
+*/
+
+#include "includes.h"
+
+#ifndef HAVE_DLOPEN
+void *dlopen(const char *name, int flags)
+{
+ return NULL;
+}
+#endif
+
+#ifndef HAVE_DLSYM
+void *dlsym(void *handle, const char *symbol)
+{
+ return NULL;
+}
+#endif
+
+#ifndef HAVE_DLERROR
+const char *dlerror(void)
+{
+ return "dynamic loading of objects not supported on this platform";
+}
+#endif
+
+#ifndef HAVE_DLCLOSE
+int dlclose(void *handle)
+{
+ return 0;
+}
+#endif
diff --git a/source4/lib/replace/replace.c b/source4/lib/replace/replace.c
index ef8e053257..aa79f23fd0 100644
--- a/source4/lib/replace/replace.c
+++ b/source4/lib/replace/replace.c
@@ -361,39 +361,6 @@ duplicate a string
#endif /* HAVE_SYSLOG */
#endif /* HAVE_VSYSLOG */
-/*******************************************************************
-yield the difference between *A and *B, in seconds, ignoring leap seconds
-********************************************************************/
-static int tm_diff(struct tm *a, struct tm *b)
-{
- int ay = a->tm_year + (1900 - 1);
- int by = b->tm_year + (1900 - 1);
- int intervening_leap_days =
- (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
- int years = ay - by;
- int days = 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
- int hours = 24*days + (a->tm_hour - b->tm_hour);
- int minutes = 60*hours + (a->tm_min - b->tm_min);
- int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
-
- return seconds;
-}
-
-/*******************************************************************
- return the UTC offset in seconds west of UTC, or 0 if it cannot be determined
- ******************************************************************/
-int get_time_zone(time_t t)
-{
- struct tm *tm = gmtime(&t);
- struct tm tm_utc;
- if (!tm)
- return 0;
- tm_utc = *tm;
- tm = localtime(&t);
- if (!tm)
- return 0;
- return tm_diff(&tm_utc,tm);
-}
#ifndef HAVE_TIMEGM
/*
@@ -496,14 +463,12 @@ int get_time_zone(time_t t)
}
#endif
-int sys_waitpid(pid_t pid,int *status,int options)
+#ifndef HAVE_WAITPID
+int waitpid(pid_t pid,int *status,int options)
{
-#ifdef HAVE_WAITPID
- return waitpid(pid,status,options);
-#else /* USE_WAITPID */
return wait4(pid, status, options, NULL);
-#endif /* USE_WAITPID */
}
+#endif
#ifndef HAVE_SETEUID
int seteuid(uid_t euid)
@@ -526,3 +491,35 @@ int sys_waitpid(pid_t pid,int *status,int options)
#endif
}
#endif
+
+/*******************************************************************
+os/2 also doesn't have chroot
+********************************************************************/
+#ifndef HAVE_CHROOT
+int chroot(const char *dname)
+{
+ static int done;
+ if (!done) {
+ DEBUG(1,("WARNING: no chroot!\n"));
+ done=1;
+ }
+ errno = ENOSYS;
+ return -1;
+}
+#endif
+
+/*****************************************************************
+ Possibly replace mkstemp if it is broken.
+*****************************************************************/
+
+#ifndef HAVE_SECURE_MKSTEMP
+int rep_mkstemp(char *template)
+{
+ /* have a reasonable go at emulating it. Hope that
+ the system mktemp() isn't completly hopeless */
+ char *p = mktemp(template);
+ if (!p)
+ return -1;
+ return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
+}
+#endif
diff --git a/source4/lib/replace/replace.h b/source4/lib/replace/replace.h
index f85c8de634..f906e7a2f5 100644
--- a/source4/lib/replace/replace.h
+++ b/source4/lib/replace/replace.h
@@ -23,6 +23,10 @@
#ifndef _replace_h
#define _replace_h
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#include "lib/replace/win32/replace.h"
+#endif
+
#ifdef __COMPAR_FN_T
#define QSORT_CAST (__compar_fn_t)
#endif
@@ -31,6 +35,15 @@
#define QSORT_CAST (int (*)(const void *, const void *))
#endif
+#ifndef HAVE_STRERROR
+extern char *sys_errlist[];
+#define strerror(i) sys_errlist[i]
+#endif
+
+#ifndef HAVE_ERRNO_DECL
+extern int errno;
+#endif
+
#ifndef HAVE_STRDUP
char *strdup(const char *s);
#endif
@@ -136,4 +149,13 @@ typedef unsigned char u_int8_t;
#define HAVE_SOCKLEN_T 1
#endif
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#ifndef HAVE_SECURE_MKSTEMP
+#define mkstemp(path) rep_mkstemp(path)
+int rep_mkstemp(char *temp);
+#endif
+
#endif