diff options
author | blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2013-06-21 16:54:37 +0000 |
---|---|---|
committer | blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2013-06-21 16:54:37 +0000 |
commit | 4d953d3a481dd847524eae78c7aae00153bc7efd (patch) | |
tree | 37c9cbe251e4fb790aaa72e862c35822be30b491 /package/utils/busybox/patches | |
parent | 801985e5286881dd578a19280b2a6c8e212a530d (diff) |
packages: clean up the package folder
Signed-off-by: John Crispin <blogic@openwrt.org>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@37007 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/utils/busybox/patches')
41 files changed, 3573 insertions, 0 deletions
diff --git a/package/utils/busybox/patches/001-init_avoid_loop_opening_tty.patch b/package/utils/busybox/patches/001-init_avoid_loop_opening_tty.patch new file mode 100644 index 0000000000..4db64c34be --- /dev/null +++ b/package/utils/busybox/patches/001-init_avoid_loop_opening_tty.patch @@ -0,0 +1,15 @@ +--- a/init/init.c ++++ b/init/init.c +@@ -573,8 +573,11 @@ static void run_actions(int action_type) + /* Only run stuff with pid == 0. If pid != 0, + * it is already running + */ +- if (a->pid == 0) ++ if (a->pid == 0) { ++ if (a->terminal[0] && access(a->terminal, R_OK | W_OK)) ++ continue; + a->pid = run(a); ++ } + } + } + } diff --git a/package/utils/busybox/patches/002-passwd_use_md5_hash_by_default_like_it_used_to_be.patch b/package/utils/busybox/patches/002-passwd_use_md5_hash_by_default_like_it_used_to_be.patch new file mode 100644 index 0000000000..ff79f3ee9c --- /dev/null +++ b/package/utils/busybox/patches/002-passwd_use_md5_hash_by_default_like_it_used_to_be.patch @@ -0,0 +1,20 @@ +From eb80c2a5315ed08bd329448217695375d89732c9 Mon Sep 17 00:00:00 2001 +From: Nicolas Thill <nico@openwrt.org> +Date: Wed, 9 Nov 2011 18:17:20 +0100 +Subject: [PATCH] passwd: use MD5 hash by default (like it used to be) + +--- + loginutils/passwd.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +--- a/loginutils/passwd.c ++++ b/loginutils/passwd.c +@@ -94,7 +94,7 @@ int passwd_main(int argc UNUSED_PARAM, c + }; + unsigned opt; + int rc; +- const char *opt_a = "d"; /* des */ ++ const char *opt_a = "m"; /* md5 */ + const char *filename; + char *myname; + char *name; diff --git a/package/utils/busybox/patches/003-brctl_show_fix.patch b/package/utils/busybox/patches/003-brctl_show_fix.patch new file mode 100644 index 0000000000..8177fb01c6 --- /dev/null +++ b/package/utils/busybox/patches/003-brctl_show_fix.patch @@ -0,0 +1,37 @@ +--- a/networking/brctl.c ++++ b/networking/brctl.c +@@ -129,7 +129,7 @@ int brctl_main(int argc UNUSED_PARAM, ch + "setageing\0" "setfd\0" "sethello\0" "setmaxage\0" + "setpathcost\0" "setportprio\0" "setbridgeprio\0" + ) +- IF_FEATURE_BRCTL_SHOW("showmacs\0" "show\0"); ++ IF_FEATURE_BRCTL_SHOW("show\0"); + + enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif + IF_FEATURE_BRCTL_FANCY(, +@@ -137,7 +137,7 @@ int brctl_main(int argc UNUSED_PARAM, ch + ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage, + ARG_setpathcost, ARG_setportprio, ARG_setbridgeprio + ) +- IF_FEATURE_BRCTL_SHOW(, ARG_showmacs, ARG_show) ++ IF_FEATURE_BRCTL_SHOW(, ARG_show) + }; + + int fd; +--- a/networking/Config.src ++++ b/networking/Config.src +@@ -82,12 +82,12 @@ config FEATURE_BRCTL_FANCY + This adds about 600 bytes. + + config FEATURE_BRCTL_SHOW +- bool "Support show, showmac and showstp" ++ bool "Support show" + default y + depends on BRCTL && FEATURE_BRCTL_FANCY + help + Add support for option which prints the current config: +- showmacs, showstp, show ++ show + + config DNSD + bool "dnsd" diff --git a/package/utils/busybox/patches/004-upstream-percent_decode_in_place.patch b/package/utils/busybox/patches/004-upstream-percent_decode_in_place.patch new file mode 100644 index 0000000000..d94ee47900 --- /dev/null +++ b/package/utils/busybox/patches/004-upstream-percent_decode_in_place.patch @@ -0,0 +1,237 @@ +http://git.busybox.net/busybox/commit/?id=dd1061b6a79b0161597799e825bfefc27993ace5 + +From dd1061b6a79b0161597799e825bfefc27993ace5 Mon Sep 17 00:00:00 2001 +From: Denys Vlasenko <vda.linux@googlemail.com> +Date: Sun, 11 Sep 2011 21:04:02 +0200 +Subject: [PATCH] wget: URL-decode user:password before base64-encoding it into auth hdr. Closes 3625. + +function old new delta +percent_decode_in_place - 152 +152 +parse_url 304 317 +13 +handle_incoming_and_exit 2795 2798 +3 +httpd_main 763 760 -3 +decodeString 152 - -152 +------------------------------------------------------------------------------ +(add/remove: 2/1 grow/shrink: 2/1 up/down: 168/-155) Total: 13 bytes + +Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> + +--- a/include/libbb.h ++++ b/include/libbb.h +@@ -1570,6 +1570,15 @@ int starts_with_cpu(const char *str) FAS + unsigned get_cpu_count(void) FAST_FUNC; + + ++/* Use strict=1 if you process input from untrusted source: ++ * it will return NULL on invalid %xx (bad hex chars) ++ * and str + 1 if decoded char is / or NUL. ++ * In non-strict mode, it always succeeds (returns str), ++ * and also it additionally decoded '+' to space. ++ */ ++char *percent_decode_in_place(char *str, int strict) FAST_FUNC; ++ ++ + extern const char bb_uuenc_tbl_base64[]; + extern const char bb_uuenc_tbl_std[]; + void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC; +--- /dev/null ++++ b/libbb/percent_decode.c +@@ -0,0 +1,69 @@ ++/* vi: set sw=4 ts=4: */ ++/* ++ * Licensed under GPLv2 or later, see file LICENSE in this source tree. ++ */ ++ ++//kbuild:lib-y += percent_decode.o ++ ++#include "libbb.h" ++ ++static unsigned hex_to_bin(unsigned char c) ++{ ++ unsigned v; ++ ++ v = c - '0'; ++ if (v <= 9) ++ return v; ++ /* c | 0x20: letters to lower case, non-letters ++ * to (potentially different) non-letters */ ++ v = (unsigned)(c | 0x20) - 'a'; ++ if (v <= 5) ++ return v + 10; ++ return ~0; ++/* For testing: ++void t(char c) { printf("'%c'(%u) %u\n", c, c, hex_to_bin(c)); } ++int main() { t(0x10); t(0x20); t('0'); t('9'); t('A'); t('F'); t('a'); t('f'); ++t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; } ++*/ ++} ++ ++char* FAST_FUNC percent_decode_in_place(char *str, int strict) ++{ ++ /* note that decoded string is always shorter than original */ ++ char *src = str; ++ char *dst = str; ++ char c; ++ ++ while ((c = *src++) != '\0') { ++ unsigned v; ++ ++ if (!strict && c == '+') { ++ *dst++ = ' '; ++ continue; ++ } ++ if (c != '%') { ++ *dst++ = c; ++ continue; ++ } ++ v = hex_to_bin(src[0]); ++ if (v > 15) { ++ bad_hex: ++ if (strict) ++ return NULL; ++ *dst++ = '%'; ++ continue; ++ } ++ v = (v * 16) | hex_to_bin(src[1]); ++ if (v > 255) ++ goto bad_hex; ++ if (strict && (v == '/' || v == '\0')) { ++ /* caller takes it as indication of invalid ++ * (dangerous wrt exploits) chars */ ++ return str + 1; ++ } ++ *dst++ = v; ++ src += 2; ++ } ++ *dst = '\0'; ++ return str; ++} +--- a/networking/httpd.c ++++ b/networking/httpd.c +@@ -820,78 +820,6 @@ static char *encodeString(const char *st + } + #endif + +-/* +- * Given a URL encoded string, convert it to plain ascii. +- * Since decoding always makes strings smaller, the decode is done in-place. +- * Thus, callers should xstrdup() the argument if they do not want the +- * argument modified. The return is the original pointer, allowing this +- * function to be easily used as arguments to other functions. +- * +- * string The first string to decode. +- * option_d 1 if called for httpd -d +- * +- * Returns a pointer to the decoded string (same as input). +- */ +-static unsigned hex_to_bin(unsigned char c) +-{ +- unsigned v; +- +- v = c - '0'; +- if (v <= 9) +- return v; +- /* c | 0x20: letters to lower case, non-letters +- * to (potentially different) non-letters */ +- v = (unsigned)(c | 0x20) - 'a'; +- if (v <= 5) +- return v + 10; +- return ~0; +-/* For testing: +-void t(char c) { printf("'%c'(%u) %u\n", c, c, hex_to_bin(c)); } +-int main() { t(0x10); t(0x20); t('0'); t('9'); t('A'); t('F'); t('a'); t('f'); +-t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; } +-*/ +-} +-static char *decodeString(char *orig, int option_d) +-{ +- /* note that decoded string is always shorter than original */ +- char *string = orig; +- char *ptr = string; +- char c; +- +- while ((c = *ptr++) != '\0') { +- unsigned v; +- +- if (option_d && c == '+') { +- *string++ = ' '; +- continue; +- } +- if (c != '%') { +- *string++ = c; +- continue; +- } +- v = hex_to_bin(ptr[0]); +- if (v > 15) { +- bad_hex: +- if (!option_d) +- return NULL; +- *string++ = '%'; +- continue; +- } +- v = (v * 16) | hex_to_bin(ptr[1]); +- if (v > 255) +- goto bad_hex; +- if (!option_d && (v == '/' || v == '\0')) { +- /* caller takes it as indication of invalid +- * (dangerous wrt exploits) chars */ +- return orig + 1; +- } +- *string++ = v; +- ptr += 2; +- } +- *string = '\0'; +- return orig; +-} +- + #if ENABLE_FEATURE_HTTPD_BASIC_AUTH + /* + * Decode a base64 data stream as per rfc1521. +@@ -1949,7 +1877,7 @@ static void handle_incoming_and_exit(con + } + + /* Decode URL escape sequences */ +- tptr = decodeString(urlcopy, 0); ++ tptr = percent_decode_in_place(urlcopy, /*strict:*/ 1); + if (tptr == NULL) + send_headers_and_exit(HTTP_BAD_REQUEST); + if (tptr == urlcopy + 1) { +@@ -2408,7 +2336,7 @@ int httpd_main(int argc UNUSED_PARAM, ch + , &verbose + ); + if (opt & OPT_DECODE_URL) { +- fputs(decodeString(url_for_decode, 1), stdout); ++ fputs(percent_decode_in_place(url_for_decode, /*strict:*/ 0), stdout); + return 0; + } + #if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR +--- a/networking/wget.c ++++ b/networking/wget.c +@@ -298,8 +298,13 @@ static void parse_url(const char *src_ur + + sp = strrchr(h->host, '@'); + if (sp != NULL) { +- h->user = h->host; ++ // URL-decode "user:password" string before base64-encoding: ++ // wget http://test:my%20pass@example.com should send ++ // Authorization: Basic dGVzdDpteSBwYXNz ++ // which decodes to "test:my pass". ++ // Standard wget and curl do this too. + *sp = '\0'; ++ h->user = percent_decode_in_place(h->host, /*strict:*/ 0); + h->host = sp + 1; + } + +@@ -661,12 +666,6 @@ static void download_one_url(const char + + #if ENABLE_FEATURE_WGET_AUTHENTICATION + if (target.user) { +-//TODO: URL-decode "user:password" string before base64-encoding: +-//wget http://test:my%20pass@example.com should send +-// Authorization: Basic dGVzdDpteSBwYXNz +-//which decodes to "test:my pass", instead of what we send now: +-// Authorization: Basic dGVzdDpteSUyMHBhc3M= +-//Can reuse decodeString() from httpd.c + fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6, + base64enc(target.user)); + } diff --git a/package/utils/busybox/patches/005-resource_h_include.patch b/package/utils/busybox/patches/005-resource_h_include.patch new file mode 100644 index 0000000000..d66d66d67e --- /dev/null +++ b/package/utils/busybox/patches/005-resource_h_include.patch @@ -0,0 +1,10 @@ +--- a/include/libbb.h ++++ b/include/libbb.h +@@ -35,6 +35,7 @@ + #include <sys/poll.h> + #include <sys/ioctl.h> + #include <sys/mman.h> ++#include <sys/resource.h> + #include <sys/socket.h> + #include <sys/stat.h> + #include <sys/time.h> diff --git a/package/utils/busybox/patches/006-upstream_CVE-2011-2716_fixes.patch b/package/utils/busybox/patches/006-upstream_CVE-2011-2716_fixes.patch new file mode 100644 index 0000000000..532fcee0fb --- /dev/null +++ b/package/utils/busybox/patches/006-upstream_CVE-2011-2716_fixes.patch @@ -0,0 +1,164 @@ +--- a/networking/udhcp/common.c ++++ b/networking/udhcp/common.c +@@ -29,16 +29,16 @@ const struct dhcp_optflag dhcp_optflags[ + // { OPTION_IP | OPTION_LIST , 0x07 }, /* DHCP_LOG_SERVER */ + // { OPTION_IP | OPTION_LIST , 0x08 }, /* DHCP_COOKIE_SERVER */ + { OPTION_IP | OPTION_LIST , 0x09 }, /* DHCP_LPR_SERVER */ +- { OPTION_STRING | OPTION_REQ, 0x0c }, /* DHCP_HOST_NAME */ ++ { OPTION_STRING_HOST | OPTION_REQ, 0x0c }, /* DHCP_HOST_NAME */ + { OPTION_U16 , 0x0d }, /* DHCP_BOOT_SIZE */ +- { OPTION_STRING | OPTION_REQ, 0x0f }, /* DHCP_DOMAIN_NAME */ ++ { OPTION_STRING_HOST | OPTION_REQ, 0x0f }, /* DHCP_DOMAIN_NAME */ + { OPTION_IP , 0x10 }, /* DHCP_SWAP_SERVER */ + { OPTION_STRING , 0x11 }, /* DHCP_ROOT_PATH */ + { OPTION_U8 , 0x17 }, /* DHCP_IP_TTL */ + { OPTION_U16 , 0x1a }, /* DHCP_MTU */ + { OPTION_IP | OPTION_REQ, 0x1c }, /* DHCP_BROADCAST */ + { OPTION_IP_PAIR | OPTION_LIST , 0x21 }, /* DHCP_ROUTES */ +- { OPTION_STRING , 0x28 }, /* DHCP_NIS_DOMAIN */ ++ { OPTION_STRING_HOST , 0x28 }, /* DHCP_NIS_DOMAIN */ + { OPTION_IP | OPTION_LIST , 0x29 }, /* DHCP_NIS_SERVER */ + { OPTION_IP | OPTION_LIST | OPTION_REQ, 0x2a }, /* DHCP_NTP_SERVER */ + { OPTION_IP | OPTION_LIST , 0x2c }, /* DHCP_WINS_SERVER */ +@@ -46,7 +46,7 @@ const struct dhcp_optflag dhcp_optflags[ + { OPTION_IP , 0x36 }, /* DHCP_SERVER_ID */ + { OPTION_STRING , 0x38 }, /* DHCP_ERR_MESSAGE */ + //TODO: must be combined with 'sname' and 'file' handling: +- { OPTION_STRING , 0x42 }, /* DHCP_TFTP_SERVER_NAME */ ++ { OPTION_STRING_HOST , 0x42 }, /* DHCP_TFTP_SERVER_NAME */ + { OPTION_STRING , 0x43 }, /* DHCP_BOOT_FILE */ + //TODO: not a string, but a set of LASCII strings: + // { OPTION_STRING , 0x4D }, /* DHCP_USER_CLASS */ +@@ -143,6 +143,7 @@ const uint8_t dhcp_option_lengths[] ALIG + [OPTION_IP_PAIR] = 8, + // [OPTION_BOOLEAN] = 1, + [OPTION_STRING] = 1, /* ignored by udhcp_str2optset */ ++ [OPTION_STRING_HOST] = 1, /* ignored by udhcp_str2optset */ + #if ENABLE_FEATURE_UDHCP_RFC3397 + [OPTION_DNS_STRING] = 1, /* ignored by both udhcp_str2optset and xmalloc_optname_optval */ + [OPTION_SIP_SERVERS] = 1, +@@ -411,7 +412,9 @@ static NOINLINE void attach_option( + /* actually 255 is ok too, but adding a space can overlow it */ + + existing->data = xrealloc(existing->data, OPT_DATA + 1 + old_len + length); +- if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING) { ++ if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING ++ || (optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING_HOST ++ ) { + /* add space separator between STRING options in a list */ + existing->data[OPT_DATA + old_len] = ' '; + old_len++; +@@ -475,6 +478,7 @@ int FAST_FUNC udhcp_str2optset(const cha + retval = udhcp_str2nip(val, buffer + 4); + break; + case OPTION_STRING: ++ case OPTION_STRING_HOST: + #if ENABLE_FEATURE_UDHCP_RFC3397 + case OPTION_DNS_STRING: + #endif +--- a/networking/udhcp/common.h ++++ b/networking/udhcp/common.h +@@ -80,6 +80,9 @@ enum { + OPTION_IP = 1, + OPTION_IP_PAIR, + OPTION_STRING, ++ /* Opts of STRING_HOST type will be sanitized before they are passed ++ * to udhcpc script's environment: */ ++ OPTION_STRING_HOST, + // OPTION_BOOLEAN, + OPTION_U8, + OPTION_U16, +--- a/networking/udhcp/dhcpc.c ++++ b/networking/udhcp/dhcpc.c +@@ -101,6 +101,7 @@ static const uint8_t len_of_option_as_st + [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2, + [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "), + [OPTION_STRING ] = 1, ++ [OPTION_STRING_HOST ] = 1, + #if ENABLE_FEATURE_UDHCP_RFC3397 + [OPTION_DNS_STRING ] = 1, /* unused */ + /* Hmmm, this severely overestimates size if SIP_SERVERS option +@@ -135,6 +136,63 @@ static int mton(uint32_t mask) + return i; + } + ++/* Check if a given label represents a valid DNS label ++ * Return pointer to the first character after the label upon success, ++ * NULL otherwise. ++ * See RFC1035, 2.3.1 ++ */ ++/* We don't need to be particularly anal. For example, allowing _, hyphen ++ * at the end, or leading and trailing dots would be ok, since it ++ * can't be used for attacks. (Leading hyphen can be, if someone uses ++ * cmd "$hostname" ++ * in the script: then hostname may be treated as an option) ++ */ ++static const char *valid_domain_label(const char *label) ++{ ++ unsigned char ch; ++ unsigned pos = 0; ++ ++ for (;;) { ++ ch = *label; ++ if ((ch|0x20) < 'a' || (ch|0x20) > 'z') { ++ if (pos == 0) { ++ /* label must begin with letter */ ++ return NULL; ++ } ++ if (ch < '0' || ch > '9') { ++ if (ch == '\0' || ch == '.') ++ return label; ++ /* DNS allows only '-', but we are more permissive */ ++ if (ch != '-' && ch != '_') ++ return NULL; ++ } ++ } ++ label++; ++ pos++; ++ //Do we want this? ++ //if (pos > 63) /* NS_MAXLABEL; labels must be 63 chars or less */ ++ // return NULL; ++ } ++} ++ ++/* Check if a given name represents a valid DNS name */ ++/* See RFC1035, 2.3.1 */ ++static int good_hostname(const char *name) ++{ ++ //const char *start = name; ++ ++ for (;;) { ++ name = valid_domain_label(name); ++ if (!name) ++ return 0; ++ if (!name[0]) ++ return 1; ++ //Do we want this? ++ //return ((name - start) < 1025); /* NS_MAXDNAME */ ++ name++; ++ } ++} ++ + /* Create "opt_name=opt_value" string */ + static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_optflag *optflag, const char *opt_name) + { +@@ -185,8 +243,11 @@ static NOINLINE char *xmalloc_optname_op + break; + } + case OPTION_STRING: ++ case OPTION_STRING_HOST: + memcpy(dest, option, len); + dest[len] = '\0'; ++ if (type == OPTION_STRING_HOST && !good_hostname(dest)) ++ safe_strncpy(dest, "bad", len); + return ret; /* Short circuit this case */ + case OPTION_STATIC_ROUTES: { + /* Option binary format: +@@ -314,6 +375,7 @@ static char **fill_envp(struct dhcp_pack + /* +1 element for each option, +2 for subnet option: */ + if (packet) { + /* note: do not search for "pad" (0) and "end" (255) options */ ++//TODO: change logic to scan packet _once_ + for (i = 1; i < 255; i++) { + temp = udhcp_get_option(packet, i); + if (temp) { diff --git a/package/utils/busybox/patches/007-upstream_mkfs_ext2_fixes.patch b/package/utils/busybox/patches/007-upstream_mkfs_ext2_fixes.patch new file mode 100644 index 0000000000..8528ee87f9 --- /dev/null +++ b/package/utils/busybox/patches/007-upstream_mkfs_ext2_fixes.patch @@ -0,0 +1,1441 @@ +--- a/e2fsprogs/e2fs_defs.h ++++ /dev/null +@@ -1,561 +0,0 @@ +-/* vi: set sw=4 ts=4: */ +-/* +- * linux/include/linux/ext2_fs.h +- * +- * Copyright (C) 1992, 1993, 1994, 1995 +- * Remy Card (card@masi.ibp.fr) +- * Laboratoire MASI - Institut Blaise Pascal +- * Universite Pierre et Marie Curie (Paris VI) +- * +- * Copyright (C) 1991, 1992 Linus Torvalds +- */ +- +-#ifndef LINUX_EXT2_FS_H +-#define LINUX_EXT2_FS_H 1 +- +-/* +- * Special inode numbers +- */ +-#define EXT2_BAD_INO 1 /* Bad blocks inode */ +-#define EXT2_ROOT_INO 2 /* Root inode */ +-#define EXT2_ACL_IDX_INO 3 /* ACL inode */ +-#define EXT2_ACL_DATA_INO 4 /* ACL inode */ +-#define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */ +-#define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */ +-#define EXT2_RESIZE_INO 7 /* Reserved group descriptors inode */ +-#define EXT2_JOURNAL_INO 8 /* Journal inode */ +- +-/* First non-reserved inode for old ext2 filesystems */ +-#define EXT2_GOOD_OLD_FIRST_INO 11 +- +-/* +- * The second extended file system magic number +- */ +-#define EXT2_SUPER_MAGIC 0xEF53 +- +-/* Assume that user mode programs are passing in an ext2fs superblock, not +- * a kernel struct super_block. This will allow us to call the feature-test +- * macros from user land. */ +-#define EXT2_SB(sb) (sb) +- +-/* +- * Maximal count of links to a file +- */ +-#define EXT2_LINK_MAX 32000 +- +-/* +- * Macro-instructions used to manage several block sizes +- */ +-#define EXT2_MIN_BLOCK_LOG_SIZE 10 /* 1024 */ +-#define EXT2_MAX_BLOCK_LOG_SIZE 16 /* 65536 */ +-#define EXT2_MIN_BLOCK_SIZE (1 << EXT2_MIN_BLOCK_LOG_SIZE) +-#define EXT2_MAX_BLOCK_SIZE (1 << EXT2_MAX_BLOCK_LOG_SIZE) +-#define EXT2_BLOCK_SIZE(s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size) +-#define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) +-#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \ +- EXT2_GOOD_OLD_INODE_SIZE : (s)->s_inode_size) +-#define EXT2_FIRST_INO(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \ +- EXT2_GOOD_OLD_FIRST_INO : (s)->s_first_ino) +-#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof(uint32_t)) +- +-/* +- * Macro-instructions used to manage fragments +- */ +-#define EXT2_MIN_FRAG_SIZE EXT2_MIN_BLOCK_SIZE +-#define EXT2_MAX_FRAG_SIZE EXT2_MAX_BLOCK_SIZE +-#define EXT2_MIN_FRAG_LOG_SIZE EXT2_MIN_BLOCK_LOG_SIZE +-#define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size) +-#define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s)) +- +-/* +- * ACL structures +- */ +-struct ext2_acl_header { /* Header of Access Control Lists */ +- uint32_t aclh_size; +- uint32_t aclh_file_count; +- uint32_t aclh_acle_count; +- uint32_t aclh_first_acle; +-}; +- +-struct ext2_acl_entry { /* Access Control List Entry */ +- uint32_t acle_size; +- uint16_t acle_perms; /* Access permissions */ +- uint16_t acle_type; /* Type of entry */ +- uint16_t acle_tag; /* User or group identity */ +- uint16_t acle_pad1; +- uint32_t acle_next; /* Pointer on next entry for the */ +- /* same inode or on next free entry */ +-}; +- +-/* +- * Structure of a blocks group descriptor +- */ +-struct ext2_group_desc { +- uint32_t bg_block_bitmap; /* Blocks bitmap block */ +- uint32_t bg_inode_bitmap; /* Inodes bitmap block */ +- uint32_t bg_inode_table; /* Inodes table block */ +- uint16_t bg_free_blocks_count; /* Free blocks count */ +- uint16_t bg_free_inodes_count; /* Free inodes count */ +- uint16_t bg_used_dirs_count; /* Directories count */ +- uint16_t bg_pad; +- uint32_t bg_reserved[3]; +-}; +- +-/* +- * Data structures used by the directory indexing feature +- * +- * Note: all of the multibyte integer fields are little endian. +- */ +- +-/* +- * Note: dx_root_info is laid out so that if it should somehow get +- * overlaid by a dirent the two low bits of the hash version will be +- * zero. Therefore, the hash version mod 4 should never be 0. +- * Sincerely, the paranoia department. +- */ +-struct ext2_dx_root_info { +- uint32_t reserved_zero; +- uint8_t hash_version; /* 0 now, 1 at release */ +- uint8_t info_length; /* 8 */ +- uint8_t indirect_levels; +- uint8_t unused_flags; +-}; +- +-#define EXT2_HASH_LEGACY 0 +-#define EXT2_HASH_HALF_MD4 1 +-#define EXT2_HASH_TEA 2 +- +-#define EXT2_HASH_FLAG_INCOMPAT 0x1 +- +-struct ext2_dx_entry { +- uint32_t hash; +- uint32_t block; +-}; +- +-struct ext2_dx_countlimit { +- uint16_t limit; +- uint16_t count; +-}; +- +- +-/* +- * Macro-instructions used to manage group descriptors +- */ +-#define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->s_blocks_per_group) +-#define EXT2_INODES_PER_GROUP(s) (EXT2_SB(s)->s_inodes_per_group) +-#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s)) +-/* limits imposed by 16-bit value gd_free_{blocks,inode}_count */ +-#define EXT2_MAX_BLOCKS_PER_GROUP(s) ((1 << 16) - 8) +-#define EXT2_MAX_INODES_PER_GROUP(s) ((1 << 16) - EXT2_INODES_PER_BLOCK(s)) +-#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc)) +- +-/* +- * Constants relative to the data blocks +- */ +-#define EXT2_NDIR_BLOCKS 12 +-#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS +-#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1) +-#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1) +-#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1) +- +-/* +- * Inode flags +- */ +-#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */ +-#define EXT2_UNRM_FL 0x00000002 /* Undelete */ +-#define EXT2_COMPR_FL 0x00000004 /* Compress file */ +-#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */ +-#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */ +-#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */ +-#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */ +-#define EXT2_NOATIME_FL 0x00000080 /* do not update atime */ +-/* Reserved for compression usage... */ +-#define EXT2_DIRTY_FL 0x00000100 +-#define EXT2_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */ +-#define EXT2_NOCOMPR_FL 0x00000400 /* Access raw compressed data */ +-#define EXT2_ECOMPR_FL 0x00000800 /* Compression error */ +-/* End compression flags --- maybe not all used */ +-#define EXT2_BTREE_FL 0x00001000 /* btree format dir */ +-#define EXT2_INDEX_FL 0x00001000 /* hash-indexed directory */ +-#define EXT2_IMAGIC_FL 0x00002000 +-#define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */ +-#define EXT2_NOTAIL_FL 0x00008000 /* file tail should not be merged */ +-#define EXT2_DIRSYNC_FL 0x00010000 /* Synchronous directory modifications */ +-#define EXT2_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ +-#define EXT3_EXTENTS_FL 0x00080000 /* Inode uses extents */ +-#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */ +- +-#define EXT2_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ +-#define EXT2_FL_USER_MODIFIABLE 0x000080FF /* User modifiable flags */ +- +-/* +- * ioctl commands +- */ +-#define EXT2_IOC_GETFLAGS _IOR('f', 1, long) +-#define EXT2_IOC_SETFLAGS _IOW('f', 2, long) +-#define EXT2_IOC_GETVERSION _IOR('v', 1, long) +-#define EXT2_IOC_SETVERSION _IOW('v', 2, long) +- +-/* +- * Structure of an inode on the disk +- */ +-struct ext2_inode { +- uint16_t i_mode; /* File mode */ +- uint16_t i_uid; /* Low 16 bits of Owner Uid */ +- uint32_t i_size; /* Size in bytes */ +- uint32_t i_atime; /* Access time */ +- uint32_t i_ctime; /* Creation time */ +- uint32_t i_mtime; /* Modification time */ +- uint32_t i_dtime; /* Deletion Time */ +- uint16_t i_gid; /* Low 16 bits of Group Id */ +- uint16_t i_links_count; /* Links count */ +- uint32_t i_blocks; /* Blocks count */ +- uint32_t i_flags; /* File flags */ +- union { +- struct { +- uint32_t l_i_reserved1; +- } linux1; +- struct { +- uint32_t h_i_translator; +- } hurd1; +- struct { +- uint32_t m_i_reserved1; +- } masix1; +- } osd1; /* OS dependent 1 */ +- uint32_t i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ +- uint32_t i_generation; /* File version (for NFS) */ +- uint32_t i_file_acl; /* File ACL */ +- uint32_t i_dir_acl; /* Directory ACL */ +- uint32_t i_faddr; /* Fragment address */ +- union { +- struct { +- uint8_t l_i_frag; /* Fragment number */ +- uint8_t l_i_fsize; /* Fragment size */ +- uint16_t i_pad1; +- uint16_t l_i_uid_high; /* these 2 fields */ +- uint16_t l_i_gid_high; /* were reserved2[0] */ +- uint32_t l_i_reserved2; +- } linux2; +- struct { +- uint8_t h_i_frag; /* Fragment number */ +- uint8_t h_i_fsize; /* Fragment size */ +- uint16_t h_i_mode_high; +- uint16_t h_i_uid_high; +- uint16_t h_i_gid_high; +- uint32_t h_i_author; +- } hurd2; +- struct { +- uint8_t m_i_frag; /* Fragment number */ +- uint8_t m_i_fsize; /* Fragment size */ +- uint16_t m_pad1; +- uint32_t m_i_reserved2[2]; +- } masix2; +- } osd2; /* OS dependent 2 */ +-}; +- +-/* +- * Permanent part of an large inode on the disk +- */ +-struct ext2_inode_large { +- uint16_t i_mode; /* File mode */ +- uint16_t i_uid; /* Low 16 bits of Owner Uid */ +- uint32_t i_size; /* Size in bytes */ +- uint32_t i_atime; /* Access time */ +- uint32_t i_ctime; /* Creation time */ +- uint32_t i_mtime; /* Modification time */ +- uint32_t i_dtime; /* Deletion Time */ +- uint16_t i_gid; /* Low 16 bits of Group Id */ +- uint16_t i_links_count; /* Links count */ +- uint32_t i_blocks; /* Blocks count */ +- uint32_t i_flags; /* File flags */ +- union { +- struct { +- uint32_t l_i_reserved1; +- } linux1; +- struct { +- uint32_t h_i_translator; +- } hurd1; +- struct { +- uint32_t m_i_reserved1; +- } masix1; +- } osd1; /* OS dependent 1 */ +- uint32_t i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ +- uint32_t i_generation; /* File version (for NFS) */ +- uint32_t i_file_acl; /* File ACL */ +- uint32_t i_dir_acl; /* Directory ACL */ +- uint32_t i_faddr; /* Fragment address */ +- union { +- struct { +- uint8_t l_i_frag; /* Fragment number */ +- uint8_t l_i_fsize; /* Fragment size */ +- uint16_t i_pad1; +- uint16_t l_i_uid_high; /* these 2 fields */ +- uint16_t l_i_gid_high; /* were reserved2[0] */ +- uint32_t l_i_reserved2; +- } linux2; +- struct { +- uint8_t h_i_frag; /* Fragment number */ +- uint8_t h_i_fsize; /* Fragment size */ +- uint16_t h_i_mode_high; +- uint16_t h_i_uid_high; +- uint16_t h_i_gid_high; +- uint32_t h_i_author; +- } hurd2; +- struct { +- uint8_t m_i_frag; /* Fragment number */ +- uint8_t m_i_fsize; /* Fragment size */ +- uint16_t m_pad1; +- uint32_t m_i_reserved2[2]; +- } masix2; +- } osd2; /* OS dependent 2 */ +- uint16_t i_extra_isize; +- uint16_t i_pad1; +-}; +- +-#define i_size_high i_dir_acl +- +-/* +- * File system states +- */ +-#define EXT2_VALID_FS 0x0001 /* Unmounted cleanly */ +-#define EXT2_ERROR_FS 0x0002 /* Errors detected */ +- +-/* +- * Mount flags +- */ +-#define EXT2_MOUNT_CHECK 0x0001 /* Do mount-time checks */ +-#define EXT2_MOUNT_GRPID 0x0004 /* Create files with directory's group */ +-#define EXT2_MOUNT_DEBUG 0x0008 /* Some debugging messages */ +-#define EXT2_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */ +-#define EXT2_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */ +-#define EXT2_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */ +-#define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */ +-#define EXT2_MOUNT_NO_UID32 0x0200 /* Disable 32-bit UIDs */ +- +-#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt +-#define set_opt(o, opt) o |= EXT2_MOUNT_##opt +-#define test_opt(sb, opt) (EXT2_SB(sb)->s_mount_opt & \ +- EXT2_MOUNT_##opt) +-/* +- * Maximal mount counts between two filesystem checks +- */ +-#define EXT2_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ +-#define EXT2_DFL_CHECKINTERVAL 0 /* Don't use interval check */ +- +-/* +- * Behaviour when detecting errors +- */ +-#define EXT2_ERRORS_CONTINUE 1 /* Continue execution */ +-#define EXT2_ERRORS_RO 2 /* Remount fs read-only */ +-#define EXT2_ERRORS_PANIC 3 /* Panic */ +-#define EXT2_ERRORS_DEFAULT EXT2_ERRORS_CONTINUE +- +-/* +- * Structure of the super block +- */ +-struct ext2_super_block { +- uint32_t s_inodes_count; /* Inodes count */ +- uint32_t s_blocks_count; /* Blocks count */ +- uint32_t s_r_blocks_count; /* Reserved blocks count */ +- uint32_t s_free_blocks_count; /* Free blocks count */ +- uint32_t s_free_inodes_count; /* Free inodes count */ +- uint32_t s_first_data_block; /* First Data Block */ +- uint32_t s_log_block_size; /* Block size */ +- int32_t s_log_frag_size; /* Fragment size */ +- uint32_t s_blocks_per_group; /* # Blocks per group */ +- uint32_t s_frags_per_group; /* # Fragments per group */ +- uint32_t s_inodes_per_group; /* # Inodes per group */ +- uint32_t s_mtime; /* Mount time */ +- uint32_t s_wtime; /* Write time */ +- uint16_t s_mnt_count; /* Mount count */ +- int16_t s_max_mnt_count; /* Maximal mount count */ +- uint16_t s_magic; /* Magic signature */ +- uint16_t s_state; /* File system state */ +- uint16_t s_errors; /* Behaviour when detecting errors */ +- uint16_t s_minor_rev_level; /* minor revision level */ +- uint32_t s_lastcheck; /* time of last check */ +- uint32_t s_checkinterval; /* max. time between checks */ +- uint32_t s_creator_os; /* OS */ +- uint32_t s_rev_level; /* Revision level */ +- uint16_t s_def_resuid; /* Default uid for reserved blocks */ +- uint16_t s_def_resgid; /* Default gid for reserved blocks */ +- /* +- * These fields are for EXT2_DYNAMIC_REV superblocks only. +- * +- * Note: the difference between the compatible feature set and +- * the incompatible feature set is that if there is a bit set +- * in the incompatible feature set that the kernel doesn't +- * know about, it should refuse to mount the filesystem. +- * +- * e2fsck's requirements are more strict; if it doesn't know +- * about a feature in either the compatible or incompatible +- * feature set, it must abort and not try to meddle with +- * things it doesn't understand... +- */ +- uint32_t s_first_ino; /* First non-reserved inode */ +- uint16_t s_inode_size; /* size of inode structure */ +- uint16_t s_block_group_nr; /* block group # of this superblock */ +- uint32_t s_feature_compat; /* compatible feature set */ +- uint32_t s_feature_incompat; /* incompatible feature set */ +- uint32_t s_feature_ro_compat; /* readonly-compatible feature set */ +- uint8_t s_uuid[16]; /* 128-bit uuid for volume */ +- char s_volume_name[16]; /* volume name */ +- char s_last_mounted[64]; /* directory where last mounted */ +- uint32_t s_algorithm_usage_bitmap; /* For compression */ +- /* +- * Performance hints. Directory preallocation should only +- * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on. +- */ +- uint8_t s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ +- uint8_t s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ +- uint16_t s_reserved_gdt_blocks; /* Per group table for online growth */ +- /* +- * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set. +- */ +- uint8_t s_journal_uuid[16]; /* uuid of journal superblock */ +- uint32_t s_journal_inum; /* inode number of journal file */ +- uint32_t s_journal_dev; /* device number of journal file */ +- uint32_t s_last_orphan; /* start of list of inodes to delete */ +- uint32_t s_hash_seed[4]; /* HTREE hash seed */ +- uint8_t s_def_hash_version; /* Default hash version to use */ +- uint8_t s_jnl_backup_type; /* Default type of journal backup */ +- uint16_t s_reserved_word_pad; +- uint32_t s_default_mount_opts; +- uint32_t s_first_meta_bg; /* First metablock group */ +- uint32_t s_mkfs_time; /* When the filesystem was created */ +- uint32_t s_jnl_blocks[17]; /* Backup of the journal inode */ +- uint32_t s_reserved[172]; /* Padding to the end of the block */ +-}; +- +-/* +- * Codes for operating systems +- */ +-#define EXT2_OS_LINUX 0 +-#define EXT2_OS_HURD 1 +-#define EXT2_OS_MASIX 2 +-#define EXT2_OS_FREEBSD 3 +-#define EXT2_OS_LITES 4 +- +-/* +- * Revision levels +- */ +-#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */ +-#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ +- +-#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV +-#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV +- +-#define EXT2_GOOD_OLD_INODE_SIZE 128 +- +-/* +- * Journal inode backup types +- */ +-#define EXT3_JNL_BACKUP_BLOCKS 1 +- +-/* +- * Feature set definitions +- */ +- +-#define EXT2_HAS_COMPAT_FEATURE(sb,mask) \ +- ( EXT2_SB(sb)->s_feature_compat & (mask) ) +-#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask) \ +- ( EXT2_SB(sb)->s_feature_ro_compat & (mask) ) +-#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \ +- ( EXT2_SB(sb)->s_feature_incompat & (mask) ) +- +-#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001 +-#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002 +-#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 +-#define EXT2_FEATURE_COMPAT_EXT_ATTR 0x0008 +-#define EXT2_FEATURE_COMPAT_RESIZE_INODE 0x0010 +-#define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020 +- +-#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 +-#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 +-/* #define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 not used */ +- +-#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001 +-#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 +-#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ +-#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ +-#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 +-#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 +- +- +-#define EXT2_FEATURE_COMPAT_SUPP 0 +-#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE) +-#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ +- EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ +- EXT2_FEATURE_RO_COMPAT_BTREE_DIR) +- +-/* +- * Default values for user and/or group using reserved blocks +- */ +-#define EXT2_DEF_RESUID 0 +-#define EXT2_DEF_RESGID 0 +- +-/* +- * Default mount options +- */ +-#define EXT2_DEFM_DEBUG 0x0001 +-#define EXT2_DEFM_BSDGROUPS 0x0002 +-#define EXT2_DEFM_XATTR_USER 0x0004 +-#define EXT2_DEFM_ACL 0x0008 +-#define EXT2_DEFM_UID16 0x0010 +-#define EXT3_DEFM_JMODE 0x0060 +-#define EXT3_DEFM_JMODE_DATA 0x0020 +-#define EXT3_DEFM_JMODE_ORDERED 0x0040 +-#define EXT3_DEFM_JMODE_WBACK 0x0060 +- +-/* +- * Structure of a directory entry +- */ +-#define EXT2_NAME_LEN 255 +- +-struct ext2_dir_entry { +- uint32_t inode; /* Inode number */ +- uint16_t rec_len; /* Directory entry length */ +- uint16_t name_len; /* Name length */ +- char name[EXT2_NAME_LEN]; /* File name */ +-}; +- +-/* +- * The new version of the directory entry. Since EXT2 structures are +- * stored in intel byte order, and the name_len field could never be +- * bigger than 255 chars, it's safe to reclaim the extra byte for the +- * file_type field. +- */ +-struct ext2_dir_entry_2 { +- uint32_t inode; /* Inode number */ +- uint16_t rec_len; /* Directory entry length */ +- uint8_t name_len; /* Name length */ +- uint8_t file_type; +- char name[EXT2_NAME_LEN]; /* File name */ +-}; +- +-/* +- * Ext2 directory file types. Only the low 3 bits are used. The +- * other bits are reserved for now. +- */ +-#define EXT2_FT_UNKNOWN 0 +-#define EXT2_FT_REG_FILE 1 +-#define EXT2_FT_DIR 2 +-#define EXT2_FT_CHRDEV 3 +-#define EXT2_FT_BLKDEV 4 +-#define EXT2_FT_FIFO 5 +-#define EXT2_FT_SOCK 6 +-#define EXT2_FT_SYMLINK 7 +- +-#define EXT2_FT_MAX 8 +- +-/* +- * EXT2_DIR_PAD defines the directory entries boundaries +- * +- * NOTE: It must be a multiple of 4 +- */ +-#define EXT2_DIR_PAD 4 +-#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1) +-#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \ +- ~EXT2_DIR_ROUND) +- +-#endif +--- a/e2fsprogs/e2fs_lib.h ++++ b/e2fsprogs/e2fs_lib.h +@@ -7,7 +7,7 @@ + */ + + /* Constants and structures */ +-#include "e2fs_defs.h" ++#include "bb_e2fs_defs.h" + + PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN + +--- a/e2fsprogs/old_e2fsprogs/e2fsck.c ++++ b/e2fsprogs/old_e2fsprogs/e2fsck.c +@@ -11577,7 +11577,7 @@ static void check_resize_inode(e2fsck_t + * s_reserved_gdt_blocks must be zero. + */ + if (!(fs->super->s_feature_compat & +- EXT2_FEATURE_COMPAT_RESIZE_INODE)) { ++ EXT2_FEATURE_COMPAT_RESIZE_INO)) { + if (fs->super->s_reserved_gdt_blocks) { + pctx.num = fs->super->s_reserved_gdt_blocks; + if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS, +@@ -11593,7 +11593,7 @@ static void check_resize_inode(e2fsck_t + retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode); + if (retval) { + if (fs->super->s_feature_compat & +- EXT2_FEATURE_COMPAT_RESIZE_INODE) ++ EXT2_FEATURE_COMPAT_RESIZE_INO) + ctx->flags |= E2F_FLAG_RESIZE_INODE; + return; + } +@@ -11603,7 +11603,7 @@ static void check_resize_inode(e2fsck_t + * the resize inode is cleared; then we're done. + */ + if (!(fs->super->s_feature_compat & +- EXT2_FEATURE_COMPAT_RESIZE_INODE)) { ++ EXT2_FEATURE_COMPAT_RESIZE_INO)) { + for (i=0; i < EXT2_N_BLOCKS; i++) { + if (inode.i_block[i]) + break; +--- a/e2fsprogs/old_e2fsprogs/e2p/feature.c ++++ b/e2fsprogs/old_e2fsprogs/e2p/feature.c +@@ -34,7 +34,7 @@ static const struct feature feature_list + "ext_attr" }, + { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_INDEX, + "dir_index" }, +- { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_RESIZE_INODE, ++ { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_RESIZE_INO, + "resize_inode" }, + { E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER, + "sparse_super" }, +--- a/e2fsprogs/old_e2fsprogs/ext2fs/ext2_fs.h ++++ b/e2fsprogs/old_e2fsprogs/ext2fs/ext2_fs.h +@@ -475,7 +475,7 @@ struct ext2_super_block { + #define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002 + #define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 + #define EXT2_FEATURE_COMPAT_EXT_ATTR 0x0008 +-#define EXT2_FEATURE_COMPAT_RESIZE_INODE 0x0010 ++#define EXT2_FEATURE_COMPAT_RESIZE_INO 0x0010 + #define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020 + + #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 +--- a/e2fsprogs/old_e2fsprogs/ext2fs/ext2fs.h ++++ b/e2fsprogs/old_e2fsprogs/ext2fs/ext2fs.h +@@ -383,7 +383,7 @@ typedef struct ext2_icount *ext2_icount_ + #define EXT2_LIB_FEATURE_COMPAT_SUPP (EXT2_FEATURE_COMPAT_DIR_PREALLOC|\ + EXT2_FEATURE_COMPAT_IMAGIC_INODES|\ + EXT3_FEATURE_COMPAT_HAS_JOURNAL|\ +- EXT2_FEATURE_COMPAT_RESIZE_INODE|\ ++ EXT2_FEATURE_COMPAT_RESIZE_INO|\ + EXT2_FEATURE_COMPAT_DIR_INDEX|\ + EXT2_FEATURE_COMPAT_EXT_ATTR) + +--- a/e2fsprogs/old_e2fsprogs/ext2fs/initialize.c ++++ b/e2fsprogs/old_e2fsprogs/ext2fs/initialize.c +@@ -284,7 +284,7 @@ retry: + /* + * check the number of reserved group descriptor table blocks + */ +- if (super->s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INODE) ++ if (super->s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INO) + rsv_gdt = calc_reserved_gdt_blocks(fs); + else + rsv_gdt = 0; +--- a/e2fsprogs/old_e2fsprogs/mke2fs.c ++++ b/e2fsprogs/old_e2fsprogs/mke2fs.c +@@ -757,7 +757,7 @@ static void parse_extended_opts(struct e + + if (rsv_gdb > 0) { + sb_param->s_feature_compat |= +- EXT2_FEATURE_COMPAT_RESIZE_INODE; ++ EXT2_FEATURE_COMPAT_RESIZE_INO; + + sb_param->s_reserved_gdt_blocks = rsv_gdb; + } +@@ -778,7 +778,7 @@ static void parse_extended_opts(struct e + + static __u32 ok_features[3] = { + EXT3_FEATURE_COMPAT_HAS_JOURNAL | +- EXT2_FEATURE_COMPAT_RESIZE_INODE | ++ EXT2_FEATURE_COMPAT_RESIZE_INO | + EXT2_FEATURE_COMPAT_DIR_INDEX, /* Compat */ + EXT2_FEATURE_INCOMPAT_FILETYPE| /* Incompat */ + EXT3_FEATURE_INCOMPAT_JOURNAL_DEV| +@@ -1123,7 +1123,7 @@ static int PRS(int argc, char **argv) + /* Since sparse_super is the default, we would only have a problem + * here if it was explicitly disabled. + */ +- if ((param.s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INODE) && ++ if ((param.s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INO) && + !(param.s_feature_ro_compat&EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) { + bb_error_msg_and_die("reserved online resize blocks not supported " + "on non-sparse filesystem"); +@@ -1312,7 +1312,7 @@ int mke2fs_main (int argc, char **argv) + reserve_inodes(fs); + create_bad_block_inode(fs, bb_list); + if (fs->super->s_feature_compat & +- EXT2_FEATURE_COMPAT_RESIZE_INODE) { ++ EXT2_FEATURE_COMPAT_RESIZE_INO) { + retval = ext2fs_create_resize_inode(fs); + mke2fs_error_msg_and_die(retval, "reserve blocks for online resize"); + } +--- a/e2fsprogs/tune2fs.c ++++ b/e2fsprogs/tune2fs.c +@@ -8,7 +8,7 @@ + */ + #include "libbb.h" + #include <linux/fs.h> +-#include <linux/ext2_fs.h> ++#include "bb_e2fs_defs.h" + + // storage helpers + char BUG_wrong_field_size(void); +--- /dev/null ++++ b/include/bb_e2fs_defs.h +@@ -0,0 +1,602 @@ ++/* vi: set sw=4 ts=4: */ ++/* ++ * linux/include/linux/ext2_fs.h ++ * ++ * Copyright (C) 1992, 1993, 1994, 1995 ++ * Remy Card (card@masi.ibp.fr) ++ * Laboratoire MASI - Institut Blaise Pascal ++ * Universite Pierre et Marie Curie (Paris VI) ++ * ++ * Copyright (C) 1991, 1992 Linus Torvalds ++ */ ++ ++#ifndef LINUX_EXT2_FS_H ++#define LINUX_EXT2_FS_H 1 ++ ++/* ++ * Special inode numbers ++ */ ++#define EXT2_BAD_INO 1 /* Bad blocks inode */ ++#define EXT2_ROOT_INO 2 /* Root inode */ ++#define EXT2_ACL_IDX_INO 3 /* ACL inode */ ++#define EXT2_ACL_DATA_INO 4 /* ACL inode */ ++#define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */ ++#define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */ ++#define EXT2_RESIZE_INO 7 /* Reserved group descriptors inode */ ++#define EXT2_JOURNAL_INO 8 /* Journal inode */ ++ ++/* First non-reserved inode for old ext2 filesystems */ ++#define EXT2_GOOD_OLD_FIRST_INO 11 ++ ++/* ++ * The second extended file system magic number ++ */ ++#define EXT2_SUPER_MAGIC 0xEF53 ++ ++/* Assume that user mode programs are passing in an ext2fs superblock, not ++ * a kernel struct super_block. This will allow us to call the feature-test ++ * macros from user land. */ ++#define EXT2_SB(sb) (sb) ++ ++/* ++ * Maximal count of links to a file ++ */ ++#define EXT2_LINK_MAX 32000 ++ ++/* ++ * Macro-instructions used to manage several block sizes ++ */ ++#define EXT2_MIN_BLOCK_LOG_SIZE 10 /* 1024 */ ++#define EXT2_MAX_BLOCK_LOG_SIZE 16 /* 65536 */ ++#define EXT2_MIN_BLOCK_SIZE (1 << EXT2_MIN_BLOCK_LOG_SIZE) ++#define EXT2_MAX_BLOCK_SIZE (1 << EXT2_MAX_BLOCK_LOG_SIZE) ++#define EXT2_BLOCK_SIZE(s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size) ++#define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) ++#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \ ++ EXT2_GOOD_OLD_INODE_SIZE : (s)->s_inode_size) ++#define EXT2_FIRST_INO(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \ ++ EXT2_GOOD_OLD_FIRST_INO : (s)->s_first_ino) ++#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof(uint32_t)) ++ ++/* ++ * Macro-instructions used to manage fragments ++ */ ++#define EXT2_MIN_FRAG_SIZE EXT2_MIN_BLOCK_SIZE ++#define EXT2_MAX_FRAG_SIZE EXT2_MAX_BLOCK_SIZE ++#define EXT2_MIN_FRAG_LOG_SIZE EXT2_MIN_BLOCK_LOG_SIZE ++#define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size) ++#define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s)) ++ ++/* ++ * ACL structures ++ */ ++struct ext2_acl_header { /* Header of Access Control Lists */ ++ uint32_t aclh_size; ++ uint32_t aclh_file_count; ++ uint32_t aclh_acle_count; ++ uint32_t aclh_first_acle; ++}; ++ ++struct ext2_acl_entry { /* Access Control List Entry */ ++ uint32_t acle_size; ++ uint16_t acle_perms; /* Access permissions */ ++ uint16_t acle_type; /* Type of entry */ ++ uint16_t acle_tag; /* User or group identity */ ++ uint16_t acle_pad1; ++ uint32_t acle_next; /* Pointer on next entry for the */ ++ /* same inode or on next free entry */ ++}; ++ ++/* ++ * Structure of a blocks group descriptor ++ */ ++struct ext2_group_desc { ++ uint32_t bg_block_bitmap; /* Blocks bitmap block */ ++ uint32_t bg_inode_bitmap; /* Inodes bitmap block */ ++ uint32_t bg_inode_table; /* Inodes table block */ ++ uint16_t bg_free_blocks_count; /* Free blocks count */ ++ uint16_t bg_free_inodes_count; /* Free inodes count */ ++ uint16_t bg_used_dirs_count; /* Directories count */ ++ uint16_t bg_pad; ++ uint32_t bg_reserved[3]; ++}; ++ ++/* ++ * Data structures used by the directory indexing feature ++ * ++ * Note: all of the multibyte integer fields are little endian. ++ */ ++ ++/* ++ * Note: dx_root_info is laid out so that if it should somehow get ++ * overlaid by a dirent the two low bits of the hash version will be ++ * zero. Therefore, the hash version mod 4 should never be 0. ++ * Sincerely, the paranoia department. ++ */ ++struct ext2_dx_root_info { ++ uint32_t reserved_zero; ++ uint8_t hash_version; /* 0 now, 1 at release */ ++ uint8_t info_length; /* 8 */ ++ uint8_t indirect_levels; ++ uint8_t unused_flags; ++}; ++ ++#define EXT2_HASH_LEGACY 0 ++#define EXT2_HASH_HALF_MD4 1 ++#define EXT2_HASH_TEA 2 ++ ++#define EXT2_HASH_FLAG_INCOMPAT 0x1 ++ ++struct ext2_dx_entry { ++ uint32_t hash; ++ uint32_t block; ++}; ++ ++struct ext2_dx_countlimit { ++ uint16_t limit; ++ uint16_t count; ++}; ++ ++ ++/* ++ * Macro-instructions used to manage group descriptors ++ */ ++#define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->s_blocks_per_group) ++#define EXT2_INODES_PER_GROUP(s) (EXT2_SB(s)->s_inodes_per_group) ++#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s)) ++/* limits imposed by 16-bit value gd_free_{blocks,inode}_count */ ++#define EXT2_MAX_BLOCKS_PER_GROUP(s) ((1 << 16) - 8) ++#define EXT2_MAX_INODES_PER_GROUP(s) ((1 << 16) - EXT2_INODES_PER_BLOCK(s)) ++#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc)) ++ ++/* ++ * Constants relative to the data blocks ++ */ ++#define EXT2_NDIR_BLOCKS 12 ++#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS ++#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1) ++#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1) ++#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1) ++ ++/* ++ * Inode flags ++ */ ++#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */ ++#define EXT2_UNRM_FL 0x00000002 /* Undelete */ ++#define EXT2_COMPR_FL 0x00000004 /* Compress file */ ++#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */ ++#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */ ++#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */ ++#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */ ++#define EXT2_NOATIME_FL 0x00000080 /* do not update atime */ ++/* Reserved for compression usage... */ ++#define EXT2_DIRTY_FL 0x00000100 ++#define EXT2_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */ ++#define EXT2_NOCOMPR_FL 0x00000400 /* Access raw compressed data */ ++#define EXT2_ECOMPR_FL 0x00000800 /* Compression error */ ++/* End compression flags --- maybe not all used */ ++#define EXT2_BTREE_FL 0x00001000 /* btree format dir */ ++#define EXT2_INDEX_FL 0x00001000 /* hash-indexed directory */ ++#define EXT2_IMAGIC_FL 0x00002000 ++#define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */ ++#define EXT2_NOTAIL_FL 0x00008000 /* file tail should not be merged */ ++#define EXT2_DIRSYNC_FL 0x00010000 /* Synchronous directory modifications */ ++#define EXT2_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ ++#define EXT3_EXTENTS_FL 0x00080000 /* Inode uses extents */ ++#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */ ++ ++#define EXT2_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ ++#define EXT2_FL_USER_MODIFIABLE 0x000080FF /* User modifiable flags */ ++ ++/* ++ * ioctl commands ++ */ ++#define EXT2_IOC_GETFLAGS _IOR('f', 1, long) ++#define EXT2_IOC_SETFLAGS _IOW('f', 2, long) ++#define EXT2_IOC_GETVERSION _IOR('v', 1, long) ++#define EXT2_IOC_SETVERSION _IOW('v', 2, long) ++ ++/* ++ * Structure of an inode on the disk ++ */ ++struct ext2_inode { ++ uint16_t i_mode; /* File mode */ ++ uint16_t i_uid; /* Low 16 bits of Owner Uid */ ++ uint32_t i_size; /* Size in bytes */ ++ uint32_t i_atime; /* Access time */ ++ uint32_t i_ctime; /* Creation time */ ++ uint32_t i_mtime; /* Modification time */ ++ uint32_t i_dtime; /* Deletion Time */ ++ uint16_t i_gid; /* Low 16 bits of Group Id */ ++ uint16_t i_links_count; /* Links count */ ++ uint32_t i_blocks; /* Blocks count */ ++ uint32_t i_flags; /* File flags */ ++ union { ++ struct { ++ uint32_t l_i_reserved1; ++ } linux1; ++ struct { ++ uint32_t h_i_translator; ++ } hurd1; ++ struct { ++ uint32_t m_i_reserved1; ++ } masix1; ++ } osd1; /* OS dependent 1 */ ++ uint32_t i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ ++ uint32_t i_generation; /* File version (for NFS) */ ++ uint32_t i_file_acl; /* File ACL */ ++ uint32_t i_dir_acl; /* Directory ACL */ ++ uint32_t i_faddr; /* Fragment address */ ++ union { ++ struct { ++ uint8_t l_i_frag; /* Fragment number */ ++ uint8_t l_i_fsize; /* Fragment size */ ++ uint16_t i_pad1; ++ uint16_t l_i_uid_high; /* these 2 fields */ ++ uint16_t l_i_gid_high; /* were reserved2[0] */ ++ uint32_t l_i_reserved2; ++ } linux2; ++ struct { ++ uint8_t h_i_frag; /* Fragment number */ ++ uint8_t h_i_fsize; /* Fragment size */ ++ uint16_t h_i_mode_high; ++ uint16_t h_i_uid_high; ++ uint16_t h_i_gid_high; ++ uint32_t h_i_author; ++ } hurd2; ++ struct { ++ uint8_t m_i_frag; /* Fragment number */ ++ uint8_t m_i_fsize; /* Fragment size */ ++ uint16_t m_pad1; ++ uint32_t m_i_reserved2[2]; ++ } masix2; ++ } osd2; /* OS dependent 2 */ ++}; ++ ++/* ++ * Permanent part of an large inode on the disk ++ */ ++struct ext2_inode_large { ++ uint16_t i_mode; /* File mode */ ++ uint16_t i_uid; /* Low 16 bits of Owner Uid */ ++ uint32_t i_size; /* Size in bytes */ ++ uint32_t i_atime; /* Access time */ ++ uint32_t i_ctime; /* Creation time */ ++ uint32_t i_mtime; /* Modification time */ ++ uint32_t i_dtime; /* Deletion Time */ ++ uint16_t i_gid; /* Low 16 bits of Group Id */ ++ uint16_t i_links_count; /* Links count */ ++ uint32_t i_blocks; /* Blocks count */ ++ uint32_t i_flags; /* File flags */ ++ union { ++ struct { ++ uint32_t l_i_reserved1; ++ } linux1; ++ struct { ++ uint32_t h_i_translator; ++ } hurd1; ++ struct { ++ uint32_t m_i_reserved1; ++ } masix1; ++ } osd1; /* OS dependent 1 */ ++ uint32_t i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ ++ uint32_t i_generation; /* File version (for NFS) */ ++ uint32_t i_file_acl; /* File ACL */ ++ uint32_t i_dir_acl; /* Directory ACL */ ++ uint32_t i_faddr; /* Fragment address */ ++ union { ++ struct { ++ uint8_t l_i_frag; /* Fragment number */ ++ uint8_t l_i_fsize; /* Fragment size */ ++ uint16_t i_pad1; ++ uint16_t l_i_uid_high; /* these 2 fields */ ++ uint16_t l_i_gid_high; /* were reserved2[0] */ ++ uint32_t l_i_reserved2; ++ } linux2; ++ struct { ++ uint8_t h_i_frag; /* Fragment number */ ++ uint8_t h_i_fsize; /* Fragment size */ ++ uint16_t h_i_mode_high; ++ uint16_t h_i_uid_high; ++ uint16_t h_i_gid_high; ++ uint32_t h_i_author; ++ } hurd2; ++ struct { ++ uint8_t m_i_frag; /* Fragment number */ ++ uint8_t m_i_fsize; /* Fragment size */ ++ uint16_t m_pad1; ++ uint32_t m_i_reserved2[2]; ++ } masix2; ++ } osd2; /* OS dependent 2 */ ++ uint16_t i_extra_isize; ++ uint16_t i_pad1; ++}; ++ ++#define i_size_high i_dir_acl ++ ++/* ++ * File system states ++ */ ++#define EXT2_VALID_FS 0x0001 /* Unmounted cleanly */ ++#define EXT2_ERROR_FS 0x0002 /* Errors detected */ ++ ++/* ++ * Mount flags ++ */ ++#define EXT2_MOUNT_CHECK 0x0001 /* Do mount-time checks */ ++#define EXT2_MOUNT_GRPID 0x0004 /* Create files with directory's group */ ++#define EXT2_MOUNT_DEBUG 0x0008 /* Some debugging messages */ ++#define EXT2_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */ ++#define EXT2_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */ ++#define EXT2_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */ ++#define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */ ++#define EXT2_MOUNT_NO_UID32 0x0200 /* Disable 32-bit UIDs */ ++ ++#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt ++#define set_opt(o, opt) o |= EXT2_MOUNT_##opt ++#define test_opt(sb, opt) (EXT2_SB(sb)->s_mount_opt & \ ++ EXT2_MOUNT_##opt) ++/* ++ * Maximal mount counts between two filesystem checks ++ */ ++#define EXT2_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ ++#define EXT2_DFL_CHECKINTERVAL 0 /* Don't use interval check */ ++ ++/* ++ * Behaviour when detecting errors ++ */ ++#define EXT2_ERRORS_CONTINUE 1 /* Continue execution */ ++#define EXT2_ERRORS_RO 2 /* Remount fs read-only */ ++#define EXT2_ERRORS_PANIC 3 /* Panic */ ++#define EXT2_ERRORS_DEFAULT EXT2_ERRORS_CONTINUE ++ ++/* ++ * Structure of the super block ++ */ ++struct ext2_super_block { ++ uint32_t s_inodes_count; /* Inodes count */ ++ uint32_t s_blocks_count; /* Blocks count */ ++ uint32_t s_r_blocks_count; /* Reserved blocks count */ ++ uint32_t s_free_blocks_count; /* Free blocks count */ ++ uint32_t s_free_inodes_count; /* Free inodes count */ ++ uint32_t s_first_data_block; /* First Data Block */ ++ uint32_t s_log_block_size; /* Block size */ ++ int32_t s_log_frag_size; /* Fragment size */ ++ uint32_t s_blocks_per_group; /* # Blocks per group */ ++ uint32_t s_frags_per_group; /* # Fragments per group */ ++ uint32_t s_inodes_per_group; /* # Inodes per group */ ++ uint32_t s_mtime; /* Mount time */ ++ uint32_t s_wtime; /* Write time */ ++ uint16_t s_mnt_count; /* Mount count */ ++ int16_t s_max_mnt_count; /* Maximal mount count */ ++ uint16_t s_magic; /* Magic signature */ ++ uint16_t s_state; /* File system state */ ++ uint16_t s_errors; /* Behaviour when detecting errors */ ++ uint16_t s_minor_rev_level; /* minor revision level */ ++ uint32_t s_lastcheck; /* time of last check */ ++ uint32_t s_checkinterval; /* max. time between checks */ ++ uint32_t s_creator_os; /* OS */ ++ uint32_t s_rev_level; /* Revision level */ ++ uint16_t s_def_resuid; /* Default uid for reserved blocks */ ++ uint16_t s_def_resgid; /* Default gid for reserved blocks */ ++ /* ++ * These fields are for EXT2_DYNAMIC_REV superblocks only. ++ * ++ * Note: the difference between the compatible feature set and ++ * the incompatible feature set is that if there is a bit set ++ * in the incompatible feature set that the kernel doesn't ++ * know about, it should refuse to mount the filesystem. ++ * ++ * e2fsck's requirements are more strict; if it doesn't know ++ * about a feature in either the compatible or incompatible ++ * feature set, it must abort and not try to meddle with ++ * things it doesn't understand... ++ */ ++ uint32_t s_first_ino; /* First non-reserved inode */ ++ uint16_t s_inode_size; /* size of inode structure */ ++ uint16_t s_block_group_nr; /* block group # of this superblock */ ++ uint32_t s_feature_compat; /* compatible feature set */ ++ uint32_t s_feature_incompat; /* incompatible feature set */ ++ uint32_t s_feature_ro_compat; /* readonly-compatible feature set */ ++ uint8_t s_uuid[16]; /* 128-bit uuid for volume */ ++ char s_volume_name[16]; /* volume name */ ++ char s_last_mounted[64]; /* directory where last mounted */ ++ uint32_t s_algorithm_usage_bitmap; /* For compression */ ++ /* ++ * Performance hints. Directory preallocation should only ++ * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on. ++ */ ++ uint8_t s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ ++ uint8_t s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ ++ uint16_t s_reserved_gdt_blocks; /* Per group table for online growth */ ++ /* ++ * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set. ++ */ ++/*D0*/ uint8_t s_journal_uuid[16]; /* uuid of journal superblock */ ++/*E0*/ uint32_t s_journal_inum; /* inode number of journal file */ ++ uint32_t s_journal_dev; /* device number of journal file */ ++ uint32_t s_last_orphan; /* start of list of inodes to delete */ ++ uint32_t s_hash_seed[4]; /* HTREE hash seed */ ++ uint8_t s_def_hash_version; /* Default hash version to use */ ++ uint8_t s_jnl_backup_type; /* Default type of journal backup */ ++ uint16_t s_reserved_word_pad; ++/*100*/ uint32_t s_default_mount_opts; ++ uint32_t s_first_meta_bg; /* First metablock group */ ++ /* ext3 additions */ ++ uint32_t s_mkfs_time; /* When the filesystem was created */ ++ uint32_t s_jnl_blocks[17]; /* Backup of the journal inode */ ++ /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */ ++/*150*/ uint32_t s_blocks_count_hi; /* Blocks count */ ++ uint32_t s_r_blocks_count_hi; /* Reserved blocks count */ ++ uint32_t s_free_blocks_count_hi; /* Free blocks count */ ++ uint16_t s_min_extra_isize; /* All inodes have at least # bytes */ ++ uint16_t s_want_extra_isize; /* New inodes should reserve # bytes */ ++ uint32_t s_flags; /* Miscellaneous flags */ ++ uint16_t s_raid_stride; /* RAID stride */ ++ uint16_t s_mmp_interval; /* # seconds to wait in MMP checking */ ++ uint64_t s_mmp_block; /* Block for multi-mount protection */ ++ uint32_t s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ ++ uint8_t s_log_groups_per_flex; /* FLEX_BG group size */ ++ uint8_t s_reserved_char_pad2; ++ uint16_t s_reserved_pad; ++ uint32_t s_reserved[162]; /* Padding to the end of the block */ ++}; ++struct BUG_ext2_super_block { ++ char bug[sizeof(struct ext2_super_block) == 1024 ? 1 : -1]; ++}; ++ ++/* ++ * Codes for operating systems ++ */ ++#define EXT2_OS_LINUX 0 ++#define EXT2_OS_HURD 1 ++#define EXT2_OS_MASIX 2 ++#define EXT2_OS_FREEBSD 3 ++#define EXT2_OS_LITES 4 ++ ++/* ++ * Revision levels ++ */ ++#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */ ++#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ ++ ++#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV ++#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV ++ ++#define EXT2_GOOD_OLD_INODE_SIZE 128 ++ ++/* ++ * Journal inode backup types ++ */ ++#define EXT3_JNL_BACKUP_BLOCKS 1 ++ ++/* ++ * Feature set definitions ++ */ ++ ++#define EXT2_HAS_COMPAT_FEATURE(sb,mask) \ ++ ( EXT2_SB(sb)->s_feature_compat & (mask) ) ++#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask) \ ++ ( EXT2_SB(sb)->s_feature_ro_compat & (mask) ) ++#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \ ++ ( EXT2_SB(sb)->s_feature_incompat & (mask) ) ++ ++/* for s_feature_compat */ ++#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001 ++#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002 ++#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 ++#define EXT2_FEATURE_COMPAT_EXT_ATTR 0x0008 ++#define EXT2_FEATURE_COMPAT_RESIZE_INO 0x0010 ++#define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020 ++ ++/* for s_feature_ro_compat */ ++#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 ++#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 ++#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 /* not used */ ++#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008 ++#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 ++#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 ++#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 ++ ++/* for s_feature_incompat */ ++#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001 ++#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 ++#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 ++#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 ++#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 ++#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 ++#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 ++#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 ++#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 ++ ++ ++#define EXT2_FEATURE_COMPAT_SUPP 0 ++#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ ++ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ ++ EXT2_FEATURE_RO_COMPAT_BTREE_DIR) ++#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ ++ EXT2_FEATURE_INCOMPAT_META_BG) ++#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED (~EXT2_FEATURE_INCOMPAT_SUPP) ++#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED (~EXT2_FEATURE_RO_COMPAT_SUPP) ++ ++#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ ++ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ ++ EXT2_FEATURE_RO_COMPAT_BTREE_DIR) ++#define EXT3_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ ++ EXT3_FEATURE_INCOMPAT_RECOVER| \ ++ EXT2_FEATURE_INCOMPAT_META_BG) ++#define EXT3_FEATURE_INCOMPAT_UNSUPPORTED (~EXT3_FEATURE_INCOMPAT_SUPP) ++#define EXT3_FEATURE_RO_COMPAT_UNSUPPORTED (~EXT3_FEATURE_RO_COMPAT_SUPP) ++ ++ ++/* ++ * Default values for user and/or group using reserved blocks ++ */ ++#define EXT2_DEF_RESUID 0 ++#define EXT2_DEF_RESGID 0 ++ ++/* ++ * Default mount options ++ */ ++#define EXT2_DEFM_DEBUG 0x0001 ++#define EXT2_DEFM_BSDGROUPS 0x0002 ++#define EXT2_DEFM_XATTR_USER 0x0004 ++#define EXT2_DEFM_ACL 0x0008 ++#define EXT2_DEFM_UID16 0x0010 ++#define EXT3_DEFM_JMODE 0x0060 ++#define EXT3_DEFM_JMODE_DATA 0x0020 ++#define EXT3_DEFM_JMODE_ORDERED 0x0040 ++#define EXT3_DEFM_JMODE_WBACK 0x0060 ++ ++/* ++ * Structure of a directory entry ++ */ ++#define EXT2_NAME_LEN 255 ++ ++struct ext2_dir_entry { ++ uint32_t inode; /* Inode number */ ++ uint16_t rec_len; /* Directory entry length */ ++ uint16_t name_len; /* Name length */ ++ char name[EXT2_NAME_LEN]; /* File name */ ++}; ++ ++/* ++ * The new version of the directory entry. Since EXT2 structures are ++ * stored in intel byte order, and the name_len field could never be ++ * bigger than 255 chars, it's safe to reclaim the extra byte for the ++ * file_type field. ++ */ ++struct ext2_dir_entry_2 { ++ uint32_t inode; /* Inode number */ ++ uint16_t rec_len; /* Directory entry length */ ++ uint8_t name_len; /* Name length */ ++ uint8_t file_type; ++ char name[EXT2_NAME_LEN]; /* File name */ ++}; ++ ++/* ++ * Ext2 directory file types. Only the low 3 bits are used. The ++ * other bits are reserved for now. ++ */ ++#define EXT2_FT_UNKNOWN 0 ++#define EXT2_FT_REG_FILE 1 ++#define EXT2_FT_DIR 2 ++#define EXT2_FT_CHRDEV 3 ++#define EXT2_FT_BLKDEV 4 ++#define EXT2_FT_FIFO 5 ++#define EXT2_FT_SOCK 6 ++#define EXT2_FT_SYMLINK 7 ++ ++#define EXT2_FT_MAX 8 ++ ++/* ++ * EXT2_DIR_PAD defines the directory entries boundaries ++ * ++ * NOTE: It must be a multiple of 4 ++ */ ++#define EXT2_DIR_PAD 4 ++#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1) ++#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \ ++ ~EXT2_DIR_ROUND) ++ ++#endif +--- a/testsuite/mount.tests ++++ b/testsuite/mount.tests +@@ -36,7 +36,8 @@ testing "mount -o remount,mand" \ + "mount -o loop mount.image1m $testdir "\ + "&& grep -Fc $testdir </proc/mounts "\ + "&& mount -o remount,mand $testdir "\ +-"&& grep -F $testdir </proc/mounts | grep -c '[, ]mand[, ]'" \ ++"&& grep -F $testdir </proc/mounts | grep -c '[, ]mand[, ]'"\ ++"|| grep -F $testdir </proc/mounts" \ + "1\n""1\n" \ + "" "" + +@@ -83,4 +84,28 @@ b + "" "" + SKIP= + ++ ++testing "mount RO loop" "\ ++exec 2>&1 ++umount -d mount.dir 2>/dev/null ++rmdir mount.dir 2>/dev/null ++mkdir -p mount.dir ++( ++cd mount.dir || { echo 'cd error'; exit 1; } ++mkdir z1 z2 || { echo 'mkdir error'; exit 1; } ++mount -t tmpfs tmpfs z1 || { echo 'mount tmpfs error'; exit 1; } ++dd if=/dev/zero of=z1/e2img count=10 bs=1M 2>/dev/null || { echo 'dd error'; exit 1; } ++mke2fs -F z1/e2img 2>/dev/null >&2 || { echo 'mke2fs error'; exit 1; } ++mount -r -o loop -t ext2 z1/e2img z2 || { echo 'mount -r -o loop error'; exit 1; } ++mount -o remount,ro z1 || { echo 'mount -o remount,ro error'; exit 1; } ++) ++umount -d mount.dir/z2 ++##losetup -d /dev/loop* ++umount -d mount.dir/z1 ++rm -rf mount.dir ++echo DONE ++" \ ++"DONE\n" "" "" ++ ++ + exit $FAILCOUNT +--- a/util-linux/mkfs_ext2.c ++++ b/util-linux/mkfs_ext2.c +@@ -48,16 +48,11 @@ + + #include "libbb.h" + #include <linux/fs.h> +-#include <linux/ext2_fs.h> ++#include "bb_e2fs_defs.h" + + #define ENABLE_FEATURE_MKFS_EXT2_RESERVED_GDT 0 + #define ENABLE_FEATURE_MKFS_EXT2_DIR_INDEX 1 + +-// from e2fsprogs +-#define s_reserved_gdt_blocks s_padding1 +-#define s_mkfs_time s_reserved[0] +-#define s_flags s_reserved[22] +- + #define EXT2_HASH_HALF_MD4 1 + #define EXT2_FLAGS_SIGNED_HASH 0x0001 + #define EXT2_FLAGS_UNSIGNED_HASH 0x0002 +@@ -482,8 +477,10 @@ int mkfs_ext2_main(int argc UNUSED_PARAM + STORE_LE(sb->s_magic, EXT2_SUPER_MAGIC); + STORE_LE(sb->s_inode_size, inodesize); + // set "Required extra isize" and "Desired extra isize" fields to 28 +- if (inodesize != sizeof(*inode)) +- STORE_LE(sb->s_reserved[21], 0x001C001C); ++ if (inodesize != sizeof(*inode)) { ++ STORE_LE(sb->s_min_extra_isize, 0x001c); ++ STORE_LE(sb->s_want_extra_isize, 0x001c); ++ } + STORE_LE(sb->s_first_ino, EXT2_GOOD_OLD_FIRST_INO); + STORE_LE(sb->s_log_block_size, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE); + STORE_LE(sb->s_log_frag_size, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE); +--- a/util-linux/volume_id/ext.c ++++ b/util-linux/volume_id/ext.c +@@ -19,28 +19,8 @@ + */ + + #include "volume_id_internal.h" ++#include "bb_e2fs_defs.h" + +-struct ext2_super_block { +- uint32_t inodes_count; +- uint32_t blocks_count; +- uint32_t r_blocks_count; +- uint32_t free_blocks_count; +- uint32_t free_inodes_count; +- uint32_t first_data_block; +- uint32_t log_block_size; +- uint32_t dummy3[7]; +- uint8_t magic[2]; +- uint16_t state; +- uint32_t dummy5[8]; +- uint32_t feature_compat; +- uint32_t feature_incompat; +- uint32_t feature_ro_compat; +- uint8_t uuid[16]; +- uint8_t volume_name[16]; +-} PACKED; +- +-#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x00000004 +-#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x00000008 + #define EXT_SUPERBLOCK_OFFSET 0x400 + + int FAST_FUNC volume_id_probe_ext(struct volume_id *id /*,uint64_t off*/) +@@ -54,23 +34,27 @@ int FAST_FUNC volume_id_probe_ext(struct + if (es == NULL) + return -1; + +- if (es->magic[0] != 0123 || es->magic[1] != 0357) { ++ if (es->s_magic != cpu_to_le16(EXT2_SUPER_MAGIC)) { + dbg("ext: no magic found"); + return -1; + } + + // volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + // volume_id_set_label_raw(id, es->volume_name, 16); +- volume_id_set_label_string(id, es->volume_name, 16); +- volume_id_set_uuid(id, es->uuid, UUID_DCE); ++ volume_id_set_label_string(id, (void*)es->s_volume_name, 16); ++ volume_id_set_uuid(id, es->s_uuid, UUID_DCE); + dbg("ext: label '%s' uuid '%s'", id->label, id->uuid); + + #if ENABLE_FEATURE_BLKID_TYPE +- if ((le32_to_cpu(es->feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) ++ if ((es->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_HUGE_FILE | EXT4_FEATURE_RO_COMPAT_DIR_NLINK)) ++ || (es->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_EXTENTS | EXT4_FEATURE_INCOMPAT_64BIT)) ++ ) { ++ id->type = "ext4"; ++ } ++ else if (es->s_feature_compat & cpu_to_le32(EXT3_FEATURE_COMPAT_HAS_JOURNAL)) + id->type = "ext3"; + else + id->type = "ext2"; + #endif +- + return 0; + } diff --git a/package/utils/busybox/patches/110-wget_getopt_fix.patch b/package/utils/busybox/patches/110-wget_getopt_fix.patch new file mode 100644 index 0000000000..1003231462 --- /dev/null +++ b/package/utils/busybox/patches/110-wget_getopt_fix.patch @@ -0,0 +1,11 @@ +--- a/networking/wget.c ++++ b/networking/wget.c +@@ -873,7 +873,7 @@ int wget_main(int argc UNUSED_PARAM, cha + /* Ignored: */ + // "tries\0" Required_argument "t" + /* Ignored (we always use PASV): */ +- "passive-ftp\0" No_argument "\xff" ++ "passive-ftp\0" No_argument "\xfd" + "header\0" Required_argument "\xfe" + "post-data\0" Required_argument "\xfd" + /* Ignored (we don't do ssl) */ diff --git a/package/utils/busybox/patches/140-trylink_bash.patch b/package/utils/busybox/patches/140-trylink_bash.patch new file mode 100644 index 0000000000..f9571fcbc8 --- /dev/null +++ b/package/utils/busybox/patches/140-trylink_bash.patch @@ -0,0 +1,8 @@ +--- a/scripts/trylink ++++ b/scripts/trylink +@@ -1,4 +1,4 @@ +-#!/bin/sh ++#!/usr/bin/env bash + + debug=false + diff --git a/package/utils/busybox/patches/141-gen_build_files_bash.patch b/package/utils/busybox/patches/141-gen_build_files_bash.patch new file mode 100644 index 0000000000..d258fb8bc4 --- /dev/null +++ b/package/utils/busybox/patches/141-gen_build_files_bash.patch @@ -0,0 +1,8 @@ +--- a/scripts/gen_build_files.sh ++++ b/scripts/gen_build_files.sh +@@ -1,4 +1,4 @@ +-#!/bin/sh ++#!/usr/bin/env bash + + # Note: was using sed OPTS CMD -- FILES + # but users complain that many sed implementations diff --git a/package/utils/busybox/patches/150-no_static_libgcc.patch b/package/utils/busybox/patches/150-no_static_libgcc.patch new file mode 100644 index 0000000000..fde6fbb869 --- /dev/null +++ b/package/utils/busybox/patches/150-no_static_libgcc.patch @@ -0,0 +1,11 @@ +--- a/Makefile.flags ++++ b/Makefile.flags +@@ -50,7 +50,7 @@ CFLAGS += $(call cc-option,-fno-builtin- + # -fno-guess-branch-probability: prohibit pseudo-random guessing + # of branch probabilities (hopefully makes bloatcheck more stable): + CFLAGS += $(call cc-option,-fno-guess-branch-probability,) +-CFLAGS += $(call cc-option,-funsigned-char -static-libgcc,) ++CFLAGS += $(call cc-option,-funsigned-char,) + CFLAGS += $(call cc-option,-falign-functions=1 -falign-jumps=1 -falign-labels=1 -falign-loops=1,) + + # FIXME: These warnings are at least partially to be concerned about and should diff --git a/package/utils/busybox/patches/200-etc_crontabs.patch b/package/utils/busybox/patches/200-etc_crontabs.patch new file mode 100644 index 0000000000..ebf2990502 --- /dev/null +++ b/package/utils/busybox/patches/200-etc_crontabs.patch @@ -0,0 +1,22 @@ +--- a/miscutils/crond.c ++++ b/miscutils/crond.c +@@ -37,7 +37,7 @@ + + + #define TMPDIR CONFIG_FEATURE_CROND_DIR +-#define CRONTABS CONFIG_FEATURE_CROND_DIR "/crontabs" ++#define CRONTABS "/etc/crontabs" + #ifndef SENDMAIL + # define SENDMAIL "sendmail" + #endif +--- a/miscutils/crontab.c ++++ b/miscutils/crontab.c +@@ -22,7 +22,7 @@ + + #include "libbb.h" + +-#define CRONTABS CONFIG_FEATURE_CROND_DIR "/crontabs" ++#define CRONTABS "/etc/crontabs" + #ifndef CRONUPDATE + #define CRONUPDATE "cron.update" + #endif diff --git a/package/utils/busybox/patches/240-udhcpc_retries.patch b/package/utils/busybox/patches/240-udhcpc_retries.patch new file mode 100644 index 0000000000..0e26864e8d --- /dev/null +++ b/package/utils/busybox/patches/240-udhcpc_retries.patch @@ -0,0 +1,20 @@ +--- a/networking/udhcp/dhcpc.c ++++ b/networking/udhcp/dhcpc.c +@@ -1319,7 +1319,7 @@ int udhcpc_main(int argc UNUSED_PARAM, c + + switch (state) { + case INIT_SELECTING: +- if (packet_num < discover_retries) { ++ if (!discover_retries || packet_num < discover_retries) { + if (packet_num == 0) + xid = random_xid(); + /* broadcast */ +@@ -1348,7 +1348,7 @@ int udhcpc_main(int argc UNUSED_PARAM, c + packet_num = 0; + continue; + case REQUESTING: +- if (packet_num < discover_retries) { ++ if (!discover_retries || packet_num < discover_retries) { + /* send broadcast select packet */ + send_select(xid, server_addr, requested_ip); + timeout = discover_timeout; diff --git a/package/utils/busybox/patches/241-udhcpc-oversized_packets.patch b/package/utils/busybox/patches/241-udhcpc-oversized_packets.patch new file mode 100644 index 0000000000..471d704a71 --- /dev/null +++ b/package/utils/busybox/patches/241-udhcpc-oversized_packets.patch @@ -0,0 +1,99 @@ +--- a/networking/udhcp/packet.c ++++ b/networking/udhcp/packet.c +@@ -158,6 +158,11 @@ uint16_t FAST_FUNC udhcp_checksum(void * + return ~sum; + } + ++int udhcp_get_payload_len(struct dhcp_packet *dhcp_pkt) ++{ ++ return sizeof(struct dhcp_packet) - DHCP_OPTIONS_BUFSIZE + udhcp_end_option(dhcp_pkt->options) + sizeof(dhcp_pkt->options[0]); ++} ++ + /* Construct a ip/udp header for a packet, send packet */ + int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt, + uint32_t source_nip, int source_port, +@@ -166,10 +171,10 @@ int FAST_FUNC udhcp_send_raw_packet(stru + { + struct sockaddr_ll dest_sll; + struct ip_udp_dhcp_packet packet; +- unsigned padding; + int fd; + int result = -1; + const char *msg; ++ int p_len = udhcp_get_payload_len(dhcp_pkt); + + fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); + if (fd < 0) { +@@ -178,8 +183,8 @@ int FAST_FUNC udhcp_send_raw_packet(stru + } + + memset(&dest_sll, 0, sizeof(dest_sll)); +- memset(&packet, 0, offsetof(struct ip_udp_dhcp_packet, data)); +- packet.data = *dhcp_pkt; /* struct copy */ ++ memset(&packet, 0, sizeof(packet)); ++ memcpy(&(packet.data), dhcp_pkt, p_len); + + dest_sll.sll_family = AF_PACKET; + dest_sll.sll_protocol = htons(ETH_P_IP); +@@ -192,36 +197,24 @@ int FAST_FUNC udhcp_send_raw_packet(stru + goto ret_close; + } + +- /* We were sending full-sized DHCP packets (zero padded), +- * but some badly configured servers were seen dropping them. +- * Apparently they drop all DHCP packets >576 *ethernet* octets big, +- * whereas they may only drop packets >576 *IP* octets big +- * (which for typical Ethernet II means 590 octets: 6+6+2 + 576). +- * +- * In order to work with those buggy servers, +- * we truncate packets after end option byte. +- */ +- padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(packet.data.options); +- + packet.ip.protocol = IPPROTO_UDP; + packet.ip.saddr = source_nip; + packet.ip.daddr = dest_nip; + packet.udp.source = htons(source_port); + packet.udp.dest = htons(dest_port); +- /* size, excluding IP header: */ +- packet.udp.len = htons(UDP_DHCP_SIZE - padding); +- /* for UDP checksumming, ip.len is set to UDP packet len */ ++ p_len += sizeof(packet.udp); ++ packet.udp.len = htons(p_len); + packet.ip.tot_len = packet.udp.len; +- packet.udp.check = udhcp_checksum(&packet, IP_UDP_DHCP_SIZE - padding); +- /* but for sending, it is set to IP packet len */ +- packet.ip.tot_len = htons(IP_UDP_DHCP_SIZE - padding); ++ p_len += sizeof(packet.ip); ++ packet.udp.check = udhcp_checksum(&packet, p_len); ++ packet.ip.tot_len = htons(p_len); + packet.ip.ihl = sizeof(packet.ip) >> 2; + packet.ip.version = IPVERSION; + packet.ip.ttl = IPDEFTTL; + packet.ip.check = udhcp_checksum(&packet.ip, sizeof(packet.ip)); + + udhcp_dump_packet(dhcp_pkt); +- result = sendto(fd, &packet, IP_UDP_DHCP_SIZE - padding, /*flags:*/ 0, ++ result = sendto(fd, &packet, p_len, /*flags:*/ 0, + (struct sockaddr *) &dest_sll, sizeof(dest_sll)); + msg = "sendto"; + ret_close: +@@ -239,7 +232,6 @@ int FAST_FUNC udhcp_send_kernel_packet(s + uint32_t dest_nip, int dest_port) + { + struct sockaddr_in client; +- unsigned padding; + int fd; + int result = -1; + const char *msg; +@@ -270,9 +262,7 @@ int FAST_FUNC udhcp_send_kernel_packet(s + } + + udhcp_dump_packet(dhcp_pkt); +- +- padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(dhcp_pkt->options); +- result = safe_write(fd, dhcp_pkt, DHCP_SIZE - padding); ++ result = safe_write(fd, dhcp_pkt, udhcp_get_payload_len(dhcp_pkt)); + msg = "write"; + ret_close: + close(fd); diff --git a/package/utils/busybox/patches/242-udhcpc_msgs.patch b/package/utils/busybox/patches/242-udhcpc_msgs.patch new file mode 100644 index 0000000000..c1c6096697 --- /dev/null +++ b/package/utils/busybox/patches/242-udhcpc_msgs.patch @@ -0,0 +1,18 @@ +--- a/networking/udhcp/dhcpc.c ++++ b/networking/udhcp/dhcpc.c +@@ -602,6 +602,7 @@ static int raw_bcast_from_client_config_ + static NOINLINE int send_discover(uint32_t xid, uint32_t requested) + { + struct dhcp_packet packet; ++ static int msgs = 0; + + /* Fill in: op, htype, hlen, cookie, chaddr fields, + * random xid field (we override it below), +@@ -619,6 +620,7 @@ static NOINLINE int send_discover(uint32 + */ + add_client_options(&packet); + ++ if (msgs++ < 3) + bb_info_msg("Sending discover..."); + return raw_bcast_from_client_config_ifindex(&packet); + } diff --git a/package/utils/busybox/patches/243-udhcpc_changed_ifindex.patch b/package/utils/busybox/patches/243-udhcpc_changed_ifindex.patch new file mode 100644 index 0000000000..cb0df224cc --- /dev/null +++ b/package/utils/busybox/patches/243-udhcpc_changed_ifindex.patch @@ -0,0 +1,15 @@ +--- a/networking/udhcp/dhcpc.c ++++ b/networking/udhcp/dhcpc.c +@@ -1267,6 +1267,12 @@ int udhcpc_main(int argc UNUSED_PARAM, c + /* silence "uninitialized!" warning */ + unsigned timestamp_before_wait = timestamp_before_wait; + ++ /* When running on a bridge, the ifindex may have changed (e.g. if ++ * member interfaces were added/removed or if the status of the ++ * bridge changed). ++ * Workaround: refresh it here before processing the next packet */ ++ udhcp_read_interface(client_config.interface, &client_config.ifindex, NULL, client_config.client_mac); ++ + //bb_error_msg("sockfd:%d, listen_mode:%d", sockfd, listen_mode); + + /* Was opening raw or udp socket here diff --git a/package/utils/busybox/patches/244-udhcpc_add_6rd_option.patch b/package/utils/busybox/patches/244-udhcpc_add_6rd_option.patch new file mode 100644 index 0000000000..2f0eadb160 --- /dev/null +++ b/package/utils/busybox/patches/244-udhcpc_add_6rd_option.patch @@ -0,0 +1,143 @@ +--- a/networking/udhcp/common.c ++++ b/networking/udhcp/common.c +@@ -60,6 +60,8 @@ const struct dhcp_optflag dhcp_optflags[ + { OPTION_U8 , 0x85 }, /* DHCP_VLAN_PRIORITY */ + #endif + { OPTION_STATIC_ROUTES , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ ++ { OPTION_6RD , 0xd4 }, /* DHCP_6RD (RFC) */ ++ { OPTION_6RD , 0x96 }, /* DHCP_6RD (Comcast) */ + { OPTION_STRING , 0xfc }, /* DHCP_WPAD */ + + /* Options below have no match in dhcp_option_strings[], +@@ -127,6 +129,8 @@ const char dhcp_option_strings[] ALIGN1 + "vlanpriority" "\0"/* DHCP_VLAN_PRIORITY */ + #endif + "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ ++ "ip6rd" "\0" /* DHCP_6RD (RFC) */ ++ "ip6rd" "\0" /* DHCP_6RD (Comcast) */ + "wpad" "\0" /* DHCP_WPAD */ + ; + +@@ -155,6 +159,7 @@ const uint8_t dhcp_option_lengths[] ALIG + [OPTION_S32] = 4, + /* Just like OPTION_STRING, we use minimum length here */ + [OPTION_STATIC_ROUTES] = 5, ++ [OPTION_6RD] = 22, + }; + + +--- a/networking/udhcp/common.h ++++ b/networking/udhcp/common.h +@@ -91,6 +91,7 @@ enum { + OPTION_S32, + OPTION_BIN, + OPTION_STATIC_ROUTES, ++ OPTION_6RD, + #if ENABLE_FEATURE_UDHCP_RFC3397 + OPTION_DNS_STRING, /* RFC1035 compressed domain name list */ + OPTION_SIP_SERVERS, +--- a/networking/udhcp/dhcpc.c ++++ b/networking/udhcp/dhcpc.c +@@ -100,6 +100,7 @@ static const uint8_t len_of_option_as_st + [OPTION_IP ] = sizeof("255.255.255.255 "), + [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2, + [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "), ++ [OPTION_6RD ] = sizeof("32 128 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF 255.255.255.255 "), + [OPTION_STRING ] = 1, + [OPTION_STRING_HOST ] = 1, + #if ENABLE_FEATURE_UDHCP_RFC3397 +@@ -124,6 +125,23 @@ static int sprint_nip(char *dest, const + return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); + } + ++static int sprint_nip6(char *dest, const char *pre, const uint8_t *ip) ++{ ++ int len = 0; ++ int off; ++ uint16_t word; ++ ++ len += sprintf(dest, "%s", pre); ++ ++ for (off = 0; off < 16; off += 2) ++ { ++ move_from_unaligned16(word, &ip[off]); ++ len += sprintf(dest+len, "%s%04X", off ? ":" : "", htons(word)); ++ } ++ ++ return len; ++} ++ + /* really simple implementation, just count the bits */ + static int mton(uint32_t mask) + { +@@ -292,6 +310,70 @@ static NOINLINE char *xmalloc_optname_op + } + + return ret; ++ } ++ case OPTION_6RD: { ++ /* Option binary format: ++ * 0 1 2 3 ++ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ++ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++ * | OPTION_6RD | option-length | IPv4MaskLen | 6rdPrefixLen | ++ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++ * | | ++ * | 6rdPrefix | ++ * | (16 octets) | ++ * | | ++ * | | ++ * | | ++ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++ * | 6rdBRIPv4Address(es) | ++ * . . ++ * . . ++ * . . ++ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++ * ++ * We convert it to a string "IPv4MaskLen 6rdPrefixLen 6rdPrefix 6rdBRIPv4Address" ++ */ ++ ++ /* Sanity check: ensure that our length is at least 22 bytes, that ++ * IPv4MaskLen is <= 32, 6rdPrefixLen <= 128 and that the sum of ++ * (32 - IPv4MaskLen) + 6rdPrefixLen is less than or equal to 128. ++ * If any of these requirements is not fulfilled, return with empty ++ * value. ++ */ ++ if ((len >= 22) && (*option <= 32) && (*(option+1) <= 128) && ++ (((32 - *option) + *(option+1)) <= 128)) ++ { ++ /* IPv4MaskLen */ ++ dest += sprintf(dest, "%u ", *option++); ++ len--; ++ ++ /* 6rdPrefixLen */ ++ dest += sprintf(dest, "%u ", *option++); ++ len--; ++ ++ /* 6rdPrefix */ ++ dest += sprint_nip6(dest, "", option); ++ option += 16; ++ len -= 16; ++ ++ /* 6rdBRIPv4Addresses */ ++ while (len >= 4) ++ { ++ dest += sprint_nip(dest, " ", option); ++ option += 4; ++ len -= 4; ++ ++ /* the code to determine the option size fails to work with ++ * lengths that are not a multiple of the minimum length, ++ * adding all advertised 6rdBRIPv4Addresses here would ++ * overflow the destination buffer, therefore skip the rest ++ * for now ++ */ ++ break; ++ } ++ } ++ ++ return ret; + } + #if ENABLE_FEATURE_UDHCP_RFC3397 + case OPTION_DNS_STRING: diff --git a/package/utils/busybox/patches/250-ash_export-n.patch b/package/utils/busybox/patches/250-ash_export-n.patch new file mode 100644 index 0000000000..048c236b85 --- /dev/null +++ b/package/utils/busybox/patches/250-ash_export-n.patch @@ -0,0 +1,34 @@ +--- a/shell/ash.c ++++ b/shell/ash.c +@@ -12611,8 +12611,17 @@ exportcmd(int argc UNUSED_PARAM, char ** + const char *p; + char **aptr; + int flag = argv[0][0] == 'r' ? VREADONLY : VEXPORT; ++ int mask = ~0; ++ int nopt; ++ while ((nopt = nextopt("np"))) { ++ if (nopt == 'n') { ++ mask = ~flag; ++ } else { /* p */ ++ break; ++ } ++ } + +- if (nextopt("p") != 'p') { ++ if (nopt != 'p') { + aptr = argptr; + name = *aptr; + if (name) { +@@ -12624,10 +12633,12 @@ exportcmd(int argc UNUSED_PARAM, char ** + vp = *findvar(hashvar(name), name); + if (vp) { + vp->flags |= flag; ++ vp->flags &= mask; + continue; + } + } + setvar(name, p, flag); ++ setvar(name, p, flag & mask); + } while ((name = *++aptr) != NULL); + return 0; + } diff --git a/package/utils/busybox/patches/251-ash_fix-redir-substitution.patch b/package/utils/busybox/patches/251-ash_fix-redir-substitution.patch new file mode 100644 index 0000000000..cb2ae94e04 --- /dev/null +++ b/package/utils/busybox/patches/251-ash_fix-redir-substitution.patch @@ -0,0 +1,12 @@ +--- a/shell/ash.c ++++ b/shell/ash.c +@@ -6846,8 +6846,7 @@ evalvar(char *p, int flags, struct strli + patloc = expdest - (char *)stackblock(); + if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype, + startloc, varflags, +-//TODO: | EXP_REDIR too? All other such places do it too +- /* quotes: */ flags & (EXP_FULL | EXP_CASE), ++ /* quotes: */ flags & (EXP_FULL | EXP_CASE | EXP_REDIR), + var_str_list) + ) { + int amount = expdest - ( diff --git a/package/utils/busybox/patches/260-vconfig_proc.patch b/package/utils/busybox/patches/260-vconfig_proc.patch new file mode 100644 index 0000000000..7ac52abbfe --- /dev/null +++ b/package/utils/busybox/patches/260-vconfig_proc.patch @@ -0,0 +1,22 @@ +--- a/networking/vconfig.c ++++ b/networking/vconfig.c +@@ -116,8 +116,6 @@ static const char name_types[] ALIGN1 = + '_', 'N', 'O', '_', 'P', 'A', 'D', 0, + }; + +-static const char conf_file_name[] ALIGN1 = "/proc/net/vlan/config"; +- + int vconfig_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; + int vconfig_main(int argc, char **argv) + { +@@ -129,10 +127,6 @@ int vconfig_main(int argc, char **argv) + bb_show_usage(); + } + +- /* Don't bother closing the filedes. It will be closed on cleanup. */ +- /* Will die if 802.1q is not present */ +- xopen(conf_file_name, O_RDONLY); +- + memset(&ifr, 0, sizeof(ifr)); + + ++argv; diff --git a/package/utils/busybox/patches/300-netmsg.patch b/package/utils/busybox/patches/300-netmsg.patch new file mode 100644 index 0000000000..e8b2513eb3 --- /dev/null +++ b/package/utils/busybox/patches/300-netmsg.patch @@ -0,0 +1,103 @@ +--- a/include/applets.src.h ++++ b/include/applets.src.h +@@ -266,6 +266,7 @@ IF_MT(APPLET(mt, BB_DIR_BIN, BB_SUID_DRO + IF_MV(APPLET(mv, BB_DIR_BIN, BB_SUID_DROP)) + IF_NAMEIF(APPLET(nameif, BB_DIR_SBIN, BB_SUID_DROP)) + IF_NC(APPLET(nc, BB_DIR_USR_BIN, BB_SUID_DROP)) ++IF_NETMSG(APPLET(netmsg, BB_DIR_BIN, BB_SUID_REQUIRE)) + IF_NETSTAT(APPLET(netstat, BB_DIR_BIN, BB_SUID_DROP)) + IF_NICE(APPLET(nice, BB_DIR_BIN, BB_SUID_DROP)) + IF_NOHUP(APPLET(nohup, BB_DIR_USR_BIN, BB_SUID_DROP)) +--- a/networking/Config.src ++++ b/networking/Config.src +@@ -612,6 +612,12 @@ config FEATURE_IPCALC_LONG_OPTIONS + help + Support long options for the ipcalc applet. + ++config NETMSG ++ bool "netmsg" ++ default n ++ help ++ simple program for sending udp broadcast messages ++ + config NETSTAT + bool "netstat" + default y +--- a/networking/Kbuild.src ++++ b/networking/Kbuild.src +@@ -27,6 +27,7 @@ lib-$(CONFIG_IP) += ip.o + lib-$(CONFIG_IPCALC) += ipcalc.o + lib-$(CONFIG_NAMEIF) += nameif.o + lib-$(CONFIG_NC) += nc.o ++lib-$(CONFIG_NETMSG) += netmsg.o + lib-$(CONFIG_NETSTAT) += netstat.o + lib-$(CONFIG_NSLOOKUP) += nslookup.o + lib-$(CONFIG_NTPD) += ntpd.o +--- /dev/null ++++ b/networking/netmsg.c +@@ -0,0 +1,65 @@ ++/* ++ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> ++ * ++ * This is free software, licensed under the GNU General Public License v2. ++ */ ++#include <sys/types.h> ++#include <sys/socket.h> ++#include <netinet/in.h> ++#include <netdb.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include "busybox.h" ++ ++//usage:#define netmsg_trivial_usage NOUSAGE_STR ++//usage:#define netmsg_full_usage "" ++ ++#ifndef CONFIG_NETMSG ++int main(int argc, char **argv) ++#else ++int netmsg_main(int argc, char **argv) ++#endif ++{ ++ int s; ++ struct sockaddr_in addr; ++ int optval = 1; ++ unsigned char buf[1001]; ++ ++ if (argc != 3) { ++ fprintf(stderr, "usage: %s <ip> \"<message>\"\n", argv[0]); ++ exit(1); ++ } ++ ++ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { ++ perror("Opening socket"); ++ exit(1); ++ } ++ ++ memset(&addr, 0, sizeof(addr)); ++ addr.sin_family = AF_INET; ++ addr.sin_addr.s_addr = inet_addr(argv[1]); ++ addr.sin_port = htons(0x1337); ++ ++ memset(buf, 0, 1001); ++ buf[0] = 0xde; ++ buf[1] = 0xad; ++ ++ strncpy(buf + 2, argv[2], 998); ++ ++ if (setsockopt (s, SOL_SOCKET, SO_BROADCAST, (caddr_t) &optval, sizeof (optval)) < 0) { ++ perror("setsockopt()"); ++ goto fail; ++ } ++ ++ if (sendto(s, buf, 1001, 0, (struct sockaddr *) &addr, sizeof(addr)) < 0) { ++ perror("sendto()"); ++ goto fail; ++ } ++ ++ return 0; ++ ++fail: ++ close(s); ++ exit(1); ++} diff --git a/package/utils/busybox/patches/310-passwd_access.patch b/package/utils/busybox/patches/310-passwd_access.patch new file mode 100644 index 0000000000..daa1b99983 --- /dev/null +++ b/package/utils/busybox/patches/310-passwd_access.patch @@ -0,0 +1,41 @@ + + Copyright (C) 2006 OpenWrt.org + +--- a/networking/httpd.c ++++ b/networking/httpd.c +@@ -1700,21 +1700,32 @@ static int check_user_passwd(const char + + if (ENABLE_FEATURE_HTTPD_AUTH_MD5) { + char *md5_passwd; ++ int user_len_p1; + + md5_passwd = strchr(cur->after_colon, ':'); +- if (md5_passwd && md5_passwd[1] == '$' && md5_passwd[2] == '1' ++ user_len_p1 = md5_passwd + 1 - cur->after_colon; ++ if (md5_passwd && !strncmp(md5_passwd + 1, "$p$", 3)) { ++ struct passwd *pwd = NULL; ++ ++ pwd = getpwnam(&md5_passwd[4]); ++ if(!pwd->pw_passwd || !pwd->pw_passwd[0] || pwd->pw_passwd[0] == '!') ++ return 1; ++ ++ md5_passwd = pwd->pw_passwd; ++ goto check_md5_pw; ++ } else if (md5_passwd && md5_passwd[1] == '$' && md5_passwd[2] == '1' + && md5_passwd[3] == '$' && md5_passwd[4] + ) { + char *encrypted; +- int r, user_len_p1; ++ int r; + + md5_passwd++; +- user_len_p1 = md5_passwd - cur->after_colon; + /* comparing "user:" */ + if (strncmp(cur->after_colon, user_and_passwd, user_len_p1) != 0) { + continue; + } + ++check_md5_pw: + encrypted = pw_encrypt( + user_and_passwd + user_len_p1 /* cleartext pwd from user */, + md5_passwd /*salt */, 1 /* cleanup */); diff --git a/package/utils/busybox/patches/340-lock_util.patch b/package/utils/busybox/patches/340-lock_util.patch new file mode 100644 index 0000000000..eb346421a4 --- /dev/null +++ b/package/utils/busybox/patches/340-lock_util.patch @@ -0,0 +1,172 @@ +--- a/include/applets.src.h ++++ b/include/applets.src.h +@@ -218,6 +218,7 @@ IF_LN(APPLET_NOEXEC(ln, ln, BB_DIR_BIN, + IF_LOAD_POLICY(APPLET(load_policy, BB_DIR_USR_SBIN, BB_SUID_DROP)) + IF_LOADFONT(APPLET(loadfont, BB_DIR_USR_SBIN, BB_SUID_DROP)) + IF_LOADKMAP(APPLET(loadkmap, BB_DIR_SBIN, BB_SUID_DROP)) ++IF_LOCK(APPLET(lock, BB_DIR_BIN, BB_SUID_DROP)) + IF_LOGGER(APPLET(logger, BB_DIR_USR_BIN, BB_SUID_DROP)) + /* Needs to be run by root or be suid root - needs to change uid and gid: */ + IF_LOGIN(APPLET(login, BB_DIR_BIN, BB_SUID_REQUIRE)) +--- a/miscutils/Config.src ++++ b/miscutils/Config.src +@@ -419,6 +419,11 @@ config FEATURE_HDPARM_HDIO_GETSET_DMA + help + Enables the 'hdparm -d' option to get/set using_dma flag. + ++config LOCK ++ bool "lock" ++ help ++ Small utility for using locks in scripts ++ + config MAKEDEVS + bool "makedevs" + default y +--- a/miscutils/Kbuild.src ++++ b/miscutils/Kbuild.src +@@ -29,6 +29,7 @@ lib-$(CONFIG_INOTIFYD) += inotifyd.o + lib-$(CONFIG_FEATURE_LAST_SMALL)+= last.o + lib-$(CONFIG_FEATURE_LAST_FANCY)+= last_fancy.o + lib-$(CONFIG_LESS) += less.o ++lib-$(CONFIG_LOCK) += lock.o + lib-$(CONFIG_MAKEDEVS) += makedevs.o + lib-$(CONFIG_MAN) += man.o + lib-$(CONFIG_MICROCOM) += microcom.o +--- /dev/null ++++ b/miscutils/lock.c +@@ -0,0 +1,135 @@ ++/* ++ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> ++ * ++ * This is free software, licensed under the GNU General Public License v2. ++ */ ++#include <sys/types.h> ++#include <sys/file.h> ++#include <sys/stat.h> ++#include <signal.h> ++#include <fcntl.h> ++#include <unistd.h> ++#include <stdio.h> ++#include "busybox.h" ++ ++//usage:#define lock_trivial_usage NOUSAGE_STR ++//usage:#define lock_full_usage "" ++ ++static int unlock = 0; ++static int shared = 0; ++static int waitonly = 0; ++static int fd; ++static char *file; ++ ++static void usage(char *name) ++{ ++ fprintf(stderr, "Usage: %s [-suw] <filename>\n" ++ " -s Use shared locking\n" ++ " -u Unlock\n" ++ " -w Wait for the lock to become free, don't acquire lock\n" ++ "\n", name); ++ exit(1); ++} ++ ++static void exit_unlock(int sig) ++{ ++ flock(fd, LOCK_UN); ++ exit(0); ++} ++ ++static int do_unlock(void) ++{ ++ FILE *f; ++ int i; ++ ++ if ((f = fopen(file, "r")) == NULL) ++ return 0; ++ ++ fscanf(f, "%d", &i); ++ if (i > 0) ++ kill(i, SIGTERM); ++ ++ fclose(f); ++ ++ return 0; ++} ++ ++static int do_lock(void) ++{ ++ int pid; ++ char pidstr[8]; ++ ++ if ((fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0700)) < 0) { ++ if ((fd = open(file, O_RDWR)) < 0) { ++ fprintf(stderr, "Can't open %s\n", file); ++ return 1; ++ } ++ } ++ ++ if (flock(fd, (shared ? LOCK_SH : LOCK_EX)) < 0) { ++ fprintf(stderr, "Can't lock %s\n", file); ++ return 1; ++ } ++ ++ pid = fork(); ++ ++ if (pid < 0) ++ return -1; ++ ++ if (pid == 0) { ++ signal(SIGKILL, exit_unlock); ++ signal(SIGTERM, exit_unlock); ++ signal(SIGINT, exit_unlock); ++ if (waitonly) ++ exit_unlock(0); ++ else ++ while (1) ++ sleep(1); ++ } else { ++ if (!waitonly) { ++ lseek(fd, 0, SEEK_SET); ++ ftruncate(fd, 0); ++ sprintf(pidstr, "%d\n", pid); ++ write(fd, pidstr, strlen(pidstr)); ++ close(fd); ++ } ++ ++ return 0; ++ } ++ return 0; ++} ++ ++int lock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; ++int lock_main(int argc, char **argv) ++{ ++ char **args = &argv[1]; ++ int c = argc - 1; ++ ++ while ((*args != NULL) && (*args)[0] == '-') { ++ char *ch = *args; ++ while (*(++ch) > 0) { ++ switch(*ch) { ++ case 'w': ++ waitonly = 1; ++ break; ++ case 's': ++ shared = 1; ++ break; ++ case 'u': ++ unlock = 1; ++ break; ++ } ++ } ++ c--; ++ args++; ++ } ++ ++ if (c != 1) ++ usage(argv[0]); ++ ++ file = *args; ++ if (unlock) ++ return do_unlock(); ++ else ++ return do_lock(); ++} diff --git a/package/utils/busybox/patches/350-httpd_redir.patch b/package/utils/busybox/patches/350-httpd_redir.patch new file mode 100644 index 0000000000..11125e71f1 --- /dev/null +++ b/package/utils/busybox/patches/350-httpd_redir.patch @@ -0,0 +1,90 @@ +--- a/networking/httpd.c ++++ b/networking/httpd.c +@@ -105,6 +105,7 @@ + //usage: IF_FEATURE_HTTPD_BASIC_AUTH(" [-r REALM]") + //usage: " [-h HOME]\n" + //usage: "or httpd -d/-e" IF_FEATURE_HTTPD_AUTH_MD5("/-m") " STRING" ++//usage: " [-R <path> [-H <host>]]" + //usage:#define httpd_full_usage "\n\n" + //usage: "Listen for incoming HTTP requests\n" + //usage: "\n -i Inetd mode" +@@ -121,6 +122,8 @@ + //usage: "\n -m STRING MD5 crypt STRING") + //usage: "\n -e STRING HTML encode STRING" + //usage: "\n -d STRING URL decode STRING" ++//usage: "\n -R PATH Redirect target path" ++//usage: "\n -H HOST Redirect target host" + + #include "libbb.h" + #if ENABLE_FEATURE_HTTPD_USE_SENDFILE +@@ -272,6 +275,8 @@ struct globals { + + const char *found_mime_type; + const char *found_moved_temporarily; ++ const char *redirect_path; ++ const char *redirect_host; + Htaccess_IP *ip_a_d; /* config allow/deny lines */ + + IF_FEATURE_HTTPD_BASIC_AUTH(const char *g_realm;) +@@ -322,6 +327,8 @@ struct globals { + #define index_page (G.index_page ) + #define found_mime_type (G.found_mime_type ) + #define found_moved_temporarily (G.found_moved_temporarily) ++#define redirect_path (G.redirect_path ) ++#define redirect_host (G.redirect_host ) + #define last_mod (G.last_mod ) + #define ip_a_d (G.ip_a_d ) + #define g_realm (G.g_realm ) +@@ -956,8 +963,11 @@ static void send_headers(int responseNum + } + #endif + if (responseNum == HTTP_MOVED_TEMPORARILY) { +- len += sprintf(iobuf + len, "Location: %s/%s%s\r\n", ++ len += sprintf(iobuf + len, "Location: %s%s%s%s%s%s\r\n", ++ (redirect_host ? "http://" : ""), ++ (redirect_host ? redirect_host : ""), + found_moved_temporarily, ++ (redirect_host ? "" : "/"), + (g_query ? "?" : ""), + (g_query ? g_query : "")); + } +@@ -1925,8 +1935,12 @@ static void handle_incoming_and_exit(con + } while (*++tptr); + *++urlp = '\0'; /* terminate after last character */ + ++ /* redirect active */ ++ if (redirect_path && (strncmp(urlcopy, redirect_path, strlen(redirect_path)) != 0)) ++ found_moved_temporarily = redirect_path; ++ + /* If URL is a directory, add '/' */ +- if (urlp[-1] != '/') { ++ if (!redirect_path && (urlp[-1] != '/')) { + if (is_directory(urlcopy + 1, 1, NULL)) { + found_moved_temporarily = urlcopy; + } +@@ -2283,7 +2297,9 @@ static void sighup_handler(int sig UNUSE + } + + enum { +- c_opt_config_file = 0, ++ R_opt_redirect_path = 0, ++ H_opt_redirect_host, ++ c_opt_config_file, + d_opt_decode_url, + h_opt_home_httpd, + IF_FEATURE_HTTPD_ENCODE_URL_STR(e_opt_encode_url,) +@@ -2332,12 +2348,13 @@ int httpd_main(int argc UNUSED_PARAM, ch + /* We do not "absolutize" path given by -h (home) opt. + * If user gives relative path in -h, + * $SCRIPT_FILENAME will not be set. */ +- opt = getopt32(argv, "c:d:h:" ++ opt = getopt32(argv, "R:H:c:d:h:" + IF_FEATURE_HTTPD_ENCODE_URL_STR("e:") + IF_FEATURE_HTTPD_BASIC_AUTH("r:") + IF_FEATURE_HTTPD_AUTH_MD5("m:") + IF_FEATURE_HTTPD_SETUID("u:") + "p:ifv", ++ &redirect_path, &redirect_host, + &opt_c_configFile, &url_for_decode, &home_httpd + IF_FEATURE_HTTPD_ENCODE_URL_STR(, &url_for_encode) + IF_FEATURE_HTTPD_BASIC_AUTH(, &g_realm) diff --git a/package/utils/busybox/patches/410-httpd_cgi_headers.patch b/package/utils/busybox/patches/410-httpd_cgi_headers.patch new file mode 100644 index 0000000000..b02a5b9d71 --- /dev/null +++ b/package/utils/busybox/patches/410-httpd_cgi_headers.patch @@ -0,0 +1,16 @@ +--- a/networking/httpd.c ++++ b/networking/httpd.c +@@ -1222,10 +1222,10 @@ static NOINLINE void cgi_io_loop_and_exi + if (full_write(STDOUT_FILENO, HTTP_200, sizeof(HTTP_200)-1) != sizeof(HTTP_200)-1) + break; + } +- /* Commented out: +- if (!strstr(rbuf, "ontent-")) { +- full_write(s, "Content-type: text/plain\r\n\r\n", 28); ++ if (!strstr(rbuf, "ontent-") && !strstr(rbuf, "ocation:")) { ++ full_write(1, "Content-type: text/plain\r\n\r\n", 28); + } ++ /* Previously commented out: + * Counter-example of valid CGI without Content-type: + * echo -en "HTTP/1.0 302 Found\r\n" + * echo -en "Location: http://www.busybox.net\r\n" diff --git a/package/utils/busybox/patches/440-httpd_chdir.patch b/package/utils/busybox/patches/440-httpd_chdir.patch new file mode 100644 index 0000000000..401c6eb5d0 --- /dev/null +++ b/package/utils/busybox/patches/440-httpd_chdir.patch @@ -0,0 +1,10 @@ +--- a/networking/httpd.c ++++ b/networking/httpd.c +@@ -1814,6 +1814,7 @@ static void handle_incoming_and_exit(con + char *header_ptr = header_ptr; + Htaccess_Proxy *proxy_entry; + #endif ++ xchdir(home_httpd); + + /* Allocation of iobuf is postponed until now + * (IOW, server process doesn't need to waste 8k) */ diff --git a/package/utils/busybox/patches/470-insmod_search.patch b/package/utils/busybox/patches/470-insmod_search.patch new file mode 100644 index 0000000000..7f0188fc82 --- /dev/null +++ b/package/utils/busybox/patches/470-insmod_search.patch @@ -0,0 +1,137 @@ +--- a/modutils/Config.src ++++ b/modutils/Config.src +@@ -247,7 +247,7 @@ config FEATURE_MODUTILS_SYMBOLS + config DEFAULT_MODULES_DIR + string "Default directory containing modules" + default "/lib/modules" +- depends on DEPMOD || MODPROBE || MODPROBE_SMALL || MODINFO ++ depends on DEPMOD || INSMOD || MODPROBE || MODPROBE_SMALL || MODINFO + help + Directory that contains kernel modules. + Defaults to "/lib/modules" +--- a/modutils/insmod.c ++++ b/modutils/insmod.c +@@ -11,6 +11,106 @@ + + #include "libbb.h" + #include "modutils.h" ++#include <sys/utsname.h> ++#ifndef CONFIG_FEATURE_2_4_MODULES ++#include <sys/mman.h> ++#include <asm/unistd.h> ++#include <sys/syscall.h> ++#endif ++ ++static char *g_filename = NULL; ++ ++static int FAST_FUNC check_module_name_match(const char *filename, struct stat *statbuf, ++ void *userdata, int depth) ++{ ++ char *fullname = (char *) userdata; ++ char *tmp; ++ ++ if (fullname[0] == '\0') ++ return FALSE; ++ ++ tmp = bb_get_last_path_component_nostrip(filename); ++ if (strcmp(tmp, fullname) == 0) { ++ /* Stop searching if we find a match */ ++ g_filename = xstrdup(filename); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++static int find_module(char *filename) ++{ ++ char *module_dir, real_module_dir[FILENAME_MAX]; ++ int len, slen, ret = ENOENT, k_version; ++ struct utsname myuname; ++ const char *suffix = ".ko"; ++ struct stat st; ++ ++ /* check the kernel version */ ++ if (uname(&myuname) != 0) ++ return EINVAL; ++ ++ k_version = myuname.release[0] - '0'; ++ ++ if (k_version < 2 || k_version > 9) ++ return EINVAL; ++ ++ if (k_version == 2) { ++ int k_patchlevel = myuname.release[2] - '0'; ++ if (k_patchlevel <= 4) ++#if ENABLE_FEATURE_2_4_MODULES ++ suffix = ".o"; ++#else ++ return EINVAL; ++#endif ++ } ++ ++ len = strlen(filename); ++ slen = strlen(suffix); ++ ++ /* check for suffix and absolute path first */ ++ if ((len < slen + 2) || (strcmp(filename + len - slen, suffix) != 0)) { ++ filename = xasprintf("%s%s", filename, suffix); ++ } else { ++ filename = strdup(filename); ++ if ((stat(filename, &st) == 0) && S_ISREG(st.st_mode)) { ++ g_filename = filename; ++ return 0; ++ } ++ free(filename); ++ return ENOENT; ++ } ++ ++ /* next: scan /lib/modules/<release> */ ++ /* Jump through hoops in case /lib/modules/`uname -r` ++ * is a symlink. We do not want recursive_action to ++ * follow symlinks, but we do want to follow the ++ * /lib/modules/`uname -r` dir, So resolve it ourselves ++ * if it is a link... */ ++ module_dir = concat_path_file(CONFIG_DEFAULT_MODULES_DIR, myuname.release); ++ if (realpath(module_dir, real_module_dir) != NULL) { ++ free(module_dir); ++ module_dir = real_module_dir; ++ } ++ ++ recursive_action(module_dir, ACTION_RECURSE, ++ check_module_name_match, 0, filename, 0); ++ ++ /* Check if we have a complete path */ ++ if (g_filename == NULL) ++ goto done; ++ ++ if ((stat(g_filename, &st) == 0) && S_ISREG(st.st_mode)) ++ ret = 0; ++ else ++ free(g_filename); ++ ++done: ++ free(filename); ++ ++ return ret; ++} + + /* 2.6 style insmod has no options and required filename + * (not module name - .ko can't be omitted) */ +@@ -58,9 +158,15 @@ int insmod_main(int argc UNUSED_PARAM, c + if (!filename) + bb_show_usage(); + +- rc = bb_init_module(filename, parse_cmdline_module_options(argv, /*quote_spaces:*/ 0)); ++ rc = find_module(filename); ++ if (rc || (g_filename == NULL)) ++ goto done; ++ ++ rc = bb_init_module(g_filename, parse_cmdline_module_options(argv, /*quote_spaces:*/ 0)); + if (rc) + bb_error_msg("can't insert '%s': %s", filename, moderror(rc)); ++ free (g_filename); + ++done: + return rc; + } diff --git a/package/utils/busybox/patches/490-mount_disable_check.patch b/package/utils/busybox/patches/490-mount_disable_check.patch new file mode 100644 index 0000000000..2fcb7f7fc2 --- /dev/null +++ b/package/utils/busybox/patches/490-mount_disable_check.patch @@ -0,0 +1,12 @@ +--- a/util-linux/mount.c ++++ b/util-linux/mount.c +@@ -128,9 +128,6 @@ + #if ENABLE_FEATURE_MOUNT_NFS + /* This is just a warning of a common mistake. Possibly this should be a + * uclibc faq entry rather than in busybox... */ +-# if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_RPC__) +-# error "You need to build uClibc with UCLIBC_HAS_RPC for NFS support" +-# endif + # include <rpc/rpc.h> + # include <rpc/pmap_prot.h> + # include <rpc/pmap_clnt.h> diff --git a/package/utils/busybox/patches/510-awk_include.patch b/package/utils/busybox/patches/510-awk_include.patch new file mode 100644 index 0000000000..9f525acf86 --- /dev/null +++ b/package/utils/busybox/patches/510-awk_include.patch @@ -0,0 +1,217 @@ +--- a/editors/awk.c ++++ b/editors/awk.c +@@ -1,3 +1,4 @@ ++ + /* vi: set sw=4 ts=4: */ + /* + * awk implementation for busybox +@@ -81,9 +82,14 @@ typedef struct chain_s { + } chain; + + /* Function */ ++typedef var *(*awk_cfunc)(var *res, var *args, int nargs); + typedef struct func_s { + unsigned nargs; ++ enum { AWKFUNC, CFUNC } type; ++ union { ++ awk_cfunc cfunc; + struct chain_s body; ++ } x; + } func; + + /* I/O stream */ +@@ -1473,7 +1479,8 @@ static void parse_program(char *p) + next_token(TC_FUNCTION); + g_pos++; + f = newfunc(t_string); +- f->body.first = NULL; ++ f->type = AWKFUNC; ++ f->x.body.first = NULL; + f->nargs = 0; + while (next_token(TC_VARIABLE | TC_SEQTERM) & TC_VARIABLE) { + v = findvar(ahash, t_string); +@@ -1482,7 +1489,7 @@ static void parse_program(char *p) + if (next_token(TC_COMMA | TC_SEQTERM) & TC_SEQTERM) + break; + } +- seq = &f->body; ++ seq = &f->x.body; + chain_group(); + clear_array(ahash); + +@@ -2580,7 +2587,8 @@ static var *evaluate(node *op, var *res) + var *vbeg, *v; + const char *sv_progname; + +- if (!op->r.f->body.first) ++ if ((op->r.f->type == AWKFUNC) && ++ !op->r.f->x.body.first) + syntax_error(EMSG_UNDEF_FUNC); + + vbeg = v = nvalloc(op->r.f->nargs + 1); +@@ -2597,7 +2605,10 @@ static var *evaluate(node *op, var *res) + fnargs = vbeg; + sv_progname = g_progname; + +- res = evaluate(op->r.f->body.first, res); ++ if (op->r.f->type == AWKFUNC) ++ res = evaluate(op->r.f->x.body.first, res); ++ else if (op->r.f->type == CFUNC) ++ res = op->r.f->x.cfunc(res, fnargs, op->r.f->nargs); + + g_progname = sv_progname; + nvfree(fnargs); +@@ -2991,6 +3002,143 @@ static rstream *next_input_file(void) + #undef files_happen + } + ++/* read the contents of an entire file */ ++static char *get_file(const char *fname) ++{ ++ FILE *F; ++ char *s = NULL; ++ int i, j, flen; ++ ++ F = fopen(fname, "r"); ++ if (!F) { ++ return NULL; ++ } ++ ++ if (fseek(F, 0, SEEK_END) == 0) { ++ flen = ftell(F); ++ s = (char *)xmalloc(flen+4); ++ fseek(F, 0, SEEK_SET); ++ i = 1 + fread(s+1, 1, flen, F); ++ } else { ++ for (i=j=1; j>0; i+=j) { ++ s = (char *)xrealloc(s, i+4096); ++ j = fread(s+i, 1, 4094, F); ++ } ++ } ++ ++ s[i] = '\0'; ++ fclose(F); ++ return s; ++} ++ ++ ++/* parse_include(): ++ * ++ * taken from parse_program from awk.c ++ * END{} is not parsed here, and BEGIN{} is executed immediately ++ */ ++static void parse_include(char *p) ++{ ++ uint32_t tclass; ++ chain *initseq = NULL; ++ chain tmp; ++ func *f; ++ var *v, *tv; ++ ++ tv = nvalloc(1); ++ memset(&tmp, 0, sizeof(tmp)); ++ g_pos = p; ++ t_lineno = 1; ++ while ((tclass = next_token(TC_EOF | TC_OPSEQ | ++ TC_OPTERM | TC_BEGIN | TC_FUNCDECL)) != TC_EOF) { ++ if (tclass & TC_OPTERM) ++ continue; ++ ++ seq = &tmp; ++ if (tclass & TC_BEGIN) { ++ initseq = xzalloc(sizeof(chain)); ++ seq = initseq; ++ chain_group(); ++ } else if (tclass & TC_FUNCDECL) { ++ next_token(TC_FUNCTION); ++ g_pos++; ++ f = newfunc(t_string); ++ f->type = AWKFUNC; ++ f->x.body.first = NULL; ++ f->nargs = 0; ++ while (next_token(TC_VARIABLE | TC_SEQTERM) & TC_VARIABLE) { ++ v = findvar(ahash, t_string); ++ v->x.aidx = (f->nargs)++; ++ ++ if (next_token(TC_COMMA | TC_SEQTERM) & TC_SEQTERM) ++ break; ++ } ++ seq = &(f->x.body); ++ chain_group(); ++ clear_array(ahash); ++ } ++ } ++ if (initseq && initseq->first) ++ tv = evaluate(initseq->first, tv); ++ nvfree(tv); ++} ++ ++ ++/* include an awk file and run its BEGIN{} section */ ++static xhash *includes = NULL; ++static void include_file(const char *filename) ++{ ++ char *s; ++ var *v; ++ int oldlnr = g_lineno; ++ const char *oldprg = g_progname; ++ ++ if (!includes) ++ includes = hash_init(); ++ ++ /* find out if the file has been included already */ ++ v = findvar(includes, filename); ++ if (istrue(v)) ++ return; ++ setvar_s(v, "1"); ++ ++ /* read include file */ ++ s = get_file(filename); ++ if (!s) { ++ fprintf(stderr, "Could not open file.\n"); ++ return; ++ } ++ g_lineno = 1; ++ g_progname = xstrdup(filename); ++ parse_include(s+1); ++ free(s); ++ g_lineno = oldlnr; ++ g_progname = oldprg; ++} ++ ++static var *include(var *res, var *args, int nargs) ++{ ++ const char *s; ++ ++ nargs = nargs; /* shut up, gcc */ ++ s = getvar_s(args); ++ if (s && (strlen(s) > 0)) ++ include_file(s); ++ ++ return res; ++} ++ ++/* registers a global c function for the awk interpreter */ ++static void register_cfunc(const char *name, awk_cfunc cfunc, int nargs) ++{ ++ func *f; ++ ++ f = newfunc(name); ++ f->type = CFUNC; ++ f->x.cfunc = cfunc; ++ f->nargs = nargs; ++} ++ + int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; + int awk_main(int argc, char **argv) + { +@@ -3056,6 +3204,9 @@ int awk_main(int argc, char **argv) + *s1 = '='; + } + } ++ ++ register_cfunc("include", include, 1); ++ + opt_complementary = "v::f::"; /* -v and -f can occur multiple times */ + opt = getopt32(argv, "F:v:f:W:", &opt_F, &list_v, &list_f, &opt_W); + argv += optind; diff --git a/package/utils/busybox/patches/524-udhcpc_renew.patch b/package/utils/busybox/patches/524-udhcpc_renew.patch new file mode 100644 index 0000000000..c22fa52ea2 --- /dev/null +++ b/package/utils/busybox/patches/524-udhcpc_renew.patch @@ -0,0 +1,10 @@ +--- a/networking/udhcp/dhcpc.c ++++ b/networking/udhcp/dhcpc.c +@@ -1045,7 +1045,6 @@ static void perform_renew(void) + state = RENEW_REQUESTED; + break; + case RENEW_REQUESTED: /* impatient are we? fine, square 1 */ +- udhcp_run_script(NULL, "deconfig"); + case REQUESTING: + case RELEASED: + change_listen_mode(LISTEN_RAW); diff --git a/package/utils/busybox/patches/610-ntpd_delayed_resolve.patch b/package/utils/busybox/patches/610-ntpd_delayed_resolve.patch new file mode 100644 index 0000000000..5e17ae16c2 --- /dev/null +++ b/package/utils/busybox/patches/610-ntpd_delayed_resolve.patch @@ -0,0 +1,48 @@ +--- a/networking/ntpd.c ++++ b/networking/ntpd.c +@@ -216,6 +216,7 @@ typedef struct { + typedef struct { + len_and_sockaddr *p_lsa; + char *p_dotted; ++ char *p_hostname; + /* when to send new query (if p_fd == -1) + * or when receive times out (if p_fd >= 0): */ + int p_fd; +@@ -646,8 +647,9 @@ add_peers(char *s) + peer_t *p; + + p = xzalloc(sizeof(*p)); +- p->p_lsa = xhost2sockaddr(s, 123); +- p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa); ++ p->p_hostname = s; ++ p->p_lsa = NULL; ++ p->p_dotted = NULL; + p->p_fd = -1; + p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); + p->next_action_time = G.cur_time; /* = set_next(p, 0); */ +@@ -696,6 +698,25 @@ send_query_to_peer(peer_t *p) + * + * Uncomment this and use strace to see it in action: + */ ++ ++ /* See if the peer hostname already resolved yet, if not, retry to resolv and return on failure */ ++ if (!p->p_lsa) ++ { ++ p->p_lsa = host2sockaddr(p->p_hostname, 123); ++ ++ if (p->p_lsa) ++ { ++ p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa); ++ VERB1 bb_error_msg("resolved peer %s to %s", p->p_hostname, p->p_dotted); ++ } ++ else ++ { ++ set_next(p, RETRY_INTERVAL); ++ VERB1 bb_error_msg("could not resolve peer %s, skipping", p->p_hostname); ++ return; ++ } ++ } ++ + #define PROBE_LOCAL_ADDR /* { len_and_sockaddr lsa; lsa.len = LSA_SIZEOF_SA; getsockname(p->query.fd, &lsa.u.sa, &lsa.len); } */ + + if (p->p_fd == -1) { diff --git a/package/utils/busybox/patches/611-upstream_ntpd_version_fix.patch b/package/utils/busybox/patches/611-upstream_ntpd_version_fix.patch new file mode 100644 index 0000000000..7bcb8475d7 --- /dev/null +++ b/package/utils/busybox/patches/611-upstream_ntpd_version_fix.patch @@ -0,0 +1,29 @@ +From b7841cf7b919b16d1bd4619154bf7cb4c22b4ccd Mon Sep 17 00:00:00 2001 +From: Paul Marks <paul@pmarks.net> +Date: Mon, 14 Jan 2013 01:39:10 +0000 +Subject: ntpd: fix incorrect m_status field in outgoing packets. Closes 5120 + +When using busybox ntpd with an NTPv3 client and NTPv4 server (or vice +versa), the version numbers can be incorrectly ORed together, yielding +the bogus value of "NTPv7". This makes ntpd unusable with clients +such as Chrony and Windows "Internet Time". + +This patch avoids the version mangling, by copying only the Leap +Indicator bits from the server's status field. + +Signed-off-by: Paul Marks <paul@pmarks.net> +Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> +--- +(limited to 'networking/ntpd.c') + +--- a/networking/ntpd.c ++++ b/networking/ntpd.c +@@ -1794,7 +1794,7 @@ recv_and_process_client_pkt(void /*int f + + /* Build a reply packet */ + memset(&msg, 0, sizeof(msg)); +- msg.m_status = G.stratum < MAXSTRAT ? G.ntp_status : LI_ALARM; ++ msg.m_status = G.stratum < MAXSTRAT ? (G.ntp_status & LI_MASK) : LI_ALARM; + msg.m_status |= (query_status & VERSION_MASK); + msg.m_status |= ((query_status & MODE_MASK) == MODE_CLIENT) ? + MODE_SERVER : MODE_SYM_PAS; diff --git a/package/utils/busybox/patches/700-hexdump_segfault_fix.patch b/package/utils/busybox/patches/700-hexdump_segfault_fix.patch new file mode 100644 index 0000000000..ab09fb3e42 --- /dev/null +++ b/package/utils/busybox/patches/700-hexdump_segfault_fix.patch @@ -0,0 +1,11 @@ +--- a/libbb/dump.c ++++ b/libbb/dump.c +@@ -301,7 +301,7 @@ static NOINLINE void rewrite(priv_dumper + ) { + fu->reps += (dumper->blocksize - fs->bcnt) / fu->bcnt; + } +- if (fu->reps > 1) { ++ if (fu->reps > 1 && fu->nextpr) { + for (pr = fu->nextpr;; pr = pr->nextpr) + if (!pr->nextpr) + break; diff --git a/package/utils/busybox/patches/802-brctl_linux24.patch b/package/utils/busybox/patches/802-brctl_linux24.patch new file mode 100644 index 0000000000..8cc19779a2 --- /dev/null +++ b/package/utils/busybox/patches/802-brctl_linux24.patch @@ -0,0 +1,74 @@ +--- a/networking/brctl.c ++++ b/networking/brctl.c +@@ -56,7 +56,7 @@ + + /* Maximum number of ports supported per bridge interface. */ + #ifndef MAX_PORTS +-# define MAX_PORTS 32 ++# define MAX_PORTS 1024 + #endif + + /* Use internal number parsing and not the "exact" conversion. */ +@@ -193,6 +193,7 @@ int brctl_main(int argc UNUSED_PARAM, ch + printf(bi.stp_enabled ? "\tyes" : "\tno"); + + /* print interface list */ ++ memset(ifidx, 0, sizeof ifidx); + arm_ioctl(args, BRCTL_GET_PORT_LIST, + (unsigned long) ifidx, MAX_PORTS); + xioctl(fd, SIOCDEVPRIVATE, &ifr); +@@ -221,9 +222,19 @@ int brctl_main(int argc UNUSED_PARAM, ch + br = *argv++; + + if (key == ARG_addbr || key == ARG_delbr) { /* addbr or delbr */ +- ioctl_or_perror_and_die(fd, +- key == ARG_addbr ? SIOCBRADDBR : SIOCBRDELBR, +- br, "bridge %s", br); ++ int ret; ++ ret = ioctl(fd, ++ key == ARG_addbr ? SIOCBRADDBR : SIOCBRDELBR, ++ br); ++ if (ret < 0) { ++ arm_ioctl(args, ++ key == ARG_addbr ? BRCTL_ADD_BRIDGE : BRCTL_DEL_BRIDGE, ++ (unsigned long) br, 0); ++ ret = ioctl(fd, SIOCSIFBR, args); ++ } ++ if (ret < 0) { ++ bb_perror_msg_and_die("bridge %s", br); ++ } + goto done; + } + +@@ -232,14 +243,27 @@ int brctl_main(int argc UNUSED_PARAM, ch + + strncpy_IFNAMSIZ(ifr.ifr_name, br); + if (key == ARG_addif || key == ARG_delif) { /* addif or delif */ ++ int ret; ++ int if_index; + brif = *argv; +- ifr.ifr_ifindex = if_nametoindex(brif); +- if (!ifr.ifr_ifindex) { ++ if_index = if_nametoindex(brif); ++ if (!if_index) { + bb_perror_msg_and_die("iface %s", brif); + } +- ioctl_or_perror_and_die(fd, ++ ifr.ifr_ifindex = if_index; ++ ret = ioctl(fd, + key == ARG_addif ? SIOCBRADDIF : SIOCBRDELIF, +- &ifr, "bridge %s", br); ++ &ifr); ++ if (ret < 0) { ++ arm_ioctl(args, ++ key == ARG_addif ? BRCTL_ADD_IF : BRCTL_DEL_IF, ++ if_index, 0); ++ ifr.ifr_data = (char *) &args; ++ ret = ioctl(fd, SIOCDEVPRIVATE, &ifr); ++ } ++ if (ret < 0) { ++ bb_perror_msg_and_die("bridge %s", br); ++ } + goto done_next_argv; + } + #if ENABLE_FEATURE_BRCTL_FANCY diff --git a/package/utils/busybox/patches/902-telnetd_intr.patch b/package/utils/busybox/patches/902-telnetd_intr.patch new file mode 100644 index 0000000000..862ece055d --- /dev/null +++ b/package/utils/busybox/patches/902-telnetd_intr.patch @@ -0,0 +1,10 @@ +--- a/networking/telnetd.c ++++ b/networking/telnetd.c +@@ -330,6 +330,7 @@ make_new_session( + + /* Restore default signal handling ASAP */ + bb_signals((1 << SIGCHLD) + (1 << SIGPIPE), SIG_DFL); ++ signal(SIGINT, SIG_DFL); + + pid = getpid(); + diff --git a/package/utils/busybox/patches/910-insmod-q-flag.patch b/package/utils/busybox/patches/910-insmod-q-flag.patch new file mode 100644 index 0000000000..6002f20f1b --- /dev/null +++ b/package/utils/busybox/patches/910-insmod-q-flag.patch @@ -0,0 +1,33 @@ +--- a/modutils/insmod.c ++++ b/modutils/insmod.c +@@ -139,7 +139,7 @@ int insmod_main(int argc, char **argv) M + int insmod_main(int argc UNUSED_PARAM, char **argv) + { + char *filename; +- int rc; ++ int rc, opt; + + /* Compat note: + * 2.6 style insmod has no options and required filename +@@ -149,10 +149,8 @@ int insmod_main(int argc UNUSED_PARAM, c + * or in $MODPATH. + */ + +- IF_FEATURE_2_4_MODULES( +- getopt32(argv, INSMOD_OPTS INSMOD_ARGS); +- argv += optind - 1; +- ); ++ opt = getopt32(argv, INSMOD_OPTS, NULL, NULL); ++ argv += optind - 1; + + filename = *++argv; + if (!filename) +@@ -163,7 +161,7 @@ int insmod_main(int argc UNUSED_PARAM, c + goto done; + + rc = bb_init_module(g_filename, parse_cmdline_module_options(argv, /*quote_spaces:*/ 0)); +- if (rc) ++ if (rc && !(opt & INSMOD_OPT_SILENT)) + bb_error_msg("can't insert '%s': %s", filename, moderror(rc)); + free (g_filename); + diff --git a/package/utils/busybox/patches/911-date-k-flag.patch b/package/utils/busybox/patches/911-date-k-flag.patch new file mode 100644 index 0000000000..c55ee23369 --- /dev/null +++ b/package/utils/busybox/patches/911-date-k-flag.patch @@ -0,0 +1,87 @@ +--- a/coreutils/date.c ++++ b/coreutils/date.c +@@ -123,6 +123,7 @@ + //usage: IF_FEATURE_DATE_ISOFMT( + //usage: "\n -D FMT Use FMT for -d TIME conversion" + //usage: ) ++//usage: "\n -k Set Kernel timezone from localtime and exit" + //usage: "\n" + //usage: "\nRecognized TIME formats:" + //usage: "\n hh:mm[:ss]" +@@ -135,6 +136,7 @@ + //usage: "Wed Apr 12 18:52:41 MDT 2000\n" + + #include "libbb.h" ++#include <sys/time.h> + #if ENABLE_FEATURE_DATE_NANO + # include <sys/syscall.h> + #endif +@@ -145,8 +147,9 @@ enum { + OPT_UTC = (1 << 2), /* u */ + OPT_DATE = (1 << 3), /* d */ + OPT_REFERENCE = (1 << 4), /* r */ +- OPT_TIMESPEC = (1 << 5) * ENABLE_FEATURE_DATE_ISOFMT, /* I */ +- OPT_HINT = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* D */ ++ OPT_KERNELTZ = (1 << 5), /* k */ ++ OPT_TIMESPEC = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* I */ ++ OPT_HINT = (1 << 7) * ENABLE_FEATURE_DATE_ISOFMT, /* D */ + }; + + static void maybe_set_utc(int opt) +@@ -164,12 +167,15 @@ static const char date_longopts[] ALIGN1 + /* "universal\0" No_argument "u" */ + "date\0" Required_argument "d" + "reference\0" Required_argument "r" ++ "set-kernel-tz\0" No_argument "k" + ; + #endif + + int date_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; + int date_main(int argc UNUSED_PARAM, char **argv) + { ++ time_t tt; ++ struct timezone tz; + struct timespec ts; + struct tm tm_time; + char buf_fmt_dt2str[64]; +@@ -184,7 +190,7 @@ int date_main(int argc UNUSED_PARAM, cha + opt_complementary = "d--s:s--d" + IF_FEATURE_DATE_ISOFMT(":R--I:I--R"); + IF_LONG_OPTS(applet_long_options = date_longopts;) +- opt = getopt32(argv, "Rs:ud:r:" ++ opt = getopt32(argv, "Rs:ud:r:k" + IF_FEATURE_DATE_ISOFMT("I::D:"), + &date_str, &date_str, &filename + IF_FEATURE_DATE_ISOFMT(, &isofmt_arg, &fmt_str2dt)); +@@ -241,6 +247,31 @@ int date_main(int argc UNUSED_PARAM, cha + if (*argv) + bb_show_usage(); + ++ /* Setting of kernel timezone was requested */ ++ if (opt & OPT_KERNELTZ) { ++ tt = time(NULL); ++ localtime_r(&tt, &tm_time); ++ ++ /* workaround warp_clock() on first invocation */ ++ memset(&tz, 0, sizeof(tz)); ++ settimeofday(NULL, &tz); ++ ++ memset(&tz, 0, sizeof(tz)); ++#ifdef __USE_BSD ++ tz.tz_minuteswest = -(tm_time.tm_gmtoff / 60); ++#else ++ tz.tz_minuteswest = -(tm_time.__tm_gmtoff / 60); ++#endif ++ ++ if (settimeofday(NULL, &tz)) ++ { ++ bb_perror_msg("can't set kernel time zone"); ++ return EXIT_FAILURE; ++ } ++ ++ return EXIT_SUCCESS; ++ } ++ + /* Now we have parsed all the information except the date format + * which depends on whether the clock is being set or read */ + diff --git a/package/utils/busybox/patches/920-portability.patch b/package/utils/busybox/patches/920-portability.patch new file mode 100644 index 0000000000..4e5b9a0576 --- /dev/null +++ b/package/utils/busybox/patches/920-portability.patch @@ -0,0 +1,13 @@ +--- a/scripts/kconfig/mconf.c ++++ b/scripts/kconfig/mconf.c +@@ -25,6 +25,10 @@ + #include <unistd.h> + #include <locale.h> + ++#ifndef SIGWINCH ++#define SIGWINCH 28 ++#endif ++ + #define LKC_DIRECT_LINK + #include "lkc.h" + diff --git a/package/utils/busybox/patches/950-partial-checksum.patch b/package/utils/busybox/patches/950-partial-checksum.patch new file mode 100644 index 0000000000..6e8a69e9a6 --- /dev/null +++ b/package/utils/busybox/patches/950-partial-checksum.patch @@ -0,0 +1,86 @@ +--- a/networking/udhcp/dhcpc.c ++++ b/networking/udhcp/dhcpc.c +@@ -26,8 +26,8 @@ + #include "dhcpc.h" + + #include <netinet/if_ether.h> +-#include <netpacket/packet.h> + #include <linux/filter.h> ++#include <linux/if_packet.h> + + /* struct client_config_t client_config is in bb_common_bufsiz1 */ + +@@ -846,17 +846,41 @@ static int send_release(uint32_t server, + static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) + { + int bytes; ++ int nocsum = 0; + struct ip_udp_dhcp_packet packet; + uint16_t check; ++ unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))]; ++ struct iovec iov = { ++ .iov_base = &packet, ++ .iov_len = sizeof(packet), ++ }; ++ struct msghdr msg = { ++ .msg_iov = &iov, ++ .msg_iovlen = 1, ++ .msg_control = cmsgbuf, ++ .msg_controllen = sizeof(cmsgbuf), ++ }; ++ struct cmsghdr *cmsg; + + memset(&packet, 0, sizeof(packet)); +- bytes = safe_read(fd, &packet, sizeof(packet)); ++ do { ++ bytes = recvmsg(fd, &msg, 0); ++ } while (bytes < 0 && errno == EINTR); ++ + if (bytes < 0) { + log1("Packet read error, ignoring"); + /* NB: possible down interface, etc. Caller should pause. */ + return bytes; /* returns -1 */ + } + ++ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { ++ if (cmsg->cmsg_level == SOL_PACKET && ++ cmsg->cmsg_type == PACKET_AUXDATA) { ++ struct tpacket_auxdata *aux = (void *)CMSG_DATA(cmsg); ++ nocsum = aux->tp_status & TP_STATUS_CSUMNOTREADY; ++ } ++ } ++ + if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp))) { + log1("Packet is too short, ignoring"); + return -2; +@@ -896,7 +920,7 @@ static NOINLINE int udhcp_recv_raw_packe + packet.ip.tot_len = packet.udp.len; /* yes, this is needed */ + check = packet.udp.check; + packet.udp.check = 0; +- if (check && check != udhcp_checksum(&packet, bytes)) { ++ if (!nocsum && check && check != udhcp_checksum(&packet, bytes)) { + log1("Packet with bad UDP checksum received, ignoring"); + return -2; + } +@@ -942,6 +966,7 @@ static int udhcp_raw_socket(int ifindex) + { + int fd; + struct sockaddr_ll sock; ++ int val; + + /* + * Comment: +@@ -1008,6 +1033,13 @@ static int udhcp_raw_socket(int ifindex) + log1("Attached filter to raw socket fd %d", fd); // log? + } + ++ val = 1; ++ if (setsockopt(fd, SOL_PACKET, PACKET_AUXDATA, &val, ++ sizeof(val)) < 0) { ++ if (errno != ENOPROTOOPT) ++ log1("Failed to set auxiliary packet data for socket fd %d", fd); ++ } ++ + log1("Created raw socket"); + + return fd; diff --git a/package/utils/busybox/patches/998-arping_missing_includes.patch b/package/utils/busybox/patches/998-arping_missing_includes.patch new file mode 100644 index 0000000000..a9d4a62af3 --- /dev/null +++ b/package/utils/busybox/patches/998-arping_missing_includes.patch @@ -0,0 +1,11 @@ +--- a/networking/arping.c ++++ b/networking/arping.c +@@ -24,6 +24,8 @@ + + #include <arpa/inet.h> + #include <net/if.h> ++#include <net/if_arp.h> ++#include <netinet/if_ether.h> + #include <netinet/ether.h> + #include <netpacket/packet.h> + diff --git a/package/utils/busybox/patches/999-musl-fixes.patch b/package/utils/busybox/patches/999-musl-fixes.patch new file mode 100644 index 0000000000..b528b3e81b --- /dev/null +++ b/package/utils/busybox/patches/999-musl-fixes.patch @@ -0,0 +1,16 @@ +--- a/include/platform.h ++++ b/include/platform.h +@@ -443,6 +443,13 @@ typedef unsigned smalluint; + # undef HAVE_NET_ETHERNET_H + #endif + ++#if defined(__musl__) ++# undef HAVE_SETBIT ++# include <stddef.h> ++# include <termios.h> ++# include <sys/ioctl.h> ++#endif ++ + /* + * Now, define prototypes for all the functions defined in platform.c + * These must come after all the HAVE_* macros are defined (or not) |