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