diff options
Diffstat (limited to 'source4/build')
37 files changed, 5116 insertions, 0 deletions
diff --git a/source4/build/m4/ax_cflags_gcc_option.m4 b/source4/build/m4/ax_cflags_gcc_option.m4 new file mode 100644 index 0000000000..ec01a000aa --- /dev/null +++ b/source4/build/m4/ax_cflags_gcc_option.m4 @@ -0,0 +1,109 @@ +dnl @synopsis AX_CFLAGS_GCC_OPTION (optionflag [,[shellvar][,[A][,[NA]]]) +dnl +dnl AX_CFLAGS_GCC_OPTION(-fvomit-frame) would show a message as like +dnl "checking CFLAGS for gcc -fvomit-frame ... yes" and adds +dnl the optionflag to CFLAGS if it is understood. You can override +dnl the shellvar-default of CFLAGS of course. The order of arguments +dnl stems from the explicit macros like AX_CFLAGS_WARN_ALL. +dnl +dnl The macro is a lot simpler than any special AX_CFLAGS_* macro (or +dnl ac_cxx_rtti.m4 macro) but allows to check for arbitrary options. +dnl However, if you use this macro in a few places, it would be great +dnl if you would make up a new function-macro and submit it to the +dnl ac-archive. +dnl +dnl - $1 option-to-check-for : required ("-option" as non-value) +dnl - $2 shell-variable-to-add-to : CFLAGS +dnl - $3 action-if-found : add value to shellvariable +dnl - $4 action-if-not-found : nothing +dnl +dnl note: in earlier versions, $1-$2 were swapped. We try to detect the +dnl situation and accept a $2=~/-/ as being the old option-to-check-for. +dnl +dnl also: there are other variants that emerged from the original macro +dnl variant which did just test an option to be possibly added. However, +dnl some compilers accept an option silently, or possibly for just +dnl another option that was not intended. Therefore, we have to do a +dnl generic test for a compiler family. For gcc we check "-pedantic" +dnl being accepted which is also understood by compilers who just want +dnl to be compatible with gcc even when not being made from gcc sources. +dnl +dnl see also: +dnl AX_CFLAGS_SUN_OPTION AX_CFLAGS_HPUX_OPTION +dnl AX_CFLAGS_AIX_OPTION AX_CFLAGS_IRIX_OPTION +dnl +dnl @, tested, experimental +dnl @version $Id: ax_cflags_gcc_option.m4,v 1.5 2003/11/29 08:13:25 guidod Exp $ +dnl @author Guido Draheim <guidod@gmx.de> +dnl http://ac-archive.sourceforge.net/C_Support/ax_cflags_gcc_option.m4 +dnl +AC_DEFUN([AX_CFLAGS_GCC_OPTION_OLD], [dnl +AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_gcc_option_$2])dnl +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_C + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-pedantic % m4_ifval($2,$2,-option)" dnl GCC + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + + +dnl ------------------------------------------------------------------------- + +AC_DEFUN([AX_CFLAGS_GCC_OPTION_NEW], [dnl +AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_gcc_option_$1])dnl +AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_C + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-pedantic % m4_ifval($1,$1,-option)" dnl GCC + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) + m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + + +AC_DEFUN([AX_CFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, +[AX_CFLAGS_GCC_OPTION_NEW($@)],[AX_CFLAGS_GCC_OPTION_OLD($@)])]) diff --git a/source4/build/m4/ax_cflags_irix_option.m4 b/source4/build/m4/ax_cflags_irix_option.m4 new file mode 100644 index 0000000000..f7fe2a19b0 --- /dev/null +++ b/source4/build/m4/ax_cflags_irix_option.m4 @@ -0,0 +1,174 @@ +dnl @synopsis AX_CFLAGS_IRIX_OPTION (optionflag [,[shellvar][,[A][,[NA]]]) +dnl +dnl AX_CFLAGS_IRIX_OPTION(-go_for_it) would show a message as like +dnl "checking CFLAGS for irix/cc -go_for_it ... yes" and adds the +dnl optionflag to CFLAGS if it is understood. You can override the +dnl shellvar-default of CFLAGS of course. The order of arguments stems +dnl from the explicit macros like AX_CFLAGS_WARN_ALL. +dnl +dnl The cousin AX_CXXFLAGS_IRIX_OPTION would check for an option to add +dnl to CXXFLAGS - and it uses the autoconf setup for C++ instead of C +dnl (since it is possible to use different compilers for C and C++). +dnl +dnl The macro is a lot simpler than any special AX_CFLAGS_* macro (or +dnl ac_cxx_rtti.m4 macro) but allows to check for arbitrary options. +dnl However, if you use this macro in a few places, it would be great +dnl if you would make up a new function-macro and submit it to the +dnl ac-archive. +dnl +dnl - $1 option-to-check-for : required ("-option" as non-value) +dnl - $2 shell-variable-to-add-to : CFLAGS (or CXXFLAGS in the other case) +dnl - $3 action-if-found : add value to shellvariable +dnl - $4 action-if-not-found : nothing +dnl +dnl note: in earlier versions, $1-$2 were swapped. We try to detect the +dnl situation and accept a $2=~/-/ as being the old +dnl option-to-check-for. +dnl +dnl see also: AX_CFLAGS_GCC_OPTION for the widely used original +dnl variant. +dnl +dnl @category C +dnl @author Guido Draheim <guidod@gmx.de> +dnl @version 2005-01-21 +dnl @license GPLWithACException + +AC_DEFUN([AX_CFLAGS_IRIX_OPTION_OLD], [dnl +AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_irix_option_$2])dnl +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for irix/cc m4_ifval($2,$2,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_C + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-fullwarn -use_readonly_const % m4_ifval($2,$2,-option)" dnl IRIX C + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + +dnl the only difference - the LANG selection... and the default FLAGS + +AC_DEFUN([AX_CXXFLAGS_IRIX_OPTION_OLD], [dnl +AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_irix_option_$2])dnl +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for irix/cc m4_ifval($2,$2,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_CXX + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-fullwarn -use_readonly_const % m4_ifval($2,$2,-option)" dnl IRIX C + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + +dnl -------------------------------------------------------------------------- + +AC_DEFUN([AX_CFLAGS_IRIX_OPTION_NEW], [dnl +AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_irix_option_$1])dnl +AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for irix/cc m4_ifval($1,$1,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_C + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-fullwarn -use_readonly_const % m4_ifval($1,$1,-option)" dnl IRIX C + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) + m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + +dnl the only difference - the LANG selection... and the default FLAGS + +AC_DEFUN([AX_CXXFLAGS_IRIX_OPTION_NEW], [dnl +AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_irix_option_$1])dnl +AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for irix/cc m4_ifval($1,$1,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_CXX + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-fullwarn -use_readonly_const % m4_ifval($1,$1,-option)" dnl IRIX C + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) + m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + +AC_DEFUN([AX_CFLAGS_IRIX_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, +[AX_CFLAGS_IRIX_OPTION_NEW($@)],[AX_CFLAGS_IRIX_OPTION_OLD($@)])]) + +AC_DEFUN([AX_CXXFLAGS_IRIX_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, +[AX_CXXFLAGS_IRIX_OPTION_NEW($@)],[AX_CXXFLAGS_IRIX_OPTION_OLD($@)])]) diff --git a/source4/build/m4/check_cc.m4 b/source4/build/m4/check_cc.m4 new file mode 100644 index 0000000000..51531ca776 --- /dev/null +++ b/source4/build/m4/check_cc.m4 @@ -0,0 +1,157 @@ +dnl SMB Build Environment CC Checks +dnl ------------------------------------------------------- +dnl Copyright (C) Stefan (metze) Metzmacher 2004 +dnl Released under the GNU GPL +dnl ------------------------------------------------------- +dnl + +AC_LIBREPLACE_CC_CHECKS + +# +# Set the debug symbol option if we have +# --enable-*developer or --enable-debug +# and the compiler supports it +# +if test x$ac_cv_prog_cc_g = xyes -a x$debug = xyes; then + CFLAGS="${CFLAGS} -g" +fi + +############################################ +# check if the compiler handles c99 struct initialization +LIBREPLACE_C99_STRUCT_INIT(samba_cv_c99_struct_initialization=yes, + samba_cv_c99_struct_initialization=no) + +if test x"$samba_cv_c99_struct_initialization" != x"yes"; then + AC_MSG_WARN([C compiler does not support c99 struct initialization!]) + AC_MSG_ERROR([Please Install gcc from http://gcc.gnu.org/]) +fi + +############################################ +# check if the compiler can handle negative enum values +# and don't truncate the values to INT_MAX +# a runtime test is needed here +AC_CACHE_CHECK([that the C compiler understands negative enum values],samba_cv_CC_NEGATIVE_ENUM_VALUES, [ + AC_TRY_RUN( +[ + #include <stdio.h> + enum negative_values { NEGATIVE_VALUE = 0xFFFFFFFF }; + int main(void) { + enum negative_values v1 = NEGATIVE_VALUE; + unsigned v2 = 0xFFFFFFFF; + if (v1 != v2) { + printf("v1=0x%08x v2=0x%08x\n", v1, v2); + return 1; + } + return 0; + } +], + samba_cv_CC_NEGATIVE_ENUM_VALUES=yes,samba_cv_CC_NEGATIVE_ENUM_VALUES=no)]) +if test x"$samba_cv_CC_NEGATIVE_ENUM_VALUES" != x"yes"; then + AC_DEFINE(USE_UINT_ENUMS, 1, [Whether the compiler has uint enum support]) +fi + +AC_MSG_CHECKING([for test routines]) +AC_TRY_RUN([#include "${srcdir-.}/build/tests/trivial.c"], + AC_MSG_RESULT(yes), + AC_MSG_ERROR([cant find test code. Aborting config]), + AC_MSG_WARN([cannot run when cross-compiling])) + +# +# Check if the compiler support ELF visibility for symbols +# + +visibility_attribute=no +VISIBILITY_CFLAGS="" +if test x"$GCC" = x"yes" ; then + AX_CFLAGS_GCC_OPTION([-fvisibility=hidden], VISIBILITY_CFLAGS) +fi + +if test -n "$VISIBILITY_CFLAGS"; then + AC_MSG_CHECKING([whether the C compiler supports the visibility attribute]) + OLD_CFLAGS="$CFLAGS" + + CFLAGS="$CFLAGS $VISIBILITY_CFLAGS" + AC_TRY_LINK([ + void vis_foo1(void) {} + __attribute__((visibility("default"))) void vis_foo2(void) {} + ],[ + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_VISIBILITY_ATTR,1,[Whether the C compiler supports the visibility attribute]) + visibility_attribute=yes + ],[ + AC_MSG_RESULT(no) + ]) + CFLAGS="$OLD_CFLAGS" +fi +AC_SUBST(visibility_attribute) + +# +# Check if the compiler can handle the options we selected by +# --enable-*developer +# +DEVELOPER_CFLAGS="" +if test x$developer = xyes; then + OLD_CFLAGS="${CFLAGS}" + + CFLAGS="${CFLAGS} -D_SAMBA_DEVELOPER_DONNOT_USE_O2_" + DEVELOPER_CFLAGS="-DDEBUG_PASSWORD -DDEVELOPER" + if test x"$GCC" = x"yes" ; then + # + # warnings we want... + # + AX_CFLAGS_GCC_OPTION(-Wall, DEVELOPER_CFLAGS) + AX_CFLAGS_GCC_OPTION(-Wshadow, DEVELOPER_CFLAGS) + AX_CFLAGS_GCC_OPTION(-Werror-implicit-function-declaration, DEVELOPER_CFLAGS) + AX_CFLAGS_GCC_OPTION(-Wstrict-prototypes, DEVELOPER_CFLAGS) + AX_CFLAGS_GCC_OPTION(-Wpointer-arith, DEVELOPER_CFLAGS) + AX_CFLAGS_GCC_OPTION(-Wcast-qual, DEVELOPER_CFLAGS) + AX_CFLAGS_GCC_OPTION(-Wcast-align, DEVELOPER_CFLAGS) + AX_CFLAGS_GCC_OPTION(-Wwrite-strings, DEVELOPER_CFLAGS) + AX_CFLAGS_GCC_OPTION(-Wmissing-format-attribute, DEVELOPER_CFLAGS) + AX_CFLAGS_GCC_OPTION(-Wformat=2, DEVELOPER_CFLAGS) + AX_CFLAGS_GCC_OPTION(-Wdeclaration-after-statement, DEVELOPER_CFLAGS) + AX_CFLAGS_GCC_OPTION(-Wunused-macros, DEVELOPER_CFLAGS) + AX_CFLAGS_GCC_OPTION(-Wno-unused-macros, CFLAG_NO_UNUSED_MACROS) + AC_SUBST(CFLAG_NO_CAST_QUAL) + AC_SUBST(CFLAG_NO_UNUSED_MACROS) + AX_CFLAGS_GCC_OPTION(-Wno-cast-qual, CFLAG_NO_CAST_QUAL) +# AX_CFLAGS_GCC_OPTION(-Wextra, DEVELOPER_CFLAGS) +# AX_CFLAGS_GCC_OPTION(-Wc++-compat, DEVELOPER_CFLAGS) +# AX_CFLAGS_GCC_OPTION(-Wmissing-prototypes, DEVELOPER_CFLAGS) +# AX_CFLAGS_GCC_OPTION(-Wmissing-declarations, DEVELOPER_CFLAGS) +# AX_CFLAGS_GCC_OPTION(-Wmissing-field-initializers, DEVELOPER_CFLAGS) + # + # warnings we don't want... + # + AX_CFLAGS_GCC_OPTION(-Wno-format-y2k, DEVELOPER_CFLAGS) + AX_CFLAGS_GCC_OPTION(-Wno-unused-parameter, DEVELOPER_CFLAGS) + else + AX_CFLAGS_IRIX_OPTION(-fullwarn, DEVELOPER_CFLAGS) + fi + + CFLAGS="${OLD_CFLAGS}" +fi +if test -n "$DEVELOPER_CFLAGS"; then + OLD_CFLAGS="${CFLAGS}" + CFLAGS="${CFLAGS} ${DEVELOPER_CFLAGS}" + AC_MSG_CHECKING([that the C compiler can use the DEVELOPER_CFLAGS]) + AC_TRY_COMPILE([],[], + AC_MSG_RESULT(yes), + DEVELOPER_CFLAGS=""; AC_MSG_RESULT(no)) + CFLAGS="${OLD_CFLAGS}" +fi + +# allow for --with-hostcc=gcc +AC_ARG_WITH(hostcc,[ --with-hostcc=compiler choose host compiler], +[HOSTCC=$withval], +[ +if test z"$cross_compiling" = "yes"; then + HOSTCC=cc +else + HOSTCC=$CC +fi +]) +AC_SUBST(HOSTCC) + +AC_PATH_PROG(GCOV,gcov) diff --git a/source4/build/m4/check_doc.m4 b/source4/build/m4/check_doc.m4 new file mode 100644 index 0000000000..2aaf9596de --- /dev/null +++ b/source4/build/m4/check_doc.m4 @@ -0,0 +1 @@ +AC_PATH_PROG(XSLTPROC, xsltproc) diff --git a/source4/build/m4/check_ld.m4 b/source4/build/m4/check_ld.m4 new file mode 100644 index 0000000000..3a74ffc239 --- /dev/null +++ b/source4/build/m4/check_ld.m4 @@ -0,0 +1,187 @@ +dnl SMB Build Environment LD Checks +dnl ------------------------------------------------------- +dnl Copyright (C) Stefan (metze) Metzmacher 2004 +dnl Copyright (C) Jelmer Vernooij 2006 +dnl Released under the GNU GPL +dnl ------------------------------------------------------- +dnl + +AC_PATH_PROG(PROG_LD,ld) +LD=${PROG_LD} +AC_PROG_LD_GNU +LD="" + +AC_SUBST(BLDSHARED) +AC_SUBST(LD) +AC_SUBST(SYS_LDFLAGS) +AC_SUBST(LDFLAGS) + +# Assume non-shared by default and override below +# these are the defaults, good for lots of systems +BLDSHARED="false" +LD="${CC}" +PICFLAG="" + +# allow for --with-hostld=gcc +AC_ARG_WITH(hostld,[ --with-hostld=linker choose host linker], +[HOSTLD=$withval], +[HOSTLD=$HOSTCC]) + +AC_MSG_CHECKING([whether to try to build shared libraries on $host_os]) + +# and these are for particular systems +case "$host_os" in + *linux*) + BLDSHARED="true" + SYS_LDFLAGS="-Wl,--export-dynamic" + ;; + *solaris*) + BLDSHARED="true" + if test "${GCC}" = "yes"; then + if test "${ac_cv_prog_gnu_ld}" = "yes"; then + SYS_LDFLAGS="-Wl,-E" + fi + fi + ;; + *sunos*) + BLDSHARED="true" + ;; + *netbsd* | *freebsd* | *dragonfly* ) + BLDSHARED="true" + SYS_LDFLAGS="-Wl,--export-dynamic" + ;; + *openbsd*) + BLDSHARED="true" + SYS_LDFLAGS="-Wl,-Bdynamic" + ;; + *irix*) + BLDSHARED="true" + ;; + *aix*) + BLDSHARED="true" + SYS_LDFLAGS="-Wl,-brtl,-bexpall,-bbigtoc" + ;; + *hpux*) + # Use special PIC flags for the native HP-UX compiler. + BLDSHARED="true" # I hope this is correct + if test "$host_cpu" = "ia64"; then + SYS_LDFLAGS="-Wl,-E,+b/usr/local/lib/hpux32:/usr/lib/hpux32" + else + SYS_LDFLAGS="-Wl,-E,+b/usr/local/lib:/usr/lib" + fi + ;; + *osf*) + BLDSHARED="true" + ;; + *unixware*) + BLDSHARED="true" + ;; + *darwin*) + BLDSHARED="true" + ;; +esac + +AC_MSG_RESULT($BLDSHARED) + +AC_MSG_CHECKING([LD]) +AC_MSG_RESULT([$LD]) +AC_MSG_CHECKING([LDFLAGS]) +AC_MSG_RESULT([$LDFLAGS]) +AC_MSG_CHECKING([SYS_LDFLAGS]) +AC_MSG_RESULT([$SYS_LDFLAGS]) + +AC_SUBST(HOSTLD) + +AC_LIBREPLACE_STLD +AC_LIBREPLACE_STLD_FLAGS + +AC_MSG_CHECKING([STLD]) +AC_MSG_RESULT([$STLD]) +AC_MSG_CHECKING([STLD_FLAGS]) +AC_MSG_RESULT([$STLD_FLAGS]) + +AC_LD_PICFLAG +AC_LD_EXPORT_DYNAMIC +AC_LD_SHLIBEXT +AC_LD_SONAMEFLAG +AC_LIBREPLACE_SHLD +AC_LIBREPLACE_SHLD_FLAGS +AC_LIBREPLACE_MDLD +AC_LIBREPLACE_MDLD_FLAGS +AC_LIBREPLACE_RUNTIME_LIB_PATH_VAR + +####################################################### +# test whether building a shared library actually works +if test $BLDSHARED = true; then + + AC_MSG_CHECKING([SHLD]) + AC_MSG_RESULT([$SHLD]) + AC_MSG_CHECKING([SHLD_FLAGS]) + AC_MSG_RESULT([$SHLD_FLAGS]) + + AC_MSG_CHECKING([MDLD]) + AC_MSG_RESULT([$MDLD]) + AC_MSG_CHECKING([MDLD_FLAGS]) + AC_MSG_RESULT([$MDLD_FLAGS]) + + AC_MSG_CHECKING([SHLIBEXT]) + AC_MSG_RESULT([$SHLIBEXT]) + AC_MSG_CHECKING([SONAMEFLAG]) + AC_MSG_RESULT([$SONAMEFLAG]) + + AC_MSG_CHECKING([PICFLAG]) + AC_MSG_RESULT([$PICFLAG]) + + AC_CACHE_CHECK([whether building shared libraries actually works], + [ac_cv_shlib_works],[ + ac_cv_shlib_works=no + # try building a trivial shared library + # TODO: also test SONAMEFLAG + ${CC} ${CFLAGS} ${PICFLAG} -c ${srcdir-.}/build/tests/shlib.c -o shlib.o && + ${SHLD} ${SHLD_FLAGS} -o shlib.${SHLIBEXT} shlib.o && + ac_cv_shlib_works=yes + rm -f shlib.${SHLIBEXT} shlib.o + ]) + AC_CACHE_CHECK([whether building shared modules actually works], + [ac_cv_shmod_works],[ + ac_cv_shmod_works=no + # try building a trivial shared library + ${CC} ${CFLAGS} ${PICFLAG} -c ${srcdir-.}/build/tests/shlib.c -o shlib.o && + ${MDLD} ${MDLD_FLAGS} -o shlib.${SHLIBEXT} shlib.o && + ac_cv_shmod_works=yes + rm -f shlib.${SHLIBEXT} shlib.o + ]) + if test $ac_cv_shlib_works = no; then + AC_MSG_ERROR(unable to build shared libraries) + fi + if test $ac_cv_shmod_works = no; then + AC_MSG_ERROR(unable to build shared modules) + fi +fi + +AC_DEFINE_UNQUOTED(SHLIBEXT, "$SHLIBEXT", [Shared library extension]) + +AC_MSG_CHECKING([if we can link using the selected flags]) +AC_TRY_RUN([#include "${srcdir-.}/build/tests/trivial.c"], + AC_MSG_RESULT(yes), + AC_MSG_ERROR([we cannot link with the selected cc and ld flags. Aborting configure]), + AC_MSG_WARN([cannot run when cross-compiling])) + + +USESHARED=false +AC_SUBST(USESHARED) + +AC_ARG_ENABLE(dso, +[ --enable-dso Enable using shared libraries internally (experimental)], +[],[enable_dso=no]) + +if test x"$enable_dso" = x"yes" -a x"$BLDSHARED" != x"true"; then + AC_MSG_ERROR([--enable-dso: no support for shared libraries]) +fi + +if test x"$enable_dso" != x"no"; then + USESHARED=$BLDSHARED +fi + +AC_MSG_CHECKING([if binaries will use shared libraries]) +AC_MSG_RESULT([$USESHARED]) diff --git a/source4/build/m4/check_make.m4 b/source4/build/m4/check_make.m4 new file mode 100644 index 0000000000..f497684453 --- /dev/null +++ b/source4/build/m4/check_make.m4 @@ -0,0 +1,39 @@ +dnl SMB Build Environment make Checks +dnl ------------------------------------------------------- +dnl Copyright (C) Stefan (metze) Metzmacher 2004 +dnl Copyright (C) Jelmer Vernooij 2005 +dnl Released under the GNU GPL +dnl ------------------------------------------------------- +dnl + +AC_PATH_PROGS(MAKE,gmake make) + +AC_CACHE_CHECK([whether we have GNU make], samba_cv_gnu_make, [ +if ! $ac_cv_path_MAKE --version | head -1 | grep GNU 2>/dev/null >/dev/null +then + AC_MSG_ERROR([Unable to find GNU make]) +fi +]) + +AC_CACHE_CHECK([GNU make version], samba_cv_gnu_make_version,[ + samba_cv_gnu_make_version=`$ac_cv_path_MAKE --version | head -1 | cut -d " " -f 3 2>/dev/null` + ]) + GNU_MAKE_VERSION=$samba_cv_gnu_make_version + AC_SUBST(GNU_MAKE_VERSION) + + +new_make=no +AC_MSG_CHECKING([for GNU make >= 3.81]) +if $PERL -e " \$_ = '$GNU_MAKE_VERSION'; s/@<:@^\d\.@:>@.*//g; exit (\$_ < 3.81);"; then + new_make=yes +fi +AC_MSG_RESULT($new_make) +automatic_dependencies=no +AX_CFLAGS_GCC_OPTION([-M -MT conftest.d -MF conftest.o], [], [ automatic_dependencies=$new_make ], []) +AC_MSG_CHECKING([Whether to use automatic dependencies]) +AC_ARG_ENABLE(automatic-dependencies, +[ --enable-automatic-dependencies Enable automatic dependencies], +[ automatic_dependencies=$enableval ], +[ automatic_dependencies=no ]) +AC_MSG_RESULT($automatic_dependencies) +AC_SUBST(automatic_dependencies) diff --git a/source4/build/m4/check_path.m4 b/source4/build/m4/check_path.m4 new file mode 100644 index 0000000000..c45a803633 --- /dev/null +++ b/source4/build/m4/check_path.m4 @@ -0,0 +1,207 @@ +dnl SMB Build Environment Path Checks +dnl ------------------------------------------------------- +dnl Copyright (C) Stefan (metze) Metzmacher 2004 +dnl Released under the GNU GPL +dnl ------------------------------------------------------- +dnl + +AC_LIBREPLACE_LOCATION_CHECKS + +################################################# +# Directory handling stuff to support both the +# legacy SAMBA directories and FHS compliant +# ones... +AC_PREFIX_DEFAULT(/usr/local/samba) + +# Defaults and --without-fhs +logfilebase="${localstatedir}" +lockdir="${localstatedir}/locks" +piddir="${localstatedir}/run" +privatedir="\${prefix}/private" +modulesdir="\${prefix}/modules" +winbindd_socket_dir="${localstatedir}/run/winbindd" +winbindd_privileged_socket_dir="${localstatedir}/lib/winbindd_privileged" +ntp_signd_socket_dir="${localstatedir}/run/ntp_signd" + +AC_ARG_WITH(fhs, +[AS_HELP_STRING([--with-fhs],[Use FHS-compliant paths (default=no)])], + lockdir="${localstatedir}/lib/samba" + piddir="${localstatedir}/run/samba" + logfilebase="${localstatedir}/log/samba" + privatedir="${localstatedir}/lib/samba/private" + sysconfdir="${sysconfdir}/samba" + modulesdir="${libdir}/samba" + datadir="${datadir}/samba" + includedir="${includedir}/samba-4.0" + ntp_signd_socket_dir="${localstatedir}/run/samba/ntp_signd" + winbindd_socket_dir="${localstatedir}/run/samba/winbindd" + winbindd_privileged_socket_dir="${localstatedir}/lib/samba/winbindd_privileged" +) + +################################################# +# set private directory location +AC_ARG_WITH(privatedir, +[AS_HELP_STRING([--with-privatedir=DIR],[Where to put sam.ldb and other private files containing key material ($ac_default_prefix/private)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-privatedir called without argument - will use default]) + ;; + * ) + privatedir="$withval" + ;; + esac]) + +################################################# +# set where the winbindd socket should be put +AC_ARG_WITH(winbindd-socket-dir, +[AS_HELP_STRING([--with-winbindd-socket-dir=DIR],[Where to put the winbindd socket ($winbindd_socket_dir)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-winbind-socketdir called without argument - will use default]) + ;; + * ) + winbindd_socket_dir="$withval" + ;; + esac]) + +################################################# +# set where the winbindd privilaged socket should be put +AC_ARG_WITH(winbindd-privileged-socket-dir, +[AS_HELP_STRING([--with-winbindd-privileged-socket-dir=DIR],[Where to put the winbindd socket ($winbindd_privileged_socket_dir)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-winbind-privileged-socketdir called without argument - will use default]) + ;; + * ) + winbindd_privileged_socket_dir="$withval" + ;; + esac]) + +################################################# +# set where the NTP signing deamon socket should be put +AC_ARG_WITH(ntp-signd-socket-dir, +[AS_HELP_STRING([--with-ntp-signd-socket-dir=DIR],[Where to put the NTP signing deamon socket ($ac_default_prefix/run/ntp_signd)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-ntp-signd-socketdir called without argument - will use default]) + ;; + * ) + ntp_signd_socket_dir="$withval" + ;; + esac]) + +################################################# +# set lock directory location +AC_ARG_WITH(lockdir, +[AS_HELP_STRING([--with-lockdir=DIR],[Where to put lock files ($ac_default_prefix/var/locks)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-lockdir called without argument - will use default]) + ;; + * ) + lockdir="$withval" + ;; + esac]) + +################################################# +# set pid directory location +AC_ARG_WITH(piddir, +[AS_HELP_STRING([--with-piddir=DIR],[Where to put pid files ($ac_default_prefix/var/locks)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-piddir called without argument - will use default]) + ;; + * ) + piddir="$withval" + ;; + esac]) + +################################################# +# set log directory location +AC_ARG_WITH(logfilebase, +[AS_HELP_STRING([--with-logfilebase=DIR],[Where to put log files (\$(VARDIR))])], +[ case "$withval" in + yes|no) + # + # Just in case anybody does it + # + AC_MSG_WARN([--with-logfilebase called without argument - will use default]) + ;; + * ) + logfilebase="$withval" + ;; + esac]) + + +AC_SUBST(lockdir) +AC_SUBST(piddir) +AC_SUBST(logfilebase) +AC_SUBST(privatedir) +AC_SUBST(bindir) +AC_SUBST(sbindir) +AC_SUBST(winbindd_socket_dir) +AC_SUBST(winbindd_privileged_socket_dir) +AC_SUBST(ntp_signd_socket_dir) +AC_SUBST(modulesdir) + +################################################# +# set prefix for 'make test' +# this is needed to workarround the 108 char +# unix socket path limitation! +# +selftest_prefix="./st" +AC_SUBST(selftest_prefix) +AC_ARG_WITH(selftest-prefix, +[AS_HELP_STRING([--with-selftest-prefix=DIR],[The prefix where make test will be run ($selftest_prefix)])], +[ case "$withval" in + yes|no) + AC_MSG_WARN([--with-selftest-prefix called without argument - will use default]) + ;; + * ) + selftest_prefix="$withval" + ;; + esac]) + +debug=no +AC_ARG_ENABLE(debug, +[AS_HELP_STRING([--enable-debug],[Turn on compiler debugging information (default=no)])], + [if test x$enable_debug = xyes; then + debug=yes + fi]) + +developer=no +AC_SUBST(developer) +AC_ARG_ENABLE(developer, +[AS_HELP_STRING([--enable-developer],[Turn on developer warnings and debugging (default=no)])], + [if test x$enable_developer = xyes; then + debug=yes + developer=yes + fi]) + +dnl disable these external libs +AC_ARG_WITH(disable-ext-lib, +[AS_HELP_STRING([--with-disable-ext-lib=LIB],[Comma-seperated list of external libraries])], +[ if test $withval; then + for i in `echo $withval | sed -e's/,/ /g'` + do + eval SMB_$i=NO + done +fi ]) diff --git a/source4/build/m4/check_perl.m4 b/source4/build/m4/check_perl.m4 new file mode 100644 index 0000000000..82ca242499 --- /dev/null +++ b/source4/build/m4/check_perl.m4 @@ -0,0 +1,28 @@ +dnl SMB Build Environment Perl Checks +dnl ------------------------------------------------------- +dnl Copyright (C) Stefan (metze) Metzmacher 2004 +dnl Released under the GNU GPL +dnl ------------------------------------------------------- +dnl + +case "$host_os" in + *irix*) + # On IRIX, we prefer Freeware or Nekoware Perl, because the + # system perl is so ancient. + AC_PATH_PROG(PERL, perl, "", "/usr/freeware/bin:/usr/nekoware/bin:$PATH") + ;; + *) + AC_PATH_PROG(PERL, perl) + ;; +esac + +if test x"$PERL" = x""; then + AC_MSG_WARN([No version of perl was found!]) + AC_MSG_ERROR([Please install perl from http://www.perl.com/]) +fi +if test x"$debug" = x"yes";then + PERL="$PERL -W" +fi +export PERL + +AC_PATH_PROG(YAPP, yapp, false) diff --git a/source4/build/m4/env.m4 b/source4/build/m4/env.m4 new file mode 100644 index 0000000000..6c040b9bab --- /dev/null +++ b/source4/build/m4/env.m4 @@ -0,0 +1,46 @@ +dnl SMB Build Environment Checks +dnl ------------------------------------------------------- +dnl Copyright (C) Stefan (metze) Metzmacher 2004 +dnl Released under the GNU GPL +dnl ------------------------------------------------------- +dnl + +AC_SUBST(srcdir) +export srcdir; + +# we always set builddir to "." as that's nicer than +# having the absolute path of the current work directory +builddir=. +AC_SUBST(builddir) +export builddir; + +AC_SUBST(datarootdir) + +AC_SUBST(VPATH) +VPATH="\$(builddir):\$(srcdir)" + +SMB_VERSION_STRING=`cat ${srcdir}/version.h | grep 'SAMBA_VERSION_OFFICIAL_STRING' | cut -d '"' -f2` +echo "SAMBA VERSION: ${SMB_VERSION_STRING}" + +SAMBA_VERSION_GIT_COMMIT_FULLREV=`cat ${srcdir}/version.h | grep 'SAMBA_VERSION_GIT_COMMIT_FULLREV' | cut -d ' ' -f3- | cut -d '"' -f2` +if test -n "${SAMBA_VERSION_GIT_COMMIT_FULLREV}";then + echo "BUILD COMMIT REVISION: ${SAMBA_VERSION_GIT_COMMIT_FULLREV}" +fi +SAMBA_VERSION_GIT_COMMIT_DATE=`cat ${srcdir}/version.h | grep 'SAMBA_VERSION_GIT_COMMIT_DATE' | cut -d ' ' -f3-` +if test -n "${SAMBA_VERSION_GIT_COMMIT_DATE}";then + echo "BUILD COMMIT DATE: ${SAMBA_VERSION_GIT_COMMIT_DATE}" +fi +SAMBA_VERSION_GIT_COMMIT_TIME=`cat ${srcdir}/version.h | grep 'SAMBA_VERSION_GIT_COMMIT_TIME' | cut -d ' ' -f3-` +if test -n "${SAMBA_VERSION_GIT_COMMIT_TIME}";then + echo "BUILD COMMIT TIME: ${SAMBA_VERSION_GIT_COMMIT_TIME}" + + # just to keep the build-farm gui happy for now... + echo "BUILD REVISION: ${SAMBA_VERSION_GIT_COMMIT_TIME}" +fi + +m4_include(build/m4/check_path.m4) +m4_include(build/m4/check_perl.m4) +m4_include(build/m4/check_cc.m4) +m4_include(build/m4/check_ld.m4) +m4_include(build/m4/check_make.m4) +m4_include(build/m4/check_doc.m4) diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4 new file mode 100644 index 0000000000..d61e00b22e --- /dev/null +++ b/source4/build/m4/public.m4 @@ -0,0 +1,229 @@ +dnl SMB Build System +dnl ---------------- +dnl Copyright (C) 2004 Stefan Metzmacher +dnl Copyright (C) 2004-2005 Jelmer Vernooij +dnl Published under the GPL +dnl +dnl SMB_EXT_LIB_FROM_PKGCONFIG(name,pkg-config name,[ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) +dnl +dnl SMB_EXT_LIB(name,libs,cflags,cppflags,ldflags) +dnl +dnl SMB_ENABLE(name,default_build) +dnl +dnl SMB_INCLUDE_MK(file) +dnl +dnl SMB_WRITE_MAKEVARS(file) +dnl +dnl SMB_WRITE_PERLVARS(file) +dnl +dnl ####################################################### +dnl ### And now the implementation ### +dnl ####################################################### + +dnl SMB_SUBSYSTEM(name,obj_files,required_subsystems,cflags) +AC_DEFUN([SMB_SUBSYSTEM], +[ +MAKE_SETTINGS="$MAKE_SETTINGS +$1_CFLAGS = $4 +$1_ENABLE = YES +$1_OBJ_FILES = $2 +" + +SMB_INFO_SUBSYSTEMS="$SMB_INFO_SUBSYSTEMS +################################### +# Start Subsystem $1 +@<:@SUBSYSTEM::$1@:>@ +PRIVATE_DEPENDENCIES = $3 +CFLAGS = \$($1_CFLAGS) +ENABLE = YES +# End Subsystem $1 +################################### +" +]) + +dnl SMB_LIBRARY(name,obj_files,required_subsystems,cflags,ldflags) +AC_DEFUN([SMB_LIBRARY], +[ +MAKE_SETTINGS="$MAKE_SETTINGS +$1_CFLAGS = $6 +$1_LDFLAGS = $7 +n1_ENABLE = YES +$1_OBJ_FILES = $2 +" + +SMB_INFO_LIBRARIES="$SMB_INFO_LIBRARIES +################################### +# Start Library $1 +@<:@LIBRARY::$1@:>@ +PRIVATE_DEPENDENCIES = $3 +CFLAGS = \$($1_CFLAGS) +LDFLAGS = \$($1_LDFLAGS) +ENABLE = YES +# End Library $1 +################################### +" +]) + +dnl SMB_EXT_LIB_FROM_PKGCONFIG(name,pkg-config name,[ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) +AC_DEFUN([SMB_EXT_LIB_FROM_PKGCONFIG], +[ + dnl Figure out the correct variables and call SMB_EXT_LIB() + + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://pkg-config.freedesktop.org/ to get pkg-config." + ac_cv_$1_found=no + else + if $PKG_CONFIG --atleast-pkgconfig-version 0.9.0; then + AC_MSG_CHECKING(for $2) + + if $PKG_CONFIG --exists '$2' ; then + AC_MSG_RESULT(yes) + + $1_CFLAGS="`$PKG_CONFIG --cflags '$2'`" + OLD_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $$1_CFLAGS" + AC_MSG_CHECKING([that the C compiler can use the $1_CFLAGS]) + AC_TRY_RUN([#include "${srcdir-.}/build/tests/trivial.c"], + SMB_ENABLE($1, YES) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no), + AC_MSG_WARN([cannot run when cross-compiling])) + CFLAGS="$OLD_CFLAGS" + + SMB_EXT_LIB($1, + [`$PKG_CONFIG --libs-only-l '$2'`], + [`$PKG_CONFIG --cflags-only-other '$2'`], + [`$PKG_CONFIG --cflags-only-I '$2'`], + [`$PKG_CONFIG --libs-only-other '$2'` `$PKG_CONFIG --libs-only-L '$2'`]) + ac_cv_$1_found=yes + + else + AC_MSG_RESULT(no) + $PKG_CONFIG --errors-to-stdout --print-errors '$2' + ac_cv_$1_found=no + fi + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://pkg-config.freedesktop.org/" + ac_cv_$1_found=no + fi + fi + if test x$ac_cv_$1_found = x"yes"; then + ifelse([$3], [], [echo -n ""], [$3]) + else + ifelse([$4], [], [ + SMB_EXT_LIB($1) + SMB_ENABLE($1, NO) + ], [$4]) + fi +]) + +dnl SMB_INCLUDE_MK(file) +AC_DEFUN([SMB_INCLUDE_MK], +[ +SMB_INFO_EXT_LIBS="$SMB_INFO_EXT_LIBS +mkinclude $1 +" +]) + +dnl SMB_EXT_LIB(name,libs,cflags,cppflags,ldflags) +AC_DEFUN([SMB_EXT_LIB], +[ +MAKE_SETTINGS="$MAKE_SETTINGS +$1_LIBS = $2 +$1_CFLAGS = $3 +$1_CPPFLAGS = $4 +$1_LDFLAGS = $5 +" + +]) + +dnl SMB_ENABLE(name,default_build) +AC_DEFUN([SMB_ENABLE], +[ + MAKE_SETTINGS="$MAKE_SETTINGS +$1_ENABLE = $2 +" +SMB_INFO_ENABLES="$SMB_INFO_ENABLES +\$enabled{$1} = \"$2\";" +]) + +dnl SMB_WRITE_MAKEVARS(path, skip_vars) +AC_DEFUN([SMB_WRITE_MAKEVARS], +[ +echo "configure: creating $1" +cat >$1<<CEOF +# $1 - Autogenerated by configure, DO NOT EDIT! +$MAKE_SETTINGS +CEOF +skip_vars=" $2 " +for ac_var in $ac_subst_vars +do + eval ac_val=\$$ac_var + if echo "$skip_vars" | grep -v " $ac_var " >/dev/null 2>/dev/null; then + echo "$ac_var = $ac_val" >> $1 + fi +done +]) + +dnl SMB_WRITE_PERLVARS(path) +AC_DEFUN([SMB_WRITE_PERLVARS], +[ +echo "configure: creating $1" +cat >$1<<CEOF +# config.pm - Autogenerate by configure. DO NOT EDIT! + +package config; +require Exporter; +@ISA = qw(Exporter); +@EXPORT_OK = qw(%enabled %config); +use strict; + +use vars qw(%enabled %config); + +%config = (AC_FOREACH([AC_Var], m4_defn([_AC_SUBST_VARS]), [ + AC_Var => '$AC_Var',]) +); + +$SMB_INFO_ENABLES +1; +CEOF +]) + +dnl SMB_BUILD_RUN(OUTPUT_FILE) +AC_DEFUN([SMB_BUILD_RUN], +[ +AC_OUTPUT_COMMANDS( +[ +test "x$ac_abs_srcdir" != "x$ac_abs_builddir" && ( + cd $builddir; + # NOTE: We *must* use -R so we don't follow symlinks (at least on BSD + # systems). + test -d heimdal || cp -R $srcdir/heimdal $builddir/ + test -d heimdal_build || cp -R $srcdir/heimdal_build $builddir/ + test -d build || builddir="$builddir" \ + srcdir="$srcdir" \ + $PERL ${srcdir}/script/buildtree.pl + ) + +$PERL -I${builddir} -I${builddir}/build \ + -I${srcdir} -I${srcdir}/build \ + ${srcdir}/build/smb_build/main.pl --output=$1 main.mk || exit $? +], +[ +srcdir="$srcdir" +builddir="$builddir" +PERL="$PERL" + +export PERL +export srcdir +export builddir +]) +]) diff --git a/source4/build/make/lex_compile.sh b/source4/build/make/lex_compile.sh new file mode 100755 index 0000000000..d05056d100 --- /dev/null +++ b/source4/build/make/lex_compile.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +LEX="$1" +SRC="$2" +DEST="$3" +shift 3 +ARGS="$*" + +dir=`dirname $SRC` +file=`basename $SRC` +base=`basename $SRC .l` +if [ -z "$LEX" ]; then + # if $DEST is more recent than $SRC, we can just touch + # otherwise we touch but print out warnings + if [ -r $DEST ]; then + if [ x`find $SRC -newer $DEST -print` = x$SRC ]; then + echo "warning: lex not found - cannot generate $SRC => $DEST" >&2 + echo "warning: lex not found - only updating the timestamp of $DEST" >&2 + fi + touch $DEST; + exit; + fi + echo "error: lex not found - cannot generate $SRC => $DEST" >&2 + exit 1; +fi +# if $DEST is more recent than $SRC, we can just touch +if [ -r $DEST ]; then + if [ x`find $SRC -newer $DEST -print` != x$SRC ]; then + touch $DEST; + exit; + fi +fi +TOP=`pwd` +echo "info: running $LEX $ARGS $file" +if cd $dir && $LEX $ARGS $file; then + if [ -r lex.yy.c ];then + # we must guarantee that config.h comes first + echo "info: move lex.yy.c to $base.c" + echo "#include \"config.h\"" > $base.c + sed -e "s|lex\.yy\.c|$DEST|" lex.yy.c >> $base.c + rm -f $base.yy.c + elif [ -r $base.yy.c ];then + # we must guarantee that config.h comes first + echo "info: move $base.yy.c to $base.c" + echo "#include \"config.h\"" > $base.c + sed -e "s|$base\.yy\.c|$DEST|" $base.yy.c >> $base.c + rm -f $base.yy.c + elif [ -r $base.c ];then + # we must guarantee that config.h comes first + echo "info: add #include \"config.h\" to $base.c" + mv $base.c $base.c.tmp + echo "#include \"config.h\"" > $base.c + sed -e "s|$base\.yy\.c|$DEST|" $base.c.tmp >> $base.c + rm -f $base.c.tmp + elif [ ! -r base.c ]; then + echo "$base.c nor $base.yy.c nor lex.yy.c generated." + exit 1 + fi +fi +cd $TOP diff --git a/source4/build/make/python.mk b/source4/build/make/python.mk new file mode 100644 index 0000000000..66e5def8f0 --- /dev/null +++ b/source4/build/make/python.mk @@ -0,0 +1,66 @@ +pythonbuilddir = $(builddir)/bin/python + +installpython:: + mkdir -p $(DESTDIR)$(pythondir) + +# Install Python +# Arguments: Module path +define python_module_template + +installpython:: $$(pythonbuilddir)/$(1) ; + mkdir -p $$(DESTDIR)$$(pythondir)/$$(dir $(1)) + cp $$< $$(DESTDIR)$$(pythondir)/$(1) + +uninstallpython:: + rm -f $$(DESTDIR)$$(pythondir)/$(1) ; + +pythonmods:: $$(pythonbuilddir)/$(1) ; + +endef + +define python_py_module_template + +$$(pythonbuilddir)/$(1): $(2) ; + mkdir -p $$(@D) + cp $$< $$@ + +$(call python_module_template,$(1)) + +endef + +# Python C module +# Arguments: File name, dependencies, link list +define python_c_module_template + +$$(pythonbuilddir)/$(1): $(2) ; + @echo Linking $$@ + @mkdir -p $$(@D) + @$$(MDLD) $$(LDFLAGS) $$(MDLD_FLAGS) $$(INTERN_LDFLAGS) -o $$@ $$(INSTALL_LINK_FLAGS) $(3) + +$(call python_module_template,$(1)) +endef + +# Swig extensions +swig:: pythonmods + +.SUFFIXES: _wrap.c .i .py + +%_wrap.c %.py: %.i + [ "$(SWIG)" == "no" ] || $(SWIG) -O -Wall -I$(srcdir)/scripting/swig -python -keyword $< + +realdistclean:: + @echo "Removing SWIG output files" + # FIXME: Remove _wrap.c files + +pythonmods:: + +clean:: + @echo "Removing python modules" + @rm -rf $(pythonbuilddir) + +pydoctor:: pythonmods + LD_LIBRARY_PATH=bin/shared PYTHONPATH=$(pythonbuilddir) pydoctor --project-name=Samba --project-url=http://www.samba.org --make-html --docformat=restructuredtext --add-package $(pythonbuilddir)/samba + +bin/python/%.py: + mkdir -p $(@D) + cp $< $@ diff --git a/source4/build/make/rules.mk b/source4/build/make/rules.mk new file mode 100644 index 0000000000..0beb0e2e11 --- /dev/null +++ b/source4/build/make/rules.mk @@ -0,0 +1,189 @@ +# Rules file for Samba 4 +# This relies on GNU make. +# +# Dependencies command +DEPENDS = $(CC) -M -MG -MP -MT $(<:.c=.o) -MT $@ -MT : \ + $(CFLAGS) $(CPPFLAGS) $< -o $@ +# Dependencies for host objects +HDEPENDS = $(CC) -M -MG -MP -MT $(<:.c=.ho) -MT $@ -MT : \ + $(HOSTCC_FLAGS) $(CPPFLAGS) $< -o $@ +# Dependencies for precompiled headers +PCHDEPENDS = $(CC) -M -MG -MT include/includes.h.gch -MT $@ \ + $(CFLAGS) $(CPPFLAGS) $< -o $@ + +# Run a static analysis checker +CHECK = $(CC_CHECKER) $(CFLAGS) $(PICFLAG) $(CPPLAGS) -c $< -o $@ + +# Run the configured compiler +COMPILE = $(CC) $(CFLAGS) $(PICFLAG) \ + $(CPPFLAGS) \ + -c $< -o $@ + +# Run the compiler for the build host +HCOMPILE = $(HOSTCC) $(HOSTCC_FLAGS) $(CPPFLAGS) -c $< -o $@ + +# Precompile headers +PCHCOMPILE = @$(CC) -Ilib/replace \ + $(CFLAGS) $(PICFLAG) $(CPPFLAGS) -c $< -o $@ + +# Partial linking +PARTLINK = @$(PROG_LD) -r + +make_utility_dir = $(srcdir)/build/make/ + +include/config.h: + @echo "include/config.h not present" + @echo "You need to rerun ./autogen.sh and ./configure" + @/bin/false + +pch:: + +clean:: clean_pch + @echo Removing objects + @-find . -name '*.o' -exec rm -f '{}' \; + @echo Removing hostcc objects + @-find . -name '*.ho' -exec rm -f '{}' \; + @echo Removing libraries + @-rm -f $(STATIC_LIBS) $(SHARED_LIBS) + @-rm -f bin/static/*.a bin/shared/*.$(SHLIBEXT) bin/mergedobj/*.o + @echo Removing modules + @-rm -f bin/modules/*/*.$(SHLIBEXT) + @-rm -f bin/*_init_module.c + @echo Removing dummy targets + @-rm -f bin/.*_* + @echo Removing generated files + @-rm -f bin/*_init_module.c + @-rm -rf librpc/gen_* + +distclean:: clean + -rm -f include/config.h include/config_tmp.h include/build.h + -rm -f data.mk + -rm -f config.status + -rm -f config.log config.cache + -rm -f config.pm config.mk + -rm -f $(PC_FILES) + +removebackup:: + -rm -f *.bak *~ */*.bak */*~ */*/*.bak */*/*~ */*/*/*.bak */*/*/*~ + +realdistclean:: distclean removebackup + -rm -f include/config_tmp.h.in + -rm -f version.h + -rm -f configure + -rm -f $(MANPAGES) + +check:: test + +unused_macros: + $(srcdir)/script/find_unused_macros.pl `find . -name "*.[ch]"` | sort + +# Create a static library +%.a: + @echo Linking $@ + @rm -f $@ + @mkdir -p $(@D) + @$(STLD) $(STLD_FLAGS) $@ $^ + +include $(make_utility_dir)/templates.mk + +############################################################################### +# File types +############################################################################### + +.SUFFIXES: .x .c .et .y .l .d .o .h .h.gch .a .$(SHLIBEXT) .1 .1.xml .3 .3.xml .5 .5.xml .7 .7.xml .8 .8.xml .ho .idl .hd + +.c.d: + @echo "Generating dependencies for $<" + @$(DEPENDS) + +.c.hd: + @echo "Generating host-compiler dependencies for $<" + @$(HDEPENDS) + +include/includes.d: include/includes.h + @echo "Generating dependencies for $<" + @$(PCHDEPENDS) + +.c.o: + @if test -n "$(CC_CHECKER)"; then \ + echo "Checking $< with '$(CC_CHECKER)'"; \ + $(CHECK) ; \ + fi + @echo "Compiling $<" + @-mkdir -p `dirname $@` + @$(COMPILE) && exit 0 ; \ + echo "The following command failed:" 1>&2;\ + echo "$(subst ",\",$(COMPILE))" 1>&2 && exit 1 + + +.c.ho: + @echo "Compiling $< with host compiler" + @-mkdir -p `dirname $@` + @$(HCOMPILE) && exit 0;\ + echo "The following command failed:" 1>&2;\ + echo "$(subst ",\",$(HCOMPILE))" 1>&2;\ + $(HCOMPILE) >/dev/null 2>&1 + +.h.h.gch: + @echo "Precompiling $<" + @$(PCHCOMPILE) + +.y.c: + @echo "Building $< with $(YACC)" + @-$(make_utility_dir)/yacc_compile.sh "$(YACC)" "$<" "$@" + +.l.c: + @echo "Building $< with $(LEX)" + @-$(make_utility_dir)/lex_compile.sh "$(LEX)" "$<" "$@" + +%.a: + @echo Linking $@ + @rm -f $@ + @mkdir -p $(@D) + @$(STLD) $(STLD_FLAGS) $@ $^ + + +DOCBOOK_MANPAGE_URL = http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl + +.1.xml.1: + $(XSLTPROC) -o $@ $(DOCBOOK_MANPAGE_URL) $< + +.3.xml.3: + $(XSLTPROC) -o $@ $(DOCBOOK_MANPAGE_URL) $< + +.5.xml.5: + $(XSLTPROC) -o $@ $(DOCBOOK_MANPAGE_URL) $< + +.7.xml.7: + $(XSLTPROC) -o $@ $(DOCBOOK_MANPAGE_URL) $< + +.8.xml.8: + $(XSLTPROC) -o $@ $(DOCBOOK_MANPAGE_URL) $< + +dist:: idl_full manpages configure distclean + +configure: + ./autogen.sh + +showflags:: + @echo 'Samba will be compiled with flags:' + @echo ' CPP = $(CPP)' + @echo ' CPPFLAGS = $(CPPFLAGS)' + @echo ' CC = $(CC)' + @echo ' CFLAGS = $(CFLAGS)' + @echo ' PICFLAG = $(PICFLAG)' + @echo ' BNLD = $(BNLD)' + @echo ' BNLD_FLAGS = $(BNLD_FLAGS)' + @echo ' STLD = $(STLD)' + @echo ' STLD_FLAGS = $(STLD_FLAGS)' + @echo ' SHLD = $(SHLD)' + @echo ' SHLD_FLAGS = $(SHLD_FLAGS)' + @echo ' MDLD = $(MDLD)' + @echo ' MDLD_FLAGS = $(MDLD_FLAGS)' + @echo ' SHLIBEXT = $(SHLIBEXT)' + +etags: + etags `find $(srcdir) -name "*.[ch]"` + +ctags: + ctags `find $(srcdir) -name "*.[ch]"` diff --git a/source4/build/make/templates.mk b/source4/build/make/templates.mk new file mode 100644 index 0000000000..f7eab6ce01 --- /dev/null +++ b/source4/build/make/templates.mk @@ -0,0 +1,141 @@ +# Templates file for Samba 4 +# This relies on GNU make. +# +# © 2008 Jelmer Vernooij <jelmer@samba.org> +# +############################################################################### +# Templates +############################################################################### + +# Partially link +# Arguments: target object file, source object files +define partial_link_template +$(1): $(2) ; + @echo Partially linking $$@ + @mkdir -p $$(@D) + $$(PARTLINK) -o $$@ $$^ +endef + +# Link a binary +# Arguments: target file, depends, flags +define binary_link_template +$(1): $(2) ; + @echo Linking $$@ + @$$(BNLD) $$(BNLD_FLAGS) $$(INTERN_LDFLAGS) -o $$@ $$(INSTALL_LINK_FLAGS) $(3) + +clean:: + @rm -f $(1) + +binaries:: $(1) + +endef + +# Link a host-machine binary +# Arguments: target file, depends, flags +define host_binary_link_template +$(1): $(2) ; + @echo Linking $$@ + @$$(HOSTLD) $$(HOSTLD_FLAGS) -L$${builddir}/bin/static -o $$@ $$(INSTALL_LINK_FLAGS) $(3) + +clean:: + rm -f $(1) + +binaries:: $(1) + +endef + +# Create a prototype header +# Arguments: header file, c files +define proto_header_template + +proto:: $(1) ; + +clean:: ; + rm -f $(1) + +$(1): $(2) ; + @echo "Creating $$@" + @$$(PERL) $$(srcdir)/script/mkproto.pl --srcdir=$$(srcdir) --builddir=$$(builddir) --public=/dev/null --private=$$@ $$^ + +endef + +# Shared module +# Arguments: Target, dependencies, objects +define shared_module_template + +$(1): $(2) ; + @echo Linking $$@ + @mkdir -p $$(@D) + @$$(MDLD) $$(LDFLAGS) $$(MDLD_FLAGS) $$(INTERN_LDFLAGS) -o $$@ $$(INSTALL_LINK_FLAGS) $(3) + +endef + +# Shared library +# Arguments: Target, dependencies, link flags, soname +define shared_library_template +$(1): $(2) + @echo Linking $$@ + @mkdir -p $$(@D) + @$$(SHLD) $$(LDFLAGS) $$(SHLD_FLAGS) $$(INTERN_LDFLAGS) -o $$@ $$(INSTALL_LINK_FLAGS) \ + $(3) \ + $$(if $$(SONAMEFLAG), $$(SONAMEFLAG)$(notdir $(4))) + +ifneq ($(notdir $(1)),$(notdir $(4))) +$(4): $(1) + @echo "Creating symbolic link for $$@" + @ln -fs $$(<F) $$@ +endif + +ifneq ($(notdir $(1)),$(notdir $(5))) +$(5): $(1) + @echo "Creating symbolic link for $$@" + @ln -fs $$(<F) $$@ +endif +endef + +# Shared alias +# Arguments: Target, subsystem name, alias name +define shared_module_alias_template +bin/modules/$(2)/$(3).$$(SHLIBEXT): $(1) + @ln -fs $$(<F) $$@ + +PLUGINS += bin/modules/$(2)/$(3).$$(SHLIBEXT) + +uninstallplugins:: + @-rm $$(DESTDIR)$$(modulesdir)/$(2)/$(3).$$(SHLIBEXT) +installplugins:: + @ln -fs $(notdir $(1)) $$(DESTDIR)$$(modulesdir)/$(2)/$(3).$$(SHLIBEXT) + +endef + +define shared_module_install_template +installplugins:: bin/modules/$(1)/$(2) + @echo Installing $(2) as $$(DESTDIR)$$(modulesdir)/$(1)/$(2) + @mkdir -p $$(DESTDIR)$$(modulesdir)/$(1)/ + @cp bin/modules/$(1)/$(2) $$(DESTDIR)$$(modulesdir)/$(1)/$(2) +uninstallplugins:: + @echo Uninstalling $$(DESTDIR)$$(modulesdir)/$(1)/$(2) + @-rm $$(DESTDIR)$$(modulesdir)/$(1)/$(2) + +endef + +# abspath for older makes +abspath = $(shell cd $(dir $(1)); pwd)/$(notdir $(1)) + +# Install a binary +# Arguments: path to binary to install +define binary_install_template +installbin:: $$(DESTDIR)$$(bindir)/$(notdir $(1)) installdirs + +uninstallbin:: + @echo "Removing $(notdir $(1))" + @rm -f $$(DESTDIR)$$(bindir)/$(notdir $(1)) +endef + +define sbinary_install_template +installsbin:: $$(DESTDIR)$$(sbindir)/$(notdir $(1)) installdirs + +uninstallsbin:: + @echo "Removing $(notdir $(1))" + @rm -f $$(DESTDIR)$$(sbindir)/$(notdir $(1)) +endef diff --git a/source4/build/make/yacc_compile.sh b/source4/build/make/yacc_compile.sh new file mode 100755 index 0000000000..ac4afea3f6 --- /dev/null +++ b/source4/build/make/yacc_compile.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +YACC="$1" +SRC="$2" +DEST="$3" + +dir=`dirname $SRC` +file=`basename $SRC` +base=`basename $SRC .y` +if [ -z "$YACC" ]; then + # if $DEST is more recent than $SRC, we can just touch + # otherwise we touch but print out warnings + if [ -r $DEST ]; then + if [ x`find $SRC -newer $DEST -print` = x$SRC ]; then + echo "warning: yacc not found - cannot generate $SRC => $DEST" >&2 + echo "warning: yacc not found - only updating the timestamp of $DEST" >&2 + fi + touch $DEST; + exit; + fi + echo "error: yacc not found - cannot generate $SRC => $DEST" >&2 + exit 1; +fi +# if $DEST is more recent than $SRC, we can just touch +if [ -r $DEST ]; then + if [ x`find $SRC -newer $DEST -print` != x$SRC ]; then + touch $DEST; + exit; + fi +fi +TOP=`pwd` +echo "info: running $YACC -d $file" +if cd $dir && $YACC -d $file; then + if [ -r y.tab.h -a -r y.tab.c ];then + echo "info: move y.tab.h to $base.h" + sed -e "/^#/!b" -e "s|y\.tab\.h|$SRC|" -e "s|\"$base.y|\"$SRC|" y.tab.h > $base.h + echo "info: move y.tab.c to $base.c" + sed -e "s|y\.tab\.c|$SRC|" -e "s|\"$base.y|\"$SRC|" y.tab.c > $base.c + rm -f y.tab.c y.tab.h + elif [ ! -r $base.h -a ! -r $base.c]; then + echo "$base.h nor $base.c generated." + exit 1 + fi +fi +cd $TOP diff --git a/source4/build/pasn1/Makefile b/source4/build/pasn1/Makefile new file mode 100644 index 0000000000..24da2b79e8 --- /dev/null +++ b/source4/build/pasn1/Makefile @@ -0,0 +1,5 @@ +asn1.pm: asn1.yp + yapp -s asn1.yp + +clean: + rm -f asn1.pm diff --git a/source4/build/pasn1/asn1.yp b/source4/build/pasn1/asn1.yp new file mode 100644 index 0000000000..7fc834ff2b --- /dev/null +++ b/source4/build/pasn1/asn1.yp @@ -0,0 +1,306 @@ +######################## +# ASN.1 Parse::Yapp parser +# Copyright (C) Stefan (metze) Metzmacher <metze@samba.org> +# released under the GNU GPL version 3 or later + + + +# the precedence actually doesn't matter at all for this grammer, but +# by providing a precedence we reduce the number of conflicts +# enormously +%left '-' '+' '&' '|' '*' '>' '.' '/' '(' ')' '[' ']' ':' ',' ';' + + +################ +# grammer +%% + +asn1: + identifier asn1_definitions asn1_delimitter asn1_begin asn1_decls asn1_end + {{ + "OBJECT" => "ASN1_DEFINITION", + "IDENTIFIER" => $_[1], + "DATA" => $_[5] + }} +; + +asn1_delimitter: + delimitter +; + +asn1_definitions: + 'DEFINITIONS' +; + +asn1_begin: + 'BEGIN' +; + +asn1_end: + 'END' +; + +asn1_decls: + asn1_def + { [ $_[1] ] } + | asn1_decls asn1_def + { push(@{$_[1]}, $_[2]); $_[1] } +; + + + +asn1_def: + asn1_target asn1_delimitter asn1_application asn1_type + {{ + "OBJECT" => "ASN1_DEF", + "IDENTIFIER" => $_[1], + "APPLICATION" => $_[3], + "STRUCTURE" => $_[4] + }} +; + +asn1_target: + identifier +; + +asn1_application: + #empty + | '[' 'APPLICATION' constant ']' + { $_[3] } +; + +asn1_type: + asn1_boolean + | asn1_integer + | asn1_bit_string + | asn1_octet_string + | asn1_null + | asn1_object_identifier + | asn1_real + | asn1_enumerated + | asn1_sequence + | identifier +; + +asn1_boolean: + 'BOOLEAN' + {{ + "TYPE" => "BOOLEAN", + "TAG" => 1 + }} +; + +asn1_integer: + 'INTEGER' + {{ + "TYPE" => "INTEGER", + "TAG" => 2 + }} + | 'INTEGER' '(' constant '.' '.' constant ')' + {{ + "TYPE" => "INTEGER", + "TAG" => 2, + "RANGE_LOW" => $_[3], + "RENAGE_HIGH" => $_[6] + }} +; + +asn1_bit_string: + 'BIT' 'STRING' + {{ + "TYPE" => "BIT STRING", + "TAG" => 3 + }} +; + +asn1_octet_string: + 'OCTET' 'STRING' + {{ + "TYPE" => "OCTET STRING", + "TAG" => 4 + }} +; + +asn1_null: + 'NULL' + {{ + "TYPE" => "NULL", + "TAG" => 5 + }} +; + +asn1_object_identifier: + 'OBJECT' 'IDENTIFIER' + {{ + "TYPE" => "OBJECT IDENTIFIER", + "TAG" => 6 + }} +; + +asn1_real: + 'REAL' + {{ + "TYPE" => "REAL", + "TAG" => 9 + }} +; + +asn1_enumerated: + 'ENUMERATED' + {{ + "TYPE" => "ENUMERATED", + "TAG" => 10 + }} +; + +asn1_sequence: + 'SEQUENCE' '{' asn1_var_dec_list '}' + {{ + "TYPE" => "SEQUENCE", + "TAG" => 16, + "STRUCTURE" => $_[3] + }} +; + +asn1_var_dec_list: + asn1_var_dec + { [ $_[1] ] } + | asn1_var_dec_list ',' asn1_var_dec + { push(@{$_[1]}, $_[3]); $_[1] } +; + +asn1_var_dec: + identifier asn1_type + {{ + "NAME" => $_[1], + "TYPE" => $_[2] + }} +; + +anytext: #empty { "" } + | identifier | constant | text + | anytext '-' anytext { "$_[1]$_[2]$_[3]" } + | anytext '.' anytext { "$_[1]$_[2]$_[3]" } + | anytext '*' anytext { "$_[1]$_[2]$_[3]" } + | anytext '>' anytext { "$_[1]$_[2]$_[3]" } + | anytext '|' anytext { "$_[1]$_[2]$_[3]" } + | anytext '&' anytext { "$_[1]$_[2]$_[3]" } + | anytext '/' anytext { "$_[1]$_[2]$_[3]" } + | anytext '+' anytext { "$_[1]$_[2]$_[3]" } + | anytext '(' anytext ')' anytext { "$_[1]$_[2]$_[3]$_[4]$_[5]" } +; + +delimitter: DELIMITTER +; + +identifier: IDENTIFIER +; + +constant: CONSTANT +; + +text: TEXT { "\"$_[1]\"" } +; + +##################################### +# start code +%% + +use util; + +sub _ASN1_Error { + if (exists $_[0]->YYData->{ERRMSG}) { + print $_[0]->YYData->{ERRMSG}; + delete $_[0]->YYData->{ERRMSG}; + return; + }; + my $line = $_[0]->YYData->{LINE}; + my $last_token = $_[0]->YYData->{LAST_TOKEN}; + my $file = $_[0]->YYData->{INPUT_FILENAME}; + + print "$file:$line: Syntax error near '$last_token'\n"; +} + +sub _ASN1_Lexer($) +{ + my($parser)=shift; + + $parser->YYData->{INPUT} + or return('',undef); + +again: + $parser->YYData->{INPUT} =~ s/^[ \t]*//; + + for ($parser->YYData->{INPUT}) { + if (/^\#/) { + if (s/^\# (\d+) \"(.*?)\"( \d+|)//) { + $parser->YYData->{LINE} = $1-1; + $parser->YYData->{INPUT_FILENAME} = $2; + goto again; + } + if (s/^\#line (\d+) \"(.*?)\"( \d+|)//) { + $parser->YYData->{LINE} = $1-1; + $parser->YYData->{INPUT_FILENAME} = $2; + goto again; + } + if (s/^(\#.*)$//m) { + goto again; + } + } + if (s/^(\n)//) { + $parser->YYData->{LINE}++; + goto again; + } + if (s/^(--.*\n)//) { + $parser->YYData->{LINE}++; + goto again; + } + if (s/^(::=)//) { + $parser->YYData->{LAST_TOKEN} = $1; + return('DELIMITTER',$1); + } + if (s/^\"(.*?)\"//) { + $parser->YYData->{LAST_TOKEN} = $1; + return('TEXT',$1); + } + if (s/^(\d+)(\W|$)/$2/) { + $parser->YYData->{LAST_TOKEN} = $1; + return('CONSTANT',$1); + } + if (s/^([\w_-]+)//) { + $parser->YYData->{LAST_TOKEN} = $1; + if ($1 =~ + /^(SEQUENCE|INTEGER|OCTET|STRING| + APPLICATION|OPTIONAL|NULL|COMPONENTS|OF| + BOOLEAN|ENUMERATED|CHOISE|REAL|BIT|OBJECT|IDENTIFIER| + DEFAULT|FALSE|TRUE|SET|DEFINITIONS|BEGIN|END)$/x) { + return $1; + } + return('IDENTIFIER',$1); + } + if (s/^(.)//s) { + $parser->YYData->{LAST_TOKEN} = $1; + return($1,$1); + } + } +} + +sub parse_asn1($$) +{ + my $self = shift; + my $filename = shift; + + my $saved_delim = $/; + undef $/; + my $cpp = $ENV{CPP}; + if (! defined $cpp) { + $cpp = "cpp" + } + my $data = `$cpp -xc $filename`; + $/ = $saved_delim; + + $self->YYData->{INPUT} = $data; + $self->YYData->{LINE} = 0; + $self->YYData->{LAST_TOKEN} = "NONE"; + return $self->YYParse( yylex => \&_ASN1_Lexer, yyerror => \&_ASN1_Error ); +} diff --git a/source4/build/pasn1/pasn1.pl b/source4/build/pasn1/pasn1.pl new file mode 100755 index 0000000000..c3689fd928 --- /dev/null +++ b/source4/build/pasn1/pasn1.pl @@ -0,0 +1,93 @@ +#!/usr/bin/perl -w + +################################################### +# package to parse ASN.1 files and generate code for +# LDAP functions in Samba +# Copyright tridge@samba.org 2002-2003 +# Copyright metze@samba.org 2004 + +# released under the GNU GPL + +use strict; + +use FindBin qw($RealBin); +use lib "$RealBin"; +use lib "$RealBin/lib"; +use Getopt::Long; +use File::Basename; +use asn1; +use util; + +my($opt_help) = 0; +my($opt_output); + +my $asn1_parser = new asn1; + +##################################################################### +# parse an ASN.1 file returning a structure containing all the data +sub ASN1Parse($) +{ + my $filename = shift; + my $asn1 = $asn1_parser->parse_asn1($filename); + util::CleanData($asn1); + return $asn1; +} + + +######################################### +# display help text +sub ShowHelp() +{ + print " + perl ASN.1 parser and code generator + Copyright (C) tridge\@samba.org + Copyright (C) metze\@samba.org + + Usage: pasn1.pl [options] <asn1file> + + Options: + --help this help page + --output OUTNAME put output in OUTNAME + \n"; + exit(0); +} + +# main program +GetOptions ( + 'help|h|?' => \$opt_help, + 'output|o=s' => \$opt_output, + ); + +if ($opt_help) { + ShowHelp(); + exit(0); +} + +sub process_file($) +{ + my $input_file = shift; + my $output_file; + my $pasn1; + + my $basename = basename($input_file, ".asn1"); + + if (!defined($opt_output)) { + $output_file = util::ChangeExtension($input_file, ".pasn1"); + } else { + $output_file = $opt_output; + } + +# if (file is .pasn1) { +# $pasn1 = util::LoadStructure($pasn1_file); +# defined $pasn1 || die "Failed to load $pasn1_file - maybe you need --parse\n"; +# } else { + $pasn1 = ASN1Parse($input_file); + defined $pasn1 || die "Failed to parse $input_file"; + util::SaveStructure($output_file, $pasn1) || + die "Failed to save $output_file\n"; + #} +} + +foreach my $filename (@ARGV) { + process_file($filename); +} diff --git a/source4/build/pasn1/util.pm b/source4/build/pasn1/util.pm new file mode 100644 index 0000000000..f822222b45 --- /dev/null +++ b/source4/build/pasn1/util.pm @@ -0,0 +1,379 @@ +################################################### +# utility functions to support pidl +# Copyright tridge@samba.org 2000 +# released under the GNU GPL +package util; + +##################################################################### +# load a data structure from a file (as saved with SaveStructure) +sub LoadStructure($) +{ + my $f = shift; + my $contents = FileLoad($f); + defined $contents || return undef; + return eval "$contents"; +} + +use strict; + +##################################################################### +# flatten an array of arrays into a single array +sub FlattenArray2($) +{ + my $a = shift; + my @b; + for my $d (@{$a}) { + for my $d1 (@{$d}) { + push(@b, $d1); + } + } + return \@b; +} + +##################################################################### +# flatten an array of arrays into a single array +sub FlattenArray($) +{ + my $a = shift; + my @b; + for my $d (@{$a}) { + for my $d1 (@{$d}) { + push(@b, $d1); + } + } + return \@b; +} + +##################################################################### +# flatten an array of hashes into a single hash +sub FlattenHash($) +{ + my $a = shift; + my %b; + for my $d (@{$a}) { + for my $k (keys %{$d}) { + $b{$k} = $d->{$k}; + } + } + return \%b; +} + + +##################################################################### +# traverse a perl data structure removing any empty arrays or +# hashes and any hash elements that map to undef +sub CleanData($) +{ + sub CleanData($); + my($v) = shift; + if (ref($v) eq "ARRAY") { + foreach my $i (0 .. $#{$v}) { + CleanData($v->[$i]); + if (ref($v->[$i]) eq "ARRAY" && $#{$v->[$i]}==-1) { + $v->[$i] = undef; + next; + } + } + # this removes any undefined elements from the array + @{$v} = grep { defined $_ } @{$v}; + } elsif (ref($v) eq "HASH") { + foreach my $x (keys %{$v}) { + CleanData($v->{$x}); + if (!defined $v->{$x}) { delete($v->{$x}); next; } + if (ref($v->{$x}) eq "ARRAY" && $#{$v->{$x}}==-1) { delete($v->{$x}); next; } + } + } +} + + +##################################################################### +# return the modification time of a file +sub FileModtime($) +{ + my($filename) = shift; + return (stat($filename))[9]; +} + + +##################################################################### +# read a file into a string +sub FileLoad($) +{ + my($filename) = shift; + local(*INPUTFILE); + open(INPUTFILE, $filename) || return undef; + my($saved_delim) = $/; + undef $/; + my($data) = <INPUTFILE>; + close(INPUTFILE); + $/ = $saved_delim; + return $data; +} + +##################################################################### +# write a string into a file +sub FileSave($$) +{ + my($filename) = shift; + my($v) = shift; + local(*FILE); + open(FILE, ">$filename") || die "can't open $filename"; + print FILE $v; + close(FILE); +} + +##################################################################### +# return a filename with a changed extension +sub ChangeExtension($$) +{ + my($fname) = shift; + my($ext) = shift; + if ($fname =~ /^(.*)\.(.*?)$/) { + return "$1$ext"; + } + return "$fname$ext"; +} + +##################################################################### +# a dumper wrapper to prevent dependence on the Data::Dumper module +# unless we actually need it +sub MyDumper($) +{ + require Data::Dumper; + my $s = shift; + return Data::Dumper::Dumper($s); +} + +##################################################################### +# save a data structure into a file +sub SaveStructure($$) +{ + my($filename) = shift; + my($v) = shift; + FileSave($filename, MyDumper($v)); +} + +##################################################################### +# see if a pidl property list contains a give property +sub has_property($$) +{ + my($e) = shift; + my($p) = shift; + + if (!defined $e->{PROPERTIES}) { + return undef; + } + + return $e->{PROPERTIES}->{$p}; +} + + +sub is_scalar_type($) +{ + my($type) = shift; + + if ($type =~ /^u?int\d+/) { + return 1; + } + if ($type =~ /char|short|long|NTTIME| + time_t|error_status_t|boolean32|unsigned32| + HYPER_T|wchar_t|DATA_BLOB/x) { + return 1; + } + + return 0; +} + +# return the NDR alignment for a type +sub type_align($) +{ + my($e) = shift; + my $type = $e->{TYPE}; + + if (need_wire_pointer($e)) { + return 4; + } + + return 4, if ($type eq "uint32"); + return 4, if ($type eq "long"); + return 2, if ($type eq "short"); + return 1, if ($type eq "char"); + return 1, if ($type eq "uint8"); + return 2, if ($type eq "uint16"); + return 4, if ($type eq "NTTIME"); + return 4, if ($type eq "time_t"); + return 8, if ($type eq "HYPER_T"); + return 2, if ($type eq "wchar_t"); + return 4, if ($type eq "DATA_BLOB"); + + # it must be an external type - all we can do is guess + return 4; +} + +# this is used to determine if the ndr push/pull functions will need +# a ndr_flags field to split by buffers/scalars +sub is_builtin_type($) +{ + my($type) = shift; + + return 1, if (is_scalar_type($type)); + + return 0; +} + +# determine if an element needs a reference pointer on the wire +# in its NDR representation +sub need_wire_pointer($) +{ + my $e = shift; + if ($e->{POINTERS} && + !has_property($e, "ref")) { + return $e->{POINTERS}; + } + return undef; +} + +# determine if an element is a pass-by-reference structure +sub is_ref_struct($) +{ + my $e = shift; + if (!is_scalar_type($e->{TYPE}) && + has_property($e, "ref")) { + return 1; + } + return 0; +} + +# determine if an element is a pure scalar. pure scalars do not +# have a "buffers" section in NDR +sub is_pure_scalar($) +{ + my $e = shift; + if (has_property($e, "ref")) { + return 1; + } + if (is_scalar_type($e->{TYPE}) && + !$e->{POINTERS} && + !array_size($e)) { + return 1; + } + return 0; +} + +# determine the array size (size_is() or ARRAY_LEN) +sub array_size($) +{ + my $e = shift; + my $size = has_property($e, "size_is"); + if ($size) { + return $size; + } + $size = $e->{ARRAY_LEN}; + if ($size) { + return $size; + } + return undef; +} + +# see if a variable needs to be allocated by the NDR subsystem on pull +sub need_alloc($) +{ + my $e = shift; + + if (has_property($e, "ref")) { + return 0; + } + + if ($e->{POINTERS} || array_size($e)) { + return 1; + } + + return 0; +} + +# determine the C prefix used to refer to a variable when passing to a push +# function. This will be '*' for pointers to scalar types, '' for scalar +# types and normal pointers and '&' for pass-by-reference structures +sub c_push_prefix($) +{ + my $e = shift; + + if ($e->{TYPE} =~ "string") { + return ""; + } + + if (is_scalar_type($e->{TYPE}) && + $e->{POINTERS}) { + return "*"; + } + if (!is_scalar_type($e->{TYPE}) && + !$e->{POINTERS} && + !array_size($e)) { + return "&"; + } + return ""; +} + + +# determine the C prefix used to refer to a variable when passing to a pull +# return '&' or '' +sub c_pull_prefix($) +{ + my $e = shift; + + if (!$e->{POINTERS} && !array_size($e)) { + return "&"; + } + + if ($e->{TYPE} =~ "string") { + return "&"; + } + + return ""; +} + +# determine if an element has a direct buffers component +sub has_direct_buffers($) +{ + my $e = shift; + if ($e->{POINTERS} || array_size($e)) { + return 1; + } + return 0; +} + +# return 1 if the string is a C constant +sub is_constant($) +{ + my $s = shift; + if ($s =~ /^\d/) { + return 1; + } + return 0; +} + +# return 1 if this is a fixed array +sub is_fixed_array($) +{ + my $e = shift; + my $len = $e->{"ARRAY_LEN"}; + if (defined $len && is_constant($len)) { + return 1; + } + return 0; +} + +# return 1 if this is a inline array +sub is_inline_array($) +{ + my $e = shift; + my $len = $e->{"ARRAY_LEN"}; + if (is_fixed_array($e) || + defined $len && $len ne "*") { + return 1; + } + return 0; +} + +1; + diff --git a/source4/build/smb_build/README.txt b/source4/build/smb_build/README.txt new file mode 100644 index 0000000000..eac3905cce --- /dev/null +++ b/source4/build/smb_build/README.txt @@ -0,0 +1,83 @@ +The Samba Build System
+======================
+
+The build system basically has two main parts: the autoconf-generated
+shell scripts which check for availability of functions and libraries
+which is stored in the .m4 files and the information about the various
+subsystems which is stored in the .mk files.
+
+Object Types
+------------
+the build system knows about the following object types
+
+SUBSYSTEM:
+ a SUBSYSTEM is basicly a collection of functions, which provide an
+ an generic API for a specific problem (e.g. libldb provides an api
+ for gneric ldb databases. libldb_plugin provides a generic api
+ for calling ldb plugins, so 'libldb' and 'libldb_plugin' are subsystems)
+
+MODULE:
+ a MODULE is a specify implementation of a API provided by a SUBSYSTEM.
+ (e.g. 'libldb_tdb' and 'libldb_ldap' are implementations of the subsystem 'libldb' API,
+ and 'libldb_plugin_timestamp' is a module of the 'libldb_plugin' subsystem)
+
+EXT_LIB:
+ an EXT_LIB is an external library which is needed by a SUBSYSTEM, MODULE, BINARY or LIBRARY.
+ (e.g. 'gtk' or 'KRB5')
+
+BINARY:
+ a BINARY means a executable binary file.
+ (e.g. 'smbtorture' or 'ldbedit')
+ a BINARY typically has only commandline handling and basic
+ functionality code in it and depends on the functions of
+ SUBSYSTEM's (REQUIRED_SUBSYSTEMS).
+
+LIBRARY:
+ a LIBRARY means a static and/or shared library,
+ which depends on the used OS.
+ (e.g. for libldb 'libldb.so', 'libldb.so.0' 'libldb.so.0.0.1'
+ and libldb.a are created on linux)
+ a LIBRARY typicly has only glue code in it and depends on
+ SUBSYSTEM's (REQUIRED_SUBSYSTEMS).
+
+File summary:
+-------------
+public.m4 - public M4 macros of the build system
+config_mk.pm - Support for reading .mk files
+dot.pm - Support for generating .dot files for analysis of dependencies
+input.pm - Input validation
+main.pm - Main
+makefile.pm - Makefile generation
+output.pm - Dependency calculation
+
+Layout
+-------
+
+Toplevel file: configure.in
+- included by autogen.sh: aclocal.m4
+ which includes the SMB_YXZ*() macros
+
+- default tests of the build system
+ are in build/smb_build/check_*.m4
+ (mostly compiler and basic C type and function
+ checks)
+
+- subsystem specific stuff should be included by 'SMB_INCLUDE_M4()'
+
+
+Generating the configure file
+-------------------------
+you need to rerun ./autogen.sh when 'configure.in' or any
+'.m4' file was modified, then you need to rerun configure.
+
+
+Generating config.status
+-----------------------------
+you need to run ./config.status (or 'configure') after a '.mk'
+file was changed.
+
+
+Examples
+--------
+for now please take a look at the .m4 and .mk files
+you find in the source tree, they should be a good reference to start.
diff --git a/source4/build/smb_build/TODO b/source4/build/smb_build/TODO new file mode 100644 index 0000000000..adfe17d423 --- /dev/null +++ b/source4/build/smb_build/TODO @@ -0,0 +1,25 @@ +- use pkg-config files in the buildsystem? +- let the build system implement some make functions($(patsubst),$(wildcard),...) and use our own implementations where `make' does not support them +- include extra_flags.txt using Makefile construction if + supported by current make +- fix shared module loading for selftest during builds without install +- remove recursive dependency between LIBSOCKET, LIBCLI_NBT and LIBCLI_RESOLVE +- clearer distinction between dcerpc and ndr. seperate interface tables? Maybe get rid of + NDR's table altogether and use dlopen/dlsym ? +- saner names for: + libcli.so.0.0.1 (rename to libsmb?) + libcli_cldap.so.0.0.1 (rename to libcldap?) + libcli_nbt.so.0.0.1 (rename to libnbt?) + libcli_wrepl.so.0.0.1 (rename to libwrepl?) +- generate headermap.txt + +set of test scripts that check the code: +- configure_check_unused.pl +- find_unused_macros.pl +- find_unused_makefilevars.pl +- find_unused_options.sh +- findstatic.pl +- minimal_includes.pl +- check dependencies based on #include lines ? +- check whether private headers are not used outside their own subsystem +- undocumented (no manpage) installed binaries diff --git a/source4/build/smb_build/config_mk.pm b/source4/build/smb_build/config_mk.pm new file mode 100644 index 0000000000..8c7d75221c --- /dev/null +++ b/source4/build/smb_build/config_mk.pm @@ -0,0 +1,284 @@ +# Samba Build System +# - config.mk parsing functions +# +# Copyright (C) Stefan (metze) Metzmacher 2004 +# Copyright (C) Jelmer Vernooij 2005 +# Released under the GNU GPL +# + +package smb_build::config_mk; +use smb_build::input; +use File::Basename; + +use strict; + +my $section_types = { + "EXT_LIB" => { + "LIBS" => "list", + "CFLAGS" => "list", + "CPPFLAGS" => "list", + "LDFLAGS" => "list", + }, + "PYTHON" => { + "LIBRARY_REALNAME" => "string", + "PRIVATE_DEPENDENCIES" => "list", + "PUBLIC_DEPENDENCIES" => "list", + "ENABLE" => "bool", + "LDFLAGS" => "list", + }, + "SUBSYSTEM" => { + "PRIVATE_DEPENDENCIES" => "list", + "PUBLIC_DEPENDENCIES" => "list", + + "ENABLE" => "bool", + + "CFLAGS" => "list", + "LDFLAGS" => "list", + "STANDARD_VISIBILITY" => "string", + "INIT_FUNCTION_SENTINEL" => "string" + }, + "MODULE" => { + "SUBSYSTEM" => "string", + + "INIT_FUNCTION" => "string", + + "PRIVATE_DEPENDENCIES" => "list", + + "ALIASES" => "list", + + "ENABLE" => "bool", + + "OUTPUT_TYPE" => "list", + + "CFLAGS" => "list" + }, + "BINARY" => { + + "PRIVATE_DEPENDENCIES" => "list", + + "ENABLE" => "bool", + + "INSTALLDIR" => "string", + "LDFLAGS" => "list", + "STANDARD_VISIBILITY" => "string", + + "USE_HOSTCC" => "bool" + }, + "LIBRARY" => { + "LIBRARY_REALNAME" => "string", + + "INIT_FUNCTION_TYPE" => "string", + "INIT_FUNCTION_SENTINEL" => "string", + "OUTPUT_TYPE" => "list", + + "PRIVATE_DEPENDENCIES" => "list", + "PUBLIC_DEPENDENCIES" => "list", + + "ENABLE" => "bool", + + "CFLAGS" => "list", + "LDFLAGS" => "list", + "STANDARD_VISIBILITY" => "string" + } +}; + +use vars qw(@parsed_files); + +@parsed_files = (); + +sub _read_config_file($$$) +{ + use Cwd; + + my ($srcdir, $builddir, $filename) = @_; + my @dirlist; + + # We need to change our working directory because config.mk files can + # give shell commands as the argument to "include". These shell + # commands can take arguments that are relative paths and we don't have + # a way of sensibly rewriting these. + my $cwd = getcwd; + chomp $cwd; + + if ($srcdir ne $builddir) { + # Push the builddir path on the front, so we prefer builddir + # to srcdir when the file exists in both. + @dirlist = ($builddir, $srcdir); + } else { + @dirlist = ($srcdir); + } + + foreach my $d (@dirlist) { + my @lines; + my $basedir; + + chdir $cwd; + chdir $d; + + # We need to catch the exception from open in the case where + # the filename is actually a shell pipeline. Why is this + # different to opening a regular file? Because this is perl! + eval { + open(CONFIG_MK, "./$filename"); + @lines = <CONFIG_MK>; + close(CONFIG_MK); + }; + + chdir $cwd; + next unless (@lines); + + # I blame abartlett for this crazy hack -- jpeach + if ($filename =~ /\|$/) { + $basedir = $builddir; + } else { + $basedir = dirname($filename); + push(@parsed_files, $filename); + } + $basedir =~ s!^($builddir|$srcdir)[/]!!; + return ($filename, $basedir, @lines); + } + + chdir $cwd; + return; +} + +########################################################### +# The parsing function which parses the file +# +# $result = _parse_config_mk($input, $srcdir, $builddir, $filename) +# +# $filename - the path of the config.mk file +# which should be parsed +sub run_config_mk($$$$) +{ + sub run_config_mk($$$$); + my ($input, $srcdir, $builddir, $filename) = @_; + my $result; + my $linenum = -1; + my $infragment = 0; + my $section = "GLOBAL"; + my $makefile = ""; + + my $basedir; + + my $parsing_file; + my @lines; + + $ENV{builddir} = $builddir; + $ENV{srcdir} = $srcdir; + + ($parsing_file, $basedir, @lines) = + _read_config_file($srcdir, $builddir, $filename); + + die ("$0: can't open '$filename'") + unless ($parsing_file and $basedir and @lines); + + my $line = ""; + my $prev = ""; + + # Emit a line that lets us match up final makefile output with the + # corresponding input files. The curlies are so you can match the + # BEGIN/END pairs in a text editor. + $makefile .= "# BEGIN{ $parsing_file\n"; + + foreach (@lines) { + $linenum++; + + # lines beginning with '#' are ignored + next if (/^\#.*$/); + + if (/^(.*)\\$/) { + $prev .= $1; + next; + } else { + $line = "$prev$_"; + $prev = ""; + } + + if ($line =~ /^\[([-a-zA-Z0-9_.:]+)\][\t ]*$/) + { + $section = $1; + $infragment = 0; + + $result->{$section}{EXISTS}{KEY} = "EXISTS"; + $result->{$section}{EXISTS}{VAL} = 1; + next; + } + + # include + if ($line =~ /^mkinclude (.*)$/) { + my $subfile= $1; + my $subdir = dirname($filename); + $subdir =~ s/^\.$//g; + $subdir =~ s/^\.\///g; + $subdir .= "/" if ($subdir ne ""); + $makefile .= "basedir := $subdir\n"; + $makefile .= run_config_mk($input, $srcdir, $builddir, $subdir.$subfile); + next; + } + + # empty line + if ($line =~ /^[ \t]*$/) { + $section = "GLOBAL"; + if ($infragment) { $makefile.="\n"; } + next; + } + + # global stuff is considered part of the makefile + if ($section eq "GLOBAL") { + if (!$infragment) { $makefile.="\n"; } + $makefile .= $line; + $infragment = 1; + next; + } + + # Assignment + if ($line =~ /^([a-zA-Z0-9_]+)[\t ]*=(.*)$/) { + $result->{$section}{$1}{VAL} = $2; + $result->{$section}{$1}{KEY} = $1; + + next; + } + + die("$parsing_file:$linenum: Bad line"); + } + + $makefile .= "# }END $parsing_file\n"; + + foreach my $section (keys %{$result}) { + my ($type, $name) = split(/::/, $section, 2); + + my $sectype = $section_types->{$type}; + if (not defined($sectype)) { + die($parsing_file.":[".$section."] unknown section type \"".$type."\"!"); + } + + $input->{$name}{NAME} = $name; + $input->{$name}{TYPE} = $type; + $input->{$name}{MK_FILE} = $parsing_file; + $input->{$name}{BASEDIR} = $basedir; + + foreach my $key (values %{$result->{$section}}) { + next if ($key->{KEY} eq "EXISTS"); + $key->{VAL} = smb_build::input::strtrim($key->{VAL}); + my $vartype = $sectype->{$key->{KEY}}; + if (not defined($vartype)) { + die($parsing_file.":[".$section."]: unknown attribute type \"$key->{KEY}\"!"); + } + if ($vartype eq "string") { + $input->{$name}{$key->{KEY}} = $key->{VAL}; + } elsif ($vartype eq "list") { + $input->{$name}{$key->{KEY}} = [smb_build::input::str2array($key->{VAL})]; + } elsif ($vartype eq "bool") { + if (($key->{VAL} ne "YES") and ($key->{VAL} ne "NO")) { + die("Invalid value for bool attribute $key->{KEY}: $key->{VAL} in section $section"); + } + $input->{$name}{$key->{KEY}} = $key->{VAL}; + } + } + } + + return $makefile; +} + +1; diff --git a/source4/build/smb_build/dot.pl b/source4/build/smb_build/dot.pl new file mode 100755 index 0000000000..b30c320c6e --- /dev/null +++ b/source4/build/smb_build/dot.pl @@ -0,0 +1,63 @@ +#!/usr/bin/perl +# Samba4 Dependency Graph Generator +# (C) 2004-2005 Jelmer Vernooij <jelmer@samba.org> +# Published under the GNU GPL + +use strict; +use lib 'build'; +use smb_build::config_mk; + +my $subsys = shift @ARGV; + +sub contains($$) +{ + my ($haystack,$needle) = @_; + foreach (@$haystack) { + return 1 if ($_ eq $needle); + } + return 0; +} + +sub generate($$$) +{ + my ($depend,$only,$name) = @_; + my $res = "digraph $name {\n"; + + foreach my $part (values %{$depend}) { + next if (defined($only) and not contains($only,$part->{NAME})); + foreach my $elem (@{$part->{PUBLIC_DEPENDENCIES}}) { + $res .= "\t\"$part->{NAME}\" -> \"$elem\" [style=filled]; /* public */\n"; + } + foreach my $elem (@{$part->{PRIVATE_DEPENDENCIES}}) { + $res .= "\t\"$part->{NAME}\" -> \"$elem\" [style=dotted]; /* private */\n"; + } + } + + return $res . "}\n"; +} + +my $INPUT = {}; +smb_build::config_mk::run_config_mk($INPUT, '.', '.', "main.mk"); + +my $name = "samba4"; + +my $only; +if (defined($subsys)) { + my $DEPEND = smb_build::input::check($INPUT, \%config::enabled, + "MERGED_OBJ", "SHARED_LIBRARY", "SHARED_LIBRARY"); + + die("No such subsystem $subsys") unless (defined($DEPEND->{$subsys})); + + $only = $DEPEND->{$subsys}->{UNIQUE_DEPENDENCIES_ALL}; + push (@$only, "$subsys"); + + $name = $subsys; +} + +my $fname = "$name-deps.dot"; +print __FILE__.": creating $fname\n"; +open DOTTY, ">$fname"; +print DOTTY generate($INPUT, $only, $name); +close DOTTY; + +1; diff --git a/source4/build/smb_build/input.pm b/source4/build/smb_build/input.pm new file mode 100644 index 0000000000..1696a364b2 --- /dev/null +++ b/source4/build/smb_build/input.pm @@ -0,0 +1,277 @@ +# Samba Build System +# - the input checking functions +# +# Copyright (C) Stefan (metze) Metzmacher 2004 +# Copyright (C) Jelmer Vernooij 2004 +# Released under the GNU GPL + +use strict; +package smb_build::input; +use File::Basename; + +sub strtrim($) +{ + $_ = shift; + s/^[\t\n ]*//g; + s/[\t\n ]*$//g; + return $_; +} + +sub str2array($) +{ + $_ = shift; + s/^[\t\n ]*//g; + s/[\t\n ]*$//g; + s/([\t\n ]+)/ /g; + + return () if (length($_)==0); + return split /[ \t\n]/; +} + +sub add_libreplace($) +{ + my ($part) = @_; + + return if ($part->{NAME} eq "LIBREPLACE"); + return if ($part->{NAME} eq "LIBREPLACE_HOSTCC"); + return if ($part->{NAME} eq "REPLACE_READDIR"); + + foreach my $n (@{$part->{PRIVATE_DEPENDENCIES}}) { + return if ($n eq "LIBREPLACE"); + return if ($n eq "LIBREPLACE_HOSTCC"); + } + foreach my $n (@{$part->{PUBLIC_DEPENDENCIES}}) { + return if ($n eq "LIBREPLACE"); + return if ($n eq "LIBREPLACE_HOSTCC"); + } + + if (defined($part->{USE_HOSTCC}) && $part->{USE_HOSTCC} eq "YES") { + unshift (@{$part->{PRIVATE_DEPENDENCIES}}, "LIBREPLACE_HOSTCC"); + } else { + unshift (@{$part->{PRIVATE_DEPENDENCIES}}, "LIBREPLACE"); + } +} + +sub check_subsystem($$$) +{ + my ($INPUT, $subsys, $default_ot) = @_; + return if ($subsys->{ENABLE} ne "YES"); + + unless (defined($subsys->{OUTPUT_TYPE})) { $subsys->{OUTPUT_TYPE} = $default_ot; } + unless (defined($subsys->{INIT_FUNCTION_TYPE})) { $subsys->{INIT_FUNCTION_TYPE} = "NTSTATUS (*) (void)"; } + unless (defined($subsys->{INIT_FUNCTION_SENTINEL})) { $subsys->{INIT_FUNCTION_SENTINEL} = "NULL"; } +} + +sub check_module($$$) +{ + my ($INPUT, $mod, $default_ot) = @_; + + die("Module $mod->{NAME} does not have a SUBSYSTEM set") if not defined($mod->{SUBSYSTEM}); + + if (not exists($INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTIONS})) { + $INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTIONS} = []; + } + + if (!(defined($INPUT->{$mod->{SUBSYSTEM}}))) { + die("Unknown subsystem $mod->{SUBSYSTEM} for module $mod->{NAME}"); + } + + if ($INPUT->{$mod->{SUBSYSTEM}} eq "NO") { + warn("Disabling module $mod->{NAME} because subsystem $mod->{SUBSYSTEM} is disabled"); + $mod->{ENABLE} = "NO"; + return; + } + + return if ($mod->{ENABLE} ne "YES"); + + if (exists($INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTION_TYPE})) { + $mod->{INIT_FUNCTION_TYPE} = $INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTION_TYPE}; + } else { + $mod->{INIT_FUNCTION_TYPE} = "NTSTATUS (*) (void)"; + } + + unless (defined($mod->{INIT_FUNCTION_SENTINEL})) { $mod->{INIT_FUNCTION_SENTINEL} = "NULL"; } + + if (not defined($mod->{OUTPUT_TYPE})) { + if ((not defined($INPUT->{$mod->{SUBSYSTEM}}->{TYPE})) or + $INPUT->{$mod->{SUBSYSTEM}}->{TYPE} eq "EXT_LIB") { + $mod->{OUTPUT_TYPE} = undef; + } else { + $mod->{OUTPUT_TYPE} = $default_ot; + } + } + + if (grep(/SHARED_LIBRARY/, @{$mod->{OUTPUT_TYPE}})) { + my $sane_subsystem = lc($mod->{SUBSYSTEM}); + $sane_subsystem =~ s/^lib//; + $mod->{INSTALLDIR} = "MODULESDIR/$sane_subsystem"; + push (@{$mod->{PUBLIC_DEPENDENCIES}}, $mod->{SUBSYSTEM}); + add_libreplace($mod); + } + if (grep(/MERGED_OBJ/, @{$mod->{OUTPUT_TYPE}})) { + push (@{$INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTIONS}}, $mod->{INIT_FUNCTION}) if defined($mod->{INIT_FUNCTION}); + push (@{$INPUT->{$mod->{SUBSYSTEM}}{PRIVATE_DEPENDENCIES}}, $mod->{NAME}); + } +} + +sub check_library($$$) +{ + my ($INPUT, $lib, $default_ot) = @_; + + return if ($lib->{ENABLE} ne "YES"); + + unless (defined($lib->{OUTPUT_TYPE})) { $lib->{OUTPUT_TYPE} = $default_ot; } + + unless (defined($lib->{INIT_FUNCTION_TYPE})) { $lib->{INIT_FUNCTION_TYPE} = "NTSTATUS (*) (void)"; } + unless (defined($lib->{INIT_FUNCTION_SENTINEL})) { $lib->{INIT_FUNCTION_SENTINEL} = "NULL"; } + unless (defined($lib->{INSTALLDIR})) { $lib->{INSTALLDIR} = "LIBDIR"; } + + add_libreplace($lib); +} + +sub check_python($$$) +{ + my ($INPUT, $python, $default_ot) = @_; + + return if ($INPUT->{LIBPYTHON}{ENABLE} ne "YES"); + + $python->{INSTALLDIR} = "PYTHONDIR"; + unless (defined($python->{CFLAGS})) { $python->{CFLAGS} = []; } + my $basename = $python->{NAME}; + $basename =~ s/^python_//g; + unless (defined($python->{LIBRARY_REALNAME})) { + $python->{LIBRARY_REALNAME} = "$basename.\$(SHLIBEXT)"; + } + $python->{INIT_FUNCTION} = "{ (char *)\"$basename\", init$basename }"; + push (@{$python->{CFLAGS}}, "\$(EXT_LIB_PYTHON_CFLAGS)"); + + $python->{SUBSYSTEM} = "LIBPYTHON"; + + check_module($INPUT, $python, $default_ot); +} + +sub check_binary($$) +{ + my ($INPUT, $bin) = @_; + + return if ($bin->{ENABLE} ne "YES"); + + ($bin->{BINARY} = (lc $bin->{NAME})) if not defined($bin->{BINARY}); + unless (defined($bin->{INIT_FUNCTION_SENTINEL})) { $bin->{INIT_FUNCTION_SENTINEL} = "NULL"; } + unless (defined($bin->{INIT_FUNCTION_TYPE})) { $bin->{INIT_FUNCTION_TYPE} = "NTSTATUS (*) (void)"; } + + $bin->{OUTPUT_TYPE} = ["BINARY"]; + add_libreplace($bin); +} + +sub add_implicit($$) +{ + my ($INPUT, $n) = @_; + + $INPUT->{$n}->{TYPE} = "MAKE_RULE"; + $INPUT->{$n}->{NAME} = $n; + $INPUT->{$n}->{OUTPUT_TYPE} = undef; + $INPUT->{$n}->{LIBS} = ["\$(".uc($n)."_LIBS)"]; + $INPUT->{$n}->{LDFLAGS} = ["\$(".uc($n)."_LDFLAGS)"]; + $INPUT->{$n}->{CFLAGS} = ["\$(".uc($n)."_CFLAGS)"]; + $INPUT->{$n}->{CPPFLAGS} = ["\$(".uc($n)."_CPPFLAGS)"]; + $INPUT->{$n}->{ENABLE} = "YES"; +} + +sub calc_unique_deps($$$$$$$$) +{ + sub calc_unique_deps($$$$$$$$); + my ($name, $INPUT, $deps, $udeps, $withlibs, $forward, $pubonly, $busy) = @_; + + foreach my $n (@$deps) { + add_implicit($INPUT, $n) unless (defined($INPUT->{$n}) and defined($INPUT->{$n}->{TYPE})); + my $dep = $INPUT->{$n}; + if (grep (/^$n$/, @$busy)) { + next if (@{$dep->{OUTPUT_TYPE}}[0] eq "MERGED_OBJ"); + die("Recursive dependency: $n, list: " . join(',', @$busy)); + } + next if (grep /^$n$/, @$udeps); + + push (@{$udeps}, $n) if $forward; + + if (defined ($dep->{OUTPUT_TYPE}) && + ($withlibs or + (@{$dep->{OUTPUT_TYPE}}[0] eq "MERGED_OBJ") or + (@{$dep->{OUTPUT_TYPE}}[0] eq "STATIC_LIBRARY"))) { + push (@$busy, $n); + calc_unique_deps($n, $INPUT, $dep->{PUBLIC_DEPENDENCIES}, $udeps, $withlibs, $forward, $pubonly, $busy); + calc_unique_deps($n, $INPUT, $dep->{PRIVATE_DEPENDENCIES}, $udeps, $withlibs, $forward, $pubonly, $busy) unless $pubonly; + pop (@$busy); + } + + unshift (@{$udeps}, $n) unless $forward; + } +} + +sub check($$$$$) +{ + my ($INPUT, $enabled, $subsys_ot, $lib_ot, $module_ot) = @_; + + foreach my $part (values %$INPUT) { + if (defined($enabled->{$part->{NAME}})) { + $part->{ENABLE} = $enabled->{$part->{NAME}}; + next; + } + + unless(defined($part->{ENABLE})) { + if ($part->{TYPE} eq "EXT_LIB") { + $part->{ENABLE} = "NO"; + } else { + $part->{ENABLE} = "YES"; + } + } + } + + foreach my $part (values %$INPUT) { + $part->{LINK_FLAGS} = []; + $part->{FULL_OBJ_LIST} = ["\$($part->{NAME}_OBJ_FILES)"]; + + if ($part->{TYPE} eq "SUBSYSTEM") { + check_subsystem($INPUT, $part, $subsys_ot); + } elsif ($part->{TYPE} eq "MODULE") { + check_module($INPUT, $part, $module_ot); + } elsif ($part->{TYPE} eq "LIBRARY") { + check_library($INPUT, $part, $lib_ot); + } elsif ($part->{TYPE} eq "BINARY") { + check_binary($INPUT, $part); + } elsif ($part->{TYPE} eq "PYTHON") { + check_python($INPUT, $part, $module_ot); + } elsif ($part->{TYPE} eq "EXT_LIB") { + } else { + die("Unknown type $part->{TYPE}"); + } + } + + foreach my $part (values %$INPUT) { + if (defined($part->{INIT_FUNCTIONS})) { + push (@{$part->{LINK_FLAGS}}, "\$(DYNEXP)"); + } + } + + foreach my $part (values %$INPUT) { + $part->{UNIQUE_DEPENDENCIES_LINK} = []; + calc_unique_deps($part->{NAME}, $INPUT, $part->{PUBLIC_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_LINK}, 0, 0, 0, []); + calc_unique_deps($part->{NAME}, $INPUT, $part->{PRIVATE_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_LINK}, 0, 0, 0, []); + } + + foreach my $part (values %$INPUT) { + $part->{UNIQUE_DEPENDENCIES_COMPILE} = []; + calc_unique_deps($part->{NAME}, $INPUT, $part->{PUBLIC_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_COMPILE}, 1, 1, 1, []); + calc_unique_deps($part->{NAME}, $INPUT, $part->{PRIVATE_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_COMPILE}, 1, 1, 1, []); + } + + foreach my $part (values %$INPUT) { + $part->{UNIQUE_DEPENDENCIES_ALL} = []; + calc_unique_deps($part->{NAME}, $INPUT, $part->{PUBLIC_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_ALL}, 1, 0, 0, []); + calc_unique_deps($part->{NAME}, $INPUT, $part->{PRIVATE_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_ALL}, 1, 0, 0, []); + } + + return $INPUT; +} + +1; diff --git a/source4/build/smb_build/main.pl b/source4/build/smb_build/main.pl new file mode 100644 index 0000000000..3c84a91a59 --- /dev/null +++ b/source4/build/smb_build/main.pl @@ -0,0 +1,104 @@ +# Samba Build System +# - the main program +# +# Copyright (C) Stefan (metze) Metzmacher 2004 +# Copyright (C) Jelmer Vernooij 2005 +# Released under the GNU GPL + +use smb_build::makefile; +use smb_build::input; +use smb_build::config_mk; +use smb_build::output; +use smb_build::summary; +use smb_build::config; +use Getopt::Long; +use strict; + +my $output_file = "data.mk"; + +my $result = GetOptions ( + 'output=s' => \$output_file); + +if (not $result) { + exit(1); +} + +my $input_file = shift @ARGV; + +my $INPUT = {}; +my $mkfile = smb_build::config_mk::run_config_mk($INPUT, $config::config{srcdir}, $config::config{builddir}, $input_file); + +my $subsys_output_type = ["MERGED_OBJ"]; + +my $library_output_type; +my $useshared = (defined($ENV{USESHARED})?$ENV{USESHARED}:$config::config{USESHARED}); + +if ($useshared eq "true") { + $library_output_type = ["SHARED_LIBRARY", "MERGED_OBJ"]; +} else { + $library_output_type = ["MERGED_OBJ"]; + push (@$library_output_type, "SHARED_LIBRARY") if + ($config::config{BLDSHARED} eq "true") +} + +my $module_output_type; +if ($useshared eq "true") { + $module_output_type = ["SHARED_LIBRARY"]; +} else { + $module_output_type = ["MERGED_OBJ"]; +} + +my $DEPEND = smb_build::input::check($INPUT, \%config::enabled, + $subsys_output_type, + $library_output_type, + $module_output_type); +my $OUTPUT = output::create_output($DEPEND, \%config::config); +my $mkenv = new smb_build::makefile(\%config::config, $mkfile); + +my $shared_libs_used = 0; +foreach my $key (values %$OUTPUT) { + next if ($key->{ENABLE} ne "YES"); + push(@{$mkenv->{all_objs}}, "\$($key->{NAME}_OBJ_FILES)"); +} + +foreach my $key (values %$OUTPUT) { + next unless defined $key->{OUTPUT_TYPE}; + + $mkenv->StaticLibraryPrimitives($key) if grep(/STATIC_LIBRARY/, @{$key->{OUTPUT_TYPE}}); + $mkenv->MergedObj($key) if grep(/MERGED_OBJ/, @{$key->{OUTPUT_TYPE}}); + $mkenv->SharedLibraryPrimitives($key) if ($key->{TYPE} eq "LIBRARY") and + grep(/SHARED_LIBRARY/, @{$key->{OUTPUT_TYPE}}); + if ($key->{TYPE} eq "LIBRARY" and + ${$key->{OUTPUT_TYPE}}[0] eq "SHARED_LIBRARY") { + $shared_libs_used = 1; + } + if ($key->{TYPE} eq "MODULE" and @{$key->{OUTPUT_TYPE}}[0] eq "MERGED_OBJ" and defined($key->{INIT_FUNCTION})) { + $mkenv->output("$key->{SUBSYSTEM}_INIT_FUNCTIONS += $key->{INIT_FUNCTION},\n"); + } + $mkenv->CFlags($key); +} + +foreach my $key (values %$OUTPUT) { + next unless defined $key->{OUTPUT_TYPE}; + + $mkenv->Integrated($key) if grep(/INTEGRATED/, @{$key->{OUTPUT_TYPE}}); +} + +foreach my $key (values %$OUTPUT) { + next unless defined $key->{OUTPUT_TYPE}; + $mkenv->StaticLibrary($key) if grep(/STATIC_LIBRARY/, @{$key->{OUTPUT_TYPE}}); + + $mkenv->SharedLibrary($key) if ($key->{TYPE} eq "LIBRARY") and + grep(/SHARED_LIBRARY/, @{$key->{OUTPUT_TYPE}}); + $mkenv->SharedModule($key) if ($key->{TYPE} eq "MODULE" and + grep(/SHARED_LIBRARY/, @{$key->{OUTPUT_TYPE}})); + $mkenv->PythonModule($key) if ($key->{TYPE} eq "PYTHON"); + $mkenv->Binary($key) if grep(/BINARY/, @{$key->{OUTPUT_TYPE}}); + $mkenv->InitFunctions($key) if defined($key->{INIT_FUNCTIONS}); +} + +$mkenv->write($output_file); + +summary::show($OUTPUT, \%config::config); + +1; diff --git a/source4/build/smb_build/makefile.pm b/source4/build/smb_build/makefile.pm new file mode 100644 index 0000000000..d9cbca0614 --- /dev/null +++ b/source4/build/smb_build/makefile.pm @@ -0,0 +1,281 @@ +# Samba Build System +# - create output for Makefile +# +# Copyright (C) Stefan (metze) Metzmacher 2004 +# Copyright (C) Jelmer Vernooij 2005 +# Released under the GNU GPL + +package smb_build::makefile; +use smb_build::output; +use File::Basename; +use strict; + +use Cwd 'abs_path'; + +sub new($$$) +{ + my ($myname, $config, $mkfile) = @_; + my $self = {}; + + bless($self, $myname); + + $self->_set_config($config); + + $self->{output} = ""; + + $self->output("################################################\n"); + $self->output("# Autogenerated by build/smb_build/makefile.pm #\n"); + $self->output("################################################\n"); + $self->output("\n"); + $self->output($mkfile); + + return $self; +} + +sub _set_config($$) +{ + my ($self, $config) = @_; + + $self->{config} = $config; + + if (not defined($self->{config}->{srcdir})) { + $self->{config}->{srcdir} = '.'; + } + + if (not defined($self->{config}->{builddir})) { + $self->{config}->{builddir} = '.'; + } + + if ($self->{config}->{prefix} eq "NONE") { + $self->{config}->{prefix} = $self->{config}->{ac_default_prefix}; + } + + if ($self->{config}->{exec_prefix} eq "NONE") { + $self->{config}->{exec_prefix} = $self->{config}->{prefix}; + } +} + +sub output($$) +{ + my ($self, $text) = @_; + + $self->{output} .= $text; +} + +sub _prepare_mk_files($) +{ + my $self = shift; + my @tmp = (); + + foreach (@smb_build::config_mk::parsed_files) { + s/ .*$//g; + push (@tmp, $_); + } + + $self->output("MK_FILES = " . array2oneperline(\@tmp) . "\n"); +} + +sub array2oneperline($) +{ + my $array = shift; + my $output = ""; + + foreach (@$array) { + next unless defined($_); + + $output .= " \\\n\t\t$_"; + } + + return $output; +} + +sub _prepare_list($$$) +{ + my ($self,$ctx,$var) = @_; + my @tmparr = (); + + push(@tmparr, @{$ctx->{$var}}) if defined($ctx->{$var}); + + my $tmplist = array2oneperline(\@tmparr); + return if ($tmplist eq ""); + + $self->output("$ctx->{NAME}_$var =$tmplist\n"); +} + +sub PythonModule($$) +{ + my ($self,$ctx) = @_; + + $self->_prepare_list($ctx, "FULL_OBJ_LIST"); + $self->_prepare_list($ctx, "DEPEND_LIST"); + $self->_prepare_list($ctx, "LINK_FLAGS"); + + $self->output("\$(eval \$(call python_c_module_template,$ctx->{LIBRARY_REALNAME},\$($ctx->{NAME}_DEPEND_LIST) \$($ctx->{NAME}_FULL_OBJ_LIST), \$($ctx->{NAME}\_FULL_OBJ_LIST) \$($ctx->{NAME}_LINK_FLAGS)))\n"); +} + +sub SharedModule($$) +{ + my ($self,$ctx) = @_; + + my $sane_subsystem = lc($ctx->{SUBSYSTEM}); + $sane_subsystem =~ s/^lib//; + + $self->output("PLUGINS += $ctx->{SHAREDDIR}/$ctx->{LIBRARY_REALNAME}\n"); + $self->output("\$(eval \$(call shared_module_install_template,$sane_subsystem,$ctx->{LIBRARY_REALNAME}))\n"); + + $self->_prepare_list($ctx, "FULL_OBJ_LIST"); + $self->_prepare_list($ctx, "DEPEND_LIST"); + $self->_prepare_list($ctx, "LINK_FLAGS"); + + if (defined($ctx->{INIT_FUNCTION}) and $ctx->{INIT_FUNCTION_TYPE} =~ /\(\*\)/ and not ($ctx->{INIT_FUNCTION} =~ /\(/)) { + $self->output("\$($ctx->{NAME}_OBJ_FILES): CFLAGS+=-D$ctx->{INIT_FUNCTION}=init_module\n"); + } + + $self->output("\$(eval \$(call shared_module_template,$ctx->{SHAREDDIR}/$ctx->{LIBRARY_REALNAME}, \$($ctx->{NAME}_DEPEND_LIST) \$($ctx->{NAME}_FULL_OBJ_LIST), \$($ctx->{NAME}\_FULL_OBJ_LIST) \$($ctx->{NAME}_LINK_FLAGS)))\n"); + + + if (defined($ctx->{ALIASES})) { + $self->output("\$(eval \$(foreach alias,". join(' ', @{$ctx->{ALIASES}}) . ",\$(call shared_module_alias_template,$ctx->{SHAREDDIR}/$ctx->{LIBRARY_REALNAME},$sane_subsystem,\$(alias))))\n"); + } +} + +sub StaticLibraryPrimitives($$) +{ + my ($self,$ctx) = @_; + + $self->output("$ctx->{NAME}_OUTPUT = $ctx->{OUTPUT}\n"); + $self->_prepare_list($ctx, "FULL_OBJ_LIST"); +} + +sub SharedLibraryPrimitives($$) +{ + my ($self,$ctx) = @_; + + if (not grep(/STATIC_LIBRARY/, @{$ctx->{OUTPUT_TYPE}})) { + $self->output("$ctx->{NAME}_OUTPUT = $ctx->{OUTPUT}\n"); + $self->_prepare_list($ctx, "FULL_OBJ_LIST"); + } +} + +sub SharedLibrary($$) +{ + my ($self,$ctx) = @_; + + $self->output("SHARED_LIBS += $ctx->{RESULT_SHARED_LIBRARY}\n"); + + $self->_prepare_list($ctx, "DEPEND_LIST"); + $self->_prepare_list($ctx, "LINK_FLAGS"); + + $self->output("\$(eval \$(call shared_library_template,$ctx->{RESULT_SHARED_LIBRARY}, \$($ctx->{NAME}_DEPEND_LIST) \$($ctx->{NAME}_FULL_OBJ_LIST), \$($ctx->{NAME}\_FULL_OBJ_LIST) \$($ctx->{NAME}_LINK_FLAGS),$ctx->{SHAREDDIR}/$ctx->{LIBRARY_SONAME},$ctx->{SHAREDDIR}/$ctx->{LIBRARY_DEBUGNAME}))\n"); +} + +sub MergedObj($$) +{ + my ($self, $ctx) = @_; + + $self->output("\$(call partial_link_template, $ctx->{OUTPUT}, \$($ctx->{NAME}_OBJ_FILES))\n"); +} + +sub InitFunctions($$) +{ + my ($self, $ctx) = @_; + $self->output("\$($ctx->{NAME}_OBJ_FILES): CFLAGS+=-DSTATIC_$ctx->{NAME}_MODULES=\"\$($ctx->{NAME}_INIT_FUNCTIONS)$ctx->{INIT_FUNCTION_SENTINEL}\"\n"); +} + +sub StaticLibrary($$) +{ + my ($self,$ctx) = @_; + + $self->output("STATIC_LIBS += $ctx->{RESULT_STATIC_LIBRARY}\n") if ($ctx->{TYPE} eq "LIBRARY"); + $self->output("$ctx->{NAME}_OUTPUT = $ctx->{OUTPUT}\n"); + $self->output("$ctx->{RESULT_STATIC_LIBRARY}: \$($ctx->{NAME}_FULL_OBJ_LIST)\n"); +} + +sub Binary($$) +{ + my ($self,$ctx) = @_; + + unless (defined($ctx->{INSTALLDIR})) { + } elsif ($ctx->{INSTALLDIR} eq "SBINDIR") { + $self->output("\$(eval \$(call sbinary_install_template,$ctx->{RESULT_BINARY}))\n"); + } elsif ($ctx->{INSTALLDIR} eq "BINDIR") { + $self->output("\$(eval \$(call binary_install_template,$ctx->{RESULT_BINARY}))\n"); + } + + $self->_prepare_list($ctx, "FULL_OBJ_LIST"); + $self->_prepare_list($ctx, "DEPEND_LIST"); + $self->_prepare_list($ctx, "LINK_FLAGS"); + + if (defined($ctx->{USE_HOSTCC}) && $ctx->{USE_HOSTCC} eq "YES") { +$self->output("\$(eval \$(call host_binary_link_template, $ctx->{RESULT_BINARY}, \$($ctx->{NAME}_FULL_OBJ_LIST) \$($ctx->{NAME}_DEPEND_LIST), \$($ctx->{NAME}_LINK_FLAGS)))\n"); + } else { +$self->output("\$(eval \$(call binary_link_template, $ctx->{RESULT_BINARY}, \$($ctx->{NAME}_FULL_OBJ_LIST) \$($ctx->{NAME}_DEPEND_LIST), \$($ctx->{NAME}_LINK_FLAGS)))\n"); + } +} + +sub write($$) +{ + my ($self, $file) = @_; + + $self->_prepare_mk_files(); + + $self->output("ALL_OBJS = " . array2oneperline($self->{all_objs}) . "\n"); + + open(MAKEFILE,">$file") || die ("Can't open $file\n"); + print MAKEFILE $self->{output}; + close(MAKEFILE); + + print __FILE__.": creating $file\n"; +} + +my $sort_available = eval "use sort 'stable'; return 1;"; +$sort_available = 0 unless defined($sort_available); + +sub by_path { + return 1 if($a =~ m#^\-I/#); + return -1 if($b =~ m#^\-I/#); + return 0; +} + +sub CFlags($$) +{ + my ($self, $key) = @_; + + my $srcdir = $self->{config}->{srcdir}; + my $builddir = $self->{config}->{builddir}; + + my $src_ne_build = ($srcdir ne $builddir) ? 1 : 0; + + return unless defined ($key->{FINAL_CFLAGS}); + return unless (@{$key->{FINAL_CFLAGS}} > 0); + + my @sorted_cflags = @{$key->{FINAL_CFLAGS}}; + if ($sort_available) { + @sorted_cflags = sort by_path @{$key->{FINAL_CFLAGS}}; + } + + # Rewrite CFLAGS so that both the source and the build + # directories are in the path. + my @cflags = (); + foreach my $flag (@sorted_cflags) { + if($src_ne_build) { + if($flag =~ m#^-I([^/].*$)#) { + my $dir = $1; + if ($dir =~ /^\$\(/) { + push (@cflags, $flag); + next; + } + $dir =~ s#^\$\((?:src|build)dir\)/?##; + push(@cflags, "-I$builddir/$dir", "-I$srcdir/$dir"); + next; + } + } + push(@cflags, $flag); + } + + my $cflags = join(' ', @cflags); + + $self->output("\$(patsubst %.ho,%.d,\$($key->{NAME}_OBJ_FILES:.o=.d)) \$($key->{NAME}_OBJ_FILES): CFLAGS+= $cflags\n"); +} + +1; diff --git a/source4/build/smb_build/output.pm b/source4/build/smb_build/output.pm new file mode 100644 index 0000000000..76c6d3fc8f --- /dev/null +++ b/source4/build/smb_build/output.pm @@ -0,0 +1,172 @@ +# SMB Build System +# - the output generating functions +# +# Copyright (C) Stefan (metze) Metzmacher 2004 +# Copyright (C) Jelmer Vernooij 2004 +# Released under the GNU GPL + +package output; +use strict; + +sub generate_shared_library($) +{ + my $lib = shift; + my $link_name; + my $lib_name; + + $lib->{DEPEND_LIST} = []; + + $link_name = lc($lib->{NAME}); + $lib_name = $link_name; + + if ($lib->{TYPE} eq "LIBRARY") { + $link_name = $lib->{NAME}; + $link_name =~ s/^LIB//; + $link_name = lc($link_name); + $lib_name = "lib$link_name"; + } + + if ($lib->{TYPE} eq "PYTHON") { + $lib->{SHAREDDIR} = "bin/python"; + } elsif (defined($lib->{LIBRARY_REALNAME})) { + $lib->{BASEDIR} =~ s/^\.\///g; + $lib->{SHAREDDIR} = $lib->{BASEDIR}; + } else { + if ($lib->{TYPE} eq "MODULE") { + my $sane_subsystem = lc($lib->{SUBSYSTEM}); + $sane_subsystem =~ s/^lib//; + $lib->{SHAREDDIR} = "bin/modules/$sane_subsystem"; + $lib->{LIBRARY_REALNAME} = $link_name; + $lib->{LIBRARY_REALNAME} =~ s/^$sane_subsystem\_//g; + $lib->{LIBRARY_REALNAME}.= ".\$(SHLIBEXT)"; + } else { + $lib->{SHAREDDIR} = "bin/shared"; + $lib->{LIBRARY_REALNAME} = "$lib_name.\$(SHLIBEXT)"; + } + } + + $lib->{LIBRARY_DEBUGNAME} = $lib->{LIBRARY_REALNAME}; + + $lib->{LIBRARY_SONAME} = "\$(if \$($lib->{NAME}_SOVERSION),$lib->{LIBRARY_REALNAME}.\$($lib->{NAME}_SOVERSION),$lib->{LIBRARY_REALNAME})"; + $lib->{LIBRARY_REALNAME} = "\$(if \$($lib->{NAME}_VERSION),$lib->{LIBRARY_REALNAME}.\$($lib->{NAME}_VERSION),$lib->{LIBRARY_REALNAME})"; + + $lib->{RESULT_SHARED_LIBRARY} = "$lib->{SHAREDDIR}/$lib->{LIBRARY_REALNAME}"; + $lib->{OUTPUT_SHARED_LIBRARY} = "-l$link_name"; + $lib->{TARGET_SHARED_LIBRARY} = "$lib->{SHAREDDIR}/$lib->{LIBRARY_DEBUGNAME}"; +} + +sub generate_merged_obj($) +{ + my $lib = shift; + + my $link_name = $lib->{NAME}; + $link_name =~ s/^LIB//; + + $lib->{MERGED_OBJNAME} = lc($link_name).".o"; + $lib->{RESULT_MERGED_OBJ} = $lib->{OUTPUT_MERGED_OBJ} = "bin/mergedobj/$lib->{MERGED_OBJNAME}"; + $lib->{TARGET_MERGED_OBJ} = $lib->{RESULT_MERGED_OBJ}; +} + +sub generate_static_library($) +{ + my $lib = shift; + my $link_name; + + $lib->{DEPEND_LIST} = []; + + $link_name = $lib->{NAME}; + $link_name =~ s/^LIB//; + + $lib->{LIBRARY_NAME} = "lib".lc($link_name).".a"; + + $lib->{RESULT_STATIC_LIBRARY} = "bin/static/$lib->{LIBRARY_NAME}"; + $lib->{TARGET_STATIC_LIBRARY} = $lib->{RESULT_STATIC_LIBRARY}; + $lib->{STATICDIR} = 'bin/static'; + $lib->{OUTPUT_STATIC_LIBRARY} = "-l".lc($link_name); +} + +sub generate_binary($) +{ + my $bin = shift; + + $bin->{DEPEND_LIST} = []; + push(@{$bin->{LINK_FLAGS}}, "\$($bin->{NAME}\_FULL_OBJ_LIST)"); + + $bin->{DEBUGDIR} = "bin"; + $bin->{RESULT_BINARY} = $bin->{OUTPUT_BINARY} = "$bin->{DEBUGDIR}/$bin->{NAME}"; + $bin->{TARGET_BINARY} = $bin->{RESULT_BINARY}; + $bin->{BINARY} = $bin->{NAME}; +} + +sub merge_array($$) +{ + # $dest is a reference to an array + # $src is an array + my ($dest, $src) = @_; + + return unless defined($src); + return unless ($#{$src} >= 0); + + foreach my $line (@{$src}) { + next if (grep /^$line$/, @{$$dest}); + push(@{$$dest}, $line); + } +} + +sub create_output($$) +{ + my ($depend, $config) = @_; + my $part; + + foreach $part (values %{$depend}) { + next unless(defined($part->{OUTPUT_TYPE})); + + generate_binary($part) if grep(/BINARY/, @{$part->{OUTPUT_TYPE}}); + generate_shared_library($part) if grep(/SHARED_LIBRARY/, @{$part->{OUTPUT_TYPE}}); + generate_static_library($part) if grep(/STATIC_LIBRARY/, @{$part->{OUTPUT_TYPE}}); + generate_merged_obj($part) if grep(/MERGED_OBJ/, @{$part->{OUTPUT_TYPE}}); + $part->{OUTPUT} = $part->{"OUTPUT_" . @{$part->{OUTPUT_TYPE}}[0]}; + $part->{TARGET} = $part->{"TARGET_" . @{$part->{OUTPUT_TYPE}}[0]}; + } + + foreach $part (values %{$depend}) { + next if not defined($part->{OUTPUT_TYPE}); + + merge_array(\$part->{FINAL_CFLAGS}, $part->{CPPFLAGS}); + merge_array(\$part->{FINAL_CFLAGS}, $part->{CFLAGS}); + + foreach (@{$part->{UNIQUE_DEPENDENCIES_ALL}}) { + my $elem = $depend->{$_}; + next if $elem == $part; + + merge_array(\$part->{FINAL_CFLAGS}, $elem->{CPPFLAGS}); + merge_array(\$part->{FINAL_CFLAGS}, $elem->{CFLAGS}); + } + + # Always import the link options of the unique dependencies + foreach (@{$part->{UNIQUE_DEPENDENCIES_LINK}}) { + my $elem = $depend->{$_}; + next if $elem == $part; + + push(@{$part->{LINK_FLAGS}}, @{$elem->{LIBS}}) if defined($elem->{LIBS}); + push(@{$part->{LINK_FLAGS}}, @{$elem->{LDFLAGS}}) if defined($elem->{LDFLAGS}); + if (defined($elem->{OUTPUT_TYPE}) and @{$elem->{OUTPUT_TYPE}}[0] eq "MERGED_OBJ") { + push (@{$part->{FULL_OBJ_LIST}}, $elem->{TARGET}); + } else { + push(@{$part->{LINK_FLAGS}}, "\$($elem->{NAME}_OUTPUT)") if defined($elem->{OUTPUT}); + push(@{$part->{DEPEND_LIST}}, $elem->{TARGET}) if (defined($elem->{TARGET})); + } + } + } + + foreach $part (values %{$depend}) { + if (defined($part->{STANDARD_VISIBILITY}) and ($part->{STANDARD_VISIBILITY} ne "default") and + ($config->{visibility_attribute} eq "yes")) { + push(@{$part->{FINAL_CFLAGS}}, "-fvisibility=$part->{STANDARD_VISIBILITY}"); + } + } + + return $depend; +} + +1; diff --git a/source4/build/smb_build/summary.pm b/source4/build/smb_build/summary.pm new file mode 100644 index 0000000000..4ea1ad525e --- /dev/null +++ b/source4/build/smb_build/summary.pm @@ -0,0 +1,79 @@ +# Samba Build System +# - write out summary +# +# Copyright (C) Jelmer Vernooij 2006 +# Released under the GNU GPL + +package summary; +use smb_build::config; +use strict; + +sub enabled($) +{ + my ($val) = @_; + + return (defined($val) && $val =~ m/yes|true/i); +} + +sub showitem($$$) +{ + my ($output,$desc,$items) = @_; + + my @need = (); + + foreach (@$items) { + push (@need, $_) if (enabled($config::enable{$_})); + } + + print "Support for $desc: "; + if ($#need >= 0) { + print "no (install " . join(',',@need) . ")\n"; + } else { + print "yes\n"; + } +} + +sub showisexternal($$$) +{ + my ($output, $desc, $name) = @_; + print "Using external $desc: ". + (($output->{$name}->{TYPE} eq "EXT_LIB")?"yes":"no")."\n"; +} + +sub show($$) +{ + my ($output,$config) = @_; + + print "Summary:\n\n"; + showitem($output, "SSL in SWAT and LDAP", ["GNUTLS"]); + showitem($output, "threads in smbd (see --with-pthread)", ["PTHREAD"]); + showitem($output, "intelligent command line editing", ["READLINE"]); + showitem($output, "changing process titles (see --with-setproctitle)", ["SETPROCTITLE"]); + showitem($output, "using extended attributes", ["XATTR"]); + showitem($output, "using libblkid", ["BLKID"]); + showitem($output, "using iconv", ["ICONV"]); + showitem($output, "using pam", ["PAM"]); + showitem($output, "python bindings", ["LIBPYTHON"]); + showisexternal($output, "popt", "LIBPOPT"); + showisexternal($output, "talloc", "LIBTALLOC"); + showisexternal($output, "tdb", "LIBTDB"); + showisexternal($output, "ldb", "LIBLDB"); + print "Developer mode: ".(enabled($config->{developer})?"yes":"no")."\n"; + print "Automatic dependencies: ". + (enabled($config->{automatic_dependencies}) + ? "yes" : "no (install GNU make >= 3.81 and see --enable-automatic-dependencies)") . + "\n"; + + print "Building shared libraries: " . + (enabled($config->{BLDSHARED}) + ? "yes" : "no (not supported on this system)") . + "\n"; + print "Using shared libraries internally: " . + (enabled($config->{USESHARED}) + ? "yes" : "no (specify --enable-dso)") . + "\n"; + + print "\n"; +} + +1; diff --git a/source4/build/tests/README b/source4/build/tests/README new file mode 100644 index 0000000000..cf1be8b00a --- /dev/null +++ b/source4/build/tests/README @@ -0,0 +1,10 @@ +This directory contains autoconf test programs that are too large to +comfortably fit in configure.in. + +These programs should test one feature of the OS and exit(0) if it +works or exit(1) if it doesn't work (do _not_ use return) + +The programs should be kept simple and to the point. Beautiful/fast +code is not necessary + + diff --git a/source4/build/tests/crypttest.c b/source4/build/tests/crypttest.c new file mode 100644 index 0000000000..0e500d5481 --- /dev/null +++ b/source4/build/tests/crypttest.c @@ -0,0 +1,851 @@ +#if defined(HAVE_UNISTD_H) +#include <unistd.h> +#endif + +#include <sys/types.h> + +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif + +#if !defined(HAVE_CRYPT) + +/* + This bit of code was derived from the UFC-crypt package which + carries the following copyright + + Modified for use by Samba by Andrew Tridgell, October 1994 + + Note that this routine is only faster on some machines. Under Linux 1.1.51 + libc 4.5.26 I actually found this routine to be slightly slower. + + Under SunOS I found a huge speedup by using these routines + (a factor of 20 or so) + + Warning: I've had a report from Steve Kennedy <steve@gbnet.org> + that this crypt routine may sometimes get the wrong answer. Only + use UFC_CRYT if you really need it. + +*/ + +/* + * UFC-crypt: ultra fast crypt(3) implementation + * + * Copyright (C) 1991-1998, Free Software Foundation, Inc. + * + * 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 + * Library 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, see <http://www.gnu.org/licenses/>. + * + * @(#)crypt_util.c 2.31 02/08/92 + * + * Support routines + * + */ + + +#ifndef long32 +#if (SIZEOF_INT == 4) +#define long32 int +#elif (SIZEOF_LONG == 4) +#define long32 long +#elif (SIZEOF_SHORT == 4) +#define long32 short +#else +/* uggh - no 32 bit type?? probably a CRAY. just hope this works ... */ +#define long32 int +#endif +#endif + +#ifndef long64 +#ifdef HAVE_LONGLONG +#define long64 long long long +#endif +#endif + +#ifndef ufc_long +#define ufc_long unsigned +#endif + +#ifndef _UFC_64_ +#define _UFC_32_ +#endif + +/* + * Permutation done once on the 56 bit + * key derived from the original 8 byte ASCII key. + */ +static int pc1[56] = { + 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 +}; + +/* + * How much to rotate each 28 bit half of the pc1 permutated + * 56 bit key before using pc2 to give the i' key + */ +static int rots[16] = { + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 +}; + +/* + * Permutation giving the key + * of the i' DES round + */ +static int pc2[48] = { + 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 +}; + +/* + * The E expansion table which selects + * bits from the 32 bit intermediate result. + */ +static int esel[48] = { + 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 +}; +static int e_inverse[64]; + +/* + * Permutation done on the + * result of sbox lookups + */ +static int perm32[32] = { + 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, + 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 +}; + +/* + * The sboxes + */ +static int sbox[8][4][16]= { + { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 }, + { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 }, + { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 }, + { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } + }, + + { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 }, + { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 }, + { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 }, + { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } + }, + + { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 }, + { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 }, + { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 }, + { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } + }, + + { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 }, + { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 }, + { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 }, + { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } + }, + + { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 }, + { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 }, + { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 }, + { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } + }, + + { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 }, + { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 }, + { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 }, + { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } + }, + + { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 }, + { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 }, + { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 }, + { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } + }, + + { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 }, + { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 }, + { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 }, + { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } + } +}; + +/* + * This is the final + * permutation matrix + */ +static int final_perm[64] = { + 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25 +}; + +/* + * The 16 DES keys in BITMASK format + */ +#ifdef _UFC_32_ +long32 _ufc_keytab[16][2]; +#endif + +#ifdef _UFC_64_ +long64 _ufc_keytab[16]; +#endif + + +#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.') +#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.') + +/* Macro to set a bit (0..23) */ +#define BITMASK(i) ( (1<<(11-(i)%12+3)) << ((i)<12?16:0) ) + +/* + * sb arrays: + * + * Workhorses of the inner loop of the DES implementation. + * They do sbox lookup, shifting of this value, 32 bit + * permutation and E permutation for the next round. + * + * Kept in 'BITMASK' format. + */ + +#ifdef _UFC_32_ +long32 _ufc_sb0[8192], _ufc_sb1[8192], _ufc_sb2[8192], _ufc_sb3[8192]; +static long32 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3}; +#endif + +#ifdef _UFC_64_ +long64 _ufc_sb0[4096], _ufc_sb1[4096], _ufc_sb2[4096], _ufc_sb3[4096]; +static long64 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3}; +#endif + +/* + * eperm32tab: do 32 bit permutation and E selection + * + * The first index is the byte number in the 32 bit value to be permuted + * - second - is the value of this byte + * - third - selects the two 32 bit values + * + * The table is used and generated internally in init_des to speed it up + */ +static ufc_long eperm32tab[4][256][2]; + +/* + * do_pc1: permform pc1 permutation in the key schedule generation. + * + * The first index is the byte number in the 8 byte ASCII key + * - second - - the two 28 bits halfs of the result + * - third - selects the 7 bits actually used of each byte + * + * The result is kept with 28 bit per 32 bit with the 4 most significant + * bits zero. + */ +static ufc_long do_pc1[8][2][128]; + +/* + * do_pc2: permform pc2 permutation in the key schedule generation. + * + * The first index is the septet number in the two 28 bit intermediate values + * - second - - - septet values + * + * Knowledge of the structure of the pc2 permutation is used. + * + * The result is kept with 28 bit per 32 bit with the 4 most significant + * bits zero. + */ +static ufc_long do_pc2[8][128]; + +/* + * efp: undo an extra e selection and do final + * permutation giving the DES result. + * + * Invoked 6 bit a time on two 48 bit values + * giving two 32 bit longs. + */ +static ufc_long efp[16][64][2]; + +static unsigned char bytemask[8] = { + 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 +}; + +static ufc_long longmask[32] = { + 0x80000000, 0x40000000, 0x20000000, 0x10000000, + 0x08000000, 0x04000000, 0x02000000, 0x01000000, + 0x00800000, 0x00400000, 0x00200000, 0x00100000, + 0x00080000, 0x00040000, 0x00020000, 0x00010000, + 0x00008000, 0x00004000, 0x00002000, 0x00001000, + 0x00000800, 0x00000400, 0x00000200, 0x00000100, + 0x00000080, 0x00000040, 0x00000020, 0x00000010, + 0x00000008, 0x00000004, 0x00000002, 0x00000001 +}; + + +/* + * Silly rewrite of 'bzero'. I do so + * because some machines don't have + * bzero and some don't have memset. + */ + +static void clearmem(char *start, int cnt) + { while(cnt--) + *start++ = '\0'; + } + +static int initialized = 0; + +/* lookup a 6 bit value in sbox */ + +#define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf]; + +/* + * Initialize unit - may be invoked directly + * by fcrypt users. + */ + +static void ufc_init_des(void) + { int comes_from_bit; + int bit, sg; + ufc_long j; + ufc_long mask1, mask2; + + /* + * Create the do_pc1 table used + * to affect pc1 permutation + * when generating keys + */ + for(bit = 0; bit < 56; bit++) { + comes_from_bit = pc1[bit] - 1; + mask1 = bytemask[comes_from_bit % 8 + 1]; + mask2 = longmask[bit % 28 + 4]; + for(j = 0; j < 128; j++) { + if(j & mask1) + do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2; + } + } + + /* + * Create the do_pc2 table used + * to affect pc2 permutation when + * generating keys + */ + for(bit = 0; bit < 48; bit++) { + comes_from_bit = pc2[bit] - 1; + mask1 = bytemask[comes_from_bit % 7 + 1]; + mask2 = BITMASK(bit % 24); + for(j = 0; j < 128; j++) { + if(j & mask1) + do_pc2[comes_from_bit / 7][j] |= mask2; + } + } + + /* + * Now generate the table used to do combined + * 32 bit permutation and e expansion + * + * We use it because we have to permute 16384 32 bit + * longs into 48 bit in order to initialize sb. + * + * Looping 48 rounds per permutation becomes + * just too slow... + * + */ + + clearmem((char*)eperm32tab, sizeof(eperm32tab)); + + for(bit = 0; bit < 48; bit++) { + ufc_long inner_mask1,comes_from; + + comes_from = perm32[esel[bit]-1]-1; + inner_mask1 = bytemask[comes_from % 8]; + + for(j = 256; j--;) { + if(j & inner_mask1) + eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK(bit % 24); + } + } + + /* + * Create the sb tables: + * + * For each 12 bit segment of an 48 bit intermediate + * result, the sb table precomputes the two 4 bit + * values of the sbox lookups done with the two 6 + * bit halves, shifts them to their proper place, + * sends them through perm32 and finally E expands + * them so that they are ready for the next + * DES round. + * + */ + for(sg = 0; sg < 4; sg++) { + int j1, j2; + int s1, s2; + + for(j1 = 0; j1 < 64; j1++) { + s1 = s_lookup(2 * sg, j1); + for(j2 = 0; j2 < 64; j2++) { + ufc_long to_permute, inx; + + s2 = s_lookup(2 * sg + 1, j2); + to_permute = ((s1 << 4) | s2) << (24 - 8 * sg); + +#ifdef _UFC_32_ + inx = ((j1 << 6) | j2) << 1; + sb[sg][inx ] = eperm32tab[0][(to_permute >> 24) & 0xff][0]; + sb[sg][inx+1] = eperm32tab[0][(to_permute >> 24) & 0xff][1]; + sb[sg][inx ] |= eperm32tab[1][(to_permute >> 16) & 0xff][0]; + sb[sg][inx+1] |= eperm32tab[1][(to_permute >> 16) & 0xff][1]; + sb[sg][inx ] |= eperm32tab[2][(to_permute >> 8) & 0xff][0]; + sb[sg][inx+1] |= eperm32tab[2][(to_permute >> 8) & 0xff][1]; + sb[sg][inx ] |= eperm32tab[3][(to_permute) & 0xff][0]; + sb[sg][inx+1] |= eperm32tab[3][(to_permute) & 0xff][1]; +#endif +#ifdef _UFC_64_ + inx = ((j1 << 6) | j2); + sb[sg][inx] = + ((long64)eperm32tab[0][(to_permute >> 24) & 0xff][0] << 32) | + (long64)eperm32tab[0][(to_permute >> 24) & 0xff][1]; + sb[sg][inx] |= + ((long64)eperm32tab[1][(to_permute >> 16) & 0xff][0] << 32) | + (long64)eperm32tab[1][(to_permute >> 16) & 0xff][1]; + sb[sg][inx] |= + ((long64)eperm32tab[2][(to_permute >> 8) & 0xff][0] << 32) | + (long64)eperm32tab[2][(to_permute >> 8) & 0xff][1]; + sb[sg][inx] |= + ((long64)eperm32tab[3][(to_permute) & 0xff][0] << 32) | + (long64)eperm32tab[3][(to_permute) & 0xff][1]; +#endif + } + } + } + + /* + * Create an inverse matrix for esel telling + * where to plug out bits if undoing it + */ + for(bit=48; bit--;) { + e_inverse[esel[bit] - 1 ] = bit; + e_inverse[esel[bit] - 1 + 32] = bit + 48; + } + + /* + * create efp: the matrix used to + * undo the E expansion and effect final permutation + */ + clearmem((char*)efp, sizeof efp); + for(bit = 0; bit < 64; bit++) { + int o_bit, o_long; + ufc_long word_value, inner_mask1, inner_mask2; + int comes_from_f_bit, comes_from_e_bit; + int comes_from_word, bit_within_word; + + /* See where bit i belongs in the two 32 bit long's */ + o_long = bit / 32; /* 0..1 */ + o_bit = bit % 32; /* 0..31 */ + + /* + * And find a bit in the e permutated value setting this bit. + * + * Note: the e selection may have selected the same bit several + * times. By the initialization of e_inverse, we only look + * for one specific instance. + */ + comes_from_f_bit = final_perm[bit] - 1; /* 0..63 */ + comes_from_e_bit = e_inverse[comes_from_f_bit]; /* 0..95 */ + comes_from_word = comes_from_e_bit / 6; /* 0..15 */ + bit_within_word = comes_from_e_bit % 6; /* 0..5 */ + + inner_mask1 = longmask[bit_within_word + 26]; + inner_mask2 = longmask[o_bit]; + + for(word_value = 64; word_value--;) { + if(word_value & inner_mask1) + efp[comes_from_word][word_value][o_long] |= inner_mask2; + } + } + initialized++; + } + +/* + * Process the elements of the sb table permuting the + * bits swapped in the expansion by the current salt. + */ + +#ifdef _UFC_32_ +static void shuffle_sb(long32 *k, ufc_long saltbits) + { ufc_long j; + long32 x; + for(j=4096; j--;) { + x = (k[0] ^ k[1]) & (long32)saltbits; + *k++ ^= x; + *k++ ^= x; + } + } +#endif + +#ifdef _UFC_64_ +static void shuffle_sb(long64 *k, ufc_long saltbits) + { ufc_long j; + long64 x; + for(j=4096; j--;) { + x = ((*k >> 32) ^ *k) & (long64)saltbits; + *k++ ^= (x << 32) | x; + } + } +#endif + +/* + * Setup the unit for a new salt + * Hopefully we'll not see a new salt in each crypt call. + */ + +static unsigned char current_salt[3] = "&&"; /* invalid value */ +static ufc_long current_saltbits = 0; +static int direction = 0; + +static void setup_salt(const char *s1) + { ufc_long i, j, saltbits; + const unsigned char *s2 = (const unsigned char *)s1; + + if(!initialized) + ufc_init_des(); + + if(s2[0] == current_salt[0] && s2[1] == current_salt[1]) + return; + current_salt[0] = s2[0]; current_salt[1] = s2[1]; + + /* + * This is the only crypt change to DES: + * entries are swapped in the expansion table + * according to the bits set in the salt. + */ + saltbits = 0; + for(i = 0; i < 2; i++) { + long c=ascii_to_bin(s2[i]); + if(c < 0 || c > 63) + c = 0; + for(j = 0; j < 6; j++) { + if((c >> j) & 0x1) + saltbits |= BITMASK(6 * i + j); + } + } + + /* + * Permute the sb table values + * to reflect the changed e + * selection table + */ + shuffle_sb(_ufc_sb0, current_saltbits ^ saltbits); + shuffle_sb(_ufc_sb1, current_saltbits ^ saltbits); + shuffle_sb(_ufc_sb2, current_saltbits ^ saltbits); + shuffle_sb(_ufc_sb3, current_saltbits ^ saltbits); + + current_saltbits = saltbits; + } + +static void ufc_mk_keytab(char *key) + { ufc_long v1, v2, *k1; + int i; +#ifdef _UFC_32_ + long32 v, *k2 = &_ufc_keytab[0][0]; +#endif +#ifdef _UFC_64_ + long64 v, *k2 = &_ufc_keytab[0]; +#endif + + v1 = v2 = 0; k1 = &do_pc1[0][0][0]; + for(i = 8; i--;) { + v1 |= k1[*key & 0x7f]; k1 += 128; + v2 |= k1[*key++ & 0x7f]; k1 += 128; + } + + for(i = 0; i < 16; i++) { + k1 = &do_pc2[0][0]; + + v1 = (v1 << rots[i]) | (v1 >> (28 - rots[i])); + v = k1[(v1 >> 21) & 0x7f]; k1 += 128; + v |= k1[(v1 >> 14) & 0x7f]; k1 += 128; + v |= k1[(v1 >> 7) & 0x7f]; k1 += 128; + v |= k1[(v1 ) & 0x7f]; k1 += 128; + +#ifdef _UFC_32_ + *k2++ = v; + v = 0; +#endif +#ifdef _UFC_64_ + v <<= 32; +#endif + + v2 = (v2 << rots[i]) | (v2 >> (28 - rots[i])); + v |= k1[(v2 >> 21) & 0x7f]; k1 += 128; + v |= k1[(v2 >> 14) & 0x7f]; k1 += 128; + v |= k1[(v2 >> 7) & 0x7f]; k1 += 128; + v |= k1[(v2 ) & 0x7f]; + + *k2++ = v; + } + + direction = 0; + } + +/* + * Undo an extra E selection and do final permutations + */ + +ufc_long *_ufc_dofinalperm(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2) + { ufc_long v1, v2, x; + static ufc_long ary[2]; + + x = (l1 ^ l2) & current_saltbits; l1 ^= x; l2 ^= x; + x = (r1 ^ r2) & current_saltbits; r1 ^= x; r2 ^= x; + + v1=v2=0; l1 >>= 3; l2 >>= 3; r1 >>= 3; r2 >>= 3; + + v1 |= efp[15][ r2 & 0x3f][0]; v2 |= efp[15][ r2 & 0x3f][1]; + v1 |= efp[14][(r2 >>= 6) & 0x3f][0]; v2 |= efp[14][ r2 & 0x3f][1]; + v1 |= efp[13][(r2 >>= 10) & 0x3f][0]; v2 |= efp[13][ r2 & 0x3f][1]; + v1 |= efp[12][(r2 >>= 6) & 0x3f][0]; v2 |= efp[12][ r2 & 0x3f][1]; + + v1 |= efp[11][ r1 & 0x3f][0]; v2 |= efp[11][ r1 & 0x3f][1]; + v1 |= efp[10][(r1 >>= 6) & 0x3f][0]; v2 |= efp[10][ r1 & 0x3f][1]; + v1 |= efp[ 9][(r1 >>= 10) & 0x3f][0]; v2 |= efp[ 9][ r1 & 0x3f][1]; + v1 |= efp[ 8][(r1 >>= 6) & 0x3f][0]; v2 |= efp[ 8][ r1 & 0x3f][1]; + + v1 |= efp[ 7][ l2 & 0x3f][0]; v2 |= efp[ 7][ l2 & 0x3f][1]; + v1 |= efp[ 6][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 6][ l2 & 0x3f][1]; + v1 |= efp[ 5][(l2 >>= 10) & 0x3f][0]; v2 |= efp[ 5][ l2 & 0x3f][1]; + v1 |= efp[ 4][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 4][ l2 & 0x3f][1]; + + v1 |= efp[ 3][ l1 & 0x3f][0]; v2 |= efp[ 3][ l1 & 0x3f][1]; + v1 |= efp[ 2][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 2][ l1 & 0x3f][1]; + v1 |= efp[ 1][(l1 >>= 10) & 0x3f][0]; v2 |= efp[ 1][ l1 & 0x3f][1]; + v1 |= efp[ 0][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 0][ l1 & 0x3f][1]; + + ary[0] = v1; ary[1] = v2; + return ary; + } + +/* + * crypt only: convert from 64 bit to 11 bit ASCII + * prefixing with the salt + */ + +static char *output_conversion(ufc_long v1, ufc_long v2, const char *salt) + { static char outbuf[14]; + int i, s; + + outbuf[0] = salt[0]; + outbuf[1] = salt[1] ? salt[1] : salt[0]; + + for(i = 0; i < 5; i++) + outbuf[i + 2] = bin_to_ascii((v1 >> (26 - 6 * i)) & 0x3f); + + s = (v2 & 0xf) << 2; + v2 = (v2 >> 2) | ((v1 & 0x3) << 30); + + for(i = 5; i < 10; i++) + outbuf[i + 2] = bin_to_ascii((v2 >> (56 - 6 * i)) & 0x3f); + + outbuf[12] = bin_to_ascii(s); + outbuf[13] = 0; + + return outbuf; + } + +/* + * UNIX crypt function + */ + +static ufc_long *_ufc_doit(ufc_long , ufc_long, ufc_long, ufc_long, ufc_long); + +char *ufc_crypt(const char *key,const char *salt) + { ufc_long *s; + char ktab[9]; + + /* + * Hack DES tables according to salt + */ + setup_salt(salt); + + /* + * Setup key schedule + */ + clearmem(ktab, sizeof ktab); + strncpy(ktab, key, 8); + ufc_mk_keytab(ktab); + + /* + * Go for the 25 DES encryptions + */ + s = _ufc_doit((ufc_long)0, (ufc_long)0, + (ufc_long)0, (ufc_long)0, (ufc_long)25); + + /* + * And convert back to 6 bit ASCII + */ + return output_conversion(s[0], s[1], salt); + } + + +#ifdef _UFC_32_ + +/* + * 32 bit version + */ + +extern long32 _ufc_keytab[16][2]; +extern long32 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[]; + +#define SBA(sb, v) (*(long32*)((char*)(sb)+(v))) + +static ufc_long *_ufc_doit(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2, ufc_long itr) + { int i; + long32 s, *k; + + while(itr--) { + k = &_ufc_keytab[0][0]; + for(i=8; i--; ) { + s = *k++ ^ r1; + l1 ^= SBA(_ufc_sb1, s & 0xffff); l2 ^= SBA(_ufc_sb1, (s & 0xffff)+4); + l1 ^= SBA(_ufc_sb0, s >>= 16); l2 ^= SBA(_ufc_sb0, (s) +4); + s = *k++ ^ r2; + l1 ^= SBA(_ufc_sb3, s & 0xffff); l2 ^= SBA(_ufc_sb3, (s & 0xffff)+4); + l1 ^= SBA(_ufc_sb2, s >>= 16); l2 ^= SBA(_ufc_sb2, (s) +4); + + s = *k++ ^ l1; + r1 ^= SBA(_ufc_sb1, s & 0xffff); r2 ^= SBA(_ufc_sb1, (s & 0xffff)+4); + r1 ^= SBA(_ufc_sb0, s >>= 16); r2 ^= SBA(_ufc_sb0, (s) +4); + s = *k++ ^ l2; + r1 ^= SBA(_ufc_sb3, s & 0xffff); r2 ^= SBA(_ufc_sb3, (s & 0xffff)+4); + r1 ^= SBA(_ufc_sb2, s >>= 16); r2 ^= SBA(_ufc_sb2, (s) +4); + } + s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s; + } + return _ufc_dofinalperm(l1, l2, r1, r2); + } + +#endif + +#ifdef _UFC_64_ + +/* + * 64 bit version + */ + +extern long64 _ufc_keytab[16]; +extern long64 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[]; + +#define SBA(sb, v) (*(long64*)((char*)(sb)+(v))) + +static ufc_long *_ufc_doit(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2, ufc_long itr) + { int i; + long64 l, r, s, *k; + + l = (((long64)l1) << 32) | ((long64)l2); + r = (((long64)r1) << 32) | ((long64)r2); + + while(itr--) { + k = &_ufc_keytab[0]; + for(i=8; i--; ) { + s = *k++ ^ r; + l ^= SBA(_ufc_sb3, (s >> 0) & 0xffff); + l ^= SBA(_ufc_sb2, (s >> 16) & 0xffff); + l ^= SBA(_ufc_sb1, (s >> 32) & 0xffff); + l ^= SBA(_ufc_sb0, (s >> 48) & 0xffff); + + s = *k++ ^ l; + r ^= SBA(_ufc_sb3, (s >> 0) & 0xffff); + r ^= SBA(_ufc_sb2, (s >> 16) & 0xffff); + r ^= SBA(_ufc_sb1, (s >> 32) & 0xffff); + r ^= SBA(_ufc_sb0, (s >> 48) & 0xffff); + } + s=l; l=r; r=s; + } + + l1 = l >> 32; l2 = l & 0xffffffff; + r1 = r >> 32; r2 = r & 0xffffffff; + return _ufc_dofinalperm(l1, l2, r1, r2); + } + +#endif + +#define crypt ufc_crypt +#endif + +main() +{ + char passwd[9]; + char salt[9]; + char c_out1[256]; + char c_out2[256]; + + char expected_out[14]; + + strcpy(expected_out, "12yJ.Of/NQ.Pk"); + strcpy(passwd, "12345678"); + strcpy(salt, "12345678"); + + strcpy(c_out1, crypt(passwd, salt)); + salt[2] = '\0'; + strcpy(c_out2, crypt(passwd, salt)); + + /* + * If the non-trucated salt fails but the + * truncated salt succeeds then exit 1. + */ + + if((strcmp(c_out1, expected_out) != 0) && + (strcmp(c_out2, expected_out) == 0)) + exit(1); + +#ifdef HAVE_BIGCRYPT + /* + * Try the same with bigcrypt... + */ + + { + char big_passwd[17]; + char big_salt[17]; + char big_c_out1[256]; + char big_c_out2[256]; + char big_expected_out[27]; + + strcpy(big_passwd, "1234567812345678"); + strcpy(big_salt, "1234567812345678"); + strcpy(big_expected_out, "12yJ.Of/NQ.PklfyCuHi/rwM"); + + strcpy(big_c_out1, bigcrypt(big_passwd, big_salt)); + big_salt[2] = '\0'; + strcpy(big_c_out2, bigcrypt(big_passwd, big_salt)); + + /* + * If the non-trucated salt fails but the + * truncated salt succeeds then exit 1. + */ + + if((strcmp(big_c_out1, big_expected_out) != 0) && + (strcmp(big_c_out2, big_expected_out) == 0)) + exit(1); + + } +#endif + + exit(0); +} diff --git a/source4/build/tests/fcntl_lock.c b/source4/build/tests/fcntl_lock.c new file mode 100644 index 0000000000..ffd1ee69fa --- /dev/null +++ b/source4/build/tests/fcntl_lock.c @@ -0,0 +1,112 @@ +/* test whether fcntl locking works on this system */ + +#if defined(HAVE_UNISTD_H) +#include <unistd.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#ifdef HAVE_SYS_FCNTL_H +#include <sys/fcntl.h> +#endif + +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + +#include <errno.h> + +#define DATA "conftest.fcntl" + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +/* lock a byte range in a open file */ +int main(int argc, char *argv[]) +{ + struct flock lock; + int fd, ret, status=1; + pid_t pid; + char *testdir = NULL; + + testdir = getenv("TESTDIR"); + if (testdir) chdir(testdir); + + alarm(10); + + if (!(pid=fork())) { + sleep(2); + fd = open(DATA, O_RDONLY); + + if (fd == -1) { + fprintf(stderr,"ERROR: failed to open %s (errno=%d)\n", + DATA, (int)errno); + exit(1); + } + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 4; + lock.l_pid = getpid(); + + lock.l_type = F_WRLCK; + + /* check if a lock applies */ + ret = fcntl(fd,F_GETLK,&lock); + + if ((ret == -1) || + (lock.l_type == F_UNLCK)) { + fprintf(stderr,"ERROR: lock test failed (ret=%d errno=%d)\n", ret, (int)errno); + exit(1); + } else { + exit(0); + } + } + + unlink(DATA); + fd = open(DATA, O_RDWR|O_CREAT|O_EXCL, 0600); + + if (fd == -1) { + fprintf(stderr,"ERROR: failed to open %s (errno=%d)\n", + DATA, (int)errno); + exit(1); + } + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 4; + lock.l_pid = getpid(); + + /* set a 4 byte write lock */ + fcntl(fd,F_SETLK,&lock); + + waitpid(pid, &status, 0); + + unlink(DATA); + +#if defined(WIFEXITED) && defined(WEXITSTATUS) + if(WIFEXITED(status)) { + status = WEXITSTATUS(status); + } else { + status = 1; + } +#else /* defined(WIFEXITED) && defined(WEXITSTATUS) */ + status = (status == 0) ? 0 : 1; +#endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */ + + if (status) { + fprintf(stderr,"ERROR: lock test failed with status=%d\n", + status); + } + + exit(status); +} diff --git a/source4/build/tests/fcntl_lock64.c b/source4/build/tests/fcntl_lock64.c new file mode 100644 index 0000000000..913580cd24 --- /dev/null +++ b/source4/build/tests/fcntl_lock64.c @@ -0,0 +1,87 @@ +/* test whether 64 bit fcntl locking really works on this system */ + +#if defined(HAVE_UNISTD_H) +#include <unistd.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#ifdef HAVE_SYS_FCNTL_H +#include <sys/fcntl.h> +#endif + +#include <errno.h> + +#define DATA "conftest.fcntl64" + +/* lock a byte range in a open file */ +int main(int argc, char *argv[]) +{ + struct flock64 lock; + int fd, ret, status=1; + pid_t pid; + + if (!(pid=fork())) { + sleep(2); + fd = open64(DATA, O_RDONLY); + + if (fd == -1) exit(1); + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 4; + lock.l_pid = getpid(); + + lock.l_type = F_WRLCK; + + /* check if a lock applies */ + ret = fcntl(fd,F_GETLK64,&lock); + + if ((ret == -1) || + (lock.l_type == F_UNLCK)) { +/* printf("No lock conflict\n"); */ + exit(1); + } else { +/* printf("lock conflict\n"); */ + exit(0); + } + } + + fd = open64(DATA, O_RDWR|O_CREAT|O_TRUNC, 0600); + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; +#if defined(COMPILER_SUPPORTS_LL) + lock.l_start = 0x100000000LL; +#else + lock.l_start = 0x100000000; +#endif + lock.l_len = 4; + lock.l_pid = getpid(); + + /* set a 4 byte write lock */ + fcntl(fd,F_SETLK64,&lock); + + sys_waitpid(pid, &status, 0); + +#if defined(WIFEXITED) && defined(WEXITSTATUS) + if(WIFEXITED(status)) { + status = WEXITSTATUS(status); + } else { + status = 1; + } +#else /* defined(WIFEXITED) && defined(WEXITSTATUS) */ + status = (status == 0) ? 0 : 1; +#endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */ + + unlink(DATA); + + exit(status); +} diff --git a/source4/build/tests/fcntl_lock_thread.c b/source4/build/tests/fcntl_lock_thread.c new file mode 100644 index 0000000000..f31105626c --- /dev/null +++ b/source4/build/tests/fcntl_lock_thread.c @@ -0,0 +1,122 @@ +/* test whether fcntl locking works between threads on this Linux system */ + +#include <unistd.h> + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> + +#include <fcntl.h> + +#include <sys/fcntl.h> + +#include <sys/wait.h> + +#include <errno.h> +#include <pthread.h> + +static int sys_waitpid(pid_t pid,int *status,int options) +{ + return waitpid(pid,status,options); +} + +#define DATA "conftest.fcntl" + +#define SEEK_SET 0 + +static void *test_thread(void *thread_parm) +{ + int *status = thread_parm; + int fd, ret; + struct flock lock; + + sleep(2); + fd = open(DATA, O_RDWR); + + if (fd == -1) { + fprintf(stderr,"ERROR: failed to open %s (errno=%d)\n", + DATA, (int)errno); + pthread_exit(thread_parm); + } + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 4; + lock.l_pid = 0; + + /* check if a lock applies */ + ret = fcntl(fd,F_SETLK,&lock); + if ((ret != -1)) { + fprintf(stderr,"ERROR: lock test failed (ret=%d errno=%d)\n", ret, (int)errno); + } else { + *status = 0; /* SUCCESS! */ + } + pthread_exit(thread_parm); +} + +/* lock a byte range in a open file */ +int main(int argc, char *argv[]) +{ + struct flock lock; + int fd, ret, status=1, rc; + pid_t pid; + char *testdir = NULL; + pthread_t thread_id; + pthread_attr_t thread_attr; + + testdir = getenv("TESTDIR"); + if (testdir) chdir(testdir); + + alarm(10); + + pthread_attr_init(&thread_attr); + pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); + rc = pthread_create(&thread_id, &thread_attr, &test_thread, &status); + pthread_attr_destroy(&thread_attr); + if (rc == 0) { + fprintf(stderr,"created thread_id=%lu\n", + (unsigned long int)thread_id); + } else { + fprintf(stderr,"ERROR: thread create failed, rc=%d\n", rc); + } + + unlink(DATA); + fd = open(DATA, O_RDWR|O_CREAT|O_RDWR, 0600); + + if (fd == -1) { + fprintf(stderr,"ERROR: failed to open %s (errno=%d)\n", + DATA, (int)errno); + exit(1); + } + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 4; + lock.l_pid = getpid(); + + /* set a 4 byte write lock */ + fcntl(fd,F_SETLK,&lock); + + sleep(4); /* allow thread to try getting lock */ + + unlink(DATA); + +#if defined(WIFEXITED) && defined(WEXITSTATUS) + if(WIFEXITED(status)) { + status = WEXITSTATUS(status); + } else { + status = 1; + } +#else /* defined(WIFEXITED) && defined(WEXITSTATUS) */ + status = (status == 0) ? 0 : 1; +#endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */ + + if (status) { + fprintf(stderr,"ERROR: lock test failed with status=%d\n", + status); + } + + exit(status); +} diff --git a/source4/build/tests/shared_mmap.c b/source4/build/tests/shared_mmap.c new file mode 100644 index 0000000000..40d462302e --- /dev/null +++ b/source4/build/tests/shared_mmap.c @@ -0,0 +1,70 @@ +/* this tests whether we can use a shared writeable mmap on a file - + as needed for the mmap variant of FAST_SHARE_MODES */ + +#if defined(HAVE_UNISTD_H) +#include <unistd.h> +#endif +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define DATA "conftest.mmap" + +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + +main() +{ + int *buf; + int i; + int fd = open(DATA,O_RDWR|O_CREAT|O_TRUNC,0666); + int count=7; + + if (fd == -1) exit(1); + + for (i=0;i<10000;i++) { + write(fd,&i,sizeof(i)); + } + + close(fd); + + if (fork() == 0) { + fd = open(DATA,O_RDWR); + if (fd == -1) exit(1); + + buf = (int *)mmap(NULL, 10000*sizeof(int), + (PROT_READ | PROT_WRITE), + MAP_FILE | MAP_SHARED, + fd, 0); + + if (buf == (int *)-1) exit(1); + + while (count-- && buf[9124] != 55732) sleep(1); + + if (count <= 0) exit(1); + + buf[1763] = 7268; + exit(0); + } + + fd = open(DATA,O_RDWR); + if (fd == -1) exit(1); + + buf = (int *)mmap(NULL, 10000*sizeof(int), + (PROT_READ | PROT_WRITE), + MAP_FILE | MAP_SHARED, + fd, 0); + + if (buf == (int *)-1) exit(1); + + buf[9124] = 55732; + + while (count-- && buf[1763] != 7268) sleep(1); + + unlink(DATA); + + if (count > 0) exit(0); + exit(1); +} diff --git a/source4/build/tests/shlib.c b/source4/build/tests/shlib.c new file mode 100644 index 0000000000..761d9fd5c5 --- /dev/null +++ b/source4/build/tests/shlib.c @@ -0,0 +1,6 @@ +/* a trivial function used to test building shared libraries */ + +int foo(void) +{ + return 1; +} diff --git a/source4/build/tests/summary.c b/source4/build/tests/summary.c new file mode 100644 index 0000000000..95fa1cbae9 --- /dev/null +++ b/source4/build/tests/summary.c @@ -0,0 +1,22 @@ +#include <stdio.h> + +void exit(int); + +main() +{ +#if !(defined(HAVE_IFACE_GETIFADDRS) || defined(HAVE_IFACE_IFCONF) || defined(HAVE_IFACE_IFREQ) || defined(HAVE_IFACE_AIX)) + printf("WARNING: No automated network interface determination\n"); +#endif + +#if !(defined(STAT_STATVFS) || defined(STAT_STATVFS64) || defined(STAT_STATFS3_OSF1) || defined(STAT_STATFS2_BSIZE) || defined(STAT_STATFS4) || defined(STAT_STATFS2_FSIZE) || defined(STAT_STATFS2_FS_DATA)) + printf("ERROR: No disk free routine!\n"); + exit(1); +#endif + +#if !((defined(HAVE_RANDOM) || defined(HAVE_RAND)) && (defined(HAVE_SRANDOM) || defined(HAVE_SRAND))) + printf("ERROR: No random or srandom routine!\n"); + exit(1); +#endif + + exit(0); +} diff --git a/source4/build/tests/trivial.c b/source4/build/tests/trivial.c new file mode 100644 index 0000000000..f7e96d8109 --- /dev/null +++ b/source4/build/tests/trivial.c @@ -0,0 +1,7 @@ + +void exit(int); + +main() +{ + exit(0); +} |