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