cal: make it NOEXEC
[oweals/busybox.git] / include / libbb.h
index 11d022fb513d0c00357f957b30dbd3e640530756..5f25b5ddeb02222e68636514bd7ef55a650a514d 100644 (file)
 #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
@@ -350,7 +358,7 @@ 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;
@@ -778,6 +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;
 
+/* 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;
@@ -864,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;
@@ -873,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,
@@ -1031,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);
@@ -1104,9 +1125,15 @@ int wait_for_exitstatus(pid_t pid) FAST_FUNC;
 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
-extern int find_applet_by_name(const char *name) FAST_FUNC;
-extern void run_applet_no_and_exit(int a, char **argv) NORETURN FAST_FUNC;
+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.
@@ -1161,39 +1188,42 @@ 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 ('+' and '-' at the start of the string), and requires
+ * 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
- * be set to 1 in order to reset getopt().  Sigh.  Standards, anyone?
+ * 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).
  */
-#ifdef __GLIBC__
+#if 1 /*def __GLIBC__*/
 #define GETOPT_RESET() (optind = 0)
 #else /* BSD style */
 #define GETOPT_RESET() (optind = 1)
@@ -1394,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><space><tab><space>#comment" is also comment, not only "line start>#comment")
        // NORMAL is:
        // * remove leading and trailing delimiters and collapse
        //   multiple delimiters into one
@@ -1449,6 +1484,21 @@ extern void run_shell(const char *shell, int loginshell, const char **args) NORE
  */
 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;
@@ -1476,6 +1526,9 @@ extern void selinux_or_die(void) FAST_FUNC;
  *   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)
@@ -1483,6 +1536,12 @@ extern void selinux_or_die(void) FAST_FUNC;
 #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;
@@ -1534,6 +1593,7 @@ 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! */
@@ -1624,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;
@@ -1642,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;
@@ -1677,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);
@@ -1685,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
 
@@ -1944,10 +2005,16 @@ 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;