diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/bb_archive.h | 1 | ||||
-rw-r--r-- | include/grp_.h | 65 | ||||
-rw-r--r-- | include/libbb.h | 3 | ||||
-rw-r--r-- | include/platform.h | 17 | ||||
-rw-r--r-- | include/pwd_.h | 53 | ||||
-rw-r--r-- | include/shadow_.h | 26 |
6 files changed, 47 insertions, 118 deletions
diff --git a/include/bb_archive.h b/include/bb_archive.h index a6b166fe3..5d9e24c17 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h | |||
@@ -184,6 +184,7 @@ char get_header_tar(archive_handle_t *archive_handle) FAST_FUNC; | |||
184 | char get_header_tar_gz(archive_handle_t *archive_handle) FAST_FUNC; | 184 | char get_header_tar_gz(archive_handle_t *archive_handle) FAST_FUNC; |
185 | char get_header_tar_bz2(archive_handle_t *archive_handle) FAST_FUNC; | 185 | char get_header_tar_bz2(archive_handle_t *archive_handle) FAST_FUNC; |
186 | char get_header_tar_lzma(archive_handle_t *archive_handle) FAST_FUNC; | 186 | char get_header_tar_lzma(archive_handle_t *archive_handle) FAST_FUNC; |
187 | char get_header_tar_xz(archive_handle_t *archive_handle) FAST_FUNC; | ||
187 | 188 | ||
188 | void seek_by_jump(int fd, off_t amount) FAST_FUNC; | 189 | void seek_by_jump(int fd, off_t amount) FAST_FUNC; |
189 | void seek_by_read(int fd, off_t amount) FAST_FUNC; | 190 | void seek_by_read(int fd, off_t amount) FAST_FUNC; |
diff --git a/include/grp_.h b/include/grp_.h index e5075e5a0..db13ce3b4 100644 --- a/include/grp_.h +++ b/include/grp_.h | |||
@@ -30,89 +30,36 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | |||
30 | * so that function calls are directed to bb_internal_XXX replacements | 30 | * so that function calls are directed to bb_internal_XXX replacements |
31 | */ | 31 | */ |
32 | #undef endgrent | 32 | #undef endgrent |
33 | #define setgrent bb_internal_setgrent | ||
34 | #define endgrent bb_internal_endgrent | 33 | #define endgrent bb_internal_endgrent |
35 | #define getgrent bb_internal_getgrent | ||
36 | #define fgetgrent bb_internal_fgetgrent | ||
37 | #define putgrent bb_internal_putgrent | ||
38 | #define getgrgid bb_internal_getgrgid | 34 | #define getgrgid bb_internal_getgrgid |
39 | #define getgrnam bb_internal_getgrnam | 35 | #define getgrnam bb_internal_getgrnam |
40 | #define getgrent_r bb_internal_getgrent_r | ||
41 | #define getgrgid_r bb_internal_getgrgid_r | ||
42 | #define getgrnam_r bb_internal_getgrnam_r | ||
43 | #define fgetgrent_r bb_internal_fgetgrent_r | ||
44 | #define getgrouplist bb_internal_getgrouplist | 36 | #define getgrouplist bb_internal_getgrouplist |
45 | #define initgroups bb_internal_initgroups | 37 | #define initgroups bb_internal_initgroups |
46 | 38 | ||
47 | |||
48 | /* All function names below should be remapped by #defines above | 39 | /* All function names below should be remapped by #defines above |
49 | * in order to not collide with libc names. */ | 40 | * in order to not collide with libc names. */ |
50 | 41 | ||
51 | |||
52 | /* Rewind the group-file stream. */ | ||
53 | extern void setgrent(void); | ||
54 | |||
55 | /* Close the group-file stream. */ | 42 | /* Close the group-file stream. */ |
56 | extern void endgrent(void); | 43 | void FAST_FUNC endgrent(void); |
57 | |||
58 | #ifdef UNUSED_SINCE_WE_AVOID_STATIC_BUFS | ||
59 | /* Read an entry from the group-file stream, opening it if necessary. */ | ||
60 | extern struct group *getgrent(void); | ||
61 | |||
62 | /* Read a group entry from STREAM. */ | ||
63 | extern struct group *fgetgrent(FILE *__stream); | ||
64 | |||
65 | /* Write the given entry onto the given stream. */ | ||
66 | extern int putgrent(const struct group *__restrict __p, | ||
67 | FILE *__restrict __f); | ||
68 | #endif | ||
69 | |||
70 | /* Search for an entry with a matching group ID. */ | ||
71 | extern struct group *getgrgid(gid_t __gid); | ||
72 | |||
73 | /* Search for an entry with a matching group name. */ | ||
74 | extern struct group *getgrnam(const char *__name); | ||
75 | |||
76 | /* Reentrant versions of some of the functions above. | ||
77 | |||
78 | PLEASE NOTE: the `getgrent_r' function is not (yet) standardized. | ||
79 | The interface may change in later versions of this library. But | ||
80 | the interface is designed following the principals used for the | ||
81 | other reentrant functions so the chances are good this is what the | ||
82 | POSIX people would choose. */ | ||
83 | |||
84 | extern int getgrent_r(struct group *__restrict __resultbuf, | ||
85 | char *__restrict __buffer, size_t __buflen, | ||
86 | struct group **__restrict __result); | ||
87 | 44 | ||
88 | /* Search for an entry with a matching group ID. */ | 45 | /* Search for an entry with a matching group ID. */ |
89 | extern int getgrgid_r(gid_t __gid, struct group *__restrict __resultbuf, | 46 | struct group* FAST_FUNC getgrgid(gid_t __gid); |
90 | char *__restrict __buffer, size_t __buflen, | ||
91 | struct group **__restrict __result); | ||
92 | 47 | ||
93 | /* Search for an entry with a matching group name. */ | 48 | /* Search for an entry with a matching group name. */ |
94 | extern int getgrnam_r(const char *__restrict __name, | 49 | struct group* FAST_FUNC getgrnam(const char *__name); |
95 | struct group *__restrict __resultbuf, | ||
96 | char *__restrict __buffer, size_t __buflen, | ||
97 | struct group **__restrict __result); | ||
98 | 50 | ||
99 | /* Read a group entry from STREAM. This function is not standardized | 51 | /* Reentrant versions of some of the functions above. */ |
100 | an probably never will. */ | ||
101 | extern int fgetgrent_r(FILE *__restrict __stream, | ||
102 | struct group *__restrict __resultbuf, | ||
103 | char *__restrict __buffer, size_t __buflen, | ||
104 | struct group **__restrict __result); | ||
105 | 52 | ||
106 | /* Store at most *NGROUPS members of the group set for USER into | 53 | /* Store at most *NGROUPS members of the group set for USER into |
107 | *GROUPS. Also include GROUP. The actual number of groups found is | 54 | *GROUPS. Also include GROUP. The actual number of groups found is |
108 | returned in *NGROUPS. Return -1 if the if *NGROUPS is too small. */ | 55 | returned in *NGROUPS. Return -1 if the if *NGROUPS is too small. */ |
109 | extern int getgrouplist(const char *__user, gid_t __group, | 56 | int FAST_FUNC getgrouplist(const char *__user, gid_t __group, |
110 | gid_t *__groups, int *__ngroups); | 57 | gid_t *__groups, int *__ngroups); |
111 | 58 | ||
112 | /* Initialize the group set for the current user | 59 | /* Initialize the group set for the current user |
113 | by reading the group database and using all groups | 60 | by reading the group database and using all groups |
114 | of which USER is a member. Also include GROUP. */ | 61 | of which USER is a member. Also include GROUP. */ |
115 | extern int initgroups(const char *__user, gid_t __group); | 62 | int FAST_FUNC initgroups(const char *__user, gid_t __group); |
116 | 63 | ||
117 | POP_SAVED_FUNCTION_VISIBILITY | 64 | POP_SAVED_FUNCTION_VISIBILITY |
118 | 65 | ||
diff --git a/include/libbb.h b/include/libbb.h index 2850b1d5a..1733e9a0f 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -402,6 +402,7 @@ const char *bb_basename(const char *name) FAST_FUNC; | |||
402 | /* NB: can violate const-ness (similarly to strchr) */ | 402 | /* NB: can violate const-ness (similarly to strchr) */ |
403 | char *last_char_is(const char *s, int c) FAST_FUNC; | 403 | char *last_char_is(const char *s, int c) FAST_FUNC; |
404 | const char* endofname(const char *name) FAST_FUNC; | 404 | const char* endofname(const char *name) FAST_FUNC; |
405 | char *is_prefixed_with(const char *string, const char *key) FAST_FUNC; | ||
405 | 406 | ||
406 | int ndelay_on(int fd) FAST_FUNC; | 407 | int ndelay_on(int fd) FAST_FUNC; |
407 | int ndelay_off(int fd) FAST_FUNC; | 408 | int ndelay_off(int fd) FAST_FUNC; |
@@ -937,9 +938,11 @@ void die_if_bad_username(const char* name) FAST_FUNC; | |||
937 | #if ENABLE_FEATURE_UTMP | 938 | #if ENABLE_FEATURE_UTMP |
938 | void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname); | 939 | void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname); |
939 | void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname); | 940 | void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname); |
941 | void FAST_FUNC update_utmp_DEAD_PROCESS(pid_t pid); | ||
940 | #else | 942 | #else |
941 | # define write_new_utmp(pid, new_type, tty_name, username, hostname) ((void)0) | 943 | # define write_new_utmp(pid, new_type, tty_name, username, hostname) ((void)0) |
942 | # define update_utmp(pid, new_type, tty_name, username, hostname) ((void)0) | 944 | # define update_utmp(pid, new_type, tty_name, username, hostname) ((void)0) |
945 | # define update_utmp_DEAD_PROCESS(pid) ((void)0) | ||
943 | #endif | 946 | #endif |
944 | 947 | ||
945 | 948 | ||
diff --git a/include/platform.h b/include/platform.h index e2b61592e..a550feae6 100644 --- a/include/platform.h +++ b/include/platform.h | |||
@@ -234,6 +234,7 @@ typedef uint64_t bb__aliased_uint64_t FIX_ALIASING; | |||
234 | * a lvalue. This makes it more likely to not swap them by mistake | 234 | * a lvalue. This makes it more likely to not swap them by mistake |
235 | */ | 235 | */ |
236 | #if defined(i386) || defined(__x86_64__) || defined(__powerpc__) | 236 | #if defined(i386) || defined(__x86_64__) || defined(__powerpc__) |
237 | # define BB_UNALIGNED_MEMACCESS_OK 1 | ||
237 | # define move_from_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp)) | 238 | # define move_from_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp)) |
238 | # define move_from_unaligned_long(v, longp) ((v) = *(bb__aliased_long*)(longp)) | 239 | # define move_from_unaligned_long(v, longp) ((v) = *(bb__aliased_long*)(longp)) |
239 | # define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p)) | 240 | # define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p)) |
@@ -242,6 +243,7 @@ typedef uint64_t bb__aliased_uint64_t FIX_ALIASING; | |||
242 | # define move_to_unaligned32(u32p, v) (*(bb__aliased_uint32_t*)(u32p) = (v)) | 243 | # define move_to_unaligned32(u32p, v) (*(bb__aliased_uint32_t*)(u32p) = (v)) |
243 | /* #elif ... - add your favorite arch today! */ | 244 | /* #elif ... - add your favorite arch today! */ |
244 | #else | 245 | #else |
246 | # define BB_UNALIGNED_MEMACCESS_OK 0 | ||
245 | /* performs reasonably well (gcc usually inlines memcpy here) */ | 247 | /* performs reasonably well (gcc usually inlines memcpy here) */ |
246 | # define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int))) | 248 | # define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int))) |
247 | # define move_from_unaligned_long(v, longp) (memcpy(&(v), (longp), sizeof(long))) | 249 | # define move_from_unaligned_long(v, longp) (memcpy(&(v), (longp), sizeof(long))) |
@@ -387,6 +389,7 @@ typedef unsigned smalluint; | |||
387 | #define HAVE_SETBIT 1 | 389 | #define HAVE_SETBIT 1 |
388 | #define HAVE_SIGHANDLER_T 1 | 390 | #define HAVE_SIGHANDLER_T 1 |
389 | #define HAVE_STPCPY 1 | 391 | #define HAVE_STPCPY 1 |
392 | #define HAVE_MEMPCPY 1 | ||
390 | #define HAVE_STRCASESTR 1 | 393 | #define HAVE_STRCASESTR 1 |
391 | #define HAVE_STRCHRNUL 1 | 394 | #define HAVE_STRCHRNUL 1 |
392 | #define HAVE_STRSEP 1 | 395 | #define HAVE_STRSEP 1 |
@@ -486,6 +489,8 @@ typedef unsigned smalluint; | |||
486 | #endif | 489 | #endif |
487 | 490 | ||
488 | #if defined(__FreeBSD__) | 491 | #if defined(__FreeBSD__) |
492 | /* users say mempcpy is not present in FreeBSD 9.x */ | ||
493 | # undef HAVE_MEMPCPY | ||
489 | # undef HAVE_CLEARENV | 494 | # undef HAVE_CLEARENV |
490 | # undef HAVE_FDATASYNC | 495 | # undef HAVE_FDATASYNC |
491 | # undef HAVE_MNTENT_H | 496 | # undef HAVE_MNTENT_H |
@@ -550,6 +555,18 @@ typedef void (*sighandler_t)(int); | |||
550 | extern char *stpcpy(char *p, const char *to_add) FAST_FUNC; | 555 | extern char *stpcpy(char *p, const char *to_add) FAST_FUNC; |
551 | #endif | 556 | #endif |
552 | 557 | ||
558 | #ifndef HAVE_MEMPCPY | ||
559 | #include <string.h> | ||
560 | /* In case we are wrong about !HAVE_MEMPCPY, and toolchain _does_ have | ||
561 | * mempcpy(), avoid colliding with it: | ||
562 | */ | ||
563 | #define mempcpy bb__mempcpy | ||
564 | static ALWAYS_INLINE void *mempcpy(void *dest, const void *src, size_t len) | ||
565 | { | ||
566 | return memcpy(dest, src, len) + len; | ||
567 | } | ||
568 | #endif | ||
569 | |||
553 | #ifndef HAVE_STRCASESTR | 570 | #ifndef HAVE_STRCASESTR |
554 | extern char *strcasestr(const char *s, const char *pattern) FAST_FUNC; | 571 | extern char *strcasestr(const char *s, const char *pattern) FAST_FUNC; |
555 | #endif | 572 | #endif |
diff --git a/include/pwd_.h b/include/pwd_.h index 625b6f5a2..17348298a 100644 --- a/include/pwd_.h +++ b/include/pwd_.h | |||
@@ -34,69 +34,30 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | |||
34 | #define setpwent bb_internal_setpwent | 34 | #define setpwent bb_internal_setpwent |
35 | #define endpwent bb_internal_endpwent | 35 | #define endpwent bb_internal_endpwent |
36 | #define getpwent bb_internal_getpwent | 36 | #define getpwent bb_internal_getpwent |
37 | #define fgetpwent bb_internal_fgetpwent | ||
38 | #define putpwent bb_internal_putpwent | ||
39 | #define getpwuid bb_internal_getpwuid | 37 | #define getpwuid bb_internal_getpwuid |
40 | #define getpwnam bb_internal_getpwnam | 38 | #define getpwnam bb_internal_getpwnam |
41 | #define getpwent_r bb_internal_getpwent_r | ||
42 | #define getpwuid_r bb_internal_getpwuid_r | ||
43 | #define getpwnam_r bb_internal_getpwnam_r | 39 | #define getpwnam_r bb_internal_getpwnam_r |
44 | #define fgetpwent_r bb_internal_fgetpwent_r | ||
45 | |||
46 | 40 | ||
47 | /* All function names below should be remapped by #defines above | 41 | /* All function names below should be remapped by #defines above |
48 | * in order to not collide with libc names. */ | 42 | * in order to not collide with libc names. */ |
49 | 43 | ||
50 | |||
51 | /* Rewind the password-file stream. */ | 44 | /* Rewind the password-file stream. */ |
52 | extern void setpwent(void); | 45 | void FAST_FUNC setpwent(void); |
53 | 46 | ||
54 | /* Close the password-file stream. */ | 47 | /* Close the password-file stream. */ |
55 | extern void endpwent(void); | 48 | void FAST_FUNC endpwent(void); |
56 | 49 | ||
57 | #ifdef UNUSED_SINCE_WE_AVOID_STATIC_BUFS | ||
58 | /* Read an entry from the password-file stream, opening it if necessary. */ | 50 | /* Read an entry from the password-file stream, opening it if necessary. */ |
59 | extern struct passwd *getpwent(void); | 51 | struct passwd* FAST_FUNC getpwent(void); |
60 | |||
61 | /* Read an entry from STREAM. */ | ||
62 | extern struct passwd *fgetpwent(FILE *__stream); | ||
63 | |||
64 | /* Write the given entry onto the given stream. */ | ||
65 | extern int putpwent(const struct passwd *__restrict __p, | ||
66 | FILE *__restrict __f); | ||
67 | #endif | ||
68 | 52 | ||
69 | /* Search for an entry with a matching user ID. */ | 53 | /* Search for an entry with a matching user ID. */ |
70 | extern struct passwd *getpwuid(uid_t __uid); | 54 | struct passwd* FAST_FUNC getpwuid(uid_t __uid); |
71 | 55 | ||
72 | /* Search for an entry with a matching username. */ | 56 | /* Search for an entry with a matching username. */ |
73 | extern struct passwd *getpwnam(const char *__name); | 57 | struct passwd* FAST_FUNC getpwnam(const char *__name); |
74 | |||
75 | /* Reentrant versions of some of the functions above. | ||
76 | |||
77 | PLEASE NOTE: the `getpwent_r' function is not (yet) standardized. | ||
78 | The interface may change in later versions of this library. But | ||
79 | the interface is designed following the principals used for the | ||
80 | other reentrant functions so the chances are good this is what the | ||
81 | POSIX people would choose. */ | ||
82 | |||
83 | extern int getpwent_r(struct passwd *__restrict __resultbuf, | ||
84 | char *__restrict __buffer, size_t __buflen, | ||
85 | struct passwd **__restrict __result); | ||
86 | |||
87 | extern int getpwuid_r(uid_t __uid, | ||
88 | struct passwd *__restrict __resultbuf, | ||
89 | char *__restrict __buffer, size_t __buflen, | ||
90 | struct passwd **__restrict __result); | ||
91 | |||
92 | extern int getpwnam_r(const char *__restrict __name, | ||
93 | struct passwd *__restrict __resultbuf, | ||
94 | char *__restrict __buffer, size_t __buflen, | ||
95 | struct passwd **__restrict __result); | ||
96 | 58 | ||
97 | /* Read an entry from STREAM. This function is not standardized and | 59 | /* Reentrant versions of some of the functions above. */ |
98 | probably never will. */ | 60 | int FAST_FUNC getpwnam_r(const char *__restrict __name, |
99 | extern int fgetpwent_r(FILE *__restrict __stream, | ||
100 | struct passwd *__restrict __resultbuf, | 61 | struct passwd *__restrict __resultbuf, |
101 | char *__restrict __buffer, size_t __buflen, | 62 | char *__restrict __buffer, size_t __buflen, |
102 | struct passwd **__restrict __result); | 63 | struct passwd **__restrict __result); |
diff --git a/include/shadow_.h b/include/shadow_.h index 7babe4f30..8e2581e7c 100644 --- a/include/shadow_.h +++ b/include/shadow_.h | |||
@@ -57,48 +57,48 @@ struct spwd { | |||
57 | 57 | ||
58 | #ifdef UNUSED_FOR_NOW | 58 | #ifdef UNUSED_FOR_NOW |
59 | /* Open database for reading */ | 59 | /* Open database for reading */ |
60 | extern void setspent(void); | 60 | void FAST_FUNC setspent(void); |
61 | 61 | ||
62 | /* Close database */ | 62 | /* Close database */ |
63 | extern void endspent(void); | 63 | void FAST_FUNC endspent(void); |
64 | 64 | ||
65 | /* Get next entry from database, perhaps after opening the file */ | 65 | /* Get next entry from database, perhaps after opening the file */ |
66 | extern struct spwd *getspent(void); | 66 | struct spwd* FAST_FUNC getspent(void); |
67 | 67 | ||
68 | /* Get shadow entry matching NAME */ | 68 | /* Get shadow entry matching NAME */ |
69 | extern struct spwd *getspnam(const char *__name); | 69 | struct spwd* FAST_FUNC getspnam(const char *__name); |
70 | 70 | ||
71 | /* Read shadow entry from STRING */ | 71 | /* Read shadow entry from STRING */ |
72 | extern struct spwd *sgetspent(const char *__string); | 72 | struct spwd* FAST_FUNC sgetspent(const char *__string); |
73 | 73 | ||
74 | /* Read next shadow entry from STREAM */ | 74 | /* Read next shadow entry from STREAM */ |
75 | extern struct spwd *fgetspent(FILE *__stream); | 75 | struct spwd* FAST_FUNC fgetspent(FILE *__stream); |
76 | 76 | ||
77 | /* Write line containing shadow password entry to stream */ | 77 | /* Write line containing shadow password entry to stream */ |
78 | extern int putspent(const struct spwd *__p, FILE *__stream); | 78 | int FAST_FUNC putspent(const struct spwd *__p, FILE *__stream); |
79 | 79 | ||
80 | /* Reentrant versions of some of the functions above */ | 80 | /* Reentrant versions of some of the functions above */ |
81 | extern int getspent_r(struct spwd *__result_buf, char *__buffer, | 81 | int FAST_FUNC getspent_r(struct spwd *__result_buf, char *__buffer, |
82 | size_t __buflen, struct spwd **__result); | 82 | size_t __buflen, struct spwd **__result); |
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | extern int getspnam_r(const char *__name, struct spwd *__result_buf, | 85 | int FAST_FUNC getspnam_r(const char *__name, struct spwd *__result_buf, |
86 | char *__buffer, size_t __buflen, | 86 | char *__buffer, size_t __buflen, |
87 | struct spwd **__result); | 87 | struct spwd **__result); |
88 | 88 | ||
89 | #ifdef UNUSED_FOR_NOW | 89 | #ifdef UNUSED_FOR_NOW |
90 | extern int sgetspent_r(const char *__string, struct spwd *__result_buf, | 90 | int FAST_FUNC sgetspent_r(const char *__string, struct spwd *__result_buf, |
91 | char *__buffer, size_t __buflen, | 91 | char *__buffer, size_t __buflen, |
92 | struct spwd **__result); | 92 | struct spwd **__result); |
93 | 93 | ||
94 | extern int fgetspent_r(FILE *__stream, struct spwd *__result_buf, | 94 | int FAST_FUNC fgetspent_r(FILE *__stream, struct spwd *__result_buf, |
95 | char *__buffer, size_t __buflen, | 95 | char *__buffer, size_t __buflen, |
96 | struct spwd **__result); | 96 | struct spwd **__result); |
97 | /* Protect password file against multi writers */ | 97 | /* Protect password file against multi writers */ |
98 | extern int lckpwdf(void); | 98 | int FAST_FUNC lckpwdf(void); |
99 | 99 | ||
100 | /* Unlock password file */ | 100 | /* Unlock password file */ |
101 | extern int ulckpwdf(void); | 101 | int FAST_FUNC ulckpwdf(void); |
102 | #endif | 102 | #endif |
103 | 103 | ||
104 | POP_SAVED_FUNCTION_VISIBILITY | 104 | POP_SAVED_FUNCTION_VISIBILITY |