X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=include%2Flibbb.h;h=5f25b5ddeb02222e68636514bd7ef55a650a514d;hb=cbdc37cae079d6b52ca39fb6c1dd6eadab48b617;hp=f04f555c0d86cb780e4801ff8d9fd53c0f1dffe4;hpb=0f296a3a56b52842057e5a2bc653621a3a6c7bec;p=oweals%2Fbusybox.git diff --git a/include/libbb.h b/include/libbb.h index f04f555c0..5f25b5dde 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -20,6 +20,7 @@ #include #include #include +#include #if defined __UCLIBC__ /* TODO: and glibc? */ /* use inlined versions of these: */ # define sigfillset(s) __sigfillset(s) @@ -44,7 +45,7 @@ #include #include #include -#ifndef major +#if !defined(major) || defined(__GLIBC__) # include #endif #include @@ -80,8 +81,6 @@ #if ENABLE_SELINUX # include # include -# include -# include #endif #if ENABLE_FEATURE_UTMP # if defined __UCLIBC__ && ( \ @@ -106,7 +105,11 @@ # define updwtmpx updwtmp # define _PATH_UTMPX _PATH_UTMP # else +# include # include +# if defined _PATH_UTMP && !defined _PATH_UTMPX +# define _PATH_UTMPX _PATH_UTMP +# endif # endif #endif #if ENABLE_LOCALE_SUPPORT @@ -137,14 +140,18 @@ # include #else # include -# if !defined(__socklen_t_defined) && !defined(_SOCKLEN_T_DECLARED) -/* We #define socklen_t *after* includes, otherwise we get - * typedef redefinition errors from system headers - * (in case "is it defined already" detection above failed) - */ -# define socklen_t bb_socklen_t - typedef unsigned socklen_t; -# endif +//This breaks on bionic: +//# if !defined(__socklen_t_defined) && !defined(_SOCKLEN_T_DECLARED) +///* We #define socklen_t *after* includes, otherwise we get +// * typedef redefinition errors from system headers +// * (in case "is it defined already" detection above failed) +// */ +//# define socklen_t bb_socklen_t +// typedef unsigned socklen_t; +//# endif +//if this is still needed, add a fix along the lines of +// ifdef SPECIFIC_BROKEN_LIBC_CHECK / typedef socklen_t / endif +//in platform.h instead! #endif #ifndef HAVE_CLEARENV # define clearenv() do { if (environ) environ[0] = NULL; } while (0) @@ -155,14 +162,22 @@ #ifndef HAVE_XTABS # define XTABS TAB3 #endif +/* + * Use '%m' to append error string on platforms that support it, + * '%s' and strerror() on those that don't. + */ +#ifdef HAVE_PRINTF_PERCENTM +# define STRERROR_FMT "%m" +# define STRERROR_ERRNO /*nothing*/ +#else +# define STRERROR_FMT "%s" +# define STRERROR_ERRNO ,strerror(errno) +#endif /* Some libc's forget to declare these, do it ourself */ extern char **environ; -#if defined(__GLIBC__) && __GLIBC__ < 2 -int vdprintf(int d, const char *format, va_list ap); -#endif /* klogctl is in libc's klog.h, but we cheat and not #include that */ int klogctl(int type, char *b, int len); #ifndef PATH_MAX @@ -176,24 +191,33 @@ int klogctl(int type, char *b, int len); /* Busybox does not use threads, we can speed up stdio. */ #ifdef HAVE_UNLOCKED_STDIO # undef getc -# define getc(stream) getc_unlocked(stream) +# define getc(stream) getc_unlocked(stream) # undef getchar -# define getchar() getchar_unlocked() +# define getchar() getchar_unlocked() # undef putc -# define putc(c, stream) putc_unlocked(c, stream) +# define putc(c,stream) putc_unlocked(c,stream) # undef putchar -# define putchar(c) putchar_unlocked(c) +# define putchar(c) putchar_unlocked(c) # undef fgetc -# define fgetc(stream) getc_unlocked(stream) +# define fgetc(stream) getc_unlocked(stream) # undef fputc -# define fputc(c, stream) putc_unlocked(c, stream) +# define fputc(c,stream) putc_unlocked(c,stream) #endif /* Above functions are required by POSIX.1-2008, below ones are extensions */ #ifdef HAVE_UNLOCKED_LINE_OPS # undef fgets -# define fgets(s, n, stream) fgets_unlocked(s, n, stream) +# define fgets(s,n,stream) fgets_unlocked(s,n,stream) # undef fputs -# define fputs(s, stream) fputs_unlocked(s, stream) +# define fputs(s,stream) fputs_unlocked(s,stream) +/* musl <= 1.1.15 does not support fflush_unlocked(NULL) */ +//# undef fflush +//# define fflush(stream) fflush_unlocked(stream) +# undef feof +# define feof(stream) feof_unlocked(stream) +# undef ferror +# define ferror(stream) ferror_unlocked(stream) +# undef fileno +# define fileno(stream) fileno_unlocked(stream) #endif @@ -326,23 +350,46 @@ extern int *const bb_errno; uint64_t bb_bswap_64(uint64_t x) FAST_FUNC; #endif +unsigned long FAST_FUNC isqrt(unsigned long long N); + unsigned long long monotonic_ns(void) FAST_FUNC; unsigned long long monotonic_us(void) FAST_FUNC; unsigned long long monotonic_ms(void) FAST_FUNC; unsigned monotonic_sec(void) FAST_FUNC; extern void chomp(char *s) FAST_FUNC; -extern void trim(char *s) FAST_FUNC; +extern char *trim(char *s) FAST_FUNC; extern char *skip_whitespace(const char *) FAST_FUNC; extern char *skip_non_whitespace(const char *) FAST_FUNC; extern char *skip_dev_pfx(const char *tty_name) FAST_FUNC; extern char *strrstr(const char *haystack, const char *needle) FAST_FUNC; +/* dmalloc will redefine these to it's own implementation. It is safe + * to have the prototypes here unconditionally. */ +void *malloc_or_warn(size_t size) FAST_FUNC RETURNS_MALLOC; +void *xmalloc(size_t size) FAST_FUNC RETURNS_MALLOC; +void *xzalloc(size_t size) FAST_FUNC RETURNS_MALLOC; +void *xrealloc(void *old, size_t size) FAST_FUNC; +/* After v = xrealloc_vector(v, SHIFT, idx) it's ok to use + * at least v[idx] and v[idx+1], for all idx values. + * SHIFT specifies how many new elements are added (1:2, 2:4, ..., 8:256...) + * when all elements are used up. New elements are zeroed out. + * xrealloc_vector(v, SHIFT, idx) *MUST* be called with consecutive IDXs - + * skipping an index is a bad bug - it may miss a realloc! + */ +#define xrealloc_vector(vector, shift, idx) \ + xrealloc_vector_helper((vector), (sizeof((vector)[0]) << 8) + (shift), (idx)) +void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) FAST_FUNC; +char *xstrdup(const char *s) FAST_FUNC RETURNS_MALLOC; +char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC; +void *xmemdup(const void *s, int n) FAST_FUNC RETURNS_MALLOC; + + //TODO: supply a pointer to char[11] buffer (avoid statics)? extern const char *bb_mode_string(mode_t mode) FAST_FUNC; extern int is_directory(const char *name, int followLinks) FAST_FUNC; -enum { /* DO NOT CHANGE THESE VALUES! cp.c, mv.c, install.c depend on them. */ +enum { /* cp.c, mv.c, install.c depend on these values. CAREFUL when changing them! */ FILEUTILS_PRESERVE_STATUS = 1 << 0, /* -p */ FILEUTILS_DEREFERENCE = 1 << 1, /* !-d */ FILEUTILS_RECUR = 1 << 2, /* -R */ @@ -352,15 +399,25 @@ enum { /* DO NOT CHANGE THESE VALUES! cp.c, mv.c, install.c depend on them. */ FILEUTILS_MAKE_SOFTLINK = 1 << 6, /* -s */ FILEUTILS_DEREF_SOFTLINK = 1 << 7, /* -L */ FILEUTILS_DEREFERENCE_L0 = 1 << 8, /* -H */ + /* -a = -pdR (mapped in cp.c) */ + /* -r = -dR (mapped in cp.c) */ + /* -P = -d (mapped in cp.c) */ + FILEUTILS_VERBOSE = (1 << 12) * ENABLE_FEATURE_VERBOSE, /* -v */ + FILEUTILS_UPDATE = 1 << 13, /* -u */ +#if ENABLE_SELINUX + FILEUTILS_PRESERVE_SECURITY_CONTEXT = 1 << 14, /* -c */ +#endif + FILEUTILS_RMDEST = 1 << (15 - !ENABLE_SELINUX), /* --remove-destination */ + /* + * Hole. cp may have some bits set here, + * they should not affect remove_file()/copy_file() + */ #if ENABLE_SELINUX - FILEUTILS_PRESERVE_SECURITY_CONTEXT = 1 << 9, /* -c */ - FILEUTILS_SET_SECURITY_CONTEXT = 1 << 10, + FILEUTILS_SET_SECURITY_CONTEXT = 1 << 30, #endif - FILEUTILS_IGNORE_CHMOD_ERR = 1 << 11, - /* -v */ - FILEUTILS_VERBOSE = (1 << 12) * ENABLE_FEATURE_VERBOSE, + FILEUTILS_IGNORE_CHMOD_ERR = 1 << 31, }; -#define FILEUTILS_CP_OPTSTR "pdRfilsLH" IF_SELINUX("c") +#define FILEUTILS_CP_OPTSTR "pdRfilsLHarPvu" IF_SELINUX("c") extern int remove_file(const char *path, int flags) FAST_FUNC; /* NB: without FILEUTILS_RECUR in flags, it will basically "cat" * the source, not copy (unless "source" is a directory). @@ -491,6 +548,7 @@ void xsetuid(uid_t uid) FAST_FUNC; void xsetegid(gid_t egid) FAST_FUNC; void xseteuid(uid_t euid) FAST_FUNC; void xchdir(const char *path) FAST_FUNC; +void xfchdir(int fd) FAST_FUNC; void xchroot(const char *path) FAST_FUNC; void xsetenv(const char *key, const char *value) FAST_FUNC; void bb_unsetenv(const char *key) FAST_FUNC; @@ -666,6 +724,56 @@ struct hostent *xgethostbyname(const char *name) FAST_FUNC; // + inet_common.c has additional IPv4-only stuff +#define TLS_MAX_MAC_SIZE 32 +#define TLS_MAX_KEY_SIZE 32 +struct tls_handshake_data; /* opaque */ +typedef struct tls_state { + int ofd; + int ifd; + + unsigned min_encrypted_len_on_read; + uint16_t cipher_id; + uint8_t encrypt_on_write; + unsigned MAC_size; + unsigned key_size; + + uint8_t *outbuf; + int outbuf_size; + + int inbuf_size; + int ofs_to_buffered; + int buffered_size; + uint8_t *inbuf; + + struct tls_handshake_data *hsd; + + // RFC 5246 + // sequence number + // Each connection state contains a sequence number, which is + // maintained separately for read and write states. The sequence + // number MUST be set to zero whenever a connection state is made the + // active state. Sequence numbers are of type uint64 and may not + // exceed 2^64-1. + /*uint64_t read_seq64_be;*/ + uint64_t write_seq64_be; + + uint8_t *client_write_key; + uint8_t *server_write_key; + uint8_t client_write_MAC_key[TLS_MAX_MAC_SIZE]; + uint8_t server_write_MAC_k__[TLS_MAX_MAC_SIZE]; + uint8_t client_write_k__[TLS_MAX_KEY_SIZE]; + uint8_t server_write_k__[TLS_MAX_KEY_SIZE]; +} tls_state_t; + +static inline tls_state_t *new_tls_state(void) +{ + tls_state_t *tls = xzalloc(sizeof(*tls)); + return tls; +} +void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC; +void tls_run_copy_loop(tls_state_t *tls) FAST_FUNC; + + void socket_want_pktinfo(int fd) FAST_FUNC; ssize_t send_to_from(int fd, void *buf, size_t len, int flags, const struct sockaddr *to, @@ -678,9 +786,8 @@ ssize_t recv_from_to(int fd, void *buf, size_t len, int flags, uint16_t inet_cksum(uint16_t *addr, int len) FAST_FUNC; -char *xstrdup(const char *s) FAST_FUNC RETURNS_MALLOC; -char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC; -void *xmemdup(const void *s, int n) FAST_FUNC RETURNS_MALLOC; +/* 0 if argv[0] is NULL: */ +unsigned string_array_len(char **argv) FAST_FUNC; void overlapping_strcpy(char *dst, const char *src) FAST_FUNC; char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC; char *strncpy_IFNAMSIZ(char *dst, const char *src) FAST_FUNC; @@ -726,24 +833,6 @@ enum { }; void visible(unsigned ch, char *buf, int flags) FAST_FUNC; -/* dmalloc will redefine these to it's own implementation. It is safe - * to have the prototypes here unconditionally. */ -void *malloc_or_warn(size_t size) FAST_FUNC RETURNS_MALLOC; -void *xmalloc(size_t size) FAST_FUNC RETURNS_MALLOC; -void *xzalloc(size_t size) FAST_FUNC RETURNS_MALLOC; -void *xrealloc(void *old, size_t size) FAST_FUNC; -/* After v = xrealloc_vector(v, SHIFT, idx) it's ok to use - * at least v[idx] and v[idx+1], for all idx values. - * SHIFT specifies how many new elements are added (1:2, 2:4, ..., 8:256...) - * when all elements are used up. New elements are zeroed out. - * xrealloc_vector(v, SHIFT, idx) *MUST* be called with consecutive IDXs - - * skipping an index is a bad bug - it may miss a realloc! - */ -#define xrealloc_vector(vector, shift, idx) \ - xrealloc_vector_helper((vector), (sizeof((vector)[0]) << 8) + (shift), (idx)) -void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) FAST_FUNC; - - extern ssize_t safe_read(int fd, void *buf, size_t count) FAST_FUNC; extern ssize_t nonblock_immune_read(int fd, void *buf, size_t count) FAST_FUNC; // NB: will return short read on error, not -1, @@ -785,7 +874,7 @@ unsigned bb_clk_tck(void) FAST_FUNC; #if SEAMLESS_COMPRESSION /* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ -extern int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC; +int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC; /* Autodetects .gz etc */ extern int open_zipped(const char *fname, int fail_if_not_compressed) FAST_FUNC; extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; @@ -794,6 +883,8 @@ extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) # define open_zipped(fname, fail_if_not_compressed) open((fname), O_RDONLY); # define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p)) #endif +/* lzma has no signature, need a little helper. NB: exist only for ENABLE_FEATURE_SEAMLESS_LZMA=y */ +void setup_lzma_on_fd(int fd) FAST_FUNC; extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC; // NB: will return short write on error, not -1, @@ -896,6 +987,7 @@ extern const struct suffix_mult bkm_suffixes[]; #define km_suffixes (bkm_suffixes + 1) extern const struct suffix_mult cwbkMG_suffixes[]; #define kMG_suffixes (cwbkMG_suffixes + 3) +extern const struct suffix_mult kmg_i_suffixes[]; #include "xatonum.h" /* Specialized: */ @@ -920,14 +1012,13 @@ long xuname2uid(const char *name) FAST_FUNC; long xgroup2gid(const char *name) FAST_FUNC; /* wrapper: allows string to contain numeric uid or gid */ unsigned long get_ug_id(const char *s, long FAST_FUNC (*xname2id)(const char *)) FAST_FUNC; -/* from chpst. Does not die, returns 0 on failure */ struct bb_uidgid_t { uid_t uid; gid_t gid; }; -/* always sets uid and gid */ -int get_uidgid(struct bb_uidgid_t*, const char*, int numeric_ok) FAST_FUNC; -/* always sets uid and gid, allows numeric; exits on failure */ +/* always sets uid and gid; returns 0 on failure */ +int get_uidgid(struct bb_uidgid_t*, const char*) FAST_FUNC; +/* always sets uid and gid; exits on failure */ void xget_uidgid(struct bb_uidgid_t*, const char*) FAST_FUNC; /* chown-like handling of "user[:[group]" */ void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group) FAST_FUNC; @@ -952,6 +1043,15 @@ void die_if_bad_username(const char* name) FAST_FUNC; #else #define die_if_bad_username(name) ((void)(name)) #endif +/* + * Returns (-1) terminated malloced result of getgroups(). + * Reallocs group_array (useful for repeated calls). + * ngroups is an initial size of array. It is rounded up to 32 for realloc. + * ngroups is updated on return. + * ngroups can be NULL: bb_getgroups(NULL, NULL) is valid usage. + * Dies on errors (on Linux, only xrealloc can cause this, not internal getgroups call). + */ +gid_t *bb_getgroups(int *ngroups, gid_t *group_array) FAST_FUNC; #if ENABLE_FEATURE_UTMP void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname); @@ -983,9 +1083,10 @@ int BB_EXECVP(const char *file, char *const argv[]) FAST_FUNC; #define BB_EXECVP(prog,cmd) execvp(prog,cmd) #define BB_EXECLP(prog,cmd,...) execlp(prog,cmd,__VA_ARGS__) #endif -int BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC; +void BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC; +void exec_prog_or_SHELL(char **argv) NORETURN FAST_FUNC; -/* xvfork() can't be a _function_, return after vfork mangles stack +/* xvfork() can't be a _function_, return after vfork in child mangles stack * in the parent. It must be a macro. */ #define xvfork() \ ({ \ @@ -997,6 +1098,7 @@ int BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC; #if BB_MMU pid_t xfork(void) FAST_FUNC; #endif +void xvfork_parent_waits_and_exits(void) FAST_FUNC; /* NOMMU friendy fork+exec: */ pid_t spawn(char **argv) FAST_FUNC; @@ -1013,10 +1115,26 @@ pid_t wait_any_nohang(int *wstat) FAST_FUNC; * if (rc > 0) bb_error_msg("exit code: %d", rc & 0xff); */ int wait4pid(pid_t pid) FAST_FUNC; +int wait_for_exitstatus(pid_t pid) FAST_FUNC; +/************************************************************************/ +/* spawn_and_wait/run_nofork_applet/run_applet_no_and_exit need to work */ +/* carefully together to reinit some global state while not disturbing */ +/* other. Be careful if you change them. Consult docs/nofork_noexec.txt */ +/************************************************************************/ /* Same as wait4pid(spawn(argv)), but with NOFORK/NOEXEC if configured: */ int spawn_and_wait(char **argv) FAST_FUNC; /* Does NOT check that applet is NOFORK, just blindly runs it */ int run_nofork_applet(int applet_no, char **argv) FAST_FUNC; +void run_noexec_applet_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC; +#ifndef BUILD_INDIVIDUAL +int find_applet_by_name(const char *name) FAST_FUNC; +void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC; +#endif +#if defined(__linux__) +void set_task_comm(const char *comm) FAST_FUNC; +#else +# define set_task_comm(name) ((void)0) +#endif /* Helpers for daemonization. * @@ -1070,21 +1188,46 @@ enum { #endif void bb_daemonize_or_rexec(int flags, char **argv) FAST_FUNC; void bb_sanitize_stdio(void) FAST_FUNC; +#define bb_daemon_helper(arg) bb_daemonize_or_rexec((arg) | DAEMON_ONLY_SANITIZE, NULL) /* Clear dangerous stuff, set PATH. Return 1 if was run by different user. */ int sanitize_env_if_suid(void) FAST_FUNC; +/* For top, ps. Some argv[i] are replaced by malloced "-opt" strings */ +void make_all_argv_opts(char **argv) FAST_FUNC; char* single_argv(char **argv) FAST_FUNC; -extern const char *const bb_argv_dash[]; /* "-", NULL */ -extern const char *opt_complementary; -#if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG -#define No_argument "\0" -#define Required_argument "\001" -#define Optional_argument "\002" -extern const char *applet_long_options; -#endif +extern const char *const bb_argv_dash[]; /* { "-", NULL } */ extern uint32_t option_mask32; -extern uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC; +uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC; +# define No_argument "\0" +# define Required_argument "\001" +# define Optional_argument "\002" +#if ENABLE_LONG_OPTS +uint32_t getopt32long(char **argv, const char *optstring, const char *longopts, ...) FAST_FUNC; +#else +#define getopt32long(argv,optstring,longopts,...) \ + getopt32(argv,optstring,##__VA_ARGS__) +#endif +/* BSD-derived getopt() functions require that optind be set to 1 in + * order to reset getopt() state. This used to be generally accepted + * way of resetting getopt(). However, glibc's getopt() + * has additional getopt() state beyond optind (specifically, glibc + * extensions such as '+' and '-' at the start of the string), and requires + * that optind be set to zero to reset its state. BSD-derived versions + * of getopt() misbehaved if optind is set to 0 in order to reset getopt(), + * and glibc's getopt() used to coredump if optind is set 1 in order + * to reset getopt(). + * Then BSD introduced additional variable "optreset" which should be + * set to 1 in order to reset getopt(). Sigh. Standards, anyone? + * + * By ~2008, OpenBSD 3.4 was changed to survive glibc-like optind = 0 + * (to interpret it as if optreset was set). + */ +#if 1 /*def __GLIBC__*/ +#define GETOPT_RESET() (optind = 0) +#else /* BSD style */ +#define GETOPT_RESET() (optind = 1) +#endif /* Having next pointer as a first member allows easy creation @@ -1142,7 +1285,6 @@ extern void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, extern void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC; extern void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC; extern void bb_perror_nomsg(void) FAST_FUNC; -extern void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; extern void bb_verror_msg(const char *s, va_list p, const char *strerr) FAST_FUNC; extern void bb_logenv_override(void) FAST_FUNC; @@ -1157,12 +1299,20 @@ extern void bb_logenv_override(void) FAST_FUNC; /* Applets which are useful from another applets */ -int bb_cat(char** argv); +int bb_cat(char** argv) FAST_FUNC; /* If shell needs them, they exist even if not enabled as applets */ int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE); int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE); -int test_main(int argc, char **argv) IF_TEST(MAIN_EXTERNALLY_VISIBLE); -int kill_main(int argc, char **argv) IF_KILL(MAIN_EXTERNALLY_VISIBLE); +int test_main(int argc, char **argv) +#if ENABLE_TEST || ENABLE_TEST1 || ENABLE_TEST2 + MAIN_EXTERNALLY_VISIBLE +#endif +; +int kill_main(int argc, char **argv) +#if ENABLE_KILL || ENABLE_KILLALL || ENABLE_KILLALL5 + MAIN_EXTERNALLY_VISIBLE +#endif +; /* Similar, but used by chgrp, not shell */ int chown_main(int argc, char **argv) IF_CHOWN(MAIN_EXTERNALLY_VISIBLE); /* Used by ftpd */ @@ -1175,6 +1325,16 @@ int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; void bb_displayroutes(int noresolve, int netstatfmt) FAST_FUNC; #endif +struct number_state { + unsigned width; + unsigned start; + unsigned inc; + const char *sep; + const char *empty_str; + smallint all, nonempty; +}; +void print_numbered_lines(struct number_state *ns, const char *filename) FAST_FUNC; + /* Networking */ /* This structure defines protocol families and their handlers. */ @@ -1216,15 +1376,8 @@ const struct hwtype *get_hwtype(const char *name) FAST_FUNC; const struct hwtype *get_hwntype(int type) FAST_FUNC; -#ifndef BUILD_INDIVIDUAL -extern int find_applet_by_name(const char *name) FAST_FUNC; -/* Returns only if applet is not found. */ -extern void run_applet_and_exit(const char *name, char **argv) FAST_FUNC; -extern void run_applet_no_and_exit(int a, char **argv) NORETURN FAST_FUNC; -#endif - +extern int fstype_matches(const char *fstype, const char *comma_list) FAST_FUNC; #ifdef HAVE_MNTENT_H -extern int match_fstype(const struct mntent *mt, const char *fstypes) FAST_FUNC; extern struct mntent *find_mount_point(const char *name, int subdir_too) FAST_FUNC; #endif extern void erase_mtab(const char * name) FAST_FUNC; @@ -1240,10 +1393,15 @@ extern int get_linux_version_code(void) FAST_FUNC; extern char *query_loop(const char *device) FAST_FUNC; extern int del_loop(const char *device) FAST_FUNC; -/* If *devname is not NULL, use that name, otherwise try to find free one, +/* + * If *devname is not NULL, use that name, otherwise try to find free one, * malloc and return it in *devname. - * return value: 1: read-only loopdev was setup, 0: rw, < 0: error */ -extern int set_loop(char **devname, const char *file, unsigned long long offset, int ro) FAST_FUNC; + * return value is the opened fd to the loop device, or < on error + */ +extern int set_loop(char **devname, const char *file, unsigned long long offset, unsigned flags) FAST_FUNC; +/* These constants match linux/loop.h (without BB_ prefix): */ +#define BB_LO_FLAGS_READ_ONLY 1 +#define BB_LO_FLAGS_AUTOCLEAR 4 /* Like bb_ask below, but asks on stdin with no timeout. */ char *bb_ask_stdin(const char * prompt) FAST_FUNC; @@ -1266,6 +1424,11 @@ enum { // keep a copy of current line PARSE_KEEP_COPY = 0x00200000 * ENABLE_FEATURE_CROND_D, PARSE_EOL_COMMENTS = 0x00400000, // comments are recognized even if they aren't the first char + PARSE_ALT_COMMENTS = 0x00800000, // delim[0] and delim[1] are two different allowed comment chars + // (so far, delim[0] will only work as comment char for full-line comment) + // (IOW: it works as if PARSE_EOL_COMMENTS is not set. sysctl applet is okay with this) + PARSE_WS_COMMENTS = 0x01000000, // comments are recognized even if there is whitespace before + // ("line start>#comment" is also comment, not only "line start>#comment") // NORMAL is: // * remove leading and trailing delimiters and collapse // multiple delimiters into one @@ -1313,7 +1476,7 @@ char *bb_simplify_abs_path_inplace(char *path) FAST_FUNC; #endif extern void bb_do_delay(int seconds) FAST_FUNC; extern void change_identity(const struct passwd *pw) FAST_FUNC; -extern void run_shell(const char *shell, int loginshell, const char *command, const char **additional_args) NORETURN FAST_FUNC; +extern void run_shell(const char *shell, int loginshell, const char **args) NORETURN FAST_FUNC; /* Returns $SHELL, getpwuid(getuid())->pw_shell, or DEFAULT_SHELL. * Note that getpwuid result might need xstrdup'ing @@ -1321,6 +1484,21 @@ extern void run_shell(const char *shell, int loginshell, const char *command, co */ const char *get_shell_name(void) FAST_FUNC; +unsigned cap_name_to_number(const char *cap) FAST_FUNC; +void printf_cap(const char *pfx, unsigned cap_no) FAST_FUNC; +void drop_capability(int cap_ordinal) FAST_FUNC; +/* Structures inside "struct caps" are Linux-specific and libcap-specific: */ +#define DEFINE_STRUCT_CAPS \ +struct caps { \ + struct __user_cap_header_struct header; \ + unsigned u32s; \ + struct __user_cap_data_struct data[2]; \ +} +void getcaps(void *caps) FAST_FUNC; + +unsigned cap_name_to_number(const char *name) FAST_FUNC; +void printf_cap(const char *pfx, unsigned cap_no) FAST_FUNC; + #if ENABLE_SELINUX extern void renew_current_security_context(void) FAST_FUNC; extern void set_current_security_context(security_context_t sid) FAST_FUNC; @@ -1334,11 +1512,6 @@ extern void selinux_preserve_fcontext(int fdesc) FAST_FUNC; extern void selinux_or_die(void) FAST_FUNC; -/* systemd support */ -#define SD_LISTEN_FDS_START 3 -int sd_listen_fds(void); - - /* setup_environment: * if chdir pw->pw_dir: ok: else if to_tmp == 1: goto /tmp else: goto / or die * if clear_env = 1: cd(pw->pw_dir), clear environment, then set @@ -1353,6 +1526,9 @@ int sd_listen_fds(void); * HOME=pw->pw_dir * SHELL=shell * else does nothing + * + * NB: CHANGEENV and CLEARENV use setenv() - this leaks memory! + * If setup_environment() is used is vforked child, this leaks memory _in parent too_! */ #define SETUP_ENV_CHANGEENV (1 << 0) #define SETUP_ENV_CLEARENV (1 << 1) @@ -1360,6 +1536,12 @@ int sd_listen_fds(void); #define SETUP_ENV_NO_CHDIR (1 << 4) void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC; void nuke_str(char *str) FAST_FUNC; +#if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM +int is_tty_secure(const char *short_tty) FAST_FUNC; +#else +static ALWAYS_INLINE int is_tty_secure(const char *short_tty UNUSED_PARAM) { return 1; } +#endif +#define CHECKPASS_PW_HAS_EMPTY_PASSWORD 2 int check_password(const struct passwd *pw, const char *plaintext) FAST_FUNC; int ask_and_check_password_extended(const struct passwd *pw, int timeout, const char *prompt) FAST_FUNC; int ask_and_check_password(const struct passwd *pw) FAST_FUNC; @@ -1405,8 +1587,14 @@ extern void print_login_prompt(void) FAST_FUNC; char *xmalloc_ttyname(int fd) FAST_FUNC RETURNS_MALLOC; /* NB: typically you want to pass fd 0, not 1. Think 'applet | grep something' */ int get_terminal_width_height(int fd, unsigned *width, unsigned *height) FAST_FUNC; +int get_terminal_width(int fd) FAST_FUNC; int tcsetattr_stdin_TCSANOW(const struct termios *tp) FAST_FUNC; +#define TERMIOS_CLEAR_ISIG (1 << 0) +#define TERMIOS_RAW_CRNL (1 << 1) +#define TERMIOS_RAW_INPUT (1 << 2) +int get_termios_and_make_raw(int fd, struct termios *newterm, struct termios *oldterm, int flags) FAST_FUNC; +int set_termios_to_raw(int fd, struct termios *oldterm, int flags) FAST_FUNC; /* NB: "unsigned request" is crucial! "int request" will break some arches! */ int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC; @@ -1439,46 +1627,46 @@ unsigned long long bb_makedev(unsigned major, unsigned minor) FAST_FUNC; * yet doesn't represent any valid Unicode character. * Also, -1 is reserved for error indication and we don't use it. */ enum { - KEYCODE_UP = -2, - KEYCODE_DOWN = -3, - KEYCODE_RIGHT = -4, - KEYCODE_LEFT = -5, - KEYCODE_HOME = -6, - KEYCODE_END = -7, - KEYCODE_INSERT = -8, - KEYCODE_DELETE = -9, - KEYCODE_PAGEUP = -10, - KEYCODE_PAGEDOWN = -11, - // -12 is reserved for Alt/Ctrl/Shift-TAB + KEYCODE_UP = -2, + KEYCODE_DOWN = -3, + KEYCODE_RIGHT = -4, + KEYCODE_LEFT = -5, + KEYCODE_HOME = -6, + KEYCODE_END = -7, + KEYCODE_INSERT = -8, + KEYCODE_DELETE = -9, + KEYCODE_PAGEUP = -10, + KEYCODE_PAGEDOWN = -11, + KEYCODE_BACKSPACE = -12, /* Used only if Alt/Ctrl/Shifted */ + KEYCODE_D = -13, /* Used only if Alted */ #if 0 - KEYCODE_FUN1 = -13, - KEYCODE_FUN2 = -14, - KEYCODE_FUN3 = -15, - KEYCODE_FUN4 = -16, - KEYCODE_FUN5 = -17, - KEYCODE_FUN6 = -18, - KEYCODE_FUN7 = -19, - KEYCODE_FUN8 = -20, - KEYCODE_FUN9 = -21, - KEYCODE_FUN10 = -22, - KEYCODE_FUN11 = -23, - KEYCODE_FUN12 = -24, -#endif - /* Be sure that last defined value is small enough - * to not interfere with Alt/Ctrl/Shift bits. - * So far we do not exceed -31 (0xfff..fffe1), - * which gives us three upper bits in LSB to play with. + KEYCODE_FUN1 = , + KEYCODE_FUN2 = , + KEYCODE_FUN3 = , + KEYCODE_FUN4 = , + KEYCODE_FUN5 = , + KEYCODE_FUN6 = , + KEYCODE_FUN7 = , + KEYCODE_FUN8 = , + KEYCODE_FUN9 = , + KEYCODE_FUN10 = , + KEYCODE_FUN11 = , + KEYCODE_FUN12 = , +#endif + /* ^^^^^ Be sure that last defined value is small enough. + * Current read_key() code allows going up to -32 (0xfff..fffe0). + * This gives three upper bits in LSB to play with: + * KEYCODE_foo values are 0xfff..fffXX, lowest XX bits are: scavvvvv, + * s=0 if SHIFT, c=0 if CTRL, a=0 if ALT, + * vvvvv bits are the same for same key regardless of "shift bits". */ - //KEYCODE_SHIFT_TAB = (-12) & ~0x80, - //KEYCODE_SHIFT_... = KEYCODE_... & ~0x80, - //KEYCODE_CTRL_UP = KEYCODE_UP & ~0x40, - //KEYCODE_CTRL_DOWN = KEYCODE_DOWN & ~0x40, - KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40, - KEYCODE_CTRL_LEFT = KEYCODE_LEFT & ~0x40, - //KEYCODE_ALT_UP = KEYCODE_UP & ~0x20, - //KEYCODE_ALT_DOWN = KEYCODE_DOWN & ~0x20, - KEYCODE_ALT_RIGHT = KEYCODE_RIGHT & ~0x20, - KEYCODE_ALT_LEFT = KEYCODE_LEFT & ~0x20, + //KEYCODE_SHIFT_... = KEYCODE_... & ~0x80, + KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40, + KEYCODE_CTRL_LEFT = KEYCODE_LEFT & ~0x40, + KEYCODE_ALT_RIGHT = KEYCODE_RIGHT & ~0x20, + KEYCODE_ALT_LEFT = KEYCODE_LEFT & ~0x20, + KEYCODE_ALT_BACKSPACE = KEYCODE_BACKSPACE & ~0x20, + KEYCODE_ALT_D = KEYCODE_D & ~0x20, KEYCODE_CURSOR_POS = -0x100, /* 0xfff..fff00 */ /* How long is the longest ESC sequence we know? @@ -1496,9 +1684,9 @@ enum { * buffer[0] is used as a counter of buffered chars and must be 0 * on first call. * timeout: - * -2: do not poll for input; - * -1: poll(-1) (i.e. block); - * >=0: poll for TIMEOUT milliseconds, return -1/EAGAIN on timeout + * -2: do not poll(-1) for input - read() it, return on EAGAIN at once + * -1: poll(-1) (i.e. block even on NONBLOCKed fd) + * >=0: poll() for TIMEOUT milliseconds, return -1/EAGAIN on timeout */ int64_t read_key(int fd, char *buffer, int timeout) FAST_FUNC; void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC; @@ -1514,6 +1702,7 @@ unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC; # endif typedef struct line_input_t { int flags; + int timeout; const char *path_lookup; # if MAX_HISTORY int cnt_history; @@ -1549,7 +1738,7 @@ line_input_t *new_line_input_t(int flags) FAST_FUNC; * 0 on ctrl-C (the line entered is still returned in 'command'), * >0 length of input string, including terminating '\n' */ -int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) FAST_FUNC; +int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize) FAST_FUNC; void show_history(const line_input_t *st) FAST_FUNC; # if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT void save_history(line_input_t *st); @@ -1557,7 +1746,7 @@ void save_history(line_input_t *st); #else #define MAX_HISTORY 0 int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC; -#define read_line_input(state, prompt, command, maxsize, timeout) \ +#define read_line_input(state, prompt, command, maxsize) \ read_line_input(prompt, command, maxsize) #endif @@ -1714,22 +1903,27 @@ typedef struct sha512_ctx_t { typedef struct sha3_ctx_t { uint64_t state[25]; unsigned bytes_queued; + unsigned input_block_bytes; } sha3_ctx_t; void md5_begin(md5_ctx_t *ctx) FAST_FUNC; void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; -void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; +unsigned md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; #define sha1_hash md5_hash -void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC; +unsigned sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC; void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; #define sha256_hash md5_hash #define sha256_end sha1_end void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; -void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; +unsigned sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC; void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; -void sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC; +unsigned sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC; +/* TLS benefits from knowing that sha1 and sha256 share these. Give them "agnostic" names too */ +typedef struct md5_ctx_t md5sha_ctx_t; +#define md5sha_hash md5_hash +#define sha_end sha1_end extern uint32_t *global_crc32_table; uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; @@ -1763,6 +1957,9 @@ void bb_progress_update(bb_progress_t *p, uoff_t transferred, uoff_t totalsize) FAST_FUNC; +unsigned ubi_devnum_from_devname(const char *str) FAST_FUNC; +int ubi_get_volid_by_name(unsigned ubi_devnum, const char *vol_name) FAST_FUNC; + extern const char *applet_name; @@ -1808,19 +2005,21 @@ extern const char bb_path_wtmp_file[] ALIGN1; #define bb_dev_null "/dev/null" extern const char bb_busybox_exec_path[] ALIGN1; -/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin, - * but I want to save a few bytes here */ -extern const char bb_PATH_root_path[] ALIGN1; /* "PATH=/sbin:/usr/sbin:/bin:/usr/bin" */ +/* allow default system PATH to be extended via CFLAGS */ +#ifndef BB_ADDITIONAL_PATH +#define BB_ADDITIONAL_PATH "" +#endif +#define BB_PATH_ROOT_PATH "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH +extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */ #define bb_default_root_path (bb_PATH_root_path + sizeof("PATH")) +/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin, + * but I want to save a few bytes here: + */ #define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin")) extern const int const_int_0; //extern const int const_int_1; - -/* Providing hard guarantee on minimum size (think of BUFSIZ == 128) */ -enum { COMMON_BUFSIZE = (BUFSIZ >= 256*sizeof(void*) ? BUFSIZ+1 : 256*sizeof(void*)) }; -extern char bb_common_bufsiz1[COMMON_BUFSIZE]; /* This struct is deliberately not defined. */ /* See docs/keep_data_small.txt */ struct globals;