1
2
3
4
5
6
7
8
9
10#ifndef LIBBB_H
11#define LIBBB_H 1
12
13#include "platform.h"
14
15#include <ctype.h>
16#include <dirent.h>
17#include <errno.h>
18#include <fcntl.h>
19#include <inttypes.h>
20#include <netdb.h>
21#include <setjmp.h>
22#include <signal.h>
23#if defined __UCLIBC__
24
25# define sigfillset(s) __sigfillset(s)
26# define sigemptyset(s) __sigemptyset(s)
27# define sigisemptyset(s) __sigisemptyset(s)
28#endif
29#include <stdint.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <stdarg.h>
33#include <stddef.h>
34#include <string.h>
35
36
37#include <libgen.h>
38#undef basename
39#define basename dont_use_basename
40#include <poll.h>
41#include <sys/ioctl.h>
42#include <sys/mman.h>
43#include <sys/socket.h>
44#include <sys/stat.h>
45#include <sys/time.h>
46#include <sys/types.h>
47#ifndef major
48# include <sys/sysmacros.h>
49#endif
50#include <sys/wait.h>
51#include <termios.h>
52#include <time.h>
53#include <sys/param.h>
54#include <pwd.h>
55#include <grp.h>
56#if ENABLE_FEATURE_SHADOWPASSWDS
57# if !ENABLE_USE_BB_SHADOW
58
59
60
61# include <shadow.h>
62# endif
63#endif
64#if defined(ANDROID) || defined(__ANDROID__)
65# define endpwent() ((void)0)
66# define endgrent() ((void)0)
67#endif
68#ifdef HAVE_MNTENT_H
69# include <mntent.h>
70#endif
71#ifdef HAVE_SYS_STATFS_H
72# include <sys/statfs.h>
73#endif
74
75
76
77
78
79
80#if ENABLE_SELINUX
81# include <selinux/selinux.h>
82# include <selinux/context.h>
83# include <selinux/flask.h>
84# include <selinux/av_permissions.h>
85#endif
86#if ENABLE_FEATURE_UTMP
87# include <utmp.h>
88#endif
89#if ENABLE_LOCALE_SUPPORT
90# include <locale.h>
91#else
92# define setlocale(x,y) ((void)0)
93#endif
94#ifdef DMALLOC
95# include <dmalloc.h>
96#endif
97
98#ifndef _PATH_PASSWD
99#define _PATH_PASSWD "/etc/passwd"
100#endif
101#ifndef _PATH_GROUP
102#define _PATH_GROUP "/etc/group"
103#endif
104#ifndef _PATH_SHADOW
105#define _PATH_SHADOW "/etc/shadow"
106#endif
107#ifndef _PATH_GSHADOW
108#define _PATH_GSHADOW "/etc/gshadow"
109#endif
110#if defined __FreeBSD__ || defined __OpenBSD__
111# include <netinet/in.h>
112# include <arpa/inet.h>
113#elif defined __APPLE__
114# include <netinet/in.h>
115#else
116# include <arpa/inet.h>
117# if !defined(__socklen_t_defined) && !defined(_SOCKLEN_T_DECLARED)
118
119
120
121
122# define socklen_t bb_socklen_t
123 typedef unsigned socklen_t;
124# endif
125#endif
126#ifndef HAVE_CLEARENV
127# define clearenv() do { if (environ) environ[0] = NULL; } while (0)
128#endif
129#ifndef HAVE_FDATASYNC
130# define fdatasync fsync
131#endif
132#ifndef HAVE_XTABS
133# define XTABS TAB3
134#endif
135
136
137
138
139extern char **environ;
140#if defined(__GLIBC__) && __GLIBC__ < 2
141int vdprintf(int d, const char *format, va_list ap);
142#endif
143
144int klogctl(int type, char *b, int len);
145#ifndef PATH_MAX
146# define PATH_MAX 256
147#endif
148#ifndef BUFSIZ
149# define BUFSIZ 4096
150#endif
151
152
153
154#ifdef HAVE_UNLOCKED_STDIO
155# undef getc
156# define getc(stream) getc_unlocked(stream)
157# undef getchar
158# define getchar() getchar_unlocked()
159# undef putc
160# define putc(c, stream) putc_unlocked(c, stream)
161# undef putchar
162# define putchar(c) putchar_unlocked(c)
163# undef fgetc
164# define fgetc(stream) getc_unlocked(stream)
165# undef fputc
166# define fputc(c, stream) putc_unlocked(c, stream)
167#endif
168
169#ifdef HAVE_UNLOCKED_LINE_OPS
170# undef fgets
171# define fgets(s, n, stream) fgets_unlocked(s, n, stream)
172# undef fputs
173# define fputs(s, stream) fputs_unlocked(s, stream)
174#endif
175
176
177
178
179PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
180
181
182#if ENABLE_USE_BB_PWD_GRP
183# include "pwd_.h"
184# include "grp_.h"
185#endif
186#if ENABLE_FEATURE_SHADOWPASSWDS
187# if ENABLE_USE_BB_SHADOW
188# include "shadow_.h"
189# endif
190#endif
191
192
193#define MAXINT(T) (T)( \
194 ((T)-1) > 0 \
195 ? (T)-1 \
196 : (T)~((T)1 << (sizeof(T)*8-1)) \
197 )
198
199#define MININT(T) (T)( \
200 ((T)-1) > 0 \
201 ? (T)0 \
202 : ((T)1 << (sizeof(T)*8-1)) \
203 )
204
205
206
207
208
209
210
211
212
213#if ENABLE_LFS
214
215# if ULONG_MAX > 0xffffffff
216
217typedef unsigned long uoff_t;
218# define XATOOFF(a) xatoul_range((a), 0, LONG_MAX)
219
220# define BB_STRTOOFF bb_strtoul
221# define STRTOOFF strtoul
222
223# define OFF_FMT "l"
224# else
225
226typedef unsigned long long uoff_t;
227# define XATOOFF(a) xatoull_range((a), 0, LLONG_MAX)
228# define BB_STRTOOFF bb_strtoull
229# define STRTOOFF strtoull
230# define OFF_FMT "ll"
231# endif
232#else
233
234# if UINT_MAX == 0xffffffff
235
236
237typedef unsigned long uoff_t;
238# define XATOOFF(a) xatoi_positive(a)
239# define BB_STRTOOFF bb_strtou
240# define STRTOOFF strtol
241# define OFF_FMT "l"
242# else
243typedef unsigned long uoff_t;
244# define XATOOFF(a) xatoul_range((a), 0, LONG_MAX)
245# define BB_STRTOOFF bb_strtoul
246# define STRTOOFF strtol
247# define OFF_FMT "l"
248# endif
249#endif
250
251#define OFF_T_MAX ((off_t)~((off_t)1 << (sizeof(off_t)*8-1)))
252
253
254
255struct BUG_off_t_size_is_misdetected {
256 char BUG_off_t_size_is_misdetected[sizeof(off_t) == sizeof(uoff_t) ? 1 : -1];
257};
258
259
260#undef FALSE
261#define FALSE ((int) 0)
262#undef TRUE
263#define TRUE ((int) 1)
264#undef SKIP
265#define SKIP ((int) 2)
266
267
268#ifndef MIN
269#define MIN(a,b) (((a)<(b))?(a):(b))
270#endif
271
272#ifndef MAX
273#define MAX(a,b) (((a)>(b))?(a):(b))
274#endif
275
276
277#if ENABLE_FEATURE_BUFFERS_GO_ON_STACK
278#define RESERVE_CONFIG_BUFFER(buffer,len) char buffer[len]
279#define RESERVE_CONFIG_UBUFFER(buffer,len) unsigned char buffer[len]
280#define RELEASE_CONFIG_BUFFER(buffer) ((void)0)
281#else
282#if ENABLE_FEATURE_BUFFERS_GO_IN_BSS
283#define RESERVE_CONFIG_BUFFER(buffer,len) static char buffer[len]
284#define RESERVE_CONFIG_UBUFFER(buffer,len) static unsigned char buffer[len]
285#define RELEASE_CONFIG_BUFFER(buffer) ((void)0)
286#else
287#define RESERVE_CONFIG_BUFFER(buffer,len) char *buffer = xmalloc(len)
288#define RESERVE_CONFIG_UBUFFER(buffer,len) unsigned char *buffer = xmalloc(len)
289#define RELEASE_CONFIG_BUFFER(buffer) free(buffer)
290#endif
291#endif
292
293#if defined(__GLIBC__)
294
295
296extern int *const bb_errno;
297#undef errno
298#define errno (*bb_errno)
299#endif
300
301#if !(ULONG_MAX > 0xffffffff)
302
303uint64_t bb_bswap_64(uint64_t x) FAST_FUNC;
304#endif
305
306unsigned long long monotonic_ns(void) FAST_FUNC;
307unsigned long long monotonic_us(void) FAST_FUNC;
308unsigned long long monotonic_ms(void) FAST_FUNC;
309unsigned monotonic_sec(void) FAST_FUNC;
310
311extern void chomp(char *s) FAST_FUNC;
312extern void trim(char *s) FAST_FUNC;
313extern char *skip_whitespace(const char *) FAST_FUNC;
314extern char *skip_non_whitespace(const char *) FAST_FUNC;
315extern char *skip_dev_pfx(const char *tty_name) FAST_FUNC;
316
317extern char *strrstr(const char *haystack, const char *needle) FAST_FUNC;
318
319
320extern const char *bb_mode_string(mode_t mode) FAST_FUNC;
321extern int is_directory(const char *name, int followLinks) FAST_FUNC;
322enum {
323 FILEUTILS_PRESERVE_STATUS = 1 << 0,
324 FILEUTILS_DEREFERENCE = 1 << 1,
325 FILEUTILS_RECUR = 1 << 2,
326 FILEUTILS_FORCE = 1 << 3,
327 FILEUTILS_INTERACTIVE = 1 << 4,
328 FILEUTILS_MAKE_HARDLINK = 1 << 5,
329 FILEUTILS_MAKE_SOFTLINK = 1 << 6,
330 FILEUTILS_DEREF_SOFTLINK = 1 << 7,
331 FILEUTILS_DEREFERENCE_L0 = 1 << 8,
332#if ENABLE_SELINUX
333 FILEUTILS_PRESERVE_SECURITY_CONTEXT = 1 << 9,
334 FILEUTILS_SET_SECURITY_CONTEXT = 1 << 10,
335#endif
336 FILEUTILS_IGNORE_CHMOD_ERR = 1 << 11,
337};
338#define FILEUTILS_CP_OPTSTR "pdRfilsLH" IF_SELINUX("c")
339extern int remove_file(const char *path, int flags) FAST_FUNC;
340
341
342
343
344extern int copy_file(const char *source, const char *dest, int flags) FAST_FUNC;
345
346enum {
347 ACTION_RECURSE = (1 << 0),
348 ACTION_FOLLOWLINKS = (1 << 1),
349 ACTION_FOLLOWLINKS_L0 = (1 << 2),
350 ACTION_DEPTHFIRST = (1 << 3),
351
352 ACTION_QUIET = (1 << 5),
353 ACTION_DANGLING_OK = (1 << 6),
354};
355typedef uint8_t recurse_flags_t;
356extern int recursive_action(const char *fileName, unsigned flags,
357 int FAST_FUNC (*fileAction)(const char *fileName, struct stat* statbuf, void* userData, int depth),
358 int FAST_FUNC (*dirAction)(const char *fileName, struct stat* statbuf, void* userData, int depth),
359 void* userData, unsigned depth) FAST_FUNC;
360extern int device_open(const char *device, int mode) FAST_FUNC;
361enum { GETPTY_BUFSIZE = 16 };
362extern int xgetpty(char *line) FAST_FUNC;
363extern int get_console_fd_or_die(void) FAST_FUNC;
364extern void console_make_active(int fd, const int vt_num) FAST_FUNC;
365extern char *find_block_device(const char *path) FAST_FUNC;
366
367extern off_t bb_copyfd_eof(int fd1, int fd2) FAST_FUNC;
368extern off_t bb_copyfd_size(int fd1, int fd2, off_t size) FAST_FUNC;
369extern void bb_copyfd_exact_size(int fd1, int fd2, off_t size) FAST_FUNC;
370
371
372extern void complain_copyfd_and_die(off_t sz) NORETURN FAST_FUNC;
373
374extern char bb_process_escape_sequence(const char **ptr) FAST_FUNC;
375char* strcpy_and_process_escape_sequences(char *dst, const char *src) FAST_FUNC;
376
377
378
379
380
381
382char *bb_get_last_path_component_strip(char *path) FAST_FUNC;
383
384char *bb_get_last_path_component_nostrip(const char *path) FAST_FUNC;
385
386const char *bb_basename(const char *name) FAST_FUNC;
387
388char *last_char_is(const char *s, int c) FAST_FUNC;
389const char* endofname(const char *name) FAST_FUNC;
390
391void ndelay_on(int fd) FAST_FUNC;
392void ndelay_off(int fd) FAST_FUNC;
393void close_on_exec_on(int fd) FAST_FUNC;
394void xdup2(int, int) FAST_FUNC;
395void xmove_fd(int, int) FAST_FUNC;
396
397
398DIR *xopendir(const char *path) FAST_FUNC;
399DIR *warn_opendir(const char *path) FAST_FUNC;
400
401char *xmalloc_realpath(const char *path) FAST_FUNC RETURNS_MALLOC;
402char *xmalloc_readlink(const char *path) FAST_FUNC RETURNS_MALLOC;
403char *xmalloc_readlink_or_warn(const char *path) FAST_FUNC RETURNS_MALLOC;
404
405char *xrealloc_getcwd_or_warn(char *cwd) FAST_FUNC;
406
407char *xmalloc_follow_symlinks(const char *path) FAST_FUNC RETURNS_MALLOC;
408
409
410enum {
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425 BB_FATAL_SIGS = (int)(0
426 + (1LL << SIGHUP)
427 + (1LL << SIGINT)
428 + (1LL << SIGTERM)
429 + (1LL << SIGPIPE)
430 + (1LL << SIGQUIT)
431 + (1LL << SIGABRT)
432 + (1LL << SIGALRM)
433 + (1LL << SIGVTALRM)
434 + (1LL << SIGXCPU)
435 + (1LL << SIGXFSZ)
436 + (1LL << SIGUSR1)
437 + (1LL << SIGUSR2)
438 + 0),
439};
440void bb_signals(int sigs, void (*f)(int)) FAST_FUNC;
441
442
443
444void bb_signals_recursive_norestart(int sigs, void (*f)(int)) FAST_FUNC;
445
446void signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int)) FAST_FUNC;
447
448void signal_SA_RESTART_empty_mask(int sig, void (*handler)(int)) FAST_FUNC;
449void wait_for_any_sig(void) FAST_FUNC;
450void kill_myself_with_sig(int sig) NORETURN FAST_FUNC;
451void sig_block(int sig) FAST_FUNC;
452void sig_unblock(int sig) FAST_FUNC;
453
454int sigaction_set(int sig, const struct sigaction *act) FAST_FUNC;
455
456int sigprocmask_allsigs(int how) FAST_FUNC;
457
458extern smallint bb_got_signal;
459void record_signo(int signo);
460
461
462void xsetgid(gid_t gid) FAST_FUNC;
463void xsetuid(uid_t uid) FAST_FUNC;
464void xsetegid(gid_t egid) FAST_FUNC;
465void xseteuid(uid_t euid) FAST_FUNC;
466void xchdir(const char *path) FAST_FUNC;
467void xchroot(const char *path) FAST_FUNC;
468void xsetenv(const char *key, const char *value) FAST_FUNC;
469void bb_unsetenv(const char *key) FAST_FUNC;
470void bb_unsetenv_and_free(char *key) FAST_FUNC;
471void xunlink(const char *pathname) FAST_FUNC;
472void xstat(const char *pathname, struct stat *buf) FAST_FUNC;
473void xfstat(int fd, struct stat *buf, const char *errmsg) FAST_FUNC;
474int open3_or_warn(const char *pathname, int flags, int mode) FAST_FUNC;
475int open_or_warn(const char *pathname, int flags) FAST_FUNC;
476int xopen3(const char *pathname, int flags, int mode) FAST_FUNC;
477int xopen(const char *pathname, int flags) FAST_FUNC;
478int xopen_nonblocking(const char *pathname) FAST_FUNC;
479int xopen_as_uid_gid(const char *pathname, int flags, uid_t u, gid_t g) FAST_FUNC;
480int open_or_warn_stdin(const char *pathname) FAST_FUNC;
481int xopen_stdin(const char *pathname) FAST_FUNC;
482void xrename(const char *oldpath, const char *newpath) FAST_FUNC;
483int rename_or_warn(const char *oldpath, const char *newpath) FAST_FUNC;
484off_t xlseek(int fd, off_t offset, int whence) FAST_FUNC;
485int xmkstemp(char *template) FAST_FUNC;
486off_t fdlength(int fd) FAST_FUNC;
487
488uoff_t FAST_FUNC get_volume_size_in_bytes(int fd,
489 const char *override,
490 unsigned override_units,
491 int extend);
492
493void xpipe(int filedes[2]) FAST_FUNC;
494
495struct fd_pair { int rd; int wr; };
496#define piped_pair(pair) pipe(&((pair).rd))
497#define xpiped_pair(pair) xpipe(&((pair).rd))
498
499
500typedef int8_t socktype_t;
501typedef int8_t family_t;
502struct BUG_too_small {
503 char BUG_socktype_t_too_small[(0
504 | SOCK_STREAM
505 | SOCK_DGRAM
506 | SOCK_RDM
507 | SOCK_SEQPACKET
508 | SOCK_RAW
509 ) <= 127 ? 1 : -1];
510 char BUG_family_t_too_small[(0
511 | AF_UNSPEC
512 | AF_INET
513 | AF_INET6
514 | AF_UNIX
515#ifdef AF_PACKET
516 | AF_PACKET
517#endif
518#ifdef AF_NETLINK
519 | AF_NETLINK
520#endif
521
522
523 ) <= 127 ? 1 : -1];
524};
525
526
527void parse_datestr(const char *date_str, struct tm *ptm) FAST_FUNC;
528time_t validate_tm_time(const char *date_str, struct tm *ptm) FAST_FUNC;
529char *strftime_HHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC;
530char *strftime_YYYYMMDDHHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC;
531
532int xsocket(int domain, int type, int protocol) FAST_FUNC;
533void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) FAST_FUNC;
534void xlisten(int s, int backlog) FAST_FUNC;
535void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) FAST_FUNC;
536ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
537 socklen_t tolen) FAST_FUNC;
538
539
540
541
542
543
544void setsockopt_reuseaddr(int fd) FAST_FUNC;
545int setsockopt_broadcast(int fd) FAST_FUNC;
546int setsockopt_bindtodevice(int fd, const char *iface) FAST_FUNC;
547
548unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port) FAST_FUNC;
549typedef struct len_and_sockaddr {
550 socklen_t len;
551 union {
552 struct sockaddr sa;
553 struct sockaddr_in sin;
554#if ENABLE_FEATURE_IPV6
555 struct sockaddr_in6 sin6;
556#endif
557 } u;
558} len_and_sockaddr;
559enum {
560 LSA_LEN_SIZE = offsetof(len_and_sockaddr, u),
561 LSA_SIZEOF_SA = sizeof(
562 union {
563 struct sockaddr sa;
564 struct sockaddr_in sin;
565#if ENABLE_FEATURE_IPV6
566 struct sockaddr_in6 sin6;
567#endif
568 }
569 )
570};
571
572
573
574
575
576
577int xsocket_type(len_and_sockaddr **lsap, int af, int sock_type) FAST_FUNC;
578int xsocket_stream(len_and_sockaddr **lsap) FAST_FUNC;
579
580
581
582
583
584int create_and_bind_stream_or_die(const char *bindaddr, int port) FAST_FUNC;
585int create_and_bind_dgram_or_die(const char *bindaddr, int port) FAST_FUNC;
586
587
588
589
590int create_and_connect_stream_or_die(const char *peer, int port) FAST_FUNC;
591
592int xconnect_stream(const len_and_sockaddr *lsa) FAST_FUNC;
593
594len_and_sockaddr *get_sock_lsa(int fd) FAST_FUNC RETURNS_MALLOC;
595
596len_and_sockaddr *get_peer_lsa(int fd) FAST_FUNC RETURNS_MALLOC;
597
598
599
600
601
602len_and_sockaddr* host2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
603
604len_and_sockaddr* xhost2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
605len_and_sockaddr* xdotted2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
606
607#if !ENABLE_FEATURE_IPV6
608#define host_and_af2sockaddr(host, port, af) host2sockaddr((host), (port))
609#define xhost_and_af2sockaddr(host, port, af) xhost2sockaddr((host), (port))
610#else
611len_and_sockaddr* host_and_af2sockaddr(const char *host, int port, sa_family_t af) FAST_FUNC RETURNS_MALLOC;
612len_and_sockaddr* xhost_and_af2sockaddr(const char *host, int port, sa_family_t af) FAST_FUNC RETURNS_MALLOC;
613#endif
614
615
616
617void set_nport(struct sockaddr *sa, unsigned port) FAST_FUNC;
618
619int get_nport(const struct sockaddr *sa) FAST_FUNC;
620
621char* xmalloc_sockaddr2host(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
622
623char* xmalloc_sockaddr2host_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
624
625char* xmalloc_sockaddr2hostonly_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
626
627char* xmalloc_sockaddr2dotted(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
628char* xmalloc_sockaddr2dotted_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
629
630
631struct hostent *xgethostbyname(const char *name) FAST_FUNC;
632
633
634
635
636void socket_want_pktinfo(int fd) FAST_FUNC;
637ssize_t send_to_from(int fd, void *buf, size_t len, int flags,
638 const struct sockaddr *to,
639 const struct sockaddr *from,
640 socklen_t tolen) FAST_FUNC;
641ssize_t recv_from_to(int fd, void *buf, size_t len, int flags,
642 struct sockaddr *from,
643 struct sockaddr *to,
644 socklen_t sa_size) FAST_FUNC;
645
646uint16_t inet_cksum(uint16_t *addr, int len) FAST_FUNC;
647
648char *xstrdup(const char *s) FAST_FUNC RETURNS_MALLOC;
649char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC;
650void overlapping_strcpy(char *dst, const char *src) FAST_FUNC;
651char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC;
652char *strncpy_IFNAMSIZ(char *dst, const char *src) FAST_FUNC;
653
654
655int bb_putchar(int ch) FAST_FUNC;
656
657int bb_putchar_stderr(char ch) FAST_FUNC;
658char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC;
659
660
661
662
663
664
665#define LONE_DASH(s) ((s)[0] == '-' && !(s)[1])
666#define NOT_LONE_DASH(s) ((s)[0] != '-' || (s)[1])
667#define LONE_CHAR(s,c) ((s)[0] == (c) && !(s)[1])
668#define NOT_LONE_CHAR(s,c) ((s)[0] != (c) || (s)[1])
669#define DOT_OR_DOTDOT(s) ((s)[0] == '.' && (!(s)[1] || ((s)[1] == '.' && !(s)[2])))
670
671typedef struct uni_stat_t {
672 unsigned byte_count;
673 unsigned unicode_count;
674 unsigned unicode_width;
675} uni_stat_t;
676
677
678const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str);
679
680
681
682enum { PRINTABLE_META = 0x100 };
683void fputc_printable(int ch, FILE *file) FAST_FUNC;
684
685
686enum {
687 VISIBLE_ENDLINE = 1 << 0,
688 VISIBLE_SHOW_TABS = 1 << 1,
689};
690void visible(unsigned ch, char *buf, int flags) FAST_FUNC;
691
692
693
694void *malloc_or_warn(size_t size) FAST_FUNC RETURNS_MALLOC;
695void *xmalloc(size_t size) FAST_FUNC RETURNS_MALLOC;
696void *xzalloc(size_t size) FAST_FUNC RETURNS_MALLOC;
697void *xrealloc(void *old, size_t size) FAST_FUNC;
698
699
700
701
702
703
704
705#define xrealloc_vector(vector, shift, idx) \
706 xrealloc_vector_helper((vector), (sizeof((vector)[0]) << 8) + (shift), (idx))
707void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) FAST_FUNC;
708
709
710extern ssize_t safe_read(int fd, void *buf, size_t count) FAST_FUNC;
711extern ssize_t nonblock_immune_read(int fd, void *buf, size_t count, int loop_on_EINTR) FAST_FUNC;
712
713
714extern ssize_t full_read(int fd, void *buf, size_t count) FAST_FUNC;
715extern void xread(int fd, void *buf, size_t count) FAST_FUNC;
716extern unsigned char xread_char(int fd) FAST_FUNC;
717extern ssize_t read_close(int fd, void *buf, size_t maxsz) FAST_FUNC;
718extern ssize_t open_read_close(const char *filename, void *buf, size_t maxsz) FAST_FUNC;
719
720
721
722extern char *xmalloc_reads(int fd, size_t *maxsz_p) FAST_FUNC;
723
724extern void *xmalloc_read(int fd, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
725
726extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
727
728extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
729
730#define SEAMLESS_COMPRESSION (0 \
731 || ENABLE_FEATURE_SEAMLESS_XZ \
732 || ENABLE_FEATURE_SEAMLESS_LZMA \
733 || ENABLE_FEATURE_SEAMLESS_BZ2 \
734 || ENABLE_FEATURE_SEAMLESS_GZ \
735 || ENABLE_FEATURE_SEAMLESS_Z)
736
737#if SEAMLESS_COMPRESSION
738
739extern int setup_unzip_on_fd(int fd, int fail_if_not_detected) FAST_FUNC;
740
741extern int open_zipped(const char *fname) FAST_FUNC;
742#else
743# define setup_unzip_on_fd(...) (0)
744# define open_zipped(fname) open((fname), O_RDONLY);
745#endif
746extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
747
748extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC;
749
750
751extern ssize_t full_write(int fd, const void *buf, size_t count) FAST_FUNC;
752extern void xwrite(int fd, const void *buf, size_t count) FAST_FUNC;
753extern void xwrite_str(int fd, const char *str) FAST_FUNC;
754extern ssize_t full_write1_str(const char *str) FAST_FUNC;
755extern ssize_t full_write2_str(const char *str) FAST_FUNC;
756extern void xopen_xwrite_close(const char* file, const char *str) FAST_FUNC;
757
758
759extern void xclose(int fd) FAST_FUNC;
760
761
762extern void xprint_and_close_file(FILE *file) FAST_FUNC;
763
764
765
766
767
768
769extern char *bb_get_chunk_from_file(FILE *file, int *end) FAST_FUNC;
770
771extern char *xmalloc_fgets_str(FILE *file, const char *terminating_string) FAST_FUNC RETURNS_MALLOC;
772
773extern char *xmalloc_fgets_str_len(FILE *file, const char *terminating_string, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
774
775extern char *xmalloc_fgetline_str(FILE *file, const char *terminating_string) FAST_FUNC RETURNS_MALLOC;
776
777extern char *xmalloc_fgets(FILE *file) FAST_FUNC RETURNS_MALLOC;
778
779extern char *xmalloc_fgetline(FILE *file) FAST_FUNC RETURNS_MALLOC;
780
781
782
783void die_if_ferror(FILE *file, const char *msg) FAST_FUNC;
784void die_if_ferror_stdout(void) FAST_FUNC;
785int fflush_all(void) FAST_FUNC;
786void fflush_stdout_and_exit(int retval) NORETURN FAST_FUNC;
787int fclose_if_not_stdin(FILE *file) FAST_FUNC;
788FILE* xfopen(const char *filename, const char *mode) FAST_FUNC;
789
790FILE* fopen_or_warn(const char *filename, const char *mode) FAST_FUNC;
791
792FILE* xfopen_stdin(const char *filename) FAST_FUNC;
793FILE* fopen_or_warn_stdin(const char *filename) FAST_FUNC;
794FILE* fopen_for_read(const char *path) FAST_FUNC;
795FILE* xfopen_for_read(const char *path) FAST_FUNC;
796FILE* fopen_for_write(const char *path) FAST_FUNC;
797FILE* xfopen_for_write(const char *path) FAST_FUNC;
798FILE* xfdopen_for_read(int fd) FAST_FUNC;
799FILE* xfdopen_for_write(int fd) FAST_FUNC;
800
801int bb_pstrcmp(const void *a, const void *b) ;
802void qsort_string_vector(char **sv, unsigned count) FAST_FUNC;
803
804
805
806
807
808int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout_ms) FAST_FUNC;
809
810char *safe_gethostname(void) FAST_FUNC;
811
812
813char* str_tolower(char *str) FAST_FUNC;
814
815char *utoa(unsigned n) FAST_FUNC;
816char *itoa(int n) FAST_FUNC;
817
818char *utoa_to_buf(unsigned n, char *buf, unsigned buflen) FAST_FUNC;
819char *itoa_to_buf(int n, char *buf, unsigned buflen) FAST_FUNC;
820
821char *smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale) FAST_FUNC;
822char *smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC;
823
824
825
826
827#define HUMAN_READABLE_MAX_WIDTH 7
828#define HUMAN_READABLE_MAX_WIDTH_STR "7"
829
830const char *make_human_readable_str(unsigned long long size,
831 unsigned long block_size, unsigned long display_unit) FAST_FUNC;
832
833char *bin2hex(char *dst, const char *src, int count) FAST_FUNC;
834
835char* hex2bin(char *dst, const char *src, int count) FAST_FUNC;
836
837
838void generate_uuid(uint8_t *buf) FAST_FUNC;
839
840
841struct suffix_mult {
842 char suffix[4];
843 unsigned mult;
844};
845extern const struct suffix_mult bkm_suffixes[];
846#define km_suffixes (bkm_suffixes + 1)
847
848#include "xatonum.h"
849
850
851
852
853
854
855
856
857
858int xatoi_positive(const char *numstr) FAST_FUNC;
859
860
861uint16_t xatou16(const char *numstr) FAST_FUNC;
862
863
864
865
866
867long xuname2uid(const char *name) FAST_FUNC;
868long xgroup2gid(const char *name) FAST_FUNC;
869
870unsigned long get_ug_id(const char *s, long FAST_FUNC (*xname2id)(const char *)) FAST_FUNC;
871
872struct bb_uidgid_t {
873 uid_t uid;
874 gid_t gid;
875};
876
877int get_uidgid(struct bb_uidgid_t*, const char*, int numeric_ok) FAST_FUNC;
878
879void xget_uidgid(struct bb_uidgid_t*, const char*) FAST_FUNC;
880
881void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group) FAST_FUNC;
882struct passwd* xgetpwnam(const char *name) FAST_FUNC;
883struct group* xgetgrnam(const char *name) FAST_FUNC;
884struct passwd* xgetpwuid(uid_t uid) FAST_FUNC;
885struct group* xgetgrgid(gid_t gid) FAST_FUNC;
886char* xuid2uname(uid_t uid) FAST_FUNC;
887char* xgid2group(gid_t gid) FAST_FUNC;
888char* uid2uname(uid_t uid) FAST_FUNC;
889char* gid2group(gid_t gid) FAST_FUNC;
890char* uid2uname_utoa(uid_t uid) FAST_FUNC;
891char* gid2group_utoa(gid_t gid) FAST_FUNC;
892
893const char* get_cached_username(uid_t uid) FAST_FUNC;
894const char* get_cached_groupname(gid_t gid) FAST_FUNC;
895void clear_username_cache(void) FAST_FUNC;
896
897enum { USERNAME_MAX_SIZE = 32 - sizeof(uid_t) };
898#if ENABLE_FEATURE_CHECK_NAMES
899void die_if_bad_username(const char* name) FAST_FUNC;
900#else
901#define die_if_bad_username(name) ((void)(name))
902#endif
903
904#if ENABLE_FEATURE_UTMP
905void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
906void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
907#else
908# define write_new_utmp(pid, new_type, tty_name, username, hostname) ((void)0)
909# define update_utmp(pid, new_type, tty_name, username, hostname) ((void)0)
910#endif
911
912
913int execable_file(const char *name) FAST_FUNC;
914char *find_execable(const char *filename, char **PATHp) FAST_FUNC;
915int exists_execable(const char *filename) FAST_FUNC;
916
917
918
919
920#if ENABLE_FEATURE_PREFER_APPLETS
921int BB_EXECVP(const char *file, char *const argv[]) FAST_FUNC;
922#define BB_EXECLP(prog,cmd,...) \
923 do { \
924 if (find_applet_by_name(prog) >= 0) \
925 execlp(bb_busybox_exec_path, cmd, __VA_ARGS__); \
926 execlp(prog, cmd, __VA_ARGS__); \
927 } while (0)
928#else
929#define BB_EXECVP(prog,cmd) execvp(prog,cmd)
930#define BB_EXECLP(prog,cmd,...) execlp(prog,cmd,__VA_ARGS__)
931#endif
932int BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;
933
934
935
936#define xvfork() \
937({ \
938 pid_t bb__xvfork_pid = vfork(); \
939 if (bb__xvfork_pid < 0) \
940 bb_perror_msg_and_die("vfork"); \
941 bb__xvfork_pid; \
942})
943#if BB_MMU
944pid_t xfork(void) FAST_FUNC;
945#endif
946
947
948pid_t spawn(char **argv) FAST_FUNC;
949pid_t xspawn(char **argv) FAST_FUNC;
950
951pid_t safe_waitpid(pid_t pid, int *wstat, int options) FAST_FUNC;
952pid_t wait_any_nohang(int *wstat) FAST_FUNC;
953
954
955
956
957
958
959
960
961int wait4pid(pid_t pid) FAST_FUNC;
962
963int spawn_and_wait(char **argv) FAST_FUNC;
964
965int run_nofork_applet(int applet_no, char **argv) FAST_FUNC;
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990enum {
991 DAEMON_CHDIR_ROOT = 1,
992 DAEMON_DEVNULL_STDIO = 2,
993 DAEMON_CLOSE_EXTRA_FDS = 4,
994 DAEMON_ONLY_SANITIZE = 8,
995 DAEMON_DOUBLE_FORK = 16,
996};
997#if BB_MMU
998 enum { re_execed = 0 };
999# define fork_or_rexec(argv) xfork()
1000# define bb_daemonize_or_rexec(flags, argv) bb_daemonize_or_rexec(flags)
1001# define bb_daemonize(flags) bb_daemonize_or_rexec(flags, bogus)
1002#else
1003 extern bool re_execed;
1004
1005
1006
1007 void re_exec(char **argv) NORETURN FAST_FUNC;
1008 pid_t fork_or_rexec(char **argv) FAST_FUNC;
1009 int BUG_fork_is_unavailable_on_nommu(void) FAST_FUNC;
1010 int BUG_daemon_is_unavailable_on_nommu(void) FAST_FUNC;
1011 void BUG_bb_daemonize_is_unavailable_on_nommu(void) FAST_FUNC;
1012# define fork() BUG_fork_is_unavailable_on_nommu()
1013# define xfork() BUG_fork_is_unavailable_on_nommu()
1014# define daemon(a,b) BUG_daemon_is_unavailable_on_nommu()
1015# define bb_daemonize(a) BUG_bb_daemonize_is_unavailable_on_nommu()
1016#endif
1017void bb_daemonize_or_rexec(int flags, char **argv) FAST_FUNC;
1018void bb_sanitize_stdio(void) FAST_FUNC;
1019
1020int sanitize_env_if_suid(void) FAST_FUNC;
1021
1022
1023char* single_argv(char **argv) FAST_FUNC;
1024extern const char *const bb_argv_dash[];
1025extern const char *opt_complementary;
1026#if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG
1027#define No_argument "\0"
1028#define Required_argument "\001"
1029#define Optional_argument "\002"
1030extern const char *applet_long_options;
1031#endif
1032extern uint32_t option_mask32;
1033extern uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC;
1034
1035
1036
1037
1038
1039
1040typedef struct llist_t {
1041 struct llist_t *link;
1042 char *data;
1043} llist_t;
1044void llist_add_to(llist_t **old_head, void *data) FAST_FUNC;
1045void llist_add_to_end(llist_t **list_head, void *data) FAST_FUNC;
1046void *llist_pop(llist_t **elm) FAST_FUNC;
1047void llist_unlink(llist_t **head, llist_t *elm) FAST_FUNC;
1048void llist_free(llist_t *elm, void (*freeit)(void *data)) FAST_FUNC;
1049llist_t *llist_rev(llist_t *list) FAST_FUNC;
1050llist_t *llist_find_str(llist_t *first, const char *str) FAST_FUNC;
1051
1052
1053
1054
1055
1056
1057#if ENABLE_FEATURE_PIDFILE || defined(WANT_PIDFILE)
1058
1059extern smallint wrote_pidfile;
1060void write_pidfile(const char *path) FAST_FUNC;
1061#define remove_pidfile(path) do { if (wrote_pidfile) unlink(path); } while (0)
1062#else
1063enum { wrote_pidfile = 0 };
1064#define write_pidfile(path) ((void)0)
1065#define remove_pidfile(path) ((void)0)
1066#endif
1067
1068enum {
1069 LOGMODE_NONE = 0,
1070 LOGMODE_STDIO = (1 << 0),
1071 LOGMODE_SYSLOG = (1 << 1) * ENABLE_FEATURE_SYSLOG,
1072 LOGMODE_BOTH = LOGMODE_SYSLOG + LOGMODE_STDIO,
1073};
1074extern const char *msg_eol;
1075extern smallint logmode;
1076extern int die_sleep;
1077extern uint8_t xfunc_error_retval;
1078extern jmp_buf die_jmp;
1079extern void xfunc_die(void) NORETURN FAST_FUNC;
1080extern void bb_show_usage(void) NORETURN FAST_FUNC;
1081extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1082extern void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
1083extern void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1084extern void bb_simple_perror_msg(const char *s) FAST_FUNC;
1085extern void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
1086extern void bb_simple_perror_msg_and_die(const char *s) NORETURN FAST_FUNC;
1087extern void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1088extern void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
1089extern void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC;
1090extern void bb_perror_nomsg(void) FAST_FUNC;
1091extern void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1092extern void bb_verror_msg(const char *s, va_list p, const char *strerr) FAST_FUNC;
1093
1094
1095
1096
1097#if ENABLE_FEATURE_INDIVIDUAL
1098#define MAIN_EXTERNALLY_VISIBLE EXTERNALLY_VISIBLE
1099#else
1100#define MAIN_EXTERNALLY_VISIBLE
1101#endif
1102
1103
1104
1105int bb_cat(char** argv);
1106
1107int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE);
1108int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE);
1109int test_main(int argc, char **argv) IF_TEST(MAIN_EXTERNALLY_VISIBLE);
1110int kill_main(int argc, char **argv) IF_KILL(MAIN_EXTERNALLY_VISIBLE);
1111
1112int chown_main(int argc, char **argv) IF_CHOWN(MAIN_EXTERNALLY_VISIBLE);
1113
1114int ls_main(int argc, char **argv) IF_LS(MAIN_EXTERNALLY_VISIBLE);
1115
1116int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1117int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1118
1119#if ENABLE_ROUTE
1120void bb_displayroutes(int noresolve, int netstatfmt) FAST_FUNC;
1121#endif
1122
1123
1124
1125
1126struct aftype {
1127 const char *name;
1128 const char *title;
1129 int af;
1130 int alen;
1131 char* FAST_FUNC (*print)(unsigned char *);
1132 const char* FAST_FUNC (*sprint)(struct sockaddr *, int numeric);
1133 int FAST_FUNC (*input)( const char *bufp, struct sockaddr *);
1134 void FAST_FUNC (*herror)(char *text);
1135 int FAST_FUNC (*rprint)(int options);
1136 int FAST_FUNC (*rinput)(int typ, int ext, char **argv);
1137
1138 int FAST_FUNC (*getmask)(char *src, struct sockaddr *mask, char *name);
1139};
1140
1141struct hwtype {
1142 const char *name;
1143 const char *title;
1144 int type;
1145 int alen;
1146 char* FAST_FUNC (*print)(unsigned char *);
1147 int FAST_FUNC (*input)(const char *, struct sockaddr *);
1148 int FAST_FUNC (*activate)(int fd);
1149 int suppress_null_addr;
1150};
1151extern smallint interface_opt_a;
1152int display_interfaces(char *ifname) FAST_FUNC;
1153int in_ether(const char *bufp, struct sockaddr *sap) FAST_FUNC;
1154#if ENABLE_FEATURE_HWIB
1155int in_ib(const char *bufp, struct sockaddr *sap) FAST_FUNC;
1156#else
1157#define in_ib(a, b) 1
1158#endif
1159const struct aftype *get_aftype(const char *name) FAST_FUNC;
1160const struct hwtype *get_hwtype(const char *name) FAST_FUNC;
1161const struct hwtype *get_hwntype(int type) FAST_FUNC;
1162
1163
1164#ifndef BUILD_INDIVIDUAL
1165extern int find_applet_by_name(const char *name) FAST_FUNC;
1166
1167extern void run_applet_and_exit(const char *name, char **argv) FAST_FUNC;
1168extern void run_applet_no_and_exit(int a, char **argv) NORETURN FAST_FUNC;
1169#endif
1170
1171#ifdef HAVE_MNTENT_H
1172extern int match_fstype(const struct mntent *mt, const char *fstypes) FAST_FUNC;
1173extern struct mntent *find_mount_point(const char *name, int subdir_too) FAST_FUNC;
1174#endif
1175extern void erase_mtab(const char * name) FAST_FUNC;
1176extern unsigned int tty_baud_to_value(speed_t speed) FAST_FUNC;
1177extern speed_t tty_value_to_baud(unsigned int value) FAST_FUNC;
1178#if ENABLE_DESKTOP
1179extern void bb_warn_ignoring_args(char *arg) FAST_FUNC;
1180#else
1181# define bb_warn_ignoring_args(arg) ((void)0)
1182#endif
1183
1184extern int get_linux_version_code(void) FAST_FUNC;
1185
1186extern char *query_loop(const char *device) FAST_FUNC;
1187extern int del_loop(const char *device) FAST_FUNC;
1188
1189
1190
1191extern int set_loop(char **devname, const char *file, unsigned long long offset, int ro) FAST_FUNC;
1192
1193
1194char *bb_ask_stdin(const char * prompt) FAST_FUNC;
1195
1196char *bb_ask(const int fd, int timeout, const char * prompt) FAST_FUNC;
1197int bb_ask_confirmation(void) FAST_FUNC;
1198
1199int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC;
1200
1201
1202
1203
1204enum {
1205 PARSE_COLLAPSE = 0x00010000,
1206 PARSE_TRIM = 0x00020000,
1207
1208 PARSE_GREEDY = 0x00040000,
1209 PARSE_MIN_DIE = 0x00100000,
1210
1211 PARSE_KEEP_COPY = 0x00200000 * ENABLE_FEATURE_CROND_D,
1212 PARSE_EOL_COMMENTS = 0x00400000,
1213
1214
1215
1216
1217
1218
1219 PARSE_NORMAL = PARSE_COLLAPSE | PARSE_TRIM | PARSE_GREEDY | PARSE_EOL_COMMENTS,
1220};
1221typedef struct parser_t {
1222 FILE *fp;
1223 char *data;
1224 char *line, *nline;
1225 size_t line_alloc, nline_alloc;
1226 int lineno;
1227} parser_t;
1228parser_t* config_open(const char *filename) FAST_FUNC;
1229parser_t* config_open2(const char *filename, FILE* FAST_FUNC (*fopen_func)(const char *path)) FAST_FUNC;
1230
1231int config_read(parser_t *parser, char **tokens, unsigned flags, const char *delims) FAST_FUNC;
1232#define config_read(parser, tokens, max, min, str, flags) \
1233 config_read(parser, tokens, ((flags) | (((min) & 0xFF) << 8) | ((max) & 0xFF)), str)
1234void config_close(parser_t *parser) FAST_FUNC;
1235
1236
1237
1238
1239
1240char *concat_path_file(const char *path, const char *filename) FAST_FUNC;
1241
1242char *concat_subpath_file(const char *path, const char *filename) FAST_FUNC;
1243
1244
1245int bb_make_directory(char *path, long mode, int flags) FAST_FUNC;
1246
1247int get_signum(const char *name) FAST_FUNC;
1248const char *get_signame(int number) FAST_FUNC;
1249void print_signames(void) FAST_FUNC;
1250
1251char *bb_simplify_path(const char *path) FAST_FUNC;
1252
1253char *bb_simplify_abs_path_inplace(char *path) FAST_FUNC;
1254
1255#define LOGIN_FAIL_DELAY 3
1256extern void bb_do_delay(int seconds) FAST_FUNC;
1257extern void change_identity(const struct passwd *pw) FAST_FUNC;
1258extern void run_shell(const char *shell, int loginshell, const char *command, const char **additional_args) NORETURN FAST_FUNC;
1259
1260
1261
1262
1263
1264const char *get_shell_name(void) FAST_FUNC;
1265
1266#if ENABLE_SELINUX
1267extern void renew_current_security_context(void) FAST_FUNC;
1268extern void set_current_security_context(security_context_t sid) FAST_FUNC;
1269extern context_t set_security_context_component(security_context_t cur_context,
1270 char *user, char *role, char *type, char *range) FAST_FUNC;
1271extern void setfscreatecon_or_die(security_context_t scontext) FAST_FUNC;
1272extern void selinux_preserve_fcontext(int fdesc) FAST_FUNC;
1273#else
1274#define selinux_preserve_fcontext(fdesc) ((void)0)
1275#endif
1276extern void selinux_or_die(void) FAST_FUNC;
1277
1278
1279
1280#define SD_LISTEN_FDS_START 3
1281int sd_listen_fds(void);
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299#define SETUP_ENV_CHANGEENV (1 << 0)
1300#define SETUP_ENV_CLEARENV (1 << 1)
1301#define SETUP_ENV_TO_TMP (1 << 2)
1302#define SETUP_ENV_NO_CHDIR (1 << 4)
1303void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC;
1304void nuke_str(char *str) FAST_FUNC;
1305int ask_and_check_password_extended(const struct passwd *pw, int timeout, const char *prompt) FAST_FUNC;
1306int ask_and_check_password(const struct passwd *pw) FAST_FUNC;
1307
1308#if !ENABLE_USE_BB_CRYPT
1309#define pw_encrypt(clear, salt, cleanup) pw_encrypt(clear, salt)
1310#endif
1311extern char *pw_encrypt(const char *clear, const char *salt, int cleanup) FAST_FUNC;
1312extern int obscure(const char *old, const char *newval, const struct passwd *pwdp) FAST_FUNC;
1313
1314
1315
1316
1317
1318
1319
1320
1321extern int crypt_make_salt(char *p, int cnt ) FAST_FUNC;
1322
1323#define MAX_PW_SALT_LEN (3 + 16 + 1)
1324extern char* crypt_make_pw_salt(char p[MAX_PW_SALT_LEN], const char *algo) FAST_FUNC;
1325
1326
1327
1328#if !(ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP)
1329#define update_passwd(filename, username, data, member) \
1330 update_passwd(filename, username, data)
1331#endif
1332extern int update_passwd(const char *filename,
1333 const char *username,
1334 const char *data,
1335 const char *member) FAST_FUNC;
1336
1337int index_in_str_array(const char *const string_array[], const char *key) FAST_FUNC;
1338int index_in_strings(const char *strings, const char *key) FAST_FUNC;
1339int index_in_substr_array(const char *const string_array[], const char *key) FAST_FUNC;
1340int index_in_substrings(const char *strings, const char *key) FAST_FUNC;
1341const char *nth_string(const char *strings, int n) FAST_FUNC;
1342
1343extern void print_login_issue(const char *issue_file, const char *tty) FAST_FUNC;
1344extern void print_login_prompt(void) FAST_FUNC;
1345
1346char *xmalloc_ttyname(int fd) FAST_FUNC RETURNS_MALLOC;
1347
1348int get_terminal_width_height(int fd, unsigned *width, unsigned *height) FAST_FUNC;
1349
1350int tcsetattr_stdin_TCSANOW(const struct termios *tp) FAST_FUNC;
1351
1352
1353int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC;
1354int ioctl_or_perror_and_die(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC;
1355#if ENABLE_IOCTL_HEX2STR_ERROR
1356int bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC;
1357int bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC;
1358#define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp,#request)
1359#define xioctl(fd,request,argp) bb_xioctl(fd,request,argp,#request)
1360#else
1361int bb_ioctl_or_warn(int fd, unsigned request, void *argp) FAST_FUNC;
1362int bb_xioctl(int fd, unsigned request, void *argp) FAST_FUNC;
1363#define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp)
1364#define xioctl(fd,request,argp) bb_xioctl(fd,request,argp)
1365#endif
1366
1367char *is_in_ino_dev_hashtable(const struct stat *statbuf) FAST_FUNC;
1368void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name) FAST_FUNC;
1369void reset_ino_dev_hashtable(void) FAST_FUNC;
1370#ifdef __GLIBC__
1371
1372unsigned long long bb_makedev(unsigned major, unsigned minor) FAST_FUNC;
1373#undef makedev
1374#define makedev(a,b) bb_makedev(a,b)
1375#endif
1376
1377
1378
1379
1380
1381
1382enum {
1383 KEYCODE_UP = -2,
1384 KEYCODE_DOWN = -3,
1385 KEYCODE_RIGHT = -4,
1386 KEYCODE_LEFT = -5,
1387 KEYCODE_HOME = -6,
1388 KEYCODE_END = -7,
1389 KEYCODE_INSERT = -8,
1390 KEYCODE_DELETE = -9,
1391 KEYCODE_PAGEUP = -10,
1392 KEYCODE_PAGEDOWN = -11,
1393
1394#if 0
1395 KEYCODE_FUN1 = -13,
1396 KEYCODE_FUN2 = -14,
1397 KEYCODE_FUN3 = -15,
1398 KEYCODE_FUN4 = -16,
1399 KEYCODE_FUN5 = -17,
1400 KEYCODE_FUN6 = -18,
1401 KEYCODE_FUN7 = -19,
1402 KEYCODE_FUN8 = -20,
1403 KEYCODE_FUN9 = -21,
1404 KEYCODE_FUN10 = -22,
1405 KEYCODE_FUN11 = -23,
1406 KEYCODE_FUN12 = -24,
1407#endif
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417 KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40,
1418 KEYCODE_CTRL_LEFT = KEYCODE_LEFT & ~0x40,
1419
1420
1421 KEYCODE_ALT_RIGHT = KEYCODE_RIGHT & ~0x20,
1422 KEYCODE_ALT_LEFT = KEYCODE_LEFT & ~0x20,
1423
1424 KEYCODE_CURSOR_POS = -0x100,
1425
1426
1427
1428
1429 KEYCODE_BUFFER_SIZE = 16
1430};
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444int64_t read_key(int fd, char *buffer, int timeout) FAST_FUNC;
1445void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC;
1446
1447
1448#if ENABLE_FEATURE_EDITING
1449
1450# if defined CONFIG_FEATURE_EDITING_HISTORY && CONFIG_FEATURE_EDITING_HISTORY > 0
1451# define MAX_HISTORY (CONFIG_FEATURE_EDITING_HISTORY + 0)
1452unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC;
1453# else
1454# define MAX_HISTORY 0
1455# endif
1456typedef struct line_input_t {
1457 int flags;
1458 const char *path_lookup;
1459# if MAX_HISTORY
1460 int cnt_history;
1461 int cur_history;
1462 int max_history;
1463# if ENABLE_FEATURE_EDITING_SAVEHISTORY
1464
1465
1466
1467
1468
1469
1470 unsigned cnt_history_in_file;
1471 const char *hist_file;
1472# endif
1473 char *history[MAX_HISTORY + 1];
1474# endif
1475} line_input_t;
1476enum {
1477 DO_HISTORY = 1 * (MAX_HISTORY > 0),
1478 TAB_COMPLETION = 2 * ENABLE_FEATURE_TAB_COMPLETION,
1479 USERNAME_COMPLETION = 4 * ENABLE_FEATURE_USERNAME_COMPLETION,
1480 VI_MODE = 8 * ENABLE_FEATURE_EDITING_VI,
1481 WITH_PATH_LOOKUP = 0x10,
1482 FOR_SHELL = DO_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION,
1483};
1484line_input_t *new_line_input_t(int flags) FAST_FUNC;
1485
1486
1487
1488
1489
1490
1491
1492
1493int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) FAST_FUNC;
1494void show_history(const line_input_t *st) FAST_FUNC;
1495# if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
1496void save_history(line_input_t *st);
1497# endif
1498#else
1499#define MAX_HISTORY 0
1500int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC;
1501#define read_line_input(state, prompt, command, maxsize, timeout) \
1502 read_line_input(prompt, command, maxsize)
1503#endif
1504
1505
1506#ifndef COMM_LEN
1507# ifdef TASK_COMM_LEN
1508enum { COMM_LEN = TASK_COMM_LEN };
1509# else
1510
1511enum { COMM_LEN = 16 };
1512# endif
1513#endif
1514
1515struct smaprec {
1516 unsigned long mapped_rw;
1517 unsigned long mapped_ro;
1518 unsigned long shared_clean;
1519 unsigned long shared_dirty;
1520 unsigned long private_clean;
1521 unsigned long private_dirty;
1522 unsigned long stack;
1523 unsigned long smap_pss, smap_swap;
1524 unsigned long smap_size;
1525 unsigned long smap_start;
1526 char smap_mode[5];
1527 char *smap_name;
1528};
1529
1530#if !ENABLE_PMAP
1531#define procps_read_smaps(pid, total, cb, data) \
1532 procps_read_smaps(pid, total)
1533#endif
1534int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
1535 void (*cb)(struct smaprec *, void *), void *data);
1536
1537typedef struct procps_status_t {
1538 DIR *dir;
1539 IF_FEATURE_SHOW_THREADS(DIR *task_dir;)
1540 uint8_t shift_pages_to_bytes;
1541 uint8_t shift_pages_to_kb;
1542
1543 uint16_t argv_len;
1544 char *argv0;
1545 char *exe;
1546 IF_SELINUX(char *context;)
1547 IF_FEATURE_SHOW_THREADS(unsigned main_thread_pid;)
1548
1549
1550 unsigned long vsz, rss;
1551 unsigned long stime, utime;
1552 unsigned long start_time;
1553 unsigned pid;
1554 unsigned ppid;
1555 unsigned pgid;
1556 unsigned sid;
1557 unsigned uid;
1558 unsigned gid;
1559#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
1560 unsigned ruid;
1561 unsigned rgid;
1562 int niceness;
1563#endif
1564 unsigned tty_major,tty_minor;
1565#if ENABLE_FEATURE_TOPMEM
1566 struct smaprec smaps;
1567#endif
1568 char state[4];
1569
1570
1571
1572 char comm[COMM_LEN];
1573
1574#if ENABLE_FEATURE_TOP_SMP_PROCESS
1575 int last_seen_on_cpu;
1576#endif
1577} procps_status_t;
1578
1579enum {
1580 PSSCAN_PID = 1 << 0,
1581 PSSCAN_PPID = 1 << 1,
1582 PSSCAN_PGID = 1 << 2,
1583 PSSCAN_SID = 1 << 3,
1584 PSSCAN_UIDGID = 1 << 4,
1585 PSSCAN_COMM = 1 << 5,
1586
1587 PSSCAN_ARGV0 = 1 << 7,
1588 PSSCAN_EXE = 1 << 8,
1589 PSSCAN_STATE = 1 << 9,
1590 PSSCAN_VSZ = 1 << 10,
1591 PSSCAN_RSS = 1 << 11,
1592 PSSCAN_STIME = 1 << 12,
1593 PSSCAN_UTIME = 1 << 13,
1594 PSSCAN_TTY = 1 << 14,
1595 PSSCAN_SMAPS = (1 << 15) * ENABLE_FEATURE_TOPMEM,
1596
1597
1598 PSSCAN_ARGVN = (1 << 16) * (ENABLE_KILLALL
1599 || ENABLE_PGREP || ENABLE_PKILL
1600 || ENABLE_PIDOF
1601 || ENABLE_SESTATUS
1602 ),
1603 PSSCAN_CONTEXT = (1 << 17) * ENABLE_SELINUX,
1604 PSSCAN_START_TIME = 1 << 18,
1605 PSSCAN_CPU = (1 << 19) * ENABLE_FEATURE_TOP_SMP_PROCESS,
1606 PSSCAN_NICE = (1 << 20) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
1607 PSSCAN_RUIDGID = (1 << 21) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
1608 PSSCAN_TASKS = (1 << 22) * ENABLE_FEATURE_SHOW_THREADS,
1609};
1610
1611void free_procps_scan(procps_status_t* sp) FAST_FUNC;
1612procps_status_t* procps_scan(procps_status_t* sp, int flags) FAST_FUNC;
1613
1614
1615void read_cmdline(char *buf, int size, unsigned pid, const char *comm) FAST_FUNC;
1616pid_t *find_pid_by_name(const char* procName) FAST_FUNC;
1617pid_t *pidlist_reverse(pid_t *pidList) FAST_FUNC;
1618int starts_with_cpu(const char *str) FAST_FUNC;
1619unsigned get_cpu_count(void) FAST_FUNC;
1620
1621
1622
1623
1624
1625
1626
1627
1628char *percent_decode_in_place(char *str, int strict) FAST_FUNC;
1629
1630
1631extern const char bb_uuenc_tbl_base64[] ALIGN1;
1632extern const char bb_uuenc_tbl_std[] ALIGN1;
1633void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC;
1634enum {
1635 BASE64_FLAG_UU_STOP = 0x100,
1636
1637 BASE64_FLAG_NO_STOP_CHAR = 0x80,
1638};
1639const char *decode_base64(char **pp_dst, const char *src) FAST_FUNC;
1640void read_base64(FILE *src_stream, FILE *dst_stream, int flags) FAST_FUNC;
1641
1642typedef struct md5_ctx_t {
1643 uint8_t wbuffer[64];
1644 void (*process_block)(struct md5_ctx_t*) FAST_FUNC;
1645 uint64_t total64;
1646 uint32_t hash[8];
1647} md5_ctx_t;
1648typedef struct md5_ctx_t sha1_ctx_t;
1649typedef struct md5_ctx_t sha256_ctx_t;
1650typedef struct sha512_ctx_t {
1651 uint64_t total64[2];
1652 uint64_t hash[8];
1653 uint8_t wbuffer[128];
1654} sha512_ctx_t;
1655typedef struct sha3_ctx_t {
1656 uint64_t state[25];
1657 unsigned bytes_queued;
1658} sha3_ctx_t;
1659void md5_begin(md5_ctx_t *ctx) FAST_FUNC;
1660void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1661void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC;
1662void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;
1663#define sha1_hash md5_hash
1664void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC;
1665void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
1666#define sha256_hash md5_hash
1667#define sha256_end sha1_end
1668void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
1669void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1670void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
1671void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC;
1672void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1673void sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC;
1674
1675extern uint32_t *global_crc32_table;
1676uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;
1677uint32_t crc32_block_endian1(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC;
1678uint32_t crc32_block_endian0(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC;
1679
1680typedef struct masks_labels_t {
1681 const char *labels;
1682 const int masks[];
1683} masks_labels_t;
1684int print_flags_separated(const int *masks, const char *labels,
1685 int flags, const char *separator) FAST_FUNC;
1686int print_flags(const masks_labels_t *ml, int flags) FAST_FUNC;
1687
1688typedef struct bb_progress_t {
1689 unsigned last_size;
1690 unsigned last_update_sec;
1691 unsigned last_change_sec;
1692 unsigned start_sec;
1693 const char *curfile;
1694} bb_progress_t;
1695
1696#define is_bb_progress_inited(p) ((p)->curfile != NULL)
1697#define bb_progress_free(p) do { \
1698 if (ENABLE_UNICODE_SUPPORT) free((char*)((p)->curfile)); \
1699 (p)->curfile = NULL; \
1700} while (0)
1701void bb_progress_init(bb_progress_t *p, const char *curfile) FAST_FUNC;
1702void bb_progress_update(bb_progress_t *p,
1703 uoff_t beg_range,
1704 uoff_t transferred,
1705 uoff_t totalsize) FAST_FUNC;
1706
1707
1708extern const char *applet_name;
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720extern const char bb_banner[] ALIGN1;
1721extern const char bb_msg_memory_exhausted[] ALIGN1;
1722extern const char bb_msg_invalid_date[] ALIGN1;
1723#define bb_msg_read_error "read error"
1724#define bb_msg_write_error "write error"
1725extern const char bb_msg_unknown[] ALIGN1;
1726extern const char bb_msg_can_not_create_raw_socket[] ALIGN1;
1727extern const char bb_msg_perm_denied_are_you_root[] ALIGN1;
1728extern const char bb_msg_you_must_be_root[] ALIGN1;
1729extern const char bb_msg_requires_arg[] ALIGN1;
1730extern const char bb_msg_invalid_arg[] ALIGN1;
1731extern const char bb_msg_standard_input[] ALIGN1;
1732extern const char bb_msg_standard_output[] ALIGN1;
1733
1734
1735extern const char bb_hexdigits_upcase[] ALIGN1;
1736
1737extern const char bb_path_wtmp_file[] ALIGN1;
1738
1739
1740
1741#define bb_path_mtab_file IF_FEATURE_MTAB_SUPPORT("/etc/mtab")IF_NOT_FEATURE_MTAB_SUPPORT("/proc/mounts")
1742
1743#define bb_path_passwd_file _PATH_PASSWD
1744#define bb_path_group_file _PATH_GROUP
1745#define bb_path_shadow_file _PATH_SHADOW
1746#define bb_path_gshadow_file _PATH_GSHADOW
1747
1748#define bb_path_motd_file "/etc/motd"
1749
1750#define bb_dev_null "/dev/null"
1751extern const char bb_busybox_exec_path[] ALIGN1;
1752
1753
1754extern const char bb_PATH_root_path[] ALIGN1;
1755#define bb_default_root_path (bb_PATH_root_path + sizeof("PATH"))
1756#define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin"))
1757
1758extern const int const_int_0;
1759extern const int const_int_1;
1760
1761
1762
1763enum { COMMON_BUFSIZE = (BUFSIZ >= 256*sizeof(void*) ? BUFSIZ+1 : 256*sizeof(void*)) };
1764extern char bb_common_bufsiz1[COMMON_BUFSIZE];
1765
1766
1767struct globals;
1768
1769
1770
1771extern struct globals *const ptr_to_globals;
1772
1773#define barrier() __asm__ __volatile__("":::"memory")
1774#define SET_PTR_TO_GLOBALS(x) do { \
1775 (*(struct globals**)&ptr_to_globals) = (void*)(x); \
1776 barrier(); \
1777} while (0)
1778#define FREE_PTR_TO_GLOBALS() do { \
1779 if (ENABLE_FEATURE_CLEAN_UP) { \
1780 free(ptr_to_globals); \
1781 } \
1782} while (0)
1783
1784
1785
1786
1787
1788#define LIBBB_DEFAULT_LOGIN_SHELL "-/bin/sh"
1789extern const char bb_default_login_shell[] ALIGN1;
1790
1791#define DEFAULT_SHELL (bb_default_login_shell+1)
1792
1793#define DEFAULT_SHELL_SHORT_NAME (bb_default_login_shell+6)
1794
1795
1796#define CURRENT_TTY "/dev/tty"
1797#define DEV_CONSOLE "/dev/console"
1798
1799#if defined(__FreeBSD_kernel__)
1800# define CURRENT_VC CURRENT_TTY
1801# define VC_1 "/dev/ttyv0"
1802# define VC_2 "/dev/ttyv1"
1803# define VC_3 "/dev/ttyv2"
1804# define VC_4 "/dev/ttyv3"
1805# define VC_5 "/dev/ttyv4"
1806# define VC_FORMAT "/dev/ttyv%d"
1807#elif defined(__GNU__)
1808# define CURRENT_VC CURRENT_TTY
1809# define VC_1 "/dev/tty1"
1810# define VC_2 "/dev/tty2"
1811# define VC_3 "/dev/tty3"
1812# define VC_4 "/dev/tty4"
1813# define VC_5 "/dev/tty5"
1814# define VC_FORMAT "/dev/tty%d"
1815#elif ENABLE_FEATURE_DEVFS
1816
1817# define CURRENT_VC "/dev/vc/0"
1818# define VC_1 "/dev/vc/1"
1819# define VC_2 "/dev/vc/2"
1820# define VC_3 "/dev/vc/3"
1821# define VC_4 "/dev/vc/4"
1822# define VC_5 "/dev/vc/5"
1823# define VC_FORMAT "/dev/vc/%d"
1824# define LOOP_FORMAT "/dev/loop/%u"
1825# define LOOP_NAMESIZE (sizeof("/dev/loop/") + sizeof(int)*3 + 1)
1826# define LOOP_NAME "/dev/loop/"
1827# define FB_0 "/dev/fb/0"
1828#else
1829
1830# define CURRENT_VC "/dev/tty0"
1831# define VC_1 "/dev/tty1"
1832# define VC_2 "/dev/tty2"
1833# define VC_3 "/dev/tty3"
1834# define VC_4 "/dev/tty4"
1835# define VC_5 "/dev/tty5"
1836# define VC_FORMAT "/dev/tty%d"
1837# define LOOP_FORMAT "/dev/loop%u"
1838# define LOOP_NAMESIZE (sizeof("/dev/loop") + sizeof(int)*3 + 1)
1839# define LOOP_NAME "/dev/loop"
1840# define FB_0 "/dev/fb0"
1841#endif
1842
1843
1844#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))
1845
1846
1847
1848
1849
1850
1851#undef isalnum
1852#undef isalpha
1853#undef isascii
1854#undef isblank
1855#undef iscntrl
1856#undef isdigit
1857#undef isgraph
1858#undef islower
1859#undef isprint
1860#undef ispunct
1861#undef isspace
1862#undef isupper
1863#undef isxdigit
1864#undef toupper
1865#undef tolower
1866
1867
1868
1869
1870
1871
1872#define isascii(a) ((unsigned char)(a) <= 0x7f)
1873#define isdigit(a) ((unsigned char)((a) - '0') <= 9)
1874#define isupper(a) ((unsigned char)((a) - 'A') <= ('Z' - 'A'))
1875#define islower(a) ((unsigned char)((a) - 'a') <= ('z' - 'a'))
1876#define isalpha(a) ((unsigned char)(((a)|0x20) - 'a') <= ('z' - 'a'))
1877#define isblank(a) ({ unsigned char bb__isblank = (a); bb__isblank == ' ' || bb__isblank == '\t'; })
1878#define iscntrl(a) ({ unsigned char bb__iscntrl = (a); bb__iscntrl < ' ' || bb__iscntrl == 0x7f; })
1879
1880
1881
1882#define isspace(a) ({ unsigned char bb__isspace = (a) - 9; bb__isspace == (' ' - 9) || bb__isspace <= (13 - 9); })
1883
1884#define ispunct(a) (strchrnul("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", (a))[0])
1885
1886#define isalnum(a) bb_ascii_isalnum(a)
1887static ALWAYS_INLINE int bb_ascii_isalnum(unsigned char a)
1888{
1889 unsigned char b = a - '0';
1890 if (b <= 9)
1891 return (b <= 9);
1892 b = (a|0x20) - 'a';
1893 return b <= 'z' - 'a';
1894}
1895#define isxdigit(a) bb_ascii_isxdigit(a)
1896static ALWAYS_INLINE int bb_ascii_isxdigit(unsigned char a)
1897{
1898 unsigned char b = a - '0';
1899 if (b <= 9)
1900 return (b <= 9);
1901 b = (a|0x20) - 'a';
1902 return b <= 'f' - 'a';
1903}
1904#define toupper(a) bb_ascii_toupper(a)
1905static ALWAYS_INLINE unsigned char bb_ascii_toupper(unsigned char a)
1906{
1907 unsigned char b = a - 'a';
1908 if (b <= ('z' - 'a'))
1909 a -= 'a' - 'A';
1910 return a;
1911}
1912#define tolower(a) bb_ascii_tolower(a)
1913static ALWAYS_INLINE unsigned char bb_ascii_tolower(unsigned char a)
1914{
1915 unsigned char b = a - 'A';
1916 if (b <= ('Z' - 'A'))
1917 a += 'a' - 'A';
1918 return a;
1919}
1920
1921
1922
1923#define isgraph(a) isgraph_is_ambiguous_dont_use(a)
1924#define isprint(a) isprint_is_ambiguous_dont_use(a)
1925
1926#define isgraph_asciionly(a) ((unsigned)((a) - 0x21) <= 0x7e - 0x21)
1927#define isprint_asciionly(a) ((unsigned)((a) - 0x20) <= 0x7e - 0x20)
1928
1929
1930POP_SAVED_FUNCTION_VISIBILITY
1931
1932#endif
1933