lib/tsocket: Free subreq as soon as possible
[Samba.git] / source3 / wscript
blobc7434fedb92856cd2a1afdb4c9a0df1ed7ccafb1
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 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')
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 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 ''')
455 conf.CHECK_SAMBA3_CHARSET() # see build/charset.py
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)
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?
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')
496 # FIXME: Add more checks here.
497 else:
498 conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
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.")
551 if conf.CHECK_FUNCS('dirfd'):
552 conf.DEFINE('HAVE_DIRFD_DECL', 1)
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)
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')
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')
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)
586 conf.CHECK_CODE('int fd = openat(AT_FDCWD, ".", O_RDONLY);',
587 'HAVE_OPENAT',
588 msg='Checking for openat',
589 headers='fcntl.h')
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')
613 if Options.options.with_winbind:
614 conf.env.build_winbind = True
615 conf.DEFINE('WITH_WINBIND', '1')
617 conf.find_program('awk', var='AWK')
619 conf.CHECK_HEADERS('asm/types.h')
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")
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")
629 conf.CHECK_STRUCTURE_MEMBER('struct dirent', 'd_off',
630 headers='unistd.h sys/types.h dirent.h',
631 define='HAVE_DIRENT_D_OFF')
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')
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')
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')
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')
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')
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')
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')
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
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
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
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
790 if not conf.CONFIG_SET('HAVE_LDAP'):
791 use_ads = False
792 use_ads_ldap = False
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.")
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")
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')
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)
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))
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
924 #endif
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
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
938 #ifdef HAVE_SECURITY_PAM_EXT_H
939 #include <security/pam_ext.h>
940 #endif
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.");
955 seteuid = False
958 # Ensure we select the correct set of system calls on Linux.
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>
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
977 #if defined(HAVE_SYSCALL_H)
978 #include <syscall.h>
979 #endif
981 #if defined(HAVE_SYS_SYSCALL_H)
982 #include <sys/syscall.h>
983 #endif
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");
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')
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"):
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')
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')
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>
1099 #define DATA "ofdtest.fcntl"
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,
1109 int ret;
1110 int fd1;
1111 int fd2;
1112 char *testdir = getenv("TESTDIR");
1114 if (testdir) {
1115 if (chdir(testdir) != 0) {
1116 goto err;
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;
1126 ret = fcntl(fd1,F_OFD_SETLKW,&lck);
1127 if (ret == -1) {
1128 goto err;
1130 ret = fcntl(fd2,F_OFD_SETLK,&lck);
1131 if (ret != -1) {
1132 goto err;
1134 if (errno != EAGAIN) {
1135 goto err;
1137 ret = fcntl(fd2,F_OFD_GETLK,&lck);
1138 if (ret == -1) {
1139 goto err;
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")
1152 conf.CHECK_CODE('''
1153 #include <fcntl.h>
1154 #include <unistd.h>
1155 #include <stdlib.h>
1156 #include <sys/socket.h>
1158 int main(void)
1160 int sockfd, ret;
1161 struct f_owner_ex owner, get_owner;
1163 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1164 if (sockfd == -1) {
1165 goto err;
1168 owner.type = F_OWNER_PID;
1169 owner.pid = getpid();
1171 ret = fcntl(sockfd, F_SETOWN_EX, &owner);
1172 if (ret == -1) {
1173 goto err;
1176 ret = fcntl(sockfd, F_GETOWN_EX, &get_owner);
1177 if (ret == -1) {
1178 goto err;
1181 if (get_owner.type != F_OWNER_PID) {
1182 goto err;
1185 if (get_owner.pid != getpid()) {
1186 goto err;
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")
1200 conf.CHECK_CODE('''
1201 #include <fcntl.h>
1202 #include <unistd.h>
1203 #include <stdlib.h>
1204 #include <stdint.h>
1206 #define DATA "hinttest.fcntl"
1208 int main(void)
1210 uint64_t hint, get_hint;
1211 int fd;
1213 fd = open(DATA, O_RDONLY | O_CREAT | O_EXCL);
1214 if (fd == -1) {
1215 goto err;
1218 hint = RWH_WRITE_LIFE_SHORT;
1219 int ret = fcntl(fd, F_SET_RW_HINT, &hint);
1220 if (ret == -1) {
1221 goto err;
1224 ret = fcntl(fd, F_GET_RW_HINT, &get_hint);
1225 if (ret == -1) {
1226 goto err;
1229 if (get_hint != RWH_WRITE_LIFE_SHORT) {
1230 goto err;
1233 hint = RWH_WRITE_LIFE_EXTREME;
1234 ret = fcntl(fd, F_SET_FILE_RW_HINT, &hint);
1235 if (ret == -1) {
1236 goto err;
1239 ret = fcntl(fd, F_GET_FILE_RW_HINT, &get_hint);
1240 if (ret == -1) {
1241 goto err;
1244 if (get_hint != RWH_WRITE_LIFE_EXTREME) {
1245 goto err;
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")
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')
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')
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')
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)
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')
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')
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');
1325 if os.path.exists('/proc/sys/kernel/core_pattern'):
1326 conf.DEFINE('HAVE_SYS_KERNEL_PROC_CORE_PATTERN', '1')
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);
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')
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')
1367 conf.CHECK_CODE('''
1368 #include <stdio.h>
1369 #include <limits.h>
1370 #include <signal.h>
1372 void exit_on_core(int ignored) {
1373 exit(1);
1376 main() {
1377 char *newpath;
1378 signal(SIGSEGV, exit_on_core);
1379 newpath = realpath("/tmp", NULL);
1380 exit((newpath != NULL) ? 0 : 1);
1382 ''',
1383 'REALPATH_TAKES_NULL',
1384 addmain=False,
1385 execute=True,
1386 msg='Checking whether the realpath function allows a NULL argument')
1388 conf.CHECK_CODE('''#include "../tests/ftruncate.c"''',
1389 'HAVE_FTRUNCATE_EXTEND',
1390 msg='Checking for ftruncate extend',
1391 addmain=False,
1392 execute=True)
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')
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')
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")
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')
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)
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')
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')
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):
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)
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')
1627 # check if Legacy quota code can be brought in
1628 # if standard interfaces are not supported
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
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 !')
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)')
1657 # Check for mallinfo
1658 conf.CHECK_CODE('''
1659 struct mallinfo mi;
1660 int tmp;
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')
1670 # cluster support (CTDB)
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)
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')
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")
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')
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)
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')
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)
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')
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')
1739 if Options.options.enable_vxfs:
1740 conf.DEFINE('HAVE_VXFS', '1')
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')
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
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")
1767 if conf.CHECK_HEADERS('ftw.h') and conf.CHECK_FUNCS('nftw'):
1768 conf.env.build_mvxattr = True
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
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")
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')
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)
1802 if conf.CONFIG_SET('HAVE_GLIB'):
1803 conf.DEFINE('WITH_TEVENT_GLIB_GLUE', '1')
1805 conf.env['libtracker']=''
1806 tracker_versions = ['2.0', '1.0', '0.16', '0.14']
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
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')
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')
1833 conf.env.with_spotlight = False
1834 if Options.options.with_spotlight is not False:
1835 backends = ['noindex']
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"')
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')
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')
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")
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
1871 if not conf.CONFIG_SET('HAVE_RPC_XDR_H'):
1872 conf.CHECK_HEADERS('rpc/xdr.h', lib='tirpc')
1874 if conf.CHECK_FUNCS_IN('nscd_flush_cache', 'nscd', headers='libnscd.h'):
1875 conf.DEFINE('HAVE_NSCD_FLUSH_CACHE', '1')
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'])
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'])
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'])
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'])
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'])
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'])
1916 if conf.CONFIG_SET('HAVE_FREEBSD_SUNACL_H'):
1917 default_shared_modules.extend(['vfs_zfsacl'])
1919 if conf.CONFIG_SET('HAVE_DIRFD_DECL'):
1920 default_shared_modules.extend(['vfs_syncops', 'vfs_dirsort'])
1922 if conf.CONFIG_SET('HAVE_STATFS_F_FSID'):
1923 default_shared_modules.extend(['vfs_fileid'])
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'])
1928 if conf.CONFIG_SET('HAVE_LIBURING'):
1929 default_shared_modules.extend(['vfs_io_uring'])
1931 if Options.options.with_pthreadpool:
1932 default_shared_modules.extend(['vfs_aio_pthread'])
1934 if conf.CONFIG_SET('HAVE_LDAP'):
1935 default_static_modules.extend(['pdb_ldapsam', 'idmap_ldap'])
1937 if conf.CONFIG_SET('DARWINOS'):
1938 default_static_modules.extend(['charset_macosxfs'])
1940 if conf.CONFIG_SET('HAVE_GPFS') and conf.CONFIG_SET('HAVE_KERNEL_OPLOCKS_LINUX'):
1941 default_shared_modules.extend(['vfs_gpfs'])
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'])
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'])
1955 if conf.CONFIG_SET('HAVE_GLUSTERFS'):
1956 default_shared_modules.extend(['vfs_glusterfs'])
1958 if conf.CONFIG_SET('HAVE_SETMNTENT'):
1959 default_shared_modules.extend(['vfs_glusterfs_fuse'])
1961 if conf.CONFIG_SET('HAVE_VXFS'):
1962 default_shared_modules.extend(['vfs_vxfs'])
1964 explicit_shared_modules = TO_LIST(Options.options.shared_modules, delimiter=',')
1965 explicit_static_modules = TO_LIST(Options.options.static_modules, delimiter=',')
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')
1980 final_static_modules = []
1981 final_static_modules.extend(TO_LIST(required_static_modules))
1982 final_shared_modules = []
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))
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)
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)
2041 conf.env['static_modules'] = final_static_modules
2042 conf.env['shared_modules'] = final_shared_modules
2044 conf.DEFINE('STRING_STATIC_MODULES', ' '.join(final_static_modules), quote=True)
2045 conf.DEFINE('STRING_SHARED_MODULES', ' '.join(final_shared_modules), quote=True)
2047 static_list = {}
2048 shared_list = {}
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)
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])))
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.")
2094 conf.SAMBA_CONFIG_H('include/config.h')