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