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