source: MondoRescue/branches/3.3/mindi-busybox/include/libbb.h@ 3723

Last change on this file since 3723 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 79.4 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * Busybox main internal header file
4 *
5 * Based in part on code from sash, Copyright (c) 1999 by David I. Bell
6 * Permission has been granted to redistribute this code under GPL.
7 *
8 * Licensed under GPLv2, see file LICENSE in this source tree.
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#include <paths.h>
24#if defined __UCLIBC__ /* TODO: and glibc? */
25/* use inlined versions of these: */
26# define sigfillset(s) __sigfillset(s)
27# define sigemptyset(s) __sigemptyset(s)
28# define sigisemptyset(s) __sigisemptyset(s)
29#endif
30#include <stdint.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <stdarg.h>
34#include <stddef.h>
35#include <string.h>
36/* There are two incompatible basename's, let's not use them! */
37/* See the dirname/basename man page for details */
38#include <libgen.h> /* dirname,basename */
39#undef basename
40#define basename dont_use_basename
41#include <poll.h>
42#include <sys/ioctl.h>
43#include <sys/mman.h>
44#include <sys/socket.h>
45#include <sys/stat.h>
46#include <sys/time.h>
47#include <sys/types.h>
48#ifndef major
49# include <sys/sysmacros.h>
50#endif
51#include <sys/wait.h>
52#include <termios.h>
53#include <time.h>
54#include <sys/param.h>
55#include <pwd.h>
56#include <grp.h>
57#if ENABLE_FEATURE_SHADOWPASSWDS
58# if !ENABLE_USE_BB_SHADOW
59/* If using busybox's shadow implementation, do not include the shadow.h
60 * header as the toolchain may not provide it at all.
61 */
62# include <shadow.h>
63# endif
64#endif
65#if defined(ANDROID) || defined(__ANDROID__)
66# define endpwent() ((void)0)
67# define endgrent() ((void)0)
68#endif
69#ifdef HAVE_MNTENT_H
70# include <mntent.h>
71#endif
72#ifdef HAVE_SYS_STATFS_H
73# include <sys/statfs.h>
74#endif
75/* Don't do this here:
76 * #include <sys/sysinfo.h>
77 * Some linux/ includes pull in conflicting definition
78 * of struct sysinfo (only in some toolchanins), which breaks build.
79 * Include sys/sysinfo.h only in those files which need it.
80 */
81#if ENABLE_SELINUX
82# include <selinux/selinux.h>
83# include <selinux/context.h>
84# include <selinux/flask.h>
85# include <selinux/av_permissions.h>
86#endif
87#if ENABLE_FEATURE_UTMP
88# if defined __UCLIBC__ && ( \
89 (UCLIBC_VERSION >= KERNEL_VERSION(0, 9, 32) \
90 && UCLIBC_VERSION < KERNEL_VERSION(0, 9, 34) \
91 && defined __UCLIBC_HAS_UTMPX__ \
92 ) || ( \
93 UCLIBC_VERSION >= KERNEL_VERSION(0, 9, 34) \
94 ) \
95 )
96# include <utmpx.h>
97# elif defined __UCLIBC__
98# include <utmp.h>
99# define utmpx utmp
100# define setutxent setutent
101# define endutxent endutent
102# define getutxent getutent
103# define getutxid getutid
104# define getutxline getutline
105# define pututxline pututline
106# define utmpxname utmpname
107# define updwtmpx updwtmp
108# define _PATH_UTMPX _PATH_UTMP
109# else
110# include <utmp.h>
111# include <utmpx.h>
112# if defined _PATH_UTMP && !defined _PATH_UTMPX
113# define _PATH_UTMPX _PATH_UTMP
114# endif
115# endif
116#endif
117#if ENABLE_LOCALE_SUPPORT
118# include <locale.h>
119#else
120# define setlocale(x,y) ((void)0)
121#endif
122#ifdef DMALLOC
123# include <dmalloc.h>
124#endif
125/* Just in case libc doesn't define some of these... */
126#ifndef _PATH_PASSWD
127#define _PATH_PASSWD "/etc/passwd"
128#endif
129#ifndef _PATH_GROUP
130#define _PATH_GROUP "/etc/group"
131#endif
132#ifndef _PATH_SHADOW
133#define _PATH_SHADOW "/etc/shadow"
134#endif
135#ifndef _PATH_GSHADOW
136#define _PATH_GSHADOW "/etc/gshadow"
137#endif
138#if defined __FreeBSD__ || defined __OpenBSD__
139# include <netinet/in.h>
140# include <arpa/inet.h>
141#elif defined __APPLE__
142# include <netinet/in.h>
143#else
144# include <arpa/inet.h>
145//This breaks on bionic:
146//# if !defined(__socklen_t_defined) && !defined(_SOCKLEN_T_DECLARED)
147///* We #define socklen_t *after* includes, otherwise we get
148// * typedef redefinition errors from system headers
149// * (in case "is it defined already" detection above failed)
150// */
151//# define socklen_t bb_socklen_t
152// typedef unsigned socklen_t;
153//# endif
154//if this is still needed, add a fix along the lines of
155// ifdef SPECIFIC_BROKEN_LIBC_CHECK / typedef socklen_t / endif
156//in platform.h instead!
157#endif
158#ifndef HAVE_CLEARENV
159# define clearenv() do { if (environ) environ[0] = NULL; } while (0)
160#endif
161#ifndef HAVE_FDATASYNC
162# define fdatasync fsync
163#endif
164#ifndef HAVE_XTABS
165# define XTABS TAB3
166#endif
167
168
169/* Some libc's forget to declare these, do it ourself */
170
171extern char **environ;
172#if defined(__GLIBC__) && __GLIBC__ < 2
173int vdprintf(int d, const char *format, va_list ap);
174#endif
175/* klogctl is in libc's klog.h, but we cheat and not #include that */
176int klogctl(int type, char *b, int len);
177#ifndef PATH_MAX
178# define PATH_MAX 256
179#endif
180#ifndef BUFSIZ
181# define BUFSIZ 4096
182#endif
183
184
185/* Busybox does not use threads, we can speed up stdio. */
186#ifdef HAVE_UNLOCKED_STDIO
187# undef getc
188# define getc(stream) getc_unlocked(stream)
189# undef getchar
190# define getchar() getchar_unlocked()
191# undef putc
192# define putc(c, stream) putc_unlocked(c, stream)
193# undef putchar
194# define putchar(c) putchar_unlocked(c)
195# undef fgetc
196# define fgetc(stream) getc_unlocked(stream)
197# undef fputc
198# define fputc(c, stream) putc_unlocked(c, stream)
199#endif
200/* Above functions are required by POSIX.1-2008, below ones are extensions */
201#ifdef HAVE_UNLOCKED_LINE_OPS
202# undef fgets
203# define fgets(s, n, stream) fgets_unlocked(s, n, stream)
204# undef fputs
205# define fputs(s, stream) fputs_unlocked(s, stream)
206#endif
207
208
209/* Make all declarations hidden (-fvisibility flag only affects definitions) */
210/* (don't include system headers after this until corresponding pop!) */
211PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
212
213
214#if ENABLE_USE_BB_PWD_GRP
215# include "pwd_.h"
216# include "grp_.h"
217#endif
218#if ENABLE_FEATURE_SHADOWPASSWDS
219# if ENABLE_USE_BB_SHADOW
220# include "shadow_.h"
221# endif
222#endif
223
224/* Tested to work correctly with all int types (IIRC :]) */
225#define MAXINT(T) (T)( \
226 ((T)-1) > 0 \
227 ? (T)-1 \
228 : (T)~((T)1 << (sizeof(T)*8-1)) \
229 )
230
231#define MININT(T) (T)( \
232 ((T)-1) > 0 \
233 ? (T)0 \
234 : ((T)1 << (sizeof(T)*8-1)) \
235 )
236
237/* Large file support */
238/* Note that CONFIG_LFS=y forces bbox to be built with all common ops
239 * (stat, lseek etc) mapped to "largefile" variants by libc.
240 * Practically it means that open() automatically has O_LARGEFILE added
241 * and all filesize/file_offset parameters and struct members are "large"
242 * (in today's world - signed 64bit). For full support of large files,
243 * we need a few helper #defines (below) and careful use of off_t
244 * instead of int/ssize_t. No lseek64(), O_LARGEFILE etc necessary */
245#if ENABLE_LFS
246/* CONFIG_LFS is on */
247# if ULONG_MAX > 0xffffffff
248/* "long" is long enough on this system */
249typedef unsigned long uoff_t;
250# define XATOOFF(a) xatoul_range((a), 0, LONG_MAX)
251/* usage: sz = BB_STRTOOFF(s, NULL, 10); if (errno || sz < 0) die(); */
252# define BB_STRTOOFF bb_strtoul
253# define STRTOOFF strtoul
254/* usage: printf("size: %"OFF_FMT"d (%"OFF_FMT"x)\n", sz, sz); */
255# define OFF_FMT "l"
256# else
257/* "long" is too short, need "long long" */
258typedef unsigned long long uoff_t;
259# define XATOOFF(a) xatoull_range((a), 0, LLONG_MAX)
260# define BB_STRTOOFF bb_strtoull
261# define STRTOOFF strtoull
262# define OFF_FMT "ll"
263# endif
264#else
265/* CONFIG_LFS is off */
266# if UINT_MAX == 0xffffffff
267/* While sizeof(off_t) == sizeof(int), off_t is typedef'ed to long anyway.
268 * gcc will throw warnings on printf("%d", off_t). Crap... */
269typedef unsigned long uoff_t;
270# define XATOOFF(a) xatoi_positive(a)
271# define BB_STRTOOFF bb_strtou
272# define STRTOOFF strtol
273# define OFF_FMT "l"
274# else
275typedef unsigned long uoff_t;
276# define XATOOFF(a) xatoul_range((a), 0, LONG_MAX)
277# define BB_STRTOOFF bb_strtoul
278# define STRTOOFF strtol
279# define OFF_FMT "l"
280# endif
281#endif
282/* scary. better ideas? (but do *test* them first!) */
283#define OFF_T_MAX ((off_t)~((off_t)1 << (sizeof(off_t)*8-1)))
284/* Users report bionic to use 32-bit off_t even if LARGEFILE support is requested.
285 * We misdetected that. Don't let it build:
286 */
287struct BUG_off_t_size_is_misdetected {
288 char BUG_off_t_size_is_misdetected[sizeof(off_t) == sizeof(uoff_t) ? 1 : -1];
289};
290
291/* Some useful definitions */
292#undef FALSE
293#define FALSE ((int) 0)
294#undef TRUE
295#define TRUE ((int) 1)
296#undef SKIP
297#define SKIP ((int) 2)
298
299/* Macros for min/max. */
300#ifndef MIN
301#define MIN(a,b) (((a)<(b))?(a):(b))
302#endif
303
304#ifndef MAX
305#define MAX(a,b) (((a)>(b))?(a):(b))
306#endif
307
308/* buffer allocation schemes */
309#if ENABLE_FEATURE_BUFFERS_GO_ON_STACK
310#define RESERVE_CONFIG_BUFFER(buffer,len) char buffer[len]
311#define RESERVE_CONFIG_UBUFFER(buffer,len) unsigned char buffer[len]
312#define RELEASE_CONFIG_BUFFER(buffer) ((void)0)
313#else
314#if ENABLE_FEATURE_BUFFERS_GO_IN_BSS
315#define RESERVE_CONFIG_BUFFER(buffer,len) static char buffer[len]
316#define RESERVE_CONFIG_UBUFFER(buffer,len) static unsigned char buffer[len]
317#define RELEASE_CONFIG_BUFFER(buffer) ((void)0)
318#else
319#define RESERVE_CONFIG_BUFFER(buffer,len) char *buffer = xmalloc(len)
320#define RESERVE_CONFIG_UBUFFER(buffer,len) unsigned char *buffer = xmalloc(len)
321#define RELEASE_CONFIG_BUFFER(buffer) free(buffer)
322#endif
323#endif
324
325#if defined(__GLIBC__)
326/* glibc uses __errno_location() to get a ptr to errno */
327/* We can just memorize it once - no multithreading in busybox :) */
328extern int *const bb_errno;
329#undef errno
330#define errno (*bb_errno)
331#endif
332
333#if !(ULONG_MAX > 0xffffffff)
334/* Only 32-bit CPUs need this, 64-bit ones use inlined version */
335uint64_t bb_bswap_64(uint64_t x) FAST_FUNC;
336#endif
337
338unsigned long long monotonic_ns(void) FAST_FUNC;
339unsigned long long monotonic_us(void) FAST_FUNC;
340unsigned long long monotonic_ms(void) FAST_FUNC;
341unsigned monotonic_sec(void) FAST_FUNC;
342
343extern void chomp(char *s) FAST_FUNC;
344extern void trim(char *s) FAST_FUNC;
345extern char *skip_whitespace(const char *) FAST_FUNC;
346extern char *skip_non_whitespace(const char *) FAST_FUNC;
347extern char *skip_dev_pfx(const char *tty_name) FAST_FUNC;
348
349extern char *strrstr(const char *haystack, const char *needle) FAST_FUNC;
350
351//TODO: supply a pointer to char[11] buffer (avoid statics)?
352extern const char *bb_mode_string(mode_t mode) FAST_FUNC;
353extern int is_directory(const char *name, int followLinks) FAST_FUNC;
354enum { /* cp.c, mv.c, install.c depend on these values. CAREFUL when changing them! */
355 FILEUTILS_PRESERVE_STATUS = 1 << 0, /* -p */
356 FILEUTILS_DEREFERENCE = 1 << 1, /* !-d */
357 FILEUTILS_RECUR = 1 << 2, /* -R */
358 FILEUTILS_FORCE = 1 << 3, /* -f */
359 FILEUTILS_INTERACTIVE = 1 << 4, /* -i */
360 FILEUTILS_MAKE_HARDLINK = 1 << 5, /* -l */
361 FILEUTILS_MAKE_SOFTLINK = 1 << 6, /* -s */
362 FILEUTILS_DEREF_SOFTLINK = 1 << 7, /* -L */
363 FILEUTILS_DEREFERENCE_L0 = 1 << 8, /* -H */
364 /* -a = -pdR (mapped in cp.c) */
365 /* -r = -dR (mapped in cp.c) */
366 /* -P = -d (mapped in cp.c) */
367 FILEUTILS_VERBOSE = (1 << 12) * ENABLE_FEATURE_VERBOSE, /* -v */
368 FILEUTILS_UPDATE = 1 << 13, /* -u */
369#if ENABLE_SELINUX
370 FILEUTILS_PRESERVE_SECURITY_CONTEXT = 1 << 14, /* -c */
371#endif
372 FILEUTILS_RMDEST = 1 << (15 - !ENABLE_SELINUX), /* --remove-destination */
373 /*
374 * Hole. cp may have some bits set here,
375 * they should not affect remove_file()/copy_file()
376 */
377#if ENABLE_SELINUX
378 FILEUTILS_SET_SECURITY_CONTEXT = 1 << 30,
379#endif
380 FILEUTILS_IGNORE_CHMOD_ERR = 1 << 31,
381};
382#define FILEUTILS_CP_OPTSTR "pdRfilsLHarPvu" IF_SELINUX("c")
383extern int remove_file(const char *path, int flags) FAST_FUNC;
384/* NB: without FILEUTILS_RECUR in flags, it will basically "cat"
385 * the source, not copy (unless "source" is a directory).
386 * This makes "cp /dev/null file" and "install /dev/null file" (!!!)
387 * work coreutils-compatibly. */
388extern int copy_file(const char *source, const char *dest, int flags) FAST_FUNC;
389
390enum {
391 ACTION_RECURSE = (1 << 0),
392 ACTION_FOLLOWLINKS = (1 << 1),
393 ACTION_FOLLOWLINKS_L0 = (1 << 2),
394 ACTION_DEPTHFIRST = (1 << 3),
395 /*ACTION_REVERSE = (1 << 4), - unused */
396 ACTION_QUIET = (1 << 5),
397 ACTION_DANGLING_OK = (1 << 6),
398};
399typedef uint8_t recurse_flags_t;
400extern int recursive_action(const char *fileName, unsigned flags,
401 int FAST_FUNC (*fileAction)(const char *fileName, struct stat* statbuf, void* userData, int depth),
402 int FAST_FUNC (*dirAction)(const char *fileName, struct stat* statbuf, void* userData, int depth),
403 void* userData, unsigned depth) FAST_FUNC;
404extern int device_open(const char *device, int mode) FAST_FUNC;
405enum { GETPTY_BUFSIZE = 16 }; /* more than enough for "/dev/ttyXXX" */
406extern int xgetpty(char *line) FAST_FUNC;
407extern int get_console_fd_or_die(void) FAST_FUNC;
408extern void console_make_active(int fd, const int vt_num) FAST_FUNC;
409extern char *find_block_device(const char *path) FAST_FUNC;
410/* bb_copyfd_XX print read/write errors and return -1 if they occur */
411extern off_t bb_copyfd_eof(int fd1, int fd2) FAST_FUNC;
412extern off_t bb_copyfd_size(int fd1, int fd2, off_t size) FAST_FUNC;
413extern void bb_copyfd_exact_size(int fd1, int fd2, off_t size) FAST_FUNC;
414/* "short" copy can be detected by return value < size */
415/* this helper yells "short read!" if param is not -1 */
416extern void complain_copyfd_and_die(off_t sz) NORETURN FAST_FUNC;
417
418extern char bb_process_escape_sequence(const char **ptr) FAST_FUNC;
419char* strcpy_and_process_escape_sequences(char *dst, const char *src) FAST_FUNC;
420/* xxxx_strip version can modify its parameter:
421 * "/" -> "/"
422 * "abc" -> "abc"
423 * "abc/def" -> "def"
424 * "abc/def/" -> "def" !!
425 */
426char *bb_get_last_path_component_strip(char *path) FAST_FUNC;
427/* "abc/def/" -> "" and it never modifies 'path' */
428char *bb_get_last_path_component_nostrip(const char *path) FAST_FUNC;
429/* Simpler version: does not special case "/" string */
430const char *bb_basename(const char *name) FAST_FUNC;
431/* NB: can violate const-ness (similarly to strchr) */
432char *last_char_is(const char *s, int c) FAST_FUNC;
433const char* endofname(const char *name) FAST_FUNC;
434char *is_prefixed_with(const char *string, const char *key) FAST_FUNC;
435char *is_suffixed_with(const char *string, const char *key) FAST_FUNC;
436
437int ndelay_on(int fd) FAST_FUNC;
438int ndelay_off(int fd) FAST_FUNC;
439void close_on_exec_on(int fd) FAST_FUNC;
440void xdup2(int, int) FAST_FUNC;
441void xmove_fd(int, int) FAST_FUNC;
442
443
444DIR *xopendir(const char *path) FAST_FUNC;
445DIR *warn_opendir(const char *path) FAST_FUNC;
446
447char *xmalloc_realpath(const char *path) FAST_FUNC RETURNS_MALLOC;
448char *xmalloc_readlink(const char *path) FAST_FUNC RETURNS_MALLOC;
449char *xmalloc_readlink_or_warn(const char *path) FAST_FUNC RETURNS_MALLOC;
450/* !RETURNS_MALLOC: it's a realloc-like function */
451char *xrealloc_getcwd_or_warn(char *cwd) FAST_FUNC;
452
453char *xmalloc_follow_symlinks(const char *path) FAST_FUNC RETURNS_MALLOC;
454
455
456enum {
457 /* bb_signals(BB_FATAL_SIGS, handler) catches all signals which
458 * otherwise would kill us, except for those resulting from bugs:
459 * SIGSEGV, SIGILL, SIGFPE.
460 * Other fatal signals not included (TODO?):
461 * SIGBUS Bus error (bad memory access)
462 * SIGPOLL Pollable event. Synonym of SIGIO
463 * SIGPROF Profiling timer expired
464 * SIGSYS Bad argument to routine
465 * SIGTRAP Trace/breakpoint trap
466 *
467 * The only known arch with some of these sigs not fitting
468 * into 32 bits is parisc (SIGXCPU=33, SIGXFSZ=34, SIGSTKFLT=36).
469 * Dance around with long long to guard against that...
470 */
471 BB_FATAL_SIGS = (int)(0
472 + (1LL << SIGHUP)
473 + (1LL << SIGINT)
474 + (1LL << SIGTERM)
475 + (1LL << SIGPIPE) // Write to pipe with no readers
476 + (1LL << SIGQUIT) // Quit from keyboard
477 + (1LL << SIGABRT) // Abort signal from abort(3)
478 + (1LL << SIGALRM) // Timer signal from alarm(2)
479 + (1LL << SIGVTALRM) // Virtual alarm clock
480 + (1LL << SIGXCPU) // CPU time limit exceeded
481 + (1LL << SIGXFSZ) // File size limit exceeded
482 + (1LL << SIGUSR1) // Yes kids, these are also fatal!
483 + (1LL << SIGUSR2)
484 + 0),
485};
486void bb_signals(int sigs, void (*f)(int)) FAST_FUNC;
487/* Unlike signal() and bb_signals, sets handler with sigaction()
488 * and in a way that while signal handler is run, no other signals
489 * will be blocked; syscalls will not be restarted: */
490void bb_signals_recursive_norestart(int sigs, void (*f)(int)) FAST_FUNC;
491/* syscalls like read() will be interrupted with EINTR: */
492void signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int)) FAST_FUNC;
493/* syscalls like read() won't be interrupted (though select/poll will be): */
494void signal_SA_RESTART_empty_mask(int sig, void (*handler)(int)) FAST_FUNC;
495void wait_for_any_sig(void) FAST_FUNC;
496void kill_myself_with_sig(int sig) NORETURN FAST_FUNC;
497void sig_block(int sig) FAST_FUNC;
498void sig_unblock(int sig) FAST_FUNC;
499/* Will do sigaction(signum, act, NULL): */
500int sigaction_set(int sig, const struct sigaction *act) FAST_FUNC;
501/* SIG_BLOCK/SIG_UNBLOCK all signals: */
502int sigprocmask_allsigs(int how) FAST_FUNC;
503/* Standard handler which just records signo */
504extern smallint bb_got_signal;
505void record_signo(int signo); /* not FAST_FUNC! */
506
507
508void xsetgid(gid_t gid) FAST_FUNC;
509void xsetuid(uid_t uid) FAST_FUNC;
510void xsetegid(gid_t egid) FAST_FUNC;
511void xseteuid(uid_t euid) FAST_FUNC;
512void xchdir(const char *path) FAST_FUNC;
513void xfchdir(int fd) FAST_FUNC;
514void xchroot(const char *path) FAST_FUNC;
515void xsetenv(const char *key, const char *value) FAST_FUNC;
516void bb_unsetenv(const char *key) FAST_FUNC;
517void bb_unsetenv_and_free(char *key) FAST_FUNC;
518void xunlink(const char *pathname) FAST_FUNC;
519void xstat(const char *pathname, struct stat *buf) FAST_FUNC;
520void xfstat(int fd, struct stat *buf, const char *errmsg) FAST_FUNC;
521int open3_or_warn(const char *pathname, int flags, int mode) FAST_FUNC;
522int open_or_warn(const char *pathname, int flags) FAST_FUNC;
523int xopen3(const char *pathname, int flags, int mode) FAST_FUNC;
524int xopen(const char *pathname, int flags) FAST_FUNC;
525int xopen_nonblocking(const char *pathname) FAST_FUNC;
526int xopen_as_uid_gid(const char *pathname, int flags, uid_t u, gid_t g) FAST_FUNC;
527int open_or_warn_stdin(const char *pathname) FAST_FUNC;
528int xopen_stdin(const char *pathname) FAST_FUNC;
529void xrename(const char *oldpath, const char *newpath) FAST_FUNC;
530int rename_or_warn(const char *oldpath, const char *newpath) FAST_FUNC;
531off_t xlseek(int fd, off_t offset, int whence) FAST_FUNC;
532int xmkstemp(char *template) FAST_FUNC;
533off_t fdlength(int fd) FAST_FUNC;
534
535uoff_t FAST_FUNC get_volume_size_in_bytes(int fd,
536 const char *override,
537 unsigned override_units,
538 int extend);
539
540void xpipe(int filedes[2]) FAST_FUNC;
541/* In this form code with pipes is much more readable */
542struct fd_pair { int rd; int wr; };
543#define piped_pair(pair) pipe(&((pair).rd))
544#define xpiped_pair(pair) xpipe(&((pair).rd))
545
546/* Useful for having small structure members/global variables */
547typedef int8_t socktype_t;
548typedef int8_t family_t;
549struct BUG_too_small {
550 char BUG_socktype_t_too_small[(0
551 | SOCK_STREAM
552 | SOCK_DGRAM
553 | SOCK_RDM
554 | SOCK_SEQPACKET
555 | SOCK_RAW
556 ) <= 127 ? 1 : -1];
557 char BUG_family_t_too_small[(0
558 | AF_UNSPEC
559 | AF_INET
560 | AF_INET6
561 | AF_UNIX
562#ifdef AF_PACKET
563 | AF_PACKET
564#endif
565#ifdef AF_NETLINK
566 | AF_NETLINK
567#endif
568 /* | AF_DECnet */
569 /* | AF_IPX */
570 ) <= 127 ? 1 : -1];
571};
572
573
574void parse_datestr(const char *date_str, struct tm *ptm) FAST_FUNC;
575time_t validate_tm_time(const char *date_str, struct tm *ptm) FAST_FUNC;
576char *strftime_HHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC;
577char *strftime_YYYYMMDDHHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC;
578
579int xsocket(int domain, int type, int protocol) FAST_FUNC;
580void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) FAST_FUNC;
581void xlisten(int s, int backlog) FAST_FUNC;
582void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) FAST_FUNC;
583ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
584 socklen_t tolen) FAST_FUNC;
585
586int setsockopt_int(int fd, int level, int optname, int optval) FAST_FUNC;
587int setsockopt_1(int fd, int level, int optname) FAST_FUNC;
588int setsockopt_SOL_SOCKET_int(int fd, int optname, int optval) FAST_FUNC;
589int setsockopt_SOL_SOCKET_1(int fd, int optname) FAST_FUNC;
590/* SO_REUSEADDR allows a server to rebind to an address that is already
591 * "in use" by old connections to e.g. previous server instance which is
592 * killed or crashed. Without it bind will fail until all such connections
593 * time out. Linux does not allow multiple live binds on same ip:port
594 * regardless of SO_REUSEADDR (unlike some other flavors of Unix).
595 * Turn it on before you call bind(). */
596void setsockopt_reuseaddr(int fd) FAST_FUNC; /* On Linux this never fails. */
597int setsockopt_keepalive(int fd) FAST_FUNC;
598int setsockopt_broadcast(int fd) FAST_FUNC;
599int setsockopt_bindtodevice(int fd, const char *iface) FAST_FUNC;
600/* NB: returns port in host byte order */
601unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port) FAST_FUNC;
602typedef struct len_and_sockaddr {
603 socklen_t len;
604 union {
605 struct sockaddr sa;
606 struct sockaddr_in sin;
607#if ENABLE_FEATURE_IPV6
608 struct sockaddr_in6 sin6;
609#endif
610 } u;
611} len_and_sockaddr;
612enum {
613 LSA_LEN_SIZE = offsetof(len_and_sockaddr, u),
614 LSA_SIZEOF_SA = sizeof(
615 union {
616 struct sockaddr sa;
617 struct sockaddr_in sin;
618#if ENABLE_FEATURE_IPV6
619 struct sockaddr_in6 sin6;
620#endif
621 }
622 )
623};
624/* Create stream socket, and allocate suitable lsa.
625 * (lsa of correct size and lsa->sa.sa_family (AF_INET/AF_INET6))
626 * af == AF_UNSPEC will result in trying to create IPv6 socket,
627 * and if kernel doesn't support it, fall back to IPv4.
628 * This is useful if you plan to bind to resulting local lsa.
629 */
630int xsocket_type(len_and_sockaddr **lsap, int af, int sock_type) FAST_FUNC;
631int xsocket_stream(len_and_sockaddr **lsap) FAST_FUNC;
632/* Create server socket bound to bindaddr:port. bindaddr can be NULL,
633 * numeric IP ("N.N.N.N") or numeric IPv6 address,
634 * and can have ":PORT" suffix (for IPv6 use "[X:X:...:X]:PORT").
635 * Only if there is no suffix, port argument is used */
636/* NB: these set SO_REUSEADDR before bind */
637int create_and_bind_stream_or_die(const char *bindaddr, int port) FAST_FUNC;
638int create_and_bind_dgram_or_die(const char *bindaddr, int port) FAST_FUNC;
639/* Create client TCP socket connected to peer:port. Peer cannot be NULL.
640 * Peer can be numeric IP ("N.N.N.N"), numeric IPv6 address or hostname,
641 * and can have ":PORT" suffix (for IPv6 use "[X:X:...:X]:PORT").
642 * If there is no suffix, port argument is used */
643int create_and_connect_stream_or_die(const char *peer, int port) FAST_FUNC;
644/* Connect to peer identified by lsa */
645int xconnect_stream(const len_and_sockaddr *lsa) FAST_FUNC;
646/* Get local address of bound or accepted socket */
647len_and_sockaddr *get_sock_lsa(int fd) FAST_FUNC RETURNS_MALLOC;
648/* Get remote address of connected or accepted socket */
649len_and_sockaddr *get_peer_lsa(int fd) FAST_FUNC RETURNS_MALLOC;
650/* Return malloc'ed len_and_sockaddr with socket address of host:port
651 * Currently will return IPv4 or IPv6 sockaddrs only
652 * (depending on host), but in theory nothing prevents e.g.
653 * UNIX socket address being returned, IPX sockaddr etc...
654 * On error does bb_error_msg and returns NULL */
655len_and_sockaddr* host2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
656/* Version which dies on error */
657len_and_sockaddr* xhost2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
658len_and_sockaddr* xdotted2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
659/* Same, useful if you want to force family (e.g. IPv6) */
660#if !ENABLE_FEATURE_IPV6
661#define host_and_af2sockaddr(host, port, af) host2sockaddr((host), (port))
662#define xhost_and_af2sockaddr(host, port, af) xhost2sockaddr((host), (port))
663#else
664len_and_sockaddr* host_and_af2sockaddr(const char *host, int port, sa_family_t af) FAST_FUNC RETURNS_MALLOC;
665len_and_sockaddr* xhost_and_af2sockaddr(const char *host, int port, sa_family_t af) FAST_FUNC RETURNS_MALLOC;
666#endif
667/* Assign sin[6]_port member if the socket is an AF_INET[6] one,
668 * otherwise no-op. Useful for ftp.
669 * NB: does NOT do htons() internally, just direct assignment. */
670void set_nport(struct sockaddr *sa, unsigned port) FAST_FUNC;
671/* Retrieve sin[6]_port or return -1 for non-INET[6] lsa's */
672int get_nport(const struct sockaddr *sa) FAST_FUNC;
673/* Reverse DNS. Returns NULL on failure. */
674char* xmalloc_sockaddr2host(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
675/* This one doesn't append :PORTNUM */
676char* xmalloc_sockaddr2host_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
677/* This one also doesn't fall back to dotted IP (returns NULL) */
678char* xmalloc_sockaddr2hostonly_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
679/* inet_[ap]ton on steroids */
680char* xmalloc_sockaddr2dotted(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
681char* xmalloc_sockaddr2dotted_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
682// "old" (ipv4 only) API
683// users: traceroute.c hostname.c - use _list_ of all IPs
684struct hostent *xgethostbyname(const char *name) FAST_FUNC;
685// Also mount.c and inetd.c are using gethostbyname(),
686// + inet_common.c has additional IPv4-only stuff
687
688
689void socket_want_pktinfo(int fd) FAST_FUNC;
690ssize_t send_to_from(int fd, void *buf, size_t len, int flags,
691 const struct sockaddr *to,
692 const struct sockaddr *from,
693 socklen_t tolen) FAST_FUNC;
694ssize_t recv_from_to(int fd, void *buf, size_t len, int flags,
695 struct sockaddr *from,
696 struct sockaddr *to,
697 socklen_t sa_size) FAST_FUNC;
698
699uint16_t inet_cksum(uint16_t *addr, int len) FAST_FUNC;
700
701char *xstrdup(const char *s) FAST_FUNC RETURNS_MALLOC;
702char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC;
703void *xmemdup(const void *s, int n) FAST_FUNC RETURNS_MALLOC;
704void overlapping_strcpy(char *dst, const char *src) FAST_FUNC;
705char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC;
706char *strncpy_IFNAMSIZ(char *dst, const char *src) FAST_FUNC;
707unsigned count_strstr(const char *str, const char *sub) FAST_FUNC;
708char *xmalloc_substitute_string(const char *src, int count, const char *sub, const char *repl) FAST_FUNC;
709/* Guaranteed to NOT be a macro (smallest code). Saves nearly 2k on uclibc.
710 * But potentially slow, don't use in one-billion-times loops */
711int bb_putchar(int ch) FAST_FUNC;
712/* Note: does not use stdio, writes to fd 2 directly */
713int bb_putchar_stderr(char ch) FAST_FUNC;
714char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC;
715char *auto_string(char *str) FAST_FUNC;
716// gcc-4.1.1 still isn't good enough at optimizing it
717// (+200 bytes compared to macro)
718//static ALWAYS_INLINE
719//int LONE_DASH(const char *s) { return s[0] == '-' && !s[1]; }
720//static ALWAYS_INLINE
721//int NOT_LONE_DASH(const char *s) { return s[0] != '-' || s[1]; }
722#define LONE_DASH(s) ((s)[0] == '-' && !(s)[1])
723#define NOT_LONE_DASH(s) ((s)[0] != '-' || (s)[1])
724#define LONE_CHAR(s,c) ((s)[0] == (c) && !(s)[1])
725#define NOT_LONE_CHAR(s,c) ((s)[0] != (c) || (s)[1])
726#define DOT_OR_DOTDOT(s) ((s)[0] == '.' && (!(s)[1] || ((s)[1] == '.' && !(s)[2])))
727
728typedef struct uni_stat_t {
729 unsigned byte_count;
730 unsigned unicode_count;
731 unsigned unicode_width;
732} uni_stat_t;
733/* Returns a string with unprintable chars replaced by '?' or
734 * SUBST_WCHAR. This function is unicode-aware. */
735const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str);
736/* Prints unprintable char ch as ^C or M-c to file
737 * (M-c is used only if ch is ORed with PRINTABLE_META),
738 * else it is printed as-is (except for ch = 0x9b) */
739enum { PRINTABLE_META = 0x100 };
740void fputc_printable(int ch, FILE *file) FAST_FUNC;
741/* Return a string that is the printable representation of character ch.
742 * Buffer must hold at least four characters. */
743enum {
744 VISIBLE_ENDLINE = 1 << 0,
745 VISIBLE_SHOW_TABS = 1 << 1,
746};
747void visible(unsigned ch, char *buf, int flags) FAST_FUNC;
748
749/* dmalloc will redefine these to it's own implementation. It is safe
750 * to have the prototypes here unconditionally. */
751void *malloc_or_warn(size_t size) FAST_FUNC RETURNS_MALLOC;
752void *xmalloc(size_t size) FAST_FUNC RETURNS_MALLOC;
753void *xzalloc(size_t size) FAST_FUNC RETURNS_MALLOC;
754void *xrealloc(void *old, size_t size) FAST_FUNC;
755/* After v = xrealloc_vector(v, SHIFT, idx) it's ok to use
756 * at least v[idx] and v[idx+1], for all idx values.
757 * SHIFT specifies how many new elements are added (1:2, 2:4, ..., 8:256...)
758 * when all elements are used up. New elements are zeroed out.
759 * xrealloc_vector(v, SHIFT, idx) *MUST* be called with consecutive IDXs -
760 * skipping an index is a bad bug - it may miss a realloc!
761 */
762#define xrealloc_vector(vector, shift, idx) \
763 xrealloc_vector_helper((vector), (sizeof((vector)[0]) << 8) + (shift), (idx))
764void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) FAST_FUNC;
765
766
767extern ssize_t safe_read(int fd, void *buf, size_t count) FAST_FUNC;
768extern ssize_t nonblock_immune_read(int fd, void *buf, size_t count) FAST_FUNC;
769// NB: will return short read on error, not -1,
770// if some data was read before error occurred
771extern ssize_t full_read(int fd, void *buf, size_t count) FAST_FUNC;
772extern void xread(int fd, void *buf, size_t count) FAST_FUNC;
773extern unsigned char xread_char(int fd) FAST_FUNC;
774extern ssize_t read_close(int fd, void *buf, size_t maxsz) FAST_FUNC;
775extern ssize_t open_read_close(const char *filename, void *buf, size_t maxsz) FAST_FUNC;
776// Reads one line a-la fgets (but doesn't save terminating '\n').
777// Reads byte-by-byte. Useful when it is important to not read ahead.
778// Bytes are appended to pfx (which must be malloced, or NULL).
779extern char *xmalloc_reads(int fd, size_t *maxsz_p) FAST_FUNC;
780/* Reads block up to *maxsz_p (default: INT_MAX - 4095) */
781extern void *xmalloc_read(int fd, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
782/* Returns NULL if file can't be opened (default max size: INT_MAX - 4095) */
783extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
784/* Never returns NULL */
785extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
786
787#if defined(ARG_MAX) && (ARG_MAX >= 60*1024 || !defined(_SC_ARG_MAX))
788/* Use _constant_ maximum if: defined && (big enough || no variable one exists) */
789# define bb_arg_max() ((unsigned)ARG_MAX)
790#elif defined(_SC_ARG_MAX)
791/* Else use variable one (a bit more expensive) */
792unsigned bb_arg_max(void) FAST_FUNC;
793#else
794/* If all else fails */
795# define bb_arg_max() ((unsigned)(32 * 1024))
796#endif
797unsigned bb_clk_tck(void) FAST_FUNC;
798
799#define SEAMLESS_COMPRESSION (0 \
800 || ENABLE_FEATURE_SEAMLESS_XZ \
801 || ENABLE_FEATURE_SEAMLESS_LZMA \
802 || ENABLE_FEATURE_SEAMLESS_BZ2 \
803 || ENABLE_FEATURE_SEAMLESS_GZ \
804 || ENABLE_FEATURE_SEAMLESS_Z)
805
806#if SEAMLESS_COMPRESSION
807/* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */
808extern int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC;
809/* Autodetects .gz etc */
810extern int open_zipped(const char *fname, int fail_if_not_compressed) FAST_FUNC;
811extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
812#else
813# define setup_unzip_on_fd(...) (0)
814# define open_zipped(fname, fail_if_not_compressed) open((fname), O_RDONLY);
815# define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p))
816#endif
817
818extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC;
819// NB: will return short write on error, not -1,
820// if some data was written before error occurred
821extern ssize_t full_write(int fd, const void *buf, size_t count) FAST_FUNC;
822extern void xwrite(int fd, const void *buf, size_t count) FAST_FUNC;
823extern void xwrite_str(int fd, const char *str) FAST_FUNC;
824extern ssize_t full_write1_str(const char *str) FAST_FUNC;
825extern ssize_t full_write2_str(const char *str) FAST_FUNC;
826extern void xopen_xwrite_close(const char* file, const char *str) FAST_FUNC;
827
828/* Close fd, but check for failures (some types of write errors) */
829extern void xclose(int fd) FAST_FUNC;
830
831/* Reads and prints to stdout till eof, then closes FILE. Exits on error: */
832extern void xprint_and_close_file(FILE *file) FAST_FUNC;
833
834/* Reads a line from a text file, up to a newline or NUL byte, inclusive.
835 * Returns malloc'ed char*. If end is NULL '\n' isn't considered
836 * end of line. If end isn't NULL, length of the chunk is stored in it.
837 * Returns NULL if EOF/error.
838 */
839extern char *bb_get_chunk_from_file(FILE *file, int *end) FAST_FUNC;
840/* Reads up to (and including) TERMINATING_STRING: */
841extern char *xmalloc_fgets_str(FILE *file, const char *terminating_string) FAST_FUNC RETURNS_MALLOC;
842/* Same, with limited max size, and returns the length (excluding NUL): */
843extern char *xmalloc_fgets_str_len(FILE *file, const char *terminating_string, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
844/* Chops off TERMINATING_STRING from the end: */
845extern char *xmalloc_fgetline_str(FILE *file, const char *terminating_string) FAST_FUNC RETURNS_MALLOC;
846/* Reads up to (and including) "\n" or NUL byte: */
847extern char *xmalloc_fgets(FILE *file) FAST_FUNC RETURNS_MALLOC;
848/* Chops off '\n' from the end, unlike fgets: */
849extern char *xmalloc_fgetline(FILE *file) FAST_FUNC RETURNS_MALLOC;
850/* Same, but doesn't try to conserve space (may have some slack after the end) */
851/* extern char *xmalloc_fgetline_fast(FILE *file) FAST_FUNC RETURNS_MALLOC; */
852
853void die_if_ferror(FILE *file, const char *msg) FAST_FUNC;
854void die_if_ferror_stdout(void) FAST_FUNC;
855int fflush_all(void) FAST_FUNC;
856void fflush_stdout_and_exit(int retval) NORETURN FAST_FUNC;
857int fclose_if_not_stdin(FILE *file) FAST_FUNC;
858FILE* xfopen(const char *filename, const char *mode) FAST_FUNC;
859/* Prints warning to stderr and returns NULL on failure: */
860FILE* fopen_or_warn(const char *filename, const char *mode) FAST_FUNC;
861/* "Opens" stdin if filename is special, else just opens file: */
862FILE* xfopen_stdin(const char *filename) FAST_FUNC;
863FILE* fopen_or_warn_stdin(const char *filename) FAST_FUNC;
864FILE* fopen_for_read(const char *path) FAST_FUNC;
865FILE* xfopen_for_read(const char *path) FAST_FUNC;
866FILE* fopen_for_write(const char *path) FAST_FUNC;
867FILE* xfopen_for_write(const char *path) FAST_FUNC;
868FILE* xfdopen_for_read(int fd) FAST_FUNC;
869FILE* xfdopen_for_write(int fd) FAST_FUNC;
870
871int bb_pstrcmp(const void *a, const void *b) /* not FAST_FUNC! */;
872void qsort_string_vector(char **sv, unsigned count) FAST_FUNC;
873
874/* Wrapper which restarts poll on EINTR or ENOMEM.
875 * On other errors complains [perror("poll")] and returns.
876 * Warning! May take (much) longer than timeout_ms to return!
877 * If this is a problem, use bare poll and open-code EINTR/ENOMEM handling */
878int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout_ms) FAST_FUNC;
879
880char *safe_gethostname(void) FAST_FUNC;
881
882/* Convert each alpha char in str to lower-case */
883char* str_tolower(char *str) FAST_FUNC;
884
885char *utoa(unsigned n) FAST_FUNC;
886char *itoa(int n) FAST_FUNC;
887/* Returns a pointer past the formatted number, does NOT null-terminate */
888char *utoa_to_buf(unsigned n, char *buf, unsigned buflen) FAST_FUNC;
889char *itoa_to_buf(int n, char *buf, unsigned buflen) FAST_FUNC;
890/* Intelligent formatters of bignums */
891char *smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale) FAST_FUNC;
892char *smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC;
893/* If block_size == 0, display size without fractional part,
894 * else display (size * block_size) with one decimal digit.
895 * If display_unit == 0, show value no bigger than 1024 with suffix (K,M,G...),
896 * else divide by display_unit and do not use suffix. */
897#define HUMAN_READABLE_MAX_WIDTH 7 /* "1024.0G" */
898#define HUMAN_READABLE_MAX_WIDTH_STR "7"
899//TODO: provide pointer to buf (avoid statics)?
900const char *make_human_readable_str(unsigned long long size,
901 unsigned long block_size, unsigned long display_unit) FAST_FUNC;
902/* Put a string of hex bytes ("1b2e66fe"...), return advanced pointer */
903char *bin2hex(char *dst, const char *src, int count) FAST_FUNC;
904/* Reverse */
905char* hex2bin(char *dst, const char *src, int count) FAST_FUNC;
906
907/* Generate a UUID */
908void generate_uuid(uint8_t *buf) FAST_FUNC;
909
910/* Last element is marked by mult == 0 */
911struct suffix_mult {
912 char suffix[4];
913 unsigned mult;
914};
915extern const struct suffix_mult bkm_suffixes[];
916#define km_suffixes (bkm_suffixes + 1)
917extern const struct suffix_mult cwbkMG_suffixes[];
918#define kMG_suffixes (cwbkMG_suffixes + 3)
919
920#include "xatonum.h"
921/* Specialized: */
922
923/* Using xatoi() instead of naive atoi() is not always convenient -
924 * in many places people want *non-negative* values, but store them
925 * in signed int. Therefore we need this one:
926 * dies if input is not in [0, INT_MAX] range. Also will reject '-0' etc.
927 * It should really be named xatoi_nonnegative (since it allows 0),
928 * but that would be too long.
929 */
930int xatoi_positive(const char *numstr) FAST_FUNC;
931
932/* Useful for reading port numbers */
933uint16_t xatou16(const char *numstr) FAST_FUNC;
934
935
936/* These parse entries in /etc/passwd and /etc/group. This is desirable
937 * for BusyBox since we want to avoid using the glibc NSS stuff, which
938 * increases target size and is often not needed on embedded systems. */
939long xuname2uid(const char *name) FAST_FUNC;
940long xgroup2gid(const char *name) FAST_FUNC;
941/* wrapper: allows string to contain numeric uid or gid */
942unsigned long get_ug_id(const char *s, long FAST_FUNC (*xname2id)(const char *)) FAST_FUNC;
943struct bb_uidgid_t {
944 uid_t uid;
945 gid_t gid;
946};
947/* always sets uid and gid; returns 0 on failure */
948int get_uidgid(struct bb_uidgid_t*, const char*) FAST_FUNC;
949/* always sets uid and gid; exits on failure */
950void xget_uidgid(struct bb_uidgid_t*, const char*) FAST_FUNC;
951/* chown-like handling of "user[:[group]" */
952void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group) FAST_FUNC;
953struct passwd* xgetpwnam(const char *name) FAST_FUNC;
954struct group* xgetgrnam(const char *name) FAST_FUNC;
955struct passwd* xgetpwuid(uid_t uid) FAST_FUNC;
956struct group* xgetgrgid(gid_t gid) FAST_FUNC;
957char* xuid2uname(uid_t uid) FAST_FUNC;
958char* xgid2group(gid_t gid) FAST_FUNC;
959char* uid2uname(uid_t uid) FAST_FUNC;
960char* gid2group(gid_t gid) FAST_FUNC;
961char* uid2uname_utoa(uid_t uid) FAST_FUNC;
962char* gid2group_utoa(gid_t gid) FAST_FUNC;
963/* versions which cache results (useful for ps, ls etc) */
964const char* get_cached_username(uid_t uid) FAST_FUNC;
965const char* get_cached_groupname(gid_t gid) FAST_FUNC;
966void clear_username_cache(void) FAST_FUNC;
967/* internally usernames are saved in fixed-sized char[] buffers */
968enum { USERNAME_MAX_SIZE = 32 - sizeof(uid_t) };
969#if ENABLE_FEATURE_CHECK_NAMES
970void die_if_bad_username(const char* name) FAST_FUNC;
971#else
972#define die_if_bad_username(name) ((void)(name))
973#endif
974
975#if ENABLE_FEATURE_UTMP
976void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
977void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
978void FAST_FUNC update_utmp_DEAD_PROCESS(pid_t pid);
979#else
980# define write_new_utmp(pid, new_type, tty_name, username, hostname) ((void)0)
981# define update_utmp(pid, new_type, tty_name, username, hostname) ((void)0)
982# define update_utmp_DEAD_PROCESS(pid) ((void)0)
983#endif
984
985
986int file_is_executable(const char *name) FAST_FUNC;
987char *find_executable(const char *filename, char **PATHp) FAST_FUNC;
988int executable_exists(const char *filename) FAST_FUNC;
989
990/* BB_EXECxx always execs (it's not doing NOFORK/NOEXEC stuff),
991 * but it may exec busybox and call applet instead of searching PATH.
992 */
993#if ENABLE_FEATURE_PREFER_APPLETS
994int BB_EXECVP(const char *file, char *const argv[]) FAST_FUNC;
995#define BB_EXECLP(prog,cmd,...) \
996 do { \
997 if (find_applet_by_name(prog) >= 0) \
998 execlp(bb_busybox_exec_path, cmd, __VA_ARGS__); \
999 execlp(prog, cmd, __VA_ARGS__); \
1000 } while (0)
1001#else
1002#define BB_EXECVP(prog,cmd) execvp(prog,cmd)
1003#define BB_EXECLP(prog,cmd,...) execlp(prog,cmd,__VA_ARGS__)
1004#endif
1005void BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;
1006void exec_prog_or_SHELL(char **argv) NORETURN FAST_FUNC;
1007
1008/* xvfork() can't be a _function_, return after vfork in child mangles stack
1009 * in the parent. It must be a macro. */
1010#define xvfork() \
1011({ \
1012 pid_t bb__xvfork_pid = vfork(); \
1013 if (bb__xvfork_pid < 0) \
1014 bb_perror_msg_and_die("vfork"); \
1015 bb__xvfork_pid; \
1016})
1017#if BB_MMU
1018pid_t xfork(void) FAST_FUNC;
1019#endif
1020void xvfork_parent_waits_and_exits(void) FAST_FUNC;
1021
1022/* NOMMU friendy fork+exec: */
1023pid_t spawn(char **argv) FAST_FUNC;
1024pid_t xspawn(char **argv) FAST_FUNC;
1025
1026pid_t safe_waitpid(pid_t pid, int *wstat, int options) FAST_FUNC;
1027pid_t wait_any_nohang(int *wstat) FAST_FUNC;
1028/* wait4pid: unlike waitpid, waits ONLY for one process.
1029 * Returns sig + 0x180 if child is killed by signal.
1030 * It's safe to pass negative 'pids' from failed [v]fork -
1031 * wait4pid will return -1 (and will not clobber [v]fork's errno).
1032 * IOW: rc = wait4pid(spawn(argv));
1033 * if (rc < 0) bb_perror_msg("%s", argv[0]);
1034 * if (rc > 0) bb_error_msg("exit code: %d", rc & 0xff);
1035 */
1036int wait4pid(pid_t pid) FAST_FUNC;
1037int wait_for_exitstatus(pid_t pid) FAST_FUNC;
1038/* Same as wait4pid(spawn(argv)), but with NOFORK/NOEXEC if configured: */
1039int spawn_and_wait(char **argv) FAST_FUNC;
1040/* Does NOT check that applet is NOFORK, just blindly runs it */
1041int run_nofork_applet(int applet_no, char **argv) FAST_FUNC;
1042
1043/* Helpers for daemonization.
1044 *
1045 * bb_daemonize(flags) = daemonize, does not compile on NOMMU
1046 *
1047 * bb_daemonize_or_rexec(flags, argv) = daemonizes on MMU (and ignores argv),
1048 * rexec's itself on NOMMU with argv passed as command line.
1049 * Thus bb_daemonize_or_rexec may cause your <applet>_main() to be re-executed
1050 * from the start. (It will detect it and not reexec again second time).
1051 * You have to audit carefully that you don't do something twice as a result
1052 * (opening files/sockets, parsing config files etc...)!
1053 *
1054 * Both of the above will redirect fd 0,1,2 to /dev/null and drop ctty
1055 * (will do setsid()).
1056 *
1057 * fork_or_rexec(argv) = bare-bones fork on MMU,
1058 * "vfork + re-exec ourself" on NOMMU. No fd redirection, no setsid().
1059 * On MMU ignores argv.
1060 *
1061 * Helper for network daemons in foreground mode:
1062 *
1063 * bb_sanitize_stdio() = make sure that fd 0,1,2 are opened by opening them
1064 * to /dev/null if they are not.
1065 */
1066enum {
1067 DAEMON_CHDIR_ROOT = 1,
1068 DAEMON_DEVNULL_STDIO = 2,
1069 DAEMON_CLOSE_EXTRA_FDS = 4,
1070 DAEMON_ONLY_SANITIZE = 8, /* internal use */
1071 DAEMON_DOUBLE_FORK = 16, /* double fork to avoid controlling tty */
1072};
1073#if BB_MMU
1074 enum { re_execed = 0 };
1075# define fork_or_rexec(argv) xfork()
1076# define bb_daemonize_or_rexec(flags, argv) bb_daemonize_or_rexec(flags)
1077# define bb_daemonize(flags) bb_daemonize_or_rexec(flags, bogus)
1078#else
1079 extern bool re_execed;
1080 /* Note: re_exec() and fork_or_rexec() do argv[0][0] |= 0x80 on NOMMU!
1081 * _Parent_ needs to undo it if it doesn't want to have argv[0] mangled.
1082 */
1083 void re_exec(char **argv) NORETURN FAST_FUNC;
1084 pid_t fork_or_rexec(char **argv) FAST_FUNC;
1085 int BUG_fork_is_unavailable_on_nommu(void) FAST_FUNC;
1086 int BUG_daemon_is_unavailable_on_nommu(void) FAST_FUNC;
1087 void BUG_bb_daemonize_is_unavailable_on_nommu(void) FAST_FUNC;
1088# define fork() BUG_fork_is_unavailable_on_nommu()
1089# define xfork() BUG_fork_is_unavailable_on_nommu()
1090# define daemon(a,b) BUG_daemon_is_unavailable_on_nommu()
1091# define bb_daemonize(a) BUG_bb_daemonize_is_unavailable_on_nommu()
1092#endif
1093void bb_daemonize_or_rexec(int flags, char **argv) FAST_FUNC;
1094void bb_sanitize_stdio(void) FAST_FUNC;
1095/* Clear dangerous stuff, set PATH. Return 1 if was run by different user. */
1096int sanitize_env_if_suid(void) FAST_FUNC;
1097
1098
1099char* single_argv(char **argv) FAST_FUNC;
1100extern const char *const bb_argv_dash[]; /* "-", NULL */
1101extern const char *opt_complementary;
1102#if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG
1103#define No_argument "\0"
1104#define Required_argument "\001"
1105#define Optional_argument "\002"
1106extern const char *applet_long_options;
1107#endif
1108extern uint32_t option_mask32;
1109extern uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC;
1110
1111
1112/* Having next pointer as a first member allows easy creation
1113 * of "llist-compatible" structs, and using llist_FOO functions
1114 * on them.
1115 */
1116typedef struct llist_t {
1117 struct llist_t *link;
1118 char *data;
1119} llist_t;
1120void llist_add_to(llist_t **old_head, void *data) FAST_FUNC;
1121void llist_add_to_end(llist_t **list_head, void *data) FAST_FUNC;
1122void *llist_pop(llist_t **elm) FAST_FUNC;
1123void llist_unlink(llist_t **head, llist_t *elm) FAST_FUNC;
1124void llist_free(llist_t *elm, void (*freeit)(void *data)) FAST_FUNC;
1125llist_t *llist_rev(llist_t *list) FAST_FUNC;
1126llist_t *llist_find_str(llist_t *first, const char *str) FAST_FUNC;
1127/* BTW, surprisingly, changing API to
1128 * llist_t *llist_add_to(llist_t *old_head, void *data)
1129 * etc does not result in smaller code... */
1130
1131/* start_stop_daemon and udhcpc are special - they want
1132 * to create pidfiles regardless of FEATURE_PIDFILE */
1133#if ENABLE_FEATURE_PIDFILE || defined(WANT_PIDFILE)
1134/* True only if we created pidfile which is *file*, not /dev/null etc */
1135extern smallint wrote_pidfile;
1136void write_pidfile(const char *path) FAST_FUNC;
1137#define remove_pidfile(path) do { if (wrote_pidfile) unlink(path); } while (0)
1138#else
1139enum { wrote_pidfile = 0 };
1140#define write_pidfile(path) ((void)0)
1141#define remove_pidfile(path) ((void)0)
1142#endif
1143
1144enum {
1145 LOGMODE_NONE = 0,
1146 LOGMODE_STDIO = (1 << 0),
1147 LOGMODE_SYSLOG = (1 << 1) * ENABLE_FEATURE_SYSLOG,
1148 LOGMODE_BOTH = LOGMODE_SYSLOG + LOGMODE_STDIO,
1149};
1150extern const char *msg_eol;
1151extern smallint syslog_level;
1152extern smallint logmode;
1153extern uint8_t xfunc_error_retval;
1154extern void (*die_func)(void);
1155extern void xfunc_die(void) NORETURN FAST_FUNC;
1156extern void bb_show_usage(void) NORETURN FAST_FUNC;
1157extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1158extern void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
1159extern void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1160extern void bb_simple_perror_msg(const char *s) FAST_FUNC;
1161extern void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
1162extern void bb_simple_perror_msg_and_die(const char *s) NORETURN FAST_FUNC;
1163extern void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1164extern void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
1165extern void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC;
1166extern void bb_perror_nomsg(void) FAST_FUNC;
1167extern void bb_verror_msg(const char *s, va_list p, const char *strerr) FAST_FUNC;
1168extern void bb_logenv_override(void) FAST_FUNC;
1169
1170/* We need to export XXX_main from libbusybox
1171 * only if we build "individual" binaries
1172 */
1173#if ENABLE_FEATURE_INDIVIDUAL
1174#define MAIN_EXTERNALLY_VISIBLE EXTERNALLY_VISIBLE
1175#else
1176#define MAIN_EXTERNALLY_VISIBLE
1177#endif
1178
1179
1180/* Applets which are useful from another applets */
1181int bb_cat(char** argv);
1182/* If shell needs them, they exist even if not enabled as applets */
1183int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE);
1184int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE);
1185int test_main(int argc, char **argv) IF_TEST(MAIN_EXTERNALLY_VISIBLE);
1186int kill_main(int argc, char **argv) IF_KILL(MAIN_EXTERNALLY_VISIBLE);
1187/* Similar, but used by chgrp, not shell */
1188int chown_main(int argc, char **argv) IF_CHOWN(MAIN_EXTERNALLY_VISIBLE);
1189/* Used by ftpd */
1190int ls_main(int argc, char **argv) IF_LS(MAIN_EXTERNALLY_VISIBLE);
1191/* Don't need IF_xxx() guard for these */
1192int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1193int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1194
1195#if ENABLE_ROUTE
1196void bb_displayroutes(int noresolve, int netstatfmt) FAST_FUNC;
1197#endif
1198
1199
1200/* Networking */
1201/* This structure defines protocol families and their handlers. */
1202struct aftype {
1203 const char *name;
1204 const char *title;
1205 int af;
1206 int alen;
1207 char* FAST_FUNC (*print)(unsigned char *);
1208 const char* FAST_FUNC (*sprint)(struct sockaddr *, int numeric);
1209 int FAST_FUNC (*input)(/*int type,*/ const char *bufp, struct sockaddr *);
1210 void FAST_FUNC (*herror)(char *text);
1211 int FAST_FUNC (*rprint)(int options);
1212 int FAST_FUNC (*rinput)(int typ, int ext, char **argv);
1213 /* may modify src */
1214 int FAST_FUNC (*getmask)(char *src, struct sockaddr *mask, char *name);
1215};
1216/* This structure defines hardware protocols and their handlers. */
1217struct hwtype {
1218 const char *name;
1219 const char *title;
1220 int type;
1221 int alen;
1222 char* FAST_FUNC (*print)(unsigned char *);
1223 int FAST_FUNC (*input)(const char *, struct sockaddr *);
1224 int FAST_FUNC (*activate)(int fd);
1225 int suppress_null_addr;
1226};
1227extern smallint interface_opt_a;
1228int display_interfaces(char *ifname) FAST_FUNC;
1229int in_ether(const char *bufp, struct sockaddr *sap) FAST_FUNC;
1230#if ENABLE_FEATURE_HWIB
1231int in_ib(const char *bufp, struct sockaddr *sap) FAST_FUNC;
1232#else
1233#define in_ib(a, b) 1 /* fail */
1234#endif
1235const struct aftype *get_aftype(const char *name) FAST_FUNC;
1236const struct hwtype *get_hwtype(const char *name) FAST_FUNC;
1237const struct hwtype *get_hwntype(int type) FAST_FUNC;
1238
1239
1240#ifndef BUILD_INDIVIDUAL
1241extern int find_applet_by_name(const char *name) FAST_FUNC;
1242extern void run_applet_no_and_exit(int a, char **argv) NORETURN FAST_FUNC;
1243#endif
1244
1245#ifdef HAVE_MNTENT_H
1246extern int match_fstype(const struct mntent *mt, const char *fstypes) FAST_FUNC;
1247extern struct mntent *find_mount_point(const char *name, int subdir_too) FAST_FUNC;
1248#endif
1249extern void erase_mtab(const char * name) FAST_FUNC;
1250extern unsigned int tty_baud_to_value(speed_t speed) FAST_FUNC;
1251extern speed_t tty_value_to_baud(unsigned int value) FAST_FUNC;
1252#if ENABLE_DESKTOP
1253extern void bb_warn_ignoring_args(char *arg) FAST_FUNC;
1254#else
1255# define bb_warn_ignoring_args(arg) ((void)0)
1256#endif
1257
1258extern int get_linux_version_code(void) FAST_FUNC;
1259
1260extern char *query_loop(const char *device) FAST_FUNC;
1261extern int del_loop(const char *device) FAST_FUNC;
1262/* If *devname is not NULL, use that name, otherwise try to find free one,
1263 * malloc and return it in *devname.
1264 * return value: 1: read-only loopdev was setup, 0: rw, < 0: error */
1265extern int set_loop(char **devname, const char *file, unsigned long long offset, int ro) FAST_FUNC;
1266
1267/* Like bb_ask below, but asks on stdin with no timeout. */
1268char *bb_ask_stdin(const char * prompt) FAST_FUNC;
1269//TODO: pass buf pointer or return allocated buf (avoid statics)?
1270char *bb_ask(const int fd, int timeout, const char * prompt) FAST_FUNC;
1271int bb_ask_confirmation(void) FAST_FUNC;
1272
1273/* Returns -1 if input is invalid. current_mode is a base for e.g. "u+rw" */
1274int bb_parse_mode(const char* s, unsigned cur_mode) FAST_FUNC;
1275
1276/*
1277 * Config file parser
1278 */
1279enum {
1280 PARSE_COLLAPSE = 0x00010000, // treat consecutive delimiters as one
1281 PARSE_TRIM = 0x00020000, // trim leading and trailing delimiters
1282// TODO: COLLAPSE and TRIM seem to always go in pair
1283 PARSE_GREEDY = 0x00040000, // last token takes entire remainder of the line
1284 PARSE_MIN_DIE = 0x00100000, // die if < min tokens found
1285 // keep a copy of current line
1286 PARSE_KEEP_COPY = 0x00200000 * ENABLE_FEATURE_CROND_D,
1287 PARSE_EOL_COMMENTS = 0x00400000, // comments are recognized even if they aren't the first char
1288 // NORMAL is:
1289 // * remove leading and trailing delimiters and collapse
1290 // multiple delimiters into one
1291 // * warn and continue if less than mintokens delimiters found
1292 // * grab everything into last token
1293 // * comments are recognized even if they aren't the first char
1294 PARSE_NORMAL = PARSE_COLLAPSE | PARSE_TRIM | PARSE_GREEDY | PARSE_EOL_COMMENTS,
1295};
1296typedef struct parser_t {
1297 FILE *fp;
1298 char *data;
1299 char *line, *nline;
1300 size_t line_alloc, nline_alloc;
1301 int lineno;
1302} parser_t;
1303parser_t* config_open(const char *filename) FAST_FUNC;
1304parser_t* config_open2(const char *filename, FILE* FAST_FUNC (*fopen_func)(const char *path)) FAST_FUNC;
1305/* delims[0] is a comment char (use '\0' to disable), the rest are token delimiters */
1306int config_read(parser_t *parser, char **tokens, unsigned flags, const char *delims) FAST_FUNC;
1307#define config_read(parser, tokens, max, min, str, flags) \
1308 config_read(parser, tokens, ((flags) | (((min) & 0xFF) << 8) | ((max) & 0xFF)), str)
1309void config_close(parser_t *parser) FAST_FUNC;
1310
1311/* Concatenate path and filename to new allocated buffer.
1312 * Add "/" only as needed (no duplicate "//" are produced).
1313 * If path is NULL, it is assumed to be "/".
1314 * filename should not be NULL. */
1315char *concat_path_file(const char *path, const char *filename) FAST_FUNC;
1316/* Returns NULL on . and .. */
1317char *concat_subpath_file(const char *path, const char *filename) FAST_FUNC;
1318
1319
1320int bb_make_directory(char *path, long mode, int flags) FAST_FUNC;
1321
1322int get_signum(const char *name) FAST_FUNC;
1323const char *get_signame(int number) FAST_FUNC;
1324void print_signames(void) FAST_FUNC;
1325
1326char *bb_simplify_path(const char *path) FAST_FUNC;
1327/* Returns ptr to NUL */
1328char *bb_simplify_abs_path_inplace(char *path) FAST_FUNC;
1329
1330#ifndef LOGIN_FAIL_DELAY
1331#define LOGIN_FAIL_DELAY 3
1332#endif
1333extern void bb_do_delay(int seconds) FAST_FUNC;
1334extern void change_identity(const struct passwd *pw) FAST_FUNC;
1335extern void run_shell(const char *shell, int loginshell, const char *command, const char **additional_args) NORETURN FAST_FUNC;
1336
1337/* Returns $SHELL, getpwuid(getuid())->pw_shell, or DEFAULT_SHELL.
1338 * Note that getpwuid result might need xstrdup'ing
1339 * if there is a possibility of intervening getpwxxx() calls.
1340 */
1341const char *get_shell_name(void) FAST_FUNC;
1342
1343#if ENABLE_SELINUX
1344extern void renew_current_security_context(void) FAST_FUNC;
1345extern void set_current_security_context(security_context_t sid) FAST_FUNC;
1346extern context_t set_security_context_component(security_context_t cur_context,
1347 char *user, char *role, char *type, char *range) FAST_FUNC;
1348extern void setfscreatecon_or_die(security_context_t scontext) FAST_FUNC;
1349extern void selinux_preserve_fcontext(int fdesc) FAST_FUNC;
1350#else
1351#define selinux_preserve_fcontext(fdesc) ((void)0)
1352#endif
1353extern void selinux_or_die(void) FAST_FUNC;
1354
1355
1356/* setup_environment:
1357 * if chdir pw->pw_dir: ok: else if to_tmp == 1: goto /tmp else: goto / or die
1358 * if clear_env = 1: cd(pw->pw_dir), clear environment, then set
1359 * TERM=(old value)
1360 * USER=pw->pw_name, LOGNAME=pw->pw_name
1361 * PATH=bb_default_[root_]path
1362 * HOME=pw->pw_dir
1363 * SHELL=shell
1364 * else if change_env = 1:
1365 * if not root (if pw->pw_uid != 0):
1366 * USER=pw->pw_name, LOGNAME=pw->pw_name
1367 * HOME=pw->pw_dir
1368 * SHELL=shell
1369 * else does nothing
1370 */
1371#define SETUP_ENV_CHANGEENV (1 << 0)
1372#define SETUP_ENV_CLEARENV (1 << 1)
1373#define SETUP_ENV_TO_TMP (1 << 2)
1374#define SETUP_ENV_NO_CHDIR (1 << 4)
1375void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC;
1376void nuke_str(char *str) FAST_FUNC;
1377int check_password(const struct passwd *pw, const char *plaintext) FAST_FUNC;
1378int ask_and_check_password_extended(const struct passwd *pw, int timeout, const char *prompt) FAST_FUNC;
1379int ask_and_check_password(const struct passwd *pw) FAST_FUNC;
1380/* Returns a malloced string */
1381#if !ENABLE_USE_BB_CRYPT
1382#define pw_encrypt(clear, salt, cleanup) pw_encrypt(clear, salt)
1383#endif
1384extern char *pw_encrypt(const char *clear, const char *salt, int cleanup) FAST_FUNC;
1385extern int obscure(const char *old, const char *newval, const struct passwd *pwdp) FAST_FUNC;
1386/*
1387 * rnd is additional random input. New one is returned.
1388 * Useful if you call crypt_make_salt many times in a row:
1389 * rnd = crypt_make_salt(buf1, 4, 0);
1390 * rnd = crypt_make_salt(buf2, 4, rnd);
1391 * rnd = crypt_make_salt(buf3, 4, rnd);
1392 * (otherwise we risk having same salt generated)
1393 */
1394extern int crypt_make_salt(char *p, int cnt /*, int rnd*/) FAST_FUNC;
1395/* "$N$" + sha_salt_16_bytes + NUL */
1396#define MAX_PW_SALT_LEN (3 + 16 + 1)
1397extern char* crypt_make_pw_salt(char p[MAX_PW_SALT_LEN], const char *algo) FAST_FUNC;
1398
1399
1400/* Returns number of lines changed, or -1 on error */
1401#if !(ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP)
1402#define update_passwd(filename, username, data, member) \
1403 update_passwd(filename, username, data)
1404#endif
1405extern int update_passwd(const char *filename,
1406 const char *username,
1407 const char *data,
1408 const char *member) FAST_FUNC;
1409
1410int index_in_str_array(const char *const string_array[], const char *key) FAST_FUNC;
1411int index_in_strings(const char *strings, const char *key) FAST_FUNC;
1412int index_in_substr_array(const char *const string_array[], const char *key) FAST_FUNC;
1413int index_in_substrings(const char *strings, const char *key) FAST_FUNC;
1414const char *nth_string(const char *strings, int n) FAST_FUNC;
1415
1416extern void print_login_issue(const char *issue_file, const char *tty) FAST_FUNC;
1417extern void print_login_prompt(void) FAST_FUNC;
1418
1419char *xmalloc_ttyname(int fd) FAST_FUNC RETURNS_MALLOC;
1420/* NB: typically you want to pass fd 0, not 1. Think 'applet | grep something' */
1421int get_terminal_width_height(int fd, unsigned *width, unsigned *height) FAST_FUNC;
1422int get_terminal_width(int fd) FAST_FUNC;
1423
1424int tcsetattr_stdin_TCSANOW(const struct termios *tp) FAST_FUNC;
1425
1426/* NB: "unsigned request" is crucial! "int request" will break some arches! */
1427int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC;
1428int ioctl_or_perror_and_die(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC;
1429#if ENABLE_IOCTL_HEX2STR_ERROR
1430int bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC;
1431int bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC;
1432#define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp,#request)
1433#define xioctl(fd,request,argp) bb_xioctl(fd,request,argp,#request)
1434#else
1435int bb_ioctl_or_warn(int fd, unsigned request, void *argp) FAST_FUNC;
1436int bb_xioctl(int fd, unsigned request, void *argp) FAST_FUNC;
1437#define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp)
1438#define xioctl(fd,request,argp) bb_xioctl(fd,request,argp)
1439#endif
1440
1441char *is_in_ino_dev_hashtable(const struct stat *statbuf) FAST_FUNC;
1442void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name) FAST_FUNC;
1443void reset_ino_dev_hashtable(void) FAST_FUNC;
1444#ifdef __GLIBC__
1445/* At least glibc has horrendously large inline for this, so wrap it */
1446unsigned long long bb_makedev(unsigned major, unsigned minor) FAST_FUNC;
1447#undef makedev
1448#define makedev(a,b) bb_makedev(a,b)
1449#endif
1450
1451
1452/* "Keycodes" that report an escape sequence.
1453 * We use something which fits into signed char,
1454 * yet doesn't represent any valid Unicode character.
1455 * Also, -1 is reserved for error indication and we don't use it. */
1456enum {
1457 KEYCODE_UP = -2,
1458 KEYCODE_DOWN = -3,
1459 KEYCODE_RIGHT = -4,
1460 KEYCODE_LEFT = -5,
1461 KEYCODE_HOME = -6,
1462 KEYCODE_END = -7,
1463 KEYCODE_INSERT = -8,
1464 KEYCODE_DELETE = -9,
1465 KEYCODE_PAGEUP = -10,
1466 KEYCODE_PAGEDOWN = -11,
1467 // -12 is reserved for Alt/Ctrl/Shift-TAB
1468#if 0
1469 KEYCODE_FUN1 = -13,
1470 KEYCODE_FUN2 = -14,
1471 KEYCODE_FUN3 = -15,
1472 KEYCODE_FUN4 = -16,
1473 KEYCODE_FUN5 = -17,
1474 KEYCODE_FUN6 = -18,
1475 KEYCODE_FUN7 = -19,
1476 KEYCODE_FUN8 = -20,
1477 KEYCODE_FUN9 = -21,
1478 KEYCODE_FUN10 = -22,
1479 KEYCODE_FUN11 = -23,
1480 KEYCODE_FUN12 = -24,
1481#endif
1482 /* Be sure that last defined value is small enough
1483 * to not interfere with Alt/Ctrl/Shift bits.
1484 * So far we do not exceed -31 (0xfff..fffe1),
1485 * which gives us three upper bits in LSB to play with.
1486 */
1487 //KEYCODE_SHIFT_TAB = (-12) & ~0x80,
1488 //KEYCODE_SHIFT_... = KEYCODE_... & ~0x80,
1489 //KEYCODE_CTRL_UP = KEYCODE_UP & ~0x40,
1490 //KEYCODE_CTRL_DOWN = KEYCODE_DOWN & ~0x40,
1491 KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40,
1492 KEYCODE_CTRL_LEFT = KEYCODE_LEFT & ~0x40,
1493 //KEYCODE_ALT_UP = KEYCODE_UP & ~0x20,
1494 //KEYCODE_ALT_DOWN = KEYCODE_DOWN & ~0x20,
1495 KEYCODE_ALT_RIGHT = KEYCODE_RIGHT & ~0x20,
1496 KEYCODE_ALT_LEFT = KEYCODE_LEFT & ~0x20,
1497
1498 KEYCODE_CURSOR_POS = -0x100, /* 0xfff..fff00 */
1499 /* How long is the longest ESC sequence we know?
1500 * We want it big enough to be able to contain
1501 * cursor position sequence "ESC [ 9999 ; 9999 R"
1502 */
1503 KEYCODE_BUFFER_SIZE = 16
1504};
1505/* Note: fd may be in blocking or non-blocking mode, both make sense.
1506 * For one, less uses non-blocking mode.
1507 * Only the first read syscall inside read_key may block indefinitely
1508 * (unless fd is in non-blocking mode),
1509 * subsequent reads will time out after a few milliseconds.
1510 * Return of -1 means EOF or error (errno == 0 on EOF).
1511 * buffer[0] is used as a counter of buffered chars and must be 0
1512 * on first call.
1513 * timeout:
1514 * -2: do not poll for input;
1515 * -1: poll(-1) (i.e. block);
1516 * >=0: poll for TIMEOUT milliseconds, return -1/EAGAIN on timeout
1517 */
1518int64_t read_key(int fd, char *buffer, int timeout) FAST_FUNC;
1519void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC;
1520
1521
1522#if ENABLE_FEATURE_EDITING
1523/* It's NOT just ENABLEd or disabled. It's a number: */
1524# if defined CONFIG_FEATURE_EDITING_HISTORY && CONFIG_FEATURE_EDITING_HISTORY > 0
1525# define MAX_HISTORY (CONFIG_FEATURE_EDITING_HISTORY + 0)
1526unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC;
1527# else
1528# define MAX_HISTORY 0
1529# endif
1530typedef struct line_input_t {
1531 int flags;
1532 const char *path_lookup;
1533# if MAX_HISTORY
1534 int cnt_history;
1535 int cur_history;
1536 int max_history; /* must never be <= 0 */
1537# if ENABLE_FEATURE_EDITING_SAVEHISTORY
1538 /* meaning of this field depends on FEATURE_EDITING_SAVE_ON_EXIT:
1539 * if !FEATURE_EDITING_SAVE_ON_EXIT: "how many lines are
1540 * in on-disk history"
1541 * if FEATURE_EDITING_SAVE_ON_EXIT: "how many in-memory lines are
1542 * also in on-disk history (and thus need to be skipped on save)"
1543 */
1544 unsigned cnt_history_in_file;
1545 const char *hist_file;
1546# endif
1547 char *history[MAX_HISTORY + 1];
1548# endif
1549} line_input_t;
1550enum {
1551 DO_HISTORY = 1 * (MAX_HISTORY > 0),
1552 TAB_COMPLETION = 2 * ENABLE_FEATURE_TAB_COMPLETION,
1553 USERNAME_COMPLETION = 4 * ENABLE_FEATURE_USERNAME_COMPLETION,
1554 VI_MODE = 8 * ENABLE_FEATURE_EDITING_VI,
1555 WITH_PATH_LOOKUP = 0x10,
1556 FOR_SHELL = DO_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION,
1557};
1558line_input_t *new_line_input_t(int flags) FAST_FUNC;
1559/* So far static: void free_line_input_t(line_input_t *n) FAST_FUNC; */
1560/*
1561 * maxsize must be >= 2.
1562 * Returns:
1563 * -1 on read errors or EOF, or on bare Ctrl-D,
1564 * 0 on ctrl-C (the line entered is still returned in 'command'),
1565 * >0 length of input string, including terminating '\n'
1566 */
1567int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) FAST_FUNC;
1568void show_history(const line_input_t *st) FAST_FUNC;
1569# if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
1570void save_history(line_input_t *st);
1571# endif
1572#else
1573#define MAX_HISTORY 0
1574int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC;
1575#define read_line_input(state, prompt, command, maxsize, timeout) \
1576 read_line_input(prompt, command, maxsize)
1577#endif
1578
1579
1580#ifndef COMM_LEN
1581# ifdef TASK_COMM_LEN
1582enum { COMM_LEN = TASK_COMM_LEN };
1583# else
1584/* synchronize with sizeof(task_struct.comm) in /usr/include/linux/sched.h */
1585enum { COMM_LEN = 16 };
1586# endif
1587#endif
1588
1589struct smaprec {
1590 unsigned long mapped_rw;
1591 unsigned long mapped_ro;
1592 unsigned long shared_clean;
1593 unsigned long shared_dirty;
1594 unsigned long private_clean;
1595 unsigned long private_dirty;
1596 unsigned long stack;
1597 unsigned long smap_pss, smap_swap;
1598 unsigned long smap_size;
1599 unsigned long smap_start;
1600 char smap_mode[5];
1601 char *smap_name;
1602};
1603
1604#if !ENABLE_PMAP
1605#define procps_read_smaps(pid, total, cb, data) \
1606 procps_read_smaps(pid, total)
1607#endif
1608int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
1609 void (*cb)(struct smaprec *, void *), void *data);
1610
1611typedef struct procps_status_t {
1612 DIR *dir;
1613 IF_FEATURE_SHOW_THREADS(DIR *task_dir;)
1614 uint8_t shift_pages_to_bytes;
1615 uint8_t shift_pages_to_kb;
1616/* Fields are set to 0/NULL if failed to determine (or not requested) */
1617 uint16_t argv_len;
1618 char *argv0;
1619 char *exe;
1620 IF_SELINUX(char *context;)
1621 IF_FEATURE_SHOW_THREADS(unsigned main_thread_pid;)
1622 /* Everything below must contain no ptrs to malloc'ed data:
1623 * it is memset(0) for each process in procps_scan() */
1624 unsigned long vsz, rss; /* we round it to kbytes */
1625 unsigned long stime, utime;
1626 unsigned long start_time;
1627 unsigned pid;
1628 unsigned ppid;
1629 unsigned pgid;
1630 unsigned sid;
1631 unsigned uid;
1632 unsigned gid;
1633#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
1634 unsigned ruid;
1635 unsigned rgid;
1636 int niceness;
1637#endif
1638 unsigned tty_major,tty_minor;
1639#if ENABLE_FEATURE_TOPMEM
1640 struct smaprec smaps;
1641#endif
1642 char state[4];
1643 /* basename of executable in exec(2), read from /proc/N/stat
1644 * (if executable is symlink or script, it is NOT replaced
1645 * by link target or interpreter name) */
1646 char comm[COMM_LEN];
1647 /* user/group? - use passwd/group parsing functions */
1648#if ENABLE_FEATURE_TOP_SMP_PROCESS
1649 int last_seen_on_cpu;
1650#endif
1651} procps_status_t;
1652/* flag bits for procps_scan(xx, flags) calls */
1653enum {
1654 PSSCAN_PID = 1 << 0,
1655 PSSCAN_PPID = 1 << 1,
1656 PSSCAN_PGID = 1 << 2,
1657 PSSCAN_SID = 1 << 3,
1658 PSSCAN_UIDGID = 1 << 4,
1659 PSSCAN_COMM = 1 << 5,
1660 /* PSSCAN_CMD = 1 << 6, - use read_cmdline instead */
1661 PSSCAN_ARGV0 = 1 << 7,
1662 PSSCAN_EXE = 1 << 8,
1663 PSSCAN_STATE = 1 << 9,
1664 PSSCAN_VSZ = 1 << 10,
1665 PSSCAN_RSS = 1 << 11,
1666 PSSCAN_STIME = 1 << 12,
1667 PSSCAN_UTIME = 1 << 13,
1668 PSSCAN_TTY = 1 << 14,
1669 PSSCAN_SMAPS = (1 << 15) * ENABLE_FEATURE_TOPMEM,
1670 /* NB: used by find_pid_by_name(). Any applet using it
1671 * needs to be mentioned here. */
1672 PSSCAN_ARGVN = (1 << 16) * (ENABLE_KILLALL
1673 || ENABLE_PGREP || ENABLE_PKILL
1674 || ENABLE_PIDOF
1675 || ENABLE_SESTATUS
1676 ),
1677 PSSCAN_CONTEXT = (1 << 17) * ENABLE_SELINUX,
1678 PSSCAN_START_TIME = 1 << 18,
1679 PSSCAN_CPU = (1 << 19) * ENABLE_FEATURE_TOP_SMP_PROCESS,
1680 PSSCAN_NICE = (1 << 20) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
1681 PSSCAN_RUIDGID = (1 << 21) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
1682 PSSCAN_TASKS = (1 << 22) * ENABLE_FEATURE_SHOW_THREADS,
1683};
1684//procps_status_t* alloc_procps_scan(void) FAST_FUNC;
1685void free_procps_scan(procps_status_t* sp) FAST_FUNC;
1686procps_status_t* procps_scan(procps_status_t* sp, int flags) FAST_FUNC;
1687/* Format cmdline (up to col chars) into char buf[size] */
1688/* Puts [comm] if cmdline is empty (-> process is a kernel thread) */
1689void read_cmdline(char *buf, int size, unsigned pid, const char *comm) FAST_FUNC;
1690pid_t *find_pid_by_name(const char* procName) FAST_FUNC;
1691pid_t *pidlist_reverse(pid_t *pidList) FAST_FUNC;
1692int starts_with_cpu(const char *str) FAST_FUNC;
1693unsigned get_cpu_count(void) FAST_FUNC;
1694
1695
1696/* Use strict=1 if you process input from untrusted source:
1697 * it will return NULL on invalid %xx (bad hex chars)
1698 * and str + 1 if decoded char is / or NUL.
1699 * In non-strict mode, it always succeeds (returns str),
1700 * and also it additionally decoded '+' to space.
1701 */
1702char *percent_decode_in_place(char *str, int strict) FAST_FUNC;
1703
1704
1705extern const char bb_uuenc_tbl_base64[] ALIGN1;
1706extern const char bb_uuenc_tbl_std[] ALIGN1;
1707void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC;
1708enum {
1709 BASE64_FLAG_UU_STOP = 0x100,
1710 /* Sign-extends to a value which never matches fgetc result: */
1711 BASE64_FLAG_NO_STOP_CHAR = 0x80,
1712};
1713const char *decode_base64(char **pp_dst, const char *src) FAST_FUNC;
1714void read_base64(FILE *src_stream, FILE *dst_stream, int flags) FAST_FUNC;
1715
1716typedef struct md5_ctx_t {
1717 uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */
1718 void (*process_block)(struct md5_ctx_t*) FAST_FUNC;
1719 uint64_t total64; /* must be directly before hash[] */
1720 uint32_t hash[8]; /* 4 elements for md5, 5 for sha1, 8 for sha256 */
1721} md5_ctx_t;
1722typedef struct md5_ctx_t sha1_ctx_t;
1723typedef struct md5_ctx_t sha256_ctx_t;
1724typedef struct sha512_ctx_t {
1725 uint64_t total64[2]; /* must be directly before hash[] */
1726 uint64_t hash[8];
1727 uint8_t wbuffer[128]; /* always correctly aligned for uint64_t */
1728} sha512_ctx_t;
1729typedef struct sha3_ctx_t {
1730 uint64_t state[25];
1731 unsigned bytes_queued;
1732} sha3_ctx_t;
1733void md5_begin(md5_ctx_t *ctx) FAST_FUNC;
1734void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1735void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC;
1736void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;
1737#define sha1_hash md5_hash
1738void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC;
1739void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
1740#define sha256_hash md5_hash
1741#define sha256_end sha1_end
1742void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
1743void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1744void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
1745void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC;
1746void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1747void sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC;
1748
1749extern uint32_t *global_crc32_table;
1750uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;
1751uint32_t crc32_block_endian1(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC;
1752uint32_t crc32_block_endian0(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC;
1753
1754typedef struct masks_labels_t {
1755 const char *labels;
1756 const int masks[];
1757} masks_labels_t;
1758int print_flags_separated(const int *masks, const char *labels,
1759 int flags, const char *separator) FAST_FUNC;
1760int print_flags(const masks_labels_t *ml, int flags) FAST_FUNC;
1761
1762typedef struct bb_progress_t {
1763 unsigned last_size;
1764 unsigned last_update_sec;
1765 unsigned last_change_sec;
1766 unsigned start_sec;
1767 const char *curfile;
1768} bb_progress_t;
1769
1770#define is_bb_progress_inited(p) ((p)->curfile != NULL)
1771#define bb_progress_free(p) do { \
1772 if (ENABLE_UNICODE_SUPPORT) free((char*)((p)->curfile)); \
1773 (p)->curfile = NULL; \
1774} while (0)
1775void bb_progress_init(bb_progress_t *p, const char *curfile) FAST_FUNC;
1776void bb_progress_update(bb_progress_t *p,
1777 uoff_t beg_range,
1778 uoff_t transferred,
1779 uoff_t totalsize) FAST_FUNC;
1780
1781unsigned ubi_devnum_from_devname(const char *str) FAST_FUNC;
1782int ubi_get_volid_by_name(unsigned ubi_devnum, const char *vol_name) FAST_FUNC;
1783
1784
1785extern const char *applet_name;
1786
1787/* Some older linkers don't perform string merging, we used to have common strings
1788 * as global arrays to do it by hand. But:
1789 * (1) newer linkers do it themselves,
1790 * (2) however, they DONT merge string constants with global arrays,
1791 * even if the value is the same (!). Thus global arrays actually
1792 * increased size a bit: for example, "/etc/passwd" string from libc
1793 * wasn't merged with bb_path_passwd_file[] array!
1794 * Therefore now we use #defines.
1795 */
1796/* "BusyBox vN.N.N (timestamp or extra_version)" */
1797extern const char bb_banner[] ALIGN1;
1798extern const char bb_msg_memory_exhausted[] ALIGN1;
1799extern const char bb_msg_invalid_date[] ALIGN1;
1800#define bb_msg_read_error "read error"
1801#define bb_msg_write_error "write error"
1802extern const char bb_msg_unknown[] ALIGN1;
1803extern const char bb_msg_can_not_create_raw_socket[] ALIGN1;
1804extern const char bb_msg_perm_denied_are_you_root[] ALIGN1;
1805extern const char bb_msg_you_must_be_root[] ALIGN1;
1806extern const char bb_msg_requires_arg[] ALIGN1;
1807extern const char bb_msg_invalid_arg_to[] ALIGN1;
1808extern const char bb_msg_standard_input[] ALIGN1;
1809extern const char bb_msg_standard_output[] ALIGN1;
1810
1811/* NB: (bb_hexdigits_upcase[i] | 0x20) -> lowercase hex digit */
1812extern const char bb_hexdigits_upcase[] ALIGN1;
1813
1814extern const char bb_path_wtmp_file[] ALIGN1;
1815
1816/* Busybox mount uses either /proc/mounts or /etc/mtab to
1817 * get the list of currently mounted filesystems */
1818#define bb_path_mtab_file IF_FEATURE_MTAB_SUPPORT("/etc/mtab")IF_NOT_FEATURE_MTAB_SUPPORT("/proc/mounts")
1819
1820#define bb_path_passwd_file _PATH_PASSWD
1821#define bb_path_group_file _PATH_GROUP
1822#define bb_path_shadow_file _PATH_SHADOW
1823#define bb_path_gshadow_file _PATH_GSHADOW
1824
1825#define bb_path_motd_file "/etc/motd"
1826
1827#define bb_dev_null "/dev/null"
1828extern const char bb_busybox_exec_path[] ALIGN1;
1829/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
1830 * but I want to save a few bytes here */
1831extern const char bb_PATH_root_path[] ALIGN1; /* "PATH=/sbin:/usr/sbin:/bin:/usr/bin" */
1832#define bb_default_root_path (bb_PATH_root_path + sizeof("PATH"))
1833#define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin"))
1834
1835extern const int const_int_0;
1836//extern const int const_int_1;
1837
1838/* This struct is deliberately not defined. */
1839/* See docs/keep_data_small.txt */
1840struct globals;
1841/* '*const' ptr makes gcc optimize code much better.
1842 * Magic prevents ptr_to_globals from going into rodata.
1843 * If you want to assign a value, use SET_PTR_TO_GLOBALS(x) */
1844extern struct globals *const ptr_to_globals;
1845/* At least gcc 3.4.6 on mipsel system needs optimization barrier */
1846#define barrier() __asm__ __volatile__("":::"memory")
1847#define SET_PTR_TO_GLOBALS(x) do { \
1848 (*(struct globals**)&ptr_to_globals) = (void*)(x); \
1849 barrier(); \
1850} while (0)
1851#define FREE_PTR_TO_GLOBALS() do { \
1852 if (ENABLE_FEATURE_CLEAN_UP) { \
1853 free(ptr_to_globals); \
1854 } \
1855} while (0)
1856
1857/* You can change LIBBB_DEFAULT_LOGIN_SHELL, but don't use it,
1858 * use bb_default_login_shell and following defines.
1859 * If you change LIBBB_DEFAULT_LOGIN_SHELL,
1860 * don't forget to change increment constant. */
1861#define LIBBB_DEFAULT_LOGIN_SHELL "-/bin/sh"
1862extern const char bb_default_login_shell[] ALIGN1;
1863/* "/bin/sh" */
1864#define DEFAULT_SHELL (bb_default_login_shell+1)
1865/* "sh" */
1866#define DEFAULT_SHELL_SHORT_NAME (bb_default_login_shell+6)
1867
1868/* The following devices are the same on all systems. */
1869#define CURRENT_TTY "/dev/tty"
1870#define DEV_CONSOLE "/dev/console"
1871
1872#if defined(__FreeBSD_kernel__)
1873# define CURRENT_VC CURRENT_TTY
1874# define VC_1 "/dev/ttyv0"
1875# define VC_2 "/dev/ttyv1"
1876# define VC_3 "/dev/ttyv2"
1877# define VC_4 "/dev/ttyv3"
1878# define VC_5 "/dev/ttyv4"
1879# define VC_FORMAT "/dev/ttyv%d"
1880#elif defined(__GNU__)
1881# define CURRENT_VC CURRENT_TTY
1882# define VC_1 "/dev/tty1"
1883# define VC_2 "/dev/tty2"
1884# define VC_3 "/dev/tty3"
1885# define VC_4 "/dev/tty4"
1886# define VC_5 "/dev/tty5"
1887# define VC_FORMAT "/dev/tty%d"
1888#elif ENABLE_FEATURE_DEVFS
1889/*Linux, obsolete devfs names */
1890# define CURRENT_VC "/dev/vc/0"
1891# define VC_1 "/dev/vc/1"
1892# define VC_2 "/dev/vc/2"
1893# define VC_3 "/dev/vc/3"
1894# define VC_4 "/dev/vc/4"
1895# define VC_5 "/dev/vc/5"
1896# define VC_FORMAT "/dev/vc/%d"
1897# define LOOP_FORMAT "/dev/loop/%u"
1898# define LOOP_NAMESIZE (sizeof("/dev/loop/") + sizeof(int)*3 + 1)
1899# define LOOP_NAME "/dev/loop/"
1900# define FB_0 "/dev/fb/0"
1901#else
1902/*Linux, normal names */
1903# define CURRENT_VC "/dev/tty0"
1904# define VC_1 "/dev/tty1"
1905# define VC_2 "/dev/tty2"
1906# define VC_3 "/dev/tty3"
1907# define VC_4 "/dev/tty4"
1908# define VC_5 "/dev/tty5"
1909# define VC_FORMAT "/dev/tty%d"
1910# define LOOP_FORMAT "/dev/loop%u"
1911# define LOOP_NAMESIZE (sizeof("/dev/loop") + sizeof(int)*3 + 1)
1912# define LOOP_NAME "/dev/loop"
1913# define FB_0 "/dev/fb0"
1914#endif
1915
1916
1917#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))
1918#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
1919
1920
1921/* We redefine ctype macros. Unicode-correct handling of char types
1922 * can't be done with such byte-oriented operations anyway,
1923 * we don't lose anything.
1924 */
1925#undef isalnum
1926#undef isalpha
1927#undef isascii
1928#undef isblank
1929#undef iscntrl
1930#undef isdigit
1931#undef isgraph
1932#undef islower
1933#undef isprint
1934#undef ispunct
1935#undef isspace
1936#undef isupper
1937#undef isxdigit
1938#undef toupper
1939#undef tolower
1940
1941/* We save ~500 bytes on isdigit alone.
1942 * BTW, x86 likes (unsigned char) cast more than (unsigned). */
1943
1944/* These work the same for ASCII and Unicode,
1945 * assuming no one asks "is this a *Unicode* letter?" using isalpha(letter) */
1946#define isascii(a) ((unsigned char)(a) <= 0x7f)
1947#define isdigit(a) ((unsigned char)((a) - '0') <= 9)
1948#define isupper(a) ((unsigned char)((a) - 'A') <= ('Z' - 'A'))
1949#define islower(a) ((unsigned char)((a) - 'a') <= ('z' - 'a'))
1950#define isalpha(a) ((unsigned char)(((a)|0x20) - 'a') <= ('z' - 'a'))
1951#define isblank(a) ({ unsigned char bb__isblank = (a); bb__isblank == ' ' || bb__isblank == '\t'; })
1952#define iscntrl(a) ({ unsigned char bb__iscntrl = (a); bb__iscntrl < ' ' || bb__iscntrl == 0x7f; })
1953/* In POSIX/C locale isspace is only these chars: "\t\n\v\f\r" and space.
1954 * "\t\n\v\f\r" happen to have ASCII codes 9,10,11,12,13.
1955 */
1956#define isspace(a) ({ unsigned char bb__isspace = (a) - 9; bb__isspace == (' ' - 9) || bb__isspace <= (13 - 9); })
1957// Unsafe wrt NUL: #define ispunct(a) (strchr("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", (a)) != NULL)
1958#define ispunct(a) (strchrnul("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", (a))[0])
1959// Bigger code: #define isalnum(a) ({ unsigned char bb__isalnum = (a) - '0'; bb__isalnum <= 9 || ((bb__isalnum - ('A' - '0')) & 0xdf) <= 25; })
1960#define isalnum(a) bb_ascii_isalnum(a)
1961static ALWAYS_INLINE int bb_ascii_isalnum(unsigned char a)
1962{
1963 unsigned char b = a - '0';
1964 if (b <= 9)
1965 return (b <= 9);
1966 b = (a|0x20) - 'a';
1967 return b <= 'z' - 'a';
1968}
1969#define isxdigit(a) bb_ascii_isxdigit(a)
1970static ALWAYS_INLINE int bb_ascii_isxdigit(unsigned char a)
1971{
1972 unsigned char b = a - '0';
1973 if (b <= 9)
1974 return (b <= 9);
1975 b = (a|0x20) - 'a';
1976 return b <= 'f' - 'a';
1977}
1978#define toupper(a) bb_ascii_toupper(a)
1979static ALWAYS_INLINE unsigned char bb_ascii_toupper(unsigned char a)
1980{
1981 unsigned char b = a - 'a';
1982 if (b <= ('z' - 'a'))
1983 a -= 'a' - 'A';
1984 return a;
1985}
1986#define tolower(a) bb_ascii_tolower(a)
1987static ALWAYS_INLINE unsigned char bb_ascii_tolower(unsigned char a)
1988{
1989 unsigned char b = a - 'A';
1990 if (b <= ('Z' - 'A'))
1991 a += 'a' - 'A';
1992 return a;
1993}
1994
1995/* In ASCII and Unicode, these are likely to be very different.
1996 * Let's prevent ambiguous usage from the start */
1997#define isgraph(a) isgraph_is_ambiguous_dont_use(a)
1998#define isprint(a) isprint_is_ambiguous_dont_use(a)
1999/* NB: must not treat EOF as isgraph or isprint */
2000#define isgraph_asciionly(a) ((unsigned)((a) - 0x21) <= 0x7e - 0x21)
2001#define isprint_asciionly(a) ((unsigned)((a) - 0x20) <= 0x7e - 0x20)
2002
2003
2004/* Simple unit-testing framework */
2005
2006typedef void (*bbunit_testfunc)(void);
2007
2008struct bbunit_listelem {
2009 const char* name;
2010 bbunit_testfunc testfunc;
2011};
2012
2013void bbunit_registertest(struct bbunit_listelem* test);
2014void bbunit_settestfailed(void);
2015
2016#define BBUNIT_DEFINE_TEST(NAME) \
2017 static void bbunit_##NAME##_test(void); \
2018 static struct bbunit_listelem bbunit_##NAME##_elem = { \
2019 .name = #NAME, \
2020 .testfunc = bbunit_##NAME##_test, \
2021 }; \
2022 static void INIT_FUNC bbunit_##NAME##_register(void) \
2023 { \
2024 bbunit_registertest(&bbunit_##NAME##_elem); \
2025 } \
2026 static void bbunit_##NAME##_test(void)
2027
2028/*
2029 * Both 'goto bbunit_end' and 'break' are here only to get rid
2030 * of compiler warnings.
2031 */
2032#define BBUNIT_ENDTEST \
2033 do { \
2034 goto bbunit_end; \
2035 bbunit_end: \
2036 break; \
2037 } while (0)
2038
2039#define BBUNIT_PRINTASSERTFAIL \
2040 do { \
2041 bb_error_msg( \
2042 "[ERROR] Assertion failed in file %s, line %d", \
2043 __FILE__, __LINE__); \
2044 } while (0)
2045
2046#define BBUNIT_ASSERTION_FAILED \
2047 do { \
2048 bbunit_settestfailed(); \
2049 goto bbunit_end; \
2050 } while (0)
2051
2052/*
2053 * Assertions.
2054 * For now we only offer assertions which cause tests to fail
2055 * immediately. In the future 'expects' might be added too -
2056 * similar to those offered by the gtest framework.
2057 */
2058#define BBUNIT_ASSERT_EQ(EXPECTED, ACTUAL) \
2059 do { \
2060 if ((EXPECTED) != (ACTUAL)) { \
2061 BBUNIT_PRINTASSERTFAIL; \
2062 bb_error_msg("[ERROR] '%s' isn't equal to '%s'", \
2063 #EXPECTED, #ACTUAL); \
2064 BBUNIT_ASSERTION_FAILED; \
2065 } \
2066 } while (0)
2067
2068#define BBUNIT_ASSERT_NOTEQ(EXPECTED, ACTUAL) \
2069 do { \
2070 if ((EXPECTED) == (ACTUAL)) { \
2071 BBUNIT_PRINTASSERTFAIL; \
2072 bb_error_msg("[ERROR] '%s' is equal to '%s'", \
2073 #EXPECTED, #ACTUAL); \
2074 BBUNIT_ASSERTION_FAILED; \
2075 } \
2076 } while (0)
2077
2078#define BBUNIT_ASSERT_NOTNULL(PTR) \
2079 do { \
2080 if ((PTR) == NULL) { \
2081 BBUNIT_PRINTASSERTFAIL; \
2082 bb_error_msg("[ERROR] '%s' is NULL!", #PTR); \
2083 BBUNIT_ASSERTION_FAILED; \
2084 } \
2085 } while (0)
2086
2087#define BBUNIT_ASSERT_NULL(PTR) \
2088 do { \
2089 if ((PTR) != NULL) { \
2090 BBUNIT_PRINTASSERTFAIL; \
2091 bb_error_msg("[ERROR] '%s' is not NULL!", #PTR); \
2092 BBUNIT_ASSERTION_FAILED; \
2093 } \
2094 } while (0)
2095
2096#define BBUNIT_ASSERT_FALSE(STATEMENT) \
2097 do { \
2098 if ((STATEMENT)) { \
2099 BBUNIT_PRINTASSERTFAIL; \
2100 bb_error_msg("[ERROR] Statement '%s' evaluated to true!", \
2101 #STATEMENT); \
2102 BBUNIT_ASSERTION_FAILED; \
2103 } \
2104 } while (0)
2105
2106#define BBUNIT_ASSERT_TRUE(STATEMENT) \
2107 do { \
2108 if (!(STATEMENT)) { \
2109 BBUNIT_PRINTASSERTFAIL; \
2110 bb_error_msg("[ERROR] Statement '%s' evaluated to false!", \
2111 #STATEMENT); \
2112 BBUNIT_ASSERTION_FAILED; \
2113 } \
2114 } while (0)
2115
2116#define BBUNIT_ASSERT_STREQ(STR1, STR2) \
2117 do { \
2118 if (strcmp(STR1, STR2) != 0) { \
2119 BBUNIT_PRINTASSERTFAIL; \
2120 bb_error_msg("[ERROR] Strings '%s' and '%s' " \
2121 "are not the same", STR1, STR2); \
2122 BBUNIT_ASSERTION_FAILED; \
2123 } \
2124 } while (0)
2125
2126#define BBUNIT_ASSERT_STRNOTEQ(STR1, STR2) \
2127 do { \
2128 if (strcmp(STR1, STR2) == 0) { \
2129 BBUNIT_PRINTASSERTFAIL; \
2130 bb_error_msg("[ERROR] Strings '%s' and '%s' " \
2131 "are the same, but were " \
2132 "expected to differ", STR1, STR2); \
2133 BBUNIT_ASSERTION_FAILED; \
2134 } \
2135 } while (0)
2136
2137
2138POP_SAVED_FUNCTION_VISIBILITY
2139
2140#endif
Note: See TracBrowser for help on using the repository browser.