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