docs: fix a typo in history file
[bbaumbach/samba-autobuild/.git] / source3 / wscript
1 #!/usr/bin/env python
2
3 srcdir = ".."
4
5 import sys, os
6 from optparse import SUPPRESS_HELP
7 sys.path.insert(0, srcdir + "/buildtools/wafsamba")
8 sys.path.insert(0, "source3")
9
10 from waflib import Options, Logs, Errors
11 import wafsamba
12 import build.charset
13 from wafsamba import samba_utils
14 from samba_utils import TO_LIST
15 import samba3
16 from waflib.Tools import bison
17
18 default_prefix = Options.default_prefix = '/usr/local/samba'
19
20 def options(opt):
21
22     opt.add_option('--with-static-modules',
23                    help=("Comma-separated list of names of modules to statically link in. "+
24                          "May include !module to disable 'module'. "+
25                          "Can be '!FORCED' to disable all non-required static only modules. "+
26                          "Can be '!DEFAULT' to disable all modules defaulting to a static build. "+
27                          "Can be 'ALL' to build all default shared modules static. "+
28                          "The most specific one wins, while the order is ignored "+
29                          "and --with-static-modules is evaluated before "+
30                          "--with-shared-modules"),
31                    action="store", dest='static_modules', default=None)
32     opt.add_option('--with-shared-modules',
33                    help=("Comma-separated list of names of modules to build shared. "+
34                          "May include !module to disable 'module'. "+
35                          "Can be '!FORCED' to disable all non-required shared only modules. "+
36                          "Can be '!DEFAULT' to disable all modules defaulting to a shared build. "+
37                          "Can be 'ALL' to build all default static modules shared. "+
38                          "The most specific one wins, while the order is ignored "+
39                          "and --with-static-modules is evaluated before "+
40                          "--with-shared-modules"),
41                    action="store", dest='shared_modules', default=None)
42
43     opt.samba_add_onoff_option('winbind')
44     opt.samba_add_onoff_option('ads')
45     opt.samba_add_onoff_option('ldap')
46     opt.samba_add_onoff_option('cups', with_name="enable", without_name="disable")
47     opt.samba_add_onoff_option('iprint', with_name="enable", without_name="disable")
48     opt.samba_add_onoff_option('pam')
49     opt.samba_add_onoff_option('quotas', default=None)
50     opt.samba_add_onoff_option('sendfile-support', default=None)
51     opt.samba_add_onoff_option('utmp')
52     opt.samba_add_onoff_option('avahi', with_name="enable", without_name="disable")
53     opt.samba_add_onoff_option('iconv')
54     opt.samba_add_onoff_option('acl-support')
55     opt.samba_add_onoff_option('dnsupdate')
56     opt.samba_add_onoff_option('syslog')
57     opt.samba_add_onoff_option('automount')
58     opt.samba_add_onoff_option('dmapi', default=None) # None means autodetection
59     opt.samba_add_onoff_option('fam', default=None) # None means autodetection
60     opt.samba_add_onoff_option('profiling-data', default=False)
61     opt.samba_add_onoff_option('libarchive', default=True)
62
63     opt.samba_add_onoff_option('cluster-support', default=False)
64
65     opt.samba_add_onoff_option('regedit', default=None)
66     opt.samba_add_onoff_option('winexe', default=None)
67
68     opt.samba_add_onoff_option('fake-kaserver',
69                           help=("Include AFS fake-kaserver support"), default=False)
70
71     opt.add_option('--with-libcephfs',
72                    help=("Directory under which libcephfs is installed"),
73                    action="store", dest='libcephfs_dir', default=None)
74
75     opt.samba_add_onoff_option('glusterfs', with_name="enable", without_name="disable", default=True)
76     opt.samba_add_onoff_option('cephfs', with_name="enable", without_name="disable", default=True)
77     opt.samba_add_onoff_option('snapper', with_name="enable", without_name="disable", default=True)
78
79     opt.add_option('--enable-vxfs',
80                   help=("enable support for VxFS (default=no)"),
81                   action="store_true", dest='enable_vxfs', default=False)
82
83     # default = None means autodetection
84     opt.samba_add_onoff_option('spotlight', with_name="enable", without_name="disable", default=None)
85
86 def configure(conf):
87     default_static_modules = []
88     default_shared_modules = []
89     required_static_modules = []
90     forced_static_modules = []
91     forced_shared_modules = []
92
93     if Options.options.developer:
94         conf.ADD_CFLAGS('-DDEVELOPER -DDEBUG_PASSWORD')
95         conf.env.developer = True
96
97     if sys.platform != 'openbsd5':
98         conf.ADD_LDFLAGS("-Wl,--export-dynamic", testflags=True)
99
100     # We crash without vfs_default
101     # and vfs_not_implemented provides helper function
102     # for other modules
103     required_static_modules.extend(TO_LIST('vfs_default vfs_not_implemented'))
104
105     conf.CHECK_HEADERS('netdb.h')
106     conf.CHECK_HEADERS('linux/falloc.h linux/ioctl.h')
107
108     conf.CHECK_FUNCS('getcwd fchown chmod fchmod mknod mknodat')
109     conf.CHECK_FUNCS('strtol strchr strupr chflags')
110     conf.CHECK_FUNCS('getrlimit fsync setpgid')
111     conf.CHECK_FUNCS('setsid glob strpbrk crypt16 getauthuid')
112     conf.CHECK_FUNCS('innetgr')
113     conf.CHECK_FUNCS('initgroups select poll rdchk getgrnam getgrent pathconf')
114     conf.CHECK_FUNCS('setpriv setgidx setuidx setgroups syscall sysconf')
115     conf.CHECK_FUNCS('atexit grantpt posix_openpt fallocate')
116     conf.CHECK_FUNCS('fseeko setluid')
117     conf.CHECK_FUNCS('getpwnam', headers='sys/types.h pwd.h')
118     conf.CHECK_FUNCS('fdopendir')
119     conf.CHECK_FUNCS('fstatat')
120     conf.CHECK_FUNCS('getpwent_r setenv clearenv strcasecmp fcvt fcvtl')
121     conf.CHECK_FUNCS('syslog vsyslog timegm setlocale')
122     conf.CHECK_FUNCS('lutimes futimes utimensat futimens')
123     conf.CHECK_FUNCS('mlock munlock mlockall munlockall')
124     conf.CHECK_FUNCS('memalign posix_memalign hstrerror')
125     conf.CHECK_FUNCS_IN('yp_get_default_domain', 'nsl')
126     conf.CHECK_FUNCS_IN('dn_expand _dn_expand __dn_expand', 'resolv')
127     conf.CHECK_FUNCS_IN('dn_expand', 'inet')
128     conf.CHECK_DECLS('readahead', reverse=True, headers='fcntl.h')
129
130     if conf.CHECK_CODE('''
131 #if defined(HAVE_UNISTD_H)
132 #include <unistd.h>
133 #endif
134 long ret = splice(0,0,1,0,400,SPLICE_F_MOVE);
135 ''',
136         'HAVE_LINUX_SPLICE',
137         headers='fcntl.h'):
138         conf.CHECK_DECLS('splice', reverse=True, headers='fcntl.h')
139
140     # Check for inotify support (Skip if we are SunOS)
141     #NOTE: illumos provides sys/inotify.h but is not an exact match for linux
142     host_os = sys.platform
143     if host_os.rfind('sunos') == -1:
144         conf.CHECK_HEADERS('sys/inotify.h')
145         if conf.env.HAVE_SYS_INOTIFY_H:
146            conf.DEFINE('HAVE_INOTIFY', 1)
147
148     # Check for kernel change notify support
149     conf.CHECK_CODE('''
150 #ifndef F_NOTIFY
151 #define F_NOTIFY 1026
152 #endif
153 main() {
154         exit(fcntl(open("/tmp", O_RDONLY), F_NOTIFY, 0) == -1 ?  1 : 0);
155 }''', 'HAVE_KERNEL_CHANGE_NOTIFY', addmain=False, execute=True,
156         headers='fcntl.h signal.h',
157         msg="Checking for kernel change notify support")
158
159     # Check for Linux kernel oplocks
160     conf.CHECK_CODE('''
161 #include <sys/types.h>
162 #include <fcntl.h>
163 #include <signal.h>
164 #ifndef F_GETLEASE
165 #define F_GETLEASE 1025
166 #endif
167 main() {
168         exit(fcntl(open("/tmp", O_RDONLY), F_GETLEASE, 0) == -1 ?  1 : 0);
169 }''', 'HAVE_KERNEL_OPLOCKS_LINUX', addmain=False, execute=True,
170         msg="Checking for Linux kernel oplocks")
171
172     # Check for kernel share modes
173     conf.CHECK_CODE('''
174 #include <sys/types.h>
175 #include <fcntl.h>
176 #include <signal.h>
177 #include <sys/file.h>
178 #ifndef LOCK_MAND
179 #define LOCK_MAND        32
180 #define LOCK_READ        64
181 #endif
182 main() {
183         exit(flock(open("/dev/null", O_RDWR), LOCK_MAND|LOCK_READ) != 0);
184 }''', 'HAVE_KERNEL_SHARE_MODES', addmain=False, execute=True,
185         msg="Checking for kernel share modes")
186
187     # check for fam libs
188     samba_fam_libs=None
189     check_for_fam=False
190     if Options.options.with_fam is None:
191         check_for_fam=True
192     elif Options.options.with_fam == True:
193         check_for_fam=True
194
195     if check_for_fam and conf.CHECK_HEADERS('fam.h'):
196         if conf.CHECK_FUNCS_IN('FAMOpen2', 'fam'):
197             samba_fam_libs='fam'
198         elif conf.CHECK_FUNCS_IN('FAMOpen2', 'fam C'):
199             samba_fam_libs='fam C'
200         conf.CHECK_TYPE('enum FAMCodes', headers='fam.h',
201             define='HAVE_FAM_H_FAMCODES_TYPEDEF',
202             msg='Checking whether enum FAMCodes is available')
203         conf.CHECK_FUNCS_IN('FAMNoExists', 'fam')
204
205     if samba_fam_libs is not None:
206         conf.DEFINE('SAMBA_FAM_LIBS', samba_fam_libs)
207         conf.DEFINE('HAVE_FAM', 1)
208     else:
209         if Options.options.with_fam == True:
210             conf.fatal('FAM support requested, but no suitable FAM library found')
211         elif check_for_fam:
212             Logs.warn('no suitable FAM library found')
213
214     # check for libarchive (tar command in smbclient)
215     # None means autodetect, True/False means enable/disable
216     conf.SET_TARGET_TYPE('archive', 'EMPTY')
217     if Options.options.with_libarchive is not False:
218         Logs.info("Checking for libarchive existence")
219         if conf.CHECK_HEADERS('archive.h') and conf.CHECK_LIB('archive', shlib=True):
220             conf.CHECK_FUNCS_IN('archive_read_support_filter_all archive_read_free', 'archive')
221         else:
222             conf.fatal("libarchive support not found. "
223                        "Try installing libarchive-dev or libarchive-devel. "
224                        "Otherwise, use --without-libarchive to "
225                        "build without libarchive support. "
226                        "libarchive support is required for the smbclient "
227                        "tar-file mode")
228     elif conf.CONFIG_GET('ENABLE_SELFTEST'):
229         raise Errors.WafError('libarchive library required for '
230                              '--enable-selftest')
231
232
233     # check for DMAPI libs
234     if Options.options.with_dmapi == False:
235         have_dmapi = False
236     else:
237         have_dmapi = True
238         Logs.info("Checking for DMAPI library existence")
239         samba_dmapi_lib = ''
240         if conf.CHECK_FUNCS_IN('dm_get_eventlist', 'dm'):
241             samba_dmapi_lib = 'dm'
242         else:
243             if conf.CHECK_FUNCS_IN('dm_get_eventlist', 'jfsdm'):
244                 samba_dmapi_lib = 'jfsdm'
245             else:
246                 if conf.CHECK_FUNCS_IN('dm_get_eventlist', 'dmapi'):
247                     samba_dmapi_lib = 'dmapi'
248                 else:
249                     if conf.CHECK_FUNCS_IN('dm_get_eventlist', 'xdsm'):
250                         samba_dmapi_lib = 'xdsm'
251         # only bother to test headers and compilation when a candidate
252         # library has been found
253         if samba_dmapi_lib == '':
254             have_dmapi = False
255             broken_dmapi = "no suitable DMAPI library found"
256
257         if have_dmapi:
258             conf.CHECK_HEADERS('sys/dmi.h xfs/dmapi.h sys/jfsdmapi.h sys/dmapi.h dmapi.h')
259             conf.CHECK_CODE('''
260 #include <time.h>      /* needed by Tru64 */
261 #include <sys/types.h> /* needed by AIX */
262 #ifdef HAVE_XFS_DMAPI_H
263 #include <xfs/dmapi.h>
264 #elif defined(HAVE_SYS_DMI_H)
265 #include <sys/dmi.h>
266 #elif defined(HAVE_SYS_JFSDMAPI_H)
267 #include <sys/jfsdmapi.h>
268 #elif defined(HAVE_SYS_DMAPI_H)
269 #include <sys/dmapi.h>
270 #elif defined(HAVE_DMAPI_H)
271 #include <dmapi.h>
272 #endif
273
274 /* This link test is designed to fail on IRI 6.4, but should
275  * succeed on Linux, IRIX 6.5 and AIX.
276  */
277 int main(int argc, char **argv)
278 {
279         char * version;
280         dm_eventset_t events;
281         /* This doesn't take an argument on IRIX 6.4. */
282         dm_init_service(&version);
283         /* IRIX 6.4 expects events to be a pointer. */
284         DMEV_ISSET(DM_EVENT_READ, events);
285
286         return 0;
287 }
288 ''',
289             'USEABLE_DMAPI_LIBRARY',
290             addmain=False,
291             execute=False,
292             lib=samba_dmapi_lib,
293             msg='Checking whether DMAPI lib '+samba_dmapi_lib+' can be used')
294             if not conf.CONFIG_SET('USEABLE_DMAPI_LIBRARY'):
295                 have_dmapi = False
296                 broken_dmapi = "no usable DMAPI library found"
297
298     if have_dmapi:
299         Logs.info("Building with DMAPI support.")
300         conf.env['dmapi_lib'] = samba_dmapi_lib
301         conf.DEFINE('USE_DMAPI', 1)
302     else:
303         if Options.options.with_dmapi == False:
304             Logs.info("Building without DMAPI support (--without-dmapi).")
305         elif Options.options.with_dmapi == True:
306             Logs.error("DMAPI support not available: " + broken_dmapi)
307             conf.fatal('DMAPI support requested but not found.');
308         else:
309             Logs.warn("Building without DMAPI support: " + broken_dmapi)
310         conf.env['dmapi_lib'] = ''
311
312     # Check for various members of the stat structure
313     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_blocks', define='HAVE_STAT_ST_BLOCKS',
314                                 headers='sys/stat.h')
315     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_blksize', define='HAVE_STAT_ST_BLKSIZE',
316                                 headers='sys/stat.h')
317     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_flags', define='HAVE_STAT_ST_FLAGS',
318                                 headers='sys/types.h sys/stat.h unistd.h')
319
320     if conf.env.HAVE_BLKCNT_T:
321         conf.CHECK_CODE('''
322         static int test_array[1 - 2 * !(((long int)(sizeof(blkcnt_t))) <= 4)];''',
323                 'SIZEOF_BLKCNT_T_4',
324                 headers='replace.h sys/types.h sys/stat.h unistd.h',
325                 msg="Checking whether blkcnt_t is 32 bit")
326
327     # If sizeof is 4 it can't be 8
328     if conf.env.HAVE_BLKCNT_T:
329         if not conf.CONFIG_SET('SIZEOF_BLKCNT_T_4'):
330             conf.CHECK_CODE('''
331             static int test_array[1 - 2 * !(((long int)(sizeof(blkcnt_t))) <= 8)];''',
332                     'SIZEOF_BLKCNT_T_8',
333                     headers='replace.h sys/types.h sys/stat.h unistd.h',
334                     msg="Checking whether blkcnt_t is 64 bit")
335
336     # Check for POSIX capability support
337     conf.CHECK_FUNCS_IN('cap_get_proc', 'cap', headers='sys/capability.h')
338
339     if conf.env.HAVE_SYS_CAPABILITY_H:
340         conf.CHECK_CODE('''
341         cap_t cap;
342         cap_value_t vals[1];
343         if (!(cap = cap_get_proc())) exit(1);
344         vals[0] = CAP_CHOWN;
345         cap_set_flag(cap, CAP_INHERITABLE, 1, vals, CAP_CLEAR);
346         cap_set_proc(cap);''',
347                         'HAVE_POSIX_CAPABILITIES', execute=True, lib="cap",
348                         headers='sys/capability.h',
349                         msg="Checking whether POSIX capabilities are available")
350
351     conf.CHECK_CODE('int i;', 'BROKEN_NISPLUS_INCLUDE_FILES',
352                     headers='sys/types.h sys/acl.h rpcsvc/nis.h',
353                     msg="Checking for broken nisplus include files")
354
355     # Check if the compiler will optimize out functions
356     conf.CHECK_CODE('''
357 #include <sys/types.h>
358 size_t __unsafe_string_function_usage_here_size_t__(void);
359 #define CHECK_STRING_SIZE(d, len) (sizeof(d) != (len) && sizeof(d) != sizeof(char *))
360 static size_t push_string_check_fn(void *dest, const char *src, size_t dest_len) {
361         return 0;
362 }
363
364 #define push_string_check(dest, src, dest_len) \
365     (CHECK_STRING_SIZE(dest, dest_len) \
366     ? __unsafe_string_function_usage_here_size_t__()    \
367     : push_string_check_fn(dest, src, dest_len))
368
369 int main(int argc, char **argv) {
370     char outbuf[1024];
371     char *p = outbuf;
372     const char *foo = "bar";
373     p += 31 + push_string_check(p + 31, foo, sizeof(outbuf) - (p + 31 - outbuf));
374     return 0;
375 }''', 'HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS',
376             addmain=False,
377             add_headers=False,
378             msg="Checking if the compiler will optimize out functions")
379
380     # Check if the compiler supports the LL suffix on long long integers
381     # AIX needs this
382     conf.CHECK_CODE('long long i = 0x8000000000LL', 'COMPILER_SUPPORTS_LL',
383                     headers='stdio.h',
384                     msg="Checking for LL suffix on long long integers")
385
386     conf.CHECK_FUNCS('''
387 DNSServiceRegister
388 atexit
389 chflags
390 chmod
391 crypt16
392 devnm
393 dirfd
394 endmntent
395 execl
396 fchmod
397 fchown
398 fcvt
399 fcvtl
400 fseeko
401 fsync
402 futimens
403 futimes
404 getauthuid
405 getcwd
406 getgrent
407 getgrnam
408 getgrouplist
409 getgrset
410 getmntent
411 getpagesize
412 getpwanam
413 getpwent_r
414 getrlimit
415 glob
416 grantpt
417 hstrerror
418 initgroups
419 innetgr
420 llseek
421 lutimes
422 memalign
423 mknod
424 mlock
425 mlockall
426 munlock
427 munlockall
428 pathconf poll
429 posix_memalign
430 pread
431 pwrite
432 rdchk
433 select
434 setenv
435 setgidx
436 setgroups
437 setlocale
438 setluid
439 setmntent
440 setpgid
441 setpriv
442 setsid
443 setuidx
444 statvfs
445 strcasecmp
446 strchr
447 strpbrk
448 strsignal
449 strtol
450 strupr
451 sysconf
452 sysctl
453 sysctlbyname
454 syslog
455 timegm
456 utimensat
457 vsyslog
458 ''')
459
460     conf.CHECK_SAMBA3_CHARSET() # see build/charset.py
461
462     # FIXME: these should be tests for features, but the old build system just
463     # checks for OSes.
464     host_os = sys.platform
465     Logs.info("building on %s" % host_os)
466
467     # Python doesn't have case switches... :/
468     # FIXME: original was *linux* | gnu* | k*bsd*-gnu | kopensolaris*-gnu | *qnx*)
469     # the search for .rfind('gnu') covers gnu* and *-gnu is that too broad?
470
471     conf.SET_TARGET_TYPE('sunacl', 'EMPTY')
472     if (host_os.rfind('linux') > -1) or (host_os.rfind('gnu') > -1) or (host_os.rfind('qnx') > -1):
473         if host_os.rfind('linux') > -1:
474             conf.DEFINE('LINUX', '1')
475         elif host_os.rfind('qnx') > -1:
476             conf.DEFINE('QNX', '1')
477         conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
478     elif (host_os.rfind('darwin') > -1):
479         conf.DEFINE('DARWINOS', 1)
480         conf.ADD_CFLAGS('-fno-common')
481         conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
482     elif (host_os.rfind('freebsd') > -1):
483         conf.DEFINE('FREEBSD', 1)
484         if conf.CHECK_HEADERS('sunacl.h'):
485             conf.DEFINE('HAVE_FREEBSD_SUNACL_H', '1')
486             conf.CHECK_FUNCS_IN(['acl'], 'sunacl')
487         conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
488     elif (host_os.rfind('irix') > -1):
489         conf.DEFINE('IRIX', 1)
490         conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
491     elif (host_os.rfind('aix') > -1):
492         conf.DEFINE('AIX', 1)
493         conf.DEFINE('STAT_ST_BLOCKSIZE', 'DEV_BSIZE')
494     elif (host_os.rfind('hpux') > -1):
495         conf.DEFINE('HPUX', 1)
496         conf.DEFINE('STAT_ST_BLOCKSIZE', '8192')
497     elif (host_os.rfind('osf') > -1):
498         conf.DEFINE('OSF1', 1)
499         conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
500
501     # FIXME: Add more checks here.
502     else:
503         conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
504
505     if Options.options.with_acl_support:
506         if (host_os.rfind('hpux') > -1):
507                 Logs.info('Using HPUX ACLs')
508                 conf.DEFINE('HAVE_HPUX_ACLS',1)
509                 conf.DEFINE('POSIX_ACL_NEEDS_MASK',1)
510                 default_static_modules.extend(TO_LIST('vfs_hpuxacl'))
511         elif (host_os.rfind('aix') > -1):
512                 Logs.info('Using AIX ACLs')
513                 conf.DEFINE('HAVE_AIX_ACLS',1)
514                 default_static_modules.extend(TO_LIST('vfs_aixacl vfs_aixacl2'))
515         elif (host_os.rfind('darwin') > -1):
516             Logs.warn('ACLs on Darwin currently not supported')
517             conf.fatal("ACL support not available on Darwin/MacOS. "
518                        "Use --without-acl-support for building without "
519                        "ACL support. "
520                        "ACL support is required to change permissions "
521                        "from Windows clients.")
522         else:
523             conf.CHECK_FUNCS_IN(['acl_get_file'], 'acl')
524             if conf.CHECK_CODE('''
525 acl_t acl;
526 int entry_id;
527 acl_entry_t *entry_p;
528 return acl_get_entry(acl, entry_id, entry_p);
529 ''',
530                         'HAVE_POSIX_ACLS',
531                         headers='sys/types.h sys/acl.h', link=False,
532                         msg="Checking for POSIX ACL support") :
533                 conf.CHECK_CODE('''
534 acl_permset_t permset_d;
535 acl_perm_t perm;
536 return acl_get_perm_np(permset_d, perm);
537 ''',
538                         'HAVE_ACL_GET_PERM_NP',
539                         headers='sys/types.h sys/acl.h', link=True,
540                         msg="Checking whether acl_get_perm_np() is available")
541                 # source3/lib/sysacls.c calls posixacl_sys_acl_get_file()
542                 required_static_modules.extend(TO_LIST('vfs_posixacl'))
543                 conf.CHECK_VARIABLE('ACL_EVERYONE', headers='sys/acl.h')
544             elif conf.CHECK_FUNCS_IN(['facl'], 'sec'):
545                 Logs.info('Using solaris or UnixWare ACLs')
546                 conf.DEFINE('HAVE_SOLARIS_UNIXWARE_ACLS',1)
547                 default_static_modules.extend(TO_LIST('vfs_solarisacl'))
548             elif conf.CHECK_FUNCS_IN(['acl_get_fd'], 'pacl'):
549                 Logs.info('Using Tru64 ACLs')
550                 conf.DEFINE('HAVE_TRU64_ACLS',1)
551                 default_static_modules.extend(TO_LIST('vfs_tru64acl'))
552             else:
553                 conf.fatal("ACL support not found. Try installing libacl1-dev "
554                            "or libacl-devel.  "
555                            "Otherwise, use --without-acl-support to build "
556                            "without ACL support. "
557                            "ACL support is required to change permissions from "
558                            "Windows clients.")
559
560     if conf.CHECK_FUNCS('dirfd'):
561         conf.DEFINE('HAVE_DIRFD_DECL', 1)
562
563     conf.CHECK_CODE('struct statfs fsd; fsid_t fsid = fsd.f_fsid; return statfs(".", &fsd);',
564                     'HAVE_STATFS_F_FSID',
565                     msg="vfs_fileid checking for statfs() and struct statfs.f_fsid",
566                     headers='sys/types.h sys/statfs.h',
567                     execute=True)
568
569     if conf.CONFIG_SET('HAVE_FALLOCATE'):
570         conf.CHECK_CODE('''
571                 int ret = fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 10);''',
572                 'HAVE_LINUX_FALLOCATE',
573                 msg="Checking whether the Linux 'fallocate' function is available",
574                 headers='unistd.h sys/types.h fcntl.h linux/falloc.h')
575         conf.CHECK_CODE('''
576                 int ret = fallocate(0, FALLOC_FL_PUNCH_HOLE, 0, 10);''',
577                 'HAVE_FALLOC_FL_PUNCH_HOLE',
578                 msg="Checking whether Linux 'fallocate' supports hole-punching",
579                 headers='unistd.h sys/types.h fcntl.h linux/falloc.h')
580
581     conf.CHECK_CODE('''
582             int ret = lseek(0, 0, SEEK_HOLE);
583             ret = lseek(0, 0, SEEK_DATA);''',
584             'HAVE_LSEEK_HOLE_DATA',
585             msg="Checking whether lseek supports hole/data seeking",
586             headers='unistd.h sys/types.h')
587
588     conf.CHECK_CODE('''
589                 ssize_t err = readahead(0,0,0x80000);''',
590                 'HAVE_LINUX_READAHEAD',
591                 msg="Checking whether Linux readahead is available",
592                 headers='unistd.h fcntl.h')
593     conf.CHECK_DECLS('readahead', headers='fcntl.h', always=True)
594
595     conf.CHECK_CODE('int fd = openat(AT_FDCWD, ".", O_RDONLY);',
596                 'HAVE_OPENAT',
597                 msg='Checking for openat',
598                 headers='fcntl.h')
599
600     conf.CHECK_CODE('''
601 struct msghdr msg;
602 union {
603         struct cmsghdr cm;
604         char control[CMSG_SPACE(sizeof(int))];
605 } control_un;
606 msg.msg_control = control_un.control;
607 msg.msg_controllen = sizeof(control_un.control);
608 ''',
609         'HAVE_STRUCT_MSGHDR_MSG_CONTROL',
610         msg='Checking if we can use msg_control for passing file descriptors',
611         headers='sys/types.h stdlib.h stddef.h sys/socket.h sys/un.h')
612     conf.CHECK_CODE('''
613 struct msghdr msg;
614 int fd;
615 msg.msg_accrights = (caddr_t) &fd;
616 msg.msg_accrightslen = sizeof(fd);
617 ''',
618         'HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS',
619         msg='Checking if we can use msg_accrights for passing file descriptors',
620         headers='sys/types.h stdlib.h stddef.h sys/socket.h sys/un.h')
621
622     if Options.options.with_winbind:
623         conf.env.build_winbind = True
624         conf.DEFINE('WITH_WINBIND', '1')
625
626     conf.find_program('awk', var='AWK')
627
628     conf.CHECK_HEADERS('asm/types.h')
629
630     conf.CHECK_CODE('dev_t dev; int i = major(dev); return 0', "HAVE_DEVICE_MAJOR_FN",
631                     headers='unistd.h sys/types.h',
632                     msg="Checking for major macro")
633
634     conf.CHECK_CODE('dev_t dev; int i = minor(dev); return 0', "HAVE_DEVICE_MINOR_FN",
635                     headers='unistd.h sys/types.h',
636                     msg="Checking for minor macro")
637
638     conf.CHECK_STRUCTURE_MEMBER('struct dirent', 'd_off',
639                                 headers='unistd.h sys/types.h dirent.h',
640                                 define='HAVE_DIRENT_D_OFF')
641
642     if (conf.CONFIG_SET('HAVE_YP_GET_DEFAULT_DOMAIN')):
643            conf.DEFINE('HAVE_NETGROUP', '1')
644
645     # Look for CUPS
646     if Options.options.with_cups:
647         conf.find_program('cups-config', var='CUPS_CONFIG')
648         if conf.env.CUPS_CONFIG:
649             # we would normally use --libs here, but cups-config incorrectly adds
650             # gssapi_krb5 and other libraries to its --libs output. That breaks the use
651             # of an in-tree heimdal kerberos
652             conf.CHECK_CFG(path=conf.env.CUPS_CONFIG, args="--cflags --ldflags",
653                            package="", uselib_store="CUPS")
654         conf.CHECK_HEADERS('cups/cups.h cups/language.h', lib='cups')
655         conf.CHECK_FUNCS_IN('httpConnect httpConnect2 httpConnectEncrypt', 'cups')
656         if conf.CONFIG_SET('HAVE_CUPS_CUPS_H') and conf.CONFIG_SET('HAVE_CUPS_LANGUAGE_H'):
657             conf.DEFINE('HAVE_CUPS', '1')
658         else:
659             conf.undefine('HAVE_CUPS')
660             conf.SET_TARGET_TYPE('cups', 'EMPTY')
661     else:
662         # define an empty subsystem for cups, to allow it to be used as an empty dependency
663         conf.SET_TARGET_TYPE('cups', 'EMPTY')
664
665     if Options.options.with_iprint:
666         if conf.CONFIG_SET('HAVE_CUPS'):
667             conf.DEFINE('HAVE_IPRINT', '1')
668         else:
669             Logs.warn("--enable-iprint=yes but cups support not sufficient")
670     if Options.options.with_syslog:
671         conf.DEFINE('WITH_SYSLOG', '1')
672     if Options.options.with_automount:
673         conf.DEFINE('WITH_AUTOMOUNT', '1')
674
675     # Check for LDAP
676     if Options.options.with_ldap:
677         conf.CHECK_HEADERS('ldap.h lber.h ldap_pvt.h')
678         conf.CHECK_TYPE('ber_tag_t', 'unsigned int', headers='ldap.h lber.h')
679         conf.CHECK_FUNCS_IN('ber_scanf ber_sockbuf_add_io', 'lber')
680         conf.CHECK_VARIABLE('LDAP_OPT_SOCKBUF', headers='ldap.h')
681
682         # if we LBER_OPT_LOG_PRINT_FN we can intercept ldap logging and print it out
683         # for the samba logs
684         conf.CHECK_VARIABLE('LBER_OPT_LOG_PRINT_FN',
685                             define='HAVE_LBER_LOG_PRINT_FN', headers='lber.h')
686
687         conf.CHECK_FUNCS_IN('ldap_init ldap_init_fd ldap_initialize ldap_set_rebind_proc', 'ldap')
688         conf.CHECK_FUNCS_IN('ldap_add_result_entry', 'ldap')
689
690         # Check if ldap_set_rebind_proc() takes three arguments
691         if conf.CHECK_CODE('ldap_set_rebind_proc(0, 0, 0)',
692                            'LDAP_SET_REBIND_PROC_ARGS',
693                            msg="Checking whether ldap_set_rebind_proc takes 3 arguments",
694                            headers='ldap.h lber.h', link=False):
695             conf.DEFINE('LDAP_SET_REBIND_PROC_ARGS', '3')
696         else:
697             conf.DEFINE('LDAP_SET_REBIND_PROC_ARGS', '2')
698
699         # last but not least, if ldap_init() exists, we want to use ldap
700         if conf.CONFIG_SET('HAVE_LDAP_INIT') and conf.CONFIG_SET('HAVE_LDAP_H'):
701             conf.DEFINE('HAVE_LDAP', '1')
702             conf.DEFINE('LDAP_DEPRECATED', '1')
703             conf.env['HAVE_LDAP'] = '1'
704             # if ber_sockbuf_add_io() and LDAP_OPT_SOCKBUF are available, we can add
705             # SASL wrapping hooks
706             if conf.CONFIG_SET('HAVE_BER_SOCKBUF_ADD_IO') and \
707                     conf.CONFIG_SET('HAVE_LDAP_OPT_SOCKBUF'):
708                 conf.DEFINE('HAVE_LDAP_SASL_WRAPPING', '1')
709         else:
710             conf.fatal("LDAP support not found. "
711                        "Try installing libldap2-dev or openldap-devel. "
712                        "Otherwise, use --without-ldap to build without "
713                        "LDAP support. "
714                        "LDAP support is required for the LDAP passdb backend, "
715                        "LDAP idmap backends and ADS. "
716                        "ADS support improves communication with "
717                        "Active Directory domain controllers.")
718     else:
719         conf.SET_TARGET_TYPE('ldap', 'EMPTY')
720         conf.SET_TARGET_TYPE('lber', 'EMPTY')
721
722     if Options.options.with_ads == False:
723         use_ads = False
724         use_ads_krb5 = False
725         use_ads_ldap = False
726     else:
727         use_ads = True
728         use_ads_krb5 = True
729         use_ads_ldap = True
730         if not conf.CONFIG_SET('HAVE_ENCTYPE_ARCFOUR_HMAC_MD5') and \
731            not conf.CONFIG_SET('HAVE_ENCTYPE_ARCFOUR_HMAC'):
732             Logs.warn("arcfour-hmac-md5 encryption type not found in -lkrb5")
733             use_ads_krb5 = False
734         if not conf.CONFIG_SET('HAVE_KRB5_MK_REQ_EXTENDED'):
735             Logs.warn("krb5_mk_req_extended not found in -lkrb5")
736             use_ads_krb5 = False
737         if not conf.CONFIG_SET('HAVE_KRB5_GET_HOST_REALM'):
738             Logs.warn("krb5_get_host_realm not found in -lkrb5")
739             use_ads_krb5 = False
740         if not conf.CONFIG_SET('HAVE_KRB5_FREE_HOST_REALM'):
741             Logs.warn("krb5_free_host_realm not found in -lkrb5")
742             use_ads_krb5 = False
743         if not conf.CONFIG_SET('HAVE_KRB5_FWD_TGT_CREDS'):
744             Logs.warn("krb5_fwd_tgt_creds found in -lkrb5")
745             use_ads_krb5 = False
746         if not conf.CONFIG_SET('HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC'):
747             Logs.warn("krb5_get_init_creds_opt_alloc not found in -lkrb5")
748             use_ads_krb5 = False
749         if not conf.CONFIG_SET('KRB5_CREDS_OPT_FREE_REQUIRES_CONTEXT'):
750             Logs.warn("krb5_get_init_creds_opt_free was not found or was too old in -lkrb5")
751             use_ads_krb5 = False
752         if not conf.CONFIG_SET('HAVE_KRB5_GET_RENEWED_CREDS'):
753             Logs.warn("krb5_get_renewed_creds not found in -lkrb5")
754             use_ads_krb5 = False
755         if not conf.CONFIG_SET('HAVE_KRB5_PRINCIPAL_COMPARE_ANY_REALM'):
756             Logs.warn("krb5_principal_compare_any_realm not found in -lkrb5")
757             use_ads_krb5 = False
758         if not conf.CONFIG_SET('HAVE_KRB5_C_STRING_TO_KEY') and \
759            not conf.CONFIG_SET('HAVE_KRB5_STRING_TO_KEY_SALT'):
760             Logs.warn("krb5_c_string_to_key not found in -lkrb5")
761             use_ads_krb5 = False
762         if not conf.CONFIG_SET('HAVE_KRB5_PRINCIPAL2SALT') and \
763            not conf.CONFIG_SET('HAVE_KRB5_GET_PW_SALT'):
764             Logs.warn("no CREATE_KEY_FUNCTIONS detected")
765             use_ads_krb5 = False
766         if not conf.CONFIG_SET('HAVE_KRB5_GET_PERMITTED_ENCTYPES') and \
767            not conf.CONFIG_SET('HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES'):
768             Logs.warn("no GET_ENCTYPES_FUNCTIONS detected")
769             use_ads_krb5 = False
770         if not conf.CONFIG_SET('HAVE_KRB5_KT_FREE_ENTRY') and \
771            not conf.CONFIG_SET('HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS'):
772             Logs.warn("no KT_FREE_FUNCTION detected")
773             use_ads_krb5 = False
774         if not conf.CONFIG_SET('HAVE_KRB5_C_VERIFY_CHECKSUM'):
775             Logs.warn("krb5_c_verify_checksum_compare not found in -lkrb5")
776             use_ads_krb5 = False
777
778         # We don't actually use
779         # gsskrb5_extract_authz_data_from_sec_context, but it is a
780         # clue that this Heimdal, which does the PAC processing we
781         # need on the standard gss_inquire_sec_context_by_oid
782         if not conf.CONFIG_SET('HAVE_GSS_GET_NAME_ATTRIBUTE') and \
783             not (conf.CONFIG_SET('HAVE_GSSKRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT') and \
784                      conf.CONFIG_SET('HAVE_GSS_INQUIRE_SEC_CONTEXT_BY_OID')):
785             Logs.warn("need either gss_get_name_attribute or gsskrb5_extract_authz_data_from_sec_context and gss_inquire_sec_context_by_oid in -lgssapi for PAC support")
786             use_ads_krb5 = False
787
788         if not conf.CONFIG_SET('HAVE_GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT'):
789             Logs.warn("need gss_krb5_export_lucid_sec_context for SPNEGO and gss_wrap support")
790             use_ads_krb5 = False
791
792         if use_ads_krb5:
793             conf.DEFINE('HAVE_KRB5', '1')
794             conf.env['HAVE_KRB5'] = '1'
795         else:
796             conf.undefine('HAVE_KRB5_H')
797             conf.undefine('HAVE_GSSAPI_H')
798             conf.undefine('HAVE_GSSAPI_GSSAPI_GENERIC_H')
799             conf.undefine('HAVE_GSSAPI_GSSAPI_H')
800             use_ads = False
801
802         if not conf.CONFIG_SET('HAVE_LDAP'):
803             use_ads = False
804             use_ads_ldap = False
805
806     if use_ads:
807         conf.DEFINE('WITH_ADS', '1')
808         conf.env['HAVE_ADS'] = '1'
809         Logs.info("Building with Active Directory support.")
810         # these have broken dependencies
811         forced_shared_modules.extend(TO_LIST('idmap_ad idmap_rfc2307'))
812     elif Options.options.with_ads == False:
813         Logs.info("Building without Active Directory support (--without-ads).")
814         if not Options.options.without_ad_dc:
815             conf.fatal("Building --without-ads requires also "
816                        "building --without-ad-dc.")
817     else:
818         if not use_ads_krb5:
819             Logs.warn("Active Directory support not available: krb5 libs don't have all required features")
820         if not use_ads_ldap:
821             Logs.warn("Active Directory support not available: LDAP support is not available.")
822         if Options.options.with_ads:
823             conf.fatal("Active Directory support not found. Use --without-ads "
824                        "for building without Active Directory support. "
825                        "ADS support improves communication with "
826                        "Active Directory domain controllers.")
827         else:
828             # this is the auto-mode case
829             Logs.warn("Building without Active Directory support.")
830
831
832     if Options.options.with_utmp:
833         conf.env.with_utmp = True
834         if not conf.CHECK_HEADERS('utmp.h'): conf.env.with_utmp = False
835         conf.CHECK_FUNCS('pututline pututxline updwtmp updwtmpx getutmpx getutxent')
836         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_name', headers='utmp.h',
837                                     define='HAVE_UT_UT_NAME')
838         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_user', headers='utmp.h',
839                                     define='HAVE_UT_UT_USER')
840         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_id', headers='utmp.h',
841                                     define='HAVE_UT_UT_ID')
842         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_host', headers='utmp.h',
843                                     define='HAVE_UT_UT_HOST')
844         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_time', headers='utmp.h',
845                                     define='HAVE_UT_UT_TIME')
846         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_tv', headers='utmp.h',
847                                     define='HAVE_UT_UT_TV')
848         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_type', headers='utmp.h',
849                                     define='HAVE_UT_UT_TYPE')
850         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_pid', headers='utmp.h',
851                                     define='HAVE_UT_UT_PID')
852         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_exit.e_exit', headers='utmp.h',
853                                     define='HAVE_UT_UT_EXIT')
854         conf.CHECK_STRUCTURE_MEMBER('struct utmpx', 'ut_syslen', headers='utmpx.h',
855                                     define='HAVE_UX_UT_SYSLEN')
856         conf.CHECK_STRUCTURE_MEMBER('struct utmpx', 'ut_host', headers='utmpx.h',
857                                     define='HAVE_UX_UT_HOST')
858         conf.CHECK_CODE('struct utmp utarg; struct utmp *utreturn; utreturn = pututline(&utarg);',
859                         'PUTUTLINE_RETURNS_UTMP', headers='utmp.h',
860                         msg="Checking whether pututline returns pointer")
861         conf.CHECK_SIZEOF(['((struct utmp *)NULL)->ut_line'], headers='utmp.h',
862                           define='SIZEOF_UTMP_UT_LINE', critical=False)
863         if not conf.CONFIG_SET('SIZEOF_UTMP_UT_LINE'):
864             conf.env.with_utmp = False
865         elif int(conf.env.SIZEOF_UTMP_UT_LINE) < 15:
866             conf.env.with_utmp = False
867         if conf.env.with_utmp:
868             conf.DEFINE('WITH_UTMP', 1)
869         else:
870             Logs.warn("--with-utmp but utmp support not sufficient")
871
872     if Options.options.with_avahi:
873         conf.env.with_avahi = True
874         if not conf.CHECK_HEADERS('avahi-common/watch.h avahi-client/client.h'): conf.env.with_avahi = False
875         if not conf.CHECK_FUNCS_IN('avahi_client_new', 'avahi-client'): conf.env.with_avahi = False
876         if not conf.CHECK_FUNCS_IN('avahi_strerror', 'avahi-common'): conf.env.with_avahi = False
877         if conf.env.with_avahi:
878             conf.DEFINE('WITH_AVAHI_SUPPORT', 1)
879     else:
880         conf.SET_TARGET_TYPE('avahi-common', 'EMPTY')
881         conf.SET_TARGET_TYPE('avahi-client', 'EMPTY')
882
883     if Options.options.with_iconv:
884         conf.env.with_iconv = True
885         if not conf.CHECK_FUNCS_IN('iconv_open', 'iconv', headers='iconv.h'):
886             conf.env.with_iconv = False
887         if conf.env.with_iconv:
888             conf.DEFINE('HAVE_ICONV', 1)
889
890     if Options.options.with_pam:
891         use_pam=True
892         conf.CHECK_HEADERS('security/pam_appl.h pam/pam_appl.h')
893         if not conf.CONFIG_SET('HAVE_SECURITY_PAM_APPL_H') and not conf.CONFIG_SET('HAVE_PAM_PAM_APPL_H'):
894             Logs.warn("--with-pam=yes but pam_appl.h not found")
895             use_pam=False
896         conf.CHECK_FUNCS_IN('pam_get_data', 'pam')
897         conf.CHECK_HEADERS('security/pam_modules.h pam/pam_modules.h')
898         if not conf.CONFIG_SET('HAVE_SECURITY_PAM_MODULES_H') and not conf.CONFIG_SET('HAVE_PAM_PAM_MODULES_H'):
899             Logs.warn("--with-pam=yes but pam_modules.h not found")
900             use_pam=False
901         conf.CHECK_HEADERS('security/pam_ext.h security/_pam_macros.h')
902         conf.CHECK_HEADERS('pam/pam_ext.h pam/_pam_macros.h')
903         conf.CHECK_FUNCS_IN('pam_vsyslog', 'pam')
904         conf.CHECK_CODE('''
905 #if defined(HAVE_SECURITY_PAM_APPL_H)
906 #include <security/pam_appl.h>
907 #elif defined(HAVE_PAM_PAM_APPL_H)
908 #include <pam/pam_appl.h>
909 #endif
910 pam_set_item(0, PAM_RHOST, 0);
911 ''',
912             'HAVE_PAM_RHOST',
913             lib='pam',
914             msg="Checking whether PAM_RHOST is available");
915         conf.CHECK_CODE('''
916 #if defined(HAVE_SECURITY_PAM_APPL_H)
917 #include <security/pam_appl.h>
918 #elif defined(HAVE_PAM_PAM_APPL_H)
919 #include <pam/pam_appl.h>
920 #endif
921 pam_set_item(0, PAM_TTY, 0);
922 ''',
923             'HAVE_PAM_TTY',
924             lib='pam',
925             msg="Checking whether PAM_TTY is available");
926         conf.CHECK_CODE('''
927 #if (!defined(LINUX))
928
929 #define PAM_EXTERN extern
930 #if defined(HAVE_SECURITY_PAM_APPL_H)
931 #include <security/pam_appl.h>
932 #elif defined(HAVE_PAM_PAM_APPL_H)
933 #include <pam/pam_appl.h>
934 #endif
935
936 #endif
937
938 #if defined(HAVE_SECURITY_PAM_MODULES_H)
939 #include <security/pam_modules.h>
940 #elif defined(HAVE_PAM_PAM_MODULES_H)
941 #include <pam/pam_modules.h>
942 #endif
943
944 #if defined(HAVE_SECURITY__PAM_MACROS_H)
945 #include <security/_pam_macros.h>
946 #elif defined(HAVE_PAM__PAM_MACROS_H)
947 #include <pam/_pam_macros.h>
948 #endif
949
950 #ifdef HAVE_SECURITY_PAM_EXT_H
951 #include <security/pam_ext.h>
952 #endif
953
954 int i; i = PAM_RADIO_TYPE;
955 ''',
956             'HAVE_PAM_RADIO_TYPE',
957             lib='pam',
958             msg="Checking whether PAM_RADIO_TYPE is available");
959         if use_pam:
960             conf.DEFINE('WITH_PAM', 1)
961             conf.DEFINE('WITH_PAM_MODULES', 1)
962         else:
963             conf.fatal("PAM support is enabled but prerequisite libraries "
964                        "or headers not found. Use --without-pam to disable "
965                        "PAM support.");
966
967     seteuid = False
968
969 #
970 # Ensure we select the correct set of system calls on Linux.
971 #
972     if (host_os.rfind('linux') > -1):
973         conf.CHECK_CODE('''
974 #if defined(HAVE_UNISTD_H)
975 #include <unistd.h>
976 #endif
977 #include <stdlib.h>
978 #include <stdio.h>
979 #include <sys/types.h>
980 #include <errno.h>
981
982 #ifdef HAVE_SYS_PRIV_H
983 #include <sys/priv.h>
984 #endif
985 #ifdef HAVE_SYS_ID_H
986 #include <sys/id.h>
987 #endif
988
989 #if defined(HAVE_SYSCALL_H)
990 #include <syscall.h>
991 #endif
992
993 #if defined(HAVE_SYS_SYSCALL_H)
994 #include <sys/syscall.h>
995 #endif
996
997 syscall(SYS_setresuid32, -1, -1, -1);
998 syscall(SYS_setresgid32, -1, -1, -1);
999 syscall(SYS_setreuid32, -1, -1);
1000 syscall(SYS_setregid32, -1, -1);
1001 syscall(SYS_setuid32, -1);
1002 syscall(SYS_setgid32, -1);
1003 syscall(SYS_setgroups32, 0, NULL);
1004 ''',
1005             'USE_LINUX_32BIT_SYSCALLS',
1006             msg="Checking whether Linux should use 32-bit credential calls");
1007
1008         if (conf.CONFIG_SET('USE_LINUX_32BIT_SYSCALLS')):
1009             seteuid = conf.CHECK_CODE('''
1010                                 #define AUTOCONF_TEST 1
1011                                 #define HAVE_LINUX_THREAD_CREDENTIALS 1
1012                                 #define USE_LINUX_32BIT_SYSCALLS 1
1013                                 #include "../lib/util/setid.c"
1014                                 #include "./lib/util_sec.c"
1015                                 ''',
1016                                 'HAVE_LINUX_THREAD_CREDENTIALS',
1017                                 addmain=False,
1018                                 execute=True,
1019                                 msg="Checking whether we can use Linux thread-specific credentials with 32-bit system calls")
1020         else:
1021             seteuid = conf.CHECK_CODE('''
1022                                 #define AUTOCONF_TEST 1
1023                                 #define HAVE_LINUX_THREAD_CREDENTIALS 1
1024                                 #include "../lib/util/setid.c"
1025                                 #include "./lib/util_sec.c"
1026                                 ''',
1027                                 'HAVE_LINUX_THREAD_CREDENTIALS',
1028                                 addmain=False,
1029                                 execute=True,
1030                                 msg="Checking whether we can use Linux thread-specific credentials")
1031     if not seteuid:
1032         seteuid = conf.CHECK_CODE('''
1033                                 #define AUTOCONF_TEST 1
1034                                 #define USE_SETREUID 1
1035                                 #include "../lib/util/setid.c"
1036                                 #include "./lib/util_sec.c"
1037                                 ''',
1038                                 'USE_SETREUID',
1039                                 addmain=False,
1040                                 execute=True,
1041                                 msg="Checking whether setreuid is available")
1042     if not seteuid:
1043         seteuid = conf.CHECK_CODE('''
1044                                 #define AUTOCONF_TEST 1
1045                                 #define USE_SETRESUID 1
1046                                 #include "../lib/util/setid.c"
1047                                 #include "./lib/util_sec.c"
1048                                 ''',
1049                                 'USE_SETRESUID',
1050                                 addmain=False,
1051                                 execute=True,
1052                                 msg="Checking whether setresuid is available")
1053     if not seteuid:
1054         seteuid = conf.CHECK_CODE('''
1055                                 #define AUTOCONF_TEST 1
1056                                 #define USE_SETEUID 1
1057                                 #include "../lib/util/setid.c"
1058                                 #include "./lib/util_sec.c"
1059                                 ''',
1060                                 'USE_SETEUID',
1061                                 addmain=False,
1062                                 execute=True,
1063                                 msg="Checking whether seteuid is available")
1064     if not seteuid:
1065         seteuid = conf.CHECK_CODE('''
1066                                 #define AUTOCONF_TEST 1
1067                                 #define USE_SETUIDX 1
1068                                 #include "../lib/util/setid.c"
1069                                 #include "./lib/util_sec.c"
1070                                 ''',
1071                                 'USE_SETUIDX',
1072                                 addmain=False,
1073                                 execute=True,
1074                                 mandatory=True,
1075                                 msg="Checking whether setuidx is available")
1076     if Options.options.with_dnsupdate:
1077         if not conf.CONFIG_SET('HAVE_KRB5'):
1078             Logs.warn("--with-dnsupdate=yes but gssapi support not sufficient")
1079         else:
1080             conf.DEFINE('WITH_DNS_UPDATES', 1)
1081     # valgrind.h or valgrind/valgrind.h is checked in lib/replace/wscript
1082     if Options.options.developer:
1083         if conf.CONFIG_SET('HAVE_VALGRIND_H') or conf.CONFIG_SET('HAVE_VALGRIND_VALGRIND_H'):
1084             conf.DEFINE('VALGRIND', '1')
1085
1086     if conf.CHECK_CODE('''
1087 #include <bits/sockaddr.h>
1088 #include <linux/netlink.h>
1089 ''',
1090                 'HAVE_LINUX_NETLINK_H',
1091                 msg="Checking whether Linux netlink is available"):
1092
1093         conf.CHECK_CODE('''
1094 #include <bits/sockaddr.h>
1095 #include <linux/netlink.h>
1096 #include <linux/rtnetlink.h>
1097 ''',
1098                 'HAVE_LINUX_RTNETLINK_H',
1099                 msg='Checking whether Linux rtnetlink is available')
1100
1101     conf.CHECK_CODE('''
1102 #include "../tests/fcntl_lock.c"
1103 ''',
1104                 'HAVE_FCNTL_LOCK',
1105                 addmain=False,
1106                 execute=True,
1107                 msg='Checking whether fcntl locking is available')
1108
1109     conf.CHECK_CODE('''
1110 #include <unistd.h>
1111 #include <sys/types.h>
1112 #include <sys/stat.h>
1113 #include <fcntl.h>
1114 #include <errno.h>
1115
1116 #define DATA "ofdtest.fcntl"
1117
1118 int main() {
1119         struct flock lck = {
1120            .l_whence = SEEK_SET,
1121            .l_type = F_WRLCK,
1122            .l_start = 0,
1123            .l_len = 1,
1124            .l_pid = 0,
1125         };
1126         int ret;
1127         int fd1;
1128         int fd2;
1129         char *testdir = getenv("TESTDIR");
1130
1131         if (testdir) {
1132            if (chdir(testdir) != 0) {
1133               goto err;
1134            }
1135         }
1136
1137         unlink(DATA);
1138         fd1 = open(DATA, O_RDWR|O_CREAT|O_EXCL, 0600);
1139         fd2 = open(DATA, O_RDWR);
1140         if (fd1 == -1 || fd2 == -1) {
1141            goto err;
1142         }
1143         ret = fcntl(fd1,F_OFD_SETLKW,&lck);
1144         if (ret == -1) {
1145           goto err;
1146         }
1147         ret = fcntl(fd2,F_OFD_SETLK,&lck);
1148         if (ret != -1) {
1149           goto err;
1150         }
1151         if (errno != EAGAIN) {
1152           goto err;
1153         }
1154         ret = fcntl(fd2,F_OFD_GETLK,&lck);
1155         if (ret == -1) {
1156           goto err;
1157         }
1158         unlink(DATA);
1159         exit(0);
1160 err:
1161         unlink(DATA);
1162         exit(1);
1163 }''',
1164             'HAVE_OFD_LOCKS',
1165             addmain=False,
1166             execute=True,
1167             msg="Checking whether fcntl lock supports open file description locks")
1168
1169     conf.CHECK_CODE('''
1170 #include <fcntl.h>
1171 #include <unistd.h>
1172 #include <stdlib.h>
1173 #include <sys/socket.h>
1174
1175 int main(void)
1176 {
1177         int sockfd, ret;
1178         struct f_owner_ex owner, get_owner;
1179
1180         sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1181         if (sockfd == -1) {
1182             goto err;
1183         }
1184
1185         owner.type = F_OWNER_PID;
1186         owner.pid = getpid();
1187
1188         ret = fcntl(sockfd, F_SETOWN_EX, &owner);
1189         if (ret == -1) {
1190             goto err;
1191         }
1192
1193         ret = fcntl(sockfd, F_GETOWN_EX, &get_owner);
1194         if (ret == -1) {
1195             goto err;
1196         }
1197
1198         if (get_owner.type != F_OWNER_PID) {
1199             goto err;
1200         }
1201
1202         if (get_owner.pid != getpid()) {
1203             goto err;
1204         }
1205
1206         close(sockfd);
1207         exit(0);
1208 err:
1209         close(sockfd);
1210         exit(1);
1211 }''',
1212             'HAVE_F_OWNER_EX',
1213             addmain=False,
1214             execute=True,
1215             msg="Checking whether fcntl supports flags to send direct I/O availability signals")
1216
1217     conf.CHECK_CODE('''
1218 #include <fcntl.h>
1219 #include <unistd.h>
1220 #include <stdlib.h>
1221 #include <stdint.h>
1222
1223 #define DATA "hinttest.fcntl"
1224
1225 int main(void)
1226 {
1227         uint64_t *hint, get_hint;
1228         int fd;
1229
1230         fd = open(DATA, O_RDONLY | O_CREAT | O_EXCL);
1231         if (fd == -1) {
1232             goto err;
1233         }
1234
1235         *hint = RWH_WRITE_LIFE_SHORT;
1236         int ret = fcntl(fd, F_SET_RW_HINT, hint);
1237         if (ret == -1) {
1238             goto err;
1239         }
1240
1241         ret = fcntl(fd, F_GET_RW_HINT, &get_hint);
1242         if (ret == -1) {
1243             goto err;
1244         }
1245
1246         if (get_hint != RWH_WRITE_LIFE_SHORT) {
1247             goto err;
1248         }
1249
1250         *hint = RWH_WRITE_LIFE_EXTREME;
1251         ret = fcntl(fd, F_SET_FILE_RW_HINT, hint);
1252         if (ret == -1) {
1253             goto err;
1254         }
1255
1256         ret = fcntl(fd, F_GET_FILE_RW_HINT, &get_hint);
1257         if (ret == -1) {
1258             goto err;
1259         }
1260
1261         if (get_hint != RWH_WRITE_LIFE_EXTREME) {
1262             goto err;
1263         }
1264
1265         close(fd);
1266         unlink(DATA);
1267         exit(0);
1268 err:
1269         close(fd);
1270         unlink(DATA);
1271         exit(1);
1272 }''',
1273             'HAVE_RW_HINTS',
1274             addmain=False,
1275             execute=True,
1276             msg="Checking whether fcntl supports setting/geting hints")
1277
1278     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtim.tv_nsec',
1279                                 define='HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC') # Linux, Solaris
1280     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtimensec',
1281                                 define='HAVE_STRUCT_STAT_ST_MTIMENSEC') # BSD, if defined _POSIX_SOURCE
1282     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtimespec.tv_nsec',
1283                                 define='HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC') # BSD, if not defined _POSIX_SOURCE
1284     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtime_n',
1285                                 define='HAVE_STRUCT_STAT_ST_MTIME_N') # AIX
1286     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_umtime',
1287                                 define='HAVE_STRUCT_STAT_ST_UMTIME') # Tru64
1288     if conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC') or \
1289        conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIMENSEC') or \
1290        conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC') or \
1291        conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIME_N') or \
1292        conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_UMTIME'):
1293         conf.DEFINE('HAVE_STAT_HIRES_TIMESTAMPS', '1')
1294
1295     # recent FreeBSD, NetBSD have creation timestamps called birthtime:
1296     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_birthtime',
1297                                 define='HAVE_STRUCT_STAT_ST_BIRTHTIME')
1298     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_birthtimespec.tv_nsec',
1299                                 define='HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC')
1300     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_birthtimensec',
1301                                 define='HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC')
1302
1303     conf.CHECK_CODE('''
1304 ssize_t err = posix_fadvise(0,0,0x80000,POSIX_FADV_WILLNEED);
1305 ''',
1306                 'HAVE_POSIX_FADVISE',
1307                 msg='Checking whether posix_fadvise is available',
1308                 headers='unistd.h fcntl.h')
1309
1310     for v in ['_SC_NGROUPS_MAX', '_SC_NPROC_ONLN', '_SC_NPROCESSORS_ONLN', '_SC_PAGESIZE' ]:
1311         conf.CHECK_CODE('''
1312                         #include <unistd.h>
1313                         return sysconf(%s) == -1 ? 1 : 0;
1314                         ''' % v,
1315                         'SYSCONF%s' % v,
1316                         msg='Checking whether sysconf(%s) is available' % v)
1317
1318     conf.CHECK_CODE('''
1319 #include <sys/syscall.h>
1320 #include <unistd.h>
1321 syscall(SYS_initgroups, 16, NULL, NULL, 0);
1322                     ''',
1323                     'HAVE_DARWIN_INITGROUPS',
1324                     msg='Checking whether to use the Darwin-specific initgroups system call')
1325
1326     conf.CHECK_CODE('''struct utimbuf tbuf;  tbuf.actime = 0; tbuf.modtime = 1; exit(utime("foo.c",&tbuf));''',
1327                     'HAVE_UTIMBUF',
1328                     headers='sys/types.h utime.h',
1329                     msg='Checking whether struct utimbuf is available')
1330
1331     if conf.CHECK_CODE('''struct sigevent s;''',
1332                     'HAVE_STRUCT_SIGEVENT',
1333                     headers='sys/types.h stdlib.h stddef.h signal.h',
1334                     msg='Checking whether we have the struct sigevent'):
1335         conf.CHECK_STRUCTURE_MEMBER('struct sigevent', 'sigev_value.sival_ptr',
1336                                     define='HAVE_STRUCT_SIGEVENT_SIGEV_VALUE_SIVAL_PTR',
1337                                     headers='signal.h');
1338         conf.CHECK_STRUCTURE_MEMBER('struct sigevent', 'sigev_value.sigval_ptr',
1339                                     define='HAVE_STRUCT_SIGEVENT_SIGEV_VALUE_SIGVAL_PTR',
1340                                     headers='signal.h');
1341
1342     if os.path.exists('/proc/sys/kernel/core_pattern'):
1343         conf.DEFINE('HAVE_SYS_KERNEL_PROC_CORE_PATTERN', '1')
1344
1345     if conf.CHECK_CODE('''
1346 #include <time.h>
1347 main() {
1348         struct tm *tm;
1349         if (sizeof(time_t) == 8) {
1350                 time_t max_time = 0x7fffffffffffffffll;
1351                 tm = gmtime(&max_time);
1352                 /* This should fail with 32-bit tm_year. */
1353                 if (tm == NULL) {
1354                         /* Max time_t that works with 32-bit int tm_year in struct tm. */
1355                         max_time = 67768036191676799ll;
1356                         tm = gmtime(&max_time);
1357                         if (tm) {
1358                                 exit(0);
1359                         }
1360                 }
1361         }
1362         exit(1);
1363 }''',
1364         '__TIME_T_MAX',
1365         addmain=False,
1366         execute=True,
1367         msg="Checking for the maximum value of the 'time_t' type"):
1368             conf.DEFINE('TIME_T_MAX', '67768036191676799ll')
1369
1370     conf.CHECK_CODE('''
1371 #if defined(HAVE_UNISTD_H)
1372 #include <unistd.h>
1373 #endif
1374 #include <sys/types.h>
1375 #if defined(HAVE_SYS_SYSMACROS_H)
1376 #include <sys/sysmacros.h>
1377 #endif
1378 main() { dev_t dev = makedev(1,2); return 0; }
1379 ''',
1380         'HAVE_MAKEDEV',
1381         addmain=False,
1382         msg='Checking whether the macro for makedev is available')
1383
1384     conf.CHECK_CODE('''
1385 #include <stdio.h>
1386 #include <limits.h>
1387 #include <signal.h>
1388
1389 void exit_on_core(int ignored) {
1390         exit(1);
1391 }
1392
1393 main() {
1394         char *newpath;
1395         signal(SIGSEGV, exit_on_core);
1396         newpath = realpath("/tmp", NULL);
1397         exit((newpath != NULL) ? 0 : 1);
1398 }
1399 ''',
1400         'REALPATH_TAKES_NULL',
1401         addmain=False,
1402         execute=True,
1403         msg='Checking whether the realpath function allows a NULL argument')
1404
1405     conf.CHECK_CODE('''#include "../tests/ftruncate.c"''',
1406                     'HAVE_FTRUNCATE_EXTEND',
1407                     msg='Checking for ftruncate extend',
1408                     addmain=False,
1409                     execute=True)
1410
1411     conf.SET_TARGET_TYPE('sendfile', 'EMPTY')
1412     conf.CHECK_LIB('sendfile')
1413     if not Options.options.with_sendfile_support == False:
1414         if (host_os.rfind('linux') > -1) or (host_os.rfind('gnu') > -1) or (host_os.rfind('k*bsd*-gnu') > -1) or (host_os.rfind('kopensolaris*-gnu') > -1):
1415             conf.CHECK_CODE('''
1416                             int tofd, fromfd;
1417                             off_t offset;
1418                             size_t total;
1419                             ssize_t nwritten = sendfile(tofd, fromfd, &offset, total);
1420                             ''',
1421                             '_HAVE_SENDFILE',
1422                             headers='sys/sendfile.h',
1423                             msg='Checking for linux sendfile support')
1424
1425             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1426                 conf.DEFINE('HAVE_SENDFILE', '1')
1427                 conf.DEFINE('LINUX_SENDFILE_API', '1')
1428         elif (host_os.rfind('freebsd') > -1) or (host_os.rfind('dragonfly') > -1):
1429             conf.CHECK_CODE('''
1430                             #include <sys/types.h>
1431                             #include <unistd.h>
1432                             #include <sys/socket.h>
1433                             #include <sys/uio.h>
1434                             int fromfd, tofd, ret, total=0;
1435                             off_t offset, nwritten;
1436                             struct sf_hdtr hdr;
1437                             struct iovec hdtrl;
1438                             hdr.headers = &hdtrl;
1439                             hdr.hdr_cnt = 1;
1440                             hdr.trailers = NULL;
1441                             hdr.trl_cnt = 0;
1442                             hdtrl.iov_base = NULL;
1443                             hdtrl.iov_len = 0;
1444                             ret = sendfile(fromfd, tofd, offset, total, &hdr, &nwritten, 0)
1445                             ''',
1446                             '_HAVE_SENDFILE',
1447                             msg='Checking for freebsd sendfile support')
1448             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1449                 conf.DEFINE('HAVE_SENDFILE', '1')
1450                 conf.DEFINE('FREEBSD_SENDFILE_API', '1')
1451         elif (host_os.rfind('darwin') > -1):
1452             conf.CHECK_CODE('''
1453                             #include <sys/types.h>
1454                             #include <sys/socket.h>
1455                             #include <sys/uio.h>
1456                             int fromfd, tofd, ret;
1457                             off_t offset, nwritten;
1458                             struct sf_hdtr hdr;
1459                             struct iovec hdtrl;
1460                             hdr.headers = &hdtrl;
1461                             hdr.hdr_cnt = 1;
1462                             hdr.trailers = (void *)0;
1463                             hdr.trl_cnt = 0;
1464                             hdtrl.iov_base = (void *)0;
1465                             hdtrl.iov_len = 0;
1466                             ret = sendfile(fromfd, tofd, offset, &nwritten, &hdr, 0);
1467                             ''',
1468                             '_HAVE_SENDFILE',
1469                             msg='Checking for darwin sendfile support')
1470             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1471                 conf.DEFINE('HAVE_SENDFILE', '1')
1472                 conf.DEFINE('DARWIN_SENDFILE_API', '1')
1473         elif (host_os.rfind('hpux') > -1) or (host_os.rfind('osf') > -1):
1474             conf.CHECK_CODE('''
1475                             #include <sys/socket.h>
1476                             #include <sys/uio.h>
1477                             int fromfd, tofd;
1478                             size_t total=0;
1479                             struct iovec hdtrl[2];
1480                             ssize_t nwritten;
1481                             off_t offset;
1482                             hdtrl[0].iov_base = 0;
1483                             hdtrl[0].iov_len = 0;
1484                             nwritten = sendfile(tofd, fromfd, offset, total, &hdtrl[0], 0);
1485                             ''',
1486                             '_HAVE_SENDFILE',
1487                             msg='Checking for osf/hpux sendfile support')
1488             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1489                 conf.DEFINE('HAVE_SENDFILE', '1')
1490                 conf.DEFINE('HPUX_SENDFILE_API', '1')
1491         elif (host_os.rfind('sunos') > -1):
1492             conf.CHECK_FUNCS_IN('sendfilev', 'sendfile')
1493             conf.CHECK_CODE('''
1494                             #include <sys/sendfile.h>,
1495                             int sfvcnt;
1496                             size_t xferred;
1497                             struct sendfilevec vec[2];
1498                             ssize_t nwritten;
1499                             int tofd;
1500                             sfvcnt = 2;
1501                             vec[0].sfv_fd = SFV_FD_SELF;
1502                             vec[0].sfv_flag = 0;
1503                             vec[0].sfv_off = 0;
1504                             vec[0].sfv_len = 0;
1505                             vec[1].sfv_fd = 0;
1506                             vec[1].sfv_flag = 0;
1507                             vec[1].sfv_off = 0;
1508                             vec[1].sfv_len = 0;
1509                             nwritten = sendfilev(tofd, vec, sfvcnt, &xferred);
1510                             ''',
1511                             '_HAVE_SENDFILEV',
1512                             msg='Checking for solaris sendfilev support',
1513                             lib='sendfile')
1514             if conf.CONFIG_SET('_HAVE_SENDFILEV'):
1515                 conf.DEFINE('HAVE_SENDFILEV', '1')
1516                 conf.DEFINE('SOLARIS_SENDFILE_API', '1')
1517         elif (host_os.rfind('aix') > -1):
1518             conf.CHECK_CODE('''
1519                             #include <sys/socket.h>
1520                             int fromfd, tofd;
1521                             size_t total=0;
1522                             struct sf_parms hdtrl;
1523                             ssize_t nwritten;
1524                             hdtrl.header_data = 0;
1525                             hdtrl.header_length = 0;
1526                             hdtrl.file_descriptor = fromfd;
1527                             hdtrl.file_offset = 0;
1528                             hdtrl.file_bytes = 0;
1529                             hdtrl.trailer_data = 0;
1530                             hdtrl.trailer_length = 0;
1531                             nwritten = send_file(&tofd, &hdtrl, 0);
1532                             ''',
1533                             '_HAVE_SENDFILE',
1534                             msg='Checking for AIX send_file support')
1535             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1536                 conf.DEFINE('HAVE_SENDFILE', '1')
1537                 conf.DEFINE('AIX_SENDFILE_API', '1')
1538
1539     if Options.options.with_sendfile_support == True and not conf.CONFIG_SET('HAVE_SENDFILE'):
1540         conf.fatal('sendfile support not found but it was requested !')
1541     # Check for getcwd allowing a NULL arg.
1542     conf.CHECK_CODE('''
1543 #include <unistd.h>
1544 main() {
1545         char *s = getcwd(NULL,0);
1546         exit(s != NULL ?  0 : 1);
1547 }''', 'GETCWD_TAKES_NULL', addmain=False, execute=True,
1548         msg="getcwd takes a NULL argument")
1549
1550
1551     # UnixWare 7.x has its getspnam in -lgen
1552     conf.CHECK_FUNCS_IN('getspnam', 'gen')
1553     conf.CHECK_FUNCS_IN('getspnam', 'security')
1554     conf.CHECK_FUNCS_IN('getspnam', 'sec')
1555
1556     legacy_quota_libs = ''
1557     if not Options.options.with_quotas == False:
1558         # For quotas on Veritas VxFS filesystems
1559         conf.CHECK_HEADERS('sys/fs/vx_quota.h')
1560         # For sys/quota.h and linux/quota.h
1561         conf.CHECK_HEADERS('sys/quota.h')
1562         # For quotas on BSD systems
1563         conf.CHECK_HEADERS('ufs/ufs/quota.h')
1564         # For quotas on AIX systems
1565         conf.CHECK_HEADERS('jfs/quota.h')
1566         # For quotas on Linux XFS filesystems
1567         if conf.CHECK_HEADERS('xfs/xqm.h'):
1568             conf.DEFINE('HAVE_XFS_QUOTAS', '1')
1569         else:
1570             # For Irix XFS
1571             conf.CHECK_CODE('''
1572                 #include "confdefs.h"
1573                 #ifdef HAVE_SYS_TYPES_H
1574                 #include <sys/types.h>
1575                 #endif
1576                 #ifdef HAVE_ASM_TYPES_H
1577                 #include <asm/types.h>
1578                 #endif
1579                 #include <sys/quota.h>
1580                 int i = Q_XGETQUOTA;''',
1581                 define='HAVE_XFS_QUOTAS',
1582                 msg='for XFS QUOTA in <sys/quota.h>',
1583                 execute=False,
1584                 local_include=False)
1585
1586         # For IRIX like dqb_isoftlimit instead of dqb_fsoftlimit in struc dqblk
1587         conf.CHECK_STRUCTURE_MEMBER('struct dqblk', 'dqb_fsoftlimit', define='HAVE_DQB_FSOFTLIMIT',
1588                                 headers='sys/quota.h')
1589         #darwin style quota bytecount
1590         conf.CHECK_STRUCTURE_MEMBER('struct dqblk', 'dqb_curbytes', define='HAVE_STRUCT_DQBLK_DQB_CURBYTES',
1591                                 headers='sys/quota.h')
1592         conf.CHECK_HEADERS('rpc/types.h rpc/xdr.h', together=True)
1593         if conf.CHECK_HEADERS('rpcsvc/rquota.h', lib='tirpc'):
1594             # Optional structure member
1595             conf.CHECK_STRUCTURE_MEMBER('struct getquota_rslt', 'getquota_rslt_u',
1596                                         define='HAVE_GETQUOTA_RSLT_GETQUOTA_RSLT_U',
1597                                         headers='rpcsvc/rquota.h',
1598                                         lib='tirpc')
1599
1600             # Required function for NFS quota support
1601             conf.CHECK_CODE('''
1602                             clnt_create("", RQUOTAPROG, RQUOTAVERS, "udp");
1603                             ''',
1604                             headers="rpc/rpc.h rpc/types.h rpcsvc/rquota.h rpc/nettype.h rpc/xdr.h",
1605                             define='HAVE_NFS_QUOTAS',
1606                             msg='checking for clnt_create()',
1607                             execute=True,
1608                             local_include=False,
1609                             lib='tirpc')
1610
1611         if (host_os.rfind('linux') > -1):
1612             conf.DEFINE('HAVE_QUOTACTL_LINUX', '1')
1613         elif not conf.CONFIG_SET("HAVE_XFS_QUOTAS"):
1614             if not conf.CHECK_CODE('''
1615                 #define HAVE_QUOTACTL_4A 1
1616                 #define AUTOCONF_TEST 1
1617                 #include "../tests/sysquotas.c"
1618                 ''',
1619                                    cflags=conf.env['WERROR_CFLAGS'],
1620                                    define='HAVE_QUOTACTL_4A',
1621                                    msg='for QUOTACTL_4A: long quotactl(int cmd, char *special, qid_t id, caddr_t addr)',
1622                                    execute=True,
1623                                    addmain=False):
1624
1625                 conf.CHECK_CODE('''
1626                 #define HAVE_QUOTACTL_4B 1
1627                 #define AUTOCONF_TEST 1
1628                 #include "../tests/sysquotas.c"
1629                 ''',
1630                                 cflags=conf.env['WERROR_CFLAGS'],
1631                                 define='HAVE_QUOTACTL_4B',
1632                                 msg='for QUOTACTL_4B:  int quotactl(const char *path, int cmd, int id, char *addr)',
1633                                 execute=True,
1634                                 addmain=False)
1635
1636         if conf.CONFIG_SET('HAVE_QUOTACTL_LINUX') or \
1637            conf.CONFIG_SET('HAVE_QUOTACTL_4A') or \
1638            conf.CONFIG_SET('HAVE_QUOTACTL_4B') or \
1639            conf.CONFIG_SET('HAVE_XFS_QUOTAS'):
1640             conf.DEFINE('HAVE_SYS_QUOTAS', '1')
1641             conf.DEFINE('WITH_QUOTAS', '1')
1642
1643         #
1644         # check if Legacy quota code can be brought in
1645         # if standard interfaces are not supported
1646         #
1647         if not conf.CONFIG_SET('WITH_QUOTAS'):
1648             if host_os.rfind('sunos5') > -1:
1649                 conf.DEFINE('SUNOS5', '1')
1650                 legacy_quota_libs = 'nsl'
1651             conf.CHECK_CODE('''
1652             #define WITH_QUOTAS 1
1653             #define AUTOCONF_TEST 1
1654             #include "../tests/oldquotas.c"
1655             ''',
1656                             cflags=conf.env['WERROR_CFLAGS'],
1657                             define='WITH_QUOTAS',
1658                             lib=legacy_quota_libs,
1659                             msg='Checking whether legacy quota code can be used',
1660                             execute=False,
1661                             addmain=False)
1662             if not conf.CONFIG_SET('WITH_QUOTAS'):
1663                 legacy_quota_libs = ''
1664     conf.env['legacy_quota_libs'] = legacy_quota_libs
1665
1666     if Options.options.with_quotas == True and not conf.CONFIG_SET('WITH_QUOTAS'):
1667         conf.fatal('quota support not found but it was requested !')
1668
1669     conf.CHECK_CODE('(void)unshare(CLONE_FS);',
1670                     headers='sched.h',
1671                     define='HAVE_UNSHARE_CLONE_FS',
1672                     msg='for Linux unshare(CLONE_FS)')
1673
1674     # Check for mallinfo
1675     conf.CHECK_CODE('''
1676     struct mallinfo mi;
1677     int tmp;
1678
1679     mi = mallinfo();
1680     tmp = mi.arena + mi.ordblks + mi.smblks + mi.hblks +
1681           mi.hblkhd + mi.usmblks + mi.fsmblks +  mi.uordblks +
1682           mi.fordblks + mi.keepcost;
1683     return tmp;
1684     ''', 'HAVE_MALLINFO', msg="Checking for mallinfo()", headers='malloc.h')
1685
1686     #
1687     # cluster support (CTDB)
1688     #
1689     if not Options.options.with_cluster_support:
1690         Logs.info("building without cluster support (--without-cluster-support)")
1691         conf.env.with_ctdb = False
1692     else:
1693         Logs.info("building with cluster support")
1694         conf.env.with_ctdb = True
1695         conf.DEFINE('CLUSTER_SUPPORT', 1)
1696
1697     conf.CHECK_CODE('void seekdir(DIR *d, long loc) { return; }',
1698                     'SEEKDIR_RETURNS_VOID',
1699                     headers='sys/types.h dirent.h',
1700                     msg='Checking whether seekdir returns void')
1701
1702     if Options.options.with_profiling_data:
1703         conf.DEFINE('WITH_PROFILE', 1);
1704         conf.CHECK_FUNCS('getrusage', headers="sys/time.h sys/resource.h")
1705
1706     if (conf.CHECK_HEADERS('linux/ioctl.h sys/ioctl.h linux/fs.h') and
1707         conf.CHECK_DECLS('FS_IOC_GETFLAGS FS_COMPR_FL', headers='linux/fs.h')):
1708             conf.DEFINE('HAVE_LINUX_IOCTL', '1')
1709
1710     conf.env['CFLAGS_CEPHFS'] = "-D_FILE_OFFSET_BITS=64"
1711     if Options.options.libcephfs_dir:
1712         Logs.error('''--with-libcephfs no longer supported, please use compiler
1713                    flags instead, e.g. GCC LIBRARY_PATH and C_INCLUDE_PATH''')
1714         sys.exit(1)
1715
1716     if (Options.options.with_cephfs and
1717         conf.CHECK_HEADERS('cephfs/libcephfs.h', False, False, 'cephfs') and
1718         conf.CHECK_LIB('cephfs', shlib=True)):
1719         if (Options.options.with_acl_support and
1720             conf.CHECK_FUNCS_IN('ceph_statx', 'cephfs',
1721                                 headers='cephfs/libcephfs.h')):
1722             conf.DEFINE('HAVE_CEPH', '1')
1723         else:
1724             Logs.warn('''Ceph support disabled due to --without-acl-support
1725                       or lack of ceph_statx support''')
1726             conf.undefine('HAVE_CEPH')
1727
1728     if Options.options.with_glusterfs:
1729         conf.CHECK_CFG(package='glusterfs-api', args='"glusterfs-api >= 4" --cflags --libs',
1730                        msg='Checking for glusterfs-api >= 4', uselib_store="GFAPI")
1731         conf.CHECK_HEADERS('glusterfs/api/glfs.h', lib='gfapi')
1732         conf.CHECK_LIB('gfapi', shlib=True)
1733
1734         if conf.CONFIG_SET('HAVE_GLUSTERFS_API_GLFS_H'):
1735             if Options.options.with_acl_support:
1736                  conf.DEFINE('HAVE_GLUSTERFS', '1')
1737             else:
1738                 Logs.warn("GlusterFS support disabled due to --without-acl-support")
1739                 conf.undefine('HAVE_GLUSTERFS')
1740         else:
1741             conf.undefine('HAVE_GLUSTERFS')
1742
1743         conf.CHECK_CFG(package='glusterfs-api', args='"glusterfs-api >= 6" --cflags --libs',
1744                        msg='Checking for glusterfs-api >= 6',
1745                        uselib_store="GFAPI_VER_6")
1746         conf.CHECK_CFG(package='glusterfs-api', args='"glusterfs-api >= 7.6" --cflags --libs',
1747                        msg='Checking for glusterfs-api >= 7.6',
1748                        uselib_store="GFAPI_VER_7_6")
1749     else:
1750         conf.SET_TARGET_TYPE('gfapi', 'EMPTY')
1751         conf.undefine('HAVE_GLUSTERFS')
1752
1753     if Options.options.enable_vxfs:
1754         conf.DEFINE('HAVE_VXFS', '1')
1755
1756     if Options.options.with_snapper:
1757         if conf.CHECK_CFG(package='dbus-1', args='--cflags --libs',
1758                       msg='Checking for dbus', uselib_store="DBUS-1"):
1759             if (conf.CHECK_HEADERS('dbus/dbus.h', lib='dbus-1')
1760                                       and conf.CHECK_LIB('dbus-1', shlib=True)):
1761                 conf.DEFINE('HAVE_DBUS', '1')
1762         else:
1763             conf.fatal("vfs_snapper is enabled but prerequisite DBUS libraries "
1764                        "or headers not found. Use --disable-snapper to disable "
1765                        "vfs_snapper support.");
1766
1767     if conf.CHECK_CFG(package='liburing', args='--cflags --libs',
1768                       msg='Checking for liburing package', uselib_store="URING"):
1769         if (conf.CHECK_HEADERS('liburing.h', lib='uring')
1770                                       and conf.CHECK_LIB('uring', shlib=True)):
1771             conf.CHECK_FUNCS_IN('io_uring_ring_dontfork', 'uring',
1772                                 headers='liburing.h')
1773             conf.DEFINE('HAVE_LIBURING', '1')
1774
1775     conf.env.build_regedit = False
1776     if not Options.options.with_regedit == False:
1777         conf.PROCESS_SEPARATE_RULE('system_ncurses')
1778         if conf.CONFIG_SET('HAVE_NCURSES'):
1779             conf.env.build_regedit = True
1780
1781     if conf.env.build_regedit:
1782         Logs.info("building regedit")
1783     else:
1784         if Options.options.with_regedit == False:
1785             Logs.info("not building regedit (--without-regedit)")
1786         elif Options.options.with_regedit == True:
1787             Logs.error("ncurses not available, cannot build regedit")
1788             conf.fatal("ncurses not available, but --with-regedit was specified")
1789         else:
1790             Logs.info("ncurses not available, not building regedit")
1791
1792     if conf.CHECK_HEADERS('ftw.h') and conf.CHECK_FUNCS('nftw'):
1793         conf.env.build_mvxattr = True
1794
1795     conf.env.build_winexe = False
1796     if not Options.options.with_winexe == False:
1797         if conf.CONFIG_SET('HAVE_WINEXE_CC_WIN32') or conf.CONFIG_SET('HAVE_WINEXE_CC_WIN64'):
1798             conf.env.build_winexe = True
1799
1800     if conf.env.build_winexe:
1801         Logs.info("building winexe")
1802     else:
1803         if Options.options.with_winexe == False:
1804             Logs.info("not building winexe (--without-winexe)")
1805         elif Options.options.with_winexe == True:
1806             Logs.error("mingw not available, cannot build winexe")
1807             conf.fatal("mingw not available, but --with-winexe was specified")
1808         else:
1809             Logs.info("mingw not available, not building winexe")
1810
1811     conf.CHECK_FUNCS_IN('DES_pcbc_encrypt', 'crypto')
1812     if Options.options.with_fake_kaserver == True:
1813         conf.CHECK_HEADERS('afs/param.h afs/stds.h', together=True)
1814         conf.CHECK_HEADERS('afs/param.h afs/stds.h', together=True)
1815         if (conf.CONFIG_SET('HAVE_AFS_PARAM_H') and conf.CONFIG_SET('HAVE_AFS_STDS_H') and conf.CONFIG_SET('HAVE_DES_PCBC_ENCRYPT')):
1816             conf.DEFINE('WITH_FAKE_KASERVER', '1')
1817         else:
1818             conf.fatal('AFS headers not available, but --with-fake-kaserver was specified')
1819
1820     if conf.CHECK_CFG(package='glib-2.0',
1821                       args='--cflags --libs',
1822                       msg='Checking for glib-2.0',
1823                       uselib_store="GLIB-2.0"):
1824         if (conf.CHECK_HEADERS('glib.h', lib='glib-2.0') and conf.CHECK_LIB('glib-2.0', shlib=True)):
1825             conf.DEFINE('HAVE_GLIB', 1)
1826
1827     if conf.CONFIG_SET('HAVE_GLIB'):
1828         conf.DEFINE('WITH_TEVENT_GLIB_GLUE', '1')
1829
1830     conf.env['libtracker']=''
1831     tracker_versions = ['2.0', '1.0', '0.16', '0.14']
1832
1833     for version in tracker_versions:
1834         testlib = 'tracker-sparql-' + version
1835         if conf.CHECK_CFG(package=testlib,
1836                           args='--cflags --libs',
1837                           mandatory=False):
1838             conf.SET_TARGET_TYPE(testlib, 'SYSLIB')
1839             conf.env['libtracker'] = testlib
1840             conf.DEFINE('HAVE_TRACKER', '1')
1841             break
1842
1843     Logs.info("Checking for bison")
1844     bison.configure(conf)
1845     if conf.env['BISON']:
1846         conf.CHECK_COMMAND('%s --version  | head -n1' % conf.env.BISON[0],
1847                            msg='Using bison version',
1848                            define=None,
1849                            on_target=False)
1850
1851     Logs.info("Checking for flex")
1852     conf.find_program('flex', var='FLEX')
1853     if conf.env['FLEX']:
1854         conf.env.FLEXFLAGS = ['-t']
1855         conf.CHECK_COMMAND('%s --version' % conf.env.FLEX[0],
1856                            msg='Using flex version',
1857                            define=None,
1858                            on_target=False)
1859
1860     with_spotlight_tracker_backend = (
1861         conf.CONFIG_SET('HAVE_TRACKER')
1862         and conf.CONFIG_SET('HAVE_GLIB')
1863         and conf.env['BISON']
1864         and conf.env['FLEX']
1865         and conf.CONFIG_GET('HAVE_UTF8_NORMALISATION')
1866     )
1867
1868     with_spotlight_es_backend = (
1869         conf.CONFIG_SET('HAVE_JSON_OBJECT')
1870         and conf.env['BISON']
1871         and conf.env['FLEX']
1872         and conf.CONFIG_GET('HAVE_UTF8_NORMALISATION')
1873     )
1874
1875     conf.env.with_spotlight = False
1876     if Options.options.with_spotlight is not False:
1877         backends = ['noindex']
1878
1879         if not conf.env['BISON']:
1880             Logs.warn("Spotlight support requested but bison missing")
1881         if not conf.env['FLEX']:
1882             Logs.warn("Spotlight support requested but flex missing")
1883         if not conf.CONFIG_GET('HAVE_UTF8_NORMALISATION'):
1884             Logs.warn("Missing support for Unicode normalisation. "
1885                       "Try installing icu-dev or libicu-devel.")
1886         if not conf.CONFIG_SET('HAVE_TRACKER'):
1887             Logs.warn('Missing libtracker-sparql development files for Spotlight backend "tracker"')
1888         if not conf.CONFIG_SET('HAVE_GLIB'):
1889             Logs.warn('Missing glib-2.0 development files for Spotlight backend "tracker"')
1890         if not conf.CONFIG_GET('HAVE_JSON_OBJECT'):
1891             Logs.warn('Missing libjansson development files for Spotlight backend "elasticsearch"')
1892
1893         if with_spotlight_tracker_backend:
1894             conf.env.spotlight_backend_tracker = True
1895             backends.append('tracker')
1896             conf.DEFINE('HAVE_SPOTLIGHT_BACKEND_TRACKER', '1')
1897
1898         if with_spotlight_es_backend:
1899             conf.env.spotlight_backend_es = True
1900             backends.append('elasticsearch')
1901             conf.DEFINE('HAVE_SPOTLIGHT_BACKEND_ES', '1')
1902
1903         if (Options.options.with_spotlight is True
1904             and not conf.env.spotlight_backend_tracker
1905             and not conf.env.spotlight_backend_es):
1906             conf.fatal("Unmet dependencies for Spotlight backends")
1907
1908         Logs.info("Building with Spotlight support, available backends: %s" % ', '.join(backends))
1909         default_static_modules.extend(TO_LIST('rpc_mdssvc_module'))
1910         conf.DEFINE('WITH_SPOTLIGHT', '1')
1911         conf.env.with_spotlight = True
1912
1913     if not conf.CONFIG_SET('HAVE_RPC_XDR_H'):
1914         conf.CHECK_HEADERS('rpc/xdr.h', lib='tirpc')
1915
1916     if conf.CHECK_FUNCS_IN('nscd_flush_cache', 'nscd', headers='libnscd.h'):
1917         conf.DEFINE('HAVE_NSCD_FLUSH_CACHE', '1')
1918
1919     forced_static_modules.extend(TO_LIST('auth_builtin auth_sam auth_winbind'))
1920     default_static_modules.extend(TO_LIST('''pdb_smbpasswd pdb_tdbsam
1921                                       auth_unix
1922                                       nss_info_template idmap_tdb idmap_passdb
1923                                       idmap_nss'''))
1924
1925     default_shared_modules.extend(TO_LIST('''
1926                                       vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit
1927                                       vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap
1928                                       vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2
1929                                       vfs_readahead vfs_xattr_tdb
1930                                       vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb
1931                                       vfs_preopen vfs_catia
1932                                       vfs_media_harmony vfs_unityed_media vfs_fruit vfs_shell_snap
1933                                       vfs_commit vfs_worm vfs_crossrename vfs_linux_xfs_sgid
1934                                       vfs_time_audit vfs_offline vfs_virusfilter vfs_widelinks
1935                                   '''))
1936     default_shared_modules.extend(TO_LIST('idmap_tdb2 idmap_script'))
1937     # these have broken dependencies
1938     forced_shared_modules.extend(TO_LIST('idmap_autorid idmap_rid idmap_hash'))
1939
1940     if Options.options.developer:
1941         default_static_modules.extend(TO_LIST('charset_weird'))
1942         default_shared_modules.extend(TO_LIST('perfcount_test'))
1943         default_shared_modules.extend(TO_LIST('vfs_skel_opaque vfs_skel_transparent vfs_shadow_copy_test'))
1944         default_shared_modules.extend(TO_LIST('auth_skel pdb_test'))
1945         default_shared_modules.extend(TO_LIST('vfs_fake_dfq'))
1946         default_shared_modules.extend(TO_LIST('gpext_security gpext_registry gpext_scripts'))
1947
1948     if Options.options.enable_selftest or Options.options.developer:
1949         default_shared_modules.extend(TO_LIST('vfs_fake_acls vfs_nfs4acl_xattr'))
1950         default_shared_modules.extend(TO_LIST('vfs_error_inject'))
1951         default_shared_modules.extend(TO_LIST('vfs_delay_inject'))
1952
1953     if conf.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'):
1954         default_static_modules.extend(TO_LIST('pdb_samba_dsdb auth_samba4 vfs_dfs_samba4'))
1955         default_shared_modules.extend(TO_LIST('vfs_posix_eadb'))
1956
1957     if conf.CONFIG_SET('HAVE_FREEBSD_SUNACL_H'):
1958         default_shared_modules.extend(TO_LIST('vfs_zfsacl'))
1959
1960     if conf.CONFIG_SET('HAVE_DIRFD_DECL'):
1961         default_shared_modules.extend(TO_LIST('vfs_syncops vfs_dirsort'))
1962
1963     if conf.CONFIG_SET('HAVE_STATFS_F_FSID'):
1964         default_shared_modules.extend(TO_LIST('vfs_fileid'))
1965
1966     if (conf.CONFIG_SET('HAVE_STRUCT_MSGHDR_MSG_CONTROL') or conf.CONFIG_SET('HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS')):
1967         default_shared_modules.extend(TO_LIST('vfs_aio_fork'))
1968
1969     if conf.CONFIG_SET('HAVE_LIBURING'):
1970         default_shared_modules.extend(TO_LIST('vfs_io_uring'))
1971
1972     if Options.options.with_pthreadpool:
1973         default_shared_modules.extend(TO_LIST('vfs_aio_pthread'))
1974
1975     if conf.CONFIG_SET('HAVE_LDAP'):
1976         default_static_modules.extend(TO_LIST('pdb_ldapsam idmap_ldap'))
1977
1978     if conf.CONFIG_SET('DARWINOS'):
1979         default_static_modules.extend(TO_LIST('charset_macosxfs'))
1980
1981     if conf.CONFIG_SET('HAVE_GPFS'):
1982         default_shared_modules.extend(TO_LIST('vfs_gpfs'))
1983
1984     if (conf.CONFIG_SET('HAVE_LINUX_IOCTL')
1985       and conf.CONFIG_SET('HAVE_BASENAME') and conf.CONFIG_SET('HAVE_DIRNAME')):
1986         default_shared_modules.extend(TO_LIST('vfs_btrfs'))
1987
1988     if conf.CONFIG_SET("HAVE_CEPH"):
1989         default_shared_modules.extend(TO_LIST('vfs_ceph'))
1990         # Unlike vfs_ceph, vfs_ceph_snapshots doesn't depend on libcephfs, so
1991         # can be enabled atop a kernel CephFS share (with vfs_default) in
1992         # addition to vfs_ceph. Still, only enable vfs_ceph_snapshots builds
1993         # if we're building with libcephfs for now.
1994         default_shared_modules.extend(TO_LIST('vfs_ceph_snapshots'))
1995
1996     if conf.CONFIG_SET('HAVE_GLUSTERFS'):
1997         default_shared_modules.extend(TO_LIST('vfs_glusterfs'))
1998
1999     if conf.CONFIG_SET('HAVE_SETMNTENT'):
2000         default_shared_modules.extend(TO_LIST('vfs_glusterfs_fuse'))
2001
2002     if conf.CONFIG_SET('HAVE_VXFS'):
2003         default_shared_modules.extend(TO_LIST('vfs_vxfs'))
2004
2005     if conf.CONFIG_SET('HAVE_DBUS'):
2006         default_shared_modules.extend(TO_LIST('vfs_snapper'))
2007
2008     explicit_shared_modules = TO_LIST(Options.options.shared_modules, delimiter=',')
2009     explicit_static_modules = TO_LIST(Options.options.static_modules, delimiter=',')
2010
2011     def replace_list_item(lst, item, value):
2012         try:
2013             idx = lst.index(item)
2014             lst[idx] = value
2015         except:
2016             pass
2017     # PDB module file name should have the same name as module registers itself
2018     # In Autoconf build we export LDAP passdb module as ldapsam but WAF build
2019     # was always exporting pdb_ldap. In order to support existing packages
2020     # allow referring to pdb_ldapsam as pdb_ldap but use proper name internally.
2021     replace_list_item(explicit_shared_modules, 'pdb_ldap', 'pdb_ldapsam')
2022     replace_list_item(explicit_static_modules, 'pdb_ldap', 'pdb_ldapsam')
2023
2024     final_static_modules = []
2025     final_static_modules.extend(TO_LIST(required_static_modules))
2026     final_shared_modules = []
2027
2028     if '!FORCED' not in explicit_static_modules:
2029         final_static_modules.extend(TO_LIST(forced_static_modules))
2030     if '!FORCED' not in explicit_shared_modules:
2031         final_shared_modules.extend(TO_LIST(forced_shared_modules))
2032     if '!DEFAULT' not in explicit_static_modules:
2033         final_static_modules.extend(TO_LIST(default_static_modules))
2034     if '!DEFAULT' not in explicit_shared_modules:
2035         final_shared_modules.extend(TO_LIST(default_shared_modules))
2036
2037     if 'ALL' in explicit_static_modules:
2038         for m in default_shared_modules:
2039             if m in final_shared_modules:
2040                 final_shared_modules.remove(m)
2041             final_static_modules.append(m)
2042     if 'ALL' in explicit_shared_modules:
2043         for m in default_static_modules:
2044             if m in final_static_modules:
2045                 final_static_modules.remove(m)
2046             final_shared_modules.append(m)
2047
2048     for m in explicit_static_modules:
2049         if m in ['ALL','!DEFAULT','!FORCED']:
2050             continue
2051         if m.startswith('!'):
2052             m = m[1:]
2053             if m in required_static_modules:
2054                 raise Errors.WafError('These modules are REQUIRED as static modules: %s' %
2055                                      ' '.join(required_static_modules))
2056             if m in final_static_modules:
2057                 final_static_modules.remove(m)
2058             continue
2059         if m in forced_shared_modules:
2060             raise Errors.WafError('These modules MUST be configured as shared modules: %s' %
2061                                  ' '.join(forced_shared_modules))
2062         if m in final_shared_modules:
2063             final_shared_modules.remove(m)
2064         if m not in final_static_modules:
2065             final_static_modules.append(m)
2066     for m in explicit_shared_modules:
2067         if m in ['ALL','!DEFAULT','!FORCED']:
2068             continue
2069         if m.startswith('!'):
2070             m = m[1:]
2071             if m in final_shared_modules:
2072                 final_shared_modules.remove(m)
2073             continue
2074         if m in required_static_modules:
2075             raise Errors.WafError('These modules are REQUIRED as static modules: %s' %
2076                                  ' '.join(required_static_modules))
2077         if m in forced_static_modules:
2078             raise Errors.WafError('These module MUST be configured as static modules: %s' %
2079                                  ' '.join(forced_static_modules))
2080         if m in final_static_modules:
2081             final_static_modules.remove(m)
2082         if m not in final_shared_modules:
2083             final_shared_modules.append(m)
2084
2085     conf.env['static_modules'] = final_static_modules
2086     conf.env['shared_modules'] = final_shared_modules
2087
2088     conf.DEFINE('STRING_STATIC_MODULES', ' '.join(final_static_modules), quote=True)
2089
2090     static_list = {}
2091     shared_list = {}
2092
2093     prefixes = ['vfs', 'pdb', 'auth', 'nss_info', 'charset', 'idmap', 'gpext', 'perfcount', 'rpc']
2094     conf.env['MODULE_PREFIXES'] = prefixes
2095     for p in prefixes:
2096         for m in final_static_modules:
2097             if m.find(p) == 0:
2098                 if not p in static_list:
2099                     static_list[p] = []
2100                 static_list[p].append(m)
2101         for m in final_shared_modules:
2102             if m.find(p) == 0:
2103                 if not p in shared_list:
2104                     shared_list[p] = []
2105                 shared_list[p].append(m)
2106
2107     for p in prefixes:
2108         static_env = "%s_STATIC" % p.upper()
2109         shared_env = "%s_SHARED" % p.upper()
2110         conf.env[static_env] = []
2111         conf.env[shared_env] = []
2112         if p in static_list:
2113             decl_list = " ".join("extern NTSTATUS %s_init(TALLOC_CTX *mem_ctx); " % entry for entry in static_list[p])
2114             for entry in static_list[p]:
2115                 conf.env[static_env].append('%s' % entry)
2116             conf.DEFINE('static_decl_%s' % p, decl_list)
2117             conf.DEFINE('static_init_%s(mem_ctx)' % p, '{ %s_init((mem_ctx)); }' % '_init((mem_ctx));  '.join(static_list[p]))
2118         else:
2119             conf.DEFINE('static_decl_%s' % p, '')
2120             conf.DEFINE('static_init_%s(mem_ctx)' % p, '{}')
2121         if p in shared_list:
2122             for entry in shared_list[p]:
2123                 conf.DEFINE('%s_init' % entry, 'samba_init_module')
2124                 conf.env[shared_env].append('%s' % entry)
2125         Logs.info("%s: %s" % (static_env, ','.join(conf.env[static_env])))
2126         Logs.info("%s: %s" % (shared_env, ','.join(conf.env[shared_env])))
2127
2128     conf.SAMBA_CONFIG_H('include/config.h')