aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--include/.gitignore1
-rw-r--r--include/bb_archive.h14
-rw-r--r--include/libbb.h453
-rw-r--r--include/mingw.h674
-rw-r--r--include/platform.h47
-rw-r--r--include/unicode.h19
-rw-r--r--include/usage.src.h6
7 files changed, 1128 insertions, 86 deletions
diff --git a/include/.gitignore b/include/.gitignore
index 13a96e018..91575ed3f 100644
--- a/include/.gitignore
+++ b/include/.gitignore
@@ -3,6 +3,7 @@
3/applets.h 3/applets.h
4/applet_tables.h 4/applet_tables.h
5/autoconf.h 5/autoconf.h
6/BB_VER.h
6/bbconfigopts_bz2.h 7/bbconfigopts_bz2.h
7/bbconfigopts.h 8/bbconfigopts.h
8/embedded_scripts.h 9/embedded_scripts.h
diff --git a/include/bb_archive.h b/include/bb_archive.h
index e0ef8fc4e..3422c9656 100644
--- a/include/bb_archive.h
+++ b/include/bb_archive.h
@@ -2,6 +2,16 @@
2#ifndef UNARCHIVE_H 2#ifndef UNARCHIVE_H
3#define UNARCHIVE_H 1 3#define UNARCHIVE_H 1
4 4
5#if !defined(BB_ARCHIVE_PUBLIC) && ENABLE_PLATFORM_MINGW32
6/* treat mingw as a non-MMU platform */
7#undef BB_MMU
8#undef USE_FOR_NOMMU
9#undef USE_FOR_MMU
10#define BB_MMU 0
11#define USE_FOR_NOMMU(...) __VA_ARGS__
12#define USE_FOR_MMU(...)
13#endif
14
5PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 15PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
6 16
7enum { 17enum {
@@ -277,7 +287,11 @@ enum {
277 BBUNPK_SEAMLESS_MAGIC = (1 << 31) * ENABLE_ZCAT * SEAMLESS_COMPRESSION, 287 BBUNPK_SEAMLESS_MAGIC = (1 << 31) * ENABLE_ZCAT * SEAMLESS_COMPRESSION,
278}; 288};
279 289
290#if !ENABLE_PLATFORM_MINGW32
280void check_errors_in_children(int signo); 291void check_errors_in_children(int signo);
292#else
293#define check_errors_in_children(s) ((void)0)
294#endif
281#if BB_MMU 295#if BB_MMU
282void fork_transformer(int fd, 296void fork_transformer(int fd,
283 int signature_skipped, 297 int signature_skipped,
diff --git a/include/libbb.h b/include/libbb.h
index 4d6193795..60037ed3d 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -10,6 +10,12 @@
10#ifndef LIBBB_H 10#ifndef LIBBB_H
11#define LIBBB_H 1 11#define LIBBB_H 1
12 12
13#if ENABLE_PLATFORM_MINGW32
14/* We have our own nanosleep(), clock_gettime() and clock_settime(). */
15/* Skip the Windows include file that declares them. */
16# define WIN_PTHREADS_TIME_H
17#endif
18
13#include "platform.h" 19#include "platform.h"
14 20
15#include <ctype.h> 21#include <ctype.h>
@@ -143,6 +149,9 @@
143# include <arpa/inet.h> 149# include <arpa/inet.h>
144#elif defined __APPLE__ 150#elif defined __APPLE__
145# include <netinet/in.h> 151# include <netinet/in.h>
152#elif ENABLE_PLATFORM_MINGW32
153# include <winsock2.h>
154# include <ws2tcpip.h>
146#else 155#else
147# include <arpa/inet.h> 156# include <arpa/inet.h>
148//This breaks on bionic: 157//This breaks on bionic:
@@ -182,7 +191,9 @@
182 191
183/* Some libc's forget to declare these, do it ourself */ 192/* Some libc's forget to declare these, do it ourself */
184 193
194#if !ENABLE_PLATFORM_MINGW32
185extern char **environ; 195extern char **environ;
196#endif
186/* klogctl is in libc's klog.h, but we cheat and not #include that */ 197/* klogctl is in libc's klog.h, but we cheat and not #include that */
187int klogctl(int type, char *b, int len); 198int klogctl(int type, char *b, int len);
188#ifndef PATH_MAX 199#ifndef PATH_MAX
@@ -192,6 +203,13 @@ int klogctl(int type, char *b, int len);
192# define BUFSIZ 4096 203# define BUFSIZ 4096
193#endif 204#endif
194 205
206#if ENABLE_PLATFORM_MINGW32
207# include "mingw.h"
208# define MINGW_SPECIAL(a) mingw_ ## a
209#else
210# define MINGW_SPECIAL(a) a
211#endif
212
195#if __GNUC_PREREQ(5,0) 213#if __GNUC_PREREQ(5,0)
196/* Since musl is apparently unable to get it right and would use 214/* Since musl is apparently unable to get it right and would use
197 * a function call to a single-instruction function of "bswap %eax", 215 * a function call to a single-instruction function of "bswap %eax",
@@ -263,6 +281,26 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
263# endif 281# endif
264#endif 282#endif
265 283
284#if ENABLE_FEATURE_TLS_SCHANNEL || ENABLE_FEATURE_USE_CNG_API
285# define SECURITY_WIN32
286# include <windows.h>
287# include <security.h>
288#endif
289
290#if ENABLE_FEATURE_USE_CNG_API
291# include <bcrypt.h>
292
293// these work on Windows >= 10
294# define BCRYPT_HMAC_SHA1_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x000000a1)
295# define BCRYPT_HMAC_SHA256_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x000000b1)
296# define sha1_begin_hmac BCRYPT_HMAC_SHA1_ALG_HANDLE
297# define sha256_begin_hmac BCRYPT_HMAC_SHA256_ALG_HANDLE
298#else
299# define sha1_begin_hmac sha1_begin
300# define sha256_begin_hmac sha256_begin
301# define hmac_uninit(...) ((void)0)
302#endif
303
266/* Tested to work correctly with all int types (IIRC :]) */ 304/* Tested to work correctly with all int types (IIRC :]) */
267#define MAXINT(T) (T)( \ 305#define MAXINT(T) (T)( \
268 ((T)-1) > 0 \ 306 ((T)-1) > 0 \
@@ -276,6 +314,20 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
276 : ((T)1 << (sizeof(T)*8-1)) \ 314 : ((T)1 << (sizeof(T)*8-1)) \
277 ) 315 )
278 316
317// UCRT supports both "ll" and "I64", but gcc warns on "I64" with UCRT mingw
318#if ENABLE_PLATFORM_MINGW32 && !defined(_UCRT) && \
319 (!defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO)
320#define LL_FMT "I64"
321#else
322#define LL_FMT "ll"
323#endif
324
325#if ENABLE_PLATFORM_MINGW32 && defined(_WIN64)
326#define PID_FMT LL_FMT
327#else
328#define PID_FMT
329#endif
330
279/* Large file support */ 331/* Large file support */
280/* Note that CONFIG_LFS=y forces bbox to be built with all common ops 332/* Note that CONFIG_LFS=y forces bbox to be built with all common ops
281 * (stat, lseek etc) mapped to "largefile" variants by libc. 333 * (stat, lseek etc) mapped to "largefile" variants by libc.
@@ -301,7 +353,7 @@ typedef unsigned long long uoff_t;
301# define XATOOFF(a) xatoull_range((a), 0, LLONG_MAX) 353# define XATOOFF(a) xatoull_range((a), 0, LLONG_MAX)
302# define BB_STRTOOFF bb_strtoull 354# define BB_STRTOOFF bb_strtoull
303# define STRTOOFF strtoull 355# define STRTOOFF strtoull
304# define OFF_FMT "ll" 356# define OFF_FMT LL_FMT
305# endif 357# endif
306#else 358#else
307/* CONFIG_LFS is off */ 359/* CONFIG_LFS is off */
@@ -570,13 +622,20 @@ char *bb_get_last_path_component_nostrip(const char *path) FAST_FUNC;
570const char *bb_basename(const char *name) FAST_FUNC; 622const char *bb_basename(const char *name) FAST_FUNC;
571/* NB: can violate const-ness (similarly to strchr) */ 623/* NB: can violate const-ness (similarly to strchr) */
572char *last_char_is(const char *s, int c) FAST_FUNC; 624char *last_char_is(const char *s, int c) FAST_FUNC;
625char *last_char_is_dir_sep(const char *s) FAST_FUNC;
573const char* endofname(const char *name) FAST_FUNC; 626const char* endofname(const char *name) FAST_FUNC;
574char *is_prefixed_with(const char *string, const char *key) FAST_FUNC; 627char *is_prefixed_with(const char *string, const char *key) FAST_FUNC;
575char *is_suffixed_with(const char *string, const char *key) FAST_FUNC; 628char *is_suffixed_with(const char *string, const char *key) FAST_FUNC;
576 629
630#if !ENABLE_PLATFORM_MINGW32
577int ndelay_on(int fd) FAST_FUNC; 631int ndelay_on(int fd) FAST_FUNC;
578int ndelay_off(int fd) FAST_FUNC; 632int ndelay_off(int fd) FAST_FUNC;
579void close_on_exec_on(int fd) FAST_FUNC; 633void close_on_exec_on(int fd) FAST_FUNC;
634#else
635static inline int ndelay_on(int fd UNUSED_PARAM) { return 0; }
636static inline int ndelay_off(int fd UNUSED_PARAM) { return 0; }
637static inline void close_on_exec_on(int fd UNUSED_PARAM) { return; }
638#endif
580void xdup2(int, int) FAST_FUNC; 639void xdup2(int, int) FAST_FUNC;
581void xmove_fd(int, int) FAST_FUNC; 640void xmove_fd(int, int) FAST_FUNC;
582 641
@@ -610,20 +669,37 @@ enum {
610 * Dance around with long long to guard against that... 669 * Dance around with long long to guard against that...
611 */ 670 */
612 BB_FATAL_SIGS = (int)(0 671 BB_FATAL_SIGS = (int)(0
672#ifdef SIGHUP
613 + (1LL << SIGHUP) 673 + (1LL << SIGHUP)
674#endif
614 + (1LL << SIGINT) 675 + (1LL << SIGINT)
615 + (1LL << SIGTERM) 676 + (1LL << SIGTERM)
616 + (1LL << SIGPIPE) // Write to pipe with no readers 677 + (1LL << SIGPIPE) // Write to pipe with no readers
678#ifdef SIGQUIT
617 + (1LL << SIGQUIT) // Quit from keyboard 679 + (1LL << SIGQUIT) // Quit from keyboard
680#endif
618 + (1LL << SIGABRT) // Abort signal from abort(3) 681 + (1LL << SIGABRT) // Abort signal from abort(3)
682#ifdef SIGALRM
619 + (1LL << SIGALRM) // Timer signal from alarm(2) 683 + (1LL << SIGALRM) // Timer signal from alarm(2)
684#endif
685#ifdef SIGVTALRM
620 + (1LL << SIGVTALRM) // Virtual alarm clock 686 + (1LL << SIGVTALRM) // Virtual alarm clock
687#endif
688#ifdef SIGXCPU
621 + (1LL << SIGXCPU) // CPU time limit exceeded 689 + (1LL << SIGXCPU) // CPU time limit exceeded
690#endif
691#ifdef SIGXFSZ
622 + (1LL << SIGXFSZ) // File size limit exceeded 692 + (1LL << SIGXFSZ) // File size limit exceeded
693#endif
694#ifdef SIGUSR1
623 + (1LL << SIGUSR1) // Yes kids, these are also fatal! 695 + (1LL << SIGUSR1) // Yes kids, these are also fatal!
696#endif
697#ifdef SIGUSR1
624 + (1LL << SIGUSR2) 698 + (1LL << SIGUSR2)
699#endif
625 + 0), 700 + 0),
626}; 701};
702#if !ENABLE_PLATFORM_MINGW32
627void bb_signals(int sigs, void (*f)(int)) FAST_FUNC; 703void bb_signals(int sigs, void (*f)(int)) FAST_FUNC;
628/* Unlike signal() and bb_signals, sets handler with sigaction() 704/* Unlike signal() and bb_signals, sets handler with sigaction()
629 * and in a way that while signal handler is run, no other signals 705 * and in a way that while signal handler is run, no other signals
@@ -643,6 +719,10 @@ int sigaction_set(int sig, const struct sigaction *act) FAST_FUNC;
643int sigprocmask_allsigs(int how) FAST_FUNC; 719int sigprocmask_allsigs(int how) FAST_FUNC;
644/* Return old set in the same set: */ 720/* Return old set in the same set: */
645int sigprocmask2(int how, sigset_t *set) FAST_FUNC; 721int sigprocmask2(int how, sigset_t *set) FAST_FUNC;
722#else
723#define bb_signals(s, f)
724#define kill_myself_with_sig(s)
725#endif
646/* Standard handler which just records signo */ 726/* Standard handler which just records signo */
647extern smallint bb_got_signal; 727extern smallint bb_got_signal;
648void record_signo(int signo); /* not FAST_FUNC! */ 728void record_signo(int signo); /* not FAST_FUNC! */
@@ -726,7 +806,7 @@ void xsettimeofday(const struct timeval *tv) FAST_FUNC;
726int xsocket(int domain, int type, int protocol) FAST_FUNC; 806int xsocket(int domain, int type, int protocol) FAST_FUNC;
727void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) FAST_FUNC; 807void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) FAST_FUNC;
728void xlisten(int s, int backlog) FAST_FUNC; 808void xlisten(int s, int backlog) FAST_FUNC;
729void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) FAST_FUNC; 809void xconnect(int s, const struct sockaddr *saddr, socklen_t addrlen) FAST_FUNC;
730ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to, 810ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
731 socklen_t tolen) FAST_FUNC; 811 socklen_t tolen) FAST_FUNC;
732 812
@@ -839,7 +919,36 @@ struct hostent *xgethostbyname(const char *name) FAST_FUNC;
839// Also mount.c and inetd.c are using gethostbyname(), 919// Also mount.c and inetd.c are using gethostbyname(),
840// + inet_common.c has additional IPv4-only stuff 920// + inet_common.c has additional IPv4-only stuff
841 921
922#if defined CONFIG_FEATURE_TLS_SCHANNEL
923typedef struct tls_state {
924 int ofd;
925 int ifd;
926
927 // handles
928 CredHandle cred_handle;
929 CtxtHandle ctx_handle;
842 930
931 // buffers
932 char in_buffer[16384 + 256]; // input buffer (to read from server)
933 unsigned long in_buffer_size; // amount of data currently in input buffer
934
935 char *out_buffer; // output buffer (for decrypted data), this is essentially the same as input buffer as data is decrypted in place
936 unsigned long out_buffer_size; // amount of data currently in output buffer
937 unsigned long out_buffer_used; // amount of extra data currently in output buffer
938
939 // data
940 char *hostname;
941 SecPkgContext_StreamSizes stream_sizes;
942
943 // booleans
944
945 // context initialized
946 int initialized;
947
948 // closed by remote peer
949 int closed;
950} tls_state_t;
951#else
843struct tls_aes { 952struct tls_aes {
844 uint32_t key[60]; 953 uint32_t key[60];
845 unsigned rounds; 954 unsigned rounds;
@@ -896,12 +1005,14 @@ typedef struct tls_state {
896 struct tls_aes aes_decrypt; 1005 struct tls_aes aes_decrypt;
897 uint8_t H[16]; //used by AES_GCM 1006 uint8_t H[16]; //used by AES_GCM
898} tls_state_t; 1007} tls_state_t;
1008#endif
899 1009
900static inline tls_state_t *new_tls_state(void) 1010static inline tls_state_t *new_tls_state(void)
901{ 1011{
902 tls_state_t *tls = xzalloc(sizeof(*tls)); 1012 tls_state_t *tls = xzalloc(sizeof(*tls));
903 return tls; 1013 return tls;
904} 1014}
1015
905void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC; 1016void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC;
906#define TLSLOOP_EXIT_ON_LOCAL_EOF (1 << 0) 1017#define TLSLOOP_EXIT_ON_LOCAL_EOF (1 << 0)
907void tls_run_copy_loop(tls_state_t *tls, unsigned flags) FAST_FUNC; 1018void tls_run_copy_loop(tls_state_t *tls, unsigned flags) FAST_FUNC;
@@ -933,7 +1044,7 @@ int bb_putchar(int ch) FAST_FUNC;
933/* Note: does not use stdio, writes to fd 2 directly */ 1044/* Note: does not use stdio, writes to fd 2 directly */
934int bb_putchar_stderr(char ch) FAST_FUNC; 1045int bb_putchar_stderr(char ch) FAST_FUNC;
935int fputs_stdout(const char *s) FAST_FUNC; 1046int fputs_stdout(const char *s) FAST_FUNC;
936char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC; 1047char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) RETURNS_MALLOC;
937char *auto_string(char *str) FAST_FUNC; 1048char *auto_string(char *str) FAST_FUNC;
938// gcc-4.1.1 still isn't good enough at optimizing it 1049// gcc-4.1.1 still isn't good enough at optimizing it
939// (+200 bytes compared to macro) 1050// (+200 bytes compared to macro)
@@ -1011,13 +1122,13 @@ unsigned bb_clk_tck(void) FAST_FUNC;
1011 1122
1012#if SEAMLESS_COMPRESSION 1123#if SEAMLESS_COMPRESSION
1013/* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ 1124/* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */
1014int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC; 1125int setup_unzip_on_fd(int fd, int die_if_not_compressed) FAST_FUNC;
1015/* Autodetects .gz etc */ 1126/* Autodetects .gz etc */
1016extern int open_zipped(const char *fname, int fail_if_not_compressed) FAST_FUNC; 1127extern int open_zipped(const char *fname, int die_if_not_compressed) FAST_FUNC;
1017extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; 1128extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
1018#else 1129#else
1019# define setup_unzip_on_fd(...) (0) 1130# define setup_unzip_on_fd(...) (0)
1020# define open_zipped(fname, fail_if_not_compressed) open((fname), O_RDONLY); 1131# define open_zipped(fname, die_if_not_compressed) open((fname), O_RDONLY);
1021# define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p)) 1132# define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p))
1022#endif 1133#endif
1023/* lzma has no signature, need a little helper. NB: exist only for ENABLE_FEATURE_SEAMLESS_LZMA=y */ 1134/* lzma has no signature, need a little helper. NB: exist only for ENABLE_FEATURE_SEAMLESS_LZMA=y */
@@ -1113,6 +1224,32 @@ char *bin2hex(char *dst, const char *src, int count) FAST_FUNC;
1113/* Reverse */ 1224/* Reverse */
1114char* hex2bin(char *dst, const char *src, int count) FAST_FUNC; 1225char* hex2bin(char *dst, const char *src, int count) FAST_FUNC;
1115 1226
1227/* Returns strlen as a bonus */
1228//size_t replace_char(char *s, char what, char with) FAST_FUNC;
1229static inline size_t replace_char(char *str, char from, char to)
1230{
1231 char *p = str;
1232 while (*p) {
1233 if (*p == from)
1234 *p = to;
1235 p++;
1236 }
1237 return p - str;
1238}
1239
1240extern const char c_escape_conv_str00[];
1241#define c_escape_conv_str07 (c_escape_conv_str00+3)
1242
1243void FAST_FUNC xorbuf_3(void *dst, const void *src1, const void *src2, unsigned count);
1244void FAST_FUNC xorbuf(void* buf, const void* mask, unsigned count);
1245void FAST_FUNC xorbuf16_aligned_long(void* buf, const void* mask);
1246void FAST_FUNC xorbuf64_3_aligned64(void *dst, const void *src1, const void *src2);
1247#if BB_UNALIGNED_MEMACCESS_OK
1248# define xorbuf16(buf,mask) xorbuf16_aligned_long(buf,mask)
1249#else
1250void FAST_FUNC xorbuf16(void* buf, const void* mask);
1251#endif
1252
1116/* Generate a UUID */ 1253/* Generate a UUID */
1117void generate_uuid(uint8_t *buf) FAST_FUNC; 1254void generate_uuid(uint8_t *buf) FAST_FUNC;
1118 1255
@@ -1208,12 +1345,20 @@ gid_t *bb_getgroups(int *ngroups, gid_t *group_array) FAST_FUNC;
1208struct cached_groupinfo { 1345struct cached_groupinfo {
1209 uid_t euid; 1346 uid_t euid;
1210 gid_t egid; 1347 gid_t egid;
1348#if !ENABLE_PLATFORM_MINGW32
1349 // If these are ever restored on Windows it will be necessary to alter
1350 // globals_misc_size()/globals_misc_copy() in ash.
1211 int ngroups; 1351 int ngroups;
1212 gid_t *supplementary_array; 1352 gid_t *supplementary_array;
1353#endif
1213}; 1354};
1214uid_t FAST_FUNC get_cached_euid(uid_t *euid); 1355uid_t FAST_FUNC get_cached_euid(uid_t *euid);
1215gid_t FAST_FUNC get_cached_egid(gid_t *egid); 1356gid_t FAST_FUNC get_cached_egid(gid_t *egid);
1357#if !ENABLE_PLATFORM_MINGW32
1216int FAST_FUNC is_in_supplementary_groups(struct cached_groupinfo *groupinfo, gid_t gid); 1358int FAST_FUNC is_in_supplementary_groups(struct cached_groupinfo *groupinfo, gid_t gid);
1359#else
1360# define is_in_supplementary_groups(g, i) (FALSE)
1361#endif
1217 1362
1218#if ENABLE_FEATURE_UTMP 1363#if ENABLE_FEATURE_UTMP
1219void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname); 1364void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
@@ -1249,6 +1394,7 @@ void BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;
1249 1394
1250/* xvfork() can't be a _function_, return after vfork in child mangles stack 1395/* xvfork() can't be a _function_, return after vfork in child mangles stack
1251 * in the parent. It must be a macro. */ 1396 * in the parent. It must be a macro. */
1397#if !ENABLE_PLATFORM_MINGW32
1252#define xvfork() \ 1398#define xvfork() \
1253({ \ 1399({ \
1254 pid_t bb__xvfork_pid = vfork(); \ 1400 pid_t bb__xvfork_pid = vfork(); \
@@ -1256,6 +1402,9 @@ void BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;
1256 bb_simple_perror_msg_and_die("vfork"); \ 1402 bb_simple_perror_msg_and_die("vfork"); \
1257 bb__xvfork_pid; \ 1403 bb__xvfork_pid; \
1258}) 1404})
1405#else
1406#define xvfork() vfork()
1407#endif
1259#if BB_MMU 1408#if BB_MMU
1260pid_t xfork(void) FAST_FUNC; 1409pid_t xfork(void) FAST_FUNC;
1261#endif 1410#endif
@@ -1290,6 +1439,15 @@ void run_noexec_applet_and_exit(int a, const char *name, char **argv) NORETURN F
1290#ifndef BUILD_INDIVIDUAL 1439#ifndef BUILD_INDIVIDUAL
1291int find_applet_by_name(const char *name) FAST_FUNC; 1440int find_applet_by_name(const char *name) FAST_FUNC;
1292void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC; 1441void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC;
1442# if ENABLE_PLATFORM_MINGW32
1443# if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE
1444int prefer_applet(const char *name, const char *path) FAST_FUNC;
1445int find_applet_by_name_for_sh(const char *name, const char *path) FAST_FUNC;
1446# endif
1447# else
1448# define prefer_applet(n, p) (1)
1449# define find_applet_by_name_for_sh(n, p) find_applet_by_name(n)
1450# endif
1293#endif 1451#endif
1294void show_usage_if_dash_dash_help(int applet_no, char **argv) FAST_FUNC; 1452void show_usage_if_dash_dash_help(int applet_no, char **argv) FAST_FUNC;
1295#if defined(__linux__) 1453#if defined(__linux__)
@@ -1370,12 +1528,12 @@ char* single_argv(char **argv) FAST_FUNC;
1370char **skip_dash_dash(char **argv) FAST_FUNC; 1528char **skip_dash_dash(char **argv) FAST_FUNC;
1371extern const char *const bb_argv_dash[]; /* { "-", NULL } */ 1529extern const char *const bb_argv_dash[]; /* { "-", NULL } */
1372extern uint32_t option_mask32; 1530extern uint32_t option_mask32;
1373uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC; 1531uint32_t getopt32(char **argv, const char *applet_opts, ...);
1374# define No_argument "\0" 1532# define No_argument "\0"
1375# define Required_argument "\001" 1533# define Required_argument "\001"
1376# define Optional_argument "\002" 1534# define Optional_argument "\002"
1377#if ENABLE_LONG_OPTS 1535#if ENABLE_LONG_OPTS
1378uint32_t getopt32long(char **argv, const char *optstring, const char *longopts, ...) FAST_FUNC; 1536uint32_t getopt32long(char **argv, const char *optstring, const char *longopts, ...);
1379#else 1537#else
1380#define getopt32long(argv,optstring,longopts,...) \ 1538#define getopt32long(argv,optstring,longopts,...) \
1381 getopt32(argv,optstring,##__VA_ARGS__) 1539 getopt32(argv,optstring,##__VA_ARGS__)
@@ -1450,17 +1608,17 @@ extern uint8_t xfunc_error_retval;
1450extern void (*die_func)(void); 1608extern void (*die_func)(void);
1451void xfunc_die(void) NORETURN FAST_FUNC; 1609void xfunc_die(void) NORETURN FAST_FUNC;
1452void bb_show_usage(void) NORETURN FAST_FUNC; 1610void bb_show_usage(void) NORETURN FAST_FUNC;
1453void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1611void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
1454void bb_simple_error_msg(const char *s) FAST_FUNC; 1612void bb_simple_error_msg(const char *s) FAST_FUNC;
1455void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC; 1613void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
1456void bb_simple_error_msg_and_die(const char *s) NORETURN FAST_FUNC; 1614void bb_simple_error_msg_and_die(const char *s) NORETURN FAST_FUNC;
1457void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1615void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
1458void bb_simple_perror_msg(const char *s) FAST_FUNC; 1616void bb_simple_perror_msg(const char *s) FAST_FUNC;
1459void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC; 1617void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
1460void bb_simple_perror_msg_and_die(const char *s) NORETURN FAST_FUNC; 1618void bb_simple_perror_msg_and_die(const char *s) NORETURN FAST_FUNC;
1461void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1619void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
1462void bb_simple_herror_msg(const char *s) FAST_FUNC; 1620void bb_simple_herror_msg(const char *s) FAST_FUNC;
1463void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC; 1621void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
1464void bb_simple_herror_msg_and_die(const char *s) NORETURN FAST_FUNC; 1622void bb_simple_herror_msg_and_die(const char *s) NORETURN FAST_FUNC;
1465void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC; 1623void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC;
1466void bb_perror_nomsg(void) FAST_FUNC; 1624void bb_perror_nomsg(void) FAST_FUNC;
@@ -1476,7 +1634,7 @@ void bb_logenv_override(void) FAST_FUNC;
1476typedef smalluint exitcode_t; 1634typedef smalluint exitcode_t;
1477 1635
1478#if ENABLE_FEATURE_SYSLOG_INFO 1636#if ENABLE_FEATURE_SYSLOG_INFO
1479void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1637void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
1480void bb_simple_info_msg(const char *s) FAST_FUNC; 1638void bb_simple_info_msg(const char *s) FAST_FUNC;
1481void bb_vinfo_msg(const char *s, va_list p) FAST_FUNC; 1639void bb_vinfo_msg(const char *s, va_list p) FAST_FUNC;
1482#else 1640#else
@@ -1806,18 +1964,25 @@ extern char *pw_encrypt(const char *clear, const char *salt, int cleanup) FAST_F
1806extern int obscure(const char *old, const char *newval, const struct passwd *pwdp) FAST_FUNC; 1964extern int obscure(const char *old, const char *newval, const struct passwd *pwdp) FAST_FUNC;
1807/* 1965/*
1808 * rnd is additional random input. New one is returned. 1966 * rnd is additional random input. New one is returned.
1809 * Useful if you call crypt_make_salt many times in a row: 1967 * Useful if you call crypt_make_rand64encoded many times in a row:
1810 * rnd = crypt_make_salt(buf1, 4, 0); 1968 * rnd = crypt_make_rand64encoded(buf1, 4, 0);
1811 * rnd = crypt_make_salt(buf2, 4, rnd); 1969 * rnd = crypt_make_rand64encoded(buf2, 4, rnd);
1812 * rnd = crypt_make_salt(buf3, 4, rnd); 1970 * rnd = crypt_make_rand64encoded(buf3, 4, rnd);
1813 * (otherwise we risk having same salt generated) 1971 * (otherwise we risk having same salt generated)
1814 */ 1972 */
1815extern int crypt_make_salt(char *p, int cnt /*, int rnd*/) FAST_FUNC; 1973extern int crypt_make_rand64encoded(char *p, int cnt /*, int rnd*/) FAST_FUNC;
1816/* "$N$" + sha_salt_16_bytes + NUL */ 1974/* Size of char salt[] to hold randomly-generated salt string
1817#define MAX_PW_SALT_LEN (3 + 16 + 1) 1975 * sha256/512:
1976 * "$5$" ["rounds=999999999$"] "<sha_salt_16_chars><NUL>"
1977 * "$6$" ["rounds=999999999$"] "<sha_salt_16_chars><NUL>"
1978 * #define MAX_PW_SALT_LEN (3 + sizeof("rounds=999999999$")-1 + 16 + 1)
1979 * yescrypt:
1980 * "$y$" <up to 8 params of up to 6 chars each> "$" <up to 86 chars salt><NUL>
1981 * (86 chars are ascii64-encoded 64 binary bytes)
1982 */
1983#define MAX_PW_SALT_LEN (3 + 8*6 + 1 + 86 + 1)
1818extern char* crypt_make_pw_salt(char p[MAX_PW_SALT_LEN], const char *algo) FAST_FUNC; 1984extern char* crypt_make_pw_salt(char p[MAX_PW_SALT_LEN], const char *algo) FAST_FUNC;
1819 1985
1820
1821/* Returns number of lines changed, or -1 on error */ 1986/* Returns number of lines changed, or -1 on error */
1822#if !(ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP) 1987#if !(ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP)
1823#define update_passwd(filename, username, data, member) \ 1988#define update_passwd(filename, username, data, member) \
@@ -1853,8 +2018,8 @@ int get_termios_and_make_raw(int fd, struct termios *newterm, struct termios *ol
1853int set_termios_to_raw(int fd, struct termios *oldterm, int flags) FAST_FUNC; 2018int set_termios_to_raw(int fd, struct termios *oldterm, int flags) FAST_FUNC;
1854 2019
1855/* NB: "unsigned request" is crucial! "int request" will break some arches! */ 2020/* NB: "unsigned request" is crucial! "int request" will break some arches! */
1856int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC; 2021int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
1857int ioctl_or_perror_and_die(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC; 2022int ioctl_or_perror_and_die(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
1858#if ENABLE_IOCTL_HEX2STR_ERROR 2023#if ENABLE_IOCTL_HEX2STR_ERROR
1859int bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC; 2024int bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC;
1860int bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC; 2025int bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC;
@@ -1867,9 +2032,15 @@ int bb_xioctl(int fd, unsigned request, void *argp) FAST_FUNC;
1867#define xioctl(fd,request,argp) bb_xioctl(fd,request,argp) 2032#define xioctl(fd,request,argp) bb_xioctl(fd,request,argp)
1868#endif 2033#endif
1869 2034
2035#if !ENABLE_PLATFORM_MINGW32 || ENABLE_FEATURE_EXTRA_FILE_DATA
1870char *is_in_ino_dev_hashtable(const struct stat *statbuf) FAST_FUNC; 2036char *is_in_ino_dev_hashtable(const struct stat *statbuf) FAST_FUNC;
1871void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name) FAST_FUNC; 2037void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name) FAST_FUNC;
1872void reset_ino_dev_hashtable(void) FAST_FUNC; 2038void reset_ino_dev_hashtable(void) FAST_FUNC;
2039#else
2040#define add_to_ino_dev_hashtable(s, n) (void)0
2041#define is_in_ino_dev_hashtable(s) NULL
2042#define reset_ino_dev_hashtable()
2043#endif
1873#ifdef __GLIBC__ 2044#ifdef __GLIBC__
1874/* At least glibc has horrendously large inline for this, so wrap it */ 2045/* At least glibc has horrendously large inline for this, so wrap it */
1875unsigned long long bb_makedev(unsigned major, unsigned minor) FAST_FUNC; 2046unsigned long long bb_makedev(unsigned major, unsigned minor) FAST_FUNC;
@@ -1947,10 +2118,17 @@ enum {
1947 * >=0: poll() for TIMEOUT milliseconds, return -1/EAGAIN on timeout 2118 * >=0: poll() for TIMEOUT milliseconds, return -1/EAGAIN on timeout
1948 */ 2119 */
1949int64_t read_key(int fd, char *buffer, int timeout) FAST_FUNC; 2120int64_t read_key(int fd, char *buffer, int timeout) FAST_FUNC;
2121#if ENABLE_PLATFORM_MINGW32
2122int64_t windows_read_key(int fd, char *buffer, int timeout) FAST_FUNC;
2123#endif
1950/* This version loops on EINTR: */ 2124/* This version loops on EINTR: */
1951int64_t safe_read_key(int fd, char *buffer, int timeout) FAST_FUNC; 2125int64_t safe_read_key(int fd, char *buffer, int timeout) FAST_FUNC;
1952void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC; 2126void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC;
1953 2127
2128int check_got_signal_and_poll(struct pollfd pfd[1], int timeout) FAST_FUNC;
2129#if ENABLE_PLATFORM_MINGW32
2130# define check_got_signal_and_poll(p, t) poll(p, 1, t)
2131#endif
1954 2132
1955#if ENABLE_FEATURE_EDITING 2133#if ENABLE_FEATURE_EDITING
1956/* It's NOT just ENABLEd or disabled. It's a number: */ 2134/* It's NOT just ENABLEd or disabled. It's a number: */
@@ -1960,8 +2138,14 @@ unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC;
1960# else 2138# else
1961# define MAX_HISTORY 0 2139# define MAX_HISTORY 0
1962# endif 2140# endif
2141# if defined CONFIG_FEATURE_EDITING_HISTORY_DEFAULT && CONFIG_FEATURE_EDITING_HISTORY_DEFAULT > 0
2142# define DEFAULT_HISTORY (CONFIG_FEATURE_EDITING_HISTORY_DEFAULT + 0)
2143# else
2144# define DEFAULT_HISTORY 0
2145# endif
1963typedef const char *get_exe_name_t(int i) FAST_FUNC; 2146typedef const char *get_exe_name_t(int i) FAST_FUNC;
1964typedef const char *sh_get_var_t(const char *name) FAST_FUNC; 2147typedef const char *sh_get_var_t(const char *name) FAST_FUNC;
2148typedef int sh_accept_glob_t(const char *name) FAST_FUNC;
1965typedef struct line_input_t { 2149typedef struct line_input_t {
1966 int flags; 2150 int flags;
1967 int timeout; 2151 int timeout;
@@ -1975,6 +2159,9 @@ typedef struct line_input_t {
1975# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH 2159# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH
1976 /* function to fetch additional application-specific names to match */ 2160 /* function to fetch additional application-specific names to match */
1977 get_exe_name_t *get_exe_name; 2161 get_exe_name_t *get_exe_name;
2162# if ENABLE_ASH_GLOB_OPTIONS
2163 sh_accept_glob_t *sh_accept_glob;
2164# endif
1978# endif 2165# endif
1979# endif 2166# endif
1980# if (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) \ 2167# if (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) \
@@ -1988,7 +2175,7 @@ typedef struct line_input_t {
1988# if MAX_HISTORY 2175# if MAX_HISTORY
1989 int cnt_history; 2176 int cnt_history;
1990 int cur_history; 2177 int cur_history;
1991 int max_history; /* must never be <= 0 */ 2178 int max_history; /* must never be < 0 */
1992# if ENABLE_FEATURE_EDITING_SAVEHISTORY 2179# if ENABLE_FEATURE_EDITING_SAVEHISTORY
1993 /* meaning of this field depends on FEATURE_EDITING_SAVE_ON_EXIT: 2180 /* meaning of this field depends on FEATURE_EDITING_SAVE_ON_EXIT:
1994 * if !FEATURE_EDITING_SAVE_ON_EXIT: "how many lines are 2181 * if !FEATURE_EDITING_SAVE_ON_EXIT: "how many lines are
@@ -2009,6 +2196,9 @@ enum {
2009 VI_MODE = 8 * ENABLE_FEATURE_EDITING_VI, 2196 VI_MODE = 8 * ENABLE_FEATURE_EDITING_VI,
2010 WITH_PATH_LOOKUP = 0x10, 2197 WITH_PATH_LOOKUP = 0x10,
2011 LI_INTERRUPTIBLE = 0x20, 2198 LI_INTERRUPTIBLE = 0x20,
2199#if ENABLE_PLATFORM_MINGW32
2200 IGNORE_CTRL_C = 0x40,
2201#endif
2012 FOR_SHELL = DO_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION | LI_INTERRUPTIBLE, 2202 FOR_SHELL = DO_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION | LI_INTERRUPTIBLE,
2013}; 2203};
2014line_input_t *new_line_input_t(int flags) FAST_FUNC; 2204line_input_t *new_line_input_t(int flags) FAST_FUNC;
@@ -2038,6 +2228,10 @@ int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC;
2038 2228
2039unsigned long* FAST_FUNC get_malloc_cpu_affinity(int pid, unsigned *sz); 2229unsigned long* FAST_FUNC get_malloc_cpu_affinity(int pid, unsigned *sz);
2040 2230
2231#if ENABLE_PLATFORM_MINGW32
2232# undef COMM_LEN
2233# define COMM_LEN 32
2234#endif
2041#ifndef COMM_LEN 2235#ifndef COMM_LEN
2042# ifdef TASK_COMM_LEN 2236# ifdef TASK_COMM_LEN
2043enum { COMM_LEN = TASK_COMM_LEN }; 2237enum { COMM_LEN = TASK_COMM_LEN };
@@ -2047,35 +2241,14 @@ enum { COMM_LEN = 16 };
2047# endif 2241# endif
2048#endif 2242#endif
2049 2243
2050struct smaprec {
2051 unsigned long mapped_rw;
2052 unsigned long mapped_ro;
2053 unsigned long shared_clean;
2054 unsigned long shared_dirty;
2055 unsigned long private_clean;
2056 unsigned long private_dirty;
2057 unsigned long stack;
2058 unsigned long smap_pss, smap_swap;
2059 unsigned long smap_size;
2060 // For mixed 32/64 userspace, 32-bit pmap still needs
2061 // 64-bit field here to correctly show 64-bit processes:
2062 unsigned long long smap_start;
2063 // (strictly speaking, other fields need to be wider too,
2064 // but they are in kbytes, not bytes, and they hold sizes,
2065 // not start addresses, sizes tend to be less than 4 terabytes)
2066 char smap_mode[5];
2067 char *smap_name;
2068};
2069
2070#if !ENABLE_PMAP
2071#define procps_read_smaps(pid, total, cb, data) \
2072 procps_read_smaps(pid, total)
2073#endif
2074int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
2075 void (*cb)(struct smaprec *, void *), void *data);
2076
2077typedef struct procps_status_t { 2244typedef struct procps_status_t {
2245#if !ENABLE_PLATFORM_MINGW32
2078 DIR *dir; 2246 DIR *dir;
2247#else
2248 HANDLE snapshot;
2249 DWORD *pids;
2250 int npids;
2251#endif
2079 IF_FEATURE_SHOW_THREADS(DIR *task_dir;) 2252 IF_FEATURE_SHOW_THREADS(DIR *task_dir;)
2080 uint8_t shift_pages_to_bytes; 2253 uint8_t shift_pages_to_bytes;
2081 uint8_t shift_pages_to_kb; 2254 uint8_t shift_pages_to_kb;
@@ -2103,7 +2276,13 @@ typedef struct procps_status_t {
2103#endif 2276#endif
2104 unsigned tty_major,tty_minor; 2277 unsigned tty_major,tty_minor;
2105#if ENABLE_FEATURE_TOPMEM 2278#if ENABLE_FEATURE_TOPMEM
2106 struct smaprec smaps; 2279 unsigned long mapped_rw;
2280 unsigned long mapped_ro;
2281 unsigned long shared_clean;
2282 unsigned long shared_dirty;
2283 unsigned long private_clean;
2284 unsigned long private_dirty;
2285 unsigned long stack;
2107#endif 2286#endif
2108 char state[4]; 2287 char state[4];
2109 /* basename of executable in exec(2), read from /proc/N/stat 2288 /* basename of executable in exec(2), read from /proc/N/stat
@@ -2152,11 +2331,15 @@ void free_procps_scan(procps_status_t* sp) FAST_FUNC;
2152procps_status_t* procps_scan(procps_status_t* sp, int flags) FAST_FUNC; 2331procps_status_t* procps_scan(procps_status_t* sp, int flags) FAST_FUNC;
2153/* Format cmdline (up to col chars) into char buf[size] */ 2332/* Format cmdline (up to col chars) into char buf[size] */
2154/* Puts [comm] if cmdline is empty (-> process is a kernel thread) */ 2333/* Puts [comm] if cmdline is empty (-> process is a kernel thread) */
2155void read_cmdline(char *buf, int size, unsigned pid, const char *comm) FAST_FUNC; 2334int read_cmdline(char *buf, int size, unsigned pid, const char *comm) FAST_FUNC;
2156pid_t *find_pid_by_name(const char* procName) FAST_FUNC; 2335pid_t *find_pid_by_name(const char* procName) FAST_FUNC;
2157pid_t *pidlist_reverse(pid_t *pidList) FAST_FUNC; 2336pid_t *pidlist_reverse(pid_t *pidList) FAST_FUNC;
2158int starts_with_cpu(const char *str) FAST_FUNC; 2337int starts_with_cpu(const char *str) FAST_FUNC;
2159unsigned get_cpu_count(void) FAST_FUNC; 2338unsigned get_cpu_count(void) FAST_FUNC;
2339/* Some internals reused by pmap: */
2340unsigned long FAST_FUNC fast_strtoul_10(char **endptr);
2341unsigned long long FAST_FUNC fast_strtoull_16(char **endptr);
2342char* FAST_FUNC skip_fields(char *str, int count);
2160 2343
2161 2344
2162/* Use strict=1 if you process input from untrusted source: 2345/* Use strict=1 if you process input from untrusted source:
@@ -2182,6 +2365,56 @@ char *decode_base64(char *dst, const char **pp_src) FAST_FUNC;
2182char *decode_base32(char *dst, const char **pp_src) FAST_FUNC; 2365char *decode_base32(char *dst, const char **pp_src) FAST_FUNC;
2183void read_base64(FILE *src_stream, FILE *dst_stream, int flags) FAST_FUNC; 2366void read_base64(FILE *src_stream, FILE *dst_stream, int flags) FAST_FUNC;
2184 2367
2368int FAST_FUNC i2a64(int i);
2369int FAST_FUNC a2i64(char c);
2370char* FAST_FUNC num2str64_lsb_first(char *s, unsigned v, int n);
2371
2372enum {
2373 /* how many bytes XYZ_end() fills */
2374 MD5_OUTSIZE = 16,
2375 SHA1_OUTSIZE = 20,
2376 SHA256_OUTSIZE = 32,
2377 SHA384_OUTSIZE = 48,
2378 SHA512_OUTSIZE = 64,
2379 //SHA3-224_OUTSIZE = 28,
2380 /* size of input block */
2381 SHA2_INSIZE = 64,
2382};
2383
2384#if defined CONFIG_FEATURE_USE_CNG_API
2385struct bcrypt_hash_ctx_t {
2386 void *handle;
2387 void *hash_obj;
2388 unsigned int output_size;
2389};
2390typedef struct bcrypt_hash_ctx_t md5_ctx_t;
2391typedef struct bcrypt_hash_ctx_t sha1_ctx_t;
2392typedef struct bcrypt_hash_ctx_t sha256_ctx_t;
2393typedef struct bcrypt_hash_ctx_t sha384_ctx_t;
2394typedef struct bcrypt_hash_ctx_t sha512_ctx_t;
2395typedef struct sha3_ctx_t {
2396 uint64_t state[25];
2397 unsigned bytes_queued;
2398 unsigned input_block_bytes;
2399} sha3_ctx_t;
2400void md5_begin(struct bcrypt_hash_ctx_t *ctx) FAST_FUNC;
2401void sha1_begin(struct bcrypt_hash_ctx_t *ctx) FAST_FUNC;
2402void sha256_begin(struct bcrypt_hash_ctx_t *ctx) FAST_FUNC;
2403void sha384_begin(struct bcrypt_hash_ctx_t *ctx) FAST_FUNC;
2404void sha512_begin(struct bcrypt_hash_ctx_t *ctx) FAST_FUNC;
2405void generic_hash(struct bcrypt_hash_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
2406unsigned generic_end(struct bcrypt_hash_ctx_t *ctx, void *resbuf) FAST_FUNC;
2407# define md5_hash generic_hash
2408# define sha1_hash generic_hash
2409# define sha256_hash generic_hash
2410# define sha384_hash generic_hash
2411# define sha512_hash generic_hash
2412# define md5_end generic_end
2413# define sha1_end generic_end
2414# define sha256_end generic_end
2415# define sha384_end generic_end
2416# define sha512_end generic_end
2417#else
2185typedef struct md5_ctx_t { 2418typedef struct md5_ctx_t {
2186 uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ 2419 uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */
2187 void (*process_block)(struct md5_ctx_t*) FAST_FUNC; 2420 void (*process_block)(struct md5_ctx_t*) FAST_FUNC;
@@ -2195,6 +2428,7 @@ typedef struct sha512_ctx_t {
2195 uint64_t hash[8]; 2428 uint64_t hash[8];
2196 uint8_t wbuffer[128]; /* always correctly aligned for uint64_t */ 2429 uint8_t wbuffer[128]; /* always correctly aligned for uint64_t */
2197} sha512_ctx_t; 2430} sha512_ctx_t;
2431typedef struct sha512_ctx_t sha384_ctx_t;
2198typedef struct sha3_ctx_t { 2432typedef struct sha3_ctx_t {
2199 uint64_t state[25]; 2433 uint64_t state[25];
2200 unsigned bytes_queued; 2434 unsigned bytes_queued;
@@ -2212,20 +2446,69 @@ void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
2212void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; 2446void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
2213void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; 2447void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
2214unsigned sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; 2448unsigned sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
2449void sha384_begin(sha384_ctx_t *ctx) FAST_FUNC;
2450#define sha384_hash sha512_hash
2451unsigned sha384_end(sha384_ctx_t *ctx, void *resbuf) FAST_FUNC;
2452#endif
2215void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC; 2453void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC;
2216void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; 2454void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
2217unsigned sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC; 2455unsigned sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC;
2456void FAST_FUNC sha256_block(const void *in, size_t len, uint8_t hash[32]);
2218/* TLS benefits from knowing that sha1 and sha256 share these. Give them "agnostic" names too */ 2457/* TLS benefits from knowing that sha1 and sha256 share these. Give them "agnostic" names too */
2458#if defined CONFIG_FEATURE_USE_CNG_API
2459typedef struct bcrypt_hash_ctx_t md5sha_ctx_t;
2460#define md5sha_hash generic_hash
2461#define sha_end generic_end
2462#else
2219typedef struct md5_ctx_t md5sha_ctx_t; 2463typedef struct md5_ctx_t md5sha_ctx_t;
2220#define md5sha_hash md5_hash 2464#define md5sha_hash md5_hash
2221#define sha_end sha1_end 2465#define sha_end sha1_end
2222enum { 2466#endif
2223 MD5_OUTSIZE = 16, 2467
2224 SHA1_OUTSIZE = 20, 2468/* RFC 2104 HMAC (hash-based message authentication code) */
2225 SHA256_OUTSIZE = 32, 2469#if !ENABLE_FEATURE_USE_CNG_API
2226 SHA512_OUTSIZE = 64, 2470typedef struct hmac_ctx {
2227 SHA3_OUTSIZE = 28, 2471 md5sha_ctx_t hashed_key_xor_ipad;
2228}; 2472 md5sha_ctx_t hashed_key_xor_opad;
2473} hmac_ctx_t;
2474#else
2475typedef struct bcrypt_hash_ctx_t hmac_ctx_t;
2476#endif
2477#define HMAC_ONLY_SHA256 (!ENABLE_FEATURE_TLS_SHA1)
2478typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC;
2479#if !ENABLE_FEATURE_USE_CNG_API
2480#if HMAC_ONLY_SHA256
2481#define hmac_begin(ctx,key,key_size,begin) \
2482 hmac_begin(ctx,key,key_size)
2483#endif
2484void FAST_FUNC hmac_begin(hmac_ctx_t *ctx, const uint8_t *key, unsigned key_size, md5sha_begin_func *begin);
2485static ALWAYS_INLINE void hmac_hash(hmac_ctx_t *ctx, const void *in, size_t len)
2486{
2487 md5sha_hash(&ctx->hashed_key_xor_ipad, in, len);
2488}
2489#else
2490# if HMAC_ONLY_SHA256
2491# define hmac_begin(pre,key,key_size,begin) \
2492 _hmac_begin(pre, key, key_size, sha256_begin_hmac)
2493# else
2494# define hmac_begin _hmac_begin
2495# endif
2496void _hmac_begin(hmac_ctx_t *pre, uint8_t *key, unsigned key_size,
2497 BCRYPT_ALG_HANDLE alg_handle);
2498void hmac_uninit(hmac_ctx_t *pre);
2499#endif
2500unsigned FAST_FUNC hmac_end(hmac_ctx_t *ctx, uint8_t *out);
2501#if HMAC_ONLY_SHA256
2502#define hmac_block(key,key_size,begin,in,sz,out) \
2503 hmac_block(key,key_size,in,sz,out)
2504#endif
2505unsigned FAST_FUNC hmac_block(const uint8_t *key, unsigned key_size,
2506 md5sha_begin_func *begin,
2507 const void *in, unsigned sz,
2508 uint8_t *out);
2509/* HMAC helpers for TLS: */
2510void FAST_FUNC hmac_hash_v(hmac_ctx_t *ctx, va_list va);
2511unsigned hmac_peek_hash(hmac_ctx_t *ctx, uint8_t *out, ...);
2229 2512
2230extern uint32_t *global_crc32_table; 2513extern uint32_t *global_crc32_table;
2231uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; 2514uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;
@@ -2309,11 +2592,18 @@ extern const char bb_path_wtmp_file[] ALIGN1;
2309#define bb_path_motd_file "/etc/motd" 2592#define bb_path_motd_file "/etc/motd"
2310 2593
2311#define bb_dev_null "/dev/null" 2594#define bb_dev_null "/dev/null"
2595#if ENABLE_PLATFORM_MINGW32
2596#define bb_busybox_exec_path get_busybox_exec_path()
2597extern char bb_comm[];
2598extern char bb_command_line[];
2599#else
2312extern const char bb_busybox_exec_path[] ALIGN1; 2600extern const char bb_busybox_exec_path[] ALIGN1;
2601#endif
2313/* allow default system PATH to be extended via CFLAGS */ 2602/* allow default system PATH to be extended via CFLAGS */
2314#ifndef BB_ADDITIONAL_PATH 2603#ifndef BB_ADDITIONAL_PATH
2315#define BB_ADDITIONAL_PATH "" 2604#define BB_ADDITIONAL_PATH ""
2316#endif 2605#endif
2606#if !ENABLE_PLATFORM_MINGW32
2317#define BB_PATH_ROOT_PATH "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH 2607#define BB_PATH_ROOT_PATH "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH
2318extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */ 2608extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */
2319#define bb_default_root_path (bb_PATH_root_path + sizeof("PATH")) 2609#define bb_default_root_path (bb_PATH_root_path + sizeof("PATH"))
@@ -2321,6 +2611,23 @@ extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */
2321 * but I want to save a few bytes here: 2611 * but I want to save a few bytes here:
2322 */ 2612 */
2323#define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin")) 2613#define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin"))
2614#define PATH_SEP ':'
2615#define PATH_SEP_STR ":"
2616#else
2617#define BB_PATH_ROOT_PATH "PATH=C:/Windows/System32;C:/Windows" BB_ADDITIONAL_PATH
2618extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */
2619#define bb_default_root_path (bb_PATH_root_path + sizeof("PATH"))
2620#define bb_default_path (bb_PATH_root_path + sizeof("PATH"))
2621#define PATH_SEP ';'
2622#define PATH_SEP_STR ";"
2623extern const char bbvar[] ALIGN1;
2624#define bbafter(p) (p + sizeof(#p))
2625#define BB_OVERRIDE_APPLETS bbvar
2626#define BB_SKIP_ANSI_EMULATION bbafter(BB_OVERRIDE_APPLETS)
2627#define BB_TERMINAL_MODE bbafter(BB_SKIP_ANSI_EMULATION)
2628#define BB_SYSTEMROOT bbafter(BB_TERMINAL_MODE)
2629#define BB_CRITICAL_ERROR_DIALOGS bbafter(BB_SYSTEMROOT)
2630#endif
2324 2631
2325extern const int const_int_0; 2632extern const int const_int_0;
2326//extern const int const_int_1; 2633//extern const int const_int_1;
@@ -2337,26 +2644,10 @@ extern struct globals *BB_GLOBAL_CONST ptr_to_globals;
2337#define barrier() asm volatile ("":::"memory") 2644#define barrier() asm volatile ("":::"memory")
2338 2645
2339#if defined(__clang_major__) && __clang_major__ >= 9 2646#if defined(__clang_major__) && __clang_major__ >= 9
2340/* Clang/llvm drops assignment to "constant" storage. Silently. 2647/* {ASSIGN,XZALLOC}_CONST_PTR() are out-of-line functions
2341 * Needs serious convincing to not eliminate the store. 2648 * to prevent clang from reading pointer before it is assigned.
2342 */
2343static ALWAYS_INLINE void* not_const_pp(const void *p)
2344{
2345 void *pp;
2346 asm volatile (
2347 "# forget that p points to const"
2348 : /*outputs*/ "=r" (pp)
2349 : /*inputs*/ "0" (p)
2350 );
2351 return pp;
2352}
2353# define ASSIGN_CONST_PTR(pptr, v) do { \
2354 *(void**)not_const_pp(pptr) = (void*)(v); \
2355 barrier(); \
2356} while (0)
2357/* XZALLOC_CONST_PTR() is an out-of-line function to prevent
2358 * clang from reading pointer before it is assigned.
2359 */ 2649 */
2650void ASSIGN_CONST_PTR(const void *pptr, void *v) FAST_FUNC;
2360void XZALLOC_CONST_PTR(const void *pptr, size_t size) FAST_FUNC; 2651void XZALLOC_CONST_PTR(const void *pptr, size_t size) FAST_FUNC;
2361#else 2652#else
2362# define ASSIGN_CONST_PTR(pptr, v) do { \ 2653# define ASSIGN_CONST_PTR(pptr, v) do { \
diff --git a/include/mingw.h b/include/mingw.h
new file mode 100644
index 000000000..276e40659
--- /dev/null
+++ b/include/mingw.h
@@ -0,0 +1,674 @@
1
2#define NOIMPL(name,...) static inline int name(__VA_ARGS__) { errno = ENOSYS; return -1; }
3#define IMPL(name,ret,retval,...) static inline ret name(__VA_ARGS__) { return retval; }
4
5/* Use 64-bit time on 32-bit platforms. */
6#if !defined(_WIN64)
7# define time_t __time64_t
8# define ctime(t) _ctime64(t)
9# define localtime(t) _localtime64(t)
10# define time(t) _time64(t)
11# define gmtime(t) _gmtime64(t)
12# define mktime(t) _mktime64(t)
13# define timespec _timespec64
14#endif
15
16/*
17 * sys/types.h
18 */
19typedef int gid_t;
20typedef int uid_t;
21
22#define DEFAULT_UID 4095
23#define DEFAULT_GID DEFAULT_UID
24
25/*
26 * arpa/inet.h
27 */
28static inline unsigned int git_ntohl(unsigned int x) { return (unsigned int)ntohl(x); }
29#define ntohl git_ntohl
30int inet_aton(const char *cp, struct in_addr *inp);
31int inet_pton(int af, const char *src, void *dst);
32
33/*
34 * fcntl.h
35 */
36#define F_DUPFD 0
37#define F_GETFD 1
38#define F_SETFD 2
39#define F_GETFL 3
40#define F_SETFL 3
41#define FD_CLOEXEC 0x1
42#define O_NONBLOCK 0
43#define O_NOFOLLOW 0
44#define O_NOCTTY 0
45#define O_DIRECT 0
46#define O_SPECIAL 0x800000
47
48#define AT_FDCWD -100
49#define AT_SYMLINK_NOFOLLOW 0x100
50
51/*
52 * grp.h
53 */
54
55struct group {
56 char *gr_name;
57 char *gr_passwd;
58 gid_t gr_gid;
59 char **gr_mem;
60};
61IMPL(getgrnam,struct group *,NULL,const char *name UNUSED_PARAM);
62struct group *getgrgid(gid_t gid);
63NOIMPL(initgroups,const char *group UNUSED_PARAM,gid_t gid UNUSED_PARAM);
64static inline void endgrent(void) {}
65int getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups);
66
67/*
68 * limits.h
69 */
70#define NAME_MAX 255
71#define MAXSYMLINKS 20
72
73#ifdef LONG_MAX
74# if LONG_MAX == 2147483647
75# define LONG_BIT 32
76# else
77/* Safe assumption. */
78# define LONG_BIT 64
79# endif
80#elif defined __LONG_MAX__
81# if __LONG_MAX__ == 2147483647
82# define LONG_BIT 32
83# else
84/* Safe assumption. */
85# define LONG_BIT 64
86# endif
87#endif
88
89/*
90 * netdb.h
91 */
92
93typedef int sa_family_t;
94
95/*
96 * linux/un.h
97 */
98struct sockaddr_un {
99 sa_family_t sun_family;
100 char sun_path[1]; /* to make compiler happy, don't bother */
101};
102
103/*
104 * pwd.h
105 */
106struct passwd {
107 char *pw_name;
108 char *pw_passwd;
109 char *pw_gecos;
110 char *pw_dir;
111 char *pw_shell;
112 uid_t pw_uid;
113 gid_t pw_gid;
114};
115
116struct passwd *getpwnam(const char *name);
117struct passwd *getpwuid(uid_t uid);
118static inline void setpwent(void) {}
119static inline void endpwent(void) {}
120IMPL(getpwent_r,int,ENOENT,struct passwd *pwbuf UNUSED_PARAM,char *buf UNUSED_PARAM,size_t buflen UNUSED_PARAM,struct passwd **pwbufp UNUSED_PARAM);
121IMPL(getpwent,struct passwd *,NULL,void)
122
123/*
124 * signal.h
125 */
126#define SIGHUP 1
127#define SIGQUIT 3
128#define SIGKILL 9
129#define SIGPIPE 13
130
131#define SIG_UNBLOCK 1
132
133typedef void (*sighandler_t)(int);
134sighandler_t winansi_signal(int signum, sighandler_t handler);
135#define signal(s, h) winansi_signal(s, h)
136
137/*
138 * stdio.h
139 */
140#undef fseeko
141#define fseeko(f,o,w) fseek(f,o,w)
142
143int fdprintf(int fd, const char *format, ...);
144FILE* mingw_fopen(const char *filename, const char *mode);
145int mingw_rename(const char*, const char*);
146#define fopen mingw_fopen
147#define rename mingw_rename
148
149FILE *mingw_popen(const char *cmd, const char *mode);
150int mingw_popen_fd(const char *exe, const char *cmd, const char *mode,
151 int fd0, pid_t *pid);
152int mingw_pclose(FILE *fd);
153pid_t mingw_fork_compressor(int fd, const char *compressor, const char *mode);
154#undef popen
155#undef pclose
156#define popen mingw_popen
157#define pclose mingw_pclose
158
159IMPL(setlinebuf, void, ,FILE *fd UNUSED_PARAM)
160
161/*
162 * ANSI emulation wrappers
163 */
164
165BOOL conToCharBuffA(LPSTR d, DWORD len);
166BOOL conToCharA(LPSTR d);
167
168// same as ReadConsoleInputA, but delivers UTF8 regardless of console CP
169BOOL readConsoleInput_utf8(HANDLE h, INPUT_RECORD *r, DWORD len, DWORD *got);
170
171void set_title(const char *str);
172int get_title(char *buf, int len);
173void move_cursor_row(int n);
174void reset_screen(void);
175int winansi_putchar(int c);
176int winansi_puts(const char *s);
177size_t winansi_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
178int winansi_fputs(const char *str, FILE *stream);
179int winansi_fputc(int c, FILE *stream);
180int winansi_vsnprintf(char *buf, size_t size, const char *format, va_list list);
181int winansi_vfprintf(FILE *stream, const char *format, va_list list);
182int winansi_printf(const char *format, ...) __attribute__((format (printf, 1, 2)));
183int winansi_fprintf(FILE *stream, const char *format, ...) __attribute__((format (printf, 2, 3)));
184int winansi_write(int fd, const void *buf, size_t count);
185int winansi_read(int fd, void *buf, size_t count);
186size_t winansi_fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
187int winansi_getc(FILE *stream);
188int winansi_getchar(void);
189char *winansi_fgets(char *s, int size, FILE *stream);
190void console_write(const char *str, int len);
191
192#define putchar winansi_putchar
193#define puts winansi_puts
194#define fwrite winansi_fwrite
195#define fputs winansi_fputs
196#define fputc winansi_fputc
197#if !defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO
198#define vsnprintf(buf, size, ...) winansi_vsnprintf(buf, size, __VA_ARGS__)
199#endif
200#define vfprintf(stream, ...) winansi_vfprintf(stream, __VA_ARGS__)
201#define vprintf(...) winansi_vfprintf(stdout, __VA_ARGS__)
202#define printf(...) winansi_printf(__VA_ARGS__)
203#define fprintf(...) winansi_fprintf(__VA_ARGS__)
204#define write winansi_write
205#define read winansi_read
206#define fread winansi_fread
207#define getc winansi_getc
208#define fgetc winansi_getc
209#define getchar winansi_getchar
210#define fgets winansi_fgets
211
212/*
213 * stdlib.h
214 */
215#define WTERMSIG(x) ((x) & 0x7f)
216#define WIFEXITED(x) (WTERMSIG(x) == 0)
217#define WEXITSTATUS(x) (((x) & 0xff00) >> 8)
218#define WIFSIGNALED(x) (((signed char) (((x) & 0x7f) + 1) >> 1) > 0)
219#define WCOREDUMP(x) 0
220#define WIFSTOPPED(x) 0
221
222int mingw_system(const char *cmd);
223#define system mingw_system
224
225int clearenv(void);
226char *mingw_getenv(const char *name);
227int mingw_putenv(const char *env);
228char *mingw_mktemp(char *template);
229int mkstemp(char *template);
230char *realpath(const char *path, char *resolved_path);
231int setenv(const char *name, const char *value, int replace);
232int unsetenv(const char *env);
233
234#define getenv mingw_getenv
235#define putenv mingw_putenv
236#define mktemp mingw_mktemp
237
238/*
239 * string.h
240 */
241char *strndup(char const *s, size_t n);
242char *mingw_strerror(int errnum);
243char *strsignal(int sig);
244int strverscmp(const char *s1, const char *s2);
245
246#define strerror mingw_strerror
247
248/*
249 * strings.h
250 */
251#if !defined(__GNUC__)
252int ffs(int i);
253#else
254# define ffs(i) __builtin_ffs(i)
255#endif
256
257/*
258 * sys/ioctl.h
259 */
260
261#define TIOCGWINSZ 0x5413
262#define TIOCSWINSZ 0x5414
263
264int ioctl(int fd, int code, ...);
265
266/*
267 * sys/socket.h
268 */
269#define hstrerror strerror
270
271#define SHUT_WR SD_SEND
272
273int mingw_socket(int domain, int type, int protocol);
274int mingw_connect(int sockfd, const struct sockaddr *sa, size_t sz);
275int mingw_bind(int sockfd, struct sockaddr *sa, size_t sz);
276int mingw_setsockopt(int sockfd, int lvl, int optname, void *optval, int optlen);
277int mingw_shutdown(int sockfd, int how);
278int mingw_listen(int sockfd, int backlog);
279int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz);
280int mingw_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds,
281 struct timeval *timeout);
282int mingw_getpeername(int fd, struct sockaddr *sa, socklen_t *sz);
283int mingw_gethostname(char *host, int namelen);
284int mingw_getaddrinfo(const char *node, const char *service,
285 const struct addrinfo *hints, struct addrinfo **res);
286struct hostent *mingw_gethostbyaddr(const void *addr, socklen_t len, int type);
287
288#define socket mingw_socket
289#define connect mingw_connect
290#define listen mingw_listen
291#define bind mingw_bind
292#define setsockopt mingw_setsockopt
293#define shutdown mingw_shutdown
294#define accept mingw_accept
295#define select mingw_select
296#define getpeername mingw_getpeername
297#define gethostname mingw_gethostname
298#define getaddrinfo mingw_getaddrinfo
299#define gethostbyaddr mingw_gethostbyaddr
300
301/*
302 * sys/time.h
303 */
304#ifndef _TIMESPEC_DEFINED
305#define _TIMESPEC_DEFINED
306struct timespec {
307 time_t tv_sec;
308 long int tv_nsec;
309};
310#endif
311
312typedef int clockid_t;
313#define CLOCK_REALTIME 0
314
315time_t timegm(struct tm *tm);
316
317int nanosleep(const struct timespec *req, struct timespec *rem);
318int clock_gettime(clockid_t clockid, struct timespec *tp);
319int clock_settime(clockid_t clockid, const struct timespec *tp);
320
321/*
322 * sys/stat.h
323 */
324#define S_ISUID 04000
325#define S_ISGID 02000
326#define S_ISVTX 01000
327#ifndef S_IRWXU
328#define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
329#endif
330#define S_IRWXG (S_IRWXU >> 3)
331#define S_IRWXO (S_IRWXG >> 3)
332
333#define S_IFSOCK 0140000
334#define S_IFLNK 0120000 /* Symbolic link */
335#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
336#define S_ISSOCK(x) 0
337
338#define S_IRGRP (S_IRUSR >> 3)
339#define S_IWGRP (S_IWUSR >> 3)
340#define S_IXGRP (S_IXUSR >> 3)
341#define S_IROTH (S_IRGRP >> 3)
342#define S_IWOTH (S_IWGRP >> 3)
343#define S_IXOTH (S_IXGRP >> 3)
344
345mode_t mingw_umask(mode_t mode);
346#define umask mingw_umask
347
348#define DEFAULT_UMASK 0002
349
350IMPL(fchmod,int,0,int fildes UNUSED_PARAM, mode_t mode UNUSED_PARAM);
351NOIMPL(fchown,int fd UNUSED_PARAM, uid_t uid UNUSED_PARAM, gid_t gid UNUSED_PARAM);
352int mingw_mkdir(const char *path, int mode);
353int mingw_chdir(const char *path);
354int mingw_chmod(const char *path, int mode);
355
356#define mkdir mingw_mkdir
357#define chdir mingw_chdir
358#define chmod mingw_chmod
359
360#if ENABLE_LFS && !defined(__MINGW64_VERSION_MAJOR)
361# define off_t off64_t
362#endif
363
364typedef int nlink_t;
365typedef int blksize_t;
366typedef off_t blkcnt_t;
367#if ENABLE_FEATURE_EXTRA_FILE_DATA
368#define ino_t uint64_t
369#endif
370
371struct mingw_stat {
372 dev_t st_dev;
373 ino_t st_ino;
374 mode_t st_mode;
375 nlink_t st_nlink;
376 uid_t st_uid;
377 gid_t st_gid;
378 dev_t st_rdev;
379 off_t st_size;
380 struct timespec st_atim;
381 struct timespec st_mtim;
382 struct timespec st_ctim;
383 blksize_t st_blksize;
384 blkcnt_t st_blocks;
385 DWORD st_attr;
386 DWORD st_tag;
387};
388#define st_atime st_atim.tv_sec
389#define st_mtime st_mtim.tv_sec
390#define st_ctime st_ctim.tv_sec
391
392int count_subdirs(const char *pathname);
393int mingw_lstat(const char *file_name, struct mingw_stat *buf);
394int mingw_stat(const char *file_name, struct mingw_stat *buf);
395int mingw_fstat(int fd, struct mingw_stat *buf);
396#undef lstat
397#undef stat
398#undef fstat
399#define lstat mingw_lstat
400#define stat mingw_stat
401#define fstat mingw_fstat
402
403#define UTIME_NOW ((1l << 30) - 1l)
404#define UTIME_OMIT ((1l << 30) - 2l)
405
406int utimensat(int fd, const char *path, const struct timespec times[2],
407 int flags);
408int futimens(int fd, const struct timespec times[2]);
409
410/*
411 * sys/sysinfo.h
412 */
413struct sysinfo {
414 long uptime; /* Seconds since boot */
415 unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
416 unsigned long totalram; /* Total usable main memory size */
417 unsigned long freeram; /* Available memory size */
418 unsigned long sharedram; /* Amount of shared memory */
419 unsigned long bufferram; /* Memory used by buffers */
420 unsigned long totalswap; /* Total swap space size */
421 unsigned long freeswap; /* Swap space still available */
422 unsigned short procs; /* Number of current processes */
423 unsigned long totalhigh; /* Total high memory size */
424 unsigned long freehigh; /* Available high memory size */
425 unsigned int mem_unit; /* Memory unit size in bytes */
426};
427
428int sysinfo(struct sysinfo *info);
429
430/*
431 * sys/sysmacros.h
432 */
433#define makedev(a,b) 0*(a)*(b) /* avoid unused warning */
434#define minor(x) 0
435#define major(x) 0
436
437/*
438 * sys/wait.h
439 */
440#define WNOHANG 1
441#define WUNTRACED 2
442pid_t waitpid(pid_t pid, int *status, int options);
443pid_t mingw_wait3(pid_t pid, int *status, int options, struct rusage *rusage);
444
445/*
446 * time.h
447 */
448struct tm *gmtime_r(const time_t *timep, struct tm *result);
449struct tm *localtime_r(const time_t *timep, struct tm *result);
450char *strptime(const char *s, const char *format, struct tm *tm);
451char *mingw_strptime(const char *s, const char *format, struct tm *tm, long *gmt);
452size_t mingw_strftime(char *buf, size_t max, const char *format, const struct tm *tm);
453
454#define strftime mingw_strftime
455
456/*
457 * times.h
458 */
459#define clock_t long
460
461struct tms {
462 clock_t tms_utime; /* user CPU time */
463 clock_t tms_stime; /* system CPU time */
464 clock_t tms_cutime; /* user CPU time of children */
465 clock_t tms_cstime; /* system CPU time of children */
466};
467
468clock_t times(struct tms *buf);
469
470/*
471 * unistd.h
472 */
473#define PIPE_BUF 8192
474
475#define _SC_CLK_TCK 2
476
477#define TICKS_PER_SECOND 100
478#define MS_PER_TICK 10
479#define HNSEC_PER_TICK 100000
480
481IMPL(alarm,unsigned int,0,unsigned int seconds UNUSED_PARAM);
482IMPL(chown,int,0,const char *path UNUSED_PARAM, uid_t uid UNUSED_PARAM, gid_t gid UNUSED_PARAM);
483NOIMPL(chroot,const char *root UNUSED_PARAM);
484NOIMPL(fchdir,int fd UNUSED_PARAM);
485int mingw_dup2 (int fd, int fdto);
486char *mingw_getcwd(char *pointer, int len);
487off_t mingw_lseek(int fd, off_t offset, int whence);
488
489
490int getuid(void);
491#define getgid getuid
492#define geteuid getuid
493#define getegid getuid
494int getgroups(int n, gid_t *groups);
495pid_t getppid(void);
496NOIMPL(getsid,pid_t pid UNUSED_PARAM);
497int getlogin_r(char *buf, size_t len);
498int fcntl(int fd, int cmd, ...);
499int fsync(int fd);
500int kill(pid_t pid, int sig);
501int link(const char *oldpath, const char *newpath);
502NOIMPL(mknod,const char *name UNUSED_PARAM, mode_t mode UNUSED_PARAM, dev_t device UNUSED_PARAM);
503/* order of devices must match that in get_dev_type */
504enum {DEV_NULL, DEV_ZERO, DEV_URANDOM, NOT_DEVICE = -1};
505int get_dev_type(const char *filename);
506void update_special_fd(int dev, int fd);
507int mingw_open (const char *filename, int oflags, ...);
508
509/* functions which add O_SPECIAL to open(2) to allow access to devices */
510int mingw_xopen(const char *filename, int oflags);
511ssize_t mingw_open_read_close(const char *fn, void *buf, size_t size) FAST_FUNC;
512
513#ifndef IO_REPARSE_TAG_APPEXECLINK
514# define IO_REPARSE_TAG_APPEXECLINK 0x8000001b
515#endif
516
517ssize_t mingw_read(int fd, void *buf, size_t count);
518int mingw_close(int fd);
519int pipe(int filedes[2]);
520NOIMPL(setgid,gid_t gid UNUSED_PARAM);
521NOIMPL(setegid,gid_t gid UNUSED_PARAM);
522NOIMPL(setsid,void);
523NOIMPL(setuid,uid_t gid UNUSED_PARAM);
524NOIMPL(seteuid,uid_t gid UNUSED_PARAM);
525unsigned int sleep(unsigned int seconds);
526int symlink(const char *target, const char *linkpath);
527int create_junction(const char *oldpath, const char *newpath);
528long sysconf(int name);
529IMPL(getpagesize,int,4096,void);
530NOIMPL(ttyname_r,int fd UNUSED_PARAM, char *buf UNUSED_PARAM, int sz UNUSED_PARAM);
531int mingw_unlink(const char *pathname);
532int mingw_access(const char *name, int mode);
533int mingw_rmdir(const char *name);
534void mingw_sync(void);
535int mingw_isatty(int fd);
536
537#define dup2 mingw_dup2
538#define getcwd mingw_getcwd
539#define lchown chown
540#define open mingw_open
541#define close mingw_close
542#define unlink mingw_unlink
543#define rmdir mingw_rmdir
544#define sync mingw_sync
545#undef lseek
546#define lseek mingw_lseek
547
548#undef access
549#define access mingw_access
550#define isatty mingw_isatty
551
552/*
553 * utime.h
554 */
555int utimes(const char *file_name, const struct timeval times[2]);
556
557/*
558 * Functions with different prototypes in BusyBox and WIN32
559 */
560#define itoa bb_itoa
561#define strrev bb_strrev
562
563/*
564 * MinGW specific
565 */
566#define is_dir_sep(c) ((c) == '/' || (c) == '\\')
567#define is_unc_path(x) (strlen(x) > 4 && is_dir_sep(x[0]) && \
568 is_dir_sep(x[1]) && !is_dir_sep(x[2]))
569
570typedef struct {
571 char *path;
572 char *name;
573 char *opts;
574 char buf[100];
575} interp_t;
576
577int FAST_FUNC parse_interpreter(const char *cmd, interp_t *interp);
578char ** FAST_FUNC grow_argv(char **argv, int n);
579pid_t FAST_FUNC mingw_spawn(char **argv);
580intptr_t FAST_FUNC mingw_spawn_detach(char **argv);
581intptr_t FAST_FUNC mingw_spawn_proc(const char **argv);
582int mingw_execv(const char *cmd, char *const *argv);
583int httpd_execv_detach(const char *cmd, char *const *argv);
584int mingw_execvp(const char *cmd, char *const *argv);
585int mingw_execve(const char *cmd, char *const *argv, char *const *envp);
586#define spawn mingw_spawn
587#define execvp mingw_execvp
588#define execve mingw_execve
589#define execv mingw_execv
590#define HTTPD_DETACH (8)
591
592#define has_dos_drive_prefix(path) (isalpha(*(path)) && (path)[1] == ':')
593
594BOOL WINAPI kill_child_ctrl_handler(DWORD dwCtrlType);
595int FAST_FUNC is_valid_signal(int number);
596int exit_code_to_wait_status(DWORD win_exit_code);
597int exit_code_to_posix(DWORD win_exit_code);
598
599#define find_mount_point(n, s) find_mount_point(n)
600
601char *is_prefixed_with_case(const char *string, const char *key) FAST_FUNC;
602char *is_suffixed_with_case(const char *string, const char *key) FAST_FUNC;
603
604#define VT_OUTPUT 1
605#define VT_INPUT 2
606
607/*
608 * helpers
609 */
610
611const char *get_busybox_exec_path(void);
612void init_winsock(void);
613
614int has_bat_suffix(const char *p);
615int has_exe_suffix(const char *p);
616int has_exe_suffix_or_dot(const char *name);
617char *alloc_ext_space(const char *path);
618int add_win32_extension(char *p);
619char *file_is_win32_exe(const char *name);
620
621#if ENABLE_UNICODE_SUPPORT
622/*
623 * windows wchar_t is 16 bit, while linux (and busybox expectation) is 32.
624 * so when (busybox) unicode.h is included, wchar_t is 32 bit.
625 * Without unicode.h, MINGW_BB_WCHAR_T is busybox wide char (32),
626 * and wchar_t is Windows wide char (16).
627 */
628#define MINGW_BB_WCHAR_T uint32_t /* keep in sync with unicode.h */
629
630MINGW_BB_WCHAR_T *bs_to_slash_u(MINGW_BB_WCHAR_T *p) FAST_FUNC;
631#endif
632
633char *bs_to_slash(char *p) FAST_FUNC;
634void slash_to_bs(char *p) FAST_FUNC;
635void strip_dot_space(char *p) FAST_FUNC;
636size_t remove_cr(char *p, size_t len) FAST_FUNC;
637
638int err_win_to_posix(void);
639
640ULONGLONG CompatGetTickCount64(void);
641#define GetTickCount64 CompatGetTickCount64
642
643ssize_t get_random_bytes(void *buf, ssize_t count);
644int enumerate_links(const char *file, char *name);
645
646int unc_root_len(const char *dir) FAST_FUNC;
647int root_len(const char *path) FAST_FUNC;
648const char *get_system_drive(void) FAST_FUNC;
649int chdir_system_drive(void);
650char *xabsolute_path(char *path) FAST_FUNC;
651char *get_drive_cwd(const char *path, char *buffer, int size) FAST_FUNC;
652void fix_path_case(char *path) FAST_FUNC;
653void make_sparse(int fd, off_t start, off_t end) FAST_FUNC;
654int terminal_mode(int reset) FAST_FUNC;
655int unix_path(const char *path) FAST_FUNC;
656int has_path(const char *file) FAST_FUNC;
657int is_relative_path(const char *path) FAST_FUNC;
658char *get_last_slash(const char *path) FAST_FUNC;
659const char *applet_to_exe(const char *name) FAST_FUNC;
660char *get_user_name(void);
661char *quote_arg(const char *arg) FAST_FUNC;
662char *find_first_executable(const char *name) FAST_FUNC;
663char *xappendword(const char *str, const char *word) FAST_FUNC;
664int windows_env(void);
665void change_critical_error_dialogs(const char *newval) FAST_FUNC;
666char *exe_relative_path(const char *tail) FAST_FUNC;
667enum {
668 ELEVATED_PRIVILEGE = 1,
669 ADMIN_ENABLED = 2
670};
671int elevation_state(void);
672void set_interp(int i) FAST_FUNC;
673int mingw_shell_execute(SHELLEXECUTEINFO *info);
674void mingw_die_if_error(NTSTATUS status, const char *function_name);
diff --git a/include/platform.h b/include/platform.h
index ea0512f36..0b88f990b 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -7,6 +7,20 @@
7#ifndef BB_PLATFORM_H 7#ifndef BB_PLATFORM_H
8#define BB_PLATFORM_H 1 8#define BB_PLATFORM_H 1
9 9
10#if ENABLE_PLATFORM_MINGW32
11# if !defined(__MINGW32__) /* HOSTCC is called */
12# undef ENABLE_PLATFORM_MINGW32
13# else
14# undef __USE_MINGW_ANSI_STDIO
15# define __USE_MINGW_ANSI_STDIO 0
16# undef _WIN32_WINNT
17# define _WIN32_WINNT 0x502
18# endif
19#else
20# if defined(__MINGW32__)
21# error "You must select target platform MS Windows, or it won't build"
22# endif
23#endif
10 24
11/* Convenience macros to test the version of gcc. */ 25/* Convenience macros to test the version of gcc. */
12#undef __GNUC_PREREQ 26#undef __GNUC_PREREQ
@@ -135,7 +149,7 @@
135 149
136/* Make all declarations hidden (-fvisibility flag only affects definitions) */ 150/* Make all declarations hidden (-fvisibility flag only affects definitions) */
137/* (don't include system headers after this until corresponding pop!) */ 151/* (don't include system headers after this until corresponding pop!) */
138#if __GNUC_PREREQ(4,1) && !defined(__CYGWIN__) 152#if __GNUC_PREREQ(4,1) && !defined(__CYGWIN__) && !ENABLE_PLATFORM_MINGW32
139# define PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN _Pragma("GCC visibility push(hidden)") 153# define PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN _Pragma("GCC visibility push(hidden)")
140# define POP_SAVED_FUNCTION_VISIBILITY _Pragma("GCC visibility pop") 154# define POP_SAVED_FUNCTION_VISIBILITY _Pragma("GCC visibility pop")
141#else 155#else
@@ -164,6 +178,13 @@
164# define bswap_64 __bswap64 178# define bswap_64 __bswap64
165# define bswap_32 __bswap32 179# define bswap_32 __bswap32
166# define bswap_16 __bswap16 180# define bswap_16 __bswap16
181#elif ENABLE_PLATFORM_MINGW32
182# define __BIG_ENDIAN 0
183# define __LITTLE_ENDIAN 1
184# define __BYTE_ORDER __LITTLE_ENDIAN
185# define bswap_16(x) ((((x) & 0xFF00) >> 8) | (((x) & 0xFF) << 8))
186# define bswap_32(x) ((bswap_16(((x) & 0xFFFF0000L) >> 16)) | (bswap_16((x) & 0xFFFFL) << 16))
187# define bswap_64(x) ((bswap_32(((x) & 0xFFFFFFFF00000000LL) >> 32)) | (bswap_32((x) & 0xFFFFFFFFLL) << 32))
167#else 188#else
168# include <byteswap.h> 189# include <byteswap.h>
169# include <endian.h> 190# include <endian.h>
@@ -187,7 +208,7 @@
187#elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN 208#elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN
188# define BB_BIG_ENDIAN 0 209# define BB_BIG_ENDIAN 0
189# define BB_LITTLE_ENDIAN 1 210# define BB_LITTLE_ENDIAN 1
190#elif defined(__386__) 211#elif defined(__i386__)
191# define BB_BIG_ENDIAN 0 212# define BB_BIG_ENDIAN 0
192# define BB_LITTLE_ENDIAN 1 213# define BB_LITTLE_ENDIAN 1
193#else 214#else
@@ -443,6 +464,26 @@ typedef unsigned smalluint;
443# endif 464# endif
444#endif 465#endif
445 466
467#if ENABLE_PLATFORM_MINGW32
468# undef HAVE_FDATASYNC
469# undef HAVE_DPRINTF
470# undef HAVE_GETLINE
471# undef HAVE_MEMRCHR
472# undef HAVE_MKDTEMP
473# undef HAVE_SETBIT
474# undef HAVE_STPCPY
475# undef HAVE_STPNCPY
476# undef HAVE_STRCASESTR
477# undef HAVE_STRCHRNUL
478# undef HAVE_STRSEP
479#if !defined(__MINGW64_VERSION_MAJOR)
480# undef HAVE_VASPRINTF
481#endif
482# undef HAVE_UNLOCKED_STDIO
483# undef HAVE_UNLOCKED_LINE_OPS
484# undef HAVE_PRINTF_PERCENTM
485#endif
486
446#if defined(__WATCOMC__) 487#if defined(__WATCOMC__)
447# undef HAVE_DPRINTF 488# undef HAVE_DPRINTF
448# undef HAVE_GETLINE 489# undef HAVE_GETLINE
@@ -563,6 +604,7 @@ extern int dprintf(int fd, const char *format, ...);
563#endif 604#endif
564 605
565#ifndef HAVE_MEMRCHR 606#ifndef HAVE_MEMRCHR
607#include <stddef.h>
566extern void *memrchr(const void *s, int c, size_t n) FAST_FUNC; 608extern void *memrchr(const void *s, int c, size_t n) FAST_FUNC;
567#endif 609#endif
568 610
@@ -626,6 +668,7 @@ extern int usleep(unsigned) FAST_FUNC;
626#endif 668#endif
627 669
628#ifndef HAVE_VASPRINTF 670#ifndef HAVE_VASPRINTF
671# include <stdarg.h>
629extern int vasprintf(char **string_ptr, const char *format, va_list p) FAST_FUNC; 672extern int vasprintf(char **string_ptr, const char *format, va_list p) FAST_FUNC;
630#endif 673#endif
631 674
diff --git a/include/unicode.h b/include/unicode.h
index 0317a2151..cdf35acb7 100644
--- a/include/unicode.h
+++ b/include/unicode.h
@@ -33,7 +33,11 @@ enum {
33 33
34# if CONFIG_LAST_SUPPORTED_WCHAR < 126 || CONFIG_LAST_SUPPORTED_WCHAR >= 0x30000 34# if CONFIG_LAST_SUPPORTED_WCHAR < 126 || CONFIG_LAST_SUPPORTED_WCHAR >= 0x30000
35# undef CONFIG_LAST_SUPPORTED_WCHAR 35# undef CONFIG_LAST_SUPPORTED_WCHAR
36# if ENABLE_PLATFORM_MINGW32
37# define CONFIG_LAST_SUPPORTED_WCHAR 0x10ffff /* full unicode range */
38# else
36# define CONFIG_LAST_SUPPORTED_WCHAR 0x2ffff 39# define CONFIG_LAST_SUPPORTED_WCHAR 0x2ffff
40# endif
37# endif 41# endif
38 42
39# if CONFIG_LAST_SUPPORTED_WCHAR < 0x300 43# if CONFIG_LAST_SUPPORTED_WCHAR < 0x300
@@ -87,6 +91,21 @@ void reinit_unicode(const char *LANG) FAST_FUNC;
87# undef MB_CUR_MAX 91# undef MB_CUR_MAX
88# define MB_CUR_MAX 6 92# define MB_CUR_MAX 6
89 93
94#if ENABLE_PLATFORM_MINGW32
95 #undef wint_t
96 #undef mbstate_t
97 #undef mbstowcs
98 #undef wcstombs
99 #undef wcrtomb
100 #undef iswspace
101 #undef iswalnum
102 #undef iswpunct
103 #undef wcwidth
104
105 #undef wchar_t
106 #define wchar_t uint32_t /* keep in sync with MINGW_BB_WCHAR_T */
107#endif
108
90/* Prevent name collisions */ 109/* Prevent name collisions */
91# define wint_t bb_wint_t 110# define wint_t bb_wint_t
92# define mbstate_t bb_mbstate_t 111# define mbstate_t bb_mbstate_t
diff --git a/include/usage.src.h b/include/usage.src.h
index 5d2038834..0881337f8 100644
--- a/include/usage.src.h
+++ b/include/usage.src.h
@@ -17,11 +17,11 @@
17#define scripted_trivial_usage NOUSAGE_STR 17#define scripted_trivial_usage NOUSAGE_STR
18#define scripted_full_usage "" 18#define scripted_full_usage ""
19 19
20#if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA 20#if !ENABLE_USE_BB_CRYPT
21# define CRYPT_METHODS_HELP_STR "des,md5,sha256/512" \ 21# define CRYPT_METHODS_HELP_STR "des,md5,sha256/512,yescrypt" \
22 " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" 22 " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")"
23#else 23#else
24# define CRYPT_METHODS_HELP_STR "des,md5" \ 24# define CRYPT_METHODS_HELP_STR "des,md5"IF_USE_BB_CRYPT_SHA(",sha256/512")IF_USE_BB_CRYPT_YES(",yescrypt") \
25 " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" 25 " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")"
26#endif 26#endif
27 27