Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/include/libbb.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 7  Line 7 
7   *   *
8   * Licensed under the GPL version 2, see the file LICENSE in this tarball.   * Licensed under the GPL version 2, see the file LICENSE in this tarball.
9   */   */
10  #ifndef __LIBBUSYBOX_H__  #ifndef LIBBB_H
11  #define __LIBBUSYBOX_H__    1  #define LIBBB_H 1
12    
13  #include "platform.h"  #include "platform.h"
14    
# Line 29  Line 29 
29  #include <sys/ioctl.h>  #include <sys/ioctl.h>
30  #include <sys/mman.h>  #include <sys/mman.h>
31  #include <sys/socket.h>  #include <sys/socket.h>
32    #if defined __FreeBSD__
33    # include <netinet/in.h>
34    # include <arpa/inet.h>
35    #endif
36  #include <sys/stat.h>  #include <sys/stat.h>
37  #include <sys/time.h>  #include <sys/time.h>
38  #include <sys/types.h>  #include <sys/types.h>
# Line 36  Line 40 
40  #include <termios.h>  #include <termios.h>
41  #include <time.h>  #include <time.h>
42  #include <unistd.h>  #include <unistd.h>
 #include <utime.h>  
43  /* Try to pull in PATH_MAX */  /* Try to pull in PATH_MAX */
44  #include <limits.h>  #include <limits.h>
45  #include <sys/param.h>  #include <sys/param.h>
46  #ifndef PATH_MAX  #ifndef PATH_MAX
47  #define PATH_MAX 256  # define PATH_MAX 256
48    #endif
49    
50    #ifndef BUFSIZ
51    # define BUFSIZ 4096
52  #endif  #endif
53    
54  #ifdef HAVE_MNTENT_H  #ifdef HAVE_MNTENT_H
# Line 60  Line 67 
67  #endif  #endif
68    
69  #if ENABLE_LOCALE_SUPPORT  #if ENABLE_LOCALE_SUPPORT
70  #include <locale.h>  # include <locale.h>
71  #else  #else
72  #define setlocale(x,y) ((void)0)  # define setlocale(x,y) ((void)0)
73  #endif  #endif
74    
75  #ifdef DMALLOC  #ifdef DMALLOC
76  #include <dmalloc.h>  # include <dmalloc.h>
77  #endif  #endif
78    
79  #include <pwd.h>  #include <pwd.h>
80  #include <grp.h>  #include <grp.h>
81  #if ENABLE_FEATURE_SHADOWPASSWDS  #if ENABLE_FEATURE_SHADOWPASSWDS
82  # include <shadow.h>  # if !ENABLE_USE_BB_SHADOW
83    /* If using busybox's shadow implementation, do not include the shadow.h
84     * header as the toolchain may not provide it at all.
85     */
86    #  include <shadow.h>
87    # endif
88  #endif  #endif
89    
90  /* Some libc's forget to declare these, do it ourself */  /* Some libc's forget to declare these, do it ourself */
# Line 86  int klogctl(int type, char *b, int len); Line 98  int klogctl(int type, char *b, int len);
98  /* This is declared here rather than #including <libgen.h> in order to avoid  /* This is declared here rather than #including <libgen.h> in order to avoid
99   * confusing the two versions of basename.  See the dirname/basename man page   * confusing the two versions of basename.  See the dirname/basename man page
100   * for details. */   * for details. */
101    #if !defined __FreeBSD__
102  char *dirname(char *path);  char *dirname(char *path);
103    #endif
104  /* Include our own copy of struct sysinfo to avoid binary compatibility  /* Include our own copy of struct sysinfo to avoid binary compatibility
105   * problems with Linux 2.4, which changed things.  Grumble, grumble. */   * problems with Linux 2.4, which changed things.  Grumble, grumble. */
106  struct sysinfo {  struct sysinfo {
# Line 110  int sysinfo(struct sysinfo* info); Line 124  int sysinfo(struct sysinfo* info);
124    
125  /* Make all declarations hidden (-fvisibility flag only affects definitions) */  /* Make all declarations hidden (-fvisibility flag only affects definitions) */
126  /* (don't include system headers after this until corresponding pop!) */  /* (don't include system headers after this until corresponding pop!) */
127  #if __GNUC_PREREQ(4,1)  PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
 # pragma GCC visibility push(hidden)  
 #endif  
128    
129    
130  #if ENABLE_USE_BB_PWD_GRP  #if ENABLE_USE_BB_PWD_GRP
# Line 150  int sysinfo(struct sysinfo* info); Line 162  int sysinfo(struct sysinfo* info);
162  /* CONFIG_LFS is on */  /* CONFIG_LFS is on */
163  # if ULONG_MAX > 0xffffffff  # if ULONG_MAX > 0xffffffff
164  /* "long" is long enough on this system */  /* "long" is long enough on this system */
165    typedef unsigned long uoff_t;
166  #  define XATOOFF(a) xatoul_range(a, 0, LONG_MAX)  #  define XATOOFF(a) xatoul_range(a, 0, LONG_MAX)
167  /* usage: sz = BB_STRTOOFF(s, NULL, 10); if (errno || sz < 0) die(); */  /* usage: sz = BB_STRTOOFF(s, NULL, 10); if (errno || sz < 0) die(); */
168  #  define BB_STRTOOFF bb_strtoul  #  define BB_STRTOOFF bb_strtoul
# Line 158  int sysinfo(struct sysinfo* info); Line 171  int sysinfo(struct sysinfo* info);
171  #  define OFF_FMT "l"  #  define OFF_FMT "l"
172  # else  # else
173  /* "long" is too short, need "long long" */  /* "long" is too short, need "long long" */
174    typedef unsigned long long uoff_t;
175  #  define XATOOFF(a) xatoull_range(a, 0, LLONG_MAX)  #  define XATOOFF(a) xatoull_range(a, 0, LLONG_MAX)
176  #  define BB_STRTOOFF bb_strtoull  #  define BB_STRTOOFF bb_strtoull
177  #  define STRTOOFF strtoull  #  define STRTOOFF strtoull
# Line 168  int sysinfo(struct sysinfo* info); Line 182  int sysinfo(struct sysinfo* info);
182  # if UINT_MAX == 0xffffffff  # if UINT_MAX == 0xffffffff
183  /* While sizeof(off_t) == sizeof(int), off_t is typedef'ed to long anyway.  /* While sizeof(off_t) == sizeof(int), off_t is typedef'ed to long anyway.
184   * gcc will throw warnings on printf("%d", off_t). Crap... */   * gcc will throw warnings on printf("%d", off_t). Crap... */
185    typedef unsigned long uoff_t;
186  #  define XATOOFF(a) xatoi_u(a)  #  define XATOOFF(a) xatoi_u(a)
187  #  define BB_STRTOOFF bb_strtou  #  define BB_STRTOOFF bb_strtou
188  #  define STRTOOFF strtol  #  define STRTOOFF strtol
189  #  define OFF_FMT "l"  #  define OFF_FMT "l"
190  # else  # else
191    typedef unsigned long uoff_t;
192  #  define XATOOFF(a) xatoul_range(a, 0, LONG_MAX)  #  define XATOOFF(a) xatoul_range(a, 0, LONG_MAX)
193  #  define BB_STRTOOFF bb_strtoul  #  define BB_STRTOOFF bb_strtoul
194  #  define STRTOOFF strtol  #  define STRTOOFF strtol
# Line 233  extern int *const bb_errno; Line 249  extern int *const bb_errno;
249    
250  unsigned long long monotonic_ns(void) FAST_FUNC;  unsigned long long monotonic_ns(void) FAST_FUNC;
251  unsigned long long monotonic_us(void) FAST_FUNC;  unsigned long long monotonic_us(void) FAST_FUNC;
252    unsigned long long monotonic_ms(void) FAST_FUNC;
253  unsigned monotonic_sec(void) FAST_FUNC;  unsigned monotonic_sec(void) FAST_FUNC;
254    
255  extern void chomp(char *s) FAST_FUNC;  extern void chomp(char *s) FAST_FUNC;
# Line 245  extern char *strrstr(const char *haystac Line 262  extern char *strrstr(const char *haystac
262  extern const char *bb_mode_string(mode_t mode) FAST_FUNC;  extern const char *bb_mode_string(mode_t mode) FAST_FUNC;
263  extern int is_directory(const char *name, int followLinks, struct stat *statBuf) FAST_FUNC;  extern int is_directory(const char *name, int followLinks, struct stat *statBuf) FAST_FUNC;
264  enum { /* DO NOT CHANGE THESE VALUES!  cp.c, mv.c, install.c depend on them. */  enum { /* DO NOT CHANGE THESE VALUES!  cp.c, mv.c, install.c depend on them. */
265   FILEUTILS_PRESERVE_STATUS = 1,   FILEUTILS_PRESERVE_STATUS = 1 << 0, /* -p */
266   FILEUTILS_DEREFERENCE = 2,   FILEUTILS_DEREFERENCE     = 1 << 1, /* !-d */
267   FILEUTILS_RECUR = 4,   FILEUTILS_RECUR           = 1 << 2, /* -R */
268   FILEUTILS_FORCE = 8,   FILEUTILS_FORCE           = 1 << 3, /* -f */
269   FILEUTILS_INTERACTIVE = 0x10,   FILEUTILS_INTERACTIVE     = 1 << 4, /* -i */
270   FILEUTILS_MAKE_HARDLINK = 0x20,   FILEUTILS_MAKE_HARDLINK   = 1 << 5, /* -l */
271   FILEUTILS_MAKE_SOFTLINK = 0x40,   FILEUTILS_MAKE_SOFTLINK   = 1 << 6, /* -s */
272   FILEUTILS_DEREF_SOFTLINK = 0x80,   FILEUTILS_DEREF_SOFTLINK  = 1 << 7, /* -L */
273     FILEUTILS_DEREFERENCE_L0  = 1 << 8, /* -H */
274  #if ENABLE_SELINUX  #if ENABLE_SELINUX
275   FILEUTILS_PRESERVE_SECURITY_CONTEXT = 0x100,   FILEUTILS_PRESERVE_SECURITY_CONTEXT = 1 << 9, /* -c */
276   FILEUTILS_SET_SECURITY_CONTEXT = 0x200   FILEUTILS_SET_SECURITY_CONTEXT = 1 << 10,
277  #endif  #endif
278  };  };
279  #define FILEUTILS_CP_OPTSTR "pdRfilsL" USE_SELINUX("c")  #define FILEUTILS_CP_OPTSTR "pdRfilsLH" IF_SELINUX("c")
280  extern int remove_file(const char *path, int flags) FAST_FUNC;  extern int remove_file(const char *path, int flags) FAST_FUNC;
281  /* NB: without FILEUTILS_RECUR in flags, it will basically "cat"  /* NB: without FILEUTILS_RECUR in flags, it will basically "cat"
282   * the source, not copy (unless "source" is a directory).   * the source, not copy (unless "source" is a directory).
# Line 273  enum { Line 291  enum {
291   ACTION_DEPTHFIRST     = (1 << 3),   ACTION_DEPTHFIRST     = (1 << 3),
292   /*ACTION_REVERSE      = (1 << 4), - unused */   /*ACTION_REVERSE      = (1 << 4), - unused */
293   ACTION_QUIET          = (1 << 5),   ACTION_QUIET          = (1 << 5),
294     ACTION_DANGLING_OK    = (1 << 6),
295  };  };
296    typedef uint8_t recurse_flags_t;
297  extern int recursive_action(const char *fileName, unsigned flags,  extern int recursive_action(const char *fileName, unsigned flags,
298   int FAST_FUNC (*fileAction)(const char *fileName, struct stat* statbuf, void* userData, int depth),   int FAST_FUNC (*fileAction)(const char *fileName, struct stat* statbuf, void* userData, int depth),
299   int FAST_FUNC (*dirAction)(const char *fileName, struct stat* statbuf, void* userData, int depth),   int FAST_FUNC (*dirAction)(const char *fileName, struct stat* statbuf, void* userData, int depth),
# Line 312  void xmove_fd(int, int) FAST_FUNC; Line 332  void xmove_fd(int, int) FAST_FUNC;
332  DIR *xopendir(const char *path) FAST_FUNC;  DIR *xopendir(const char *path) FAST_FUNC;
333  DIR *warn_opendir(const char *path) FAST_FUNC;  DIR *warn_opendir(const char *path) FAST_FUNC;
334    
335  /* UNUSED: char *xmalloc_realpath(const char *path) FAST_FUNC; */  /* UNUSED: char *xmalloc_realpath(const char *path) FAST_FUNC RETURNS_MALLOC; */
336  char *xmalloc_readlink(const char *path) FAST_FUNC;  char *xmalloc_readlink(const char *path) FAST_FUNC RETURNS_MALLOC;
337  char *xmalloc_readlink_or_warn(const char *path) FAST_FUNC;  char *xmalloc_readlink_or_warn(const char *path) FAST_FUNC RETURNS_MALLOC;
338    /* !RETURNS_MALLOC: it's a realloc-like function */
339  char *xrealloc_getcwd_or_warn(char *cwd) FAST_FUNC;  char *xrealloc_getcwd_or_warn(char *cwd) FAST_FUNC;
340    
341  char *xmalloc_follow_symlinks(const char *path) FAST_FUNC;  char *xmalloc_follow_symlinks(const char *path) FAST_FUNC RETURNS_MALLOC;
342    
343    
344  enum {  enum {
# Line 353  enum { Line 374  enum {
374  void bb_signals(int sigs, void (*f)(int)) FAST_FUNC;  void bb_signals(int sigs, void (*f)(int)) FAST_FUNC;
375  /* Unlike signal() and bb_signals, sets handler with sigaction()  /* Unlike signal() and bb_signals, sets handler with sigaction()
376   * and in a way that while signal handler is run, no other signals   * and in a way that while signal handler is run, no other signals
377   * will be blocked: */   * will be blocked; syscalls will not be restarted: */
378  void bb_signals_recursive(int sigs, void (*f)(int)) FAST_FUNC;  void bb_signals_recursive_norestart(int sigs, void (*f)(int)) FAST_FUNC;
379  /* syscalls like read() will be interrupted with EINTR: */  /* syscalls like read() will be interrupted with EINTR: */
380  void signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int)) FAST_FUNC;  void signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int)) FAST_FUNC;
381  /* syscalls like read() won't be interrupted (though select/poll will be): */  /* syscalls like read() won't be interrupted (though select/poll will be): */
# Line 377  void xsetuid(uid_t uid) FAST_FUNC; Line 398  void xsetuid(uid_t uid) FAST_FUNC;
398  void xchdir(const char *path) FAST_FUNC;  void xchdir(const char *path) FAST_FUNC;
399  void xchroot(const char *path) FAST_FUNC;  void xchroot(const char *path) FAST_FUNC;
400  void xsetenv(const char *key, const char *value) FAST_FUNC;  void xsetenv(const char *key, const char *value) FAST_FUNC;
401    void bb_unsetenv(const char *key) FAST_FUNC;
402  void xunlink(const char *pathname) FAST_FUNC;  void xunlink(const char *pathname) FAST_FUNC;
403  void xstat(const char *pathname, struct stat *buf) FAST_FUNC;  void xstat(const char *pathname, struct stat *buf) FAST_FUNC;
404  int xopen(const char *pathname, int flags) FAST_FUNC FAST_FUNC;  int xopen(const char *pathname, int flags) FAST_FUNC;
405    int xopen_nonblocking(const char *pathname) FAST_FUNC;
406  int xopen3(const char *pathname, int flags, int mode) FAST_FUNC;  int xopen3(const char *pathname, int flags, int mode) FAST_FUNC;
407  int open_or_warn(const char *pathname, int flags) FAST_FUNC;  int open_or_warn(const char *pathname, int flags) FAST_FUNC;
408  int open3_or_warn(const char *pathname, int flags, int mode) FAST_FUNC;  int open3_or_warn(const char *pathname, int flags, int mode) FAST_FUNC;
# Line 423  struct BUG_too_small { Line 446  struct BUG_too_small {
446  };  };
447    
448    
449    void parse_datestr(const char *date_str, struct tm *ptm) FAST_FUNC;
450    time_t validate_tm_time(const char *date_str, struct tm *ptm) FAST_FUNC;
451    
452    
453  int xsocket(int domain, int type, int protocol) FAST_FUNC;  int xsocket(int domain, int type, int protocol) FAST_FUNC;
454  void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) FAST_FUNC;  void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) FAST_FUNC;
455  void xlisten(int s, int backlog) FAST_FUNC;  void xlisten(int s, int backlog) FAST_FUNC;
# Line 465  enum { Line 492  enum {
492  /* Create stream socket, and allocate suitable lsa.  /* Create stream socket, and allocate suitable lsa.
493   * (lsa of correct size and lsa->sa.sa_family (AF_INET/AF_INET6))   * (lsa of correct size and lsa->sa.sa_family (AF_INET/AF_INET6))
494   * af == AF_UNSPEC will result in trying to create IPv6 socket,   * af == AF_UNSPEC will result in trying to create IPv6 socket,
495   * and if kernel doesn't support it, IPv4.   * and if kernel doesn't support it, fall back to IPv4.
496     * This is useful if you plan to bind to resulting local lsa.
497   */   */
498  #if ENABLE_FEATURE_IPV6  #if ENABLE_FEATURE_IPV6
499  int xsocket_type(len_and_sockaddr **lsap, int af, int sock_type) FAST_FUNC;  int xsocket_type(len_and_sockaddr **lsap, int af, int sock_type) FAST_FUNC;
# Line 488  int create_and_bind_dgram_or_die(const c Line 516  int create_and_bind_dgram_or_die(const c
516  int create_and_connect_stream_or_die(const char *peer, int port) FAST_FUNC;  int create_and_connect_stream_or_die(const char *peer, int port) FAST_FUNC;
517  /* Connect to peer identified by lsa */  /* Connect to peer identified by lsa */
518  int xconnect_stream(const len_and_sockaddr *lsa) FAST_FUNC;  int xconnect_stream(const len_and_sockaddr *lsa) FAST_FUNC;
519    /* Get local address of bound or accepted socket */
520    len_and_sockaddr *get_sock_lsa(int fd) FAST_FUNC RETURNS_MALLOC;
521  /* Return malloc'ed len_and_sockaddr with socket address of host:port  /* Return malloc'ed len_and_sockaddr with socket address of host:port
522   * Currently will return IPv4 or IPv6 sockaddrs only   * Currently will return IPv4 or IPv6 sockaddrs only
523   * (depending on host), but in theory nothing prevents e.g.   * (depending on host), but in theory nothing prevents e.g.
524   * UNIX socket address being returned, IPX sockaddr etc...   * UNIX socket address being returned, IPX sockaddr etc...
525   * On error does bb_error_msg and returns NULL */   * On error does bb_error_msg and returns NULL */
526  len_and_sockaddr* host2sockaddr(const char *host, int port) FAST_FUNC;  len_and_sockaddr* host2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
527  /* Version which dies on error */  /* Version which dies on error */
528  len_and_sockaddr* xhost2sockaddr(const char *host, int port) FAST_FUNC;  len_and_sockaddr* xhost2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
529  len_and_sockaddr* xdotted2sockaddr(const char *host, int port) FAST_FUNC;  len_and_sockaddr* xdotted2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
530  /* Same, useful if you want to force family (e.g. IPv6) */  /* Same, useful if you want to force family (e.g. IPv6) */
531  #if !ENABLE_FEATURE_IPV6  #if !ENABLE_FEATURE_IPV6
532  #define host_and_af2sockaddr(host, port, af) host2sockaddr((host), (port))  #define host_and_af2sockaddr(host, port, af) host2sockaddr((host), (port))
533  #define xhost_and_af2sockaddr(host, port, af) xhost2sockaddr((host), (port))  #define xhost_and_af2sockaddr(host, port, af) xhost2sockaddr((host), (port))
534  #else  #else
535  len_and_sockaddr* host_and_af2sockaddr(const char *host, int port, sa_family_t af) FAST_FUNC;  len_and_sockaddr* host_and_af2sockaddr(const char *host, int port, sa_family_t af) FAST_FUNC RETURNS_MALLOC;
536  len_and_sockaddr* xhost_and_af2sockaddr(const char *host, int port, sa_family_t af) FAST_FUNC;  len_and_sockaddr* xhost_and_af2sockaddr(const char *host, int port, sa_family_t af) FAST_FUNC RETURNS_MALLOC;
537  #endif  #endif
538  /* Assign sin[6]_port member if the socket is an AF_INET[6] one,  /* Assign sin[6]_port member if the socket is an AF_INET[6] one,
539   * otherwise no-op. Useful for ftp.   * otherwise no-op. Useful for ftp.
# Line 512  void set_nport(len_and_sockaddr *lsa, un Line 542  void set_nport(len_and_sockaddr *lsa, un
542  /* Retrieve sin[6]_port or return -1 for non-INET[6] lsa's */  /* Retrieve sin[6]_port or return -1 for non-INET[6] lsa's */
543  int get_nport(const struct sockaddr *sa) FAST_FUNC;  int get_nport(const struct sockaddr *sa) FAST_FUNC;
544  /* Reverse DNS. Returns NULL on failure. */  /* Reverse DNS. Returns NULL on failure. */
545  char* xmalloc_sockaddr2host(const struct sockaddr *sa) FAST_FUNC;  char* xmalloc_sockaddr2host(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
546  /* This one doesn't append :PORTNUM */  /* This one doesn't append :PORTNUM */
547  char* xmalloc_sockaddr2host_noport(const struct sockaddr *sa) FAST_FUNC;  char* xmalloc_sockaddr2host_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
548  /* This one also doesn't fall back to dotted IP (returns NULL) */  /* This one also doesn't fall back to dotted IP (returns NULL) */
549  char* xmalloc_sockaddr2hostonly_noport(const struct sockaddr *sa) FAST_FUNC;  char* xmalloc_sockaddr2hostonly_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
550  /* inet_[ap]ton on steroids */  /* inet_[ap]ton on steroids */
551  char* xmalloc_sockaddr2dotted(const struct sockaddr *sa) FAST_FUNC;  char* xmalloc_sockaddr2dotted(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
552  char* xmalloc_sockaddr2dotted_noport(const struct sockaddr *sa) FAST_FUNC;  char* xmalloc_sockaddr2dotted_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
553  // "old" (ipv4 only) API  // "old" (ipv4 only) API
554  // users: traceroute.c hostname.c - use _list_ of all IPs  // users: traceroute.c hostname.c - use _list_ of all IPs
555  struct hostent *xgethostbyname(const char *name) FAST_FUNC;  struct hostent *xgethostbyname(const char *name) FAST_FUNC;
# Line 537  ssize_t recv_from_to(int fd, void *buf, Line 567  ssize_t recv_from_to(int fd, void *buf,
567   struct sockaddr *to,   struct sockaddr *to,
568   socklen_t sa_size) FAST_FUNC;   socklen_t sa_size) FAST_FUNC;
569    
570  char *xstrdup(const char *s) FAST_FUNC;  
571  char *xstrndup(const char *s, int n) FAST_FUNC;  char *xstrdup(const char *s) FAST_FUNC RETURNS_MALLOC;
572    char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC;
573  void overlapping_strcpy(char *dst, const char *src) FAST_FUNC;  void overlapping_strcpy(char *dst, const char *src) FAST_FUNC;
574  char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC;  char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC;
575    char *strncpy_IFNAMSIZ(char *dst, const char *src) FAST_FUNC;
576  /* Guaranteed to NOT be a macro (smallest code). Saves nearly 2k on uclibc.  /* Guaranteed to NOT be a macro (smallest code). Saves nearly 2k on uclibc.
577   * But potentially slow, don't use in one-billion-times loops */   * But potentially slow, don't use in one-billion-times loops */
578  int bb_putchar(int ch) FAST_FUNC;  int bb_putchar(int ch) FAST_FUNC;
579  char *xasprintf(const char *format, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;  char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC;
580  /* Prints unprintable chars ch as ^C or M-c to file  /* Prints unprintable chars ch as ^C or M-c to file
581   * (M-c is used only if ch is ORed with PRINTABLE_META),   * (M-c is used only if ch is ORed with PRINTABLE_META),
582   * else it is printed as-is (except for ch = 0x9b) */   * else it is printed as-is (except for ch = 0x9b) */
# Line 564  void fputc_printable(int ch, FILE *file) Line 596  void fputc_printable(int ch, FILE *file)
596    
597  /* dmalloc will redefine these to it's own implementation. It is safe  /* dmalloc will redefine these to it's own implementation. It is safe
598   * to have the prototypes here unconditionally.  */   * to have the prototypes here unconditionally.  */
599  void *malloc_or_warn(size_t size) FAST_FUNC;  void *malloc_or_warn(size_t size) FAST_FUNC RETURNS_MALLOC;
600  void *xmalloc(size_t size) FAST_FUNC;  void *xmalloc(size_t size) FAST_FUNC RETURNS_MALLOC;
601  void *xzalloc(size_t size) FAST_FUNC;  void *xzalloc(size_t size) FAST_FUNC RETURNS_MALLOC;
602  void *xrealloc(void *old, size_t size) FAST_FUNC;  void *xrealloc(void *old, size_t size) FAST_FUNC;
603  /* After xrealloc_vector(v, 4, idx) it's ok to use  /* After xrealloc_vector(v, 4, idx) it's ok to use
604   * at least v[idx] and v[idx+1], for all idx values.   * at least v[idx] and v[idx+1], for all idx values.
# Line 590  extern ssize_t open_read_close(const cha Line 622  extern ssize_t open_read_close(const cha
622  // Reads byte-by-byte. Useful when it is important to not read ahead.  // Reads byte-by-byte. Useful when it is important to not read ahead.
623  // Bytes are appended to pfx (which must be malloced, or NULL).  // Bytes are appended to pfx (which must be malloced, or NULL).
624  extern char *xmalloc_reads(int fd, char *pfx, size_t *maxsz_p) FAST_FUNC;  extern char *xmalloc_reads(int fd, char *pfx, size_t *maxsz_p) FAST_FUNC;
625  /* Reads block up to *maxsz_p (default: MAX_INT(ssize_t)) */  /* Reads block up to *maxsz_p (default: INT_MAX - 4095) */
626  extern void *xmalloc_read(int fd, size_t *maxsz_p) FAST_FUNC;  extern void *xmalloc_read(int fd, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
627  /* Returns NULL if file can't be opened */  /* Returns NULL if file can't be opened (default max size: INT_MAX - 4095) */
628  extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC;  extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
629  /* Autodetects .gz etc */  /* Autodetects .gz etc */
630  extern int open_zipped(const char *fname) FAST_FUNC;  extern int open_zipped(const char *fname) FAST_FUNC;
631  extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC;  extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
632  /* Never returns NULL */  /* Never returns NULL */
633  extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC;  extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
634    
635  extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC;  extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC;
636  // NB: will return short write on error, not -1,  // NB: will return short write on error, not -1,
637  // if some data was written before error occurred  // if some data was written before error occurred
638  extern ssize_t full_write(int fd, const void *buf, size_t count) FAST_FUNC;  extern ssize_t full_write(int fd, const void *buf, size_t count) FAST_FUNC;
639  extern void xwrite(int fd, const void *buf, size_t count) FAST_FUNC;  extern void xwrite(int fd, const void *buf, size_t count) FAST_FUNC;
640    extern void xwrite_str(int fd, const char *str) FAST_FUNC;
641  extern void xopen_xwrite_close(const char* file, const char *str) FAST_FUNC;  extern void xopen_xwrite_close(const char* file, const char *str) FAST_FUNC;
642    
643    /* Close fd, but check for failures (some types of write errors) */
644    extern void xclose(int fd) FAST_FUNC;
645    
646  /* Reads and prints to stdout till eof, then closes FILE. Exits on error: */  /* Reads and prints to stdout till eof, then closes FILE. Exits on error: */
647  extern void xprint_and_close_file(FILE *file) FAST_FUNC;  extern void xprint_and_close_file(FILE *file) FAST_FUNC;
648    
649  extern char *bb_get_chunk_from_file(FILE *file, int *end) FAST_FUNC;  extern char *bb_get_chunk_from_file(FILE *file, int *end) FAST_FUNC;
650  extern char *bb_get_chunk_with_continuation(FILE *file, int *end, int *lineno) FAST_FUNC;  extern char *bb_get_chunk_with_continuation(FILE *file, int *end, int *lineno) FAST_FUNC;
651  /* Reads up to (and including) TERMINATING_STRING: */  /* Reads up to (and including) TERMINATING_STRING: */
652  extern char *xmalloc_fgets_str(FILE *file, const char *terminating_string) FAST_FUNC;  extern char *xmalloc_fgets_str(FILE *file, const char *terminating_string) FAST_FUNC RETURNS_MALLOC;
653    /* Same, with limited max size, and returns the length (excluding NUL): */
654    extern char *xmalloc_fgets_str_len(FILE *file, const char *terminating_string, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
655  /* Chops off TERMINATING_STRING from the end: */  /* Chops off TERMINATING_STRING from the end: */
656  extern char *xmalloc_fgetline_str(FILE *file, const char *terminating_string) FAST_FUNC;  extern char *xmalloc_fgetline_str(FILE *file, const char *terminating_string) FAST_FUNC RETURNS_MALLOC;
657  /* Reads up to (and including) "\n" or NUL byte: */  /* Reads up to (and including) "\n" or NUL byte: */
658  extern char *xmalloc_fgets(FILE *file) FAST_FUNC;  extern char *xmalloc_fgets(FILE *file) FAST_FUNC RETURNS_MALLOC;
659  /* Chops off '\n' from the end, unlike fgets: */  /* Chops off '\n' from the end, unlike fgets: */
660  extern char *xmalloc_fgetline(FILE *file) FAST_FUNC;  extern char *xmalloc_fgetline(FILE *file) FAST_FUNC RETURNS_MALLOC;
661  /* Same, but doesn't try to conserve space (may have some slack after the end) */  /* Same, but doesn't try to conserve space (may have some slack after the end) */
662  /* extern char *xmalloc_fgetline_fast(FILE *file) FAST_FUNC; */  /* extern char *xmalloc_fgetline_fast(FILE *file) FAST_FUNC RETURNS_MALLOC; */
663    
664  extern void die_if_ferror(FILE *file, const char *msg) FAST_FUNC;  void die_if_ferror(FILE *file, const char *msg) FAST_FUNC;
665  extern void die_if_ferror_stdout(void) FAST_FUNC;  void die_if_ferror_stdout(void) FAST_FUNC;
666  extern void xfflush_stdout(void) FAST_FUNC;  int fflush_all(void) FAST_FUNC;
667  extern void fflush_stdout_and_exit(int retval) NORETURN FAST_FUNC;  void fflush_stdout_and_exit(int retval) NORETURN FAST_FUNC;
668  extern int fclose_if_not_stdin(FILE *file) FAST_FUNC;  int fclose_if_not_stdin(FILE *file) FAST_FUNC;
669  extern FILE *xfopen(const char *filename, const char *mode) FAST_FUNC;  FILE* xfopen(const char *filename, const char *mode) FAST_FUNC;
670  /* Prints warning to stderr and returns NULL on failure: */  /* Prints warning to stderr and returns NULL on failure: */
671  extern FILE *fopen_or_warn(const char *filename, const char *mode) FAST_FUNC;  FILE* fopen_or_warn(const char *filename, const char *mode) FAST_FUNC;
672  /* "Opens" stdin if filename is special, else just opens file: */  /* "Opens" stdin if filename is special, else just opens file: */
673  extern FILE *xfopen_stdin(const char *filename) FAST_FUNC;  FILE* xfopen_stdin(const char *filename) FAST_FUNC;
674  extern FILE *fopen_or_warn_stdin(const char *filename) FAST_FUNC;  FILE* fopen_or_warn_stdin(const char *filename) FAST_FUNC;
675  extern FILE* fopen_for_read(const char *path) FAST_FUNC;  FILE* fopen_for_read(const char *path) FAST_FUNC;
676  extern FILE* xfopen_for_read(const char *path) FAST_FUNC;  FILE* xfopen_for_read(const char *path) FAST_FUNC;
677  extern FILE* fopen_for_write(const char *path) FAST_FUNC;  FILE* fopen_for_write(const char *path) FAST_FUNC;
678  extern FILE* xfopen_for_write(const char *path) FAST_FUNC;  FILE* xfopen_for_write(const char *path) FAST_FUNC;
679    FILE* xfdopen_for_read(int fd) FAST_FUNC;
680    FILE* xfdopen_for_write(int fd) FAST_FUNC;
681    
682  int bb_pstrcmp(const void *a, const void *b) /* not FAST_FUNC! */;  int bb_pstrcmp(const void *a, const void *b) /* not FAST_FUNC! */;
683  void qsort_string_vector(char **sv, unsigned count) FAST_FUNC;  void qsort_string_vector(char **sv, unsigned count) FAST_FUNC;
# Line 662  char *itoa_to_buf(int n, char *buf, unsi Line 702  char *itoa_to_buf(int n, char *buf, unsi
702  /* Intelligent formatters of bignums */  /* Intelligent formatters of bignums */
703  void smart_ulltoa4(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC;  void smart_ulltoa4(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC;
704  void smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC;  void smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC;
705    /* If block_size == 0, display size without fractional part,
706     * else display (size * block_size) with one decimal digit.
707     * If display_unit == 0, show value no bigger than 1024 with suffix (K,M,G...),
708     * else divide by display_unit and do not use suffix. */
709    #define HUMAN_READABLE_MAX_WIDTH      7  /* "1024.0G" */
710    #define HUMAN_READABLE_MAX_WIDTH_STR "7"
711  //TODO: provide pointer to buf (avoid statics)?  //TODO: provide pointer to buf (avoid statics)?
712  const char *make_human_readable_str(unsigned long long size,  const char *make_human_readable_str(unsigned long long size,
713   unsigned long block_size, unsigned long display_unit) FAST_FUNC;   unsigned long block_size, unsigned long display_unit) FAST_FUNC;
714  /* Put a string of hex bytes ("1b2e66fe"...), return advanced pointer */  /* Put a string of hex bytes ("1b2e66fe"...), return advanced pointer */
715  char *bin2hex(char *buf, const char *cp, int count) FAST_FUNC;  char *bin2hex(char *buf, const char *cp, int count) FAST_FUNC;
716    
717    /* Generate a UUID */
718    void generate_uuid(uint8_t *buf) FAST_FUNC;
719    
720  /* Last element is marked by mult == 0 */  /* Last element is marked by mult == 0 */
721  struct suffix_mult {  struct suffix_mult {
722   char suffix[4];   char suffix[4];
# Line 702  int get_uidgid(struct bb_uidgid_t*, cons Line 751  int get_uidgid(struct bb_uidgid_t*, cons
751  void xget_uidgid(struct bb_uidgid_t*, const char*) FAST_FUNC;  void xget_uidgid(struct bb_uidgid_t*, const char*) FAST_FUNC;
752  /* chown-like handling of "user[:[group]" */  /* chown-like handling of "user[:[group]" */
753  void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group) FAST_FUNC;  void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group) FAST_FUNC;
754  /* bb_getpwuid, bb_getgrgid:  struct passwd* xgetpwnam(const char *name) FAST_FUNC;
755   * bb_getXXXid(buf, bufsz, id) - copy user/group name or id  struct group* xgetgrnam(const char *name) FAST_FUNC;
756   *              as a string to buf, return user/group name or NULL  struct passwd* xgetpwuid(uid_t uid) FAST_FUNC;
757   * bb_getXXXid(NULL, 0, id) - return user/group name or NULL  struct group* xgetgrgid(gid_t gid) FAST_FUNC;
758   * bb_getXXXid(NULL, -1, id) - return user/group name or exit  char* xuid2uname(uid_t uid) FAST_FUNC;
759  */  char* xgid2group(gid_t gid) FAST_FUNC;
760  char *bb_getpwuid(char *name, int bufsize, long uid) FAST_FUNC;  char* uid2uname(uid_t uid) FAST_FUNC;
761  char *bb_getgrgid(char *group, int bufsize, long gid) FAST_FUNC;  char* gid2group(gid_t gid) FAST_FUNC;
762    char* uid2uname_utoa(long uid) FAST_FUNC;
763    char* gid2group_utoa(long gid) FAST_FUNC;
764  /* versions which cache results (useful for ps, ls etc) */  /* versions which cache results (useful for ps, ls etc) */
765  const char* get_cached_username(uid_t uid) FAST_FUNC;  const char* get_cached_username(uid_t uid) FAST_FUNC;
766  const char* get_cached_groupname(gid_t gid) FAST_FUNC;  const char* get_cached_groupname(gid_t gid) FAST_FUNC;
# Line 754  pid_t safe_waitpid(pid_t pid, int *wstat Line 805  pid_t safe_waitpid(pid_t pid, int *wstat
805   */   */
806  int wait4pid(pid_t pid) FAST_FUNC;  int wait4pid(pid_t pid) FAST_FUNC;
807  pid_t wait_any_nohang(int *wstat) FAST_FUNC;  pid_t wait_any_nohang(int *wstat) FAST_FUNC;
 #define wait_crashed(w) ((w) & 127)  
 #define wait_exitcode(w) ((w) >> 8)  
 #define wait_stopsig(w) ((w) >> 8)  
 #define wait_stopped(w) (((w) & 127) == 127)  
808  /* wait4pid(spawn(argv)) + NOFORK/NOEXEC (if configured) */  /* wait4pid(spawn(argv)) + NOFORK/NOEXEC (if configured) */
809  pid_t spawn_and_wait(char **argv) FAST_FUNC;  int spawn_and_wait(char **argv) FAST_FUNC;
810  struct nofork_save_area {  struct nofork_save_area {
811   jmp_buf die_jmp;   jmp_buf die_jmp;
812   const char *applet_name;   const char *applet_name;
# Line 788  int run_nofork_applet_prime(struct nofor Line 835  int run_nofork_applet_prime(struct nofor
835   * Both of the above will redirect fd 0,1,2 to /dev/null and drop ctty   * Both of the above will redirect fd 0,1,2 to /dev/null and drop ctty
836   * (will do setsid()).   * (will do setsid()).
837   *   *
838   * forkexit_or_rexec(argv) = bare-bones "fork + parent exits" on MMU,   * fork_or_rexec(argv) = bare-bones "fork" on MMU,
839   *      "vfork + re-exec ourself" on NOMMU. No fd redirection, no setsid().   *      "vfork + re-exec ourself" on NOMMU. No fd redirection, no setsid().
840   *      Currently used for setsid only. On MMU ignores argv.   *      On MMU ignores argv.
841   *   *
842   * Helper for network daemons in foreground mode:   * Helper for network daemons in foreground mode:
843   *   *
# Line 804  enum { Line 851  enum {
851   DAEMON_ONLY_SANITIZE = 8, /* internal use */   DAEMON_ONLY_SANITIZE = 8, /* internal use */
852  };  };
853  #if BB_MMU  #if BB_MMU
854    void forkexit_or_rexec(void) FAST_FUNC;    pid_t fork_or_rexec(void) FAST_FUNC;
855    enum { re_execed = 0 };    enum { re_execed = 0 };
856  # define forkexit_or_rexec(argv)            forkexit_or_rexec()  # define fork_or_rexec(argv)                fork_or_rexec()
857  # define bb_daemonize_or_rexec(flags, argv) bb_daemonize_or_rexec(flags)  # define bb_daemonize_or_rexec(flags, argv) bb_daemonize_or_rexec(flags)
858  # define bb_daemonize(flags)                bb_daemonize_or_rexec(flags, bogus)  # define bb_daemonize(flags)                bb_daemonize_or_rexec(flags, bogus)
859  #else  #else
860    void re_exec(char **argv) NORETURN FAST_FUNC;    void re_exec(char **argv) NORETURN FAST_FUNC;
861    void forkexit_or_rexec(char **argv) FAST_FUNC;    pid_t fork_or_rexec(char **argv) FAST_FUNC;
862    extern bool re_execed;    extern bool re_execed;
863    int  BUG_fork_is_unavailable_on_nommu(void) FAST_FUNC;    int  BUG_fork_is_unavailable_on_nommu(void) FAST_FUNC;
864    int  BUG_daemon_is_unavailable_on_nommu(void) FAST_FUNC;    int  BUG_daemon_is_unavailable_on_nommu(void) FAST_FUNC;
# Line 826  void bb_sanitize_stdio(void) FAST_FUNC; Line 873  void bb_sanitize_stdio(void) FAST_FUNC;
873  int sanitize_env_if_suid(void) FAST_FUNC;  int sanitize_env_if_suid(void) FAST_FUNC;
874    
875    
876    char* single_argv(char **argv) FAST_FUNC;
877  extern const char *const bb_argv_dash[]; /* "-", NULL */  extern const char *const bb_argv_dash[]; /* "-", NULL */
878  extern const char *opt_complementary;  extern const char *opt_complementary;
879  #if ENABLE_GETOPT_LONG  #if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG
880  #define No_argument "\0"  #define No_argument "\0"
881  #define Required_argument "\001"  #define Required_argument "\001"
882  #define Optional_argument "\002"  #define Optional_argument "\002"
# Line 848  void *llist_pop(llist_t **elm) FAST_FUNC Line 896  void *llist_pop(llist_t **elm) FAST_FUNC
896  void llist_unlink(llist_t **head, llist_t *elm) FAST_FUNC;  void llist_unlink(llist_t **head, llist_t *elm) FAST_FUNC;
897  void llist_free(llist_t *elm, void (*freeit)(void *data)) FAST_FUNC;  void llist_free(llist_t *elm, void (*freeit)(void *data)) FAST_FUNC;
898  llist_t *llist_rev(llist_t *list) FAST_FUNC;  llist_t *llist_rev(llist_t *list) FAST_FUNC;
899    llist_t *llist_find_str(llist_t *first, const char *str) FAST_FUNC;
900  /* BTW, surprisingly, changing API to  /* BTW, surprisingly, changing API to
901   *   llist_t *llist_add_to(llist_t *old_head, void *data)   *   llist_t *llist_add_to(llist_t *old_head, void *data)
902   * etc does not result in smaller code... */   * etc does not result in smaller code... */
# Line 883  extern void bb_error_msg_and_die(const c Line 932  extern void bb_error_msg_and_die(const c
932  extern void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;  extern void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
933  extern void bb_simple_perror_msg(const char *s) FAST_FUNC;  extern void bb_simple_perror_msg(const char *s) FAST_FUNC;
934  extern void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;  extern void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
935  extern void bb_simple_perror_msg_and_die(const char *s) __attribute__ ((noreturn)) FAST_FUNC;  extern void bb_simple_perror_msg_and_die(const char *s) NORETURN FAST_FUNC;
936  extern void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;  extern void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
937  extern void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;  extern void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
938  extern void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC;  extern void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC;
# Line 904  extern void bb_verror_msg(const char *s, Line 953  extern void bb_verror_msg(const char *s,
953  /* Applets which are useful from another applets */  /* Applets which are useful from another applets */
954  int bb_cat(char** argv);  int bb_cat(char** argv);
955  /* If shell needs them, they exist even if not enabled as applets */  /* If shell needs them, they exist even if not enabled as applets */
956  int echo_main(int argc, char** argv) USE_ECHO(MAIN_EXTERNALLY_VISIBLE);  int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE);
957  int printf_main(int argc, char **argv) USE_PRINTF(MAIN_EXTERNALLY_VISIBLE);  int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE);
958  int test_main(int argc, char **argv) USE_TEST(MAIN_EXTERNALLY_VISIBLE);  int test_main(int argc, char **argv) IF_TEST(MAIN_EXTERNALLY_VISIBLE);
959  int kill_main(int argc, char **argv) USE_KILL(MAIN_EXTERNALLY_VISIBLE);  int kill_main(int argc, char **argv) IF_KILL(MAIN_EXTERNALLY_VISIBLE);
960  /* Similar, but used by chgrp, not shell */  /* Similar, but used by chgrp, not shell */
961  int chown_main(int argc, char **argv) USE_CHOWN(MAIN_EXTERNALLY_VISIBLE);  int chown_main(int argc, char **argv) IF_CHOWN(MAIN_EXTERNALLY_VISIBLE);
962  /* Don't need USE_xxx() guard for these */  /* Used by ftpd */
963    int ls_main(int argc, char **argv) IF_LS(MAIN_EXTERNALLY_VISIBLE);
964    /* Don't need IF_xxx() guard for these */
965  int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;  int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
966  int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;  int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
967    
# Line 919  void bb_displayroutes(int noresolve, int Line 970  void bb_displayroutes(int noresolve, int
970  #endif  #endif
971    
972    
 /* "Keycodes" that report an escape sequence.  
  * We use something which fits into signed char,  
  * yet doesn't represent any valid Unicode characher.  
  * 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,  
 #if 0  
  KEYCODE_FUN1     = -12,  
  KEYCODE_FUN2     = -13,  
  KEYCODE_FUN3     = -14,  
  KEYCODE_FUN4     = -15,  
  KEYCODE_FUN5     = -16,  
  KEYCODE_FUN6     = -17,  
  KEYCODE_FUN7     = -18,  
  KEYCODE_FUN8     = -19,  
  KEYCODE_FUN9     = -20,  
  KEYCODE_FUN10    = -21,  
  KEYCODE_FUN11    = -22,  
  KEYCODE_FUN12    = -23,  
 #endif  
  /* How long the longest ESC sequence we know? */  
  KEYCODE_BUFFER_SIZE = 4  
 };  
 int read_key(int fd, smalluint *nbuffered, char *buffer) FAST_FUNC;  
   
   
973  /* Networking */  /* Networking */
974  int create_icmp_socket(void) FAST_FUNC;  int create_icmp_socket(void) FAST_FUNC;
975  int create_icmp6_socket(void) FAST_FUNC;  int create_icmp6_socket(void) FAST_FUNC;
# Line 1005  extern void run_applet_no_and_exit(int a Line 1021  extern void run_applet_no_and_exit(int a
1021    
1022  #ifdef HAVE_MNTENT_H  #ifdef HAVE_MNTENT_H
1023  extern int match_fstype(const struct mntent *mt, const char *fstypes) FAST_FUNC;  extern int match_fstype(const struct mntent *mt, const char *fstypes) FAST_FUNC;
1024  extern struct mntent *find_mount_point(const char *name, const char *table) FAST_FUNC;  extern struct mntent *find_mount_point(const char *name, int subdir_too) FAST_FUNC;
1025  #endif  #endif
1026  extern void erase_mtab(const char * name) FAST_FUNC;  extern void erase_mtab(const char * name) FAST_FUNC;
1027  extern unsigned int tty_baud_to_value(speed_t speed) FAST_FUNC;  extern unsigned int tty_baud_to_value(speed_t speed) FAST_FUNC;
1028  extern speed_t tty_value_to_baud(unsigned int value) FAST_FUNC;  extern speed_t tty_value_to_baud(unsigned int value) FAST_FUNC;
1029  extern void bb_warn_ignoring_args(int n) FAST_FUNC;  #if ENABLE_DESKTOP
1030    extern void bb_warn_ignoring_args(char *arg) FAST_FUNC;
1031    #else
1032    # define bb_warn_ignoring_args(arg) ((void)0)
1033    #endif
1034    
1035  extern int get_linux_version_code(void) FAST_FUNC;  extern int get_linux_version_code(void) FAST_FUNC;
1036    
# Line 1021  extern int del_loop(const char *device) Line 1041  extern int del_loop(const char *device)
1041   * return value: 1: read-only loopdev was setup, 0: rw, < 0: error */   * return value: 1: read-only loopdev was setup, 0: rw, < 0: error */
1042  extern int set_loop(char **devname, const char *file, unsigned long long offset) FAST_FUNC;  extern int set_loop(char **devname, const char *file, unsigned long long offset) FAST_FUNC;
1043    
1044    /* Like bb_ask below, but asks on stdin with no timeout.  */
1045    char *bb_ask_stdin(const char * prompt) FAST_FUNC;
1046  //TODO: pass buf pointer or return allocated buf (avoid statics)?  //TODO: pass buf pointer or return allocated buf (avoid statics)?
1047  char *bb_askpass(int timeout, const char * prompt) FAST_FUNC;  char *bb_ask(const int fd, int timeout, const char * prompt) FAST_FUNC;
1048  int bb_ask_confirmation(void) FAST_FUNC;  int bb_ask_confirmation(void) FAST_FUNC;
1049    
1050  int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC;  int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC;
# Line 1078  const char *get_signame(int number) FAST Line 1099  const char *get_signame(int number) FAST
1099  void print_signames(void) FAST_FUNC;  void print_signames(void) FAST_FUNC;
1100    
1101  char *bb_simplify_path(const char *path) FAST_FUNC;  char *bb_simplify_path(const char *path) FAST_FUNC;
1102    /* Returns ptr to NUL */
1103    char *bb_simplify_abs_path_inplace(char *path) FAST_FUNC;
1104    
1105  #define FAIL_DELAY 3  #define FAIL_DELAY 3
1106  extern void bb_do_delay(int seconds) FAST_FUNC;  extern void bb_do_delay(int seconds) FAST_FUNC;
# Line 1127  extern int obscure(const char *old, cons Line 1150  extern int obscure(const char *old, cons
1150   * (otherwise we risk having same salt generated)   * (otherwise we risk having same salt generated)
1151   */   */
1152  extern int crypt_make_salt(char *p, int cnt, int rnd) FAST_FUNC;  extern int crypt_make_salt(char *p, int cnt, int rnd) FAST_FUNC;
1153    
1154  /* Returns number of lines changed, or -1 on error */  /* Returns number of lines changed, or -1 on error */
1155  extern int update_passwd(const char *filename, const char *username,  #if !(ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP)
1156   const char *new_pw) FAST_FUNC;  #define update_passwd(filename, username, data, member) \
1157     update_passwd(filename, username, data)
1158    #endif
1159    extern int update_passwd(const char *filename,
1160     const char *username,
1161     const char *data,
1162     const char *member) FAST_FUNC;
1163    
1164  int index_in_str_array(const char *const string_array[], const char *key) FAST_FUNC;  int index_in_str_array(const char *const string_array[], const char *key) FAST_FUNC;
1165  int index_in_strings(const char *strings, const char *key) FAST_FUNC;  int index_in_strings(const char *strings, const char *key) FAST_FUNC;
# Line 1140  const char *nth_string(const char *strin Line 1170  const char *nth_string(const char *strin
1170  extern void print_login_issue(const char *issue_file, const char *tty) FAST_FUNC;  extern void print_login_issue(const char *issue_file, const char *tty) FAST_FUNC;
1171  extern void print_login_prompt(void) FAST_FUNC;  extern void print_login_prompt(void) FAST_FUNC;
1172    
1173    char *xmalloc_ttyname(int fd) FAST_FUNC RETURNS_MALLOC;
1174  /* NB: typically you want to pass fd 0, not 1. Think 'applet | grep something' */  /* NB: typically you want to pass fd 0, not 1. Think 'applet | grep something' */
1175  int get_terminal_width_height(int fd, unsigned *width, unsigned *height) FAST_FUNC;  int get_terminal_width_height(int fd, unsigned *width, unsigned *height) FAST_FUNC;
1176    
# Line 1171  unsigned long long bb_makedev(unsigned i Line 1202  unsigned long long bb_makedev(unsigned i
1202  #endif  #endif
1203    
1204    
1205    /* "Keycodes" that report an escape sequence.
1206     * We use something which fits into signed char,
1207     * yet doesn't represent any valid Unicode character.
1208     * Also, -1 is reserved for error indication and we don't use it. */
1209    enum {
1210     KEYCODE_UP       =  -2,
1211     KEYCODE_DOWN     =  -3,
1212     KEYCODE_RIGHT    =  -4,
1213     KEYCODE_LEFT     =  -5,
1214     KEYCODE_HOME     =  -6,
1215     KEYCODE_END      =  -7,
1216     KEYCODE_INSERT   =  -8,
1217     KEYCODE_DELETE   =  -9,
1218     KEYCODE_PAGEUP   = -10,
1219     KEYCODE_PAGEDOWN = -11,
1220    
1221     KEYCODE_CTRL_UP    = KEYCODE_UP    & ~0x40,
1222     KEYCODE_CTRL_DOWN  = KEYCODE_DOWN  & ~0x40,
1223     KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40,
1224     KEYCODE_CTRL_LEFT  = KEYCODE_LEFT  & ~0x40,
1225    #if 0
1226     KEYCODE_FUN1     = -12,
1227     KEYCODE_FUN2     = -13,
1228     KEYCODE_FUN3     = -14,
1229     KEYCODE_FUN4     = -15,
1230     KEYCODE_FUN5     = -16,
1231     KEYCODE_FUN6     = -17,
1232     KEYCODE_FUN7     = -18,
1233     KEYCODE_FUN8     = -19,
1234     KEYCODE_FUN9     = -20,
1235     KEYCODE_FUN10    = -21,
1236     KEYCODE_FUN11    = -22,
1237     KEYCODE_FUN12    = -23,
1238    #endif
1239     KEYCODE_CURSOR_POS = -0x100, /* 0xfff..fff00 */
1240     /* How long is the longest ESC sequence we know?
1241     * We want it big enough to be able to contain
1242     * cursor position sequence "ESC [ 9999 ; 9999 R"
1243     */
1244     KEYCODE_BUFFER_SIZE = 16
1245    };
1246    /* Note: fd may be in blocking or non-blocking mode, both make sense.
1247     * For one, less uses non-blocking mode.
1248     * Only the first read syscall inside read_key may block indefinitely
1249     * (unless fd is in non-blocking mode),
1250     * subsequent reads will time out after a few milliseconds.
1251     * Return of -1 means EOF or error (errno == 0 on EOF).
1252     * buffer[0] is used as a counter of buffered chars and must be 0
1253     * on first call.
1254     */
1255    int64_t read_key(int fd, char *buffer) FAST_FUNC;
1256    
1257    
1258  #if ENABLE_FEATURE_EDITING  #if ENABLE_FEATURE_EDITING
1259  /* It's NOT just ENABLEd or disabled. It's a number: */  /* It's NOT just ENABLEd or disabled. It's a number: */
1260  #ifdef CONFIG_FEATURE_EDITING_HISTORY  # ifdef CONFIG_FEATURE_EDITING_HISTORY
1261  #define MAX_HISTORY (CONFIG_FEATURE_EDITING_HISTORY + 0)  #  define MAX_HISTORY (CONFIG_FEATURE_EDITING_HISTORY + 0)
1262  #else  # else
1263  #define MAX_HISTORY 0  #  define MAX_HISTORY 0
1264  #endif  # endif
1265  typedef struct line_input_t {  typedef struct line_input_t {
1266   int flags;   int flags;
1267   const char *path_lookup;   const char *path_lookup;
1268  #if MAX_HISTORY  # if MAX_HISTORY
1269   int cnt_history;   int cnt_history;
1270   int cur_history;   int cur_history;
1271   USE_FEATURE_EDITING_SAVEHISTORY(const char *hist_file;)  #  if ENABLE_FEATURE_EDITING_SAVEHISTORY
1272     unsigned cnt_history_in_file;
1273     const char *hist_file;
1274    #  endif
1275   char *history[MAX_HISTORY + 1];   char *history[MAX_HISTORY + 1];
1276  #endif  # endif
1277  } line_input_t;  } line_input_t;
1278  enum {  enum {
1279   DO_HISTORY = 1 * (MAX_HISTORY > 0),   DO_HISTORY = 1 * (MAX_HISTORY > 0),
# Line 1198  enum { Line 1285  enum {
1285   FOR_SHELL = DO_HISTORY | SAVE_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION,   FOR_SHELL = DO_HISTORY | SAVE_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION,
1286  };  };
1287  line_input_t *new_line_input_t(int flags) FAST_FUNC;  line_input_t *new_line_input_t(int flags) FAST_FUNC;
1288  /* Returns:  /* So far static: void free_line_input_t(line_input_t *n) FAST_FUNC; */
1289    /* maxsize must be >= 2.
1290     * Returns:
1291   * -1 on read errors or EOF, or on bare Ctrl-D,   * -1 on read errors or EOF, or on bare Ctrl-D,
1292   * 0  on ctrl-C (the line entered is still returned in 'command'),   * 0  on ctrl-C (the line entered is still returned in 'command'),
1293   * >0 length of input string, including terminating '\n'   * >0 length of input string, including terminating '\n'
1294   */   */
1295  int read_line_input(const char* prompt, char* command, int maxsize, line_input_t *state) FAST_FUNC;  int read_line_input(const char* prompt, char* command, int maxsize, line_input_t *state) FAST_FUNC;
1296  #else  #else
1297    #define MAX_HISTORY 0
1298  int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC;  int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC;
1299  #define read_line_input(prompt, command, maxsize, state) \  #define read_line_input(prompt, command, maxsize, state) \
1300   read_line_input(prompt, command, maxsize)   read_line_input(prompt, command, maxsize)
# Line 1212  int read_line_input(const char* prompt, Line 1302  int read_line_input(const char* prompt,
1302    
1303    
1304  #ifndef COMM_LEN  #ifndef COMM_LEN
1305  #ifdef TASK_COMM_LEN  # ifdef TASK_COMM_LEN
1306  enum { COMM_LEN = TASK_COMM_LEN };  enum { COMM_LEN = TASK_COMM_LEN };
1307  #else  # else
1308  /* synchronize with sizeof(task_struct.comm) in /usr/include/linux/sched.h */  /* synchronize with sizeof(task_struct.comm) in /usr/include/linux/sched.h */
1309  enum { COMM_LEN = 16 };  enum { COMM_LEN = 16 };
1310  #endif  # endif
1311  #endif  #endif
1312  typedef struct procps_status_t {  typedef struct procps_status_t {
1313   DIR *dir;   DIR *dir;
1314     IF_FEATURE_SHOW_THREADS(DIR *task_dir;)
1315   uint8_t shift_pages_to_bytes;   uint8_t shift_pages_to_bytes;
1316   uint8_t shift_pages_to_kb;   uint8_t shift_pages_to_kb;
1317  /* Fields are set to 0/NULL if failed to determine (or not requested) */  /* Fields are set to 0/NULL if failed to determine (or not requested) */
1318   uint16_t argv_len;   uint16_t argv_len;
1319   char *argv0;   char *argv0;
1320   USE_SELINUX(char *context;)   char *exe;
1321     IF_SELINUX(char *context;)
1322   /* Everything below must contain no ptrs to malloc'ed data:   /* Everything below must contain no ptrs to malloc'ed data:
1323   * it is memset(0) for each process in procps_scan() */   * it is memset(0) for each process in procps_scan() */
1324   unsigned long vsz, rss; /* we round it to kbytes */   unsigned long vsz, rss; /* we round it to kbytes */
# Line 1238  typedef struct procps_status_t { Line 1330  typedef struct procps_status_t {
1330   unsigned sid;   unsigned sid;
1331   unsigned uid;   unsigned uid;
1332   unsigned gid;   unsigned gid;
1333    #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
1334     unsigned ruid;
1335     unsigned rgid;
1336     int niceness;
1337    #endif
1338   unsigned tty_major,tty_minor;   unsigned tty_major,tty_minor;
1339  #if ENABLE_FEATURE_TOPMEM  #if ENABLE_FEATURE_TOPMEM
1340   unsigned long mapped_rw;   unsigned long mapped_rw;
# Line 1258  typedef struct procps_status_t { Line 1355  typedef struct procps_status_t {
1355   int last_seen_on_cpu;   int last_seen_on_cpu;
1356  #endif  #endif
1357  } procps_status_t;  } procps_status_t;
1358    /* flag bits for procps_scan(xx, flags) calls */
1359  enum {  enum {
1360   PSSCAN_PID      = 1 << 0,   PSSCAN_PID      = 1 << 0,
1361   PSSCAN_PPID     = 1 << 1,   PSSCAN_PPID     = 1 << 1,
# Line 1267  enum { Line 1365  enum {
1365   PSSCAN_COMM     = 1 << 5,   PSSCAN_COMM     = 1 << 5,
1366   /* PSSCAN_CMD      = 1 << 6, - use read_cmdline instead */   /* PSSCAN_CMD      = 1 << 6, - use read_cmdline instead */
1367   PSSCAN_ARGV0    = 1 << 7,   PSSCAN_ARGV0    = 1 << 7,
1368   /* PSSCAN_EXE      = 1 << 8, - not implemented */   PSSCAN_EXE      = 1 << 8,
1369   PSSCAN_STATE    = 1 << 9,   PSSCAN_STATE    = 1 << 9,
1370   PSSCAN_VSZ      = 1 << 10,   PSSCAN_VSZ      = 1 << 10,
1371   PSSCAN_RSS      = 1 << 11,   PSSCAN_RSS      = 1 << 11,
# Line 1280  enum { Line 1378  enum {
1378   PSSCAN_ARGVN    = (1 << 16) * (ENABLE_KILLALL   PSSCAN_ARGVN    = (1 << 16) * (ENABLE_KILLALL
1379   || ENABLE_PGREP || ENABLE_PKILL   || ENABLE_PGREP || ENABLE_PKILL
1380   || ENABLE_PIDOF   || ENABLE_PIDOF
1381   || ENABLE_SESTATUS   || ENABLE_SESTATUS
1382   ),   ),
1383   USE_SELINUX(PSSCAN_CONTEXT = 1 << 17,)   PSSCAN_CONTEXT  = (1 << 17) * ENABLE_SELINUX,
1384   PSSCAN_START_TIME = 1 << 18,   PSSCAN_START_TIME = 1 << 18,
1385   PSSCAN_CPU      = 1 << 19,   PSSCAN_CPU      = (1 << 19) * ENABLE_FEATURE_TOP_SMP_PROCESS,
1386     PSSCAN_NICE     = (1 << 20) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
1387     PSSCAN_RUIDGID  = (1 << 21) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
1388     PSSCAN_TASKS = (1 << 22) * ENABLE_FEATURE_SHOW_THREADS,
1389   /* These are all retrieved from proc/NN/stat in one go: */   /* These are all retrieved from proc/NN/stat in one go: */
1390   PSSCAN_STAT     = PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID   PSSCAN_STAT     = PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID
1391   /**/            | PSSCAN_COMM | PSSCAN_STATE   /**/            | PSSCAN_COMM | PSSCAN_STATE
1392   /**/            | PSSCAN_VSZ | PSSCAN_RSS   /**/            | PSSCAN_VSZ | PSSCAN_RSS
1393   /**/            | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_START_TIME   /**/            | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_START_TIME
1394   /**/            | PSSCAN_TTY   /**/            | PSSCAN_TTY | PSSCAN_NICE
 #if ENABLE_FEATURE_TOP_SMP_PROCESS  
1395   /**/            | PSSCAN_CPU   /**/            | PSSCAN_CPU
 #endif  
1396  };  };
1397  //procps_status_t* alloc_procps_scan(void) FAST_FUNC;  //procps_status_t* alloc_procps_scan(void) FAST_FUNC;
1398  void free_procps_scan(procps_status_t* sp) FAST_FUNC;  void free_procps_scan(procps_status_t* sp) FAST_FUNC;
1399  procps_status_t* procps_scan(procps_status_t* sp, int flags) FAST_FUNC;  procps_status_t* procps_scan(procps_status_t* sp, int flags) FAST_FUNC;
1400  /* Format cmdline (up to col chars) into char buf[col+1] */  /* Format cmdline (up to col chars) into char buf[size] */
1401  /* Puts [comm] if cmdline is empty (-> process is a kernel thread) */  /* Puts [comm] if cmdline is empty (-> process is a kernel thread) */
1402  void read_cmdline(char *buf, int col, unsigned pid, const char *comm) FAST_FUNC;  void read_cmdline(char *buf, int size, unsigned pid, const char *comm) FAST_FUNC;
1403  pid_t *find_pid_by_name(const char* procName) FAST_FUNC;  pid_t *find_pid_by_name(const char* procName) FAST_FUNC;
1404  pid_t *pidlist_reverse(pid_t *pidList) FAST_FUNC;  pid_t *pidlist_reverse(pid_t *pidList) FAST_FUNC;
1405    
# Line 1310  extern const char bb_uuenc_tbl_std[]; Line 1409  extern const char bb_uuenc_tbl_std[];
1409  void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC;  void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC;
1410    
1411  typedef struct sha1_ctx_t {  typedef struct sha1_ctx_t {
1412   uint32_t count[2];   uint32_t hash[8];    /* 5, +3 elements for sha256 */
1413   uint32_t hash[5];   uint64_t total64;
1414   uint32_t wbuf[16];   uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */
1415     void (*process_block)(struct sha1_ctx_t*) FAST_FUNC;
1416  } sha1_ctx_t;  } sha1_ctx_t;
1417  void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;  void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;
1418  void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) FAST_FUNC;  void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) FAST_FUNC;
1419  void *sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC;  void sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC;
1420    typedef struct sha1_ctx_t sha256_ctx_t;
1421    void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
1422    #define sha256_hash sha1_hash
1423    #define sha256_end sha1_end
1424    typedef struct sha512_ctx_t {
1425     uint64_t hash[8];
1426     uint64_t total64[2];
1427     uint8_t wbuffer[128]; /* NB: always correctly aligned for uint64_t */
1428    } sha512_ctx_t;
1429    void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
1430    void sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) FAST_FUNC;
1431    void sha512_end(void *resbuf, sha512_ctx_t *ctx) FAST_FUNC;
1432    #if 1
1433  typedef struct md5_ctx_t {  typedef struct md5_ctx_t {
1434   uint32_t A;   uint32_t A;
1435   uint32_t B;   uint32_t B;
# Line 1327  typedef struct md5_ctx_t { Line 1439  typedef struct md5_ctx_t {
1439   uint32_t buflen;   uint32_t buflen;
1440   char buffer[128];   char buffer[128];
1441  } md5_ctx_t;  } md5_ctx_t;
1442    #else
1443    /* libbb/md5prime.c uses a bit different one: */
1444    typedef struct md5_ctx_t {
1445     uint32_t state[4]; /* state (ABCD) */
1446     uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
1447     unsigned char buffer[64]; /* input buffer */
1448    } md5_ctx_t;
1449    #endif
1450  void md5_begin(md5_ctx_t *ctx) FAST_FUNC;  void md5_begin(md5_ctx_t *ctx) FAST_FUNC;
1451  void md5_hash(const void *data, size_t length, md5_ctx_t *ctx) FAST_FUNC;  void md5_hash(const void *data, size_t length, md5_ctx_t *ctx) FAST_FUNC;
1452  void *md5_end(void *resbuf, md5_ctx_t *ctx) FAST_FUNC;  void md5_end(void *resbuf, md5_ctx_t *ctx) FAST_FUNC;
1453    
1454    
1455  uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;  uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;
1456    
# Line 1341  int print_flags_separated(const int *mas Line 1462  int print_flags_separated(const int *mas
1462   int flags, const char *separator) FAST_FUNC;   int flags, const char *separator) FAST_FUNC;
1463  int print_flags(const masks_labels_t *ml, int flags) FAST_FUNC;  int print_flags(const masks_labels_t *ml, int flags) FAST_FUNC;
1464    
1465    typedef struct bb_progress_t {
1466     off_t lastsize;
1467     unsigned lastupdate_sec;
1468     unsigned start_sec;
1469    } bb_progress_t;
1470    
1471    void bb_progress_init(bb_progress_t *p) FAST_FUNC;
1472    void bb_progress_update(bb_progress_t *p, const char *curfile,
1473     off_t beg_range, off_t transferred,
1474     off_t totalsize) FAST_FUNC;
1475    
1476  extern const char *applet_name;  extern const char *applet_name;
1477  /* "BusyBox vN.N.N (timestamp or extra_version)" */  /* "BusyBox vN.N.N (timestamp or extra_version)" */
# Line 1352  extern const char bb_msg_write_error[]; Line 1483  extern const char bb_msg_write_error[];
1483  extern const char bb_msg_unknown[];  extern const char bb_msg_unknown[];
1484  extern const char bb_msg_can_not_create_raw_socket[];  extern const char bb_msg_can_not_create_raw_socket[];
1485  extern const char bb_msg_perm_denied_are_you_root[];  extern const char bb_msg_perm_denied_are_you_root[];
1486    extern const char bb_msg_you_must_be_root[];
1487  extern const char bb_msg_requires_arg[];  extern const char bb_msg_requires_arg[];
1488  extern const char bb_msg_invalid_arg[];  extern const char bb_msg_invalid_arg[];
1489  extern const char bb_msg_standard_input[];  extern const char bb_msg_standard_input[];
# Line 1380  extern const int const_int_0; Line 1512  extern const int const_int_0;
1512  extern const int const_int_1;  extern const int const_int_1;
1513    
1514    
 #ifndef BUFSIZ  
 #define BUFSIZ 4096  
 #endif  
