48194f261a487a2363838d6ce4c05398ba0b3588
[amitay/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         if not Options.options.without_ad_dc:
814             conf.fatal("Building --without-ads requires also "
815                        "building --without-ad-dc.")
816     else:
817         if not use_ads_krb5:
818             Logs.warn("Active Directory support not available: krb5 libs don't have all required features")
819         if not use_ads_ldap:
820             Logs.warn("Active Directory support not available: LDAP support is not available.")
821         if Options.options.with_ads:
822             conf.fatal("Active Directory support not found. Use --without-ads "
823                        "for building without Active Directory support. "
824                        "ADS support improves communication with "
825                        "Active Directory domain controllers.")
826         else:
827             # this is the auto-mode case
828             Logs.warn("Building without Active Directory support.")
829
830
831     if Options.options.with_utmp:
832         conf.env.with_utmp = True
833         if not conf.CHECK_HEADERS('utmp.h'): conf.env.with_utmp = False
834         conf.CHECK_FUNCS('pututline pututxline updwtmp updwtmpx getutmpx getutxent')
835         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_name', headers='utmp.h',
836                                     define='HAVE_UT_UT_NAME')
837         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_user', headers='utmp.h',
838                                     define='HAVE_UT_UT_USER')
839         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_id', headers='utmp.h',
840                                     define='HAVE_UT_UT_ID')
841         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_host', headers='utmp.h',
842                                     define='HAVE_UT_UT_HOST')
843         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_time', headers='utmp.h',
844                                     define='HAVE_UT_UT_TIME')
845         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_tv', headers='utmp.h',
846                                     define='HAVE_UT_UT_TV')
847         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_type', headers='utmp.h',
848                                     define='HAVE_UT_UT_TYPE')
849         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_pid', headers='utmp.h',
850                                     define='HAVE_UT_UT_PID')
851         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_exit.e_exit', headers='utmp.h',
852                                     define='HAVE_UT_UT_EXIT')
853         conf.CHECK_STRUCTURE_MEMBER('struct utmpx', 'ut_syslen', headers='utmpx.h',
854                                     define='HAVE_UX_UT_SYSLEN')
855         conf.CHECK_STRUCTURE_MEMBER('struct utmpx', 'ut_host', headers='utmpx.h',
856                                     define='HAVE_UX_UT_HOST')
857         conf.CHECK_CODE('struct utmp utarg; struct utmp *utreturn; utreturn = pututline(&utarg);',
858                         'PUTUTLINE_RETURNS_UTMP', headers='utmp.h',
859                         msg="Checking whether pututline returns pointer")
860         conf.CHECK_SIZEOF(['((struct utmp *)NULL)->ut_line'], headers='utmp.h',
861                           define='SIZEOF_UTMP_UT_LINE', critical=False)
862         if not conf.CONFIG_SET('SIZEOF_UTMP_UT_LINE'):
863             conf.env.with_utmp = False
864         elif int(conf.env.SIZEOF_UTMP_UT_LINE) < 15:
865             conf.env.with_utmp = False
866         if conf.env.with_utmp:
867             conf.DEFINE('WITH_UTMP', 1)
868         else:
869             Logs.warn("--with-utmp but utmp support not sufficient")
870
871     if Options.options.with_avahi:
872         conf.env.with_avahi = True
873         if not conf.CHECK_HEADERS('avahi-common/watch.h avahi-client/client.h'): conf.env.with_avahi = False
874         if not conf.CHECK_FUNCS_IN('avahi_client_new', 'avahi-client'): conf.env.with_avahi = False
875         if not conf.CHECK_FUNCS_IN('avahi_strerror', 'avahi-common'): conf.env.with_avahi = False
876         if conf.env.with_avahi:
877             conf.DEFINE('WITH_AVAHI_SUPPORT', 1)
878     else:
879         conf.SET_TARGET_TYPE('avahi-common', 'EMPTY')
880         conf.SET_TARGET_TYPE('avahi-client', 'EMPTY')
881
882     if Options.options.with_iconv:
883         conf.env.with_iconv = True
884         if not conf.CHECK_FUNCS_IN('iconv_open', 'iconv', headers='iconv.h'):
885             conf.env.with_iconv = False
886         if conf.env.with_iconv:
887             conf.DEFINE('HAVE_ICONV', 1)
888
889     if Options.options.with_pam:
890         use_pam=True
891         conf.CHECK_HEADERS('security/pam_appl.h pam/pam_appl.h')
892         if not conf.CONFIG_SET('HAVE_SECURITY_PAM_APPL_H') and not conf.CONFIG_SET('HAVE_PAM_PAM_APPL_H'):
893             Logs.warn("--with-pam=yes but pam_appl.h not found")
894             use_pam=False
895         conf.CHECK_FUNCS_IN('pam_get_data', 'pam')
896         conf.CHECK_HEADERS('security/pam_modules.h pam/pam_modules.h')
897         if not conf.CONFIG_SET('HAVE_SECURITY_PAM_MODULES_H') and not conf.CONFIG_SET('HAVE_PAM_PAM_MODULES_H'):
898             Logs.warn("--with-pam=yes but pam_modules.h not found")
899             use_pam=False
900         conf.CHECK_HEADERS('security/pam_ext.h security/_pam_macros.h')
901         conf.CHECK_HEADERS('pam/pam_ext.h pam/_pam_macros.h')
902         conf.CHECK_FUNCS_IN('pam_vsyslog', 'pam')
903         conf.CHECK_CODE('''
904 #if defined(HAVE_SECURITY_PAM_APPL_H)
905 #include <security/pam_appl.h>
906 #elif defined(HAVE_PAM_PAM_APPL_H)
907 #include <pam/pam_appl.h>
908 #endif
909 pam_set_item(0, PAM_RHOST, 0);
910 ''',
911             'HAVE_PAM_RHOST',
912             lib='pam',
913             msg="Checking whether PAM_RHOST is available");
914         conf.CHECK_CODE('''
915 #if defined(HAVE_SECURITY_PAM_APPL_H)
916 #include <security/pam_appl.h>
917 #elif defined(HAVE_PAM_PAM_APPL_H)
918 #include <pam/pam_appl.h>
919 #endif
920 pam_set_item(0, PAM_TTY, 0);
921 ''',
922             'HAVE_PAM_TTY',
923             lib='pam',
924             msg="Checking whether PAM_TTY is available");
925         conf.CHECK_CODE('''
926 #if (!defined(LINUX))
927
928 #define PAM_EXTERN extern
929 #if defined(HAVE_SECURITY_PAM_APPL_H)
930 #include <security/pam_appl.h>
931 #elif defined(HAVE_PAM_PAM_APPL_H)
932 #include <pam/pam_appl.h>
933 #endif
934
935 #endif
936
937 #if defined(HAVE_SECURITY_PAM_MODULES_H)
938 #include <security/pam_modules.h>
939 #elif defined(HAVE_PAM_PAM_MODULES_H)
940 #include <pam/pam_modules.h>
941 #endif
942
943 #if defined(HAVE_SECURITY__PAM_MACROS_H)
944 #include <security/_pam_macros.h>
945 #elif defined(HAVE_PAM__PAM_MACROS_H)
946 #include <pam/_pam_macros.h>
947 #endif
948
949 #ifdef HAVE_SECURITY_PAM_EXT_H
950 #include <security/pam_ext.h>
951 #endif
952
953 int i; i = PAM_RADIO_TYPE;
954 ''',
955             'HAVE_PAM_RADIO_TYPE',
956             lib='pam',
957             msg="Checking whether PAM_RADIO_TYPE is available");
958         if use_pam:
959             conf.DEFINE('WITH_PAM', 1)
960             conf.DEFINE('WITH_PAM_MODULES', 1)
961         else:
962             conf.fatal("PAM support is enabled but prerequisite libraries "
963                        "or headers not found. Use --without-pam to disable "
964                        "PAM support.");
965
966     seteuid = False
967
968 #
969 # Ensure we select the correct set of system calls on Linux.
970 #
971     if (host_os.rfind('linux') > -1):
972         conf.CHECK_CODE('''
973 #if defined(HAVE_UNISTD_H)
974 #include <unistd.h>
975 #endif
976 #include <stdlib.h>
977 #include <stdio.h>
978 #include <sys/types.h>
979 #include <errno.h>
980
981 #ifdef HAVE_SYS_PRIV_H
982 #include <sys/priv.h>
983 #endif
984 #ifdef HAVE_SYS_ID_H
985 #include <sys/id.h>
986 #endif
987
988 #if defined(HAVE_SYSCALL_H)
989 #include <syscall.h>
990 #endif
991
992 #if defined(HAVE_SYS_SYSCALL_H)
993 #include <sys/syscall.h>
994 #endif
995
996 syscall(SYS_setresuid32, -1, -1, -1);
997 syscall(SYS_setresgid32, -1, -1, -1);
998 syscall(SYS_setreuid32, -1, -1);
999 syscall(SYS_setregid32, -1, -1);
1000 syscall(SYS_setuid32, -1);
1001 syscall(SYS_setgid32, -1);
1002 syscall(SYS_setgroups32, 0, NULL);
1003 ''',
1004             'USE_LINUX_32BIT_SYSCALLS',
1005             msg="Checking whether Linux should use 32-bit credential calls");
1006
1007         if (conf.CONFIG_SET('USE_LINUX_32BIT_SYSCALLS')):
1008             seteuid = conf.CHECK_CODE('''
1009                                 #define AUTOCONF_TEST 1
1010                                 #define HAVE_LINUX_THREAD_CREDENTIALS 1
1011                                 #define USE_LINUX_32BIT_SYSCALLS 1
1012                                 #include "../lib/util/setid.c"
1013                                 #include "./lib/util_sec.c"
1014                                 ''',
1015                                 'HAVE_LINUX_THREAD_CREDENTIALS',
1016                                 addmain=False,
1017                                 execute=True,
1018                                 msg="Checking whether we can use Linux thread-specific credentials with 32-bit system calls")
1019         else:
1020             seteuid = conf.CHECK_CODE('''
1021                                 #define AUTOCONF_TEST 1
1022                                 #define HAVE_LINUX_THREAD_CREDENTIALS 1
1023                                 #include "../lib/util/setid.c"
1024                                 #include "./lib/util_sec.c"
1025                                 ''',
1026                                 'HAVE_LINUX_THREAD_CREDENTIALS',
1027                                 addmain=False,
1028                                 execute=True,
1029                                 msg="Checking whether we can use Linux thread-specific credentials")
1030     if not seteuid:
1031         seteuid = conf.CHECK_CODE('''
1032                                 #define AUTOCONF_TEST 1
1033                                 #define USE_SETREUID 1
1034                                 #include "../lib/util/setid.c"
1035                                 #include "./lib/util_sec.c"
1036                                 ''',
1037                                 'USE_SETREUID',
1038                                 addmain=False,
1039                                 execute=True,
1040                                 msg="Checking whether setreuid is available")
1041     if not seteuid:
1042         seteuid = conf.CHECK_CODE('''
1043                                 #define AUTOCONF_TEST 1
1044                                 #define USE_SETRESUID 1
1045                                 #include "../lib/util/setid.c"
1046                                 #include "./lib/util_sec.c"
1047                                 ''',
1048                                 'USE_SETRESUID',
1049                                 addmain=False,
1050                                 execute=True,
1051                                 msg="Checking whether setresuid is available")
1052     if not seteuid:
1053         seteuid = conf.CHECK_CODE('''
1054                                 #define AUTOCONF_TEST 1
1055                                 #define USE_SETEUID 1
1056                                 #include "../lib/util/setid.c"
1057                                 #include "./lib/util_sec.c"
1058                                 ''',
1059                                 'USE_SETEUID',
1060                                 addmain=False,
1061                                 execute=True,
1062                                 msg="Checking whether seteuid is available")
1063     if not seteuid:
1064         seteuid = conf.CHECK_CODE('''
1065                                 #define AUTOCONF_TEST 1
1066                                 #define USE_SETUIDX 1
1067                                 #include "../lib/util/setid.c"
1068                                 #include "./lib/util_sec.c"
1069                                 ''',
1070                                 'USE_SETUIDX',
1071                                 addmain=False,
1072                                 execute=True,
1073                                 mandatory=True,
1074                                 msg="Checking whether setuidx is available")
1075     if Options.options.with_dnsupdate:
1076         if not conf.CONFIG_SET('HAVE_KRB5'):
1077             Logs.warn("--with-dnsupdate=yes but gssapi support not sufficient")
1078         else:
1079             conf.DEFINE('WITH_DNS_UPDATES', 1)
1080     # valgrind.h or valgrind/valgrind.h is checked in lib/replace/wscript
1081     if Options.options.developer:
1082         if conf.CONFIG_SET('HAVE_VALGRIND_H') or conf.CONFIG_SET('HAVE_VALGRIND_VALGRIND_H'):
1083             conf.DEFINE('VALGRIND', '1')
1084
1085     if conf.CHECK_CODE('''
1086 #include <bits/sockaddr.h>
1087 #include <linux/netlink.h>
1088 ''',
1089                 'HAVE_LINUX_NETLINK_H',
1090                 msg="Checking whether Linux netlink is available"):
1091
1092         conf.CHECK_CODE('''
1093 #include <bits/sockaddr.h>
1094 #include <linux/netlink.h>
1095 #include <linux/rtnetlink.h>
1096 ''',
1097                 'HAVE_LINUX_RTNETLINK_H',
1098                 msg='Checking whether Linux rtnetlink is available')
1099
1100     conf.CHECK_CODE('''
1101 #include "../tests/fcntl_lock.c"
1102 ''',
1103                 'HAVE_FCNTL_LOCK',
1104                 addmain=False,
1105                 execute=True,
1106                 msg='Checking whether fcntl locking is available')
1107
1108     conf.CHECK_CODE('''
1109 #include <unistd.h>
1110 #include <sys/types.h>
1111 #include <sys/stat.h>
1112 #include <fcntl.h>
1113 #include <errno.h>
1114
1115 #define DATA "ofdtest.fcntl"
1116
1117 int main() {
1118         struct flock lck = {
1119            .l_whence = SEEK_SET,
1120            .l_type = F_WRLCK,
1121            .l_start = 0,
1122            .l_len = 1,
1123            .l_pid = 0,
1124         };
1125         int ret;
1126         int fd1;
1127         int fd2;
1128         char *testdir = getenv("TESTDIR");
1129
1130         if (testdir) {
1131            if (chdir(testdir) != 0) {
1132               goto err;
1133            }
1134         }
1135
1136         unlink(DATA);
1137         fd1 = open(DATA, O_RDWR|O_CREAT|O_EXCL, 0600);
1138         fd2 = open(DATA, O_RDWR);
1139         if (fd1 == -1 || fd2 == -1) {
1140            goto err;
1141         }
1142         ret = fcntl(fd1,F_OFD_SETLKW,&lck);
1143         if (ret == -1) {
1144           goto err;
1145         }
1146         ret = fcntl(fd2,F_OFD_SETLK,&lck);
1147         if (ret != -1) {
1148           goto err;
1149         }
1150         if (errno != EAGAIN) {
1151           goto err;
1152         }
1153         ret = fcntl(fd2,F_OFD_GETLK,&lck);
1154         if (ret == -1) {
1155           goto err;
1156         }
1157         unlink(DATA);
1158         exit(0);
1159 err:
1160         unlink(DATA);
1161         exit(1);
1162 }''',
1163             'HAVE_OFD_LOCKS',
1164             addmain=False,
1165             execute=True,
1166             msg="Checking whether fcntl lock supports open file description locks")
1167
1168     conf.CHECK_CODE('''
1169 #include <fcntl.h>
1170 #include <unistd.h>
1171 #include <stdlib.h>
1172 #include <sys/socket.h>
1173
1174 int main(void)
1175 {
1176         int sockfd, ret;
1177         struct f_owner_ex owner, get_owner;
1178
1179         sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1180         if (sockfd == -1) {
1181             goto err;
1182         }
1183
1184         owner.type = F_OWNER_PID;
1185         owner.pid = getpid();
1186
1187         ret = fcntl(sockfd, F_SETOWN_EX, &owner);
1188         if (ret == -1) {
1189             goto err;
1190         }
1191
1192         ret = fcntl(sockfd, F_GETOWN_EX, &get_owner);
1193         if (ret == -1) {
1194             goto err;
1195         }
1196
1197         if (get_owner.type != F_OWNER_PID) {
1198             goto err;
1199         }
1200
1201         if (get_owner.pid != getpid()) {
1202             goto err;
1203         }
1204
1205         close(sockfd);
1206         exit(0);
1207 err:
1208         close(sockfd);
1209         exit(1);
1210 }''',
1211             'HAVE_F_OWNER_EX',
1212             addmain=False,
1213             execute=True,
1214             msg="Checking whether fcntl supports flags to send direct I/O availability signals")
1215
1216     conf.CHECK_CODE('''
1217 #include <fcntl.h>
1218 #include <unistd.h>
1219 #include <stdlib.h>
1220 #include <stdint.h>
1221
1222 #define DATA "hinttest.fcntl"
1223
1224 int main(void)
1225 {
1226         uint64_t *hint, get_hint;
1227         int fd;
1228
1229         fd = open(DATA, O_RDONLY | O_CREAT | O_EXCL);
1230         if (fd == -1) {
1231             goto err;
1232         }
1233
1234         *hint = RWH_WRITE_LIFE_SHORT;
1235         int ret = fcntl(fd, F_SET_RW_HINT, hint);
1236         if (ret == -1) {
1237             goto err;
1238         }
1239
1240         ret = fcntl(fd, F_GET_RW_HINT, &get_hint);
1241         if (ret == -1) {
1242             goto err;
1243         }
1244
1245         if (get_hint != RWH_WRITE_LIFE_SHORT) {
1246             goto err;
1247         }
1248
1249         *hint = RWH_WRITE_LIFE_EXTREME;
1250         ret = fcntl(fd, F_SET_FILE_RW_HINT, hint);
1251         if (ret == -1) {
1252             goto err;
1253         }
1254
1255         ret = fcntl(fd, F_GET_FILE_RW_HINT, &get_hint);
1256         if (ret == -1) {
1257             goto err;
1258         }
1259
1260         if (get_hint != RWH_WRITE_LIFE_EXTREME) {
1261             goto err;
1262         }
1263
1264         close(fd);
1265         unlink(DATA);
1266         exit(0);
1267 err:
1268         close(fd);
1269         unlink(DATA);
1270         exit(1);
1271 }''',
1272             'HAVE_RW_HINTS',
1273             addmain=False,
1274             execute=True,
1275             msg="Checking whether fcntl supports setting/geting hints")
1276
1277     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtim.tv_nsec',
1278                                 define='HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC') # Linux, Solaris
1279     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtimensec',
1280                                 define='HAVE_STRUCT_STAT_ST_MTIMENSEC') # BSD, if defined _POSIX_SOURCE
1281     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtimespec.tv_nsec',
1282                                 define='HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC') # BSD, if not defined _POSIX_SOURCE
1283     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtime_n',
1284                                 define='HAVE_STRUCT_STAT_ST_MTIME_N') # AIX
1285     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_umtime',
1286                                 define='HAVE_STRUCT_STAT_ST_UMTIME') # Tru64
1287     if conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC') or \
1288        conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIMENSEC') or \
1289        conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC') or \
1290        conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIME_N') or \
1291        conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_UMTIME'):
1292         conf.DEFINE('HAVE_STAT_HIRES_TIMESTAMPS', '1')
1293
1294     # recent FreeBSD, NetBSD have creation timestamps called birthtime:
1295     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_birthtime',
1296                                 define='HAVE_STRUCT_STAT_ST_BIRTHTIME')
1297     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_birthtimespec.tv_nsec',
1298                                 define='HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC')
1299     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_birthtimensec',
1300                                 define='HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC')
1301
1302     conf.CHECK_CODE('''
1303 ssize_t err = posix_fadvise(0,0,0x80000,POSIX_FADV_WILLNEED);
1304 ''',
1305                 'HAVE_POSIX_FADVISE',
1306                 msg='Checking whether posix_fadvise is available',
1307                 headers='unistd.h fcntl.h')
1308
1309     for v in ['_SC_NGROUPS_MAX', '_SC_NPROC_ONLN', '_SC_NPROCESSORS_ONLN', '_SC_PAGESIZE' ]:
1310         conf.CHECK_CODE('''
1311                         #include <unistd.h>
1312                         return sysconf(%s) == -1 ? 1 : 0;
1313                         ''' % v,
1314                         'SYSCONF%s' % v,
1315                         msg='Checking whether sysconf(%s) is available' % v)
1316
1317     conf.CHECK_CODE('''
1318 #include <sys/syscall.h>
1319 #include <unistd.h>
1320 syscall(SYS_initgroups, 16, NULL, NULL, 0);
1321                     ''',
1322                     'HAVE_DARWIN_INITGROUPS',
1323                     msg='Checking whether to use the Darwin-specific initgroups system call')
1324
1325     conf.CHECK_CODE('''struct utimbuf tbuf;  tbuf.actime = 0; tbuf.modtime = 1; exit(utime("foo.c",&tbuf));''',
1326                     'HAVE_UTIMBUF',
1327                     headers='sys/types.h utime.h',
1328                     msg='Checking whether struct utimbuf is available')
1329
1330     if conf.CHECK_CODE('''struct sigevent s;''',
1331                     'HAVE_STRUCT_SIGEVENT',
1332                     headers='sys/types.h stdlib.h stddef.h signal.h',
1333                     msg='Checking whether we have the struct sigevent'):
1334         conf.CHECK_STRUCTURE_MEMBER('struct sigevent', 'sigev_value.sival_ptr',
1335                                     define='HAVE_STRUCT_SIGEVENT_SIGEV_VALUE_SIVAL_PTR',
1336                                     headers='signal.h');
1337         conf.CHECK_STRUCTURE_MEMBER('struct sigevent', 'sigev_value.sigval_ptr',
1338                                     define='HAVE_STRUCT_SIGEVENT_SIGEV_VALUE_SIGVAL_PTR',
1339                                     headers='signal.h');
1340
1341     if os.path.exists('/proc/sys/kernel/core_pattern'):
1342         conf.DEFINE('HAVE_SYS_KERNEL_PROC_CORE_PATTERN', '1')
1343
1344     if conf.CHECK_CODE('''
1345 #include <time.h>
1346 main() {
1347         struct tm *tm;
1348         if (sizeof(time_t) == 8) {
1349                 time_t max_time = 0x7fffffffffffffffll;
1350                 tm = gmtime(&max_time);
1351                 /* This should fail with 32-bit tm_year. */
1352                 if (tm == NULL) {
1353                         /* Max time_t that works with 32-bit int tm_year in struct tm. */
1354                         max_time = 67768036191676799ll;
1355                         tm = gmtime(&max_time);
1356                         if (tm) {
1357                                 exit(0);
1358                         }
1359                 }
1360         }
1361         exit(1);
1362 }''',
1363         '__TIME_T_MAX',
1364         addmain=False,
1365         execute=True,
1366         msg="Checking for the maximum value of the 'time_t' type"):
1367             conf.DEFINE('TIME_T_MAX', '67768036191676799ll')
1368
1369     conf.CHECK_CODE('''
1370 #if defined(HAVE_UNISTD_H)
1371 #include <unistd.h>
1372 #endif
1373 #include <sys/types.h>
1374 #if defined(HAVE_SYS_SYSMACROS_H)
1375 #include <sys/sysmacros.h>
1376 #endif
1377 main() { dev_t dev = makedev(1,2); return 0; }
1378 ''',
1379         'HAVE_MAKEDEV',
1380         addmain=False,
1381         msg='Checking whether the macro for makedev is available')
1382
1383     conf.CHECK_CODE('''
1384 #include <stdio.h>
1385 #include <limits.h>
1386 #include <signal.h>
1387
1388 void exit_on_core(int ignored) {
1389         exit(1);
1390 }
1391
1392 main() {
1393         char *newpath;
1394         signal(SIGSEGV, exit_on_core);
1395         newpath = realpath("/tmp", NULL);
1396         exit((newpath != NULL) ? 0 : 1);
1397 }
1398 ''',
1399         'REALPATH_TAKES_NULL',
1400         addmain=False,
1401         execute=True,
1402         msg='Checking whether the realpath function allows a NULL argument')
1403
1404     conf.CHECK_CODE('''#include "../tests/ftruncate.c"''',
1405                     'HAVE_FTRUNCATE_EXTEND',
1406                     msg='Checking for ftruncate extend',
1407                     addmain=False,
1408                     execute=True)
1409
1410     conf.SET_TARGET_TYPE('sendfile', 'EMPTY')
1411     conf.CHECK_LIB('sendfile')
1412     if not Options.options.with_sendfile_support == False:
1413         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):
1414             conf.CHECK_CODE('''
1415                             int tofd, fromfd;
1416                             off_t offset;
1417                             size_t total;
1418                             ssize_t nwritten = sendfile(tofd, fromfd, &offset, total);
1419                             ''',
1420                             '_HAVE_SENDFILE',
1421                             headers='sys/sendfile.h',
1422                             msg='Checking for linux sendfile support')
1423
1424             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1425                 conf.DEFINE('HAVE_SENDFILE', '1')
1426                 conf.DEFINE('LINUX_SENDFILE_API', '1')
1427         elif (host_os.rfind('freebsd') > -1) or (host_os.rfind('dragonfly') > -1):
1428             conf.CHECK_CODE('''
1429                             #include <sys/types.h>
1430                             #include <unistd.h>
1431                             #include <sys/socket.h>
1432                             #include <sys/uio.h>
1433                             int fromfd, tofd, ret, total=0;
1434                             off_t offset, nwritten;
1435                             struct sf_hdtr hdr;
1436                             struct iovec hdtrl;
1437                             hdr.headers = &hdtrl;
1438                             hdr.hdr_cnt = 1;
1439                             hdr.trailers = NULL;
1440                             hdr.trl_cnt = 0;
1441                             hdtrl.iov_base = NULL;
1442                             hdtrl.iov_len = 0;
1443                             ret = sendfile(fromfd, tofd, offset, total, &hdr, &nwritten, 0)
1444                             ''',
1445                             '_HAVE_SENDFILE',
1446                             msg='Checking for freebsd sendfile support')
1447             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1448                 conf.DEFINE('HAVE_SENDFILE', '1')
1449                 conf.DEFINE('FREEBSD_SENDFILE_API', '1')
1450         elif (host_os.rfind('darwin') > -1):
1451             conf.CHECK_CODE('''
1452                             #include <sys/types.h>
1453                             #include <sys/socket.h>
1454                             #include <sys/uio.h>
1455                             int fromfd, tofd, ret;
1456                             off_t offset, nwritten;
1457                             struct sf_hdtr hdr;
1458                             struct iovec hdtrl;
1459                             hdr.headers = &hdtrl;
1460                             hdr.hdr_cnt = 1;
1461                             hdr.trailers = (void *)0;
1462                             hdr.trl_cnt = 0;
1463                             hdtrl.iov_base = (void *)0;
1464                             hdtrl.iov_len = 0;
1465                             ret = sendfile(fromfd, tofd, offset, &nwritten, &hdr, 0);
1466                             ''',
1467                             '_HAVE_SENDFILE',
1468                             msg='Checking for darwin sendfile support')
1469             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1470                 conf.DEFINE('HAVE_SENDFILE', '1')
1471                 conf.DEFINE('DARWIN_SENDFILE_API', '1')
1472         elif (host_os.rfind('hpux') > -1) or (host_os.rfind('osf') > -1):
1473             conf.CHECK_CODE('''
1474                             #include <sys/socket.h>
1475                             #include <sys/uio.h>
1476                             int fromfd, tofd;
1477                             size_t total=0;
1478                             struct iovec hdtrl[2];
1479                             ssize_t nwritten;
1480                             off_t offset;
1481                             hdtrl[0].iov_base = 0;
1482                             hdtrl[0].iov_len = 0;
1483                             nwritten = sendfile(tofd, fromfd, offset, total, &hdtrl[0], 0);
1484                             ''',
1485                             '_HAVE_SENDFILE',
1486                             msg='Checking for osf/hpux sendfile support')
1487             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1488                 conf.DEFINE('HAVE_SENDFILE', '1')
1489                 conf.DEFINE('HPUX_SENDFILE_API', '1')
1490         elif (host_os.rfind('sunos') > -1):
1491             conf.CHECK_FUNCS_IN('sendfilev', 'sendfile')
1492             conf.CHECK_CODE('''
1493                             #include <sys/sendfile.h>,
1494                             int sfvcnt;
1495                             size_t xferred;
1496                             struct sendfilevec vec[2];
1497                             ssize_t nwritten;
1498                             int tofd;
1499                             sfvcnt = 2;
1500                             vec[0].sfv_fd = SFV_FD_SELF;
1501                             vec[0].sfv_flag = 0;
1502                             vec[0].sfv_off = 0;
1503                             vec[0].sfv_len = 0;
1504                             vec[1].sfv_fd = 0;
1505                             vec[1].sfv_flag = 0;
1506                             vec[1].sfv_off = 0;
1507                             vec[1].sfv_len = 0;
1508                             nwritten = sendfilev(tofd, vec, sfvcnt, &xferred);
1509                             ''',
1510                             '_HAVE_SENDFILEV',
1511                             msg='Checking for solaris sendfilev support',
1512                             lib='sendfile')
1513             if conf.CONFIG_SET('_HAVE_SENDFILEV'):
1514                 conf.DEFINE('HAVE_SENDFILEV', '1')
1515                 conf.DEFINE('SOLARIS_SENDFILE_API', '1')
1516         elif (host_os.rfind('aix') > -1):
1517             conf.CHECK_CODE('''
1518                             #include <sys/socket.h>
1519                             int fromfd, tofd;
1520                             size_t total=0;
1521                             struct sf_parms hdtrl;
1522                             ssize_t nwritten;
1523                             hdtrl.header_data = 0;
1524                             hdtrl.header_length = 0;
1525                             hdtrl.file_descriptor = fromfd;
1526                             hdtrl.file_offset = 0;
1527                             hdtrl.file_bytes = 0;
1528                             hdtrl.trailer_data = 0;
1529                             hdtrl.trailer_length = 0;
1530                             nwritten = send_file(&tofd, &hdtrl, 0);
1531                             ''',
1532                             '_HAVE_SENDFILE',
1533                             msg='Checking for AIX send_file support')
1534             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1535                 conf.DEFINE('HAVE_SENDFILE', '1')
1536                 conf.DEFINE('AIX_SENDFILE_API', '1')
1537
1538     if Options.options.with_sendfile_support == True and not conf.CONFIG_SET('HAVE_SENDFILE'):
1539         conf.fatal('sendfile support not found but it was requested !')
1540     # Check for getcwd allowing a NULL arg.
1541     conf.CHECK_CODE('''
1542 #include <unistd.h>
1543 main() {
1544         char *s = getcwd(NULL,0);
1545         exit(s != NULL ?  0 : 1);
1546 }''', 'GETCWD_TAKES_NULL', addmain=False, execute=True,
1547         msg="getcwd takes a NULL argument")
1548
1549
1550     # UnixWare 7.x has its getspnam in -lgen
1551     conf.CHECK_FUNCS_IN('getspnam', 'gen')
1552     conf.CHECK_FUNCS_IN('getspnam', 'security')
1553     conf.CHECK_FUNCS_IN('getspnam', 'sec')
1554
1555     legacy_quota_libs = ''
1556     if not Options.options.with_quotas == False:
1557         # For quotas on Veritas VxFS filesystems
1558         conf.CHECK_HEADERS('sys/fs/vx_quota.h')
1559         # For sys/quota.h and linux/quota.h
1560         conf.CHECK_HEADERS('sys/quota.h')
1561         # For quotas on BSD systems
1562         conf.CHECK_HEADERS('ufs/ufs/quota.h')
1563         # For quotas on AIX systems
1564         conf.CHECK_HEADERS('jfs/quota.h')
1565         # For quotas on Linux XFS filesystems
1566         if conf.CHECK_HEADERS('xfs/xqm.h'):
1567             conf.DEFINE('HAVE_XFS_QUOTAS', '1')
1568         else:
1569             # For Irix XFS
1570             conf.CHECK_CODE('''
1571                 #include "confdefs.h"
1572                 #ifdef HAVE_SYS_TYPES_H
1573                 #include <sys/types.h>
1574                 #endif
1575                 #ifdef HAVE_ASM_TYPES_H
1576                 #include <asm/types.h>
1577                 #endif
1578                 #include <sys/quota.h>
1579                 int i = Q_XGETQUOTA;''',
1580                 define='HAVE_XFS_QUOTAS',
1581                 msg='for XFS QUOTA in <sys/quota.h>',
1582                 execute=False,
1583                 local_include=False)
1584
1585         # For IRIX like dqb_isoftlimit instead of dqb_fsoftlimit in struc dqblk
1586         conf.CHECK_STRUCTURE_MEMBER('struct dqblk', 'dqb_fsoftlimit', define='HAVE_DQB_FSOFTLIMIT',
1587                                 headers='sys/quota.h')
1588         #darwin style quota bytecount
1589         conf.CHECK_STRUCTURE_MEMBER('struct dqblk', 'dqb_curbytes', define='HAVE_STRUCT_DQBLK_DQB_CURBYTES',
1590                                 headers='sys/quota.h')
1591         conf.CHECK_HEADERS('rpc/types.h rpc/xdr.h', together=True)
1592         if conf.CHECK_HEADERS('rpcsvc/rquota.h', lib='tirpc'):
1593             # Optional structure member
1594             conf.CHECK_STRUCTURE_MEMBER('struct getquota_rslt', 'getquota_rslt_u',
1595                                         define='HAVE_GETQUOTA_RSLT_GETQUOTA_RSLT_U',
1596                                         headers='rpcsvc/rquota.h',
1597                                         lib='tirpc')
1598
1599             # Required function for NFS quota support
1600             conf.CHECK_CODE('''
1601                             clnt_create("", RQUOTAPROG, RQUOTAVERS, "udp");
1602                             ''',
1603                             headers="rpc/rpc.h rpc/types.h rpcsvc/rquota.h rpc/nettype.h rpc/xdr.h",
1604                             define='HAVE_NFS_QUOTAS',
1605                             msg='checking for clnt_create()',
1606                             execute=True,
1607                             local_include=False,
1608                             lib='tirpc')
1609
1610         if (host_os.rfind('linux') > -1):
1611             conf.DEFINE('HAVE_QUOTACTL_LINUX', '1')
1612         elif not conf.CONFIG_SET("HAVE_XFS_QUOTAS"):
1613             if not conf.CHECK_CODE('''
1614                 #define HAVE_QUOTACTL_4A 1
1615                 #define AUTOCONF_TEST 1
1616                 #include "../tests/sysquotas.c"
1617                 ''',
1618                                    cflags=conf.env['WERROR_CFLAGS'],
1619                                    define='HAVE_QUOTACTL_4A',
1620                                    msg='for QUOTACTL_4A: long quotactl(int cmd, char *special, qid_t id, caddr_t addr)',
1621                                    execute=True,
1622                                    addmain=False):
1623
1624                 conf.CHECK_CODE('''
1625                 #define HAVE_QUOTACTL_4B 1
1626                 #define AUTOCONF_TEST 1
1627                 #include "../tests/sysquotas.c"
1628                 ''',
1629                                 cflags=conf.env['WERROR_CFLAGS'],
1630                                 define='HAVE_QUOTACTL_4B',
1631                                 msg='for QUOTACTL_4B:  int quotactl(const char *path, int cmd, int id, char *addr)',
1632                                 execute=True,
1633                                 addmain=False)
1634
1635         if conf.CONFIG_SET('HAVE_QUOTACTL_LINUX') or \
1636            conf.CONFIG_SET('HAVE_QUOTACTL_4A') or \
1637            conf.CONFIG_SET('HAVE_QUOTACTL_4B') or \
1638            conf.CONFIG_SET('HAVE_XFS_QUOTAS'):
1639             conf.DEFINE('HAVE_SYS_QUOTAS', '1')
1640             conf.DEFINE('WITH_QUOTAS', '1')
1641
1642         #
1643         # check if Legacy quota code can be brought in
1644         # if standard interfaces are not supported
1645         #
1646         if not conf.CONFIG_SET('WITH_QUOTAS'):
1647             if host_os.rfind('sunos5') > -1:
1648                 conf.DEFINE('SUNOS5', '1')
1649                 legacy_quota_libs = 'nsl'
1650             conf.CHECK_CODE('''
1651             #define WITH_QUOTAS 1
1652             #define AUTOCONF_TEST 1
1653             #include "../tests/oldquotas.c"
1654             ''',
1655                             cflags=conf.env['WERROR_CFLAGS'],
1656                             define='WITH_QUOTAS',
1657                             lib=legacy_quota_libs,
1658                             msg='Checking whether legacy quota code can be used',
1659                             execute=False,
1660                             addmain=False)
1661             if not conf.CONFIG_SET('WITH_QUOTAS'):
1662                 legacy_quota_libs = ''
1663     conf.env['legacy_quota_libs'] = legacy_quota_libs
1664
1665     if Options.options.with_quotas == True and not conf.CONFIG_SET('WITH_QUOTAS'):
1666         conf.fatal('quota support not found but it was equested !')
1667
1668     conf.CHECK_CODE('(void)unshare(CLONE_FS);',
1669                     headers='sched.h',
1670                     define='HAVE_UNSHARE_CLONE_FS',
1671                     msg='for Linux unshare(CLONE_FS)')
1672
1673     # Check for mallinfo
1674     conf.CHECK_CODE('''
1675     struct mallinfo mi;
1676     int tmp;
1677
1678     mi = mallinfo();
1679     tmp = mi.arena + mi.ordblks + mi.smblks + mi.hblks +
1680           mi.hblkhd + mi.usmblks + mi.fsmblks +  mi.uordblks +
1681           mi.fordblks + mi.keepcost;
1682     return tmp;
1683     ''', 'HAVE_MALLINFO', msg="Checking for mallinfo()", headers='malloc.h')
1684
1685     #
1686     # cluster support (CTDB)
1687     #
1688     if not Options.options.with_cluster_support:
1689         Logs.info("building without cluster support (--without-cluster-support)")
1690         conf.env.with_ctdb = False
1691     else:
1692         Logs.info("building with cluster support")
1693         conf.env.with_ctdb = True
1694         conf.DEFINE('CLUSTER_SUPPORT', 1)
1695
1696     conf.CHECK_CODE('void seekdir(DIR *d, long loc) { return; }',
1697                     'SEEKDIR_RETURNS_VOID',
1698                     headers='sys/types.h dirent.h',
1699                     msg='Checking whether seekdir returns void')
1700
1701     if Options.options.with_profiling_data:
1702         conf.DEFINE('WITH_PROFILE', 1);
1703         conf.CHECK_FUNCS('getrusage', headers="sys/time.h sys/resource.h")
1704
1705     if (conf.CHECK_HEADERS('linux/ioctl.h sys/ioctl.h linux/fs.h') and
1706         conf.CHECK_DECLS('FS_IOC_GETFLAGS FS_COMPR_FL', headers='linux/fs.h')):
1707             conf.DEFINE('HAVE_LINUX_IOCTL', '1')
1708
1709     conf.env['CFLAGS_CEPHFS'] = "-D_FILE_OFFSET_BITS=64"
1710     if Options.options.libcephfs_dir:
1711         Logs.error('''--with-libcephfs no longer supported, please use compiler
1712                    flags instead, e.g. GCC LIBRARY_PATH and C_INCLUDE_PATH''')
1713         sys.exit(1)
1714
1715     if (Options.options.with_cephfs and
1716         conf.CHECK_HEADERS('cephfs/libcephfs.h', False, False, 'cephfs') and
1717         conf.CHECK_LIB('cephfs', shlib=True)):
1718         if (Options.options.with_acl_support and
1719             conf.CHECK_FUNCS_IN('ceph_statx', 'cephfs',
1720                                 headers='cephfs/libcephfs.h')):
1721             conf.DEFINE('HAVE_CEPH', '1')
1722         else:
1723             Logs.warn('''Ceph support disabled due to --without-acl-support
1724                       or lack of ceph_statx support''')
1725             conf.undefine('HAVE_CEPH')
1726
1727     if Options.options.with_glusterfs:
1728         conf.CHECK_CFG(package='glusterfs-api', args='"glusterfs-api >= 4" --cflags --libs',
1729                        msg='Checking for glusterfs-api >= 4', uselib_store="GFAPI")
1730         conf.CHECK_HEADERS('glusterfs/api/glfs.h', lib='gfapi')
1731         conf.CHECK_LIB('gfapi', shlib=True)
1732
1733         if conf.CONFIG_SET('HAVE_GLUSTERFS_API_GLFS_H'):
1734             if Options.options.with_acl_support:
1735                  conf.DEFINE('HAVE_GLUSTERFS', '1')
1736             else:
1737                 Logs.warn("GlusterFS support disabled due to --without-acl-support")
1738                 conf.undefine('HAVE_GLUSTERFS')
1739         else:
1740             conf.undefine('HAVE_GLUSTERFS')
1741
1742         conf.CHECK_CFG(package='glusterfs-api', args='"glusterfs-api >= 6" --cflags --libs',
1743                        msg='Checking for glusterfs-api >= 6',
1744                        uselib_store="GFAPI_VER_6")
1745         conf.CHECK_CFG(package='glusterfs-api', args='"glusterfs-api >= 7.6" --cflags --libs',
1746                        msg='Checking for glusterfs-api >= 7.6',
1747                        uselib_store="GFAPI_VER_7_6")
1748     else:
1749         conf.SET_TARGET_TYPE('gfapi', 'EMPTY')
1750         conf.undefine('HAVE_GLUSTERFS')
1751
1752     if Options.options.enable_vxfs:
1753         conf.DEFINE('HAVE_VXFS', '1')
1754
1755     if conf.CHECK_CFG(package='dbus-1', args='--cflags --libs',
1756                       msg='Checking for dbus', uselib_store="DBUS-1"):
1757         if (conf.CHECK_HEADERS('dbus/dbus.h', lib='dbus-1')
1758                                       and conf.CHECK_LIB('dbus-1', shlib=True)):
1759             conf.DEFINE('HAVE_DBUS', '1')
1760
1761     if conf.CHECK_CFG(package='liburing', args='--cflags --libs',
1762                       msg='Checking for liburing package', uselib_store="URING"):
1763         if (conf.CHECK_HEADERS('liburing.h', lib='uring')
1764                                       and conf.CHECK_LIB('uring', shlib=True)):
1765             conf.CHECK_FUNCS_IN('io_uring_ring_dontfork', 'uring',
1766                                 headers='liburing.h')
1767             conf.DEFINE('HAVE_LIBURING', '1')
1768
1769     conf.env.build_regedit = False
1770     if not Options.options.with_regedit == False:
1771         conf.PROCESS_SEPARATE_RULE('system_ncurses')
1772         if conf.CONFIG_SET('HAVE_NCURSES'):
1773             conf.env.build_regedit = True
1774
1775     if conf.env.build_regedit:
1776         Logs.info("building regedit")
1777     else:
1778         if Options.options.with_regedit == False:
1779             Logs.info("not building regedit (--without-regedit)")
1780         elif Options.options.with_regedit == True:
1781             Logs.error("ncurses not available, cannot build regedit")
1782             conf.fatal("ncurses not available, but --with-regedit was specified")
1783         else:
1784             Logs.info("ncurses not available, not building regedit")
1785
1786     if conf.CHECK_HEADERS('ftw.h') and conf.CHECK_FUNCS('nftw'):
1787         conf.env.build_mvxattr = True
1788
1789     conf.env.build_winexe = False
1790     if not Options.options.with_winexe == False:
1791         if conf.CONFIG_SET('HAVE_WINEXE_CC_WIN32') or conf.CONFIG_SET('HAVE_WINEXE_CC_WIN64'):
1792             conf.env.build_winexe = True
1793
1794     if conf.env.build_winexe:
1795         Logs.info("building winexe")
1796     else:
1797         if Options.options.with_winexe == False:
1798             Logs.info("not building winexe (--without-winexe)")
1799         elif Options.options.with_winexe == True:
1800             Logs.error("mingw not available, cannot build winexe")
1801             conf.fatal("mingw not available, but --with-winexe was specified")
1802         else:
1803             Logs.info("mingw not available, not building winexe")
1804
1805     conf.CHECK_FUNCS_IN('DES_pcbc_encrypt', 'crypto')
1806     if Options.options.with_fake_kaserver == True:
1807         conf.CHECK_HEADERS('afs/param.h afs/stds.h', together=True)
1808         conf.CHECK_HEADERS('afs/param.h afs/stds.h', together=True)
1809         if (conf.CONFIG_SET('HAVE_AFS_PARAM_H') and conf.CONFIG_SET('HAVE_AFS_STDS_H') and conf.CONFIG_SET('HAVE_DES_PCBC_ENCRYPT')):
1810             conf.DEFINE('WITH_FAKE_KASERVER', '1')
1811         else:
1812             conf.fatal('AFS headers not available, but --with-fake-kaserver was specified')
1813
1814     if conf.CHECK_CFG(package='glib-2.0',
1815                       args='--cflags --libs',
1816                       msg='Checking for glib-2.0',
1817                       uselib_store="GLIB-2.0"):
1818         if (conf.CHECK_HEADERS('glib.h', lib='glib-2.0') and conf.CHECK_LIB('glib-2.0', shlib=True)):
1819             conf.DEFINE('HAVE_GLIB', 1)
1820
1821     if conf.CONFIG_SET('HAVE_GLIB'):
1822         conf.DEFINE('WITH_TEVENT_GLIB_GLUE', '1')
1823
1824     conf.env['libtracker']=''
1825     tracker_versions = ['2.0', '1.0', '0.16', '0.14']
1826
1827     for version in tracker_versions:
1828         testlib = 'tracker-sparql-' + version
1829         if conf.CHECK_CFG(package=testlib,
1830                           args='--cflags --libs',
1831                           mandatory=False):
1832             conf.SET_TARGET_TYPE(testlib, 'SYSLIB')
1833             conf.env['libtracker'] = testlib
1834             conf.DEFINE('HAVE_TRACKER', '1')
1835             break
1836
1837     Logs.info("Checking for bison")
1838     bison.configure(conf)
1839     if conf.env['BISON']:
1840         conf.CHECK_COMMAND('%s --version  | head -n1' % conf.env.BISON[0],
1841                            msg='Using bison version',
1842                            define=None,
1843                            on_target=False)
1844
1845     Logs.info("Checking for flex")
1846     conf.find_program('flex', var='FLEX')
1847     if conf.env['FLEX']:
1848         conf.env.FLEXFLAGS = ['-t']
1849         conf.CHECK_COMMAND('%s --version' % conf.env.FLEX[0],
1850                            msg='Using flex version',
1851                            define=None,
1852                            on_target=False)
1853
1854     with_spotlight_tracker_backend = (
1855         conf.CONFIG_SET('HAVE_TRACKER')
1856         and conf.CONFIG_SET('HAVE_GLIB')
1857         and conf.env['BISON']
1858         and conf.env['FLEX']
1859         and conf.CONFIG_GET('HAVE_UTF8_NORMALISATION')
1860     )
1861
1862     with_spotlight_es_backend = (
1863         conf.CONFIG_SET('HAVE_JSON_OBJECT')
1864         and conf.env['BISON']
1865         and conf.env['FLEX']
1866         and conf.CONFIG_GET('HAVE_UTF8_NORMALISATION')
1867     )
1868
1869     conf.env.with_spotlight = False
1870     if Options.options.with_spotlight is not False:
1871         backends = ['noindex']
1872
1873         if not conf.env['BISON']:
1874             Logs.warn("Spotlight support requested but bison missing")
1875         if not conf.env['FLEX']:
1876             Logs.warn("Spotlight support requested but flex missing")
1877         if not conf.CONFIG_GET('HAVE_UTF8_NORMALISATION'):
1878             Logs.warn("Missing support for Unicode normalisation. "
1879                       "Try installing icu-dev or libicu-devel.")
1880         if not conf.CONFIG_SET('HAVE_TRACKER'):
1881             Logs.warn('Missing libtracker-sparql development files for Spotlight backend "tracker"')
1882         if not conf.CONFIG_SET('HAVE_GLIB'):
1883             Logs.warn('Missing glib-2.0 development files for Spotlight backend "tracker"')
1884         if not conf.CONFIG_GET('HAVE_JSON_OBJECT'):
1885             Logs.warn('Missing libjansson development files for Spotlight backend "elasticsearch"')
1886
1887         if with_spotlight_tracker_backend:
1888             conf.env.spotlight_backend_tracker = True
1889             backends.append('tracker')
1890             conf.DEFINE('HAVE_SPOTLIGHT_BACKEND_TRACKER', '1')
1891
1892         if with_spotlight_es_backend:
1893             conf.env.spotlight_backend_es = True
1894             backends.append('elasticsearch')
1895             conf.DEFINE('HAVE_SPOTLIGHT_BACKEND_ES', '1')
1896
1897         if (Options.options.with_spotlight is True
1898             and not conf.env.spotlight_backend_tracker
1899             and not conf.env.spotlight_backend_es):
1900             conf.fatal("Unmet dependencies for Spotlight backends")
1901
1902         Logs.info("Building with Spotlight support, available backends: %s" % ', '.join(backends))
1903         default_static_modules.extend(TO_LIST('rpc_mdssvc_module'))
1904         conf.DEFINE('WITH_SPOTLIGHT', '1')
1905         conf.env.with_spotlight = True
1906
1907     if not conf.CONFIG_SET('HAVE_RPC_XDR_H'):
1908         conf.CHECK_HEADERS('rpc/xdr.h', lib='tirpc')
1909
1910     if conf.CHECK_FUNCS_IN('nscd_flush_cache', 'nscd', headers='libnscd.h'):
1911         conf.DEFINE('HAVE_NSCD_FLUSH_CACHE', '1')
1912
1913     forced_static_modules.extend(TO_LIST('auth_builtin auth_sam auth_winbind'))
1914     default_static_modules.extend(TO_LIST('''pdb_smbpasswd pdb_tdbsam
1915                                       auth_unix
1916                                       nss_info_template idmap_tdb idmap_passdb
1917                                       idmap_nss'''))
1918
1919     default_shared_modules.extend(TO_LIST('''
1920                                       vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit
1921                                       vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap
1922                                       vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2
1923                                       vfs_readahead vfs_xattr_tdb
1924                                       vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb
1925                                       vfs_preopen vfs_catia
1926                                       vfs_media_harmony vfs_unityed_media vfs_fruit vfs_shell_snap
1927                                       vfs_commit vfs_worm vfs_crossrename vfs_linux_xfs_sgid
1928                                       vfs_time_audit vfs_offline vfs_virusfilter
1929                                   '''))
1930     default_shared_modules.extend(TO_LIST('idmap_tdb2 idmap_script'))
1931     # these have broken dependencies
1932     forced_shared_modules.extend(TO_LIST('idmap_autorid idmap_rid idmap_hash'))
1933
1934     if Options.options.developer:
1935         default_static_modules.extend(TO_LIST('charset_weird'))
1936         default_shared_modules.extend(TO_LIST('perfcount_test'))
1937         default_shared_modules.extend(TO_LIST('vfs_skel_opaque vfs_skel_transparent vfs_shadow_copy_test'))
1938         default_shared_modules.extend(TO_LIST('auth_skel pdb_test'))
1939         default_shared_modules.extend(TO_LIST('vfs_fake_dfq'))
1940         default_shared_modules.extend(TO_LIST('gpext_security gpext_registry gpext_scripts'))
1941
1942     if Options.options.enable_selftest or Options.options.developer:
1943         default_shared_modules.extend(TO_LIST('vfs_fake_acls vfs_nfs4acl_xattr'))
1944         default_shared_modules.extend(TO_LIST('vfs_error_inject'))
1945         default_shared_modules.extend(TO_LIST('vfs_delay_inject'))
1946
1947     if conf.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'):
1948         default_static_modules.extend(TO_LIST('pdb_samba_dsdb auth_samba4 vfs_dfs_samba4'))
1949         default_shared_modules.extend(TO_LIST('vfs_posix_eadb'))
1950
1951     if conf.CONFIG_SET('HAVE_FREEBSD_SUNACL_H'):
1952         default_shared_modules.extend(TO_LIST('vfs_zfsacl'))
1953
1954     if conf.CONFIG_SET('HAVE_DIRFD_DECL'):
1955         default_shared_modules.extend(TO_LIST('vfs_syncops vfs_dirsort'))
1956
1957     if conf.CONFIG_SET('HAVE_STATFS_F_FSID'):
1958         default_shared_modules.extend(TO_LIST('vfs_fileid'))
1959
1960     if (conf.CONFIG_SET('HAVE_STRUCT_MSGHDR_MSG_CONTROL') or conf.CONFIG_SET('HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS')):
1961         default_shared_modules.extend(TO_LIST('vfs_aio_fork'))
1962
1963     if conf.CONFIG_SET('HAVE_LIBURING'):
1964         default_shared_modules.extend(TO_LIST('vfs_io_uring'))
1965
1966     if Options.options.with_pthreadpool:
1967         default_shared_modules.extend(TO_LIST('vfs_aio_pthread'))
1968
1969     if conf.CONFIG_SET('HAVE_LDAP'):
1970         default_static_modules.extend(TO_LIST('pdb_ldapsam idmap_ldap'))
1971
1972     if conf.CONFIG_SET('DARWINOS'):
1973         default_static_modules.extend(TO_LIST('charset_macosxfs'))
1974
1975     if conf.CONFIG_SET('HAVE_GPFS'):
1976         default_shared_modules.extend(TO_LIST('vfs_gpfs'))
1977
1978     if (conf.CONFIG_SET('HAVE_LINUX_IOCTL')
1979       and conf.CONFIG_SET('HAVE_BASENAME') and conf.CONFIG_SET('HAVE_DIRNAME')):
1980         default_shared_modules.extend(TO_LIST('vfs_btrfs'))
1981
1982     if conf.CONFIG_SET("HAVE_CEPH"):
1983         default_shared_modules.extend(TO_LIST('vfs_ceph'))
1984         # Unlike vfs_ceph, vfs_ceph_snapshots doesn't depend on libcephfs, so
1985         # can be enabled atop a kernel CephFS share (with vfs_default) in
1986         # addition to vfs_ceph. Still, only enable vfs_ceph_snapshots builds
1987         # if we're building with libcephfs for now.
1988         default_shared_modules.extend(TO_LIST('vfs_ceph_snapshots'))
1989
1990     if conf.CONFIG_SET('HAVE_GLUSTERFS'):
1991         default_shared_modules.extend(TO_LIST('vfs_glusterfs'))
1992
1993     if conf.CONFIG_SET('HAVE_SETMNTENT'):
1994         default_shared_modules.extend(TO_LIST('vfs_glusterfs_fuse'))
1995
1996     if conf.CONFIG_SET('HAVE_VXFS'):
1997         default_shared_modules.extend(TO_LIST('vfs_vxfs'))
1998
1999     if conf.CONFIG_SET('HAVE_DBUS'):
2000         default_shared_modules.extend(TO_LIST('vfs_snapper'))
2001
2002     explicit_shared_modules = TO_LIST(Options.options.shared_modules, delimiter=',')
2003     explicit_static_modules = TO_LIST(Options.options.static_modules, delimiter=',')
2004
2005     def replace_list_item(lst, item, value):
2006         try:
2007             idx = lst.index(item)
2008             lst[idx] = value
2009         except:
2010             pass
2011     # PDB module file name should have the same name as module registers itself
2012     # In Autoconf build we export LDAP passdb module as ldapsam but WAF build
2013     # was always exporting pdb_ldap. In order to support existing packages
2014     # allow referring to pdb_ldapsam as pdb_ldap but use proper name internally.
2015     replace_list_item(explicit_shared_modules, 'pdb_ldap', 'pdb_ldapsam')
2016     replace_list_item(explicit_static_modules, 'pdb_ldap', 'pdb_ldapsam')
2017
2018     final_static_modules = []
2019     final_static_modules.extend(TO_LIST(required_static_modules))
2020     final_shared_modules = []
2021
2022     if '!FORCED' not in explicit_static_modules:
2023         final_static_modules.extend(TO_LIST(forced_static_modules))
2024     if '!FORCED' not in explicit_shared_modules:
2025         final_shared_modules.extend(TO_LIST(forced_shared_modules))
2026     if '!DEFAULT' not in explicit_static_modules:
2027         final_static_modules.extend(TO_LIST(default_static_modules))
2028     if '!DEFAULT' not in explicit_shared_modules:
2029         final_shared_modules.extend(TO_LIST(default_shared_modules))
2030
2031     if 'ALL' in explicit_static_modules:
2032         for m in default_shared_modules:
2033             if m in final_shared_modules:
2034                 final_shared_modules.remove(m)
2035             final_static_modules.append(m)
2036     if 'ALL' in explicit_shared_modules:
2037         for m in default_static_modules:
2038             if m in final_static_modules:
2039                 final_static_modules.remove(m)
2040             final_shared_modules.append(m)
2041
2042     for m in explicit_static_modules:
2043         if m in ['ALL','!DEFAULT','!FORCED']:
2044             continue
2045         if m.startswith('!'):
2046             m = m[1:]
2047             if m in required_static_modules:
2048                 raise Errors.WafError('These modules are REQUIRED as static modules: %s' %
2049                                      ' '.join(required_static_modules))
2050             if m in final_static_modules:
2051                 final_static_modules.remove(m)
2052             continue
2053         if m in forced_shared_modules:
2054             raise Errors.WafError('These modules MUST be configured as shared modules: %s' %
2055                                  ' '.join(forced_shared_modules))
2056         if m in final_shared_modules:
2057             final_shared_modules.remove(m)
2058         if m not in final_static_modules:
2059             final_static_modules.append(m)
2060     for m in explicit_shared_modules:
2061         if m in ['ALL','!DEFAULT','!FORCED']:
2062             continue
2063         if m.startswith('!'):
2064             m = m[1:]
2065             if m in final_shared_modules:
2066                 final_shared_modules.remove(m)
2067             continue
2068         if m in required_static_modules:
2069             raise Errors.WafError('These modules are REQUIRED as static modules: %s' %
2070                                  ' '.join(required_static_modules))
2071         if m in forced_static_modules:
2072             raise Errors.WafError('These module MUST be configured as static modules: %s' %
2073                                  ' '.join(forced_static_modules))
2074         if m in final_static_modules:
2075             final_static_modules.remove(m)
2076         if m not in final_shared_modules:
2077             final_shared_modules.append(m)
2078
2079     conf.env['static_modules'] = final_static_modules
2080     conf.env['shared_modules'] = final_shared_modules
2081
2082     conf.DEFINE('STRING_STATIC_MODULES', ' '.join(final_static_modules), quote=True)
2083
2084     static_list = {}
2085     shared_list = {}
2086
2087     prefixes = ['vfs', 'pdb', 'auth', 'nss_info', 'charset', 'idmap', 'gpext', 'perfcount', 'rpc']
2088     conf.env['MODULE_PREFIXES'] = prefixes
2089     for p in prefixes:
2090         for m in final_static_modules:
2091             if m.find(p) == 0:
2092                 if not p in static_list:
2093                     static_list[p] = []
2094                 static_list[p].append(m)
2095         for m in final_shared_modules:
2096             if m.find(p) == 0:
2097                 if not p in shared_list:
2098                     shared_list[p] = []
2099                 shared_list[p].append(m)
2100
2101     for p in prefixes:
2102         static_env = "%s_STATIC" % p.upper()
2103         shared_env = "%s_SHARED" % p.upper()
2104         conf.env[static_env] = []
2105         conf.env[shared_env] = []
2106         if p in static_list:
2107             decl_list = " ".join("extern NTSTATUS %s_init(TALLOC_CTX *mem_ctx); " % entry for entry in static_list[p])
2108             for entry in static_list[p]:
2109                 conf.env[static_env].append('%s' % entry)
2110             conf.DEFINE('static_decl_%s' % p, decl_list)
2111             conf.DEFINE('static_init_%s(mem_ctx)' % p, '{ %s_init((mem_ctx)); }' % '_init((mem_ctx));  '.join(static_list[p]))
2112         else:
2113             conf.DEFINE('static_decl_%s' % p, '')
2114             conf.DEFINE('static_init_%s(mem_ctx)' % p, '{}')
2115         if p in shared_list:
2116             for entry in shared_list[p]:
2117                 conf.DEFINE('%s_init' % entry, 'samba_init_module')
2118                 conf.env[shared_env].append('%s' % entry)
2119         Logs.info("%s: %s" % (static_env, ','.join(conf.env[static_env])))
2120         Logs.info("%s: %s" % (shared_env, ','.join(conf.env[shared_env])))
2121
2122     conf.SAMBA_CONFIG_H('include/config.h')