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