1515  /* Providing hard guarantee on minimum size (think of BUFSIZ == 128) */  /* Providing hard guarantee on minimum size (think of BUFSIZ == 128) */
1516  enum { COMMON_BUFSIZE = (BUFSIZ >= 256*sizeof(void*) ? BUFSIZ+1 : 256*sizeof(void*)) };  enum { COMMON_BUFSIZE = (BUFSIZ >= 256*sizeof(void*) ? BUFSIZ+1 : 256*sizeof(void*)) };
1517  extern char bb_common_bufsiz1[COMMON_BUFSIZE];  extern char bb_common_bufsiz1[COMMON_BUFSIZE];
# Line 1396  extern struct globals *const ptr_to_glob Line 1525  extern struct globals *const ptr_to_glob
1525  /* At least gcc 3.4.6 on mipsel system needs optimization barrier */  /* At least gcc 3.4.6 on mipsel system needs optimization barrier */
1526  #define barrier() __asm__ __volatile__("":::"memory")  #define barrier() __asm__ __volatile__("":::"memory")
1527  #define SET_PTR_TO_GLOBALS(x) do { \  #define SET_PTR_TO_GLOBALS(x) do { \
1528   (*(struct globals**)&ptr_to_globals) = (x); \   (*(struct globals**)&ptr_to_globals) = (void*)(x); \
1529   barrier(); \   barrier(); \
1530  } while (0)  } while (0)
1531    
# Line 1463  extern const char bb_default_login_shell Line 1592  extern const char bb_default_login_shell
1592  #define DEV_CONSOLE "/dev/console"  #define DEV_CONSOLE "/dev/console"
1593    
1594    
1595  #ifndef RB_POWER_OFF  #define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))
1596  /* Stop system and switch power off if possible.  */  
 #define RB_POWER_OFF   0x4321fedc  
 #endif  
