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 FILEUTILS_VERBOSE = (1 << 12) * ENABLE_FEATURE_VERBOSE,
339};
340#define FILEUTILS_CP_OPTSTR "pdRfilsLH" IF_SELINUX("c")
341extern int remove_file(const char *path, int flags) FAST_FUNC;
342
343
344
345
346extern int copy_file(const char *source, const char *dest, int flags) FAST_FUNC;
347
348enum {
349 ACTION_RECURSE = (1 << 0),
350 ACTION_FOLLOWLINKS = (1 << 1),
351 ACTION_FOLLOWLINKS_L0 = (1 << 2),
352 ACTION_DEPTHFIRST = (1 << 3),
353
354 ACTION_QUIET = (1 << 5),
355 ACTION_DANGLING_OK = (1 << 6),
356};
357typedef uint8_t recurse_flags_t;
358extern int recursive_action(const char *fileName, unsigned flags,
359 int FAST_FUNC (*fileAction)(const char *fileName, struct stat* statbuf, void* userData, int depth),
360 int FAST_FUNC (*dirAction)(const char *fileName, struct stat* statbuf, void* userData, int depth),
361 void* userData, unsigned depth) FAST_FUNC;
362extern int device_open(const char *device, int mode) FAST_FUNC;
363enum { GETPTY_BUFSIZE = 16 };
364extern int xgetpty(char *line) FAST_FUNC;
365extern int get_console_fd_or_die(void) FAST_FUNC;
366extern void console_make_active(int fd, const int vt_num) FAST_FUNC;
367extern char *find_block_device(const char *path) FAST_FUNC;
368
369extern off_t bb_copyfd_eof(int fd1, int fd2) FAST_FUNC;
370extern off_t bb_copyfd_size(int fd1, int fd2, off_t size) FAST_FUNC;
371extern void bb_copyfd_exact_size(int fd1, int fd2, off_t size) FAST_FUNC;
372
373
374extern void complain_copyfd_and_die(off_t sz) NORETURN FAST_FUNC;
375
376extern char bb_process_escape_sequence(const char **ptr) FAST_FUNC;
377char* strcpy_and_process_escape_sequences(char *dst, const char *src) FAST_FUNC;
378
379
380
381
382
383
384char *bb_get_last_path_component_strip(char *path) FAST_FUNC;
385
386char *bb_get_last_path_component_nostrip(const char *path) FAST_FUNC;
387
388const char *bb_basename(const char *name) FAST_FUNC;
389
390char *last_char_is(const char *s, int c) FAST_FUNC;
391const char* endofname(const char *name) FAST_FUNC;
392
393int ndelay_on(int fd) FAST_FUNC;
394int ndelay_off(int fd) FAST_FUNC;
395void close_on_exec_on(int fd) FAST_FUNC;
396void xdup2(int, int) FAST_FUNC;
397void xmove_fd(int, int) FAST_FUNC;
398
399
400DIR *xopendir(const char *path) FAST_FUNC;
401DIR *warn_opendir(const char *path) FAST_FUNC;
402
403char *xmalloc_realpath(const char *path) FAST_FUNC RETURNS_MALLOC;
404char *xmalloc_readlink(const char *path) FAST_FUNC RETURNS_MALLOC;
405char *xmalloc_readlink_or_warn(const char *path) FAST_FUNC RETURNS_MALLOC;
406
407char *xrealloc_getcwd_or_warn(char *cwd) FAST_FUNC;
408
409char *xmalloc_follow_symlinks(const char *path) FAST_FUNC RETURNS_MALLOC;
410
411
412enum {
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427 BB_FATAL_SIGS = (int)(0
428 + (1LL << SIGHUP)
429 + (1LL << SIGINT)
430 + (1LL << SIGTERM)
431 + (1LL << SIGPIPE)
432 + (1LL << SIGQUIT)
433 + (1LL << SIGABRT)
434 + (1LL << SIGALRM)
435 + (1LL << SIGVTALRM)
436 + (1LL << SIGXCPU)
437 + (1LL << SIGXFSZ)
438 + (1LL << SIGUSR1)
439 + (1LL << SIGUSR2)
440 + 0),
441};
442void bb_signals(int sigs, void (*f)(int)) FAST_FUNC;
443
444
445
446void bb_signals_recursive_norestart(int sigs, void (*f)(int)) FAST_FUNC;
447
448void signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int)) FAST_FUNC;
449
450void signal_SA_RESTART_empty_mask(int sig, void (*handler)(int)) FAST_FUNC;
451void wait_for_any_sig(void) FAST_FUNC;
452void kill_myself_with_sig(int sig) NORETURN FAST_FUNC;
453void sig_block(int sig) FAST_FUNC;
454void sig_unblock(int sig) FAST_FUNC;
455
456int sigaction_set(int sig, const struct sigaction *act) FAST_FUNC;
457
458int sigprocmask_allsigs(int how) FAST_FUNC;
459
460extern smallint bb_got_signal;
461void record_signo(int signo);
462
463
464void xsetgid(gid_t gid) FAST_FUNC;
465void xsetuid(uid_t uid) FAST_FUNC;
466void xsetegid(gid_t egid) FAST_FUNC;
467void xseteuid(uid_t euid) FAST_FUNC;
468void xchdir(const char *path) FAST_FUNC;
469void xchroot(const char *path) FAST_FUNC;
470void xsetenv(const char *key, const char *value) FAST_FUNC;
471void bb_unsetenv(const char *key) FAST_FUNC;
472void bb_unsetenv_and_free(char *key) FAST_FUNC;
473void xunlink(const char *pathname) FAST_FUNC;
474void xstat(const char *pathname, struct stat *buf) FAST_FUNC;
475void xfstat(int fd, struct stat *buf, const char *errmsg) FAST_FUNC;
476int open3_or_warn(const char *pathname, int flags, int mode) FAST_FUNC;
477int open_or_warn(const char *pathname, int flags) FAST_FUNC;
478int xopen3(const char *pathname, int flags, int mode) FAST_FUNC;
479int xopen(const char *pathname, int flags) FAST_FUNC;
480int xopen_nonblocking(const char *pathname) FAST_FUNC;
481int xopen_as_uid_gid(const char *pathname, int flags, uid_t u, gid_t g) FAST_FUNC;
482int open_or_warn_stdin(const char *pathname) FAST_FUNC;
483int xopen_stdin(const char *pathname) FAST_FUNC;
484void xrename(const char *oldpath, const char *newpath) FAST_FUNC;
485int rename_or_warn(const char *oldpath, const char *newpath) FAST_FUNC;
486off_t xlseek(int fd, off_t offset, int whence) FAST_FUNC;
487int xmkstemp(char *template) FAST_FUNC;
488off_t fdlength(int fd) FAST_FUNC;
489
490uoff_t FAST_FUNC get_volume_size_in_bytes(int fd,
491 const char *override,
492 unsigned override_units,
493 int extend);
494
495void xpipe(int filedes[2]) FAST_FUNC;
496
497struct fd_pair { int rd; int wr; };
498#define piped_pair(pair) pipe(&((pair).rd))
499#define xpiped_pair(pair) xpipe(&((pair).rd))
500
501
502typedef int8_t socktype_t;
503typedef int8_t family_t;
504struct BUG_too_small {
505 char BUG_socktype_t_too_small[(0
506 | SOCK_STREAM
507 | SOCK_DGRAM
508 | SOCK_RDM
509 | SOCK_SEQPACKET
510 | SOCK_RAW
511 ) <= 127 ? 1 : -1];
512 char BUG_family_t_too_small[(0
513 | AF_UNSPEC
514 | AF_INET
515 | AF_INET6
516 | AF_UNIX
517#ifdef AF_PACKET
518 | AF_PACKET
519#endif
520#ifdef AF_NETLINK
521 | AF_NETLINK
522#endif
523
524
525 ) <= 127 ? 1 : -1];
526};
527
528
529void parse_datestr(const char *date_str, struct tm *ptm) FAST_FUNC;
530time_t validate_tm_time(const char *date_str, struct tm *ptm) FAST_FUNC;
531char *strftime_HHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC;
532char *strftime_YYYYMMDDHHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC;
533
534int xsocket(int domain, int type, int protocol) FAST_FUNC;
535void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) FAST_FUNC;
536void xlisten(int s, int backlog) FAST_FUNC;
537void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) FAST_FUNC;
538ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
539 socklen_t tolen) FAST_FUNC;
540
541
542
543
544
545
546void setsockopt_reuseaddr(int fd) FAST_FUNC;
547int setsockopt_broadcast(int fd) FAST_FUNC;
548int setsockopt_bindtodevice(int fd, const char *iface) FAST_FUNC;
549
550unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port) FAST_FUNC;
551typedef struct len_and_sockaddr {
552 socklen_t len;
553 union {
554 struct sockaddr sa;
555 struct sockaddr_in sin;
556#if ENABLE_FEATURE_IPV6
557 struct sockaddr_in6 sin6;
558#endif
559 } u;
560} len_and_sockaddr;
561enum {
562 LSA_LEN_SIZE = offsetof(len_and_sockaddr, u),
563 LSA_SIZEOF_SA = sizeof(
564 union {
565 struct sockaddr sa;
566 struct sockaddr_in sin;
567#if ENABLE_FEATURE_IPV6
568 struct sockaddr_in6 sin6;
569#endif
570 }
571 )
572};
573
574
575
576
577
578
579int xsocket_type(len_and_sockaddr **lsap, int af, int sock_type) FAST_FUNC;
580int xsocket_stream(len_and_sockaddr **lsap) FAST_FUNC;
581
582
583
584
585
586int create_and_bind_stream_or_die(const char *bindaddr, int port) FAST_FUNC;
587int create_and_bind_dgram_or_die(const char *bindaddr, int port) FAST_FUNC;
588
589
590
591
592int create_and_connect_stream_or_die(const char *peer, int port) FAST_FUNC;
593
594int xconnect_stream(const len_and_sockaddr *lsa) FAST_FUNC;
595
596len_and_sockaddr *get_sock_lsa(int fd) FAST_FUNC RETURNS_MALLOC;
597
598len_and_sockaddr *get_peer_lsa(int fd) FAST_FUNC RETURNS_MALLOC;
599
600
601
602
603
604len_and_sockaddr* host2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
605
606len_and_sockaddr* xhost2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
607len_and_sockaddr* xdotted2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
608
609#if !ENABLE_FEATURE_IPV6
610#define host_and_af2sockaddr(host, port, af) host2sockaddr((host), (port))
611#define xhost_and_af2sockaddr(host, port, af) xhost2sockaddr((host), (port))
612#else
613len_and_sockaddr* host_and_af2sockaddr(const char *host, int port, sa_family_t af) FAST_FUNC RETURNS_MALLOC;
614len_and_sockaddr* xhost_and_af2sockaddr(const char *host, int port, sa_family_t af) FAST_FUNC RETURNS_MALLOC;
615#endif
616
617
618
619void set_nport(struct sockaddr *sa, unsigned port) FAST_FUNC;
620
621int get_nport(const struct sockaddr *sa) FAST_FUNC;
622
623char* xmalloc_sockaddr2host(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
624
625char* xmalloc_sockaddr2host_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
626
627char* xmalloc_sockaddr2hostonly_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
628
629char* xmalloc_sockaddr2dotted(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
630char* xmalloc_sockaddr2dotted_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
631
632
633struct hostent *xgethostbyname(const char *name) FAST_FUNC;
634
635
636
637
638void socket_want_pktinfo(int fd) FAST_FUNC;
639ssize_t send_to_from(int fd, void *buf, size_t len, int flags,
640 const struct sockaddr *to,
641 const struct sockaddr *from,
642 socklen_t tolen) FAST_FUNC;
643ssize_t recv_from_to(int fd, void *buf, size_t len, int flags,
644 struct sockaddr *from,
645 struct sockaddr *to,
646 socklen_t sa_size) FAST_FUNC;
647
648uint16_t inet_cksum(uint16_t *addr, int len) FAST_FUNC;
649
650char *xstrdup(const char *s) FAST_FUNC RETURNS_MALLOC;
651char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC;
652void overlapping_strcpy(char *dst, const char *src) FAST_FUNC;
653char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC;
654char *strncpy_IFNAMSIZ(char *dst, const char *src) FAST_FUNC;
655unsigned count_strstr(const char *str, const char *sub) FAST_FUNC;
656char *xmalloc_substitute_string(const char *src, int count, const char *sub, const char *repl) FAST_FUNC;
657
658
659int bb_putchar(int ch) FAST_FUNC;
660
661int bb_putchar_stderr(char ch) FAST_FUNC;
662char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC;
663
664
665
666
667
668
669#define LONE_DASH(s) ((s)[0] == '-' && !(s)[1])
670#define NOT_LONE_DASH(s) ((s)[0] != '-' || (s)[1])
671#define LONE_CHAR(s,c) ((s)[0] == (c) && !(s)[1])
672#define NOT_LONE_CHAR(s,c) ((s)[0] != (c) || (s)[1])
673#define DOT_OR_DOTDOT(s) ((s)[0] == '.' && (!(s)[1] || ((s)[1] == '.' && !(s)[2])))
674
675typedef struct uni_stat_t {
676 unsigned byte_count;
677 unsigned unicode_count;
678 unsigned unicode_width;
679} uni_stat_t;
680
681
682const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str);
683
684
685
686enum { PRINTABLE_META = 0x100 };
687void fputc_printable(int ch, FILE *file) FAST_FUNC;
688
689
690enum {
691 VISIBLE_ENDLINE = 1 << 0,
692 VISIBLE_SHOW_TABS = 1 << 1,
693};
694void visible(unsigned ch, char *buf, int flags) FAST_FUNC;
695
696
697
698void *malloc_or_warn(size_t size) FAST_FUNC RETURNS_MALLOC;
699void *xmalloc(size_t size) FAST_FUNC RETURNS_MALLOC;
700void *xzalloc(size_t size) FAST_FUNC RETURNS_MALLOC;
701void *xrealloc(void *old, size_t size) FAST_FUNC;
702
703
704
705
706
707
708
709#define xrealloc_vector(vector, shift, idx) \
710 xrealloc_vector_helper((vector), (sizeof((vector)[0]) << 8) + (shift), (idx))
711void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) FAST_FUNC;
712
713
714extern ssize_t safe_read(int fd, void *buf, size_t count) FAST_FUNC;
715extern ssize_t nonblock_immune_read(int fd, void *buf, size_t count, int loop_on_EINTR) FAST_FUNC;
716
717
718extern ssize_t full_read(int fd, void *buf, size_t count) FAST_FUNC;
719extern void xread(int fd, void *buf, size_t count) FAST_FUNC;
720extern unsigned char xread_char(int fd) FAST_FUNC;
721extern ssize_t read_close(int fd, void *buf, size_t maxsz) FAST_FUNC;
722extern ssize_t open_read_close(const char *filename, void *buf, size_t maxsz) FAST_FUNC;
723
724
725
726extern char *xmalloc_reads(int fd, size_t *maxsz_p) FAST_FUNC;
727
728extern void *xmalloc_read(int fd, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
729
730extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
731
732extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
733
734#if defined(ARG_MAX) && (ARG_MAX >= 60*1024 || !defined(_SC_ARG_MAX))
735
736# define bb_arg_max() ((unsigned)ARG_MAX)
737#elif defined(_SC_ARG_MAX)
738
739unsigned bb_arg_max(void) FAST_FUNC;
740#else
741
742# define bb_arg_max() ((unsigned)(32 * 1024))
743#endif
744unsigned bb_clk_tck(void) FAST_FUNC;
745
746#define SEAMLESS_COMPRESSION (0 \
747 || ENABLE_FEATURE_SEAMLESS_XZ \
748 || ENABLE_FEATURE_SEAMLESS_LZMA \
749 || ENABLE_FEATURE_SEAMLESS_BZ2 \
750 || ENABLE_FEATURE_SEAMLESS_GZ \
751 || ENABLE_FEATURE_SEAMLESS_Z)
752
753#if SEAMLESS_COMPRESSION
754
755extern int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC;
756
757extern int open_zipped(const char *fname, int fail_if_not_compressed) FAST_FUNC;
758extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
759#else
760# define setup_unzip_on_fd(...) (0)
761# define open_zipped(fname, fail_if_not_compressed) open((fname), O_RDONLY);
762# define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p))
763#endif
764
765extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC;
766
767
768extern ssize_t full_write(int fd, const void *buf, size_t count) FAST_FUNC;
769extern void xwrite(int fd, const void *buf, size_t count) FAST_FUNC;
770extern void xwrite_str(int fd, const char *str) FAST_FUNC;
771extern ssize_t full_write1_str(const char *str) FAST_FUNC;
772extern ssize_t full_write2_str(const char *str) FAST_FUNC;
773extern void xopen_xwrite_close(const char* file, const char *str) FAST_FUNC;
774
775
776extern void xclose(int fd) FAST_FUNC;
777
778
779extern void xprint_and_close_file(FILE *file) FAST_FUNC;
780
781
782
783
784
785
786extern char *bb_get_chunk_from_file(FILE *file, int *end) FAST_FUNC;
787
788extern char *xmalloc_fgets_str(FILE *file, const char *terminating_string) FAST_FUNC RETURNS_MALLOC;
789
790extern char *xmalloc_fgets_str_len(FILE *file, const char *terminating_string, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
791
792extern char *xmalloc_fgetline_str(FILE *file, const char *terminating_string) FAST_FUNC RETURNS_MALLOC;
793
794extern char *xmalloc_fgets(FILE *file) FAST_FUNC RETURNS_MALLOC;
795
796extern char *xmalloc_fgetline(FILE *file) FAST_FUNC RETURNS_MALLOC;
797
798
799
800void die_if_ferror(FILE *file, const char *msg) FAST_FUNC;
801void die_if_ferror_stdout(void) FAST_FUNC;
802int fflush_all(void) FAST_FUNC;
803void fflush_stdout_and_exit(int retval) NORETURN FAST_FUNC;
804int fclose_if_not_stdin(FILE *file) FAST_FUNC;
805FILE* xfopen(const char *filename, const char *mode) FAST_FUNC;
806
807FILE* fopen_or_warn(const char *filename, const char *mode) FAST_FUNC;
808
809FILE* xfopen_stdin(const char *filename) FAST_FUNC;
810FILE* fopen_or_warn_stdin(const char *filename) FAST_FUNC;
811FILE* fopen_for_read(const char *path) FAST_FUNC;
812FILE* xfopen_for_read(const char *path) FAST_FUNC;
813FILE* fopen_for_write(const char *path) FAST_FUNC;
814FILE* xfopen_for_write(const char *path) FAST_FUNC;
815FILE* xfdopen_for_read(int fd) FAST_FUNC;
816FILE* xfdopen_for_write(int fd) FAST_FUNC;
817
818int bb_pstrcmp(const void *a, const void *b) ;
819void qsort_string_vector(char **sv, unsigned count) FAST_FUNC;
820
821
822
823
824
825int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout_ms) FAST_FUNC;
826
827char *safe_gethostname(void) FAST_FUNC;
828
829
830char* str_tolower(char *str) FAST_FUNC;
831
832char *utoa(unsigned n) FAST_FUNC;
833char *itoa(int n) FAST_FUNC;
834
835char *utoa_to_buf(unsigned n, char *buf, unsigned buflen) FAST_FUNC;
836char *itoa_to_buf(int n, char *buf, unsigned buflen) FAST_FUNC;
837
838char *smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale) FAST_FUNC;
839char *smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC;
840
841
842
843
844#define HUMAN_READABLE_MAX_WIDTH 7
845#define HUMAN_READABLE_MAX_WIDTH_STR "7"
846
847const char *make_human_readable_str(unsigned long long size,
848 unsigned long block_size, unsigned long display_unit) FAST_FUNC;
849
850char *bin2hex(char *dst, const char *src, int count) FAST_FUNC;
851
852char* hex2bin(char *dst, const char *src, int count) FAST_FUNC;
853
854
855void generate_uuid(uint8_t *buf) FAST_FUNC;
856
857
858struct suffix_mult {
859 char suffix[4];
860 unsigned mult;
861};
862extern const struct suffix_mult bkm_suffixes[];
863#define km_suffixes (bkm_suffixes + 1)
864
865#include "xatonum.h"
866
867
868
869
870
871
872
873
874
875int xatoi_positive(const char *numstr) FAST_FUNC;
876
877
878uint16_t xatou16(const char *numstr) FAST_FUNC;
879
880
881
882
883
884long xuname2uid(const char *name) FAST_FUNC;
885long xgroup2gid(const char *name) FAST_FUNC;
886
887unsigned long get_ug_id(const char *s, long FAST_FUNC (*xname2id)(const char *)) FAST_FUNC;
888
889struct bb_uidgid_t {
890 uid_t uid;
891 gid_t gid;
892};
893
894int get_uidgid(struct bb_uidgid_t*, const char*, int numeric_ok) FAST_FUNC;
895
896void xget_uidgid(struct bb_uidgid_t*, const char*) FAST_FUNC;
897
898void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group) FAST_FUNC;
899struct passwd* xgetpwnam(const char *name) FAST_FUNC;
900struct group* xgetgrnam(const char *name) FAST_FUNC;
901struct passwd* xgetpwuid(uid_t uid) FAST_FUNC;
902struct group* xgetgrgid(gid_t gid) FAST_FUNC;
903char* xuid2uname(uid_t uid) FAST_FUNC;
904char* xgid2group(gid_t gid) FAST_FUNC;
905char* uid2uname(uid_t uid) FAST_FUNC;
906char* gid2group(gid_t gid) FAST_FUNC;
907char* uid2uname_utoa(uid_t uid) FAST_FUNC;
908char* gid2group_utoa(gid_t gid) FAST_FUNC;
909
910const char* get_cached_username(uid_t uid) FAST_FUNC;
911const char* get_cached_groupname(gid_t gid) FAST_FUNC;
912void clear_username_cache(void) FAST_FUNC;
913
914enum { USERNAME_MAX_SIZE = 32 - sizeof(uid_t) };
915#if ENABLE_FEATURE_CHECK_NAMES
916void die_if_bad_username(const char* name) FAST_FUNC;
917#else
918#define die_if_bad_username(name) ((void)(name))
919#endif
920
921#if ENABLE_FEATURE_UTMP
922void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
923void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
924#else
925# define write_new_utmp(pid, new_type, tty_name, username, hostname) ((void)0)
926# define update_utmp(pid, new_type, tty_name, username, hostname) ((void)0)
927#endif
928
929
930int file_is_executable(const char *name) FAST_FUNC;
931char *find_executable(const char *filename, char **PATHp) FAST_FUNC;
932int executable_exists(const char *filename) FAST_FUNC;
933
934
935
936
937#if ENABLE_FEATURE_PREFER_APPLETS
938int BB_EXECVP(const char *file, char *const argv[]) FAST_FUNC;
939#define BB_EXECLP(prog,cmd,...) \
940 do { \
941 if (find_applet_by_name(prog) >= 0) \
942 execlp(bb_busybox_exec_path, cmd, __VA_ARGS__); \
943 execlp(prog, cmd, __VA_ARGS__); \
944 } while (0)
945#else
946#define BB_EXECVP(prog,cmd) execvp(prog,cmd)
947#define BB_EXECLP(prog,cmd,...) execlp(prog,cmd,__VA_ARGS__)
948#endif
949int BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;
950
951
952
953#define xvfork() \
954({ \
955 pid_t bb__xvfork_pid = vfork(); \
956 if (bb__xvfork_pid < 0) \
957 bb_perror_msg_and_die("vfork"); \
958 bb__xvfork_pid; \
959})
960#if BB_MMU
961pid_t xfork(void) FAST_FUNC;
962#endif
963
964
965pid_t spawn(char **argv) FAST_FUNC;
966pid_t xspawn(char **argv) FAST_FUNC;
967
968pid_t safe_waitpid(pid_t pid, int *wstat, int options) FAST_FUNC;
969pid_t wait_any_nohang(int *wstat) FAST_FUNC;
970
971
972
973
974
975
976
977
978int wait4pid(pid_t pid) FAST_FUNC;
979
980int spawn_and_wait(char **argv) FAST_FUNC;
981
982int run_nofork_applet(int applet_no, char **argv) FAST_FUNC;
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007enum {
1008 DAEMON_CHDIR_ROOT = 1,
1009 DAEMON_DEVNULL_STDIO = 2,
1010 DAEMON_CLOSE_EXTRA_FDS = 4,
1011 DAEMON_ONLY_SANITIZE = 8,
1012 DAEMON_DOUBLE_FORK = 16,
1013};
1014#if BB_MMU
1015 enum { re_execed = 0 };
1016# define fork_or_rexec(argv) xfork()
1017# define bb_daemonize_or_rexec(flags, argv) bb_daemonize_or_rexec(flags)
1018# define bb_daemonize(flags) bb_daemonize_or_rexec(flags, bogus)
1019#else
1020 extern bool re_execed;
1021
1022
1023
1024 void re_exec(char **argv) NORETURN FAST_FUNC;
1025 pid_t fork_or_rexec(char **argv) FAST_FUNC;
1026 int BUG_fork_is_unavailable_on_nommu(void) FAST_FUNC;
1027 int BUG_daemon_is_unavailable_on_nommu(void) FAST_FUNC;
1028 void BUG_bb_daemonize_is_unavailable_on_nommu(void) FAST_FUNC;
1029# define fork() BUG_fork_is_unavailable_on_nommu()
1030# define xfork() BUG_fork_is_unavailable_on_nommu()
1031# define daemon(a,b) BUG_daemon_is_unavailable_on_nommu()
1032# define bb_daemonize(a) BUG_bb_daemonize_is_unavailable_on_nommu()
1033#endif
1034void bb_daemonize_or_rexec(int flags, char **argv) FAST_FUNC;
1035void bb_sanitize_stdio(void) FAST_FUNC;
1036
1037int sanitize_env_if_suid(void) FAST_FUNC;
1038
1039
1040char* single_argv(char **argv) FAST_FUNC;
1041extern const char *const bb_argv_dash[];
1042extern const char *opt_complementary;
1043#if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG
1044#define No_argument "\0"
1045#define Required_argument "\001"
1046#define Optional_argument "\002"
1047extern const char *applet_long_options;
1048#endif
1049extern uint32_t option_mask32;
1050extern uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC;
1051
1052
1053
1054
1055
1056
1057typedef struct llist_t {
1058 struct llist_t *link;
1059 char *data;
1060} llist_t;
1061void llist_add_to(llist_t **old_head, void *data) FAST_FUNC;
1062void llist_add_to_end(llist_t **list_head, void *data) FAST_FUNC;
1063void *llist_pop(llist_t **elm) FAST_FUNC;
1064void llist_unlink(llist_t **head, llist_t *elm) FAST_FUNC;
1065void llist_free(llist_t *elm, void (*freeit)(void *data)) FAST_FUNC;
1066llist_t *llist_rev(llist_t *list) FAST_FUNC;
1067llist_t *llist_find_str(llist_t *first, const char *str) FAST_FUNC;
1068
1069
1070
1071
1072
1073
1074#if ENABLE_FEATURE_PIDFILE || defined(WANT_PIDFILE)
1075
1076extern smallint wrote_pidfile;
1077void write_pidfile(const char *path) FAST_FUNC;
1078#define remove_pidfile(path) do { if (wrote_pidfile) unlink(path); } while (0)
1079#else
1080enum { wrote_pidfile = 0 };
1081#define write_pidfile(path) ((void)0)
1082#define remove_pidfile(path) ((void)0)
1083#endif
1084
1085enum {
1086 LOGMODE_NONE = 0,
1087 LOGMODE_STDIO = (1 << 0),
1088 LOGMODE_SYSLOG = (1 << 1) * ENABLE_FEATURE_SYSLOG,
1089 LOGMODE_BOTH = LOGMODE_SYSLOG + LOGMODE_STDIO,
1090};
1091extern const char *msg_eol;
1092extern smallint syslog_level;
1093extern smallint logmode;
1094extern int die_sleep;
1095extern uint8_t xfunc_error_retval;
1096extern jmp_buf die_jmp;
1097extern void xfunc_die(void) NORETURN FAST_FUNC;
1098extern void bb_show_usage(void) NORETURN FAST_FUNC;
1099extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1100extern void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
1101extern void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1102extern void bb_simple_perror_msg(const char *s) FAST_FUNC;
1103extern void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
1104extern void bb_simple_perror_msg_and_die(const char *s) NORETURN FAST_FUNC;
1105extern void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1106extern void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
1107extern void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC;
1108extern void bb_perror_nomsg(void) FAST_FUNC;
1109extern void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1110extern void bb_verror_msg(const char *s, va_list p, const char *strerr) FAST_FUNC;
1111extern void bb_logenv_override(void) FAST_FUNC;
1112
1113
1114
1115
1116#if ENABLE_FEATURE_INDIVIDUAL
1117#define MAIN_EXTERNALLY_VISIBLE EXTERNALLY_VISIBLE
1118#else
1119#define MAIN_EXTERNALLY_VISIBLE
1120#endif
1121
1122
1123
1124int bb_cat(char** argv);
1125
1126int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE);
1127int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE);
1128int test_main(int argc, char **argv) IF_TEST(MAIN_EXTERNALLY_VISIBLE);
1129int kill_main(int argc, char **argv) IF_KILL(MAIN_EXTERNALLY_VISIBLE);
1130
1131int chown_main(int argc, char **argv) IF_CHOWN(MAIN_EXTERNALLY_VISIBLE);
1132
1133int ls_main(int argc, char **argv) IF_LS(MAIN_EXTERNALLY_VISIBLE);
1134
1135int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1136int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1137
1138#if ENABLE_ROUTE
1139void bb_displayroutes(int noresolve, int netstatfmt) FAST_FUNC;
1140#endif
1141
1142
1143
1144
1145struct aftype {
1146 const char *name;
1147 const char *title;
1148 int af;
1149 int alen;
1150 char* FAST_FUNC (*print)(unsigned char *);
1151 const char* FAST_FUNC (*sprint)(struct sockaddr *, int numeric);
1152 int FAST_FUNC (*input)( const char *bufp, struct sockaddr *);
1153 void FAST_FUNC (*herror)(char *text);
1154 int FAST_FUNC (*rprint)(int options);
1155 int FAST_FUNC (*rinput)(int typ, int ext, char **argv);
1156
1157 int FAST_FUNC (*getmask)(char *src, struct sockaddr *mask, char *name);
1158};
1159
1160struct hwtype {
1161 const char *name;
1162 const char *title;
1163 int type;
1164 int alen;
1165 char* FAST_FUNC (*print)(unsigned char *);
1166 int FAST_FUNC (*input)(const char *, struct sockaddr *);
1167 int FAST_FUNC (*activate)(int fd);
1168 int suppress_null_addr;
1169};
1170extern smallint interface_opt_a;
1171int display_interfaces(char *ifname) FAST_FUNC;
1172int in_ether(const char *bufp, struct sockaddr *sap) FAST_FUNC;
1173#if ENABLE_FEATURE_HWIB
1174int in_ib(const char *bufp, struct sockaddr *sap) FAST_FUNC;
1175#else
1176#define in_ib(a, b) 1
1177#endif
1178const struct aftype *get_aftype(const char *name) FAST_FUNC;
1179const struct hwtype *get_hwtype(const char *name) FAST_FUNC;
1180const struct hwtype *get_hwntype(int type) FAST_FUNC;
1181
1182
1183#ifndef BUILD_INDIVIDUAL
1184extern int find_applet_by_name(const char *name) FAST_FUNC;
1185
1186extern void run_applet_and_exit(const char *name, char **argv) FAST_FUNC;
1187extern void run_applet_no_and_exit(int a, char **argv) NORETURN FAST_FUNC;
1188#endif
1189
1190#ifdef HAVE_MNTENT_H
1191extern int match_fstype(const struct mntent *mt, const char *fstypes) FAST_FUNC;
1192extern struct mntent *find_mount_point(const char *name, int subdir_too) FAST_FUNC;
1193#endif
1194extern void erase_mtab(const char * name) FAST_FUNC;
1195extern unsigned int tty_baud_to_value(speed_t speed) FAST_FUNC;
1196extern speed_t tty_value_to_baud(unsigned int value) FAST_FUNC;
1197#if ENABLE_DESKTOP
1198extern void bb_warn_ignoring_args(char *arg) FAST_FUNC;
1199#else
1200# define bb_warn_ignoring_args(arg) ((void)0)
1201#endif
1202
1203extern int get_linux_version_code(void) FAST_FUNC;
1204
1205extern char *query_loop(const char *device) FAST_FUNC;
1206extern int del_loop(const char *device) FAST_FUNC;
1207
1208
1209
1210extern int set_loop(char **devname, const char *file, unsigned long long offset, int ro) FAST_FUNC;
1211
1212
1213char *bb_ask_stdin(const char * prompt) FAST_FUNC;
1214
1215char *bb_ask(const int fd, int timeout, const char * prompt) FAST_FUNC;
1216int bb_ask_confirmation(void) FAST_FUNC;
1217
1218int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC;
1219
1220
1221
1222
1223enum {
1224 PARSE_COLLAPSE = 0x00010000,
1225 PARSE_TRIM = 0x00020000,
1226
1227 PARSE_GREEDY = 0x00040000,
1228 PARSE_MIN_DIE = 0x00100000,
1229
1230 PARSE_KEEP_COPY = 0x00200000 * ENABLE_FEATURE_CROND_D,
1231 PARSE_EOL_COMMENTS = 0x00400000,
1232
1233
1234
1235
1236
1237
1238 PARSE_NORMAL = PARSE_COLLAPSE | PARSE_TRIM | PARSE_GREEDY | PARSE_EOL_COMMENTS,
1239};
1240typedef struct parser_t {
1241 FILE *fp;
1242 char *data;
1243 char *line, *nline;
1244 size_t line_alloc, nline_alloc;
1245 int lineno;
1246} parser_t;
1247parser_t* config_open(const char *filename) FAST_FUNC;
1248parser_t* config_open2(const char *filename, FILE* FAST_FUNC (*fopen_func)(const char *path)) FAST_FUNC;
1249
1250int config_read(parser_t *parser, char **tokens, unsigned flags, const char *delims) FAST_FUNC;
1251#define config_read(parser, tokens, max, min, str, flags) \
1252 config_read(parser, tokens, ((flags) | (((min) & 0xFF) << 8) | ((max) & 0xFF)), str)
1253void config_close(parser_t *parser) FAST_FUNC;
1254
1255
1256
1257
1258
1259char *concat_path_file(const char *path, const char *filename) FAST_FUNC;
1260
1261char *concat_subpath_file(const char *path, const char *filename) FAST_FUNC;
1262
1263
1264int bb_make_directory(char *path, long mode, int flags) FAST_FUNC;
1265
1266int get_signum(const char *name) FAST_FUNC;
1267const char *get_signame(int number) FAST_FUNC;
1268void print_signames(void) FAST_FUNC;
1269
1270char *bb_simplify_path(const char *path) FAST_FUNC;
1271
1272char *bb_simplify_abs_path_inplace(char *path) FAST_FUNC;
1273
1274#ifndef LOGIN_FAIL_DELAY
1275#define LOGIN_FAIL_DELAY 3
1276#endif
1277extern void bb_do_delay(int seconds) FAST_FUNC;
1278extern void change_identity(const struct passwd *pw) FAST_FUNC;
1279extern void run_shell(const char *shell, int loginshell, const char *command, const char **additional_args) NORETURN FAST_FUNC;
1280
1281
1282
1283
1284
1285const char *get_shell_name(void) FAST_FUNC;
1286
1287#if ENABLE_SELINUX
1288extern void renew_current_security_context(void) FAST_FUNC;
1289extern void set_current_security_context(security_context_t sid) FAST_FUNC;
1290extern context_t set_security_context_component(security_context_t cur_context,
1291 char *user, char *role, char *type, char *range) FAST_FUNC;
1292extern void setfscreatecon_or_die(security_context_t scontext) FAST_FUNC;
1293extern void selinux_preserve_fcontext(int fdesc) FAST_FUNC;
1294#else
1295#define selinux_preserve_fcontext(fdesc) ((void)0)
1296#endif
1297extern void selinux_or_die(void) FAST_FUNC;
1298
1299
1300
1301#define SD_LISTEN_FDS_START 3
1302int sd_listen_fds(void);
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320#define SETUP_ENV_CHANGEENV (1 << 0)
1321#define SETUP_ENV_CLEARENV (1 << 1)
1322#define SETUP_ENV_TO_TMP (1 << 2)
1323#define SETUP_ENV_NO_CHDIR (1 << 4)
1324void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC;
1325void nuke_str(char *str) FAST_FUNC;
1326int check_password(const struct passwd *pw, const char *plaintext) FAST_FUNC;
1327int ask_and_check_password_extended(const struct passwd *pw, int timeout, const char *prompt) FAST_FUNC;
1328int ask_and_check_password(const struct passwd *pw) FAST_FUNC;
1329
1330#if !ENABLE_USE_BB_CRYPT
1331#define pw_encrypt(clear, salt, cleanup) pw_encrypt(clear, salt)
1332#endif
1333extern char *pw_encrypt(const char *clear, const char *salt, int cleanup) FAST_FUNC;
1334extern int obscure(const char *old, const char *newval, const struct passwd *pwdp) FAST_FUNC;
1335
1336
1337
1338
1339
1340
1341
1342
1343extern int crypt_make_salt(char *p, int cnt ) FAST_FUNC;
1344
1345#define MAX_PW_SALT_LEN (3 + 16 + 1)
1346extern char* crypt_make_pw_salt(char p[MAX_PW_SALT_LEN], const char *algo) FAST_FUNC;
1347
1348
1349
1350#if !(ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP)
1351#define update_passwd(filename, username, data, member) \
1352 update_passwd(filename, username, data)
1353#endif
1354extern int update_passwd(const char *filename,
1355 const char *username,
1356 const char *data,
1357 const char *member) FAST_FUNC;
1358
1359int index_in_str_array(const char *const string_array[], const char *key) FAST_FUNC;
1360int index_in_strings(const char *strings, const char *key) FAST_FUNC;
1361int index_in_substr_array(const char *const string_array[], const char *key) FAST_FUNC;
1362int index_in_substrings(const char *strings, const char *key) FAST_FUNC;
1363const char *nth_string(const char *strings, int n) FAST_FUNC;
1364
1365extern void print_login_issue(const char *issue_file, const char *tty) FAST_FUNC;
1366extern void print_login_prompt(void) FAST_FUNC;
1367
1368char *xmalloc_ttyname(int fd) FAST_FUNC RETURNS_MALLOC;
1369
1370int get_terminal_width_height(int fd, unsigned *width, unsigned *height) FAST_FUNC;
1371
1372int tcsetattr_stdin_TCSANOW(const struct termios *tp) FAST_FUNC;
1373
1374
1375int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC;
1376int ioctl_or_perror_and_die(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC;
1377#if ENABLE_IOCTL_HEX2STR_ERROR
1378int bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC;
1379int bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC;
1380#define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp,#request)
1381#define xioctl(fd,request,argp) bb_xioctl(fd,request,argp,#request)
1382#else
1383int bb_ioctl_or_warn(int fd, unsigned request, void *argp) FAST_FUNC;
1384int bb_xioctl(int fd, unsigned request, void *argp) FAST_FUNC;
1385#define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp)
1386#define xioctl(fd,request,argp) bb_xioctl(fd,request,argp)
1387#endif
1388
1389char *is_in_ino_dev_hashtable(const struct stat *statbuf) FAST_FUNC;
1390void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name) FAST_FUNC;
1391void reset_ino_dev_hashtable(void) FAST_FUNC;
1392#ifdef __GLIBC__
1393
1394unsigned long long bb_makedev(unsigned major, unsigned minor) FAST_FUNC;
1395#undef makedev
1396#define makedev(a,b) bb_makedev(a,b)
1397#endif
1398
1399
1400
1401
1402
1403
1404enum {
1405 KEYCODE_UP = -2,
1406 KEYCODE_DOWN = -3,
1407 KEYCODE_RIGHT = -4,
1408 KEYCODE_LEFT = -5,
1409 KEYCODE_HOME = -6,
1410 KEYCODE_END = -7,
1411 KEYCODE_INSERT = -8,
1412 KEYCODE_DELETE = -9,
1413 KEYCODE_PAGEUP = -10,
1414 KEYCODE_PAGEDOWN = -11,
1415
1416#if 0
1417 KEYCODE_FUN1 = -13,
1418 KEYCODE_FUN2 = -14,
1419 KEYCODE_FUN3 = -15,
1420 KEYCODE_FUN4 = -16,
1421 KEYCODE_FUN5 = -17,
1422 KEYCODE_FUN6 = -18,
1423 KEYCODE_FUN7 = -19,
1424 KEYCODE_FUN8 = -20,
1425 KEYCODE_FUN9 = -21,
1426 KEYCODE_FUN10 = -22,
1427 KEYCODE_FUN11 = -23,
1428 KEYCODE_FUN12 = -24,
1429#endif
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439 KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40,
1440 KEYCODE_CTRL_LEFT = KEYCODE_LEFT & ~0x40,
1441
1442
1443 KEYCODE_ALT_RIGHT = KEYCODE_RIGHT & ~0x20,
1444 KEYCODE_ALT_LEFT = KEYCODE_LEFT & ~0x20,
1445
1446 KEYCODE_CURSOR_POS = -0x100,
1447
1448
1449
1450
1451 KEYCODE_BUFFER_SIZE = 16
1452};
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466int64_t read_key(int fd, char *buffer, int timeout) FAST_FUNC;
1467void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC;
1468
1469
1470#if ENABLE_FEATURE_EDITING
1471
1472# if defined CONFIG_FEATURE_EDITING_HISTORY && CONFIG_FEATURE_EDITING_HISTORY > 0
1473# define MAX_HISTORY (CONFIG_FEATURE_EDITING_HISTORY + 0)
1474unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC;
1475# else
1476# define MAX_HISTORY 0
1477# endif
1478typedef struct line_input_t {
1479 int flags;
1480 const char *path_lookup;
1481# if MAX_HISTORY
1482 int cnt_history;
1483 int cur_history;
1484 int max_history;
1485# if ENABLE_FEATURE_EDITING_SAVEHISTORY
1486
1487
1488
1489
1490
1491
1492 unsigned cnt_history_in_file;
1493 const char *hist_file;
1494# endif
1495 char *history[MAX_HISTORY + 1];
1496# endif
1497} line_input_t;
1498enum {
1499 DO_HISTORY = 1 * (MAX_HISTORY > 0),
1500 TAB_COMPLETION = 2 * ENABLE_FEATURE_TAB_COMPLETION,
1501 USERNAME_COMPLETION = 4 * ENABLE_FEATURE_USERNAME_COMPLETION,
1502 VI_MODE = 8 * ENABLE_FEATURE_EDITING_VI,
1503 WITH_PATH_LOOKUP = 0x10,
1504 FOR_SHELL = DO_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION,
1505};
1506line_input_t *new_line_input_t(int flags) FAST_FUNC;
1507
1508
1509
1510
1511
1512
1513
1514
1515int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) FAST_FUNC;
1516void show_history(const line_input_t *st) FAST_FUNC;
1517# if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
1518void save_history(line_input_t *st);
1519# endif
1520#else
1521#define MAX_HISTORY 0
1522int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC;
1523#define read_line_input(state, prompt, command, maxsize, timeout) \
1524 read_line_input(prompt, command, maxsize)
1525#endif
1526
1527
1528#ifndef COMM_LEN
1529# ifdef TASK_COMM_LEN
1530enum { COMM_LEN = TASK_COMM_LEN };
1531# else
1532
1533enum { COMM_LEN = 16 };
1534# endif
1535#endif
1536
1537struct smaprec {
1538 unsigned long mapped_rw;
1539 unsigned long mapped_ro;
1540 unsigned long shared_clean;
1541 unsigned long shared_dirty;
1542 unsigned long private_clean;
1543 unsigned long private_dirty;
1544 unsigned long stack;
1545 unsigned long smap_pss, smap_swap;
1546 unsigned long smap_size;
1547 unsigned long smap_start;
1548 char smap_mode[5];
1549 char *smap_name;
1550};
1551
1552#if !ENABLE_PMAP
1553#define procps_read_smaps(pid, total, cb, data) \
1554 procps_read_smaps(pid, total)
1555#endif
1556int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
1557 void (*cb)(struct smaprec *, void *), void *data);
1558
1559typedef struct procps_status_t {
1560 DIR *dir;
1561 IF_FEATURE_SHOW_THREADS(DIR *task_dir;)
1562 uint8_t shift_pages_to_bytes;
1563 uint8_t shift_pages_to_kb;
1564
1565 uint16_t argv_len;
1566 char *argv0;
1567 char *exe;
1568 IF_SELINUX(char *context;)
1569 IF_FEATURE_SHOW_THREADS(unsigned main_thread_pid;)
1570
1571
1572 unsigned long vsz, rss;
1573 unsigned long stime, utime;
1574 unsigned long start_time;
1575 unsigned pid;
1576 unsigned ppid;
1577 unsigned pgid;
1578 unsigned sid;
1579 unsigned uid;
1580 unsigned gid;
1581#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
1582 unsigned ruid;
1583 unsigned rgid;
1584 int niceness;
1585#endif
1586 unsigned tty_major,tty_minor;
1587#if ENABLE_FEATURE_TOPMEM
1588 struct smaprec smaps;
1589#endif
1590 char state[4];
1591
1592
1593
1594 char comm[COMM_LEN];
1595
1596#if ENABLE_FEATURE_TOP_SMP_PROCESS
1597 int last_seen_on_cpu;
1598#endif
1599} procps_status_t;
1600
1601enum {
1602 PSSCAN_PID = 1 << 0,
1603 PSSCAN_PPID = 1 << 1,
1604 PSSCAN_PGID = 1 << 2,
1605 PSSCAN_SID = 1 << 3,
1606 PSSCAN_UIDGID = 1 << 4,
1607 PSSCAN_COMM = 1 << 5,
1608
1609 PSSCAN_ARGV0 = 1 << 7,
1610 PSSCAN_EXE = 1 << 8,
1611 PSSCAN_STATE = 1 << 9,
1612 PSSCAN_VSZ = 1 << 10,
1613 PSSCAN_RSS = 1 << 11,
1614 PSSCAN_STIME = 1 << 12,
1615 PSSCAN_UTIME = 1 << 13,
1616 PSSCAN_TTY = 1 << 14,
1617 PSSCAN_SMAPS = (1 << 15) * ENABLE_FEATURE_TOPMEM,
1618
1619
1620 PSSCAN_ARGVN = (1 << 16) * (ENABLE_KILLALL
1621 || ENABLE_PGREP || ENABLE_PKILL
1622 || ENABLE_PIDOF
1623 || ENABLE_SESTATUS
1624 ),
1625 PSSCAN_CONTEXT = (1 << 17) * ENABLE_SELINUX,
1626 PSSCAN_START_TIME = 1 << 18,
1627 PSSCAN_CPU = (1 << 19) * ENABLE_FEATURE_TOP_SMP_PROCESS,
1628 PSSCAN_NICE = (1 << 20) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
1629 PSSCAN_RUIDGID = (1 << 21) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
1630 PSSCAN_TASKS = (1 << 22) * ENABLE_FEATURE_SHOW_THREADS,
1631};
1632
1633void free_procps_scan(procps_status_t* sp) FAST_FUNC;
1634procps_status_t* procps_scan(procps_status_t* sp, int flags) FAST_FUNC;
1635
1636
1637void read_cmdline(char *buf, int size, unsigned pid, const char *comm) FAST_FUNC;
1638pid_t *find_pid_by_name(const char* procName) FAST_FUNC;
1639pid_t *pidlist_reverse(pid_t *pidList) FAST_FUNC;
1640int starts_with_cpu(const char *str) FAST_FUNC;
1641unsigned get_cpu_count(void) FAST_FUNC;
1642
1643
1644
1645
1646
1647
1648
1649
1650char *percent_decode_in_place(char *str, int strict) FAST_FUNC;
1651
1652
1653extern const char bb_uuenc_tbl_base64[] ALIGN1;
1654extern const char bb_uuenc_tbl_std[] ALIGN1;
1655void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC;
1656enum {
1657 BASE64_FLAG_UU_STOP = 0x100,
1658
1659 BASE64_FLAG_NO_STOP_CHAR = 0x80,
1660};
1661const char *decode_base64(char **pp_dst, const char *src) FAST_FUNC;
1662void read_base64(FILE *src_stream, FILE *dst_stream, int flags) FAST_FUNC;
1663
1664typedef struct md5_ctx_t {
1665 uint8_t wbuffer[64];
1666 void (*process_block)(struct md5_ctx_t*) FAST_FUNC;
1667 uint64_t total64;
1668 uint32_t hash[8];
1669} md5_ctx_t;
1670typedef struct md5_ctx_t sha1_ctx_t;
1671typedef struct md5_ctx_t sha256_ctx_t;
1672typedef struct sha512_ctx_t {
1673 uint64_t total64[2];
1674 uint64_t hash[8];
1675 uint8_t wbuffer[128];
1676} sha512_ctx_t;
1677typedef struct sha3_ctx_t {
1678 uint64_t state[25];
1679 unsigned bytes_queued;
1680} sha3_ctx_t;
1681void md5_begin(md5_ctx_t *ctx) FAST_FUNC;
1682void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1683void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC;
1684void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;
1685#define sha1_hash md5_hash
1686void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC;
1687void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
1688#define sha256_hash md5_hash
1689#define sha256_end sha1_end
1690void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
1691void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1692void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
1693void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC;
1694void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1695void sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC;
1696
1697extern uint32_t *global_crc32_table;
1698uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;
1699uint32_t crc32_block_endian1(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC;
1700uint32_t crc32_block_endian0(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC;
1701
1702typedef struct masks_labels_t {
1703 const char *labels;
1704 const int masks[];
1705} masks_labels_t;
1706int print_flags_separated(const int *masks, const char *labels,
1707 int flags, const char *separator) FAST_FUNC;
1708int print_flags(const masks_labels_t *ml, int flags) FAST_FUNC;
1709
1710typedef struct bb_progress_t {
1711 unsigned last_size;
1712 unsigned last_update_sec;
1713 unsigned last_change_sec;
1714 unsigned start_sec;
1715 const char *curfile;
1716} bb_progress_t;
1717
1718#define is_bb_progress_inited(p) ((p)->curfile != NULL)
1719#define bb_progress_free(p) do { \
1720 if (ENABLE_UNICODE_SUPPORT) free((char*)((p)->curfile)); \
1721 (p)->curfile = NULL; \
1722} while (0)
1723void bb_progress_init(bb_progress_t *p, const char *curfile) FAST_FUNC;
1724void bb_progress_update(bb_progress_t *p,
1725 uoff_t beg_range,
1726 uoff_t transferred,
1727 uoff_t totalsize) FAST_FUNC;
1728
1729
1730extern const char *applet_name;
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742extern const char bb_banner[] ALIGN1;
1743extern const char bb_msg_memory_exhausted[] ALIGN1;
1744extern const char bb_msg_invalid_date[] ALIGN1;
1745#define bb_msg_read_error "read error"
1746#define bb_msg_write_error "write error"
1747extern const char bb_msg_unknown[] ALIGN1;
1748extern const char bb_msg_can_not_create_raw_socket[] ALIGN1;
1749extern const char bb_msg_perm_denied_are_you_root[] ALIGN1;
1750extern const char bb_msg_you_must_be_root[] ALIGN1;
1751extern const char bb_msg_requires_arg[] ALIGN1;
1752extern const char bb_msg_invalid_arg[] ALIGN1;
1753extern const char bb_msg_standard_input[] ALIGN1;
1754extern const char bb_msg_standard_output[] ALIGN1;
1755
1756
1757extern const char bb_hexdigits_upcase[] ALIGN1;
1758
1759extern const char bb_path_wtmp_file[] ALIGN1;
1760
1761
1762
1763#define bb_path_mtab_file IF_FEATURE_MTAB_SUPPORT("/etc/mtab")IF_NOT_FEATURE_MTAB_SUPPORT("/proc/mounts")
1764
1765#define bb_path_passwd_file _PATH_PASSWD
1766#define bb_path_group_file _PATH_GROUP
1767#define bb_path_shadow_file _PATH_SHADOW
1768#define bb_path_gshadow_file _PATH_GSHADOW
1769
1770#define bb_path_motd_file "/etc/motd"
1771
1772#define bb_dev_null "/dev/null"
1773extern const char bb_busybox_exec_path[] ALIGN1;
1774
1775
1776extern const char bb_PATH_root_path[] ALIGN1;
1777#define bb_default_root_path (bb_PATH_root_path + sizeof("PATH"))
1778#define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin"))
1779
1780extern const int const_int_0;
1781extern const int const_int_1;
1782
1783
1784
1785enum { COMMON_BUFSIZE = (BUFSIZ >= 256*sizeof(void*) ? BUFSIZ+1 : 256*sizeof(void*)) };
1786extern char bb_common_bufsiz1[COMMON_BUFSIZE];
1787
1788
1789struct globals;
1790
1791
1792
1793extern struct globals *const ptr_to_globals;
1794
1795#define barrier() __asm__ __volatile__("":::"memory")
1796#define SET_PTR_TO_GLOBALS(x) do { \
1797 (*(struct globals**)&ptr_to_globals) = (void*)(x); \
1798 barrier(); \
1799} while (0)
1800#define FREE_PTR_TO_GLOBALS() do { \
1801 if (ENABLE_FEATURE_CLEAN_UP) { \
1802 free(ptr_to_globals); \
1803 } \
1804} while (0)
1805
1806
1807
1808
1809
1810#define LIBBB_DEFAULT_LOGIN_SHELL "-/bin/sh"
1811extern const char bb_default_login_shell[] ALIGN1;
1812
1813#define DEFAULT_SHELL (bb_default_login_shell+1)
1814
1815#define DEFAULT_SHELL_SHORT_NAME (bb_default_login_shell+6)
1816
1817
1818#define CURRENT_TTY "/dev/tty"
1819#define DEV_CONSOLE "/dev/console"
1820
1821#if defined(__FreeBSD_kernel__)
1822# define CURRENT_VC CURRENT_TTY
1823# define VC_1 "/dev/ttyv0"
1824# define VC_2 "/dev/ttyv1"
1825# define VC_3 "/dev/ttyv2"
1826# define VC_4 "/dev/ttyv3"
1827# define VC_5 "/dev/ttyv4"
1828# define VC_FORMAT "/dev/ttyv%d"
1829#elif defined(__GNU__)
1830# define CURRENT_VC CURRENT_TTY
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#elif ENABLE_FEATURE_DEVFS
1838
1839# define CURRENT_VC "/dev/vc/0"
1840# define VC_1 "/dev/vc/1"
1841# define VC_2 "/dev/vc/2"
1842# define VC_3 "/dev/vc/3"
1843# define VC_4 "/dev/vc/4"
1844# define VC_5 "/dev/vc/5"
1845# define VC_FORMAT "/dev/vc/%d"
1846# define LOOP_FORMAT "/dev/loop/%u"
1847# define LOOP_NAMESIZE (sizeof("/dev/loop/") + sizeof(int)*3 + 1)
1848# define LOOP_NAME "/dev/loop/"
1849# define FB_0 "/dev/fb/0"
1850#else
1851
1852# define CURRENT_VC "/dev/tty0"
1853# define VC_1 "/dev/tty1"
1854# define VC_2 "/dev/tty2"
1855# define VC_3 "/dev/tty3"
1856# define VC_4 "/dev/tty4"
1857# define VC_5 "/dev/tty5"
1858# define VC_FORMAT "/dev/tty%d"
1859# define LOOP_FORMAT "/dev/loop%u"
1860# define LOOP_NAMESIZE (sizeof("/dev/loop") + sizeof(int)*3 + 1)
1861# define LOOP_NAME "/dev/loop"
1862# define FB_0 "/dev/fb0"
1863#endif
1864
1865
1866#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))
1867
1868
1869
1870
1871
1872
1873#undef isalnum
1874#undef isalpha
1875#undef isascii
1876#undef isblank
1877#undef iscntrl
1878#undef isdigit
1879#undef isgraph
1880#undef islower
1881#undef isprint
1882#undef ispunct
1883#undef isspace
1884#undef isupper
1885#undef isxdigit
1886#undef toupper
1887#undef tolower
1888
1889
1890
1891
1892
1893
1894#define isascii(a) ((unsigned char)(a) <= 0x7f)
1895#define isdigit(a) ((unsigned char)((a) - '0') <= 9)
1896#define isupper(a) ((unsigned char)((a) - 'A') <= ('Z' - 'A'))
1897#define islower(a) ((unsigned char)((a) - 'a') <= ('z' - 'a'))
1898#define isalpha(a) ((unsigned char)(((a)|0x20) - 'a') <= ('z' - 'a'))
1899#define isblank(a) ({ unsigned char bb__isblank = (a); bb__isblank == ' ' || bb__isblank == '\t'; })
1900#define iscntrl(a) ({ unsigned char bb__iscntrl = (a); bb__iscntrl < ' ' || bb__iscntrl == 0x7f; })
1901
1902
1903
1904#define isspace(a) ({ unsigned char bb__isspace = (a) - 9; bb__isspace == (' ' - 9) || bb__isspace <= (13 - 9); })
1905
1906#define ispunct(a) (strchrnul("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", (a))[0])
1907
1908#define isalnum(a) bb_ascii_isalnum(a)
1909static ALWAYS_INLINE int bb_ascii_isalnum(unsigned char a)
1910{
1911 unsigned char b = a - '0';
1912 if (b <= 9)
1913 return (b <= 9);
1914 b = (a|0x20) - 'a';
1915 return b <= 'z' - 'a';
1916}
1917#define isxdigit(a) bb_ascii_isxdigit(a)
1918static ALWAYS_INLINE int bb_ascii_isxdigit(unsigned char a)
1919{
1920 unsigned char b = a - '0';
1921 if (b <= 9)
1922 return (b <= 9);
1923 b = (a|0x20) - 'a';
1924 return b <= 'f' - 'a';
1925}
1926#define toupper(a) bb_ascii_toupper(a)
1927static ALWAYS_INLINE unsigned char bb_ascii_toupper(unsigned char a)
1928{
1929 unsigned char b = a - 'a';
1930 if (b <= ('z' - 'a'))
1931 a -= 'a' - 'A';
1932 return a;
1933}
1934#define tolower(a) bb_ascii_tolower(a)
1935static ALWAYS_INLINE unsigned char bb_ascii_tolower(unsigned char a)
1936{
1937 unsigned char b = a - 'A';
1938 if (b <= ('Z' - 'A'))
1939 a += 'a' - 'A';
1940 return a;
1941}
1942
1943
1944
1945#define isgraph(a) isgraph_is_ambiguous_dont_use(a)
1946#define isprint(a) isprint_is_ambiguous_dont_use(a)
1947
1948#define isgraph_asciionly(a) ((unsigned)((a) - 0x21) <= 0x7e - 0x21)
1949#define isprint_asciionly(a) ((unsigned)((a) - 0x20) <= 0x7e - 0x20)
1950
1951
1952
1953
1954typedef void (*bbunit_testfunc)(void);
1955
1956struct bbunit_listelem {
1957 struct bbunit_listelem* next;
1958 const char* name;
1959 bbunit_testfunc testfunc;
1960};
1961
1962void bbunit_registertest(struct bbunit_listelem* test);
1963void bbunit_settestfailed(void);
1964
1965#define BBUNIT_DEFINE_TEST(NAME) \
1966 static void bbunit_##NAME##_test(void); \
1967 static struct bbunit_listelem bbunit_##NAME##_elem = { \
1968 .name = #NAME, \
1969 .testfunc = bbunit_##NAME##_test, \
1970 }; \
1971 static void INIT_FUNC bbunit_##NAME##_register(void) \
1972 { \
1973 bbunit_registertest(&bbunit_##NAME##_elem); \
1974 } \
1975 static void bbunit_##NAME##_test(void)
1976
1977
1978
1979
1980
1981#define BBUNIT_ENDTEST \
1982 do { \
1983 goto bbunit_end; \
1984 bbunit_end: \
1985 break; \
1986 } while (0)
1987
1988#define BBUNIT_PRINTASSERTFAIL \
1989 do { \
1990 bb_error_msg( \
1991 "[ERROR] Assertion failed in file %s, line %d", \
1992 __FILE__, __LINE__); \
1993 } while (0)
1994
1995#define BBUNIT_ASSERTION_FAILED \
1996 do { \
1997 bbunit_settestfailed(); \
1998 goto bbunit_end; \
1999 } while (0)
2000
2001
2002
2003
2004
2005
2006
2007#define BBUNIT_ASSERT_EQ(EXPECTED, ACTUAL) \
2008 do { \
2009 if ((EXPECTED) != (ACTUAL)) { \
2010 BBUNIT_PRINTASSERTFAIL; \
2011 bb_error_msg("[ERROR] '%s' isn't equal to '%s'", \
2012 #EXPECTED, #ACTUAL); \
2013 BBUNIT_ASSERTION_FAILED; \
2014 } \
2015 } while (0)
2016
2017#define BBUNIT_ASSERT_NOTEQ(EXPECTED, ACTUAL) \
2018 do { \
2019 if ((EXPECTED) == (ACTUAL)) { \
2020 BBUNIT_PRINTASSERTFAIL; \
2021 bb_error_msg("[ERROR] '%s' is equal to '%s'", \
2022 #EXPECTED, #ACTUAL); \
2023 BBUNIT_ASSERTION_FAILED; \
2024 } \
2025 } while (0)
2026
2027#define BBUNIT_ASSERT_NOTNULL(PTR) \
2028 do { \
2029 if ((PTR) == NULL) { \
2030 BBUNIT_PRINTASSERTFAIL; \
2031 bb_error_msg("[ERROR] '%s' is NULL!", #PTR); \
2032 BBUNIT_ASSERTION_FAILED; \
2033 } \
2034 } while (0)
2035
2036#define BBUNIT_ASSERT_NULL(PTR) \
2037 do { \
2038 if ((PTR) != NULL) { \
2039 BBUNIT_PRINTASSERTFAIL; \
2040 bb_error_msg("[ERROR] '%s' is not NULL!", #PTR); \
2041 BBUNIT_ASSERTION_FAILED; \
2042 } \
2043 } while (0)
2044
2045#define BBUNIT_ASSERT_FALSE(STATEMENT) \
2046 do { \
2047 if ((STATEMENT)) { \
2048 BBUNIT_PRINTASSERTFAIL; \
2049 bb_error_msg("[ERROR] Statement '%s' evaluated to true!", \
2050 #STATEMENT); \
2051 BBUNIT_ASSERTION_FAILED; \
2052 } \
2053 } while (0)
2054
2055#define BBUNIT_ASSERT_TRUE(STATEMENT) \
2056 do { \
2057 if (!(STATEMENT)) { \
2058 BBUNIT_PRINTASSERTFAIL; \
2059 bb_error_msg("[ERROR] Statement '%s' evaluated to false!", \
2060 #STATEMENT); \
2061 BBUNIT_ASSERTION_FAILED; \
2062 } \
2063 } while (0)
2064
2065#define BBUNIT_ASSERT_STREQ(STR1, STR2) \
2066 do { \
2067 if (strcmp(STR1, STR2) != 0) { \
2068 BBUNIT_PRINTASSERTFAIL; \
2069 bb_error_msg("[ERROR] Strings '%s' and '%s' " \
2070 "are not the same", STR1, STR2); \
2071 BBUNIT_ASSERTION_FAILED; \
2072 } \
2073 } while (0)
2074
2075#define BBUNIT_ASSERT_STRNOTEQ(STR1, STR2) \
2076 do { \
2077 if (strcmp(STR1, STR2) == 0) { \
2078 BBUNIT_PRINTASSERTFAIL; \
2079 bb_error_msg("[ERROR] Strings '%s' and '%s' " \
2080 "are the same, but were " \
2081 "expected to differ", STR1, STR2); \
2082 BBUNIT_ASSERTION_FAILED; \
2083 } \
2084 } while (0)
2085
2086
2087POP_SAVED_FUNCTION_VISIBILITY
2088
2089#endif
2090