1597    
1598  /* Make sure we call functions instead of macros.  */  /* We redefine ctype macros. Unicode-correct handling of char types
1599     * can't be done with such byte-oriented operations anyway,
1600     * we don't lose anything.
1601     */
1602  #undef isalnum  #undef isalnum
1603  #undef isalpha  #undef isalpha
1604  #undef isascii  #undef isascii
1605  #undef isblank  #undef isblank
1606  #undef iscntrl  #undef iscntrl
1607    #undef isdigit
1608  #undef isgraph  #undef isgraph
1609  #undef islower  #undef islower
1610  #undef isprint  #undef isprint
# Line 1481  extern const char bb_default_login_shell Line 1612  extern const char bb_default_login_shell
1612  #undef isspace  #undef isspace
1613  #undef isupper  #undef isupper
1614  #undef isxdigit  #undef isxdigit
1615    #undef toupper
1616    #undef tolower
1617    
1618  /* This one is more efficient - we save ~400 bytes */  /* We save ~500 bytes on isdigit alone.
1619  #undef isdigit   * BTW, x86 likes (unsigned char) cast more than (unsigned). */
 #define isdigit(a) ((unsigned)((a) - '0') <= 9)  
   
 #define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))  
1620    
1621    /* These work the same for ASCII and Unicode,
1622     * assuming no one asks "is this a *Unicode* letter?" using isalpha(letter) */
1623    #define isascii(a) ((unsigned char)(a) <= 0x7f)
1624    #define isdigit(a) ((unsigned char)((a) - '0') <= 9)
1625    #define isupper(a) ((unsigned char)((a) - 'A') <= ('Z' - 'A'))
1626    #define islower(a) ((unsigned char)((a) - 'a') <= ('z' - 'a'))
1627    #define isalpha(a) ((unsigned char)(((a)|0x20) - 'a') <= ('z' - 'a'))
1628    #define isblank(a) ({ unsigned char bb__isblank = (a); bb__isblank == ' ' || bb__isblank == '\t'; })
1629    #define iscntrl(a) ({ unsigned char bb__iscntrl = (a); bb__iscntrl < ' ' || bb__iscntrl == 0x7f; })
1630    /* In POSIX/C locale isspace is only these chars: "\t\n\v\f\r" and space.
1631     * "\t\n\v\f\r" happen to have ASCII codes 9,10,11,12,13.
1632     */
1633    #define isspace(a) ({ unsigned char bb__isspace = (a) - 9; bb__isspace == (' ' - 9) || bb__isspace <= (13 - 9); })
1634    // Unsafe wrt NUL: #define ispunct(a) (strchr("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", (a)) != NULL)
1635    #define ispunct(a) (strchrnul("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", (a))[0])
1636    // Bigger code: #define isalnum(a) ({ unsigned char bb__isalnum = (a) - '0'; bb__isalnum <= 9 || ((bb__isalnum - ('A' - '0')) & 0xdf) <= 25; })
1637    #define isalnum(a) bb_ascii_isalnum(a)
1638    static ALWAYS_INLINE int bb_ascii_isalnum(unsigned char a)
1639    {
1640     unsigned char b = a - '0';
1641     if (b <= 9)
1642     return (b <= 9);
1643     b = (a|0x20) - 'a';
1644     return b <= 'z' - 'a';
1645    }
1646    #define isxdigit(a) bb_ascii_isxdigit(a)
1647    static ALWAYS_INLINE int bb_ascii_isxdigit(unsigned char a)
1648    {
1649     unsigned char b = a - '0';
1650     if (b <= 9)
1651     return (b <= 9);
1652     b = (a|0x20) - 'a';
1653     return b <= 'f' - 'a';
1654    }
1655    #define toupper(a) bb_ascii_toupper(a)
1656    static ALWAYS_INLINE unsigned char bb_ascii_toupper(unsigned char a)
1657    {
1658     unsigned char b = a - 'a';
1659     if (b <= ('z' - 'a'))
1660     a -= 'a' - 'A';
1661     return a;
1662    }
1663    #define tolower(a) bb_ascii_tolower(a)
1664    static ALWAYS_INLINE unsigned char bb_ascii_tolower(unsigned char a)
1665    {
1666     unsigned char b = a - 'A';
1667     if (b <= ('Z' - 'A'))
1668     a += 'a' - 'A';
1669     return a;
1670    }
1671    
1672    /* In ASCII and Unicode, these are likely to be very different.
1673     * Let's prevent ambiguous usage from the start */
1674    #define isgraph(a) isgraph_is_ambiguous_dont_use(a)
1675    #define isprint(a) isprint_is_ambiguous_dont_use(a)
1676    /* NB: must not treat EOF as isgraph or isprint */
1677    #define isgraph_asciionly(a) ((unsigned)((a) - 0x21) <= 0x7e - 0x21)
1678    #define isprint_asciionly(a) ((unsigned)((a) - 0x20) <= 0x7e - 0x20)
1679    
 #if __GNUC_PREREQ(4,1)  
 # pragma GCC visibility pop  
 #endif  
1680    
1681    POP_SAVED_FUNCTION_VISIBILITY
1682    
1683  #endif /* __LIBBUSYBOX_H__ */  #endif

Legend:
Removed from v.983  
changed lines
  Added in v.984